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