/** @file
  Main file for BCFG command.

  (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/


#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_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 occured.
**/
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 = AllocateCopyPool(NewSize, OriginalData);
    if (NewData == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
    } else {
      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 occured.
**/
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, FALSE, 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 = AllocateCopyPool(sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount), &NewKeyOption);
        if (KeyOptionBuffer == NULL) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");  
          ShellStatus = SHELL_OUT_OF_RESOURCES;
        }
      }
      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);
}

