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