]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
Eliminate duplicated file GUID.
[mirror_edk2.git] / ShellPkg / Library / UefiHandleParsingLib / UefiHandleParsingLib.c
... / ...
CommitLineData
1/** @file\r
2 Provides interface to advanced shell functionality for parsing both handle and protocol database.\r
3\r
4 Copyright (c) 2013 - 2014, Hewlett-Packard Development Company, L.P.\r
5 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "UefiHandleParsingLib.h"\r
17#include "IndustryStandard/Acpi10.h"\r
18\r
19EFI_HANDLE mHandleParsingHiiHandle;\r
20HANDLE_INDEX_LIST mHandleList = {{{NULL,NULL},0,0},0};\r
21GUID_INFO_BLOCK *GuidList;\r
22UINTN GuidListCount;\r
23/**\r
24 Function to translate the EFI_MEMORY_TYPE into a string.\r
25\r
26 @param[in] Memory The memory type.\r
27\r
28 @retval A string representation of the type allocated from BS Pool.\r
29**/\r
30CHAR16*\r
31EFIAPI\r
32ConvertMemoryType (\r
33 IN CONST EFI_MEMORY_TYPE Memory\r
34 )\r
35{\r
36 CHAR16 *RetVal;\r
37 RetVal = NULL;\r
38\r
39 switch (Memory) {\r
40 case EfiReservedMemoryType: StrnCatGrow(&RetVal, NULL, L"EfiReservedMemoryType", 0); break;\r
41 case EfiLoaderCode: StrnCatGrow(&RetVal, NULL, L"EfiLoaderCode", 0); break;\r
42 case EfiLoaderData: StrnCatGrow(&RetVal, NULL, L"EfiLoaderData", 0); break;\r
43 case EfiBootServicesCode: StrnCatGrow(&RetVal, NULL, L"EfiBootServicesCode", 0); break;\r
44 case EfiBootServicesData: StrnCatGrow(&RetVal, NULL, L"EfiBootServicesData", 0); break;\r
45 case EfiRuntimeServicesCode: StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesCode", 0); break;\r
46 case EfiRuntimeServicesData: StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesData", 0); break;\r
47 case EfiConventionalMemory: StrnCatGrow(&RetVal, NULL, L"EfiConventionalMemory", 0); break;\r
48 case EfiUnusableMemory: StrnCatGrow(&RetVal, NULL, L"EfiUnusableMemory", 0); break;\r
49 case EfiACPIReclaimMemory: StrnCatGrow(&RetVal, NULL, L"EfiACPIReclaimMemory", 0); break;\r
50 case EfiACPIMemoryNVS: StrnCatGrow(&RetVal, NULL, L"EfiACPIMemoryNVS", 0); break;\r
51 case EfiMemoryMappedIO: StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIO", 0); break;\r
52 case EfiMemoryMappedIOPortSpace: StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIOPortSpace", 0); break;\r
53 case EfiPalCode: StrnCatGrow(&RetVal, NULL, L"EfiPalCode", 0); break;\r
54 case EfiMaxMemoryType: StrnCatGrow(&RetVal, NULL, L"EfiMaxMemoryType", 0); break;\r
55 default: ASSERT(FALSE);\r
56 }\r
57 return (RetVal);\r
58}\r
59\r
60/**\r
61 Function to translate the EFI_GRAPHICS_PIXEL_FORMAT into a string.\r
62\r
63 @param[in] Fmt The format type.\r
64\r
65 @retval A string representation of the type allocated from BS Pool.\r
66**/\r
67CHAR16*\r
68EFIAPI\r
69ConvertPixelFormat (\r
70 IN CONST EFI_GRAPHICS_PIXEL_FORMAT Fmt\r
71 )\r
72{\r
73 CHAR16 *RetVal;\r
74 RetVal = NULL;\r
75\r
76 switch (Fmt) {\r
77 case PixelRedGreenBlueReserved8BitPerColor: StrnCatGrow(&RetVal, NULL, L"PixelRedGreenBlueReserved8BitPerColor", 0); break;\r
78 case PixelBlueGreenRedReserved8BitPerColor: StrnCatGrow(&RetVal, NULL, L"PixelBlueGreenRedReserved8BitPerColor", 0); break;\r
79 case PixelBitMask: StrnCatGrow(&RetVal, NULL, L"PixelBitMask", 0); break;\r
80 case PixelBltOnly: StrnCatGrow(&RetVal, NULL, L"PixelBltOnly", 0); break;\r
81 case PixelFormatMax: StrnCatGrow(&RetVal, NULL, L"PixelFormatMax", 0); break;\r
82 default: ASSERT(FALSE);\r
83 }\r
84 return (RetVal);\r
85}\r
86\r
87/**\r
88 Constructor for the library.\r
89\r
90 @param[in] ImageHandle Ignored.\r
91 @param[in] SystemTable Ignored.\r
92\r
93 @retval EFI_SUCCESS The operation was successful.\r
94**/\r
95EFI_STATUS\r
96EFIAPI\r
97HandleParsingLibConstructor (\r
98 IN EFI_HANDLE ImageHandle,\r
99 IN EFI_SYSTEM_TABLE *SystemTable\r
100 )\r
101{\r
102 GuidListCount = 0;\r
103 GuidList = NULL;\r
104\r
105 mHandleParsingHiiHandle = HiiAddPackages (&gHandleParsingHiiGuid, gImageHandle, UefiHandleParsingLibStrings, NULL);\r
106 if (mHandleParsingHiiHandle == NULL) {\r
107 return (EFI_DEVICE_ERROR);\r
108 }\r
109\r
110 return (EFI_SUCCESS);\r
111}\r
112\r
113/**\r
114 Destructor for the library. free any resources.\r
115\r
116 @param[in] ImageHandle Ignored.\r
117 @param[in] SystemTable Ignored.\r
118\r
119 @retval EFI_SUCCESS The operation was successful.\r
120**/\r
121EFI_STATUS\r
122EFIAPI\r
123HandleParsingLibDestructor (\r
124 IN EFI_HANDLE ImageHandle,\r
125 IN EFI_SYSTEM_TABLE *SystemTable\r
126 )\r
127{\r
128 UINTN LoopCount;\r
129\r
130 for (LoopCount = 0; GuidList != NULL && LoopCount < GuidListCount; LoopCount++) {\r
131 SHELL_FREE_NON_NULL(GuidList[LoopCount].GuidId);\r
132 }\r
133\r
134 SHELL_FREE_NON_NULL(GuidList);\r
135 if (mHandleParsingHiiHandle != NULL) {\r
136 HiiRemovePackages(mHandleParsingHiiHandle);\r
137 }\r
138 return (EFI_SUCCESS);\r
139}\r
140\r
141/**\r
142 Function to dump information about LoadedImage.\r
143\r
144 This will allocate the return buffer from boot services pool.\r
145\r
146 @param[in] TheHandle The handle that has LoadedImage installed.\r
147 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
148\r
149 @retval A poitner to a string containing the information.\r
150**/\r
151CHAR16*\r
152EFIAPI\r
153LoadedImageProtocolDumpInformation(\r
154 IN CONST EFI_HANDLE TheHandle,\r
155 IN CONST BOOLEAN Verbose\r
156 )\r
157{\r
158 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
159 EFI_STATUS Status;\r
160 CHAR16 *RetVal;\r
161 CHAR16 *Temp;\r
162 CHAR16 *CodeType;\r
163 CHAR16 *DataType;\r
164\r
165 if (!Verbose) {\r
166 return (CatSPrint(NULL, L"LoadedImage"));\r
167 }\r
168\r
169 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_LI_DUMP_MAIN), NULL);\r
170 RetVal = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));\r
171 if (Temp == NULL || RetVal == NULL) {\r
172 SHELL_FREE_NON_NULL(Temp);\r
173 SHELL_FREE_NON_NULL(RetVal);\r
174 return NULL;\r
175 }\r
176\r
177 Status = gBS->OpenProtocol (\r
178 TheHandle,\r
179 &gEfiLoadedImageProtocolGuid,\r
180 (VOID**)&LoadedImage,\r
181 gImageHandle,\r
182 NULL,\r
183 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
184 );\r
185\r
186 if (EFI_ERROR (Status)) {\r
187 SHELL_FREE_NON_NULL (Temp);\r
188 SHELL_FREE_NON_NULL (RetVal);\r
189 return NULL;\r
190 }\r
191\r
192 DataType = ConvertMemoryType(LoadedImage->ImageDataType);\r
193 CodeType = ConvertMemoryType(LoadedImage->ImageCodeType);\r
194\r
195 RetVal = CatSPrint(RetVal,\r
196 Temp,\r
197 LoadedImage->Revision,\r
198 LoadedImage->ParentHandle,\r
199 LoadedImage->SystemTable,\r
200 LoadedImage->DeviceHandle,\r
201 LoadedImage->FilePath,\r
202 LoadedImage->LoadOptionsSize,\r
203 LoadedImage->LoadOptions,\r
204 LoadedImage->ImageBase,\r
205 LoadedImage->ImageSize,\r
206 CodeType,\r
207 DataType,\r
208 LoadedImage->Unload);\r
209\r
210 \r
211 SHELL_FREE_NON_NULL(Temp);\r
212 SHELL_FREE_NON_NULL(CodeType);\r
213 SHELL_FREE_NON_NULL(DataType);\r
214\r
215 return RetVal;\r
216}\r
217\r
218/**\r
219 Function to dump information about GOP.\r
220\r
221 This will allocate the return buffer from boot services pool.\r
222\r
223 @param[in] TheHandle The handle that has LoadedImage installed.\r
224 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
225\r
226 @retval A poitner to a string containing the information.\r
227**/\r
228CHAR16*\r
229EFIAPI\r
230GraphicsOutputProtocolDumpInformation(\r
231 IN CONST EFI_HANDLE TheHandle,\r
232 IN CONST BOOLEAN Verbose\r
233 )\r
234{\r
235 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
236 EFI_STATUS Status;\r
237 CHAR16 *RetVal;\r
238 CHAR16 *Temp;\r
239 CHAR16 *Fmt;\r
240\r
241 if (!Verbose) {\r
242 return (CatSPrint(NULL, L"GraphicsOutput"));\r
243 }\r
244\r
245 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_GOP_DUMP_MAIN), NULL);\r
246 RetVal = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));\r
247 if (Temp == NULL || RetVal == NULL) {\r
248 SHELL_FREE_NON_NULL(Temp);\r
249 SHELL_FREE_NON_NULL(RetVal);\r
250 return NULL;\r
251 }\r
252\r
253 Status = gBS->OpenProtocol (\r
254 TheHandle,\r
255 &gEfiGraphicsOutputProtocolGuid,\r
256 (VOID**)&GraphicsOutput,\r
257 gImageHandle,\r
258 NULL,\r
259 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
260 );\r
261\r
262 if (EFI_ERROR (Status)) {\r
263 SHELL_FREE_NON_NULL (Temp);\r
264 SHELL_FREE_NON_NULL (RetVal);\r
265 return NULL;\r
266 }\r
267\r
268 Fmt = ConvertPixelFormat(GraphicsOutput->Mode->Info->PixelFormat);\r
269\r
270 RetVal = CatSPrint(RetVal,\r
271 Temp,\r
272 GraphicsOutput->Mode->MaxMode,\r
273 GraphicsOutput->Mode->Mode,\r
274 GraphicsOutput->Mode->FrameBufferBase,\r
275 (UINT64)GraphicsOutput->Mode->FrameBufferSize,\r
276 (UINT64)GraphicsOutput->Mode->SizeOfInfo,\r
277 GraphicsOutput->Mode->Info->Version,\r
278 GraphicsOutput->Mode->Info->HorizontalResolution,\r
279 GraphicsOutput->Mode->Info->VerticalResolution,\r
280 Fmt,\r
281 GraphicsOutput->Mode->Info->PixelsPerScanLine,\r
282 GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.RedMask,\r
283 GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.GreenMask,\r
284 GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.BlueMask\r
285 );\r
286 \r
287 SHELL_FREE_NON_NULL(Temp);\r
288 SHELL_FREE_NON_NULL(Fmt);\r
289\r
290 return RetVal;\r
291}\r
292\r
293/**\r
294 Function to dump information about PciRootBridgeIo.\r
295\r
296 This will allocate the return buffer from boot services pool.\r
297\r
298 @param[in] TheHandle The handle that has PciRootBridgeIo installed.\r
299 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
300\r
301 @retval A poitner to a string containing the information.\r
302**/\r
303CHAR16*\r
304EFIAPI\r
305PciRootBridgeIoDumpInformation(\r
306 IN CONST EFI_HANDLE TheHandle,\r
307 IN CONST BOOLEAN Verbose\r
308 )\r
309{\r
310 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
311 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;\r
312 UINT64 Supports;\r
313 UINT64 Attributes;\r
314 CHAR16 *Temp;\r
315 CHAR16 *Temp2;\r
316 CHAR16 *RetVal;\r
317 EFI_STATUS Status;\r
318\r
319 RetVal = NULL;\r
320\r
321 if (!Verbose) {\r
322 return (CatSPrint(NULL, L"PciRootBridgeIo"));\r
323 }\r
324\r
325 Status = gBS->HandleProtocol(\r
326 TheHandle,\r
327 &gEfiPciRootBridgeIoProtocolGuid,\r
328 (VOID**)&PciRootBridgeIo);\r
329\r
330 if (EFI_ERROR(Status)) {\r
331 return NULL;\r
332 }\r
333\r
334 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_PH), NULL);\r
335 ASSERT (Temp != NULL);\r
336 Temp2 = CatSPrint(L"\r\n", Temp, PciRootBridgeIo->ParentHandle);\r
337 FreePool(Temp);\r
338 RetVal = Temp2;\r
339 Temp2 = NULL;\r
340 \r
341 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SEG), NULL);\r
342 ASSERT (Temp != NULL);\r
343 Temp2 = CatSPrint(RetVal, Temp, PciRootBridgeIo->SegmentNumber);\r
344 FreePool(Temp);\r
345 FreePool(RetVal);\r
346 RetVal = Temp2;\r
347 Temp2 = NULL;\r
348\r
349 Supports = 0;\r
350 Attributes = 0;\r
351 Status = PciRootBridgeIo->GetAttributes (PciRootBridgeIo, &Supports, &Attributes);\r
352 if (!EFI_ERROR(Status)) {\r
353 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_ATT), NULL);\r
354 ASSERT (Temp != NULL); \r
355 Temp2 = CatSPrint(RetVal, Temp, Attributes);\r
356 FreePool(Temp);\r
357 FreePool(RetVal);\r
358 RetVal = Temp2;\r
359 Temp2 = NULL;\r
360 \r
361 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SUPPORTS), NULL);\r
362 ASSERT (Temp != NULL);\r
363 Temp2 = CatSPrint(RetVal, Temp, Supports);\r
364 FreePool(Temp);\r
365 FreePool(RetVal);\r
366 RetVal = Temp2;\r
367 Temp2 = NULL;\r
368 }\r
369\r
370 Configuration = NULL;\r
371 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Configuration);\r
372 if (!EFI_ERROR(Status) && Configuration != NULL) {\r
373 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_TITLE), NULL);\r
374 ASSERT (Temp != NULL);\r
375 Temp2 = CatSPrint(RetVal, Temp, Supports);\r
376 FreePool(Temp);\r
377 FreePool(RetVal);\r
378 RetVal = Temp2;\r
379 Temp2 = NULL;\r
380 while (Configuration->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
381 Temp = NULL;\r
382 switch (Configuration->ResType) {\r
383 case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
384 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_MEM), NULL);\r
385 break;\r
386 case ACPI_ADDRESS_SPACE_TYPE_IO:\r
387 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_IO), NULL);\r
388 break;\r
389 case ACPI_ADDRESS_SPACE_TYPE_BUS:\r
390 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_BUS), NULL);\r
391 break;\r
392 }\r
393 if (Temp != NULL) {\r
394 Temp2 = CatSPrint(RetVal, L"%s", Temp);\r
395 FreePool(Temp);\r
396 FreePool(RetVal);\r
397 RetVal = Temp2;\r
398 Temp2 = NULL;\r
399 }\r
400\r
401 Temp2 = CatSPrint(RetVal, \r
402 L"%H%02x %016lx %016lx %02x%N\r\n",\r
403 Configuration->SpecificFlag,\r
404 Configuration->AddrRangeMin,\r
405 Configuration->AddrRangeMax,\r
406 Configuration->AddrSpaceGranularity\r
407 );\r
408 FreePool(RetVal);\r
409 RetVal = Temp2;\r
410 Temp2 = NULL;\r
411 Configuration++;\r
412 }\r
413 }\r
414 return (RetVal);\r
415}\r
416\r
417/**\r
418 Function to dump information about SimpleTextOut.\r
419\r
420 This will allocate the return buffer from boot services pool.\r
421\r
422 @param[in] TheHandle The handle that has SimpleTextOut installed.\r
423 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
424\r
425 @retval A poitner to a string containing the information.\r
426**/\r
427CHAR16*\r
428EFIAPI\r
429TxtOutProtocolDumpInformation(\r
430 IN CONST EFI_HANDLE TheHandle,\r
431 IN CONST BOOLEAN Verbose\r
432 )\r
433{\r
434 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Dev;\r
435 INTN Index;\r
436 UINTN Col;\r
437 UINTN Row;\r
438 EFI_STATUS Status;\r
439 CHAR16 *RetVal;\r
440 UINTN Size;\r
441 CHAR16 *Temp;\r
442 UINTN NewSize;\r
443\r
444 if (!Verbose) {\r
445 return (NULL);\r
446 }\r
447\r
448 RetVal = NULL;\r
449 Size = 0;\r
450\r
451 Status = gBS->HandleProtocol(\r
452 TheHandle,\r
453 &gEfiSimpleTextOutProtocolGuid,\r
454 (VOID**)&Dev);\r
455\r
456 ASSERT_EFI_ERROR(Status);\r
457 ASSERT (Dev != NULL && Dev->Mode != NULL);\r
458\r
459 Size = (Dev->Mode->MaxMode + 1) * 80;\r
460 RetVal = AllocateZeroPool(Size);\r
461\r
462 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_HEADER), NULL);\r
463 if (Temp != NULL) {\r
464 UnicodeSPrint(RetVal, Size, Temp, Dev, Dev->Mode->Attribute);\r
465 FreePool(Temp);\r
466 }\r
467\r
468 //\r
469 // Dump TextOut Info\r
470 //\r
471 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_LINE), NULL);\r
472 for (Index = 0; Index < Dev->Mode->MaxMode; Index++) {\r
473 Status = Dev->QueryMode (Dev, Index, &Col, &Row);\r
474 NewSize = Size - StrSize(RetVal);\r
475 UnicodeSPrint(\r
476 RetVal + StrLen(RetVal),\r
477 NewSize,\r
478 Temp == NULL?L"":Temp,\r
479 Index == Dev->Mode->Mode ? L'*' : L' ',\r
480 Index,\r
481 !EFI_ERROR(Status)?(INTN)Col:-1,\r
482 !EFI_ERROR(Status)?(INTN)Row:-1\r
483 );\r
484 }\r
485 FreePool(Temp);\r
486 return (RetVal);\r
487}\r
488\r
489STATIC CONST UINTN VersionStringSize = 60;\r
490\r
491/**\r
492 Function to dump information about EfiDriverSupportedEfiVersion protocol.\r
493\r
494 This will allocate the return buffer from boot services pool.\r
495\r
496 @param[in] TheHandle The handle that has the protocol installed.\r
497 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
498\r
499 @retval A poitner to a string containing the information.\r
500**/\r
501CHAR16*\r
502EFIAPI\r
503DriverEfiVersionProtocolDumpInformation(\r
504 IN CONST EFI_HANDLE TheHandle,\r
505 IN CONST BOOLEAN Verbose\r
506 )\r
507{\r
508 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;\r
509 EFI_STATUS Status;\r
510 CHAR16 *RetVal;\r
511\r
512 Status = gBS->HandleProtocol(\r
513 TheHandle,\r
514 &gEfiDriverSupportedEfiVersionProtocolGuid,\r
515 (VOID**)&DriverEfiVersion);\r
516\r
517 ASSERT_EFI_ERROR(Status);\r
518\r
519 RetVal = AllocateZeroPool(VersionStringSize);\r
520 ASSERT(RetVal != NULL);\r
521 UnicodeSPrint(RetVal, VersionStringSize, L"0x%08x", DriverEfiVersion->FirmwareVersion);\r
522 return (RetVal);\r
523}\r
524\r
525/**\r
526 Function to dump information about DevicePath protocol.\r
527\r
528 This will allocate the return buffer from boot services pool.\r
529\r
530 @param[in] TheHandle The handle that has the protocol installed.\r
531 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
532\r
533 @retval A poitner to a string containing the information.\r
534**/\r
535CHAR16*\r
536EFIAPI\r
537DevicePathProtocolDumpInformation(\r
538 IN CONST EFI_HANDLE TheHandle,\r
539 IN CONST BOOLEAN Verbose\r
540 )\r
541{\r
542 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
543 CHAR16 *Temp;\r
544 CHAR16 *Temp2;\r
545 EFI_STATUS Status;\r
546 Temp = NULL;\r
547\r
548 Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
549 if (!EFI_ERROR(Status)) {\r
550 //\r
551 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)\r
552 //\r
553 Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);\r
554 gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);\r
555 }\r
556 if (!Verbose && Temp != NULL && StrLen(Temp) > 30) {\r
557 Temp2 = NULL;\r
558 Temp2 = StrnCatGrow(&Temp2, NULL, Temp+(StrLen(Temp) - 30), 30);\r
559 FreePool(Temp);\r
560 Temp = Temp2;\r
561 }\r
562 return (Temp);\r
563}\r
564\r
565//\r
566// Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg\r
567//\r
568#define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \\r
569 { \\r
570 0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
571 }\r
572\r
573#define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \\r
574 { \\r
575 0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
576 }\r
577\r
578#define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \\r
579 { \\r
580 0xc95a93d, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
581 }\r
582STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID;\r
583STATIC CONST EFI_GUID WinNtIoProtocolGuid = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;\r
584STATIC CONST EFI_GUID WinNtSerialPortGuid = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;\r
585\r
586STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {\r
587 {STRING_TOKEN(STR_WINNT_THUNK), (EFI_GUID*)&WinNtThunkProtocolGuid, NULL},\r
588 {STRING_TOKEN(STR_WINNT_DRIVER_IO), (EFI_GUID*)&WinNtIoProtocolGuid, NULL},\r
589 {STRING_TOKEN(STR_WINNT_SERIAL_PORT), (EFI_GUID*)&WinNtSerialPortGuid, NULL},\r
590 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},\r
591};\r
592\r
593STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {\r
594 {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, LoadedImageProtocolDumpInformation},\r
595 {STRING_TOKEN(STR_DEVICE_PATH), &gEfiDevicePathProtocolGuid, DevicePathProtocolDumpInformation},\r
596 {STRING_TOKEN(STR_IMAGE_PATH), &gEfiLoadedImageDevicePathProtocolGuid, DevicePathProtocolDumpInformation},\r
597 {STRING_TOKEN(STR_DEVICE_PATH_UTIL), &gEfiDevicePathUtilitiesProtocolGuid, NULL},\r
598 {STRING_TOKEN(STR_DEVICE_PATH_TXT), &gEfiDevicePathToTextProtocolGuid, NULL},\r
599 {STRING_TOKEN(STR_DEVICE_PATH_FTXT), &gEfiDevicePathFromTextProtocolGuid, NULL},\r
600 {STRING_TOKEN(STR_DEVICE_PATH_PC), &gEfiPcAnsiGuid, NULL},\r
601 {STRING_TOKEN(STR_DEVICE_PATH_VT100), &gEfiVT100Guid, NULL},\r
602 {STRING_TOKEN(STR_DEVICE_PATH_VT100P), &gEfiVT100PlusGuid, NULL},\r
603 {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8), &gEfiVTUTF8Guid, NULL},\r
604 {STRING_TOKEN(STR_DRIVER_BINDING), &gEfiDriverBindingProtocolGuid, NULL},\r
605 {STRING_TOKEN(STR_PLATFORM_OVERRIDE), &gEfiPlatformDriverOverrideProtocolGuid, NULL},\r
606 {STRING_TOKEN(STR_BUS_OVERRIDE), &gEfiBusSpecificDriverOverrideProtocolGuid, NULL},\r
607 {STRING_TOKEN(STR_DRIVER_DIAG), &gEfiDriverDiagnosticsProtocolGuid, NULL},\r
608 {STRING_TOKEN(STR_DRIVER_DIAG2), &gEfiDriverDiagnostics2ProtocolGuid, NULL},\r
609 {STRING_TOKEN(STR_DRIVER_CN), &gEfiComponentNameProtocolGuid, NULL},\r
610 {STRING_TOKEN(STR_DRIVER_CN2), &gEfiComponentName2ProtocolGuid, NULL},\r
611 {STRING_TOKEN(STR_PLAT_DRV_CFG), &gEfiPlatformToDriverConfigurationProtocolGuid, NULL},\r
612 {STRING_TOKEN(STR_DRIVER_VERSION), &gEfiDriverSupportedEfiVersionProtocolGuid, DriverEfiVersionProtocolDumpInformation},\r
613 {STRING_TOKEN(STR_TXT_IN), &gEfiSimpleTextInProtocolGuid, NULL},\r
614 {STRING_TOKEN(STR_TXT_IN_EX), &gEfiSimpleTextInputExProtocolGuid, NULL},\r
615 {STRING_TOKEN(STR_TXT_OUT), &gEfiSimpleTextOutProtocolGuid, TxtOutProtocolDumpInformation},\r
616 {STRING_TOKEN(STR_SIM_POINTER), &gEfiSimplePointerProtocolGuid, NULL},\r
617 {STRING_TOKEN(STR_ABS_POINTER), &gEfiAbsolutePointerProtocolGuid, NULL},\r
618 {STRING_TOKEN(STR_SERIAL_IO), &gEfiSerialIoProtocolGuid, NULL},\r
619 {STRING_TOKEN(STR_GRAPHICS_OUTPUT), &gEfiGraphicsOutputProtocolGuid, GraphicsOutputProtocolDumpInformation},\r
620 {STRING_TOKEN(STR_EDID_DISCOVERED), &gEfiEdidDiscoveredProtocolGuid, NULL},\r
621 {STRING_TOKEN(STR_EDID_ACTIVE), &gEfiEdidActiveProtocolGuid, NULL},\r
622 {STRING_TOKEN(STR_EDID_OVERRIDE), &gEfiEdidOverrideProtocolGuid, NULL},\r
623 {STRING_TOKEN(STR_CON_IN), &gEfiConsoleInDeviceGuid, NULL},\r
624 {STRING_TOKEN(STR_CON_OUT), &gEfiConsoleOutDeviceGuid, NULL},\r
625 {STRING_TOKEN(STR_STD_ERR), &gEfiStandardErrorDeviceGuid, NULL},\r
626 {STRING_TOKEN(STR_LOAD_FILE), &gEfiLoadFileProtocolGuid, NULL},\r
627 {STRING_TOKEN(STR_LOAD_FILE2), &gEfiLoadFile2ProtocolGuid, NULL},\r
628 {STRING_TOKEN(STR_SIMPLE_FILE_SYS), &gEfiSimpleFileSystemProtocolGuid, NULL},\r
629 {STRING_TOKEN(STR_TAPE_IO), &gEfiTapeIoProtocolGuid, NULL},\r
630 {STRING_TOKEN(STR_DISK_IO), &gEfiDiskIoProtocolGuid, NULL},\r
631 {STRING_TOKEN(STR_BLK_IO), &gEfiBlockIoProtocolGuid, NULL},\r
632 {STRING_TOKEN(STR_UC), &gEfiUnicodeCollationProtocolGuid, NULL},\r
633 {STRING_TOKEN(STR_UC2), &gEfiUnicodeCollation2ProtocolGuid, NULL},\r
634 {STRING_TOKEN(STR_PCIRB_IO), &gEfiPciRootBridgeIoProtocolGuid, PciRootBridgeIoDumpInformation},\r
635 {STRING_TOKEN(STR_PCI_IO), &gEfiPciIoProtocolGuid, NULL},\r
636 {STRING_TOKEN(STR_SCSI_PT), &gEfiScsiPassThruProtocolGuid, NULL},\r
637 {STRING_TOKEN(STR_SCSI_IO), &gEfiScsiIoProtocolGuid, NULL},\r
638 {STRING_TOKEN(STR_SCSI_PT_EXT), &gEfiExtScsiPassThruProtocolGuid, NULL},\r
639 {STRING_TOKEN(STR_ISCSI), &gEfiIScsiInitiatorNameProtocolGuid, NULL},\r
640 {STRING_TOKEN(STR_USB_IO), &gEfiUsbIoProtocolGuid, NULL},\r
641 {STRING_TOKEN(STR_USB_HC), &gEfiUsbHcProtocolGuid, NULL},\r
642 {STRING_TOKEN(STR_USB_HC2), &gEfiUsb2HcProtocolGuid, NULL},\r
643 {STRING_TOKEN(STR_DEBUG_SUPPORT), &gEfiDebugSupportProtocolGuid, NULL},\r
644 {STRING_TOKEN(STR_DEBUG_PORT), &gEfiDebugPortProtocolGuid, NULL},\r
645 {STRING_TOKEN(STR_DECOMPRESS), &gEfiDecompressProtocolGuid, NULL},\r
646 {STRING_TOKEN(STR_ACPI_TABLE), &gEfiAcpiTableProtocolGuid, NULL},\r
647 {STRING_TOKEN(STR_EBC_INTERPRETER), &gEfiEbcProtocolGuid, NULL},\r
648 {STRING_TOKEN(STR_SNP), &gEfiSimpleNetworkProtocolGuid, NULL},\r
649 {STRING_TOKEN(STR_NII), &gEfiNetworkInterfaceIdentifierProtocolGuid, NULL},\r
650 {STRING_TOKEN(STR_NII_31), &gEfiNetworkInterfaceIdentifierProtocolGuid_31, NULL},\r
651 {STRING_TOKEN(STR_PXE_BC), &gEfiPxeBaseCodeProtocolGuid, NULL},\r
652 {STRING_TOKEN(STR_PXE_CB), &gEfiPxeBaseCodeCallbackProtocolGuid, NULL},\r
653 {STRING_TOKEN(STR_BIS), &gEfiBisProtocolGuid, NULL},\r
654 {STRING_TOKEN(STR_MNP_SB), &gEfiManagedNetworkServiceBindingProtocolGuid, NULL},\r
655 {STRING_TOKEN(STR_MNP), &gEfiManagedNetworkProtocolGuid, NULL},\r
656 {STRING_TOKEN(STR_ARP_SB), &gEfiArpServiceBindingProtocolGuid, NULL},\r
657 {STRING_TOKEN(STR_ARP), &gEfiArpProtocolGuid, NULL},\r
658 {STRING_TOKEN(STR_DHCPV4_SB), &gEfiDhcp4ServiceBindingProtocolGuid, NULL},\r
659 {STRING_TOKEN(STR_DHCPV4), &gEfiDhcp4ProtocolGuid, NULL},\r
660 {STRING_TOKEN(STR_TCPV4_SB), &gEfiTcp4ServiceBindingProtocolGuid, NULL},\r
661 {STRING_TOKEN(STR_TCPV4), &gEfiTcp4ProtocolGuid, NULL},\r
662 {STRING_TOKEN(STR_IPV4_SB), &gEfiIp4ServiceBindingProtocolGuid, NULL},\r
663 {STRING_TOKEN(STR_IPV4), &gEfiIp4ProtocolGuid, NULL},\r
664 {STRING_TOKEN(STR_IPV4_CFG), &gEfiIp4ConfigProtocolGuid, NULL},\r
665 {STRING_TOKEN(STR_UDPV4_SB), &gEfiUdp4ServiceBindingProtocolGuid, NULL},\r
666 {STRING_TOKEN(STR_UDPV4), &gEfiUdp4ProtocolGuid, NULL},\r
667 {STRING_TOKEN(STR_MTFTPV4_SB), &gEfiMtftp4ServiceBindingProtocolGuid, NULL},\r
668 {STRING_TOKEN(STR_MTFTPV4), &gEfiMtftp4ProtocolGuid, NULL},\r
669 {STRING_TOKEN(STR_AUTH_INFO), &gEfiAuthenticationInfoProtocolGuid, NULL},\r
670 {STRING_TOKEN(STR_HASH_SB), &gEfiHashServiceBindingProtocolGuid, NULL},\r
671 {STRING_TOKEN(STR_HASH), &gEfiHashProtocolGuid, NULL},\r
672 {STRING_TOKEN(STR_HII_FONT), &gEfiHiiFontProtocolGuid, NULL},\r
673 {STRING_TOKEN(STR_HII_STRING), &gEfiHiiStringProtocolGuid, NULL},\r
674 {STRING_TOKEN(STR_HII_IMAGE), &gEfiHiiImageProtocolGuid, NULL},\r
675 {STRING_TOKEN(STR_HII_DATABASE), &gEfiHiiDatabaseProtocolGuid, NULL},\r
676 {STRING_TOKEN(STR_HII_CONFIG_ROUT), &gEfiHiiConfigRoutingProtocolGuid, NULL},\r
677 {STRING_TOKEN(STR_HII_CONFIG_ACC), &gEfiHiiConfigAccessProtocolGuid, NULL},\r
678 {STRING_TOKEN(STR_HII_FORM_BROWSER2), &gEfiFormBrowser2ProtocolGuid, NULL},\r
679 {STRING_TOKEN(STR_DRIVER_FAM_OVERRIDE), &gEfiDriverFamilyOverrideProtocolGuid, NULL},\r
680 {STRING_TOKEN(STR_PCD), &gPcdProtocolGuid, NULL},\r
681 {STRING_TOKEN(STR_TCG), &gEfiTcgProtocolGuid, NULL},\r
682 {STRING_TOKEN(STR_HII_PACKAGE_LIST), &gEfiHiiPackageListProtocolGuid, NULL},\r
683\r
684//\r
685// the ones under this are deprecated by the current UEFI Spec, but may be found anyways...\r
686//\r
687 {STRING_TOKEN(STR_SHELL_INTERFACE), &gEfiShellInterfaceGuid, NULL},\r
688 {STRING_TOKEN(STR_SHELL_ENV2), &gEfiShellEnvironment2Guid, NULL},\r
689 {STRING_TOKEN(STR_SHELL_ENV), &gEfiShellEnvironment2Guid, NULL},\r
690 {STRING_TOKEN(STR_DEVICE_IO), &gEfiDeviceIoProtocolGuid, NULL},\r
691 {STRING_TOKEN(STR_UGA_DRAW), &gEfiUgaDrawProtocolGuid, NULL},\r
692 {STRING_TOKEN(STR_UGA_IO), &gEfiUgaIoProtocolGuid, NULL},\r
693 {STRING_TOKEN(STR_ESP), &gEfiPartTypeSystemPartGuid, NULL},\r
694 {STRING_TOKEN(STR_GPT_NBR), &gEfiPartTypeLegacyMbrGuid, NULL},\r
695 {STRING_TOKEN(STR_DRIVER_CONFIG), &gEfiDriverConfigurationProtocolGuid, NULL},\r
696 {STRING_TOKEN(STR_DRIVER_CONFIG2), &gEfiDriverConfiguration2ProtocolGuid, NULL},\r
697\r
698//\r
699// the ones under this are GUID identified structs, not protocols\r
700//\r
701 {STRING_TOKEN(STR_FILE_INFO), &gEfiFileInfoGuid, NULL},\r
702 {STRING_TOKEN(STR_FILE_SYS_INFO), &gEfiFileSystemInfoGuid, NULL},\r
703\r
704//\r
705// the ones under this are misc GUIDS.\r
706//\r
707 {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE), &gEfiGlobalVariableGuid, NULL},\r
708\r
709//\r
710// UEFI 2.2\r
711//\r
712 {STRING_TOKEN(STR_IP6_SB), &gEfiIp6ServiceBindingProtocolGuid, NULL},\r
713 {STRING_TOKEN(STR_IP6), &gEfiIp6ProtocolGuid, NULL},\r
714 {STRING_TOKEN(STR_IP6_CONFIG), &gEfiIp6ConfigProtocolGuid, NULL},\r
715 {STRING_TOKEN(STR_MTFTP6_SB), &gEfiMtftp6ServiceBindingProtocolGuid, NULL},\r
716 {STRING_TOKEN(STR_MTFTP6), &gEfiMtftp6ProtocolGuid, NULL},\r
717 {STRING_TOKEN(STR_DHCP6_SB), &gEfiDhcp6ServiceBindingProtocolGuid, NULL},\r
718 {STRING_TOKEN(STR_DHCP6), &gEfiDhcp6ProtocolGuid, NULL},\r
719 {STRING_TOKEN(STR_UDP6_SB), &gEfiUdp6ServiceBindingProtocolGuid, NULL},\r
720 {STRING_TOKEN(STR_UDP6), &gEfiUdp6ProtocolGuid, NULL},\r
721 {STRING_TOKEN(STR_TCP6_SB), &gEfiTcp6ServiceBindingProtocolGuid, NULL},\r
722 {STRING_TOKEN(STR_TCP6), &gEfiTcp6ProtocolGuid, NULL},\r
723 {STRING_TOKEN(STR_VLAN_CONFIG), &gEfiVlanConfigProtocolGuid, NULL},\r
724 {STRING_TOKEN(STR_EAP), &gEfiEapProtocolGuid, NULL},\r
725 {STRING_TOKEN(STR_EAP_MGMT), &gEfiEapManagementProtocolGuid, NULL},\r
726 {STRING_TOKEN(STR_FTP4_SB), &gEfiFtp4ServiceBindingProtocolGuid, NULL},\r
727 {STRING_TOKEN(STR_FTP4), &gEfiFtp4ProtocolGuid, NULL},\r
728 {STRING_TOKEN(STR_IP_SEC_CONFIG), &gEfiIpSecConfigProtocolGuid, NULL},\r
729 {STRING_TOKEN(STR_DH), &gEfiDriverHealthProtocolGuid, NULL},\r
730 {STRING_TOKEN(STR_DEF_IMG_LOAD), &gEfiDeferredImageLoadProtocolGuid, NULL},\r
731 {STRING_TOKEN(STR_USER_CRED), &gEfiUserCredentialProtocolGuid, NULL},\r
732 {STRING_TOKEN(STR_USER_MNGR), &gEfiUserManagerProtocolGuid, NULL},\r
733 {STRING_TOKEN(STR_ATA_PASS_THRU), &gEfiAtaPassThruProtocolGuid, NULL},\r
734\r
735//\r
736// UEFI 2.3\r
737//\r
738 {STRING_TOKEN(STR_FW_MGMT), &gEfiFirmwareManagementProtocolGuid, NULL},\r
739 {STRING_TOKEN(STR_IP_SEC), &gEfiIpSecProtocolGuid, NULL},\r
740 {STRING_TOKEN(STR_IP_SEC2), &gEfiIpSec2ProtocolGuid, NULL},\r
741\r
742//\r
743// UEFI 2.3.1\r
744//\r
745 {STRING_TOKEN(STR_KMS), &gEfiKmsProtocolGuid, NULL},\r
746 {STRING_TOKEN(STR_BLK_IO2), &gEfiBlockIo2ProtocolGuid, NULL},\r
747 {STRING_TOKEN(STR_SSC), &gEfiStorageSecurityCommandProtocolGuid, NULL},\r
748 {STRING_TOKEN(STR_UCRED2), &gEfiUserCredential2ProtocolGuid, NULL},\r
749\r
750//\r
751// UEFI 2.4\r
752//\r
753 {STRING_TOKEN(STR_DISK_IO2), &gEfiDiskIo2ProtocolGuid, NULL},\r
754 {STRING_TOKEN(STR_ADAPTER_INFO), &gEfiAdapterInformationProtocolGuid, NULL},\r
755\r
756//\r
757// PI Spec ones\r
758//\r
759 {STRING_TOKEN(STR_IDE_CONT_INIT), &gEfiIdeControllerInitProtocolGuid, NULL},\r
760\r
761//\r
762// UEFI Shell Spec 2.0\r
763//\r
764 {STRING_TOKEN(STR_SHELL_PARAMETERS), &gEfiShellParametersProtocolGuid, NULL},\r
765 {STRING_TOKEN(STR_SHELL), &gEfiShellProtocolGuid, NULL},\r
766\r
767//\r
768// UEFI Shell Spec 2.1\r
769//\r
770 {STRING_TOKEN(STR_SHELL_DYNAMIC), &gEfiShellDynamicCommandProtocolGuid, NULL},\r
771\r
772//\r
773// terminator\r
774//\r
775 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},\r
776};\r
777\r
778/**\r
779 Function to get the node for a protocol or struct from it's GUID.\r
780\r
781 if Guid is NULL, then ASSERT.\r
782\r
783 @param[in] Guid The GUID to look for the name of.\r
784\r
785 @return The node.\r
786**/\r
787CONST GUID_INFO_BLOCK *\r
788EFIAPI\r
789InternalShellGetNodeFromGuid(\r
790 IN CONST EFI_GUID* Guid\r
791 )\r
792{\r
793 CONST GUID_INFO_BLOCK *ListWalker;\r
794 UINTN LoopCount;\r
795\r
796 ASSERT(Guid != NULL);\r
797\r
798 for (LoopCount = 0, ListWalker = GuidList; GuidList != NULL && LoopCount < GuidListCount; LoopCount++, ListWalker++) {\r
799 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
800 return (ListWalker);\r
801 }\r
802 }\r
803\r
804 if (PcdGetBool(PcdShellIncludeNtGuids)) {\r
805 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
806 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
807 return (ListWalker);\r
808 }\r
809 }\r
810 }\r
811 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
812 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
813 return (ListWalker);\r
814 }\r
815 }\r
816 return (NULL);\r
817}\r
818\r
819/**\r
820Function to add a new GUID/Name mapping.\r
821\r
822@param[in] Guid The Guid\r
823@param[in] NameId The STRING id of the HII string to use\r
824@param[in] Dump The pointer to the dump function\r
825\r
826\r
827@retval EFI_SUCCESS The operation was sucessful\r
828@retval EFI_OUT_OF_RESOURCES A memory allocation failed\r
829@retval EFI_INVALID_PARAMETER Guid NameId was invalid\r
830**/\r
831STATIC\r
832EFI_STATUS\r
833EFIAPI\r
834InsertNewGuidNameMapping(\r
835 IN CONST EFI_GUID *Guid,\r
836 IN CONST EFI_STRING_ID NameID,\r
837 IN CONST DUMP_PROTOCOL_INFO DumpFunc OPTIONAL\r
838 )\r
839{\r
840 ASSERT(Guid != NULL);\r
841 ASSERT(NameID != 0);\r
842\r
843 GuidList = ReallocatePool(GuidListCount * sizeof(GUID_INFO_BLOCK), GuidListCount+1 * sizeof(GUID_INFO_BLOCK), GuidList);\r
844 if (GuidList == NULL) {\r
845 GuidListCount = 0;\r
846 return (EFI_OUT_OF_RESOURCES);\r
847 }\r
848 GuidListCount++;\r
849\r
850 GuidList[GuidListCount - 1].GuidId = AllocateCopyPool(sizeof(EFI_GUID), Guid);\r
851 GuidList[GuidListCount - 1].StringId = NameID;\r
852 GuidList[GuidListCount - 1].DumpInfo = DumpFunc;\r
853\r
854 if (GuidList[GuidListCount - 1].GuidId == NULL) {\r
855 return (EFI_OUT_OF_RESOURCES);\r
856 }\r
857\r
858 return (EFI_SUCCESS);\r
859}\r
860\r
861/**\r
862 Function to add a new GUID/Name mapping.\r
863\r
864 This cannot overwrite an existing mapping.\r
865\r
866 @param[in] Guid The Guid\r
867 @param[in] TheName The Guid's name\r
868 @param[in] Lang RFC4646 language code list or NULL\r
869\r
870 @retval EFI_SUCCESS The operation was sucessful\r
871 @retval EFI_ACCESS_DENIED There was a duplicate\r
872 @retval EFI_OUT_OF_RESOURCES A memory allocation failed\r
873 @retval EFI_INVALID_PARAMETER Guid or TheName was NULL\r
874**/\r
875EFI_STATUS\r
876EFIAPI\r
877AddNewGuidNameMapping(\r
878 IN CONST EFI_GUID *Guid,\r
879 IN CONST CHAR16 *TheName,\r
880 IN CONST CHAR8 *Lang OPTIONAL\r
881 )\r
882{\r
883 CONST GUID_INFO_BLOCK *Temp;\r
884 EFI_STRING_ID NameID;\r
885\r
886 if (Guid == NULL || TheName == NULL){\r
887 return (EFI_INVALID_PARAMETER);\r
888 }\r
889\r
890 if ((Temp = InternalShellGetNodeFromGuid(Guid)) != NULL) {\r
891 return (EFI_ACCESS_DENIED);\r
892 }\r
893\r
894 NameID = HiiSetString(mHandleParsingHiiHandle, 0, (CHAR16*)TheName, Lang);\r
895 if (NameID == 0) {\r
896 return (EFI_OUT_OF_RESOURCES);\r
897 }\r
898\r
899 return (InsertNewGuidNameMapping(Guid, NameID, NULL));\r
900}\r
901\r
902/**\r
903 Function to get the name of a protocol or struct from it's GUID.\r
904\r
905 if Guid is NULL, then ASSERT.\r
906\r
907 @param[in] Guid The GUID to look for the name of.\r
908 @param[in] Lang The language to use.\r
909\r
910 @return pointer to string of the name. The caller\r
911 is responsible to free this memory.\r
912**/\r
913CHAR16*\r
914EFIAPI\r
915GetStringNameFromGuid(\r
916 IN CONST EFI_GUID *Guid,\r
917 IN CONST CHAR8 *Lang OPTIONAL\r
918 )\r
919{\r
920 CONST GUID_INFO_BLOCK *Id;\r
921\r
922 Id = InternalShellGetNodeFromGuid(Guid);\r
923 return (HiiGetString(mHandleParsingHiiHandle, Id==NULL?STRING_TOKEN(STR_UNKNOWN_DEVICE):Id->StringId, Lang));\r
924}\r
925\r
926/**\r
927 Function to dump protocol information from a handle.\r
928\r
929 This function will return a allocated string buffer containing the\r
930 information. The caller is responsible for freeing the memory.\r
931\r
932 If Guid is NULL, ASSERT().\r
933 If TheHandle is NULL, ASSERT().\r
934\r
935 @param[in] TheHandle The handle to dump information from.\r
936 @param[in] Guid The GUID of the protocol to dump.\r
937 @param[in] Verbose TRUE for extra info. FALSE otherwise.\r
938\r
939 @return The pointer to string.\r
940 @retval NULL An error was encountered.\r
941**/\r
942CHAR16*\r
943EFIAPI\r
944GetProtocolInformationDump(\r
945 IN CONST EFI_HANDLE TheHandle,\r
946 IN CONST EFI_GUID *Guid,\r
947 IN CONST BOOLEAN Verbose\r
948 )\r
949{\r
950 CONST GUID_INFO_BLOCK *Id;\r
951\r
952 ASSERT(TheHandle != NULL);\r
953 ASSERT(Guid != NULL);\r
954\r
955 if (TheHandle == NULL || Guid == NULL) {\r
956 return (NULL);\r
957 }\r
958\r
959 Id = InternalShellGetNodeFromGuid(Guid);\r
960 if (Id != NULL && Id->DumpInfo != NULL) {\r
961 return (Id->DumpInfo(TheHandle, Verbose));\r
962 }\r
963 return (NULL);\r
964}\r
965\r
966/**\r
967 Function to get the Guid for a protocol or struct based on it's string name.\r
968\r
969 do not modify the returned Guid.\r
970\r
971 @param[in] Name The pointer to the string name.\r
972 @param[in] Lang The pointer to the language code.\r
973 @param[out] Guid The pointer to the Guid.\r
974\r
975 @retval EFI_SUCCESS The operation was sucessful.\r
976**/\r
977EFI_STATUS\r
978EFIAPI\r
979GetGuidFromStringName(\r
980 IN CONST CHAR16 *Name,\r
981 IN CONST CHAR8 *Lang OPTIONAL,\r
982 OUT EFI_GUID **Guid\r
983 )\r
984{\r
985 CONST GUID_INFO_BLOCK *ListWalker;\r
986 CHAR16 *String;\r
987 UINTN LoopCount;\r
988\r
989 ASSERT(Guid != NULL);\r
990 if (Guid == NULL) {\r
991 return (EFI_INVALID_PARAMETER);\r
992 }\r
993 *Guid = NULL;\r
994\r
995 if (PcdGetBool(PcdShellIncludeNtGuids)) {\r
996 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
997 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
998 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {\r
999 *Guid = ListWalker->GuidId;\r
1000 }\r
1001 SHELL_FREE_NON_NULL(String);\r
1002 if (*Guid != NULL) {\r
1003 return (EFI_SUCCESS);\r
1004 }\r
1005 }\r
1006 }\r
1007 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
1008 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
1009 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {\r
1010 *Guid = ListWalker->GuidId;\r
1011 }\r
1012 SHELL_FREE_NON_NULL(String);\r
1013 if (*Guid != NULL) {\r
1014 return (EFI_SUCCESS);\r
1015 }\r
1016 }\r
1017\r
1018 for (LoopCount = 0, ListWalker = GuidList; GuidList != NULL && LoopCount < GuidListCount; LoopCount++, ListWalker++) {\r
1019 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
1020 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {\r
1021 *Guid = ListWalker->GuidId;\r
1022 }\r
1023 SHELL_FREE_NON_NULL(String);\r
1024 if (*Guid != NULL) {\r
1025 return (EFI_SUCCESS);\r
1026 }\r
1027 }\r
1028\r
1029 return (EFI_NOT_FOUND);\r
1030}\r
1031\r
1032/**\r
1033 Get best support language for this driver.\r
1034 \r
1035 First base on the user input language to search, second base on the current \r
1036 platform used language to search, third get the first language from the \r
1037 support language list. The caller need to free the buffer of the best language.\r
1038\r
1039 @param[in] SupportedLanguages The support languages for this driver.\r
1040 @param[in] InputLanguage The user input language.\r
1041 @param[in] Iso639Language Whether get language for ISO639.\r
1042\r
1043 @return The best support language for this driver.\r
1044**/\r
1045CHAR8 *\r
1046EFIAPI\r
1047GetBestLanguageForDriver (\r
1048 IN CONST CHAR8 *SupportedLanguages,\r
1049 IN CONST CHAR8 *InputLanguage,\r
1050 IN BOOLEAN Iso639Language\r
1051 )\r
1052{\r
1053 CHAR8 *LanguageVariable;\r
1054 CHAR8 *BestLanguage;\r
1055\r
1056 LanguageVariable = GetVariable (Iso639Language ? L"Lang" : L"PlatformLang", &gEfiGlobalVariableGuid);\r
1057\r
1058 BestLanguage = GetBestLanguage(\r
1059 SupportedLanguages,\r
1060 Iso639Language,\r
1061 (InputLanguage != NULL) ? InputLanguage : "",\r
1062 (LanguageVariable != NULL) ? LanguageVariable : "",\r
1063 SupportedLanguages,\r
1064 NULL\r
1065 );\r
1066\r
1067 if (LanguageVariable != NULL) {\r
1068 FreePool (LanguageVariable);\r
1069 }\r
1070\r
1071 return BestLanguage;\r
1072}\r
1073\r
1074/**\r
1075 Function to retrieve the driver name (if possible) from the ComponentName or\r
1076 ComponentName2 protocol\r
1077\r
1078 @param[in] TheHandle The driver handle to get the name of.\r
1079 @param[in] Language The language to use.\r
1080\r
1081 @retval NULL The name could not be found.\r
1082 @return A pointer to the string name. Do not de-allocate the memory.\r
1083**/\r
1084CONST CHAR16*\r
1085EFIAPI\r
1086GetStringNameFromHandle(\r
1087 IN CONST EFI_HANDLE TheHandle,\r
1088 IN CONST CHAR8 *Language\r
1089 )\r
1090{\r
1091 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;\r
1092 EFI_STATUS Status;\r
1093 CHAR16 *RetVal;\r
1094 CHAR8 *BestLang;\r
1095\r
1096 BestLang = NULL;\r
1097\r
1098 Status = gBS->OpenProtocol(\r
1099 TheHandle,\r
1100 &gEfiComponentName2ProtocolGuid,\r
1101 (VOID**)&CompNameStruct,\r
1102 gImageHandle,\r
1103 NULL,\r
1104 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
1105 if (!EFI_ERROR(Status)) {\r
1106 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);\r
1107 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);\r
1108 if (BestLang != NULL) {\r
1109 FreePool (BestLang);\r
1110 BestLang = NULL;\r
1111 }\r
1112 if (!EFI_ERROR(Status)) {\r
1113 return (RetVal);\r
1114 }\r
1115 }\r
1116 Status = gBS->OpenProtocol(\r
1117 TheHandle,\r
1118 &gEfiComponentNameProtocolGuid,\r
1119 (VOID**)&CompNameStruct,\r
1120 gImageHandle,\r
1121 NULL,\r
1122 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
1123 if (!EFI_ERROR(Status)) {\r
1124 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);\r
1125 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);\r
1126 if (BestLang != NULL) {\r
1127 FreePool (BestLang);\r
1128 }\r
1129 if (!EFI_ERROR(Status)) {\r
1130 return (RetVal);\r
1131 }\r
1132 }\r
1133 return (NULL);\r
1134}\r
1135\r
1136/**\r
1137 Function to initialize the file global mHandleList object for use in\r
1138 vonverting handles to index and index to handle.\r
1139\r
1140 @retval EFI_SUCCESS The operation was successful.\r
1141**/\r
1142EFI_STATUS\r
1143EFIAPI\r
1144InternalShellInitHandleList(\r
1145 VOID\r
1146 )\r
1147{\r
1148 EFI_STATUS Status;\r
1149 EFI_HANDLE *HandleBuffer;\r
1150 UINTN HandleCount;\r
1151 HANDLE_LIST *ListWalker;\r
1152\r
1153 if (mHandleList.NextIndex != 0) {\r
1154 return EFI_SUCCESS;\r
1155 }\r
1156 InitializeListHead(&mHandleList.List.Link);\r
1157 mHandleList.NextIndex = 1;\r
1158 Status = gBS->LocateHandleBuffer (\r
1159 AllHandles,\r
1160 NULL,\r
1161 NULL,\r
1162 &HandleCount,\r
1163 &HandleBuffer\r
1164 );\r
1165 ASSERT_EFI_ERROR(Status);\r
1166 if (EFI_ERROR(Status)) {\r
1167 return (Status);\r
1168 }\r
1169 for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){\r
1170 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
1171 ASSERT(ListWalker != NULL);\r
1172 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex-1];\r
1173 ListWalker->TheIndex = mHandleList.NextIndex;\r
1174 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);\r
1175 }\r
1176 FreePool(HandleBuffer);\r
1177 return (EFI_SUCCESS);\r
1178}\r
1179\r
1180/**\r
1181 Function to retrieve the human-friendly index of a given handle. If the handle\r
1182 does not have a index one will be automatically assigned. The index value is valid\r
1183 until the termination of the shell application.\r
1184\r
1185 @param[in] TheHandle The handle to retrieve an index for.\r
1186\r
1187 @retval 0 A memory allocation failed.\r
1188 @return The index of the handle.\r
1189\r
1190**/\r
1191UINTN\r
1192EFIAPI\r
1193ConvertHandleToHandleIndex(\r
1194 IN CONST EFI_HANDLE TheHandle\r
1195 )\r
1196{\r
1197 EFI_STATUS Status;\r
1198 EFI_GUID **ProtocolBuffer;\r
1199 UINTN ProtocolCount;\r
1200 HANDLE_LIST *ListWalker;\r
1201\r
1202 if (TheHandle == NULL) {\r
1203 return 0;\r
1204 }\r
1205\r
1206 InternalShellInitHandleList();\r
1207\r
1208 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)\r
1209 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)\r
1210 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)\r
1211 ){\r
1212 if (ListWalker->TheHandle == TheHandle) {\r
1213 //\r
1214 // Verify that TheHandle is still present in the Handle Database\r
1215 //\r
1216 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);\r
1217 if (EFI_ERROR (Status)) {\r
1218 //\r
1219 // TheHandle is not present in the Handle Database, so delete from the handle list\r
1220 //\r
1221 RemoveEntryList (&ListWalker->Link);\r
1222 return 0;\r
1223 }\r
1224 FreePool (ProtocolBuffer);\r
1225 return (ListWalker->TheIndex);\r
1226 }\r
1227 }\r
1228\r
1229 //\r
1230 // Verify that TheHandle is valid handle\r
1231 //\r
1232 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);\r
1233 if (EFI_ERROR (Status)) {\r
1234 //\r
1235 // TheHandle is not valid, so do not add to handle list\r
1236 //\r
1237 return 0;\r
1238 }\r
1239 FreePool (ProtocolBuffer);\r
1240\r
1241 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
1242 ASSERT(ListWalker != NULL);\r
1243 ListWalker->TheHandle = TheHandle;\r
1244 ListWalker->TheIndex = mHandleList.NextIndex++;\r
1245 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);\r
1246 return (ListWalker->TheIndex);\r
1247}\r
1248\r
1249\r
1250\r
1251/**\r
1252 Function to retrieve the EFI_HANDLE from the human-friendly index.\r
1253\r
1254 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.\r
1255\r
1256 @retval NULL The index was invalid.\r
1257 @return The EFI_HANDLE that index represents.\r
1258\r
1259**/\r
1260EFI_HANDLE\r
1261EFIAPI\r
1262ConvertHandleIndexToHandle(\r
1263 IN CONST UINTN TheIndex\r
1264 )\r
1265{\r
1266 EFI_STATUS Status;\r
1267 EFI_GUID **ProtocolBuffer;\r
1268 UINTN ProtocolCount;\r
1269 HANDLE_LIST *ListWalker;\r
1270\r
1271 InternalShellInitHandleList();\r
1272\r
1273 if (TheIndex >= mHandleList.NextIndex) {\r
1274 return NULL;\r
1275 }\r
1276\r
1277 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)\r
1278 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)\r
1279 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)\r
1280 ){\r
1281 if (ListWalker->TheIndex == TheIndex && ListWalker->TheHandle != NULL) {\r
1282 //\r
1283 // Verify that LinkWalker->TheHandle is valid handle\r
1284 //\r
1285 Status = gBS->ProtocolsPerHandle(ListWalker->TheHandle, &ProtocolBuffer, &ProtocolCount);\r
1286 if (EFI_ERROR (Status)) {\r
1287 //\r
1288 // TheHandle is not valid, so do not add to handle list\r
1289 //\r
1290 ListWalker->TheHandle = NULL;\r
1291 }\r
1292 return (ListWalker->TheHandle);\r
1293 }\r
1294 }\r
1295 return NULL;\r
1296}\r
1297\r
1298/**\r
1299 Gets all the related EFI_HANDLEs based on the mask supplied.\r
1300\r
1301 This function scans all EFI_HANDLES in the UEFI environment's handle database\r
1302 and returns the ones with the specified relationship (Mask) to the specified\r
1303 controller handle.\r
1304\r
1305 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.\r
1306 If MatchingHandleCount is NULL, then ASSERT.\r
1307\r
1308 If MatchingHandleBuffer is not NULL upon a successful return the memory must be\r
1309 caller freed.\r
1310\r
1311 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.\r
1312 @param[in] ControllerHandle The handle with Device Path protocol on it.\r
1313 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in\r
1314 MatchingHandleBuffer.\r
1315 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount\r
1316 EFI_HANDLEs with a terminating NULL EFI_HANDLE.\r
1317 @param[out] HandleType An array of type information.\r
1318\r
1319 @retval EFI_SUCCESS The operation was successful, and any related handles\r
1320 are in MatchingHandleBuffer.\r
1321 @retval EFI_NOT_FOUND No matching handles were found.\r
1322 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.\r
1323**/\r
1324EFI_STATUS\r
1325EFIAPI\r
1326ParseHandleDatabaseByRelationshipWithType (\r
1327 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,\r
1328 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
1329 IN UINTN *HandleCount,\r
1330 OUT EFI_HANDLE **HandleBuffer,\r
1331 OUT UINTN **HandleType\r
1332 )\r
1333{\r
1334 EFI_STATUS Status;\r
1335 UINTN HandleIndex;\r
1336 EFI_GUID **ProtocolGuidArray;\r
1337 UINTN ArrayCount;\r
1338 UINTN ProtocolIndex;\r
1339 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
1340 UINTN OpenInfoCount;\r
1341 UINTN OpenInfoIndex;\r
1342 UINTN ChildIndex;\r
1343 INTN DriverBindingHandleIndex;\r
1344\r
1345 ASSERT(HandleCount != NULL);\r
1346 ASSERT(HandleBuffer != NULL);\r
1347 ASSERT(HandleType != NULL);\r
1348 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);\r
1349\r
1350 *HandleCount = 0;\r
1351 *HandleBuffer = NULL;\r
1352 *HandleType = NULL;\r
1353\r
1354 //\r
1355 // Retrieve the list of all handles from the handle database\r
1356 //\r
1357 Status = gBS->LocateHandleBuffer (\r
1358 AllHandles,\r
1359 NULL,\r
1360 NULL,\r
1361 HandleCount,\r
1362 HandleBuffer\r
1363 );\r
1364 if (EFI_ERROR (Status)) {\r
1365 return (Status);\r
1366 }\r
1367\r
1368 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));\r
1369 ASSERT(*HandleType != NULL);\r
1370\r
1371 DriverBindingHandleIndex = -1;\r
1372 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
1373 if (DriverBindingHandle != NULL && (*HandleBuffer)[HandleIndex] == DriverBindingHandle) {\r
1374 DriverBindingHandleIndex = (INTN)HandleIndex;\r
1375 }\r
1376 }\r
1377\r
1378 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
1379 //\r
1380 // Retrieve the list of all the protocols on each handle\r
1381 //\r
1382 Status = gBS->ProtocolsPerHandle (\r
1383 (*HandleBuffer)[HandleIndex],\r
1384 &ProtocolGuidArray,\r
1385 &ArrayCount\r
1386 );\r
1387 if (EFI_ERROR (Status)) {\r
1388 continue;\r
1389 }\r
1390\r
1391 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
1392\r
1393 //\r
1394 // Set the bit describing what this handle has\r
1395 //\r
1396 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) ) {\r
1397 (*HandleType)[HandleIndex] |= HR_IMAGE_HANDLE;\r
1398 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) ) {\r
1399 (*HandleType)[HandleIndex] |= HR_DRIVER_BINDING_HANDLE;\r
1400 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {\r
1401 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;\r
1402 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {\r
1403 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;\r
1404 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid) ) {\r
1405 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;\r
1406 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) ) {\r
1407 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;\r
1408 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid) ) {\r
1409 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;\r
1410 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) {\r
1411 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;\r
1412 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) ) {\r
1413 (*HandleType)[HandleIndex] |= HR_DEVICE_HANDLE;\r
1414 } else {\r
1415 DEBUG_CODE_BEGIN();\r
1416 ASSERT((*HandleType)[HandleIndex] == (*HandleType)[HandleIndex]);\r
1417 DEBUG_CODE_END();\r
1418 }\r
1419 //\r
1420 // Retrieve the list of agents that have opened each protocol\r
1421 //\r
1422 Status = gBS->OpenProtocolInformation (\r
1423 (*HandleBuffer)[HandleIndex],\r
1424 ProtocolGuidArray[ProtocolIndex],\r
1425 &OpenInfo,\r
1426 &OpenInfoCount\r
1427 );\r
1428 if (EFI_ERROR (Status)) {\r
1429 continue;\r
1430 }\r
1431\r
1432 if (ControllerHandle == NULL) {\r
1433 //\r
1434 // ControllerHandle == NULL and DriverBindingHandle != NULL. \r
1435 // Return information on all the controller handles that the driver specified by DriverBindingHandle is managing\r
1436 //\r
1437 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1438 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1439 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1440 if (DriverBindingHandleIndex != -1) {\r
1441 (*HandleType)[DriverBindingHandleIndex] |= HR_DEVICE_DRIVER;\r
1442 }\r
1443 }\r
1444 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1445 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1446 if (DriverBindingHandleIndex != -1) {\r
1447 (*HandleType)[DriverBindingHandleIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1448 }\r
1449 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1450 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1451 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
1452 }\r
1453 }\r
1454 }\r
1455 }\r
1456 }\r
1457 if (DriverBindingHandle == NULL && ControllerHandle != NULL) {\r
1458 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {\r
1459 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1460 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1461 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1462 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1463 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1464 (*HandleType)[ChildIndex] |= HR_DEVICE_DRIVER;\r
1465 }\r
1466 }\r
1467 }\r
1468 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1469 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1470 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1471 (*HandleType)[ChildIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1472 }\r
1473 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1474 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
1475 }\r
1476 }\r
1477 }\r
1478 }\r
1479 } else {\r
1480 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1481 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1482 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {\r
1483 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_PARENT_HANDLE);\r
1484 }\r
1485 }\r
1486 }\r
1487 }\r
1488 }\r
1489 if (DriverBindingHandle != NULL && ControllerHandle != NULL) {\r
1490 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {\r
1491 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1492 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1493 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1494 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
1495 if (DriverBindingHandleIndex != -1) {\r
1496 (*HandleType)[DriverBindingHandleIndex] |= HR_DEVICE_DRIVER;\r
1497 }\r
1498 }\r
1499 }\r
1500 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1501 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
1502 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1503 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1504 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
1505 }\r
1506 }\r
1507 }\r
1508\r
1509 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1510 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1511 (*HandleType)[ChildIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1512 }\r
1513 }\r
1514 }\r
1515 }\r
1516 } else {\r
1517 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1518 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1519 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {\r
1520 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_PARENT_HANDLE);\r
1521 }\r
1522 }\r
1523 }\r
1524 }\r
1525 }\r
1526 FreePool (OpenInfo);\r
1527 }\r
1528 FreePool (ProtocolGuidArray);\r
1529 }\r
1530 return EFI_SUCCESS;\r
1531}\r
1532\r
1533/**\r
1534 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask\r
1535 supplied.\r
1536\r
1537 This function will scan all EFI_HANDLES in the UEFI environment's handle database\r
1538 and return all the ones with the specified relationship (Mask) to the specified\r
1539 controller handle.\r
1540\r
1541 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.\r
1542 If MatchingHandleCount is NULL, then ASSERT.\r
1543\r
1544 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be\r
1545 caller freed.\r
1546\r
1547 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol\r
1548 on it.\r
1549 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.\r
1550 @param[in] Mask Mask of what relationship(s) is desired.\r
1551 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in\r
1552 MatchingHandleBuffer.\r
1553 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount\r
1554 EFI_HANDLEs and a terminating NULL EFI_HANDLE.\r
1555\r
1556 @retval EFI_SUCCESS The operation was sucessful and any related handles\r
1557 are in MatchingHandleBuffer;\r
1558 @retval EFI_NOT_FOUND No matching handles were found.\r
1559 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.\r
1560**/\r
1561EFI_STATUS\r
1562EFIAPI\r
1563ParseHandleDatabaseByRelationship (\r
1564 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,\r
1565 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
1566 IN CONST UINTN Mask,\r
1567 IN UINTN *MatchingHandleCount,\r
1568 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1569 )\r
1570{\r
1571 EFI_STATUS Status;\r
1572 UINTN HandleCount;\r
1573 EFI_HANDLE *HandleBuffer;\r
1574 UINTN *HandleType;\r
1575 UINTN HandleIndex;\r
1576\r
1577 ASSERT(MatchingHandleCount != NULL);\r
1578 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);\r
1579\r
1580 if ((Mask & HR_VALID_MASK) != Mask) {\r
1581 return (EFI_INVALID_PARAMETER);\r
1582 }\r
1583\r
1584 if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {\r
1585 return (EFI_INVALID_PARAMETER);\r
1586 }\r
1587\r
1588 *MatchingHandleCount = 0;\r
1589 if (MatchingHandleBuffer != NULL) {\r
1590 *MatchingHandleBuffer = NULL;\r
1591 }\r
1592\r
1593 HandleBuffer = NULL;\r
1594 HandleType = NULL;\r
1595\r
1596 Status = ParseHandleDatabaseByRelationshipWithType (\r
1597 DriverBindingHandle,\r
1598 ControllerHandle,\r
1599 &HandleCount,\r
1600 &HandleBuffer,\r
1601 &HandleType\r
1602 );\r
1603 if (!EFI_ERROR (Status)) {\r
1604 //\r
1605 // Count the number of handles that match the attributes in Mask\r
1606 //\r
1607 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
1608 if ((HandleType[HandleIndex] & Mask) == Mask) {\r
1609 (*MatchingHandleCount)++;\r
1610 }\r
1611 }\r
1612 //\r
1613 // If no handles match the attributes in Mask then return EFI_NOT_FOUND\r
1614 //\r
1615 if (*MatchingHandleCount == 0) {\r
1616 Status = EFI_NOT_FOUND;\r
1617 } else {\r
1618\r
1619 if (MatchingHandleBuffer == NULL) {\r
1620 //\r
1621 // Someone just wanted the count...\r
1622 //\r
1623 Status = EFI_SUCCESS;\r
1624 } else {\r
1625 //\r
1626 // Allocate a handle buffer for the number of handles that matched the attributes in Mask\r
1627 //\r
1628 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));\r
1629 ASSERT(*MatchingHandleBuffer != NULL);\r
1630\r
1631 for (HandleIndex = 0,*MatchingHandleCount = 0\r
1632 ; HandleIndex < HandleCount\r
1633 ; HandleIndex++\r
1634 ){\r
1635 //\r
1636 // Fill the allocated buffer with the handles that matched the attributes in Mask\r
1637 //\r
1638 if ((HandleType[HandleIndex] & Mask) == Mask) {\r
1639 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];\r
1640 }\r
1641 }\r
1642\r
1643 //\r
1644 // Make the last one NULL\r
1645 //\r
1646 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;\r
1647\r
1648 Status = EFI_SUCCESS;\r
1649 } // MacthingHandleBuffer == NULL (ELSE)\r
1650 } // *MatchingHandleCount == 0 (ELSE)\r
1651 } // no error on ParseHandleDatabaseByRelationshipWithType\r
1652\r
1653 if (HandleBuffer != NULL) {\r
1654 FreePool (HandleBuffer);\r
1655 }\r
1656\r
1657 if (HandleType != NULL) {\r
1658 FreePool (HandleType);\r
1659 }\r
1660\r
1661 return Status;\r
1662}\r
1663\r
1664/**\r
1665 Gets handles for any child controllers of the passed in controller.\r
1666\r
1667 @param[in] ControllerHandle The handle of the "parent controller"\r
1668 @param[in] MatchingHandleCount Pointer to the number of handles in\r
1669 MatchingHandleBuffer on return.\r
1670 @param[out] MatchingHandleBuffer Buffer containing handles on a successful\r
1671 return.\r
1672\r
1673\r
1674 @retval EFI_SUCCESS The operation was sucessful.\r
1675**/\r
1676EFI_STATUS\r
1677EFIAPI\r
1678ParseHandleDatabaseForChildControllers(\r
1679 IN CONST EFI_HANDLE ControllerHandle,\r
1680 IN UINTN *MatchingHandleCount,\r
1681 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1682 )\r
1683{\r
1684 EFI_STATUS Status;\r
1685 UINTN HandleIndex;\r
1686 UINTN DriverBindingHandleCount;\r
1687 EFI_HANDLE *DriverBindingHandleBuffer;\r
1688 UINTN DriverBindingHandleIndex;\r
1689 UINTN ChildControllerHandleCount;\r
1690 EFI_HANDLE *ChildControllerHandleBuffer;\r
1691 UINTN ChildControllerHandleIndex;\r
1692 EFI_HANDLE *HandleBufferForReturn;\r
1693\r
1694 if (MatchingHandleCount == NULL) {\r
1695 return (EFI_INVALID_PARAMETER);\r
1696 }\r
1697 *MatchingHandleCount = 0;\r
1698\r
1699 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (\r
1700 ControllerHandle,\r
1701 &DriverBindingHandleCount,\r
1702 &DriverBindingHandleBuffer\r
1703 );\r
1704 if (EFI_ERROR (Status)) {\r
1705 return Status;\r
1706 }\r
1707\r
1708 //\r
1709 // Get a buffer big enough for all the controllers.\r
1710 //\r
1711 HandleBufferForReturn = GetHandleListByProtocol(NULL);\r
1712 if (HandleBufferForReturn == NULL) {\r
1713 FreePool (DriverBindingHandleBuffer);\r
1714 return (EFI_NOT_FOUND);\r
1715 }\r
1716\r
1717 for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {\r
1718 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
1719 DriverBindingHandleBuffer[DriverBindingHandleIndex],\r
1720 ControllerHandle,\r
1721 &ChildControllerHandleCount,\r
1722 &ChildControllerHandleBuffer\r
1723 );\r
1724 if (EFI_ERROR (Status)) {\r
1725 continue;\r
1726 }\r
1727\r
1728 for (ChildControllerHandleIndex = 0;\r
1729 ChildControllerHandleIndex < ChildControllerHandleCount;\r
1730 ChildControllerHandleIndex++\r
1731 ) {\r
1732 for (HandleIndex = 0; HandleIndex < *MatchingHandleCount; HandleIndex++) {\r
1733 if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {\r
1734 break;\r
1735 }\r
1736 }\r
1737 if (HandleIndex >= *MatchingHandleCount) {\r
1738 HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];\r
1739 }\r
1740 }\r
1741\r
1742 FreePool (ChildControllerHandleBuffer);\r
1743 }\r
1744\r
1745 FreePool (DriverBindingHandleBuffer);\r
1746\r
1747 if (MatchingHandleBuffer != NULL) {\r
1748 *MatchingHandleBuffer = HandleBufferForReturn;\r
1749 } else {\r
1750 FreePool(HandleBufferForReturn);\r
1751 }\r
1752\r
1753 return (EFI_SUCCESS);\r
1754}\r
1755\r
1756/**\r
1757 Appends 1 buffer to another buffer. This will re-allocate the destination buffer\r
1758 if necessary to fit all of the data.\r
1759\r
1760 If DestinationBuffer is NULL, then ASSERT().\r
1761\r
1762 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.\r
1763 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.\r
1764 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.\r
1765 @param[in] SourceSize The number of bytes of SourceBuffer to append.\r
1766\r
1767 @retval NULL A memory allocation failed.\r
1768 @retval NULL A parameter was invalid.\r
1769 @return A pointer to (*DestinationBuffer).\r
1770**/\r
1771VOID*\r
1772EFIAPI\r
1773BuffernCatGrow (\r
1774 IN OUT VOID **DestinationBuffer,\r
1775 IN OUT UINTN *DestinationSize,\r
1776 IN VOID *SourceBuffer,\r
1777 IN UINTN SourceSize\r
1778 )\r
1779{\r
1780 UINTN LocalDestinationSize;\r
1781 UINTN LocalDestinationFinalSize;\r
1782\r
1783 ASSERT(DestinationBuffer != NULL);\r
1784\r
1785 if (SourceSize == 0 || SourceBuffer == NULL) {\r
1786 return (*DestinationBuffer);\r
1787 }\r
1788\r
1789 if (DestinationSize == NULL) {\r
1790 LocalDestinationSize = 0;\r
1791 } else {\r
1792 LocalDestinationSize = *DestinationSize;\r
1793 }\r
1794\r
1795 LocalDestinationFinalSize = LocalDestinationSize + SourceSize;\r
1796\r
1797 if (DestinationSize != NULL) {\r
1798 *DestinationSize = LocalDestinationSize;\r
1799 }\r
1800\r
1801 if (LocalDestinationSize == 0) {\r
1802 // allcoate\r
1803 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);\r
1804 } else {\r
1805 // reallocate\r
1806 *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);\r
1807 }\r
1808\r
1809 ASSERT(*DestinationBuffer != NULL);\r
1810\r
1811 // copy\r
1812 return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));\r
1813}\r
1814\r
1815/**\r
1816 Gets handles for any child devices produced by the passed in driver.\r
1817\r
1818 @param[in] DriverHandle The handle of the driver.\r
1819 @param[in] MatchingHandleCount Pointer to the number of handles in\r
1820 MatchingHandleBuffer on return.\r
1821 @param[out] MatchingHandleBuffer Buffer containing handles on a successful\r
1822 return.\r
1823 @retval EFI_SUCCESS The operation was sucessful.\r
1824 @sa ParseHandleDatabaseByRelationship\r
1825**/\r
1826EFI_STATUS\r
1827EFIAPI\r
1828ParseHandleDatabaseForChildDevices(\r
1829 IN CONST EFI_HANDLE DriverHandle,\r
1830 IN UINTN *MatchingHandleCount,\r
1831 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1832 )\r
1833{\r
1834 EFI_HANDLE *Buffer;\r
1835 EFI_HANDLE *Buffer2;\r
1836 UINTN Count1;\r
1837 UINTN Count2;\r
1838 UINTN HandleIndex;\r
1839 EFI_STATUS Status;\r
1840 UINTN HandleBufferSize;\r
1841\r
1842 ASSERT(MatchingHandleCount != NULL);\r
1843\r
1844 HandleBufferSize = 0;\r
1845 Buffer = NULL;\r
1846 Buffer2 = NULL;\r
1847 *MatchingHandleCount = 0;\r
1848\r
1849 Status = PARSE_HANDLE_DATABASE_DEVICES (\r
1850 DriverHandle,\r
1851 &Count1,\r
1852 &Buffer\r
1853 );\r
1854 if (!EFI_ERROR (Status)) {\r
1855 for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {\r
1856 //\r
1857 // now find the children\r
1858 //\r
1859 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
1860 DriverHandle,\r
1861 Buffer[HandleIndex],\r
1862 &Count2,\r
1863 &Buffer2\r
1864 );\r
1865 if (EFI_ERROR(Status)) {\r
1866 break;\r
1867 }\r
1868 //\r
1869 // save out required and optional data elements\r
1870 //\r
1871 *MatchingHandleCount += Count2;\r
1872 if (MatchingHandleBuffer != NULL) {\r
1873 *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));\r
1874 }\r
1875\r
1876 //\r
1877 // free the memory\r
1878 //\r
1879 if (Buffer2 != NULL) {\r
1880 FreePool(Buffer2);\r
1881 }\r
1882 }\r
1883 }\r
1884\r
1885 if (Buffer != NULL) {\r
1886 FreePool(Buffer);\r
1887 }\r
1888 return (Status);\r
1889}\r
1890\r
1891/**\r
1892 Function to get all handles that support a given protocol or all handles.\r
1893\r
1894 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL\r
1895 then the function will return all handles.\r
1896\r
1897 @retval NULL A memory allocation failed.\r
1898 @return A NULL terminated list of handles.\r
1899**/\r
1900EFI_HANDLE*\r
1901EFIAPI\r
1902GetHandleListByProtocol (\r
1903 IN CONST EFI_GUID *ProtocolGuid OPTIONAL\r
1904 )\r
1905{\r
1906 EFI_HANDLE *HandleList;\r
1907 UINTN Size;\r
1908 EFI_STATUS Status;\r
1909\r
1910 Size = 0;\r
1911 HandleList = NULL;\r
1912\r
1913 //\r
1914 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!\r
1915 //\r
1916 if (ProtocolGuid == NULL) {\r
1917 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);\r
1918 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1919 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
1920 if (HandleList == NULL) {\r
1921 return (NULL);\r
1922 }\r
1923 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);\r
1924 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;\r
1925 }\r
1926 } else {\r
1927 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);\r
1928 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1929 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
1930 if (HandleList == NULL) {\r
1931 return (NULL);\r
1932 }\r
1933 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);\r
1934 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;\r
1935 }\r
1936 }\r
1937 if (EFI_ERROR(Status)) {\r
1938 if (HandleList != NULL) {\r
1939 FreePool(HandleList);\r
1940 }\r
1941 return (NULL);\r
1942 }\r
1943 return (HandleList);\r
1944}\r
1945\r
1946/**\r
1947 Function to get all handles that support some protocols.\r
1948\r
1949 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.\r
1950\r
1951 @retval NULL A memory allocation failed.\r
1952 @retval NULL ProtocolGuids was NULL.\r
1953 @return A NULL terminated list of EFI_HANDLEs.\r
1954**/\r
1955EFI_HANDLE*\r
1956EFIAPI\r
1957GetHandleListByProtocolList (\r
1958 IN CONST EFI_GUID **ProtocolGuids\r
1959 )\r
1960{\r
1961 EFI_HANDLE *HandleList;\r
1962 UINTN Size;\r
1963 UINTN TotalSize;\r
1964 UINTN TempSize;\r
1965 EFI_STATUS Status;\r
1966 CONST EFI_GUID **GuidWalker;\r
1967 EFI_HANDLE *HandleWalker1;\r
1968 EFI_HANDLE *HandleWalker2;\r
1969\r
1970 Size = 0;\r
1971 HandleList = NULL;\r
1972 TotalSize = sizeof(EFI_HANDLE);\r
1973\r
1974 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){\r
1975 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);\r
1976 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1977 TotalSize += Size;\r
1978 }\r
1979 }\r
1980\r
1981 //\r
1982 // No handles were found... \r
1983 //\r
1984 if (TotalSize == sizeof(EFI_HANDLE)) {\r
1985 return (NULL);\r
1986 }\r
1987\r
1988 HandleList = AllocateZeroPool(TotalSize);\r
1989 if (HandleList == NULL) {\r
1990 return (NULL);\r
1991 }\r
1992\r
1993 Size = 0;\r
1994 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){\r
1995 TempSize = TotalSize - Size;\r
1996 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));\r
1997\r
1998 //\r
1999 // Allow for missing protocols... Only update the 'used' size upon success.\r
2000 //\r
2001 if (!EFI_ERROR(Status)) {\r
2002 Size += TempSize;\r
2003 }\r
2004 }\r
2005 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);\r
2006\r
2007 for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {\r
2008 for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {\r
2009 if (*HandleWalker1 == *HandleWalker2) {\r
2010 //\r
2011 // copy memory back 1 handle width.\r
2012 //\r
2013 CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));\r
2014 }\r
2015 }\r
2016 }\r
2017\r
2018 return (HandleList);\r
2019}\r
2020\r
2021\r
2022\r
2023\r
2024\r
2025\r
2026\r
2027\r
2028\r
2029\r