TianoCore EDK2 master
Loading...
Searching...
No Matches
SetVar.c
Go to the documentation of this file.
1
11
12STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
13 { L"-guid", TypeValue },
14 { L"-bs", TypeFlag },
15 { L"-rt", TypeFlag },
16 { L"-nv", TypeFlag },
17 { NULL, TypeMax }
18};
19
20typedef enum {
21 DataTypeHexNumber = 0,
22 DataTypeHexArray = 1,
23 DataTypeAscii = 2,
24 DataTypeUnicode = 3,
25 DataTypeDevicePath = 4,
26 DataTypeUnKnow = 5
27} DATA_TYPE;
28
29typedef union {
30 UINT8 HexNumber8;
31 UINT16 HexNumber16;
32 UINT32 HexNumber32;
33 UINT64 HexNumber64;
35
47BOOLEAN
49 IN CONST CHAR16 *String
50 )
51{
52 CONST CHAR16 *Pos;
53
54 for (Pos = String; *Pos != L'\0'; ++Pos) {
56 return FALSE;
57 }
58 }
59
60 return TRUE;
61}
62
70DATA_TYPE
72 IN CONST CHAR16 *Data
73 )
74{
75 if ((Data[0] == L'0') && ((Data[1] == L'x') || (Data[1] == L'X'))) {
76 if (IsStringOfHexNibbles (Data+2) && (StrLen (Data + 2) <= 16)) {
77 return DataTypeHexNumber;
78 } else {
79 return DataTypeUnKnow;
80 }
81 } else if (Data[0] == L'H') {
82 if (IsStringOfHexNibbles (Data + 1) && (StrLen (Data + 1) % 2 == 0)) {
83 return DataTypeHexArray;
84 } else {
85 return DataTypeUnKnow;
86 }
87 } else if (Data[0] == L'S') {
88 return DataTypeAscii;
89 } else if (Data[0] == L'L') {
90 return DataTypeUnicode;
91 } else if ((Data[0] == L'P') || (StrnCmp (Data, L"--", 2) == 0)) {
92 return DataTypeDevicePath;
93 }
94
95 if (IsStringOfHexNibbles (Data) && (StrLen (Data) % 2 == 0)) {
96 return DataTypeHexArray;
97 }
98
99 return DataTypeAscii;
100}
101
118 IN CONST CHAR16 *Data,
119 OUT VOID *Buffer,
120 IN OUT UINTN *BufferSize
121 )
122{
123 UINT64 HexNumber;
124 UINTN HexNumberLen;
125 UINTN Size;
126 CHAR8 *AsciiBuffer;
127 DATA_TYPE DataType;
129 EFI_STATUS Status;
130
131 HexNumber = 0;
132 HexNumberLen = 0;
133 Size = 0;
134 AsciiBuffer = NULL;
135 DevPath = NULL;
136 Status = EFI_SUCCESS;
137
138 if ((Data == NULL) || (BufferSize == NULL)) {
139 return EFI_INVALID_PARAMETER;
140 }
141
142 DataType = TestDataType (Data);
143 if (DataType == DataTypeHexNumber) {
144 //
145 // hex number
146 //
147 StrHexToUint64S (Data + 2, NULL, &HexNumber);
148 HexNumberLen = StrLen (Data + 2);
149 if ((HexNumberLen >= 1) && (HexNumberLen <= 2)) {
150 Size = 1;
151 } else if ((HexNumberLen >= 3) && (HexNumberLen <= 4)) {
152 Size = 2;
153 } else if ((HexNumberLen >= 5) && (HexNumberLen <= 8)) {
154 Size = 4;
155 } else if ((HexNumberLen >= 9) && (HexNumberLen <= 16)) {
156 Size = 8;
157 }
158
159 if ((Buffer != NULL) && (*BufferSize >= Size)) {
160 CopyMem (Buffer, (VOID *)&HexNumber, Size);
161 } else {
162 Status = EFI_BUFFER_TOO_SMALL;
163 }
164
165 *BufferSize = Size;
166 } else if (DataType == DataTypeHexArray) {
167 //
168 // hex array
169 //
170 if (*Data == L'H') {
171 Data = Data + 1;
172 }
173
174 Size = StrLen (Data) / 2;
175 if ((Buffer != NULL) && (*BufferSize >= Size)) {
176 StrHexToBytes (Data, StrLen (Data), (UINT8 *)Buffer, Size);
177 } else {
178 Status = EFI_BUFFER_TOO_SMALL;
179 }
180
181 *BufferSize = Size;
182 } else if (DataType == DataTypeAscii) {
183 //
184 // ascii text
185 //
186 if (*Data == L'S') {
187 Data = Data + 1;
188 }
189
190 AsciiBuffer = AllocateZeroPool (StrSize (Data) / 2);
191 if (AsciiBuffer == NULL) {
192 Status = EFI_OUT_OF_RESOURCES;
193 } else {
194 AsciiSPrint (AsciiBuffer, StrSize (Data) / 2, "%s", (CHAR8 *)Data);
195
196 Size = StrSize (Data) / 2 - 1;
197 if ((Buffer != NULL) && (*BufferSize >= Size)) {
198 CopyMem (Buffer, AsciiBuffer, Size);
199 } else {
200 Status = EFI_BUFFER_TOO_SMALL;
201 }
202
203 *BufferSize = Size;
204 }
205
206 SHELL_FREE_NON_NULL (AsciiBuffer);
207 } else if (DataType == DataTypeUnicode) {
208 //
209 // unicode text
210 //
211 if (*Data == L'L') {
212 Data = Data + 1;
213 }
214
215 Size = StrSize (Data) - sizeof (CHAR16);
216 if ((Buffer != NULL) && (*BufferSize >= Size)) {
217 CopyMem (Buffer, Data, Size);
218 } else {
219 Status = EFI_BUFFER_TOO_SMALL;
220 }
221
222 *BufferSize = Size;
223 } else if (DataType == DataTypeDevicePath) {
224 if (*Data == L'P') {
225 Data = Data + 1;
226 } else if (StrnCmp (Data, L"--", 2) == 0) {
227 Data = Data + 2;
228 }
229
230 DevPath = ConvertTextToDevicePath (Data);
231 if (DevPath == NULL) {
232 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
233 Status = EFI_INVALID_PARAMETER;
234 } else {
235 Size = GetDevicePathSize (DevPath);
236 if ((Buffer != NULL) && (*BufferSize >= Size)) {
237 CopyMem (Buffer, DevPath, Size);
238 } else {
239 Status = EFI_BUFFER_TOO_SMALL;
240 }
241
242 *BufferSize = Size;
243 }
244
245 SHELL_FREE_NON_NULL (DevPath);
246 } else {
247 Status = EFI_INVALID_PARAMETER;
248 }
249
250 return Status;
251}
252
266 IN CONST LIST_ENTRY *Package,
267 OUT UINT8 **Buffer,
268 OUT UINTN *BufferSize
269 )
270{
271 CONST CHAR16 *TempData;
272 UINTN Index;
273 UINTN TotalSize;
274 UINTN Size;
275 UINT8 *BufferWalker;
276 EFI_STATUS Status;
277
278 TotalSize = 0;
279 Size = 0;
280 Status = EFI_SUCCESS;
281
282 if ((BufferSize == NULL) || (Buffer == NULL) || (ShellCommandLineGetCount (Package) < 3)) {
283 return EFI_INVALID_PARAMETER;
284 }
285
286 for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) {
287 TempData = ShellCommandLineGetRawValue (Package, Index);
288 if (TempData == NULL) {
289 ASSERT (TempData != NULL);
290 return EFI_INVALID_PARAMETER;
291 }
292
293 if (TempData[0] != L'=') {
294 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData);
295 return EFI_INVALID_PARAMETER;
296 }
297
298 TempData = TempData + 1;
299 Size = 0;
300 Status = ParseParameterData (TempData, NULL, &Size);
301 if (EFI_ERROR (Status)) {
302 if (Status == EFI_BUFFER_TOO_SMALL) {
303 //
304 // We expect return EFI_BUFFER_TOO_SMALL when pass 'NULL' as second parameter to the function ParseParameterData.
305 //
306 TotalSize += Size;
307 } else {
308 if (Status == EFI_INVALID_PARAMETER) {
309 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData);
310 } else if (Status == EFI_NOT_FOUND) {
311 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
312 }
313
314 return Status;
315 }
316 }
317 }
318
319 *BufferSize = TotalSize;
320 *Buffer = AllocateZeroPool (TotalSize);
321
322 if (*Buffer == NULL) {
323 Status = EFI_OUT_OF_RESOURCES;
324 } else {
325 BufferWalker = *Buffer;
326 for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) {
327 TempData = ShellCommandLineGetRawValue (Package, Index);
328 TempData = TempData + 1;
329
330 Size = TotalSize;
331 Status = ParseParameterData (TempData, (VOID *)BufferWalker, &Size);
332 if (!EFI_ERROR (Status)) {
333 BufferWalker = BufferWalker + Size;
334 TotalSize = TotalSize - Size;
335 } else {
336 return Status;
337 }
338 }
339 }
340
341 return EFI_SUCCESS;
342}
343
351EFIAPI
353 IN EFI_HANDLE ImageHandle,
354 IN EFI_SYSTEM_TABLE *SystemTable
355 )
356{
357 EFI_STATUS Status;
358 RETURN_STATUS RStatus;
359 LIST_ENTRY *Package;
360 CHAR16 *ProblemParam;
361 SHELL_STATUS ShellStatus;
362 CONST CHAR16 *VariableName;
363 EFI_GUID Guid;
364 CONST CHAR16 *StringGuid;
365 UINT32 Attributes;
366 VOID *Buffer;
367 UINTN Size;
368 UINTN LoopVar;
369
370 ShellStatus = SHELL_SUCCESS;
371 Status = EFI_SUCCESS;
372 Buffer = NULL;
373 Size = 0;
374 Attributes = 0;
375
376 //
377 // initialize the shell lib (we must be in non-auto-init...)
378 //
379 Status = ShellInitialize ();
380 ASSERT_EFI_ERROR (Status);
381
382 Status = CommandInit ();
383 ASSERT_EFI_ERROR (Status);
384
385 //
386 // parse the command line
387 //
388 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
389 if (EFI_ERROR (Status)) {
390 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
391 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"setvar", ProblemParam);
392 FreePool (ProblemParam);
393 ShellStatus = SHELL_INVALID_PARAMETER;
394 } else {
395 ASSERT (FALSE);
396 }
397 } else if (ShellCommandLineCheckDuplicate (Package, &ProblemParam) != EFI_SUCCESS) {
398 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_DUPLICATE), gShellDebug1HiiHandle, L"setvar", ProblemParam);
399 FreePool (ProblemParam);
400 ShellStatus = SHELL_INVALID_PARAMETER;
401 } else {
402 if (ShellCommandLineGetCount (Package) < 2) {
403 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"setvar");
404 ShellStatus = SHELL_INVALID_PARAMETER;
405 } else {
406 VariableName = ShellCommandLineGetRawValue (Package, 1);
407 if (VariableName == NULL) {
410 }
411
412 if (!ShellCommandLineGetFlag (Package, L"-guid")) {
413 CopyGuid (&Guid, &gEfiGlobalVariableGuid);
414 } else {
415 StringGuid = ShellCommandLineGetValue (Package, L"-guid");
416 if (StringGuid != NULL) {
417 RStatus = StrToGuid (StringGuid, &Guid);
418 } else {
419 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid);
422 }
423
424 if (RETURN_ERROR (RStatus) || (StringGuid[GUID_STRING_LENGTH] != L'\0')) {
425 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid);
426 ShellStatus = SHELL_INVALID_PARAMETER;
427 }
428 }
429
430 if (ShellCommandLineGetCount (Package) == 2) {
431 //
432 // Display
433 //
434 Status = gRT->GetVariable ((CHAR16 *)VariableName, &Guid, &Attributes, &Size, Buffer);
435 if (Status == EFI_BUFFER_TOO_SMALL) {
436 Buffer = AllocateZeroPool (Size);
437 if (Buffer == NULL) {
438 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"setvar");
441 }
442
443 Status = gRT->GetVariable ((CHAR16 *)VariableName, &Guid, &Attributes, &Size, Buffer);
444 }
445
446 if (!EFI_ERROR (Status) && (Buffer != NULL)) {
447 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);
448 for (LoopVar = 0; LoopVar < Size; LoopVar++) {
449 ShellPrintEx (-1, -1, L"%02x ", ((UINT8 *)Buffer)[LoopVar]);
450 }
451
452 ShellPrintEx (-1, -1, L"\r\n");
453 } else {
454 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
455 ShellStatus = SHELL_ACCESS_DENIED;
456 }
457 } else {
458 //
459 // Create, Delete or Modify.
460 //
461 Status = gRT->GetVariable ((CHAR16 *)VariableName, &Guid, &Attributes, &Size, Buffer);
462 if (Status == EFI_BUFFER_TOO_SMALL) {
463 Buffer = AllocateZeroPool (Size);
464 if (Buffer == NULL) {
465 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"setvar");
468 }
469
470 Status = gRT->GetVariable ((CHAR16 *)VariableName, &Guid, &Attributes, &Size, Buffer);
471 }
472
473 if (EFI_ERROR (Status) || (Buffer == NULL)) {
474 //
475 // Creating a new variable. determine attributes from command line.
476 //
477 Attributes = 0;
478 if (ShellCommandLineGetFlag (Package, L"-bs")) {
479 Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
480 }
481
482 if (ShellCommandLineGetFlag (Package, L"-rt")) {
483 Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |
484 EFI_VARIABLE_BOOTSERVICE_ACCESS;
485 }
486
487 if (ShellCommandLineGetFlag (Package, L"-nv")) {
488 Attributes |= EFI_VARIABLE_NON_VOLATILE;
489 }
490 }
491
492 SHELL_FREE_NON_NULL (Buffer);
493
494 Size = 0;
495 Status = GetVariableDataFromParameter (Package, (UINT8 **)&Buffer, &Size);
496 if (!EFI_ERROR (Status)) {
497 Status = gRT->SetVariable ((CHAR16 *)VariableName, &Guid, Attributes, Size, Buffer);
498 }
499
500 if (EFI_ERROR (Status)) {
501 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
502 ShellStatus = SHELL_ACCESS_DENIED;
503 } else {
504 ASSERT (ShellStatus == SHELL_SUCCESS);
505 }
506 }
507 }
508
510 }
511
512 if (Buffer != NULL) {
513 FreePool (Buffer);
514 }
515
516 return (ShellStatus);
517}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
INTN EFIAPI StrnCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString, IN UINTN Length)
Definition: String.c:162
RETURN_STATUS EFIAPI StrToGuid(IN CONST CHAR16 *String, OUT GUID *Guid)
Definition: SafeString.c:1500
RETURN_STATUS EFIAPI StrHexToBytes(IN CONST CHAR16 *String, IN UINTN Length, OUT UINT8 *Buffer, IN UINTN MaxBufferSize)
Definition: SafeString.c:1615
RETURN_STATUS EFIAPI StrHexToUint64S(IN CONST CHAR16 *String, OUT CHAR16 **EndPointer OPTIONAL, OUT UINT64 *Data)
Definition: SafeString.c:994
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI ConvertTextToDevicePath(IN CONST CHAR16 *TextDevicePath)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
SHELL_STATUS
Definition: Shell.h:21
@ SHELL_OUT_OF_RESOURCES
Definition: Shell.h:73
@ SHELL_ACCESS_DENIED
Definition: Shell.h:106
@ SHELL_SUCCESS
Definition: Shell.h:25
@ SHELL_INVALID_PARAMETER
Definition: Shell.h:35
DATA_TYPE TestDataType(IN CONST CHAR16 *Data)
Definition: SetVar.c:71
EFI_STATUS ParseParameterData(IN CONST CHAR16 *Data, OUT VOID *Buffer, IN OUT UINTN *BufferSize)
Definition: SetVar.c:117
SHELL_STATUS EFIAPI ShellCommandRunSetVar(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: SetVar.c:352
EFI_STATUS GetVariableDataFromParameter(IN CONST LIST_ENTRY *Package, OUT UINT8 **Buffer, OUT UINTN *BufferSize)
Definition: SetVar.c:265
BOOLEAN IsStringOfHexNibbles(IN CONST CHAR16 *String)
Definition: SetVar.c:48
EFI_STATUS EFIAPI CommandInit(VOID)
BOOLEAN EFIAPI ShellIsHexaDecimalDigitCharacter(IN CHAR16 Char)
Definition: UefiShellLib.c:171
CONST CHAR16 *EFIAPI ShellCommandLineGetValue(IN CONST LIST_ENTRY *CheckPackage, IN CHAR16 *KeyString)
#define ShellCommandLineParse(CheckList, CheckPackage, ProblemParam, AutoPageBreak)
Make it easy to upgrade from older versions of the shell library.
Definition: ShellLib.h:755
EFI_STATUS EFIAPI ShellPrintHiiEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR8 *Language OPTIONAL, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle,...)
BOOLEAN EFIAPI ShellCommandLineGetFlag(IN CONST LIST_ENTRY *CONST CheckPackage, IN CONST CHAR16 *CONST KeyString)
@ TypeValue
A flag that has some data following it with a space (IE "-a 1").
Definition: ShellLib.h:700
@ TypeFlag
A flag that is present or not present only (IE "-a").
Definition: ShellLib.h:699
EFI_STATUS EFIAPI ShellCommandLineCheckDuplicate(IN CONST LIST_ENTRY *CheckPackage, OUT CHAR16 **Param)
VOID EFIAPI ShellCommandLineFreeVarList(IN LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellInitialize(VOID)
Definition: UefiShellLib.c:532
EFI_STATUS EFIAPI ShellPrintEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR16 *Format,...)
CONST CHAR16 *EFIAPI ShellCommandLineGetRawValue(IN CONST LIST_ENTRY *CONST CheckPackage, IN UINTN Position)
UINTN EFIAPI ShellCommandLineGetCount(IN CONST LIST_ENTRY *CheckPackage)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
#define STRING_TOKEN(t)
#define EFI_VARIABLE_NON_VOLATILE
Definition: Base.h:213