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   UINT32      Index;
     33 
     34   if (Argc == 1) {
     35     AsciiPrint("Variable name is missing.\n");
     36     return Status;
     37   }
     38 
     39   for (Index = 1; Index < Argc; Index++) {
     40     if (Argv[Index][0] == '-') {
     41       AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);
     42     } else {
     43       AsciiVariableName = Argv[Index];
     44     }
     45   }
     46 
     47   if (AsciiVariableName == NULL) {
     48     AsciiPrint("Variable name is missing.\n");
     49     return Status;
     50   } else {
     51     VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16));
     52     AsciiStrToUnicodeStr (AsciiVariableName,VariableName);
     53   }
     54 
     55   // Try to get the variable size.
     56   Value = NULL;
     57   Size = 0;
     58   Status = gRT->GetVariable (VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);
     59   if (Status == EFI_NOT_FOUND) {
     60     AsciiPrint("Variable name '%s' not found.\n",VariableName);
     61   } else if (Status == EFI_BUFFER_TOO_SMALL) {
     62     // Get the environment variable value
     63     Value = AllocatePool (Size);
     64     if (Value == NULL) {
     65       return EFI_OUT_OF_RESOURCES;
     66     }
     67 
     68     Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);
     69     if (EFI_ERROR (Status)) {
     70       AsciiPrint("Error: '%r'\n",Status);
     71     } else {
     72       AsciiPrint("%a=%a\n",AsciiVariableName,Value);
     73     }
     74     FreePool(Value);
     75   } else {
     76     AsciiPrint("Error: '%r'\n",Status);
     77   }
     78 
     79   FreePool(VariableName);
     80   return Status;
     81 }
     82 
     83 EFI_STATUS
     84 EFIAPI
     85 EblSetCmd (
     86   IN UINTN  Argc,
     87   IN CHAR8  **Argv
     88   )
     89 {
     90   EFI_STATUS    Status = EFI_INVALID_PARAMETER;
     91   CHAR8*        AsciiVariableSetting = NULL;
     92   CHAR8*        AsciiVariableName;
     93   CHAR8*        AsciiValue;
     94   UINT32        AsciiValueLength;
     95   CHAR16*       VariableName;
     96   UINT32        Index;
     97   UINT32        EscapedQuotes = 0;
     98   BOOLEAN       Volatile = FALSE;
     99 
    100   if (Argc == 1) {
    101     AsciiPrint("Variable name is missing.\n");
    102     return Status;
    103   }
    104 
    105   for (Index = 1; Index < Argc; Index++) {
    106     if (AsciiStrCmp(Argv[Index],"-v") == 0) {
    107       Volatile = 0;
    108     } else if (Argv[Index][0] == '-') {
    109       AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);
    110     } else {
    111       AsciiVariableSetting = Argv[Index];
    112     }
    113   }
    114 
    115   if (AsciiVariableSetting == NULL) {
    116     AsciiPrint("Variable name is missing.\n");
    117     return Status;
    118   }
    119 
    120   // Check if it is a valid variable setting
    121   AsciiValue = AsciiStrStr (AsciiVariableSetting,"=");
    122   if (AsciiValue == NULL) {
    123     //
    124     // There is no value. It means this variable will be deleted
    125     //
    126 
    127     // Convert VariableName into Unicode
    128     VariableName = AllocatePool((AsciiStrLen (AsciiVariableSetting) + 1) * sizeof (CHAR16));
    129     AsciiStrToUnicodeStr (AsciiVariableSetting,VariableName);
    130 
    131     Status = gRT->SetVariable (
    132                           VariableName,
    133                           &gEfiGlobalVariableGuid,
    134                           ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |
    135                           EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
    136                           0,
    137                           NULL
    138                           );
    139     if (!EFI_ERROR(Status)) {
    140       AsciiPrint("Variable '%s' deleted\n",VariableName);
    141     } else {
    142       AsciiPrint("Variable setting is incorrect. It should be VariableName=Value\n");
    143     }
    144     return Status;
    145   }
    146 
    147   AsciiValue[0] = '\0';
    148   AsciiVariableName = AsciiVariableSetting;
    149   AsciiValue++;
    150 
    151   // Clean AsciiValue from quote
    152   if (AsciiValue[0] == '"') {
    153     AsciiValue++;
    154   }
    155   AsciiValueLength = AsciiStrLen (AsciiValue);
    156   if ((AsciiValue[AsciiValueLength-2] != '\\') && (AsciiValue[AsciiValueLength-1] == '"')) {
    157     AsciiValue[AsciiValueLength-1] = '\0';
    158   }
    159 
    160   // Clean AsciiValue from escaped quotes
    161   for (Index = 0; Index < AsciiValueLength; Index++) {
    162     if ((Index > 0) && (AsciiValue[Index-1] == '\\') && (AsciiValue[Index] == '"')) {
    163       EscapedQuotes++;
    164     }
    165     AsciiValue[Index-EscapedQuotes] = AsciiValue[Index];
    166   }
    167   // Fill the end of the value with '\0'
    168   for (Index = 0; Index < EscapedQuotes; Index++) {
    169     AsciiValue[AsciiValueLength-1-Index] = '\0';
    170   }
    171 
    172   // Convert VariableName into Unicode
    173   VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16));
    174   AsciiStrToUnicodeStr (AsciiVariableName,VariableName);
    175 
    176   Status = gRT->SetVariable (
    177                       VariableName,
    178                       &gEfiGlobalVariableGuid,
    179                       ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |
    180                       EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
    181                       AsciiStrLen (AsciiValue)+1,
    182                       AsciiValue
    183                       );
    184   if (!EFI_ERROR(Status)) {
    185     AsciiPrint("'%a'='%a'\n",AsciiVariableName,AsciiValue);
    186   }
    187 
    188   return Status;
    189 }
    190 
    191 GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdVariableTemplate[] =
    192 {
    193   {
    194     "get",
    195     " ; get UEFI variable\n\r   [v]; verbose",
    196     NULL,
    197     EblGetCmd
    198   },
    199   {
    200     "set",
    201     " ; set UEFI variable\n\r   [v]; create volatile variable",
    202     NULL,
    203     EblSetCmd
    204   }
    205 };
    206 
    207 /**
    208   Initialize the commands in this in this file
    209 **/
    210 VOID
    211 EblInitializeVariableCmds (
    212   VOID
    213   )
    214 {
    215   EblAddCommands (mCmdVariableTemplate, sizeof (mCmdVariableTemplate)/sizeof (EBL_COMMAND_TABLE));
    216 }
    217