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