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