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