]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
ShellPkg/pci: Fix extended register dumping for MFVC capability
[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
e9597b45 5 Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>\r
5d73d92f 6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "UefiShellDebug1CommandsLib.h"\r
17\r
7e63fc9d
RN
18typedef enum {\r
19 DmpStoreDisplay,\r
20 DmpStoreDelete,\r
21 DmpStoreSave,\r
22 DmpStoreLoad\r
23} DMP_STORE_TYPE;\r
24\r
25typedef struct {\r
26 UINT32 Signature;\r
27 CHAR16 *Name;\r
28 EFI_GUID Guid;\r
29 UINT32 Attributes;\r
30 UINT32 DataSize;\r
31 UINT8 *Data;\r
32 LIST_ENTRY Link;\r
33} DMP_STORE_VARIABLE;\r
34\r
35#define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's')\r
36\r
cd0842dc
ED
37/**\r
38 Base on the input attribute value to return the attribute string.\r
39\r
40 @param[in] Atts The input attribute value\r
cd0842dc
ED
41\r
42 @retval The attribute string info.\r
43**/\r
d6972185 44CHAR16 *\r
73c82041 45GetAttrType (\r
d6972185 46 IN CONST UINT32 Atts\r
73c82041
ED
47 )\r
48{\r
99bb0f8d 49 UINTN BufLen;\r
d6972185 50 CHAR16 *RetString;\r
73c82041 51\r
d6972185
ED
52 BufLen = 0;\r
53 RetString = NULL;\r
54 \r
cd0842dc 55 if ((Atts & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
d6972185 56 StrnCatGrow (&RetString, &BufLen, L"+NV", 0);\r
73c82041 57 }\r
cd0842dc 58 if ((Atts & EFI_VARIABLE_RUNTIME_ACCESS) != 0) {\r
14868afb 59 StrnCatGrow (&RetString, &BufLen, L"+RT+BS", 0);\r
cd0842dc 60 } else if ((Atts & EFI_VARIABLE_BOOTSERVICE_ACCESS) != 0) {\r
d6972185 61 StrnCatGrow (&RetString, &BufLen, L"+BS", 0);\r
73c82041 62 }\r
cd0842dc 63 if ((Atts & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) {\r
d6972185 64 StrnCatGrow (&RetString, &BufLen, L"+HR", 0);\r
73c82041 65 }\r
cd0842dc 66 if ((Atts & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
d6972185 67 StrnCatGrow (&RetString, &BufLen, L"+AW", 0);\r
73c82041 68 }\r
cd0842dc 69 if ((Atts & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
d6972185 70 StrnCatGrow (&RetString, &BufLen, L"+AT", 0);\r
73c82041
ED
71 }\r
72\r
d6972185
ED
73 if (RetString == NULL) {\r
74 RetString = StrnCatGrow(&RetString, &BufLen, L"Invalid", 0);\r
73c82041 75 }\r
d6972185 76\r
44890dbd 77 if ((RetString != NULL) && (RetString[0] == L'+')) {\r
d6972185 78 CopyMem(RetString, RetString + 1, StrSize(RetString + 1));\r
73c82041 79 }\r
d6972185
ED
80\r
81 return RetString;\r
73c82041 82}\r
5d73d92f 83\r
e9597b45
RN
84/**\r
85 Convert binary to hex format string.\r
86\r
e9597b45 87 @param[in] Buffer The binary data.\r
ff28c72b 88 @param[in] BufferSize The size in bytes of the binary data.\r
e9597b45
RN
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
7e63fc9d
RN
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
5511b319
SQ
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
7e63fc9d 132**/\r
5511b319 133SHELL_STATUS\r
7e63fc9d
RN
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
5511b319 142 SHELL_STATUS ShellStatus;\r
7e63fc9d
RN
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
5511b319 158 return SHELL_DEVICE_ERROR;\r
7e63fc9d 159 }\r
5511b319
SQ
160 \r
161 ShellStatus = SHELL_SUCCESS;\r
162 \r
7e63fc9d
RN
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
5511b319 173 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
7e63fc9d
RN
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
5511b319 183 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
7e63fc9d
RN
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
5511b319 194 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
7e63fc9d
RN
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
5511b319 200 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
7e63fc9d
RN
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
5511b319 218 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
7e63fc9d
RN
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
5511b319 227 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
7e63fc9d
RN
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
5511b319 243 if ((Position != FileSize) || (ShellStatus != SHELL_SUCCESS)) {\r
4092a8f6 244 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE), gShellDebug1HiiHandle, L"dmpstore"); \r
5511b319
SQ
245 if (Position != FileSize) {\r
246 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
247 }\r
7e63fc9d
RN
248 }\r
249 \r
250 for ( Link = GetFirstNode (&List)\r
5511b319 251 ; !IsNull (&List, Link) && (ShellStatus == SHELL_SUCCESS)\r
7e63fc9d
RN
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
4092a8f6 275 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", Variable->Name, Status); \r
7e63fc9d
RN
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
5511b319 286 return ShellStatus;\r
7e63fc9d
RN
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
88963516 373 (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize + sizeof (UINT32))\r
7e63fc9d
RN
374 ) {\r
375 Status = EFI_DEVICE_ERROR;\r
376 }\r
377 \r
378 return Status;\r
379}\r
380\r
3737ac2b 381/**\r
5bd12b05
JC
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
3737ac2b 388\r
e9597b45
RN
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
3737ac2b 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
5d73d92f 405SHELL_STATUS\r
5bd12b05 406CascadeProcessVariables (\r
7e63fc9d
RN
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
e9597b45
RN
413 IN BOOLEAN *FoundOne,\r
414 IN BOOLEAN StandardFormatOutput\r
5d73d92f 415 )\r
416{\r
417 EFI_STATUS Status;\r
5d73d92f 418 CHAR16 *FoundVarName;\r
5d73d92f 419 UINT8 *DataBuffer;\r
420 UINTN DataSize;\r
421 UINT32 Atts;\r
422 SHELL_STATUS ShellStatus;\r
73c82041 423 UINTN NameSize;\r
e9597b45
RN
424 CHAR16 *AttrString;\r
425 CHAR16 *HexString;\r
ff28c72b 426 EFI_STATUS SetStatus;\r
5d73d92f 427\r
5bd12b05
JC
428 if (ShellGetExecutionBreakFlag()) {\r
429 return (SHELL_ABORTED);\r
5d73d92f 430 }\r
431\r
5bd12b05
JC
432 NameSize = 0;\r
433 FoundVarName = NULL;\r
5d73d92f 434\r
5bd12b05
JC
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
03bc7c2b
SQ
445 if (FoundVarName != NULL) {\r
446 if (PrevName != NULL) {\r
4dc0d578 447 StrnCpyS(FoundVarName, NameSize/sizeof(CHAR16), PrevName, NameSize/sizeof(CHAR16) - 1);\r
03bc7c2b
SQ
448 }\r
449\r
450 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
451 } else {\r
452 Status = EFI_OUT_OF_RESOURCES;\r
5d73d92f 453 }\r
5bd12b05
JC
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
e9597b45 470 ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne, StandardFormatOutput);\r
5bd12b05 471\r
148af387
TS
472 if (ShellGetExecutionBreakFlag() || (ShellStatus == SHELL_ABORTED)) {\r
473 SHELL_FREE_NON_NULL(FoundVarName);\r
474 return (SHELL_ABORTED);\r
475 }\r
476\r
5bd12b05
JC
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
7e63fc9d
RN
481 if ( ( Name == NULL \r
482 || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) )\r
5bd12b05
JC
483 && ( Guid == NULL \r
484 || CompareGuid(&FoundVarGuid, Guid) )\r
485 ) {\r
486 DataSize = 0;\r
487 DataBuffer = NULL;\r
5d73d92f 488 //\r
5bd12b05 489 // do the print or delete\r
5d73d92f 490 //\r
5bd12b05
JC
491 *FoundOne = TRUE;\r
492 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
73c82041 493 if (Status == EFI_BUFFER_TOO_SMALL) {\r
5bd12b05
JC
494 SHELL_FREE_NON_NULL (DataBuffer);\r
495 DataBuffer = AllocatePool (DataSize);\r
73c82041
ED
496 if (DataBuffer == NULL) {\r
497 Status = EFI_OUT_OF_RESOURCES;\r
5bd12b05
JC
498 } else {\r
499 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
73c82041 500 }\r
5bd12b05 501 }\r
5bd12b05
JC
502 //\r
503 // Last error check then print this variable out.\r
504 //\r
e9597b45 505 if (Type == DmpStoreDisplay) {\r
5511b319 506 if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
e9597b45
RN
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
7e63fc9d 522 } else {\r
e9597b45
RN
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
7e63fc9d 528 }\r
e9597b45
RN
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
5bd12b05 547 }\r
7e63fc9d 548 } else if (Type == DmpStoreDelete) {\r
5bd12b05
JC
549 //\r
550 // We only need name to delete it...\r
551 //\r
ff28c72b 552 SetStatus = gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL);\r
e9597b45
RN
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
d6972185 566 }\r
5bd12b05 567 SHELL_FREE_NON_NULL(DataBuffer);\r
5d73d92f 568 }\r
569\r
5bd12b05
JC
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
5d73d92f 578 }\r
5bd12b05
JC
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
e9597b45
RN
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
5bd12b05
JC
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
5bd12b05 599ProcessVariables (\r
7e63fc9d
RN
600 IN CONST CHAR16 *Name OPTIONAL,\r
601 IN CONST EFI_GUID *Guid OPTIONAL,\r
602 IN DMP_STORE_TYPE Type,\r
e9597b45
RN
603 IN SHELL_FILE_HANDLE FileHandle OPTIONAL,\r
604 IN BOOLEAN StandardFormatOutput\r
5bd12b05
JC
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
e9597b45
RN
615 if (StandardFormatOutput) {\r
616 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_SFO_HEADER), gShellDebug1HiiHandle, L"dmpstore");\r
617 }\r
618\r
7e63fc9d 619 if (Type == DmpStoreLoad) {\r
5511b319 620 ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found);\r
7e63fc9d 621 } else {\r
e9597b45 622 ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found, StandardFormatOutput);\r
7e63fc9d 623 }\r
5bd12b05 624\r
3737ac2b 625 if (!Found) {\r
5bd12b05 626 if (ShellStatus == SHELL_OUT_OF_RESOURCES) {\r
4092a8f6 627 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"dmpstore"); \r
5bd12b05 628 return (ShellStatus);\r
7e63fc9d 629 } else if (Name != NULL && Guid == NULL) {\r
e9597b45
RN
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
7e63fc9d 635 } else if (Name != NULL && Guid != NULL) {\r
4092a8f6 636 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, L"dmpstore", Guid, Name); \r
7e63fc9d 637 } else if (Name == NULL && Guid == NULL) {\r
e9597b45
RN
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
7e63fc9d 643 } else if (Name == NULL && Guid != NULL) {\r
e9597b45
RN
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
3737ac2b 649 } \r
650 return (SHELL_NOT_FOUND);\r
651 }\r
224e8e2f 652 return (ShellStatus);\r
5d73d92f 653}\r
654\r
655STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
656 {L"-d", TypeFlag},\r
7e63fc9d
RN
657 {L"-l", TypeValue},\r
658 {L"-s", TypeValue},\r
5d73d92f 659 {L"-all", TypeFlag},\r
660 {L"-guid", TypeValue},\r
e9597b45 661 {L"-sfo", TypeFlag},\r
5d73d92f 662 {NULL, TypeMax}\r
663 };\r
664\r
3737ac2b 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
5d73d92f 671SHELL_STATUS\r
672EFIAPI\r
673ShellCommandRunDmpStore (\r
674 IN EFI_HANDLE ImageHandle,\r
675 IN EFI_SYSTEM_TABLE *SystemTable\r
676 )\r
677{\r
7e63fc9d
RN
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
e9597b45 690 BOOLEAN StandardFormatOutput;\r
5d73d92f 691\r
e9597b45
RN
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
5d73d92f 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
4092a8f6 702 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"dmpstore", ProblemParam); \r
5d73d92f 703 FreePool(ProblemParam);\r
704 ShellStatus = SHELL_INVALID_PARAMETER;\r
705 } else {\r
706 ASSERT(FALSE);\r
707 }\r
708 } else {\r
3737ac2b 709 if (ShellCommandLineGetCount(Package) > 2) {\r
4092a8f6 710 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmpstore"); \r
5d73d92f 711 ShellStatus = SHELL_INVALID_PARAMETER;\r
712 } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {\r
4092a8f6 713 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-all", L"-guid"); \r
5d73d92f 714 ShellStatus = SHELL_INVALID_PARAMETER;\r
7e63fc9d 715 } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {\r
4092a8f6 716 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l", L"-s"); \r
7e63fc9d 717 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 718 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {\r
4092a8f6 719 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-d"); \r
5d73d92f 720 ShellStatus = SHELL_INVALID_PARAMETER;\r
e9597b45
RN
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
5d73d92f 724 } else {\r
9954df7b
JC
725 //\r
726 // Determine the GUID to search for based on -all and -guid parameters\r
727 //\r
5d73d92f 728 if (!ShellCommandLineGetFlag(Package, L"-all")) {\r
7e63fc9d
RN
729 GuidStr = ShellCommandLineGetValue(Package, L"-guid");\r
730 if (GuidStr != NULL) {\r
731 Status = ConvertStringToGuid(GuidStr, &GuidData);\r
5d73d92f 732 if (EFI_ERROR(Status)) {\r
4092a8f6 733 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmpstore", GuidStr); \r
5d73d92f 734 ShellStatus = SHELL_INVALID_PARAMETER;\r
735 }\r
736 Guid = &GuidData;\r
737 } else {\r
738 Guid = &gEfiGlobalVariableGuid;\r
739 }\r
5d73d92f 740 } else {\r
7e63fc9d 741 Guid = NULL;\r
5d73d92f 742 }\r
9954df7b
JC
743\r
744 //\r
745 // Get the Name of the variable to find\r
746 //\r
747 Name = ShellCommandLineGetRawValue(Package, 1);\r
748\r
5d73d92f 749 if (ShellStatus == SHELL_SUCCESS) {\r
7e63fc9d
RN
750 if (ShellCommandLineGetFlag(Package, L"-s")) {\r
751 Type = DmpStoreSave;\r
752 File = ShellCommandLineGetValue(Package, L"-s");\r
753 if (File == NULL) {\r
4092a8f6 754 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-s"); \r
7e63fc9d
RN
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
4092a8f6 764 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
765 Status = EFI_DEVICE_ERROR;\r
766 } else {\r
767 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
4092a8f6 768 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
769 Status = EFI_INVALID_PARAMETER;\r
770 } else {\r
771 Status = ShellDeleteFile (&FileHandle);\r
772 if (EFI_ERROR (Status)) {\r
4092a8f6 773 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
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
4092a8f6 787 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
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
4092a8f6 793 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
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
4092a8f6 805 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-l"); \r
7e63fc9d
RN
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
4092a8f6 810 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
811 ShellStatus = SHELL_INVALID_PARAMETER;\r
812 } else {\r
813 FileInfo = ShellGetFileInfo (FileHandle);\r
814 if (FileInfo == NULL) {\r
4092a8f6 815 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
816 ShellStatus = SHELL_DEVICE_ERROR;\r
817 } else {\r
818 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
4092a8f6 819 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
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
e9597b45
RN
829\r
830 if (ShellCommandLineGetFlag (Package,L"-sfo")) {\r
831 StandardFormatOutput = TRUE;\r
832 }\r
7e63fc9d
RN
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
e9597b45 841 ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle, StandardFormatOutput);\r
7e63fc9d
RN
842 if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {\r
843 ShellCloseFile (&FileHandle);\r
5d73d92f 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