/** @file
  Main file for DrvCfg shell Driver1 function.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UefiShellDriver1CommandsLib.h"
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/HiiDatabase.h>

STATIC CONST EFI_GUID  *CfgGuidList[] = { &gEfiDriverConfigurationProtocolGuid, &gEfiDriverConfiguration2ProtocolGuid, NULL };

/**
  Find the EFI_HII_HANDLE by device path.

  @param[in] DevPath1     The Device Path to match.
  @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.
  @param[in] HiiDb        The Hii database protocol

  @retval EFI_SUCCESS     The operation was successful.
  @retval EFI_NOT_FOUND   There was no EFI_HII_HANDLE found for that deviec path.
**/
EFI_STATUS
FindHiiHandleViaDevPath (
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevPath1,
  OUT EFI_HII_HANDLE                 *HiiHandle,
  IN EFI_HII_DATABASE_PROTOCOL       *HiiDb
  )
{
  EFI_HII_HANDLE               *HandleBuffer;
  UINTN                        HandleBufferSize;
  VOID                         *MainBuffer;
  UINTN                        MainBufferSize;
  EFI_HII_PACKAGE_LIST_HEADER  *PackageListHeader;
  EFI_HII_PACKAGE_HEADER       *PackageHeader;
  UINTN                        LoopVariable;
  EFI_DEVICE_PATH_PROTOCOL     *DevPath2;
  EFI_STATUS                   Status;

  ASSERT (DevPath1 != NULL);
  ASSERT (HiiHandle != NULL);
  ASSERT (*HiiHandle == NULL);
  ASSERT (HiiDb != NULL);

  HandleBufferSize = 0;
  HandleBuffer     = NULL;
  Status           = HiiDb->ListPackageLists (HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    HandleBuffer = AllocateZeroPool (HandleBufferSize);
    if (HandleBuffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
    } else {
      Status = HiiDb->ListPackageLists (HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);
    }
  }

  if (EFI_ERROR (Status)) {
    SHELL_FREE_NON_NULL (HandleBuffer);
    return (Status);
  }

  if (HandleBuffer == NULL) {
    return EFI_NOT_FOUND;
  }

  for (LoopVariable = 0; LoopVariable < (HandleBufferSize/sizeof (HandleBuffer[0])) && *HiiHandle == NULL; LoopVariable++) {
    MainBufferSize = 0;
    MainBuffer     = NULL;
    Status         = HiiDb->ExportPackageLists (HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);
    if (Status == EFI_BUFFER_TOO_SMALL) {
      MainBuffer = AllocateZeroPool (MainBufferSize);
      if (MainBuffer != NULL) {
        Status = HiiDb->ExportPackageLists (HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);
      }
    }

    if (EFI_ERROR (Status)) {
      continue;
    }

    //
    // Enumerate through the block of returned memory.
    // This should actually be a small block, but we need to be sure.
    //
    for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)MainBuffer
         ; PackageListHeader != NULL && ((CHAR8 *)PackageListHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && *HiiHandle == NULL
         ; PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)(((CHAR8 *)(PackageListHeader)) + PackageListHeader->PackageLength))
    {
      for (PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageListHeader))+sizeof (EFI_HII_PACKAGE_LIST_HEADER))
           ; PackageHeader != NULL && ((CHAR8 *)PackageHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END && *HiiHandle == NULL
           ; PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageHeader))+PackageHeader->Length))
      {
        if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {
          DevPath2 = (EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER));
          if (DevicePathCompare (&DevPath1, &DevPath2) == 0) {
            *HiiHandle = HandleBuffer[LoopVariable];
            break;
          }
        }
      }
    }

    SHELL_FREE_NON_NULL (MainBuffer);
  }

  SHELL_FREE_NON_NULL (HandleBuffer);

  if (*HiiHandle == NULL) {
    return (EFI_NOT_FOUND);
  }

  return (EFI_SUCCESS);
}

/**
  Convert a EFI_HANDLE to a EFI_HII_HANDLE.

  @param[in] Handle       The EFI_HANDLE to convert.
  @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.
  @param[in] HiiDb        The Hii database protocol

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
ConvertHandleToHiiHandle (
  IN CONST EFI_HANDLE           Handle,
  OUT EFI_HII_HANDLE            *HiiHandle,
  IN EFI_HII_DATABASE_PROTOCOL  *HiiDb
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevPath1;

  if ((HiiHandle == NULL) || (HiiDb == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  *HiiHandle = NULL;

  if (Handle == NULL) {
    return (EFI_SUCCESS);
  }

  DevPath1 = NULL;
  Status   = gBS->OpenProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPath1, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (EFI_ERROR (Status) || (DevPath1 == NULL)) {
    return (EFI_NOT_FOUND);
  }

  return (FindHiiHandleViaDevPath (DevPath1, HiiHandle, HiiDb));
}

/**
  Function to print out all HII configuration information to a file.

  @param[in] Handle           The handle to get info on.  NULL to do all handles.
  @param[in] FileName         The filename to rwite the info to.
**/
SHELL_STATUS
ConfigToFile (
  IN CONST EFI_HANDLE  Handle,
  IN CONST CHAR16      *FileName
  )
{
  EFI_HII_DATABASE_PROTOCOL  *HiiDatabase;
  EFI_STATUS                 Status;
  VOID                       *MainBuffer;
  UINTN                      MainBufferSize;
  EFI_HII_HANDLE             HiiHandle;
  SHELL_FILE_HANDLE          FileHandle;

  HiiDatabase    = NULL;
  MainBufferSize = 0;
  MainBuffer     = NULL;
  FileHandle     = NULL;

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
      gShellDriver1HiiHandle,
      L"drvcfg",
      FileName,
      Status
      );
    return (SHELL_DEVICE_ERROR);
  }

  //
  // Locate HII Database protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **)&HiiDatabase
                  );

  if (EFI_ERROR (Status) || (HiiDatabase == NULL)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_GEN_PROTOCOL_NF),
      gShellDriver1HiiHandle,
      L"drvcfg",
      L"EfiHiiDatabaseProtocol",
      &gEfiHiiDatabaseProtocolGuid
      );
    ShellCloseFile (&FileHandle);
    return (SHELL_NOT_FOUND);
  }

  HiiHandle = NULL;
  Status    = ConvertHandleToHiiHandle (Handle, &HiiHandle, HiiDatabase);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_GEN_HANDLE_NOT),
      gShellDriver1HiiHandle,
      L"drvcfg",
      ConvertHandleToHandleIndex (Handle),
      L"Device"
      );
    ShellCloseFile (&FileHandle);
    return (SHELL_DEVICE_ERROR);
  }

  Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    MainBuffer = AllocateZeroPool (MainBufferSize);
    if (MainBuffer == NULL) {
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_GEN_OUT_MEM),
        gShellDriver1HiiHandle,
        L"drvcfg"
        );
      ShellCloseFile (&FileHandle);
      return (SHELL_OUT_OF_RESOURCES);
    }

    Status = HiiDatabase->ExportPackageLists (HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);
    if (EFI_ERROR (Status)) {
      SHELL_FREE_NON_NULL (MainBuffer);
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_GEN_OUT_MEM),
        gShellDriver1HiiHandle,
        L"drvcfg"
        );
      ShellCloseFile (&FileHandle);
      return (SHELL_DEVICE_ERROR);
    }
  }

  Status = ShellWriteFile (FileHandle, &MainBufferSize, MainBuffer);

  ShellCloseFile (&FileHandle);
  SHELL_FREE_NON_NULL (MainBuffer);

  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_FILE_WRITE_FAIL),
      gShellDriver1HiiHandle,
      L"drvcfg",
      FileName
      );
    return (SHELL_DEVICE_ERROR);
  }

  ShellPrintHiiDefaultEx (
    STRING_TOKEN (STR_DRVCFG_COMP),
    gShellDriver1HiiHandle
    );

  return (SHELL_SUCCESS);
}

/** Parse the config contained in the input Buffer.

  @param[in] Handle           The handle to get info for.
  @param[in] MainBuffer       Main Buffer, containing the list of package list.
  @param[in] MainBufferSize   Main Buffer Size.
  @param[in] HiiDatabase      HII Database.
**/
STATIC
SHELL_STATUS
ParseBufferConfig (
  IN  EFI_HANDLE                 Handle,
  IN  VOID                       *MainBuffer,
  IN  UINTN                      MainBufferSize,
  IN  EFI_HII_DATABASE_PROTOCOL  *HiiDatabase
  )
{
  CHAR16                       *TempDevPathString;
  EFI_DEVICE_PATH_PROTOCOL     *DevPath;
  EFI_HII_HANDLE               HiiHandle;
  EFI_HII_PACKAGE_LIST_HEADER  *PackageListHeader;
  UINTN                        HandleIndex;
  EFI_STATUS                   Status;
  EFI_HII_PACKAGE_HEADER       *PackageHeader;

  //
  // we need to parse the buffer and try to match the device paths for each item to try to find it's device path.
  //

  for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)MainBuffer
       ; PackageListHeader != NULL && ((CHAR8 *)PackageListHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize)
       ; PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)(((CHAR8 *)(PackageListHeader)) + PackageListHeader->PackageLength))
  {
    for (PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageListHeader))+sizeof (EFI_HII_PACKAGE_LIST_HEADER))
         ; PackageHeader != NULL && ((CHAR8 *)PackageHeader) < (((CHAR8 *)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END
         ; PackageHeader = (EFI_HII_PACKAGE_HEADER *)(((CHAR8 *)(PackageHeader))+PackageHeader->Length))
    {
      if (PackageHeader->Type != EFI_HII_PACKAGE_DEVICE_PATH) {
        continue;
      }

      HiiHandle = NULL;
      Status    = FindHiiHandleViaDevPath ((EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER)), &HiiHandle, HiiDatabase);
      if (EFI_ERROR (Status)) {
        //
        // print out an error.
        //
        TempDevPathString = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER)), TRUE, TRUE);
        if (TempDevPathString == NULL) {
          ShellPrintHiiDefaultEx (
            STRING_TOKEN (STR_GEN_OUT_MEM),
            gShellDriver1HiiHandle,
            L"drvcfg"
            );

          return SHELL_OUT_OF_RESOURCES;
        }

        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_DRVCFG_IN_FILE_NF),
          gShellDriver1HiiHandle,
          TempDevPathString
          );
        SHELL_FREE_NON_NULL (TempDevPathString);
      } else {
        Status = HiiDatabase->UpdatePackageList (HiiDatabase, HiiHandle, PackageListHeader);
        if (EFI_ERROR (Status)) {
          ShellPrintHiiDefaultEx (
            STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN),
            gShellDriver1HiiHandle,
            L"drvcfg",
            L"HiiDatabase->UpdatePackageList",
            Status
            );

          return SHELL_DEVICE_ERROR;
        }

        DevPath = (EFI_DEVICE_PATH_PROTOCOL *)(((CHAR8 *)PackageHeader) + sizeof (EFI_HII_PACKAGE_HEADER));
        gBS->LocateDevicePath (&gEfiHiiConfigAccessProtocolGuid, &DevPath, &Handle);
        HandleIndex = ConvertHandleToHandleIndex (Handle);
        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_DRVCFG_DONE_HII),
          gShellDriver1HiiHandle,
          HandleIndex
          );
      }
    }
  }

  return SHELL_SUCCESS;
}

/**
  Function to read in HII configuration information from a file.

  @param[in] Handle           The handle to get info for.
  @param[in] FileName         The filename to read the info from.
**/
SHELL_STATUS
ConfigFromFile (
  IN       EFI_HANDLE  Handle,
  IN CONST CHAR16      *FileName
  )
{
  EFI_HII_DATABASE_PROTOCOL  *HiiDatabase;
  EFI_STATUS                 Status;
  VOID                       *MainBuffer;
  UINT64                     Temp;
  UINTN                      MainBufferSize;
  EFI_HII_HANDLE             HiiHandle;
  SHELL_FILE_HANDLE          FileHandle;
  SHELL_STATUS               ShellStatus;

  HiiDatabase    = NULL;
  MainBufferSize = 0;
  MainBuffer     = NULL;
  FileHandle     = NULL;
  ShellStatus    = SHELL_SUCCESS;

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
      gShellDriver1HiiHandle,
      L"drvcfg",
      FileName,
      Status
      );

    ShellStatus = SHELL_DEVICE_ERROR;
    goto Done;
  }

  //
  // Locate HII Database protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **)&HiiDatabase
                  );

  if (EFI_ERROR (Status) || (HiiDatabase == NULL)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_GEN_PROTOCOL_NF),
      gShellDriver1HiiHandle,
      L"drvcfg",
      L"EfiHiiDatabaseProtocol",
      &gEfiHiiDatabaseProtocolGuid
      );

    ShellStatus = SHELL_NOT_FOUND;
    goto Done;
  }

  Status         = ShellGetFileSize (FileHandle, &Temp);
  MainBufferSize = (UINTN)Temp;
  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_FILE_READ_FAIL),
      gShellDriver1HiiHandle,
      L"drvcfg",
      FileName
      );

    ShellStatus = SHELL_DEVICE_ERROR;
    goto Done;
  }

  MainBuffer = AllocateZeroPool ((UINTN)MainBufferSize);
  if (MainBuffer == NULL) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_GEN_OUT_MEM),
      gShellDriver1HiiHandle,
      L"drvcfg"
      );

    ShellStatus = SHELL_OUT_OF_RESOURCES;
    goto Done;
  }

  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_GEN_OUT_MEM),
      gShellDriver1HiiHandle,
      L"drvcfg"
      );

    ShellStatus = SHELL_DEVICE_ERROR;
    goto Done;
  }

  Status = ShellReadFile (FileHandle, &MainBufferSize, MainBuffer);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_FILE_READ_FAIL),
      gShellDriver1HiiHandle,
      L"drvcfg",
      FileName
      );

    ShellStatus = SHELL_DEVICE_ERROR;
    goto Done;
  }

  ShellCloseFile (&FileHandle);
  FileHandle = NULL;

  if (Handle != NULL) {
    //
    // User override in place.  Just do it.
    //
    HiiHandle = NULL;
    Status    = ConvertHandleToHiiHandle (Handle, &HiiHandle, HiiDatabase);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_GEN_HANDLE_NOT),
        gShellDriver1HiiHandle,
        L"drvcfg",
        ConvertHandleToHandleIndex (Handle),
        L"Device"
        );

      ShellStatus = SHELL_DEVICE_ERROR;
      goto Done;
    }

    Status = HiiDatabase->UpdatePackageList (HiiDatabase, HiiHandle, MainBuffer);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN),
        gShellDriver1HiiHandle,
        L"drvcfg",
        L"HiiDatabase->UpdatePackageList",
        Status
        );

      ShellStatus = SHELL_DEVICE_ERROR;
      goto Done;
    }
  } else {
    ShellStatus = ParseBufferConfig (Handle, MainBuffer, MainBufferSize, HiiDatabase);
  }

Done:
  SHELL_FREE_NON_NULL (MainBuffer);

  if (FileHandle != NULL) {
    ShellCloseFile (&FileHandle);
  }

  if (ShellStatus == SHELL_SUCCESS) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_DRVCFG_COMP),
      gShellDriver1HiiHandle
      );
  }

  return ShellStatus;
}

/**
  Present a requested action to the user.

  @param[in] DriverImageHandle  The handle for the driver to configure.
  @param[in] ControllerHandle   The handle of the device being managed by the Driver specified.
  @param[in] ChildHandle        The handle of a child device of the specified device.
  @param[in] ActionRequired     The required HII action.

  @retval SHELL_INVALID_PARAMETER   A parameter has a invalid value.
**/
EFI_STATUS
ShellCmdDriverConfigurationProcessActionRequired (
  EFI_HANDLE                                DriverImageHandle,
  EFI_HANDLE                                ControllerHandle,
  EFI_HANDLE                                ChildHandle,
  EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired
  )
{
  EFI_HANDLE  ConnectControllerContextOverride[2];

  switch (ActionRequired) {
    case EfiDriverConfigurationActionNone:
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);
      break;

    case EfiDriverConfigurationActionStopController:
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_STOP), gShellDriver1HiiHandle);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"stop controller");
      ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL);

      gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"stopped");
      break;

    case EfiDriverConfigurationActionRestartController:
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"controller");
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart controller");
      ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL);

      gBS->DisconnectController (ControllerHandle, DriverImageHandle, ChildHandle);
      ConnectControllerContextOverride[0] = DriverImageHandle;
      ConnectControllerContextOverride[1] = NULL;
      gBS->ConnectController (ControllerHandle, ConnectControllerContextOverride, NULL, TRUE);
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_CTLR_S), gShellDriver1HiiHandle, L"restarted");
      break;

    case EfiDriverConfigurationActionRestartPlatform:
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_RESTART_S), gShellDriver1HiiHandle, L"platform");
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_ENTER_S), gShellDriver1HiiHandle, L"restart platform");
      ShellPromptForResponse (ShellPromptResponseTypeEnterContinue, NULL, NULL);

      gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
      break;

    default:
      return (EFI_INVALID_PARAMETER);
  }

  return EFI_SUCCESS;
}

/**
  Do the configuration in an environment without HII.

  @param[in] Language           The language code.
  @param[in] ForceDefaults      TRUE to force defaults, FALSE otherwise.
  @param[in] DefaultType        If ForceDefaults is TRUE, specifies the default type.
  @param[in] AllChildren        TRUE to configure all children, FALSE otherwise.
  @param[in] ValidateOptions    TRUE to validate existing options, FALSE otherwise.
  @param[in] SetOptions         TRUE to set options, FALSE otherwise.
  @param[in] DriverImageHandle  The handle for the driver to configure.
  @param[in] DeviceHandle       The handle of the device being managed by the Driver specified.
  @param[in] ChildHandle        The handle of a child device of the specified device.

  @retval SHELL_NOT_FOUND           A specified handle could not be found.
  @retval SHELL_INVALID_PARAMETER   A parameter has a invalid value.
**/
SHELL_STATUS
PreHiiDrvCfg (
  IN CONST CHAR8  *Language,
  IN BOOLEAN      ForceDefaults,
  IN UINT32       DefaultType,
  IN BOOLEAN      AllChildren,
  IN BOOLEAN      ValidateOptions,
  IN BOOLEAN      SetOptions,
  IN EFI_HANDLE   DriverImageHandle,
  IN EFI_HANDLE   DeviceHandle,
  IN EFI_HANDLE   ChildHandle
  )
{
  EFI_STATUS                                Status;
  SHELL_STATUS                              ShellStatus;
  UINTN                                     OuterLoopCounter;
  CHAR8                                     *BestLanguage;
  UINTN                                     DriverImageHandleCount;
  EFI_HANDLE                                *DriverImageHandleBuffer;
  UINTN                                     HandleCount;
  EFI_HANDLE                                *HandleBuffer;
  UINTN                                     *HandleType;
  UINTN                                     LoopCounter;
  UINTN                                     ChildIndex;
  UINTN                                     ChildHandleCount;
  EFI_HANDLE                                *ChildHandleBuffer;
  UINTN                                     *ChildHandleType;
  EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED  ActionRequired;
  EFI_DRIVER_CONFIGURATION_PROTOCOL         *DriverConfiguration;
  BOOLEAN                                   Iso639Language;
  UINTN                                     HandleIndex1;
  UINTN                                     HandleIndex2;
  UINTN                                     HandleIndex3;

  ShellStatus = SHELL_SUCCESS;

  if ((ChildHandle == NULL) && AllChildren) {
    SetOptions = FALSE;
  }

  if (ForceDefaults) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_DRVCFG_FORCE_D),
      gShellDriver1HiiHandle,
      DefaultType
      );
  } else if (ValidateOptions) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_DRVCFG_VALIDATE),
      gShellDriver1HiiHandle
      );
  } else if (SetOptions) {
    ShellPrintHiiDefaultEx (
      STRING_TOKEN (STR_DRVCFG_SET),
      gShellDriver1HiiHandle
      );
  }

  if (DriverImageHandle == 0) {
    DriverImageHandleBuffer = GetHandleListByProtocolList (CfgGuidList);
    if (DriverImageHandleBuffer == NULL) {
      ShellStatus = SHELL_NOT_FOUND;
      goto Done;
    }

    for (
         HandleBuffer = DriverImageHandleBuffer, DriverImageHandleCount = 0
         ; HandleBuffer != NULL && *HandleBuffer != NULL
         ; HandleBuffer++, DriverImageHandleCount++)
    {
    }
  } else {
    DriverImageHandleCount = 1;
    //
    // Allocate buffer to hold the image handle so as to
    // keep consistent with the above clause
    //
    DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE));
    if (DriverImageHandleBuffer == NULL) {
      ASSERT (DriverImageHandleBuffer);
      ShellStatus = SHELL_OUT_OF_RESOURCES;
      goto Done;
    }

    DriverImageHandleBuffer[0] = DriverImageHandle;
  }

  for (OuterLoopCounter = 0; OuterLoopCounter < DriverImageHandleCount; OuterLoopCounter++) {
    Iso639Language = FALSE;
    Status         = gBS->OpenProtocol (
                            DriverImageHandleBuffer[OuterLoopCounter],
                            &gEfiDriverConfiguration2ProtocolGuid,
                            (VOID **)&DriverConfiguration,
                            NULL,
                            NULL,
                            EFI_OPEN_PROTOCOL_GET_PROTOCOL
                            );
    if (EFI_ERROR (Status)) {
      Iso639Language = TRUE;
      Status         = gBS->OpenProtocol (
                              DriverImageHandleBuffer[OuterLoopCounter],
                              &gEfiDriverConfigurationProtocolGuid,
                              (VOID **)&DriverConfiguration,
                              NULL,
                              NULL,
                              EFI_OPEN_PROTOCOL_GET_PROTOCOL
                              );
    }

    if (EFI_ERROR (Status)) {
      //      ShellPrintHiiDefaultEx (
      //        STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),
      //        gShellDriver1HiiHandle,
      //        ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter])
      //        );
      ShellStatus = SHELL_UNSUPPORTED;
      continue;
    }

    BestLanguage = GetBestLanguage (
                     DriverConfiguration->SupportedLanguages,
                     Iso639Language,
                     Language != NULL ? Language : "",
                     DriverConfiguration->SupportedLanguages,
                     NULL
                     );
    if (BestLanguage == NULL) {
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_GEN_NO_VALUE),
        gShellDriver1HiiHandle,
        L"drvcfg",
        L"-l"
        );
      ShellStatus = SHELL_INVALID_PARAMETER;
      continue;
    }

    Status = ParseHandleDatabaseByRelationshipWithType (
               DriverImageHandleBuffer[OuterLoopCounter],
               NULL,
               &HandleCount,
               &HandleBuffer,
               &HandleType
               );
    if (EFI_ERROR (Status)) {
      continue;
    }

    if (SetOptions && (DeviceHandle == NULL)) {
      gST->ConOut->ClearScreen (gST->ConOut);
      Status = DriverConfiguration->SetOptions (
                                      DriverConfiguration,
                                      NULL,
                                      NULL,
                                      BestLanguage,
                                      &ActionRequired
                                      );
      gST->ConOut->ClearScreen (gST->ConOut);

      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_DRVCFG_ALL_LANG),
        gShellDriver1HiiHandle,
        ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]),
        DriverConfiguration->SupportedLanguages
        );
      if (!EFI_ERROR (Status)) {
        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
          gShellDriver1HiiHandle
          );
        for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {
          if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) == HR_CONTROLLER_HANDLE) {
            ShellCmdDriverConfigurationProcessActionRequired (
              DriverImageHandleBuffer[OuterLoopCounter],
              HandleBuffer[LoopCounter],
              NULL,
              ActionRequired
              );
          }
        }
      } else {
        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_DRVCFG_NOT_SET),
          gShellDriver1HiiHandle,
          Status
          );
      }

      continue;
    }

    for (LoopCounter = 0; LoopCounter < HandleCount; LoopCounter++) {
      if ((HandleType[LoopCounter] & HR_CONTROLLER_HANDLE) != HR_CONTROLLER_HANDLE) {
        continue;
      }

      if ((DeviceHandle != NULL) && (DeviceHandle != HandleBuffer[LoopCounter])) {
        continue;
      }

      if (ChildHandle == NULL) {
        HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
        HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_DRVCFG_CTRL_LANG),
          gShellDriver1HiiHandle,
          HandleIndex1,
          HandleIndex2,
          DriverConfiguration->SupportedLanguages
          );

        if (ForceDefaults) {
          Status = DriverConfiguration->ForceDefaults (
                                          DriverConfiguration,
                                          HandleBuffer[LoopCounter],
                                          NULL,
                                          DefaultType,
                                          &ActionRequired
                                          );

          if (!EFI_ERROR (Status)) {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_DEF_FORCED),
              gShellDriver1HiiHandle
              );
            ShellCmdDriverConfigurationProcessActionRequired (
              DriverImageHandleBuffer[OuterLoopCounter],
              HandleBuffer[LoopCounter],
              NULL,
              ActionRequired
              );
          } else {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_FORCE_FAILED),
              gShellDriver1HiiHandle,
              Status
              );
            ShellStatus = SHELL_DEVICE_ERROR;
          }
        } else if (ValidateOptions) {
          Status = DriverConfiguration->OptionsValid (
                                          DriverConfiguration,
                                          HandleBuffer[LoopCounter],
                                          NULL
                                          );

          if (!EFI_ERROR (Status)) {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID),
              gShellDriver1HiiHandle
              );
          } else {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_OPTIONS_INV),
              gShellDriver1HiiHandle,
              Status
              );
            ShellStatus = SHELL_DEVICE_ERROR;
          }
        } else if (SetOptions) {
          gST->ConOut->ClearScreen (gST->ConOut);
          Status = DriverConfiguration->SetOptions (
                                          DriverConfiguration,
                                          HandleBuffer[LoopCounter],
                                          NULL,
                                          BestLanguage,
                                          &ActionRequired
                                          );
          gST->ConOut->ClearScreen (gST->ConOut);
          HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
          HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
          ShellPrintHiiDefaultEx (
            STRING_TOKEN (STR_DRVCFG_CTRL_LANG),
            gShellDriver1HiiHandle,
            HandleIndex1,
            HandleIndex2,
            DriverConfiguration->SupportedLanguages
            );
          if (!EFI_ERROR (Status)) {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
              gShellDriver1HiiHandle
              );

            ShellCmdDriverConfigurationProcessActionRequired (
              DriverImageHandleBuffer[OuterLoopCounter],
              HandleBuffer[LoopCounter],
              NULL,
              ActionRequired
              );
          } else {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_NOT_SET),
              gShellDriver1HiiHandle,
              Status
              );
            ShellStatus = SHELL_DEVICE_ERROR;
          }
        } else {
          Print (L"\n");
        }
      }

      if ((ChildHandle == NULL) && !AllChildren) {
        continue;
      }

      Status = ParseHandleDatabaseByRelationshipWithType (
                 DriverImageHandleBuffer[OuterLoopCounter],
                 HandleBuffer[LoopCounter],
                 &ChildHandleCount,
                 &ChildHandleBuffer,
                 &ChildHandleType
                 );
      if (EFI_ERROR (Status)) {
        continue;
      }

      for (ChildIndex = 0; ChildIndex < ChildHandleCount; ChildIndex++) {
        if ((ChildHandleType[ChildIndex] & HR_CHILD_HANDLE) != HR_CHILD_HANDLE) {
          continue;
        }

        if ((ChildHandle != NULL) && (ChildHandle != ChildHandleBuffer[ChildIndex])) {
          continue;
        }

        HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
        HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
        HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]);
        ShellPrintHiiDefaultEx (
          STRING_TOKEN (STR_DRVCFG_CHILD_LANG),
          gShellDriver1HiiHandle,
          HandleIndex1,
          HandleIndex2,
          HandleIndex3,
          DriverConfiguration->SupportedLanguages
          );

        if (ForceDefaults) {
          Status = DriverConfiguration->ForceDefaults (
                                          DriverConfiguration,
                                          HandleBuffer[LoopCounter],
                                          ChildHandleBuffer[ChildIndex],
                                          DefaultType,
                                          &ActionRequired
                                          );

          if (!EFI_ERROR (Status)) {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_DEF_FORCED),
              gShellDriver1HiiHandle
              );

            ShellCmdDriverConfigurationProcessActionRequired (
              DriverImageHandleBuffer[OuterLoopCounter],
              HandleBuffer[LoopCounter],
              ChildHandleBuffer[ChildIndex],
              ActionRequired
              );
          } else {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_FORCE_FAILED),
              gShellDriver1HiiHandle,
              Status
              );
            ShellStatus = SHELL_DEVICE_ERROR;
          }
        } else if (ValidateOptions) {
          Status = DriverConfiguration->OptionsValid (
                                          DriverConfiguration,
                                          HandleBuffer[LoopCounter],
                                          ChildHandleBuffer[ChildIndex]
                                          );

          if (!EFI_ERROR (Status)) {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_OPTIONS_VALID),
              gShellDriver1HiiHandle
              );
          } else {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_OPTIONS_INV),
              gShellDriver1HiiHandle,
              Status
              );
            ShellStatus = SHELL_DEVICE_ERROR;
          }
        } else if (SetOptions) {
          gST->ConOut->ClearScreen (gST->ConOut);
          Status = DriverConfiguration->SetOptions (
                                          DriverConfiguration,
                                          HandleBuffer[LoopCounter],
                                          ChildHandleBuffer[ChildIndex],
                                          BestLanguage,
                                          &ActionRequired
                                          );
          gST->ConOut->ClearScreen (gST->ConOut);
          HandleIndex1 = ConvertHandleToHandleIndex (DriverImageHandleBuffer[OuterLoopCounter]);
          HandleIndex2 = ConvertHandleToHandleIndex (HandleBuffer[LoopCounter]);
          HandleIndex3 = ConvertHandleToHandleIndex (ChildHandleBuffer[ChildIndex]);
          ShellPrintHiiDefaultEx (
            STRING_TOKEN (STR_DRVCFG_CHILD_LANG),
            gShellDriver1HiiHandle,
            HandleIndex1,
            HandleIndex2,
            HandleIndex3,
            DriverConfiguration->SupportedLanguages
            );
          if (!EFI_ERROR (Status)) {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_OPTIONS_SET),
              gShellDriver1HiiHandle
              );

            ShellCmdDriverConfigurationProcessActionRequired (
              DriverImageHandleBuffer[OuterLoopCounter],
              HandleBuffer[LoopCounter],
              ChildHandleBuffer[ChildIndex],
              ActionRequired
              );
          } else {
            ShellPrintHiiDefaultEx (
              STRING_TOKEN (STR_DRVCFG_NOT_SET),
              gShellDriver1HiiHandle,
              Status
              );
            ShellStatus = SHELL_DEVICE_ERROR;
          }
        } else {
          Print (L"\n");
        }
      }

      FreePool (ChildHandleBuffer);
      FreePool (ChildHandleType);
    }

    FreePool (BestLanguage);
    FreePool (HandleBuffer);
    FreePool (HandleType);
  }

  if ((DriverImageHandle != NULL) && (DriverImageHandleCount != 0)) {
    FreePool (DriverImageHandleBuffer);
  }

Done:
  return ShellStatus;
}

/**
  Function to print out configuration information on all configurable handles.

  @param[in] ChildrenToo    TRUE to tewst for children.
  @param[in] Language       ASCII string for language code.
  @param[in] UseHii         TRUE to check for Hii and DPC, FALSE for DCP only.

  @retval SHELL_SUCCESS     The operation was successful.
**/
SHELL_STATUS
PrintConfigInfoOnAll (
  IN CONST BOOLEAN  ChildrenToo,
  IN CONST CHAR8    *Language,
  IN CONST BOOLEAN  UseHii
  )
{
  EFI_HANDLE  *HandleList;
  EFI_HANDLE  *CurrentHandle;
  BOOLEAN     Found;
  UINTN       Index2;

  Found         = FALSE;
  HandleList    = NULL;
  CurrentHandle = NULL;

  if (UseHii) {
    //
    // HII method
    //
    HandleList = GetHandleListByProtocol (&gEfiHiiConfigAccessProtocolGuid);
    for (CurrentHandle = HandleList; CurrentHandle != NULL && *CurrentHandle != NULL; CurrentHandle++) {
      Found  = TRUE;
      Index2 = *CurrentHandle == NULL ? 0 : ConvertHandleToHandleIndex (*CurrentHandle);
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_DRVCFG_LINE_HII),
        gShellDriver1HiiHandle,
        Index2
        );
    }

    SHELL_FREE_NON_NULL (HandleList);
  }

  if (PreHiiDrvCfg (
        Language,
        FALSE,
        0,
        ChildrenToo,
        FALSE,
        FALSE,
        0,
        0,
        0
        ) == SHELL_SUCCESS)
  {
    Found = TRUE;
  }

  if (!Found) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_DRVCFG_NONE_FOUND), gShellDriver1HiiHandle);
    return (SHELL_SUCCESS);
  }

  return (SHELL_SUCCESS);
}

STATIC CONST SHELL_PARAM_ITEM  ParamListHii[] = {
  { L"-s", TypeFlag  },
  { L"-l", TypeValue },
  { L"-f", TypeValue },
  { L"-o", TypeValue },
  { L"-i", TypeValue },
  { NULL,  TypeMax   }
};
STATIC CONST SHELL_PARAM_ITEM  ParamListPreHii[] = {
  { L"-c", TypeFlag  },
  { L"-s", TypeFlag  },
  { L"-v", TypeFlag  },
  { L"-l", TypeValue },
  { L"-f", TypeValue },
  { NULL,  TypeMax   }
};

/**
  Function for 'drvcfg' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunDrvCfg (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;
  CHAR8         *Language;
  CONST CHAR16  *Lang;
  CONST CHAR16  *HandleIndex1;
  CONST CHAR16  *HandleIndex2;
  CONST CHAR16  *HandleIndex3;
  CONST CHAR16  *ForceTypeString;
  BOOLEAN       Force;
  BOOLEAN       Set;
  BOOLEAN       Validate;
  BOOLEAN       InFromFile;
  BOOLEAN       OutToFile;
  BOOLEAN       AllChildren;
  BOOLEAN       UseHii;
  UINT32        ForceType;
  UINT64        Intermediate;
  EFI_HANDLE    Handle1;
  EFI_HANDLE    Handle2;
  EFI_HANDLE    Handle3;
  CONST CHAR16  *FileName;

  ShellStatus  = SHELL_SUCCESS;
  Status       = EFI_SUCCESS;
  Language     = NULL;
  UseHii       = TRUE;
  ProblemParam = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize ();
  ASSERT_EFI_ERROR (Status);

  Status = CommandInit ();
  ASSERT_EFI_ERROR (Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamListHii, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status) || (ShellCommandLineGetCount (Package) > 2)) {
    UseHii = FALSE;
    if (Package != NULL) {
      ShellCommandLineFreeVarList (Package);
    }

    SHELL_FREE_NON_NULL (ProblemParam);
    Status = ShellCommandLineParse (ParamListPreHii, &Package, &ProblemParam, TRUE);
    if (EFI_ERROR (Status)) {
      if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drvcfg", ProblemParam);
        FreePool (ProblemParam);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      } else {
        ASSERT (FALSE);
      }
    }
  }

  if (ShellStatus == SHELL_SUCCESS) {
    if (ShellCommandLineGetCount (Package) > 4) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drvcfg");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    Lang = ShellCommandLineGetValue (Package, L"-l");
    if (Lang != NULL) {
      Language = AllocateZeroPool (StrSize (Lang));
      if (Language == NULL) {
        ShellStatus = SHELL_OUT_OF_RESOURCES;
        goto Done;
      }

      AsciiSPrint (Language, StrSize (Lang), "%S", Lang);
    } else if (ShellCommandLineGetFlag (Package, L"-l")) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-l");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    Set             = ShellCommandLineGetFlag (Package, L"-s");
    Validate        = ShellCommandLineGetFlag (Package, L"-v");
    InFromFile      = ShellCommandLineGetFlag (Package, L"-i");
    OutToFile       = ShellCommandLineGetFlag (Package, L"-o");
    AllChildren     = ShellCommandLineGetFlag (Package, L"-c");
    Force           = ShellCommandLineGetFlag (Package, L"-f");
    ForceTypeString = ShellCommandLineGetValue (Package, L"-f");

    if (OutToFile) {
      FileName = ShellCommandLineGetValue (Package, L"-o");
    } else if (InFromFile) {
      FileName = ShellCommandLineGetValue (Package, L"-i");
    } else {
      FileName = NULL;
    }

    if (InFromFile && EFI_ERROR (ShellFileExists (FileName))) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FIND_FAIL), gShellDriver1HiiHandle, L"drvcfg", FileName);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (OutToFile && !EFI_ERROR (ShellFileExists (FileName))) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_FILE_EXIST), gShellDriver1HiiHandle, L"drvcfg", FileName);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (Force && (ForceTypeString == NULL)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", L"-f");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (Force) {
      Status = ShellConvertStringToUint64 (ForceTypeString, &Intermediate, FALSE, FALSE);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDriver1HiiHandle, L"drvcfg", ForceTypeString, L"-f");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }

      ForceType = (UINT32)Intermediate;
    } else {
      ForceType = 0;
    }

    HandleIndex1 = ShellCommandLineGetRawValue (Package, 1);
    Handle1      = NULL;
    if ((HandleIndex1 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex1, &Intermediate, TRUE, FALSE))) {
      Handle1 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
      if ((Handle1 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex1);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }

    HandleIndex2 = ShellCommandLineGetRawValue (Package, 2);
    Handle2      = NULL;
    if ((HandleIndex2 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex2, &Intermediate, TRUE, FALSE))) {
      Handle2 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
      if ((Handle2 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex2);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }

    HandleIndex3 = ShellCommandLineGetRawValue (Package, 3);
    Handle3      = NULL;
    if ((HandleIndex3 != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (HandleIndex3, &Intermediate, TRUE, FALSE))) {
      Handle3 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
      if ((Handle3 == NULL) || ((UINT64)(UINTN)Intermediate != Intermediate)) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"drvcfg", HandleIndex3);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }

    if ((InFromFile || OutToFile) && (FileName == NULL)) {
      if (FileName == NULL) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvcfg", InFromFile ? L"-i" : L"-o");
      } else {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_HANDLE_REQ), gShellDriver1HiiHandle, L"drvcfg");
      }

      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (!UseHii && (InFromFile || OutToFile)) {
      if (InFromFile) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-i");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }

      if (OutToFile) {
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDriver1HiiHandle, L"drvcfg", L"-o");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }

    if (Validate && Force) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-f");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (Validate && Set) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-v", L"-s");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (Set && Force) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-s", L"-f");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (OutToFile && InFromFile) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDriver1HiiHandle, L"drvcfg", L"-i", L"-o");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    //
    // We do HII first.
    //
    if (UseHii) {
      if ((Handle1 != NULL) && EFI_ERROR (gBS->OpenProtocol (Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
        //
        // no HII on this handle.
        //
        ShellStatus = SHELL_UNSUPPORTED;
      } else if (Validate) {
      } else if (Force) {
      } else if (Set) {
      } else if (InFromFile) {
        ShellStatus = ConfigFromFile (Handle1, FileName);
        if ((Handle1 != NULL) && (ShellStatus == SHELL_SUCCESS)) {
          goto Done;
        }
      } else if (OutToFile) {
        ShellStatus = ConfigToFile (Handle1, FileName);
        if ((Handle1 != NULL) && (ShellStatus == SHELL_SUCCESS)) {
          goto Done;
        }
      } else if (HandleIndex1 == NULL) {
        //
        // display all that are configurable
        //
        ShellStatus = PrintConfigInfoOnAll (AllChildren, Language, UseHii);
        goto Done;
      } else {
        if (!EFI_ERROR (gBS->OpenProtocol (Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
          ShellPrintHiiDefaultEx (
            STRING_TOKEN (STR_DRVCFG_LINE_HII),
            gShellDriver1HiiHandle,
            ConvertHandleToHandleIndex (Handle1)
            );
          goto Done;
        }
      }
    }

    //
    // We allways need to do this one since it does both by default.
    //
    if (!InFromFile && !OutToFile) {
      ShellStatus = PreHiiDrvCfg (
                      Language,
                      Force,
                      ForceType,
                      AllChildren,
                      Validate,
                      Set,
                      Handle1,
                      Handle2,
                      Handle3
                      );
    }

    if (ShellStatus == SHELL_UNSUPPORTED) {
      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),
        gShellDriver1HiiHandle,
        ConvertHandleToHandleIndex (Handle1)
        );
    }
  }

Done:
  ShellCommandLineFreeVarList (Package);
  SHELL_FREE_NON_NULL (Language);
  return (ShellStatus);
}
