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