]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Hand/Locate.c
Update to fix minor coding style issues.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Hand / Locate.c
CommitLineData
23c98c94 1/** @file\r
2 Locate handle functions\r
28a00297 3\r
23c98c94 4Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
504214c4 9\r
23c98c94 10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
28a00297 12\r
504214c4 13**/\r
28a00297 14\r
15#include <DxeMain.h>\r
16\r
17//\r
18// ProtocolRequest - Last LocateHandle request ID\r
19//\r
20UINTN mEfiLocateHandleRequest = 0;\r
21\r
22//\r
23// Internal prototypes\r
24//\r
25\r
26typedef struct {\r
27 EFI_GUID *Protocol;\r
28 VOID *SearchKey;\r
29 LIST_ENTRY *Position;\r
30 PROTOCOL_ENTRY *ProtEntry;\r
31} LOCATE_POSITION;\r
32\r
33typedef \r
34IHANDLE *\r
35(* CORE_GET_NEXT) (\r
36 IN OUT LOCATE_POSITION *Position,\r
37 OUT VOID **Interface\r
38 );\r
39\r
162ed594 40/**\r
41 Routine to get the next Handle, when you are searching for all handles.\r
42\r
43 @param Position Information about which Handle to seach for. \r
44 @param Interface Return the interface structure for the matching \r
45 protocol. \r
46\r
47 @retval IHANDLE An IHANDLE is returned if the next Position is \r
48 not the end of the list. A NULL_HANDLE is \r
49 returned if it's the end of the list.\r
50\r
51**/\r
28a00297 52IHANDLE *\r
53CoreGetNextLocateAllHandles (\r
54 IN OUT LOCATE_POSITION *Position,\r
55 OUT VOID **Interface\r
56 );\r
57\r
162ed594 58/**\r
59 Routine to get the next Handle, when you are searching for register protocol\r
60 notifies.\r
61\r
62 @param Position Information about which Handle to seach for. \r
63 @param Interface Return the interface structure for the matching \r
64 protocol. \r
65\r
66 @retval IHANDLE An IHANDLE is returned if the next Position is \r
67 not the end of the list. A NULL_HANDLE is \r
68 returned if it's the end of the list.\r
69\r
70**/\r
28a00297 71IHANDLE *\r
72CoreGetNextLocateByRegisterNotify (\r
73 IN OUT LOCATE_POSITION *Position,\r
74 OUT VOID **Interface\r
75 );\r
76\r
162ed594 77/**\r
78 Routine to get the next Handle, when you are searching for a given protocol.\r
79\r
80 @param Position Information about which Handle to seach for. \r
81 @param Interface Return the interface structure for the matching \r
82 protocol. \r
83\r
84 @retval IHANDLE An IHANDLE is returned if the next Position is \r
85 not the end of the list. A NULL_HANDLE is \r
86 returned if it's the end of the list.\r
87\r
88**/\r
28a00297 89IHANDLE *\r
90CoreGetNextLocateByProtocol (\r
91 IN OUT LOCATE_POSITION *Position,\r
92 OUT VOID **Interface\r
93 );\r
94\r
28a00297 95\r
162ed594 96/**\r
97 Locates the requested handle(s) and returns them in Buffer.\r
98\r
99 @param SearchType The type of search to perform to locate the \r
100 handles \r
101 @param Protocol The protocol to search for \r
102 @param SearchKey Dependant on SearchType \r
103 @param BufferSize On input the size of Buffer. On output the \r
104 size of data returned. \r
105 @param Buffer The buffer to return the results in \r
28a00297 106\r
162ed594 107 @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is \r
108 returned in BufferSize. \r
109 @retval EFI_INVALID_PARAMETER Invalid parameter \r
110 @retval EFI_SUCCESS Successfully found the requested handle(s) and \r
111 returns them in Buffer.\r
28a00297 112\r
162ed594 113**/\r
28a00297 114EFI_STATUS\r
115EFIAPI\r
116CoreLocateHandle (\r
117 IN EFI_LOCATE_SEARCH_TYPE SearchType,\r
118 IN EFI_GUID *Protocol OPTIONAL,\r
119 IN VOID *SearchKey OPTIONAL,\r
120 IN OUT UINTN *BufferSize,\r
121 OUT EFI_HANDLE *Buffer\r
122 )\r
28a00297 123{\r
124 EFI_STATUS Status;\r
125 LOCATE_POSITION Position;\r
126 PROTOCOL_NOTIFY *ProtNotify;\r
127 CORE_GET_NEXT GetNext;\r
128 UINTN ResultSize;\r
129 IHANDLE *Handle;\r
130 IHANDLE **ResultBuffer;\r
131 VOID *Interface;\r
132 \r
133 if (BufferSize == NULL) {\r
134 Status = EFI_INVALID_PARAMETER;\r
135 }\r
136 \r
137 if ((*BufferSize > 0) && (Buffer == NULL)) {\r
138 return EFI_INVALID_PARAMETER;\r
139 }\r
140 \r
141 GetNext = NULL;\r
142 //\r
143 // Set initial position\r
144 //\r
145\r
146 Position.Protocol = Protocol;\r
147 Position.SearchKey = SearchKey;\r
148 Position.Position = &gHandleList;\r
149\r
150 ResultSize = 0;\r
151 ResultBuffer = (IHANDLE **) Buffer;\r
152 Status = EFI_SUCCESS;\r
153\r
154 //\r
155 // Lock the protocol database\r
156 //\r
157 \r
158 CoreAcquireProtocolLock ();\r
159\r
160 //\r
161 // Get the search function based on type\r
162 //\r
163 switch (SearchType) {\r
164 case AllHandles: \r
165 GetNext = CoreGetNextLocateAllHandles; \r
166 break;\r
167\r
168 case ByRegisterNotify: \r
169 //\r
170 // Must have SearchKey for locate ByRegisterNotify\r
171 //\r
172 if (SearchKey == NULL) {\r
173 Status = EFI_INVALID_PARAMETER;\r
174 break;\r
175 }\r
176 GetNext = CoreGetNextLocateByRegisterNotify; \r
177 break;\r
178\r
179 case ByProtocol: \r
180 GetNext = CoreGetNextLocateByProtocol;\r
181 if (Protocol == NULL) {\r
182 Status = EFI_INVALID_PARAMETER;\r
183 break;\r
184 }\r
185 //\r
186 // Look up the protocol entry and set the head pointer\r
187 //\r
188 Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);\r
189 if (Position.ProtEntry == NULL) {\r
190 Status = EFI_NOT_FOUND;\r
191 break;\r
192 }\r
193 Position.Position = &Position.ProtEntry->Protocols;\r
194 break;\r
195\r
196 default:\r
197 Status = EFI_INVALID_PARAMETER;\r
198 break;\r
199 }\r
200\r
201 if (EFI_ERROR(Status)) {\r
202 CoreReleaseProtocolLock ();\r
203 return Status;\r
204 }\r
205\r
206 //\r
207 // Enumerate out the matching handles\r
208 //\r
209 mEfiLocateHandleRequest += 1;\r
210 for (; ;) {\r
211 //\r
212 // Get the next handle. If no more handles, stop\r
213 //\r
214 Handle = GetNext (&Position, &Interface);\r
215 if (NULL == Handle) {\r
216 break;\r
217 }\r
218\r
219 //\r
220 // Increase the resulting buffer size, and if this handle\r
221 // fits return it\r
222 //\r
223 ResultSize += sizeof(Handle);\r
224 if (ResultSize <= *BufferSize) {\r
225 *ResultBuffer = Handle;\r
226 ResultBuffer += 1;\r
227 }\r
228 }\r
229\r
230 //\r
231 // If the result is a zero length buffer, then there were no\r
232 // matching handles\r
233 //\r
234 if (ResultSize == 0) {\r
235 Status = EFI_NOT_FOUND;\r
236 } else {\r
237 //\r
238 // Return the resulting buffer size. If it's larger than what\r
239 // was passed, then set the error code\r
240 //\r
241 if (ResultSize > *BufferSize) {\r
242 Status = EFI_BUFFER_TOO_SMALL;\r
243 } \r
244 \r
245 *BufferSize = ResultSize;\r
246\r
247 if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {\r
248 //\r
249 // If this is a search by register notify and a handle was\r
250 // returned, update the register notification position\r
251 // \r
252 ProtNotify = SearchKey;\r
253 ProtNotify->Position = ProtNotify->Position->ForwardLink;\r
254 }\r
255 }\r
256\r
257 CoreReleaseProtocolLock ();\r
258 return Status;\r
259}\r
260\r
261\r
162ed594 262\r
263/**\r
264 Routine to get the next Handle, when you are searching for all handles.\r
265\r
266 @param Position Information about which Handle to seach for. \r
267 @param Interface Return the interface structure for the matching \r
268 protocol. \r
269\r
270 @retval IHANDLE An IHANDLE is returned if the next Position is \r
271 not the end of the list. A NULL_HANDLE is \r
272 returned if it's the end of the list.\r
273\r
274**/\r
28a00297 275IHANDLE *\r
276CoreGetNextLocateAllHandles (\r
277 IN OUT LOCATE_POSITION *Position,\r
278 OUT VOID **Interface\r
279 )\r
28a00297 280{\r
281 IHANDLE *Handle;\r
282\r
283 //\r
284 // Next handle\r
285 //\r
286 Position->Position = Position->Position->ForwardLink;\r
287\r
288 //\r
289 // If not at the end of the list, get the handle\r
290 //\r
291 Handle = NULL_HANDLE;\r
292 *Interface = NULL;\r
293 if (Position->Position != &gHandleList) {\r
294 Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);\r
295 }\r
296\r
297 return Handle;\r
298}\r
299\r
300\r
162ed594 301\r
302/**\r
303 Routine to get the next Handle, when you are searching for register protocol\r
304 notifies.\r
305\r
306 @param Position Information about which Handle to seach for. \r
307 @param Interface Return the interface structure for the matching \r
308 protocol. \r
309\r
310 @retval IHANDLE An IHANDLE is returned if the next Position is \r
311 not the end of the list. A NULL_HANDLE is \r
312 returned if it's the end of the list.\r
313\r
314**/\r
28a00297 315IHANDLE *\r
316CoreGetNextLocateByRegisterNotify (\r
317 IN OUT LOCATE_POSITION *Position,\r
318 OUT VOID **Interface\r
319 )\r
28a00297 320{\r
321 IHANDLE *Handle;\r
322 PROTOCOL_NOTIFY *ProtNotify;\r
323 PROTOCOL_INTERFACE *Prot;\r
324 LIST_ENTRY *Link; \r
325\r
326 Handle = NULL_HANDLE;\r
327 *Interface = NULL;\r
328 ProtNotify = Position->SearchKey;\r
329\r
330 //\r
331 // If this is the first request, get the next handle\r
332 //\r
333 if (ProtNotify != NULL) {\r
334 ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);\r
335 Position->SearchKey = NULL;\r
336\r
337 //\r
338 // If not at the end of the list, get the next handle\r
339 //\r
340 Link = ProtNotify->Position->ForwardLink;\r
341 if (Link != &ProtNotify->Protocol->Protocols) {\r
342 Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);\r
343 Handle = (IHANDLE *) Prot->Handle;\r
344 *Interface = Prot->Interface;\r
345 } \r
346 }\r
347\r
348 return Handle;\r
349}\r
350\r
351\r
162ed594 352\r
353/**\r
354 Routine to get the next Handle, when you are searching for a given protocol.\r
355\r
356 @param Position Information about which Handle to seach for. \r
357 @param Interface Return the interface structure for the matching \r
358 protocol. \r
359\r
360 @retval IHANDLE An IHANDLE is returned if the next Position is \r
361 not the end of the list. A NULL_HANDLE is \r
362 returned if it's the end of the list.\r
363\r
364**/\r
28a00297 365IHANDLE *\r
366CoreGetNextLocateByProtocol (\r
367 IN OUT LOCATE_POSITION *Position,\r
368 OUT VOID **Interface\r
369 )\r
28a00297 370{\r
371 IHANDLE *Handle;\r
372 LIST_ENTRY *Link;\r
373 PROTOCOL_INTERFACE *Prot;\r
374 \r
375 Handle = NULL_HANDLE;\r
376 *Interface = NULL;\r
377 for (; ;) {\r
378 //\r
379 // Next entry\r
380 //\r
381 Link = Position->Position->ForwardLink;\r
382 Position->Position = Link;\r
383\r
384 //\r
385 // If not at the end, return the handle\r
386 //\r
387 if (Link == &Position->ProtEntry->Protocols) {\r
388 Handle = NULL_HANDLE;\r
389 break;\r
390 }\r
391\r
392 //\r
393 // Get the handle\r
394 //\r
395 Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);\r
396 Handle = (IHANDLE *) Prot->Handle;\r
397 *Interface = Prot->Interface;\r
398\r
399 //\r
400 // If this handle has not been returned this request, then \r
401 // return it now\r
402 //\r
403 if (Handle->LocateRequest != mEfiLocateHandleRequest) {\r
404 Handle->LocateRequest = mEfiLocateHandleRequest;\r
405 break;\r
406 }\r
407 }\r
408\r
409 return Handle;\r
410}\r
411\r
412\r
413\r
162ed594 414\r
415/**\r
416 Locates the handle to a device on the device path that best matches the specified protocol.\r
417\r
418 @param Protocol The protocol to search for. \r
419 @param DevicePath On input, a pointer to a pointer to the device \r
420 path. On output, the device path pointer is \r
421 modified to point to the remaining part of the \r
422 devicepath. \r
423 @param Device A pointer to the returned device handle. \r
424\r
425 @retval EFI_SUCCESS The resulting handle was returned. \r
426 @retval EFI_NOT_FOUND No handles matched the search. \r
427 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
428\r
429**/\r
28a00297 430EFI_STATUS\r
431EFIAPI\r
432CoreLocateDevicePath (\r
433 IN EFI_GUID *Protocol,\r
434 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
435 OUT EFI_HANDLE *Device\r
436 )\r
28a00297 437{\r
438 INTN SourceSize;\r
439 INTN Size;\r
440 INTN BestMatch;\r
441 UINTN HandleCount;\r
442 UINTN Index;\r
443 EFI_STATUS Status;\r
444 EFI_HANDLE *Handles;\r
445 EFI_HANDLE Handle;\r
446 EFI_DEVICE_PATH_PROTOCOL *SourcePath;\r
447 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
448 \r
449 if (Protocol == NULL) {\r
450 return EFI_INVALID_PARAMETER;\r
451 }\r
452 \r
453 if ((DevicePath == NULL) || (*DevicePath == NULL)) {\r
454 return EFI_INVALID_PARAMETER;\r
455 }\r
456 \r
457 if (Device == NULL) {\r
458 return EFI_INVALID_PARAMETER;\r
459 }\r
460 \r
461 *Device = NULL_HANDLE;\r
462 SourcePath = *DevicePath;\r
463 SourceSize = CoreDevicePathSize (SourcePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
464 \r
465 //\r
466 // The source path can only have 1 instance\r
467 //\r
468 if (CoreIsDevicePathMultiInstance (SourcePath)) {\r
162ed594 469 DEBUG((DEBUG_ERROR, "LocateDevicePath: Device path has too many instances\n"));\r
28a00297 470 return EFI_INVALID_PARAMETER;\r
471 }\r
472\r
473 //\r
474 // Get a list of all handles that support the requested protocol\r
475 //\r
476 Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles);\r
477 if (EFI_ERROR (Status) || HandleCount == 0) {\r
478 return EFI_NOT_FOUND;\r
479 }\r
480\r
481 BestMatch = -1;\r
482 for(Index = 0; Index < HandleCount; Index += 1) {\r
483 Handle = Handles[Index];\r
484 Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&TmpDevicePath);\r
485 if (EFI_ERROR (Status)) {\r
486 //\r
487 // If this handle doesn't support device path, then skip it\r
488 //\r
489 continue;\r
490 }\r
491\r
492 //\r
493 // Check if DevicePath is first part of SourcePath\r
494 //\r
495 Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
496 if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, Size) == 0) {\r
497 //\r
498 // If the size is equal to the best match, then we\r
499 // have a duplice device path for 2 different device\r
500 // handles\r
501 //\r
502 ASSERT (Size != BestMatch);\r
503 \r
504 //\r
505 // We've got a match, see if it's the best match so far\r
506 //\r
507 if (Size > BestMatch) {\r
508 BestMatch = Size;\r
509 *Device = Handle;\r
510 }\r
511 }\r
512 }\r
513\r
514 CoreFreePool (Handles);\r
515 \r
516 //\r
517 // If there wasn't any match, then no parts of the device path was found. \r
518 // Which is strange since there is likely a "root level" device path in the system.\r
519 //\r
520 if (BestMatch == -1) {\r
521 return EFI_NOT_FOUND;\r
522 }\r
523\r
524 //\r
525 // Return the remaining part of the device path\r
526 //\r
527 *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch);\r
528 return EFI_SUCCESS;\r
529}\r
530\r
531\r
532 \r
28a00297 533\r
162ed594 534/**\r
28a00297 535 Return the first Protocol Interface that matches the Protocol GUID. If\r
536 Registration is pasased in return a Protocol Instance that was just add\r
537 to the system. If Retistration is NULL return the first Protocol Interface\r
538 you find.\r
539\r
162ed594 540 @param Protocol The protocol to search for \r
541 @param Registration Optional Registration Key returned from \r
542 RegisterProtocolNotify() \r
543 @param Interface Return the Protocol interface (instance). \r
28a00297 544\r
162ed594 545 @retval EFI_SUCCESS If a valid Interface is returned \r
546 @retval EFI_INVALID_PARAMETER Invalid parameter \r
547 @retval EFI_NOT_FOUND Protocol interface not found\r
28a00297 548\r
162ed594 549**/\r
550EFI_STATUS\r
551EFIAPI\r
552CoreLocateProtocol (\r
553 IN EFI_GUID *Protocol,\r
554 IN VOID *Registration OPTIONAL,\r
555 OUT VOID **Interface\r
556 )\r
28a00297 557{\r
558 EFI_STATUS Status;\r
559 LOCATE_POSITION Position;\r
560 PROTOCOL_NOTIFY *ProtNotify;\r
561 IHANDLE *Handle;\r
562\r
563 if (Interface == NULL) {\r
564 return EFI_INVALID_PARAMETER;\r
565 }\r
566 \r
567 if (Protocol == NULL) {\r
568 return EFI_NOT_FOUND;\r
569 }\r
570 \r
571 *Interface = NULL;\r
572 Status = EFI_SUCCESS;\r
573\r
574 //\r
575 // Set initial position\r
576 //\r
577 Position.Protocol = Protocol;\r
578 Position.SearchKey = Registration;\r
579 Position.Position = &gHandleList;\r
580 \r
581 //\r
582 // Lock the protocol database\r
583 //\r
584 CoreAcquireProtocolLock ();\r
585\r
586 mEfiLocateHandleRequest += 1;\r
587\r
588 if (NULL == Registration) {\r
589 //\r
590 // Look up the protocol entry and set the head pointer\r
591 //\r
592 Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);\r
593 if (Position.ProtEntry == NULL) {\r
594 Status = EFI_NOT_FOUND;\r
595 goto Done;\r
596 }\r
597 Position.Position = &Position.ProtEntry->Protocols;\r
598\r
599 Handle = CoreGetNextLocateByProtocol (&Position, Interface);\r
600 } else {\r
601 Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface); \r
602 }\r
603\r
604 if (NULL == Handle) {\r
605 Status = EFI_NOT_FOUND;\r
606 } else if (NULL != Registration) {\r
607 //\r
608 // If this is a search by register notify and a handle was\r
609 // returned, update the register notification position\r
610 // \r
611 ProtNotify = Registration;\r
612 ProtNotify->Position = ProtNotify->Position->ForwardLink;\r
613 }\r
614\r
615Done:\r
616 CoreReleaseProtocolLock ();\r
617 return Status;\r
618}\r
619\r
620\r
621 \r
162ed594 622\r
623/**\r
624 Function returns an array of handles that support the requested protocol\r
625 in a buffer allocated from pool. This is a version of CoreLocateHandle()\r
626 that allocates a buffer for the caller.\r
627\r
628 @param SearchType Specifies which handle(s) are to be returned. \r
629 @param Protocol Provides the protocol to search by. This \r
630 parameter is only valid for SearchType \r
631 ByProtocol. \r
632 @param SearchKey Supplies the search key depending on the \r
633 SearchType. \r
634 @param NumberHandles The number of handles returned in Buffer. \r
635 @param Buffer A pointer to the buffer to return the requested \r
636 array of handles that support Protocol. \r
637\r
638 @retval EFI_SUCCESS The result array of handles was returned. \r
639 @retval EFI_NOT_FOUND No handles match the search. \r
640 @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the \r
641 matching results. \r
642 @retval EFI_INVALID_PARAMETER Invalid parameter\r
643\r
644**/\r
28a00297 645EFI_STATUS\r
646EFIAPI\r
647CoreLocateHandleBuffer (\r
648 IN EFI_LOCATE_SEARCH_TYPE SearchType,\r
649 IN EFI_GUID *Protocol OPTIONAL,\r
650 IN VOID *SearchKey OPTIONAL,\r
651 IN OUT UINTN *NumberHandles,\r
652 OUT EFI_HANDLE **Buffer\r
653 )\r
28a00297 654{\r
655 EFI_STATUS Status;\r
656 UINTN BufferSize;\r
657\r
658 if (NumberHandles == NULL) {\r
659 return EFI_INVALID_PARAMETER;\r
660 }\r
661\r
662 if (Buffer == NULL) {\r
663 return EFI_INVALID_PARAMETER;\r
664 }\r
665\r
666 BufferSize = 0;\r
667 *NumberHandles = 0;\r
668 *Buffer = NULL;\r
669 Status = CoreLocateHandle (\r
670 SearchType,\r
671 Protocol,\r
672 SearchKey,\r
673 &BufferSize,\r
674 *Buffer\r
675 );\r
676 //\r
677 // LocateHandleBuffer() returns incorrect status code if SearchType is\r
678 // invalid.\r
679 //\r
680 // Add code to correctly handle expected errors from CoreLocateHandle().\r
681 //\r
682 if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {\r
683 if (Status != EFI_INVALID_PARAMETER) {\r
684 Status = EFI_NOT_FOUND;\r
685 }\r
686 return Status;\r
687 }\r
688\r
689 *Buffer = CoreAllocateBootServicesPool (BufferSize);\r
690 if (*Buffer == NULL) {\r
691 return EFI_OUT_OF_RESOURCES;\r
692 }\r
693\r
694 Status = CoreLocateHandle (\r
695 SearchType,\r
696 Protocol,\r
697 SearchKey,\r
698 &BufferSize,\r
699 *Buffer\r
700 );\r
701\r
702 *NumberHandles = BufferSize/sizeof(EFI_HANDLE);\r
703 if (EFI_ERROR(Status)) {\r
704 *NumberHandles = 0;\r
705 }\r
706\r
707 return Status;\r
708}\r
709\r
710\r
162ed594 711\r