]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
ShellPkg: Add EfiIdeControllerInitProtocol to Shell’s output
[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
12f1a36c 622 {STRING_TOKEN(STR_UCRED2), &gEfiUserCredential2ProtocolGuid, NULL},\r
dee34318 623\r
28cdb62b
CP
624//\r
625// UEFI 2.4\r
626//\r
627 {STRING_TOKEN(STR_DISK_IO2), &gEfiDiskIo2ProtocolGuid, NULL},\r
628\r
6b640b4a
JC
629//\r
630// PI Spec ones\r
631//\r
632 {STRING_TOKEN(STR_IDE_CONT_INIT), &gEfiIdeControllerInitProtocolGuid, NULL},\r
633\r
dee34318 634//\r
635// terminator\r
636//\r
a405b86d 637 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},\r
638};\r
639\r
640/**\r
641 Function to get the node for a protocol or struct from it's GUID.\r
642\r
643 if Guid is NULL, then ASSERT.\r
644\r
645 @param[in] Guid The GUID to look for the name of.\r
646\r
647 @return The node.\r
648**/\r
dee34318 649CONST GUID_INFO_BLOCK *\r
a405b86d 650EFIAPI\r
651InternalShellGetNodeFromGuid(\r
652 IN CONST EFI_GUID* Guid\r
653 )\r
654{\r
dee34318 655 CONST GUID_INFO_BLOCK *ListWalker;\r
a405b86d 656\r
657 ASSERT(Guid != NULL);\r
658\r
659 if (PcdGetBool(PcdShellIncludeNtGuids)) {\r
660 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
661 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
662 return (ListWalker);\r
663 }\r
664 }\r
665 }\r
666 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
667 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
668 return (ListWalker);\r
669 }\r
670 }\r
671 return (ListWalker);\r
672}\r
673\r
674/**\r
675 Function to get the name of a protocol or struct from it's GUID.\r
676\r
677 if Guid is NULL, then ASSERT.\r
678\r
679 @param[in] Guid The GUID to look for the name of.\r
680 @param[in] Lang The language to use.\r
681\r
682 @return pointer to string of the name. The caller\r
683 is responsible to free this memory.\r
684**/\r
685CHAR16*\r
686EFIAPI\r
687GetStringNameFromGuid(\r
688 IN CONST EFI_GUID *Guid,\r
689 IN CONST CHAR8 *Lang OPTIONAL\r
690 )\r
691{\r
dee34318 692 CONST GUID_INFO_BLOCK *Id;\r
a405b86d 693\r
694 Id = InternalShellGetNodeFromGuid(Guid);\r
695 return (HiiGetString(mHandleParsingHiiHandle, Id->StringId, Lang));\r
696}\r
697\r
698/**\r
699 Function to dump protocol information from a handle.\r
700\r
701 This function will return a allocated string buffer containing the\r
702 information. The caller is responsible for freeing the memory.\r
703\r
704 If Guid is NULL, ASSERT().\r
705 If TheHandle is NULL, ASSERT().\r
706\r
707 @param[in] TheHandle The handle to dump information from.\r
708 @param[in] Guid The GUID of the protocol to dump.\r
709 @param[in] Verbose TRUE for extra info. FALSE otherwise.\r
710\r
711 @return The pointer to string.\r
712 @retval NULL An error was encountered.\r
713**/\r
714CHAR16*\r
715EFIAPI\r
716GetProtocolInformationDump(\r
717 IN CONST EFI_HANDLE TheHandle,\r
718 IN CONST EFI_GUID *Guid,\r
719 IN CONST BOOLEAN Verbose\r
720 )\r
721{\r
dee34318 722 CONST GUID_INFO_BLOCK *Id;\r
a405b86d 723\r
724 ASSERT(TheHandle != NULL);\r
725 ASSERT(Guid != NULL);\r
726\r
727 if (TheHandle == NULL || Guid == NULL) {\r
728 return (NULL);\r
729 }\r
730\r
731 Id = InternalShellGetNodeFromGuid(Guid);\r
732 if (Id != NULL && Id->DumpInfo != NULL) {\r
733 return (Id->DumpInfo(TheHandle, Verbose));\r
734 }\r
735 return (NULL);\r
736}\r
737\r
738/**\r
739 Function to get the Guid for a protocol or struct based on it's string name.\r
740\r
741 @param[in] Name The pointer to the string name.\r
742 @param[in] Lang The pointer to the language code.\r
743 @param[in] Guid The pointer to the Guid.\r
744\r
745 @retval EFI_SUCCESS The operation was sucessful.\r
746**/\r
747EFI_STATUS\r
748EFIAPI\r
749GetGuidFromStringName(\r
750 IN CONST CHAR16 *Name,\r
751 IN CONST CHAR8 *Lang OPTIONAL,\r
752 IN EFI_GUID **Guid\r
753 )\r
754{\r
dee34318 755 CONST GUID_INFO_BLOCK *ListWalker;\r
a405b86d 756 CHAR16 *String;\r
757\r
758 ASSERT(Guid != NULL);\r
759 if (Guid == NULL) {\r
760 return (EFI_INVALID_PARAMETER);\r
761 }\r
762 *Guid = NULL;\r
763\r
764 if (PcdGetBool(PcdShellIncludeNtGuids)) {\r
765 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
766 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
28cdb62b 767 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {\r
a405b86d 768 *Guid = ListWalker->GuidId;\r
769 }\r
770 SHELL_FREE_NON_NULL(String);\r
771 if (*Guid != NULL) {\r
772 return (EFI_SUCCESS);\r
773 }\r
774 }\r
775 }\r
776 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
777 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
28cdb62b 778 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {\r
a405b86d 779 *Guid = ListWalker->GuidId;\r
780 }\r
781 SHELL_FREE_NON_NULL(String);\r
782 if (*Guid != NULL) {\r
783 return (EFI_SUCCESS);\r
784 }\r
785 }\r
786 return (EFI_NOT_FOUND);\r
787}\r
788\r
36384ceb
ED
789/**\r
790 Get best support language for this driver.\r
791 \r
a71003f2
ED
792 First base on the user input language to search, second base on the current \r
793 platform used language to search, third get the first language from the \r
794 support language list. The caller need to free the buffer of the best language.\r
36384ceb
ED
795\r
796 @param[in] SupportedLanguages The support languages for this driver.\r
a71003f2 797 @param[in] InputLanguage The user input language.\r
36384ceb
ED
798 @param[in] Iso639Language Whether get language for ISO639.\r
799\r
800 @return The best support language for this driver.\r
801**/\r
802CHAR8 *\r
a71003f2 803EFIAPI\r
36384ceb 804GetBestLanguageForDriver (\r
a71003f2
ED
805 IN CONST CHAR8 *SupportedLanguages,\r
806 IN CONST CHAR8 *InputLanguage,\r
36384ceb
ED
807 IN BOOLEAN Iso639Language\r
808 )\r
809{\r
810 CHAR8 *LanguageVariable;\r
811 CHAR8 *BestLanguage;\r
812\r
813 LanguageVariable = GetVariable (Iso639Language ? L"Lang" : L"PlatformLang", &gEfiGlobalVariableGuid);\r
814\r
815 BestLanguage = GetBestLanguage(\r
816 SupportedLanguages,\r
817 Iso639Language,\r
a71003f2 818 (InputLanguage != NULL) ? InputLanguage : "",\r
36384ceb 819 (LanguageVariable != NULL) ? LanguageVariable : "",\r
a71003f2 820 SupportedLanguages,\r
36384ceb
ED
821 NULL\r
822 );\r
823\r
824 if (LanguageVariable != NULL) {\r
825 FreePool (LanguageVariable);\r
826 }\r
827\r
828 return BestLanguage;\r
829}\r
830\r
a405b86d 831/**\r
832 Function to retrieve the driver name (if possible) from the ComponentName or\r
833 ComponentName2 protocol\r
834\r
835 @param[in] TheHandle The driver handle to get the name of.\r
836 @param[in] Language The language to use.\r
837\r
838 @retval NULL The name could not be found.\r
839 @return A pointer to the string name. Do not de-allocate the memory.\r
840**/\r
841CONST CHAR16*\r
842EFIAPI\r
843GetStringNameFromHandle(\r
844 IN CONST EFI_HANDLE TheHandle,\r
845 IN CONST CHAR8 *Language\r
846 )\r
847{\r
848 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;\r
849 EFI_STATUS Status;\r
850 CHAR16 *RetVal;\r
36384ceb
ED
851 CHAR8 *BestLang;\r
852\r
853 BestLang = NULL;\r
a405b86d 854\r
855 Status = gBS->OpenProtocol(\r
856 TheHandle,\r
857 &gEfiComponentName2ProtocolGuid,\r
858 (VOID**)&CompNameStruct,\r
859 gImageHandle,\r
860 NULL,\r
861 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
862 if (!EFI_ERROR(Status)) {\r
a71003f2
ED
863 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);\r
864 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);\r
36384ceb
ED
865 if (BestLang != NULL) {\r
866 FreePool (BestLang);\r
867 BestLang = NULL;\r
868 }\r
a405b86d 869 if (!EFI_ERROR(Status)) {\r
870 return (RetVal);\r
871 }\r
872 }\r
873 Status = gBS->OpenProtocol(\r
874 TheHandle,\r
875 &gEfiComponentNameProtocolGuid,\r
876 (VOID**)&CompNameStruct,\r
877 gImageHandle,\r
878 NULL,\r
879 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
880 if (!EFI_ERROR(Status)) {\r
a71003f2
ED
881 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);\r
882 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);\r
36384ceb
ED
883 if (BestLang != NULL) {\r
884 FreePool (BestLang);\r
885 }\r
a405b86d 886 if (!EFI_ERROR(Status)) {\r
887 return (RetVal);\r
888 }\r
889 }\r
890 return (NULL);\r
891}\r
892\r
893/**\r
894 Function to initialize the file global mHandleList object for use in\r
895 vonverting handles to index and index to handle.\r
896\r
897 @retval EFI_SUCCESS The operation was successful.\r
898**/\r
899EFI_STATUS\r
900EFIAPI\r
901InternalShellInitHandleList(\r
902 VOID\r
903 )\r
904{\r
905 EFI_STATUS Status;\r
906 EFI_HANDLE *HandleBuffer;\r
907 UINTN HandleCount;\r
908 HANDLE_LIST *ListWalker;\r
909\r
910 if (mHandleList.NextIndex != 0) {\r
911 return EFI_SUCCESS;\r
912 }\r
913 InitializeListHead(&mHandleList.List.Link);\r
914 mHandleList.NextIndex = 1;\r
915 Status = gBS->LocateHandleBuffer (\r
916 AllHandles,\r
917 NULL,\r
918 NULL,\r
919 &HandleCount,\r
920 &HandleBuffer\r
921 );\r
922 ASSERT_EFI_ERROR(Status);\r
923 if (EFI_ERROR(Status)) {\r
924 return (Status);\r
925 }\r
926 for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){\r
78ed876b 927 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
a405b86d 928 ASSERT(ListWalker != NULL);\r
929 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex-1];\r
930 ListWalker->TheIndex = mHandleList.NextIndex;\r
931 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);\r
932 }\r
933 FreePool(HandleBuffer);\r
934 return (EFI_SUCCESS);\r
935}\r
936\r
937/**\r
938 Function to retrieve the human-friendly index of a given handle. If the handle\r
939 does not have a index one will be automatically assigned. The index value is valid\r
940 until the termination of the shell application.\r
941\r
942 @param[in] TheHandle The handle to retrieve an index for.\r
943\r
944 @retval 0 A memory allocation failed.\r
945 @return The index of the handle.\r
946\r
947**/\r
948UINTN\r
949EFIAPI\r
950ConvertHandleToHandleIndex(\r
951 IN CONST EFI_HANDLE TheHandle\r
952 )\r
953{\r
f330ff35 954 EFI_STATUS Status;\r
955 EFI_GUID **ProtocolBuffer;\r
956 UINTN ProtocolCount;\r
957 HANDLE_LIST *ListWalker;\r
958\r
78ed876b 959 if (TheHandle == NULL) {\r
960 return 0;\r
961 }\r
a405b86d 962\r
963 InternalShellInitHandleList();\r
964\r
965 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)\r
966 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)\r
967 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)\r
968 ){\r
969 if (ListWalker->TheHandle == TheHandle) {\r
f330ff35 970 //\r
971 // Verify that TheHandle is still present in the Handle Database\r
972 //\r
973 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);\r
974 if (EFI_ERROR (Status)) {\r
975 //\r
976 // TheHandle is not present in the Handle Database, so delete from the handle list\r
977 //\r
978 RemoveEntryList (&ListWalker->Link);\r
979 return 0;\r
980 }\r
981 FreePool (ProtocolBuffer);\r
a405b86d 982 return (ListWalker->TheIndex);\r
983 }\r
984 }\r
f330ff35 985\r
986 //\r
987 // Verify that TheHandle is valid handle\r
988 //\r
989 Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);\r
990 if (EFI_ERROR (Status)) {\r
991 //\r
992 // TheHandle is not valid, so do not add to handle list\r
993 //\r
994 return 0;\r
995 }\r
996 FreePool (ProtocolBuffer);\r
997\r
78ed876b 998 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
a405b86d 999 ASSERT(ListWalker != NULL);\r
1000 ListWalker->TheHandle = TheHandle;\r
1001 ListWalker->TheIndex = mHandleList.NextIndex++;\r
1002 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);\r
1003 return (ListWalker->TheIndex);\r
1004}\r
1005\r
1006\r
1007\r
1008/**\r
1009 Function to retrieve the EFI_HANDLE from the human-friendly index.\r
1010\r
1011 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.\r
1012\r
1013 @retval NULL The index was invalid.\r
1014 @return The EFI_HANDLE that index represents.\r
1015\r
1016**/\r
1017EFI_HANDLE\r
1018EFIAPI\r
1019ConvertHandleIndexToHandle(\r
1020 IN CONST UINTN TheIndex\r
1021 )\r
1022{\r
f330ff35 1023 EFI_STATUS Status;\r
1024 EFI_GUID **ProtocolBuffer;\r
1025 UINTN ProtocolCount;\r
a405b86d 1026 HANDLE_LIST *ListWalker;\r
1027\r
1028 InternalShellInitHandleList();\r
1029\r
1030 if (TheIndex >= mHandleList.NextIndex) {\r
f330ff35 1031 return NULL;\r
a405b86d 1032 }\r
1033\r
1034 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)\r
1035 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)\r
1036 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)\r
1037 ){\r
f330ff35 1038 if (ListWalker->TheIndex == TheIndex && ListWalker->TheHandle != NULL) {\r
1039 //\r
1040 // Verify that LinkWalker->TheHandle is valid handle\r
1041 //\r
1042 Status = gBS->ProtocolsPerHandle(ListWalker->TheHandle, &ProtocolBuffer, &ProtocolCount);\r
1043 if (EFI_ERROR (Status)) {\r
1044 //\r
1045 // TheHandle is not valid, so do not add to handle list\r
1046 //\r
1047 ListWalker->TheHandle = NULL;\r
1048 }\r
a405b86d 1049 return (ListWalker->TheHandle);\r
1050 }\r
1051 }\r
f330ff35 1052 return NULL;\r
a405b86d 1053}\r
1054\r
1055/**\r
1056 Gets all the related EFI_HANDLEs based on the mask supplied.\r
1057\r
1058 This function scans all EFI_HANDLES in the UEFI environment's handle database\r
1059 and returns the ones with the specified relationship (Mask) to the specified\r
1060 controller handle.\r
1061\r
1062 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.\r
1063 If MatchingHandleCount is NULL, then ASSERT.\r
1064\r
1065 If MatchingHandleBuffer is not NULL upon a successful return the memory must be\r
1066 caller freed.\r
1067\r
1068 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.\r
1069 @param[in] ControllerHandle The handle with Device Path protocol on it.\r
1070 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in\r
1071 MatchingHandleBuffer.\r
1072 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount\r
1073 EFI_HANDLEs with a terminating NULL EFI_HANDLE.\r
1074 @param[out] HandleType An array of type information.\r
1075\r
1076 @retval EFI_SUCCESS The operation was successful, and any related handles\r
1077 are in MatchingHandleBuffer.\r
1078 @retval EFI_NOT_FOUND No matching handles were found.\r
1079 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.\r
1080**/\r
1081EFI_STATUS\r
1082EFIAPI\r
1083ParseHandleDatabaseByRelationshipWithType (\r
1084 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,\r
1085 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
1086 IN UINTN *HandleCount,\r
1087 OUT EFI_HANDLE **HandleBuffer,\r
1088 OUT UINTN **HandleType\r
1089 )\r
1090{\r
1091 EFI_STATUS Status;\r
1092 UINTN HandleIndex;\r
1093 EFI_GUID **ProtocolGuidArray;\r
1094 UINTN ArrayCount;\r
1095 UINTN ProtocolIndex;\r
1096 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
1097 UINTN OpenInfoCount;\r
1098 UINTN OpenInfoIndex;\r
1099 UINTN ChildIndex;\r
f330ff35 1100 INTN DriverBindingHandleIndex;\r
a405b86d 1101\r
1102 ASSERT(HandleCount != NULL);\r
1103 ASSERT(HandleBuffer != NULL);\r
1104 ASSERT(HandleType != NULL);\r
1105 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);\r
1106\r
1107 *HandleCount = 0;\r
1108 *HandleBuffer = NULL;\r
1109 *HandleType = NULL;\r
1110\r
1111 //\r
1112 // Retrieve the list of all handles from the handle database\r
1113 //\r
1114 Status = gBS->LocateHandleBuffer (\r
1115 AllHandles,\r
1116 NULL,\r
1117 NULL,\r
1118 HandleCount,\r
1119 HandleBuffer\r
1120 );\r
1121 if (EFI_ERROR (Status)) {\r
1122 return (Status);\r
1123 }\r
1124\r
1125 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));\r
1126 ASSERT(*HandleType != NULL);\r
1127\r
f330ff35 1128 DriverBindingHandleIndex = -1;\r
1129 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
1130 if (DriverBindingHandle != NULL && (*HandleBuffer)[HandleIndex] == DriverBindingHandle) {\r
1131 DriverBindingHandleIndex = (INTN)HandleIndex;\r
1132 }\r
1133 }\r
1134\r
a405b86d 1135 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
1136 //\r
1137 // Retrieve the list of all the protocols on each handle\r
1138 //\r
1139 Status = gBS->ProtocolsPerHandle (\r
1140 (*HandleBuffer)[HandleIndex],\r
1141 &ProtocolGuidArray,\r
1142 &ArrayCount\r
1143 );\r
f330ff35 1144 if (EFI_ERROR (Status)) {\r
1145 continue;\r
1146 }\r
a405b86d 1147\r
f330ff35 1148 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
a405b86d 1149\r
f330ff35 1150 //\r
1151 // Set the bit describing what this handle has\r
1152 //\r
1153 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) ) {\r
1154 (*HandleType)[HandleIndex] |= HR_IMAGE_HANDLE;\r
1155 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) ) {\r
1156 (*HandleType)[HandleIndex] |= HR_DRIVER_BINDING_HANDLE;\r
1157 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {\r
1158 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;\r
1159 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {\r
1160 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;\r
1161 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid) ) {\r
1162 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;\r
1163 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) ) {\r
1164 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;\r
1165 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid) ) {\r
1166 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;\r
1167 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) {\r
1168 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;\r
1169 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) ) {\r
1170 (*HandleType)[HandleIndex] |= HR_DEVICE_HANDLE;\r
1171 } else {\r
1172 DEBUG_CODE_BEGIN();\r
1173 ASSERT((*HandleType)[HandleIndex] == (*HandleType)[HandleIndex]);\r
1174 DEBUG_CODE_END();\r
1175 }\r
1176 //\r
1177 // Retrieve the list of agents that have opened each protocol\r
1178 //\r
1179 Status = gBS->OpenProtocolInformation (\r
a405b86d 1180 (*HandleBuffer)[HandleIndex],\r
1181 ProtocolGuidArray[ProtocolIndex],\r
1182 &OpenInfo,\r
1183 &OpenInfoCount\r
1184 );\r
f330ff35 1185 if (EFI_ERROR (Status)) {\r
1186 continue;\r
1187 }\r
1188\r
1189 if (ControllerHandle == NULL) {\r
1190 //\r
1191 // ControllerHandle == NULL and DriverBindingHandle != NULL. \r
1192 // Return information on all the controller handles that the driver specified by DriverBindingHandle is managing\r
1193 //\r
1194 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1195 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1196 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1197 if (DriverBindingHandleIndex != -1) {\r
1198 (*HandleType)[DriverBindingHandleIndex] |= HR_DEVICE_DRIVER;\r
1199 }\r
1200 }\r
1201 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1202 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1203 if (DriverBindingHandleIndex != -1) {\r
1204 (*HandleType)[DriverBindingHandleIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1205 }\r
1206 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1207 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1208 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
1209 }\r
1210 }\r
1211 }\r
1212 }\r
1213 }\r
1214 if (DriverBindingHandle == NULL && ControllerHandle != NULL) {\r
1215 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {\r
1216 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
a405b86d 1217 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
f330ff35 1218 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1219 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1220 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1221 (*HandleType)[ChildIndex] |= HR_DEVICE_DRIVER;\r
1222 }\r
a405b86d 1223 }\r
f330ff35 1224 }\r
1225 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1226 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1227 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1228 (*HandleType)[ChildIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1229 }\r
1230 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1231 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
a405b86d 1232 }\r
1233 }\r
1234 }\r
f330ff35 1235 }\r
1236 } else {\r
1237 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1238 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1239 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {\r
1240 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_PARENT_HANDLE);\r
1241 }\r
1242 }\r
1243 }\r
1244 }\r
1245 }\r
1246 if (DriverBindingHandle != NULL && ControllerHandle != NULL) {\r
1247 if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {\r
1248 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
1249 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1250 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
1251 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
1252 if (DriverBindingHandleIndex != -1) {\r
1253 (*HandleType)[DriverBindingHandleIndex] |= HR_DEVICE_DRIVER;\r
a405b86d 1254 }\r
1255 }\r
f330ff35 1256 }\r
1257 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1258 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
a405b86d 1259 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
f330ff35 1260 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1261 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
a405b86d 1262 }\r
1263 }\r
1264 }\r
f330ff35 1265\r
1266 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1267 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {\r
1268 (*HandleType)[ChildIndex] |= (HR_BUS_DRIVER | HR_DEVICE_DRIVER);\r
1269 }\r
1270 }\r
1271 }\r
1272 }\r
1273 } else {\r
1274 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
1275 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1276 if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {\r
1277 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_PARENT_HANDLE);\r
1278 }\r
a405b86d 1279 }\r
1280 }\r
a405b86d 1281 }\r
1282 }\r
f330ff35 1283 FreePool (OpenInfo);\r
a405b86d 1284 }\r
f330ff35 1285 FreePool (ProtocolGuidArray);\r
a405b86d 1286 }\r
f330ff35 1287 return EFI_SUCCESS;\r
a405b86d 1288}\r
1289\r
1290/**\r
1291 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask\r
1292 supplied.\r
1293\r
1294 This function will scan all EFI_HANDLES in the UEFI environment's handle database\r
1295 and return all the ones with the specified relationship (Mask) to the specified\r
1296 controller handle.\r
1297\r
1298 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.\r
1299 If MatchingHandleCount is NULL, then ASSERT.\r
1300\r
1301 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be\r
1302 caller freed.\r
1303\r
1304 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol\r
1305 on it.\r
1306 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.\r
1307 @param[in] Mask Mask of what relationship(s) is desired.\r
1308 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in\r
1309 MatchingHandleBuffer.\r
1310 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount\r
1311 EFI_HANDLEs and a terminating NULL EFI_HANDLE.\r
1312\r
1313 @retval EFI_SUCCESS The operation was sucessful and any related handles\r
1314 are in MatchingHandleBuffer;\r
1315 @retval EFI_NOT_FOUND No matching handles were found.\r
1316 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.\r
1317**/\r
1318EFI_STATUS\r
1319EFIAPI\r
1320ParseHandleDatabaseByRelationship (\r
1321 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,\r
1322 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
1323 IN CONST UINTN Mask,\r
1324 IN UINTN *MatchingHandleCount,\r
1325 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1326 )\r
1327{\r
1328 EFI_STATUS Status;\r
1329 UINTN HandleCount;\r
1330 EFI_HANDLE *HandleBuffer;\r
1331 UINTN *HandleType;\r
1332 UINTN HandleIndex;\r
1333\r
1334 ASSERT(MatchingHandleCount != NULL);\r
1335 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);\r
1336\r
1337 if ((Mask & HR_VALID_MASK) != Mask) {\r
1338 return (EFI_INVALID_PARAMETER);\r
1339 }\r
1340\r
1341 if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {\r
1342 return (EFI_INVALID_PARAMETER);\r
1343 }\r
1344\r
1345 *MatchingHandleCount = 0;\r
1346 if (MatchingHandleBuffer != NULL) {\r
1347 *MatchingHandleBuffer = NULL;\r
1348 }\r
1349\r
1350 HandleBuffer = NULL;\r
1351 HandleType = NULL;\r
1352\r
1353 Status = ParseHandleDatabaseByRelationshipWithType (\r
1354 DriverBindingHandle,\r
1355 ControllerHandle,\r
1356 &HandleCount,\r
1357 &HandleBuffer,\r
1358 &HandleType\r
1359 );\r
1360 if (!EFI_ERROR (Status)) {\r
1361 //\r
1362 // Count the number of handles that match the attributes in Mask\r
1363 //\r
1364 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
1365 if ((HandleType[HandleIndex] & Mask) == Mask) {\r
1366 (*MatchingHandleCount)++;\r
1367 }\r
1368 }\r
1369 //\r
1370 // If no handles match the attributes in Mask then return EFI_NOT_FOUND\r
1371 //\r
1372 if (*MatchingHandleCount == 0) {\r
1373 Status = EFI_NOT_FOUND;\r
1374 } else {\r
1375\r
1376 if (MatchingHandleBuffer == NULL) {\r
1377 //\r
1378 // Someone just wanted the count...\r
1379 //\r
1380 Status = EFI_SUCCESS;\r
1381 } else {\r
1382 //\r
1383 // Allocate a handle buffer for the number of handles that matched the attributes in Mask\r
1384 //\r
78ed876b 1385 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));\r
a405b86d 1386 ASSERT(*MatchingHandleBuffer != NULL);\r
1387\r
1388 for (HandleIndex = 0,*MatchingHandleCount = 0\r
1389 ; HandleIndex < HandleCount\r
1390 ; HandleIndex++\r
1391 ){\r
1392 //\r
1393 // Fill the allocated buffer with the handles that matched the attributes in Mask\r
1394 //\r
1395 if ((HandleType[HandleIndex] & Mask) == Mask) {\r
1396 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];\r
1397 }\r
1398 }\r
1399\r
1400 //\r
1401 // Make the last one NULL\r
1402 //\r
1403 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;\r
1404\r
1405 Status = EFI_SUCCESS;\r
1406 } // MacthingHandleBuffer == NULL (ELSE)\r
1407 } // *MatchingHandleCount == 0 (ELSE)\r
1408 } // no error on ParseHandleDatabaseByRelationshipWithType\r
1409\r
1410 if (HandleBuffer != NULL) {\r
1411 FreePool (HandleBuffer);\r
1412 }\r
1413\r
1414 if (HandleType != NULL) {\r
1415 FreePool (HandleType);\r
1416 }\r
1417\r
1418 return Status;\r
1419}\r
1420\r
1421/**\r
1422 Gets handles for any child controllers of the passed in controller.\r
1423\r
1424 @param[in] ControllerHandle The handle of the "parent controller"\r
1425 @param[in] MatchingHandleCount Pointer to the number of handles in\r
1426 MatchingHandleBuffer on return.\r
1427 @param[out] MatchingHandleBuffer Buffer containing handles on a successful\r
1428 return.\r
1429\r
1430\r
1431 @retval EFI_SUCCESS The operation was sucessful.\r
1432**/\r
1433EFI_STATUS\r
1434EFIAPI\r
1435ParseHandleDatabaseForChildControllers(\r
1436 IN CONST EFI_HANDLE ControllerHandle,\r
1437 IN UINTN *MatchingHandleCount,\r
1438 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1439 )\r
1440{\r
1441 EFI_STATUS Status;\r
f330ff35 1442 UINTN HandleIndex;\r
a405b86d 1443 UINTN DriverBindingHandleCount;\r
1444 EFI_HANDLE *DriverBindingHandleBuffer;\r
1445 UINTN DriverBindingHandleIndex;\r
1446 UINTN ChildControllerHandleCount;\r
1447 EFI_HANDLE *ChildControllerHandleBuffer;\r
1448 UINTN ChildControllerHandleIndex;\r
a405b86d 1449 EFI_HANDLE *HandleBufferForReturn;\r
1450\r
ff51746b 1451 if (MatchingHandleCount == NULL) {\r
1452 return (EFI_INVALID_PARAMETER);\r
1453 }\r
64d753f1 1454 *MatchingHandleCount = 0;\r
a405b86d 1455\r
1456 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (\r
1457 ControllerHandle,\r
1458 &DriverBindingHandleCount,\r
1459 &DriverBindingHandleBuffer\r
1460 );\r
1461 if (EFI_ERROR (Status)) {\r
1462 return Status;\r
1463 }\r
1464\r
ff51746b 1465 //\r
1466 // Get a buffer big enough for all the controllers.\r
1467 //\r
f330ff35 1468 HandleBufferForReturn = GetHandleListByProtocol(NULL);\r
a405b86d 1469 if (HandleBufferForReturn == NULL) {\r
1470 FreePool (DriverBindingHandleBuffer);\r
ff51746b 1471 return (EFI_NOT_FOUND);\r
a405b86d 1472 }\r
1473\r
a405b86d 1474 for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {\r
1475 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
1476 DriverBindingHandleBuffer[DriverBindingHandleIndex],\r
1477 ControllerHandle,\r
1478 &ChildControllerHandleCount,\r
1479 &ChildControllerHandleBuffer\r
1480 );\r
1481 if (EFI_ERROR (Status)) {\r
1482 continue;\r
1483 }\r
1484\r
1485 for (ChildControllerHandleIndex = 0;\r
1486 ChildControllerHandleIndex < ChildControllerHandleCount;\r
1487 ChildControllerHandleIndex++\r
1488 ) {\r
f330ff35 1489 for (HandleIndex = 0; HandleIndex < *MatchingHandleCount; HandleIndex++) {\r
1490 if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {\r
1491 break;\r
1492 }\r
1493 }\r
1494 if (HandleIndex >= *MatchingHandleCount) {\r
1495 HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];\r
1496 }\r
a405b86d 1497 }\r
1498\r
1499 FreePool (ChildControllerHandleBuffer);\r
1500 }\r
1501\r
1502 FreePool (DriverBindingHandleBuffer);\r
1503\r
1504 if (MatchingHandleBuffer != NULL) {\r
1505 *MatchingHandleBuffer = HandleBufferForReturn;\r
1506 } else {\r
1507 FreePool(HandleBufferForReturn);\r
1508 }\r
1509\r
1510 return (EFI_SUCCESS);\r
1511}\r
1512\r
1513/**\r
1514 Appends 1 buffer to another buffer. This will re-allocate the destination buffer\r
1515 if necessary to fit all of the data.\r
1516\r
1517 If DestinationBuffer is NULL, then ASSERT().\r
1518\r
4ff7e37b
ED
1519 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.\r
1520 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.\r
1521 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.\r
1522 @param[in] SourceSize The number of bytes of SourceBuffer to append.\r
a405b86d 1523\r
1524 @retval NULL A memory allocation failed.\r
1525 @retval NULL A parameter was invalid.\r
1526 @return A pointer to (*DestinationBuffer).\r
1527**/\r
1528VOID*\r
1529EFIAPI\r
1530BuffernCatGrow (\r
1531 IN OUT VOID **DestinationBuffer,\r
1532 IN OUT UINTN *DestinationSize,\r
1533 IN VOID *SourceBuffer,\r
1534 IN UINTN SourceSize\r
1535 )\r
1536{\r
1537 UINTN LocalDestinationSize;\r
1538 UINTN LocalDestinationFinalSize;\r
1539\r
1540 ASSERT(DestinationBuffer != NULL);\r
1541\r
1542 if (SourceSize == 0 || SourceBuffer == NULL) {\r
1543 return (*DestinationBuffer);\r
1544 }\r
1545\r
1546 if (DestinationSize == NULL) {\r
1547 LocalDestinationSize = 0;\r
1548 } else {\r
1549 LocalDestinationSize = *DestinationSize;\r
1550 }\r
1551\r
1552 LocalDestinationFinalSize = LocalDestinationSize + SourceSize;\r
1553\r
1554 if (DestinationSize != NULL) {\r
1555 *DestinationSize = LocalDestinationSize;\r
1556 }\r
1557\r
1558 if (LocalDestinationSize == 0) {\r
1559 // allcoate\r
78ed876b 1560 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);\r
a405b86d 1561 } else {\r
1562 // reallocate\r
1563 *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);\r
1564 }\r
1565\r
1566 ASSERT(*DestinationBuffer != NULL);\r
1567\r
1568 // copy\r
1569 return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));\r
1570}\r
1571\r
1572/**\r
1573 Gets handles for any child devices produced by the passed in driver.\r
1574\r
1575 @param[in] DriverHandle The handle of the driver.\r
1576 @param[in] MatchingHandleCount Pointer to the number of handles in\r
1577 MatchingHandleBuffer on return.\r
1578 @param[out] MatchingHandleBuffer Buffer containing handles on a successful\r
1579 return.\r
1580 @retval EFI_SUCCESS The operation was sucessful.\r
1581 @sa ParseHandleDatabaseByRelationship\r
1582**/\r
1583EFI_STATUS\r
1584EFIAPI\r
1585ParseHandleDatabaseForChildDevices(\r
1586 IN CONST EFI_HANDLE DriverHandle,\r
1587 IN UINTN *MatchingHandleCount,\r
1588 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1589 )\r
1590{\r
1591 EFI_HANDLE *Buffer;\r
1592 EFI_HANDLE *Buffer2;\r
1593 UINTN Count1;\r
1594 UINTN Count2;\r
1595 UINTN HandleIndex;\r
1596 EFI_STATUS Status;\r
1597 UINTN HandleBufferSize;\r
1598\r
1599 ASSERT(MatchingHandleCount != NULL);\r
1600\r
1601 HandleBufferSize = 0;\r
1602 Buffer = NULL;\r
1603 Buffer2 = NULL;\r
1604 *MatchingHandleCount = 0;\r
1605\r
1606 Status = PARSE_HANDLE_DATABASE_DEVICES (\r
1607 DriverHandle,\r
1608 &Count1,\r
1609 &Buffer\r
1610 );\r
1611 if (!EFI_ERROR (Status)) {\r
1612 for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {\r
1613 //\r
1614 // now find the children\r
1615 //\r
1616 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
1617 DriverHandle,\r
1618 Buffer[HandleIndex],\r
1619 &Count2,\r
1620 &Buffer2\r
1621 );\r
1622 if (EFI_ERROR(Status)) {\r
1623 break;\r
1624 }\r
1625 //\r
1626 // save out required and optional data elements\r
1627 //\r
1628 *MatchingHandleCount += Count2;\r
1629 if (MatchingHandleBuffer != NULL) {\r
1630 *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));\r
1631 }\r
1632\r
1633 //\r
1634 // free the memory\r
1635 //\r
1636 if (Buffer2 != NULL) {\r
1637 FreePool(Buffer2);\r
1638 }\r
1639 }\r
1640 }\r
1641\r
1642 if (Buffer != NULL) {\r
1643 FreePool(Buffer);\r
1644 }\r
1645 return (Status);\r
1646}\r
1647\r
1648/**\r
1649 Function to get all handles that support a given protocol or all handles.\r
1650\r
1651 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL\r
1652 then the function will return all handles.\r
1653\r
1654 @retval NULL A memory allocation failed.\r
1655 @return A NULL terminated list of handles.\r
1656**/\r
1657EFI_HANDLE*\r
1658EFIAPI\r
40d7a9cf 1659GetHandleListByProtocol (\r
a405b86d 1660 IN CONST EFI_GUID *ProtocolGuid OPTIONAL\r
1661 )\r
1662{\r
1663 EFI_HANDLE *HandleList;\r
1664 UINTN Size;\r
1665 EFI_STATUS Status;\r
1666\r
1667 Size = 0;\r
1668 HandleList = NULL;\r
1669\r
1670 //\r
1671 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!\r
1672 //\r
1673 if (ProtocolGuid == NULL) {\r
1674 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);\r
1675 if (Status == EFI_BUFFER_TOO_SMALL) {\r
78ed876b 1676 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
40d7a9cf 1677 if (HandleList == NULL) {\r
1678 return (NULL);\r
1679 }\r
a405b86d 1680 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);\r
1681 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;\r
1682 }\r
1683 } else {\r
1684 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);\r
1685 if (Status == EFI_BUFFER_TOO_SMALL) {\r
78ed876b 1686 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
40d7a9cf 1687 if (HandleList == NULL) {\r
1688 return (NULL);\r
1689 }\r
a405b86d 1690 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);\r
1691 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;\r
1692 }\r
1693 }\r
1694 if (EFI_ERROR(Status)) {\r
1695 if (HandleList != NULL) {\r
1696 FreePool(HandleList);\r
1697 }\r
1698 return (NULL);\r
1699 }\r
1700 return (HandleList);\r
1701}\r
1702\r
1703/**\r
1704 Function to get all handles that support some protocols.\r
1705\r
1706 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.\r
1707\r
1708 @retval NULL A memory allocation failed.\r
ff51746b 1709 @retval NULL ProtocolGuids was NULL.\r
1710 @return A NULL terminated list of EFI_HANDLEs.\r
a405b86d 1711**/\r
1712EFI_HANDLE*\r
1713EFIAPI\r
40d7a9cf 1714GetHandleListByProtocolList (\r
a405b86d 1715 IN CONST EFI_GUID **ProtocolGuids\r
1716 )\r
1717{\r
1718 EFI_HANDLE *HandleList;\r
1719 UINTN Size;\r
1720 UINTN TotalSize;\r
40d7a9cf 1721 UINTN TempSize;\r
a405b86d 1722 EFI_STATUS Status;\r
1723 CONST EFI_GUID **GuidWalker;\r
1724 EFI_HANDLE *HandleWalker1;\r
1725 EFI_HANDLE *HandleWalker2;\r
1726\r
1727 Size = 0;\r
1728 HandleList = NULL;\r
1729 TotalSize = sizeof(EFI_HANDLE);\r
1730\r
1731 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){\r
1732 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);\r
1733 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1734 TotalSize += Size;\r
1735 }\r
1736 }\r
40d7a9cf 1737\r
1738 //\r
1739 // No handles were found... \r
1740 //\r
1741 if (TotalSize == sizeof(EFI_HANDLE)) {\r
1742 return (NULL);\r
1743 }\r
1744\r
1745 HandleList = AllocateZeroPool(TotalSize);\r
a405b86d 1746 if (HandleList == NULL) {\r
1747 return (NULL);\r
1748 }\r
1749\r
1750 Size = 0;\r
1751 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){\r
40d7a9cf 1752 TempSize = TotalSize - Size;\r
ff51746b 1753 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));\r
40d7a9cf 1754\r
1755 //\r
1756 // Allow for missing protocols... Only update the 'used' size upon success.\r
1757 //\r
1758 if (!EFI_ERROR(Status)) {\r
ff51746b 1759 Size += TempSize;\r
40d7a9cf 1760 }\r
a405b86d 1761 }\r
ff51746b 1762 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);\r
a405b86d 1763\r
1764 for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {\r
1765 for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {\r
1766 if (*HandleWalker1 == *HandleWalker2) {\r
1767 //\r
1768 // copy memory back 1 handle width.\r
1769 //\r
1770 CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));\r
1771 }\r
1772 }\r
1773 }\r
1774\r
1775 return (HandleList);\r
1776}\r
1777\r
1778\r
1779\r
1780\r
1781\r
1782\r
1783\r
1784\r
1785\r
1786\r