TianoCore EDK2 master
Loading...
Searching...
No Matches
Locate.c
Go to the documentation of this file.
1
9#include "PiSmmCore.h"
10
11//
12// ProtocolRequest - Last LocateHandle request ID
13//
14UINTN mEfiLocateHandleRequest = 0;
15
16//
17// Internal prototypes
18//
19
20typedef struct {
21 EFI_GUID *Protocol;
22 VOID *SearchKey;
23 LIST_ENTRY *Position;
24 PROTOCOL_ENTRY *ProtEntry;
26
27typedef
28IHANDLE *
29(*CORE_GET_NEXT) (
30 IN OUT LOCATE_POSITION *Position,
31 OUT VOID **Interface
32 );
33
45IHANDLE *
47 IN OUT LOCATE_POSITION *Position,
48 OUT VOID **Interface
49 )
50{
51 IHANDLE *Handle;
52
53 //
54 // Next handle
55 //
56 Position->Position = Position->Position->ForwardLink;
57
58 //
59 // If not at the end of the list, get the handle
60 //
61 Handle = NULL;
62 *Interface = NULL;
63 if (Position->Position != &gHandleList) {
64 Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
65 }
66
67 return Handle;
68}
69
82IHANDLE *
84 IN OUT LOCATE_POSITION *Position,
85 OUT VOID **Interface
86 )
87{
88 IHANDLE *Handle;
89 PROTOCOL_NOTIFY *ProtNotify;
91 LIST_ENTRY *Link;
92
93 Handle = NULL;
94 *Interface = NULL;
95 ProtNotify = Position->SearchKey;
96
97 //
98 // If this is the first request, get the next handle
99 //
100 if (ProtNotify != NULL) {
101 ASSERT (ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);
102 Position->SearchKey = NULL;
103
104 //
105 // If not at the end of the list, get the next handle
106 //
107 Link = ProtNotify->Position->ForwardLink;
108 if (Link != &ProtNotify->Protocol->Protocols) {
109 Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
110 Handle = Prot->Handle;
111 *Interface = Prot->Interface;
112 }
113 }
114
115 return Handle;
116}
117
129IHANDLE *
131 IN OUT LOCATE_POSITION *Position,
132 OUT VOID **Interface
133 )
134{
135 IHANDLE *Handle;
136 LIST_ENTRY *Link;
137 PROTOCOL_INTERFACE *Prot;
138
139 Handle = NULL;
140 *Interface = NULL;
141 for ( ; ;) {
142 //
143 // Next entry
144 //
145 Link = Position->Position->ForwardLink;
146 Position->Position = Link;
147
148 //
149 // If not at the end, return the handle
150 //
151 if (Link == &Position->ProtEntry->Protocols) {
152 Handle = NULL;
153 break;
154 }
155
156 //
157 // Get the handle
158 //
159 Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
160 Handle = Prot->Handle;
161 *Interface = Prot->Interface;
162
163 //
164 // If this handle has not been returned this request, then
165 // return it now
166 //
167 if (Handle->LocateRequest != mEfiLocateHandleRequest) {
168 Handle->LocateRequest = mEfiLocateHandleRequest;
169 break;
170 }
171 }
172
173 return Handle;
174}
175
193EFIAPI
195 IN EFI_GUID *Protocol,
196 IN VOID *Registration OPTIONAL,
197 OUT VOID **Interface
198 )
199{
200 EFI_STATUS Status;
201 LOCATE_POSITION Position;
202 PROTOCOL_NOTIFY *ProtNotify;
203 IHANDLE *Handle;
204
205 if ((Interface == NULL) || (Protocol == NULL)) {
206 return EFI_INVALID_PARAMETER;
207 }
208
209 *Interface = NULL;
210 Status = EFI_SUCCESS;
211
212 //
213 // Set initial position
214 //
215 Position.Protocol = Protocol;
216 Position.SearchKey = Registration;
217 Position.Position = &gHandleList;
218
219 mEfiLocateHandleRequest += 1;
220
221 if (Registration == NULL) {
222 //
223 // Look up the protocol entry and set the head pointer
224 //
225 Position.ProtEntry = SmmFindProtocolEntry (Protocol, FALSE);
226 if (Position.ProtEntry == NULL) {
227 return EFI_NOT_FOUND;
228 }
229
230 Position.Position = &Position.ProtEntry->Protocols;
231
232 Handle = SmmGetNextLocateByProtocol (&Position, Interface);
233 } else {
234 Handle = SmmGetNextLocateByRegisterNotify (&Position, Interface);
235 }
236
237 if (Handle == NULL) {
238 Status = EFI_NOT_FOUND;
239 } else if (Registration != NULL) {
240 //
241 // If this is a search by register notify and a handle was
242 // returned, update the register notification position
243 //
244 ProtNotify = Registration;
245 ProtNotify->Position = ProtNotify->Position->ForwardLink;
246 }
247
248 return Status;
249}
250
270EFIAPI
272 IN EFI_LOCATE_SEARCH_TYPE SearchType,
273 IN EFI_GUID *Protocol OPTIONAL,
274 IN VOID *SearchKey OPTIONAL,
275 IN OUT UINTN *BufferSize,
276 OUT EFI_HANDLE *Buffer
277 )
278{
279 EFI_STATUS Status;
280 LOCATE_POSITION Position;
281 PROTOCOL_NOTIFY *ProtNotify;
282 CORE_GET_NEXT GetNext;
283 UINTN ResultSize;
284 IHANDLE *Handle;
285 IHANDLE **ResultBuffer;
286 VOID *Interface;
287
288 if (BufferSize == NULL) {
289 return EFI_INVALID_PARAMETER;
290 }
291
292 if ((*BufferSize > 0) && (Buffer == NULL)) {
293 return EFI_INVALID_PARAMETER;
294 }
295
296 GetNext = NULL;
297
298 //
299 // Set initial position
300 //
301 Position.Protocol = Protocol;
302 Position.SearchKey = SearchKey;
303 Position.Position = &gHandleList;
304
305 ResultSize = 0;
306 ResultBuffer = (IHANDLE **)Buffer;
307 Status = EFI_SUCCESS;
308
309 //
310 // Get the search function based on type
311 //
312 switch (SearchType) {
313 case AllHandles:
315 break;
316
317 case ByRegisterNotify:
319 //
320 // Must have SearchKey for locate ByRegisterNotify
321 //
322 if (SearchKey == NULL) {
323 Status = EFI_INVALID_PARAMETER;
324 }
325
326 break;
327
328 case ByProtocol:
330 if (Protocol == NULL) {
331 Status = EFI_INVALID_PARAMETER;
332 break;
333 }
334
335 //
336 // Look up the protocol entry and set the head pointer
337 //
338 Position.ProtEntry = SmmFindProtocolEntry (Protocol, FALSE);
339 if (Position.ProtEntry == NULL) {
340 Status = EFI_NOT_FOUND;
341 break;
342 }
343
344 Position.Position = &Position.ProtEntry->Protocols;
345 break;
346
347 default:
348 Status = EFI_INVALID_PARAMETER;
349 break;
350 }
351
352 if (EFI_ERROR (Status)) {
353 return Status;
354 }
355
356 //
357 // Enumerate out the matching handles
358 //
359 mEfiLocateHandleRequest += 1;
360 for ( ; ;) {
361 //
362 // Get the next handle. If no more handles, stop
363 //
364 Handle = GetNext (&Position, &Interface);
365 if (NULL == Handle) {
366 break;
367 }
368
369 //
370 // Increase the resulting buffer size, and if this handle
371 // fits return it
372 //
373 ResultSize += sizeof (Handle);
374 if (ResultSize <= *BufferSize) {
375 *ResultBuffer = Handle;
376 ResultBuffer += 1;
377 }
378 }
379
380 //
381 // If the result is a zero length buffer, then there were no
382 // matching handles
383 //
384 if (ResultSize == 0) {
385 Status = EFI_NOT_FOUND;
386 } else {
387 //
388 // Return the resulting buffer size. If it's larger than what
389 // was passed, then set the error code
390 //
391 if (ResultSize > *BufferSize) {
392 Status = EFI_BUFFER_TOO_SMALL;
393 }
394
395 *BufferSize = ResultSize;
396
397 if ((SearchType == ByRegisterNotify) && !EFI_ERROR (Status)) {
398 ASSERT (SearchKey != NULL);
399 //
400 // If this is a search by register notify and a handle was
401 // returned, update the register notification position
402 //
403 ProtNotify = SearchKey;
404 ProtNotify->Position = ProtNotify->Position->ForwardLink;
405 }
406 }
407
408 return Status;
409}
410
434EFIAPI
436 IN EFI_LOCATE_SEARCH_TYPE SearchType,
437 IN EFI_GUID *Protocol OPTIONAL,
438 IN VOID *SearchKey OPTIONAL,
439 IN OUT UINTN *NumberHandles,
440 OUT EFI_HANDLE **Buffer
441 )
442{
443 EFI_STATUS Status;
444 UINTN BufferSize;
445
446 if (NumberHandles == NULL) {
447 return EFI_INVALID_PARAMETER;
448 }
449
450 if (Buffer == NULL) {
451 return EFI_INVALID_PARAMETER;
452 }
453
454 BufferSize = 0;
455 *NumberHandles = 0;
456 *Buffer = NULL;
457 Status = SmmLocateHandle (
458 SearchType,
459 Protocol,
460 SearchKey,
461 &BufferSize,
462 *Buffer
463 );
464 //
465 // LocateHandleBuffer() returns incorrect status code if SearchType is
466 // invalid.
467 //
468 // Add code to correctly handle expected errors from SmmLocateHandle().
469 //
470 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
471 if (Status != EFI_INVALID_PARAMETER) {
472 Status = EFI_NOT_FOUND;
473 }
474
475 return Status;
476 }
477
478 *Buffer = AllocatePool (BufferSize);
479 if (*Buffer == NULL) {
480 return EFI_OUT_OF_RESOURCES;
481 }
482
483 Status = SmmLocateHandle (
484 SearchType,
485 Protocol,
486 SearchKey,
487 &BufferSize,
488 *Buffer
489 );
490
491 *NumberHandles = BufferSize / sizeof (EFI_HANDLE);
492 if (EFI_ERROR (Status)) {
493 *NumberHandles = 0;
494 }
495
496 return Status;
497}
UINT64 UINTN
PROTOCOL_ENTRY * SmmFindProtocolEntry(IN EFI_GUID *Protocol, IN BOOLEAN Create)
Definition: Handle.c:56
IHANDLE * SmmGetNextLocateByProtocol(IN OUT LOCATE_POSITION *Position, OUT VOID **Interface)
Definition: Locate.c:130
EFI_STATUS EFIAPI SmmLocateProtocol(IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface)
Definition: Locate.c:194
IHANDLE * SmmGetNextLocateByRegisterNotify(IN OUT LOCATE_POSITION *Position, OUT VOID **Interface)
Definition: Locate.c:83
EFI_STATUS EFIAPI SmmLocateHandle(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *BufferSize, OUT EFI_HANDLE *Buffer)
Definition: Locate.c:271
EFI_STATUS EFIAPI SmmLocateHandleBuffer(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *NumberHandles, OUT EFI_HANDLE **Buffer)
Definition: Locate.c:435
IHANDLE * SmmGetNextLocateAllHandles(IN OUT LOCATE_POSITION *Position, OUT VOID **Interface)
Definition: Locate.c:46
#define NULL
Definition: Base.h:319
#define VOID
Definition: Base.h:269
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:660
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_LOCATE_SEARCH_TYPE
Definition: UefiSpec.h:1515
@ ByProtocol
Definition: UefiSpec.h:1528
@ ByRegisterNotify
Definition: UefiSpec.h:1523
@ AllHandles
Definition: UefiSpec.h:1519
Definition: Base.h:213
Definition: Handle.h:17
LIST_ENTRY Protocols
All protocol interfaces.
Definition: Handle.h:44
IHANDLE * Handle
Back pointer.
Definition: Handle.h:60
VOID * Interface
The interface value.
Definition: Handle.h:66
LIST_ENTRY * Position
Last position notified.
Definition: Handle.h:98