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