/** @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 optioanl data.
  @param[in]      Target    The target of the operation.

  @retval EFI_SUCCESS       The data was sucessfully 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 sucessfully 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 sucessful return the device path to the handle.

  @retval EFI_SUCCESS           The device path was sucessfully 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);
}

/**
  Functino 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 sucessful 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);
}

/**
  Funciton 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);
}

/**
  Funciton 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 sucessfully
  @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);
}
