]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
ShellPkg/UefiShellDebug1CommandsLib: Remove unnecessary EFIAPI
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / DmpStore.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for DmpStore shell Debug1 function.\r
148af387 3 \r
c011b6c9 4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
e75390f0 5 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>\r
5d73d92f 6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "UefiShellDebug1CommandsLib.h"\r
17\r
7e63fc9d
RN
18typedef enum {\r
19 DmpStoreDisplay,\r
20 DmpStoreDelete,\r
21 DmpStoreSave,\r
22 DmpStoreLoad\r
23} DMP_STORE_TYPE;\r
24\r
25typedef struct {\r
26 UINT32 Signature;\r
27 CHAR16 *Name;\r
28 EFI_GUID Guid;\r
29 UINT32 Attributes;\r
30 UINT32 DataSize;\r
31 UINT8 *Data;\r
32 LIST_ENTRY Link;\r
33} DMP_STORE_VARIABLE;\r
34\r
35#define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's')\r
36\r
cd0842dc
ED
37/**\r
38 Base on the input attribute value to return the attribute string.\r
39\r
40 @param[in] Atts The input attribute value\r
cd0842dc
ED
41\r
42 @retval The attribute string info.\r
43**/\r
d6972185 44CHAR16 *\r
73c82041 45GetAttrType (\r
d6972185 46 IN CONST UINT32 Atts\r
73c82041
ED
47 )\r
48{\r
99bb0f8d 49 UINTN BufLen;\r
d6972185 50 CHAR16 *RetString;\r
73c82041 51\r
d6972185
ED
52 BufLen = 0;\r
53 RetString = NULL;\r
54 \r
cd0842dc 55 if ((Atts & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
d6972185 56 StrnCatGrow (&RetString, &BufLen, L"+NV", 0);\r
73c82041 57 }\r
cd0842dc 58 if ((Atts & EFI_VARIABLE_RUNTIME_ACCESS) != 0) {\r
14868afb 59 StrnCatGrow (&RetString, &BufLen, L"+RT+BS", 0);\r
cd0842dc 60 } else if ((Atts & EFI_VARIABLE_BOOTSERVICE_ACCESS) != 0) {\r
d6972185 61 StrnCatGrow (&RetString, &BufLen, L"+BS", 0);\r
73c82041 62 }\r
cd0842dc 63 if ((Atts & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) {\r
d6972185 64 StrnCatGrow (&RetString, &BufLen, L"+HR", 0);\r
73c82041 65 }\r
cd0842dc 66 if ((Atts & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
d6972185 67 StrnCatGrow (&RetString, &BufLen, L"+AW", 0);\r
73c82041 68 }\r
cd0842dc 69 if ((Atts & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
d6972185 70 StrnCatGrow (&RetString, &BufLen, L"+AT", 0);\r
73c82041
ED
71 }\r
72\r
d6972185
ED
73 if (RetString == NULL) {\r
74 RetString = StrnCatGrow(&RetString, &BufLen, L"Invalid", 0);\r
73c82041 75 }\r
d6972185 76\r
44890dbd 77 if ((RetString != NULL) && (RetString[0] == L'+')) {\r
d6972185 78 CopyMem(RetString, RetString + 1, StrSize(RetString + 1));\r
73c82041 79 }\r
d6972185
ED
80\r
81 return RetString;\r
73c82041 82}\r
5d73d92f 83\r
7e63fc9d
RN
84/**\r
85 Load the variable data from file and set to variable data base.\r
86\r
87 @param[in] FileHandle The file to be read.\r
88 @param[in] Name The name of the variables to be loaded.\r
89 @param[in] Guid The guid of the variables to be loaded.\r
90 @param[out] Found TRUE when at least one variable was loaded and set.\r
91\r
5511b319
SQ
92 @retval SHELL_DEVICE_ERROR Cannot access the file.\r
93 @retval SHELL_VOLUME_CORRUPTED The file is in bad format.\r
94 @retval SHELL_OUT_OF_RESOURCES There is not enough memory to perform the operation.\r
95 @retval SHELL_SUCCESS Successfully load and set the variables.\r
7e63fc9d 96**/\r
5511b319 97SHELL_STATUS\r
7e63fc9d
RN
98LoadVariablesFromFile (\r
99 IN SHELL_FILE_HANDLE FileHandle,\r
100 IN CONST CHAR16 *Name,\r
101 IN CONST EFI_GUID *Guid,\r
102 OUT BOOLEAN *Found\r
103 )\r
104{\r
105 EFI_STATUS Status;\r
5511b319 106 SHELL_STATUS ShellStatus;\r
7e63fc9d
RN
107 UINT32 NameSize;\r
108 UINT32 DataSize;\r
109 UINTN BufferSize;\r
110 UINTN RemainingSize;\r
111 UINT64 Position;\r
112 UINT64 FileSize;\r
113 LIST_ENTRY List;\r
114 DMP_STORE_VARIABLE *Variable;\r
115 LIST_ENTRY *Link;\r
116 CHAR16 *Attributes;\r
117 UINT8 *Buffer;\r
118 UINT32 Crc32;\r
119\r
120 Status = ShellGetFileSize (FileHandle, &FileSize);\r
121 if (EFI_ERROR (Status)) {\r
5511b319 122 return SHELL_DEVICE_ERROR;\r
7e63fc9d 123 }\r
5511b319
SQ
124 \r
125 ShellStatus = SHELL_SUCCESS;\r
126 \r
7e63fc9d
RN
127 InitializeListHead (&List);\r
128 \r
129 Position = 0;\r
130 while (Position < FileSize) {\r
131 //\r
132 // NameSize\r
133 //\r
134 BufferSize = sizeof (NameSize);\r
135 Status = ShellReadFile (FileHandle, &BufferSize, &NameSize);\r
136 if (EFI_ERROR (Status) || (BufferSize != sizeof (NameSize))) {\r
5511b319 137 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
7e63fc9d
RN
138 break;\r
139 }\r
140\r
141 //\r
142 // DataSize\r
143 //\r
144 BufferSize = sizeof (DataSize);\r
145 Status = ShellReadFile (FileHandle, &BufferSize, &DataSize);\r
146 if (EFI_ERROR (Status) || (BufferSize != sizeof (DataSize))) {\r
5511b319 147 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
7e63fc9d
RN
148 break;\r
149 }\r
150\r
151 //\r
152 // Name, Guid, Attributes, Data, Crc32\r
153 //\r
154 RemainingSize = NameSize + sizeof (EFI_GUID) + sizeof (UINT32) + DataSize + sizeof (Crc32);\r
155 BufferSize = sizeof (NameSize) + sizeof (DataSize) + RemainingSize;\r
156 Buffer = AllocatePool (BufferSize);\r
157 if (Buffer == NULL) {\r
5511b319 158 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
7e63fc9d
RN
159 break;\r
160 }\r
161 BufferSize = RemainingSize;\r
162 Status = ShellReadFile (FileHandle, &BufferSize, (UINT32 *) Buffer + 2);\r
163 if (EFI_ERROR (Status) || (BufferSize != RemainingSize)) {\r
5511b319 164 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
7e63fc9d
RN
165 FreePool (Buffer);\r
166 break;\r
167 }\r
168\r
169 //\r
170 // Check Crc32\r
171 //\r
172 * (UINT32 *) Buffer = NameSize;\r
173 * ((UINT32 *) Buffer + 1) = DataSize;\r
174 BufferSize = RemainingSize + sizeof (NameSize) + sizeof (DataSize) - sizeof (Crc32);\r
175 gBS->CalculateCrc32 (\r
176 Buffer,\r
177 BufferSize,\r
178 &Crc32\r
179 );\r
180 if (Crc32 != * (UINT32 *) (Buffer + BufferSize)) {\r
181 FreePool (Buffer);\r
5511b319 182 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
7e63fc9d
RN
183 break;\r
184 }\r
185\r
186 Position += BufferSize + sizeof (Crc32);\r
187 \r
188 Variable = AllocateZeroPool (sizeof (*Variable) + NameSize + DataSize);\r
189 if (Variable == NULL) {\r
190 FreePool (Buffer);\r
5511b319 191 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
7e63fc9d
RN
192 break;\r
193 }\r
194 Variable->Signature = DMP_STORE_VARIABLE_SIGNATURE;\r
195 Variable->Name = (CHAR16 *) (Variable + 1);\r
196 Variable->DataSize = DataSize;\r
197 Variable->Data = (UINT8 *) Variable->Name + NameSize;\r
198 CopyMem (Variable->Name, Buffer + sizeof (NameSize) + sizeof (DataSize), NameSize);\r
199 CopyMem (&Variable->Guid, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize, sizeof (EFI_GUID));\r
200 CopyMem (&Variable->Attributes, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID), sizeof (UINT32));\r
201 CopyMem (Variable->Data, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID) + sizeof (UINT32), DataSize);\r
202\r
203 InsertTailList (&List, &Variable->Link);\r
204 FreePool (Buffer);\r
205 }\r
206 \r
5511b319 207 if ((Position != FileSize) || (ShellStatus != SHELL_SUCCESS)) {\r
4092a8f6 208 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE), gShellDebug1HiiHandle, L"dmpstore"); \r
5511b319
SQ
209 if (Position != FileSize) {\r
210 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
211 }\r
7e63fc9d
RN
212 }\r
213 \r
214 for ( Link = GetFirstNode (&List)\r
5511b319 215 ; !IsNull (&List, Link) && (ShellStatus == SHELL_SUCCESS)\r
7e63fc9d
RN
216 ; Link = GetNextNode (&List, Link)\r
217 ) {\r
218 Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);\r
219 \r
220 if (((Name == NULL) || gUnicodeCollation->MetaiMatch (gUnicodeCollation, Variable->Name, (CHAR16 *) Name)) &&\r
221 ((Guid == NULL) || CompareGuid (&Variable->Guid, Guid))\r
222 ) {\r
223 Attributes = GetAttrType (Variable->Attributes);\r
224 ShellPrintHiiEx (\r
225 -1, -1, NULL, STRING_TOKEN(STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,\r
226 Attributes, &Variable->Guid, Variable->Name, Variable->DataSize\r
227 );\r
228 SHELL_FREE_NON_NULL(Attributes);\r
229\r
230 *Found = TRUE;\r
231 Status = gRT->SetVariable (\r
232 Variable->Name,\r
233 &Variable->Guid,\r
234 Variable->Attributes,\r
235 Variable->DataSize,\r
236 Variable->Data\r
237 );\r
238 if (EFI_ERROR (Status)) {\r
4092a8f6 239 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", Variable->Name, Status); \r
7e63fc9d
RN
240 }\r
241 }\r
242 }\r
243\r
244 for (Link = GetFirstNode (&List); !IsNull (&List, Link); ) {\r
245 Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);\r
246 Link = RemoveEntryList (&Variable->Link);\r
247 FreePool (Variable);\r
248 }\r
249\r
5511b319 250 return ShellStatus;\r
7e63fc9d
RN
251}\r
252\r
253/**\r
254 Append one variable to file.\r
255\r
256 @param[in] FileHandle The file to be appended.\r
257 @param[in] Name The variable name.\r
258 @param[in] Guid The variable GUID.\r
259 @param[in] Attributes The variable attributes.\r
260 @param[in] DataSize The variable data size.\r
261 @param[in] Data The variable data.\r
262\r
263 @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation.\r
264 @retval EFI_SUCCESS The variable is appended to file successfully.\r
265 @retval others Failed to append the variable to file.\r
266**/\r
267EFI_STATUS\r
268AppendSingleVariableToFile (\r
269 IN SHELL_FILE_HANDLE FileHandle,\r
270 IN CONST CHAR16 *Name,\r
271 IN CONST EFI_GUID *Guid,\r
272 IN UINT32 Attributes,\r
273 IN UINT32 DataSize,\r
274 IN CONST UINT8 *Data\r
275 )\r
276{\r
277 UINT32 NameSize;\r
278 UINT8 *Buffer;\r
279 UINT8 *Ptr;\r
280 UINTN BufferSize;\r
281 EFI_STATUS Status;\r
282\r
283 NameSize = (UINT32) StrSize (Name);\r
284 BufferSize = sizeof (NameSize) + sizeof (DataSize)\r
285 + sizeof (*Guid)\r
286 + sizeof (Attributes)\r
287 + NameSize + DataSize\r
288 + sizeof (UINT32);\r
289\r
290 Buffer = AllocatePool (BufferSize);\r
291 if (Buffer == NULL) {\r
292 return EFI_OUT_OF_RESOURCES;\r
293 }\r
294\r
295 Ptr = Buffer;\r
296 //\r
297 // NameSize and DataSize\r
298 //\r
299 * (UINT32 *) Ptr = NameSize;\r
300 Ptr += sizeof (NameSize);\r
301 *(UINT32 *) Ptr = DataSize;\r
302 Ptr += sizeof (DataSize);\r
303\r
304 //\r
305 // Name\r
306 //\r
307 CopyMem (Ptr, Name, NameSize);\r
308 Ptr += NameSize;\r
309\r
310 //\r
311 // Guid\r
312 //\r
313 CopyMem (Ptr, Guid, sizeof (*Guid));\r
314 Ptr += sizeof (*Guid);\r
315\r
316 //\r
317 // Attributes\r
318 //\r
319 * (UINT32 *) Ptr = Attributes;\r
320 Ptr += sizeof (Attributes);\r
321\r
322 //\r
323 // Data\r
324 //\r
325 CopyMem (Ptr, Data, DataSize);\r
326 Ptr += DataSize;\r
327\r
328 //\r
329 // Crc32\r
330 //\r
331 gBS->CalculateCrc32 (Buffer, (UINTN) (Ptr - Buffer), (UINT32 *) Ptr);\r
332\r
333 Status = ShellWriteFile (FileHandle, &BufferSize, Buffer);\r
334 FreePool (Buffer);\r
335\r
336 if (!EFI_ERROR (Status) && \r
88963516 337 (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize + sizeof (UINT32))\r
7e63fc9d
RN
338 ) {\r
339 Status = EFI_DEVICE_ERROR;\r
340 }\r
341 \r
342 return Status;\r
343}\r
344\r
3737ac2b 345/**\r
5bd12b05
JC
346 Recursive function to display or delete variables.\r
347\r
348 This function will call itself to create a stack-based list of allt he variables to process, \r
349 then fromt he last to the first, they will do either printing or deleting.\r
350\r
351 This is necessary since once a delete happens GetNextVariableName() will work.\r
3737ac2b 352\r
7e63fc9d 353 @param[in] Name The variable name of the EFI variable (or NULL).\r
3737ac2b 354 @param[in] Guid The GUID of the variable set (or NULL).\r
7e63fc9d
RN
355 @param[in] Type The operation type.\r
356 @param[in] FileHandle The file to operate on (or NULL).\r
5bd12b05
JC
357 @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.\r
358 @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.\r
359 @param[in] FoundOne If a VariableName or Guid was specified and one was printed or\r
360 deleted, then set this to TRUE, otherwise ignored.\r
3737ac2b 361\r
362 @retval SHELL_SUCCESS The operation was successful.\r
363 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
364 @retval SHELL_ABORTED The abort message was received.\r
365 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
366 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
367**/\r
5d73d92f 368SHELL_STATUS\r
5bd12b05 369CascadeProcessVariables (\r
7e63fc9d
RN
370 IN CONST CHAR16 *Name OPTIONAL,\r
371 IN CONST EFI_GUID *Guid OPTIONAL,\r
372 IN DMP_STORE_TYPE Type,\r
373 IN EFI_FILE_PROTOCOL *FileHandle OPTIONAL,\r
374 IN CONST CHAR16 * CONST PrevName,\r
375 IN EFI_GUID FoundVarGuid,\r
376 IN BOOLEAN *FoundOne\r
5d73d92f 377 )\r
378{\r
379 EFI_STATUS Status;\r
5d73d92f 380 CHAR16 *FoundVarName;\r
5d73d92f 381 UINT8 *DataBuffer;\r
382 UINTN DataSize;\r
383 UINT32 Atts;\r
384 SHELL_STATUS ShellStatus;\r
73c82041 385 UINTN NameSize;\r
d6972185 386 CHAR16 *RetString;\r
5d73d92f 387\r
5bd12b05
JC
388 if (ShellGetExecutionBreakFlag()) {\r
389 return (SHELL_ABORTED);\r
5d73d92f 390 }\r
391\r
5bd12b05
JC
392 NameSize = 0;\r
393 FoundVarName = NULL;\r
5d73d92f 394\r
5bd12b05
JC
395 if (PrevName!=NULL) {\r
396 StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);\r
397 } else {\r
398 FoundVarName = AllocateZeroPool(sizeof(CHAR16));\r
399 }\r
400\r
401 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
402 if (Status == EFI_BUFFER_TOO_SMALL) {\r
403 SHELL_FREE_NON_NULL(FoundVarName);\r
404 FoundVarName = AllocateZeroPool (NameSize);\r
03bc7c2b
SQ
405 if (FoundVarName != NULL) {\r
406 if (PrevName != NULL) {\r
4dc0d578 407 StrnCpyS(FoundVarName, NameSize/sizeof(CHAR16), PrevName, NameSize/sizeof(CHAR16) - 1);\r
03bc7c2b
SQ
408 }\r
409\r
410 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
411 } else {\r
412 Status = EFI_OUT_OF_RESOURCES;\r
5d73d92f 413 }\r
5bd12b05
JC
414 }\r
415\r
416 //\r
417 // No more is fine.\r
418 //\r
419 if (Status == EFI_NOT_FOUND) {\r
420 SHELL_FREE_NON_NULL(FoundVarName);\r
421 return (SHELL_SUCCESS);\r
422 } else if (EFI_ERROR(Status)) {\r
423 SHELL_FREE_NON_NULL(FoundVarName);\r
424 return (SHELL_DEVICE_ERROR);\r
425 }\r
426\r
427 //\r
428 // Recurse to the next iteration. We know "our" variable's name.\r
429 //\r
7e63fc9d 430 ShellStatus = CascadeProcessVariables(Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne);\r
5bd12b05 431\r
148af387
TS
432 if (ShellGetExecutionBreakFlag() || (ShellStatus == SHELL_ABORTED)) {\r
433 SHELL_FREE_NON_NULL(FoundVarName);\r
434 return (SHELL_ABORTED);\r
435 }\r
436\r
5bd12b05
JC
437 //\r
438 // No matter what happened we process our own variable\r
439 // Only continue if Guid and VariableName are each either NULL or a match\r
440 //\r
7e63fc9d
RN
441 if ( ( Name == NULL \r
442 || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) )\r
5bd12b05
JC
443 && ( Guid == NULL \r
444 || CompareGuid(&FoundVarGuid, Guid) )\r
445 ) {\r
446 DataSize = 0;\r
447 DataBuffer = NULL;\r
5d73d92f 448 //\r
5bd12b05 449 // do the print or delete\r
5d73d92f 450 //\r
5bd12b05
JC
451 *FoundOne = TRUE;\r
452 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
73c82041 453 if (Status == EFI_BUFFER_TOO_SMALL) {\r
5bd12b05
JC
454 SHELL_FREE_NON_NULL (DataBuffer);\r
455 DataBuffer = AllocatePool (DataSize);\r
73c82041
ED
456 if (DataBuffer == NULL) {\r
457 Status = EFI_OUT_OF_RESOURCES;\r
5bd12b05
JC
458 } else {\r
459 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
73c82041 460 }\r
5bd12b05 461 }\r
7e63fc9d 462 if ((Type == DmpStoreDisplay) || (Type == DmpStoreSave)) {\r
5bd12b05
JC
463 //\r
464 // Last error check then print this variable out.\r
465 //\r
5511b319 466 if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
5bd12b05
JC
467 RetString = GetAttrType(Atts);\r
468 ShellPrintHiiEx(\r
469 -1,\r
470 -1,\r
471 NULL,\r
472 STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),\r
473 gShellDebug1HiiHandle,\r
474 RetString,\r
475 &FoundVarGuid,\r
476 FoundVarName,\r
477 DataSize);\r
7e63fc9d
RN
478 if (Type == DmpStoreDisplay) {\r
479 DumpHex(2, 0, DataSize, DataBuffer);\r
480 } else {\r
481 Status = AppendSingleVariableToFile (\r
482 FileHandle,\r
483 FoundVarName,\r
484 &FoundVarGuid,\r
485 Atts,\r
486 (UINT32) DataSize,\r
487 DataBuffer\r
488 );\r
489 }\r
5bd12b05
JC
490 SHELL_FREE_NON_NULL(RetString);\r
491 }\r
7e63fc9d 492 } else if (Type == DmpStoreDelete) {\r
5bd12b05
JC
493 //\r
494 // We only need name to delete it...\r
495 //\r
7e63fc9d 496 ShellPrintHiiEx (\r
5d73d92f 497 -1,\r
498 -1,\r
499 NULL,\r
500 STRING_TOKEN(STR_DMPSTORE_DELETE_LINE),\r
501 gShellDebug1HiiHandle,\r
502 &FoundVarGuid,\r
7e63fc9d
RN
503 FoundVarName,\r
504 gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL)\r
505 );\r
d6972185 506 }\r
5bd12b05 507 SHELL_FREE_NON_NULL(DataBuffer);\r
5d73d92f 508 }\r
509\r
5bd12b05
JC
510 SHELL_FREE_NON_NULL(FoundVarName);\r
511\r
512 if (Status == EFI_DEVICE_ERROR) {\r
513 ShellStatus = SHELL_DEVICE_ERROR;\r
514 } else if (Status == EFI_SECURITY_VIOLATION) {\r
515 ShellStatus = SHELL_SECURITY_VIOLATION;\r
516 } else if (EFI_ERROR(Status)) {\r
517 ShellStatus = SHELL_NOT_READY;\r
5d73d92f 518 }\r
5bd12b05
JC
519\r
520 return (ShellStatus);\r
521}\r
522\r
523/**\r
524 Function to display or delete variables. This will set up and call into the recursive function.\r
525\r
7e63fc9d
RN
526 @param[in] Name The variable name of the EFI variable (or NULL).\r
527 @param[in] Guid The GUID of the variable set (or NULL).\r
528 @param[in] Type The operation type.\r
529 @param[in] FileHandle The file to save or load variables.\r
5bd12b05
JC
530\r
531 @retval SHELL_SUCCESS The operation was successful.\r
532 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
533 @retval SHELL_ABORTED The abort message was received.\r
534 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
535 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
536**/\r
537SHELL_STATUS\r
5bd12b05 538ProcessVariables (\r
7e63fc9d
RN
539 IN CONST CHAR16 *Name OPTIONAL,\r
540 IN CONST EFI_GUID *Guid OPTIONAL,\r
541 IN DMP_STORE_TYPE Type,\r
542 IN SHELL_FILE_HANDLE FileHandle OPTIONAL\r
5bd12b05
JC
543 )\r
544{\r
545 SHELL_STATUS ShellStatus;\r
546 BOOLEAN Found;\r
547 EFI_GUID FoundVarGuid;\r
548\r
549 Found = FALSE;\r
550 ShellStatus = SHELL_SUCCESS;\r
551 ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));\r
552\r
7e63fc9d 553 if (Type == DmpStoreLoad) {\r
5511b319 554 ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found);\r
7e63fc9d
RN
555 } else {\r
556 ShellStatus = CascadeProcessVariables(Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found);\r
557 }\r
5bd12b05 558\r
3737ac2b 559 if (!Found) {\r
5bd12b05 560 if (ShellStatus == SHELL_OUT_OF_RESOURCES) {\r
4092a8f6 561 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"dmpstore"); \r
5bd12b05 562 return (ShellStatus);\r
7e63fc9d 563 } else if (Name != NULL && Guid == NULL) {\r
4092a8f6 564 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, L"dmpstore", Name); \r
7e63fc9d 565 } else if (Name != NULL && Guid != NULL) {\r
4092a8f6 566 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, L"dmpstore", Guid, Name); \r
7e63fc9d 567 } else if (Name == NULL && Guid == NULL) {\r
4092a8f6 568 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND), gShellDebug1HiiHandle, L"dmpstore"); \r
7e63fc9d 569 } else if (Name == NULL && Guid != NULL) {\r
4092a8f6 570 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G), gShellDebug1HiiHandle, L"dmpstore", Guid); \r
3737ac2b 571 } \r
572 return (SHELL_NOT_FOUND);\r
573 }\r
224e8e2f 574 return (ShellStatus);\r
5d73d92f 575}\r
576\r
577STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
578 {L"-d", TypeFlag},\r
7e63fc9d
RN
579 {L"-l", TypeValue},\r
580 {L"-s", TypeValue},\r
5d73d92f 581 {L"-all", TypeFlag},\r
582 {L"-guid", TypeValue},\r
583 {NULL, TypeMax}\r
584 };\r
585\r
3737ac2b 586/**\r
587 Function for 'dmpstore' command.\r
588\r
589 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
590 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
591**/\r
5d73d92f 592SHELL_STATUS\r
593EFIAPI\r
594ShellCommandRunDmpStore (\r
595 IN EFI_HANDLE ImageHandle,\r
596 IN EFI_SYSTEM_TABLE *SystemTable\r
597 )\r
598{\r
7e63fc9d
RN
599 EFI_STATUS Status;\r
600 LIST_ENTRY *Package;\r
601 CHAR16 *ProblemParam;\r
602 SHELL_STATUS ShellStatus;\r
603 CONST CHAR16 *GuidStr;\r
604 CONST CHAR16 *File;\r
605 EFI_GUID *Guid;\r
606 EFI_GUID GuidData;\r
607 CONST CHAR16 *Name;\r
608 DMP_STORE_TYPE Type;\r
609 SHELL_FILE_HANDLE FileHandle;\r
610 EFI_FILE_INFO *FileInfo;\r
5d73d92f 611\r
612 ShellStatus = SHELL_SUCCESS;\r
613 Package = NULL;\r
7e63fc9d
RN
614 FileHandle = NULL;\r
615 File = NULL;\r
616 Type = DmpStoreDisplay;\r
5d73d92f 617\r
618 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
619 if (EFI_ERROR(Status)) {\r
620 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
4092a8f6 621 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"dmpstore", ProblemParam); \r
5d73d92f 622 FreePool(ProblemParam);\r
623 ShellStatus = SHELL_INVALID_PARAMETER;\r
624 } else {\r
625 ASSERT(FALSE);\r
626 }\r
627 } else {\r
3737ac2b 628 if (ShellCommandLineGetCount(Package) > 2) {\r
4092a8f6 629 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmpstore"); \r
5d73d92f 630 ShellStatus = SHELL_INVALID_PARAMETER;\r
631 } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {\r
4092a8f6 632 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-all", L"-guid"); \r
5d73d92f 633 ShellStatus = SHELL_INVALID_PARAMETER;\r
7e63fc9d 634 } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {\r
4092a8f6 635 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l", L"-s"); \r
7e63fc9d 636 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 637 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {\r
4092a8f6 638 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-d"); \r
5d73d92f 639 ShellStatus = SHELL_INVALID_PARAMETER;\r
640 } else {\r
9954df7b
JC
641 //\r
642 // Determine the GUID to search for based on -all and -guid parameters\r
643 //\r
5d73d92f 644 if (!ShellCommandLineGetFlag(Package, L"-all")) {\r
7e63fc9d
RN
645 GuidStr = ShellCommandLineGetValue(Package, L"-guid");\r
646 if (GuidStr != NULL) {\r
647 Status = ConvertStringToGuid(GuidStr, &GuidData);\r
5d73d92f 648 if (EFI_ERROR(Status)) {\r
4092a8f6 649 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmpstore", GuidStr); \r
5d73d92f 650 ShellStatus = SHELL_INVALID_PARAMETER;\r
651 }\r
652 Guid = &GuidData;\r
653 } else {\r
654 Guid = &gEfiGlobalVariableGuid;\r
655 }\r
5d73d92f 656 } else {\r
7e63fc9d 657 Guid = NULL;\r
5d73d92f 658 }\r
9954df7b
JC
659\r
660 //\r
661 // Get the Name of the variable to find\r
662 //\r
663 Name = ShellCommandLineGetRawValue(Package, 1);\r
664\r
5d73d92f 665 if (ShellStatus == SHELL_SUCCESS) {\r
7e63fc9d
RN
666 if (ShellCommandLineGetFlag(Package, L"-s")) {\r
667 Type = DmpStoreSave;\r
668 File = ShellCommandLineGetValue(Package, L"-s");\r
669 if (File == NULL) {\r
4092a8f6 670 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-s"); \r
7e63fc9d
RN
671 ShellStatus = SHELL_INVALID_PARAMETER;\r
672 } else {\r
673 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
674 if (!EFI_ERROR (Status)) {\r
675 //\r
676 // Delete existing file, but do not delete existing directory\r
677 //\r
678 FileInfo = ShellGetFileInfo (FileHandle);\r
679 if (FileInfo == NULL) {\r
4092a8f6 680 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
681 Status = EFI_DEVICE_ERROR;\r
682 } else {\r
683 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
4092a8f6 684 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
685 Status = EFI_INVALID_PARAMETER;\r
686 } else {\r
687 Status = ShellDeleteFile (&FileHandle);\r
688 if (EFI_ERROR (Status)) {\r
4092a8f6 689 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
690 }\r
691 }\r
692 FreePool (FileInfo);\r
693 }\r
694 } else if (Status == EFI_NOT_FOUND) {\r
695 //\r
696 // Good when file doesn't exist\r
697 //\r
698 Status = EFI_SUCCESS;\r
699 } else {\r
700 //\r
701 // Otherwise it's bad.\r
702 //\r
4092a8f6 703 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
704 }\r
705\r
706 if (!EFI_ERROR (Status)) {\r
707 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
708 if (EFI_ERROR (Status)) {\r
4092a8f6 709 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
710 }\r
711 }\r
712\r
713 if (EFI_ERROR (Status)) {\r
714 ShellStatus = SHELL_INVALID_PARAMETER;\r
715 }\r
716 }\r
717 } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
718 Type = DmpStoreLoad;\r
719 File = ShellCommandLineGetValue(Package, L"-l");\r
720 if (File == NULL) {\r
4092a8f6 721 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-l"); \r
7e63fc9d
RN
722 ShellStatus = SHELL_INVALID_PARAMETER;\r
723 } else {\r
724 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_READ, 0);\r
725 if (EFI_ERROR (Status)) {\r
4092a8f6 726 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
727 ShellStatus = SHELL_INVALID_PARAMETER;\r
728 } else {\r
729 FileInfo = ShellGetFileInfo (FileHandle);\r
730 if (FileInfo == NULL) {\r
4092a8f6 731 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
732 ShellStatus = SHELL_DEVICE_ERROR;\r
733 } else {\r
734 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
4092a8f6 735 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
736 ShellStatus = SHELL_INVALID_PARAMETER;\r
737 }\r
738 FreePool (FileInfo);\r
739 }\r
740 }\r
741 }\r
742 } else if (ShellCommandLineGetFlag(Package, L"-d")) {\r
743 Type = DmpStoreDelete;\r
744 }\r
745 }\r
746\r
747 if (ShellStatus == SHELL_SUCCESS) {\r
748 if (Type == DmpStoreSave) {\r
749 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_SAVE), gShellDebug1HiiHandle, File);\r
750 } else if (Type == DmpStoreLoad) {\r
751 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD), gShellDebug1HiiHandle, File);\r
752 }\r
753 ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle);\r
754 if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {\r
755 ShellCloseFile (&FileHandle);\r
5d73d92f 756 }\r
757 }\r
758 }\r
759 }\r
760\r
761 if (Package != NULL) {\r
762 ShellCommandLineFreeVarList (Package);\r
763 }\r
764 return ShellStatus;\r
765}\r
766\r