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