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