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