2 Main file for SetVar shell Debug1 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2017, 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
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.
16 #include "UefiShellDebug1CommandsLib.h"
18 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
19 {L
"-guid", TypeValue
},
27 DataTypeHexNumber
= 0,
31 DataTypeDevicePath
= 4,
43 Check if the input is a (potentially empty) string of hexadecimal nibbles.
45 @param[in] String The CHAR16 string to check.
47 @retval FALSE A character has been found in String for which
48 ShellIsHexaDecimalDigitCharacter() returned FALSE.
50 @retval TRUE Otherwise. (Note that this covers the case when String is
54 IsStringOfHexNibbles (
55 IN CONST CHAR16
*String
60 for (Pos
= String
; *Pos
!= L
'\0'; ++Pos
) {
61 if (!ShellIsHexaDecimalDigitCharacter (*Pos
)) {
69 Function to check the TYPE of Data.
71 @param[in] Data The Data to be check.
73 @retval DATA_TYPE The TYPE of Data.
80 if (Data
[0] == L
'0' && (Data
[1] == L
'x' || Data
[1] == L
'X')) {
81 if (IsStringOfHexNibbles (Data
+2) && StrLen (Data
+ 2) <= 16) {
82 return DataTypeHexNumber
;
84 return DataTypeUnKnow
;
86 } else if (Data
[0] == L
'H') {
87 if (IsStringOfHexNibbles (Data
+ 1) && StrLen (Data
+ 1) % 2 == 0) {
88 return DataTypeHexArray
;
90 return DataTypeUnKnow
;
92 } else if (Data
[0] == L
'S') {
94 } else if (Data
[0] == L
'L') {
95 return DataTypeUnicode
;
96 } else if (Data
[0] == L
'P' || StrnCmp (Data
, L
"--", 2) == 0) {
97 return DataTypeDevicePath
;
100 if (IsStringOfHexNibbles (Data
) && StrLen (Data
) % 2 == 0) {
101 return DataTypeHexArray
;
104 return DataTypeAscii
;
108 Function to parse the Data by the type of Data, and save in the Buffer.
110 @param[in] Data A pointer to a buffer to be parsed.
111 @param[out] Buffer A pointer to a buffer to hold the return data.
112 @param[in,out] BufferSize On input, indicates the size of Buffer in bytes.
113 On output,indicates the size of data return in Buffer.
114 Or the size in bytes of the buffer needed to obtain.
116 @retval EFI_INVALID_PARAMETER The Buffer or BufferSize is NULL.
117 @retval EFI_BUFFER_TOO_SMALL The Buffer is too small to hold the data.
118 @retval EFI_OUT_OF_RESOURCES A memory allcation failed.
119 @retval EFI_SUCCESS The Data parsed successful and save in the Buffer.
123 IN CONST CHAR16
*Data
,
125 IN OUT UINTN
*BufferSize
133 EFI_DEVICE_PATH_PROTOCOL
*DevPath
;
141 Status
= EFI_SUCCESS
;
143 if (Data
== NULL
|| BufferSize
== NULL
) {
144 return EFI_INVALID_PARAMETER
;
147 DataType
= TestDataType (Data
);
148 if (DataType
== DataTypeHexNumber
) {
152 StrHexToUint64S (Data
+ 2, NULL
, &HexNumber
);
153 HexNumberLen
= StrLen (Data
+ 2);
154 if (HexNumberLen
>= 1 && HexNumberLen
<= 2) {
156 } else if (HexNumberLen
>= 3 && HexNumberLen
<= 4) {
158 } else if (HexNumberLen
>= 5 && HexNumberLen
<= 8) {
160 } else if (HexNumberLen
>= 9 && HexNumberLen
<= 16) {
163 if (Buffer
!= NULL
&& *BufferSize
>= Size
) {
164 CopyMem(Buffer
, (VOID
*)&HexNumber
, Size
);
166 Status
= EFI_BUFFER_TOO_SMALL
;
169 } else if (DataType
== DataTypeHexArray
) {
177 Size
= StrLen (Data
) / 2;
178 if (Buffer
!= NULL
&& *BufferSize
>= Size
) {
179 StrHexToBytes(Data
, StrLen (Data
), (UINT8
*)Buffer
, Size
);
181 Status
= EFI_BUFFER_TOO_SMALL
;
184 } else if (DataType
== DataTypeAscii
) {
191 AsciiBuffer
= AllocateZeroPool (StrSize (Data
) / 2);
192 if (AsciiBuffer
== NULL
) {
193 Status
= EFI_OUT_OF_RESOURCES
;
195 AsciiSPrint (AsciiBuffer
, StrSize (Data
) / 2, "%s", (CHAR8
*)Data
);
197 Size
= StrSize (Data
) / 2 - 1;
198 if (Buffer
!= NULL
&& *BufferSize
>= Size
) {
199 CopyMem (Buffer
, AsciiBuffer
, Size
);
201 Status
= EFI_BUFFER_TOO_SMALL
;
205 SHELL_FREE_NON_NULL (AsciiBuffer
);
206 } else if (DataType
== DataTypeUnicode
) {
213 Size
= StrSize (Data
) - sizeof (CHAR16
);
214 if (Buffer
!= NULL
&& *BufferSize
>= Size
) {
215 CopyMem (Buffer
, Data
, Size
);
217 Status
= EFI_BUFFER_TOO_SMALL
;
220 } else if (DataType
== DataTypeDevicePath
) {
223 } else if (StrnCmp (Data
, L
"--", 2) == 0) {
226 DevPath
= ConvertTextToDevicePath (Data
);
227 if (DevPath
== NULL
) {
228 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SETVAR_ERROR_DPFT
), gShellDebug1HiiHandle
, L
"setvar");
229 Status
= EFI_INVALID_PARAMETER
;
231 Size
= GetDevicePathSize (DevPath
);
232 if (Buffer
!= NULL
&& *BufferSize
>= Size
) {
233 CopyMem (Buffer
, DevPath
, Size
);
235 Status
= EFI_BUFFER_TOO_SMALL
;
239 SHELL_FREE_NON_NULL (DevPath
);
241 Status
= EFI_INVALID_PARAMETER
;
248 Function to get each data from parameters.
250 @param[in] Pacakge The package of checked values.
251 @param[out] Buffer A pointer to a buffer to hold the return data.
252 @param[out] BufferSize Indicates the size of data in bytes return in Buffer.
254 @retval EFI_INVALID_PARAMETER Buffer or BufferSize is NULL.
255 @retval EFI_OUT_OF_RESOURCES A memory allcation failed.
256 @retval EFI_SUCCESS Get each parameter data was successful.
259 GetVariableDataFromParameter (
260 IN CONST LIST_ENTRY
*Package
,
262 OUT UINTN
*BufferSize
265 CONST CHAR16
*TempData
;
274 Status
= EFI_SUCCESS
;
276 if (BufferSize
== NULL
|| Buffer
== NULL
|| ShellCommandLineGetCount (Package
) < 3) {
277 return EFI_INVALID_PARAMETER
;
280 for (Index
= 2; Index
< ShellCommandLineGetCount (Package
); Index
++) {
281 TempData
= ShellCommandLineGetRawValue (Package
, Index
);
283 if (TempData
[0] != L
'=') {
284 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellDebug1HiiHandle
, L
"setvar", TempData
);
285 return EFI_INVALID_PARAMETER
;
288 TempData
= TempData
+ 1;
290 Status
= ParseParameterData (TempData
, NULL
, &Size
);
291 if (EFI_ERROR (Status
)) {
292 if (Status
== EFI_BUFFER_TOO_SMALL
) {
294 // We expect return EFI_BUFFER_TOO_SMALL when pass 'NULL' as second parameter to the function ParseParameterData.
298 if (Status
== EFI_INVALID_PARAMETER
) {
299 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellDebug1HiiHandle
, L
"setvar", TempData
);
300 } else if (Status
== EFI_NOT_FOUND
) {
301 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_SETVAR_ERROR_DPFT
), gShellDebug1HiiHandle
, L
"setvar");
308 *BufferSize
= TotalSize
;
309 *Buffer
= AllocateZeroPool (TotalSize
);
311 if (*Buffer
== NULL
) {
312 Status
= EFI_OUT_OF_RESOURCES
;
314 BufferWalker
= *Buffer
;
315 for (Index
= 2; Index
< ShellCommandLineGetCount (Package
); Index
++) {
316 TempData
= ShellCommandLineGetRawValue (Package
, Index
);
317 TempData
= TempData
+ 1;
320 Status
= ParseParameterData (TempData
, (VOID
*)BufferWalker
, &Size
);
321 if (!EFI_ERROR (Status
)) {
322 BufferWalker
= BufferWalker
+ Size
;
323 TotalSize
= TotalSize
- Size
;
334 Function for 'setvar' command.
336 @param[in] ImageHandle Handle to the Image (NULL if Internal).
337 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
341 ShellCommandRunSetVar (
342 IN EFI_HANDLE ImageHandle
,
343 IN EFI_SYSTEM_TABLE
*SystemTable
347 RETURN_STATUS RStatus
;
349 CHAR16
*ProblemParam
;
350 SHELL_STATUS ShellStatus
;
351 CONST CHAR16
*VariableName
;
353 CONST CHAR16
*StringGuid
;
359 ShellStatus
= SHELL_SUCCESS
;
360 Status
= EFI_SUCCESS
;
366 // initialize the shell lib (we must be in non-auto-init...)
368 Status
= ShellInitialize();
369 ASSERT_EFI_ERROR(Status
);
371 Status
= CommandInit();
372 ASSERT_EFI_ERROR(Status
);
375 // parse the command line
377 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
378 if (EFI_ERROR(Status
)) {
379 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
380 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"setvar", ProblemParam
);
381 FreePool(ProblemParam
);
382 ShellStatus
= SHELL_INVALID_PARAMETER
;
387 if (ShellCommandLineGetCount(Package
) < 2) {
388 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
, L
"setvar");
389 ShellStatus
= SHELL_INVALID_PARAMETER
;
391 VariableName
= ShellCommandLineGetRawValue(Package
, 1);
392 if (!ShellCommandLineGetFlag(Package
, L
"-guid")){
393 CopyGuid(&Guid
, &gEfiGlobalVariableGuid
);
395 StringGuid
= ShellCommandLineGetValue(Package
, L
"-guid");
396 RStatus
= StrToGuid (StringGuid
, &Guid
);
397 if (RETURN_ERROR (RStatus
) || (StringGuid
[GUID_STRING_LENGTH
] != L
'\0')) {
398 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PARAM_INV
), gShellDebug1HiiHandle
, L
"setvar", StringGuid
);
399 ShellStatus
= SHELL_INVALID_PARAMETER
;
403 if (ShellCommandLineGetCount(Package
) == 2) {
407 Status
= gRT
->GetVariable((CHAR16
*)VariableName
, &Guid
, &Attributes
, &Size
, Buffer
);
408 if (Status
== EFI_BUFFER_TOO_SMALL
) {
409 Buffer
= AllocateZeroPool(Size
);
410 Status
= gRT
->GetVariable((CHAR16
*)VariableName
, &Guid
, &Attributes
, &Size
, Buffer
);
412 if (!EFI_ERROR(Status
) && Buffer
!= NULL
) {
413 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_SETVAR_PRINT
), gShellDebug1HiiHandle
, &Guid
, VariableName
, Size
);
414 for (LoopVar
= 0; LoopVar
< Size
; LoopVar
++) {
415 ShellPrintEx(-1, -1, L
"%02x ", ((UINT8
*)Buffer
)[LoopVar
]);
417 ShellPrintEx(-1, -1, L
"\r\n");
419 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_SETVAR_ERROR_GET
), gShellDebug1HiiHandle
, L
"setvar", &Guid
, VariableName
);
420 ShellStatus
= SHELL_ACCESS_DENIED
;
424 // Create, Delete or Modify.
426 Status
= gRT
->GetVariable((CHAR16
*)VariableName
, &Guid
, &Attributes
, &Size
, Buffer
);
427 if (Status
== EFI_BUFFER_TOO_SMALL
) {
428 Buffer
= AllocateZeroPool(Size
);
429 Status
= gRT
->GetVariable((CHAR16
*)VariableName
, &Guid
, &Attributes
, &Size
, Buffer
);
431 if (EFI_ERROR(Status
) || Buffer
== NULL
) {
433 // Creating a new variable. determine attributes from command line.
436 if (ShellCommandLineGetFlag(Package
, L
"-bs")) {
437 Attributes
|= EFI_VARIABLE_BOOTSERVICE_ACCESS
;
439 if (ShellCommandLineGetFlag(Package
, L
"-rt")) {
440 Attributes
|= EFI_VARIABLE_RUNTIME_ACCESS
|
441 EFI_VARIABLE_BOOTSERVICE_ACCESS
;
443 if (ShellCommandLineGetFlag(Package
, L
"-nv")) {
444 Attributes
|= EFI_VARIABLE_NON_VOLATILE
;
447 SHELL_FREE_NON_NULL(Buffer
);
450 Status
= GetVariableDataFromParameter(Package
, (UINT8
**)&Buffer
, &Size
);
451 if (!EFI_ERROR(Status
)) {
452 Status
= gRT
->SetVariable((CHAR16
*)VariableName
, &Guid
, Attributes
, Size
, Buffer
);
454 if (EFI_ERROR(Status
)) {
455 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN(STR_SETVAR_ERROR_SET
), gShellDebug1HiiHandle
, L
"setvar", &Guid
, VariableName
);
456 ShellStatus
= SHELL_ACCESS_DENIED
;
458 ASSERT(ShellStatus
== SHELL_SUCCESS
);
462 ShellCommandLineFreeVarList (Package
);
465 if (Buffer
!= NULL
) {
469 return (ShellStatus
);