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