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