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