]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
Update to new SVN URL in readme.txt
[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
352 !EFI_ERROR(Status)?Col:-1,\r
353 !EFI_ERROR(Status)?Row:-1\r
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
417 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
418 Temp = NULL;\r
419\r
420 Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID**)&DevPathToText);\r
421 if (!EFI_ERROR(Status)) {\r
422 Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
423 if (!EFI_ERROR(Status)) {\r
424 //\r
425 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)\r
426 //\r
427 Temp = DevPathToText->ConvertDevicePathToText(DevPath, TRUE, TRUE);\r
428 gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);\r
429 }\r
430 }\r
78ed876b 431 if (!Verbose && Temp != NULL && StrLen(Temp) > 30) {\r
a405b86d 432 Temp2 = NULL;\r
433 Temp2 = StrnCatGrow(&Temp2, NULL, Temp+(StrLen(Temp) - 30), 30);\r
434 FreePool(Temp);\r
435 Temp = Temp2;\r
436 }\r
437 return (Temp);\r
438}\r
439\r
440//\r
441// Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg\r
442//\r
443#define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \\r
444 { \\r
ce68d3bc 445 0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
a405b86d 446 }\r
447\r
448#define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \\r
449 { \\r
ce68d3bc 450 0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
a405b86d 451 }\r
452\r
453#define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \\r
454 { \\r
ce68d3bc 455 0xc95a93d, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
a405b86d 456 }\r
457STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID;\r
458STATIC CONST EFI_GUID WinNtIoProtocolGuid = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;\r
459STATIC CONST EFI_GUID WinNtSerialPortGuid = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;\r
460\r
dee34318 461STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {\r
a405b86d 462 {STRING_TOKEN(STR_WINNT_THUNK), (EFI_GUID*)&WinNtThunkProtocolGuid, NULL},\r
463 {STRING_TOKEN(STR_WINNT_DRIVER_IO), (EFI_GUID*)&WinNtIoProtocolGuid, NULL},\r
464 {STRING_TOKEN(STR_WINNT_SERIAL_PORT), (EFI_GUID*)&WinNtSerialPortGuid, NULL},\r
465 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},\r
466};\r
467\r
dee34318 468STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {\r
a405b86d 469 {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, NULL},\r
470 {STRING_TOKEN(STR_DEVICE_PATH), &gEfiDevicePathProtocolGuid, DevicePathProtocolDumpInformation},\r
471 {STRING_TOKEN(STR_IMAGE_PATH), &gEfiLoadedImageDevicePathProtocolGuid, DevicePathProtocolDumpInformation},\r
472 {STRING_TOKEN(STR_DEVICE_PATH_UTIL), &gEfiDevicePathUtilitiesProtocolGuid, NULL},\r
473 {STRING_TOKEN(STR_DEVICE_PATH_TXT), &gEfiDevicePathToTextProtocolGuid, NULL},\r
474 {STRING_TOKEN(STR_DEVICE_PATH_FTXT), &gEfiDevicePathFromTextProtocolGuid, NULL},\r
475 {STRING_TOKEN(STR_DEVICE_PATH_PC), &gEfiPcAnsiGuid, NULL},\r
476 {STRING_TOKEN(STR_DEVICE_PATH_VT100), &gEfiVT100Guid, NULL},\r
477 {STRING_TOKEN(STR_DEVICE_PATH_VT100P), &gEfiVT100PlusGuid, NULL},\r
478 {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8), &gEfiVTUTF8Guid, NULL},\r
479 {STRING_TOKEN(STR_DRIVER_BINDING), &gEfiDriverBindingProtocolGuid, NULL},\r
480 {STRING_TOKEN(STR_PLATFORM_OVERRIDE), &gEfiPlatformDriverOverrideProtocolGuid, NULL},\r
481 {STRING_TOKEN(STR_BUS_OVERRIDE), &gEfiBusSpecificDriverOverrideProtocolGuid, NULL},\r
482 {STRING_TOKEN(STR_DRIVER_DIAG), &gEfiDriverDiagnosticsProtocolGuid, NULL},\r
483 {STRING_TOKEN(STR_DRIVER_DIAG2), &gEfiDriverDiagnostics2ProtocolGuid, NULL},\r
484 {STRING_TOKEN(STR_DRIVER_CN), &gEfiComponentNameProtocolGuid, NULL},\r
485 {STRING_TOKEN(STR_DRIVER_CN2), &gEfiComponentName2ProtocolGuid, NULL},\r
486 {STRING_TOKEN(STR_PLAT_DRV_CFG), &gEfiPlatformToDriverConfigurationProtocolGuid, NULL},\r
487 {STRING_TOKEN(STR_DRIVER_VERSION), &gEfiDriverSupportedEfiVersionProtocolGuid, DriverEfiVersionProtocolDumpInformation},\r
488 {STRING_TOKEN(STR_TXT_IN), &gEfiSimpleTextInProtocolGuid, NULL},\r
489 {STRING_TOKEN(STR_TXT_IN_EX), &gEfiSimpleTextInputExProtocolGuid, NULL},\r
490 {STRING_TOKEN(STR_TXT_OUT), &gEfiSimpleTextOutProtocolGuid, TxtOutProtocolDumpInformation},\r
491 {STRING_TOKEN(STR_SIM_POINTER), &gEfiSimplePointerProtocolGuid, NULL},\r
492 {STRING_TOKEN(STR_ABS_POINTER), &gEfiAbsolutePointerProtocolGuid, NULL},\r
493 {STRING_TOKEN(STR_SERIAL_IO), &gEfiSerialIoProtocolGuid, NULL},\r
494 {STRING_TOKEN(STR_GRAPHICS_OUTPUT), &gEfiGraphicsOutputProtocolGuid, NULL},\r
495 {STRING_TOKEN(STR_EDID_DISCOVERED), &gEfiEdidDiscoveredProtocolGuid, NULL},\r
496 {STRING_TOKEN(STR_EDID_ACTIVE), &gEfiEdidActiveProtocolGuid, NULL},\r
497 {STRING_TOKEN(STR_EDID_OVERRIDE), &gEfiEdidOverrideProtocolGuid, NULL},\r
498 {STRING_TOKEN(STR_CON_IN), &gEfiConsoleInDeviceGuid, NULL},\r
499 {STRING_TOKEN(STR_CON_OUT), &gEfiConsoleOutDeviceGuid, NULL},\r
500 {STRING_TOKEN(STR_STD_ERR), &gEfiStandardErrorDeviceGuid, NULL},\r
501 {STRING_TOKEN(STR_LOAD_FILE), &gEfiLoadFileProtocolGuid, NULL},\r
502 {STRING_TOKEN(STR_LOAD_FILE2), &gEfiLoadFile2ProtocolGuid, NULL},\r
503 {STRING_TOKEN(STR_SIMPLE_FILE_SYS), &gEfiSimpleFileSystemProtocolGuid, NULL},\r
a405b86d 504 {STRING_TOKEN(STR_TAPE_IO), &gEfiTapeIoProtocolGuid, NULL},\r
505 {STRING_TOKEN(STR_DISK_IO), &gEfiDiskIoProtocolGuid, NULL},\r
506 {STRING_TOKEN(STR_BLK_IO), &gEfiBlockIoProtocolGuid, NULL},\r
507 {STRING_TOKEN(STR_UC), &gEfiUnicodeCollationProtocolGuid, NULL},\r
508 {STRING_TOKEN(STR_UC2), &gEfiUnicodeCollation2ProtocolGuid, NULL},\r
f4f3c6bf 509 {STRING_TOKEN(STR_PCIRB_IO), &gEfiPciRootBridgeIoProtocolGuid, PciRootBridgeIoDumpInformation},\r
a405b86d 510 {STRING_TOKEN(STR_PCI_IO), &gEfiPciIoProtocolGuid, NULL},\r
511 {STRING_TOKEN(STR_SCSI_PT), &gEfiScsiPassThruProtocolGuid, NULL},\r
512 {STRING_TOKEN(STR_SCSI_IO), &gEfiScsiIoProtocolGuid, NULL},\r
513 {STRING_TOKEN(STR_SCSI_PT_EXT), &gEfiExtScsiPassThruProtocolGuid, NULL},\r
514 {STRING_TOKEN(STR_ISCSI), &gEfiIScsiInitiatorNameProtocolGuid, NULL},\r
515 {STRING_TOKEN(STR_USB_IO), &gEfiUsbIoProtocolGuid, NULL},\r
516 {STRING_TOKEN(STR_USB_HC), &gEfiUsbHcProtocolGuid, NULL},\r
517 {STRING_TOKEN(STR_USB_HC2), &gEfiUsb2HcProtocolGuid, NULL},\r
518 {STRING_TOKEN(STR_DEBUG_SUPPORT), &gEfiDebugSupportProtocolGuid, NULL},\r
519 {STRING_TOKEN(STR_DEBUG_PORT), &gEfiDebugPortProtocolGuid, NULL},\r
520 {STRING_TOKEN(STR_DECOMPRESS), &gEfiDecompressProtocolGuid, NULL},\r
521 {STRING_TOKEN(STR_ACPI_TABLE), &gEfiAcpiTableProtocolGuid, NULL},\r
522 {STRING_TOKEN(STR_EBC_INTERPRETER), &gEfiEbcProtocolGuid, NULL},\r
523 {STRING_TOKEN(STR_SNP), &gEfiSimpleNetworkProtocolGuid, NULL},\r
524 {STRING_TOKEN(STR_NII), &gEfiNetworkInterfaceIdentifierProtocolGuid, NULL},\r
525 {STRING_TOKEN(STR_NII_31), &gEfiNetworkInterfaceIdentifierProtocolGuid_31, NULL},\r
526 {STRING_TOKEN(STR_PXE_BC), &gEfiPxeBaseCodeProtocolGuid, NULL},\r
527 {STRING_TOKEN(STR_PXE_CB), &gEfiPxeBaseCodeCallbackProtocolGuid, NULL},\r
528 {STRING_TOKEN(STR_BIS), &gEfiBisProtocolGuid, NULL},\r
529 {STRING_TOKEN(STR_MNP_SB), &gEfiManagedNetworkServiceBindingProtocolGuid, NULL},\r
530 {STRING_TOKEN(STR_MNP), &gEfiManagedNetworkProtocolGuid, NULL},\r
531 {STRING_TOKEN(STR_ARP_SB), &gEfiArpServiceBindingProtocolGuid, NULL},\r
532 {STRING_TOKEN(STR_ARP), &gEfiArpProtocolGuid, NULL},\r
533 {STRING_TOKEN(STR_DHCPV4_SB), &gEfiDhcp4ServiceBindingProtocolGuid, NULL},\r
534 {STRING_TOKEN(STR_DHCPV4), &gEfiDhcp4ProtocolGuid, NULL},\r
535 {STRING_TOKEN(STR_TCPV4_SB), &gEfiTcp4ServiceBindingProtocolGuid, NULL},\r
536 {STRING_TOKEN(STR_TCPV4), &gEfiTcp4ProtocolGuid, NULL},\r
537 {STRING_TOKEN(STR_IPV4_SB), &gEfiIp4ServiceBindingProtocolGuid, NULL},\r
538 {STRING_TOKEN(STR_IPV4), &gEfiIp4ProtocolGuid, NULL},\r
539 {STRING_TOKEN(STR_IPV4_CFG), &gEfiIp4ConfigProtocolGuid, NULL},\r
540 {STRING_TOKEN(STR_SHELL_PARAMETERS), &gEfiShellParametersProtocolGuid, NULL},\r
541 {STRING_TOKEN(STR_SHELL), &gEfiShellProtocolGuid, NULL},\r
a405b86d 542 {STRING_TOKEN(STR_UDPV4_SB), &gEfiUdp4ServiceBindingProtocolGuid, NULL},\r
543 {STRING_TOKEN(STR_UDPV4), &gEfiUdp4ProtocolGuid, NULL},\r
544 {STRING_TOKEN(STR_MTFTPV4_SB), &gEfiMtftp4ServiceBindingProtocolGuid, NULL},\r
545 {STRING_TOKEN(STR_MTFTPV4), &gEfiMtftp4ProtocolGuid, NULL},\r
546 {STRING_TOKEN(STR_AUTH_INFO), &gEfiAuthenticationInfoProtocolGuid, NULL},\r
547 {STRING_TOKEN(STR_HASH_SB), &gEfiHashServiceBindingProtocolGuid, NULL},\r
548 {STRING_TOKEN(STR_HASH), &gEfiHashProtocolGuid, NULL},\r
549 {STRING_TOKEN(STR_HII_FONT), &gEfiHiiFontProtocolGuid, NULL},\r
550 {STRING_TOKEN(STR_HII_STRING), &gEfiHiiStringProtocolGuid, NULL},\r
551 {STRING_TOKEN(STR_HII_IMAGE), &gEfiHiiImageProtocolGuid, NULL},\r
552 {STRING_TOKEN(STR_HII_DATABASE), &gEfiHiiDatabaseProtocolGuid, NULL},\r
553 {STRING_TOKEN(STR_HII_CONFIG_ROUT), &gEfiHiiConfigRoutingProtocolGuid, NULL},\r
554 {STRING_TOKEN(STR_HII_CONFIG_ACC), &gEfiHiiConfigAccessProtocolGuid, NULL},\r
555 {STRING_TOKEN(STR_HII_FORM_BROWSER2), &gEfiFormBrowser2ProtocolGuid, NULL},\r
dee34318 556 {STRING_TOKEN(STR_DRIVER_FAM_OVERRIDE), &gEfiDriverFamilyOverrideProtocolGuid, NULL},\r
557 {STRING_TOKEN(STR_PCD), &gPcdProtocolGuid, NULL},\r
558 {STRING_TOKEN(STR_TCG), &gEfiTcgProtocolGuid, NULL},\r
559 {STRING_TOKEN(STR_HII_PACKAGE_LIST), &gEfiHiiPackageListProtocolGuid, NULL},\r
560\r
561//\r
562// the ones under this are deprecated by the current UEFI Spec, but may be found anyways...\r
563//\r
a405b86d 564 {STRING_TOKEN(STR_SHELL_INTERFACE), &gEfiShellInterfaceGuid, NULL},\r
565 {STRING_TOKEN(STR_SHELL_ENV2), &gEfiShellEnvironment2Guid, NULL},\r
566 {STRING_TOKEN(STR_SHELL_ENV), &gEfiShellEnvironment2Guid, NULL},\r
567 {STRING_TOKEN(STR_DEVICE_IO), &gEfiDeviceIoProtocolGuid, NULL},\r
568 {STRING_TOKEN(STR_UGA_DRAW), &gEfiUgaDrawProtocolGuid, NULL},\r
569 {STRING_TOKEN(STR_UGA_IO), &gEfiUgaIoProtocolGuid, NULL},\r
570 {STRING_TOKEN(STR_ESP), &gEfiPartTypeSystemPartGuid, NULL},\r
571 {STRING_TOKEN(STR_GPT_NBR), &gEfiPartTypeLegacyMbrGuid, NULL},\r
572 {STRING_TOKEN(STR_DRIVER_CONFIG), &gEfiDriverConfigurationProtocolGuid, NULL},\r
573 {STRING_TOKEN(STR_DRIVER_CONFIG2), &gEfiDriverConfiguration2ProtocolGuid, NULL},\r
dee34318 574\r
575//\r
576// the ones under this are GUID identified structs, not protocols\r
577//\r
578 {STRING_TOKEN(STR_FILE_INFO), &gEfiFileInfoGuid, NULL},\r
579 {STRING_TOKEN(STR_FILE_SYS_INFO), &gEfiFileSystemInfoGuid, NULL},\r
580\r
581//\r
582// the ones under this are misc GUIDS.\r
583//\r
584 {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE), &gEfiGlobalVariableGuid, NULL},\r
585\r
586//\r
587// UEFI 2.2\r
588//\r
589 {STRING_TOKEN(STR_IP6_SB), &gEfiIp6ServiceBindingProtocolGuid, NULL},\r
590 {STRING_TOKEN(STR_IP6), &gEfiIp6ProtocolGuid, NULL},\r
591 {STRING_TOKEN(STR_IP6_CONFIG), &gEfiIp6ConfigProtocolGuid, NULL},\r
592 {STRING_TOKEN(STR_MTFTP6_SB), &gEfiMtftp6ServiceBindingProtocolGuid, NULL},\r
593 {STRING_TOKEN(STR_MTFTP6), &gEfiMtftp6ProtocolGuid, NULL},\r
594 {STRING_TOKEN(STR_DHCP6_SB), &gEfiDhcp6ServiceBindingProtocolGuid, NULL},\r
595 {STRING_TOKEN(STR_DHCP6), &gEfiDhcp6ProtocolGuid, NULL},\r
596 {STRING_TOKEN(STR_UDP6_SB), &gEfiUdp6ServiceBindingProtocolGuid, NULL},\r
597 {STRING_TOKEN(STR_UDP6), &gEfiUdp6ProtocolGuid, NULL},\r
598 {STRING_TOKEN(STR_TCP6_SB), &gEfiTcp6ServiceBindingProtocolGuid, NULL},\r
599 {STRING_TOKEN(STR_TCP6), &gEfiTcp6ProtocolGuid, NULL},\r
600 {STRING_TOKEN(STR_VLAN_CONFIG), &gEfiVlanConfigProtocolGuid, NULL},\r
601 {STRING_TOKEN(STR_EAP), &gEfiEapProtocolGuid, NULL},\r
602 {STRING_TOKEN(STR_EAP_MGMT), &gEfiEapManagementProtocolGuid, NULL},\r
603 {STRING_TOKEN(STR_FTP4_SB), &gEfiFtp4ServiceBindingProtocolGuid, NULL},\r
604 {STRING_TOKEN(STR_FTP4), &gEfiFtp4ProtocolGuid, NULL},\r
605 {STRING_TOKEN(STR_IP_SEC_CONFIG), &gEfiIpSecConfigProtocolGuid, NULL},\r
606 {STRING_TOKEN(STR_DH), &gEfiDriverHealthProtocolGuid, NULL},\r
607 {STRING_TOKEN(STR_DEF_IMG_LOAD), &gEfiDeferredImageLoadProtocolGuid, NULL},\r
608 {STRING_TOKEN(STR_USER_CRED), &gEfiUserCredentialProtocolGuid, NULL},\r
609 {STRING_TOKEN(STR_USER_MNGR), &gEfiUserManagerProtocolGuid, NULL},\r
610 {STRING_TOKEN(STR_ATA_PASS_THRU), &gEfiAtaPassThruProtocolGuid, NULL},\r
611\r
612//\r
613// UEFI 2.3\r
614//\r
615 {STRING_TOKEN(STR_FW_MGMT), &gEfiFirmwareManagementProtocolGuid, NULL},\r
616 {STRING_TOKEN(STR_IP_SEC), &gEfiIpSecProtocolGuid, NULL},\r
617 {STRING_TOKEN(STR_IP_SEC2), &gEfiIpSec2ProtocolGuid, NULL},\r
618\r
619//\r
620// UEFI 2.3.1\r
621//\r
622 {STRING_TOKEN(STR_KMS), &gEfiKmsProtocolGuid, NULL},\r
623 {STRING_TOKEN(STR_BLK_IO2), &gEfiBlockIo2ProtocolGuid, NULL},\r
624 {STRING_TOKEN(STR_SSC), &gEfiStorageSecurityCommandProtocolGuid, NULL},\r
625 {STRING_TOKEN(STR_UC2), &gEfiUserCredential2ProtocolGuid, NULL},\r
626\r
627//\r
628// terminator\r
629//\r
a405b86d 630 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},\r
631};\r
632\r
633/**\r
634 Function to get the node for a protocol or struct from it's GUID.\r
635\r
636 if Guid is NULL, then ASSERT.\r
637\r
638 @param[in] Guid The GUID to look for the name of.\r
639\r
640 @return The node.\r
641**/\r
dee34318 642CONST GUID_INFO_BLOCK *\r
a405b86d 643EFIAPI\r
644InternalShellGetNodeFromGuid(\r
645 IN CONST EFI_GUID* Guid\r
646 )\r
647{\r
dee34318 648 CONST GUID_INFO_BLOCK *ListWalker;\r
a405b86d 649\r
650 ASSERT(Guid != NULL);\r
651\r
652 if (PcdGetBool(PcdShellIncludeNtGuids)) {\r
653 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
654 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
655 return (ListWalker);\r
656 }\r
657 }\r
658 }\r
659 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
660 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
661 return (ListWalker);\r
662 }\r
663 }\r
664 return (ListWalker);\r
665}\r
666\r
667/**\r
668 Function to get the name of a protocol or struct from it's GUID.\r
669\r
670 if Guid is NULL, then ASSERT.\r
671\r
672 @param[in] Guid The GUID to look for the name of.\r
673 @param[in] Lang The language to use.\r
674\r
675 @return pointer to string of the name. The caller\r
676 is responsible to free this memory.\r
677**/\r
678CHAR16*\r
679EFIAPI\r
680GetStringNameFromGuid(\r
681 IN CONST EFI_GUID *Guid,\r
682 IN CONST CHAR8 *Lang OPTIONAL\r
683 )\r
684{\r
dee34318 685 CONST GUID_INFO_BLOCK *Id;\r
a405b86d 686\r
687 Id = InternalShellGetNodeFromGuid(Guid);\r
688 return (HiiGetString(mHandleParsingHiiHandle, Id->StringId, Lang));\r
689}\r
690\r
691/**\r
692 Function to dump protocol information from a handle.\r
693\r
694 This function will return a allocated string buffer containing the\r
695 information. The caller is responsible for freeing the memory.\r
696\r
697 If Guid is NULL, ASSERT().\r
698 If TheHandle is NULL, ASSERT().\r
699\r
700 @param[in] TheHandle The handle to dump information from.\r
701 @param[in] Guid The GUID of the protocol to dump.\r
702 @param[in] Verbose TRUE for extra info. FALSE otherwise.\r
703\r
704 @return The pointer to string.\r
705 @retval NULL An error was encountered.\r
706**/\r
707CHAR16*\r
708EFIAPI\r
709GetProtocolInformationDump(\r
710 IN CONST EFI_HANDLE TheHandle,\r
711 IN CONST EFI_GUID *Guid,\r
712 IN CONST BOOLEAN Verbose\r
713 )\r
714{\r
dee34318 715 CONST GUID_INFO_BLOCK *Id;\r
a405b86d 716\r
717 ASSERT(TheHandle != NULL);\r
718 ASSERT(Guid != NULL);\r
719\r
720 if (TheHandle == NULL || Guid == NULL) {\r
721 return (NULL);\r
722 }\r
723\r
724 Id = InternalShellGetNodeFromGuid(Guid);\r
725 if (Id != NULL && Id->DumpInfo != NULL) {\r
726 return (Id->DumpInfo(TheHandle, Verbose));\r
727 }\r
728 return (NULL);\r
729}\r
730\r
731/**\r
732 Function to get the Guid for a protocol or struct based on it's string name.\r
733\r
734 @param[in] Name The pointer to the string name.\r
735 @param[in] Lang The pointer to the language code.\r
736 @param[in] Guid The pointer to the Guid.\r
737\r
738 @retval EFI_SUCCESS The operation was sucessful.\r
739**/\r
740EFI_STATUS\r
741EFIAPI\r
742GetGuidFromStringName(\r
743 IN CONST CHAR16 *Name,\r
744 IN CONST CHAR8 *Lang OPTIONAL,\r
745 IN EFI_GUID **Guid\r
746 )\r
747{\r
dee34318 748 CONST GUID_INFO_BLOCK *ListWalker;\r
a405b86d 749 CHAR16 *String;\r
750\r
751 ASSERT(Guid != NULL);\r
752 if (Guid == NULL) {\r
753 return (EFI_INVALID_PARAMETER);\r
754 }\r
755 *Guid = NULL;\r
756\r
757 if (PcdGetBool(PcdShellIncludeNtGuids)) {\r
758 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
759 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
760 if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {\r
761 *Guid = ListWalker->GuidId;\r
762 }\r
763 SHELL_FREE_NON_NULL(String);\r
764 if (*Guid != NULL) {\r
765 return (EFI_SUCCESS);\r
766 }\r
767 }\r
768 }\r
769 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
770 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
771 if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {\r
772 *Guid = ListWalker->GuidId;\r
773 }\r
774 SHELL_FREE_NON_NULL(String);\r
775 if (*Guid != NULL) {\r
776 return (EFI_SUCCESS);\r
777 }\r
778 }\r
779 return (EFI_NOT_FOUND);\r
780}\r
781\r
36384ceb
ED
782/**\r
783 Get best support language for this driver.\r
784 \r
785 First base on the current platform used language to search,Second base on the \r
786 default language to search. The caller need to free the buffer of the best \r
787 language.\r
788\r
789 @param[in] SupportedLanguages The support languages for this driver.\r
790 @param[in] Iso639Language Whether get language for ISO639.\r
791\r
792 @return The best support language for this driver.\r
793**/\r
794CHAR8 *\r
795GetBestLanguageForDriver (\r
796 IN CONST CHAR8 *SupportedLanguages, \r
797 IN BOOLEAN Iso639Language\r
798 )\r
799{\r
800 CHAR8 *LanguageVariable;\r
801 CHAR8 *BestLanguage;\r
802\r
803 LanguageVariable = GetVariable (Iso639Language ? L"Lang" : L"PlatformLang", &gEfiGlobalVariableGuid);\r
804\r
805 BestLanguage = GetBestLanguage(\r
806 SupportedLanguages,\r
807 Iso639Language,\r
808 (LanguageVariable != NULL) ? LanguageVariable : "",\r
809 Iso639Language ? "en" : "en-US",\r
810 NULL\r
811 );\r
812\r
813 if (LanguageVariable != NULL) {\r
814 FreePool (LanguageVariable);\r
815 }\r
816\r
817 return BestLanguage;\r
818}\r
819\r
a405b86d 820/**\r
821 Function to retrieve the driver name (if possible) from the ComponentName or\r
822 ComponentName2 protocol\r
823\r
824 @param[in] TheHandle The driver handle to get the name of.\r
825 @param[in] Language The language to use.\r
826\r
827 @retval NULL The name could not be found.\r
828 @return A pointer to the string name. Do not de-allocate the memory.\r
829**/\r
830CONST CHAR16*\r
831EFIAPI\r
832GetStringNameFromHandle(\r
833 IN CONST EFI_HANDLE TheHandle,\r
834 IN CONST CHAR8 *Language\r
835 )\r
836{\r
837 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;\r
838 EFI_STATUS Status;\r
839 CHAR16 *RetVal;\r
36384ceb
ED
840 CHAR8 *BestLang;\r
841\r
842 BestLang = NULL;\r
a405b86d 843\r
844 Status = gBS->OpenProtocol(\r
845 TheHandle,\r
846 &gEfiComponentName2ProtocolGuid,\r
847 (VOID**)&CompNameStruct,\r
848 gImageHandle,\r
849 NULL,\r
850 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
851 if (!EFI_ERROR(Status)) {\r
36384ceb
ED
852 if (Language == NULL) {\r
853 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, FALSE);\r
854 Language = BestLang;\r
855 }\r
a405b86d 856 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);\r
36384ceb
ED
857\r
858 if (BestLang != NULL) {\r
859 FreePool (BestLang);\r
860 BestLang = NULL;\r
861 }\r
a405b86d 862 if (!EFI_ERROR(Status)) {\r
863 return (RetVal);\r
864 }\r
865 }\r
866 Status = gBS->OpenProtocol(\r
867 TheHandle,\r
868 &gEfiComponentNameProtocolGuid,\r
869 (VOID**)&CompNameStruct,\r
870 gImageHandle,\r
871 NULL,\r
872 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
873 if (!EFI_ERROR(Status)) {\r
36384ceb
ED
874 if (Language == NULL) {\r
875 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, FALSE);\r
876 Language = BestLang;\r
877 }\r
a405b86d 878 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);\r
36384ceb
ED
879 \r
880 if (BestLang != NULL) {\r
881 FreePool (BestLang);\r
882 }\r
a405b86d 883 if (!EFI_ERROR(Status)) {\r
884 return (RetVal);\r
885 }\r
886 }\r
887 return (NULL);\r
888}\r
889\r
890/**\r
891 Function to initialize the file global mHandleList object for use in\r
892 vonverting handles to index and index to handle.\r
893\r
894 @retval EFI_SUCCESS The operation was successful.\r
895**/\r
896EFI_STATUS\r
897EFIAPI\r
898InternalShellInitHandleList(\r
899 VOID\r
900 )\r
901{\r
902 EFI_STATUS Status;\r
903 EFI_HANDLE *HandleBuffer;\r
904 UINTN HandleCount;\r
905 HANDLE_LIST *ListWalker;\r
906\r
907 if (mHandleList.NextIndex != 0) {\r
908 return EFI_SUCCESS;\r
909 }\r
910 InitializeListHead(&mHandleList.List.Link);\r
911 mHandleList.NextIndex = 1;\r
912 Status = gBS->LocateHandleBuffer (\r
913 AllHandles,\r
914 NULL,\r
915 NULL,\r
916 &HandleCount,\r
917 &HandleBuffer\r
918 );\r
919 ASSERT_EFI_ERROR(Status);\r
920 if (EFI_ERROR(Status)) {\r
921 return (Status);\r
922 }\r
923 for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){\r
78ed876b 924 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
a405b86d 925 ASSERT(ListWalker != NULL);\r
926 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex-1];\r
927 ListWalker->TheIndex = mHandleList.NextIndex;\r
928 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);\r
929 }\r
930 FreePool(HandleBuffer);\r
931 return (EFI_SUCCESS);\r
932}\r
933\r
934/**\r
935 Function to retrieve the human-friendly index of a given handle. If the handle\r
936 does not have a index one will be automatically assigned. The index value is valid\r
937 until the termination of the shell application.\r
938\r
939 @param[in] TheHandle The handle to retrieve an index for.\r
940\r
941 @retval 0 A memory allocation failed.\r
942 @return The index of the handle.\r
943\r
944**/\r
945UINTN\r
946EFIAPI\r
947ConvertHandleToHandleIndex(\r
948 IN CONST EFI_HANDLE TheHandle\r
949 )\r
950{\r
f330ff35 951 EFI_STATUS Status;\r
952 EFI_GUID **ProtocolBuffer;\r
953 UINTN ProtocolCount;\r
954 HANDLE_LIST *ListWalker;\r
955\r
78ed876b 956 if (TheHandle == NULL) {\r
957 return 0;\r
958 }\r
a405b86d 959\r
960 InternalShellInitHandleList();\r
961\r
962 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)\r
963 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)\r
964 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)\r
965 ){\r
966 if (ListWalker->TheHandle == TheHandle) {\r
f330ff35 967 //\r
968 // Verify that TheHandle is still present in the Handle Database\r
969 //\r
970 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);\r
971 if (EFI_ERROR (Status)) {\r
972 //\r
973 // TheHandle is not present in the Handle Database, so delete from the handle list\r
974 //\r
975 RemoveEntryList (&ListWalker->Link);\r
976 return 0;\r
977 }\r
978 FreePool (ProtocolBuffer);\r
a405b86d 979 return (ListWalker->TheIndex);\r
980 }\r
981 }\r
f330ff35 982\r
983 //\r
984 // Verify that TheHandle is valid handle\r
985 //\r
986 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);\r
987 if (EFI_ERROR (Status)) {\r
988 //\r
989 // TheHandle is not valid, so do not add to handle list\r
990 //\r
991 return 0;\r
992 }\r
993 FreePool (ProtocolBuffer);\r
994\r
78ed876b 995 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
a405b86d 996 ASSERT(ListWalker != NULL);\r
997 ListWalker->TheHandle = TheHandle;\r
998 ListWalker->TheIndex = mHandleList.NextIndex++;\r
999 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);\r
1000 return (ListWalker->TheIndex);\r
1001}\r
1002\r
1003\r
1004\r
1005/**\r
1006 Function to retrieve the EFI_HANDLE from the human-friendly index.\r
1007\r
1008 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.\r
1009\r
1010 @retval NULL The index was invalid.\r
1011 @return The EFI_HANDLE that index represents.\r
1012\r
1013**/\r
1014EFI_HANDLE\r
1015EFIAPI\r
1016ConvertHandleIndexToHandle(\r
1017 IN CONST UINTN TheIndex\r
1018 )\r
1019{\r
f330ff35 1020 EFI_STATUS Status;\r
1021 EFI_GUID **ProtocolBuffer;\r
1022 UINTN ProtocolCount;\r
a405b86d 1023 HANDLE_LIST *ListWalker;\r
1024\r
1025 InternalShellInitHandleList();\r
1026\r
1027 if (TheIndex >= mHandleList.NextIndex) {\r
f330ff35 1028 return NULL;\r
a405b86d 1029 }\r
1030\r
1031 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)\r
1032 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)\r
1033 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)\r
1034 ){\r
f330ff35 1035 if (ListWalker->TheIndex == TheIndex && ListWalker->TheHandle != NULL) {\r
1036 //\r
1037 // Verify that LinkWalker->TheHandle is valid handle\r
1038 //\r
1039 Status = gBS->ProtocolsPerHandle(ListWalker->TheHandle, &ProtocolBuffer, &ProtocolCount);\r
1040 if (EFI_ERROR (Status)) {\r
1041 //\r
1042 // TheHandle is not valid, so do not add to handle list\r
1043 //\r
1044 ListWalker->TheHandle = NULL;\r
1045 }\r
a405b86d 1046 return (ListWalker->TheHandle);\r
1047 }\r
1048 }\r
f330ff35 1049 return NULL;\r
a405b86d 1050}\r
1051\r
1052/**\r
1053 Gets all the related EFI_HANDLEs based on the mask supplied.\r
1054\r
1055 This function scans all EFI_HANDLES in the UEFI environment's handle database\r
1056 and returns the ones with the specified relationship (Mask) to the specified\r
1057 controller handle.\r
1058\r
1059 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.\r
1060 If MatchingHandleCount is NULL, then ASSERT.\r
1061\r
1062 If MatchingHandleBuffer is not NULL upon a successful return the memory must be\r
1063 caller freed.\r
1064\r
1065 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.\r
1066 @param[in] ControllerHandle The handle with Device Path protocol on it.\r
1067 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in\r
1068 MatchingHandleBuffer.\r
1069 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount\r
1070 EFI_HANDLEs with a terminating NULL EFI_HANDLE.\r
1071 @param[out] HandleType An array of type information.\r
1072\r
1073 @retval EFI_SUCCESS The operation was successful, and any related handles\r
1074 are in MatchingHandleBuffer.\r
1075 @retval EFI_NOT_FOUND No matching handles were found.\r
1076 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.\r
1077**/\r
1078EFI_STATUS\r
1079EFIAPI\r
1080ParseHandleDatabaseByRelationshipWithType (\r
1081 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,\r
1082 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
1083 IN UINTN *HandleCount,\r
1084 OUT EFI_HANDLE **HandleBuffer,\r
1085 OUT UINTN **HandleType\r
1086 )\r
1087{\r
1088 EFI_STATUS Status;\r
1089 UINTN HandleIndex;\r
1090 EFI_GUID **ProtocolGuidArray;\r
1091 UINTN ArrayCount;\r
1092 UINTN ProtocolIndex;\r
1093 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
1094 UINTN OpenInfoCount;\r
1095 UINTN OpenInfoIndex;\r
1096 UINTN ChildIndex;\r
f330ff35 1097 INTN DriverBindingHandleIndex;\r
a405b86d 1098\r
1099 ASSERT(HandleCount != NULL);\r
1100 ASSERT(HandleBuffer != NULL);\r
1101 ASSERT(HandleType != NULL);\r
1102 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);\r
1103\r
1104 *HandleCount = 0;\r
1105 *HandleBuffer = NULL;\r
1106 *HandleType = NULL;\r
1107\r
1108 //\r
1109 // Retrieve the list of all handles from the handle database\r
1110 //\r
1111 Status = gBS->LocateHandleBuffer (\r
1112 AllHandles,\r
1113 NULL,\r
1114 NULL,\r
1115 HandleCount,\r
1116 HandleBuffer\r
1117 );\r
1118 if (EFI_ERROR (Status)) {\r
1119 return (Status);\r
1120 }\r
1121\r
1122 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));\r
1123 ASSERT(*HandleType != NULL);\r
1124\r
f330ff35 1125 DriverBindingHandleIndex = -1;\r
1126 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
1127 if (DriverBindingHandle != NULL && (*HandleBuffer)[HandleIndex] == DriverBindingHandle) {\r
1128 DriverBindingHandleIndex = (INTN)HandleIndex;\r
1129 }\r
1130 }\r
1131\r
a405b86d 1132 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
1133 //\r
1134 // Retrieve the list of all the protocols on each handle\r
1135 //\r
1136 Status = gBS->ProtocolsPerHandle (\r
1137 (*HandleBuffer)[HandleIndex],\r
1138 &ProtocolGuidArray,\r
1139 &ArrayCount\r
1140 );\r
f330ff35 1141 if (EFI_ERROR (Status)) {\r
1142 continue;\r
1143 }\r
a405b86d 1144\r
f330ff35 1145 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
a405b86d 1146\r
f330ff35 1147 //\r
1148 // Set the bit describing what this handle has\r
1149 //\r
1150 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) ) {\r
1151 (*HandleType)[HandleIndex] |= HR_IMAGE_HANDLE;\r
1152 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) ) {\r
1153 (*HandleType)[HandleIndex] |= HR_DRIVER_BINDING_HANDLE;\r
1154 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {\r
1155 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;\r
1156 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {\r
1157 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;\r
1158 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid) ) {\r
1159 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;\r
1160 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) ) {\r
1161 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;\r
1162 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid) ) {\r
1163 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;\r
1164 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) {\r
1165 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;\r
1166 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) ) {\r
1167 (*HandleType)[HandleIndex] |= HR_DEVICE_HANDLE;\r
1168 } else {\r
1169 DEBUG_CODE_BEGIN();\r
1170 ASSERT((*HandleType)[HandleIndex] == (*HandleType)[HandleIndex]);\r
1171 DEBUG_CODE_END();\r
1172 }\r
1173 //\r
1174 // Retrieve the list of agents that have opened each protocol\r
1175 //\r
1176 Status = gBS->OpenProtocolInformation (\r
a405b86d 1177 (*HandleBuffer)[HandleIndex],\r
1178 ProtocolGuidArray[ProtocolIndex],\r
1179 &OpenInfo,\r
1180 &OpenInfoCount\r
1181 );\r
f330ff35 1182 if (EFI_ERROR (Status)) {\r
1183 continue;\r
1184 }\r
1185\r
1186 if (ControllerHandle == NULL) {\r
1187 //\r
1188 // ControllerHandle == NULL and DriverBindingHandle != NULL. \r
1189 // Return information on all the controller handles that the driver specified by DriverBindingHandle is managing\r
1190 //\r
1191 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1192 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1193 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1194 if (DriverBindingHandleIndex != -1) {\r
1195 (*HandleType)[DriverBindingHandleIndex] |= HR_DEVICE_DRIVER;\r
1196 }\r
1197 }\r
1198 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1199 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1200 if (DriverBindingHandleIndex != -1) {\r
1201 (*HandleType)[DriverBindingHandleIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1202 }\r
1203 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1204 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1205 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
1206 }\r
1207 }\r
1208 }\r
1209 }\r
1210 }\r
1211 if (DriverBindingHandle == NULL && ControllerHandle != NULL) {\r
1212 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {\r
1213 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
a405b86d 1214 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
f330ff35 1215 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1216 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1217 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1218 (*HandleType)[ChildIndex] |= HR_DEVICE_DRIVER;\r
1219 }\r
a405b86d 1220 }\r
f330ff35 1221 }\r
1222 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1223 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1224 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1225 (*HandleType)[ChildIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1226 }\r
1227 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1228 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
a405b86d 1229 }\r
1230 }\r
1231 }\r
f330ff35 1232 }\r
1233 } else {\r
1234 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1235 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1236 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {\r
1237 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_PARENT_HANDLE);\r
1238 }\r
1239 }\r
1240 }\r
1241 }\r
1242 }\r
1243 if (DriverBindingHandle != NULL && ControllerHandle != NULL) {\r
1244 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {\r
1245 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1246 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1247 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1248 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
1249 if (DriverBindingHandleIndex != -1) {\r
1250 (*HandleType)[DriverBindingHandleIndex] |= HR_DEVICE_DRIVER;\r
a405b86d 1251 }\r
1252 }\r
f330ff35 1253 }\r
1254 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1255 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
a405b86d 1256 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
f330ff35 1257 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1258 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
a405b86d 1259 }\r
1260 }\r
1261 }\r
f330ff35 1262\r
1263 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1264 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1265 (*HandleType)[ChildIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1266 }\r
1267 }\r
1268 }\r
1269 }\r
1270 } else {\r
1271 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1272 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1273 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {\r
1274 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_PARENT_HANDLE);\r
1275 }\r
a405b86d 1276 }\r
1277 }\r
a405b86d 1278 }\r
1279 }\r
f330ff35 1280 FreePool (OpenInfo);\r
a405b86d 1281 }\r
f330ff35 1282 FreePool (ProtocolGuidArray);\r
a405b86d 1283 }\r
f330ff35 1284 return EFI_SUCCESS;\r
a405b86d 1285}\r
1286\r
1287/**\r
1288 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask\r
1289 supplied.\r
1290\r
1291 This function will scan all EFI_HANDLES in the UEFI environment's handle database\r
1292 and return all the ones with the specified relationship (Mask) to the specified\r
1293 controller handle.\r
1294\r
1295 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.\r
1296 If MatchingHandleCount is NULL, then ASSERT.\r
1297\r
1298 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be\r
1299 caller freed.\r
1300\r
1301 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol\r
1302 on it.\r
1303 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.\r
1304 @param[in] Mask Mask of what relationship(s) is desired.\r
1305 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in\r
1306 MatchingHandleBuffer.\r
1307 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount\r
1308 EFI_HANDLEs and a terminating NULL EFI_HANDLE.\r
1309\r
1310 @retval EFI_SUCCESS The operation was sucessful and any related handles\r
1311 are in MatchingHandleBuffer;\r
1312 @retval EFI_NOT_FOUND No matching handles were found.\r
1313 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.\r
1314**/\r
1315EFI_STATUS\r
1316EFIAPI\r
1317ParseHandleDatabaseByRelationship (\r
1318 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,\r
1319 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
1320 IN CONST UINTN Mask,\r
1321 IN UINTN *MatchingHandleCount,\r
1322 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1323 )\r
1324{\r
1325 EFI_STATUS Status;\r
1326 UINTN HandleCount;\r
1327 EFI_HANDLE *HandleBuffer;\r
1328 UINTN *HandleType;\r
1329 UINTN HandleIndex;\r
1330\r
1331 ASSERT(MatchingHandleCount != NULL);\r
1332 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);\r
1333\r
1334 if ((Mask & HR_VALID_MASK) != Mask) {\r
1335 return (EFI_INVALID_PARAMETER);\r
1336 }\r
1337\r
1338 if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {\r
1339 return (EFI_INVALID_PARAMETER);\r
1340 }\r
1341\r
1342 *MatchingHandleCount = 0;\r
1343 if (MatchingHandleBuffer != NULL) {\r
1344 *MatchingHandleBuffer = NULL;\r
1345 }\r
1346\r
1347 HandleBuffer = NULL;\r
1348 HandleType = NULL;\r
1349\r
1350 Status = ParseHandleDatabaseByRelationshipWithType (\r
1351 DriverBindingHandle,\r
1352 ControllerHandle,\r
1353 &HandleCount,\r
1354 &HandleBuffer,\r
1355 &HandleType\r
1356 );\r
1357 if (!EFI_ERROR (Status)) {\r
1358 //\r
1359 // Count the number of handles that match the attributes in Mask\r
1360 //\r
1361 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
1362 if ((HandleType[HandleIndex] & Mask) == Mask) {\r
1363 (*MatchingHandleCount)++;\r
1364 }\r
1365 }\r
1366 //\r
1367 // If no handles match the attributes in Mask then return EFI_NOT_FOUND\r
1368 //\r
1369 if (*MatchingHandleCount == 0) {\r
1370 Status = EFI_NOT_FOUND;\r
1371 } else {\r
1372\r
1373 if (MatchingHandleBuffer == NULL) {\r
1374 //\r
1375 // Someone just wanted the count...\r
1376 //\r
1377 Status = EFI_SUCCESS;\r
1378 } else {\r
1379 //\r
1380 // Allocate a handle buffer for the number of handles that matched the attributes in Mask\r
1381 //\r
78ed876b 1382 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));\r
a405b86d 1383 ASSERT(*MatchingHandleBuffer != NULL);\r
1384\r
1385 for (HandleIndex = 0,*MatchingHandleCount = 0\r
1386 ; HandleIndex < HandleCount\r
1387 ; HandleIndex++\r
1388 ){\r
1389 //\r
1390 // Fill the allocated buffer with the handles that matched the attributes in Mask\r
1391 //\r
1392 if ((HandleType[HandleIndex] & Mask) == Mask) {\r
1393 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];\r
1394 }\r
1395 }\r
1396\r
1397 //\r
1398 // Make the last one NULL\r
1399 //\r
1400 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;\r
1401\r
1402 Status = EFI_SUCCESS;\r
1403 } // MacthingHandleBuffer == NULL (ELSE)\r
1404 } // *MatchingHandleCount == 0 (ELSE)\r
1405 } // no error on ParseHandleDatabaseByRelationshipWithType\r
1406\r
1407 if (HandleBuffer != NULL) {\r
1408 FreePool (HandleBuffer);\r
1409 }\r
1410\r
1411 if (HandleType != NULL) {\r
1412 FreePool (HandleType);\r
1413 }\r
1414\r
1415 return Status;\r
1416}\r
1417\r
1418/**\r
1419 Gets handles for any child controllers of the passed in controller.\r
1420\r
1421 @param[in] ControllerHandle The handle of the "parent controller"\r
1422 @param[in] MatchingHandleCount Pointer to the number of handles in\r
1423 MatchingHandleBuffer on return.\r
1424 @param[out] MatchingHandleBuffer Buffer containing handles on a successful\r
1425 return.\r
1426\r
1427\r
1428 @retval EFI_SUCCESS The operation was sucessful.\r
1429**/\r
1430EFI_STATUS\r
1431EFIAPI\r
1432ParseHandleDatabaseForChildControllers(\r
1433 IN CONST EFI_HANDLE ControllerHandle,\r
1434 IN UINTN *MatchingHandleCount,\r
1435 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1436 )\r
1437{\r
1438 EFI_STATUS Status;\r
f330ff35 1439 UINTN HandleIndex;\r
a405b86d 1440 UINTN DriverBindingHandleCount;\r
1441 EFI_HANDLE *DriverBindingHandleBuffer;\r
1442 UINTN DriverBindingHandleIndex;\r
1443 UINTN ChildControllerHandleCount;\r
1444 EFI_HANDLE *ChildControllerHandleBuffer;\r
1445 UINTN ChildControllerHandleIndex;\r
a405b86d 1446 EFI_HANDLE *HandleBufferForReturn;\r
1447\r
ff51746b 1448 if (MatchingHandleCount == NULL) {\r
1449 return (EFI_INVALID_PARAMETER);\r
1450 }\r
64d753f1 1451 *MatchingHandleCount = 0;\r
a405b86d 1452\r
1453 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (\r
1454 ControllerHandle,\r
1455 &DriverBindingHandleCount,\r
1456 &DriverBindingHandleBuffer\r
1457 );\r
1458 if (EFI_ERROR (Status)) {\r
1459 return Status;\r
1460 }\r
1461\r
ff51746b 1462 //\r
1463 // Get a buffer big enough for all the controllers.\r
1464 //\r
f330ff35 1465 HandleBufferForReturn = GetHandleListByProtocol(NULL);\r
a405b86d 1466 if (HandleBufferForReturn == NULL) {\r
1467 FreePool (DriverBindingHandleBuffer);\r
ff51746b 1468 return (EFI_NOT_FOUND);\r
a405b86d 1469 }\r
1470\r
a405b86d 1471 for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {\r
1472 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
1473 DriverBindingHandleBuffer[DriverBindingHandleIndex],\r
1474 ControllerHandle,\r
1475 &ChildControllerHandleCount,\r
1476 &ChildControllerHandleBuffer\r
1477 );\r
1478 if (EFI_ERROR (Status)) {\r
1479 continue;\r
1480 }\r
1481\r
1482 for (ChildControllerHandleIndex = 0;\r
1483 ChildControllerHandleIndex < ChildControllerHandleCount;\r
1484 ChildControllerHandleIndex++\r
1485 ) {\r
f330ff35 1486 for (HandleIndex = 0; HandleIndex < *MatchingHandleCount; HandleIndex++) {\r
1487 if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {\r
1488 break;\r
1489 }\r
1490 }\r
1491 if (HandleIndex >= *MatchingHandleCount) {\r
1492 HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];\r
1493 }\r
a405b86d 1494 }\r
1495\r
1496 FreePool (ChildControllerHandleBuffer);\r
1497 }\r
1498\r
1499 FreePool (DriverBindingHandleBuffer);\r
1500\r
1501 if (MatchingHandleBuffer != NULL) {\r
1502 *MatchingHandleBuffer = HandleBufferForReturn;\r
1503 } else {\r
1504 FreePool(HandleBufferForReturn);\r
1505 }\r
1506\r
1507 return (EFI_SUCCESS);\r
1508}\r
1509\r
1510/**\r
1511 Appends 1 buffer to another buffer. This will re-allocate the destination buffer\r
1512 if necessary to fit all of the data.\r
1513\r
1514 If DestinationBuffer is NULL, then ASSERT().\r
1515\r
4ff7e37b
ED
1516 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.\r
1517 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.\r
1518 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.\r
1519 @param[in] SourceSize The number of bytes of SourceBuffer to append.\r
a405b86d 1520\r
1521 @retval NULL A memory allocation failed.\r
1522 @retval NULL A parameter was invalid.\r
1523 @return A pointer to (*DestinationBuffer).\r
1524**/\r
1525VOID*\r
1526EFIAPI\r
1527BuffernCatGrow (\r
1528 IN OUT VOID **DestinationBuffer,\r
1529 IN OUT UINTN *DestinationSize,\r
1530 IN VOID *SourceBuffer,\r
1531 IN UINTN SourceSize\r
1532 )\r
1533{\r
1534 UINTN LocalDestinationSize;\r
1535 UINTN LocalDestinationFinalSize;\r
1536\r
1537 ASSERT(DestinationBuffer != NULL);\r
1538\r
1539 if (SourceSize == 0 || SourceBuffer == NULL) {\r
1540 return (*DestinationBuffer);\r
1541 }\r
1542\r
1543 if (DestinationSize == NULL) {\r
1544 LocalDestinationSize = 0;\r
1545 } else {\r
1546 LocalDestinationSize = *DestinationSize;\r
1547 }\r
1548\r
1549 LocalDestinationFinalSize = LocalDestinationSize + SourceSize;\r
1550\r
1551 if (DestinationSize != NULL) {\r
1552 *DestinationSize = LocalDestinationSize;\r
1553 }\r
1554\r
1555 if (LocalDestinationSize == 0) {\r
1556 // allcoate\r
78ed876b 1557 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);\r
a405b86d 1558 } else {\r
1559 // reallocate\r
1560 *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);\r
1561 }\r
1562\r
1563 ASSERT(*DestinationBuffer != NULL);\r
1564\r
1565 // copy\r
1566 return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));\r
1567}\r
1568\r
1569/**\r
1570 Gets handles for any child devices produced by the passed in driver.\r
1571\r
1572 @param[in] DriverHandle The handle of the driver.\r
1573 @param[in] MatchingHandleCount Pointer to the number of handles in\r
1574 MatchingHandleBuffer on return.\r
1575 @param[out] MatchingHandleBuffer Buffer containing handles on a successful\r
1576 return.\r
1577 @retval EFI_SUCCESS The operation was sucessful.\r
1578 @sa ParseHandleDatabaseByRelationship\r
1579**/\r
1580EFI_STATUS\r
1581EFIAPI\r
1582ParseHandleDatabaseForChildDevices(\r
1583 IN CONST EFI_HANDLE DriverHandle,\r
1584 IN UINTN *MatchingHandleCount,\r
1585 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1586 )\r
1587{\r
1588 EFI_HANDLE *Buffer;\r
1589 EFI_HANDLE *Buffer2;\r
1590 UINTN Count1;\r
1591 UINTN Count2;\r
1592 UINTN HandleIndex;\r
1593 EFI_STATUS Status;\r
1594 UINTN HandleBufferSize;\r
1595\r
1596 ASSERT(MatchingHandleCount != NULL);\r
1597\r
1598 HandleBufferSize = 0;\r
1599 Buffer = NULL;\r
1600 Buffer2 = NULL;\r
1601 *MatchingHandleCount = 0;\r
1602\r
1603 Status = PARSE_HANDLE_DATABASE_DEVICES (\r
1604 DriverHandle,\r
1605 &Count1,\r
1606 &Buffer\r
1607 );\r
1608 if (!EFI_ERROR (Status)) {\r
1609 for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {\r
1610 //\r
1611 // now find the children\r
1612 //\r
1613 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
1614 DriverHandle,\r
1615 Buffer[HandleIndex],\r
1616 &Count2,\r
1617 &Buffer2\r
1618 );\r
1619 if (EFI_ERROR(Status)) {\r
1620 break;\r
1621 }\r
1622 //\r
1623 // save out required and optional data elements\r
1624 //\r
1625 *MatchingHandleCount += Count2;\r
1626 if (MatchingHandleBuffer != NULL) {\r
1627 *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));\r
1628 }\r
1629\r
1630 //\r
1631 // free the memory\r
1632 //\r
1633 if (Buffer2 != NULL) {\r
1634 FreePool(Buffer2);\r
1635 }\r
1636 }\r
1637 }\r
1638\r
1639 if (Buffer != NULL) {\r
1640 FreePool(Buffer);\r
1641 }\r
1642 return (Status);\r
1643}\r
1644\r
1645/**\r
1646 Function to get all handles that support a given protocol or all handles.\r
1647\r
1648 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL\r
1649 then the function will return all handles.\r
1650\r
1651 @retval NULL A memory allocation failed.\r
1652 @return A NULL terminated list of handles.\r
1653**/\r
1654EFI_HANDLE*\r
1655EFIAPI\r
40d7a9cf 1656GetHandleListByProtocol (\r
a405b86d 1657 IN CONST EFI_GUID *ProtocolGuid OPTIONAL\r
1658 )\r
1659{\r
1660 EFI_HANDLE *HandleList;\r
1661 UINTN Size;\r
1662 EFI_STATUS Status;\r
1663\r
1664 Size = 0;\r
1665 HandleList = NULL;\r
1666\r
1667 //\r
1668 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!\r
1669 //\r
1670 if (ProtocolGuid == NULL) {\r
1671 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);\r
1672 if (Status == EFI_BUFFER_TOO_SMALL) {\r
78ed876b 1673 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
40d7a9cf 1674 if (HandleList == NULL) {\r
1675 return (NULL);\r
1676 }\r
a405b86d 1677 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);\r
1678 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;\r
1679 }\r
1680 } else {\r
1681 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);\r
1682 if (Status == EFI_BUFFER_TOO_SMALL) {\r
78ed876b 1683 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
40d7a9cf 1684 if (HandleList == NULL) {\r
1685 return (NULL);\r
1686 }\r
a405b86d 1687 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);\r
1688 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;\r
1689 }\r
1690 }\r
1691 if (EFI_ERROR(Status)) {\r
1692 if (HandleList != NULL) {\r
1693 FreePool(HandleList);\r
1694 }\r
1695 return (NULL);\r
1696 }\r
1697 return (HandleList);\r
1698}\r
1699\r
1700/**\r
1701 Function to get all handles that support some protocols.\r
1702\r
1703 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.\r
1704\r
1705 @retval NULL A memory allocation failed.\r
ff51746b 1706 @retval NULL ProtocolGuids was NULL.\r
1707 @return A NULL terminated list of EFI_HANDLEs.\r
a405b86d 1708**/\r
1709EFI_HANDLE*\r
1710EFIAPI\r
40d7a9cf 1711GetHandleListByProtocolList (\r
a405b86d 1712 IN CONST EFI_GUID **ProtocolGuids\r
1713 )\r
1714{\r
1715 EFI_HANDLE *HandleList;\r
1716 UINTN Size;\r
1717 UINTN TotalSize;\r
40d7a9cf 1718 UINTN TempSize;\r
a405b86d 1719 EFI_STATUS Status;\r
1720 CONST EFI_GUID **GuidWalker;\r
1721 EFI_HANDLE *HandleWalker1;\r
1722 EFI_HANDLE *HandleWalker2;\r
1723\r
1724 Size = 0;\r
1725 HandleList = NULL;\r
1726 TotalSize = sizeof(EFI_HANDLE);\r
1727\r
1728 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){\r
1729 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);\r
1730 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1731 TotalSize += Size;\r
1732 }\r
1733 }\r
40d7a9cf 1734\r
1735 //\r
1736 // No handles were found... \r
1737 //\r
1738 if (TotalSize == sizeof(EFI_HANDLE)) {\r
1739 return (NULL);\r
1740 }\r
1741\r
1742 HandleList = AllocateZeroPool(TotalSize);\r
a405b86d 1743 if (HandleList == NULL) {\r
1744 return (NULL);\r
1745 }\r
1746\r
1747 Size = 0;\r
1748 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){\r
40d7a9cf 1749 TempSize = TotalSize - Size;\r
ff51746b 1750 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));\r
40d7a9cf 1751\r
1752 //\r
1753 // Allow for missing protocols... Only update the 'used' size upon success.\r
1754 //\r
1755 if (!EFI_ERROR(Status)) {\r
ff51746b 1756 Size += TempSize;\r
40d7a9cf 1757 }\r
a405b86d 1758 }\r
ff51746b 1759 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);\r
a405b86d 1760\r
1761 for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {\r
1762 for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {\r
1763 if (*HandleWalker1 == *HandleWalker2) {\r
1764 //\r
1765 // copy memory back 1 handle width.\r
1766 //\r
1767 CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));\r
1768 }\r
1769 }\r
1770 }\r
1771\r
1772 return (HandleList);\r
1773}\r
1774\r
1775\r
1776\r
1777\r
1778\r
1779\r
1780\r
1781\r
1782\r
1783\r