]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Hand/Locate.c
Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings
[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
e94a9ff7 142\r
28a00297 143 //\r
144 // Set initial position\r
145 //\r
28a00297 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
28a00297 157 CoreAcquireProtocolLock ();\r
158\r
159 //\r
160 // Get the search function based on type\r
161 //\r
162 switch (SearchType) {\r
163 case AllHandles: \r
164 GetNext = CoreGetNextLocateAllHandles; \r
165 break;\r
166\r
167 case ByRegisterNotify: \r
168 //\r
169 // Must have SearchKey for locate ByRegisterNotify\r
170 //\r
171 if (SearchKey == NULL) {\r
172 Status = EFI_INVALID_PARAMETER;\r
173 break;\r
174 }\r
175 GetNext = CoreGetNextLocateByRegisterNotify; \r
176 break;\r
177\r
178 case ByProtocol: \r
179 GetNext = CoreGetNextLocateByProtocol;\r
180 if (Protocol == NULL) {\r
181 Status = EFI_INVALID_PARAMETER;\r
182 break;\r
183 }\r
184 //\r
185 // Look up the protocol entry and set the head pointer\r
186 //\r
187 Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);\r
188 if (Position.ProtEntry == NULL) {\r
189 Status = EFI_NOT_FOUND;\r
190 break;\r
191 }\r
192 Position.Position = &Position.ProtEntry->Protocols;\r
193 break;\r
194\r
195 default:\r
196 Status = EFI_INVALID_PARAMETER;\r
197 break;\r
198 }\r
199\r
200 if (EFI_ERROR(Status)) {\r
201 CoreReleaseProtocolLock ();\r
202 return Status;\r
203 }\r
204\r
205 //\r
206 // Enumerate out the matching handles\r
207 //\r
208 mEfiLocateHandleRequest += 1;\r
209 for (; ;) {\r
210 //\r
211 // Get the next handle. If no more handles, stop\r
212 //\r
213 Handle = GetNext (&Position, &Interface);\r
214 if (NULL == Handle) {\r
215 break;\r
216 }\r
217\r
218 //\r
219 // Increase the resulting buffer size, and if this handle\r
220 // fits return it\r
221 //\r
222 ResultSize += sizeof(Handle);\r
223 if (ResultSize <= *BufferSize) {\r
224 *ResultBuffer = Handle;\r
225 ResultBuffer += 1;\r
226 }\r
227 }\r
228\r
229 //\r
230 // If the result is a zero length buffer, then there were no\r
231 // matching handles\r
232 //\r
233 if (ResultSize == 0) {\r
234 Status = EFI_NOT_FOUND;\r
235 } else {\r
236 //\r
237 // Return the resulting buffer size. If it's larger than what\r
238 // was passed, then set the error code\r
239 //\r
240 if (ResultSize > *BufferSize) {\r
241 Status = EFI_BUFFER_TOO_SMALL;\r
242 } \r
243 \r
244 *BufferSize = ResultSize;\r
245\r
246 if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {\r
247 //\r
248 // If this is a search by register notify and a handle was\r
249 // returned, update the register notification position\r
250 // \r
251 ProtNotify = SearchKey;\r
252 ProtNotify->Position = ProtNotify->Position->ForwardLink;\r
253 }\r
254 }\r
255\r
256 CoreReleaseProtocolLock ();\r
257 return Status;\r
258}\r
259\r
260\r
162ed594 261\r
262/**\r
263 Routine to get the next Handle, when you are searching for all handles.\r
264\r
265 @param Position Information about which Handle to seach for. \r
266 @param Interface Return the interface structure for the matching \r
267 protocol. \r
268\r
e94a9ff7 269 @return An pointer to IHANDLE if the next Position is not the end of the list.\r
270 Otherwise,NULL_HANDLE is returned.\r
162ed594 271\r
272**/\r
28a00297 273IHANDLE *\r
274CoreGetNextLocateAllHandles (\r
275 IN OUT LOCATE_POSITION *Position,\r
276 OUT VOID **Interface\r
277 )\r
28a00297 278{\r
279 IHANDLE *Handle;\r
280\r
281 //\r
282 // Next handle\r
283 //\r
284 Position->Position = Position->Position->ForwardLink;\r
285\r
286 //\r
287 // If not at the end of the list, get the handle\r
288 //\r
289 Handle = NULL_HANDLE;\r
290 *Interface = NULL;\r
291 if (Position->Position != &gHandleList) {\r
292 Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);\r
293 }\r
294\r
295 return Handle;\r
296}\r
297\r
298\r
162ed594 299\r
300/**\r
301 Routine to get the next Handle, when you are searching for register protocol\r
302 notifies.\r
303\r
304 @param Position Information about which Handle to seach for. \r
305 @param Interface Return the interface structure for the matching \r
306 protocol. \r
307\r
e94a9ff7 308 @return An pointer to IHANDLE if the next Position is not the end of the list.\r
309 Otherwise,NULL_HANDLE is returned.\r
162ed594 310\r
311**/\r
28a00297 312IHANDLE *\r
313CoreGetNextLocateByRegisterNotify (\r
314 IN OUT LOCATE_POSITION *Position,\r
315 OUT VOID **Interface\r
316 )\r
28a00297 317{\r
318 IHANDLE *Handle;\r
319 PROTOCOL_NOTIFY *ProtNotify;\r
320 PROTOCOL_INTERFACE *Prot;\r
321 LIST_ENTRY *Link; \r
322\r
323 Handle = NULL_HANDLE;\r
324 *Interface = NULL;\r
325 ProtNotify = Position->SearchKey;\r
326\r
327 //\r
328 // If this is the first request, get the next handle\r
329 //\r
330 if (ProtNotify != NULL) {\r
331 ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);\r
332 Position->SearchKey = NULL;\r
333\r
334 //\r
335 // If not at the end of the list, get the next handle\r
336 //\r
337 Link = ProtNotify->Position->ForwardLink;\r
338 if (Link != &ProtNotify->Protocol->Protocols) {\r
339 Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);\r
340 Handle = (IHANDLE *) Prot->Handle;\r
341 *Interface = Prot->Interface;\r
342 } \r
343 }\r
344\r
345 return Handle;\r
346}\r
347\r
348\r
162ed594 349/**\r
350 Routine to get the next Handle, when you are searching for a given protocol.\r
351\r
352 @param Position Information about which Handle to seach for. \r
353 @param Interface Return the interface structure for the matching \r
354 protocol. \r
355\r
e94a9ff7 356 @return An pointer to IHANDLE if the next Position is not the end of the list.\r
357 Otherwise,NULL_HANDLE is returned.\r
162ed594 358\r
359**/\r
28a00297 360IHANDLE *\r
361CoreGetNextLocateByProtocol (\r
362 IN OUT LOCATE_POSITION *Position,\r
363 OUT VOID **Interface\r
364 )\r
28a00297 365{\r
366 IHANDLE *Handle;\r
367 LIST_ENTRY *Link;\r
368 PROTOCOL_INTERFACE *Prot;\r
369 \r
370 Handle = NULL_HANDLE;\r
371 *Interface = NULL;\r
372 for (; ;) {\r
373 //\r
374 // Next entry\r
375 //\r
376 Link = Position->Position->ForwardLink;\r
377 Position->Position = Link;\r
378\r
379 //\r
380 // If not at the end, return the handle\r
381 //\r
382 if (Link == &Position->ProtEntry->Protocols) {\r
383 Handle = NULL_HANDLE;\r
384 break;\r
385 }\r
386\r
387 //\r
388 // Get the handle\r
389 //\r
390 Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);\r
391 Handle = (IHANDLE *) Prot->Handle;\r
392 *Interface = Prot->Interface;\r
393\r
394 //\r
395 // If this handle has not been returned this request, then \r
396 // return it now\r
397 //\r
398 if (Handle->LocateRequest != mEfiLocateHandleRequest) {\r
399 Handle->LocateRequest = mEfiLocateHandleRequest;\r
400 break;\r
401 }\r
402 }\r
403\r
404 return Handle;\r
405}\r
406\r
407\r
162ed594 408/**\r
409 Locates the handle to a device on the device path that best matches the specified protocol.\r
410\r
411 @param Protocol The protocol to search for. \r
412 @param DevicePath On input, a pointer to a pointer to the device \r
413 path. On output, the device path pointer is \r
414 modified to point to the remaining part of the \r
415 devicepath. \r
416 @param Device A pointer to the returned device handle. \r
417\r
418 @retval EFI_SUCCESS The resulting handle was returned. \r
419 @retval EFI_NOT_FOUND No handles matched the search. \r
420 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
421\r
422**/\r
28a00297 423EFI_STATUS\r
424EFIAPI\r
425CoreLocateDevicePath (\r
426 IN EFI_GUID *Protocol,\r
427 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
428 OUT EFI_HANDLE *Device\r
429 )\r
28a00297 430{\r
431 INTN SourceSize;\r
432 INTN Size;\r
433 INTN BestMatch;\r
434 UINTN HandleCount;\r
435 UINTN Index;\r
436 EFI_STATUS Status;\r
437 EFI_HANDLE *Handles;\r
438 EFI_HANDLE Handle;\r
439 EFI_DEVICE_PATH_PROTOCOL *SourcePath;\r
440 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
441 \r
442 if (Protocol == NULL) {\r
443 return EFI_INVALID_PARAMETER;\r
444 }\r
445 \r
446 if ((DevicePath == NULL) || (*DevicePath == NULL)) {\r
447 return EFI_INVALID_PARAMETER;\r
448 }\r
449 \r
450 if (Device == NULL) {\r
451 return EFI_INVALID_PARAMETER;\r
452 }\r
453 \r
454 *Device = NULL_HANDLE;\r
455 SourcePath = *DevicePath;\r
456 SourceSize = CoreDevicePathSize (SourcePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
457 \r
458 //\r
459 // The source path can only have 1 instance\r
460 //\r
461 if (CoreIsDevicePathMultiInstance (SourcePath)) {\r
162ed594 462 DEBUG((DEBUG_ERROR, "LocateDevicePath: Device path has too many instances\n"));\r
28a00297 463 return EFI_INVALID_PARAMETER;\r
464 }\r
465\r
466 //\r
467 // Get a list of all handles that support the requested protocol\r
468 //\r
469 Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles);\r
470 if (EFI_ERROR (Status) || HandleCount == 0) {\r
471 return EFI_NOT_FOUND;\r
472 }\r
473\r
474 BestMatch = -1;\r
475 for(Index = 0; Index < HandleCount; Index += 1) {\r
476 Handle = Handles[Index];\r
477 Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&TmpDevicePath);\r
478 if (EFI_ERROR (Status)) {\r
479 //\r
480 // If this handle doesn't support device path, then skip it\r
481 //\r
482 continue;\r
483 }\r
484\r
485 //\r
486 // Check if DevicePath is first part of SourcePath\r
487 //\r
488 Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
489 if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, Size) == 0) {\r
490 //\r
491 // If the size is equal to the best match, then we\r
492 // have a duplice device path for 2 different device\r
493 // handles\r
494 //\r
495 ASSERT (Size != BestMatch);\r
496 \r
497 //\r
498 // We've got a match, see if it's the best match so far\r
499 //\r
500 if (Size > BestMatch) {\r
501 BestMatch = Size;\r
502 *Device = Handle;\r
503 }\r
504 }\r
505 }\r
506\r
507 CoreFreePool (Handles);\r
508 \r
509 //\r
510 // If there wasn't any match, then no parts of the device path was found. \r
511 // Which is strange since there is likely a "root level" device path in the system.\r
512 //\r
513 if (BestMatch == -1) {\r
514 return EFI_NOT_FOUND;\r
515 }\r
516\r
517 //\r
518 // Return the remaining part of the device path\r
519 //\r
520 *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch);\r
521 return EFI_SUCCESS;\r
522}\r
523\r
524\r
e94a9ff7 525 /**\r
28a00297 526 Return the first Protocol Interface that matches the Protocol GUID. If\r
527 Registration is pasased in return a Protocol Instance that was just add\r
528 to the system. If Retistration is NULL return the first Protocol Interface\r
529 you find.\r
530\r
162ed594 531 @param Protocol The protocol to search for \r
532 @param Registration Optional Registration Key returned from \r
533 RegisterProtocolNotify() \r
534 @param Interface Return the Protocol interface (instance). \r
28a00297 535\r
162ed594 536 @retval EFI_SUCCESS If a valid Interface is returned \r
537 @retval EFI_INVALID_PARAMETER Invalid parameter \r
538 @retval EFI_NOT_FOUND Protocol interface not found\r
28a00297 539\r
162ed594 540**/\r
541EFI_STATUS\r
542EFIAPI\r
543CoreLocateProtocol (\r
544 IN EFI_GUID *Protocol,\r
545 IN VOID *Registration OPTIONAL,\r
546 OUT VOID **Interface\r
547 )\r
28a00297 548{\r
549 EFI_STATUS Status;\r
550 LOCATE_POSITION Position;\r
551 PROTOCOL_NOTIFY *ProtNotify;\r
552 IHANDLE *Handle;\r
553\r
554 if (Interface == NULL) {\r
555 return EFI_INVALID_PARAMETER;\r
556 }\r
557 \r
558 if (Protocol == NULL) {\r
559 return EFI_NOT_FOUND;\r
560 }\r
561 \r
562 *Interface = NULL;\r
563 Status = EFI_SUCCESS;\r
564\r
565 //\r
566 // Set initial position\r
567 //\r
568 Position.Protocol = Protocol;\r
569 Position.SearchKey = Registration;\r
570 Position.Position = &gHandleList;\r
571 \r
572 //\r
573 // Lock the protocol database\r
574 //\r
575 CoreAcquireProtocolLock ();\r
576\r
577 mEfiLocateHandleRequest += 1;\r
578\r
e94a9ff7 579 if (Registration == NULL) {\r
28a00297 580 //\r
581 // Look up the protocol entry and set the head pointer\r
582 //\r
583 Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);\r
584 if (Position.ProtEntry == NULL) {\r
585 Status = EFI_NOT_FOUND;\r
586 goto Done;\r
587 }\r
588 Position.Position = &Position.ProtEntry->Protocols;\r
589\r
590 Handle = CoreGetNextLocateByProtocol (&Position, Interface);\r
591 } else {\r
592 Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface); \r
593 }\r
594\r
e94a9ff7 595 if (Handle == NULL) {\r
28a00297 596 Status = EFI_NOT_FOUND;\r
e94a9ff7 597 } else if (Registration != NULL) {\r
28a00297 598 //\r
599 // If this is a search by register notify and a handle was\r
600 // returned, update the register notification position\r
601 // \r
602 ProtNotify = Registration;\r
603 ProtNotify->Position = ProtNotify->Position->ForwardLink;\r
604 }\r
605\r
606Done:\r
607 CoreReleaseProtocolLock ();\r
608 return Status;\r
609}\r
610\r
611\r
162ed594 612/**\r
613 Function returns an array of handles that support the requested protocol\r
614 in a buffer allocated from pool. This is a version of CoreLocateHandle()\r
615 that allocates a buffer for the caller.\r
616\r
617 @param SearchType Specifies which handle(s) are to be returned. \r
618 @param Protocol Provides the protocol to search by. This \r
619 parameter is only valid for SearchType \r
620 ByProtocol. \r
621 @param SearchKey Supplies the search key depending on the \r
622 SearchType. \r
623 @param NumberHandles The number of handles returned in Buffer. \r
624 @param Buffer A pointer to the buffer to return the requested \r
625 array of handles that support Protocol. \r
626\r
627 @retval EFI_SUCCESS The result array of handles was returned. \r
628 @retval EFI_NOT_FOUND No handles match the search. \r
629 @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the \r
630 matching results. \r
e94a9ff7 631 @retval EFI_INVALID_PARAMETER One or more paramters are not valid.\r
162ed594 632\r
633**/\r
28a00297 634EFI_STATUS\r
635EFIAPI\r
636CoreLocateHandleBuffer (\r
637 IN EFI_LOCATE_SEARCH_TYPE SearchType,\r
638 IN EFI_GUID *Protocol OPTIONAL,\r
639 IN VOID *SearchKey OPTIONAL,\r
640 IN OUT UINTN *NumberHandles,\r
641 OUT EFI_HANDLE **Buffer\r
642 )\r
28a00297 643{\r
644 EFI_STATUS Status;\r
645 UINTN BufferSize;\r
646\r
647 if (NumberHandles == NULL) {\r
648 return EFI_INVALID_PARAMETER;\r
649 }\r
650\r
651 if (Buffer == NULL) {\r
652 return EFI_INVALID_PARAMETER;\r
653 }\r
654\r
655 BufferSize = 0;\r
656 *NumberHandles = 0;\r
657 *Buffer = NULL;\r
658 Status = CoreLocateHandle (\r
659 SearchType,\r
660 Protocol,\r
661 SearchKey,\r
662 &BufferSize,\r
663 *Buffer\r
664 );\r
665 //\r
666 // LocateHandleBuffer() returns incorrect status code if SearchType is\r
667 // invalid.\r
668 //\r
669 // Add code to correctly handle expected errors from CoreLocateHandle().\r
670 //\r
671 if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {\r
672 if (Status != EFI_INVALID_PARAMETER) {\r
673 Status = EFI_NOT_FOUND;\r
674 }\r
675 return Status;\r
676 }\r
677\r
678 *Buffer = CoreAllocateBootServicesPool (BufferSize);\r
679 if (*Buffer == NULL) {\r
680 return EFI_OUT_OF_RESOURCES;\r
681 }\r
682\r
683 Status = CoreLocateHandle (\r
684 SearchType,\r
685 Protocol,\r
686 SearchKey,\r
687 &BufferSize,\r
688 *Buffer\r
689 );\r
690\r
e94a9ff7 691 *NumberHandles = BufferSize / sizeof(EFI_HANDLE);\r
28a00297 692 if (EFI_ERROR(Status)) {\r
693 *NumberHandles = 0;\r
694 }\r
695\r
696 return Status;\r
697}\r
698\r
699\r
162ed594 700\r