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