Home | History | Annotate | Download | only in Ebl
      1 /** @file
      2 *
      3 *  Copyright (c) 2011, ARM Limited. All rights reserved.
      4 *  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
      5 *
      6 *  This program and the accompanying materials
      7 *  are licensed and made available under the terms and conditions of the BSD License
      8 *  which accompanies this distribution.  The full text of the license may be found at
      9 *  http://opensource.org/licenses/bsd-license.php
     10 *
     11 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 *
     14 **/
     15 
     16 #include "Ebl.h"
     17 
     18 #include <Guid/GlobalVariable.h>
     19 
     20 EFI_STATUS
     21 EFIAPI
     22 EblGetCmd (
     23   IN UINTN  Argc,
     24   IN CHAR8  **Argv
     25   )
     26 {
     27   EFI_STATUS        Status = EFI_INVALID_PARAMETER;
     28   UINTN       Size;
     29   VOID*       Value;
     30   CHAR8*      AsciiVariableName = NULL;
     31   CHAR16*     VariableName;
     32   UINTN       VariableNameLen;
     33   UINT32      Index;
     34 
     35   if (Argc == 1) {
     36     AsciiPrint("Variable name is missing.\n");
     37     return Status;
     38   }
     39 
     40   for (Index = 1; Index < Argc; Index++) {
     41     if (Argv[Index][0] == '-') {
     42       AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);
     43     } else {
     44       AsciiVariableName = Argv[Index];
     45     }
     46   }
     47 
     48   if (AsciiVariableName == NULL) {
     49     AsciiPrint("Variable name is missing.\n");
     50     return Status;
     51   } else {
     52     VariableNameLen = AsciiStrLen (AsciiVariableName) + 1;
     53     VariableName = AllocatePool (VariableNameLen * sizeof (CHAR16));
     54     AsciiStrToUnicodeStrS (AsciiVariableName, VariableName, VariableNameLen);
     55   }
     56 
     57   // Try to get the variable size.
     58   Value = NULL;
     59   Size = 0;
     60   Status = gRT->GetVariable (VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);
     61   if (Status == EFI_NOT_FOUND) {
     62     AsciiPrint("Variable name '%s' not found.\n",VariableName);
     63   } else if (Status == EFI_BUFFER_TOO_SMALL) {
     64     // Get the environment variable value
     65     Value = AllocatePool (Size);
     66     if (Value == NULL) {
     67       return EFI_OUT_OF_RESOURCES;
     68     }
     69 
     70     Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);
     71     if (EFI_ERROR (Status)) {
     72       AsciiPrint("Error: '%r'\n",Status);
     73     } else {
     74       AsciiPrint("%a=%a\n",AsciiVariableName,Value);
     75     }
     76     FreePool(Value);
     77   } else {
     78     AsciiPrint("Error: '%r'\n",Status);
     79   }
     80 
     81   FreePool(VariableName);
     82   return Status;
     83 }
     84 
     85 EFI_STATUS
     86 EFIAPI
     87 EblSetCmd (
     88   IN UINTN  Argc,
     89   IN CHAR8  **Argv
     90   )
     91 {
     92   EFI_STATUS    Status = EFI_INVALID_PARAMETER;
     93   CHAR8*        AsciiVariableSetting = NULL;
     94   CHAR8*        AsciiVariableName;
     95   CHAR8*        AsciiValue;
     96   UINT32        AsciiValueLength;
     97   CHAR16*       VariableName;
     98   UINTN         VariableNameLen;
     99   UINT32        Index;
    100   UINT32        EscapedQuotes = 0;
    101   BOOLEAN       Volatile = FALSE;
    102 
    103   if (Argc == 1) {
    104     AsciiPrint("Variable name is missing.\n");
    105     return Status;
    106   }
    107 
    108   for (Index = 1; Index < Argc; Index++) {
    109     if (AsciiStrCmp(Argv[Index],"-v") == 0) {
    110       Volatile = 0;
    111     } else if (Argv[Index][0] == '-') {
    112       AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);
    113     } else {
    114       AsciiVariableSetting = Argv[Index];
    115     }
    116   }
    117 
    118   if (AsciiVariableSetting == NULL) {
    119     AsciiPrint("Variable name is missing.\n");
    120     return Status;
    121   }
    122 
    123   // Check if it is a valid variable setting
    124   AsciiValue = AsciiStrStr (AsciiVariableSetting,"=");
    125   if (AsciiValue == NULL) {
    126     //
    127     // There is no value. It means this variable will be deleted
    128     //
    129 
    130     // Convert VariableName into Unicode
    131     VariableNameLen = AsciiStrLen (AsciiVariableSetting) + 1;
    132     VariableName = AllocatePool (VariableNameLen * sizeof (CHAR16));
    133     AsciiStrToUnicodeStrS (AsciiVariableSetting, VariableName, VariableNameLen);
    134 
    135     Status = gRT->SetVariable (
    136                           VariableName,
    137                           &gEfiGlobalVariableGuid,
    138                           ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |
    139                           EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
    140                           0,
    141                           NULL
    142                           );
    143     if (!EFI_ERROR(Status)) {
    144       AsciiPrint("Variable '%s' deleted\n",VariableName);
    145     } else {
    146       AsciiPrint("Variable setting is incorrect. It should be VariableName=Value\n");
    147     }
    148     return Status;
    149   }
    150 
    151   AsciiValue[0] = '\0';
    152   AsciiVariableName = AsciiVariableSetting;
    153   AsciiValue++;
    154 
    155   // Clean AsciiValue from quote
    156   if (AsciiValue[0] == '"') {
    157     AsciiValue++;
    158   }
    159   AsciiValueLength = AsciiStrLen (AsciiValue);
    160   if ((AsciiValue[AsciiValueLength-2] != '\\') && (AsciiValue[AsciiValueLength-1] == '"')) {
    161     AsciiValue[AsciiValueLength-1] = '\0';
    162   }
    163 
    164   // Clean AsciiValue from escaped quotes
    165   for (Index = 0; Index < AsciiValueLength; Index++) {
    166     if ((Index > 0) && (AsciiValue[Index-1] == '\\') && (AsciiValue[Index] == '"')) {
    167       EscapedQuotes++;
    168     }
    169     AsciiValue[Index-EscapedQuotes] = AsciiValue[Index];
    170   }
    171   // Fill the end of the value with '\0'
    172   for (Index = 0; Index < EscapedQuotes; Index++) {
    173     AsciiValue[AsciiValueLength-1-Index] = '\0';
    174   }
    175 
    176   // Convert VariableName into Unicode
    177   VariableNameLen = AsciiStrLen (AsciiVariableName) + 1;
    178   VariableName = AllocatePool (VariableNameLen * sizeof (CHAR16));
    179   AsciiStrToUnicodeStrS (AsciiVariableName, VariableName, VariableNameLen);
    180 
    181   Status = gRT->SetVariable (
    182                       VariableName,
    183                       &gEfiGlobalVariableGuid,
    184                       ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |
    185                       EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
    186                       AsciiStrLen (AsciiValue)+1,
    187                       AsciiValue
    188                       );
    189   if (!EFI_ERROR(Status)) {
    190     AsciiPrint("'%a'='%a'\n",AsciiVariableName,AsciiValue);
    191   }
    192 
    193   return Status;
    194 }
    195 
    196 GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdVariableTemplate[] =
    197 {
    198   {
    199     "get",
    200     " ; get UEFI variable\n\r   [v]; verbose",
    201     NULL,
    202     EblGetCmd
    203   },
    204   {
    205     "set",
    206     " ; set UEFI variable\n\r   [v]; create volatile variable",
    207     NULL,
    208     EblSetCmd
    209   }
    210 };
    211 
    212 /**
    213   Initialize the commands in this in this file
    214 **/
    215 VOID
    216 EblInitializeVariableCmds (
    217   VOID
    218   )
    219 {
    220   EblAddCommands (mCmdVariableTemplate, sizeof (mCmdVariableTemplate)/sizeof (EBL_COMMAND_TABLE));
    221 }
    222