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
);
209 UnicodeSPrint(RetVal
, Size
, Temp
, Dev
, Dev
->Mode
->Attribute
);
215 Temp
= HiiGetString(mHandleParsingHiiHandle
, STRING_TOKEN(STR_TXT_OUT_DUMP_LINE
), NULL
);
216 for (Index
= 0; Index
< Dev
->Mode
->MaxMode
; Index
++) {
217 Status
= Dev
->QueryMode (Dev
, Index
, &Col
, &Row
);
218 NewSize
= Size
- StrSize(RetVal
);
220 RetVal
+ StrLen(RetVal
),
223 Index
== Dev
->Mode
->Mode
? L
'*' : L
' ',
225 !EFI_ERROR(Status
)?Col
:-1,
226 !EFI_ERROR(Status
)?Row
:-1
233 STATIC CONST UINTN VersionStringSize
= 60;
236 Function to dump information about EfiDriverSupportedEfiVersion protocol.
238 This will allocate the return buffer from boot services pool.
240 @param[in] TheHandle The handle that has the protocol installed.
241 @param[in] Verbose TRUE for additional information, FALSE otherwise.
243 @retval A poitner to a string containing the information.
247 DriverEfiVersionProtocolDumpInformation(
248 IN CONST EFI_HANDLE TheHandle
,
249 IN CONST BOOLEAN Verbose
252 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
*DriverEfiVersion
;
256 Status
= gBS
->HandleProtocol(
258 &gEfiDriverSupportedEfiVersionProtocolGuid
,
259 (VOID
**)&DriverEfiVersion
);
261 ASSERT_EFI_ERROR(Status
);
263 RetVal
= AllocateZeroPool(VersionStringSize
);
264 ASSERT(RetVal
!= NULL
);
265 UnicodeSPrint(RetVal
, VersionStringSize
, L
"0x%08x", DriverEfiVersion
->FirmwareVersion
);
270 Function to dump information about DevicePath protocol.
272 This will allocate the return buffer from boot services pool.
274 @param[in] TheHandle The handle that has the protocol installed.
275 @param[in] Verbose TRUE for additional information, FALSE otherwise.
277 @retval A poitner to a string containing the information.
281 DevicePathProtocolDumpInformation(
282 IN CONST EFI_HANDLE TheHandle
,
283 IN CONST BOOLEAN Verbose
286 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
290 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*DevPathToText
;
293 Status
= gBS
->LocateProtocol(&gEfiDevicePathToTextProtocolGuid
, NULL
, (VOID
**)&DevPathToText
);
294 if (!EFI_ERROR(Status
)) {
295 Status
= gBS
->OpenProtocol(TheHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPath
, gImageHandle
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
296 if (!EFI_ERROR(Status
)) {
298 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)
300 Temp
= DevPathToText
->ConvertDevicePathToText(DevPath
, TRUE
, TRUE
);
301 gBS
->CloseProtocol(TheHandle
, &gEfiDevicePathProtocolGuid
, gImageHandle
, NULL
);
304 if (!Verbose
&& Temp
!= NULL
&& StrLen(Temp
) > 30) {
306 Temp2
= StrnCatGrow(&Temp2
, NULL
, Temp
+(StrLen(Temp
) - 30), 30);
314 // Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
316 #define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \
318 0x58c518b1, 0x76f3, 0x11d4, 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
321 #define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \
323 0x96eb4ad6, 0xa32a, 0x11d4, 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
326 #define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \
328 0xc95a93d, 0xa006, 0x11d4, 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
330 STATIC CONST EFI_GUID WinNtThunkProtocolGuid
= LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID
;
331 STATIC CONST EFI_GUID WinNtIoProtocolGuid
= LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID
;
332 STATIC CONST EFI_GUID WinNtSerialPortGuid
= LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID
;
334 STATIC CONST PROTOCOL_INFO_BLOCK mGuidStringListNT
[] = {
335 {STRING_TOKEN(STR_WINNT_THUNK
), (EFI_GUID
*)&WinNtThunkProtocolGuid
, NULL
},
336 {STRING_TOKEN(STR_WINNT_DRIVER_IO
), (EFI_GUID
*)&WinNtIoProtocolGuid
, NULL
},
337 {STRING_TOKEN(STR_WINNT_SERIAL_PORT
), (EFI_GUID
*)&WinNtSerialPortGuid
, NULL
},
338 {STRING_TOKEN(STR_UNKNOWN_DEVICE
), NULL
, NULL
},
341 STATIC CONST PROTOCOL_INFO_BLOCK mGuidStringList
[] = {
342 {STRING_TOKEN(STR_LOADED_IMAGE
), &gEfiLoadedImageProtocolGuid
, NULL
},
343 {STRING_TOKEN(STR_DEVICE_PATH
), &gEfiDevicePathProtocolGuid
, DevicePathProtocolDumpInformation
},
344 {STRING_TOKEN(STR_IMAGE_PATH
), &gEfiLoadedImageDevicePathProtocolGuid
, DevicePathProtocolDumpInformation
},
345 {STRING_TOKEN(STR_DEVICE_PATH_UTIL
), &gEfiDevicePathUtilitiesProtocolGuid
, NULL
},
346 {STRING_TOKEN(STR_DEVICE_PATH_TXT
), &gEfiDevicePathToTextProtocolGuid
, NULL
},
347 {STRING_TOKEN(STR_DEVICE_PATH_FTXT
), &gEfiDevicePathFromTextProtocolGuid
, NULL
},
348 {STRING_TOKEN(STR_DEVICE_PATH_PC
), &gEfiPcAnsiGuid
, NULL
},
349 {STRING_TOKEN(STR_DEVICE_PATH_VT100
), &gEfiVT100Guid
, NULL
},
350 {STRING_TOKEN(STR_DEVICE_PATH_VT100P
), &gEfiVT100PlusGuid
, NULL
},
351 {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8
), &gEfiVTUTF8Guid
, NULL
},
352 {STRING_TOKEN(STR_DRIVER_BINDING
), &gEfiDriverBindingProtocolGuid
, NULL
},
353 {STRING_TOKEN(STR_PLATFORM_OVERRIDE
), &gEfiPlatformDriverOverrideProtocolGuid
, NULL
},
354 {STRING_TOKEN(STR_BUS_OVERRIDE
), &gEfiBusSpecificDriverOverrideProtocolGuid
, NULL
},
355 {STRING_TOKEN(STR_DRIVER_DIAG
), &gEfiDriverDiagnosticsProtocolGuid
, NULL
},
356 {STRING_TOKEN(STR_DRIVER_DIAG2
), &gEfiDriverDiagnostics2ProtocolGuid
, NULL
},
357 {STRING_TOKEN(STR_DRIVER_CN
), &gEfiComponentNameProtocolGuid
, NULL
},
358 {STRING_TOKEN(STR_DRIVER_CN2
), &gEfiComponentName2ProtocolGuid
, NULL
},
359 {STRING_TOKEN(STR_PLAT_DRV_CFG
), &gEfiPlatformToDriverConfigurationProtocolGuid
, NULL
},
360 {STRING_TOKEN(STR_DRIVER_VERSION
), &gEfiDriverSupportedEfiVersionProtocolGuid
, DriverEfiVersionProtocolDumpInformation
},
361 {STRING_TOKEN(STR_TXT_IN
), &gEfiSimpleTextInProtocolGuid
, NULL
},
362 {STRING_TOKEN(STR_TXT_IN_EX
), &gEfiSimpleTextInputExProtocolGuid
, NULL
},
363 {STRING_TOKEN(STR_TXT_OUT
), &gEfiSimpleTextOutProtocolGuid
, TxtOutProtocolDumpInformation
},
364 {STRING_TOKEN(STR_SIM_POINTER
), &gEfiSimplePointerProtocolGuid
, NULL
},
365 {STRING_TOKEN(STR_ABS_POINTER
), &gEfiAbsolutePointerProtocolGuid
, NULL
},
366 {STRING_TOKEN(STR_SERIAL_IO
), &gEfiSerialIoProtocolGuid
, NULL
},
367 {STRING_TOKEN(STR_GRAPHICS_OUTPUT
), &gEfiGraphicsOutputProtocolGuid
, NULL
},
368 {STRING_TOKEN(STR_EDID_DISCOVERED
), &gEfiEdidDiscoveredProtocolGuid
, NULL
},
369 {STRING_TOKEN(STR_EDID_ACTIVE
), &gEfiEdidActiveProtocolGuid
, NULL
},
370 {STRING_TOKEN(STR_EDID_OVERRIDE
), &gEfiEdidOverrideProtocolGuid
, NULL
},
371 {STRING_TOKEN(STR_CON_IN
), &gEfiConsoleInDeviceGuid
, NULL
},
372 {STRING_TOKEN(STR_CON_OUT
), &gEfiConsoleOutDeviceGuid
, NULL
},
373 {STRING_TOKEN(STR_STD_ERR
), &gEfiStandardErrorDeviceGuid
, NULL
},
374 {STRING_TOKEN(STR_LOAD_FILE
), &gEfiLoadFileProtocolGuid
, NULL
},
375 {STRING_TOKEN(STR_LOAD_FILE2
), &gEfiLoadFile2ProtocolGuid
, NULL
},
376 {STRING_TOKEN(STR_SIMPLE_FILE_SYS
), &gEfiSimpleFileSystemProtocolGuid
, NULL
},
377 {STRING_TOKEN(STR_FILE_INFO
), &gEfiFileInfoGuid
, NULL
},
378 {STRING_TOKEN(STR_FILE_SYS_INFO
), &gEfiFileSystemInfoGuid
, 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_EFI_GLOBAL_VARIABLE
), &gEfiGlobalVariableGuid
, NULL
},
418 {STRING_TOKEN(STR_UDPV4_SB
), &gEfiUdp4ServiceBindingProtocolGuid
, NULL
},
419 {STRING_TOKEN(STR_UDPV4
), &gEfiUdp4ProtocolGuid
, NULL
},
420 {STRING_TOKEN(STR_MTFTPV4_SB
), &gEfiMtftp4ServiceBindingProtocolGuid
, NULL
},
421 {STRING_TOKEN(STR_MTFTPV4
), &gEfiMtftp4ProtocolGuid
, NULL
},
422 {STRING_TOKEN(STR_AUTH_INFO
), &gEfiAuthenticationInfoProtocolGuid
, NULL
},
423 {STRING_TOKEN(STR_HASH_SB
), &gEfiHashServiceBindingProtocolGuid
, NULL
},
424 {STRING_TOKEN(STR_HASH
), &gEfiHashProtocolGuid
, NULL
},
425 {STRING_TOKEN(STR_HII_FONT
), &gEfiHiiFontProtocolGuid
, NULL
},
426 {STRING_TOKEN(STR_HII_STRING
), &gEfiHiiStringProtocolGuid
, NULL
},
427 {STRING_TOKEN(STR_HII_IMAGE
), &gEfiHiiImageProtocolGuid
, NULL
},
428 {STRING_TOKEN(STR_HII_DATABASE
), &gEfiHiiDatabaseProtocolGuid
, NULL
},
429 {STRING_TOKEN(STR_HII_CONFIG_ROUT
), &gEfiHiiConfigRoutingProtocolGuid
, NULL
},
430 {STRING_TOKEN(STR_HII_CONFIG_ACC
), &gEfiHiiConfigAccessProtocolGuid
, NULL
},
431 {STRING_TOKEN(STR_HII_FORM_BROWSER2
), &gEfiFormBrowser2ProtocolGuid
, NULL
},
432 {STRING_TOKEN(STR_SHELL_INTERFACE
), &gEfiShellInterfaceGuid
, NULL
},
433 {STRING_TOKEN(STR_SHELL_ENV2
), &gEfiShellEnvironment2Guid
, NULL
},
434 {STRING_TOKEN(STR_SHELL_ENV
), &gEfiShellEnvironment2Guid
, NULL
},
435 {STRING_TOKEN(STR_DEVICE_IO
), &gEfiDeviceIoProtocolGuid
, NULL
},
436 {STRING_TOKEN(STR_UGA_DRAW
), &gEfiUgaDrawProtocolGuid
, NULL
},
437 {STRING_TOKEN(STR_UGA_IO
), &gEfiUgaIoProtocolGuid
, NULL
},
438 {STRING_TOKEN(STR_ESP
), &gEfiPartTypeSystemPartGuid
, NULL
},
439 {STRING_TOKEN(STR_GPT_NBR
), &gEfiPartTypeLegacyMbrGuid
, NULL
},
440 {STRING_TOKEN(STR_DRIVER_CONFIG
), &gEfiDriverConfigurationProtocolGuid
, NULL
},
441 {STRING_TOKEN(STR_DRIVER_CONFIG2
), &gEfiDriverConfiguration2ProtocolGuid
, NULL
},
442 {STRING_TOKEN(STR_UNKNOWN_DEVICE
), NULL
, NULL
},
446 Function to get the node for a protocol or struct from it's GUID.
448 if Guid is NULL, then ASSERT.
450 @param[in] Guid The GUID to look for the name of.
454 CONST PROTOCOL_INFO_BLOCK
*
456 InternalShellGetNodeFromGuid(
457 IN CONST EFI_GUID
* Guid
460 CONST PROTOCOL_INFO_BLOCK
*ListWalker
;
462 ASSERT(Guid
!= NULL
);
464 if (PcdGetBool(PcdShellIncludeNtGuids
)) {
465 for (ListWalker
= mGuidStringListNT
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
466 if (CompareGuid(ListWalker
->GuidId
, Guid
)) {
471 for (ListWalker
= mGuidStringList
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
472 if (CompareGuid(ListWalker
->GuidId
, Guid
)) {
480 Function to get the name of a protocol or struct from it's GUID.
482 if Guid is NULL, then ASSERT.
484 @param[in] Guid The GUID to look for the name of.
485 @param[in] Lang The language to use.
487 @return pointer to string of the name. The caller
488 is responsible to free this memory.
492 GetStringNameFromGuid(
493 IN CONST EFI_GUID
*Guid
,
494 IN CONST CHAR8
*Lang OPTIONAL
497 CONST PROTOCOL_INFO_BLOCK
*Id
;
499 Id
= InternalShellGetNodeFromGuid(Guid
);
500 return (HiiGetString(mHandleParsingHiiHandle
, Id
->StringId
, Lang
));
504 Function to dump protocol information from a handle.
506 This function will return a allocated string buffer containing the
507 information. The caller is responsible for freeing the memory.
509 If Guid is NULL, ASSERT().
510 If TheHandle is NULL, ASSERT().
512 @param[in] TheHandle The handle to dump information from.
513 @param[in] Guid The GUID of the protocol to dump.
514 @param[in] Verbose TRUE for extra info. FALSE otherwise.
516 @return The pointer to string.
517 @retval NULL An error was encountered.
521 GetProtocolInformationDump(
522 IN CONST EFI_HANDLE TheHandle
,
523 IN CONST EFI_GUID
*Guid
,
524 IN CONST BOOLEAN Verbose
527 CONST PROTOCOL_INFO_BLOCK
*Id
;
529 ASSERT(TheHandle
!= NULL
);
530 ASSERT(Guid
!= NULL
);
532 if (TheHandle
== NULL
|| Guid
== NULL
) {
536 Id
= InternalShellGetNodeFromGuid(Guid
);
537 if (Id
!= NULL
&& Id
->DumpInfo
!= NULL
) {
538 return (Id
->DumpInfo(TheHandle
, Verbose
));
544 Function to get the Guid for a protocol or struct based on it's string name.
546 @param[in] Name The pointer to the string name.
547 @param[in] Lang The pointer to the language code.
548 @param[in] Guid The pointer to the Guid.
550 @retval EFI_SUCCESS The operation was sucessful.
554 GetGuidFromStringName(
555 IN CONST CHAR16
*Name
,
556 IN CONST CHAR8
*Lang OPTIONAL
,
560 CONST PROTOCOL_INFO_BLOCK
*ListWalker
;
563 ASSERT(Guid
!= NULL
);
565 return (EFI_INVALID_PARAMETER
);
569 if (PcdGetBool(PcdShellIncludeNtGuids
)) {
570 for (ListWalker
= mGuidStringListNT
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
571 String
= HiiGetString(mHandleParsingHiiHandle
, ListWalker
->StringId
, Lang
);
572 if (Name
!= NULL
&& String
!= NULL
&& StrCmp(Name
, String
)==0) {
573 *Guid
= ListWalker
->GuidId
;
575 SHELL_FREE_NON_NULL(String
);
577 return (EFI_SUCCESS
);
581 for (ListWalker
= mGuidStringList
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
582 String
= HiiGetString(mHandleParsingHiiHandle
, ListWalker
->StringId
, Lang
);
583 if (Name
!= NULL
&& String
!= NULL
&& StrCmp(Name
, String
)==0) {
584 *Guid
= ListWalker
->GuidId
;
586 SHELL_FREE_NON_NULL(String
);
588 return (EFI_SUCCESS
);
591 return (EFI_NOT_FOUND
);
595 Function to retrieve the driver name (if possible) from the ComponentName or
596 ComponentName2 protocol
598 @param[in] TheHandle The driver handle to get the name of.
599 @param[in] Language The language to use.
601 @retval NULL The name could not be found.
602 @return A pointer to the string name. Do not de-allocate the memory.
606 GetStringNameFromHandle(
607 IN CONST EFI_HANDLE TheHandle
,
608 IN CONST CHAR8
*Language
611 EFI_COMPONENT_NAME2_PROTOCOL
*CompNameStruct
;
615 Status
= gBS
->OpenProtocol(
617 &gEfiComponentName2ProtocolGuid
,
618 (VOID
**)&CompNameStruct
,
621 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
622 if (!EFI_ERROR(Status
)) {
623 Status
= CompNameStruct
->GetDriverName(CompNameStruct
, (CHAR8
*)Language
, &RetVal
);
624 if (!EFI_ERROR(Status
)) {
628 Status
= gBS
->OpenProtocol(
630 &gEfiComponentNameProtocolGuid
,
631 (VOID
**)&CompNameStruct
,
634 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
635 if (!EFI_ERROR(Status
)) {
636 Status
= CompNameStruct
->GetDriverName(CompNameStruct
, (CHAR8
*)Language
, &RetVal
);
637 if (!EFI_ERROR(Status
)) {
645 Function to initialize the file global mHandleList object for use in
646 vonverting handles to index and index to handle.
648 @retval EFI_SUCCESS The operation was successful.
652 InternalShellInitHandleList(
657 EFI_HANDLE
*HandleBuffer
;
659 HANDLE_LIST
*ListWalker
;
661 if (mHandleList
.NextIndex
!= 0) {
664 InitializeListHead(&mHandleList
.List
.Link
);
665 mHandleList
.NextIndex
= 1;
666 Status
= gBS
->LocateHandleBuffer (
673 ASSERT_EFI_ERROR(Status
);
674 if (EFI_ERROR(Status
)) {
677 for (mHandleList
.NextIndex
= 1 ; mHandleList
.NextIndex
<= HandleCount
; mHandleList
.NextIndex
++){
678 ListWalker
= AllocateZeroPool(sizeof(HANDLE_LIST
));
679 ASSERT(ListWalker
!= NULL
);
680 ListWalker
->TheHandle
= HandleBuffer
[mHandleList
.NextIndex
-1];
681 ListWalker
->TheIndex
= mHandleList
.NextIndex
;
682 InsertTailList(&mHandleList
.List
.Link
,&ListWalker
->Link
);
684 FreePool(HandleBuffer
);
685 return (EFI_SUCCESS
);
689 Function to retrieve the human-friendly index of a given handle. If the handle
690 does not have a index one will be automatically assigned. The index value is valid
691 until the termination of the shell application.
693 @param[in] TheHandle The handle to retrieve an index for.
695 @retval 0 A memory allocation failed.
696 @return The index of the handle.
701 ConvertHandleToHandleIndex(
702 IN CONST EFI_HANDLE TheHandle
705 HANDLE_LIST
*ListWalker
;
706 if (TheHandle
== NULL
) {
710 InternalShellInitHandleList();
712 for (ListWalker
= (HANDLE_LIST
*)GetFirstNode(&mHandleList
.List
.Link
)
713 ; !IsNull(&mHandleList
.List
.Link
,&ListWalker
->Link
)
714 ; ListWalker
= (HANDLE_LIST
*)GetNextNode(&mHandleList
.List
.Link
,&ListWalker
->Link
)
716 if (ListWalker
->TheHandle
== TheHandle
) {
717 return (ListWalker
->TheIndex
);
720 ListWalker
= AllocateZeroPool(sizeof(HANDLE_LIST
));
721 ASSERT(ListWalker
!= NULL
);
722 ListWalker
->TheHandle
= TheHandle
;
723 ListWalker
->TheIndex
= mHandleList
.NextIndex
++;
724 InsertTailList(&mHandleList
.List
.Link
,&ListWalker
->Link
);
725 return (ListWalker
->TheIndex
);
731 Function to retrieve the EFI_HANDLE from the human-friendly index.
733 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.
735 @retval NULL The index was invalid.
736 @return The EFI_HANDLE that index represents.
741 ConvertHandleIndexToHandle(
742 IN CONST UINTN TheIndex
745 HANDLE_LIST
*ListWalker
;
747 InternalShellInitHandleList();
749 if (TheIndex
>= mHandleList
.NextIndex
) {
753 for (ListWalker
= (HANDLE_LIST
*)GetFirstNode(&mHandleList
.List
.Link
)
754 ; !IsNull(&mHandleList
.List
.Link
,&ListWalker
->Link
)
755 ; ListWalker
= (HANDLE_LIST
*)GetNextNode(&mHandleList
.List
.Link
,&ListWalker
->Link
)
757 if (ListWalker
->TheIndex
== TheIndex
) {
758 return (ListWalker
->TheHandle
);
765 Gets all the related EFI_HANDLEs based on the mask supplied.
767 This function scans all EFI_HANDLES in the UEFI environment's handle database
768 and returns the ones with the specified relationship (Mask) to the specified
771 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
772 If MatchingHandleCount is NULL, then ASSERT.
774 If MatchingHandleBuffer is not NULL upon a successful return the memory must be
777 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.
778 @param[in] ControllerHandle The handle with Device Path protocol on it.
779 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in
780 MatchingHandleBuffer.
781 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount
782 EFI_HANDLEs with a terminating NULL EFI_HANDLE.
783 @param[out] HandleType An array of type information.
785 @retval EFI_SUCCESS The operation was successful, and any related handles
786 are in MatchingHandleBuffer.
787 @retval EFI_NOT_FOUND No matching handles were found.
788 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
792 ParseHandleDatabaseByRelationshipWithType (
793 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL
,
794 IN CONST EFI_HANDLE ControllerHandle OPTIONAL
,
795 IN UINTN
*HandleCount
,
796 OUT EFI_HANDLE
**HandleBuffer
,
797 OUT UINTN
**HandleType
802 EFI_GUID
**ProtocolGuidArray
;
805 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfo
;
810 ASSERT(HandleCount
!= NULL
);
811 ASSERT(HandleBuffer
!= NULL
);
812 ASSERT(HandleType
!= NULL
);
813 ASSERT(DriverBindingHandle
!= NULL
|| ControllerHandle
!= NULL
);
816 *HandleBuffer
= NULL
;
820 // Retrieve the list of all handles from the handle database
822 Status
= gBS
->LocateHandleBuffer (
829 if (EFI_ERROR (Status
)) {
833 *HandleType
= AllocateZeroPool (*HandleCount
* sizeof (UINTN
));
834 ASSERT(*HandleType
!= NULL
);
836 for (HandleIndex
= 0; HandleIndex
< *HandleCount
; HandleIndex
++) {
838 // Retrieve the list of all the protocols on each handle
840 Status
= gBS
->ProtocolsPerHandle (
841 (*HandleBuffer
)[HandleIndex
],
845 if (!EFI_ERROR (Status
)) {
847 for (ProtocolIndex
= 0; ProtocolIndex
< ArrayCount
; ProtocolIndex
++) {
850 // Set the bit describing what this handle has
852 if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiLoadedImageProtocolGuid
) ) {
853 (*HandleType
)[HandleIndex
] |= HR_IMAGE_HANDLE
;
854 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverBindingProtocolGuid
) ) {
855 (*HandleType
)[HandleIndex
] |= HR_DRIVER_BINDING_HANDLE
;
856 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverConfiguration2ProtocolGuid
)) {
857 (*HandleType
)[HandleIndex
] |= HR_DRIVER_CONFIGURATION_HANDLE
;
858 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverConfigurationProtocolGuid
) ) {
859 (*HandleType
)[HandleIndex
] |= HR_DRIVER_CONFIGURATION_HANDLE
;
860 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverDiagnostics2ProtocolGuid
) ) {
861 (*HandleType
)[HandleIndex
] |= HR_DRIVER_DIAGNOSTICS_HANDLE
;
862 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverDiagnosticsProtocolGuid
) ) {
863 (*HandleType
)[HandleIndex
] |= HR_DRIVER_DIAGNOSTICS_HANDLE
;
864 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiComponentName2ProtocolGuid
) ) {
865 (*HandleType
)[HandleIndex
] |= HR_COMPONENT_NAME_HANDLE
;
866 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiComponentNameProtocolGuid
) ) {
867 (*HandleType
)[HandleIndex
] |= HR_COMPONENT_NAME_HANDLE
;
868 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDevicePathProtocolGuid
) ) {
869 (*HandleType
)[HandleIndex
] |= HR_DEVICE_HANDLE
;
872 ASSERT((*HandleType
)[HandleIndex
] == (*HandleType
)[HandleIndex
]);
876 // Retrieve the list of agents that have opened each protocol
878 Status
= gBS
->OpenProtocolInformation (
879 (*HandleBuffer
)[HandleIndex
],
880 ProtocolGuidArray
[ProtocolIndex
],
884 if (!EFI_ERROR (Status
)) {
885 for (OpenInfoIndex
= 0; OpenInfoIndex
< OpenInfoCount
; OpenInfoIndex
++) {
886 if (DriverBindingHandle
!= NULL
&& OpenInfo
[OpenInfoIndex
].AgentHandle
== DriverBindingHandle
) {
887 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) == EFI_OPEN_PROTOCOL_BY_DRIVER
) {
888 (*HandleType
)[HandleIndex
] |= (HR_DEVICE_HANDLE
| HR_CONTROLLER_HANDLE
);
890 if (ControllerHandle
!= NULL
&& (*HandleBuffer
)[HandleIndex
] == ControllerHandle
) {
891 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
892 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
893 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].ControllerHandle
) {
894 (*HandleType
)[ChildIndex
] |= (HR_DEVICE_HANDLE
| HR_CHILD_HANDLE
);
900 if (DriverBindingHandle
== NULL
&& OpenInfo
[OpenInfoIndex
].ControllerHandle
== ControllerHandle
) {
901 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) == EFI_OPEN_PROTOCOL_BY_DRIVER
) {
902 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
903 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].AgentHandle
) {
904 (*HandleType
)[ChildIndex
] |= HR_DEVICE_DRIVER
;
908 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
909 (*HandleType
)[HandleIndex
] |= HR_PARENT_HANDLE
;
910 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
911 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].AgentHandle
) {
912 (*HandleType
)[ChildIndex
] |= HR_BUS_DRIVER
;
923 FreePool (ProtocolGuidArray
);
927 if (EFI_ERROR(Status
)) {
928 if (*HandleType
!= NULL
) {
929 FreePool (*HandleType
);
931 if (*HandleBuffer
!= NULL
) {
932 FreePool (*HandleBuffer
);
936 *HandleBuffer
= NULL
;
944 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
947 This function will scan all EFI_HANDLES in the UEFI environment's handle database
948 and return all the ones with the specified relationship (Mask) to the specified
951 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
952 If MatchingHandleCount is NULL, then ASSERT.
954 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
957 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol
959 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.
960 @param[in] Mask Mask of what relationship(s) is desired.
961 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in
962 MatchingHandleBuffer.
963 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount
964 EFI_HANDLEs and a terminating NULL EFI_HANDLE.
966 @retval EFI_SUCCESS The operation was sucessful and any related handles
967 are in MatchingHandleBuffer;
968 @retval EFI_NOT_FOUND No matching handles were found.
969 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
973 ParseHandleDatabaseByRelationship (
974 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL
,
975 IN CONST EFI_HANDLE ControllerHandle OPTIONAL
,
977 IN UINTN
*MatchingHandleCount
,
978 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
983 EFI_HANDLE
*HandleBuffer
;
987 ASSERT(MatchingHandleCount
!= NULL
);
988 ASSERT(DriverBindingHandle
!= NULL
|| ControllerHandle
!= NULL
);
990 if ((Mask
& HR_VALID_MASK
) != Mask
) {
991 return (EFI_INVALID_PARAMETER
);
994 if ((Mask
& HR_CHILD_HANDLE
) != 0 && DriverBindingHandle
== NULL
) {
995 return (EFI_INVALID_PARAMETER
);
998 *MatchingHandleCount
= 0;
999 if (MatchingHandleBuffer
!= NULL
) {
1000 *MatchingHandleBuffer
= NULL
;
1003 HandleBuffer
= NULL
;
1006 Status
= ParseHandleDatabaseByRelationshipWithType (
1007 DriverBindingHandle
,
1013 if (!EFI_ERROR (Status
)) {
1015 // Count the number of handles that match the attributes in Mask
1017 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
1018 if ((HandleType
[HandleIndex
] & Mask
) == Mask
) {
1019 (*MatchingHandleCount
)++;
1023 // If no handles match the attributes in Mask then return EFI_NOT_FOUND
1025 if (*MatchingHandleCount
== 0) {
1026 Status
= EFI_NOT_FOUND
;
1029 if (MatchingHandleBuffer
== NULL
) {
1031 // Someone just wanted the count...
1033 Status
= EFI_SUCCESS
;
1036 // Allocate a handle buffer for the number of handles that matched the attributes in Mask
1038 *MatchingHandleBuffer
= AllocateZeroPool ((*MatchingHandleCount
+1)* sizeof (EFI_HANDLE
));
1039 ASSERT(*MatchingHandleBuffer
!= NULL
);
1041 for (HandleIndex
= 0,*MatchingHandleCount
= 0
1042 ; HandleIndex
< HandleCount
1046 // Fill the allocated buffer with the handles that matched the attributes in Mask
1048 if ((HandleType
[HandleIndex
] & Mask
) == Mask
) {
1049 (*MatchingHandleBuffer
)[(*MatchingHandleCount
)++] = HandleBuffer
[HandleIndex
];
1054 // Make the last one NULL
1056 (*MatchingHandleBuffer
)[*MatchingHandleCount
] = NULL
;
1058 Status
= EFI_SUCCESS
;
1059 } // MacthingHandleBuffer == NULL (ELSE)
1060 } // *MatchingHandleCount == 0 (ELSE)
1061 } // no error on ParseHandleDatabaseByRelationshipWithType
1063 if (HandleBuffer
!= NULL
) {
1064 FreePool (HandleBuffer
);
1067 if (HandleType
!= NULL
) {
1068 FreePool (HandleType
);
1075 Gets handles for any child controllers of the passed in controller.
1077 @param[in] ControllerHandle The handle of the "parent controller"
1078 @param[in] MatchingHandleCount Pointer to the number of handles in
1079 MatchingHandleBuffer on return.
1080 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1084 @retval EFI_SUCCESS The operation was sucessful.
1088 ParseHandleDatabaseForChildControllers(
1089 IN CONST EFI_HANDLE ControllerHandle
,
1090 IN UINTN
*MatchingHandleCount
,
1091 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
1095 // UINTN HandleIndex;
1096 UINTN DriverBindingHandleCount
;
1097 EFI_HANDLE
*DriverBindingHandleBuffer
;
1098 UINTN DriverBindingHandleIndex
;
1099 UINTN ChildControllerHandleCount
;
1100 EFI_HANDLE
*ChildControllerHandleBuffer
;
1101 UINTN ChildControllerHandleIndex
;
1103 EFI_HANDLE
*HandleBufferForReturn
;
1105 if (MatchingHandleCount
== NULL
) {
1106 return (EFI_INVALID_PARAMETER
);
1108 *MatchingHandleCount
= 0;
1110 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
1112 &DriverBindingHandleCount
,
1113 &DriverBindingHandleBuffer
1115 if (EFI_ERROR (Status
)) {
1120 // Get a buffer big enough for all the controllers.
1122 HandleBufferForReturn
= GetHandleListByProtocol(&gEfiDevicePathProtocolGuid
);
1123 if (HandleBufferForReturn
== NULL
) {
1124 FreePool (DriverBindingHandleBuffer
);
1125 return (EFI_NOT_FOUND
);
1128 for (DriverBindingHandleIndex
= 0; DriverBindingHandleIndex
< DriverBindingHandleCount
; DriverBindingHandleIndex
++) {
1129 Status
= PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1130 DriverBindingHandleBuffer
[DriverBindingHandleIndex
],
1132 &ChildControllerHandleCount
,
1133 &ChildControllerHandleBuffer
1135 if (EFI_ERROR (Status
)) {
1139 for (ChildControllerHandleIndex
= 0;
1140 ChildControllerHandleIndex
< ChildControllerHandleCount
;
1141 ChildControllerHandleIndex
++
1144 HandleBufferForReturn
[(*MatchingHandleCount
)++] = ChildControllerHandleBuffer
[ChildControllerHandleIndex
];
1145 // for (HandleIndex = 0; HandleBufferForReturn[HandleIndex] != NULL; HandleIndex++) {
1146 // if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
1153 // HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1157 FreePool (ChildControllerHandleBuffer
);
1160 FreePool (DriverBindingHandleBuffer
);
1162 if (MatchingHandleBuffer
!= NULL
) {
1163 *MatchingHandleBuffer
= HandleBufferForReturn
;
1165 FreePool(HandleBufferForReturn
);
1168 return (EFI_SUCCESS
);
1172 Appends 1 buffer to another buffer. This will re-allocate the destination buffer
1173 if necessary to fit all of the data.
1175 If DestinationBuffer is NULL, then ASSERT().
1177 @param[in, out] DestinationBuffer The pointer to the pointer to the buffer to append onto.
1178 @param[in, out] DestinationSize The pointer to the size of DestinationBuffer.
1179 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.
1180 @param[in] SourceSize The number of bytes of SourceBuffer to append.
1182 @retval NULL A memory allocation failed.
1183 @retval NULL A parameter was invalid.
1184 @return A pointer to (*DestinationBuffer).
1189 IN OUT VOID
**DestinationBuffer
,
1190 IN OUT UINTN
*DestinationSize
,
1191 IN VOID
*SourceBuffer
,
1195 UINTN LocalDestinationSize
;
1196 UINTN LocalDestinationFinalSize
;
1198 ASSERT(DestinationBuffer
!= NULL
);
1200 if (SourceSize
== 0 || SourceBuffer
== NULL
) {
1201 return (*DestinationBuffer
);
1204 if (DestinationSize
== NULL
) {
1205 LocalDestinationSize
= 0;
1207 LocalDestinationSize
= *DestinationSize
;
1210 LocalDestinationFinalSize
= LocalDestinationSize
+ SourceSize
;
1212 if (DestinationSize
!= NULL
) {
1213 *DestinationSize
= LocalDestinationSize
;
1216 if (LocalDestinationSize
== 0) {
1218 *DestinationBuffer
= AllocateZeroPool(LocalDestinationFinalSize
);
1221 *DestinationBuffer
= ReallocatePool(LocalDestinationSize
, LocalDestinationFinalSize
, *DestinationBuffer
);
1224 ASSERT(*DestinationBuffer
!= NULL
);
1227 return (CopyMem(((UINT8
*)(*DestinationBuffer
)) + LocalDestinationSize
, SourceBuffer
, SourceSize
));
1231 Gets handles for any child devices produced by the passed in driver.
1233 @param[in] DriverHandle The handle of the driver.
1234 @param[in] MatchingHandleCount Pointer to the number of handles in
1235 MatchingHandleBuffer on return.
1236 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1238 @retval EFI_SUCCESS The operation was sucessful.
1239 @sa ParseHandleDatabaseByRelationship
1243 ParseHandleDatabaseForChildDevices(
1244 IN CONST EFI_HANDLE DriverHandle
,
1245 IN UINTN
*MatchingHandleCount
,
1246 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
1250 EFI_HANDLE
*Buffer2
;
1255 UINTN HandleBufferSize
;
1257 ASSERT(MatchingHandleCount
!= NULL
);
1259 HandleBufferSize
= 0;
1262 *MatchingHandleCount
= 0;
1264 Status
= PARSE_HANDLE_DATABASE_DEVICES (
1269 if (!EFI_ERROR (Status
)) {
1270 for (HandleIndex
= 0; HandleIndex
< Count1
; HandleIndex
++) {
1272 // now find the children
1274 Status
= PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1276 Buffer
[HandleIndex
],
1280 if (EFI_ERROR(Status
)) {
1284 // save out required and optional data elements
1286 *MatchingHandleCount
+= Count2
;
1287 if (MatchingHandleBuffer
!= NULL
) {
1288 *MatchingHandleBuffer
= BuffernCatGrow((VOID
**)MatchingHandleBuffer
, &HandleBufferSize
, Buffer2
, Count2
* sizeof(Buffer2
[0]));
1294 if (Buffer2
!= NULL
) {
1300 if (Buffer
!= NULL
) {
1307 Function to get all handles that support a given protocol or all handles.
1309 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL
1310 then the function will return all handles.
1312 @retval NULL A memory allocation failed.
1313 @return A NULL terminated list of handles.
1317 GetHandleListByProtocol (
1318 IN CONST EFI_GUID
*ProtocolGuid OPTIONAL
1321 EFI_HANDLE
*HandleList
;
1329 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
1331 if (ProtocolGuid
== NULL
) {
1332 Status
= gBS
->LocateHandle(AllHandles
, NULL
, NULL
, &Size
, HandleList
);
1333 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1334 HandleList
= AllocateZeroPool(Size
+ sizeof(EFI_HANDLE
));
1335 if (HandleList
== NULL
) {
1338 Status
= gBS
->LocateHandle(AllHandles
, NULL
, NULL
, &Size
, HandleList
);
1339 HandleList
[Size
/sizeof(EFI_HANDLE
)] = NULL
;
1342 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)ProtocolGuid
, NULL
, &Size
, HandleList
);
1343 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1344 HandleList
= AllocateZeroPool(Size
+ sizeof(EFI_HANDLE
));
1345 if (HandleList
== NULL
) {
1348 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)ProtocolGuid
, NULL
, &Size
, HandleList
);
1349 HandleList
[Size
/sizeof(EFI_HANDLE
)] = NULL
;
1352 if (EFI_ERROR(Status
)) {
1353 if (HandleList
!= NULL
) {
1354 FreePool(HandleList
);
1358 return (HandleList
);
1362 Function to get all handles that support some protocols.
1364 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.
1366 @retval NULL A memory allocation failed.
1367 @retval NULL ProtocolGuids was NULL.
1368 @return A NULL terminated list of EFI_HANDLEs.
1372 GetHandleListByProtocolList (
1373 IN CONST EFI_GUID
**ProtocolGuids
1376 EFI_HANDLE
*HandleList
;
1381 CONST EFI_GUID
**GuidWalker
;
1382 EFI_HANDLE
*HandleWalker1
;
1383 EFI_HANDLE
*HandleWalker2
;
1387 TotalSize
= sizeof(EFI_HANDLE
);
1389 for (GuidWalker
= ProtocolGuids
; GuidWalker
!= NULL
&& *GuidWalker
!= NULL
; GuidWalker
++,Size
= 0){
1390 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)(*GuidWalker
), NULL
, &Size
, NULL
);
1391 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1397 // No handles were found...
1399 if (TotalSize
== sizeof(EFI_HANDLE
)) {
1403 HandleList
= AllocateZeroPool(TotalSize
);
1404 if (HandleList
== NULL
) {
1409 for (GuidWalker
= ProtocolGuids
; GuidWalker
!= NULL
&& *GuidWalker
!= NULL
; GuidWalker
++){
1410 TempSize
= TotalSize
- Size
;
1411 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)(*GuidWalker
), NULL
, &TempSize
, HandleList
+(Size
/sizeof(EFI_HANDLE
)));
1414 // Allow for missing protocols... Only update the 'used' size upon success.
1416 if (!EFI_ERROR(Status
)) {
1420 ASSERT(HandleList
[(TotalSize
/sizeof(EFI_HANDLE
))-1] == NULL
);
1422 for (HandleWalker1
= HandleList
; HandleWalker1
!= NULL
&& *HandleWalker1
!= NULL
; HandleWalker1
++) {
1423 for (HandleWalker2
= HandleWalker1
+ 1; HandleWalker2
!= NULL
&& *HandleWalker2
!= NULL
; HandleWalker2
++) {
1424 if (*HandleWalker1
== *HandleWalker2
) {
1426 // copy memory back 1 handle width.
1428 CopyMem(HandleWalker2
, HandleWalker2
+ 1, TotalSize
- ((HandleWalker2
-HandleList
+1)*sizeof(EFI_HANDLE
)));
1433 return (HandleList
);