]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / SetVar.c
index f8c6dd2e30d3c2383a369adaf7f92616893be9e5..61788d199365113b2a13053f17ac989b5d8821b1 100644 (file)
 /** @file\r
   Main file for SetVar shell Debug1 function.\r
 \r
-  Copyright (c) 2010, 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
+  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "UefiShellDebug1CommandsLib.h"\r
 \r
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
-  {L"-guid", TypeValue},\r
-  {L"-bs", TypeFlag},\r
-  {L"-rt", TypeFlag},\r
-  {L"-nv", TypeFlag},\r
-  {NULL, TypeMax}\r
-  };\r
+STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {\r
+  { L"-guid", TypeValue },\r
+  { L"-bs",   TypeFlag  },\r
+  { L"-rt",   TypeFlag  },\r
+  { L"-nv",   TypeFlag  },\r
+  { NULL,     TypeMax   }\r
+};\r
+\r
+typedef enum {\r
+  DataTypeHexNumber  = 0,\r
+  DataTypeHexArray   = 1,\r
+  DataTypeAscii      = 2,\r
+  DataTypeUnicode    = 3,\r
+  DataTypeDevicePath = 4,\r
+  DataTypeUnKnow     = 5\r
+} DATA_TYPE;\r
+\r
+typedef union {\r
+  UINT8     HexNumber8;\r
+  UINT16    HexNumber16;\r
+  UINT32    HexNumber32;\r
+  UINT64    HexNumber64;\r
+} HEX_NUMBER;\r
+\r
+/**\r
+  Check if the input is a (potentially empty) string of hexadecimal nibbles.\r
+\r
+  @param[in] String  The CHAR16 string to check.\r
+\r
+  @retval FALSE  A character has been found in String for which\r
+                 ShellIsHexaDecimalDigitCharacter() returned FALSE.\r
+\r
+  @retval TRUE   Otherwise. (Note that this covers the case when String is\r
+                 empty.)\r
+**/\r
+BOOLEAN\r
+IsStringOfHexNibbles (\r
+  IN CONST CHAR16  *String\r
+  )\r
+{\r
+  CONST CHAR16  *Pos;\r
+\r
+  for (Pos = String; *Pos != L'\0'; ++Pos) {\r
+    if (!ShellIsHexaDecimalDigitCharacter (*Pos)) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Function to check the TYPE of Data.\r
+\r
+  @param[in]    Data          The Data to be check.\r
+\r
+  @retval       DATA_TYPE     The TYPE of Data.\r
+**/\r
+DATA_TYPE\r
+TestDataType (\r
+  IN CONST CHAR16  *Data\r
+  )\r
+{\r
+  if ((Data[0] == L'0') && ((Data[1] == L'x') || (Data[1] == L'X'))) {\r
+    if (IsStringOfHexNibbles (Data+2) && (StrLen (Data + 2) <= 16)) {\r
+      return DataTypeHexNumber;\r
+    } else {\r
+      return DataTypeUnKnow;\r
+    }\r
+  } else if (Data[0] == L'H') {\r
+    if (IsStringOfHexNibbles (Data + 1) && (StrLen (Data + 1) % 2 == 0)) {\r
+      return DataTypeHexArray;\r
+    } else {\r
+      return DataTypeUnKnow;\r
+    }\r
+  } else if (Data[0] == L'S') {\r
+    return DataTypeAscii;\r
+  } else if (Data[0] == L'L') {\r
+    return DataTypeUnicode;\r
+  } else if ((Data[0] == L'P') || (StrnCmp (Data, L"--", 2) == 0)) {\r
+    return DataTypeDevicePath;\r
+  }\r
+\r
+  if (IsStringOfHexNibbles (Data) && (StrLen (Data) % 2 == 0)) {\r
+    return DataTypeHexArray;\r
+  }\r
+\r
+  return DataTypeAscii;\r
+}\r
+\r
+/**\r
+  Function to parse the Data by the type of Data, and save in the Buffer.\r
+\r
+  @param[in]      Data                A pointer to a buffer to be parsed.\r
+  @param[out]     Buffer              A pointer to a buffer to hold the return data.\r
+  @param[in,out]  BufferSize          On input, indicates the size of Buffer in bytes.\r
+                                      On output,indicates the size of data return in Buffer.\r
+                                      Or the size in bytes of the buffer needed to obtain.\r
+\r
+  @retval   EFI_INVALID_PARAMETER     The Buffer or BufferSize is NULL.\r
+  @retval   EFI_BUFFER_TOO_SMALL      The Buffer is too small to hold the data.\r
+  @retval   EFI_OUT_OF_RESOURCES      A memory allcation failed.\r
+  @retval   EFI_SUCCESS               The Data parsed successful and save in the Buffer.\r
+**/\r
+EFI_STATUS\r
+ParseParameterData (\r
+  IN CONST CHAR16  *Data,\r
+  OUT VOID         *Buffer,\r
+  IN OUT UINTN     *BufferSize\r
+  )\r
+{\r
+  UINT64                    HexNumber;\r
+  UINTN                     HexNumberLen;\r
+  UINTN                     Size;\r
+  CHAR8                     *AsciiBuffer;\r
+  DATA_TYPE                 DataType;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
+  EFI_STATUS                Status;\r
+\r
+  HexNumber    = 0;\r
+  HexNumberLen = 0;\r
+  Size         = 0;\r
+  AsciiBuffer  = NULL;\r
+  DevPath      = NULL;\r
+  Status       = EFI_SUCCESS;\r
 \r
+  if ((Data == NULL) || (BufferSize == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  DataType = TestDataType (Data);\r
+  if (DataType == DataTypeHexNumber) {\r
+    //\r
+    // hex number\r
+    //\r
+    StrHexToUint64S (Data + 2, NULL, &HexNumber);\r
+    HexNumberLen = StrLen (Data + 2);\r
+    if ((HexNumberLen >= 1) && (HexNumberLen <= 2)) {\r
+      Size = 1;\r
+    } else if ((HexNumberLen >= 3) && (HexNumberLen <= 4)) {\r
+      Size = 2;\r
+    } else if ((HexNumberLen >= 5) && (HexNumberLen <= 8)) {\r
+      Size = 4;\r
+    } else if ((HexNumberLen >= 9) && (HexNumberLen <= 16)) {\r
+      Size = 8;\r
+    }\r
+\r
+    if ((Buffer != NULL) && (*BufferSize >= Size)) {\r
+      CopyMem (Buffer, (VOID *)&HexNumber, Size);\r
+    } else {\r
+      Status = EFI_BUFFER_TOO_SMALL;\r
+    }\r
+\r
+    *BufferSize = Size;\r
+  } else if (DataType == DataTypeHexArray) {\r
+    //\r
+    // hex array\r
+    //\r
+    if (*Data == L'H') {\r
+      Data = Data + 1;\r
+    }\r
+\r
+    Size = StrLen (Data) / 2;\r
+    if ((Buffer != NULL) && (*BufferSize >= Size)) {\r
+      StrHexToBytes (Data, StrLen (Data), (UINT8 *)Buffer, Size);\r
+    } else {\r
+      Status = EFI_BUFFER_TOO_SMALL;\r
+    }\r
+\r
+    *BufferSize = Size;\r
+  } else if (DataType == DataTypeAscii) {\r
+    //\r
+    // ascii text\r
+    //\r
+    if (*Data == L'S') {\r
+      Data = Data + 1;\r
+    }\r
+\r
+    AsciiBuffer = AllocateZeroPool (StrSize (Data) / 2);\r
+    if (AsciiBuffer == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+    } else {\r
+      AsciiSPrint (AsciiBuffer, StrSize (Data) / 2, "%s", (CHAR8 *)Data);\r
+\r
+      Size = StrSize (Data) / 2 - 1;\r
+      if ((Buffer != NULL) && (*BufferSize >= Size)) {\r
+        CopyMem (Buffer, AsciiBuffer, Size);\r
+      } else {\r
+        Status = EFI_BUFFER_TOO_SMALL;\r
+      }\r
+\r
+      *BufferSize = Size;\r
+    }\r
+\r
+    SHELL_FREE_NON_NULL (AsciiBuffer);\r
+  } else if (DataType == DataTypeUnicode) {\r
+    //\r
+    // unicode text\r
+    //\r
+    if (*Data == L'L') {\r
+      Data = Data + 1;\r
+    }\r
+\r
+    Size = StrSize (Data) - sizeof (CHAR16);\r
+    if ((Buffer != NULL) && (*BufferSize >= Size)) {\r
+      CopyMem (Buffer, Data, Size);\r
+    } else {\r
+      Status = EFI_BUFFER_TOO_SMALL;\r
+    }\r
+\r
+    *BufferSize = Size;\r
+  } else if (DataType == DataTypeDevicePath) {\r
+    if (*Data == L'P') {\r
+      Data = Data + 1;\r
+    } else if (StrnCmp (Data, L"--", 2) == 0) {\r
+      Data = Data + 2;\r
+    }\r
+\r
+    DevPath = ConvertTextToDevicePath (Data);\r
+    if (DevPath == NULL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");\r
+      Status = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      Size = GetDevicePathSize (DevPath);\r
+      if ((Buffer != NULL) && (*BufferSize >= Size)) {\r
+        CopyMem (Buffer, DevPath, Size);\r
+      } else {\r
+        Status = EFI_BUFFER_TOO_SMALL;\r
+      }\r
+\r
+      *BufferSize = Size;\r
+    }\r
+\r
+    SHELL_FREE_NON_NULL (DevPath);\r
+  } else {\r
+    Status = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Function to get each data from parameters.\r
+\r
+  @param[in]    Package               The package of checked values.\r
+  @param[out]   Buffer                A pointer to a buffer to hold the return data.\r
+  @param[out]   BufferSize            Indicates the size of data in bytes return in Buffer.\r
+\r
+  @retval   EFI_INVALID_PARAMETER     Buffer or BufferSize is NULL.\r
+  @retval   EFI_OUT_OF_RESOURCES      A memory allcation failed.\r
+  @retval   EFI_SUCCESS               Get each parameter data was successful.\r
+**/\r
+EFI_STATUS\r
+GetVariableDataFromParameter (\r
+  IN CONST LIST_ENTRY  *Package,\r
+  OUT UINT8            **Buffer,\r
+  OUT UINTN            *BufferSize\r
+  )\r
+{\r
+  CONST CHAR16  *TempData;\r
+  UINTN         Index;\r
+  UINTN         TotalSize;\r
+  UINTN         Size;\r
+  UINT8         *BufferWalker;\r
+  EFI_STATUS    Status;\r
+\r
+  TotalSize = 0;\r
+  Size      = 0;\r
+  Status    = EFI_SUCCESS;\r
+\r
+  if ((BufferSize == NULL) || (Buffer == NULL) || (ShellCommandLineGetCount (Package) < 3)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) {\r
+    TempData = ShellCommandLineGetRawValue (Package, Index);\r
+    ASSERT (TempData != NULL);\r
+\r
+    if (TempData[0] != L'=') {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData);\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    TempData = TempData + 1;\r
+    Size     = 0;\r
+    Status   = ParseParameterData (TempData, NULL, &Size);\r
+    if (EFI_ERROR (Status)) {\r
+      if (Status == EFI_BUFFER_TOO_SMALL) {\r
+        //\r
+        // We expect return EFI_BUFFER_TOO_SMALL when pass 'NULL' as second parameter to the function ParseParameterData.\r
+        //\r
+        TotalSize += Size;\r
+      } else {\r
+        if (Status == EFI_INVALID_PARAMETER) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData);\r
+        } else if (Status == EFI_NOT_FOUND) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");\r
+        }\r
+\r
+        return Status;\r
+      }\r
+    }\r
+  }\r
+\r
+  *BufferSize = TotalSize;\r
+  *Buffer     = AllocateZeroPool (TotalSize);\r
+\r
+  if (*Buffer == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+  } else {\r
+    BufferWalker = *Buffer;\r
+    for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) {\r
+      TempData = ShellCommandLineGetRawValue (Package, Index);\r
+      TempData = TempData + 1;\r
+\r
+      Size   = TotalSize;\r
+      Status = ParseParameterData (TempData, (VOID *)BufferWalker, &Size);\r
+      if (!EFI_ERROR (Status)) {\r
+        BufferWalker = BufferWalker + Size;\r
+        TotalSize    = TotalSize - Size;\r
+      } else {\r
+        return Status;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Function for 'setvar' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+**/\r
 SHELL_STATUS\r
 EFIAPI\r
 ShellCommandRunSetVar (\r
@@ -29,199 +351,139 @@ ShellCommandRunSetVar (
   IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  LIST_ENTRY          *Package;\r
-  CHAR16              *ProblemParam;\r
-  SHELL_STATUS        ShellStatus;\r
-  CONST CHAR16        *VariableName;\r
-  CONST CHAR16        *Data;\r
-  EFI_GUID            Guid;\r
-  CONST CHAR16        *StringGuid;\r
-  UINT32              Attributes;\r
-  VOID                *Buffer;\r
-  UINTN               Size;\r
-  UINTN               LoopVar;\r
-  EFI_DEVICE_PATH_PROTOCOL           *DevPath;\r
-  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DevPathFromText;\r
-\r
-  ShellStatus         = SHELL_SUCCESS;\r
-  Status              = EFI_SUCCESS;\r
-  Buffer              = NULL;\r
-  Size                = 0;\r
-  Attributes          = 0;\r
-  DevPath             = NULL;\r
+  EFI_STATUS     Status;\r
+  RETURN_STATUS  RStatus;\r
+  LIST_ENTRY     *Package;\r
+  CHAR16         *ProblemParam;\r
+  SHELL_STATUS   ShellStatus;\r
+  CONST CHAR16   *VariableName;\r
+  EFI_GUID       Guid;\r
+  CONST CHAR16   *StringGuid;\r
+  UINT32         Attributes;\r
+  VOID           *Buffer;\r
+  UINTN          Size;\r
+  UINTN          LoopVar;\r
+\r
+  ShellStatus = SHELL_SUCCESS;\r
+  Status      = EFI_SUCCESS;\r
+  Buffer      = NULL;\r
+  Size        = 0;\r
+  Attributes  = 0;\r
 \r
   //\r
   // initialize the shell lib (we must be in non-auto-init...)\r
   //\r
-  Status = ShellInitialize();\r
-  ASSERT_EFI_ERROR(Status);\r
+  Status = ShellInitialize ();\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = CommandInit();\r
-  ASSERT_EFI_ERROR(Status);\r
+  Status = CommandInit ();\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   // parse the command line\r
   //\r
   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), gShellDebug1HiiHandle, ProblemParam);\r
-      FreePool(ProblemParam);\r
+  if (EFI_ERROR (Status)) {\r
+    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"setvar", ProblemParam);\r
+      FreePool (ProblemParam);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
-      ASSERT(FALSE);\r
+      ASSERT (FALSE);\r
     }\r
+  } else if (ShellCommandLineCheckDuplicate (Package, &ProblemParam) != EFI_SUCCESS) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DUPLICATE), gShellDebug1HiiHandle, L"setvar", ProblemParam);\r
+    FreePool (ProblemParam);\r
+    ShellStatus = SHELL_INVALID_PARAMETER;\r
   } else {\r
-    if (ShellCommandLineGetCount(Package) < 2) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
-      ShellStatus = SHELL_INVALID_PARAMETER;\r
-    } else if (ShellCommandLineGetCount(Package) > 3) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
+    if (ShellCommandLineGetCount (Package) < 2) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"setvar");\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
-      VariableName  = ShellCommandLineGetRawValue(Package, 1);\r
-      Data          = ShellCommandLineGetRawValue(Package, 2);\r
-      if (!ShellCommandLineGetFlag(Package, L"-guid")){\r
-        CopyGuid(&Guid, &gEfiGlobalVariableGuid);\r
+      VariableName = ShellCommandLineGetRawValue (Package, 1);\r
+      if (!ShellCommandLineGetFlag (Package, L"-guid")) {\r
+        CopyGuid (&Guid, &gEfiGlobalVariableGuid);\r
       } else {\r
-        StringGuid = ShellCommandLineGetValue(Package, L"-guid");\r
-        Status = ConvertStringToGuid(StringGuid, &Guid);\r
-        if (EFI_ERROR(Status)) {\r
-          ShellStatus = SHELL_NOT_FOUND;\r
+        StringGuid = ShellCommandLineGetValue (Package, L"-guid");\r
+        RStatus    = StrToGuid (StringGuid, &Guid);\r
+        if (RETURN_ERROR (RStatus) || (StringGuid[GUID_STRING_LENGTH] != L'\0')) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid);\r
+          ShellStatus = SHELL_INVALID_PARAMETER;\r
         }\r
       }\r
-      if (Data == NULL) {\r
+\r
+      if (ShellCommandLineGetCount (Package) == 2) {\r
         //\r
-        // Display what's there\r
+        // Display\r
         //\r
-        Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);\r
+        Status = gRT->GetVariable ((CHAR16 *)VariableName, &Guid, &Attributes, &Size, Buffer);\r
         if (Status == EFI_BUFFER_TOO_SMALL) {\r
-          Buffer = AllocatePool(Size);\r
-          Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);\r
+          Buffer = AllocateZeroPool (Size);\r
+          Status = gRT->GetVariable ((CHAR16 *)VariableName, &Guid, &Attributes, &Size, Buffer);\r
         }\r
-        if (!EFI_ERROR(Status)&& Buffer != NULL) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);\r
-          for (LoopVar = 0 ; LoopVar < Size ; LoopVar++) {\r
-            ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]);\r
+\r
+        if (!EFI_ERROR (Status) && (Buffer != NULL)) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);\r
+          for (LoopVar = 0; LoopVar < Size; LoopVar++) {\r
+            ShellPrintEx (-1, -1, L"%02x ", ((UINT8 *)Buffer)[LoopVar]);\r
           }\r
-          ShellPrintEx(-1, -1, L"\r\n");\r
+\r
+          ShellPrintEx (-1, -1, L"\r\n");\r
         } else {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
-          ShellStatus = SHELL_ACCESS_DENIED;\r
-        }\r
-      } else if (StrCmp(Data, L"=") == 0) {\r
-        //\r
-        // Delete what's there!\r
-        //\r
-        Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, 0, NULL);\r
-        if (EFI_ERROR(Status)) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);\r
           ShellStatus = SHELL_ACCESS_DENIED;\r
-        } else {\r
-          ASSERT(ShellStatus == SHELL_SUCCESS);\r
         }\r
       } else {\r
-        if (Data[0] == L'=') {\r
-          Data++;\r
-        }\r
         //\r
-        // Change what's there\r
+        // Create, Delete or Modify.\r
         //\r
-        if (ShellCommandLineGetFlag(Package, L"-bs")) {\r
-          Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
-        }\r
-        if (ShellCommandLineGetFlag(Package, L"-rt")) {\r
-          Attributes |= EFI_VARIABLE_RUNTIME_ACCESS;\r
-        }\r
-        if (ShellCommandLineGetFlag(Package, L"-nv")) {\r
-          Attributes |= EFI_VARIABLE_NON_VOLATILE;\r
+        Status = gRT->GetVariable ((CHAR16 *)VariableName, &Guid, &Attributes, &Size, Buffer);\r
+        if (Status == EFI_BUFFER_TOO_SMALL) {\r
+          Buffer = AllocateZeroPool (Size);\r
+          Status = gRT->GetVariable ((CHAR16 *)VariableName, &Guid, &Attributes, &Size, Buffer);\r
         }\r
-        if (ShellIsHexOrDecimalNumber(Data, TRUE, FALSE)) {\r
-          //\r
-          // arbitrary buffer\r
-          //\r
-          Buffer = AllocateZeroPool((StrLen(Data) / 2));\r
-          for (LoopVar = 0 ; LoopVar < (StrLen(Data) / 2) ; LoopVar++) {\r
-            ((UINT8*)Buffer)[LoopVar] = (UINT8)(HexCharToUintn(Data[LoopVar*2]) * 16);\r
-            ((UINT8*)Buffer)[LoopVar] = (UINT8)(((UINT8*)Buffer)[LoopVar] + HexCharToUintn(Data[LoopVar*2+1]));\r
-          }\r
-          Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrLen(Data) / 2, Buffer);\r
-          if (EFI_ERROR(Status)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
-            ShellStatus = SHELL_ACCESS_DENIED;\r
-          } else {\r
-            ASSERT(ShellStatus == SHELL_SUCCESS);\r
-          }\r
-        } else if (StrnCmp(Data, L"\"", 1) == 0) {\r
+\r
+        if (EFI_ERROR (Status) || (Buffer == NULL)) {\r
           //\r
-          // ascii text\r
+          // Creating a new variable.  determine attributes from command line.\r
           //\r
-          Data++;\r
-          Buffer = AllocateZeroPool(StrSize(Data) / 2);\r
-          AsciiSPrint(Buffer, StrSize(Data) / 2, "%s", Data);\r
-          ((CHAR8*)Buffer)[AsciiStrLen(Buffer)-1] = CHAR_NULL;\r
-\r
-          Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, AsciiStrSize(Buffer)-sizeof(CHAR8), Buffer);\r
-          if (EFI_ERROR(Status)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
-            ShellStatus = SHELL_ACCESS_DENIED;\r
-          } else {\r
-            ASSERT(ShellStatus == SHELL_SUCCESS);\r
+          Attributes = 0;\r
+          if (ShellCommandLineGetFlag (Package, L"-bs")) {\r
+            Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
           }\r
-        } else if (StrnCmp(Data, L"L\"", 2) == 0) {\r
-          //\r
-          // ucs2 text\r
-          //\r
-          Data++;\r
-          Data++;\r
-          Buffer = AllocateZeroPool(StrSize(Data));\r
-          UnicodeSPrint(Buffer, StrSize(Data), L"%s", Data);\r
-          ((CHAR16*)Buffer)[StrLen(Buffer)-1] = CHAR_NULL;\r
-\r
-          Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrSize(Buffer)-sizeof(CHAR16), Buffer);\r
-          if (EFI_ERROR(Status)) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
-            ShellStatus = SHELL_ACCESS_DENIED;\r
-          } else {\r
-            ASSERT(ShellStatus == SHELL_SUCCESS);\r
+\r
+          if (ShellCommandLineGetFlag (Package, L"-rt")) {\r
+            Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |\r
+                          EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
           }\r
-        } else if (StrnCmp(Data, L"--", 2) == 0) {\r
-          //\r
-          // device path in text format\r
-          //\r
-          Data++;\r
-          Data++;\r
-          Status = gBS->LocateProtocol(&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID**)&DevPathFromText);\r
-          ASSERT_EFI_ERROR(Status);\r
-          DevPath = DevPathFromText->ConvertTextToDevicePath(Data);\r
-          if (DevPath == NULL) {\r
-            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, Status);\r
-            ShellStatus = SHELL_INVALID_PARAMETER;\r
-          } else {\r
-            Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, GetDevicePathSize(DevPath), DevPath);\r
-            if (EFI_ERROR(Status)) {\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
-              ShellStatus = SHELL_ACCESS_DENIED;\r
-            } else {\r
-              ASSERT(ShellStatus == SHELL_SUCCESS);\r
-            }\r
+\r
+          if (ShellCommandLineGetFlag (Package, L"-nv")) {\r
+            Attributes |= EFI_VARIABLE_NON_VOLATILE;\r
           }\r
+        }\r
+\r
+        SHELL_FREE_NON_NULL (Buffer);\r
+\r
+        Size   = 0;\r
+        Status = GetVariableDataFromParameter (Package, (UINT8 **)&Buffer, &Size);\r
+        if (!EFI_ERROR (Status)) {\r
+          Status = gRT->SetVariable ((CHAR16 *)VariableName, &Guid, Attributes, Size, Buffer);\r
+        }\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);\r
+          ShellStatus = SHELL_ACCESS_DENIED;\r
         } else {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Data);\r
-          ShellStatus = SHELL_INVALID_PARAMETER;\r
+          ASSERT (ShellStatus == SHELL_SUCCESS);\r
         }\r
       }\r
     }\r
+\r
     ShellCommandLineFreeVarList (Package);\r
   }\r
 \r
   if (Buffer != NULL) {\r
-    FreePool(Buffer);\r
-  }\r
-\r
-  if (DevPath != NULL) {\r
-    FreePool(DevPath);\r
+    FreePool (Buffer);\r
   }\r
 \r
   return (ShellStatus);\r