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