Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Tapan Shah <tapandshah@hp.com> Reviewed-by: Jaben Carsey <jaben.carsey@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16759 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			985 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			985 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Main file for Dh shell Driver1 function.
 | |
| 
 | |
|   (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
 | |
|   Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
 | |
|   This program and the accompanying materials
 | |
|   are licensed and made available under the terms and conditions of the BSD License
 | |
|   which accompanies this distribution.  The full text of the license may be found at
 | |
|   http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
|   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
|   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "UefiShellDriver1CommandsLib.h"
 | |
| 
 | |
| STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
 | |
|   {L"-p", TypeValue},
 | |
|   {L"-d", TypeFlag},
 | |
|   {L"-v", TypeFlag},
 | |
|   {L"-verbose", TypeFlag},
 | |
|   {L"-sfo", TypeFlag},
 | |
|   {L"-l", TypeValue},
 | |
|   {NULL, TypeMax}
 | |
|   };
 | |
| 
 | |
| STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = {
 | |
|   &gEfiDriverBindingProtocolGuid,
 | |
|   &gEfiPlatformDriverOverrideProtocolGuid,
 | |
|   &gEfiBusSpecificDriverOverrideProtocolGuid,
 | |
|   &gEfiDriverDiagnosticsProtocolGuid,
 | |
|   &gEfiDriverDiagnostics2ProtocolGuid,
 | |
|   &gEfiComponentNameProtocolGuid,
 | |
|   &gEfiComponentName2ProtocolGuid,
 | |
|   &gEfiPlatformToDriverConfigurationProtocolGuid,
 | |
|   &gEfiDriverSupportedEfiVersionProtocolGuid,
 | |
|   &gEfiDriverFamilyOverrideProtocolGuid,
 | |
|   &gEfiDriverHealthProtocolGuid,
 | |
|   &gEfiLoadedImageProtocolGuid,
 | |
|   NULL
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Get the name of a driver by it's handle.
 | |
| 
 | |
|   If a name is found the memory must be callee freed.
 | |
| 
 | |
|   @param[in] TheHandle    The driver's handle.
 | |
|   @param[in] Language     The language to use.
 | |
|   @param[in] NameFound    Upon a successful return the name found.
 | |
| 
 | |
|   @retval EFI_SUCCESS     The name was found.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| GetDriverName (
 | |
|   IN EFI_HANDLE   TheHandle,
 | |
|   IN CONST CHAR8  *Language,
 | |
|   IN CHAR16       **NameFound
 | |
|   )
 | |
| {
 | |
|   CHAR8                             *Lang;
 | |
|   EFI_STATUS                        Status;
 | |
|   EFI_COMPONENT_NAME2_PROTOCOL      *CompName2;
 | |
|   CHAR16                            *NameToReturn;
 | |
|   //
 | |
|   // Go through those handles until we get one that passes for GetComponentName
 | |
|   //
 | |
|   Status = gBS->OpenProtocol(
 | |
|     TheHandle,
 | |
|     &gEfiComponentName2ProtocolGuid,
 | |
|     (VOID**)&CompName2,
 | |
|     gImageHandle,
 | |
|     NULL,
 | |
|     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     Status = gBS->OpenProtocol(
 | |
|       TheHandle,
 | |
|       &gEfiComponentNameProtocolGuid,
 | |
|       (VOID**)&CompName2,
 | |
|       gImageHandle,
 | |
|       NULL,
 | |
|       EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     return (EFI_NOT_FOUND);
 | |
|   }
 | |
|   Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
 | |
|   Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn);
 | |
|   FreePool(Lang);
 | |
| 
 | |
|   if (!EFI_ERROR(Status) && NameToReturn != NULL) {
 | |
|     *NameFound = NULL;
 | |
|     StrnCatGrow(NameFound, NULL, NameToReturn, 0);
 | |
|   }
 | |
|   return (Status);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Discover if a protocol guid is one of the UEFI Driver Model Protocols.
 | |
| 
 | |
|   @param[in] Guid   The guid to test.
 | |
| 
 | |
|   @retval TRUE      The guid does represent a driver model protocol.
 | |
|   @retval FALSE     The guid does not represent a driver model protocol.
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| IsDriverProt (
 | |
|   IN CONST EFI_GUID *Guid
 | |
|   )
 | |
| {
 | |
|   CONST EFI_GUID            **GuidWalker;
 | |
|   BOOLEAN                   GuidFound;
 | |
|   GuidFound = FALSE;
 | |
|   for (GuidWalker = UefiDriverModelProtocolsGuidArray
 | |
|     ;  GuidWalker != NULL && *GuidWalker != NULL
 | |
|     ;  GuidWalker++
 | |
|    ){
 | |
|     if (CompareGuid(*GuidWalker, Guid)) {
 | |
|       GuidFound = TRUE;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   return (GuidFound);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get information for a handle.
 | |
| 
 | |
|   @param[in] TheHandle        The handles to show info on.
 | |
|   @param[in] Language         Language string per UEFI specification.
 | |
|   @param[in] Seperator        Separator string between information blocks.
 | |
|   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
 | |
|   @param[in] ExtraInfo        TRUE for extra info, FALSE otherwise.
 | |
| 
 | |
|   @retval SHELL_SUCCESS           The operation was successful.
 | |
|   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
 | |
| **/
 | |
| CHAR16*
 | |
| EFIAPI
 | |
| GetProtocolInfoString(
 | |
|   IN CONST EFI_HANDLE TheHandle,
 | |
|   IN CONST CHAR8      *Language,
 | |
|   IN CONST CHAR16     *Seperator,
 | |
|   IN CONST BOOLEAN    Verbose,
 | |
|   IN CONST BOOLEAN    ExtraInfo
 | |
|   )
 | |
| {
 | |
|   EFI_GUID                  **ProtocolGuidArray;
 | |
|   UINTN                     ArrayCount;
 | |
|   UINTN                     ProtocolIndex;
 | |
|   EFI_STATUS                Status;
 | |
|   CHAR16                    *RetVal;
 | |
|   UINTN                     Size;
 | |
|   CHAR16                    *Temp;
 | |
| 
 | |
|   ProtocolGuidArray = NULL;
 | |
|   RetVal            = NULL;
 | |
|   Size              = 0;
 | |
| 
 | |
|   Status = gBS->ProtocolsPerHandle (
 | |
|                 TheHandle,
 | |
|                 &ProtocolGuidArray,
 | |
|                 &ArrayCount
 | |
|                );
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
 | |
|       Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language);
 | |
|       if (Temp != NULL) {
 | |
|         ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
 | |
|         if (Size != 0) {
 | |
|           StrnCatGrow(&RetVal, &Size, Seperator, 0);
 | |
|         }
 | |
|         StrnCatGrow(&RetVal, &Size, L"%H", 0);
 | |
|         StrnCatGrow(&RetVal, &Size, Temp, 0);
 | |
|         StrnCatGrow(&RetVal, &Size, L"%N", 0);
 | |
|         FreePool(Temp);
 | |
|       }
 | |
|       if (ExtraInfo) {
 | |
|         Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose);
 | |
|         if (Temp != NULL) {
 | |
|           ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
 | |
|           if (!Verbose) {
 | |
|             StrnCatGrow(&RetVal, &Size, L"(", 0);
 | |
|             StrnCatGrow(&RetVal, &Size, Temp, 0);
 | |
|             StrnCatGrow(&RetVal, &Size, L")\r\n", 0);
 | |
|           } else {
 | |
|             StrnCatGrow(&RetVal, &Size, Seperator, 0);
 | |
|             StrnCatGrow(&RetVal, &Size, Temp, 0);
 | |
|           }
 | |
|           FreePool(Temp);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   SHELL_FREE_NON_NULL(ProtocolGuidArray);
 | |
| 
 | |
|   if (RetVal == NULL) {
 | |
|     return (NULL);
 | |
|   }
 | |
| 
 | |
|   ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
 | |
|   StrnCatGrow(&RetVal, &Size, Seperator, 0);
 | |
|   return (RetVal);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Gets the name of the loaded image.
 | |
| 
 | |
|   @param[in] TheHandle    The handle of the driver to get info on.
 | |
|   @param[out] Name        The pointer to the pointer.  Valid upon a successful return.
 | |
| 
 | |
|   @retval EFI_SUCCESS     The operation was successful.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| GetDriverImageName (
 | |
|   IN EFI_HANDLE   TheHandle,
 | |
|   OUT CHAR16      **Name
 | |
|   )
 | |
| {
 | |
|   // get loaded image and devicepathtotext on image->Filepath
 | |
|   EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
 | |
|   EFI_STATUS                Status;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
 | |
| 
 | |
|   if (TheHandle == NULL || Name == NULL) {
 | |
|     return (EFI_INVALID_PARAMETER);
 | |
|   }
 | |
| 
 | |
|   Status = gBS->OpenProtocol (
 | |
|                 TheHandle,
 | |
|                 &gEfiLoadedImageProtocolGuid,
 | |
|                 (VOID **) &LoadedImage,
 | |
|                 gImageHandle,
 | |
|                 NULL,
 | |
|                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                );
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     return (Status);
 | |
|   }
 | |
|   DevicePath = LoadedImage->FilePath;
 | |
|   *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
 | |
|   return (EFI_SUCCESS);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Display driver model information for a given handle.
 | |
|   
 | |
|   @param[in] Handle     The handle to display info on.
 | |
|   @param[in] BestName   Use the best name?
 | |
|   @param[in] Language   The language to output in.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| DisplayDriverModelHandle (
 | |
|   IN EFI_HANDLE  Handle,
 | |
|   IN BOOLEAN     BestName,
 | |
|   IN CONST CHAR8 *Language OPTIONAL
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                  Status;
 | |
|   BOOLEAN                     ConfigurationStatus;
 | |
|   BOOLEAN                     DiagnosticsStatus;
 | |
|   UINTN                       DriverBindingHandleCount;
 | |
|   EFI_HANDLE                  *DriverBindingHandleBuffer;
 | |
|   UINTN                       ParentControllerHandleCount;
 | |
|   EFI_HANDLE                  *ParentControllerHandleBuffer;
 | |
|   UINTN                       ChildControllerHandleCount;
 | |
|   EFI_HANDLE                  *ChildControllerHandleBuffer;
 | |
|   CHAR16                      *TempStringPointer;
 | |
|   EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
 | |
|   UINTN                       Index;
 | |
|   CHAR16                      *DriverName;
 | |
|   EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
 | |
|   UINTN                       NumberOfChildren;
 | |
|   UINTN                       HandleIndex;
 | |
|   UINTN                       ControllerHandleCount;
 | |
|   EFI_HANDLE                  *ControllerHandleBuffer;
 | |
|   UINTN                       ChildIndex;
 | |
|   BOOLEAN                     Image;
 | |
| 
 | |
|   DriverName = NULL;
 | |
| 
 | |
|   //
 | |
|   // See if Handle is a device handle and display its details.
 | |
|   //
 | |
|   DriverBindingHandleBuffer = NULL;
 | |
|   Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
 | |
|             Handle,
 | |
|             &DriverBindingHandleCount,
 | |
|             &DriverBindingHandleBuffer
 | |
|             );
 | |
| 
 | |
|   ParentControllerHandleBuffer = NULL;
 | |
|   Status = PARSE_HANDLE_DATABASE_PARENTS (
 | |
|             Handle,
 | |
|             &ParentControllerHandleCount,
 | |
|             &ParentControllerHandleBuffer
 | |
|             );
 | |
| 
 | |
|   ChildControllerHandleBuffer = NULL;
 | |
|   Status = ParseHandleDatabaseForChildControllers (
 | |
|             Handle,
 | |
|             &ChildControllerHandleCount,
 | |
|             &ChildControllerHandleBuffer
 | |
|             );
 | |
| 
 | |
|   DiagnosticsStatus = FALSE;
 | |
|   ConfigurationStatus = FALSE;
 | |
| 
 | |
|   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
 | |
|     ConfigurationStatus = TRUE;
 | |
|   }
 | |
|   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfiguration2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
 | |
|     ConfigurationStatus = TRUE;
 | |
|   }
 | |
|   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
 | |
|     DiagnosticsStatus = TRUE;
 | |
|   }
 | |
|   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
 | |
|     DiagnosticsStatus = TRUE;
 | |
|   }
 | |
| 
 | |
|   Status = EFI_SUCCESS;
 | |
| 
 | |
|   if (DriverBindingHandleCount > 0 || ParentControllerHandleCount > 0 || ChildControllerHandleCount > 0) {
 | |
| 
 | |
| 
 | |
| 
 | |
|     DevicePath          = NULL;
 | |
|     TempStringPointer   = NULL;
 | |
|     Status              = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);
 | |
| 
 | |
|     Status = gEfiShellProtocol->GetDeviceName(Handle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
 | |
|     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DRIVER1), gShellDriver1HiiHandle, TempStringPointer!=NULL?TempStringPointer:L"<Unknown>");
 | |
|     SHELL_FREE_NON_NULL(TempStringPointer);
 | |
|   
 | |
|     TempStringPointer = ConvertDevicePathToText(DevicePath, TRUE, FALSE);
 | |
|     ShellPrintHiiEx(
 | |
|       -1, 
 | |
|       -1, 
 | |
|       NULL, 
 | |
|       STRING_TOKEN (STR_DH_OUTPUT_DRIVER2), 
 | |
|       gShellDriver1HiiHandle, 
 | |
|       TempStringPointer!=NULL?TempStringPointer:L"<None>",
 | |
|       ParentControllerHandleCount == 0?L"ROOT":(ChildControllerHandleCount > 0)?L"BUS":L"DEVICE",
 | |
|       ConfigurationStatus?L"YES":L"NO",
 | |
|       DiagnosticsStatus?L"YES":L"NO"
 | |
|       );
 | |
| 
 | |
|     SHELL_FREE_NON_NULL(TempStringPointer);
 | |
| 
 | |
|     if (DriverBindingHandleCount == 0) {
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL, 
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_DRIVER3), 
 | |
|         gShellDriver1HiiHandle, 
 | |
|         L"<None>"
 | |
|         );
 | |
|     } else {
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL, 
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_DRIVER3), 
 | |
|         gShellDriver1HiiHandle, 
 | |
|         L""
 | |
|         );
 | |
|       for (Index = 0; Index < DriverBindingHandleCount; Index++) {
 | |
|         Image = FALSE;
 | |
|         Status = GetDriverName (
 | |
|                   DriverBindingHandleBuffer[Index],
 | |
|                   Language,
 | |
|                   &DriverName
 | |
|                   );
 | |
|         if (EFI_ERROR (Status)) {
 | |
|           Status = GetDriverImageName (
 | |
|                     DriverBindingHandleBuffer[Index],
 | |
|                     &DriverName
 | |
|                     );
 | |
|           if (EFI_ERROR (Status)) {
 | |
|             DriverName = NULL;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         if (Image) {
 | |
|           ShellPrintHiiEx(
 | |
|             -1, 
 | |
|             -1, 
 | |
|             NULL, 
 | |
|             STRING_TOKEN (STR_DH_OUTPUT_DRIVER4A),
 | |
|             gShellDriver1HiiHandle,
 | |
|             ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
 | |
|             DriverName!=NULL?DriverName:L"<Unknown>"
 | |
|             );
 | |
|         } else {
 | |
|           ShellPrintHiiEx(
 | |
|             -1, 
 | |
|             -1, 
 | |
|             NULL, 
 | |
|             STRING_TOKEN (STR_DH_OUTPUT_DRIVER4B),
 | |
|             gShellDriver1HiiHandle,
 | |
|             ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
 | |
|             DriverName!=NULL?DriverName:L"<Unknown>"
 | |
|             );
 | |
|         }
 | |
|         SHELL_FREE_NON_NULL(DriverName);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (ParentControllerHandleCount == 0) {
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL, 
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_DRIVER5), 
 | |
|         gShellDriver1HiiHandle, 
 | |
|         L"<None>"
 | |
|         );
 | |
|     } else {
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL, 
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_DRIVER5), 
 | |
|         gShellDriver1HiiHandle, 
 | |
|         L""
 | |
|         );
 | |
|       for (Index = 0; Index < ParentControllerHandleCount; Index++) {
 | |
|         Status = gEfiShellProtocol->GetDeviceName(ParentControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
 | |
|         ShellPrintHiiEx(
 | |
|           -1, 
 | |
|           -1, 
 | |
|           NULL, 
 | |
|           STRING_TOKEN (STR_DH_OUTPUT_DRIVER5B),
 | |
|           gShellDriver1HiiHandle,
 | |
|           ConvertHandleToHandleIndex (ParentControllerHandleBuffer[Index]),
 | |
|           TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
 | |
|           );
 | |
|         SHELL_FREE_NON_NULL(TempStringPointer);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (ChildControllerHandleCount == 0) {
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL, 
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), 
 | |
|         gShellDriver1HiiHandle, 
 | |
|         L"<None>"
 | |
|         );
 | |
|     } else {
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL, 
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), 
 | |
|         gShellDriver1HiiHandle, 
 | |
|         L""
 | |
|         );
 | |
|       for (Index = 0; Index < ChildControllerHandleCount; Index++) {
 | |
|         Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
 | |
|         ShellPrintHiiEx(
 | |
|           -1, 
 | |
|           -1, 
 | |
|           NULL, 
 | |
|           STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
 | |
|           gShellDriver1HiiHandle,
 | |
|           ConvertHandleToHandleIndex (ChildControllerHandleBuffer[Index]),
 | |
|           TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
 | |
|           );
 | |
|         SHELL_FREE_NON_NULL(TempStringPointer);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   SHELL_FREE_NON_NULL(DriverBindingHandleBuffer);
 | |
| 
 | |
|   SHELL_FREE_NON_NULL(ParentControllerHandleBuffer);
 | |
| 
 | |
|   SHELL_FREE_NON_NULL(ChildControllerHandleBuffer);
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
|   //
 | |
|   // See if Handle is a driver binding handle and display its details.
 | |
|   //
 | |
|   Status = gBS->OpenProtocol (
 | |
|                 Handle,
 | |
|                 &gEfiDriverBindingProtocolGuid,
 | |
|                 (VOID **) &DriverBinding,
 | |
|                 NULL,
 | |
|                 NULL,
 | |
|                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | |
|                 );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   NumberOfChildren        = 0;
 | |
|   ControllerHandleBuffer  = NULL;
 | |
|   Status = PARSE_HANDLE_DATABASE_DEVICES (
 | |
|             Handle,
 | |
|             &ControllerHandleCount,
 | |
|             &ControllerHandleBuffer
 | |
|             );
 | |
|   if (ControllerHandleCount > 0) {
 | |
|     for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
 | |
|       Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
 | |
|                 Handle,
 | |
|                 ControllerHandleBuffer[HandleIndex],
 | |
|                 &ChildControllerHandleCount,
 | |
|                 NULL
 | |
|                 );
 | |
|       NumberOfChildren += ChildControllerHandleCount;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Status = GetDriverName (Handle, Language, &DriverName);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DriverName = NULL;
 | |
|   }
 | |
| 
 | |
|   ShellPrintHiiEx(
 | |
|     -1, 
 | |
|     -1, 
 | |
|     NULL, 
 | |
|     STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
 | |
|     gShellDriver1HiiHandle,
 | |
|     ConvertHandleToHandleIndex(Handle),
 | |
|     DriverName!=NULL?DriverName:L"<Unknown>"
 | |
|     );
 | |
|   SHELL_FREE_NON_NULL(DriverName);
 | |
|   Status = GetDriverImageName (
 | |
|             Handle,
 | |
|             &DriverName
 | |
|             );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DriverName = NULL;
 | |
|   }
 | |
|   ShellPrintHiiEx(
 | |
|     -1, 
 | |
|     -1, 
 | |
|     NULL, 
 | |
|     STRING_TOKEN (STR_DH_OUTPUT_DRIVER7B),
 | |
|     gShellDriver1HiiHandle,
 | |
|     DriverName!=NULL?DriverName:L"<Unknown>"
 | |
|     );
 | |
|   SHELL_FREE_NON_NULL(DriverName);
 | |
| 
 | |
|   ShellPrintHiiEx(
 | |
|     -1, 
 | |
|     -1, 
 | |
|     NULL, 
 | |
|     STRING_TOKEN (STR_DH_OUTPUT_DRIVER8), 
 | |
|     gShellDriver1HiiHandle, 
 | |
|     DriverBinding->Version,
 | |
|     NumberOfChildren > 0?L"Bus":ControllerHandleCount > 0?L"Device":L"<Unknown>",
 | |
|     ConfigurationStatus?L"YES":L"NO",
 | |
|     DiagnosticsStatus?L"YES":L"NO"
 | |
|     );
 | |
| 
 | |
|   if (ControllerHandleCount == 0) {
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL, 
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), 
 | |
|         gShellDriver1HiiHandle, 
 | |
|         L"None"
 | |
|         );
 | |
|   } else {
 | |
|     ShellPrintHiiEx(
 | |
|       -1, 
 | |
|       -1, 
 | |
|       NULL, 
 | |
|       STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), 
 | |
|       gShellDriver1HiiHandle, 
 | |
|       L""
 | |
|       );
 | |
|     for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
 | |
|       Status = gEfiShellProtocol->GetDeviceName(ControllerHandleBuffer[HandleIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
 | |
| 
 | |
|       ShellPrintHiiEx(
 | |
|         -1, 
 | |
|         -1, 
 | |
|         NULL, 
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_DRIVER9B),
 | |
|         gShellDriver1HiiHandle,
 | |
|         ConvertHandleToHandleIndex(ControllerHandleBuffer[HandleIndex]),
 | |
|         TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
 | |
|         );
 | |
|       SHELL_FREE_NON_NULL(TempStringPointer);
 | |
| 
 | |
|       Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
 | |
|                 Handle,
 | |
|                 ControllerHandleBuffer[HandleIndex],
 | |
|                 &ChildControllerHandleCount,
 | |
|                 &ChildControllerHandleBuffer
 | |
|                 );
 | |
|       if (!EFI_ERROR (Status)) {
 | |
|         for (ChildIndex = 0; ChildIndex < ChildControllerHandleCount; ChildIndex++) {
 | |
|           Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[ChildIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
 | |
| 
 | |
|           ShellPrintHiiEx(
 | |
|             -1, 
 | |
|             -1, 
 | |
|             NULL, 
 | |
|             STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
 | |
|             gShellDriver1HiiHandle,
 | |
|             ConvertHandleToHandleIndex(ChildControllerHandleBuffer[ChildIndex]),
 | |
|             TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
 | |
|             );
 | |
|           SHELL_FREE_NON_NULL(TempStringPointer);
 | |
|         }
 | |
| 
 | |
|         SHELL_FREE_NON_NULL (ChildControllerHandleBuffer);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     SHELL_FREE_NON_NULL (ControllerHandleBuffer);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Display information for a handle.
 | |
| 
 | |
|   @param[in] TheHandle        The handles to show info on.
 | |
|   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
 | |
|   @param[in] Sfo              TRUE to output in standard format output (spec).
 | |
|   @param[in] Language         Language string per UEFI specification.
 | |
|   @param[in] DriverInfo       TRUE to show all info about the handle.
 | |
|   @param[in] Multiple         TRUE indicates more than  will be output,
 | |
|                               FALSE for a single one.
 | |
| 
 | |
|   @retval SHELL_SUCCESS           The operation was successful.
 | |
|   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| DoDhByHandle(
 | |
|   IN CONST EFI_HANDLE TheHandle,
 | |
|   IN CONST BOOLEAN    Verbose,
 | |
|   IN CONST BOOLEAN    Sfo,
 | |
|   IN CONST CHAR8      *Language,
 | |
|   IN CONST BOOLEAN    DriverInfo,
 | |
|   IN CONST BOOLEAN    Multiple
 | |
|   )
 | |
| {
 | |
|   CHAR16              *ProtocolInfoString;
 | |
|   SHELL_STATUS        ShellStatus;
 | |
| 
 | |
|   ShellStatus         = SHELL_SUCCESS;
 | |
|   ProtocolInfoString  = NULL;
 | |
| 
 | |
|   if (!Sfo) {
 | |
|     if (Multiple) {
 | |
|       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", Verbose, TRUE);
 | |
|       ShellPrintHiiEx(
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_DH_OUTPUT),
 | |
|         gShellDriver1HiiHandle,
 | |
|         ConvertHandleToHandleIndex(TheHandle),
 | |
|         ProtocolInfoString==NULL?L"":ProtocolInfoString);
 | |
|     } else {
 | |
|       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L"\r\n", Verbose, TRUE);
 | |
|       ShellPrintHiiEx(
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_SINGLE),
 | |
|         gShellDriver1HiiHandle,
 | |
|         ConvertHandleToHandleIndex(TheHandle),
 | |
|         TheHandle,
 | |
|         ProtocolInfoString==NULL?L"":ProtocolInfoString);
 | |
|     }
 | |
| 
 | |
|     if (DriverInfo) {
 | |
|       DisplayDriverModelHandle ((EFI_HANDLE)TheHandle, TRUE, Language);
 | |
|     }
 | |
|   } else {
 | |
|       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", FALSE, FALSE);
 | |
|       ShellPrintHiiEx(
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_DH_OUTPUT_SFO),
 | |
|         gShellDriver1HiiHandle,
 | |
|         Multiple ?L"HandlesInfo":L"HandleInfo",
 | |
|         L"DriverName",
 | |
|         L"ControllerName",
 | |
|         ConvertHandleToHandleIndex(TheHandle),
 | |
|         L"DevPath",
 | |
|         ProtocolInfoString==NULL?L"":ProtocolInfoString);
 | |
| 
 | |
| 
 | |
|   }
 | |
| 
 | |
| 
 | |
|   if (ProtocolInfoString != NULL) {
 | |
|     FreePool(ProtocolInfoString);
 | |
|   }
 | |
|   return (ShellStatus);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Display information for all handles on a list.
 | |
| 
 | |
|   @param[in] HandleList       The NULL-terminated list of handles.
 | |
|   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
 | |
|   @param[in] Sfo              TRUE to output in standard format output (spec).
 | |
|   @param[in] Language         Language string per UEFI specification.
 | |
|   @param[in] DriverInfo       TRUE to show all info about the handle.
 | |
| 
 | |
|   @retval SHELL_SUCCESS           The operation was successful.
 | |
|   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| DoDhForHandleList(
 | |
|   IN CONST EFI_HANDLE *HandleList,
 | |
|   IN CONST BOOLEAN    Verbose,
 | |
|   IN CONST BOOLEAN    Sfo,
 | |
|   IN CONST CHAR8      *Language,
 | |
|   IN CONST BOOLEAN    DriverInfo
 | |
|   )
 | |
| {
 | |
|   CONST EFI_HANDLE  *HandleWalker;
 | |
|   SHELL_STATUS      ShellStatus;
 | |
| 
 | |
|   ShellStatus       = SHELL_SUCCESS;
 | |
| 
 | |
|   for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL && ShellStatus == SHELL_SUCCESS; HandleWalker++) {
 | |
|     ShellStatus = DoDhByHandle(
 | |
|           *HandleWalker,
 | |
|           Verbose,
 | |
|           Sfo,
 | |
|           Language,
 | |
|           DriverInfo,
 | |
|           TRUE
 | |
|          );
 | |
|     if (ShellGetExecutionBreakFlag ()) {
 | |
|       ShellStatus = SHELL_ABORTED;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   return (ShellStatus);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Display information for all handles.
 | |
| 
 | |
|   @param[in] Sfo              TRUE to output in standard format output (spec).
 | |
|   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
 | |
|   @param[in] Language         Language string per UEFI specification.
 | |
|   @param[in] DriverInfo       TRUE to show all info about the handle.
 | |
| 
 | |
|   @retval SHELL_SUCCESS           The operation was successful.
 | |
|   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| DoDhForAll(
 | |
|   IN CONST BOOLEAN  Sfo,
 | |
|   IN CONST BOOLEAN  Verbose,
 | |
|   IN CONST CHAR8    *Language,
 | |
|   IN CONST BOOLEAN  DriverInfo
 | |
|   )
 | |
| {
 | |
|   EFI_HANDLE    *HandleList;
 | |
|   SHELL_STATUS  ShellStatus;
 | |
| 
 | |
|   HandleList = GetHandleListByProtocol(NULL);
 | |
| 
 | |
|   ShellStatus = DoDhForHandleList(
 | |
|     HandleList,
 | |
|     Verbose,
 | |
|     Sfo,
 | |
|     Language,
 | |
|     DriverInfo);
 | |
| 
 | |
|   FreePool(HandleList);
 | |
| 
 | |
|   return (ShellStatus);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Display information for all handles which have a specific protocol.
 | |
| 
 | |
|   @param[in] ProtocolName     The pointer to the name of the protocol.
 | |
|   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
 | |
|   @param[in] Sfo              TRUE to output in standard format output (spec).
 | |
|   @param[in] Language         Language string per UEFI specification.
 | |
|   @param[in] DriverInfo       TRUE to show all info about the handle.
 | |
| 
 | |
|   @retval SHELL_SUCCESS           The operation was successful.
 | |
|   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| DoDhByProtocol(
 | |
|   IN CONST CHAR16   *ProtocolName,
 | |
|   IN CONST BOOLEAN  Verbose,
 | |
|   IN CONST BOOLEAN  Sfo,
 | |
|   IN CONST CHAR8    *Language,
 | |
|   IN CONST BOOLEAN  DriverInfo
 | |
|   )
 | |
| {
 | |
|   EFI_GUID      *Guid;
 | |
|   EFI_STATUS    Status;
 | |
|   EFI_HANDLE    *HandleList;
 | |
|   SHELL_STATUS  ShellStatus;
 | |
| 
 | |
|   if (ProtocolName == NULL) {
 | |
|     return (SHELL_INVALID_PARAMETER);
 | |
|   }
 | |
| 
 | |
|   Status = GetGuidFromStringName(ProtocolName, Language, &Guid);
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, ProtocolName);
 | |
|     return (SHELL_INVALID_PARAMETER);
 | |
|   }
 | |
| 
 | |
|   HandleList = GetHandleListByProtocol(Guid);
 | |
| 
 | |
|   ShellStatus = DoDhForHandleList(
 | |
|     HandleList,
 | |
|     Verbose,
 | |
|     Sfo,
 | |
|     Language,
 | |
|     DriverInfo);
 | |
| 
 | |
|   SHELL_FREE_NON_NULL(HandleList);
 | |
| 
 | |
|   return (ShellStatus);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Function for 'dh' command.
 | |
| 
 | |
|   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
 | |
|   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| ShellCommandRunDh (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS          Status;
 | |
|   LIST_ENTRY          *Package;
 | |
|   CHAR16              *ProblemParam;
 | |
|   SHELL_STATUS        ShellStatus;
 | |
|   CHAR8               *Language;
 | |
|   CONST CHAR16        *Lang;
 | |
|   CONST CHAR16        *Temp2;
 | |
|   BOOLEAN             SfoMode;
 | |
|   BOOLEAN             FlagD;
 | |
|   BOOLEAN             Verbose;
 | |
|   UINT64              Intermediate;
 | |
| 
 | |
|   ShellStatus         = SHELL_SUCCESS;
 | |
|   Status              = EFI_SUCCESS;
 | |
|   Language            = NULL;
 | |
| 
 | |
|   //
 | |
|   // initialize the shell lib (we must be in non-auto-init...)
 | |
|   //
 | |
|   Status = ShellInitialize();
 | |
|   ASSERT_EFI_ERROR(Status);
 | |
| 
 | |
|   Status = CommandInit();
 | |
|   ASSERT_EFI_ERROR(Status);
 | |
| 
 | |
|   //
 | |
|   // parse the command line
 | |
|   //
 | |
|   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
 | |
|   if (EFI_ERROR(Status)) {
 | |
|     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"dh", ProblemParam);  
 | |
|       FreePool(ProblemParam);
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     } else {
 | |
|       ASSERT(FALSE);
 | |
|     }
 | |
|   } else {
 | |
|     if (ShellCommandLineGetCount(Package) > 2) {
 | |
|       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");  
 | |
|       ShellCommandLineFreeVarList (Package);
 | |
|       return (SHELL_INVALID_PARAMETER);
 | |
|     }
 | |
| 
 | |
|     Lang = ShellCommandLineGetValue(Package, L"-l");
 | |
|     if (Lang != NULL) {
 | |
|       Language = AllocateZeroPool(StrSize(Lang));
 | |
|       AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
 | |
|     } else if (!ShellCommandLineGetFlag(Package, L"-l")){
 | |
|       Language = AllocateZeroPool(10);
 | |
|       AsciiSPrint(Language, 10, "en-us");
 | |
|     } else {
 | |
|       ASSERT(Language == NULL);
 | |
|       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh",  L"-l");  
 | |
|       ShellCommandLineFreeVarList (Package);
 | |
|       return (SHELL_INVALID_PARAMETER);
 | |
|     }
 | |
| 
 | |
|     SfoMode = ShellCommandLineGetFlag(Package, L"-sfo");
 | |
|     FlagD   = ShellCommandLineGetFlag(Package, L"-d");
 | |
|     Verbose = (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-v") || ShellCommandLineGetFlag(Package, L"-verbose"));
 | |
| 
 | |
|     if (ShellCommandLineGetFlag(Package, L"-p")) {
 | |
|       if (ShellCommandLineGetCount(Package) > 1) {
 | |
|         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");  
 | |
|         ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       } else if (ShellCommandLineGetValue(Package, L"-p") == NULL) {
 | |
|         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh",  L"-p");  
 | |
|         ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|       } else {
 | |
|         //
 | |
|         // print by protocol
 | |
|         //
 | |
|         ShellStatus = DoDhByProtocol(
 | |
|           ShellCommandLineGetValue(Package, L"-p"),
 | |
|           Verbose,
 | |
|           SfoMode,
 | |
|           Lang==NULL?NULL:Language,
 | |
|           FlagD
 | |
|          );
 | |
|       }
 | |
|     } else {
 | |
|       Temp2 = ShellCommandLineGetRawValue(Package, 1);
 | |
|       if (Temp2 == NULL) {
 | |
|         //
 | |
|         // Print everything
 | |
|         //
 | |
|         ShellStatus = DoDhForAll(
 | |
|           SfoMode,
 | |
|           Verbose,
 | |
|           Lang==NULL?NULL:Language,
 | |
|           FlagD
 | |
|          );
 | |
|       } else {
 | |
|         Status = ShellConvertStringToUint64(Temp2, &Intermediate, TRUE, FALSE);
 | |
|         if (EFI_ERROR(Status) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) {
 | |
|           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", Temp2);  
 | |
|           ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|         } else {
 | |
|           //
 | |
|           // print 1 handle
 | |
|           //
 | |
|           ShellStatus = DoDhByHandle(
 | |
|             ConvertHandleIndexToHandle((UINTN)Intermediate),
 | |
|             Verbose,
 | |
|             SfoMode,
 | |
|             Lang==NULL?NULL:Language,
 | |
|             FlagD,
 | |
|             FALSE
 | |
|            );
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
| 
 | |
|     ShellCommandLineFreeVarList (Package);
 | |
|     SHELL_FREE_NON_NULL(Language);
 | |
|   }
 | |
| 
 | |
|   return (ShellStatus);
 | |
| }
 |