Home | History | Annotate | Download | only in UefiShellDriver1CommandsLib
      1 /** @file
      2   Main file for Drivers shell Driver1 function.
      3 
      4   (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR>
      5   Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "UefiShellDriver1CommandsLib.h"
     17 
     18 #define MAX_LEN_DRIVER_NAME 35
     19 
     20 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
     21   {L"-sfo", TypeFlag},
     22   {L"-l", TypeValue},
     23   {NULL, TypeMax}
     24   };
     25 
     26 /**
     27   Get a device path (in text format) for a given handle.
     28 
     29   @param[in] TheHandle      The handle to get the device path for.
     30 
     31   @retval NULL    An error occured.
     32   @return         A pointer to the driver path as a string.  The callee must
     33                   free this memory.
     34 **/
     35 CHAR16*
     36 EFIAPI
     37 GetDevicePathTextForHandle(
     38   IN EFI_HANDLE TheHandle
     39   )
     40 {
     41   EFI_STATUS                Status;
     42   EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
     43   EFI_DEVICE_PATH_PROTOCOL  *ImageDevicePath;
     44   EFI_DEVICE_PATH_PROTOCOL  *FinalPath;
     45   CHAR16                    *RetVal;
     46 
     47   FinalPath = NULL;
     48 
     49   Status = gBS->OpenProtocol (
     50                 TheHandle,
     51                 &gEfiLoadedImageProtocolGuid,
     52                 (VOID**)&LoadedImage,
     53                 gImageHandle,
     54                 NULL,
     55                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
     56                );
     57   if (!EFI_ERROR (Status)) {
     58     Status = gBS->OpenProtocol (
     59                   LoadedImage->DeviceHandle,
     60                   &gEfiDevicePathProtocolGuid,
     61                   (VOID**)&ImageDevicePath,
     62                   gImageHandle,
     63                   NULL,
     64                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
     65                  );
     66     if (!EFI_ERROR (Status)) {
     67       FinalPath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
     68       gBS->CloseProtocol(
     69         LoadedImage->DeviceHandle,
     70         &gEfiDevicePathProtocolGuid,
     71         gImageHandle,
     72         NULL);
     73     }
     74     gBS->CloseProtocol(
     75                 TheHandle,
     76                 &gEfiLoadedImageProtocolGuid,
     77                 gImageHandle,
     78                 NULL);
     79   }
     80 
     81   if (FinalPath == NULL) {
     82     return (NULL);
     83   }
     84   RetVal = gEfiShellProtocol->GetFilePathFromDevicePath(FinalPath);
     85   if (RetVal == NULL) {
     86     RetVal = ConvertDevicePathToText(FinalPath, TRUE, TRUE);
     87   }
     88   FreePool(FinalPath);
     89   return (RetVal);
     90 }
     91 
     92 /**
     93   Determine if the given handle has Driver Configuration protocol.
     94 
     95   @param[in] TheHandle      The handle to the driver to test.
     96 
     97   @retval TRUE              The driver does have Driver Configuration.
     98   @retval FALSE             The driver does not have Driver Configuration.
     99 **/
    100 BOOLEAN
    101 EFIAPI
    102 ReturnDriverConfig(
    103   IN CONST EFI_HANDLE TheHandle
    104   )
    105 {
    106   EFI_STATUS                  Status;
    107   Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverConfigurationProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
    108   if (EFI_ERROR(Status)) {
    109     return (FALSE);
    110   }
    111   return (TRUE);
    112 }
    113 
    114 /**
    115   Determine if the given handle has DriverDiagnostics protocol.
    116 
    117   @param[in] TheHandle      The handle to the driver to test.
    118 
    119   @retval TRUE              The driver does have Driver Diasgnostics.
    120   @retval FALSE             The driver does not have Driver Diagnostics.
    121 **/
    122 BOOLEAN
    123 EFIAPI
    124 ReturnDriverDiag(
    125   IN CONST EFI_HANDLE TheHandle
    126   )
    127 {
    128   EFI_STATUS                  Status;
    129   Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
    130   if (EFI_ERROR(Status)) {
    131     Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverDiagnosticsProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
    132     if (EFI_ERROR(Status)) {
    133       return (FALSE);
    134     }
    135   }
    136   return (TRUE);
    137 }
    138 
    139 /**
    140   Finds and returns the version of the driver specified by TheHandle.
    141 
    142   @param[in] TheHandle      The driver handle to get the version of.
    143 
    144   @return             The version of the driver.
    145   @retval 0xFFFFFFFF  An error ocurred.
    146 **/
    147 UINT32
    148 EFIAPI
    149 ReturnDriverVersion(
    150   IN CONST EFI_HANDLE TheHandle
    151   )
    152 {
    153   EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
    154   EFI_STATUS                  Status;
    155   UINT32                      RetVal;
    156 
    157   RetVal = (UINT32)-1;
    158 
    159   Status = gBS->OpenProtocol((EFI_HANDLE)TheHandle, &gEfiDriverBindingProtocolGuid, (VOID**)&DriverBinding, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    160   if (!EFI_ERROR(Status)) {
    161     RetVal = DriverBinding->Version;
    162     gBS->CloseProtocol(TheHandle, &gEfiDriverBindingProtocolGuid, gImageHandle, NULL);
    163   }
    164   return (RetVal);
    165 }
    166 
    167 /**
    168   Function for 'drivers' command.
    169 
    170   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
    171   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
    172 **/
    173 SHELL_STATUS
    174 EFIAPI
    175 ShellCommandRunDrivers (
    176   IN EFI_HANDLE        ImageHandle,
    177   IN EFI_SYSTEM_TABLE  *SystemTable
    178   )
    179 {
    180   EFI_STATUS          Status;
    181   LIST_ENTRY          *Package;
    182   CHAR16              *ProblemParam;
    183   SHELL_STATUS        ShellStatus;
    184   CHAR8               *Language;
    185   CONST CHAR16        *Lang;
    186   EFI_HANDLE          *HandleList;
    187   EFI_HANDLE          *HandleWalker;
    188   UINTN               ChildCount;
    189   UINTN               DeviceCount;
    190   CHAR16              *Temp2;
    191   CONST CHAR16        *FullDriverName;
    192   CHAR16              *TruncatedDriverName;
    193   CHAR16              *FormatString;
    194   UINT32              DriverVersion;
    195   BOOLEAN             DriverConfig;
    196   BOOLEAN             DriverDiag;
    197   BOOLEAN             SfoFlag;
    198 
    199   ShellStatus         = SHELL_SUCCESS;
    200   Status              = EFI_SUCCESS;
    201   Language            = NULL;
    202   FormatString        = NULL;
    203   SfoFlag             = FALSE;
    204 
    205   //
    206   // initialize the shell lib (we must be in non-auto-init...)
    207   //
    208   Status = ShellInitialize();
    209   ASSERT_EFI_ERROR(Status);
    210 
    211   Status = CommandInit();
    212   ASSERT_EFI_ERROR(Status);
    213 
    214   //
    215   // parse the command line
    216   //
    217   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
    218   if (EFI_ERROR(Status)) {
    219     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
    220       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drivers", ProblemParam);
    221       FreePool(ProblemParam);
    222       ShellStatus = SHELL_INVALID_PARAMETER;
    223     } else {
    224       ASSERT(FALSE);
    225     }
    226   } else {
    227     if (ShellCommandLineGetCount(Package) > 1) {
    228       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drivers");
    229       ShellStatus = SHELL_INVALID_PARAMETER;
    230     } else {
    231       if (ShellCommandLineGetFlag(Package, L"-l")){
    232         Lang = ShellCommandLineGetValue(Package, L"-l");
    233         if (Lang != NULL) {
    234           Language = AllocateZeroPool(StrSize(Lang));
    235           AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
    236         } else {
    237           ASSERT(Language == NULL);
    238           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drivers", L"-l");
    239           ShellCommandLineFreeVarList (Package);
    240           return (SHELL_INVALID_PARAMETER);
    241         }
    242       }
    243 
    244       if (ShellCommandLineGetFlag (Package, L"-sfo")) {
    245         SfoFlag = TRUE;
    246         FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE_SFO), Language);
    247         //
    248         // print the SFO header
    249         //
    250         ShellPrintHiiEx (
    251           -1,
    252           -1,
    253           Language,
    254           STRING_TOKEN (STR_GEN_SFO_HEADER),
    255           gShellDriver1HiiHandle,
    256           L"drivers");
    257       } else {
    258         FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE), Language);
    259         //
    260         // print the header row
    261         //
    262         ShellPrintHiiEx(
    263           -1,
    264           -1,
    265           Language,
    266           STRING_TOKEN (STR_DRIVERS_HEADER_LINES),
    267           gShellDriver1HiiHandle);
    268       }
    269 
    270       HandleList = GetHandleListByProtocol(&gEfiDriverBindingProtocolGuid);
    271       for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL ; HandleWalker++){
    272         ChildCount     = 0;
    273         DeviceCount    = 0;
    274         Status         = ParseHandleDatabaseForChildDevices (*HandleWalker, &ChildCount , NULL);
    275         Status         = PARSE_HANDLE_DATABASE_DEVICES      (*HandleWalker, &DeviceCount, NULL);
    276         Temp2          = GetDevicePathTextForHandle(*HandleWalker);
    277         DriverVersion  = ReturnDriverVersion(*HandleWalker);
    278         DriverConfig   = ReturnDriverConfig(*HandleWalker);
    279         DriverDiag     = ReturnDriverDiag  (*HandleWalker);
    280         FullDriverName = GetStringNameFromHandle(*HandleWalker, Language);
    281 
    282         TruncatedDriverName = NULL;
    283         if (!SfoFlag && (FullDriverName != NULL)) {
    284           TruncatedDriverName = AllocateZeroPool ((MAX_LEN_DRIVER_NAME + 1) * sizeof (CHAR16));
    285           StrnCpyS (TruncatedDriverName, MAX_LEN_DRIVER_NAME + 1, FullDriverName, MAX_LEN_DRIVER_NAME);
    286         }
    287 
    288         ShellPrintEx(
    289           -1,
    290           -1,
    291           FormatString,
    292           ConvertHandleToHandleIndex(*HandleWalker),
    293           DriverVersion,
    294           ChildCount > 0?L'B':(DeviceCount > 0?L'D':L'?'),
    295           DriverConfig?L'Y':L'N',
    296           DriverDiag?L'Y':L'N',
    297           DeviceCount,
    298           ChildCount,
    299           SfoFlag?FullDriverName:TruncatedDriverName,
    300           Temp2==NULL?L"":Temp2
    301          );
    302         if (TruncatedDriverName != NULL) {
    303           FreePool (TruncatedDriverName);
    304         }
    305         if (Temp2 != NULL) {
    306           FreePool(Temp2);
    307         }
    308 
    309         if (ShellGetExecutionBreakFlag ()) {
    310           ShellStatus = SHELL_ABORTED;
    311           break;
    312         }
    313       }
    314     }
    315     SHELL_FREE_NON_NULL(Language);
    316     ShellCommandLineFreeVarList (Package);
    317     SHELL_FREE_NON_NULL(FormatString);
    318   }
    319 
    320   return (ShellStatus);
    321 }
    322