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