DuetPkg BootSector: Clean up .S files for 64-bit Duet for GCC build.
[mirror_edk2.git] / ShellPkg / Library / UefiHandleParsingLib / UefiHandleParsingLib.c
CommitLineData
a405b86d 1/** @file\r
2 Provides interface to advanced shell functionality for parsing both handle and protocol database.\r
3\r
dee34318 4 Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
a405b86d 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiHandleParsingLib.h"\r
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
ecae5117 209 if (Temp != NULL) {\r
210 UnicodeSPrint(RetVal, Size, Temp, Dev, Dev->Mode->Attribute);\r
211 FreePool(Temp);\r
212 }\r
a405b86d 213\r
214 //\r
215 // Dump TextOut Info\r
216 //\r
217 Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_LINE), NULL);\r
218 for (Index = 0; Index < Dev->Mode->MaxMode; Index++) {\r
219 Status = Dev->QueryMode (Dev, Index, &Col, &Row);\r
220 NewSize = Size - StrSize(RetVal);\r
221 UnicodeSPrint(\r
222 RetVal + StrLen(RetVal),\r
223 NewSize,\r
ecae5117 224 Temp == NULL?L"":Temp,\r
a405b86d 225 Index == Dev->Mode->Mode ? L'*' : L' ',\r
226 Index,\r
227 !EFI_ERROR(Status)?Col:-1,\r
228 !EFI_ERROR(Status)?Row:-1\r
229 );\r
230 }\r
231 FreePool(Temp);\r
232 return (RetVal);\r
233}\r
234\r
235STATIC CONST UINTN VersionStringSize = 60;\r
236\r
237/**\r
238 Function to dump information about EfiDriverSupportedEfiVersion protocol.\r
239\r
240 This will allocate the return buffer from boot services pool.\r
241\r
242 @param[in] TheHandle The handle that has the protocol installed.\r
243 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
244\r
245 @retval A poitner to a string containing the information.\r
246**/\r
247CHAR16*\r
248EFIAPI\r
249DriverEfiVersionProtocolDumpInformation(\r
250 IN CONST EFI_HANDLE TheHandle,\r
251 IN CONST BOOLEAN Verbose\r
252 )\r
253{\r
254 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;\r
255 EFI_STATUS Status;\r
256 CHAR16 *RetVal;\r
257\r
258 Status = gBS->HandleProtocol(\r
259 TheHandle,\r
260 &gEfiDriverSupportedEfiVersionProtocolGuid,\r
261 (VOID**)&DriverEfiVersion);\r
262\r
263 ASSERT_EFI_ERROR(Status);\r
264\r
78ed876b 265 RetVal = AllocateZeroPool(VersionStringSize);\r
a405b86d 266 ASSERT(RetVal != NULL);\r
267 UnicodeSPrint(RetVal, VersionStringSize, L"0x%08x", DriverEfiVersion->FirmwareVersion);\r
268 return (RetVal);\r
269}\r
270\r
271/**\r
272 Function to dump information about DevicePath protocol.\r
273\r
274 This will allocate the return buffer from boot services pool.\r
275\r
276 @param[in] TheHandle The handle that has the protocol installed.\r
277 @param[in] Verbose TRUE for additional information, FALSE otherwise.\r
278\r
279 @retval A poitner to a string containing the information.\r
280**/\r
281CHAR16*\r
282EFIAPI\r
283DevicePathProtocolDumpInformation(\r
284 IN CONST EFI_HANDLE TheHandle,\r
285 IN CONST BOOLEAN Verbose\r
286 )\r
287{\r
288 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
289 CHAR16 *Temp;\r
290 CHAR16 *Temp2;\r
291 EFI_STATUS Status;\r
292 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
293 Temp = NULL;\r
294\r
295 Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID**)&DevPathToText);\r
296 if (!EFI_ERROR(Status)) {\r
297 Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
298 if (!EFI_ERROR(Status)) {\r
299 //\r
300 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)\r
301 //\r
302 Temp = DevPathToText->ConvertDevicePathToText(DevPath, TRUE, TRUE);\r
303 gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);\r
304 }\r
305 }\r
78ed876b 306 if (!Verbose && Temp != NULL && StrLen(Temp) > 30) {\r
a405b86d 307 Temp2 = NULL;\r
308 Temp2 = StrnCatGrow(&Temp2, NULL, Temp+(StrLen(Temp) - 30), 30);\r
309 FreePool(Temp);\r
310 Temp = Temp2;\r
311 }\r
312 return (Temp);\r
313}\r
314\r
315//\r
316// Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg\r
317//\r
318#define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \\r
319 { \\r
320 0x58c518b1, 0x76f3, 0x11d4, 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \\r
321 }\r
322\r
323#define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \\r
324 { \\r
325 0x96eb4ad6, 0xa32a, 0x11d4, 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \\r
326 }\r
327\r
328#define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \\r
329 { \\r
330 0xc95a93d, 0xa006, 0x11d4, 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \\r
331 }\r
332STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID;\r
333STATIC CONST EFI_GUID WinNtIoProtocolGuid = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;\r
334STATIC CONST EFI_GUID WinNtSerialPortGuid = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;\r
335\r
dee34318 336STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {\r
a405b86d 337 {STRING_TOKEN(STR_WINNT_THUNK), (EFI_GUID*)&WinNtThunkProtocolGuid, NULL},\r
338 {STRING_TOKEN(STR_WINNT_DRIVER_IO), (EFI_GUID*)&WinNtIoProtocolGuid, NULL},\r
339 {STRING_TOKEN(STR_WINNT_SERIAL_PORT), (EFI_GUID*)&WinNtSerialPortGuid, NULL},\r
340 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},\r
341};\r
342\r
dee34318 343STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {\r
a405b86d 344 {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, NULL},\r
345 {STRING_TOKEN(STR_DEVICE_PATH), &gEfiDevicePathProtocolGuid, DevicePathProtocolDumpInformation},\r
346 {STRING_TOKEN(STR_IMAGE_PATH), &gEfiLoadedImageDevicePathProtocolGuid, DevicePathProtocolDumpInformation},\r
347 {STRING_TOKEN(STR_DEVICE_PATH_UTIL), &gEfiDevicePathUtilitiesProtocolGuid, NULL},\r
348 {STRING_TOKEN(STR_DEVICE_PATH_TXT), &gEfiDevicePathToTextProtocolGuid, NULL},\r
349 {STRING_TOKEN(STR_DEVICE_PATH_FTXT), &gEfiDevicePathFromTextProtocolGuid, NULL},\r
350 {STRING_TOKEN(STR_DEVICE_PATH_PC), &gEfiPcAnsiGuid, NULL},\r
351 {STRING_TOKEN(STR_DEVICE_PATH_VT100), &gEfiVT100Guid, NULL},\r
352 {STRING_TOKEN(STR_DEVICE_PATH_VT100P), &gEfiVT100PlusGuid, NULL},\r
353 {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8), &gEfiVTUTF8Guid, NULL},\r
354 {STRING_TOKEN(STR_DRIVER_BINDING), &gEfiDriverBindingProtocolGuid, NULL},\r
355 {STRING_TOKEN(STR_PLATFORM_OVERRIDE), &gEfiPlatformDriverOverrideProtocolGuid, NULL},\r
356 {STRING_TOKEN(STR_BUS_OVERRIDE), &gEfiBusSpecificDriverOverrideProtocolGuid, NULL},\r
357 {STRING_TOKEN(STR_DRIVER_DIAG), &gEfiDriverDiagnosticsProtocolGuid, NULL},\r
358 {STRING_TOKEN(STR_DRIVER_DIAG2), &gEfiDriverDiagnostics2ProtocolGuid, NULL},\r
359 {STRING_TOKEN(STR_DRIVER_CN), &gEfiComponentNameProtocolGuid, NULL},\r
360 {STRING_TOKEN(STR_DRIVER_CN2), &gEfiComponentName2ProtocolGuid, NULL},\r
361 {STRING_TOKEN(STR_PLAT_DRV_CFG), &gEfiPlatformToDriverConfigurationProtocolGuid, NULL},\r
362 {STRING_TOKEN(STR_DRIVER_VERSION), &gEfiDriverSupportedEfiVersionProtocolGuid, DriverEfiVersionProtocolDumpInformation},\r
363 {STRING_TOKEN(STR_TXT_IN), &gEfiSimpleTextInProtocolGuid, NULL},\r
364 {STRING_TOKEN(STR_TXT_IN_EX), &gEfiSimpleTextInputExProtocolGuid, NULL},\r
365 {STRING_TOKEN(STR_TXT_OUT), &gEfiSimpleTextOutProtocolGuid, TxtOutProtocolDumpInformation},\r
366 {STRING_TOKEN(STR_SIM_POINTER), &gEfiSimplePointerProtocolGuid, NULL},\r
367 {STRING_TOKEN(STR_ABS_POINTER), &gEfiAbsolutePointerProtocolGuid, NULL},\r
368 {STRING_TOKEN(STR_SERIAL_IO), &gEfiSerialIoProtocolGuid, NULL},\r
369 {STRING_TOKEN(STR_GRAPHICS_OUTPUT), &gEfiGraphicsOutputProtocolGuid, NULL},\r
370 {STRING_TOKEN(STR_EDID_DISCOVERED), &gEfiEdidDiscoveredProtocolGuid, NULL},\r
371 {STRING_TOKEN(STR_EDID_ACTIVE), &gEfiEdidActiveProtocolGuid, NULL},\r
372 {STRING_TOKEN(STR_EDID_OVERRIDE), &gEfiEdidOverrideProtocolGuid, NULL},\r
373 {STRING_TOKEN(STR_CON_IN), &gEfiConsoleInDeviceGuid, NULL},\r
374 {STRING_TOKEN(STR_CON_OUT), &gEfiConsoleOutDeviceGuid, NULL},\r
375 {STRING_TOKEN(STR_STD_ERR), &gEfiStandardErrorDeviceGuid, NULL},\r
376 {STRING_TOKEN(STR_LOAD_FILE), &gEfiLoadFileProtocolGuid, NULL},\r
377 {STRING_TOKEN(STR_LOAD_FILE2), &gEfiLoadFile2ProtocolGuid, NULL},\r
378 {STRING_TOKEN(STR_SIMPLE_FILE_SYS), &gEfiSimpleFileSystemProtocolGuid, NULL},\r
a405b86d 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
a405b86d 417 {STRING_TOKEN(STR_UDPV4_SB), &gEfiUdp4ServiceBindingProtocolGuid, NULL},\r
418 {STRING_TOKEN(STR_UDPV4), &gEfiUdp4ProtocolGuid, NULL},\r
419 {STRING_TOKEN(STR_MTFTPV4_SB), &gEfiMtftp4ServiceBindingProtocolGuid, NULL},\r
420 {STRING_TOKEN(STR_MTFTPV4), &gEfiMtftp4ProtocolGuid, NULL},\r
421 {STRING_TOKEN(STR_AUTH_INFO), &gEfiAuthenticationInfoProtocolGuid, NULL},\r
422 {STRING_TOKEN(STR_HASH_SB), &gEfiHashServiceBindingProtocolGuid, NULL},\r
423 {STRING_TOKEN(STR_HASH), &gEfiHashProtocolGuid, NULL},\r
424 {STRING_TOKEN(STR_HII_FONT), &gEfiHiiFontProtocolGuid, NULL},\r
425 {STRING_TOKEN(STR_HII_STRING), &gEfiHiiStringProtocolGuid, NULL},\r
426 {STRING_TOKEN(STR_HII_IMAGE), &gEfiHiiImageProtocolGuid, NULL},\r
427 {STRING_TOKEN(STR_HII_DATABASE), &gEfiHiiDatabaseProtocolGuid, NULL},\r
428 {STRING_TOKEN(STR_HII_CONFIG_ROUT), &gEfiHiiConfigRoutingProtocolGuid, NULL},\r
429 {STRING_TOKEN(STR_HII_CONFIG_ACC), &gEfiHiiConfigAccessProtocolGuid, NULL},\r
430 {STRING_TOKEN(STR_HII_FORM_BROWSER2), &gEfiFormBrowser2ProtocolGuid, NULL},\r
dee34318 431 {STRING_TOKEN(STR_DRIVER_FAM_OVERRIDE), &gEfiDriverFamilyOverrideProtocolGuid, NULL},\r
432 {STRING_TOKEN(STR_PCD), &gPcdProtocolGuid, NULL},\r
433 {STRING_TOKEN(STR_TCG), &gEfiTcgProtocolGuid, NULL},\r
434 {STRING_TOKEN(STR_HII_PACKAGE_LIST), &gEfiHiiPackageListProtocolGuid, NULL},\r
435\r
436//\r
437// the ones under this are deprecated by the current UEFI Spec, but may be found anyways...\r
438//\r
a405b86d 439 {STRING_TOKEN(STR_SHELL_INTERFACE), &gEfiShellInterfaceGuid, NULL},\r
440 {STRING_TOKEN(STR_SHELL_ENV2), &gEfiShellEnvironment2Guid, NULL},\r
441 {STRING_TOKEN(STR_SHELL_ENV), &gEfiShellEnvironment2Guid, NULL},\r
442 {STRING_TOKEN(STR_DEVICE_IO), &gEfiDeviceIoProtocolGuid, NULL},\r
443 {STRING_TOKEN(STR_UGA_DRAW), &gEfiUgaDrawProtocolGuid, NULL},\r
444 {STRING_TOKEN(STR_UGA_IO), &gEfiUgaIoProtocolGuid, NULL},\r
445 {STRING_TOKEN(STR_ESP), &gEfiPartTypeSystemPartGuid, NULL},\r
446 {STRING_TOKEN(STR_GPT_NBR), &gEfiPartTypeLegacyMbrGuid, NULL},\r
447 {STRING_TOKEN(STR_DRIVER_CONFIG), &gEfiDriverConfigurationProtocolGuid, NULL},\r
448 {STRING_TOKEN(STR_DRIVER_CONFIG2), &gEfiDriverConfiguration2ProtocolGuid, NULL},\r
dee34318 449\r
450//\r
451// the ones under this are GUID identified structs, not protocols\r
452//\r
453 {STRING_TOKEN(STR_FILE_INFO), &gEfiFileInfoGuid, NULL},\r
454 {STRING_TOKEN(STR_FILE_SYS_INFO), &gEfiFileSystemInfoGuid, NULL},\r
455\r
456//\r
457// the ones under this are misc GUIDS.\r
458//\r
459 {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE), &gEfiGlobalVariableGuid, NULL},\r
460\r
461//\r
462// UEFI 2.2\r
463//\r
464 {STRING_TOKEN(STR_IP6_SB), &gEfiIp6ServiceBindingProtocolGuid, NULL},\r
465 {STRING_TOKEN(STR_IP6), &gEfiIp6ProtocolGuid, NULL},\r
466 {STRING_TOKEN(STR_IP6_CONFIG), &gEfiIp6ConfigProtocolGuid, NULL},\r
467 {STRING_TOKEN(STR_MTFTP6_SB), &gEfiMtftp6ServiceBindingProtocolGuid, NULL},\r
468 {STRING_TOKEN(STR_MTFTP6), &gEfiMtftp6ProtocolGuid, NULL},\r
469 {STRING_TOKEN(STR_DHCP6_SB), &gEfiDhcp6ServiceBindingProtocolGuid, NULL},\r
470 {STRING_TOKEN(STR_DHCP6), &gEfiDhcp6ProtocolGuid, NULL},\r
471 {STRING_TOKEN(STR_UDP6_SB), &gEfiUdp6ServiceBindingProtocolGuid, NULL},\r
472 {STRING_TOKEN(STR_UDP6), &gEfiUdp6ProtocolGuid, NULL},\r
473 {STRING_TOKEN(STR_TCP6_SB), &gEfiTcp6ServiceBindingProtocolGuid, NULL},\r
474 {STRING_TOKEN(STR_TCP6), &gEfiTcp6ProtocolGuid, NULL},\r
475 {STRING_TOKEN(STR_VLAN_CONFIG), &gEfiVlanConfigProtocolGuid, NULL},\r
476 {STRING_TOKEN(STR_EAP), &gEfiEapProtocolGuid, NULL},\r
477 {STRING_TOKEN(STR_EAP_MGMT), &gEfiEapManagementProtocolGuid, NULL},\r
478 {STRING_TOKEN(STR_FTP4_SB), &gEfiFtp4ServiceBindingProtocolGuid, NULL},\r
479 {STRING_TOKEN(STR_FTP4), &gEfiFtp4ProtocolGuid, NULL},\r
480 {STRING_TOKEN(STR_IP_SEC_CONFIG), &gEfiIpSecConfigProtocolGuid, NULL},\r
481 {STRING_TOKEN(STR_DH), &gEfiDriverHealthProtocolGuid, NULL},\r
482 {STRING_TOKEN(STR_DEF_IMG_LOAD), &gEfiDeferredImageLoadProtocolGuid, NULL},\r
483 {STRING_TOKEN(STR_USER_CRED), &gEfiUserCredentialProtocolGuid, NULL},\r
484 {STRING_TOKEN(STR_USER_MNGR), &gEfiUserManagerProtocolGuid, NULL},\r
485 {STRING_TOKEN(STR_ATA_PASS_THRU), &gEfiAtaPassThruProtocolGuid, NULL},\r
486\r
487//\r
488// UEFI 2.3\r
489//\r
490 {STRING_TOKEN(STR_FW_MGMT), &gEfiFirmwareManagementProtocolGuid, NULL},\r
491 {STRING_TOKEN(STR_IP_SEC), &gEfiIpSecProtocolGuid, NULL},\r
492 {STRING_TOKEN(STR_IP_SEC2), &gEfiIpSec2ProtocolGuid, NULL},\r
493\r
494//\r
495// UEFI 2.3.1\r
496//\r
497 {STRING_TOKEN(STR_KMS), &gEfiKmsProtocolGuid, NULL},\r
498 {STRING_TOKEN(STR_BLK_IO2), &gEfiBlockIo2ProtocolGuid, NULL},\r
499 {STRING_TOKEN(STR_SSC), &gEfiStorageSecurityCommandProtocolGuid, NULL},\r
500 {STRING_TOKEN(STR_UC2), &gEfiUserCredential2ProtocolGuid, NULL},\r
501\r
502//\r
503// terminator\r
504//\r
a405b86d 505 {STRING_TOKEN(STR_UNKNOWN_DEVICE), NULL, NULL},\r
506};\r
507\r
508/**\r
509 Function to get the node for a protocol or struct from it's GUID.\r
510\r
511 if Guid is NULL, then ASSERT.\r
512\r
513 @param[in] Guid The GUID to look for the name of.\r
514\r
515 @return The node.\r
516**/\r
dee34318 517CONST GUID_INFO_BLOCK *\r
a405b86d 518EFIAPI\r
519InternalShellGetNodeFromGuid(\r
520 IN CONST EFI_GUID* Guid\r
521 )\r
522{\r
dee34318 523 CONST GUID_INFO_BLOCK *ListWalker;\r
a405b86d 524\r
525 ASSERT(Guid != NULL);\r
526\r
527 if (PcdGetBool(PcdShellIncludeNtGuids)) {\r
528 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
529 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
530 return (ListWalker);\r
531 }\r
532 }\r
533 }\r
534 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
535 if (CompareGuid(ListWalker->GuidId, Guid)) {\r
536 return (ListWalker);\r
537 }\r
538 }\r
539 return (ListWalker);\r
540}\r
541\r
542/**\r
543 Function to get the name of a protocol or struct from it's GUID.\r
544\r
545 if Guid is NULL, then ASSERT.\r
546\r
547 @param[in] Guid The GUID to look for the name of.\r
548 @param[in] Lang The language to use.\r
549\r
550 @return pointer to string of the name. The caller\r
551 is responsible to free this memory.\r
552**/\r
553CHAR16*\r
554EFIAPI\r
555GetStringNameFromGuid(\r
556 IN CONST EFI_GUID *Guid,\r
557 IN CONST CHAR8 *Lang OPTIONAL\r
558 )\r
559{\r
dee34318 560 CONST GUID_INFO_BLOCK *Id;\r
a405b86d 561\r
562 Id = InternalShellGetNodeFromGuid(Guid);\r
563 return (HiiGetString(mHandleParsingHiiHandle, Id->StringId, Lang));\r
564}\r
565\r
566/**\r
567 Function to dump protocol information from a handle.\r
568\r
569 This function will return a allocated string buffer containing the\r
570 information. The caller is responsible for freeing the memory.\r
571\r
572 If Guid is NULL, ASSERT().\r
573 If TheHandle is NULL, ASSERT().\r
574\r
575 @param[in] TheHandle The handle to dump information from.\r
576 @param[in] Guid The GUID of the protocol to dump.\r
577 @param[in] Verbose TRUE for extra info. FALSE otherwise.\r
578\r
579 @return The pointer to string.\r
580 @retval NULL An error was encountered.\r
581**/\r
582CHAR16*\r
583EFIAPI\r
584GetProtocolInformationDump(\r
585 IN CONST EFI_HANDLE TheHandle,\r
586 IN CONST EFI_GUID *Guid,\r
587 IN CONST BOOLEAN Verbose\r
588 )\r
589{\r
dee34318 590 CONST GUID_INFO_BLOCK *Id;\r
a405b86d 591\r
592 ASSERT(TheHandle != NULL);\r
593 ASSERT(Guid != NULL);\r
594\r
595 if (TheHandle == NULL || Guid == NULL) {\r
596 return (NULL);\r
597 }\r
598\r
599 Id = InternalShellGetNodeFromGuid(Guid);\r
600 if (Id != NULL && Id->DumpInfo != NULL) {\r
601 return (Id->DumpInfo(TheHandle, Verbose));\r
602 }\r
603 return (NULL);\r
604}\r
605\r
606/**\r
607 Function to get the Guid for a protocol or struct based on it's string name.\r
608\r
609 @param[in] Name The pointer to the string name.\r
610 @param[in] Lang The pointer to the language code.\r
611 @param[in] Guid The pointer to the Guid.\r
612\r
613 @retval EFI_SUCCESS The operation was sucessful.\r
614**/\r
615EFI_STATUS\r
616EFIAPI\r
617GetGuidFromStringName(\r
618 IN CONST CHAR16 *Name,\r
619 IN CONST CHAR8 *Lang OPTIONAL,\r
620 IN EFI_GUID **Guid\r
621 )\r
622{\r
dee34318 623 CONST GUID_INFO_BLOCK *ListWalker;\r
a405b86d 624 CHAR16 *String;\r
625\r
626 ASSERT(Guid != NULL);\r
627 if (Guid == NULL) {\r
628 return (EFI_INVALID_PARAMETER);\r
629 }\r
630 *Guid = NULL;\r
631\r
632 if (PcdGetBool(PcdShellIncludeNtGuids)) {\r
633 for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
634 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
635 if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {\r
636 *Guid = ListWalker->GuidId;\r
637 }\r
638 SHELL_FREE_NON_NULL(String);\r
639 if (*Guid != NULL) {\r
640 return (EFI_SUCCESS);\r
641 }\r
642 }\r
643 }\r
644 for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {\r
645 String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);\r
646 if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {\r
647 *Guid = ListWalker->GuidId;\r
648 }\r
649 SHELL_FREE_NON_NULL(String);\r
650 if (*Guid != NULL) {\r
651 return (EFI_SUCCESS);\r
652 }\r
653 }\r
654 return (EFI_NOT_FOUND);\r
655}\r
656\r
657/**\r
658 Function to retrieve the driver name (if possible) from the ComponentName or\r
659 ComponentName2 protocol\r
660\r
661 @param[in] TheHandle The driver handle to get the name of.\r
662 @param[in] Language The language to use.\r
663\r
664 @retval NULL The name could not be found.\r
665 @return A pointer to the string name. Do not de-allocate the memory.\r
666**/\r
667CONST CHAR16*\r
668EFIAPI\r
669GetStringNameFromHandle(\r
670 IN CONST EFI_HANDLE TheHandle,\r
671 IN CONST CHAR8 *Language\r
672 )\r
673{\r
674 EFI_COMPONENT_NAME2_PROTOCOL *CompNameStruct;\r
675 EFI_STATUS Status;\r
676 CHAR16 *RetVal;\r
677\r
678 Status = gBS->OpenProtocol(\r
679 TheHandle,\r
680 &gEfiComponentName2ProtocolGuid,\r
681 (VOID**)&CompNameStruct,\r
682 gImageHandle,\r
683 NULL,\r
684 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
685 if (!EFI_ERROR(Status)) {\r
686 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);\r
687 if (!EFI_ERROR(Status)) {\r
688 return (RetVal);\r
689 }\r
690 }\r
691 Status = gBS->OpenProtocol(\r
692 TheHandle,\r
693 &gEfiComponentNameProtocolGuid,\r
694 (VOID**)&CompNameStruct,\r
695 gImageHandle,\r
696 NULL,\r
697 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
698 if (!EFI_ERROR(Status)) {\r
699 Status = CompNameStruct->GetDriverName(CompNameStruct, (CHAR8*)Language, &RetVal);\r
700 if (!EFI_ERROR(Status)) {\r
701 return (RetVal);\r
702 }\r
703 }\r
704 return (NULL);\r
705}\r
706\r
707/**\r
708 Function to initialize the file global mHandleList object for use in\r
709 vonverting handles to index and index to handle.\r
710\r
711 @retval EFI_SUCCESS The operation was successful.\r
712**/\r
713EFI_STATUS\r
714EFIAPI\r
715InternalShellInitHandleList(\r
716 VOID\r
717 )\r
718{\r
719 EFI_STATUS Status;\r
720 EFI_HANDLE *HandleBuffer;\r
721 UINTN HandleCount;\r
722 HANDLE_LIST *ListWalker;\r
723\r
724 if (mHandleList.NextIndex != 0) {\r
725 return EFI_SUCCESS;\r
726 }\r
727 InitializeListHead(&mHandleList.List.Link);\r
728 mHandleList.NextIndex = 1;\r
729 Status = gBS->LocateHandleBuffer (\r
730 AllHandles,\r
731 NULL,\r
732 NULL,\r
733 &HandleCount,\r
734 &HandleBuffer\r
735 );\r
736 ASSERT_EFI_ERROR(Status);\r
737 if (EFI_ERROR(Status)) {\r
738 return (Status);\r
739 }\r
740 for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){\r
78ed876b 741 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
a405b86d 742 ASSERT(ListWalker != NULL);\r
743 ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex-1];\r
744 ListWalker->TheIndex = mHandleList.NextIndex;\r
745 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);\r
746 }\r
747 FreePool(HandleBuffer);\r
748 return (EFI_SUCCESS);\r
749}\r
750\r
751/**\r
752 Function to retrieve the human-friendly index of a given handle. If the handle\r
753 does not have a index one will be automatically assigned. The index value is valid\r
754 until the termination of the shell application.\r
755\r
756 @param[in] TheHandle The handle to retrieve an index for.\r
757\r
758 @retval 0 A memory allocation failed.\r
759 @return The index of the handle.\r
760\r
761**/\r
762UINTN\r
763EFIAPI\r
764ConvertHandleToHandleIndex(\r
765 IN CONST EFI_HANDLE TheHandle\r
766 )\r
767{\r
768 HANDLE_LIST *ListWalker;\r
78ed876b 769 if (TheHandle == NULL) {\r
770 return 0;\r
771 }\r
a405b86d 772\r
773 InternalShellInitHandleList();\r
774\r
775 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)\r
776 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)\r
777 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)\r
778 ){\r
779 if (ListWalker->TheHandle == TheHandle) {\r
780 return (ListWalker->TheIndex);\r
781 }\r
782 }\r
78ed876b 783 ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));\r
a405b86d 784 ASSERT(ListWalker != NULL);\r
785 ListWalker->TheHandle = TheHandle;\r
786 ListWalker->TheIndex = mHandleList.NextIndex++;\r
787 InsertTailList(&mHandleList.List.Link,&ListWalker->Link);\r
788 return (ListWalker->TheIndex);\r
789}\r
790\r
791\r
792\r
793/**\r
794 Function to retrieve the EFI_HANDLE from the human-friendly index.\r
795\r
796 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.\r
797\r
798 @retval NULL The index was invalid.\r
799 @return The EFI_HANDLE that index represents.\r
800\r
801**/\r
802EFI_HANDLE\r
803EFIAPI\r
804ConvertHandleIndexToHandle(\r
805 IN CONST UINTN TheIndex\r
806 )\r
807{\r
808 HANDLE_LIST *ListWalker;\r
809\r
810 InternalShellInitHandleList();\r
811\r
812 if (TheIndex >= mHandleList.NextIndex) {\r
813 return (NULL);\r
814 }\r
815\r
816 for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)\r
817 ; !IsNull(&mHandleList.List.Link,&ListWalker->Link)\r
818 ; ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)\r
819 ){\r
820 if (ListWalker->TheIndex == TheIndex) {\r
821 return (ListWalker->TheHandle);\r
822 }\r
823 }\r
824 return (NULL);\r
825}\r
826\r
827/**\r
828 Gets all the related EFI_HANDLEs based on the mask supplied.\r
829\r
830 This function scans all EFI_HANDLES in the UEFI environment's handle database\r
831 and returns the ones with the specified relationship (Mask) to the specified\r
832 controller handle.\r
833\r
834 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.\r
835 If MatchingHandleCount is NULL, then ASSERT.\r
836\r
837 If MatchingHandleBuffer is not NULL upon a successful return the memory must be\r
838 caller freed.\r
839\r
840 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.\r
841 @param[in] ControllerHandle The handle with Device Path protocol on it.\r
842 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in\r
843 MatchingHandleBuffer.\r
844 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount\r
845 EFI_HANDLEs with a terminating NULL EFI_HANDLE.\r
846 @param[out] HandleType An array of type information.\r
847\r
848 @retval EFI_SUCCESS The operation was successful, and any related handles\r
849 are in MatchingHandleBuffer.\r
850 @retval EFI_NOT_FOUND No matching handles were found.\r
851 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.\r
852**/\r
853EFI_STATUS\r
854EFIAPI\r
855ParseHandleDatabaseByRelationshipWithType (\r
856 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,\r
857 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
858 IN UINTN *HandleCount,\r
859 OUT EFI_HANDLE **HandleBuffer,\r
860 OUT UINTN **HandleType\r
861 )\r
862{\r
863 EFI_STATUS Status;\r
864 UINTN HandleIndex;\r
865 EFI_GUID **ProtocolGuidArray;\r
866 UINTN ArrayCount;\r
867 UINTN ProtocolIndex;\r
868 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
869 UINTN OpenInfoCount;\r
870 UINTN OpenInfoIndex;\r
871 UINTN ChildIndex;\r
872\r
873 ASSERT(HandleCount != NULL);\r
874 ASSERT(HandleBuffer != NULL);\r
875 ASSERT(HandleType != NULL);\r
876 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);\r
877\r
878 *HandleCount = 0;\r
879 *HandleBuffer = NULL;\r
880 *HandleType = NULL;\r
881\r
882 //\r
883 // Retrieve the list of all handles from the handle database\r
884 //\r
885 Status = gBS->LocateHandleBuffer (\r
886 AllHandles,\r
887 NULL,\r
888 NULL,\r
889 HandleCount,\r
890 HandleBuffer\r
891 );\r
892 if (EFI_ERROR (Status)) {\r
893 return (Status);\r
894 }\r
895\r
896 *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));\r
897 ASSERT(*HandleType != NULL);\r
898\r
899 for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
900 //\r
901 // Retrieve the list of all the protocols on each handle\r
902 //\r
903 Status = gBS->ProtocolsPerHandle (\r
904 (*HandleBuffer)[HandleIndex],\r
905 &ProtocolGuidArray,\r
906 &ArrayCount\r
907 );\r
908 if (!EFI_ERROR (Status)) {\r
909\r
910 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
911\r
912 //\r
913 // Set the bit describing what this handle has\r
914 //\r
915 if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid) ) {\r
916 (*HandleType)[HandleIndex] |= HR_IMAGE_HANDLE;\r
917 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid) ) {\r
918 (*HandleType)[HandleIndex] |= HR_DRIVER_BINDING_HANDLE;\r
919 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {\r
920 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;\r
921 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {\r
922 (*HandleType)[HandleIndex] |= HR_DRIVER_CONFIGURATION_HANDLE;\r
923 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid) ) {\r
924 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;\r
925 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid) ) {\r
926 (*HandleType)[HandleIndex] |= HR_DRIVER_DIAGNOSTICS_HANDLE;\r
927 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid) ) {\r
928 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;\r
929 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) {\r
930 (*HandleType)[HandleIndex] |= HR_COMPONENT_NAME_HANDLE;\r
931 } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid) ) {\r
932 (*HandleType)[HandleIndex] |= HR_DEVICE_HANDLE;\r
933 } else {\r
934 DEBUG_CODE_BEGIN();\r
935 ASSERT((*HandleType)[HandleIndex] == (*HandleType)[HandleIndex]);\r
936 DEBUG_CODE_END();\r
937 }\r
938 //\r
939 // Retrieve the list of agents that have opened each protocol\r
940 //\r
941 Status = gBS->OpenProtocolInformation (\r
942 (*HandleBuffer)[HandleIndex],\r
943 ProtocolGuidArray[ProtocolIndex],\r
944 &OpenInfo,\r
945 &OpenInfoCount\r
946 );\r
947 if (!EFI_ERROR (Status)) {\r
948 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
949 if (DriverBindingHandle != NULL && OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {\r
950 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {\r
951 (*HandleType)[HandleIndex] |= (HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);\r
952 }\r
953 if (ControllerHandle != NULL && (*HandleBuffer)[HandleIndex] == ControllerHandle) {\r
954 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
955 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
956 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].ControllerHandle) {\r
957 (*HandleType)[ChildIndex] |= (HR_DEVICE_HANDLE | HR_CHILD_HANDLE);\r
958 }\r
959 }\r
960 }\r
961 }\r
962 }\r
963 if (DriverBindingHandle == NULL && OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {\r
964 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {\r
965 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
966 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {\r
967 (*HandleType)[ChildIndex] |= HR_DEVICE_DRIVER;\r
968 }\r
969 }\r
970 }\r
971 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
972 (*HandleType)[HandleIndex] |= HR_PARENT_HANDLE;\r
973 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {\r
974 if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) {\r
975 (*HandleType)[ChildIndex] |= HR_BUS_DRIVER;\r
976 }\r
977 }\r
978 }\r
979 }\r
980 }\r
981\r
982 FreePool (OpenInfo);\r
983 }\r
984 }\r
985\r
986 FreePool (ProtocolGuidArray);\r
987 }\r
988 }\r
989\r
990 if (EFI_ERROR(Status)) {\r
991 if (*HandleType != NULL) {\r
992 FreePool (*HandleType);\r
993 }\r
994 if (*HandleBuffer != NULL) {\r
995 FreePool (*HandleBuffer);\r
996 }\r
997\r
998 *HandleCount = 0;\r
999 *HandleBuffer = NULL;\r
1000 *HandleType = NULL;\r
1001 }\r
1002\r
1003 return Status;\r
1004}\r
1005\r
1006/**\r
1007 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask\r
1008 supplied.\r
1009\r
1010 This function will scan all EFI_HANDLES in the UEFI environment's handle database\r
1011 and return all the ones with the specified relationship (Mask) to the specified\r
1012 controller handle.\r
1013\r
1014 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.\r
1015 If MatchingHandleCount is NULL, then ASSERT.\r
1016\r
1017 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be\r
1018 caller freed.\r
1019\r
1020 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol\r
1021 on it.\r
1022 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.\r
1023 @param[in] Mask Mask of what relationship(s) is desired.\r
1024 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in\r
1025 MatchingHandleBuffer.\r
1026 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount\r
1027 EFI_HANDLEs and a terminating NULL EFI_HANDLE.\r
1028\r
1029 @retval EFI_SUCCESS The operation was sucessful and any related handles\r
1030 are in MatchingHandleBuffer;\r
1031 @retval EFI_NOT_FOUND No matching handles were found.\r
1032 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.\r
1033**/\r
1034EFI_STATUS\r
1035EFIAPI\r
1036ParseHandleDatabaseByRelationship (\r
1037 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,\r
1038 IN CONST EFI_HANDLE ControllerHandle OPTIONAL,\r
1039 IN CONST UINTN Mask,\r
1040 IN UINTN *MatchingHandleCount,\r
1041 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1042 )\r
1043{\r
1044 EFI_STATUS Status;\r
1045 UINTN HandleCount;\r
1046 EFI_HANDLE *HandleBuffer;\r
1047 UINTN *HandleType;\r
1048 UINTN HandleIndex;\r
1049\r
1050 ASSERT(MatchingHandleCount != NULL);\r
1051 ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);\r
1052\r
1053 if ((Mask & HR_VALID_MASK) != Mask) {\r
1054 return (EFI_INVALID_PARAMETER);\r
1055 }\r
1056\r
1057 if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {\r
1058 return (EFI_INVALID_PARAMETER);\r
1059 }\r
1060\r
1061 *MatchingHandleCount = 0;\r
1062 if (MatchingHandleBuffer != NULL) {\r
1063 *MatchingHandleBuffer = NULL;\r
1064 }\r
1065\r
1066 HandleBuffer = NULL;\r
1067 HandleType = NULL;\r
1068\r
1069 Status = ParseHandleDatabaseByRelationshipWithType (\r
1070 DriverBindingHandle,\r
1071 ControllerHandle,\r
1072 &HandleCount,\r
1073 &HandleBuffer,\r
1074 &HandleType\r
1075 );\r
1076 if (!EFI_ERROR (Status)) {\r
1077 //\r
1078 // Count the number of handles that match the attributes in Mask\r
1079 //\r
1080 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
1081 if ((HandleType[HandleIndex] & Mask) == Mask) {\r
1082 (*MatchingHandleCount)++;\r
1083 }\r
1084 }\r
1085 //\r
1086 // If no handles match the attributes in Mask then return EFI_NOT_FOUND\r
1087 //\r
1088 if (*MatchingHandleCount == 0) {\r
1089 Status = EFI_NOT_FOUND;\r
1090 } else {\r
1091\r
1092 if (MatchingHandleBuffer == NULL) {\r
1093 //\r
1094 // Someone just wanted the count...\r
1095 //\r
1096 Status = EFI_SUCCESS;\r
1097 } else {\r
1098 //\r
1099 // Allocate a handle buffer for the number of handles that matched the attributes in Mask\r
1100 //\r
78ed876b 1101 *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));\r
a405b86d 1102 ASSERT(*MatchingHandleBuffer != NULL);\r
1103\r
1104 for (HandleIndex = 0,*MatchingHandleCount = 0\r
1105 ; HandleIndex < HandleCount\r
1106 ; HandleIndex++\r
1107 ){\r
1108 //\r
1109 // Fill the allocated buffer with the handles that matched the attributes in Mask\r
1110 //\r
1111 if ((HandleType[HandleIndex] & Mask) == Mask) {\r
1112 (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];\r
1113 }\r
1114 }\r
1115\r
1116 //\r
1117 // Make the last one NULL\r
1118 //\r
1119 (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;\r
1120\r
1121 Status = EFI_SUCCESS;\r
1122 } // MacthingHandleBuffer == NULL (ELSE)\r
1123 } // *MatchingHandleCount == 0 (ELSE)\r
1124 } // no error on ParseHandleDatabaseByRelationshipWithType\r
1125\r
1126 if (HandleBuffer != NULL) {\r
1127 FreePool (HandleBuffer);\r
1128 }\r
1129\r
1130 if (HandleType != NULL) {\r
1131 FreePool (HandleType);\r
1132 }\r
1133\r
1134 return Status;\r
1135}\r
1136\r
1137/**\r
1138 Gets handles for any child controllers of the passed in controller.\r
1139\r
1140 @param[in] ControllerHandle The handle of the "parent controller"\r
1141 @param[in] MatchingHandleCount Pointer to the number of handles in\r
1142 MatchingHandleBuffer on return.\r
1143 @param[out] MatchingHandleBuffer Buffer containing handles on a successful\r
1144 return.\r
1145\r
1146\r
1147 @retval EFI_SUCCESS The operation was sucessful.\r
1148**/\r
1149EFI_STATUS\r
1150EFIAPI\r
1151ParseHandleDatabaseForChildControllers(\r
1152 IN CONST EFI_HANDLE ControllerHandle,\r
1153 IN UINTN *MatchingHandleCount,\r
1154 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1155 )\r
1156{\r
1157 EFI_STATUS Status;\r
78ed876b 1158// UINTN HandleIndex;\r
a405b86d 1159 UINTN DriverBindingHandleCount;\r
1160 EFI_HANDLE *DriverBindingHandleBuffer;\r
1161 UINTN DriverBindingHandleIndex;\r
1162 UINTN ChildControllerHandleCount;\r
1163 EFI_HANDLE *ChildControllerHandleBuffer;\r
1164 UINTN ChildControllerHandleIndex;\r
78ed876b 1165// BOOLEAN Found;\r
a405b86d 1166 EFI_HANDLE *HandleBufferForReturn;\r
1167\r
ff51746b 1168 if (MatchingHandleCount == NULL) {\r
1169 return (EFI_INVALID_PARAMETER);\r
1170 }\r
64d753f1 1171 *MatchingHandleCount = 0;\r
a405b86d 1172\r
1173 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (\r
1174 ControllerHandle,\r
1175 &DriverBindingHandleCount,\r
1176 &DriverBindingHandleBuffer\r
1177 );\r
1178 if (EFI_ERROR (Status)) {\r
1179 return Status;\r
1180 }\r
1181\r
ff51746b 1182 //\r
1183 // Get a buffer big enough for all the controllers.\r
1184 //\r
1185 HandleBufferForReturn = GetHandleListByProtocol(&gEfiDevicePathProtocolGuid);\r
a405b86d 1186 if (HandleBufferForReturn == NULL) {\r
1187 FreePool (DriverBindingHandleBuffer);\r
ff51746b 1188 return (EFI_NOT_FOUND);\r
a405b86d 1189 }\r
1190\r
a405b86d 1191 for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {\r
1192 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
1193 DriverBindingHandleBuffer[DriverBindingHandleIndex],\r
1194 ControllerHandle,\r
1195 &ChildControllerHandleCount,\r
1196 &ChildControllerHandleBuffer\r
1197 );\r
1198 if (EFI_ERROR (Status)) {\r
1199 continue;\r
1200 }\r
1201\r
1202 for (ChildControllerHandleIndex = 0;\r
1203 ChildControllerHandleIndex < ChildControllerHandleCount;\r
1204 ChildControllerHandleIndex++\r
1205 ) {\r
78ed876b 1206// Found = FALSE;\r
1207 HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];\r
1208// for (HandleIndex = 0; HandleBufferForReturn[HandleIndex] != NULL; HandleIndex++) {\r
1209// if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {\r
1210// Found = TRUE;\r
1211// break;\r
1212// }\r
1213// }\r
1214\r
1215// if (Found) {\r
1216// HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];\r
1217// }\r
a405b86d 1218 }\r
1219\r
1220 FreePool (ChildControllerHandleBuffer);\r
1221 }\r
1222\r
1223 FreePool (DriverBindingHandleBuffer);\r
1224\r
1225 if (MatchingHandleBuffer != NULL) {\r
1226 *MatchingHandleBuffer = HandleBufferForReturn;\r
1227 } else {\r
1228 FreePool(HandleBufferForReturn);\r
1229 }\r
1230\r
1231 return (EFI_SUCCESS);\r
1232}\r
1233\r
1234/**\r
1235 Appends 1 buffer to another buffer. This will re-allocate the destination buffer\r
1236 if necessary to fit all of the data.\r
1237\r
1238 If DestinationBuffer is NULL, then ASSERT().\r
1239\r
4ff7e37b
ED
1240 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.\r
1241 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.\r
1242 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.\r
1243 @param[in] SourceSize The number of bytes of SourceBuffer to append.\r
a405b86d 1244\r
1245 @retval NULL A memory allocation failed.\r
1246 @retval NULL A parameter was invalid.\r
1247 @return A pointer to (*DestinationBuffer).\r
1248**/\r
1249VOID*\r
1250EFIAPI\r
1251BuffernCatGrow (\r
1252 IN OUT VOID **DestinationBuffer,\r
1253 IN OUT UINTN *DestinationSize,\r
1254 IN VOID *SourceBuffer,\r
1255 IN UINTN SourceSize\r
1256 )\r
1257{\r
1258 UINTN LocalDestinationSize;\r
1259 UINTN LocalDestinationFinalSize;\r
1260\r
1261 ASSERT(DestinationBuffer != NULL);\r
1262\r
1263 if (SourceSize == 0 || SourceBuffer == NULL) {\r
1264 return (*DestinationBuffer);\r
1265 }\r
1266\r
1267 if (DestinationSize == NULL) {\r
1268 LocalDestinationSize = 0;\r
1269 } else {\r
1270 LocalDestinationSize = *DestinationSize;\r
1271 }\r
1272\r
1273 LocalDestinationFinalSize = LocalDestinationSize + SourceSize;\r
1274\r
1275 if (DestinationSize != NULL) {\r
1276 *DestinationSize = LocalDestinationSize;\r
1277 }\r
1278\r
1279 if (LocalDestinationSize == 0) {\r
1280 // allcoate\r
78ed876b 1281 *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);\r
a405b86d 1282 } else {\r
1283 // reallocate\r
1284 *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);\r
1285 }\r
1286\r
1287 ASSERT(*DestinationBuffer != NULL);\r
1288\r
1289 // copy\r
1290 return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));\r
1291}\r
1292\r
1293/**\r
1294 Gets handles for any child devices produced by the passed in driver.\r
1295\r
1296 @param[in] DriverHandle The handle of the driver.\r
1297 @param[in] MatchingHandleCount Pointer to the number of handles in\r
1298 MatchingHandleBuffer on return.\r
1299 @param[out] MatchingHandleBuffer Buffer containing handles on a successful\r
1300 return.\r
1301 @retval EFI_SUCCESS The operation was sucessful.\r
1302 @sa ParseHandleDatabaseByRelationship\r
1303**/\r
1304EFI_STATUS\r
1305EFIAPI\r
1306ParseHandleDatabaseForChildDevices(\r
1307 IN CONST EFI_HANDLE DriverHandle,\r
1308 IN UINTN *MatchingHandleCount,\r
1309 OUT EFI_HANDLE **MatchingHandleBuffer OPTIONAL\r
1310 )\r
1311{\r
1312 EFI_HANDLE *Buffer;\r
1313 EFI_HANDLE *Buffer2;\r
1314 UINTN Count1;\r
1315 UINTN Count2;\r
1316 UINTN HandleIndex;\r
1317 EFI_STATUS Status;\r
1318 UINTN HandleBufferSize;\r
1319\r
1320 ASSERT(MatchingHandleCount != NULL);\r
1321\r
1322 HandleBufferSize = 0;\r
1323 Buffer = NULL;\r
1324 Buffer2 = NULL;\r
1325 *MatchingHandleCount = 0;\r
1326\r
1327 Status = PARSE_HANDLE_DATABASE_DEVICES (\r
1328 DriverHandle,\r
1329 &Count1,\r
1330 &Buffer\r
1331 );\r
1332 if (!EFI_ERROR (Status)) {\r
1333 for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {\r
1334 //\r
1335 // now find the children\r
1336 //\r
1337 Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
1338 DriverHandle,\r
1339 Buffer[HandleIndex],\r
1340 &Count2,\r
1341 &Buffer2\r
1342 );\r
1343 if (EFI_ERROR(Status)) {\r
1344 break;\r
1345 }\r
1346 //\r
1347 // save out required and optional data elements\r
1348 //\r
1349 *MatchingHandleCount += Count2;\r
1350 if (MatchingHandleBuffer != NULL) {\r
1351 *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));\r
1352 }\r
1353\r
1354 //\r
1355 // free the memory\r
1356 //\r
1357 if (Buffer2 != NULL) {\r
1358 FreePool(Buffer2);\r
1359 }\r
1360 }\r
1361 }\r
1362\r
1363 if (Buffer != NULL) {\r
1364 FreePool(Buffer);\r
1365 }\r
1366 return (Status);\r
1367}\r
1368\r
1369/**\r
1370 Function to get all handles that support a given protocol or all handles.\r
1371\r
1372 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL\r
1373 then the function will return all handles.\r
1374\r
1375 @retval NULL A memory allocation failed.\r
1376 @return A NULL terminated list of handles.\r
1377**/\r
1378EFI_HANDLE*\r
1379EFIAPI\r
40d7a9cf 1380GetHandleListByProtocol (\r
a405b86d 1381 IN CONST EFI_GUID *ProtocolGuid OPTIONAL\r
1382 )\r
1383{\r
1384 EFI_HANDLE *HandleList;\r
1385 UINTN Size;\r
1386 EFI_STATUS Status;\r
1387\r
1388 Size = 0;\r
1389 HandleList = NULL;\r
1390\r
1391 //\r
1392 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!\r
1393 //\r
1394 if (ProtocolGuid == NULL) {\r
1395 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);\r
1396 if (Status == EFI_BUFFER_TOO_SMALL) {\r
78ed876b 1397 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
40d7a9cf 1398 if (HandleList == NULL) {\r
1399 return (NULL);\r
1400 }\r
a405b86d 1401 Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);\r
1402 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;\r
1403 }\r
1404 } else {\r
1405 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);\r
1406 if (Status == EFI_BUFFER_TOO_SMALL) {\r
78ed876b 1407 HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));\r
40d7a9cf 1408 if (HandleList == NULL) {\r
1409 return (NULL);\r
1410 }\r
a405b86d 1411 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);\r
1412 HandleList[Size/sizeof(EFI_HANDLE)] = NULL;\r
1413 }\r
1414 }\r
1415 if (EFI_ERROR(Status)) {\r
1416 if (HandleList != NULL) {\r
1417 FreePool(HandleList);\r
1418 }\r
1419 return (NULL);\r
1420 }\r
1421 return (HandleList);\r
1422}\r
1423\r
1424/**\r
1425 Function to get all handles that support some protocols.\r
1426\r
1427 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.\r
1428\r
1429 @retval NULL A memory allocation failed.\r
ff51746b 1430 @retval NULL ProtocolGuids was NULL.\r
1431 @return A NULL terminated list of EFI_HANDLEs.\r
a405b86d 1432**/\r
1433EFI_HANDLE*\r
1434EFIAPI\r
40d7a9cf 1435GetHandleListByProtocolList (\r
a405b86d 1436 IN CONST EFI_GUID **ProtocolGuids\r
1437 )\r
1438{\r
1439 EFI_HANDLE *HandleList;\r
1440 UINTN Size;\r
1441 UINTN TotalSize;\r
40d7a9cf 1442 UINTN TempSize;\r
a405b86d 1443 EFI_STATUS Status;\r
1444 CONST EFI_GUID **GuidWalker;\r
1445 EFI_HANDLE *HandleWalker1;\r
1446 EFI_HANDLE *HandleWalker2;\r
1447\r
1448 Size = 0;\r
1449 HandleList = NULL;\r
1450 TotalSize = sizeof(EFI_HANDLE);\r
1451\r
1452 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){\r
1453 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);\r
1454 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1455 TotalSize += Size;\r
1456 }\r
1457 }\r
40d7a9cf 1458\r
1459 //\r
1460 // No handles were found... \r
1461 //\r
1462 if (TotalSize == sizeof(EFI_HANDLE)) {\r
1463 return (NULL);\r
1464 }\r
1465\r
1466 HandleList = AllocateZeroPool(TotalSize);\r
a405b86d 1467 if (HandleList == NULL) {\r
1468 return (NULL);\r
1469 }\r
1470\r
1471 Size = 0;\r
1472 for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){\r
40d7a9cf 1473 TempSize = TotalSize - Size;\r
ff51746b 1474 Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));\r
40d7a9cf 1475\r
1476 //\r
1477 // Allow for missing protocols... Only update the 'used' size upon success.\r
1478 //\r
1479 if (!EFI_ERROR(Status)) {\r
ff51746b 1480 Size += TempSize;\r
40d7a9cf 1481 }\r
a405b86d 1482 }\r
ff51746b 1483 ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);\r
a405b86d 1484\r
1485 for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {\r
1486 for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {\r
1487 if (*HandleWalker1 == *HandleWalker2) {\r
1488 //\r
1489 // copy memory back 1 handle width.\r
1490 //\r
1491 CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));\r
1492 }\r
1493 }\r
1494 }\r
1495\r
1496 return (HandleList);\r
1497}\r
1498\r
1499\r
1500\r
1501\r
1502\r
1503\r
1504\r
1505\r
1506\r
1507\r