]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
ArmPlatformPkg/ArmVExpressLibRTSM: Added support for the additional 2GB memory of...
[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) 2013 Hewlett-Packard Development Company, L.P.\r
5 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
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
17#include "IndustryStandard/Acpi10.h"\r
18\r
19EFI_HANDLE mHandleParsingHiiHandle;\r
20HANDLE_INDEX_LIST mHandleList = {{{NULL,NULL},0,0},0};\r
21\r
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
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
74 mHandleParsingHiiHandle = HiiAddPackages (&gHandleParsingHiiGuid, gImageHandle, UefiHandleParsingLibStrings, NULL);\r
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
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
113CHAR16*\r
114EFIAPI\r
115LoadedImageProtocolDumpInformation(\r
116 IN CONST EFI_HANDLE TheHandle,\r
117 IN CONST BOOLEAN Verbose\r
118 )\r
119{\r
120 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
121 EFI_STATUS Status;\r
122 CHAR16 *RetVal;\r
123 CHAR16 *Temp;\r
124 CHAR16 *CodeType;\r
125 CHAR16 *DataType;\r
126\r
127 if (!Verbose) {\r
128 return (CatSPrint(NULL, L"LoadedImage"));\r
129 }\r
130\r
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
137 }\r
138\r
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
172}\r
173\r
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
216 ASSERT (Temp != NULL);\r
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
223 ASSERT (Temp != NULL);\r
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
235 ASSERT (Temp != NULL); \r
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
243 ASSERT (Temp != NULL);\r
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
255 ASSERT (Temp != NULL);\r
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
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
344 if (Temp != NULL) {\r
345 UnicodeSPrint(RetVal, Size, Temp, Dev, Dev->Mode->Attribute);\r
346 FreePool(Temp);\r
347 }\r
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
359 Temp == NULL?L"":Temp,\r
360 Index == Dev->Mode->Mode ? L'*' : L' ',\r
361 Index,\r
362 !EFI_ERROR(Status)?(INTN)Col:-1,\r
363 !EFI_ERROR(Status)?(INTN)Row:-1\r
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
400 RetVal = AllocateZeroPool(VersionStringSize);\r
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
427 Temp = NULL;\r
428\r
429 Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
430 if (!EFI_ERROR(Status)) {\r
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
436 }\r
437 if (!Verbose && Temp != NULL && StrLen(Temp) > 30) {\r
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
451 0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
452 }\r
453\r
454#define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \\r
455 { \\r
456 0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
457 }\r
458\r
459#define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \\r
460 { \\r
461 0xc95a93d, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \\r
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
467STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {\r
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
474STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {\r
475 {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, LoadedImageProtocolDumpInformation},\r
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
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
515 {STRING_TOKEN(STR_PCIRB_IO), &gEfiPciRootBridgeIoProtocolGuid, PciRootBridgeIoDumpInformation},\r
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
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
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
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
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
631 {STRING_TOKEN(STR_UCRED2), &gEfiUserCredential2ProtocolGuid, NULL},\r
632\r
633//\r
634// UEFI 2.4\r
635//\r
636 {STRING_TOKEN(STR_DISK_IO2), &gEfiDiskIo2ProtocolGuid, NULL},\r
637\r
638//\r
639// PI Spec ones\r
640//\r
641 {STRING_TOKEN(STR_IDE_CONT_INIT), &gEfiIdeControllerInitProtocolGuid, NULL},\r
642\r
643//\r
644// terminator\r
645//\r
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
658CONST GUID_INFO_BLOCK *\r
659EFIAPI\r
660InternalShellGetNodeFromGuid(\r
661 IN CONST EFI_GUID* Guid\r
662 )\r
663{\r
664 CONST GUID_INFO_BLOCK *ListWalker;\r
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
701 CONST GUID_INFO_BLOCK *Id;\r
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
731 CONST GUID_INFO_BLOCK *Id;\r
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
764 CONST GUID_INFO_BLOCK *ListWalker;\r
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
776 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {\r
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
787 if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {\r
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
798/**\r
799 Get best support language for this driver.\r
800 \r
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
804\r
805 @param[in] SupportedLanguages The support languages for this driver.\r
806 @param[in] InputLanguage The user input language.\r
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
812EFIAPI\r
813GetBestLanguageForDriver (\r
814 IN CONST CHAR8 *SupportedLanguages,\r
815 IN CONST CHAR8 *InputLanguage,\r
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
827 (InputLanguage != NULL) ? InputLanguage : "",\r
828 (LanguageVariable != NULL) ? LanguageVariable : "",\r
829 SupportedLanguages,\r
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
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
860 CHAR8 *BestLang;\r
861\r
862 BestLang = NULL;\r
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
872 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);\r
873 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);\r
874 if (BestLang != NULL) {\r
875 FreePool (BestLang);\r
876 BestLang = NULL;\r
877 }\r
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
890 BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);\r
891 Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);\r
892 if (BestLang != NULL) {\r
893 FreePool (BestLang);\r
894 }\r
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
936 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
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
963 EFI_STATUS Status;\r
964 EFI_GUID **ProtocolBuffer;\r
965 UINTN ProtocolCount;\r
966 HANDLE_LIST *ListWalker;\r
967\r
968 if (TheHandle == NULL) {\r
969 return 0;\r
970 }\r
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
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
991 return (ListWalker->TheIndex);\r
992 }\r
993 }\r
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
1007 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
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
1032 EFI_STATUS Status;\r
1033 EFI_GUID **ProtocolBuffer;\r
1034 UINTN ProtocolCount;\r
1035 HANDLE_LIST *ListWalker;\r
1036\r
1037 InternalShellInitHandleList();\r
1038\r
1039 if (TheIndex >= mHandleList.NextIndex) {\r
1040 return NULL;\r
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
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
1058 return (ListWalker->TheHandle);\r
1059 }\r
1060 }\r
1061 return NULL;\r
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
1109 INTN DriverBindingHandleIndex;\r
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
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
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
1153 if (EFI_ERROR (Status)) {\r
1154 continue;\r
1155 }\r
1156\r
1157 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
1158\r
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
1189 (*HandleBuffer)[HandleIndex],\r
1190 ProtocolGuidArray[ProtocolIndex],\r
1191 &OpenInfo,\r
1192 &OpenInfoCount\r
1193 );\r
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
1226 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
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
1232 }\r
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
1241 }\r
1242 }\r
1243 }\r
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
1263 }\r
1264 }\r
1265 }\r
1266 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
1267 if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
1268 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
1269 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {\r
1270 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
1271 }\r
1272 }\r
1273 }\r
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
1288 }\r
1289 }\r
1290 }\r
1291 }\r
1292 FreePool (OpenInfo);\r
1293 }\r
1294 FreePool (ProtocolGuidArray);\r
1295 }\r
1296 return EFI_SUCCESS;\r
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
1394 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));\r
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
1451 UINTN HandleIndex;\r
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
1458 EFI_HANDLE *HandleBufferForReturn;\r
1459\r
1460 if (MatchingHandleCount == NULL) {\r
1461 return (EFI_INVALID_PARAMETER);\r
1462 }\r
1463 *MatchingHandleCount = 0;\r
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
1474 //\r
1475 // Get a buffer big enough for all the controllers.\r
1476 //\r
1477 HandleBufferForReturn = GetHandleListByProtocol(NULL);\r
1478 if (HandleBufferForReturn == NULL) {\r
1479 FreePool (DriverBindingHandleBuffer);\r
1480 return (EFI_NOT_FOUND);\r
1481 }\r
1482\r
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
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
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
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
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
1569 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);\r
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
1668GetHandleListByProtocol (\r
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
1685 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
1686 if (HandleList == NULL) {\r
1687 return (NULL);\r
1688 }\r
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
1695 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
1696 if (HandleList == NULL) {\r
1697 return (NULL);\r
1698 }\r
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
1718 @retval NULL ProtocolGuids was NULL.\r
1719 @return A NULL terminated list of EFI_HANDLEs.\r
1720**/\r
1721EFI_HANDLE*\r
1722EFIAPI\r
1723GetHandleListByProtocolList (\r
1724 IN CONST EFI_GUID **ProtocolGuids\r
1725 )\r
1726{\r
1727 EFI_HANDLE *HandleList;\r
1728 UINTN Size;\r
1729 UINTN TotalSize;\r
1730 UINTN TempSize;\r
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
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
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
1761 TempSize = TotalSize - Size;\r
1762 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));\r
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
1768 Size += TempSize;\r
1769 }\r
1770 }\r
1771 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);\r
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