]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
ShellPkg: Skip leading tabs when processing command line and scripts
[mirror_edk2.git] / ShellPkg / Library / UefiHandleParsingLib / UefiHandleParsingLib.c
... / ...
CommitLineData
1/** @file\r
2 Provides interface to advanced shell functionality for parsing both handle and protocol database.\r
3\r
4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
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
16#include "IndustryStandard/Acpi10.h"\r
17\r
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
36 mHandleParsingHiiHandle = HiiAddPackages (&gHandleParsingHiiGuid, gImageHandle, UefiHandleParsingLibStrings, NULL);\r
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
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
206 ASSERT (Temp != NULL);\r
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
213 ASSERT (Temp != NULL);\r
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
225 ASSERT (Temp != NULL); \r
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
233 ASSERT (Temp != NULL);\r
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
245 ASSERT (Temp != NULL);\r
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
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
334 if (Temp != NULL) {\r
335 UnicodeSPrint(RetVal, Size, Temp, Dev, Dev->Mode->Attribute);\r
336 FreePool(Temp);\r
337 }\r
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
349 Temp == NULL?L"":Temp,\r
350 Index == Dev->Mode->Mode ? L'*' : L' ',\r
351 Index,\r
352 !EFI_ERROR(Status)?(INTN)Col:-1,\r
353 !EFI_ERROR(Status)?(INTN)Row:-1\r
354 );\r
355 }\r
356 FreePool(Temp);\r
357 return (RetVal);\r
358}\r
359\r
360STATIC CONST UINTN VersionStringSize = 60;\r
361\r
362/**\r
363 Function to dump information about EfiDriverSupportedEfiVersion protocol.\r
364\r
365 This will allocate the return buffer from boot services pool.\r
366\r
367 @param[in] TheHandle The handle that has the protocol installed.\r
368 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
369\r
370 @retval A poitner to a string containing the information.\r
371**/\r
372CHAR16*\r
373EFIAPI\r
374DriverEfiVersionProtocolDumpInformation(\r
375 IN CONST EFI_HANDLE TheHandle,\r
376 IN CONST BOOLEAN Verbose\r
377 )\r
378{\r
379 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;\r
380 EFI_STATUS Status;\r
381 CHAR16 *RetVal;\r
382\r
383 Status = gBS->HandleProtocol(\r
384 TheHandle,\r
385 &gEfiDriverSupportedEfiVersionProtocolGuid,\r
386 (VOID**)&DriverEfiVersion);\r
387\r
388 ASSERT_EFI_ERROR(Status);\r
389\r
390 RetVal = AllocateZeroPool(VersionStringSize);\r
391 ASSERT(RetVal != NULL);\r
392 UnicodeSPrint(RetVal, VersionStringSize, L"0x%08x", DriverEfiVersion->FirmwareVersion);\r
393 return (RetVal);\r
394}\r
395\r
396/**\r
397 Function to dump information about DevicePath protocol.\r
398\r
399 This will allocate the return buffer from boot services pool.\r
400\r
401 @param[in] TheHandle The handle that has the protocol installed.\r
402 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
403\r
404 @retval A poitner to a string containing the information.\r
405**/\r
406CHAR16*\r
407EFIAPI\r
408DevicePathProtocolDumpInformation(\r
409 IN CONST EFI_HANDLE TheHandle,\r
410 IN CONST BOOLEAN Verbose\r
411 )\r
412{\r
413 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
414 CHAR16 *Temp;\r
415 CHAR16 *Temp2;\r
416 EFI_STATUS Status;\r
417 Temp = NULL;\r
418\r
419 Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
420 if (!EFI_ERROR(Status)) {\r
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
426 }\r
427 if (!Verbose && Temp != NULL && StrLen(Temp) > 30) {\r
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
441 0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
442 }\r
443\r
444#define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \\r
445 { \\r
446 0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
447 }\r
448\r
449#define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \\r
450 { \\r
451 0xc95a93d, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
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
457STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {\r
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
464STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {\r
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
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
505 {STRING_TOKEN(STR_PCIRB_IO), &gEfiPciRootBridgeIoProtocolGuid, PciRootBridgeIoDumpInformation},\r
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
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
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
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
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
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
638CONST GUID_INFO_BLOCK *\r
639EFIAPI\r
640InternalShellGetNodeFromGuid(\r
641 IN CONST EFI_GUID* Guid\r
642 )\r
643{\r
644 CONST GUID_INFO_BLOCK *ListWalker;\r
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
681 CONST GUID_INFO_BLOCK *Id;\r
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
711 CONST GUID_INFO_BLOCK *Id;\r
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
744 CONST GUID_INFO_BLOCK *ListWalker;\r
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
778/**\r
779 Get best support language for this driver.\r
780 \r
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
784\r
785 @param[in] SupportedLanguages The support languages for this driver.\r
786 @param[in] InputLanguage The user input language.\r
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
792EFIAPI\r
793GetBestLanguageForDriver (\r
794 IN CONST CHAR8 *SupportedLanguages,\r
795 IN CONST CHAR8 *InputLanguage,\r
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
807 (InputLanguage != NULL) ? InputLanguage : "",\r
808 (LanguageVariable != NULL) ? LanguageVariable : "",\r
809 SupportedLanguages,\r
810 NULL\r
811 );\r
812\r
813 if (LanguageVariable != NULL) {\r
814 FreePool (LanguageVariable);\r
815 }\r
816\r
817 return BestLanguage;\r
818}\r
819\r
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
840 CHAR8 *BestLang;\r
841\r
842 BestLang = NULL;\r
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
852 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);\r
853 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);\r
854 if (BestLang != NULL) {\r
855 FreePool (BestLang);\r
856 BestLang = NULL;\r
857 }\r
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
870 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);\r
871 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);\r
872 if (BestLang != NULL) {\r
873 FreePool (BestLang);\r
874 }\r
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
916 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
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
943 EFI_STATUS Status;\r
944 EFI_GUID **ProtocolBuffer;\r
945 UINTN ProtocolCount;\r
946 HANDLE_LIST *ListWalker;\r
947\r
948 if (TheHandle == NULL) {\r
949 return 0;\r
950 }\r
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
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
971 return (ListWalker->TheIndex);\r
972 }\r
973 }\r
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
987 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
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
1012 EFI_STATUS Status;\r
1013 EFI_GUID **ProtocolBuffer;\r
1014 UINTN ProtocolCount;\r
1015 HANDLE_LIST *ListWalker;\r
1016\r
1017 InternalShellInitHandleList();\r
1018\r
1019 if (TheIndex >= mHandleList.NextIndex) {\r
1020 return NULL;\r
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
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
1038 return (ListWalker->TheHandle);\r
1039 }\r
1040 }\r
1041 return NULL;\r
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
1089 INTN DriverBindingHandleIndex;\r
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
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
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
1133 if (EFI_ERROR (Status)) {\r
1134 continue;\r
1135 }\r
1136\r
1137 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
1138\r
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
1169 (*HandleBuffer)[HandleIndex],\r
1170 ProtocolGuidArray[ProtocolIndex],\r
1171 &OpenInfo,\r
1172 &OpenInfoCount\r
1173 );\r
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
1206 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
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
1212 }\r
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
1221 }\r
1222 }\r
1223 }\r
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
1243 }\r
1244 }\r
1245 }\r
1246 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1247 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
1248 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1249 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1250 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
1251 }\r
1252 }\r
1253 }\r
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
1268 }\r
1269 }\r
1270 }\r
1271 }\r
1272 FreePool (OpenInfo);\r
1273 }\r
1274 FreePool (ProtocolGuidArray);\r
1275 }\r
1276 return EFI_SUCCESS;\r
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
1374 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));\r
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
1431 UINTN HandleIndex;\r
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
1438 EFI_HANDLE *HandleBufferForReturn;\r
1439\r
1440 if (MatchingHandleCount == NULL) {\r
1441 return (EFI_INVALID_PARAMETER);\r
1442 }\r
1443 *MatchingHandleCount = 0;\r
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
1454 //\r
1455 // Get a buffer big enough for all the controllers.\r
1456 //\r
1457 HandleBufferForReturn = GetHandleListByProtocol(NULL);\r
1458 if (HandleBufferForReturn == NULL) {\r
1459 FreePool (DriverBindingHandleBuffer);\r
1460 return (EFI_NOT_FOUND);\r
1461 }\r
1462\r
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
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
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
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
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
1549 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);\r
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
1648GetHandleListByProtocol (\r
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
1665 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
1666 if (HandleList == NULL) {\r
1667 return (NULL);\r
1668 }\r
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
1675 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
1676 if (HandleList == NULL) {\r
1677 return (NULL);\r
1678 }\r
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
1698 @retval NULL ProtocolGuids was NULL.\r
1699 @return A NULL terminated list of EFI_HANDLEs.\r
1700**/\r
1701EFI_HANDLE*\r
1702EFIAPI\r
1703GetHandleListByProtocolList (\r
1704 IN CONST EFI_GUID **ProtocolGuids\r
1705 )\r
1706{\r
1707 EFI_HANDLE *HandleList;\r
1708 UINTN Size;\r
1709 UINTN TotalSize;\r
1710 UINTN TempSize;\r
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
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
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
1741 TempSize = TotalSize - Size;\r
1742 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));\r
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
1748 Size += TempSize;\r
1749 }\r
1750 }\r
1751 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);\r
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