]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.c
ShellPkg: Fix misuses of AllocateCopyPool
[mirror_edk2.git] / ShellPkg / Library / UefiShellBcfgCommandLib / UefiShellBcfgCommandLib.c
index aac85d3850907a86feefdd0a78ebf28cd2de8895..ee3db6335871456d29bd36e38446016fea4297b6 100644 (file)
@@ -2,7 +2,7 @@
   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
+  Copyright (c) 2010 - 2017, 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
 \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
@@ -42,6 +41,7 @@
 #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
@@ -60,7 +60,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,7 +93,6 @@ typedef struct {
   @retval other             A error occured.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 UpdateOptionalData(\r
   UINT16                          Index, \r
   UINTN                           DataSize, \r
@@ -140,10 +143,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
@@ -175,7 +179,6 @@ UpdateOptionalData(
   @retval other                 A error occured.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 GetBootOptionCrc(\r
   UINT32      *Crc, \r
   UINT16      BootIndex\r
@@ -232,7 +235,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 +280,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 +539,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 +553,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
@@ -462,9 +706,9 @@ BcfgAdd(
           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 +716,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
@@ -561,33 +796,34 @@ BcfgAdd(
     if (EFI_ERROR(Status)) {\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 +862,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
@@ -687,7 +922,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
@@ -748,7 +982,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
@@ -888,11 +1121,13 @@ BcfgAddOpt(
         // 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
           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
@@ -1035,7 +1270,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,13 +1282,13 @@ 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
@@ -1066,7 +1300,6 @@ BcfgDisplayDump(
   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
@@ -1112,16 +1345,17 @@ BcfgDisplayDump(
     }\r
 \r
     LoadOption      = (EFI_LOAD_OPTION *)Buffer;\r
-    Description     = (CHAR16 *)(&LoadOption->FilePathListLength + 1);\r
+    Description     = (CHAR16*)(Buffer + sizeof (EFI_LOAD_OPTION));\r
     DescriptionSize = StrSize (Description);\r
 \r
     if (LoadOption->FilePathListLength != 0) {\r
-      DevPath = AllocateZeroPool(LoadOption->FilePathListLength);\r
-      if (DevPath != NULL) {\r
-        CopyMem(DevPath, Buffer+6+DescriptionSize, LoadOption->FilePathListLength);\r
-        DevPathString = ConvertDevicePathToText(DevPath, TRUE, FALSE);\r
-      }\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
@@ -1132,30 +1366,21 @@ BcfgDisplayDump(
       VariableName,\r
       Description,\r
       DevPathString,\r
-      (DescriptionSize + LoadOption->FilePathListLength + 6) <= BufferSize?L'N':L'Y');\r
-    if (VerboseOutput) {\r
-      for (LoopVar2 = (DescriptionSize + LoadOption->FilePathListLength + 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
@@ -1169,7 +1394,6 @@ Cleanup:
   @param[in] Struct   The stuct to initialize.\r
 **/\r
 VOID\r
-EFIAPI\r
 InitBcfgStruct(\r
   IN BGFG_OPERATION *Struct\r
   )\r
@@ -1312,6 +1536,10 @@ 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
           ShellStatus = SHELL_INVALID_PARAMETER;\r
@@ -1426,6 +1654,102 @@ ShellCommandRunBcfg (
               }\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
           ShellStatus = SHELL_INVALID_PARAMETER;\r
@@ -1473,6 +1797,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