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