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"
18 STATIC CONST EFI_GUID mHandleParsingHiiGuid
= \
20 0xb8969637, 0x81de, 0x43af, { 0xbc, 0x9a, 0x24, 0xd9, 0x89, 0x13, 0xf2, 0xf6 } \
22 EFI_HANDLE mHandleParsingHiiHandle
;
23 HANDLE_INDEX_LIST mHandleList
= {{{NULL
,NULL
},0,0},0};
26 Constructor for the library.
28 @param[in] ImageHandle Ignored.
29 @param[in] SystemTable Ignored.
31 @retval EFI_SUCCESS The operation was successful.
35 HandleParsingLibConstructor (
36 IN EFI_HANDLE ImageHandle
,
37 IN EFI_SYSTEM_TABLE
*SystemTable
40 mHandleParsingHiiHandle
= HiiAddPackages (&mHandleParsingHiiGuid
, gImageHandle
, UefiHandleParsingLibStrings
, NULL
);
41 if (mHandleParsingHiiHandle
== NULL
) {
42 return (EFI_DEVICE_ERROR
);
49 Destructor for the library. free any resources.
51 @param[in] ImageHandle Ignored.
52 @param[in] SystemTable Ignored.
54 @retval EFI_SUCCESS The operation was successful.
58 HandleParsingLibDestructor (
59 IN EFI_HANDLE ImageHandle
,
60 IN EFI_SYSTEM_TABLE
*SystemTable
63 if (mHandleParsingHiiHandle
!= NULL
) {
64 HiiRemovePackages(mHandleParsingHiiHandle
);
72 LoadedImageProtocolDumpInformation(
73 IN CONST EFI_HANDLE TheHandle,
74 IN CONST BOOLEAN Verbose
77 EFI_LOADED_IMAGE_PROTOCOL *Image;
79 EFI_DEVICE_PATH_PROTOCOL *DevPath;
80 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
83 UINT32 AuthenticationStatus;
85 EFI_FIRMWARE_VOLUME_PROTOCOL *FV;
86 EFI_FIRMWARE_VOLUME2_PROTOCOL *FV2;
93 Status = HandleProtocol (
95 &gEfiLoadedImageProtocolGuid,
97 ASSERT_EFI_ERROR(Status);
99 DevPath = UnpackDevicePath (Image->FilePath);
101 if (DevPath == NULL) {
105 DevPathNode = DevPath;
107 while (!IsDevicePathEnd (DevPathNode)) {
109 // Find the Fv File path
111 NameGuid = GetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevPathNode);
112 if (NameGuid != NULL) {
113 Status = BS->HandleProtocol (
115 &gEfiFirmwareVolumeProtocolGuid,
118 if (!EFI_ERROR (Status)) {
119 Status = FV->ReadSection (
122 EFI_SECTION_USER_INTERFACE,
126 &AuthenticationStatus
128 if (!EFI_ERROR (Status)) {
134 Status = BS->HandleProtocol (
136 &gEfiFirmwareVolume2ProtocolGuid,
139 if (!EFI_ERROR (Status)) {
140 Status = FV2->ReadSection (
143 EFI_SECTION_USER_INTERFACE,
147 &AuthenticationStatus
149 if (!EFI_ERROR (Status)) {
158 // Next device path node
160 DevPathNode = NextDevicePathNode (DevPathNode);
169 Function to dump information about SimpleTextOut.
171 This will allocate the return buffer from boot services pool.
173 @param[in] TheHandle The handle that has SimpleTextOut installed.
174 @param[in] Verbose TRUE for additional information, FALSE otherwise.
176 @retval A poitner to a string containing the information.
180 TxtOutProtocolDumpInformation(
181 IN CONST EFI_HANDLE TheHandle
,
182 IN CONST BOOLEAN Verbose
185 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*Dev
;
202 Status
= gBS
->HandleProtocol(
204 &gEfiSimpleTextOutProtocolGuid
,
207 ASSERT_EFI_ERROR(Status
);
208 ASSERT (Dev
!= NULL
&& Dev
->Mode
!= NULL
);
210 Size
= (Dev
->Mode
->MaxMode
+ 1) * 80;
211 RetVal
= AllocateZeroPool(Size
);
213 Temp
= HiiGetString(mHandleParsingHiiHandle
, STRING_TOKEN(STR_TXT_OUT_DUMP_HEADER
), NULL
);
214 UnicodeSPrint(RetVal
, Size
, Temp
, Dev
, Dev
->Mode
->Attribute
);
220 Temp
= HiiGetString(mHandleParsingHiiHandle
, STRING_TOKEN(STR_TXT_OUT_DUMP_LINE
), NULL
);
221 for (Index
= 0; Index
< Dev
->Mode
->MaxMode
; Index
++) {
222 Status
= Dev
->QueryMode (Dev
, Index
, &Col
, &Row
);
223 NewSize
= Size
- StrSize(RetVal
);
225 RetVal
+ StrLen(RetVal
),
228 Index
== Dev
->Mode
->Mode
? L
'*' : L
' ',
230 !EFI_ERROR(Status
)?Col
:-1,
231 !EFI_ERROR(Status
)?Row
:-1
238 STATIC CONST UINTN VersionStringSize
= 60;
241 Function to dump information about EfiDriverSupportedEfiVersion protocol.
243 This will allocate the return buffer from boot services pool.
245 @param[in] TheHandle The handle that has the protocol installed.
246 @param[in] Verbose TRUE for additional information, FALSE otherwise.
248 @retval A poitner to a string containing the information.
252 DriverEfiVersionProtocolDumpInformation(
253 IN CONST EFI_HANDLE TheHandle
,
254 IN CONST BOOLEAN Verbose
257 EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
*DriverEfiVersion
;
261 Status
= gBS
->HandleProtocol(
263 &gEfiDriverSupportedEfiVersionProtocolGuid
,
264 (VOID
**)&DriverEfiVersion
);
266 ASSERT_EFI_ERROR(Status
);
268 RetVal
= AllocateZeroPool(VersionStringSize
);
269 ASSERT(RetVal
!= NULL
);
270 UnicodeSPrint(RetVal
, VersionStringSize
, L
"0x%08x", DriverEfiVersion
->FirmwareVersion
);
275 Function to dump information about DevicePath protocol.
277 This will allocate the return buffer from boot services pool.
279 @param[in] TheHandle The handle that has the protocol installed.
280 @param[in] Verbose TRUE for additional information, FALSE otherwise.
282 @retval A poitner to a string containing the information.
286 DevicePathProtocolDumpInformation(
287 IN CONST EFI_HANDLE TheHandle
,
288 IN CONST BOOLEAN Verbose
291 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
295 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*DevPathToText
;
298 Status
= gBS
->LocateProtocol(&gEfiDevicePathToTextProtocolGuid
, NULL
, (VOID
**)&DevPathToText
);
299 if (!EFI_ERROR(Status
)) {
300 Status
= gBS
->OpenProtocol(TheHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPath
, gImageHandle
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
301 if (!EFI_ERROR(Status
)) {
303 // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)
305 Temp
= DevPathToText
->ConvertDevicePathToText(DevPath
, TRUE
, TRUE
);
306 gBS
->CloseProtocol(TheHandle
, &gEfiDevicePathProtocolGuid
, gImageHandle
, NULL
);
309 if (!Verbose
&& Temp
!= NULL
&& StrLen(Temp
) > 30) {
311 Temp2
= StrnCatGrow(&Temp2
, NULL
, Temp
+(StrLen(Temp
) - 30), 30);
319 // Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
321 #define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \
323 0x58c518b1, 0x76f3, 0x11d4, 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
326 #define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \
328 0x96eb4ad6, 0xa32a, 0x11d4, 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
331 #define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \
333 0xc95a93d, 0xa006, 0x11d4, 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 \
335 STATIC CONST EFI_GUID WinNtThunkProtocolGuid
= LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID
;
336 STATIC CONST EFI_GUID WinNtIoProtocolGuid
= LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID
;
337 STATIC CONST EFI_GUID WinNtSerialPortGuid
= LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID
;
339 STATIC CONST PROTOCOL_INFO_BLOCK mGuidStringListNT
[] = {
340 {STRING_TOKEN(STR_WINNT_THUNK
), (EFI_GUID
*)&WinNtThunkProtocolGuid
, NULL
},
341 {STRING_TOKEN(STR_WINNT_DRIVER_IO
), (EFI_GUID
*)&WinNtIoProtocolGuid
, NULL
},
342 {STRING_TOKEN(STR_WINNT_SERIAL_PORT
), (EFI_GUID
*)&WinNtSerialPortGuid
, NULL
},
343 {STRING_TOKEN(STR_UNKNOWN_DEVICE
), NULL
, NULL
},
346 STATIC CONST PROTOCOL_INFO_BLOCK mGuidStringList
[] = {
347 {STRING_TOKEN(STR_LOADED_IMAGE
), &gEfiLoadedImageProtocolGuid
, NULL
},
348 {STRING_TOKEN(STR_DEVICE_PATH
), &gEfiDevicePathProtocolGuid
, DevicePathProtocolDumpInformation
},
349 {STRING_TOKEN(STR_IMAGE_PATH
), &gEfiLoadedImageDevicePathProtocolGuid
, DevicePathProtocolDumpInformation
},
350 {STRING_TOKEN(STR_DEVICE_PATH_UTIL
), &gEfiDevicePathUtilitiesProtocolGuid
, NULL
},
351 {STRING_TOKEN(STR_DEVICE_PATH_TXT
), &gEfiDevicePathToTextProtocolGuid
, NULL
},
352 {STRING_TOKEN(STR_DEVICE_PATH_FTXT
), &gEfiDevicePathFromTextProtocolGuid
, NULL
},
353 {STRING_TOKEN(STR_DEVICE_PATH_PC
), &gEfiPcAnsiGuid
, NULL
},
354 {STRING_TOKEN(STR_DEVICE_PATH_VT100
), &gEfiVT100Guid
, NULL
},
355 {STRING_TOKEN(STR_DEVICE_PATH_VT100P
), &gEfiVT100PlusGuid
, NULL
},
356 {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8
), &gEfiVTUTF8Guid
, NULL
},
357 {STRING_TOKEN(STR_DRIVER_BINDING
), &gEfiDriverBindingProtocolGuid
, NULL
},
358 {STRING_TOKEN(STR_PLATFORM_OVERRIDE
), &gEfiPlatformDriverOverrideProtocolGuid
, NULL
},
359 {STRING_TOKEN(STR_BUS_OVERRIDE
), &gEfiBusSpecificDriverOverrideProtocolGuid
, NULL
},
360 {STRING_TOKEN(STR_DRIVER_DIAG
), &gEfiDriverDiagnosticsProtocolGuid
, NULL
},
361 {STRING_TOKEN(STR_DRIVER_DIAG2
), &gEfiDriverDiagnostics2ProtocolGuid
, NULL
},
362 {STRING_TOKEN(STR_DRIVER_CN
), &gEfiComponentNameProtocolGuid
, NULL
},
363 {STRING_TOKEN(STR_DRIVER_CN2
), &gEfiComponentName2ProtocolGuid
, NULL
},
364 {STRING_TOKEN(STR_PLAT_DRV_CFG
), &gEfiPlatformToDriverConfigurationProtocolGuid
, NULL
},
365 {STRING_TOKEN(STR_DRIVER_VERSION
), &gEfiDriverSupportedEfiVersionProtocolGuid
, DriverEfiVersionProtocolDumpInformation
},
366 {STRING_TOKEN(STR_TXT_IN
), &gEfiSimpleTextInProtocolGuid
, NULL
},
367 {STRING_TOKEN(STR_TXT_IN_EX
), &gEfiSimpleTextInputExProtocolGuid
, NULL
},
368 {STRING_TOKEN(STR_TXT_OUT
), &gEfiSimpleTextOutProtocolGuid
, TxtOutProtocolDumpInformation
},
369 {STRING_TOKEN(STR_SIM_POINTER
), &gEfiSimplePointerProtocolGuid
, NULL
},
370 {STRING_TOKEN(STR_ABS_POINTER
), &gEfiAbsolutePointerProtocolGuid
, NULL
},
371 {STRING_TOKEN(STR_SERIAL_IO
), &gEfiSerialIoProtocolGuid
, NULL
},
372 {STRING_TOKEN(STR_GRAPHICS_OUTPUT
), &gEfiGraphicsOutputProtocolGuid
, NULL
},
373 {STRING_TOKEN(STR_EDID_DISCOVERED
), &gEfiEdidDiscoveredProtocolGuid
, NULL
},
374 {STRING_TOKEN(STR_EDID_ACTIVE
), &gEfiEdidActiveProtocolGuid
, NULL
},
375 {STRING_TOKEN(STR_EDID_OVERRIDE
), &gEfiEdidOverrideProtocolGuid
, NULL
},
376 {STRING_TOKEN(STR_CON_IN
), &gEfiConsoleInDeviceGuid
, NULL
},
377 {STRING_TOKEN(STR_CON_OUT
), &gEfiConsoleOutDeviceGuid
, NULL
},
378 {STRING_TOKEN(STR_STD_ERR
), &gEfiStandardErrorDeviceGuid
, NULL
},
379 {STRING_TOKEN(STR_LOAD_FILE
), &gEfiLoadFileProtocolGuid
, NULL
},
380 {STRING_TOKEN(STR_LOAD_FILE2
), &gEfiLoadFile2ProtocolGuid
, NULL
},
381 {STRING_TOKEN(STR_SIMPLE_FILE_SYS
), &gEfiSimpleFileSystemProtocolGuid
, NULL
},
382 {STRING_TOKEN(STR_FILE_INFO
), &gEfiFileInfoGuid
, NULL
},
383 {STRING_TOKEN(STR_FILE_SYS_INFO
), &gEfiFileSystemInfoGuid
, NULL
},
384 {STRING_TOKEN(STR_TAPE_IO
), &gEfiTapeIoProtocolGuid
, NULL
},
385 {STRING_TOKEN(STR_DISK_IO
), &gEfiDiskIoProtocolGuid
, NULL
},
386 {STRING_TOKEN(STR_BLK_IO
), &gEfiBlockIoProtocolGuid
, NULL
},
387 {STRING_TOKEN(STR_UC
), &gEfiUnicodeCollationProtocolGuid
, NULL
},
388 {STRING_TOKEN(STR_UC2
), &gEfiUnicodeCollation2ProtocolGuid
, NULL
},
389 {STRING_TOKEN(STR_PCIRB_IO
), &gEfiPciRootBridgeIoProtocolGuid
, NULL
},
390 {STRING_TOKEN(STR_PCI_IO
), &gEfiPciIoProtocolGuid
, NULL
},
391 {STRING_TOKEN(STR_SCSI_PT
), &gEfiScsiPassThruProtocolGuid
, NULL
},
392 {STRING_TOKEN(STR_SCSI_IO
), &gEfiScsiIoProtocolGuid
, NULL
},
393 {STRING_TOKEN(STR_SCSI_PT_EXT
), &gEfiExtScsiPassThruProtocolGuid
, NULL
},
394 {STRING_TOKEN(STR_ISCSI
), &gEfiIScsiInitiatorNameProtocolGuid
, NULL
},
395 {STRING_TOKEN(STR_USB_IO
), &gEfiUsbIoProtocolGuid
, NULL
},
396 {STRING_TOKEN(STR_USB_HC
), &gEfiUsbHcProtocolGuid
, NULL
},
397 {STRING_TOKEN(STR_USB_HC2
), &gEfiUsb2HcProtocolGuid
, NULL
},
398 {STRING_TOKEN(STR_DEBUG_SUPPORT
), &gEfiDebugSupportProtocolGuid
, NULL
},
399 {STRING_TOKEN(STR_DEBUG_PORT
), &gEfiDebugPortProtocolGuid
, NULL
},
400 {STRING_TOKEN(STR_DECOMPRESS
), &gEfiDecompressProtocolGuid
, NULL
},
401 {STRING_TOKEN(STR_ACPI_TABLE
), &gEfiAcpiTableProtocolGuid
, NULL
},
402 {STRING_TOKEN(STR_EBC_INTERPRETER
), &gEfiEbcProtocolGuid
, NULL
},
403 {STRING_TOKEN(STR_SNP
), &gEfiSimpleNetworkProtocolGuid
, NULL
},
404 {STRING_TOKEN(STR_NII
), &gEfiNetworkInterfaceIdentifierProtocolGuid
, NULL
},
405 {STRING_TOKEN(STR_NII_31
), &gEfiNetworkInterfaceIdentifierProtocolGuid_31
, NULL
},
406 {STRING_TOKEN(STR_PXE_BC
), &gEfiPxeBaseCodeProtocolGuid
, NULL
},
407 {STRING_TOKEN(STR_PXE_CB
), &gEfiPxeBaseCodeCallbackProtocolGuid
, NULL
},
408 {STRING_TOKEN(STR_BIS
), &gEfiBisProtocolGuid
, NULL
},
409 {STRING_TOKEN(STR_MNP_SB
), &gEfiManagedNetworkServiceBindingProtocolGuid
, NULL
},
410 {STRING_TOKEN(STR_MNP
), &gEfiManagedNetworkProtocolGuid
, NULL
},
411 {STRING_TOKEN(STR_ARP_SB
), &gEfiArpServiceBindingProtocolGuid
, NULL
},
412 {STRING_TOKEN(STR_ARP
), &gEfiArpProtocolGuid
, NULL
},
413 {STRING_TOKEN(STR_DHCPV4_SB
), &gEfiDhcp4ServiceBindingProtocolGuid
, NULL
},
414 {STRING_TOKEN(STR_DHCPV4
), &gEfiDhcp4ProtocolGuid
, NULL
},
415 {STRING_TOKEN(STR_TCPV4_SB
), &gEfiTcp4ServiceBindingProtocolGuid
, NULL
},
416 {STRING_TOKEN(STR_TCPV4
), &gEfiTcp4ProtocolGuid
, NULL
},
417 {STRING_TOKEN(STR_IPV4_SB
), &gEfiIp4ServiceBindingProtocolGuid
, NULL
},
418 {STRING_TOKEN(STR_IPV4
), &gEfiIp4ProtocolGuid
, NULL
},
419 {STRING_TOKEN(STR_IPV4_CFG
), &gEfiIp4ConfigProtocolGuid
, NULL
},
420 {STRING_TOKEN(STR_SHELL_PARAMETERS
), &gEfiShellParametersProtocolGuid
, NULL
},
421 {STRING_TOKEN(STR_SHELL
), &gEfiShellProtocolGuid
, NULL
},
422 {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE
), &gEfiGlobalVariableGuid
, NULL
},
423 {STRING_TOKEN(STR_UDPV4_SB
), &gEfiUdp4ServiceBindingProtocolGuid
, NULL
},
424 {STRING_TOKEN(STR_UDPV4
), &gEfiUdp4ProtocolGuid
, NULL
},
425 {STRING_TOKEN(STR_MTFTPV4_SB
), &gEfiMtftp4ServiceBindingProtocolGuid
, NULL
},
426 {STRING_TOKEN(STR_MTFTPV4
), &gEfiMtftp4ProtocolGuid
, NULL
},
427 {STRING_TOKEN(STR_AUTH_INFO
), &gEfiAuthenticationInfoProtocolGuid
, NULL
},
428 {STRING_TOKEN(STR_HASH_SB
), &gEfiHashServiceBindingProtocolGuid
, NULL
},
429 {STRING_TOKEN(STR_HASH
), &gEfiHashProtocolGuid
, NULL
},
430 {STRING_TOKEN(STR_HII_FONT
), &gEfiHiiFontProtocolGuid
, NULL
},
431 {STRING_TOKEN(STR_HII_STRING
), &gEfiHiiStringProtocolGuid
, NULL
},
432 {STRING_TOKEN(STR_HII_IMAGE
), &gEfiHiiImageProtocolGuid
, NULL
},
433 {STRING_TOKEN(STR_HII_DATABASE
), &gEfiHiiDatabaseProtocolGuid
, NULL
},
434 {STRING_TOKEN(STR_HII_CONFIG_ROUT
), &gEfiHiiConfigRoutingProtocolGuid
, NULL
},
435 {STRING_TOKEN(STR_HII_CONFIG_ACC
), &gEfiHiiConfigAccessProtocolGuid
, NULL
},
436 {STRING_TOKEN(STR_HII_FORM_BROWSER2
), &gEfiFormBrowser2ProtocolGuid
, NULL
},
437 {STRING_TOKEN(STR_SHELL_INTERFACE
), &gEfiShellInterfaceGuid
, NULL
},
438 {STRING_TOKEN(STR_SHELL_ENV2
), &gEfiShellEnvironment2Guid
, NULL
},
439 {STRING_TOKEN(STR_SHELL_ENV
), &gEfiShellEnvironment2Guid
, NULL
},
440 {STRING_TOKEN(STR_DEVICE_IO
), &gEfiDeviceIoProtocolGuid
, NULL
},
441 {STRING_TOKEN(STR_UGA_DRAW
), &gEfiUgaDrawProtocolGuid
, NULL
},
442 {STRING_TOKEN(STR_UGA_IO
), &gEfiUgaIoProtocolGuid
, NULL
},
443 {STRING_TOKEN(STR_ESP
), &gEfiPartTypeSystemPartGuid
, NULL
},
444 {STRING_TOKEN(STR_GPT_NBR
), &gEfiPartTypeLegacyMbrGuid
, NULL
},
445 {STRING_TOKEN(STR_DRIVER_CONFIG
), &gEfiDriverConfigurationProtocolGuid
, NULL
},
446 {STRING_TOKEN(STR_DRIVER_CONFIG2
), &gEfiDriverConfiguration2ProtocolGuid
, NULL
},
447 {STRING_TOKEN(STR_UNKNOWN_DEVICE
), NULL
, NULL
},
451 Function to get the node for a protocol or struct from it's GUID.
453 if Guid is NULL, then ASSERT.
455 @param[in] Guid The GUID to look for the name of.
459 CONST PROTOCOL_INFO_BLOCK
*
461 InternalShellGetNodeFromGuid(
462 IN CONST EFI_GUID
* Guid
465 CONST PROTOCOL_INFO_BLOCK
*ListWalker
;
467 ASSERT(Guid
!= NULL
);
469 if (PcdGetBool(PcdShellIncludeNtGuids
)) {
470 for (ListWalker
= mGuidStringListNT
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
471 if (CompareGuid(ListWalker
->GuidId
, Guid
)) {
476 for (ListWalker
= mGuidStringList
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
477 if (CompareGuid(ListWalker
->GuidId
, Guid
)) {
485 Function to get the name of a protocol or struct from it's GUID.
487 if Guid is NULL, then ASSERT.
489 @param[in] Guid The GUID to look for the name of.
490 @param[in] Lang The language to use.
492 @return pointer to string of the name. The caller
493 is responsible to free this memory.
497 GetStringNameFromGuid(
498 IN CONST EFI_GUID
*Guid
,
499 IN CONST CHAR8
*Lang OPTIONAL
502 CONST PROTOCOL_INFO_BLOCK
*Id
;
504 Id
= InternalShellGetNodeFromGuid(Guid
);
505 return (HiiGetString(mHandleParsingHiiHandle
, Id
->StringId
, Lang
));
509 Function to dump protocol information from a handle.
511 This function will return a allocated string buffer containing the
512 information. The caller is responsible for freeing the memory.
514 If Guid is NULL, ASSERT().
515 If TheHandle is NULL, ASSERT().
517 @param[in] TheHandle The handle to dump information from.
518 @param[in] Guid The GUID of the protocol to dump.
519 @param[in] Verbose TRUE for extra info. FALSE otherwise.
521 @return The pointer to string.
522 @retval NULL An error was encountered.
526 GetProtocolInformationDump(
527 IN CONST EFI_HANDLE TheHandle
,
528 IN CONST EFI_GUID
*Guid
,
529 IN CONST BOOLEAN Verbose
532 CONST PROTOCOL_INFO_BLOCK
*Id
;
534 ASSERT(TheHandle
!= NULL
);
535 ASSERT(Guid
!= NULL
);
537 if (TheHandle
== NULL
|| Guid
== NULL
) {
541 Id
= InternalShellGetNodeFromGuid(Guid
);
542 if (Id
!= NULL
&& Id
->DumpInfo
!= NULL
) {
543 return (Id
->DumpInfo(TheHandle
, Verbose
));
549 Function to get the Guid for a protocol or struct based on it's string name.
551 @param[in] Name The pointer to the string name.
552 @param[in] Lang The pointer to the language code.
553 @param[in] Guid The pointer to the Guid.
555 @retval EFI_SUCCESS The operation was sucessful.
559 GetGuidFromStringName(
560 IN CONST CHAR16
*Name
,
561 IN CONST CHAR8
*Lang OPTIONAL
,
565 CONST PROTOCOL_INFO_BLOCK
*ListWalker
;
568 ASSERT(Guid
!= NULL
);
570 return (EFI_INVALID_PARAMETER
);
574 if (PcdGetBool(PcdShellIncludeNtGuids
)) {
575 for (ListWalker
= mGuidStringListNT
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
576 String
= HiiGetString(mHandleParsingHiiHandle
, ListWalker
->StringId
, Lang
);
577 if (Name
!= NULL
&& String
!= NULL
&& StrCmp(Name
, String
)==0) {
578 *Guid
= ListWalker
->GuidId
;
580 SHELL_FREE_NON_NULL(String
);
582 return (EFI_SUCCESS
);
586 for (ListWalker
= mGuidStringList
; ListWalker
!= NULL
&& ListWalker
->GuidId
!= NULL
; ListWalker
++) {
587 String
= HiiGetString(mHandleParsingHiiHandle
, ListWalker
->StringId
, Lang
);
588 if (Name
!= NULL
&& String
!= NULL
&& StrCmp(Name
, String
)==0) {
589 *Guid
= ListWalker
->GuidId
;
591 SHELL_FREE_NON_NULL(String
);
593 return (EFI_SUCCESS
);
596 return (EFI_NOT_FOUND
);
600 Function to retrieve the driver name (if possible) from the ComponentName or
601 ComponentName2 protocol
603 @param[in] TheHandle The driver handle to get the name of.
604 @param[in] Language The language to use.
606 @retval NULL The name could not be found.
607 @return A pointer to the string name. Do not de-allocate the memory.
611 GetStringNameFromHandle(
612 IN CONST EFI_HANDLE TheHandle
,
613 IN CONST CHAR8
*Language
616 EFI_COMPONENT_NAME2_PROTOCOL
*CompNameStruct
;
620 Status
= gBS
->OpenProtocol(
622 &gEfiComponentName2ProtocolGuid
,
623 (VOID
**)&CompNameStruct
,
626 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
627 if (!EFI_ERROR(Status
)) {
628 Status
= CompNameStruct
->GetDriverName(CompNameStruct
, (CHAR8
*)Language
, &RetVal
);
629 if (!EFI_ERROR(Status
)) {
633 Status
= gBS
->OpenProtocol(
635 &gEfiComponentNameProtocolGuid
,
636 (VOID
**)&CompNameStruct
,
639 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
640 if (!EFI_ERROR(Status
)) {
641 Status
= CompNameStruct
->GetDriverName(CompNameStruct
, (CHAR8
*)Language
, &RetVal
);
642 if (!EFI_ERROR(Status
)) {
650 Function to initialize the file global mHandleList object for use in
651 vonverting handles to index and index to handle.
653 @retval EFI_SUCCESS The operation was successful.
657 InternalShellInitHandleList(
662 EFI_HANDLE
*HandleBuffer
;
664 HANDLE_LIST
*ListWalker
;
666 if (mHandleList
.NextIndex
!= 0) {
669 InitializeListHead(&mHandleList
.List
.Link
);
670 mHandleList
.NextIndex
= 1;
671 Status
= gBS
->LocateHandleBuffer (
678 ASSERT_EFI_ERROR(Status
);
679 if (EFI_ERROR(Status
)) {
682 for (mHandleList
.NextIndex
= 1 ; mHandleList
.NextIndex
<= HandleCount
; mHandleList
.NextIndex
++){
683 ListWalker
= AllocateZeroPool(sizeof(HANDLE_LIST
));
684 ASSERT(ListWalker
!= NULL
);
685 ListWalker
->TheHandle
= HandleBuffer
[mHandleList
.NextIndex
-1];
686 ListWalker
->TheIndex
= mHandleList
.NextIndex
;
687 InsertTailList(&mHandleList
.List
.Link
,&ListWalker
->Link
);
689 FreePool(HandleBuffer
);
690 return (EFI_SUCCESS
);
694 Function to retrieve the human-friendly index of a given handle. If the handle
695 does not have a index one will be automatically assigned. The index value is valid
696 until the termination of the shell application.
698 @param[in] TheHandle The handle to retrieve an index for.
700 @retval 0 A memory allocation failed.
701 @return The index of the handle.
706 ConvertHandleToHandleIndex(
707 IN CONST EFI_HANDLE TheHandle
710 HANDLE_LIST
*ListWalker
;
711 if (TheHandle
== NULL
) {
715 InternalShellInitHandleList();
717 for (ListWalker
= (HANDLE_LIST
*)GetFirstNode(&mHandleList
.List
.Link
)
718 ; !IsNull(&mHandleList
.List
.Link
,&ListWalker
->Link
)
719 ; ListWalker
= (HANDLE_LIST
*)GetNextNode(&mHandleList
.List
.Link
,&ListWalker
->Link
)
721 if (ListWalker
->TheHandle
== TheHandle
) {
722 return (ListWalker
->TheIndex
);
725 ListWalker
= AllocateZeroPool(sizeof(HANDLE_LIST
));
726 ASSERT(ListWalker
!= NULL
);
727 ListWalker
->TheHandle
= TheHandle
;
728 ListWalker
->TheIndex
= mHandleList
.NextIndex
++;
729 InsertTailList(&mHandleList
.List
.Link
,&ListWalker
->Link
);
730 return (ListWalker
->TheIndex
);
736 Function to retrieve the EFI_HANDLE from the human-friendly index.
738 @param[in] TheIndex The index to retrieve the EFI_HANDLE for.
740 @retval NULL The index was invalid.
741 @return The EFI_HANDLE that index represents.
746 ConvertHandleIndexToHandle(
747 IN CONST UINTN TheIndex
750 HANDLE_LIST
*ListWalker
;
752 InternalShellInitHandleList();
754 if (TheIndex
>= mHandleList
.NextIndex
) {
758 for (ListWalker
= (HANDLE_LIST
*)GetFirstNode(&mHandleList
.List
.Link
)
759 ; !IsNull(&mHandleList
.List
.Link
,&ListWalker
->Link
)
760 ; ListWalker
= (HANDLE_LIST
*)GetNextNode(&mHandleList
.List
.Link
,&ListWalker
->Link
)
762 if (ListWalker
->TheIndex
== TheIndex
) {
763 return (ListWalker
->TheHandle
);
770 Gets all the related EFI_HANDLEs based on the mask supplied.
772 This function scans all EFI_HANDLES in the UEFI environment's handle database
773 and returns the ones with the specified relationship (Mask) to the specified
776 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
777 If MatchingHandleCount is NULL, then ASSERT.
779 If MatchingHandleBuffer is not NULL upon a successful return the memory must be
782 @param[in] DriverBindingHandle The handle with Driver Binding protocol on it.
783 @param[in] ControllerHandle The handle with Device Path protocol on it.
784 @param[in] MatchingHandleCount The pointer to UINTN that specifies the number of HANDLES in
785 MatchingHandleBuffer.
786 @param[out] MatchingHandleBuffer On a successful return, a buffer of MatchingHandleCount
787 EFI_HANDLEs with a terminating NULL EFI_HANDLE.
788 @param[out] HandleType An array of type information.
790 @retval EFI_SUCCESS The operation was successful, and any related handles
791 are in MatchingHandleBuffer.
792 @retval EFI_NOT_FOUND No matching handles were found.
793 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
797 ParseHandleDatabaseByRelationshipWithType (
798 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL
,
799 IN CONST EFI_HANDLE ControllerHandle OPTIONAL
,
800 IN UINTN
*HandleCount
,
801 OUT EFI_HANDLE
**HandleBuffer
,
802 OUT UINTN
**HandleType
807 EFI_GUID
**ProtocolGuidArray
;
810 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfo
;
815 ASSERT(HandleCount
!= NULL
);
816 ASSERT(HandleBuffer
!= NULL
);
817 ASSERT(HandleType
!= NULL
);
818 ASSERT(DriverBindingHandle
!= NULL
|| ControllerHandle
!= NULL
);
821 *HandleBuffer
= NULL
;
825 // Retrieve the list of all handles from the handle database
827 Status
= gBS
->LocateHandleBuffer (
834 if (EFI_ERROR (Status
)) {
838 *HandleType
= AllocateZeroPool (*HandleCount
* sizeof (UINTN
));
839 ASSERT(*HandleType
!= NULL
);
841 for (HandleIndex
= 0; HandleIndex
< *HandleCount
; HandleIndex
++) {
843 // Retrieve the list of all the protocols on each handle
845 Status
= gBS
->ProtocolsPerHandle (
846 (*HandleBuffer
)[HandleIndex
],
850 if (!EFI_ERROR (Status
)) {
852 for (ProtocolIndex
= 0; ProtocolIndex
< ArrayCount
; ProtocolIndex
++) {
855 // Set the bit describing what this handle has
857 if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiLoadedImageProtocolGuid
) ) {
858 (*HandleType
)[HandleIndex
] |= HR_IMAGE_HANDLE
;
859 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverBindingProtocolGuid
) ) {
860 (*HandleType
)[HandleIndex
] |= HR_DRIVER_BINDING_HANDLE
;
861 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverConfiguration2ProtocolGuid
)) {
862 (*HandleType
)[HandleIndex
] |= HR_DRIVER_CONFIGURATION_HANDLE
;
863 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverConfigurationProtocolGuid
) ) {
864 (*HandleType
)[HandleIndex
] |= HR_DRIVER_CONFIGURATION_HANDLE
;
865 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverDiagnostics2ProtocolGuid
) ) {
866 (*HandleType
)[HandleIndex
] |= HR_DRIVER_DIAGNOSTICS_HANDLE
;
867 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDriverDiagnosticsProtocolGuid
) ) {
868 (*HandleType
)[HandleIndex
] |= HR_DRIVER_DIAGNOSTICS_HANDLE
;
869 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiComponentName2ProtocolGuid
) ) {
870 (*HandleType
)[HandleIndex
] |= HR_COMPONENT_NAME_HANDLE
;
871 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiComponentNameProtocolGuid
) ) {
872 (*HandleType
)[HandleIndex
] |= HR_COMPONENT_NAME_HANDLE
;
873 } else if (CompareGuid (ProtocolGuidArray
[ProtocolIndex
], &gEfiDevicePathProtocolGuid
) ) {
874 (*HandleType
)[HandleIndex
] |= HR_DEVICE_HANDLE
;
877 ASSERT((*HandleType
)[HandleIndex
] == (*HandleType
)[HandleIndex
]);
881 // Retrieve the list of agents that have opened each protocol
883 Status
= gBS
->OpenProtocolInformation (
884 (*HandleBuffer
)[HandleIndex
],
885 ProtocolGuidArray
[ProtocolIndex
],
889 if (!EFI_ERROR (Status
)) {
890 for (OpenInfoIndex
= 0; OpenInfoIndex
< OpenInfoCount
; OpenInfoIndex
++) {
891 if (DriverBindingHandle
!= NULL
&& OpenInfo
[OpenInfoIndex
].AgentHandle
== DriverBindingHandle
) {
892 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) == EFI_OPEN_PROTOCOL_BY_DRIVER
) {
893 (*HandleType
)[HandleIndex
] |= (HR_DEVICE_HANDLE
| HR_CONTROLLER_HANDLE
);
895 if (ControllerHandle
!= NULL
&& (*HandleBuffer
)[HandleIndex
] == ControllerHandle
) {
896 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
897 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
898 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].ControllerHandle
) {
899 (*HandleType
)[ChildIndex
] |= (HR_DEVICE_HANDLE
| HR_CHILD_HANDLE
);
905 if (DriverBindingHandle
== NULL
&& OpenInfo
[OpenInfoIndex
].ControllerHandle
== ControllerHandle
) {
906 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) == EFI_OPEN_PROTOCOL_BY_DRIVER
) {
907 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
908 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].AgentHandle
) {
909 (*HandleType
)[ChildIndex
] |= HR_DEVICE_DRIVER
;
913 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
914 (*HandleType
)[HandleIndex
] |= HR_PARENT_HANDLE
;
915 for (ChildIndex
= 0; ChildIndex
< *HandleCount
; ChildIndex
++) {
916 if ((*HandleBuffer
)[ChildIndex
] == OpenInfo
[OpenInfoIndex
].AgentHandle
) {
917 (*HandleType
)[ChildIndex
] |= HR_BUS_DRIVER
;
928 FreePool (ProtocolGuidArray
);
932 if (EFI_ERROR(Status
)) {
933 if (*HandleType
!= NULL
) {
934 FreePool (*HandleType
);
936 if (*HandleBuffer
!= NULL
) {
937 FreePool (*HandleBuffer
);
941 *HandleBuffer
= NULL
;
949 Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
952 This function will scan all EFI_HANDLES in the UEFI environment's handle database
953 and return all the ones with the specified relationship (Mask) to the specified
956 If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
957 If MatchingHandleCount is NULL, then ASSERT.
959 If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
962 @param[in] DriverBindingHandle Handle to a object with Driver Binding protocol
964 @param[in] ControllerHandle Handle to a device with Device Path protocol on it.
965 @param[in] Mask Mask of what relationship(s) is desired.
966 @param[in] MatchingHandleCount Poitner to UINTN specifying number of HANDLES in
967 MatchingHandleBuffer.
968 @param[out] MatchingHandleBuffer On a sucessful return a buffer of MatchingHandleCount
969 EFI_HANDLEs and a terminating NULL EFI_HANDLE.
971 @retval EFI_SUCCESS The operation was sucessful and any related handles
972 are in MatchingHandleBuffer;
973 @retval EFI_NOT_FOUND No matching handles were found.
974 @retval EFI_INVALID_PARAMETER A parameter was invalid or out of range.
978 ParseHandleDatabaseByRelationship (
979 IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL
,
980 IN CONST EFI_HANDLE ControllerHandle OPTIONAL
,
982 IN UINTN
*MatchingHandleCount
,
983 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
988 EFI_HANDLE
*HandleBuffer
;
992 ASSERT(MatchingHandleCount
!= NULL
);
993 ASSERT(DriverBindingHandle
!= NULL
|| ControllerHandle
!= NULL
);
995 if ((Mask
& HR_VALID_MASK
) != Mask
) {
996 return (EFI_INVALID_PARAMETER
);
999 if ((Mask
& HR_CHILD_HANDLE
) != 0 && DriverBindingHandle
== NULL
) {
1000 return (EFI_INVALID_PARAMETER
);
1003 *MatchingHandleCount
= 0;
1004 if (MatchingHandleBuffer
!= NULL
) {
1005 *MatchingHandleBuffer
= NULL
;
1008 HandleBuffer
= NULL
;
1011 Status
= ParseHandleDatabaseByRelationshipWithType (
1012 DriverBindingHandle
,
1018 if (!EFI_ERROR (Status
)) {
1020 // Count the number of handles that match the attributes in Mask
1022 for (HandleIndex
= 0; HandleIndex
< HandleCount
; HandleIndex
++) {
1023 if ((HandleType
[HandleIndex
] & Mask
) == Mask
) {
1024 (*MatchingHandleCount
)++;
1028 // If no handles match the attributes in Mask then return EFI_NOT_FOUND
1030 if (*MatchingHandleCount
== 0) {
1031 Status
= EFI_NOT_FOUND
;
1034 if (MatchingHandleBuffer
== NULL
) {
1036 // Someone just wanted the count...
1038 Status
= EFI_SUCCESS
;
1041 // Allocate a handle buffer for the number of handles that matched the attributes in Mask
1043 *MatchingHandleBuffer
= AllocateZeroPool ((*MatchingHandleCount
+1)* sizeof (EFI_HANDLE
));
1044 ASSERT(*MatchingHandleBuffer
!= NULL
);
1046 for (HandleIndex
= 0,*MatchingHandleCount
= 0
1047 ; HandleIndex
< HandleCount
1051 // Fill the allocated buffer with the handles that matched the attributes in Mask
1053 if ((HandleType
[HandleIndex
] & Mask
) == Mask
) {
1054 (*MatchingHandleBuffer
)[(*MatchingHandleCount
)++] = HandleBuffer
[HandleIndex
];
1059 // Make the last one NULL
1061 (*MatchingHandleBuffer
)[*MatchingHandleCount
] = NULL
;
1063 Status
= EFI_SUCCESS
;
1064 } // MacthingHandleBuffer == NULL (ELSE)
1065 } // *MatchingHandleCount == 0 (ELSE)
1066 } // no error on ParseHandleDatabaseByRelationshipWithType
1068 if (HandleBuffer
!= NULL
) {
1069 FreePool (HandleBuffer
);
1072 if (HandleType
!= NULL
) {
1073 FreePool (HandleType
);
1080 Gets handles for any child controllers of the passed in controller.
1082 @param[in] ControllerHandle The handle of the "parent controller"
1083 @param[in] MatchingHandleCount Pointer to the number of handles in
1084 MatchingHandleBuffer on return.
1085 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1089 @retval EFI_SUCCESS The operation was sucessful.
1093 ParseHandleDatabaseForChildControllers(
1094 IN CONST EFI_HANDLE ControllerHandle
,
1095 IN UINTN
*MatchingHandleCount
,
1096 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
1100 // UINTN HandleIndex;
1101 UINTN DriverBindingHandleCount
;
1102 EFI_HANDLE
*DriverBindingHandleBuffer
;
1103 UINTN DriverBindingHandleIndex
;
1104 UINTN ChildControllerHandleCount
;
1105 EFI_HANDLE
*ChildControllerHandleBuffer
;
1106 UINTN ChildControllerHandleIndex
;
1108 EFI_HANDLE
*HandleBufferForReturn
;
1110 if (MatchingHandleCount
== NULL
) {
1111 return (EFI_INVALID_PARAMETER
);
1113 *MatchingHandleCount
= 0;
1115 Status
= PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
1117 &DriverBindingHandleCount
,
1118 &DriverBindingHandleBuffer
1120 if (EFI_ERROR (Status
)) {
1125 // Get a buffer big enough for all the controllers.
1127 HandleBufferForReturn
= GetHandleListByProtocol(&gEfiDevicePathProtocolGuid
);
1128 if (HandleBufferForReturn
== NULL
) {
1129 FreePool (DriverBindingHandleBuffer
);
1130 return (EFI_NOT_FOUND
);
1133 for (DriverBindingHandleIndex
= 0; DriverBindingHandleIndex
< DriverBindingHandleCount
; DriverBindingHandleIndex
++) {
1134 Status
= PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1135 DriverBindingHandleBuffer
[DriverBindingHandleIndex
],
1137 &ChildControllerHandleCount
,
1138 &ChildControllerHandleBuffer
1140 if (EFI_ERROR (Status
)) {
1144 for (ChildControllerHandleIndex
= 0;
1145 ChildControllerHandleIndex
< ChildControllerHandleCount
;
1146 ChildControllerHandleIndex
++
1149 HandleBufferForReturn
[(*MatchingHandleCount
)++] = ChildControllerHandleBuffer
[ChildControllerHandleIndex
];
1150 // for (HandleIndex = 0; HandleBufferForReturn[HandleIndex] != NULL; HandleIndex++) {
1151 // if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
1158 // HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
1162 FreePool (ChildControllerHandleBuffer
);
1165 FreePool (DriverBindingHandleBuffer
);
1167 if (MatchingHandleBuffer
!= NULL
) {
1168 *MatchingHandleBuffer
= HandleBufferForReturn
;
1170 FreePool(HandleBufferForReturn
);
1173 return (EFI_SUCCESS
);
1177 Appends 1 buffer to another buffer. This will re-allocate the destination buffer
1178 if necessary to fit all of the data.
1180 If DestinationBuffer is NULL, then ASSERT().
1182 @param[in,out] DestinationBuffer The pointer to the pointer to the buffer to append onto.
1183 @param[in,out] DestinationSize The pointer to the size of DestinationBuffer.
1184 @param[in] SourceBuffer The pointer to the buffer to append onto DestinationBuffer.
1185 @param[in] SourceSize The number of bytes of SourceBuffer to append.
1187 @retval NULL A memory allocation failed.
1188 @retval NULL A parameter was invalid.
1189 @return A pointer to (*DestinationBuffer).
1194 IN OUT VOID
**DestinationBuffer
,
1195 IN OUT UINTN
*DestinationSize
,
1196 IN VOID
*SourceBuffer
,
1200 UINTN LocalDestinationSize
;
1201 UINTN LocalDestinationFinalSize
;
1203 ASSERT(DestinationBuffer
!= NULL
);
1205 if (SourceSize
== 0 || SourceBuffer
== NULL
) {
1206 return (*DestinationBuffer
);
1209 if (DestinationSize
== NULL
) {
1210 LocalDestinationSize
= 0;
1212 LocalDestinationSize
= *DestinationSize
;
1215 LocalDestinationFinalSize
= LocalDestinationSize
+ SourceSize
;
1217 if (DestinationSize
!= NULL
) {
1218 *DestinationSize
= LocalDestinationSize
;
1221 if (LocalDestinationSize
== 0) {
1223 *DestinationBuffer
= AllocateZeroPool(LocalDestinationFinalSize
);
1226 *DestinationBuffer
= ReallocatePool(LocalDestinationSize
, LocalDestinationFinalSize
, *DestinationBuffer
);
1229 ASSERT(*DestinationBuffer
!= NULL
);
1232 return (CopyMem(((UINT8
*)(*DestinationBuffer
)) + LocalDestinationSize
, SourceBuffer
, SourceSize
));
1236 Gets handles for any child devices produced by the passed in driver.
1238 @param[in] DriverHandle The handle of the driver.
1239 @param[in] MatchingHandleCount Pointer to the number of handles in
1240 MatchingHandleBuffer on return.
1241 @param[out] MatchingHandleBuffer Buffer containing handles on a successful
1243 @retval EFI_SUCCESS The operation was sucessful.
1244 @sa ParseHandleDatabaseByRelationship
1248 ParseHandleDatabaseForChildDevices(
1249 IN CONST EFI_HANDLE DriverHandle
,
1250 IN UINTN
*MatchingHandleCount
,
1251 OUT EFI_HANDLE
**MatchingHandleBuffer OPTIONAL
1255 EFI_HANDLE
*Buffer2
;
1260 UINTN HandleBufferSize
;
1262 ASSERT(MatchingHandleCount
!= NULL
);
1264 HandleBufferSize
= 0;
1267 *MatchingHandleCount
= 0;
1269 Status
= PARSE_HANDLE_DATABASE_DEVICES (
1274 if (!EFI_ERROR (Status
)) {
1275 for (HandleIndex
= 0; HandleIndex
< Count1
; HandleIndex
++) {
1277 // now find the children
1279 Status
= PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
1281 Buffer
[HandleIndex
],
1285 if (EFI_ERROR(Status
)) {
1289 // save out required and optional data elements
1291 *MatchingHandleCount
+= Count2
;
1292 if (MatchingHandleBuffer
!= NULL
) {
1293 *MatchingHandleBuffer
= BuffernCatGrow((VOID
**)MatchingHandleBuffer
, &HandleBufferSize
, Buffer2
, Count2
* sizeof(Buffer2
[0]));
1299 if (Buffer2
!= NULL
) {
1305 if (Buffer
!= NULL
) {
1312 Function to get all handles that support a given protocol or all handles.
1314 @param[in] ProtocolGuid The guid of the protocol to get handles for. If NULL
1315 then the function will return all handles.
1317 @retval NULL A memory allocation failed.
1318 @return A NULL terminated list of handles.
1322 GetHandleListByProtocol (
1323 IN CONST EFI_GUID
*ProtocolGuid OPTIONAL
1326 EFI_HANDLE
*HandleList
;
1334 // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
1336 if (ProtocolGuid
== NULL
) {
1337 Status
= gBS
->LocateHandle(AllHandles
, NULL
, NULL
, &Size
, HandleList
);
1338 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1339 HandleList
= AllocateZeroPool(Size
+ sizeof(EFI_HANDLE
));
1340 if (HandleList
== NULL
) {
1343 Status
= gBS
->LocateHandle(AllHandles
, NULL
, NULL
, &Size
, HandleList
);
1344 HandleList
[Size
/sizeof(EFI_HANDLE
)] = NULL
;
1347 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)ProtocolGuid
, NULL
, &Size
, HandleList
);
1348 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1349 HandleList
= AllocateZeroPool(Size
+ sizeof(EFI_HANDLE
));
1350 if (HandleList
== NULL
) {
1353 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)ProtocolGuid
, NULL
, &Size
, HandleList
);
1354 HandleList
[Size
/sizeof(EFI_HANDLE
)] = NULL
;
1357 if (EFI_ERROR(Status
)) {
1358 if (HandleList
!= NULL
) {
1359 FreePool(HandleList
);
1363 return (HandleList
);
1367 Function to get all handles that support some protocols.
1369 @param[in] ProtocolGuids A NULL terminated list of protocol GUIDs.
1371 @retval NULL A memory allocation failed.
1372 @retval NULL ProtocolGuids was NULL.
1373 @return A NULL terminated list of EFI_HANDLEs.
1377 GetHandleListByProtocolList (
1378 IN CONST EFI_GUID
**ProtocolGuids
1381 EFI_HANDLE
*HandleList
;
1386 CONST EFI_GUID
**GuidWalker
;
1387 EFI_HANDLE
*HandleWalker1
;
1388 EFI_HANDLE
*HandleWalker2
;
1392 TotalSize
= sizeof(EFI_HANDLE
);
1394 for (GuidWalker
= ProtocolGuids
; GuidWalker
!= NULL
&& *GuidWalker
!= NULL
; GuidWalker
++,Size
= 0){
1395 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)(*GuidWalker
), NULL
, &Size
, NULL
);
1396 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1402 // No handles were found...
1404 if (TotalSize
== sizeof(EFI_HANDLE
)) {
1408 HandleList
= AllocateZeroPool(TotalSize
);
1409 if (HandleList
== NULL
) {
1414 for (GuidWalker
= ProtocolGuids
; GuidWalker
!= NULL
&& *GuidWalker
!= NULL
; GuidWalker
++){
1415 TempSize
= TotalSize
- Size
;
1416 Status
= gBS
->LocateHandle(ByProtocol
, (EFI_GUID
*)(*GuidWalker
), NULL
, &TempSize
, HandleList
+(Size
/sizeof(EFI_HANDLE
)));
1419 // Allow for missing protocols... Only update the 'used' size upon success.
1421 if (!EFI_ERROR(Status
)) {
1425 ASSERT(HandleList
[(TotalSize
/sizeof(EFI_HANDLE
))-1] == NULL
);
1427 for (HandleWalker1
= HandleList
; HandleWalker1
!= NULL
&& *HandleWalker1
!= NULL
; HandleWalker1
++) {
1428 for (HandleWalker2
= HandleWalker1
+ 1; HandleWalker2
!= NULL
&& *HandleWalker2
!= NULL
; HandleWalker2
++) {
1429 if (*HandleWalker1
== *HandleWalker2
) {
1431 // copy memory back 1 handle width.
1433 CopyMem(HandleWalker2
, HandleWalker2
+ 1, TotalSize
- ((HandleWalker2
-HandleList
+1)*sizeof(EFI_HANDLE
)));
1438 return (HandleList
);