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
EblGetCmd(IN UINTN Argc,IN CHAR8 ** Argv)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
EblSetCmd(IN UINTN Argc,IN CHAR8 ** Argv)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
EblInitializeVariableCmds(VOID)216 EblInitializeVariableCmds (
217 VOID
218 )
219 {
220 EblAddCommands (mCmdVariableTemplate, sizeof (mCmdVariableTemplate)/sizeof (EBL_COMMAND_TABLE));
221 }
222