]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
ShellPkg: Update SetVar to use existing attributes for updating existing variables.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / SetVar.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for SetVar shell Debug1 function.\r
3\r
475387e9 4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
5d73d92f 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellDebug1CommandsLib.h"\r
16\r
17STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
18 {L"-guid", TypeValue},\r
19 {L"-bs", TypeFlag},\r
20 {L"-rt", TypeFlag},\r
21 {L"-nv", TypeFlag},\r
22 {NULL, TypeMax}\r
23 };\r
24\r
3737ac2b 25/**\r
26 Function for 'setvar' command.\r
27\r
28 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
29 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
30**/\r
5d73d92f 31SHELL_STATUS\r
32EFIAPI\r
33ShellCommandRunSetVar (\r
34 IN EFI_HANDLE ImageHandle,\r
35 IN EFI_SYSTEM_TABLE *SystemTable\r
36 )\r
37{\r
38 EFI_STATUS Status;\r
39 LIST_ENTRY *Package;\r
40 CHAR16 *ProblemParam;\r
41 SHELL_STATUS ShellStatus;\r
42 CONST CHAR16 *VariableName;\r
43 CONST CHAR16 *Data;\r
44 EFI_GUID Guid;\r
45 CONST CHAR16 *StringGuid;\r
46 UINT32 Attributes;\r
47 VOID *Buffer;\r
48 UINTN Size;\r
49 UINTN LoopVar;\r
50 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
5d73d92f 51\r
52 ShellStatus = SHELL_SUCCESS;\r
53 Status = EFI_SUCCESS;\r
54 Buffer = NULL;\r
55 Size = 0;\r
56 Attributes = 0;\r
57 DevPath = NULL;\r
58\r
59 //\r
60 // initialize the shell lib (we must be in non-auto-init...)\r
61 //\r
62 Status = ShellInitialize();\r
63 ASSERT_EFI_ERROR(Status);\r
64\r
65 Status = CommandInit();\r
66 ASSERT_EFI_ERROR(Status);\r
67\r
68 //\r
69 // parse the command line\r
70 //\r
71 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
72 if (EFI_ERROR(Status)) {\r
73 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
74 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);\r
75 FreePool(ProblemParam);\r
76 ShellStatus = SHELL_INVALID_PARAMETER;\r
77 } else {\r
78 ASSERT(FALSE);\r
79 }\r
80 } else {\r
81 if (ShellCommandLineGetCount(Package) < 2) {\r
82 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);\r
83 ShellStatus = SHELL_INVALID_PARAMETER;\r
84 } else if (ShellCommandLineGetCount(Package) > 3) {\r
85 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
86 ShellStatus = SHELL_INVALID_PARAMETER;\r
87 } else {\r
88 VariableName = ShellCommandLineGetRawValue(Package, 1);\r
89 Data = ShellCommandLineGetRawValue(Package, 2);\r
90 if (!ShellCommandLineGetFlag(Package, L"-guid")){\r
91 CopyGuid(&Guid, &gEfiGlobalVariableGuid);\r
92 } else {\r
93 StringGuid = ShellCommandLineGetValue(Package, L"-guid");\r
94 Status = ConvertStringToGuid(StringGuid, &Guid);\r
95 if (EFI_ERROR(Status)) {\r
3737ac2b 96 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, StringGuid);\r
97 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 98 }\r
99 }\r
475387e9 100 if (Data == NULL || Data[0] != L'=') {\r
5d73d92f 101 //\r
102 // Display what's there\r
103 //\r
104 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);\r
105 if (Status == EFI_BUFFER_TOO_SMALL) {\r
3737ac2b 106 Buffer = AllocateZeroPool(Size);\r
5d73d92f 107 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);\r
108 }\r
109 if (!EFI_ERROR(Status)&& Buffer != NULL) {\r
110 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);\r
111 for (LoopVar = 0 ; LoopVar < Size ; LoopVar++) {\r
112 ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]);\r
113 }\r
114 ShellPrintEx(-1, -1, L"\r\n");\r
115 } else {\r
116 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
117 ShellStatus = SHELL_ACCESS_DENIED;\r
118 }\r
119 } else if (StrCmp(Data, L"=") == 0) {\r
120 //\r
121 // Delete what's there!\r
122 //\r
123 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, 0, NULL);\r
124 if (EFI_ERROR(Status)) {\r
125 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
126 ShellStatus = SHELL_ACCESS_DENIED;\r
127 } else {\r
128 ASSERT(ShellStatus == SHELL_SUCCESS);\r
129 }\r
130 } else {\r
5d73d92f 131 //\r
475387e9 132 // Change what's there or create a new one.\r
5d73d92f 133 //\r
475387e9
JC
134\r
135 ASSERT(Data[0] == L'=');\r
136 Data++;\r
137\r
138 //\r
139 // Determine if the variable exists and get the attributes\r
140 //\r
141 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);\r
142 if (Status == EFI_BUFFER_TOO_SMALL) {\r
143 Buffer = AllocateZeroPool(Size);\r
144 Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);\r
5d73d92f 145 }\r
475387e9
JC
146\r
147 if (EFI_ERROR(Status) || Buffer == NULL) {\r
148 //\r
149 // Creating a new variable. determine attributes from command line.\r
150 //\r
151 Attributes = 0;\r
152 if (ShellCommandLineGetFlag(Package, L"-bs")) {\r
153 Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
154 }\r
155 if (ShellCommandLineGetFlag(Package, L"-rt")) {\r
156 Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |\r
157 EFI_VARIABLE_BOOTSERVICE_ACCESS;\r
158 }\r
159 if (ShellCommandLineGetFlag(Package, L"-nv")) {\r
160 Attributes |= EFI_VARIABLE_NON_VOLATILE;\r
161 }\r
5d73d92f 162 }\r
475387e9
JC
163 SHELL_FREE_NON_NULL(Buffer);\r
164\r
165 //\r
166 // What type is the new data.\r
167 //\r
5d73d92f 168 if (ShellIsHexOrDecimalNumber(Data, TRUE, FALSE)) {\r
3737ac2b 169 if (StrLen(Data) % 2 != 0) {\r
170 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, Data);\r
171 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 172 } else {\r
3737ac2b 173 //\r
174 // arbitrary buffer\r
175 //\r
176 Buffer = AllocateZeroPool((StrLen(Data) / 2));\r
33c031ee 177 if (Buffer == NULL) {\r
178 Status = EFI_OUT_OF_RESOURCES;\r
179 } else {\r
180 for (LoopVar = 0 ; LoopVar < (StrLen(Data) / 2) ; LoopVar++) {\r
181 ((UINT8*)Buffer)[LoopVar] = (UINT8)(HexCharToUintn(Data[LoopVar*2]) * 16);\r
182 ((UINT8*)Buffer)[LoopVar] = (UINT8)(((UINT8*)Buffer)[LoopVar] + HexCharToUintn(Data[LoopVar*2+1]));\r
183 }\r
184 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrLen(Data) / 2, Buffer);\r
3737ac2b 185 }\r
3737ac2b 186 if (EFI_ERROR(Status)) {\r
187 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
188 ShellStatus = SHELL_ACCESS_DENIED;\r
189 } else {\r
190 ASSERT(ShellStatus == SHELL_SUCCESS);\r
191 }\r
5d73d92f 192 }\r
193 } else if (StrnCmp(Data, L"\"", 1) == 0) {\r
194 //\r
195 // ascii text\r
196 //\r
197 Data++;\r
198 Buffer = AllocateZeroPool(StrSize(Data) / 2);\r
33c031ee 199 if (Buffer == NULL) {\r
200 Status = EFI_OUT_OF_RESOURCES;\r
201 } else {\r
202 AsciiSPrint(Buffer, StrSize(Data) / 2, "%s", Data);\r
203 ((CHAR8*)Buffer)[AsciiStrLen(Buffer)-1] = CHAR_NULL;\r
204 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, AsciiStrSize(Buffer)-sizeof(CHAR8), Buffer);\r
205 }\r
5d73d92f 206 if (EFI_ERROR(Status)) {\r
207 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
208 ShellStatus = SHELL_ACCESS_DENIED;\r
209 } else {\r
210 ASSERT(ShellStatus == SHELL_SUCCESS);\r
211 }\r
212 } else if (StrnCmp(Data, L"L\"", 2) == 0) {\r
213 //\r
214 // ucs2 text\r
215 //\r
216 Data++;\r
217 Data++;\r
218 Buffer = AllocateZeroPool(StrSize(Data));\r
cbdd109b 219 if (Buffer == NULL) {\r
220 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);\r
221 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
5d73d92f 222 } else {\r
cbdd109b 223 UnicodeSPrint(Buffer, StrSize(Data), L"%s", Data);\r
224 ((CHAR16*)Buffer)[StrLen(Buffer)-1] = CHAR_NULL;\r
225\r
226 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrSize(Buffer)-sizeof(CHAR16), Buffer);\r
227 if (EFI_ERROR(Status)) {\r
228 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
229 ShellStatus = SHELL_ACCESS_DENIED;\r
230 } else {\r
231 ASSERT(ShellStatus == SHELL_SUCCESS);\r
232 }\r
5d73d92f 233 }\r
234 } else if (StrnCmp(Data, L"--", 2) == 0) {\r
235 //\r
236 // device path in text format\r
237 //\r
238 Data++;\r
239 Data++;\r
863986b3 240 DevPath = ConvertTextToDevicePath(Data);\r
5d73d92f 241 if (DevPath == NULL) {\r
242 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, Status);\r
243 ShellStatus = SHELL_INVALID_PARAMETER;\r
244 } else {\r
245 Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, GetDevicePathSize(DevPath), DevPath);\r
246 if (EFI_ERROR(Status)) {\r
247 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);\r
248 ShellStatus = SHELL_ACCESS_DENIED;\r
249 } else {\r
250 ASSERT(ShellStatus == SHELL_SUCCESS);\r
251 }\r
252 }\r
253 } else {\r
254 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Data);\r
255 ShellStatus = SHELL_INVALID_PARAMETER;\r
256 }\r
257 }\r
258 }\r
259 ShellCommandLineFreeVarList (Package);\r
260 }\r
261\r
262 if (Buffer != NULL) {\r
263 FreePool(Buffer);\r
264 }\r
265\r
266 if (DevPath != NULL) {\r
267 FreePool(DevPath);\r
268 }\r
269\r
270 return (ShellStatus);\r
271}\r