]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
Update the comments in function headers to follow Doxygen special documentation block...
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / DmpStore.c
CommitLineData
5d73d92f 1/** @file\r
2 Main file for DmpStore shell Debug1 function.\r
3\r
de4ebdcf 4 Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>\r
5d73d92f 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
7e63fc9d
RN
17typedef enum {\r
18 DmpStoreDisplay,\r
19 DmpStoreDelete,\r
20 DmpStoreSave,\r
21 DmpStoreLoad\r
22} DMP_STORE_TYPE;\r
23\r
24typedef struct {\r
25 UINT32 Signature;\r
26 CHAR16 *Name;\r
27 EFI_GUID Guid;\r
28 UINT32 Attributes;\r
29 UINT32 DataSize;\r
30 UINT8 *Data;\r
31 LIST_ENTRY Link;\r
32} DMP_STORE_VARIABLE;\r
33\r
34#define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's')\r
35\r
cd0842dc
ED
36/**\r
37 Base on the input attribute value to return the attribute string.\r
38\r
39 @param[in] Atts The input attribute value\r
cd0842dc
ED
40\r
41 @retval The attribute string info.\r
42**/\r
d6972185 43CHAR16 *\r
73c82041
ED
44EFIAPI\r
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
d6972185 59 StrnCatGrow (&RetString, &BufLen, L"+RS+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
7e63fc9d 208 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE), gShellDebug1HiiHandle);\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
239 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL), gShellDebug1HiiHandle, 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
337 (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize)\r
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
369EFIAPI\r
5bd12b05 370CascadeProcessVariables (\r
7e63fc9d
RN
371 IN CONST CHAR16 *Name OPTIONAL,\r
372 IN CONST EFI_GUID *Guid OPTIONAL,\r
373 IN DMP_STORE_TYPE Type,\r
374 IN EFI_FILE_PROTOCOL *FileHandle OPTIONAL,\r
375 IN CONST CHAR16 * CONST PrevName,\r
376 IN EFI_GUID FoundVarGuid,\r
377 IN BOOLEAN *FoundOne\r
5d73d92f 378 )\r
379{\r
380 EFI_STATUS Status;\r
5d73d92f 381 CHAR16 *FoundVarName;\r
5d73d92f 382 UINT8 *DataBuffer;\r
383 UINTN DataSize;\r
384 UINT32 Atts;\r
385 SHELL_STATUS ShellStatus;\r
73c82041 386 UINTN NameSize;\r
d6972185 387 CHAR16 *RetString;\r
5d73d92f 388\r
5bd12b05
JC
389 if (ShellGetExecutionBreakFlag()) {\r
390 return (SHELL_ABORTED);\r
5d73d92f 391 }\r
392\r
5bd12b05
JC
393 NameSize = 0;\r
394 FoundVarName = NULL;\r
5d73d92f 395\r
5bd12b05
JC
396 if (PrevName!=NULL) {\r
397 StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);\r
398 } else {\r
399 FoundVarName = AllocateZeroPool(sizeof(CHAR16));\r
400 }\r
401\r
402 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
403 if (Status == EFI_BUFFER_TOO_SMALL) {\r
404 SHELL_FREE_NON_NULL(FoundVarName);\r
405 FoundVarName = AllocateZeroPool (NameSize);\r
03bc7c2b
SQ
406 if (FoundVarName != NULL) {\r
407 if (PrevName != NULL) {\r
408 StrCpy(FoundVarName, PrevName);\r
409 }\r
410\r
411 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
412 } else {\r
413 Status = EFI_OUT_OF_RESOURCES;\r
5d73d92f 414 }\r
5bd12b05
JC
415 }\r
416\r
417 //\r
418 // No more is fine.\r
419 //\r
420 if (Status == EFI_NOT_FOUND) {\r
421 SHELL_FREE_NON_NULL(FoundVarName);\r
422 return (SHELL_SUCCESS);\r
423 } else if (EFI_ERROR(Status)) {\r
424 SHELL_FREE_NON_NULL(FoundVarName);\r
425 return (SHELL_DEVICE_ERROR);\r
426 }\r
427\r
428 //\r
429 // Recurse to the next iteration. We know "our" variable's name.\r
430 //\r
7e63fc9d 431 ShellStatus = CascadeProcessVariables(Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne);\r
5bd12b05
JC
432\r
433 //\r
434 // No matter what happened we process our own variable\r
435 // Only continue if Guid and VariableName are each either NULL or a match\r
436 //\r
7e63fc9d
RN
437 if ( ( Name == NULL \r
438 || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) )\r
5bd12b05
JC
439 && ( Guid == NULL \r
440 || CompareGuid(&FoundVarGuid, Guid) )\r
441 ) {\r
442 DataSize = 0;\r
443 DataBuffer = NULL;\r
5d73d92f 444 //\r
5bd12b05 445 // do the print or delete\r
5d73d92f 446 //\r
5bd12b05
JC
447 *FoundOne = TRUE;\r
448 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
73c82041 449 if (Status == EFI_BUFFER_TOO_SMALL) {\r
5bd12b05
JC
450 SHELL_FREE_NON_NULL (DataBuffer);\r
451 DataBuffer = AllocatePool (DataSize);\r
73c82041
ED
452 if (DataBuffer == NULL) {\r
453 Status = EFI_OUT_OF_RESOURCES;\r
5bd12b05
JC
454 } else {\r
455 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
73c82041 456 }\r
5bd12b05 457 }\r
7e63fc9d 458 if ((Type == DmpStoreDisplay) || (Type == DmpStoreSave)) {\r
5bd12b05
JC
459 //\r
460 // Last error check then print this variable out.\r
461 //\r
5511b319 462 if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
5bd12b05
JC
463 RetString = GetAttrType(Atts);\r
464 ShellPrintHiiEx(\r
465 -1,\r
466 -1,\r
467 NULL,\r
468 STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),\r
469 gShellDebug1HiiHandle,\r
470 RetString,\r
471 &FoundVarGuid,\r
472 FoundVarName,\r
473 DataSize);\r
7e63fc9d
RN
474 if (Type == DmpStoreDisplay) {\r
475 DumpHex(2, 0, DataSize, DataBuffer);\r
476 } else {\r
477 Status = AppendSingleVariableToFile (\r
478 FileHandle,\r
479 FoundVarName,\r
480 &FoundVarGuid,\r
481 Atts,\r
482 (UINT32) DataSize,\r
483 DataBuffer\r
484 );\r
485 }\r
5bd12b05
JC
486 SHELL_FREE_NON_NULL(RetString);\r
487 }\r
7e63fc9d 488 } else if (Type == DmpStoreDelete) {\r
5bd12b05
JC
489 //\r
490 // We only need name to delete it...\r
491 //\r
7e63fc9d 492 ShellPrintHiiEx (\r
5d73d92f 493 -1,\r
494 -1,\r
495 NULL,\r
496 STRING_TOKEN(STR_DMPSTORE_DELETE_LINE),\r
497 gShellDebug1HiiHandle,\r
498 &FoundVarGuid,\r
7e63fc9d
RN
499 FoundVarName,\r
500 gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL)\r
501 );\r
d6972185 502 }\r
5bd12b05 503 SHELL_FREE_NON_NULL(DataBuffer);\r
5d73d92f 504 }\r
505\r
5bd12b05
JC
506 SHELL_FREE_NON_NULL(FoundVarName);\r
507\r
508 if (Status == EFI_DEVICE_ERROR) {\r
509 ShellStatus = SHELL_DEVICE_ERROR;\r
510 } else if (Status == EFI_SECURITY_VIOLATION) {\r
511 ShellStatus = SHELL_SECURITY_VIOLATION;\r
512 } else if (EFI_ERROR(Status)) {\r
513 ShellStatus = SHELL_NOT_READY;\r
5d73d92f 514 }\r
5bd12b05
JC
515\r
516 return (ShellStatus);\r
517}\r
518\r
519/**\r
520 Function to display or delete variables. This will set up and call into the recursive function.\r
521\r
7e63fc9d
RN
522 @param[in] Name The variable name of the EFI variable (or NULL).\r
523 @param[in] Guid The GUID of the variable set (or NULL).\r
524 @param[in] Type The operation type.\r
525 @param[in] FileHandle The file to save or load variables.\r
5bd12b05
JC
526\r
527 @retval SHELL_SUCCESS The operation was successful.\r
528 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
529 @retval SHELL_ABORTED The abort message was received.\r
530 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
531 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
532**/\r
533SHELL_STATUS\r
534EFIAPI\r
535ProcessVariables (\r
7e63fc9d
RN
536 IN CONST CHAR16 *Name OPTIONAL,\r
537 IN CONST EFI_GUID *Guid OPTIONAL,\r
538 IN DMP_STORE_TYPE Type,\r
539 IN SHELL_FILE_HANDLE FileHandle OPTIONAL\r
5bd12b05
JC
540 )\r
541{\r
542 SHELL_STATUS ShellStatus;\r
543 BOOLEAN Found;\r
544 EFI_GUID FoundVarGuid;\r
545\r
546 Found = FALSE;\r
547 ShellStatus = SHELL_SUCCESS;\r
548 ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));\r
549\r
7e63fc9d 550 if (Type == DmpStoreLoad) {\r
5511b319 551 ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found);\r
7e63fc9d
RN
552 } else {\r
553 ShellStatus = CascadeProcessVariables(Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found);\r
554 }\r
5bd12b05 555\r
3737ac2b 556 if (!Found) {\r
5bd12b05 557 if (ShellStatus == SHELL_OUT_OF_RESOURCES) {\r
73c82041 558 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);\r
5bd12b05 559 return (ShellStatus);\r
7e63fc9d
RN
560 } else if (Name != NULL && Guid == NULL) {\r
561 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, Name);\r
562 } else if (Name != NULL && Guid != NULL) {\r
563 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, Guid, Name);\r
564 } else if (Name == NULL && Guid == NULL) {\r
3737ac2b 565 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND), gShellDebug1HiiHandle);\r
7e63fc9d 566 } else if (Name == NULL && Guid != NULL) {\r
3737ac2b 567 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G), gShellDebug1HiiHandle, Guid);\r
568 } \r
569 return (SHELL_NOT_FOUND);\r
570 }\r
224e8e2f 571 return (ShellStatus);\r
5d73d92f 572}\r
573\r
574STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
575 {L"-d", TypeFlag},\r
7e63fc9d
RN
576 {L"-l", TypeValue},\r
577 {L"-s", TypeValue},\r
5d73d92f 578 {L"-all", TypeFlag},\r
579 {L"-guid", TypeValue},\r
580 {NULL, TypeMax}\r
581 };\r
582\r
3737ac2b 583/**\r
584 Function for 'dmpstore' command.\r
585\r
586 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
587 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
588**/\r
5d73d92f 589SHELL_STATUS\r
590EFIAPI\r
591ShellCommandRunDmpStore (\r
592 IN EFI_HANDLE ImageHandle,\r
593 IN EFI_SYSTEM_TABLE *SystemTable\r
594 )\r
595{\r
7e63fc9d
RN
596 EFI_STATUS Status;\r
597 LIST_ENTRY *Package;\r
598 CHAR16 *ProblemParam;\r
599 SHELL_STATUS ShellStatus;\r
600 CONST CHAR16 *GuidStr;\r
601 CONST CHAR16 *File;\r
602 EFI_GUID *Guid;\r
603 EFI_GUID GuidData;\r
604 CONST CHAR16 *Name;\r
605 DMP_STORE_TYPE Type;\r
606 SHELL_FILE_HANDLE FileHandle;\r
607 EFI_FILE_INFO *FileInfo;\r
5d73d92f 608\r
609 ShellStatus = SHELL_SUCCESS;\r
610 Package = NULL;\r
7e63fc9d
RN
611 FileHandle = NULL;\r
612 File = NULL;\r
613 Type = DmpStoreDisplay;\r
5d73d92f 614\r
615 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
616 if (EFI_ERROR(Status)) {\r
617 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
618 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);\r
619 FreePool(ProblemParam);\r
620 ShellStatus = SHELL_INVALID_PARAMETER;\r
621 } else {\r
622 ASSERT(FALSE);\r
623 }\r
624 } else {\r
3737ac2b 625 if (ShellCommandLineGetCount(Package) > 2) {\r
5d73d92f 626 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
627 ShellStatus = SHELL_INVALID_PARAMETER;\r
628 } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {\r
629 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-all", L"-guid");\r
630 ShellStatus = SHELL_INVALID_PARAMETER;\r
7e63fc9d
RN
631 } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {\r
632 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-l", L"-s");\r
633 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 634 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {\r
635 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-l or -s", L"-d");\r
636 ShellStatus = SHELL_INVALID_PARAMETER;\r
637 } else {\r
638 if (!ShellCommandLineGetFlag(Package, L"-all")) {\r
7e63fc9d
RN
639 GuidStr = ShellCommandLineGetValue(Package, L"-guid");\r
640 if (GuidStr != NULL) {\r
641 Status = ConvertStringToGuid(GuidStr, &GuidData);\r
5d73d92f 642 if (EFI_ERROR(Status)) {\r
7e63fc9d 643 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, GuidStr);\r
5d73d92f 644 ShellStatus = SHELL_INVALID_PARAMETER;\r
645 }\r
646 Guid = &GuidData;\r
647 } else {\r
648 Guid = &gEfiGlobalVariableGuid;\r
649 }\r
7e63fc9d 650 Name = ShellCommandLineGetRawValue(Package, 1);\r
5d73d92f 651 } else {\r
7e63fc9d
RN
652 Name = NULL;\r
653 Guid = NULL;\r
5d73d92f 654 }\r
655 if (ShellStatus == SHELL_SUCCESS) {\r
7e63fc9d
RN
656 if (ShellCommandLineGetFlag(Package, L"-s")) {\r
657 Type = DmpStoreSave;\r
658 File = ShellCommandLineGetValue(Package, L"-s");\r
659 if (File == NULL) {\r
660 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-s");\r
661 ShellStatus = SHELL_INVALID_PARAMETER;\r
662 } else {\r
663 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
664 if (!EFI_ERROR (Status)) {\r
665 //\r
666 // Delete existing file, but do not delete existing directory\r
667 //\r
668 FileInfo = ShellGetFileInfo (FileHandle);\r
669 if (FileInfo == NULL) {\r
670 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
671 Status = EFI_DEVICE_ERROR;\r
672 } else {\r
673 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
674 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, File);\r
675 Status = EFI_INVALID_PARAMETER;\r
676 } else {\r
677 Status = ShellDeleteFile (&FileHandle);\r
678 if (EFI_ERROR (Status)) {\r
679 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, File);\r
680 }\r
681 }\r
682 FreePool (FileInfo);\r
683 }\r
684 } else if (Status == EFI_NOT_FOUND) {\r
685 //\r
686 // Good when file doesn't exist\r
687 //\r
688 Status = EFI_SUCCESS;\r
689 } else {\r
690 //\r
691 // Otherwise it's bad.\r
692 //\r
693 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
694 }\r
695\r
696 if (!EFI_ERROR (Status)) {\r
697 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
698 if (EFI_ERROR (Status)) {\r
699 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
700 }\r
701 }\r
702\r
703 if (EFI_ERROR (Status)) {\r
704 ShellStatus = SHELL_INVALID_PARAMETER;\r
705 }\r
706 }\r
707 } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
708 Type = DmpStoreLoad;\r
709 File = ShellCommandLineGetValue(Package, L"-l");\r
710 if (File == NULL) {\r
711 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-l");\r
712 ShellStatus = SHELL_INVALID_PARAMETER;\r
713 } else {\r
714 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_READ, 0);\r
715 if (EFI_ERROR (Status)) {\r
716 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
717 ShellStatus = SHELL_INVALID_PARAMETER;\r
718 } else {\r
719 FileInfo = ShellGetFileInfo (FileHandle);\r
720 if (FileInfo == NULL) {\r
721 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
722 ShellStatus = SHELL_DEVICE_ERROR;\r
723 } else {\r
724 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
725 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, File);\r
726 ShellStatus = SHELL_INVALID_PARAMETER;\r
727 }\r
728 FreePool (FileInfo);\r
729 }\r
730 }\r
731 }\r
732 } else if (ShellCommandLineGetFlag(Package, L"-d")) {\r
733 Type = DmpStoreDelete;\r
734 }\r
735 }\r
736\r
737 if (ShellStatus == SHELL_SUCCESS) {\r
738 if (Type == DmpStoreSave) {\r
739 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_SAVE), gShellDebug1HiiHandle, File);\r
740 } else if (Type == DmpStoreLoad) {\r
741 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD), gShellDebug1HiiHandle, File);\r
742 }\r
743 ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle);\r
744 if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {\r
745 ShellCloseFile (&FileHandle);\r
5d73d92f 746 }\r
747 }\r
748 }\r
749 }\r
750\r
751 if (Package != NULL) {\r
752 ShellCommandLineFreeVarList (Package);\r
753 }\r
754 return ShellStatus;\r
755}\r
756\r