Home | History | Annotate | Download | only in UefiShellDriver1CommandsLib
      1 /** @file
      2   Main file for devices shell Driver1 function.
      3 
      4   (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR>
      5   Copyright (c) 2010 - 2014, 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 /**
     19   Get lots of info about a device from its handle.
     20 
     21   @param[in] TheHandle       The device handle to get info on.
     22   @param[in, out] Type       On successful return R, B, or D (root, bus, or
     23                              device) will be placed in this buffer.
     24   @param[in, out] Cfg        On successful return this buffer will be
     25                              TRUE if the handle has configuration, FALSE
     26                              otherwise.
     27   @param[in, out] Diag       On successful return this buffer will be
     28                              TRUE if the handle has disgnostics, FALSE
     29                              otherwise.
     30   @param[in, out] Parents    On successful return this buffer will be
     31                              contain the number of parent handles.
     32   @param[in, out] Devices    On successful return this buffer will be
     33                              contain the number of devices controlled.
     34   @param[in, out] Children   On successful return this buffer will be
     35                              contain the number of child handles.
     36   @param[out] Name           The pointer to a buffer that will be allocated
     37                              and contain the string name of the handle.
     38                              The caller must free this memory.
     39   @param[in] Language        The language code as defined by the UEFI spec.
     40 
     41   @retval EFI_SUCCESS           The info is there.
     42   @retval EFI_INVALID_PARAMETER A parameter was invalid.
     43 **/
     44 EFI_STATUS
     45 EFIAPI
     46 GetDeviceHandleInfo (
     47   IN EFI_HANDLE   TheHandle,
     48   IN OUT CHAR16   *Type,
     49   IN OUT BOOLEAN  *Cfg,
     50   IN OUT BOOLEAN  *Diag,
     51   IN OUT UINTN    *Parents,
     52   IN OUT UINTN    *Devices,
     53   IN OUT UINTN    *Children,
     54   OUT CHAR16      **Name,
     55   IN CONST CHAR8  *Language
     56   )
     57 {
     58   EFI_STATUS    Status;
     59   EFI_HANDLE    *HandleBuffer;
     60   UINTN         Count;
     61 
     62   if (TheHandle == NULL
     63     || Type == NULL
     64     || Cfg == NULL
     65     || Diag == NULL
     66     || Parents == NULL
     67     || Devices == NULL
     68     || Children == NULL
     69     || Name == NULL ) {
     70     return (EFI_INVALID_PARAMETER);
     71   }
     72 
     73   *Cfg          = FALSE;
     74   *Diag         = FALSE;
     75   *Children     = 0;
     76   *Parents      = 0;
     77   *Devices      = 0;
     78   *Type         = L' ';
     79   *Name         = CHAR_NULL;
     80   HandleBuffer  = NULL;
     81   Status        = EFI_SUCCESS;
     82 
     83   gEfiShellProtocol->GetDeviceName(TheHandle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, Name);
     84 
     85   Status = ParseHandleDatabaseForChildControllers(TheHandle, Children, NULL);
     86 //  if (!EFI_ERROR(Status)) {
     87     Status = PARSE_HANDLE_DATABASE_PARENTS(TheHandle, Parents, NULL);
     88     if (/*!EFI_ERROR(Status) && */Parents != NULL && Children != NULL) {
     89       if (*Parents == 0) {
     90         *Type = L'R';
     91       } else if (*Children > 0) {
     92         *Type = L'B';
     93       } else {
     94         *Type = L'D';
     95       }
     96     }
     97 //  }
     98   Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS(TheHandle, Devices, &HandleBuffer);
     99   if (!EFI_ERROR(Status) && Devices != NULL && HandleBuffer != NULL) {
    100     for (Count = 0 ; Count < *Devices ; Count++) {
    101       if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    102         *Cfg = TRUE;
    103       }
    104       if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    105         *Diag = TRUE;
    106       }
    107       if (!EFI_ERROR(gBS->OpenProtocol(HandleBuffer[Count], &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    108         *Diag = TRUE;
    109       }
    110     }
    111     SHELL_FREE_NON_NULL(HandleBuffer);
    112   }
    113 
    114   return (Status);
    115 }
    116 
    117 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
    118   {L"-sfo", TypeFlag},
    119   {L"-l", TypeValue},
    120   {NULL, TypeMax}
    121   };
    122 
    123 /**
    124   Function for 'devices' command.
    125 
    126   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
    127   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
    128 **/
    129 SHELL_STATUS
    130 EFIAPI
    131 ShellCommandRunDevices (
    132   IN EFI_HANDLE        ImageHandle,
    133   IN EFI_SYSTEM_TABLE  *SystemTable
    134   )
    135 {
    136   EFI_STATUS          Status;
    137   LIST_ENTRY          *Package;
    138   CHAR16              *ProblemParam;
    139   SHELL_STATUS        ShellStatus;
    140   CHAR8               *Language;
    141   EFI_HANDLE          *HandleList;
    142   EFI_HANDLE          *HandleListWalker;
    143   CHAR16              Type;
    144   BOOLEAN             Cfg;
    145   BOOLEAN             Diag;
    146   UINTN               Parents;
    147   UINTN               Devices;
    148   UINTN               Children;
    149   CHAR16              *Name;
    150   CONST CHAR16        *Lang;
    151   BOOLEAN             SfoFlag;
    152 
    153   ShellStatus         = SHELL_SUCCESS;
    154   Language            = NULL;
    155   SfoFlag             = FALSE;
    156 
    157   //
    158   // initialize the shell lib (we must be in non-auto-init...)
    159   //
    160   Status = ShellInitialize();
    161   ASSERT_EFI_ERROR(Status);
    162 
    163   Status = CommandInit();
    164   ASSERT_EFI_ERROR(Status);
    165 
    166   //
    167   // parse the command line
    168   //
    169   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
    170   if (EFI_ERROR(Status)) {
    171     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
    172       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"devices", ProblemParam);
    173       FreePool(ProblemParam);
    174       ShellStatus = SHELL_INVALID_PARAMETER;
    175     } else {
    176       ASSERT(FALSE);
    177     }
    178   } else {
    179     //
    180     // if more than 0 'value' parameters  we have too many parameters
    181     //
    182     if (ShellCommandLineGetRawValue(Package, 1) != NULL){
    183       //
    184       // error for too many parameters
    185       //
    186       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"devices");
    187       ShellStatus = SHELL_INVALID_PARAMETER;
    188     } else {
    189       //
    190       // get the language if necessary
    191       //
    192       Lang = ShellCommandLineGetValue(Package, L"-l");
    193       if (Lang != NULL) {
    194         Language = AllocateZeroPool(StrSize(Lang));
    195         AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
    196       } else if (!ShellCommandLineGetFlag(Package, L"-l")){
    197         ASSERT(Language == NULL);
    198 //        Language = AllocateZeroPool(10);
    199 //        AsciiSPrint(Language, 10, "en-us");
    200       } else {
    201         ASSERT(Language == NULL);
    202         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"devices",  L"-l");
    203         ShellCommandLineFreeVarList (Package);
    204         return (SHELL_INVALID_PARAMETER);
    205       }
    206 
    207 
    208       //
    209       // Print Header
    210 
    211       //
    212       if (ShellCommandLineGetFlag (Package, L"-sfo")) {
    213         ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDriver1HiiHandle, L"devices");
    214         SfoFlag = TRUE;
    215       } else {
    216         ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_DEVICES_HEADER_LINES), gShellDriver1HiiHandle);
    217       }
    218 
    219       //
    220       // loop through each handle
    221       //
    222       HandleList = GetHandleListByProtocol(NULL);
    223       ASSERT(HandleList != NULL);
    224       for (HandleListWalker = HandleList
    225         ;  HandleListWalker != NULL && *HandleListWalker != NULL /*&& !EFI_ERROR(Status)*/
    226         ;  HandleListWalker++
    227        ){
    228 
    229         //
    230         // get all the info on each handle
    231         //
    232         Name = NULL;
    233         Status = GetDeviceHandleInfo(*HandleListWalker, &Type, &Cfg, &Diag, &Parents, &Devices, &Children, &Name, Language);
    234         if (Name != NULL && (Parents != 0 || Devices != 0 || Children != 0)) {
    235           ShellPrintHiiEx (
    236             -1,
    237             -1,
    238             Language,
    239             SfoFlag?STRING_TOKEN (STR_DEVICES_ITEM_LINE_SFO):STRING_TOKEN (STR_DEVICES_ITEM_LINE),
    240             gShellDriver1HiiHandle,
    241             ConvertHandleToHandleIndex (*HandleListWalker),
    242             Type,
    243             Cfg?(SfoFlag?L'Y':L'X'):(SfoFlag?L'N':L'-'),
    244             Diag?(SfoFlag?L'Y':L'X'):(SfoFlag?L'N':L'-'),
    245             Parents,
    246             Devices,
    247             Children,
    248             Name!=NULL?Name:L"<UNKNOWN>");
    249         }
    250         if (Name != NULL) {
    251           FreePool(Name);
    252         }
    253         if (ShellGetExecutionBreakFlag ()) {
    254           ShellStatus = SHELL_ABORTED;
    255           break;
    256         }
    257 
    258       }
    259 
    260       if (HandleList != NULL) {
    261         FreePool(HandleList);
    262       }
    263 
    264     }
    265     SHELL_FREE_NON_NULL(Language);
    266     ShellCommandLineFreeVarList (Package);
    267   }
    268   return (ShellStatus);
    269 }
    270 
    271