/** @file
  Main file for BCFG command.

  (C) Copyright 2014-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 <Uefi.h>

#include <Guid/GlobalVariable.h>
#include <Guid/ShellLibHiiGuid.h>

#include <Protocol/Shell.h>
#include <Protocol/ShellParameters.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/UnicodeCollation.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/ShellCommandLib.h>
#include <Library/ShellLib.h>
#include <Library/SortLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/HiiLib.h>
#include <Library/FileHandleLib.h>
#include <Library/PrintLib.h>
#include <Library/HandleParsingLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootManagerLib.h>

STATIC CONST CHAR16    mFileName[]         = L"ShellCommands";
STATIC EFI_HII_HANDLE  gShellBcfgHiiHandle = NULL;

typedef enum {
  BcfgTargetBootOrder   = 0,
  BcfgTargetDriverOrder = 1,
  BcfgTargetMax         = 2
} BCFG_OPERATION_TARGET;

typedef enum {
  BcfgTypeDump = 0,
  BcfgTypeAdd  = 1,
  BcfgTypeAddp = 2,
  BcfgTypeAddh = 3,
  BcfgTypeRm   = 4,
  BcfgTypeMv   = 5,
  BcfgTypeOpt  = 6,
  BcfgTypeMod  = 7,
  BcfgTypeModf = 8,
  BcfgTypeModp = 9,
  BcfgTypeModh = 10,
  BcfgTypeMax  = 11
} BCFG_OPERATION_TYPE;

typedef struct {
  BCFG_OPERATION_TARGET    Target;
  BCFG_OPERATION_TYPE      Type;
  UINT16                   Number1;
  UINT16                   Number2;
  UINTN                    HandleIndex;
  CHAR16                   *FileName;
  CHAR16                   *Description;
  UINT16                   *Order;
  CONST CHAR16             *OptData;
} BGFG_OPERATION;

/**
  Update the optional data for a boot or driver option.

  If optional data exists it will be changed.

  @param[in]      Index     The boot or driver option index update.
  @param[in]      DataSize  The size in bytes of Data.
  @param[in]      Data      The buffer for the optional data.
  @param[in]      Target    The target of the operation.

  @retval EFI_SUCCESS       The data was successfully updated.
  @retval other             A error occurred.
**/
EFI_STATUS
UpdateOptionalData (
  UINT16                          Index,
  UINTN                           DataSize,
  UINT8                           *Data,
  IN CONST BCFG_OPERATION_TARGET  Target
  )
{
  EFI_STATUS  Status;
  CHAR16      VariableName[12];
  UINTN       OriginalSize;
  UINT8       *OriginalData;
  UINTN       NewSize;
  UINT8       *NewData;
  UINTN       OriginalOptionDataSize;

  UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", Index);

  OriginalSize = 0;
  OriginalData = NULL;
  NewData      = NULL;
  NewSize      = 0;

  Status = gRT->GetVariable (
                  VariableName,
                  (EFI_GUID *)&gEfiGlobalVariableGuid,
                  NULL,
                  &OriginalSize,
                  OriginalData
                  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    OriginalData = AllocateZeroPool (OriginalSize);
    if (OriginalData == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }

    Status = gRT->GetVariable (
                    VariableName,
                    (EFI_GUID *)&gEfiGlobalVariableGuid,
                    NULL,
                    &OriginalSize,
                    OriginalData
                    );
  }

  if (!EFI_ERROR (Status)) {
    //
    // Allocate new struct and discard old optional data.
    //
    ASSERT (OriginalData != NULL);
    OriginalOptionDataSize  = sizeof (UINT32) + sizeof (UINT16) + StrSize (((CHAR16 *)(OriginalData + sizeof (UINT32) + sizeof (UINT16))));
    OriginalOptionDataSize += (*(UINT16 *)(OriginalData + sizeof (UINT32)));
    OriginalOptionDataSize -= OriginalSize;
    NewSize                 = OriginalSize - OriginalOptionDataSize + DataSize;
    NewData                 = AllocatePool (NewSize);
    if (NewData == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
    } else {
      CopyMem (NewData, OriginalData, OriginalSize - OriginalOptionDataSize);
      CopyMem (NewData + OriginalSize - OriginalOptionDataSize, Data, DataSize);
    }
  }

  if (!EFI_ERROR (Status)) {
    //
    // put the data back under the variable
    //
    Status = gRT->SetVariable (
                    VariableName,
                    (EFI_GUID *)&gEfiGlobalVariableGuid,
                    EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
                    NewSize,
                    NewData
                    );
  }

  SHELL_FREE_NON_NULL (OriginalData);
  SHELL_FREE_NON_NULL (NewData);
  return (Status);
}

/**
  This function will get a CRC for a boot option.

  @param[in, out] Crc         The CRC value to return.
  @param[in]      BootIndex   The boot option index to CRC.

  @retval EFI_SUCCESS           The CRC was successfully returned.
  @retval other                 A error occurred.
**/
EFI_STATUS
GetBootOptionCrc (
  UINT32  *Crc,
  UINT16  BootIndex
  )
{
  CHAR16      VariableName[12];
  EFI_STATUS  Status;
  UINT8       *Buffer;
  UINTN       BufferSize;

  Buffer     = NULL;
  BufferSize = 0;

  //
  // Get the data Buffer
  //
  UnicodeSPrint (VariableName, sizeof (VariableName), L"%Boot%04x", BootIndex);
  Status = gRT->GetVariable (
                  VariableName,
                  (EFI_GUID *)&gEfiGlobalVariableGuid,
                  NULL,
                  &BufferSize,
                  NULL
                  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    Buffer = AllocateZeroPool (BufferSize);
    Status = gRT->GetVariable (
                    VariableName,
                    (EFI_GUID *)&gEfiGlobalVariableGuid,
                    NULL,
                    &BufferSize,
                    Buffer
                    );
  }

  //
  // Get the CRC computed
  //
  if (!EFI_ERROR (Status)) {
    Status = gBS->CalculateCrc32 (Buffer, BufferSize, Crc);
  }

  SHELL_FREE_NON_NULL (Buffer);
  return EFI_SUCCESS;
}

/**
  This function will populate the device path protocol parameter based on TheHandle.

  @param[in]      TheHandle     Driver handle.
  @param[in, out] FilePath      On a successful return the device path to the handle.

  @retval EFI_SUCCESS           The device path was successfully returned.
  @retval other                 A error from gBS->HandleProtocol.

  @sa HandleProtocol
**/
EFI_STATUS
GetDevicePathForDriverHandle (
  IN EFI_HANDLE                    TheHandle,
  IN OUT EFI_DEVICE_PATH_PROTOCOL  **FilePath
  )
{
  EFI_STATUS                 Status;
  EFI_LOADED_IMAGE_PROTOCOL  *LoadedImage;
  EFI_DEVICE_PATH_PROTOCOL   *ImageDevicePath;

  Status = gBS->OpenProtocol (
                  TheHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **)&LoadedImage,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    LoadedImage->DeviceHandle,
                    &gEfiDevicePathProtocolGuid,
                    (VOID **)&ImageDevicePath,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      //      *DevPath  = DuplicateDevicePath (ImageDevicePath);
      //      *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
      *FilePath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
      gBS->CloseProtocol (
             LoadedImage->DeviceHandle,
             &gEfiDevicePathProtocolGuid,
             gImageHandle,
             NULL
             );
    }

    gBS->CloseProtocol (
           TheHandle,
           &gEfiLoadedImageProtocolGuid,
           gImageHandle,
           NULL
           );
  }

  return (Status);
}

/**
  Function to get Device Path by a handle.

  @param[in]        TheHandle   Use it to get DevicePath.
  @param[in]        Target      Boot option target.
  @param[in, out]   DevicePath  On a successful return the device path to the handle.

  @retval   SHELL_INVALID_PARAMETER The handle was NULL.
  @retval   SHELL_NOT_FOUND         Not found device path by handle.
  @retval   SHELL_SUCCESS           Get device path successfully.
**/
SHELL_STATUS
GetDevicePathByHandle (
  IN     EFI_HANDLE                TheHandle,
  IN     BCFG_OPERATION_TARGET     Target,
  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath
  )
{
  EFI_STATUS    Status;
  SHELL_STATUS  ShellStatus;

  UINTN  DriverBindingHandleCount;
  UINTN  ParentControllerHandleCount;
  UINTN  ChildControllerHandleCount;

  ShellStatus = SHELL_SUCCESS;

  if (TheHandle == NULL) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
    return SHELL_INVALID_PARAMETER;
  }

  Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle, &DriverBindingHandleCount, NULL);
  if (EFI_ERROR (Status)) {
    DriverBindingHandleCount = 0;
  }

  Status = PARSE_HANDLE_DATABASE_PARENTS (TheHandle, &ParentControllerHandleCount, NULL);
  if (EFI_ERROR (Status)) {
    ParentControllerHandleCount = 0;
  }

  Status = ParseHandleDatabaseForChildControllers (TheHandle, &ChildControllerHandleCount, NULL);
  if (EFI_ERROR (Status)) {
    ChildControllerHandleCount = 0;
  }

  Status = gBS->HandleProtocol (TheHandle, &gEfiDevicePathProtocolGuid, (VOID **)DevicePath);

  if ((DriverBindingHandleCount    > 0) ||
      (ParentControllerHandleCount > 0) ||
      (ChildControllerHandleCount  > 0) ||
      !EFI_ERROR (Status)
      )
  {
    //
    // The handle points to a real controller which has a device path.
    //
    if (Target == BcfgTargetDriverOrder) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_GEN_PARAM_INV),
        gShellBcfgHiiHandle,
        L"bcfg",
        L"Handle should point to driver image."
        );
      ShellStatus = SHELL_NOT_FOUND;
    }
  } else {
    //
    // The handle points to a driver image.
    //
    if (Target == BcfgTargetBootOrder) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_GEN_PARAM_INV),
        gShellBcfgHiiHandle,
        L"bcfg",
        L"Handle should point to controller."
        );
      ShellStatus = SHELL_NOT_FOUND;
    } else {
      if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle, DevicePath))) {
        ShellStatus = SHELL_NOT_FOUND;
      }
    }
  }

  return (ShellStatus);
}

/**
  Function to modify an option.

  @param[in] BcfgOperation  Pointer to BCFG operation.
  @param[in] OrderCount     The number if items in CurrentOrder.

  @retval SHELL_SUCCESS             The operation was successful.
  @retval SHELL_INVALID_PARAMETER   A parameter was invalid.
  @retval SHELL_OUT_OF_RESOUCES     A memory allocation failed.
**/
SHELL_STATUS
BcfgMod (
  IN CONST BGFG_OPERATION  *BcfgOperation,
  IN CONST UINTN           OrderCount
  )
{
  EFI_STATUS                    Status;
  EFI_HANDLE                    CurHandle;
  SHELL_STATUS                  ShellStatus;
  CHAR16                        OptionStr[40];
  EFI_SHELL_FILE_INFO           *FileList;
  EFI_SHELL_FILE_INFO           *Arg;
  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL      *DevicePathBuffer;
  EFI_DEVICE_PATH_PROTOCOL      *DevicePathWalker;
  EFI_BOOT_MANAGER_LOAD_OPTION  LoadOption;

  ShellStatus      = SHELL_SUCCESS;
  FileList         = NULL;
  DevicePath       = NULL;
  DevicePathBuffer = NULL;

  ZeroMem (&LoadOption, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));

  if (((BcfgOperation->Type == BcfgTypeMod) && (BcfgOperation->Description == NULL))  ||
      ((BcfgOperation->Type == BcfgTypeModf) && (BcfgOperation->FileName == NULL))     ||
      ((BcfgOperation->Type == BcfgTypeModp) && (BcfgOperation->FileName == NULL))     ||
      ((BcfgOperation->Type == BcfgTypeModh) && (BcfgOperation->HandleIndex == 0))     ||
      (BcfgOperation->Number1 > OrderCount)
      )
  {
    return (SHELL_INVALID_PARAMETER);
  }

  if (BcfgOperation->Type == BcfgTypeModh) {
    CurHandle   = ConvertHandleIndexToHandle (BcfgOperation->HandleIndex);
    ShellStatus = GetDevicePathByHandle (CurHandle, BcfgOperation->Target, &DevicePathBuffer);
    if (ShellStatus == SHELL_SUCCESS) {
      DevicePath = DuplicateDevicePath (DevicePathBuffer);
    }
  } else if ((BcfgOperation->Type == BcfgTypeModf) || (BcfgOperation->Type == BcfgTypeModp)) {
    //
    // Get Device Path by FileName.
    //
    ShellOpenFileMetaArg ((CHAR16 *)BcfgOperation->FileName, EFI_FILE_MODE_READ, &FileList);
    if (FileList == NULL) {
      //
      // The name of file matched nothing.
      //
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
      //
      // If the name of file expanded to multiple names, it's fail.
      //
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);
      if (EFI_ERROR (Arg->Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        DevicePathBuffer = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);
        if (DevicePathBuffer == NULL) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);
          ShellStatus = SHELL_UNSUPPORTED;
        }
      }
    }

    if (ShellStatus == SHELL_SUCCESS) {
      if (BcfgOperation->Type == BcfgTypeModp) {
        ShellStatus      = SHELL_INVALID_PARAMETER;
        DevicePathWalker = DevicePathBuffer;
        while (!IsDevicePathEnd (DevicePathWalker)) {
          if ((DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH) &&
              (DevicePathSubType (DevicePathWalker) == MEDIA_HARDDRIVE_DP)
              )
          {
            //
            // We found the portion of device path starting with the hard driver partition.
            //
            ShellStatus = SHELL_SUCCESS;
            DevicePath  = DuplicateDevicePath (DevicePathWalker);
            break;
          } else {
            DevicePathWalker = NextDevicePathNode (DevicePathWalker);
          }
        }
      } else {
        DevicePath = DuplicateDevicePath (DevicePathBuffer);
      }

      FreePool (DevicePathBuffer);
    }
  }

  if (ShellStatus == SHELL_SUCCESS) {
    if (BcfgOperation->Target == BcfgTargetBootOrder) {
      UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Boot%04x", BcfgOperation->Order[BcfgOperation->Number1]);
    } else {
      UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Driver%04x", BcfgOperation->Order[BcfgOperation->Number1]);
    }

    Status = EfiBootManagerVariableToLoadOption (OptionStr, &LoadOption);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle);
      ShellStatus = SHELL_NOT_FOUND;
    }
  }

  if (ShellStatus == SHELL_SUCCESS) {
    if (BcfgOperation->Type == BcfgTypeMod) {
      SHELL_FREE_NON_NULL (LoadOption.Description);
      LoadOption.Description = AllocateCopyPool (StrSize (BcfgOperation->Description), BcfgOperation->Description);
    } else {
      SHELL_FREE_NON_NULL (LoadOption.FilePath);
      LoadOption.FilePath = DuplicateDevicePath (DevicePath);
    }

    Status = EfiBootManagerLoadOptionToVariable (&LoadOption);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);
      ShellStatus = SHELL_INVALID_PARAMETER;
    }
  }

  EfiBootManagerFreeLoadOption (&LoadOption);

  if (DevicePath != NULL) {
    FreePool (DevicePath);
  }

  if (FileList != NULL) {
    ShellCloseFileMetaArg (&FileList);
  }

  return (ShellStatus);
}

/**
  Function to add a option.

  @param[in] Position       The position to add Target at.
  @param[in] File           The file to make the target.
  @param[in] Desc           The description text.
  @param[in] CurrentOrder   The pointer to the current order of items.
  @param[in] OrderCount     The number if items in CurrentOrder.
  @param[in] Target         The info on the option to add.
  @param[in] UseHandle      TRUE to use HandleNumber, FALSE to use File and Desc.
  @param[in] UsePath        TRUE to convert to devicepath.
  @param[in] HandleNumber   The handle number to add.

  @retval SHELL_SUCCESS             The operation was successful.
  @retval SHELL_INVALID_PARAMETER   A parameter was invalid.
**/
SHELL_STATUS
BcfgAdd (
  IN       UINTN                  Position,
  IN CONST CHAR16                 *File,
  IN CONST CHAR16                 *Desc,
  IN CONST UINT16                 *CurrentOrder,
  IN CONST UINTN                  OrderCount,
  IN CONST BCFG_OPERATION_TARGET  Target,
  IN CONST BOOLEAN                UseHandle,
  IN CONST BOOLEAN                UsePath,
  IN CONST UINTN                  HandleNumber
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
  CHAR16                    *Str;
  UINT8                     *TempByteBuffer;
  UINT8                     *TempByteStart;
  EFI_SHELL_FILE_INFO       *Arg;
  EFI_SHELL_FILE_INFO       *FileList;
  CHAR16                    OptionStr[40];
  UINTN                     DescSize, FilePathSize;
  BOOLEAN                   Found;
  UINTN                     TargetLocation;
  UINTN                     Index;
  EFI_HANDLE                *Handles;
  EFI_HANDLE                CurHandle;
  UINTN                     DriverBindingHandleCount;
  UINTN                     ParentControllerHandleCount;
  UINTN                     ChildControllerHandleCount;
  SHELL_STATUS              ShellStatus;
  UINT16                    *NewOrder;

  if (!UseHandle) {
    if ((File == NULL) || (Desc == NULL)) {
      return (SHELL_INVALID_PARAMETER);
    }
  } else {
    if (HandleNumber == 0) {
      return (SHELL_INVALID_PARAMETER);
    }
  }

  if (Position > OrderCount) {
    Position =  OrderCount;
  }

  Str            = NULL;
  FilePath       = NULL;
  FileList       = NULL;
  Handles        = NULL;
  ShellStatus    = SHELL_SUCCESS;
  TargetLocation = 0xFFFF;

  if (UseHandle) {
    CurHandle = ConvertHandleIndexToHandle (HandleNumber);
    if (CurHandle == NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      if (Target == BcfgTargetBootOrder) {
        //
        // Make sure that the handle should point to a real controller
        //
        Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
                   CurHandle,
                   &DriverBindingHandleCount,
                   NULL
                   );

        Status = PARSE_HANDLE_DATABASE_PARENTS (
                   CurHandle,
                   &ParentControllerHandleCount,
                   NULL
                   );

        Status = ParseHandleDatabaseForChildControllers (
                   CurHandle,
                   &ChildControllerHandleCount,
                   NULL
                   );

        if (  (DriverBindingHandleCount > 0)
           || (ParentControllerHandleCount > 0)
           || (ChildControllerHandleCount > 0))
        {
          FilePath = NULL;
          Status   = gBS->HandleProtocol (
                            CurHandle,
                            &gEfiDevicePathProtocolGuid,
                            (VOID **)&FilePath
                            );
        }

        if (EFI_ERROR (Status)) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellBcfgHiiHandle, L"bcfg", HandleNumber);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
      } else {
        //
        // Make sure that the handle should point to driver, not a controller.
        //
        Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
                   CurHandle,
                   &DriverBindingHandleCount,
                   NULL
                   );

        Status = PARSE_HANDLE_DATABASE_PARENTS (
                   CurHandle,
                   &ParentControllerHandleCount,
                   NULL
                   );

        Status = ParseHandleDatabaseForChildControllers (
                   CurHandle,
                   &ChildControllerHandleCount,
                   NULL
                   );

        Status = gBS->HandleProtocol (
                        CurHandle,
                        &gEfiDevicePathProtocolGuid,
                        (VOID **)&FilePath
                        );

        if (  (DriverBindingHandleCount > 0)
           || (ParentControllerHandleCount > 0)
           || (ChildControllerHandleCount > 0)
           || !EFI_ERROR (Status))
        {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");
          ShellStatus = SHELL_INVALID_PARAMETER;
        } else {
          //
          // Get the DevicePath from the loaded image information.
          //
          Status = GetDevicePathForDriverHandle (CurHandle, &FilePath);
        }
      }
    }
  } else {
    //
    // Get file info
    //
    ShellOpenFileMetaArg ((CHAR16 *)File, EFI_FILE_MODE_READ, &FileList);

    if (FileList == NULL) {
      //
      // If filename matched nothing fail
      //
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", File);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {
      //
      // If filename expanded to multiple names, fail
      //
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", File);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);
      if (EFI_ERROR (Arg->Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", File);
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        //
        // Build FilePath to the filename
        //

        //
        // get the device path
        //
        DevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);
        if (DevicePath == NULL) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);
          ShellStatus = SHELL_UNSUPPORTED;
        } else {
          if (UsePath) {
            DevPath     = DevicePath;
            ShellStatus = SHELL_INVALID_PARAMETER;
            while (!IsDevicePathEnd (DevPath)) {
              if ((DevicePathType (DevPath) == MEDIA_DEVICE_PATH) &&
                  (DevicePathSubType (DevPath) == MEDIA_HARDDRIVE_DP))
              {
                //
                // If we find it use it instead
                //
                ShellStatus = SHELL_SUCCESS;
                FilePath    = DuplicateDevicePath (DevPath);
                break;
              }

              DevPath = NextDevicePathNode (DevPath);
            }
          } else {
            FilePath = DuplicateDevicePath (DevicePath);
          }

          FreePool (DevicePath);
        }
      }
    }
  }

  if (ShellStatus == SHELL_SUCCESS) {
    //
    // Find a free target ,a brute force implementation
    //
    Found = FALSE;
    for (TargetLocation = 0; TargetLocation < 0xFFFF; TargetLocation++) {
      Found = TRUE;
      for (Index = 0; Index < OrderCount; Index++) {
        if (CurrentOrder[Index] == TargetLocation) {
          Found = FALSE;
          break;
        }
      }

      if (Found) {
        break;
      }
    }

    if (TargetLocation == 0xFFFF) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellBcfgHiiHandle, L"bcfg");
    } else {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellBcfgHiiHandle, TargetLocation);
    }
  }

  if (ShellStatus == SHELL_SUCCESS) {
    //
    // Add the option
    //
    DescSize     = StrSize (Desc);
    FilePathSize = GetDevicePathSize (FilePath);

    TempByteBuffer = AllocateZeroPool (sizeof (UINT32) + sizeof (UINT16) + DescSize + FilePathSize);
    if (TempByteBuffer != NULL) {
      TempByteStart               = TempByteBuffer;
      *((UINT32 *)TempByteBuffer) = LOAD_OPTION_ACTIVE;       // Attributes
      TempByteBuffer             += sizeof (UINT32);

      *((UINT16 *)TempByteBuffer) = (UINT16)FilePathSize;     // FilePathListLength
      TempByteBuffer             += sizeof (UINT16);

      CopyMem (TempByteBuffer, Desc, DescSize);
      TempByteBuffer += DescSize;
      ASSERT (FilePath != NULL);
      CopyMem (TempByteBuffer, FilePath, FilePathSize);

      UnicodeSPrint (OptionStr, sizeof (OptionStr), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", TargetLocation);
      Status = gRT->SetVariable (
                      OptionStr,
                      &gEfiGlobalVariableGuid,
                      EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
                      sizeof (UINT32) + sizeof (UINT16) + DescSize + FilePathSize,
                      TempByteStart
                      );

      FreePool (TempByteStart);
    } else {
      Status = EFI_OUT_OF_RESOURCES;
    }

    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);
    } else {
      NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (NewOrder[0]));
      if (NewOrder != NULL) {
        CopyMem (NewOrder, CurrentOrder, (OrderCount) * sizeof (NewOrder[0]));

        //
        // Insert target into order list
        //
        for (Index = OrderCount; Index > Position; Index--) {
          NewOrder[Index] = NewOrder[Index - 1];
        }

        NewOrder[Position] = (UINT16)TargetLocation;
        Status             = gRT->SetVariable (
                                    Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder",
                                    &gEfiGlobalVariableGuid,
                                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                                    (OrderCount + 1) * sizeof (UINT16),
                                    NewOrder
                                    );

        FreePool (NewOrder);

        if (EFI_ERROR (Status)) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder");
          ShellStatus = SHELL_INVALID_PARAMETER;
        } else {
          Print (L"bcfg: Add %s as %x\n", OptionStr, Position);
        }
      }
    }
  }

  //
  // If always Free FilePath, will free devicepath in system when use "addh"
  //
  if ((FilePath != NULL) && !UseHandle) {
    FreePool (FilePath);
  }

  if (Str != NULL) {
    FreePool (Str);
  }

  if (Handles != NULL) {
    FreePool (Handles);
  }

  if (FileList != NULL) {
    ShellCloseFileMetaArg (&FileList);
  }

  return (ShellStatus);
}

/**
  Function to remove an item.

  @param[in] Target         The target item to move.
  @param[in] CurrentOrder   The pointer to the current order of items.
  @param[in] OrderCount     The number if items in CurrentOrder.
  @param[in] Location       The current location of the Target.

  @retval SHELL_SUCCESS             The operation was successful.
  @retval SHELL_INVALID_PARAMETER   A parameter was invalid.
**/
SHELL_STATUS
BcfgRemove (
  IN CONST BCFG_OPERATION_TARGET  Target,
  IN CONST UINT16                 *CurrentOrder,
  IN CONST UINTN                  OrderCount,
  IN CONST UINT16                 Location
  )
{
  CHAR16      VariableName[12];
  UINT16      *NewOrder;
  EFI_STATUS  Status;
  UINTN       NewCount;

  UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Target == BcfgTargetBootOrder ? L"Boot" : L"Driver", CurrentOrder[Location]);
  Status = gRT->SetVariable (
                  VariableName,
                  (EFI_GUID *)&gEfiGlobalVariableGuid,
                  EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
                  0,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
    return (SHELL_INVALID_PARAMETER);
  }

  NewOrder = AllocateZeroPool (OrderCount*sizeof (CurrentOrder[0]));
  if (NewOrder != NULL) {
    NewCount = OrderCount;
    CopyMem (NewOrder, CurrentOrder, OrderCount*sizeof (CurrentOrder[0]));
    CopyMem (NewOrder+Location, NewOrder+Location+1, (OrderCount - Location - 1)*sizeof (CurrentOrder[0]));
    NewCount--;

    Status = gRT->SetVariable (
                    Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
                    (EFI_GUID *)&gEfiGlobalVariableGuid,
                    EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
                    NewCount*sizeof (NewOrder[0]),
                    NewOrder
                    );
    FreePool (NewOrder);
  } else {
    Status = EFI_OUT_OF_RESOURCES;
  }

  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder");
    return (SHELL_INVALID_PARAMETER);
  }

  return (SHELL_SUCCESS);
}

/**
  Function to move a item to another location.

  @param[in] Target         The target item to move.
  @param[in] CurrentOrder   The pointer to the current order of items.
  @param[in] OrderCount     The number if items in CurrentOrder.
  @param[in] OldLocation    The current location of the Target.
  @param[in] NewLocation    The desired location of the Target.

  @retval SHELL_SUCCESS             The operation was successful.
  @retval SHELL_INVALID_PARAMETER   A parameter was invalid.
**/
SHELL_STATUS
BcfgMove (
  IN CONST BCFG_OPERATION_TARGET  Target,
  IN CONST UINT16                 *CurrentOrder,
  IN CONST UINTN                  OrderCount,
  IN CONST UINT16                 OldLocation,
  IN       UINT16                 NewLocation
  )
{
  UINT16      *NewOrder;
  EFI_STATUS  Status;
  UINT16      Temp;

  NewOrder = AllocateCopyPool (OrderCount*sizeof (CurrentOrder[0]), CurrentOrder);
  if (NewOrder == NULL) {
    return (SHELL_OUT_OF_RESOURCES);
  }

  //
  // correct the new location
  //
  if (NewLocation >= OrderCount) {
    if (OrderCount > 0) {
      NewLocation = (UINT16)OrderCount - 1;
    } else {
      NewLocation = 0;
    }
  }

  Temp = CurrentOrder[OldLocation];
  CopyMem (NewOrder+OldLocation, NewOrder+OldLocation+1, (OrderCount - OldLocation - 1)*sizeof (CurrentOrder[0]));
  CopyMem (NewOrder+NewLocation+1, NewOrder+NewLocation, (OrderCount - NewLocation - 1)*sizeof (CurrentOrder[0]));
  NewOrder[NewLocation] = Temp;

  Status = gRT->SetVariable (
                  Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
                  (EFI_GUID *)&gEfiGlobalVariableGuid,
                  EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
                  OrderCount*sizeof (CurrentOrder[0]),
                  NewOrder
                  );

  FreePool (NewOrder);

  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder");
    return (SHELL_INVALID_PARAMETER);
  }

  return (SHELL_SUCCESS);
}

/**
  Function to add optional data to an option.

  @param[in] OptData      The optional data to add.
  @param[in] CurrentOrder The pointer to the current order of items.
  @param[in] OrderCount   The number if items in CurrentOrder.
  @param[in] Target       The target of the operation.

  @retval SHELL_SUCCESS   The operation was succesful.
**/
SHELL_STATUS
BcfgAddOpt (
  IN CONST CHAR16                 *OptData,
  IN CONST UINT16                 *CurrentOrder,
  IN CONST UINTN                  OrderCount,
  IN CONST BCFG_OPERATION_TARGET  Target
  )
{
  EFI_KEY_OPTION  NewKeyOption;
  EFI_KEY_OPTION  *KeyOptionBuffer;
  SHELL_STATUS    ShellStatus;
  EFI_STATUS      Status;
  UINT16          OptionIndex;
  UINT16          LoopCounter;
  UINT64          Intermediate;
  CONST CHAR16    *Temp;
  CONST CHAR16    *Walker;
  CHAR16          *FileName;
  CHAR16          *Temp2;
  CHAR16          *Data;
  UINT32          KeyIndex;
  CHAR16          VariableName[12];
  VOID            *VariableData;

  SHELL_FILE_HANDLE  FileHandle;

  Status          = EFI_SUCCESS;
  ShellStatus     = SHELL_SUCCESS;
  Walker          = OptData;
  FileName        = NULL;
  Data            = NULL;
  KeyOptionBuffer = NULL;
  VariableData    = NULL;

  ZeroMem (&NewKeyOption, sizeof (EFI_KEY_OPTION));
  ZeroMem (VariableName, sizeof (VariableName));

  while (Walker[0] == L' ') {
    Walker++;
  }

  //
  // Get the index of the variable we are changing.
  //
  Status = ShellConvertStringToUint64 (Walker, &Intermediate, TRUE, TRUE);
  if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL) || (((UINT16)Intermediate) > ((UINT16)OrderCount))) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");
    ShellStatus = SHELL_INVALID_PARAMETER;
    return (ShellStatus);
  }

  OptionIndex = (UINT16)Intermediate;

  Temp = StrStr (Walker, L" ");
  if (Temp != NULL) {
    Walker = Temp;
  }

  while (Walker[0] == L' ') {
    Walker++;
  }

  //
  // determine whether we have file with data, quote delimited information, or a hot-key
  //
  if (Walker[0] == L'\"') {
    //
    // quoted filename or quoted information.
    //
    Temp = StrStr (Walker+1, L"\"");
    if ((Temp == NULL) || (StrLen (Temp) != 1)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      FileName = StrnCatGrow (&FileName, NULL, Walker+1, 0);
      if (FileName == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellBcfgHiiHandle, L"bcfg");
        ShellStatus = SHELL_OUT_OF_RESOURCES;
        return (ShellStatus);
      }

      Temp2 = StrStr (FileName, L"\"");
      ASSERT (Temp2 != NULL);
      Temp2[0] = CHAR_NULL;
      Temp2++;
      if (StrLen (Temp2) > 0) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
        ShellStatus = SHELL_INVALID_PARAMETER;
      }

      if (EFI_ERROR (ShellFileExists (Walker))) {
        //
        // Not a file.  must be misc information.
        //
        Data     = FileName;
        FileName = NULL;
      } else {
        FileName = StrnCatGrow (&FileName, NULL, Walker, 0);
      }
    }
  } else {
    //
    // filename or hot key information.
    //
    if (StrStr (Walker, L" ") == NULL) {
      //
      // filename
      //
      if (EFI_ERROR (ShellFileExists (Walker))) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellBcfgHiiHandle, L"bcfg", Walker);
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        FileName = StrnCatGrow (&FileName, NULL, Walker, 0);
      }
    } else {
      if (Target != BcfgTargetBootOrder) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_BOOT_ONLY), gShellBcfgHiiHandle, L"bcfg");
        ShellStatus = SHELL_INVALID_PARAMETER;
      }

      if (ShellStatus == SHELL_SUCCESS) {
        //
        // Get hot key information
        //
        Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
        if (EFI_ERROR (Status) || (((UINT32)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL)) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }

        NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;
        Temp                             = StrStr (Walker, L" ");
        if (Temp != NULL) {
          Walker = Temp;
        }

        while (Walker[0] == L' ') {
          Walker++;
        }
      }

      if (ShellStatus == SHELL_SUCCESS) {
        //
        // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
        // Re-allocate with the added information.
        //
        KeyOptionBuffer = AllocatePool (sizeof (EFI_KEY_OPTION) + (sizeof (EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount));
        if (KeyOptionBuffer == NULL) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
          ShellStatus = SHELL_OUT_OF_RESOURCES;
          return ShellStatus;
        }

        CopyMem (KeyOptionBuffer, &NewKeyOption, sizeof (EFI_KEY_OPTION));
      }

      for (LoopCounter = 0; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {
        //
        // ScanCode
        //
        Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
        if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate) || (StrStr (Walker, L" ") == NULL)) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }

        ((EFI_INPUT_KEY *)(((UINT8 *)KeyOptionBuffer) + sizeof (EFI_KEY_OPTION)))[LoopCounter].ScanCode = (UINT16)Intermediate;
        Temp                                                                                            = StrStr (Walker, L" ");
        if (Temp != NULL) {
          Walker = Temp;
        }

        while (Walker[0] == L' ') {
          Walker++;
        }

        //
        // UnicodeChar
        //
        Status = ShellConvertStringToUint64 (Walker, &Intermediate, FALSE, TRUE);
        if (EFI_ERROR (Status) || (((UINT16)Intermediate) != Intermediate)) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }

        ((EFI_INPUT_KEY *)(((UINT8 *)KeyOptionBuffer) + sizeof (EFI_KEY_OPTION)))[LoopCounter].UnicodeChar = (UINT16)Intermediate;
        Temp                                                                                               = StrStr (Walker, L" ");
        if (Temp != NULL) {
          Walker = Temp;
        }

        while (Walker[0] == L' ') {
          Walker++;
        }
      }

      if (ShellStatus == SHELL_SUCCESS) {
        //
        // Now do the BootOption / BootOptionCrc
        //
        ASSERT (OptionIndex <= OrderCount);
        KeyOptionBuffer->BootOption = CurrentOrder[OptionIndex];
        Status                      = GetBootOptionCrc (&(KeyOptionBuffer->BootOptionCrc), KeyOptionBuffer->BootOption);
        if (EFI_ERROR (Status)) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
      }

      if (ShellStatus == SHELL_SUCCESS) {
        for (Temp2 = NULL, KeyIndex = 0; KeyIndex <= 0xFFFF; KeyIndex++) {
          UnicodeSPrint (VariableName, sizeof (VariableName), L"Key%04x", KeyIndex);
          Status = GetEfiGlobalVariable2 (VariableName, &VariableData, NULL);
          if (Status == EFI_NOT_FOUND) {
            break;
          }

          if (!EFI_ERROR (Status)) {
            SHELL_FREE_NON_NULL (VariableData);
          }
        }

        if (KeyIndex <= 0xFFFF) {
          Status = gRT->SetVariable (
                          VariableName,
                          (EFI_GUID *)&gEfiGlobalVariableGuid,
                          EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
                          sizeof (EFI_KEY_OPTION) + (sizeof (EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount),
                          KeyOptionBuffer
                          );
          if (EFI_ERROR (Status)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
            ShellStatus = SHELL_INVALID_PARAMETER;
          }
        } else {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_VAR_NO_NUM), gShellBcfgHiiHandle, L"bcfg");
          ShellStatus = SHELL_INVALID_PARAMETER;
        }

        ASSERT (FileName == NULL && Data == NULL);
      }
    }
  }

  //
  // Shouldn't be possible to have have both. Neither is ok though.
  //
  ASSERT (FileName == NULL || Data == NULL);

  if ((ShellStatus == SHELL_SUCCESS) && ((FileName != NULL) || (Data != NULL))) {
    if (FileName != NULL) {
      //
      // Open the file and populate the data buffer.
      //
      Status = ShellOpenFileByName (
                 FileName,
                 &FileHandle,
                 EFI_FILE_MODE_READ,
                 0
                 );
      if (!EFI_ERROR (Status)) {
        Status = ShellGetFileSize (FileHandle, &Intermediate);
      }

      Data = AllocateZeroPool ((UINTN)Intermediate);
      if (Data == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");
        ShellStatus = SHELL_OUT_OF_RESOURCES;
      }

      if (!EFI_ERROR (Status)) {
        Status = ShellReadFile (FileHandle, (UINTN *)&Intermediate, Data);
      }
    } else {
      Intermediate = StrSize (Data);
    }

    if (!EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS) && (Data != NULL)) {
      Status = UpdateOptionalData (CurrentOrder[OptionIndex], (UINTN)Intermediate, (UINT8 *)Data, Target);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
        ShellStatus = SHELL_INVALID_PARAMETER;
      }
    }

    if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
      ShellStatus = SHELL_INVALID_PARAMETER;
    }
  }

  SHELL_FREE_NON_NULL (Data);
  SHELL_FREE_NON_NULL (KeyOptionBuffer);
  SHELL_FREE_NON_NULL (FileName);
  return ShellStatus;
}

/**
  Function to dump the Bcfg information.

  @param[in] Op             The operation.
  @param[in] OrderCount     How many to dump.
  @param[in] CurrentOrder   The pointer to the current order of items.
  @param[in] VerboseOutput  TRUE for extra output.  FALSE otherwise.

  @retval SHELL_SUCCESS           The dump was successful.
  @retval SHELL_INVALID_PARAMETER A parameter was invalid.
**/
SHELL_STATUS
BcfgDisplayDump (
  IN CONST CHAR16   *Op,
  IN CONST UINTN    OrderCount,
  IN CONST UINT16   *CurrentOrder,
  IN CONST BOOLEAN  VerboseOutput
  )
{
  EFI_STATUS       Status;
  UINT8            *Buffer;
  UINTN            BufferSize;
  CHAR16           VariableName[12];
  UINTN            LoopVar;
  CHAR16           *DevPathString;
  VOID             *FilePathList;
  UINTN            Errors;
  EFI_LOAD_OPTION  *LoadOption;
  CHAR16           *Description;
  UINTN            DescriptionSize;
  UINTN            OptionalDataOffset;

  if (OrderCount == 0) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle, L"bcfg");
    return (SHELL_SUCCESS);
  }

  Errors = 0;

  for (LoopVar = 0; LoopVar < OrderCount; LoopVar++) {
    Buffer        = NULL;
    BufferSize    = 0;
    DevPathString = NULL;

    UnicodeSPrint (VariableName, sizeof (VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);

    Status = gRT->GetVariable (
                    VariableName,
                    (EFI_GUID *)&gEfiGlobalVariableGuid,
                    NULL,
                    &BufferSize,
                    Buffer
                    );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      Buffer = AllocateZeroPool (BufferSize);
      Status = gRT->GetVariable (
                      VariableName,
                      (EFI_GUID *)&gEfiGlobalVariableGuid,
                      NULL,
                      &BufferSize,
                      Buffer
                      );
    }

    if (EFI_ERROR (Status) || (Buffer == NULL)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);
      ++Errors;
      goto Cleanup;
    }

    //
    // We expect the Attributes, FilePathListLength, and L'\0'-terminated
    // Description fields to be present.
    //
    if (BufferSize < sizeof *LoadOption + sizeof (CHAR16)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_BCFG_VAR_CORRUPT),
        gShellBcfgHiiHandle,
        L"bcfg",
        VariableName
        );
      ++Errors;
      goto Cleanup;
    }

    LoadOption      = (EFI_LOAD_OPTION *)Buffer;
    Description     = (CHAR16 *)(Buffer + sizeof (EFI_LOAD_OPTION));
    DescriptionSize = StrSize (Description);

    if (LoadOption->FilePathListLength != 0) {
      FilePathList  = (UINT8 *)Description + DescriptionSize;
      DevPathString = ConvertDevicePathToText (FilePathList, TRUE, FALSE);
    }

    OptionalDataOffset = sizeof *LoadOption + DescriptionSize +
                         LoadOption->FilePathListLength;

    ShellPrintHiiEx (
      -1,
      -1,
      NULL,
      STRING_TOKEN (STR_BCFG_LOAD_OPTIONS),
      gShellBcfgHiiHandle,
      LoopVar,
      VariableName,
      Description,
      DevPathString,
      OptionalDataOffset >= BufferSize ? L'N' : L'Y'
      );
    if (VerboseOutput && (OptionalDataOffset < BufferSize)) {
      DumpHex (
        2,                               // Indent
        0,                               // Offset (displayed)
        BufferSize - OptionalDataOffset, // DataSize
        Buffer + OptionalDataOffset      // UserData
        );
    }

Cleanup:
    if (Buffer != NULL) {
      FreePool (Buffer);
    }

    if (DevPathString != NULL) {
      FreePool (DevPathString);
    }
  }

  return (Errors > 0) ? SHELL_INVALID_PARAMETER : SHELL_SUCCESS;
}

/**
  Function to initialize the BCFG operation structure.

  @param[in] Struct   The stuct to initialize.
**/
VOID
InitBcfgStruct (
  IN BGFG_OPERATION  *Struct
  )
{
  ASSERT (Struct != NULL);
  Struct->Target      = BcfgTargetMax;
  Struct->Type        = BcfgTypeMax;
  Struct->Number1     = 0;
  Struct->Number2     = 0;
  Struct->HandleIndex = 0;
  Struct->FileName    = NULL;
  Struct->Description = NULL;
  Struct->Order       = NULL;
  Struct->OptData     = NULL;
}

STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {
  { L"-v",   TypeFlag     },
  { L"-opt", TypeMaxValue },
  { NULL,    TypeMax      }
};

/**
  Function for 'bcfg' 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
ShellCommandRunBcfg (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS      Status;
  LIST_ENTRY      *Package;
  CHAR16          *ProblemParam;
  SHELL_STATUS    ShellStatus;
  UINTN           ParamNumber;
  CONST CHAR16    *CurrentParam;
  BGFG_OPERATION  CurrentOperation;
  UINTN           Length;
  UINT64          Intermediate;
  UINT16          Count;

  Length       = 0;
  ProblemParam = NULL;
  Package      = NULL;
  ShellStatus  = SHELL_SUCCESS;

  InitBcfgStruct (&CurrentOperation);

  //
  // 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 (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellBcfgHiiHandle, L"bcfg", ProblemParam);
      FreePool (ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT (FALSE);
    }
  } else {
    //
    // Read in if we are doing -OPT
    //
    if (ShellCommandLineGetFlag (Package, L"-opt")) {
      CurrentOperation.OptData = ShellCommandLineGetValue (Package, L"-opt");
      if (CurrentOperation.OptData == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellBcfgHiiHandle, L"bcfg", L"-opt");
        ShellStatus = SHELL_INVALID_PARAMETER;
      }

      CurrentOperation.Type = BcfgTypeOpt;
    }

    //
    // small block to read the target of the operation
    //
    if (((ShellCommandLineGetCount (Package) < 3) && (CurrentOperation.Type != BcfgTypeOpt)) ||
        ((ShellCommandLineGetCount (Package) < 2) && (CurrentOperation.Type == BcfgTypeOpt))
        )
    {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)ShellCommandLineGetRawValue (Package, 1), L"driver") == 0) {
      CurrentOperation.Target = BcfgTargetDriverOrder;
    } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)ShellCommandLineGetRawValue (Package, 1), L"boot") == 0) {
      CurrentOperation.Target = BcfgTargetBootOrder;
    } else {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellBcfgHiiHandle, L"bcfg");
      ShellStatus = SHELL_INVALID_PARAMETER;
    }

    //
    // Read in the boot or driver order environment variable (not needed for opt)
    //
    if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax)) {
      Length = 0;
      Status = gRT->GetVariable (
                      CurrentOperation.Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
                      (EFI_GUID *)&gEfiGlobalVariableGuid,
                      NULL,
                      &Length,
                      CurrentOperation.Order
                      );
      if (Status == EFI_BUFFER_TOO_SMALL) {
        CurrentOperation.Order = AllocateZeroPool (Length+(4*sizeof (CurrentOperation.Order[0])));
        if (CurrentOperation.Order == NULL) {
          ShellStatus = SHELL_OUT_OF_RESOURCES;
        } else {
          Status = gRT->GetVariable (
                          CurrentOperation.Target == BcfgTargetBootOrder ? (CHAR16 *)L"BootOrder" : (CHAR16 *)L"DriverOrder",
                          (EFI_GUID *)&gEfiGlobalVariableGuid,
                          NULL,
                          &Length,
                          CurrentOperation.Order
                          );
        }
      }
    }

    Count = (UINT16)(Length / sizeof (CurrentOperation.Order[0]));

    //
    // large block to read the type of operation and verify parameter types for the info.
    //
    if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax)) {
      for (ParamNumber = 2; ParamNumber < ShellCommandLineGetCount (Package) && ShellStatus == SHELL_SUCCESS; ParamNumber++) {
        CurrentParam = ShellCommandLineGetRawValue (Package, ParamNumber);
        if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"dump") == 0) {
          CurrentOperation.Type = BcfgTypeDump;
          if (ShellCommandLineGetCount (Package) > 3) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          }
        } else if (ShellCommandLineGetFlag (Package, L"-v")) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"-v (without dump)");
          ShellStatus = SHELL_INVALID_PARAMETER;
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"add") == 0) {
          if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          }

          CurrentOperation.Type = BcfgTypeAdd;
          CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
          if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
            CurrentOperation.Number1 = (UINT16)Intermediate;
            ASSERT (CurrentOperation.FileName == NULL);
            CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
            ASSERT (CurrentOperation.Description == NULL);
            CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
          }
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"addp") == 0) {
          if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          }

          CurrentOperation.Type = BcfgTypeAddp;
          CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
          if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
            CurrentOperation.Number1 = (UINT16)Intermediate;
            ASSERT (CurrentOperation.FileName == NULL);
            CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
            ASSERT (CurrentOperation.Description == NULL);
            CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
          }
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"addh") == 0) {
          if ((ParamNumber + 3) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          }

          CurrentOperation.Type = BcfgTypeAddh;
          CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
          if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
            CurrentOperation.Number1 = (UINT16)Intermediate;
            CurrentParam             = ShellCommandLineGetRawValue (Package, ++ParamNumber);
            if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
              ShellStatus = SHELL_INVALID_PARAMETER;
            } else {
              Status                       = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
              CurrentOperation.HandleIndex = (UINT16)Intermediate;
              ASSERT (CurrentOperation.Description == NULL);
              CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
            }
          }
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"rm") == 0) {
          if ((ParamNumber + 1) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          }

          CurrentOperation.Type = BcfgTypeRm;
          CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
          if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
            CurrentOperation.Number1 = (UINT16)Intermediate;
            if (CurrentOperation.Number1 >= Count) {
              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
              ShellStatus = SHELL_INVALID_PARAMETER;
            }
          }
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"mv") == 0) {
          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          }

          CurrentOperation.Type = BcfgTypeMv;
          CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
          if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
            CurrentOperation.Number1 = (UINT16)Intermediate;
            if (CurrentOperation.Number1 >= Count) {
              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
              ShellStatus = SHELL_INVALID_PARAMETER;
            } else {
              CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
              if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
                ShellStatus = SHELL_INVALID_PARAMETER;
              } else {
                Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
                CurrentOperation.Number2 = (UINT16)Intermediate;
              }

              if (  (CurrentOperation.Number2 == CurrentOperation.Number1)
                 || (CurrentOperation.Number2 >= Count)
                    )
              {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
                ShellStatus = SHELL_INVALID_PARAMETER;
              }
            }
          }
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"mod") == 0) {
          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            CurrentOperation.Type = BcfgTypeMod;
            CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
            if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
              ShellStatus = SHELL_INVALID_PARAMETER;
            } else {
              Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
              CurrentOperation.Number1 = (UINT16)Intermediate;
              if (CurrentOperation.Number1 >= Count) {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
                ShellStatus = SHELL_INVALID_PARAMETER;
              } else {
                ASSERT (CurrentOperation.Description == NULL);
                CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
              }
            }
          }
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modf") == 0) {
          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            CurrentOperation.Type = BcfgTypeModf;
            CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
            if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
              ShellStatus = SHELL_INVALID_PARAMETER;
            } else {
              Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
              CurrentOperation.Number1 = (UINT16)Intermediate;
              if (CurrentOperation.Number1 >= Count) {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
                ShellStatus = SHELL_INVALID_PARAMETER;
              } else {
                ASSERT (CurrentOperation.FileName == NULL);
                CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
              }
            }
          }
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modp") == 0) {
          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            CurrentOperation.Type = BcfgTypeModp;
            CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
            if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
              ShellStatus = SHELL_INVALID_PARAMETER;
            } else {
              Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
              CurrentOperation.Number1 = (UINT16)Intermediate;
              if (CurrentOperation.Number1 >= Count) {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
                ShellStatus = SHELL_INVALID_PARAMETER;
              } else {
                ASSERT (CurrentOperation.FileName == NULL);
                CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);
              }
            }
          }
        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)CurrentParam, L"modh") == 0) {
          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            CurrentOperation.Type = BcfgTypeModh;
            CurrentParam          = ShellCommandLineGetRawValue (Package, ++ParamNumber);
            if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
              ShellStatus = SHELL_INVALID_PARAMETER;
            } else {
              Status                   = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
              CurrentOperation.Number1 = (UINT16)Intermediate;
              if (CurrentOperation.Number1 >= Count) {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);
                ShellStatus = SHELL_INVALID_PARAMETER;
              } else {
                CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);
                if ((CurrentParam == NULL) || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {
                  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
                  ShellStatus = SHELL_INVALID_PARAMETER;
                } else {
                  Status                       = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);
                  CurrentOperation.HandleIndex = (UINT16)Intermediate;
                }
              }
            }
          }
        } else {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
      }
    }

    if ((ShellStatus == SHELL_SUCCESS) && (CurrentOperation.Target < BcfgTargetMax) && (CurrentOperation.Type < BcfgTypeMax)) {
      //
      // we have all the info.  Do the work
      //
      switch (CurrentOperation.Type) {
        case BcfgTypeDump:
          ShellStatus = BcfgDisplayDump (
                          CurrentOperation.Target == BcfgTargetBootOrder ? L"Boot" : L"Driver",
                          Count,
                          CurrentOperation.Order,
                          ShellCommandLineGetFlag (Package, L"-v")
                          );
          break;
        case BcfgTypeMv:
          ShellStatus = BcfgMove (
                          CurrentOperation.Target,
                          CurrentOperation.Order,
                          Count,
                          CurrentOperation.Number1,
                          CurrentOperation.Number2
                          );
          break;
        case BcfgTypeRm:
          ShellStatus = BcfgRemove (
                          CurrentOperation.Target,
                          CurrentOperation.Order,
                          Count,
                          CurrentOperation.Number1
                          );
          break;
        case BcfgTypeAdd:
        case BcfgTypeAddp:
        case BcfgTypeAddh:
          ShellStatus = BcfgAdd (
                          CurrentOperation.Number1,
                          CurrentOperation.FileName,
                          CurrentOperation.Description == NULL ? L"" : CurrentOperation.Description,
                          CurrentOperation.Order,
                          Count,
                          CurrentOperation.Target,
                          (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddh),
                          (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),
                          CurrentOperation.HandleIndex
                          );
          break;
        case BcfgTypeMod:
        case BcfgTypeModf:
        case BcfgTypeModp:
        case BcfgTypeModh:
          ShellStatus = BcfgMod (&CurrentOperation, Count);
          break;
        case BcfgTypeOpt:
          ShellStatus = BcfgAddOpt (
                          CurrentOperation.OptData,
                          CurrentOperation.Order,
                          Count,
                          CurrentOperation.Target
                          );
          break;
        default:
          ASSERT (FALSE);
      }
    }
  }

  if (Package != NULL) {
    ShellCommandLineFreeVarList (Package);
  }

  if (CurrentOperation.FileName != NULL) {
    FreePool (CurrentOperation.FileName);
  }

  if (CurrentOperation.Description != NULL) {
    FreePool (CurrentOperation.Description);
  }

  if (CurrentOperation.Order != NULL) {
    FreePool (CurrentOperation.Order);
  }

  return (ShellStatus);
}

/**
  Function to get the filename with help context if HII will not be used.

  @return   The filename with help text in it.
**/
CONST CHAR16 *
EFIAPI
ShellCommandGetManFileNameBcfg (
  VOID
  )
{
  return (mFileName);
}

/**
  "Constructor" for the library.

  This will register the handler for the bcfg command.

  @param[in] ImageHandle    the image handle of the process
  @param[in] SystemTable    the EFI System Table pointer
  @param[in] Name           the profile name to use

  @retval EFI_SUCCESS        the shell command handlers were installed successfully
  @retval EFI_UNSUPPORTED    the shell level required was not found.
**/
EFI_STATUS
EFIAPI
BcfgLibraryRegisterBcfgCommand (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable,
  IN CONST CHAR16      *Name
  )
{
  if (gShellBcfgHiiHandle != NULL) {
    return (EFI_SUCCESS);
  }

  gShellBcfgHiiHandle = HiiAddPackages (&gShellBcfgHiiGuid, gImageHandle, UefiShellBcfgCommandLibStrings, NULL);
  if (gShellBcfgHiiHandle == NULL) {
    return (EFI_DEVICE_ERROR);
  }

  //
  // install our shell command handler
  //
  ShellCommandRegisterCommandName (L"bcfg", ShellCommandRunBcfg, ShellCommandGetManFileNameBcfg, 0, Name, FALSE, gShellBcfgHiiHandle, STRING_TOKEN (STR_GET_HELP_BCFG));

  return (EFI_SUCCESS);
}

/**
  Destructor for the library.  free any resources.

  @param ImageHandle            The image handle of the process.
  @param SystemTable            The EFI System Table pointer.
**/
EFI_STATUS
EFIAPI
BcfgLibraryUnregisterBcfgCommand (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  if (gShellBcfgHiiHandle != NULL) {
    HiiRemovePackages (gShellBcfgHiiHandle);
  }

  gShellBcfgHiiHandle = NULL;
  return (EFI_SUCCESS);
}
