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