VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c@ 81028

最後變更 在這個檔案從81028是 80721,由 vboxsync 提交於 6 年 前

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 14.1 KB
 
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 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
10#include "UefiShellDebug1CommandsLib.h"
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;
34} HEX_NUMBER;
35
36/**
37 Check if the input is a (potentially empty) string of hexadecimal nibbles.
38
39 @param[in] String The CHAR16 string to check.
40
41 @retval FALSE A character has been found in String for which
42 ShellIsHexaDecimalDigitCharacter() returned FALSE.
43
44 @retval TRUE Otherwise. (Note that this covers the case when String is
45 empty.)
46**/
47BOOLEAN
48IsStringOfHexNibbles (
49 IN CONST CHAR16 *String
50 )
51{
52 CONST CHAR16 *Pos;
53
54 for (Pos = String; *Pos != L'\0'; ++Pos) {
55 if (!ShellIsHexaDecimalDigitCharacter (*Pos)) {
56 return FALSE;
57 }
58 }
59 return TRUE;
60}
61
62/**
63 Function to check the TYPE of Data.
64
65 @param[in] Data The Data to be check.
66
67 @retval DATA_TYPE The TYPE of Data.
68**/
69DATA_TYPE
70TestDataType (
71 IN CONST CHAR16 *Data
72 )
73{
74 if (Data[0] == L'0' && (Data[1] == L'x' || Data[1] == L'X')) {
75 if (IsStringOfHexNibbles (Data+2) && StrLen (Data + 2) <= 16) {
76 return DataTypeHexNumber;
77 } else {
78 return DataTypeUnKnow;
79 }
80 } else if (Data[0] == L'H') {
81 if (IsStringOfHexNibbles (Data + 1) && StrLen (Data + 1) % 2 == 0) {
82 return DataTypeHexArray;
83 } else {
84 return DataTypeUnKnow;
85 }
86 } else if (Data[0] == L'S') {
87 return DataTypeAscii;
88 } else if (Data[0] == L'L') {
89 return DataTypeUnicode;
90 } else if (Data[0] == L'P' || StrnCmp (Data, L"--", 2) == 0) {
91 return DataTypeDevicePath;
92 }
93
94 if (IsStringOfHexNibbles (Data) && StrLen (Data) % 2 == 0) {
95 return DataTypeHexArray;
96 }
97
98 return DataTypeAscii;
99}
100
101/**
102 Function to parse the Data by the type of Data, and save in the Buffer.
103
104 @param[in] Data A pointer to a buffer to be parsed.
105 @param[out] Buffer A pointer to a buffer to hold the return data.
106 @param[in,out] BufferSize On input, indicates the size of Buffer in bytes.
107 On output,indicates the size of data return in Buffer.
108 Or the size in bytes of the buffer needed to obtain.
109
110 @retval EFI_INVALID_PARAMETER The Buffer or BufferSize is NULL.
111 @retval EFI_BUFFER_TOO_SMALL The Buffer is too small to hold the data.
112 @retval EFI_OUT_OF_RESOURCES A memory allcation failed.
113 @retval EFI_SUCCESS The Data parsed successful and save in the Buffer.
114**/
115EFI_STATUS
116ParseParameterData (
117 IN CONST CHAR16 *Data,
118 OUT VOID *Buffer,
119 IN OUT UINTN *BufferSize
120 )
121{
122 UINT64 HexNumber;
123 UINTN HexNumberLen;
124 UINTN Size;
125 CHAR8 *AsciiBuffer;
126 DATA_TYPE DataType;
127 EFI_DEVICE_PATH_PROTOCOL *DevPath;
128 EFI_STATUS Status;
129
130 HexNumber = 0;
131 HexNumberLen = 0;
132 Size = 0;
133 AsciiBuffer = NULL;
134 DevPath = NULL;
135 Status = EFI_SUCCESS;
136
137 if (Data == NULL || BufferSize == NULL) {
138 return EFI_INVALID_PARAMETER;
139 }
140
141 DataType = TestDataType (Data);
142 if (DataType == DataTypeHexNumber) {
143 //
144 // hex number
145 //
146 StrHexToUint64S (Data + 2, NULL, &HexNumber);
147 HexNumberLen = StrLen (Data + 2);
148 if (HexNumberLen >= 1 && HexNumberLen <= 2) {
149 Size = 1;
150 } else if (HexNumberLen >= 3 && HexNumberLen <= 4) {
151 Size = 2;
152 } else if (HexNumberLen >= 5 && HexNumberLen <= 8) {
153 Size = 4;
154 } else if (HexNumberLen >= 9 && HexNumberLen <= 16) {
155 Size = 8;
156 }
157 if (Buffer != NULL && *BufferSize >= Size) {
158 CopyMem(Buffer, (VOID *)&HexNumber, Size);
159 } else {
160 Status = EFI_BUFFER_TOO_SMALL;
161 }
162 *BufferSize = Size;
163 } else if (DataType == DataTypeHexArray) {
164 //
165 // hex array
166 //
167 if (*Data == L'H') {
168 Data = Data + 1;
169 }
170
171 Size = StrLen (Data) / 2;
172 if (Buffer != NULL && *BufferSize >= Size) {
173 StrHexToBytes(Data, StrLen (Data), (UINT8 *)Buffer, Size);
174 } else {
175 Status = EFI_BUFFER_TOO_SMALL;
176 }
177 *BufferSize = Size;
178 } else if (DataType == DataTypeAscii) {
179 //
180 // ascii text
181 //
182 if (*Data == L'S') {
183 Data = Data + 1;
184 }
185 AsciiBuffer = AllocateZeroPool (StrSize (Data) / 2);
186 if (AsciiBuffer == NULL) {
187 Status = EFI_OUT_OF_RESOURCES;
188 } else {
189 AsciiSPrint (AsciiBuffer, StrSize (Data) / 2, "%s", (CHAR8 *)Data);
190
191 Size = StrSize (Data) / 2 - 1;
192 if (Buffer != NULL && *BufferSize >= Size) {
193 CopyMem (Buffer, AsciiBuffer, Size);
194 } else {
195 Status = EFI_BUFFER_TOO_SMALL;
196 }
197 *BufferSize = Size;
198 }
199 SHELL_FREE_NON_NULL (AsciiBuffer);
200 } else if (DataType == DataTypeUnicode) {
201 //
202 // unicode text
203 //
204 if (*Data == L'L') {
205 Data = Data + 1;
206 }
207 Size = StrSize (Data) - sizeof (CHAR16);
208 if (Buffer != NULL && *BufferSize >= Size) {
209 CopyMem (Buffer, Data, Size);
210 } else {
211 Status = EFI_BUFFER_TOO_SMALL;
212 }
213 *BufferSize = Size;
214 } else if (DataType == DataTypeDevicePath) {
215 if (*Data == L'P') {
216 Data = Data + 1;
217 } else if (StrnCmp (Data, L"--", 2) == 0) {
218 Data = Data + 2;
219 }
220 DevPath = ConvertTextToDevicePath (Data);
221 if (DevPath == NULL) {
222 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
223 Status = EFI_INVALID_PARAMETER;
224 } else {
225 Size = GetDevicePathSize (DevPath);
226 if (Buffer != NULL && *BufferSize >= Size) {
227 CopyMem (Buffer, DevPath, Size);
228 } else {
229 Status = EFI_BUFFER_TOO_SMALL;
230 }
231 *BufferSize = Size;
232 }
233 SHELL_FREE_NON_NULL (DevPath);
234 } else {
235 Status = EFI_INVALID_PARAMETER;
236 }
237
238 return Status;
239}
240
241/**
242 Function to get each data from parameters.
243
244 @param[in] Package The package of checked values.
245 @param[out] Buffer A pointer to a buffer to hold the return data.
246 @param[out] BufferSize Indicates the size of data in bytes return in Buffer.
247
248 @retval EFI_INVALID_PARAMETER Buffer or BufferSize is NULL.
249 @retval EFI_OUT_OF_RESOURCES A memory allcation failed.
250 @retval EFI_SUCCESS Get each parameter data was successful.
251**/
252EFI_STATUS
253GetVariableDataFromParameter (
254 IN CONST LIST_ENTRY *Package,
255 OUT UINT8 **Buffer,
256 OUT UINTN *BufferSize
257 )
258{
259 CONST CHAR16 *TempData;
260 UINTN Index;
261 UINTN TotalSize;
262 UINTN Size;
263 UINT8 *BufferWalker;
264 EFI_STATUS Status;
265
266 TotalSize = 0;
267 Size = 0;
268 Status = EFI_SUCCESS;
269
270 if (BufferSize == NULL || Buffer == NULL || ShellCommandLineGetCount (Package) < 3) {
271 return EFI_INVALID_PARAMETER;
272 }
273
274 for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) {
275 TempData = ShellCommandLineGetRawValue (Package, Index);
276 ASSERT (TempData != NULL);
277
278 if (TempData[0] != L'=') {
279 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData);
280 return EFI_INVALID_PARAMETER;
281 }
282
283 TempData = TempData + 1;
284 Size = 0;
285 Status = ParseParameterData (TempData, NULL, &Size);
286 if (EFI_ERROR (Status)) {
287 if (Status == EFI_BUFFER_TOO_SMALL) {
288 //
289 // We expect return EFI_BUFFER_TOO_SMALL when pass 'NULL' as second parameter to the function ParseParameterData.
290 //
291 TotalSize += Size;
292 } else {
293 if (Status == EFI_INVALID_PARAMETER) {
294 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData);
295 } else if (Status == EFI_NOT_FOUND) {
296 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
297 }
298 return Status;
299 }
300 }
301 }
302
303 *BufferSize = TotalSize;
304 *Buffer = AllocateZeroPool (TotalSize);
305
306 if (*Buffer == NULL) {
307 Status = EFI_OUT_OF_RESOURCES;
308 } else {
309 BufferWalker = *Buffer;
310 for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) {
311 TempData = ShellCommandLineGetRawValue (Package, Index);
312 TempData = TempData + 1;
313
314 Size = TotalSize;
315 Status = ParseParameterData (TempData, (VOID *)BufferWalker, &Size);
316 if (!EFI_ERROR (Status)) {
317 BufferWalker = BufferWalker + Size;
318 TotalSize = TotalSize - Size;
319 } else {
320 return Status;
321 }
322 }
323 }
324
325 return EFI_SUCCESS;
326}
327
328/**
329 Function for 'setvar' command.
330
331 @param[in] ImageHandle Handle to the Image (NULL if Internal).
332 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
333**/
334SHELL_STATUS
335EFIAPI
336ShellCommandRunSetVar (
337 IN EFI_HANDLE ImageHandle,
338 IN EFI_SYSTEM_TABLE *SystemTable
339 )
340{
341 EFI_STATUS Status;
342 RETURN_STATUS RStatus;
343 LIST_ENTRY *Package;
344 CHAR16 *ProblemParam;
345 SHELL_STATUS ShellStatus;
346 CONST CHAR16 *VariableName;
347 EFI_GUID Guid;
348 CONST CHAR16 *StringGuid;
349 UINT32 Attributes;
350 VOID *Buffer;
351 UINTN Size;
352 UINTN LoopVar;
353
354 ShellStatus = SHELL_SUCCESS;
355 Status = EFI_SUCCESS;
356 Buffer = NULL;
357 Size = 0;
358 Attributes = 0;
359
360 //
361 // initialize the shell lib (we must be in non-auto-init...)
362 //
363 Status = ShellInitialize();
364 ASSERT_EFI_ERROR(Status);
365
366 Status = CommandInit();
367 ASSERT_EFI_ERROR(Status);
368
369 //
370 // parse the command line
371 //
372 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
373 if (EFI_ERROR(Status)) {
374 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
375 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"setvar", ProblemParam);
376 FreePool(ProblemParam);
377 ShellStatus = SHELL_INVALID_PARAMETER;
378 } else {
379 ASSERT(FALSE);
380 }
381 } else if (ShellCommandLineCheckDuplicate (Package,&ProblemParam) != EFI_SUCCESS) {
382 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DUPLICATE), gShellDebug1HiiHandle, L"setvar", ProblemParam);
383 FreePool(ProblemParam);
384 ShellStatus = SHELL_INVALID_PARAMETER;
385 } else {
386 if (ShellCommandLineGetCount(Package) < 2) {
387 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"setvar");
388 ShellStatus = SHELL_INVALID_PARAMETER;
389 } else {
390 VariableName = ShellCommandLineGetRawValue(Package, 1);
391 if (!ShellCommandLineGetFlag(Package, L"-guid")){
392 CopyGuid(&Guid, &gEfiGlobalVariableGuid);
393 } else {
394 StringGuid = ShellCommandLineGetValue(Package, L"-guid");
395 RStatus = StrToGuid (StringGuid, &Guid);
396 if (RETURN_ERROR (RStatus) || (StringGuid[GUID_STRING_LENGTH] != L'\0')) {
397 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid);
398 ShellStatus = SHELL_INVALID_PARAMETER;
399 }
400 }
401
402 if (ShellCommandLineGetCount(Package) == 2) {
403 //
404 // Display
405 //
406 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
407 if (Status == EFI_BUFFER_TOO_SMALL) {
408 Buffer = AllocateZeroPool(Size);
409 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
410 }
411 if (!EFI_ERROR(Status) && Buffer != NULL) {
412 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);
413 for (LoopVar = 0; LoopVar < Size; LoopVar++) {
414 ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]);
415 }
416 ShellPrintEx(-1, -1, L"\r\n");
417 } else {
418 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
419 ShellStatus = SHELL_ACCESS_DENIED;
420 }
421 } else {
422 //
423 // Create, Delete or Modify.
424 //
425 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
426 if (Status == EFI_BUFFER_TOO_SMALL) {
427 Buffer = AllocateZeroPool(Size);
428 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
429 }
430 if (EFI_ERROR(Status) || Buffer == NULL) {
431 //
432 // Creating a new variable. determine attributes from command line.
433 //
434 Attributes = 0;
435 if (ShellCommandLineGetFlag(Package, L"-bs")) {
436 Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
437 }
438 if (ShellCommandLineGetFlag(Package, L"-rt")) {
439 Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |
440 EFI_VARIABLE_BOOTSERVICE_ACCESS;
441 }
442 if (ShellCommandLineGetFlag(Package, L"-nv")) {
443 Attributes |= EFI_VARIABLE_NON_VOLATILE;
444 }
445 }
446 SHELL_FREE_NON_NULL(Buffer);
447
448 Size = 0;
449 Status = GetVariableDataFromParameter(Package, (UINT8 **)&Buffer, &Size);
450 if (!EFI_ERROR(Status)) {
451 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, Size, Buffer);
452 }
453 if (EFI_ERROR(Status)) {
454 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
455 ShellStatus = SHELL_ACCESS_DENIED;
456 } else {
457 ASSERT(ShellStatus == SHELL_SUCCESS);
458 }
459 }
460 }
461 ShellCommandLineFreeVarList (Package);
462 }
463
464 if (Buffer != NULL) {
465 FreePool(Buffer);
466 }
467
468 return (ShellStatus);
469}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette