]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
ShellPkg: Refine type cast for pointer subtraction
[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
7f6511ee 5 Copyright (c) 2005 - 2017, 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
810c635d 367 gBS->CalculateCrc32 (Buffer, (UINTN) Ptr - (UINTN) Buffer, (UINT32 *) Ptr);\r
7e63fc9d
RN
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 678 EFI_STATUS Status;\r
7f6511ee 679 RETURN_STATUS RStatus;\r
7e63fc9d
RN
680 LIST_ENTRY *Package;\r
681 CHAR16 *ProblemParam;\r
682 SHELL_STATUS ShellStatus;\r
683 CONST CHAR16 *GuidStr;\r
684 CONST CHAR16 *File;\r
685 EFI_GUID *Guid;\r
686 EFI_GUID GuidData;\r
687 CONST CHAR16 *Name;\r
688 DMP_STORE_TYPE Type;\r
689 SHELL_FILE_HANDLE FileHandle;\r
690 EFI_FILE_INFO *FileInfo;\r
e9597b45 691 BOOLEAN StandardFormatOutput;\r
5d73d92f 692\r
e9597b45
RN
693 ShellStatus = SHELL_SUCCESS;\r
694 Package = NULL;\r
695 FileHandle = NULL;\r
696 File = NULL;\r
697 Type = DmpStoreDisplay;\r
698 StandardFormatOutput = FALSE;\r
5d73d92f 699\r
700 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
701 if (EFI_ERROR(Status)) {\r
702 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
4092a8f6 703 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"dmpstore", ProblemParam); \r
5d73d92f 704 FreePool(ProblemParam);\r
705 ShellStatus = SHELL_INVALID_PARAMETER;\r
706 } else {\r
707 ASSERT(FALSE);\r
708 }\r
709 } else {\r
3737ac2b 710 if (ShellCommandLineGetCount(Package) > 2) {\r
4092a8f6 711 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmpstore"); \r
5d73d92f 712 ShellStatus = SHELL_INVALID_PARAMETER;\r
713 } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {\r
4092a8f6 714 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-all", L"-guid"); \r
5d73d92f 715 ShellStatus = SHELL_INVALID_PARAMETER;\r
7e63fc9d 716 } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {\r
4092a8f6 717 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l", L"-s"); \r
7e63fc9d 718 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 719 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {\r
4092a8f6 720 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-d"); \r
5d73d92f 721 ShellStatus = SHELL_INVALID_PARAMETER;\r
e9597b45
RN
722 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-sfo")) {\r
723 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-sfo"); \r
724 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 725 } else {\r
9954df7b
JC
726 //\r
727 // Determine the GUID to search for based on -all and -guid parameters\r
728 //\r
5d73d92f 729 if (!ShellCommandLineGetFlag(Package, L"-all")) {\r
7e63fc9d
RN
730 GuidStr = ShellCommandLineGetValue(Package, L"-guid");\r
731 if (GuidStr != NULL) {\r
7f6511ee
RN
732 RStatus = StrToGuid (GuidStr, &GuidData);\r
733 if (RETURN_ERROR (RStatus) || (GuidStr[GUID_STRING_LENGTH] != L'\0')) {\r
4092a8f6 734 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmpstore", GuidStr); \r
5d73d92f 735 ShellStatus = SHELL_INVALID_PARAMETER;\r
736 }\r
737 Guid = &GuidData;\r
738 } else {\r
739 Guid = &gEfiGlobalVariableGuid;\r
740 }\r
5d73d92f 741 } else {\r
7e63fc9d 742 Guid = NULL;\r
5d73d92f 743 }\r
9954df7b
JC
744\r
745 //\r
746 // Get the Name of the variable to find\r
747 //\r
748 Name = ShellCommandLineGetRawValue(Package, 1);\r
749\r
5d73d92f 750 if (ShellStatus == SHELL_SUCCESS) {\r
7e63fc9d
RN
751 if (ShellCommandLineGetFlag(Package, L"-s")) {\r
752 Type = DmpStoreSave;\r
753 File = ShellCommandLineGetValue(Package, L"-s");\r
754 if (File == NULL) {\r
4092a8f6 755 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-s"); \r
7e63fc9d
RN
756 ShellStatus = SHELL_INVALID_PARAMETER;\r
757 } else {\r
758 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
759 if (!EFI_ERROR (Status)) {\r
760 //\r
761 // Delete existing file, but do not delete existing directory\r
762 //\r
763 FileInfo = ShellGetFileInfo (FileHandle);\r
764 if (FileInfo == NULL) {\r
4092a8f6 765 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
766 Status = EFI_DEVICE_ERROR;\r
767 } else {\r
768 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
4092a8f6 769 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
770 Status = EFI_INVALID_PARAMETER;\r
771 } else {\r
772 Status = ShellDeleteFile (&FileHandle);\r
773 if (EFI_ERROR (Status)) {\r
4092a8f6 774 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
775 }\r
776 }\r
777 FreePool (FileInfo);\r
778 }\r
779 } else if (Status == EFI_NOT_FOUND) {\r
780 //\r
781 // Good when file doesn't exist\r
782 //\r
783 Status = EFI_SUCCESS;\r
784 } else {\r
785 //\r
786 // Otherwise it's bad.\r
787 //\r
4092a8f6 788 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
789 }\r
790\r
791 if (!EFI_ERROR (Status)) {\r
792 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
793 if (EFI_ERROR (Status)) {\r
4092a8f6 794 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
795 }\r
796 }\r
797\r
798 if (EFI_ERROR (Status)) {\r
799 ShellStatus = SHELL_INVALID_PARAMETER;\r
800 }\r
801 }\r
802 } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
803 Type = DmpStoreLoad;\r
804 File = ShellCommandLineGetValue(Package, L"-l");\r
805 if (File == NULL) {\r
4092a8f6 806 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-l"); \r
7e63fc9d
RN
807 ShellStatus = SHELL_INVALID_PARAMETER;\r
808 } else {\r
809 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_READ, 0);\r
810 if (EFI_ERROR (Status)) {\r
4092a8f6 811 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
812 ShellStatus = SHELL_INVALID_PARAMETER;\r
813 } else {\r
814 FileInfo = ShellGetFileInfo (FileHandle);\r
815 if (FileInfo == NULL) {\r
4092a8f6 816 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
817 ShellStatus = SHELL_DEVICE_ERROR;\r
818 } else {\r
819 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
4092a8f6 820 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
821 ShellStatus = SHELL_INVALID_PARAMETER;\r
822 }\r
823 FreePool (FileInfo);\r
824 }\r
825 }\r
826 }\r
827 } else if (ShellCommandLineGetFlag(Package, L"-d")) {\r
828 Type = DmpStoreDelete;\r
829 }\r
e9597b45
RN
830\r
831 if (ShellCommandLineGetFlag (Package,L"-sfo")) {\r
832 StandardFormatOutput = TRUE;\r
833 }\r
7e63fc9d
RN
834 }\r
835\r
836 if (ShellStatus == SHELL_SUCCESS) {\r
837 if (Type == DmpStoreSave) {\r
838 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_SAVE), gShellDebug1HiiHandle, File);\r
839 } else if (Type == DmpStoreLoad) {\r
840 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD), gShellDebug1HiiHandle, File);\r
841 }\r
e9597b45 842 ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle, StandardFormatOutput);\r
7e63fc9d
RN
843 if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {\r
844 ShellCloseFile (&FileHandle);\r
5d73d92f 845 }\r
846 }\r
847 }\r
848 }\r
849\r
850 if (Package != NULL) {\r
851 ShellCommandLineFreeVarList (Package);\r
852 }\r
853 return ShellStatus;\r
854}\r
855\r