]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
afeedb09591ec95aef652b954a8476ad9d4cce66
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / DmpStore.c
1 /** @file
2 Main file for DmpStore shell Debug1 function.
3
4 Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "UefiShellDebug1CommandsLib.h"
16
17 /**
18 Base on the input attribute value to return the attribute string.
19
20 @param[in] Atts The input attribute value
21
22 @retval The attribute string info.
23 **/
24 CHAR16 *
25 EFIAPI
26 GetAttrType (
27 IN CONST UINT32 Atts
28 )
29 {
30 UINTN BufLen;
31 CHAR16 *RetString;
32
33 BufLen = 0;
34 RetString = NULL;
35
36 if ((Atts & EFI_VARIABLE_NON_VOLATILE) != 0) {
37 StrnCatGrow (&RetString, &BufLen, L"+NV", 0);
38 }
39 if ((Atts & EFI_VARIABLE_RUNTIME_ACCESS) != 0) {
40 StrnCatGrow (&RetString, &BufLen, L"+RS+BS", 0);
41 } else if ((Atts & EFI_VARIABLE_BOOTSERVICE_ACCESS) != 0) {
42 StrnCatGrow (&RetString, &BufLen, L"+BS", 0);
43 }
44 if ((Atts & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) {
45 StrnCatGrow (&RetString, &BufLen, L"+HR", 0);
46 }
47 if ((Atts & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
48 StrnCatGrow (&RetString, &BufLen, L"+AW", 0);
49 }
50 if ((Atts & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
51 StrnCatGrow (&RetString, &BufLen, L"+AT", 0);
52 }
53
54 if (RetString == NULL) {
55 RetString = StrnCatGrow(&RetString, &BufLen, L"Invalid", 0);
56 }
57
58 if ((RetString != NULL) && (RetString[0] == L'+')) {
59 CopyMem(RetString, RetString + 1, StrSize(RetString + 1));
60 }
61
62 return RetString;
63 }
64
65 /**
66 Recursive function to display or delete variables.
67
68 This function will call itself to create a stack-based list of allt he variables to process,
69 then fromt he last to the first, they will do either printing or deleting.
70
71 This is necessary since once a delete happens GetNextVariableName() will work.
72
73 @param[in] VariableName The variable name of the EFI variable (or NULL).
74 @param[in] Guid The GUID of the variable set (or NULL).
75 @param[in] Delete TRUE to delete, FALSE otherwise.
76 @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.
77 @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.
78 @param[in] FoundOne If a VariableName or Guid was specified and one was printed or
79 deleted, then set this to TRUE, otherwise ignored.
80
81 @retval SHELL_SUCCESS The operation was successful.
82 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
83 @retval SHELL_ABORTED The abort message was received.
84 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.
85 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.
86 **/
87 SHELL_STATUS
88 EFIAPI
89 CascadeProcessVariables (
90 IN CONST CHAR16 *VariableName OPTIONAL,
91 IN CONST EFI_GUID *Guid OPTIONAL,
92 IN BOOLEAN Delete,
93 IN CONST CHAR16 * CONST PrevName,
94 IN EFI_GUID FoundVarGuid,
95 IN BOOLEAN *FoundOne
96 )
97 {
98 EFI_STATUS Status;
99 CHAR16 *FoundVarName;
100 UINT8 *DataBuffer;
101 UINTN DataSize;
102 UINT32 Atts;
103 SHELL_STATUS ShellStatus;
104 UINTN NameSize;
105 CHAR16 *RetString;
106
107 if (ShellGetExecutionBreakFlag()) {
108 return (SHELL_ABORTED);
109 }
110
111 NameSize = 0;
112 FoundVarName = NULL;
113
114 if (PrevName!=NULL) {
115 StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);
116 } else {
117 FoundVarName = AllocateZeroPool(sizeof(CHAR16));
118 }
119
120 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
121 if (Status == EFI_BUFFER_TOO_SMALL) {
122 SHELL_FREE_NON_NULL(FoundVarName);
123 FoundVarName = AllocateZeroPool (NameSize);
124 if (PrevName != NULL) {
125 StrCpy(FoundVarName, PrevName);
126 }
127
128 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
129 }
130
131 //
132 // No more is fine.
133 //
134 if (Status == EFI_NOT_FOUND) {
135 SHELL_FREE_NON_NULL(FoundVarName);
136 return (SHELL_SUCCESS);
137 } else if (EFI_ERROR(Status)) {
138 SHELL_FREE_NON_NULL(FoundVarName);
139 return (SHELL_DEVICE_ERROR);
140 }
141
142 //
143 // Recurse to the next iteration. We know "our" variable's name.
144 //
145 ShellStatus = CascadeProcessVariables(VariableName, Guid, Delete, FoundVarName, FoundVarGuid, FoundOne);
146
147 //
148 // No matter what happened we process our own variable
149 // Only continue if Guid and VariableName are each either NULL or a match
150 //
151 if ( ( VariableName == NULL
152 || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*)VariableName) )
153 && ( Guid == NULL
154 || CompareGuid(&FoundVarGuid, Guid) )
155 ) {
156 DataSize = 0;
157 DataBuffer = NULL;
158 //
159 // do the print or delete
160 //
161 *FoundOne = TRUE;
162 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
163 if (Status == EFI_BUFFER_TOO_SMALL) {
164 SHELL_FREE_NON_NULL (DataBuffer);
165 DataBuffer = AllocatePool (DataSize);
166 if (DataBuffer == NULL) {
167 Status = EFI_OUT_OF_RESOURCES;
168 } else {
169 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
170 }
171 }
172 if (!Delete) {
173 //
174 // Last error check then print this variable out.
175 //
176 if (!EFI_ERROR(Status) && DataBuffer != NULL) {
177 RetString = GetAttrType(Atts);
178 ShellPrintHiiEx(
179 -1,
180 -1,
181 NULL,
182 STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),
183 gShellDebug1HiiHandle,
184 RetString,
185 &FoundVarGuid,
186 FoundVarName,
187 DataSize);
188 DumpHex(2, 0, DataSize, DataBuffer);
189 SHELL_FREE_NON_NULL(RetString);
190 }
191 } else {
192 //
193 // We only need name to delete it...
194 //
195 ShellPrintHiiEx(
196 -1,
197 -1,
198 NULL,
199 STRING_TOKEN(STR_DMPSTORE_DELETE_LINE),
200 gShellDebug1HiiHandle,
201 &FoundVarGuid,
202 FoundVarName);
203 ShellPrintHiiEx(
204 -1,
205 -1,
206 NULL,
207 STRING_TOKEN(STR_DMPSTORE_DELETE_DONE),
208 gShellDebug1HiiHandle,
209 gRT->SetVariable(FoundVarName, &FoundVarGuid, Atts, 0, NULL));
210 }
211 SHELL_FREE_NON_NULL(DataBuffer);
212 }
213
214 SHELL_FREE_NON_NULL(FoundVarName);
215
216 if (Status == EFI_DEVICE_ERROR) {
217 ShellStatus = SHELL_DEVICE_ERROR;
218 } else if (Status == EFI_SECURITY_VIOLATION) {
219 ShellStatus = SHELL_SECURITY_VIOLATION;
220 } else if (EFI_ERROR(Status)) {
221 ShellStatus = SHELL_NOT_READY;
222 }
223
224 return (ShellStatus);
225 }
226
227 /**
228 Function to display or delete variables. This will set up and call into the recursive function.
229
230 @param[in] VariableName The variable name of the EFI variable (or NULL).
231 @param[in] Guid The GUID of the variable set (or NULL).
232 @param[in] Delete TRUE to delete, FALSE otherwise.
233
234 @retval SHELL_SUCCESS The operation was successful.
235 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
236 @retval SHELL_ABORTED The abort message was received.
237 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.
238 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.
239 **/
240 SHELL_STATUS
241 EFIAPI
242 ProcessVariables (
243 IN CONST CHAR16 *VariableName OPTIONAL,
244 IN CONST EFI_GUID *Guid OPTIONAL,
245 IN BOOLEAN Delete
246 )
247 {
248 SHELL_STATUS ShellStatus;
249 BOOLEAN Found;
250 EFI_GUID FoundVarGuid;
251
252 Found = FALSE;
253 ShellStatus = SHELL_SUCCESS;
254 ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));
255
256 ShellStatus = CascadeProcessVariables(VariableName, Guid, Delete, NULL, FoundVarGuid, &Found);
257
258 if (!Found) {
259 if (ShellStatus == SHELL_OUT_OF_RESOURCES) {
260 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
261 return (ShellStatus);
262 } else if (VariableName != NULL && Guid == NULL) {
263 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, VariableName);
264 } else if (VariableName != NULL && Guid != NULL) {
265 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, Guid, VariableName);
266 } else if (VariableName == NULL && Guid == NULL) {
267 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND), gShellDebug1HiiHandle);
268 } else if (VariableName == NULL && Guid != NULL) {
269 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G), gShellDebug1HiiHandle, Guid);
270 }
271 return (SHELL_NOT_FOUND);
272 }
273 return (ShellStatus);
274 }
275
276 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
277 {L"-d", TypeFlag},
278 {L"-l", TypeFlag},
279 {L"-s", TypeFlag},
280 {L"-all", TypeFlag},
281 {L"-guid", TypeValue},
282 {NULL, TypeMax}
283 };
284
285 /**
286 Function for 'dmpstore' command.
287
288 @param[in] ImageHandle Handle to the Image (NULL if Internal).
289 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
290 **/
291 SHELL_STATUS
292 EFIAPI
293 ShellCommandRunDmpStore (
294 IN EFI_HANDLE ImageHandle,
295 IN EFI_SYSTEM_TABLE *SystemTable
296 )
297 {
298 EFI_STATUS Status;
299 LIST_ENTRY *Package;
300 CHAR16 *ProblemParam;
301 SHELL_STATUS ShellStatus;
302 CONST CHAR16 *Temp;
303 EFI_GUID *Guid;
304 EFI_GUID GuidData;
305 CONST CHAR16 *VariableName;
306
307 ShellStatus = SHELL_SUCCESS;
308 Package = NULL;
309
310 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
311 if (EFI_ERROR(Status)) {
312 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
313 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);
314 FreePool(ProblemParam);
315 ShellStatus = SHELL_INVALID_PARAMETER;
316 } else {
317 ASSERT(FALSE);
318 }
319 } else {
320 if (ShellCommandLineGetCount(Package) > 2) {
321 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
322 ShellStatus = SHELL_INVALID_PARAMETER;
323 } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {
324 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-all", L"-guid");
325 ShellStatus = SHELL_INVALID_PARAMETER;
326 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {
327 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-l or -s", L"-d");
328 ShellStatus = SHELL_INVALID_PARAMETER;
329 } else {
330 if (!ShellCommandLineGetFlag(Package, L"-all")) {
331 Temp = ShellCommandLineGetValue(Package, L"-guid");
332 if (Temp != NULL) {
333 Status = ConvertStringToGuid(Temp, &GuidData);
334 if (EFI_ERROR(Status)) {
335 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
336 ShellStatus = SHELL_INVALID_PARAMETER;
337 }
338 Guid = &GuidData;
339 } else {
340 Guid = &gEfiGlobalVariableGuid;
341 }
342 VariableName = ShellCommandLineGetRawValue(Package, 1);
343 } else {
344 VariableName = NULL;
345 Guid = NULL;
346 }
347 if (ShellStatus == SHELL_SUCCESS) {
348 if (ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) {
349 ///@todo fix this after lib ready...
350 ShellPrintEx(-1, -1, L"Not implemeneted yet.\r\n");
351 ShellStatus = SHELL_UNSUPPORTED;
352 } else {
353 ShellStatus = ProcessVariables (VariableName, Guid, ShellCommandLineGetFlag(Package, L"-d"));
354 }
355 }
356 }
357 }
358
359 if (Package != NULL) {
360 ShellCommandLineFreeVarList (Package);
361 }
362 return ShellStatus;
363 }
364