2 Provides interface to advanced shell functionality for parsing both handle and protocol database.
4 Copyright (c) 2010 - 2011, 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
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.
15 #include "UefiHandleParsingLib.h"
17 EFI_HANDLE mHandleParsingHiiHandle
;
18 HANDLE_INDEX_LIST mHandleList
= {{{NULL
,NULL
},0,0},0};
21 Constructor for the library.
23 @param[in] ImageHandle Ignored.
24 @param[in] SystemTable Ignored.
26 @retval EFI_SUCCESS The operation was successful.
30 HandleParsingLibConstructor (
31 IN EFI_HANDLE ImageHandle
,
32 IN EFI_SYSTEM_TABLE
*SystemTable
35 mHandleParsingHiiHandle
= HiiAddPackages (&gHandleParsingHiiGuid
, gImageHandle
, UefiHandleParsingLibStrings
, NULL
);
36 if (mHandleParsingHiiHandle
== NULL
) {
37 return (EFI_DEVICE_ERROR
);
44 Destructor for the library. free any resources.
46 @param[in] ImageHandle Ignored.
47 @param[in] SystemTable Ignored.
49 @retval EFI_SUCCESS The operation was successful.
53 HandleParsingLibDestructor (
54 IN EFI_HANDLE ImageHandle
,
55 IN EFI_SYSTEM_TABLE
*SystemTable
58 if (mHandleParsingHiiHandle
!= NULL
) {
59 HiiRemovePackages(mHandleParsingHiiHandle
);
67 LoadedImageProtocolDumpInformation(
68 IN CONST EFI_HANDLE TheHandle,
69 IN CONST BOOLEAN Verbose
72 EFI_LOADED_IMAGE_PROTOCOL *Image;
74 EFI_DEVICE_PATH_PROTOCOL *DevPath;
75 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
78 UINT32 AuthenticationStatus;
80 EFI_FIRMWARE_VOLUME_PROTOCOL *FV;
81 EFI_FIRMWARE_VOLUME2_PROTOCOL *FV2;
88 Status = HandleProtocol (
90 &gEfiLoadedImageProtocolGuid,
92 ASSERT_EFI_ERROR(Status);
94 DevPath = UnpackDevicePath (Image->FilePath);
96 if (DevPath == NULL) {
100 DevPathNode = DevPath;
102 while (!IsDevicePathEnd (DevPathNode)) {
104 // Find the Fv File path
106 NameGuid = GetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevPathNode);
107 if (NameGuid != NULL) {
108 Status = BS->HandleProtocol (
110 &gEfiFirmwareVolumeProtocolGuid,
113 if (!EFI_ERROR (Status)) {
114 Status = FV->ReadSection (
117 EFI_SECTION_USER_INTERFACE,
121 &AuthenticationStatus
123 if (!EFI_ERROR (Status)) {
129 Status = BS->HandleProtocol (
131 &gEfiFirmwareVolume2ProtocolGuid,
134 if (!EFI_ERROR (Status)) {
135 Status = FV2->ReadSection (
138 EFI_SECTION_USER_INTERFACE,
142 &AuthenticationStatus
144 if (!EFI_ERROR (Status)) {
153 // Next device path node
155 DevPathNode = NextDevicePathNode (DevPathNode);
164 Function to dump information about SimpleTextOut.
166 This will allocate the return buffer from boot services pool.
168 @param[in] TheHandle The handle that has SimpleTextOut installed.
169 @param[in] Verbose TRUE for additional information, FALSE otherwise.
171 @retval A poitner to a string containing the information.
175 TxtOutProtocolDumpInformation(
176 IN CONST EFI_HANDLE TheHandle
,
177 IN CONST BOOLEAN Verbose
180 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Dev
;
197 Status
= gBS
->HandleProtocol(
199 &gEfiSimpleTextOutProtocolGuid
,
202 ASSERT_EFI_ERROR(Status
);
203 ASSERT (Dev
!= NULL
&& Dev
->Mode
!= NULL
);
205 Size
= (Dev
->Mode
->MaxMode
+ 1) * 80;
206 RetVal
= AllocateZeroPool(Size
);
208 Temp
= HiiGetString(mHandleParsingHiiHandle
, STRING_TOKEN(STR_TXT_OUT_DUMP_HEADER
), NULL
);
210 UnicodeSPrint(RetVal
, Size
, Temp
, Dev
, Dev
->Mode
->Attribute
);
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
);
222 RetVal
+ StrLen(RetVal
),
224 Temp
== NULL
?L
"":Temp
,
225 Index
== Dev
->Mode
->Mode
? L
'*' : L
' ',
227 !EFI_ERROR(Status
)?Col
:-1,
228 !EFI_ERROR(Status
)?Row
:-1
235 STATIC CONST UINTN VersionStringSize
= 60;
238 Function to dump information about EfiDriverSupportedEfiVersion protocol.
240 This will allocate the return buffer from boot services pool.
242 @param[in] TheHandle The handle that has the protocol installed.
243 @param[in] Verbose TRUE for additional information, FALSE otherwise.
245 @retval A poitner to a string containing the information.
249 DriverEfiVersionProtocolDumpInformation(
250 IN CONST EFI_HANDLE TheHandle
,
251 IN CONST BOOLEAN Verbose
254 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
*DriverEfiVersion
;
258 Status
= gBS
->HandleProtocol(
260 &gEfiDriverSupportedEfiVersionProtocolGuid
,
261 (VOID
**)&DriverEfiVersion
);
263 ASSERT_EFI_ERROR(Status
);
265 RetVal
= AllocateZeroPool(VersionStringSize
);
266 ASSERT(RetVal
!= NULL
);
267 UnicodeSPrint(RetVal
, VersionStringSize
, L
"0x%08x", DriverEfiVersion
->FirmwareVersion
);
272 Function to dump information about DevicePath protocol.
274 This will allocate the return buffer from boot services pool.
276 @param[in] TheHandle The handle that has the protocol installed.
277 @param[in] Verbose TRUE for additional information, FALSE otherwise.
279 @retval A poitner to a string containing the information.
283 DevicePathProtocolDumpInformation(
284 IN CONST EFI_HANDLE TheHandle
,
285 IN CONST BOOLEAN Verbose
288 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
292 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*DevPathToText
;
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
)) {
300 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)
302 Temp
= DevPathToText
->ConvertDevicePathToText(DevPath
, TRUE
, TRUE
);
303 gBS
->CloseProtocol(TheHandle
, &gEfiDevicePathProtocolGuid
, gImageHandle
, NULL
);
306 if (!Verbose
&& Temp
!= NULL
&& StrLen(Temp
) > 30) {
308 Temp2
= StrnCatGrow(&Temp2
, NULL
, Temp
+(StrLen(Temp
) - 30), 30);
316 // Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
318 #define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \
320 0x58c518b1, 0x76f3, 0x11d4, 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
323 #define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \
325 0x96eb4ad6, 0xa32a, 0x11d4, 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
328 #define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \
330 0xc95a93d, 0xa006, 0x11d4, 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
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
;
336 STATIC CONST PROTOCOL_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
},
343 STATIC CONST PROTOCOL_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_FILE_INFO
), &gEfiFileInfoGuid
, NULL
},
380 {STRING_TOKEN(STR_FILE_SYS_INFO
), &gEfiFileSystemInfoGuid
, NULL
},
381 {STRING_TOKEN(STR_TAPE_IO
), &gEfiTapeIoProtocolGuid
, NULL
},
382 {STRING_TOKEN(STR_DISK_IO
), &gEfiDiskIoProtocolGuid
, NULL
},
383 {STRING_TOKEN(STR_BLK_IO
), &gEfiBlockIoProtocolGuid
, NULL
},
384 {STRING_TOKEN(STR_UC
), &gEfiUnicodeCollationProtocolGuid
, NULL
},
385 {STRING_TOKEN(STR_UC2
), &gEfiUnicodeCollation2ProtocolGuid
, NULL
},
386 {STRING_TOKEN(STR_PCIRB_IO
), &gEfiPciRootBridgeIoProtocolGuid
, NULL
},
387 {STRING_TOKEN(STR_PCI_IO
), &gEfiPciIoProtocolGuid
, NULL
},
388 {STRING_TOKEN(STR_SCSI_PT
), &gEfiScsiPassThruProtocolGuid
, NULL
},
389 {STRING_TOKEN(STR_SCSI_IO
), &gEfiScsiIoProtocolGuid
, NULL
},
390 {STRING_TOKEN(STR_SCSI_PT_EXT
), &gEfiExtScsiPassThruProtocolGuid
, NULL
},
391 {STRING_TOKEN(STR_ISCSI
), &gEfiIScsiInitiatorNameProtocolGuid
, NULL
},
392 {STRING_TOKEN(STR_USB_IO
), &gEfiUsbIoProtocolGuid
, NULL
},
393 {STRING_TOKEN(STR_USB_HC
), &gEfiUsbHcProtocolGuid
, NULL
},
394 {STRING_TOKEN(STR_USB_HC2
), &gEfiUsb2HcProtocolGuid
, NULL
},
395 {STRING_TOKEN(STR_DEBUG_SUPPORT
), &gEfiDebugSupportProtocolGuid
, NULL
},
396 {STRING_TOKEN(STR_DEBUG_PORT
), &gEfiDebugPortProtocolGuid
, NULL
},
397 {STRING_TOKEN(STR_DECOMPRESS
), &gEfiDecompressProtocolGuid
, NULL
},
398 {STRING_TOKEN(STR_ACPI_TABLE
), &gEfiAcpiTableProtocolGuid
, NULL
},
399 {STRING_TOKEN(STR_EBC_INTERPRETER
), &gEfiEbcProtocolGuid
, NULL
},
400 {STRING_TOKEN(STR_SNP
), &gEfiSimpleNetworkProtocolGuid
, NULL
},
401 {STRING_TOKEN(STR_NII
), &gEfiNetworkInterfaceIdentifierProtocolGuid
, NULL
},
402 {STRING_TOKEN(STR_NII_31
), &gEfiNetworkInterfaceIdentifierProtocolGuid_31
, NULL
},
403 {STRING_TOKEN(STR_PXE_BC
), &gEfiPxeBaseCodeProtocolGuid
, NULL
},
404 {STRING_TOKEN(STR_PXE_CB
), &gEfiPxeBaseCodeCallbackProtocolGuid
, NULL
},
405 {STRING_TOKEN(STR_BIS
), &gEfiBisProtocolGuid
, NULL
},
406 {STRING_TOKEN(STR_MNP_SB
), &gEfiManagedNetworkServiceBindingProtocolGuid
, NULL
},
407 {STRING_TOKEN(STR_MNP
), &gEfiManagedNetworkProtocolGuid
, NULL
},
408 {STRING_TOKEN(STR_ARP_SB
), &gEfiArpServiceBindingProtocolGuid
, NULL
},
409 {STRING_TOKEN(STR_ARP
), &gEfiArpProtocolGuid
, NULL
},
410 {STRING_TOKEN(STR_DHCPV4_SB
), &gEfiDhcp4ServiceBindingProtocolGuid
, NULL
},
411 {STRING_TOKEN(STR_DHCPV4
), &gEfiDhcp4ProtocolGuid
, NULL
},
412 {STRING_TOKEN(STR_TCPV4_SB
), &gEfiTcp4ServiceBindingProtocolGuid
, NULL
},
413 {STRING_TOKEN(STR_TCPV4
), &gEfiTcp4ProtocolGuid
, NULL
},
414 {STRING_TOKEN(STR_IPV4_SB
), &gEfiIp4ServiceBindingProtocolGuid
, NULL
},
415 {STRING_TOKEN(STR_IPV4
), &gEfiIp4ProtocolGuid
, NULL
},
416 {STRING_TOKEN(STR_IPV4_CFG
), &gEfiIp4ConfigProtocolGuid
, NULL
},
417 {STRING_TOKEN(STR_SHELL_PARAMETERS
), &gEfiShellParametersProtocolGuid
, NULL
},
418 {STRING_TOKEN(STR_SHELL
), &gEfiShellProtocolGuid
, NULL
},
419 {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE
), &gEfiGlobalVariableGuid
, NULL
},
420 {STRING_TOKEN(STR_UDPV4_SB
), &gEfiUdp4ServiceBindingProtocolGuid
, NULL
},
421 {STRING_TOKEN(STR_UDPV4
), &gEfiUdp4ProtocolGuid
, NULL
},
422 {STRING_TOKEN(STR_MTFTPV4_SB
), &gEfiMtftp4ServiceBindingProtocolGuid
, NULL
},
423 {STRING_TOKEN(STR_MTFTPV4
), &gEfiMtftp4ProtocolGuid
, NULL
},
424 {STRING_TOKEN(STR_AUTH_INFO
), &gEfiAuthenticationInfoProtocolGuid
, NULL
},
425 {STRING_TOKEN(STR_HASH_SB
), &gEfiHashServiceBindingProtocolGuid
, NULL
},
426 {STRING_TOKEN(STR_HASH
), &gEfiHashProtocolGuid
, NULL
},
427 {STRING_TOKEN(STR_HII_FONT
), &gEfiHiiFontProtocolGuid
, NULL
},
428 {STRING_TOKEN(STR_HII_STRING
), &gEfiHiiStringProtocolGuid
, NULL
},
429 {STRING_TOKEN(STR_HII_IMAGE
), &gEfiHiiImageProtocolGuid
, NULL
},
430 {STRING_TOKEN(STR_HII_DATABASE
), &gEfiHiiDatabaseProtocolGuid
, NULL
},
431 {STRING_TOKEN(STR_HII_CONFIG_ROUT
), &gEfiHiiConfigRoutingProtocolGuid
, NULL
},
432 {STRING_TOKEN(STR_HII_CONFIG_ACC
), &gEfiHiiConfigAccessProtocolGuid
, NULL
},
433 {STRING_TOKEN(STR_HII_FORM_BROWSER2
), &gEfiFormBrowser2ProtocolGuid
, NULL
},
434 {STRING_TOKEN(STR_SHELL_INTERFACE
), &gEfiShellInterfaceGuid
, NULL
},
435 {STRING_TOKEN(STR_SHELL_ENV2
), &gEfiShellEnvironment2Guid
, NULL
},
436 {STRING_TOKEN(STR_SHELL_ENV
), &gEfiShellEnvironment2Guid
, NULL
},
437 {STRING_TOKEN(STR_DEVICE_IO
), &gEfiDeviceIoProtocolGuid
, NULL
},
438 {STRING_TOKEN(STR_UGA_DRAW
), &gEfiUgaDrawProtocolGuid
, NULL
},
439 {STRING_TOKEN(STR_UGA_IO
), &gEfiUgaIoProtocolGuid
, NULL
},
440 {STRING_TOKEN(STR_ESP
), &gEfiPartTypeSystemPartGuid
, NULL
},
441 {STRING_TOKEN(STR_GPT_NBR
), &gEfiPartTypeLegacyMbrGuid
, NULL
},
442 {STRING_TOKEN(STR_DRIVER_CONFIG
), &gEfiDriverConfigurationProtocolGuid
, NULL
},
443 {STRING_TOKEN(STR_DRIVER_CONFIG2
), &gEfiDriverConfiguration2ProtocolGuid
, NULL
},
444 {STRING_TOKEN(STR_UNKNOWN_DEVICE
), NULL
, NULL
},
448 Function to get the node for a protocol or struct from it's GUID.
450 if Guid is NULL, then ASSERT.
452 @param[in] Guid The GUID to look for the name of.
456 CONST PROTOCOL_INFO_BLOCK
*
458 InternalShellGetNodeFromGuid(
459 IN CONST EFI_GUID
* Guid
462 CONST PROTOCOL_INFO_BLOCK
*ListWalker
;
464 ASSERT(Guid
!= NULL
);
466 if (PcdGetBool(PcdShellIncludeNtGuids
)) {
467 for (ListWalker
= mGuidStringListNT
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
468 if (CompareGuid(ListWalker
->GuidId
, Guid
)) {
473 for (ListWalker
= mGuidStringList
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
474 if (CompareGuid(ListWalker
->GuidId
, Guid
)) {
482 Function to get the name of a protocol or struct from it's GUID.
484 if Guid is NULL, then ASSERT.
486 @param[in] Guid The GUID to look for the name of.
487 @param[in] Lang The language to use.
489 @return pointer to string of the name. The caller
490 is responsible to free this memory.
494 GetStringNameFromGuid(
495 IN CONST EFI_GUID
*Guid
,
496 IN CONST CHAR8
*Lang OPTIONAL
499 CONST PROTOCOL_INFO_BLOCK
*Id
;
501 Id
= InternalShellGetNodeFromGuid(Guid
);
502 return (HiiGetString(mHandleParsingHiiHandle
, Id
->StringId
, Lang
));
506 Function to dump protocol information from a handle.
508 This function will return a allocated string buffer containing the
509 information. The caller is responsible for freeing the memory.
511 If Guid is NULL, ASSERT().
512 If TheHandle is NULL, ASSERT().
514 @param[in] TheHandle The handle to dump information from.
515 @param[in] Guid The GUID of the protocol to dump.
516 @param[in] Verbose TRUE for extra info. FALSE otherwise.
518 @return The pointer to string.
519 @retval NULL An error was encountered.
523 GetProtocolInformationDump(
524 IN CONST EFI_HANDLE TheHandle
,
525 IN CONST EFI_GUID
*Guid
,
526 IN CONST BOOLEAN Verbose
529 CONST PROTOCOL_INFO_BLOCK
*Id
;
531 ASSERT(TheHandle
!= NULL
);
532 ASSERT(Guid
!= NULL
);
534 if (TheHandle
== NULL
|| Guid
== NULL
) {
538 Id
= InternalShellGetNodeFromGuid(Guid
);
539 if (Id
!= NULL
&& Id
->DumpInfo
!= NULL
) {
540 return (Id
->DumpInfo(TheHandle
, Verbose
));
546 Function to get the Guid for a protocol or struct based on it's string name.
548 @param[in] Name The pointer to the string name.
549 @param[in] Lang The pointer to the language code.
550 @param[in] Guid The pointer to the Guid.
552 @retval EFI_SUCCESS The operation was sucessful.
556 GetGuidFromStringName(
557 IN CONST CHAR16
*Name
,
558 IN CONST CHAR8
*Lang OPTIONAL
,
562 CONST PROTOCOL_INFO_BLOCK
*ListWalker
;
565 ASSERT(Guid
!= NULL
);
567 return (EFI_INVALID_PARAMETER
);
571 if (PcdGetBool(PcdShellIncludeNtGuids
)) {
572 for (ListWalker
= mGuidStringListNT
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
573 String
= HiiGetString(mHandleParsingHiiHandle
, ListWalker
->StringId
, Lang
);
574 if (Name
!= NULL
&& String
!= NULL
&& StrCmp(Name
, String
)==0) {
575 *Guid
= ListWalker
->GuidId
;
577 SHELL_FREE_NON_NULL(String
);
579 return (EFI_SUCCESS
);
583 for (ListWalker
= mGuidStringList
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
584 String
= HiiGetString(mHandleParsingHiiHandle
, ListWalker
->StringId
, Lang
);
585 if (Name
!= NULL
&& String
!= NULL
&& StrCmp(Name
, String
)==0) {
586 *Guid
= ListWalker
->GuidId
;
588 SHELL_FREE_NON_NULL(String
);
590 return (EFI_SUCCESS
);
593 return (EFI_NOT_FOUND
);
597 Function to retrieve the driver name (if possible) from the ComponentName or
598 ComponentName2 protocol
600 @param[in] TheHandle The driver handle to get the name of.
601 @param[in] Language The language to use.
603 @retval NULL The name could not be found.
604 @return A pointer to the string name. Do not de-allocate the memory.
608 GetStringNameFromHandle(
609 IN CONST EFI_HANDLE TheHandle
,
610 IN CONST CHAR8
*Language
613 EFI_COMPONENT_NAME2_PROTOCOL
*CompNameStruct
;
617 Status
= gBS
->OpenProtocol(
619 &gEfiComponentName2ProtocolGuid
,
620 (VOID
**)&CompNameStruct
,
623 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
624 if (!EFI_ERROR(Status
)) {
625 Status
= CompNameStruct
->GetDriverName(CompNameStruct
, (CHAR8
*)Language
, &RetVal
);
626 if (!EFI_ERROR(Status
)) {
630 Status
= gBS
->OpenProtocol(
632 &gEfiComponentNameProtocolGuid
,
633 (VOID
**)&CompNameStruct
,
636 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
637 if (!EFI_ERROR(Status
)) {
638 Status
= CompNameStruct
->GetDriverName(CompNameStruct
, (CHAR8
*)Language
, &RetVal
);
639 if (!EFI_ERROR(Status
)) {
647 Function to initialize the file global mHandleList object for use in
648 vonverting handles to index and index to handle.
650 @retval EFI_SUCCESS The operation was successful.
654 InternalShellInitHandleList(
659 EFI_HANDLE
*HandleBuffer
;
661 HANDLE_LIST
*ListWalker
;
663 if (mHandleList
.NextIndex
!= 0) {
666 InitializeListHead(&mHandleList
.List
.Link
);
667 mHandleList
.NextIndex
= 1;
668 Status
= gBS
->LocateHandleBuffer (
675 ASSERT_EFI_ERROR(Status
);
676 if (EFI_ERROR(Status
)) {
679 for (mHandleList
.NextIndex
= 1 ; mHandleList
.NextIndex
<= HandleCount
; mHandleList
.NextIndex
++){
680 ListWalker
= AllocateZeroPool(sizeof(HANDLE_LIST
));
681 ASSERT(ListWalker
!= NULL
);
682 ListWalker
->TheHandle
= HandleBuffer
[mHandleList
.NextIndex
-1];
683 ListWalker
->TheIndex
= mHandleList
.NextIndex
;
684 InsertTailList(&mHandleList
.List
.Link
,&ListWalker
->Link
);
686 FreePool(HandleBuffer
);
687 return (EFI_SUCCESS
);
691 Function to retrieve the human-friendly index of a given handle. If the handle
692 does not have a index one will be automatically assigned. The index value is valid
693 until the termination of the shell application.
695 @param[in] TheHandle The handle to retrieve an index for.
697 @retval 0 A memory allocation failed.
698 @return The index of the handle.
703 ConvertHandleToHandleIndex(
704 IN CONST EFI_HANDLE TheHandle
707 HANDLE_LIST
*ListWalker
;
708 if (TheHandle
== NULL
) {
712 InternalShellInitHandleList();
714 for (ListWalker
= (HANDLE_LIST
*)GetFirstNode(&mHandleList
.List
.Link
)
715 ; !IsNull(&mHandleList
.List
.Link
,&ListWalker
->Link
)
716 ; ListWalker
= (HANDLE_LIST
*)GetNextNode(&mHandleList
.List
.Link
,&ListWalker
->Link
)
718 if (ListWalker
->TheHandle
== TheHandle
) {
719 return (ListWalker
->TheIndex
);
722 ListWalker
= AllocateZeroPool(sizeof(HANDLE_LIST
));
723 ASSERT(ListWalker
!= NULL
);
724 ListWalker
->TheHandle
= TheHandle
;
725 ListWalker
->TheIndex
= mHandleList
.NextIndex
++;
726 InsertTailList(&mHandleList
.List
.Link
,&ListWalker
->Link
);
727 return (ListWalker
->TheIndex
);
733 Function to retrieve the EFI_HANDLE from the human-friendly index.
735 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.
737 @retval NULL The index was invalid.
738 @return The EFI_HANDLE that index represents.
743 ConvertHandleIndexToHandle(
744 IN CONST UINTN TheIndex
747 HANDLE_LIST
*ListWalker
;
749 InternalShellInitHandleList();
751 if (TheIndex
>= mHandleList
.NextIndex
) {
755 for (ListWalker
= (HANDLE_LIST
*)GetFirstNode(&mHandleList
.List
.Link
)
756 ; !IsNull(&mHandleList
.List
.Link
,&ListWalker
->Link
)
757 ; ListWalker
= (HANDLE_LIST
*)GetNextNode(&mHandleList
.List
.Link
,&ListWalker
->Link
)
759 if (ListWalker
->TheIndex
== TheIndex
) {
760 return (ListWalker
->TheHandle
);
767 Gets all the related EFI_HANDLEs based on the mask supplied.
769 This function scans all EFI_HANDLES in the UEFI environment's handle database
770 and returns the ones with the specified relationship (Mask) to the specified
773 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
774 If MatchingHandleCount is NULL, then ASSERT.
776 If MatchingHandleBuffer is not NULL upon a successful return the memory must be
779 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.
780 @param[in] ControllerHandle The handle with Device Path protocol on it.
781 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in
782 MatchingHandleBuffer.
783 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount
784 EFI_HANDLEs with a terminating NULL EFI_HANDLE.
785 @param[out] HandleType An array of type information.
787 @retval EFI_SUCCESS The operation was successful, and any related handles
788 are in MatchingHandleBuffer.
789 @retval EFI_NOT_FOUND No matching handles were found.
790 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
794 ParseHandleDatabaseByRelationshipWithType (
795 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL
,
796 IN CONST EFI_HANDLE ControllerHandle OPTIONAL
,
797 IN UINTN
*HandleCount
,
798 OUT EFI_HANDLE
**HandleBuffer
,
799 OUT UINTN
**HandleType
804 EFI_GUID
**ProtocolGuidArray
;
807 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfo
;
812 ASSERT(HandleCount
!= NULL
);
813 ASSERT(HandleBuffer
!= NULL
);
814 ASSERT(HandleType
!= NULL
);
815 ASSERT(DriverBindingHandle
!= NULL
|| ControllerHandle
!= NULL
);
818 *HandleBuffer
= NULL
;
822 // Retrieve the list of all handles from the handle database
824 Status
= gBS
->LocateHandleBuffer (
831 if (EFI_ERROR (Status
)) {
835 *HandleType
= AllocateZeroPool (*HandleCount
* sizeof (UINTN
));
836 ASSERT(*HandleType
!= NULL
);
838 for (HandleIndex
= 0; HandleIndex
< *HandleCount
; HandleIndex
++) {
840 // Retrieve the list of all the protocols on each handle
842 Status
= gBS
->ProtocolsPerHandle (
843 (*HandleBuffer
)[HandleIndex
],
847 if (!EFI_ERROR (Status
)) {
849 for (ProtocolIndex
= 0; ProtocolIndex
< ArrayCount
; ProtocolIndex
++) {
852 // Set the bit describing what this handle has
854 if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiLoadedImageProtocolGuid
) ) {
855 (*HandleType
)[HandleIndex
] |= HR_IMAGE_HANDLE
;
856 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverBindingProtocolGuid
) ) {
857 (*HandleType
)[HandleIndex
] |= HR_DRIVER_BINDING_HANDLE
;
858 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverConfiguration2ProtocolGuid
)) {
859 (*HandleType
)[HandleIndex
] |= HR_DRIVER_CONFIGURATION_HANDLE
;
860 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverConfigurationProtocolGuid
) ) {
861 (*HandleType
)[HandleIndex
] |= HR_DRIVER_CONFIGURATION_HANDLE
;
862 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverDiagnostics2ProtocolGuid
) ) {
863 (*HandleType
)[HandleIndex
] |= HR_DRIVER_DIAGNOSTICS_HANDLE
;
864 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverDiagnosticsProtocolGuid
) ) {
865 (*HandleType
)[HandleIndex
] |= HR_DRIVER_DIAGNOSTICS_HANDLE
;
866 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiComponentName2ProtocolGuid
) ) {
867 (*HandleType
)[HandleIndex
] |= HR_COMPONENT_NAME_HANDLE
;
868 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiComponentNameProtocolGuid
) ) {
869 (*HandleType
)[HandleIndex
] |= HR_COMPONENT_NAME_HANDLE
;
870 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDevicePathProtocolGuid
) ) {
871 (*HandleType
)[HandleIndex
] |= HR_DEVICE_HANDLE
;
874 ASSERT((*HandleType
)[HandleIndex
] == (*HandleType
)[HandleIndex
]);
878 // Retrieve the list of agents that have opened each protocol
880 Status
= gBS
->OpenProtocolInformation (
881 (*HandleBuffer
)[HandleIndex
],
882 ProtocolGuidArray
[ProtocolIndex
],
886 if (!EFI_ERROR (Status
)) {
887 for (OpenInfoIndex
= 0; OpenInfoIndex
< OpenInfoCount
; OpenInfoIndex
++) {
888 if (DriverBindingHandle
!= NULL
&& OpenInfo
[OpenInfoIndex
].AgentHandle
== DriverBindingHandle
) {
889 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) == EFI_OPEN_PROTOCOL_BY_DRIVER
) {
890 (*HandleType
)[HandleIndex
] |= (HR_DEVICE_HANDLE
| HR_CONTROLLER_HANDLE
);
892 if (ControllerHandle
!= NULL
&& (*HandleBuffer
)[HandleIndex
] == ControllerHandle
) {
893 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
894 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
895 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].ControllerHandle
) {
896 (*HandleType
)[ChildIndex
] |= (HR_DEVICE_HANDLE
| HR_CHILD_HANDLE
);
902 if (DriverBindingHandle
== NULL
&& OpenInfo
[OpenInfoIndex
].ControllerHandle
== ControllerHandle
) {
903 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) == EFI_OPEN_PROTOCOL_BY_DRIVER
) {
904 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
905 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].AgentHandle
) {
906 (*HandleType
)[ChildIndex
] |= HR_DEVICE_DRIVER
;
910 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
911 (*HandleType
)[HandleIndex
] |= HR_PARENT_HANDLE
;
912 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
913 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].AgentHandle
) {
914 (*HandleType
)[ChildIndex
] |= HR_BUS_DRIVER
;
925 FreePool (ProtocolGuidArray
);
929 if (EFI_ERROR(Status
)) {
930 if (*HandleType
!= NULL
) {
931 FreePool (*HandleType
);
933 if (*HandleBuffer
!= NULL
) {
934 FreePool (*HandleBuffer
);
938 *HandleBuffer
= NULL
;
946 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
949 This function will scan all EFI_HANDLES in the UEFI environment's handle database
950 and return all the ones with the specified relationship (Mask) to the specified
953 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
954 If MatchingHandleCount is NULL, then ASSERT.
956 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
959 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol
961 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.
962 @param[in] Mask Mask of what relationship(s) is desired.
963 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in
964 MatchingHandleBuffer.
965 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount
966 EFI_HANDLEs and a terminating NULL EFI_HANDLE.
968 @retval EFI_SUCCESS The operation was sucessful and any related handles
969 are in MatchingHandleBuffer;
970 @retval EFI_NOT_FOUND No matching handles were found.
971 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
975 ParseHandleDatabaseByRelationship (
976 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL
,
977 IN CONST EFI_HANDLE ControllerHandle OPTIONAL
,
979 IN UINTN
*MatchingHandleCount
,
980 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
985 EFI_HANDLE
*HandleBuffer
;
989 ASSERT(MatchingHandleCount
!= NULL
);
990 ASSERT(DriverBindingHandle
!= NULL
|| ControllerHandle
!= NULL
);
992 if ((Mask
& HR_VALID_MASK
) != Mask
) {
993 return (EFI_INVALID_PARAMETER
);
996 if ((Mask
& HR_CHILD_HANDLE
) != 0 && DriverBindingHandle
== NULL
) {
997 return (EFI_INVALID_PARAMETER
);
1000 *MatchingHandleCount
= 0;
1001 if (MatchingHandleBuffer
!= NULL
) {
1002 *MatchingHandleBuffer
= NULL
;
1005 HandleBuffer
= NULL
;
1008 Status
= ParseHandleDatabaseByRelationshipWithType (
1009 DriverBindingHandle
,
1015 if (!EFI_ERROR (Status
)) {
1017 // Count the number of handles that match the attributes in Mask
1019 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
1020 if ((HandleType
[HandleIndex
] & Mask
) == Mask
) {
1021 (*MatchingHandleCount
)++;
1025 // If no handles match the attributes in Mask then return EFI_NOT_FOUND
1027 if (*MatchingHandleCount
== 0) {
1028 Status
= EFI_NOT_FOUND
;
1031 if (MatchingHandleBuffer
== NULL
) {
1033 // Someone just wanted the count...
1035 Status
= EFI_SUCCESS
;
1038 // Allocate a handle buffer for the number of handles that matched the attributes in Mask
1040 *MatchingHandleBuffer
= AllocateZeroPool ((*MatchingHandleCount
+1)* sizeof (EFI_HANDLE
));
1041 ASSERT(*MatchingHandleBuffer
!= NULL
);
1043 for (HandleIndex
= 0,*MatchingHandleCount
= 0
1044 ; HandleIndex
< HandleCount
1048 // Fill the allocated buffer with the handles that matched the attributes in Mask
1050 if ((HandleType
[HandleIndex
] & Mask
) == Mask
) {
1051 (*MatchingHandleBuffer
)[(*MatchingHandleCount
)++] = HandleBuffer
[HandleIndex
];
1056 // Make the last one NULL
1058 (*MatchingHandleBuffer
)[*MatchingHandleCount
] = NULL
;
1060 Status
= EFI_SUCCESS
;
1061 } // MacthingHandleBuffer == NULL (ELSE)
1062 } // *MatchingHandleCount == 0 (ELSE)
1063 } // no error on ParseHandleDatabaseByRelationshipWithType
1065 if (HandleBuffer
!= NULL
) {
1066 FreePool (HandleBuffer
);
1069 if (HandleType
!= NULL
) {
1070 FreePool (HandleType
);
1077 Gets handles for any child controllers of the passed in controller.
1079 @param[in] ControllerHandle The handle of the "parent controller"
1080 @param[in] MatchingHandleCount Pointer to the number of handles in
1081 MatchingHandleBuffer on return.
1082 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1086 @retval EFI_SUCCESS The operation was sucessful.
1090 ParseHandleDatabaseForChildControllers(
1091 IN CONST EFI_HANDLE ControllerHandle
,
1092 IN UINTN
*MatchingHandleCount
,
1093 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
1097 // UINTN HandleIndex;
1098 UINTN DriverBindingHandleCount
;
1099 EFI_HANDLE
*DriverBindingHandleBuffer
;
1100 UINTN DriverBindingHandleIndex
;
1101 UINTN ChildControllerHandleCount
;
1102 EFI_HANDLE
*ChildControllerHandleBuffer
;
1103 UINTN ChildControllerHandleIndex
;
1105 EFI_HANDLE
*HandleBufferForReturn
;
1107 if (MatchingHandleCount
== NULL
) {
1108 return (EFI_INVALID_PARAMETER
);
1110 *MatchingHandleCount
= 0;
1112 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
1114 &DriverBindingHandleCount
,
1115 &DriverBindingHandleBuffer
1117 if (EFI_ERROR (Status
)) {
1122 // Get a buffer big enough for all the controllers.
1124 HandleBufferForReturn
= GetHandleListByProtocol(&gEfiDevicePathProtocolGuid
);
1125 if (HandleBufferForReturn
== NULL
) {
1126 FreePool (DriverBindingHandleBuffer
);
1127 return (EFI_NOT_FOUND
);
1130 for (DriverBindingHandleIndex
= 0; DriverBindingHandleIndex
< DriverBindingHandleCount
; DriverBindingHandleIndex
++) {
1131 Status
= PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1132 DriverBindingHandleBuffer
[DriverBindingHandleIndex
],
1134 &ChildControllerHandleCount
,
1135 &ChildControllerHandleBuffer
1137 if (EFI_ERROR (Status
)) {
1141 for (ChildControllerHandleIndex
= 0;
1142 ChildControllerHandleIndex
< ChildControllerHandleCount
;
1143 ChildControllerHandleIndex
++
1146 HandleBufferForReturn
[(*MatchingHandleCount
)++] = ChildControllerHandleBuffer
[ChildControllerHandleIndex
];
1147 // for (HandleIndex = 0; HandleBufferForReturn[HandleIndex] != NULL; HandleIndex++) {
1148 // if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
1155 // HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1159 FreePool (ChildControllerHandleBuffer
);
1162 FreePool (DriverBindingHandleBuffer
);
1164 if (MatchingHandleBuffer
!= NULL
) {
1165 *MatchingHandleBuffer
= HandleBufferForReturn
;
1167 FreePool(HandleBufferForReturn
);
1170 return (EFI_SUCCESS
);
1174 Appends 1 buffer to another buffer. This will re-allocate the destination buffer
1175 if necessary to fit all of the data.
1177 If DestinationBuffer is NULL, then ASSERT().
1179 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.
1180 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.
1181 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.
1182 @param[in] SourceSize The number of bytes of SourceBuffer to append.
1184 @retval NULL A memory allocation failed.
1185 @retval NULL A parameter was invalid.
1186 @return A pointer to (*DestinationBuffer).
1191 IN OUT VOID
**DestinationBuffer
,
1192 IN OUT UINTN
*DestinationSize
,
1193 IN VOID
*SourceBuffer
,
1197 UINTN LocalDestinationSize
;
1198 UINTN LocalDestinationFinalSize
;
1200 ASSERT(DestinationBuffer
!= NULL
);
1202 if (SourceSize
== 0 || SourceBuffer
== NULL
) {
1203 return (*DestinationBuffer
);
1206 if (DestinationSize
== NULL
) {
1207 LocalDestinationSize
= 0;
1209 LocalDestinationSize
= *DestinationSize
;
1212 LocalDestinationFinalSize
= LocalDestinationSize
+ SourceSize
;
1214 if (DestinationSize
!= NULL
) {
1215 *DestinationSize
= LocalDestinationSize
;
1218 if (LocalDestinationSize
== 0) {
1220 *DestinationBuffer
= AllocateZeroPool(LocalDestinationFinalSize
);
1223 *DestinationBuffer
= ReallocatePool(LocalDestinationSize
, LocalDestinationFinalSize
, *DestinationBuffer
);
1226 ASSERT(*DestinationBuffer
!= NULL
);
1229 return (CopyMem(((UINT8
*)(*DestinationBuffer
)) + LocalDestinationSize
, SourceBuffer
, SourceSize
));
1233 Gets handles for any child devices produced by the passed in driver.
1235 @param[in] DriverHandle The handle of the driver.
1236 @param[in] MatchingHandleCount Pointer to the number of handles in
1237 MatchingHandleBuffer on return.
1238 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1240 @retval EFI_SUCCESS The operation was sucessful.
1241 @sa ParseHandleDatabaseByRelationship
1245 ParseHandleDatabaseForChildDevices(
1246 IN CONST EFI_HANDLE DriverHandle
,
1247 IN UINTN
*MatchingHandleCount
,
1248 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
1252 EFI_HANDLE
*Buffer2
;
1257 UINTN HandleBufferSize
;
1259 ASSERT(MatchingHandleCount
!= NULL
);
1261 HandleBufferSize
= 0;
1264 *MatchingHandleCount
= 0;
1266 Status
= PARSE_HANDLE_DATABASE_DEVICES (
1271 if (!EFI_ERROR (Status
)) {
1272 for (HandleIndex
= 0; HandleIndex
< Count1
; HandleIndex
++) {
1274 // now find the children
1276 Status
= PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1278 Buffer
[HandleIndex
],
1282 if (EFI_ERROR(Status
)) {
1286 // save out required and optional data elements
1288 *MatchingHandleCount
+= Count2
;
1289 if (MatchingHandleBuffer
!= NULL
) {
1290 *MatchingHandleBuffer
= BuffernCatGrow((VOID
**)MatchingHandleBuffer
, &HandleBufferSize
, Buffer2
, Count2
* sizeof(Buffer2
[0]));
1296 if (Buffer2
!= NULL
) {
1302 if (Buffer
!= NULL
) {
1309 Function to get all handles that support a given protocol or all handles.
1311 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL
1312 then the function will return all handles.
1314 @retval NULL A memory allocation failed.
1315 @return A NULL terminated list of handles.
1319 GetHandleListByProtocol (
1320 IN CONST EFI_GUID
*ProtocolGuid OPTIONAL
1323 EFI_HANDLE
*HandleList
;
1331 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
1333 if (ProtocolGuid
== NULL
) {
1334 Status
= gBS
->LocateHandle(AllHandles
, NULL
, NULL
, &Size
, HandleList
);
1335 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1336 HandleList
= AllocateZeroPool(Size
+ sizeof(EFI_HANDLE
));
1337 if (HandleList
== NULL
) {
1340 Status
= gBS
->LocateHandle(AllHandles
, NULL
, NULL
, &Size
, HandleList
);
1341 HandleList
[Size
/sizeof(EFI_HANDLE
)] = NULL
;
1344 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)ProtocolGuid
, NULL
, &Size
, HandleList
);
1345 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1346 HandleList
= AllocateZeroPool(Size
+ sizeof(EFI_HANDLE
));
1347 if (HandleList
== NULL
) {
1350 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)ProtocolGuid
, NULL
, &Size
, HandleList
);
1351 HandleList
[Size
/sizeof(EFI_HANDLE
)] = NULL
;
1354 if (EFI_ERROR(Status
)) {
1355 if (HandleList
!= NULL
) {
1356 FreePool(HandleList
);
1360 return (HandleList
);
1364 Function to get all handles that support some protocols.
1366 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.
1368 @retval NULL A memory allocation failed.
1369 @retval NULL ProtocolGuids was NULL.
1370 @return A NULL terminated list of EFI_HANDLEs.
1374 GetHandleListByProtocolList (
1375 IN CONST EFI_GUID
**ProtocolGuids
1378 EFI_HANDLE
*HandleList
;
1383 CONST EFI_GUID
**GuidWalker
;
1384 EFI_HANDLE
*HandleWalker1
;
1385 EFI_HANDLE
*HandleWalker2
;
1389 TotalSize
= sizeof(EFI_HANDLE
);
1391 for (GuidWalker
= ProtocolGuids
; GuidWalker
!= NULL
&& *GuidWalker
!= NULL
; GuidWalker
++,Size
= 0){
1392 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)(*GuidWalker
), NULL
, &Size
, NULL
);
1393 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1399 // No handles were found...
1401 if (TotalSize
== sizeof(EFI_HANDLE
)) {
1405 HandleList
= AllocateZeroPool(TotalSize
);
1406 if (HandleList
== NULL
) {
1411 for (GuidWalker
= ProtocolGuids
; GuidWalker
!= NULL
&& *GuidWalker
!= NULL
; GuidWalker
++){
1412 TempSize
= TotalSize
- Size
;
1413 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)(*GuidWalker
), NULL
, &TempSize
, HandleList
+(Size
/sizeof(EFI_HANDLE
)));
1416 // Allow for missing protocols... Only update the 'used' size upon success.
1418 if (!EFI_ERROR(Status
)) {
1422 ASSERT(HandleList
[(TotalSize
/sizeof(EFI_HANDLE
))-1] == NULL
);
1424 for (HandleWalker1
= HandleList
; HandleWalker1
!= NULL
&& *HandleWalker1
!= NULL
; HandleWalker1
++) {
1425 for (HandleWalker2
= HandleWalker1
+ 1; HandleWalker2
!= NULL
&& *HandleWalker2
!= NULL
; HandleWalker2
++) {
1426 if (*HandleWalker1
== *HandleWalker2
) {
1428 // copy memory back 1 handle width.
1430 CopyMem(HandleWalker2
, HandleWalker2
+ 1, TotalSize
- ((HandleWalker2
-HandleList
+1)*sizeof(EFI_HANDLE
)));
1435 return (HandleList
);