]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.c
ShellPkg: stop using EFI_HANDLE in place of EFI_HII_HANDLE
[mirror_edk2.git] / ShellPkg / Library / UefiShellBcfgCommandLib / UefiShellBcfgCommandLib.c
index f5ae7bc0d9de6fdd7d9cfada2a6215d704323b07..f8bcaebe46c855bbaebfd0bf1f5e9215afb265bc 100644 (file)
@@ -2,26 +2,19 @@
   Main file for BCFG command.\r
 \r
   (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>\r
-  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
 #include <Uefi.h>\r
-#include <ShellBase.h>\r
 \r
 #include <Guid/GlobalVariable.h>\r
 #include <Guid/ShellLibHiiGuid.h>\r
 \r
-#include <Protocol/EfiShell.h>\r
-#include <Protocol/EfiShellParameters.h>\r
+#include <Protocol/Shell.h>\r
+#include <Protocol/ShellParameters.h>\r
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/LoadedImage.h>\r
 #include <Protocol/UnicodeCollation.h>\r
 #include <Library/PrintLib.h>\r
 #include <Library/HandleParsingLib.h>\r
 #include <Library/DevicePathLib.h>\r
+#include <Library/UefiBootManagerLib.h>\r
 \r
 STATIC CONST CHAR16 mFileName[] = L"ShellCommands";\r
-STATIC EFI_HANDLE gShellBcfgHiiHandle  = NULL;\r
+STATIC EFI_HII_HANDLE gShellBcfgHiiHandle  = NULL;\r
 \r
 typedef enum {\r
   BcfgTargetBootOrder    = 0,\r
@@ -60,7 +54,11 @@ typedef enum {
   BcfgTypeRm         = 4,\r
   BcfgTypeMv         = 5,\r
   BcfgTypeOpt        = 6,\r
-  BcfgTypeMax        = 7\r
+  BcfgTypeMod        = 7,\r
+  BcfgTypeModf       = 8,\r
+  BcfgTypeModp       = 9,\r
+  BcfgTypeModh       = 10,\r
+  BcfgTypeMax        = 11\r
 } BCFG_OPERATION_TYPE;\r
 \r
 typedef struct {\r
@@ -89,10 +87,9 @@ typedef struct {
   @retval other             A error occured.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 UpdateOptionalData(\r
-  UINT16                          Index, \r
-  UINTN                           DataSize, \r
+  UINT16                          Index,\r
+  UINTN                           DataSize,\r
   UINT8                           *Data,\r
   IN CONST BCFG_OPERATION_TARGET  Target\r
   )\r
@@ -106,7 +103,7 @@ UpdateOptionalData(
   UINTN       OriginalOptionDataSize;\r
 \r
   UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Target == BcfgTargetBootOrder?L"Boot":L"Driver", Index);\r
-  \r
+\r
   OriginalSize = 0;\r
   OriginalData = NULL;\r
   NewData      = NULL;\r
@@ -140,10 +137,11 @@ UpdateOptionalData(
     OriginalOptionDataSize += (*(UINT16*)(OriginalData + sizeof(UINT32)));\r
     OriginalOptionDataSize -= OriginalSize;\r
     NewSize = OriginalSize - OriginalOptionDataSize + DataSize;\r
-    NewData = AllocateCopyPool(NewSize, OriginalData);\r
+    NewData = AllocatePool(NewSize);\r
     if (NewData == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
     } else {\r
+      CopyMem (NewData, OriginalData, OriginalSize - OriginalOptionDataSize);\r
       CopyMem(NewData + OriginalSize - OriginalOptionDataSize, Data, DataSize);\r
     }\r
   }\r
@@ -153,7 +151,7 @@ UpdateOptionalData(
     // put the data back under the variable\r
     //\r
     Status = gRT->SetVariable(\r
-      VariableName, \r
+      VariableName,\r
       (EFI_GUID*)&gEfiGlobalVariableGuid,\r
       EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
       NewSize,\r
@@ -175,9 +173,8 @@ UpdateOptionalData(
   @retval other                 A error occured.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 GetBootOptionCrc(\r
-  UINT32      *Crc, \r
+  UINT32      *Crc,\r
   UINT16      BootIndex\r
   )\r
 {\r
@@ -232,7 +229,6 @@ GetBootOptionCrc(
   @sa HandleProtocol\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 GetDevicePathForDriverHandle (\r
   IN EFI_HANDLE                   TheHandle,\r
   IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath\r
@@ -278,6 +274,248 @@ GetDevicePathForDriverHandle (
   return (Status);\r
 }\r
 \r
+/**\r
+  Functino to get Device Path by a handle.\r
+\r
+  @param[in]        TheHandle   Use it to get DevicePath.\r
+  @param[in]        Target      Boot option target.\r
+  @param[in, out]   DevicePath  On a sucessful return the device path to the handle.\r
+\r
+  @retval   SHELL_INVALID_PARAMETER The handle was NULL.\r
+  @retval   SHELL_NOT_FOUND         Not found device path by handle.\r
+  @retval   SHELL_SUCCESS           Get device path successfully.\r
+**/\r
+SHELL_STATUS\r
+GetDevicePathByHandle(\r
+  IN     EFI_HANDLE               TheHandle,\r
+  IN     BCFG_OPERATION_TARGET    Target,\r
+  IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
+  )\r
+{\r
+  EFI_STATUS   Status;\r
+  SHELL_STATUS ShellStatus;\r
+\r
+  UINTN DriverBindingHandleCount;\r
+  UINTN ParentControllerHandleCount;\r
+  UINTN ChildControllerHandleCount;\r
+\r
+  ShellStatus = SHELL_SUCCESS;\r
+\r
+  if (TheHandle == NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");\r
+    return SHELL_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle, &DriverBindingHandleCount, NULL);\r
+  if (EFI_ERROR(Status)) {\r
+    DriverBindingHandleCount = 0;\r
+  }\r
+\r
+  Status = PARSE_HANDLE_DATABASE_PARENTS (TheHandle, &ParentControllerHandleCount, NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    ParentControllerHandleCount = 0;\r
+  }\r
+\r
+  Status = ParseHandleDatabaseForChildControllers (TheHandle, &ChildControllerHandleCount, NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    ChildControllerHandleCount = 0;\r
+  }\r
+\r
+  Status = gBS->HandleProtocol (TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)DevicePath);\r
+\r
+  if ( DriverBindingHandleCount    > 0 ||\r
+       ParentControllerHandleCount > 0 ||\r
+       ChildControllerHandleCount  > 0 ||\r
+       !EFI_ERROR(Status)\r
+     ) {\r
+    //\r
+    // The handle points to a real controller which has a device path.\r
+    //\r
+    if (Target == BcfgTargetDriverOrder) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,STRING_TOKEN (STR_GEN_PARAM_INV),\r
+        gShellBcfgHiiHandle,\r
+        L"bcfg",\r
+        L"Handle should point to driver image."\r
+      );\r
+      ShellStatus = SHELL_NOT_FOUND;\r
+    }\r
+  } else {\r
+    //\r
+    // The handle points to a driver image.\r
+    //\r
+    if (Target == BcfgTargetBootOrder) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_PARAM_INV),\r
+        gShellBcfgHiiHandle,\r
+        L"bcfg",\r
+        L"Handle should point to controller."\r
+      );\r
+      ShellStatus = SHELL_NOT_FOUND;\r
+    } else {\r
+      if (EFI_ERROR (GetDevicePathForDriverHandle (TheHandle, DevicePath))) {\r
+        ShellStatus = SHELL_NOT_FOUND;\r
+      }\r
+    }\r
+  }\r
+\r
+  return (ShellStatus);\r
+}\r
+\r
+/**\r
+  Function to modify an option.\r
+\r
+  @param[in] BcfgOperation  Pointer to BCFG operation.\r
+  @param[in] OrderCount     The number if items in CurrentOrder.\r
+\r
+  @retval SHELL_SUCCESS             The operation was successful.\r
+  @retval SHELL_INVALID_PARAMETER   A parameter was invalid.\r
+  @retval SHELL_OUT_OF_RESOUCES     A memory allocation failed.\r
+**/\r
+SHELL_STATUS\r
+BcfgMod (\r
+  IN CONST BGFG_OPERATION   *BcfgOperation,\r
+  IN CONST UINTN            OrderCount\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    CurHandle;\r
+  SHELL_STATUS                  ShellStatus;\r
+  CHAR16                        OptionStr[40];\r
+  EFI_SHELL_FILE_INFO           *FileList;\r
+  EFI_SHELL_FILE_INFO           *Arg;\r
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePathBuffer;\r
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePathWalker;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION  LoadOption;\r
+\r
+  ShellStatus       = SHELL_SUCCESS;\r
+  FileList          = NULL;\r
+  DevicePath        = NULL;\r
+  DevicePathBuffer  = NULL;\r
+\r
+  ZeroMem (&LoadOption, sizeof(EFI_BOOT_MANAGER_LOAD_OPTION));\r
+\r
+  if ( (BcfgOperation->Type == BcfgTypeMod  && BcfgOperation->Description == NULL)  ||\r
+       (BcfgOperation->Type == BcfgTypeModf && BcfgOperation->FileName == NULL)     ||\r
+       (BcfgOperation->Type == BcfgTypeModp && BcfgOperation->FileName == NULL)     ||\r
+       (BcfgOperation->Type == BcfgTypeModh && BcfgOperation->HandleIndex == 0)     ||\r
+       (BcfgOperation->Number1 > OrderCount)\r
+     ) {\r
+    return (SHELL_INVALID_PARAMETER);\r
+  }\r
+\r
+  if (BcfgOperation->Type == BcfgTypeModh) {\r
+    CurHandle = ConvertHandleIndexToHandle (BcfgOperation->HandleIndex);\r
+    ShellStatus = GetDevicePathByHandle (CurHandle, BcfgOperation->Target, &DevicePathBuffer);\r
+    if (ShellStatus == SHELL_SUCCESS) {\r
+      DevicePath = DuplicateDevicePath (DevicePathBuffer);\r
+    }\r
+  } else if (BcfgOperation->Type == BcfgTypeModf || BcfgOperation->Type == BcfgTypeModp) {\r
+    //\r
+    // Get Device Path by FileName.\r
+    //\r
+    ShellOpenFileMetaArg ((CHAR16 *)BcfgOperation->FileName, EFI_FILE_MODE_READ, &FileList);\r
+    if (FileList == NULL) {\r
+      //\r
+      // The name of file matched nothing.\r
+      //\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+    }\r
+    else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {\r
+      //\r
+      // If the name of file expanded to multiple names, it's fail.\r
+      //\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+    } else {\r
+      Arg = (EFI_SHELL_FILE_INFO *)GetFirstNode (&FileList->Link);\r
+      if (EFI_ERROR (Arg->Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", BcfgOperation->FileName);\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+      } else {\r
+        DevicePathBuffer = gEfiShellProtocol->GetDevicePathFromFilePath (Arg->FullName);\r
+        if (DevicePathBuffer == NULL) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);\r
+          ShellStatus = SHELL_UNSUPPORTED;\r
+        }\r
+      }\r
+    }\r
+\r
+    if (ShellStatus == SHELL_SUCCESS) {\r
+      if (BcfgOperation->Type == BcfgTypeModp) {\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        DevicePathWalker = DevicePathBuffer;\r
+        while (!IsDevicePathEnd (DevicePathWalker)) {\r
+          if ( DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH &&\r
+               DevicePathSubType (DevicePathWalker) == MEDIA_HARDDRIVE_DP\r
+             ) {\r
+            //\r
+            // We found the portion of device path starting with the hard driver partition.\r
+            //\r
+            ShellStatus = SHELL_SUCCESS;\r
+            DevicePath = DuplicateDevicePath (DevicePathWalker);\r
+            break;\r
+          } else {\r
+            DevicePathWalker = NextDevicePathNode (DevicePathWalker);\r
+          }\r
+        }\r
+      } else {\r
+        DevicePath = DuplicateDevicePath (DevicePathBuffer);\r
+      }\r
+\r
+      FreePool (DevicePathBuffer);\r
+    }\r
+  }\r
+\r
+  if (ShellStatus == SHELL_SUCCESS) {\r
+    if (BcfgOperation->Target == BcfgTargetBootOrder) {\r
+      UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Boot%04x", BcfgOperation->Order[BcfgOperation->Number1]);\r
+    } else {\r
+      UnicodeSPrint (OptionStr, sizeof (OptionStr), L"Driver%04x", BcfgOperation->Order[BcfgOperation->Number1]);\r
+    }\r
+    Status = EfiBootManagerVariableToLoadOption (OptionStr, &LoadOption);\r
+    if (EFI_ERROR(Status)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NONE), gShellBcfgHiiHandle);\r
+      ShellStatus = SHELL_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  if (ShellStatus == SHELL_SUCCESS) {\r
+    if (BcfgOperation->Type == BcfgTypeMod) {\r
+      SHELL_FREE_NON_NULL (LoadOption.Description);\r
+      LoadOption.Description = AllocateCopyPool (StrSize (BcfgOperation->Description), BcfgOperation->Description);\r
+    } else {\r
+      SHELL_FREE_NON_NULL (LoadOption.FilePath);\r
+      LoadOption.FilePath = DuplicateDevicePath (DevicePath);\r
+    }\r
+\r
+    Status = EfiBootManagerLoadOptionToVariable (&LoadOption);\r
+    if (EFI_ERROR(Status)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  EfiBootManagerFreeLoadOption (&LoadOption);\r
+\r
+  if (DevicePath != NULL) {\r
+    FreePool (DevicePath);\r
+  }\r
+\r
+  if (FileList != NULL) {\r
+    ShellCloseFileMetaArg (&FileList);\r
+  }\r
+\r
+  return (ShellStatus);\r
+}\r
+\r
 /**\r
   Function to add a option.\r
 \r
@@ -295,7 +533,6 @@ GetDevicePathForDriverHandle (
   @retval SHELL_INVALID_PARAMETER   A parameter was invalid.\r
 **/\r
 SHELL_STATUS\r
-EFIAPI\r
 BcfgAdd(\r
   IN       UINTN                  Position,\r
   IN CONST CHAR16                 *File,\r
@@ -310,6 +547,7 @@ BcfgAdd(
 {\r
   EFI_STATUS                Status;\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
   EFI_DEVICE_PATH_PROTOCOL  *FilePath;\r
   CHAR16                    *Str;\r
   UINT8                     *TempByteBuffer;\r
@@ -385,7 +623,7 @@ BcfgAdd(
                      (VOID**)&FilePath);\r
         }\r
         if (EFI_ERROR (Status)) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellBcfgHiiHandle, L"bcfg", HandleNumber);  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_HANDLE), gShellBcfgHiiHandle, L"bcfg", HandleNumber);\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         }\r
       } else {\r
@@ -416,7 +654,7 @@ BcfgAdd(
               || ParentControllerHandleCount > 0\r
               || ChildControllerHandleCount > 0\r
               || !EFI_ERROR(Status) ) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Handle Number");\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         } else {\r
           //\r
@@ -436,18 +674,18 @@ BcfgAdd(
       //\r
       // If filename matched nothing fail\r
       //\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", File);  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellBcfgHiiHandle, L"bcfg", File);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else if (FileList->Link.ForwardLink != FileList->Link.BackLink) {\r
       //\r
       // If filename expanded to multiple names, fail\r
       //\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", File);  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE), gShellBcfgHiiHandle, L"bcfg", File);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
       Arg = (EFI_SHELL_FILE_INFO*)GetFirstNode(&FileList->Link);\r
       if (EFI_ERROR(Arg->Status)) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", File);  \r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_OPEN), gShellBcfgHiiHandle, L"bcfg", File);\r
         ShellStatus = SHELL_INVALID_PARAMETER;\r
       } else {\r
         //\r
@@ -459,12 +697,12 @@ BcfgAdd(
         //\r
         DevicePath = gEfiShellProtocol->GetDevicePathFromFilePath(Arg->FullName);\r
         if (DevicePath == NULL) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_FILE_DP), gShellBcfgHiiHandle, L"bcfg", Arg->FullName);\r
           ShellStatus = SHELL_UNSUPPORTED;\r
         } else {\r
-/*\r
           if (UsePath) {\r
-            DevPath = DevicePath;\r
+            DevPath     = DevicePath;\r
+            ShellStatus = SHELL_INVALID_PARAMETER;\r
             while (!IsDevicePathEnd(DevPath)) {\r
               if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&\r
                 (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {\r
@@ -472,24 +710,15 @@ BcfgAdd(
                 //\r
                 // If we find it use it instead\r
                 //\r
-                DevicePath = DevPath;\r
+                ShellStatus = SHELL_SUCCESS;\r
+                FilePath    = DuplicateDevicePath (DevPath);\r
                 break;\r
               }\r
               DevPath = NextDevicePathNode(DevPath);\r
             }\r
-            //\r
-            // append the file\r
-            //\r
-            for(StringWalker=Arg->FullName; *StringWalker != CHAR_NULL && *StringWalker != ':'; StringWalker++);\r
-            FileNode = FileDevicePath(NULL, StringWalker+1);\r
-            FilePath = AppendDevicePath(DevicePath, FileNode);\r
-            FreePool(FileNode);\r
           } else {\r
-*/\r
             FilePath = DuplicateDevicePath(DevicePath);\r
-/*\r
           }\r
-*/\r
           FreePool(DevicePath);\r
         }\r
       }\r
@@ -517,7 +746,7 @@ BcfgAdd(
     }\r
 \r
     if (TargetLocation == 0xFFFF) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellBcfgHiiHandle, L"bcfg");  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET_NF), gShellBcfgHiiHandle, L"bcfg");\r
     } else {\r
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_TARGET), gShellBcfgHiiHandle, TargetLocation);\r
     }\r
@@ -559,35 +788,36 @@ BcfgAdd(
     }\r
 \r
     if (EFI_ERROR(Status)) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", OptionStr);\r
     } else {\r
-      NewOrder = AllocateZeroPool((OrderCount+1)*sizeof(NewOrder[0]));\r
-      ASSERT(NewOrder != NULL);\r
-      CopyMem(NewOrder, CurrentOrder, (OrderCount)*sizeof(NewOrder[0]));\r
+      NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (NewOrder[0]));\r
+      if (NewOrder != NULL) {\r
+        CopyMem (NewOrder, CurrentOrder, (OrderCount) * sizeof (NewOrder[0]));\r
 \r
-      //\r
-      // Insert target into order list\r
-      //\r
-      for (Index=OrderCount; Index > Position; Index--) {\r
-        NewOrder[Index] = NewOrder[Index-1];\r
-      }\r
+        //\r
+        // Insert target into order list\r
+        //\r
+        for (Index = OrderCount; Index > Position; Index--) {\r
+          NewOrder[Index] = NewOrder[Index - 1];\r
+        }\r
 \r
-      NewOrder[Position] = (UINT16) TargetLocation;\r
-      Status = gRT->SetVariable (\r
-        Target == BcfgTargetBootOrder?L"BootOrder":L"DriverOrder",\r
-        &gEfiGlobalVariableGuid,\r
-        EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,\r
-        (OrderCount+1) * sizeof(UINT16),\r
-        NewOrder\r
-       );\r
+        NewOrder[Position] = (UINT16) TargetLocation;\r
+        Status = gRT->SetVariable (\r
+          Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder",\r
+          &gEfiGlobalVariableGuid,\r
+          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+          (OrderCount + 1) * sizeof (UINT16),\r
+          NewOrder\r
+        );\r
 \r
-      FreePool(NewOrder);\r
+        FreePool (NewOrder);\r
 \r
-      if (EFI_ERROR(Status)) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder?L"BootOrder":L"DriverOrder");  \r
-        ShellStatus = SHELL_INVALID_PARAMETER;\r
-      } else {\r
-        Print (L"bcfg: Add %s as %x\n", OptionStr, Position);\r
+        if (EFI_ERROR (Status)) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder ? L"BootOrder" : L"DriverOrder");\r
+          ShellStatus = SHELL_INVALID_PARAMETER;\r
+        } else {\r
+          Print (L"bcfg: Add %s as %x\n", OptionStr, Position);\r
+        }\r
       }\r
     }\r
   }\r
@@ -626,7 +856,6 @@ BcfgAdd(
   @retval SHELL_INVALID_PARAMETER   A parameter was invalid.\r
 **/\r
 SHELL_STATUS\r
-EFIAPI\r
 BcfgRemove(\r
   IN CONST BCFG_OPERATION_TARGET  Target,\r
   IN CONST UINT16                 *CurrentOrder,\r
@@ -647,7 +876,7 @@ BcfgRemove(
     0,\r
     NULL);\r
   if (EFI_ERROR(Status)) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);  \r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
     return (SHELL_INVALID_PARAMETER);\r
   }\r
   NewOrder = AllocateZeroPool(OrderCount*sizeof(CurrentOrder[0]));\r
@@ -668,7 +897,7 @@ BcfgRemove(
     Status = EFI_OUT_OF_RESOURCES;\r
   }\r
   if (EFI_ERROR(Status)) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder");  \r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder");\r
     return (SHELL_INVALID_PARAMETER);\r
   }\r
   return (SHELL_SUCCESS);\r
@@ -687,7 +916,6 @@ BcfgRemove(
   @retval SHELL_INVALID_PARAMETER   A parameter was invalid.\r
 **/\r
 SHELL_STATUS\r
-EFIAPI\r
 BcfgMove(\r
   IN CONST BCFG_OPERATION_TARGET  Target,\r
   IN CONST UINT16                 *CurrentOrder,\r
@@ -731,7 +959,7 @@ BcfgMove(
   FreePool(NewOrder);\r
 \r
   if (EFI_ERROR(Status)) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder");  \r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_WRITE_FAIL), gShellBcfgHiiHandle, L"bcfg", Target == BcfgTargetBootOrder?(CHAR16*)L"BootOrder":(CHAR16*)L"DriverOrder");\r
     return (SHELL_INVALID_PARAMETER);\r
   }\r
   return (SHELL_SUCCESS);\r
@@ -748,7 +976,6 @@ BcfgMove(
   @retval SHELL_SUCCESS   The operation was succesful.\r
 **/\r
 SHELL_STATUS\r
-EFIAPI\r
 BcfgAddOpt(\r
   IN CONST CHAR16                 *OptData,\r
   IN CONST UINT16                 *CurrentOrder,\r
@@ -792,9 +1019,9 @@ BcfgAddOpt(
   //\r
   // Get the index of the variable we are changing.\r
   //\r
-  Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);\r
+  Status = ShellConvertStringToUint64(Walker, &Intermediate, TRUE, TRUE);\r
   if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL || ((UINT16)Intermediate) > ((UINT16)OrderCount)) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");  \r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");\r
     ShellStatus = SHELL_INVALID_PARAMETER;\r
     return (ShellStatus);\r
   }\r
@@ -809,7 +1036,7 @@ BcfgAddOpt(
   }\r
 \r
   //\r
-  // determine whether we have file with data, quote delimited information, or a hot-key \r
+  // determine whether we have file with data, quote delimited information, or a hot-key\r
   //\r
   if (Walker[0] == L'\"') {\r
     //\r
@@ -817,12 +1044,12 @@ BcfgAddOpt(
     //\r
     Temp = StrStr(Walker+1, L"\"");\r
     if (Temp == NULL || StrLen(Temp) != 1) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
       FileName = StrnCatGrow(&FileName, NULL, Walker+1, 0);\r
       if (FileName == NULL) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellBcfgHiiHandle, L"bcfg");  \r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellBcfgHiiHandle, L"bcfg");\r
         ShellStatus = SHELL_OUT_OF_RESOURCES;\r
         return (ShellStatus);\r
       }\r
@@ -831,7 +1058,7 @@ BcfgAddOpt(
       Temp2[0] = CHAR_NULL;\r
       Temp2++;\r
       if (StrLen(Temp2)>0) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);  \r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
         ShellStatus = SHELL_INVALID_PARAMETER;\r
       }\r
       if (EFI_ERROR(ShellFileExists(Walker))) {\r
@@ -853,14 +1080,14 @@ BcfgAddOpt(
       // filename\r
       //\r
       if (EFI_ERROR(ShellFileExists(Walker))) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellBcfgHiiHandle, L"bcfg", Walker);  \r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellBcfgHiiHandle, L"bcfg", Walker);\r
         ShellStatus = SHELL_INVALID_PARAMETER;\r
       } else {\r
         FileName = StrnCatGrow(&FileName, NULL, Walker, 0);\r
       }\r
     } else {\r
       if (Target != BcfgTargetBootOrder) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_BOOT_ONLY), gShellBcfgHiiHandle, L"bcfg");  \r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_BOOT_ONLY), gShellBcfgHiiHandle, L"bcfg");\r
         ShellStatus = SHELL_INVALID_PARAMETER;\r
       }\r
 \r
@@ -870,7 +1097,7 @@ BcfgAddOpt(
         //\r
         Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);\r
         if (EFI_ERROR(Status) || (((UINT32)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         }\r
         NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;\r
@@ -885,14 +1112,16 @@ BcfgAddOpt(
 \r
       if (ShellStatus == SHELL_SUCCESS) {\r
         //\r
-        // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.  \r
+        // Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.\r
         // Re-allocate with the added information.\r
         //\r
-        KeyOptionBuffer = AllocateCopyPool(sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount), &NewKeyOption);\r
+        KeyOptionBuffer = AllocatePool (sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount));\r
         if (KeyOptionBuffer == NULL) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");\r
           ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+          return ShellStatus;\r
         }\r
+        CopyMem (KeyOptionBuffer, &NewKeyOption, sizeof(EFI_KEY_OPTION));\r
       }\r
       for (LoopCounter = 0 ; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {\r
         //\r
@@ -900,7 +1129,7 @@ BcfgAddOpt(
         //\r
         Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);\r
         if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate) || StrStr(Walker, L" ") == NULL) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         }\r
         ((EFI_INPUT_KEY*)(((UINT8*)KeyOptionBuffer) + sizeof(EFI_KEY_OPTION)))[LoopCounter].ScanCode = (UINT16)Intermediate;\r
@@ -917,7 +1146,7 @@ BcfgAddOpt(
         //\r
         Status = ShellConvertStringToUint64(Walker, &Intermediate, FALSE, TRUE);\r
         if (EFI_ERROR(Status) || (((UINT16)Intermediate) != Intermediate)) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", Walker);\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         }\r
         ((EFI_INPUT_KEY*)(((UINT8*)KeyOptionBuffer) + sizeof(EFI_KEY_OPTION)))[LoopCounter].UnicodeChar = (UINT16)Intermediate;\r
@@ -938,9 +1167,9 @@ BcfgAddOpt(
         KeyOptionBuffer->BootOption    = CurrentOrder[OptionIndex];\r
         Status = GetBootOptionCrc(&(KeyOptionBuffer->BootOptionCrc), KeyOptionBuffer->BootOption);\r
         if (EFI_ERROR(Status)) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"Option Index");\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
-        }        \r
+        }\r
       }\r
 \r
       if (ShellStatus == SHELL_SUCCESS) {\r
@@ -962,11 +1191,11 @@ BcfgAddOpt(
             sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount),\r
             KeyOptionBuffer);\r
           if (EFI_ERROR(Status)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
-          }   \r
+          }\r
         } else {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_VAR_NO_NUM), gShellBcfgHiiHandle, L"bcfg");  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_VAR_NO_NUM), gShellBcfgHiiHandle, L"bcfg");\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         }\r
         ASSERT(FileName == NULL && Data == NULL);\r
@@ -994,7 +1223,7 @@ BcfgAddOpt(
       }\r
       Data = AllocateZeroPool((UINTN)Intermediate);\r
       if (Data == NULL) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");  \r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellBcfgHiiHandle, L"bcfg");\r
         ShellStatus = SHELL_OUT_OF_RESOURCES;\r
       }\r
       if (!EFI_ERROR(Status)) {\r
@@ -1007,14 +1236,14 @@ BcfgAddOpt(
     if (!EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS && Data != NULL) {\r
       Status = UpdateOptionalData(CurrentOrder[OptionIndex], (UINTN)Intermediate, (UINT8*)Data, Target);\r
       if (EFI_ERROR(Status)) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);  \r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
         ShellStatus = SHELL_INVALID_PARAMETER;\r
-      }   \r
+      }\r
     }\r
     if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
-    }   \r
+    }\r
   }\r
 \r
   SHELL_FREE_NON_NULL(Data);\r
@@ -1035,7 +1264,6 @@ BcfgAddOpt(
   @retval SHELL_INVALID_PARAMETER A parameter was invalid.\r
 **/\r
 SHELL_STATUS\r
-EFIAPI\r
 BcfgDisplayDump(\r
   IN CONST CHAR16   *Op,\r
   IN CONST UINTN    OrderCount,\r
@@ -1048,19 +1276,24 @@ BcfgDisplayDump(
   UINTN           BufferSize;\r
   CHAR16          VariableName[12];\r
   UINTN           LoopVar;\r
-  UINTN           LoopVar2;\r
   CHAR16          *DevPathString;\r
-  VOID            *DevPath;\r
+  VOID            *FilePathList;\r
+  UINTN           Errors;\r
+  EFI_LOAD_OPTION *LoadOption;\r
+  CHAR16          *Description;\r
+  UINTN           DescriptionSize;\r
+  UINTN           OptionalDataOffset;\r
 \r
   if (OrderCount == 0) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_BCFG_NONE), gShellBcfgHiiHandle, L"bcfg");  \r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_BCFG_NONE), gShellBcfgHiiHandle, L"bcfg");\r
     return (SHELL_SUCCESS);\r
   }\r
 \r
+  Errors = 0;\r
+\r
   for (LoopVar = 0 ; LoopVar < OrderCount ; LoopVar++) {\r
     Buffer        = NULL;\r
     BufferSize    = 0;\r
-    DevPath       = NULL;\r
     DevPathString = NULL;\r
 \r
     UnicodeSPrint(VariableName, sizeof(VariableName), L"%s%04x", Op, CurrentOrder[LoopVar]);\r
@@ -1082,17 +1315,41 @@ BcfgDisplayDump(
     }\r
 \r
     if (EFI_ERROR(Status) || Buffer == NULL) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);  \r
-      return (SHELL_INVALID_PARAMETER);\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_READ_FAIL), gShellBcfgHiiHandle, L"bcfg", VariableName);\r
+      ++Errors;\r
+      goto Cleanup;\r
     }\r
 \r
-    if ((*(UINT16*)(Buffer+4)) != 0) {\r
-      DevPath = AllocateZeroPool(*(UINT16*)(Buffer+4));\r
-      if (DevPath != NULL) {\r
-        CopyMem(DevPath, Buffer+6+StrSize((CHAR16*)(Buffer+6)), *(UINT16*)(Buffer+4));\r
-        DevPathString = ConvertDevicePathToText(DevPath, TRUE, FALSE);\r
-      }\r
+    //\r
+    // We expect the Attributes, FilePathListLength, and L'\0'-terminated\r
+    // Description fields to be present.\r
+    //\r
+    if (BufferSize < sizeof *LoadOption + sizeof (CHAR16)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_BCFG_VAR_CORRUPT),\r
+        gShellBcfgHiiHandle,\r
+        L"bcfg",\r
+        VariableName\r
+        );\r
+      ++Errors;\r
+      goto Cleanup;\r
+    }\r
+\r
+    LoadOption      = (EFI_LOAD_OPTION *)Buffer;\r
+    Description     = (CHAR16*)(Buffer + sizeof (EFI_LOAD_OPTION));\r
+    DescriptionSize = StrSize (Description);\r
+\r
+    if (LoadOption->FilePathListLength != 0) {\r
+      FilePathList = (UINT8 *)Description + DescriptionSize;\r
+      DevPathString = ConvertDevicePathToText(FilePathList, TRUE, FALSE);\r
     }\r
+\r
+    OptionalDataOffset = sizeof *LoadOption + DescriptionSize +\r
+                         LoadOption->FilePathListLength;\r
+\r
     ShellPrintHiiEx(\r
       -1,\r
       -1,\r
@@ -1101,36 +1358,28 @@ BcfgDisplayDump(
       gShellBcfgHiiHandle,\r
       LoopVar,\r
       VariableName,\r
-      (CHAR16*)(Buffer+6),\r
+      Description,\r
       DevPathString,\r
-      (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6) <= BufferSize?L'N':L'Y');\r
-    if (VerboseOutput) {\r
-      for (LoopVar2 = (StrSize((CHAR16*)(Buffer+6)) + *(UINT16*)(Buffer+4) + 6);LoopVar2<BufferSize;LoopVar2++){\r
-        ShellPrintEx(\r
-          -1,\r
-          -1,\r
-          NULL,\r
-          L"%02x",\r
-          Buffer[LoopVar2]);\r
-      }\r
-      ShellPrintEx(\r
-        -1,\r
-        -1,\r
-        NULL,\r
-        L"\r\n");\r
+      OptionalDataOffset >= BufferSize ? L'N' : L'Y'\r
+      );\r
+    if (VerboseOutput && (OptionalDataOffset < BufferSize)) {\r
+      DumpHex (\r
+        2,                               // Indent\r
+        0,                               // Offset (displayed)\r
+        BufferSize - OptionalDataOffset, // DataSize\r
+        Buffer + OptionalDataOffset      // UserData\r
+        );\r
     }\r
 \r
+Cleanup:\r
     if (Buffer != NULL) {\r
       FreePool(Buffer);\r
     }\r
-    if (DevPath != NULL) {\r
-      FreePool(DevPath);\r
-    }\r
     if (DevPathString != NULL) {\r
       FreePool(DevPathString);\r
     }\r
   }\r
-  return (SHELL_SUCCESS);\r
+  return (Errors > 0) ? SHELL_INVALID_PARAMETER : SHELL_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -1139,7 +1388,6 @@ BcfgDisplayDump(
   @param[in] Struct   The stuct to initialize.\r
 **/\r
 VOID\r
-EFIAPI\r
 InitBcfgStruct(\r
   IN BGFG_OPERATION *Struct\r
   )\r
@@ -1209,7 +1457,7 @@ ShellCommandRunBcfg (
   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
   if (EFI_ERROR(Status)) {\r
     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellBcfgHiiHandle, L"bcfg", ProblemParam);  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellBcfgHiiHandle, L"bcfg", ProblemParam);\r
       FreePool(ProblemParam);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
@@ -1222,7 +1470,7 @@ ShellCommandRunBcfg (
     if (ShellCommandLineGetFlag(Package, L"-opt")) {\r
       CurrentOperation.OptData = ShellCommandLineGetValue(Package, L"-opt");\r
       if (CurrentOperation.OptData == NULL) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellBcfgHiiHandle, L"bcfg", L"-opt");  \r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellBcfgHiiHandle, L"bcfg", L"-opt");\r
         ShellStatus = SHELL_INVALID_PARAMETER;\r
       }\r
       CurrentOperation.Type = BcfgTypeOpt;\r
@@ -1234,14 +1482,14 @@ ShellCommandRunBcfg (
     if ((ShellCommandLineGetCount(Package) < 3 && CurrentOperation.Type != BcfgTypeOpt) ||\r
         (ShellCommandLineGetCount(Package) < 2 && CurrentOperation.Type == BcfgTypeOpt)\r
        ){\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"driver") == 0) {\r
       CurrentOperation.Target = BcfgTargetDriverOrder;\r
     } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)ShellCommandLineGetRawValue(Package, 1), L"boot") == 0) {\r
       CurrentOperation.Target = BcfgTargetBootOrder;\r
     } else {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellBcfgHiiHandle, L"bcfg");  \r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_DRIVER_BOOT), gShellBcfgHiiHandle, L"bcfg");\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     }\r
 \r
@@ -1282,18 +1530,22 @@ ShellCommandRunBcfg (
         CurrentParam = ShellCommandLineGetRawValue(Package, ParamNumber);\r
         if        (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"dump") == 0)    {\r
           CurrentOperation.Type = BcfgTypeDump;\r
+          if (ShellCommandLineGetCount(Package) > 3) {\r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellBcfgHiiHandle, L"bcfg");\r
+            ShellStatus = SHELL_INVALID_PARAMETER;\r
+          }\r
         } else if (ShellCommandLineGetFlag(Package, L"-v")) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"-v (without dump)");  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", L"-v (without dump)");\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"add") == 0)     {\r
           if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           }\r
           CurrentOperation.Type = BcfgTypeAdd;\r
           CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
           if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           } else {\r
             Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
@@ -1305,13 +1557,13 @@ ShellCommandRunBcfg (
           }\r
         } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addp") == 0)    {\r
           if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           }\r
           CurrentOperation.Type = BcfgTypeAddp;\r
           CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
           if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           } else {\r
             Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
@@ -1323,20 +1575,20 @@ ShellCommandRunBcfg (
           }\r
         } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"addh") == 0)    {\r
           if ((ParamNumber + 3) >= ShellCommandLineGetCount(Package)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           }\r
           CurrentOperation.Type = BcfgTypeAddh;\r
           CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
           if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           } else {\r
             Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
             CurrentOperation.Number1     = (UINT16)Intermediate;\r
             CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
             if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);  \r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
               ShellStatus = SHELL_INVALID_PARAMETER;\r
             } else {\r
               Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
@@ -1347,42 +1599,42 @@ ShellCommandRunBcfg (
           }\r
         } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"rm") == 0)      {\r
           if ((ParamNumber + 1) >= ShellCommandLineGetCount(Package)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           }\r
           CurrentOperation.Type = BcfgTypeRm;\r
           CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
           if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           } else {\r
             Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
             CurrentOperation.Number1     = (UINT16)Intermediate;\r
             if (CurrentOperation.Number1 >= Count){\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);  \r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
               ShellStatus = SHELL_INVALID_PARAMETER;\r
             }\r
           }\r
         } else if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16*)CurrentParam, L"mv") == 0)      {\r
           if ((ParamNumber + 2) >= ShellCommandLineGetCount(Package)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           }\r
           CurrentOperation.Type = BcfgTypeMv;\r
           CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
           if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);  \r
+            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
             ShellStatus = SHELL_INVALID_PARAMETER;\r
           } else {\r
             Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
             CurrentOperation.Number1     = (UINT16)Intermediate;\r
             if (CurrentOperation.Number1 >= Count){\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);  \r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
               ShellStatus = SHELL_INVALID_PARAMETER;\r
             } else {\r
               CurrentParam = ShellCommandLineGetRawValue(Package, ++ParamNumber);\r
               if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber(CurrentParam, TRUE, FALSE)) {\r
-                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);  \r
+                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
                 ShellStatus = SHELL_INVALID_PARAMETER;\r
               } else {\r
                 Status = ShellConvertStringToUint64(CurrentParam, &Intermediate, TRUE, FALSE);\r
@@ -1391,13 +1643,109 @@ ShellCommandRunBcfg (
               if (CurrentOperation.Number2 == CurrentOperation.Number1\r
                 ||CurrentOperation.Number2 >= Count\r
                ){\r
-                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);  \r
+                ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
+                ShellStatus = SHELL_INVALID_PARAMETER;\r
+              }\r
+            }\r
+          }\r
+        }\r
+        else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)CurrentParam, L"mod") == 0) {\r
+          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {\r
+            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
+            ShellStatus = SHELL_INVALID_PARAMETER;\r
+          } else {\r
+            CurrentOperation.Type = BcfgTypeMod;\r
+            CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
+            if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
+              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
+              ShellStatus = SHELL_INVALID_PARAMETER;\r
+            } else {\r
+              Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
+              CurrentOperation.Number1 = (UINT16)Intermediate;\r
+              if (CurrentOperation.Number1 >= Count) {\r
+                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
+                ShellStatus = SHELL_INVALID_PARAMETER;\r
+              } else {\r
+                ASSERT (CurrentOperation.Description == NULL);\r
+                CurrentOperation.Description = StrnCatGrow (&CurrentOperation.Description, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);\r
+              }\r
+            }\r
+          }\r
+        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)CurrentParam, L"modf") == 0) {\r
+          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {\r
+            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
+            ShellStatus = SHELL_INVALID_PARAMETER;\r
+          } else {\r
+            CurrentOperation.Type = BcfgTypeModf;\r
+            CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
+            if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
+              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
+              ShellStatus = SHELL_INVALID_PARAMETER;\r
+            } else {\r
+              Status = ShellConvertStringToUint64  (CurrentParam, &Intermediate, TRUE, FALSE);\r
+              CurrentOperation.Number1 = (UINT16)Intermediate;\r
+              if (CurrentOperation.Number1 >= Count) {\r
+                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
                 ShellStatus = SHELL_INVALID_PARAMETER;\r
+              } else {\r
+                ASSERT (CurrentOperation.FileName == NULL);\r
+                CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);\r
+              }\r
+            }\r
+          }\r
+        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)CurrentParam, L"modp") == 0) {\r
+          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {\r
+            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
+            ShellStatus = SHELL_INVALID_PARAMETER;\r
+          } else {\r
+            CurrentOperation.Type = BcfgTypeModp;\r
+            CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
+            if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
+              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
+              ShellStatus = SHELL_INVALID_PARAMETER;\r
+            } else {\r
+              Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
+              CurrentOperation.Number1 = (UINT16)Intermediate;\r
+              if (CurrentOperation.Number1 >= Count) {\r
+                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
+                ShellStatus = SHELL_INVALID_PARAMETER;\r
+              } else {\r
+                ASSERT (CurrentOperation.FileName == NULL);\r
+                CurrentOperation.FileName = StrnCatGrow (&CurrentOperation.FileName, NULL, ShellCommandLineGetRawValue (Package, ++ParamNumber), 0);\r
+              }\r
+            }\r
+          }\r
+        } else if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16*)CurrentParam, L"modh") == 0) {\r
+          if ((ParamNumber + 2) >= ShellCommandLineGetCount (Package)) {\r
+            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellBcfgHiiHandle, L"bcfg");\r
+            ShellStatus = SHELL_INVALID_PARAMETER;\r
+          } else {\r
+            CurrentOperation.Type = BcfgTypeModh;\r
+            CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
+            if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
+              ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
+              ShellStatus = SHELL_INVALID_PARAMETER;\r
+            }\r
+            else {\r
+              Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
+              CurrentOperation.Number1 = (UINT16)Intermediate;\r
+              if (CurrentOperation.Number1 >= Count) {\r
+                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_BCFG_NUMB_RANGE), gShellBcfgHiiHandle, L"bcfg", Count);\r
+                ShellStatus = SHELL_INVALID_PARAMETER;\r
+              } else {\r
+                CurrentParam = ShellCommandLineGetRawValue (Package, ++ParamNumber);\r
+                if (CurrentParam == NULL || !ShellIsHexOrDecimalNumber (CurrentParam, TRUE, FALSE)) {\r
+                  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
+                  ShellStatus = SHELL_INVALID_PARAMETER;\r
+                } else {\r
+                  Status = ShellConvertStringToUint64 (CurrentParam, &Intermediate, TRUE, FALSE);\r
+                  CurrentOperation.HandleIndex = (UINT16)Intermediate;\r
+                }\r
               }\r
             }\r
           }\r
         } else {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);  \r
+          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellBcfgHiiHandle, L"bcfg", CurrentParam);\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         }\r
       }\r
@@ -1443,6 +1791,12 @@ ShellCommandRunBcfg (
             (BOOLEAN)(CurrentOperation.Type == BcfgTypeAddp),\r
             CurrentOperation.HandleIndex);\r
           break;\r
+        case   BcfgTypeMod:\r
+        case   BcfgTypeModf:\r
+        case   BcfgTypeModp:\r
+        case   BcfgTypeModh:\r
+          ShellStatus = BcfgMod (&CurrentOperation, Count);\r
+          break;\r
         case   BcfgTypeOpt:\r
           ShellStatus = BcfgAddOpt(\r
             CurrentOperation.OptData,\r