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 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
EblSetCmd(IN UINTN Argc,IN CHAR8 ** Argv)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
EblInitializeVariableCmds(VOID)211 EblInitializeVariableCmds (
212 VOID
213 )
214 {
215 EblAddCommands (mCmdVariableTemplate, sizeof (mCmdVariableTemplate)/sizeof (EBL_COMMAND_TABLE));
216 }
217