Home | History | Annotate | Download | only in UefiShellDriver1CommandsLib
      1 /** @file
      2   Main file for DrvCfg shell Driver1 function.
      3 
      4   (C) Copyright 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 #include <Protocol/HiiConfigAccess.h>
     18 #include <Protocol/HiiDatabase.h>
     19 
     20 STATIC CONST EFI_GUID *CfgGuidList[] = {&gEfiDriverConfigurationProtocolGuid, &gEfiDriverConfiguration2ProtocolGuid, NULL};
     21 
     22 /**
     23   Find the EFI_HII_HANDLE by device path.
     24 
     25   @param[in] DevPath1     The Device Path to match.
     26   @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.
     27   @param[in] HiiDb        The Hii database protocol
     28 
     29   @retval EFI_SUCCESS     The operation was successful.
     30   @retval EFI_NOT_FOUND   There was no EFI_HII_HANDLE found for that deviec path.
     31 **/
     32 EFI_STATUS
     33 EFIAPI
     34 FindHiiHandleViaDevPath(
     35   IN CONST EFI_DEVICE_PATH_PROTOCOL *DevPath1,
     36   OUT EFI_HII_HANDLE                *HiiHandle,
     37   IN EFI_HII_DATABASE_PROTOCOL      *HiiDb
     38   )
     39 {
     40   EFI_HII_HANDLE                *HandleBuffer;
     41   UINTN                         HandleBufferSize;
     42   VOID                          *MainBuffer;
     43   UINTN                         MainBufferSize;
     44   EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;
     45   EFI_HII_PACKAGE_HEADER        *PackageHeader;
     46   UINTN                         LoopVariable;
     47   EFI_DEVICE_PATH_PROTOCOL      *DevPath2;
     48   EFI_STATUS                    Status;
     49 
     50   ASSERT(DevPath1 != NULL);
     51   ASSERT(HiiHandle != NULL);
     52   ASSERT(*HiiHandle == NULL);
     53   ASSERT(HiiDb != NULL);
     54 
     55   HandleBufferSize  = 0;
     56   HandleBuffer      = NULL;
     57   Status = HiiDb->ListPackageLists(HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);
     58   if (Status == EFI_BUFFER_TOO_SMALL) {
     59     HandleBuffer = AllocateZeroPool(HandleBufferSize);
     60     ASSERT (HandleBuffer != NULL);
     61     Status = HiiDb->ListPackageLists(HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);
     62   }
     63   if (EFI_ERROR(Status)) {
     64     SHELL_FREE_NON_NULL(HandleBuffer);
     65     return (Status);
     66   }
     67 
     68   if (HandleBuffer == NULL) {
     69     return EFI_NOT_FOUND;
     70   }
     71 
     72   for (LoopVariable = 0 ; LoopVariable < (HandleBufferSize/sizeof(HandleBuffer[0])) && *HiiHandle == NULL ; LoopVariable++) {
     73     MainBufferSize    = 0;
     74     MainBuffer        = NULL;
     75     Status = HiiDb->ExportPackageLists(HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);
     76     if (Status == EFI_BUFFER_TOO_SMALL) {
     77       MainBuffer = AllocateZeroPool(MainBufferSize);
     78       ASSERT (MainBuffer != NULL);
     79       Status = HiiDb->ExportPackageLists(HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);
     80     }
     81     //
     82     // Enumerate through the block of returned memory.
     83     // This should actually be a small block, but we need to be sure.
     84     //
     85     for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)MainBuffer
     86       ;  PackageListHeader != NULL && ((CHAR8*)PackageListHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && *HiiHandle == NULL
     87       ;  PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)(((CHAR8*)(PackageListHeader)) + PackageListHeader->PackageLength )) {
     88         for (PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageListHeader))+sizeof(EFI_HII_PACKAGE_LIST_HEADER))
     89           ; PackageHeader != NULL && ((CHAR8*)PackageHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END && *HiiHandle == NULL
     90           ; PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageHeader))+PackageHeader->Length)) {
     91             if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {
     92               DevPath2 = (EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER));
     93               if (DevicePathCompare(&DevPath1, &DevPath2) == 0) {
     94                 *HiiHandle = HandleBuffer[LoopVariable];
     95                 break;
     96               }
     97             }
     98         }
     99     }
    100     SHELL_FREE_NON_NULL(MainBuffer);
    101   }
    102   SHELL_FREE_NON_NULL(HandleBuffer);
    103 
    104   if (*HiiHandle == NULL) {
    105     return (EFI_NOT_FOUND);
    106   }
    107   return (EFI_SUCCESS);
    108 }
    109 
    110 /**
    111   Convert a EFI_HANDLE to a EFI_HII_HANDLE.
    112 
    113   @param[in] Handle       The EFI_HANDLE to convert.
    114   @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.
    115   @param[in] HiiDb        The Hii database protocol
    116 
    117   @retval EFI_SUCCESS   The operation was successful.
    118 **/
    119 EFI_STATUS
    120 EFIAPI
    121 ConvertHandleToHiiHandle(
    122   IN CONST EFI_HANDLE           Handle,
    123   OUT EFI_HII_HANDLE            *HiiHandle,
    124   IN EFI_HII_DATABASE_PROTOCOL  *HiiDb
    125   )
    126 {
    127   EFI_STATUS                    Status;
    128   EFI_DEVICE_PATH_PROTOCOL      *DevPath1;
    129 
    130   if (HiiHandle == NULL || HiiDb == NULL) {
    131     return (EFI_INVALID_PARAMETER);
    132   }
    133   *HiiHandle = NULL;
    134 
    135   if (Handle == NULL) {
    136     return (EFI_SUCCESS);
    137   }
    138 
    139   DevPath1 = NULL;
    140   Status = gBS->OpenProtocol(Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath1, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    141   if (EFI_ERROR(Status) || DevPath1 == NULL) {
    142     return (EFI_NOT_FOUND);
    143   }
    144 
    145   return (FindHiiHandleViaDevPath(DevPath1, HiiHandle, HiiDb));
    146 }
    147 
    148 /**
    149   Function to print out all HII configuration information to a file.
    150 
    151   @param[in] Handle           The handle to get info on.  NULL to do all handles.
    152   @param[in] FileName         The filename to rwite the info to.
    153 **/
    154 SHELL_STATUS
    155 EFIAPI
    156 ConfigToFile(
    157   IN CONST EFI_HANDLE     Handle,
    158   IN CONST CHAR16         *FileName
    159   )
    160 {
    161   EFI_HII_DATABASE_PROTOCOL     *HiiDatabase;
    162   EFI_STATUS                    Status;
    163   VOID                          *MainBuffer;
    164   UINTN                         MainBufferSize;
    165   EFI_HII_HANDLE                HiiHandle;
    166   SHELL_FILE_HANDLE             FileHandle;
    167 
    168   HiiDatabase       = NULL;
    169   MainBufferSize    = 0;
    170   MainBuffer        = NULL;
    171   FileHandle        = NULL;
    172 
    173   Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
    174   if (EFI_ERROR(Status)) {
    175     ShellPrintHiiEx(
    176       -1,
    177       -1,
    178       NULL,
    179       STRING_TOKEN(STR_GEN_FILE_OPEN_FAIL),
    180       gShellDriver1HiiHandle,
    181       L"drvcfg",
    182       FileName,
    183       Status);
    184     return (SHELL_DEVICE_ERROR);
    185   }
    186 
    187   //
    188   // Locate HII Database protocol
    189   //
    190   Status = gBS->LocateProtocol (
    191                   &gEfiHiiDatabaseProtocolGuid,
    192                   NULL,
    193                   (VOID **) &HiiDatabase
    194                   );
    195 
    196   if (EFI_ERROR(Status) || HiiDatabase == NULL) {
    197     ShellPrintHiiEx(
    198       -1,
    199       -1,
    200       NULL,
    201       STRING_TOKEN(STR_GEN_PROTOCOL_NF),
    202       gShellDriver1HiiHandle,
    203       L"drvcfg",
    204       L"EfiHiiDatabaseProtocol",
    205       &gEfiHiiDatabaseProtocolGuid);
    206     ShellCloseFile(&FileHandle);
    207     return (SHELL_NOT_FOUND);
    208   }
    209 
    210   HiiHandle = NULL;
    211   Status = ConvertHandleToHiiHandle(Handle, &HiiHandle, HiiDatabase);
    212   if (EFI_ERROR(Status)) {
    213     ShellPrintHiiEx(
    214       -1,
    215       -1,
    216       NULL,
    217       STRING_TOKEN(STR_GEN_HANDLE_NOT),
    218       gShellDriver1HiiHandle,
    219       L"drvcfg",
    220       ConvertHandleToHandleIndex(Handle),
    221       L"Device");
    222     ShellCloseFile(&FileHandle);
    223     return (SHELL_DEVICE_ERROR);
    224   }
    225 
    226   Status = HiiDatabase->ExportPackageLists(HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);
    227   if (Status == EFI_BUFFER_TOO_SMALL) {
    228     MainBuffer = AllocateZeroPool(MainBufferSize);
    229     Status = HiiDatabase->ExportPackageLists(HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);
    230   }
    231 
    232   Status = ShellWriteFile(FileHandle, &MainBufferSize, MainBuffer);
    233 
    234   ShellCloseFile(&FileHandle);
    235   SHELL_FREE_NON_NULL(MainBuffer);
    236 
    237   if (EFI_ERROR(Status)) {
    238     ShellPrintHiiEx(
    239       -1,
    240       -1,
    241       NULL,
    242       STRING_TOKEN(STR_FILE_WRITE_FAIL),
    243       gShellDriver1HiiHandle,
    244       L"drvcfg",
    245       FileName);
    246     return (SHELL_DEVICE_ERROR);
    247   }
    248   ShellPrintHiiEx(
    249     -1,
    250     -1,
    251     NULL,
    252     STRING_TOKEN(STR_DRVCFG_COMP),
    253     gShellDriver1HiiHandle);
    254 
    255   return (SHELL_SUCCESS);
    256 }
    257 
    258 /**
    259   Function to read in HII configuration information from a file.
    260 
    261   @param[in] Handle           The handle to get info for.
    262   @param[in] FileName         The filename to read the info from.
    263 **/
    264 SHELL_STATUS
    265 EFIAPI
    266 ConfigFromFile(
    267   IN       EFI_HANDLE     Handle,
    268   IN CONST CHAR16         *FileName
    269   )
    270 {
    271   EFI_HII_DATABASE_PROTOCOL     *HiiDatabase;
    272   EFI_STATUS                    Status;
    273   VOID                          *MainBuffer;
    274   UINT64                        Temp;
    275   UINTN                         MainBufferSize;
    276   EFI_HII_HANDLE                HiiHandle;
    277   SHELL_FILE_HANDLE             FileHandle;
    278   CHAR16                        *TempDevPathString;
    279   EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;
    280   EFI_HII_PACKAGE_HEADER        *PackageHeader;
    281   EFI_DEVICE_PATH_PROTOCOL      *DevPath;
    282   UINTN                         HandleIndex;
    283 
    284   HiiDatabase       = NULL;
    285   MainBufferSize    = 0;
    286   MainBuffer        = NULL;
    287   FileHandle        = NULL;
    288 
    289   Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
    290   if (EFI_ERROR(Status)) {
    291     ShellPrintHiiEx(
    292       -1,
    293       -1,
    294       NULL,
    295       STRING_TOKEN(STR_GEN_FILE_OPEN_FAIL),
    296       gShellDriver1HiiHandle,
    297       L"drvcfg",
    298       FileName,
    299       Status);
    300     return (SHELL_DEVICE_ERROR);
    301   }
    302 
    303   //
    304   // Locate HII Database protocol
    305   //
    306   Status = gBS->LocateProtocol (
    307                   &gEfiHiiDatabaseProtocolGuid,
    308                   NULL,
    309                   (VOID **) &HiiDatabase
    310                   );
    311 
    312   if (EFI_ERROR(Status) || HiiDatabase == NULL) {
    313     ShellPrintHiiEx(
    314       -1,
    315       -1,
    316       NULL,
    317       STRING_TOKEN(STR_GEN_PROTOCOL_NF),
    318       gShellDriver1HiiHandle,
    319       L"drvcfg",
    320       L"EfiHiiDatabaseProtocol",
    321       &gEfiHiiDatabaseProtocolGuid);
    322     ShellCloseFile(&FileHandle);
    323     return (SHELL_NOT_FOUND);
    324   }
    325 
    326   Status = ShellGetFileSize(FileHandle, &Temp);
    327   MainBufferSize = (UINTN)Temp;
    328   if (EFI_ERROR(Status)) {
    329     ShellPrintHiiEx(
    330       -1,
    331       -1,
    332       NULL,
    333       STRING_TOKEN(STR_FILE_READ_FAIL),
    334       gShellDriver1HiiHandle,
    335       L"drvcfg",
    336       FileName);
    337 
    338     ShellCloseFile(&FileHandle);
    339     return (SHELL_DEVICE_ERROR);
    340   }
    341   MainBuffer = AllocateZeroPool((UINTN)MainBufferSize);
    342   if (EFI_ERROR(Status)) {
    343     ShellPrintHiiEx(
    344       -1,
    345       -1,
    346       NULL,
    347       STRING_TOKEN(STR_GEN_OUT_MEM),
    348       gShellDriver1HiiHandle, L"drvcfg");
    349     ShellCloseFile(&FileHandle);
    350     return (SHELL_DEVICE_ERROR);
    351   }
    352   Status = ShellReadFile(FileHandle, &MainBufferSize, MainBuffer);
    353   if (EFI_ERROR(Status)) {
    354     ShellPrintHiiEx(
    355       -1,
    356       -1,
    357       NULL,
    358       STRING_TOKEN(STR_FILE_READ_FAIL),
    359       gShellDriver1HiiHandle,
    360       L"drvcfg",
    361       FileName);
    362 
    363     ShellCloseFile(&FileHandle);
    364     SHELL_FREE_NON_NULL(MainBuffer);
    365     return (SHELL_DEVICE_ERROR);
    366   }
    367 
    368   ShellCloseFile(&FileHandle);
    369 
    370   if (Handle != NULL) {
    371     //
    372     // User override in place.  Just do it.
    373     //
    374     HiiHandle         = NULL;
    375     Status = ConvertHandleToHiiHandle(Handle, &HiiHandle, HiiDatabase);
    376     if (EFI_ERROR(Status)) {
    377       ShellPrintHiiEx(
    378         -1,
    379         -1,
    380         NULL,
    381         STRING_TOKEN(STR_GEN_HANDLE_NOT),
    382         gShellDriver1HiiHandle, L"drvcfg",
    383         ConvertHandleToHandleIndex(Handle),
    384         L"Device");
    385       ShellCloseFile(&FileHandle);
    386       return (SHELL_DEVICE_ERROR);
    387     }
    388     Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, MainBuffer);
    389     if (EFI_ERROR(Status)) {
    390       ShellPrintHiiEx(
    391         -1,
    392         -1,
    393         NULL,
    394         STRING_TOKEN(STR_GEN_UEFI_FUNC_WARN),
    395         gShellDriver1HiiHandle,
    396         L"drvcfg",
    397         L"HiiDatabase->UpdatePackageList",
    398         Status);
    399       return (SHELL_DEVICE_ERROR);
    400     }
    401   } else {
    402     //
    403     // we need to parse the buffer and try to match the device paths for each item to try to find it's device path.
    404     //
    405 
    406     for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)MainBuffer
    407       ;  PackageListHeader != NULL && ((CHAR8*)PackageListHeader) < (((CHAR8*)MainBuffer)+MainBufferSize)
    408       ;  PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)(((CHAR8*)(PackageListHeader)) + PackageListHeader->PackageLength )) {
    409         for (PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageListHeader))+sizeof(EFI_HII_PACKAGE_LIST_HEADER))
    410           ; PackageHeader != NULL && ((CHAR8*)PackageHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END
    411           ; PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageHeader))+PackageHeader->Length)) {
    412             if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {
    413               HiiHandle         = NULL;
    414               Status = FindHiiHandleViaDevPath((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), &HiiHandle, HiiDatabase);
    415               if (EFI_ERROR(Status)) {
    416                 //
    417                 // print out an error.
    418                 //
    419                 TempDevPathString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), TRUE, TRUE);
    420                 ShellPrintHiiEx(
    421                   -1,
    422                   -1,
    423                   NULL,
    424                   STRING_TOKEN(STR_DRVCFG_IN_FILE_NF),
    425                   gShellDriver1HiiHandle,
    426                   TempDevPathString);
    427                 SHELL_FREE_NON_NULL(TempDevPathString);
    428              } else {
    429                 Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, PackageListHeader);
    430                 if (EFI_ERROR(Status)) {
    431                   ShellPrintHiiEx(
    432                     -1,
    433                     -1,
    434                     NULL,
    435                     STRING_TOKEN(STR_GEN_UEFI_FUNC_WARN),
    436                     gShellDriver1HiiHandle,
    437                     L"drvcfg",
    438                     L"HiiDatabase->UpdatePackageList",
    439                     Status);
    440                   return (SHELL_DEVICE_ERROR);
    441                 } else {
    442                   DevPath = (EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER));
    443                   gBS->LocateDevicePath(&gEfiHiiConfigAccessProtocolGuid, &DevPath, &Handle);
    444                   HandleIndex = ConvertHandleToHandleIndex(Handle);
    445                   ShellPrintHiiEx(
    446                     -1,
    447                     -1,
    448                     NULL,
    449                     STRING_TOKEN(STR_DRVCFG_DONE_HII),
    450                     gShellDriver1HiiHandle,
    451                     HandleIndex);
    452                 }
    453               }
    454             }
    455         }
    456     }
    457   }
    458 
    459   SHELL_FREE_NON_NULL(MainBuffer);
    460 
    461 
    462   ShellPrintHiiEx(
    463     -1,
    464     -1,
    465     NULL,
    466     STRING_TOKEN(STR_DRVCFG_COMP),
    467     gShellDriver1HiiHandle);
    468   return (SHELL_SUCCESS);
    469 }
    470 
    471 /**
    472   Present a requested action to the user.
    473 
    474   @param[in] DriverImageHandle  The handle for the driver to configure.
    475   @param[in] ControllerHandle   The handle of the device being managed by the Driver specified.
    476   @param[in] ChildHandle        The handle of a child device of the specified device.
    477   @param[in] ActionRequired     The required HII action.
    478 
    479   @retval SHELL_INVALID_PARAMETER   A parameter has a invalid value.
    480 **/
    481 EFI_STATUS
    482 EFIAPI
    483 ShellCmdDriverConfigurationProcessActionRequired (
    484   EFI_HANDLE                                DriverImageHandle,
    485   EFI_HANDLE                                ControllerHandle,
    486   EFI_HANDLE                                ChildHandle,
    487   EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired
    488   )
    489 {
    490   EFI_HANDLE  ConnectControllerContextOverride[2];
    491 
    492   switch (ActionRequired) {
    493   case EfiDriverConfigurationActionNone:
    494     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);
    495     break;
    496 
    497   case EfiDriverConfigurationActionStopController:
    498     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_STOP), gShellDriver1HiiHandle);
    499     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"stop controller");
    500     ShellPromptForResponse(ShellPromptResponseTypeEnterContinue, NULL, NULL);
    501 
    502     gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle);
    503     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"stopped");
    504     break;
    505 
    506   case EfiDriverConfigurationActionRestartController:
    507     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"controller");
    508     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart controller");
    509     ShellPromptForResponse(ShellPromptResponseTypeEnterContinue, NULL, NULL);
    510 
    511     gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle);
    512     ConnectControllerContextOverride[0]  = DriverImageHandle;
    513     ConnectControllerContextOverride[1]  = NULL;
    514     gBS->ConnectController (ControllerHandle, ConnectControllerContextOverride, NULL, TRUE);
    515     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"restarted");
    516     break;
    517 
    518   case EfiDriverConfigurationActionRestartPlatform:
    519     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"platform");
    520     ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart platform");
    521     ShellPromptForResponse(ShellPromptResponseTypeEnterContinue, NULL, NULL);
    522 
    523     gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
    524     break;
    525 
    526   default:
    527     return (EFI_INVALID_PARAMETER);
    528   }
    529 
    530   return EFI_SUCCESS;
    531 }
    532 
    533 /**
    534   Do the configuration in an environment without HII.
    535 
    536   @param[in] Language           The language code.
    537   @param[in] ForceDefaults      TRUE to force defaults, FALSE otherwise.
    538   @param[in] DefaultType        If ForceDefaults is TRUE, specifies the default type.
    539   @param[in] AllChildren        TRUE to configure all children, FALSE otherwise.
    540   @param[in] ValidateOptions    TRUE to validate existing options, FALSE otherwise.
    541   @param[in] SetOptions         TRUE to set options, FALSE otherwise.
    542   @param[in] DriverImageHandle  The handle for the driver to configure.
    543   @param[in] DeviceHandle       The handle of the device being managed by the Driver specified.
    544   @param[in] ChildHandle        The handle of a child device of the specified device.
    545 
    546   @retval SHELL_NOT_FOUND           A specified handle could not be found.
    547   @retval SHELL_INVALID_PARAMETER   A parameter has a invalid value.
    548 **/
    549 SHELL_STATUS
    550 EFIAPI
    551 PreHiiDrvCfg (
    552   IN CONST CHAR8    *Language,
    553   IN BOOLEAN        ForceDefaults,
    554   IN UINT32         DefaultType,
    555   IN BOOLEAN        AllChildren,
    556   IN BOOLEAN        ValidateOptions,
    557   IN BOOLEAN        SetOptions,
    558   IN EFI_HANDLE     DriverImageHandle,
    559   IN EFI_HANDLE     DeviceHandle,
    560   IN EFI_HANDLE     ChildHandle
    561   )
    562 {
    563   EFI_STATUS                                Status;
    564   SHELL_STATUS                              ShellStatus;
    565   UINTN                                     OuterLoopCounter;
    566   CHAR8                                     *BestLanguage;
    567   UINTN                                     DriverImageHandleCount;
    568   EFI_HANDLE                                *DriverImageHandleBuffer;
    569   UINTN                                     HandleCount;
    570   EFI_HANDLE                                *HandleBuffer;
    571   UINTN                                     *HandleType;
    572   UINTN                                     LoopCounter;
    573   UINTN                                     ChildIndex;
    574   UINTN                                     ChildHandleCount;
    575   EFI_HANDLE                                *ChildHandleBuffer;
    576   UINTN                                     *ChildHandleType;
    577   EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired;
    578   EFI_DRIVER_CONFIGURATION_PROTOCOL         *DriverConfiguration;
    579   BOOLEAN                                   Iso639Language;
    580   UINTN                                     HandleIndex1;
    581   UINTN                                     HandleIndex2;
    582   UINTN                                     HandleIndex3;
    583 
    584   ShellStatus = SHELL_SUCCESS;
    585 
    586   if (ChildHandle == NULL && AllChildren) {
    587     SetOptions = FALSE;
    588   }
    589 
    590   if (ForceDefaults) {
    591     ShellPrintHiiEx(
    592       -1,
    593       -1,
    594       NULL,
    595       STRING_TOKEN (STR_DRVCFG_FORCE_D),
    596       gShellDriver1HiiHandle,
    597       DefaultType);
    598   } else if (ValidateOptions) {
    599     ShellPrintHiiEx(
    600       -1,
    601       -1,
    602       NULL,
    603       STRING_TOKEN (STR_DRVCFG_VALIDATE),
    604       gShellDriver1HiiHandle);
    605   } else if (SetOptions) {
    606     ShellPrintHiiEx(
    607       -1,
    608       -1,
    609       NULL,
    610       STRING_TOKEN (STR_DRVCFG_SET),
    611       gShellDriver1HiiHandle);
    612   }
    613 
    614   if (DriverImageHandle == 0) {
    615     DriverImageHandleBuffer = GetHandleListByProtocolList(CfgGuidList);
    616     if (DriverImageHandleBuffer == NULL) {
    617       ShellStatus = SHELL_NOT_FOUND;
    618       goto Done;
    619     }
    620     for (
    621       HandleBuffer = DriverImageHandleBuffer, DriverImageHandleCount = 0
    622       ; HandleBuffer != NULL && *HandleBuffer != NULL
    623       ; HandleBuffer++,DriverImageHandleCount++);
    624   } else {
    625     DriverImageHandleCount = 1;
    626     //
    627     // Allocate buffer to hold the image handle so as to
    628     // keep consistent with the above clause
    629     //
    630     DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE));
    631     ASSERT (DriverImageHandleBuffer);
    632     DriverImageHandleBuffer[0] = DriverImageHandle;
    633   }
    634 
    635   for (OuterLoopCounter = 0; OuterLoopCounter < DriverImageHandleCount; OuterLoopCounter++) {
    636     Iso639Language = FALSE;
    637     Status = gBS->OpenProtocol (
    638                   DriverImageHandleBuffer[OuterLoopCounter],
    639                   &gEfiDriverConfiguration2ProtocolGuid,
    640                   (VOID **) &DriverConfiguration,
    641                   NULL,
    642                   NULL,
    643                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    644                   );
    645     if (EFI_ERROR (Status)) {
    646       Iso639Language = TRUE;
    647       Status = gBS->OpenProtocol (
    648                     DriverImageHandleBuffer[OuterLoopCounter],
    649                     &gEfiDriverConfigurationProtocolGuid,
    650                     (VOID **) &DriverConfiguration,
    651                     NULL,
    652                     NULL,
    653                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    654                     );
    655     }
    656     if (EFI_ERROR (Status)) {
    657 //      ShellPrintHiiEx(
    658 //        -1,
    659 //        -1,
    660 //        NULL,
    661 //        STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),
    662 //        gShellDriver1HiiHandle,
    663 //        ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter])
    664 //        );
    665       ShellStatus = SHELL_UNSUPPORTED;
    666       continue;
    667     }
    668 
    669     BestLanguage = GetBestLanguage (
    670                           DriverConfiguration->SupportedLanguages,
    671                           Iso639Language,
    672                           Language!=NULL?Language:"",
    673                           DriverConfiguration->SupportedLanguages,
    674                           NULL
    675                           );
    676     if (BestLanguage == NULL) {
    677       ShellPrintHiiEx(
    678         -1,
    679         -1,
    680         NULL,
    681         STRING_TOKEN (STR_GEN_NO_VALUE),
    682         gShellDriver1HiiHandle,
    683         L"drvcfg",
    684         L"-l"
    685         );
    686       ShellStatus = SHELL_INVALID_PARAMETER;
    687       continue;
    688     }
    689 
    690     Status = ParseHandleDatabaseByRelationshipWithType (
    691               DriverImageHandleBuffer[OuterLoopCounter],
    692               NULL,
    693               &HandleCount,
    694               &HandleBuffer,
    695               &HandleType
    696               );
    697     if (EFI_ERROR (Status)) {
    698       continue;
    699     }
    700 
    701     if (SetOptions && DeviceHandle == NULL) {
    702 
    703       gST->ConOut->ClearScreen (gST->ConOut);
    704       Status = DriverConfiguration->SetOptions (
    705                                       DriverConfiguration,
    706                                       NULL,
    707                                       NULL,
    708                                       BestLanguage,
    709                                       &ActionRequired
    710                                       );
    711       gST->ConOut->ClearScreen (gST->ConOut);
    712 
    713       ShellPrintHiiEx(
    714         -1,
    715         -1,
    716         NULL,
    717         STRING_TOKEN (STR_DRVCFG_ALL_LANG),
    718         gShellDriver1HiiHandle,
    719         ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]),
    720         DriverConfiguration->SupportedLanguages
    721         );
    722       if (!EFI_ERROR (Status)) {
    723         ShellPrintHiiEx(
    724           -1,
    725           -1,
    726           NULL,
    727           STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
    728           gShellDriver1HiiHandle);
    729         for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {
    730           if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) == HR_CONTROLLER_HANDLE) {
    731             ShellCmdDriverConfigurationProcessActionRequired (
    732               DriverImageHandleBuffer[OuterLoopCounter],
    733               HandleBuffer[LoopCounter],
    734               NULL,
    735               ActionRequired
    736               );
    737           }
    738         }
    739       } else {
    740         ShellPrintHiiEx(
    741           -1,
    742           -1,
    743           NULL,
    744           STRING_TOKEN (STR_DRVCFG_NOT_SET),
    745           gShellDriver1HiiHandle,
    746           Status);
    747       }
    748       continue;
    749     }
    750 
    751     for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {
    752       if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) != HR_CONTROLLER_HANDLE) {
    753         continue;
    754       }
    755       if (DeviceHandle != NULL && DeviceHandle != HandleBuffer[LoopCounter]) {
    756         continue;
    757       }
    758       if (ChildHandle == NULL) {
    759         HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
    760         HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
    761         ShellPrintHiiEx(
    762           -1,
    763           -1,
    764           NULL,
    765           STRING_TOKEN (STR_DRVCFG_CTRL_LANG),
    766           gShellDriver1HiiHandle,
    767           HandleIndex1,
    768           HandleIndex2,
    769           DriverConfiguration->SupportedLanguages
    770           );
    771 
    772         if (ForceDefaults) {
    773           Status = DriverConfiguration->ForceDefaults (
    774                                           DriverConfiguration,
    775                                           HandleBuffer[LoopCounter],
    776                                           NULL,
    777                                           DefaultType,
    778                                           &ActionRequired
    779                                           );
    780 
    781           if (!EFI_ERROR (Status)) {
    782             ShellPrintHiiEx(
    783               -1,
    784               -1,
    785               NULL,
    786               STRING_TOKEN (STR_DRVCFG_DEF_FORCED),
    787               gShellDriver1HiiHandle);
    788             ShellCmdDriverConfigurationProcessActionRequired (
    789               DriverImageHandleBuffer[OuterLoopCounter],
    790               HandleBuffer[LoopCounter],
    791               NULL,
    792               ActionRequired
    793               );
    794           } else {
    795             ShellPrintHiiEx(
    796               -1,
    797               -1,
    798               NULL,
    799               STRING_TOKEN (STR_DRVCFG_FORCE_FAILED),
    800               gShellDriver1HiiHandle,
    801               Status);
    802            ShellStatus = SHELL_DEVICE_ERROR;
    803          }
    804         } else if (ValidateOptions) {
    805           Status = DriverConfiguration->OptionsValid (
    806                                           DriverConfiguration,
    807                                           HandleBuffer[LoopCounter],
    808                                           NULL
    809                                           );
    810 
    811           if (!EFI_ERROR (Status)) {
    812             ShellPrintHiiEx(
    813               -1,
    814               -1,
    815               NULL,
    816               STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID),
    817               gShellDriver1HiiHandle);
    818           } else {
    819             ShellPrintHiiEx(
    820               -1,
    821               -1,
    822               NULL,
    823               STRING_TOKEN (STR_DRVCFG_OPTIONS_INV),
    824               gShellDriver1HiiHandle,
    825               Status);
    826             ShellStatus = SHELL_DEVICE_ERROR;
    827           }
    828         } else if (SetOptions) {
    829           gST->ConOut->ClearScreen (gST->ConOut);
    830           Status = DriverConfiguration->SetOptions (
    831                                           DriverConfiguration,
    832                                           HandleBuffer[LoopCounter],
    833                                           NULL,
    834                                           BestLanguage,
    835                                           &ActionRequired
    836                                           );
    837           gST->ConOut->ClearScreen (gST->ConOut);
    838           HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
    839           HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
    840           ShellPrintHiiEx(
    841             -1,
    842             -1,
    843             NULL,
    844             STRING_TOKEN (STR_DRVCFG_CTRL_LANG),
    845             gShellDriver1HiiHandle,
    846             HandleIndex1,
    847             HandleIndex2,
    848             DriverConfiguration->SupportedLanguages
    849             );
    850           if (!EFI_ERROR (Status)) {
    851             ShellPrintHiiEx(
    852               -1,
    853               -1,
    854               NULL,
    855               STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
    856               gShellDriver1HiiHandle);
    857 
    858             ShellCmdDriverConfigurationProcessActionRequired (
    859               DriverImageHandleBuffer[OuterLoopCounter],
    860               HandleBuffer[LoopCounter],
    861               NULL,
    862               ActionRequired
    863               );
    864 
    865           } else {
    866             ShellPrintHiiEx(
    867               -1,
    868               -1,
    869               NULL,
    870               STRING_TOKEN (STR_DRVCFG_NOT_SET),
    871               gShellDriver1HiiHandle,
    872               Status);
    873             ShellStatus = SHELL_DEVICE_ERROR;
    874           }
    875         } else {
    876           Print (L"\n");
    877         }
    878       }
    879 
    880       if (ChildHandle == NULL && !AllChildren) {
    881         continue;
    882       }
    883 
    884       Status = ParseHandleDatabaseByRelationshipWithType (
    885                 DriverImageHandleBuffer[OuterLoopCounter],
    886                 HandleBuffer[LoopCounter],
    887                 &ChildHandleCount,
    888                 &ChildHandleBuffer,
    889                 &ChildHandleType
    890                 );
    891       if (EFI_ERROR (Status)) {
    892         continue;
    893       }
    894 
    895       for (ChildIndex = 0; ChildIndex < ChildHandleCount; ChildIndex++) {
    896 
    897         if ((ChildHandleType[ChildIndex] & HR_CHILD_HANDLE) != HR_CHILD_HANDLE) {
    898           continue;
    899         }
    900 
    901         if (ChildHandle != NULL && ChildHandle != ChildHandleBuffer[ChildIndex]) {
    902           continue;
    903         }
    904 
    905         HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
    906         HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
    907         HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]);
    908         ShellPrintHiiEx(
    909           -1,
    910           -1,
    911           NULL,
    912           STRING_TOKEN (STR_DRVCFG_CHILD_LANG),
    913           gShellDriver1HiiHandle,
    914           HandleIndex1,
    915           HandleIndex2,
    916           HandleIndex3,
    917           DriverConfiguration->SupportedLanguages);
    918 
    919         if (ForceDefaults) {
    920           Status = DriverConfiguration->ForceDefaults (
    921                                           DriverConfiguration,
    922                                           HandleBuffer[LoopCounter],
    923                                           ChildHandleBuffer[ChildIndex],
    924                                           DefaultType,
    925                                           &ActionRequired
    926                                           );
    927 
    928           if (!EFI_ERROR (Status)) {
    929             ShellPrintHiiEx(
    930               -1,
    931               -1,
    932               NULL,
    933               STRING_TOKEN (STR_DRVCFG_DEF_FORCED),
    934               gShellDriver1HiiHandle);
    935 
    936             ShellCmdDriverConfigurationProcessActionRequired (
    937               DriverImageHandleBuffer[OuterLoopCounter],
    938               HandleBuffer[LoopCounter],
    939               ChildHandleBuffer[ChildIndex],
    940               ActionRequired
    941               );
    942 
    943           } else {
    944             ShellPrintHiiEx(
    945               -1,
    946               -1,
    947               NULL,
    948               STRING_TOKEN (STR_DRVCFG_FORCE_FAILED),
    949               gShellDriver1HiiHandle,
    950               Status);
    951             ShellStatus = SHELL_DEVICE_ERROR;
    952           }
    953         } else if (ValidateOptions) {
    954           Status = DriverConfiguration->OptionsValid (
    955                                           DriverConfiguration,
    956                                           HandleBuffer[LoopCounter],
    957                                           ChildHandleBuffer[ChildIndex]
    958                                           );
    959 
    960           if (!EFI_ERROR (Status)) {
    961             ShellPrintHiiEx(
    962               -1,
    963               -1,
    964               NULL,
    965               STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID),
    966               gShellDriver1HiiHandle);
    967           } else {
    968             ShellPrintHiiEx(
    969               -1,
    970               -1,
    971               NULL,
    972               STRING_TOKEN (STR_DRVCFG_OPTIONS_INV),
    973               gShellDriver1HiiHandle,
    974               Status);
    975             ShellStatus = SHELL_DEVICE_ERROR;
    976           }
    977         } else if (SetOptions) {
    978           gST->ConOut->ClearScreen (gST->ConOut);
    979           Status = DriverConfiguration->SetOptions (
    980                                           DriverConfiguration,
    981                                           HandleBuffer[LoopCounter],
    982                                           ChildHandleBuffer[ChildIndex],
    983                                           BestLanguage,
    984                                           &ActionRequired
    985                                           );
    986           gST->ConOut->ClearScreen (gST->ConOut);
    987           HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
    988           HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
    989           HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]);
    990           ShellPrintHiiEx(
    991             -1,
    992             -1,
    993             NULL,
    994             STRING_TOKEN (STR_DRVCFG_CHILD_LANG),
    995             gShellDriver1HiiHandle,
    996             HandleIndex1,
    997             HandleIndex2,
    998             HandleIndex3,
    999             DriverConfiguration->SupportedLanguages
   1000             );
   1001           if (!EFI_ERROR (Status)) {
   1002             ShellPrintHiiEx(
   1003               -1,
   1004               -1,
   1005               NULL,
   1006               STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
   1007               gShellDriver1HiiHandle);
   1008 
   1009             ShellCmdDriverConfigurationProcessActionRequired (
   1010               DriverImageHandleBuffer[OuterLoopCounter],
   1011               HandleBuffer[LoopCounter],
   1012               ChildHandleBuffer[ChildIndex],
   1013               ActionRequired
   1014               );
   1015 
   1016           } else {
   1017             ShellPrintHiiEx(
   1018               -1,
   1019               -1,
   1020               NULL,
   1021               STRING_TOKEN (STR_DRVCFG_NOT_SET),
   1022               gShellDriver1HiiHandle,
   1023               Status);
   1024             ShellStatus = SHELL_DEVICE_ERROR;
   1025           }
   1026         } else {
   1027           Print (L"\n");
   1028         }
   1029       }
   1030 
   1031       FreePool (ChildHandleBuffer);
   1032       FreePool (ChildHandleType);
   1033     }
   1034 
   1035     FreePool (BestLanguage);
   1036     FreePool (HandleBuffer);
   1037     FreePool (HandleType);
   1038   }
   1039 
   1040   if (DriverImageHandle != NULL && DriverImageHandleCount != 0) {
   1041     FreePool (DriverImageHandleBuffer);
   1042   }
   1043 
   1044 Done:
   1045   return ShellStatus;
   1046 }
   1047 
   1048 /**
   1049   Function to print out configuration information on all configurable handles.
   1050 
   1051   @param[in] ChildrenToo    TRUE to tewst for children.
   1052   @param[in] Language       ASCII string for language code.
   1053   @param[in] UseHii         TRUE to check for Hii and DPC, FALSE for DCP only.
   1054 
   1055   @retval SHELL_SUCCESS     The operation was successful.
   1056 **/
   1057 SHELL_STATUS
   1058 EFIAPI
   1059 PrintConfigInfoOnAll(
   1060   IN CONST BOOLEAN ChildrenToo,
   1061   IN CONST CHAR8   *Language,
   1062   IN CONST BOOLEAN UseHii
   1063   )
   1064 {
   1065   EFI_HANDLE        *HandleList;
   1066   EFI_HANDLE        *CurrentHandle;
   1067   BOOLEAN           Found;
   1068   UINTN             Index2;
   1069 
   1070 
   1071   Found             = FALSE;
   1072   HandleList        = NULL;
   1073   CurrentHandle     = NULL;
   1074 
   1075   if (UseHii) {
   1076     //
   1077     // HII method
   1078     //
   1079     HandleList = GetHandleListByProtocol(&gEfiHiiConfigAccessProtocolGuid);
   1080     for (CurrentHandle = HandleList ; CurrentHandle != NULL && *CurrentHandle != NULL; CurrentHandle++){
   1081       Found = TRUE;
   1082       Index2 = *CurrentHandle == NULL ? 0 : ConvertHandleToHandleIndex(*CurrentHandle);
   1083       ShellPrintHiiEx(
   1084         -1,
   1085         -1,
   1086         NULL,
   1087         STRING_TOKEN (STR_DRVCFG_LINE_HII),
   1088         gShellDriver1HiiHandle,
   1089         Index2
   1090         );
   1091     }
   1092     SHELL_FREE_NON_NULL(HandleList);
   1093   }
   1094 
   1095   if (PreHiiDrvCfg (
   1096     Language,
   1097     FALSE,
   1098     0,
   1099     ChildrenToo,
   1100     FALSE,
   1101     FALSE,
   1102     0,
   1103     0,
   1104     0) == SHELL_SUCCESS) {
   1105       Found = TRUE;
   1106   }
   1107 
   1108   if (!Found) {
   1109     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE_FOUND), gShellDriver1HiiHandle);
   1110     return (SHELL_SUCCESS);
   1111   }
   1112 
   1113   return (SHELL_SUCCESS);
   1114 }
   1115 
   1116 STATIC CONST SHELL_PARAM_ITEM ParamListHii[] = {
   1117   {L"-s", TypeFlag},
   1118   {L"-l", TypeValue},
   1119   {L"-f", TypeValue},
   1120   {L"-o", TypeValue},
   1121   {L"-i", TypeValue},
   1122   {NULL, TypeMax}
   1123   };
   1124 STATIC CONST SHELL_PARAM_ITEM ParamListPreHii[] = {
   1125   {L"-c", TypeFlag},
   1126   {L"-s", TypeFlag},
   1127   {L"-v", TypeFlag},
   1128   {L"-l", TypeValue},
   1129   {L"-f", TypeValue},
   1130   {NULL, TypeMax}
   1131   };
   1132 
   1133 /**
   1134   Function for 'drvcfg' command.
   1135 
   1136   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
   1137   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
   1138 **/
   1139 SHELL_STATUS
   1140 EFIAPI
   1141 ShellCommandRunDrvCfg (
   1142   IN EFI_HANDLE        ImageHandle,
   1143   IN EFI_SYSTEM_TABLE  *SystemTable
   1144   )
   1145 {
   1146   EFI_STATUS          Status;
   1147   LIST_ENTRY          *Package;
   1148   CHAR16              *ProblemParam;
   1149   SHELL_STATUS        ShellStatus;
   1150   CHAR8               *Language;
   1151   CONST CHAR16        *Lang;
   1152   CONST CHAR16        *HandleIndex1;
   1153   CONST CHAR16        *HandleIndex2;
   1154   CONST CHAR16        *HandleIndex3;
   1155   CONST CHAR16        *ForceTypeString;
   1156   BOOLEAN             Force;
   1157   BOOLEAN             Set;
   1158   BOOLEAN             Validate;
   1159   BOOLEAN             InFromFile;
   1160   BOOLEAN             OutToFile;
   1161   BOOLEAN             AllChildren;
   1162   BOOLEAN             UseHii;
   1163   UINT32              ForceType;
   1164   UINT64              Intermediate;
   1165   EFI_HANDLE          Handle1;
   1166   EFI_HANDLE          Handle2;
   1167   EFI_HANDLE          Handle3;
   1168   CONST CHAR16        *FileName;
   1169 
   1170   ShellStatus         = SHELL_SUCCESS;
   1171   Status              = EFI_SUCCESS;
   1172   Language            = NULL;
   1173   UseHii              = TRUE;
   1174   ProblemParam        = NULL;
   1175 
   1176   //
   1177   // initialize the shell lib (we must be in non-auto-init...)
   1178   //
   1179   Status = ShellInitialize();
   1180   ASSERT_EFI_ERROR(Status);
   1181 
   1182   Status = CommandInit();
   1183   ASSERT_EFI_ERROR(Status);
   1184 
   1185   //
   1186   // parse the command line
   1187   //
   1188   Status = ShellCommandLineParse (ParamListHii, &Package, &ProblemParam, TRUE);
   1189   if (EFI_ERROR(Status) || ShellCommandLineGetCount(Package) > 2) {
   1190     UseHii = FALSE;
   1191     if (Package != NULL) {
   1192       ShellCommandLineFreeVarList (Package);
   1193     }
   1194     SHELL_FREE_NON_NULL(ProblemParam);
   1195     Status = ShellCommandLineParse (ParamListPreHii, &Package, &ProblemParam, TRUE);
   1196     if (EFI_ERROR(Status)) {
   1197       if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
   1198         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drvcfg", ProblemParam);
   1199         FreePool(ProblemParam);
   1200         ShellStatus = SHELL_INVALID_PARAMETER;
   1201         goto Done;
   1202       } else {
   1203         ASSERT(FALSE);
   1204       }
   1205     }
   1206   }
   1207   if (ShellStatus == SHELL_SUCCESS) {
   1208     Lang = ShellCommandLineGetValue(Package, L"-l");
   1209     if (Lang != NULL) {
   1210       Language = AllocateZeroPool(StrSize(Lang));
   1211       AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
   1212     } else if (ShellCommandLineGetFlag(Package, L"-l")){
   1213       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg",  L"-l");
   1214       ShellStatus = SHELL_INVALID_PARAMETER;
   1215       goto Done;
   1216     }
   1217     Set                 = ShellCommandLineGetFlag (Package, L"-s");
   1218     Validate            = ShellCommandLineGetFlag (Package, L"-v");
   1219     InFromFile          = ShellCommandLineGetFlag (Package, L"-i");
   1220     OutToFile           = ShellCommandLineGetFlag (Package, L"-o");
   1221     AllChildren         = ShellCommandLineGetFlag (Package, L"-c");
   1222     Force               = ShellCommandLineGetFlag (Package, L"-f");
   1223     ForceTypeString     = ShellCommandLineGetValue(Package, L"-f");
   1224 
   1225     if (OutToFile) {
   1226       FileName = ShellCommandLineGetValue(Package, L"-o");
   1227     } else if (InFromFile) {
   1228       FileName = ShellCommandLineGetValue(Package, L"-i");
   1229     } else {
   1230       FileName = NULL;
   1231     }
   1232 
   1233     if (InFromFile && EFI_ERROR(ShellFileExists(FileName))) {
   1234       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName);
   1235       ShellStatus = SHELL_INVALID_PARAMETER;
   1236       goto Done;
   1237     }
   1238     if (OutToFile && !EFI_ERROR(ShellFileExists(FileName))) {
   1239       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_EXIST), gShellDriver1HiiHandle, L"drvcfg", FileName);
   1240       ShellStatus = SHELL_INVALID_PARAMETER;
   1241       goto Done;
   1242     }
   1243     if (Force && ForceTypeString == NULL) {
   1244       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-f");
   1245       ShellStatus = SHELL_INVALID_PARAMETER;
   1246       goto Done;
   1247     }
   1248     if (Force) {
   1249       Status = ShellConvertStringToUint64(ForceTypeString, &Intermediate, FALSE, FALSE);
   1250       if (EFI_ERROR(Status)) {
   1251         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDriver1HiiHandle, L"drvcfg", ForceTypeString, L"-f");
   1252         ShellStatus = SHELL_INVALID_PARAMETER;
   1253         goto Done;
   1254       }
   1255       ForceType = (UINT32)Intermediate;
   1256     } else {
   1257       ForceType = 0;
   1258     }
   1259     HandleIndex1        = ShellCommandLineGetRawValue(Package, 1);
   1260     Handle1             = NULL;
   1261     if (HandleIndex1 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex1, &Intermediate, TRUE, FALSE))) {
   1262       Handle1 = ConvertHandleIndexToHandle((UINTN)Intermediate);
   1263       if (Handle1 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
   1264         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex1);
   1265         ShellStatus = SHELL_INVALID_PARAMETER;
   1266         goto Done;
   1267       }
   1268     }
   1269     HandleIndex2        = ShellCommandLineGetRawValue(Package, 2);
   1270     Handle2             = NULL;
   1271     if (HandleIndex2 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex2, &Intermediate, TRUE, FALSE))) {
   1272       Handle2 = ConvertHandleIndexToHandle((UINTN)Intermediate);
   1273       if (Handle2 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
   1274         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex2);
   1275         ShellStatus = SHELL_INVALID_PARAMETER;
   1276         goto Done;
   1277       }
   1278     }
   1279     HandleIndex3        = ShellCommandLineGetRawValue(Package, 3);
   1280     Handle3             = NULL;
   1281     if (HandleIndex3 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex3, &Intermediate, TRUE, FALSE))) {
   1282       Handle3 = ConvertHandleIndexToHandle((UINTN)Intermediate);
   1283       if (Handle3 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
   1284         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex3);
   1285         ShellStatus = SHELL_INVALID_PARAMETER;
   1286         goto Done;
   1287       }
   1288     }
   1289 
   1290     if ((InFromFile || OutToFile) && (FileName == NULL)) {
   1291       if (FileName == NULL) {
   1292         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg",  InFromFile?L"-i":L"-o");
   1293       } else {
   1294         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_REQ), gShellDriver1HiiHandle, L"drvcfg");
   1295       }
   1296       ShellStatus = SHELL_INVALID_PARAMETER;
   1297       goto Done;
   1298     }
   1299     if (!UseHii && (InFromFile || OutToFile)) {
   1300       if (InFromFile) {
   1301         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-i");
   1302         ShellStatus = SHELL_INVALID_PARAMETER;
   1303         goto Done;
   1304       }
   1305       if (OutToFile) {
   1306         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-o");
   1307         ShellStatus = SHELL_INVALID_PARAMETER;
   1308         goto Done;
   1309       }
   1310     }
   1311     if (Validate && Force) {
   1312       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-f");
   1313       ShellStatus = SHELL_INVALID_PARAMETER;
   1314       goto Done;
   1315     }
   1316     if (Validate && Set) {
   1317       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-s");
   1318       ShellStatus = SHELL_INVALID_PARAMETER;
   1319       goto Done;
   1320     }
   1321     if (Set && Force) {
   1322       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-s", L"-f");
   1323       ShellStatus = SHELL_INVALID_PARAMETER;
   1324       goto Done;
   1325     }
   1326     if (OutToFile && InFromFile) {
   1327       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-i", L"-o");
   1328       ShellStatus = SHELL_INVALID_PARAMETER;
   1329       goto Done;
   1330     }
   1331 
   1332     //
   1333     // We do HII first.
   1334     //
   1335     if (UseHii) {
   1336       if (Handle1 != NULL && EFI_ERROR(gBS->OpenProtocol(Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
   1337         //
   1338         // no HII on this handle.
   1339         //
   1340         ShellStatus = SHELL_UNSUPPORTED;
   1341       } else if (Validate) {
   1342       } else if (Force) {
   1343       } else if (Set) {
   1344       } else if (InFromFile) {
   1345         ShellStatus = ConfigFromFile(Handle1, FileName);
   1346         if (Handle1 != NULL && ShellStatus == SHELL_SUCCESS) {
   1347           goto Done;
   1348         }
   1349       } else if (OutToFile) {
   1350         ShellStatus = ConfigToFile(Handle1, FileName);
   1351         if (Handle1 != NULL && ShellStatus == SHELL_SUCCESS) {
   1352           goto Done;
   1353         }
   1354       } else if (HandleIndex1 == NULL) {
   1355         //
   1356         // display all that are configurable
   1357         //
   1358         ShellStatus = PrintConfigInfoOnAll(AllChildren, Language, UseHii);
   1359         goto Done;
   1360       } else {
   1361         if (!EFI_ERROR(gBS->OpenProtocol(Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
   1362           ShellPrintHiiEx(
   1363             -1,
   1364             -1,
   1365             NULL,
   1366             STRING_TOKEN (STR_DRVCFG_LINE_HII),
   1367             gShellDriver1HiiHandle,
   1368             ConvertHandleToHandleIndex(Handle1)
   1369             );
   1370           goto Done;
   1371         }
   1372       }
   1373     }
   1374 
   1375     //
   1376     // We allways need to do this one since it does both by default.
   1377     //
   1378     if (!InFromFile && !OutToFile) {
   1379       ShellStatus = PreHiiDrvCfg (
   1380         Language,
   1381         Force,
   1382         ForceType,
   1383         AllChildren,
   1384         Validate,
   1385         Set,
   1386         Handle1,
   1387         Handle2,
   1388         Handle3);
   1389     }
   1390 
   1391     if (ShellStatus == SHELL_UNSUPPORTED) {
   1392       ShellPrintHiiEx(
   1393         -1,
   1394         -1,
   1395         NULL,
   1396         STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),
   1397         gShellDriver1HiiHandle,
   1398         ConvertHandleToHandleIndex(Handle1)
   1399         );
   1400     }
   1401   }
   1402 
   1403 Done:
   1404   ShellCommandLineFreeVarList (Package);
   1405   SHELL_FREE_NON_NULL(Language);
   1406   return (ShellStatus);
   1407 }
   1408