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