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