]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
ShellPkg/UefiShellDebug1CommandsLib: Remove unnecessary EFIAPI
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / SetVar.c
1 /** @file
2 Main file for SetVar shell Debug1 function.
3
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
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 "UefiShellDebug1CommandsLib.h"
17
18 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
19 {L"-guid", TypeValue},
20 {L"-bs", TypeFlag},
21 {L"-rt", TypeFlag},
22 {L"-nv", TypeFlag},
23 {NULL, TypeMax}
24 };
25
26
27 /**
28 Check if the input is a (potentially empty) string of hexadecimal nibbles.
29
30 @param[in] String The CHAR16 string to check.
31
32 @retval FALSE A character has been found in String for which
33 ShellIsHexaDecimalDigitCharacter() returned FALSE.
34
35 @retval TRUE Otherwise. (Note that this covers the case when String is
36 empty.)
37 **/
38 BOOLEAN
39 IsStringOfHexNibbles (
40 IN CONST CHAR16 *String
41 )
42 {
43 CONST CHAR16 *Pos;
44
45 for (Pos = String; *Pos != L'\0'; ++Pos) {
46 if (!ShellIsHexaDecimalDigitCharacter (*Pos)) {
47 return FALSE;
48 }
49 }
50 return TRUE;
51 }
52
53
54 /**
55 Function for 'setvar' command.
56
57 @param[in] ImageHandle Handle to the Image (NULL if Internal).
58 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
59 **/
60 SHELL_STATUS
61 EFIAPI
62 ShellCommandRunSetVar (
63 IN EFI_HANDLE ImageHandle,
64 IN EFI_SYSTEM_TABLE *SystemTable
65 )
66 {
67 EFI_STATUS Status;
68 LIST_ENTRY *Package;
69 CHAR16 *ProblemParam;
70 SHELL_STATUS ShellStatus;
71 CONST CHAR16 *VariableName;
72 CONST CHAR16 *Data;
73 EFI_GUID Guid;
74 CONST CHAR16 *StringGuid;
75 UINT32 Attributes;
76 VOID *Buffer;
77 UINTN Size;
78 UINTN LoopVar;
79 EFI_DEVICE_PATH_PROTOCOL *DevPath;
80
81 ShellStatus = SHELL_SUCCESS;
82 Status = EFI_SUCCESS;
83 Buffer = NULL;
84 Size = 0;
85 Attributes = 0;
86 DevPath = NULL;
87
88 //
89 // initialize the shell lib (we must be in non-auto-init...)
90 //
91 Status = ShellInitialize();
92 ASSERT_EFI_ERROR(Status);
93
94 Status = CommandInit();
95 ASSERT_EFI_ERROR(Status);
96
97 //
98 // parse the command line
99 //
100 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
101 if (EFI_ERROR(Status)) {
102 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
103 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"setvar", ProblemParam);
104 FreePool(ProblemParam);
105 ShellStatus = SHELL_INVALID_PARAMETER;
106 } else {
107 ASSERT(FALSE);
108 }
109 } else {
110 if (ShellCommandLineGetCount(Package) < 2) {
111 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"setvar");
112 ShellStatus = SHELL_INVALID_PARAMETER;
113 } else if (ShellCommandLineGetCount(Package) > 3) {
114 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"setvar");
115 ShellStatus = SHELL_INVALID_PARAMETER;
116 } else {
117 VariableName = ShellCommandLineGetRawValue(Package, 1);
118 Data = ShellCommandLineGetRawValue(Package, 2);
119 if (!ShellCommandLineGetFlag(Package, L"-guid")){
120 CopyGuid(&Guid, &gEfiGlobalVariableGuid);
121 } else {
122 StringGuid = ShellCommandLineGetValue(Package, L"-guid");
123 Status = ConvertStringToGuid(StringGuid, &Guid);
124 if (EFI_ERROR(Status)) {
125 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid);
126 ShellStatus = SHELL_INVALID_PARAMETER;
127 }
128 }
129 if (Data == NULL || Data[0] != L'=') {
130 //
131 // Display what's there
132 //
133 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
134 if (Status == EFI_BUFFER_TOO_SMALL) {
135 Buffer = AllocateZeroPool(Size);
136 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
137 }
138 if (!EFI_ERROR(Status)&& Buffer != NULL) {
139 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);
140 for (LoopVar = 0 ; LoopVar < Size ; LoopVar++) {
141 ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]);
142 }
143 ShellPrintEx(-1, -1, L"\r\n");
144 } else {
145 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
146 ShellStatus = SHELL_ACCESS_DENIED;
147 }
148 } else if (StrCmp(Data, L"=") == 0) {
149 //
150 // Delete what's there!
151 //
152 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, 0, NULL);
153 if (EFI_ERROR(Status)) {
154 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
155 ShellStatus = SHELL_ACCESS_DENIED;
156 } else {
157 ASSERT(ShellStatus == SHELL_SUCCESS);
158 }
159 } else {
160 //
161 // Change what's there or create a new one.
162 //
163
164 ASSERT(Data[0] == L'=');
165 Data++;
166 ASSERT(Data[0] != L'\0');
167
168 //
169 // Determine if the variable exists and get the attributes
170 //
171 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
172 if (Status == EFI_BUFFER_TOO_SMALL) {
173 Buffer = AllocateZeroPool(Size);
174 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
175 }
176
177 if (EFI_ERROR(Status) || Buffer == NULL) {
178 //
179 // Creating a new variable. determine attributes from command line.
180 //
181 Attributes = 0;
182 if (ShellCommandLineGetFlag(Package, L"-bs")) {
183 Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
184 }
185 if (ShellCommandLineGetFlag(Package, L"-rt")) {
186 Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |
187 EFI_VARIABLE_BOOTSERVICE_ACCESS;
188 }
189 if (ShellCommandLineGetFlag(Package, L"-nv")) {
190 Attributes |= EFI_VARIABLE_NON_VOLATILE;
191 }
192 }
193 SHELL_FREE_NON_NULL(Buffer);
194
195 //
196 // What type is the new data.
197 //
198 if (IsStringOfHexNibbles(Data)) {
199 if (StrLen(Data) % 2 != 0) {
200 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", Data);
201 ShellStatus = SHELL_INVALID_PARAMETER;
202 } else {
203 //
204 // arbitrary buffer
205 //
206 Buffer = AllocateZeroPool((StrLen(Data) / 2));
207 if (Buffer == NULL) {
208 Status = EFI_OUT_OF_RESOURCES;
209 } else {
210 for (LoopVar = 0 ; LoopVar < (StrLen(Data) / 2) ; LoopVar++) {
211 ((UINT8*)Buffer)[LoopVar] = (UINT8)(HexCharToUintn(Data[LoopVar*2]) * 16);
212 ((UINT8*)Buffer)[LoopVar] = (UINT8)(((UINT8*)Buffer)[LoopVar] + HexCharToUintn(Data[LoopVar*2+1]));
213 }
214 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrLen(Data) / 2, Buffer);
215 }
216 if (EFI_ERROR(Status)) {
217 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
218 ShellStatus = SHELL_ACCESS_DENIED;
219 } else {
220 ASSERT(ShellStatus == SHELL_SUCCESS);
221 }
222 }
223 } else if (StrnCmp(Data, L"\"", 1) == 0) {
224 //
225 // ascii text
226 //
227 Data++;
228 Buffer = AllocateZeroPool(StrSize(Data) / 2);
229 if (Buffer == NULL) {
230 Status = EFI_OUT_OF_RESOURCES;
231 } else {
232 AsciiSPrint(Buffer, StrSize(Data) / 2, "%s", Data);
233 ((CHAR8*)Buffer)[AsciiStrLen(Buffer)-1] = CHAR_NULL;
234 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, AsciiStrSize(Buffer)-sizeof(CHAR8), Buffer);
235 }
236 if (EFI_ERROR(Status)) {
237 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
238 ShellStatus = SHELL_ACCESS_DENIED;
239 } else {
240 ASSERT(ShellStatus == SHELL_SUCCESS);
241 }
242 } else if (StrnCmp(Data, L"L\"", 2) == 0) {
243 //
244 // ucs2 text
245 //
246 Data++;
247 Data++;
248 Buffer = AllocateZeroPool(StrSize(Data));
249 if (Buffer == NULL) {
250 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"setvar");
251 ShellStatus = SHELL_OUT_OF_RESOURCES;
252 } else {
253 UnicodeSPrint(Buffer, StrSize(Data), L"%s", Data);
254 ((CHAR16*)Buffer)[StrLen(Buffer)-1] = CHAR_NULL;
255
256 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrSize(Buffer)-sizeof(CHAR16), Buffer);
257 if (EFI_ERROR(Status)) {
258 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
259 ShellStatus = SHELL_ACCESS_DENIED;
260 } else {
261 ASSERT(ShellStatus == SHELL_SUCCESS);
262 }
263 }
264 } else if (StrnCmp(Data, L"--", 2) == 0) {
265 //
266 // device path in text format
267 //
268 Data++;
269 Data++;
270 DevPath = ConvertTextToDevicePath(Data);
271 if (DevPath == NULL) {
272 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
273 ShellStatus = SHELL_INVALID_PARAMETER;
274 } else {
275 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, GetDevicePathSize(DevPath), DevPath);
276 if (EFI_ERROR(Status)) {
277 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
278 ShellStatus = SHELL_ACCESS_DENIED;
279 } else {
280 ASSERT(ShellStatus == SHELL_SUCCESS);
281 }
282 }
283 } else {
284 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", Data);
285 ShellStatus = SHELL_INVALID_PARAMETER;
286 }
287 }
288 }
289 ShellCommandLineFreeVarList (Package);
290 }
291
292 if (Buffer != NULL) {
293 FreePool(Buffer);
294 }
295
296 if (DevPath != NULL) {
297 FreePool(DevPath);
298 }
299
300 return (ShellStatus);
301 }