]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
MdeModulePkg/DxeCore: Fixed Interface returned by CoreOpenProtocol
[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
980af1eb 439 NameSize = sizeof(CHAR16);\r
5bd12b05
JC
440 }\r
441\r
442 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
443 if (Status == EFI_BUFFER_TOO_SMALL) {\r
444 SHELL_FREE_NON_NULL(FoundVarName);\r
445 FoundVarName = AllocateZeroPool (NameSize);\r
03bc7c2b
SQ
446 if (FoundVarName != NULL) {\r
447 if (PrevName != NULL) {\r
4dc0d578 448 StrnCpyS(FoundVarName, NameSize/sizeof(CHAR16), PrevName, NameSize/sizeof(CHAR16) - 1);\r
03bc7c2b
SQ
449 }\r
450\r
451 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
452 } else {\r
453 Status = EFI_OUT_OF_RESOURCES;\r
5d73d92f 454 }\r
5bd12b05
JC
455 }\r
456\r
457 //\r
458 // No more is fine.\r
459 //\r
460 if (Status == EFI_NOT_FOUND) {\r
461 SHELL_FREE_NON_NULL(FoundVarName);\r
462 return (SHELL_SUCCESS);\r
463 } else if (EFI_ERROR(Status)) {\r
464 SHELL_FREE_NON_NULL(FoundVarName);\r
465 return (SHELL_DEVICE_ERROR);\r
466 }\r
467\r
468 //\r
469 // Recurse to the next iteration. We know "our" variable's name.\r
470 //\r
e9597b45 471 ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne, StandardFormatOutput);\r
5bd12b05 472\r
148af387
TS
473 if (ShellGetExecutionBreakFlag() || (ShellStatus == SHELL_ABORTED)) {\r
474 SHELL_FREE_NON_NULL(FoundVarName);\r
475 return (SHELL_ABORTED);\r
476 }\r
477\r
5bd12b05
JC
478 //\r
479 // No matter what happened we process our own variable\r
480 // Only continue if Guid and VariableName are each either NULL or a match\r
481 //\r
7e63fc9d
RN
482 if ( ( Name == NULL \r
483 || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) )\r
5bd12b05
JC
484 && ( Guid == NULL \r
485 || CompareGuid(&FoundVarGuid, Guid) )\r
486 ) {\r
487 DataSize = 0;\r
488 DataBuffer = NULL;\r
5d73d92f 489 //\r
5bd12b05 490 // do the print or delete\r
5d73d92f 491 //\r
5bd12b05
JC
492 *FoundOne = TRUE;\r
493 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
73c82041 494 if (Status == EFI_BUFFER_TOO_SMALL) {\r
5bd12b05
JC
495 SHELL_FREE_NON_NULL (DataBuffer);\r
496 DataBuffer = AllocatePool (DataSize);\r
73c82041
ED
497 if (DataBuffer == NULL) {\r
498 Status = EFI_OUT_OF_RESOURCES;\r
5bd12b05
JC
499 } else {\r
500 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
73c82041 501 }\r
5bd12b05 502 }\r
5bd12b05
JC
503 //\r
504 // Last error check then print this variable out.\r
505 //\r
e9597b45 506 if (Type == DmpStoreDisplay) {\r
5511b319 507 if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
e9597b45
RN
508 AttrString = GetAttrType(Atts);\r
509 if (StandardFormatOutput) {\r
510 HexString = AllocatePool ((DataSize * 2 + 1) * sizeof (CHAR16));\r
511 if (HexString != NULL) {\r
512 ShellPrintHiiEx (\r
513 -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_VAR_SFO), gShellDebug1HiiHandle,\r
514 FoundVarName, &FoundVarGuid, Atts, DataSize,\r
515 BinaryToHexString (\r
516 DataBuffer, DataSize, HexString, (DataSize * 2 + 1) * sizeof (CHAR16)\r
517 )\r
518 );\r
519 FreePool (HexString);\r
520 } else {\r
521 Status = EFI_OUT_OF_RESOURCES;\r
522 }\r
7e63fc9d 523 } else {\r
e9597b45
RN
524 ShellPrintHiiEx (\r
525 -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,\r
526 AttrString, &FoundVarGuid, FoundVarName, DataSize\r
527 );\r
528 DumpHex (2, 0, DataSize, DataBuffer);\r
7e63fc9d 529 }\r
e9597b45
RN
530 SHELL_FREE_NON_NULL (AttrString);\r
531 }\r
532 } else if (Type == DmpStoreSave) {\r
533 if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
534 AttrString = GetAttrType (Atts);\r
535 ShellPrintHiiEx (\r
536 -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,\r
537 AttrString, &FoundVarGuid, FoundVarName, DataSize\r
538 );\r
539 Status = AppendSingleVariableToFile (\r
540 FileHandle,\r
541 FoundVarName,\r
542 &FoundVarGuid,\r
543 Atts,\r
544 (UINT32) DataSize,\r
545 DataBuffer\r
546 );\r
547 SHELL_FREE_NON_NULL (AttrString);\r
5bd12b05 548 }\r
7e63fc9d 549 } else if (Type == DmpStoreDelete) {\r
5bd12b05
JC
550 //\r
551 // We only need name to delete it...\r
552 //\r
ff28c72b 553 SetStatus = gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL);\r
e9597b45
RN
554 if (StandardFormatOutput) {\r
555 if (SetStatus == EFI_SUCCESS) {\r
556 ShellPrintHiiEx (\r
557 -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_NG_SFO), gShellDebug1HiiHandle,\r
558 FoundVarName, &FoundVarGuid\r
559 );\r
560 }\r
561 } else {\r
562 ShellPrintHiiEx (\r
563 -1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_DELETE_LINE), gShellDebug1HiiHandle,\r
564 &FoundVarGuid, FoundVarName, SetStatus\r
565 );\r
566 }\r
d6972185 567 }\r
5bd12b05 568 SHELL_FREE_NON_NULL(DataBuffer);\r
5d73d92f 569 }\r
570\r
5bd12b05
JC
571 SHELL_FREE_NON_NULL(FoundVarName);\r
572\r
573 if (Status == EFI_DEVICE_ERROR) {\r
574 ShellStatus = SHELL_DEVICE_ERROR;\r
575 } else if (Status == EFI_SECURITY_VIOLATION) {\r
576 ShellStatus = SHELL_SECURITY_VIOLATION;\r
577 } else if (EFI_ERROR(Status)) {\r
578 ShellStatus = SHELL_NOT_READY;\r
5d73d92f 579 }\r
5bd12b05
JC
580\r
581 return (ShellStatus);\r
582}\r
583\r
584/**\r
585 Function to display or delete variables. This will set up and call into the recursive function.\r
586\r
e9597b45
RN
587 @param[in] Name The variable name of the EFI variable (or NULL).\r
588 @param[in] Guid The GUID of the variable set (or NULL).\r
589 @param[in] Type The operation type.\r
590 @param[in] FileHandle The file to save or load variables.\r
591 @param[in] StandardFormatOutput TRUE indicates Standard-Format Output.\r
5bd12b05
JC
592\r
593 @retval SHELL_SUCCESS The operation was successful.\r
594 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
595 @retval SHELL_ABORTED The abort message was received.\r
596 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
597 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
598**/\r
599SHELL_STATUS\r
5bd12b05 600ProcessVariables (\r
7e63fc9d
RN
601 IN CONST CHAR16 *Name OPTIONAL,\r
602 IN CONST EFI_GUID *Guid OPTIONAL,\r
603 IN DMP_STORE_TYPE Type,\r
e9597b45
RN
604 IN SHELL_FILE_HANDLE FileHandle OPTIONAL,\r
605 IN BOOLEAN StandardFormatOutput\r
5bd12b05
JC
606 )\r
607{\r
608 SHELL_STATUS ShellStatus;\r
609 BOOLEAN Found;\r
610 EFI_GUID FoundVarGuid;\r
611\r
612 Found = FALSE;\r
613 ShellStatus = SHELL_SUCCESS;\r
614 ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));\r
615\r
e9597b45
RN
616 if (StandardFormatOutput) {\r
617 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_SFO_HEADER), gShellDebug1HiiHandle, L"dmpstore");\r
618 }\r
619\r
7e63fc9d 620 if (Type == DmpStoreLoad) {\r
5511b319 621 ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found);\r
7e63fc9d 622 } else {\r
e9597b45 623 ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found, StandardFormatOutput);\r
7e63fc9d 624 }\r
5bd12b05 625\r
3737ac2b 626 if (!Found) {\r
5bd12b05 627 if (ShellStatus == SHELL_OUT_OF_RESOURCES) {\r
4092a8f6 628 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"dmpstore"); \r
5bd12b05 629 return (ShellStatus);\r
7e63fc9d 630 } else if (Name != NULL && Guid == NULL) {\r
e9597b45
RN
631 if (StandardFormatOutput) {\r
632 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N_SFO), gShellDebug1HiiHandle, Name);\r
633 } else {\r
634 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, L"dmpstore", Name); \r
635 }\r
7e63fc9d 636 } else if (Name != NULL && Guid != NULL) {\r
4092a8f6 637 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, L"dmpstore", Guid, Name); \r
7e63fc9d 638 } else if (Name == NULL && Guid == NULL) {\r
e9597b45
RN
639 if (StandardFormatOutput) {\r
640 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_SFO), gShellDebug1HiiHandle);\r
641 } else {\r
642 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND), gShellDebug1HiiHandle, L"dmpstore");\r
643 }\r
7e63fc9d 644 } else if (Name == NULL && Guid != NULL) {\r
e9597b45
RN
645 if (StandardFormatOutput) {\r
646 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G_SFO), gShellDebug1HiiHandle, Guid);\r
647 } else {\r
648 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G), gShellDebug1HiiHandle, L"dmpstore", Guid);\r
649 }\r
3737ac2b 650 } \r
651 return (SHELL_NOT_FOUND);\r
652 }\r
224e8e2f 653 return (ShellStatus);\r
5d73d92f 654}\r
655\r
656STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
657 {L"-d", TypeFlag},\r
7e63fc9d
RN
658 {L"-l", TypeValue},\r
659 {L"-s", TypeValue},\r
5d73d92f 660 {L"-all", TypeFlag},\r
661 {L"-guid", TypeValue},\r
e9597b45 662 {L"-sfo", TypeFlag},\r
5d73d92f 663 {NULL, TypeMax}\r
664 };\r
665\r
3737ac2b 666/**\r
667 Function for 'dmpstore' command.\r
668\r
669 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
670 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
671**/\r
5d73d92f 672SHELL_STATUS\r
673EFIAPI\r
674ShellCommandRunDmpStore (\r
675 IN EFI_HANDLE ImageHandle,\r
676 IN EFI_SYSTEM_TABLE *SystemTable\r
677 )\r
678{\r
7e63fc9d 679 EFI_STATUS Status;\r
7f6511ee 680 RETURN_STATUS RStatus;\r
7e63fc9d
RN
681 LIST_ENTRY *Package;\r
682 CHAR16 *ProblemParam;\r
683 SHELL_STATUS ShellStatus;\r
684 CONST CHAR16 *GuidStr;\r
685 CONST CHAR16 *File;\r
686 EFI_GUID *Guid;\r
687 EFI_GUID GuidData;\r
688 CONST CHAR16 *Name;\r
689 DMP_STORE_TYPE Type;\r
690 SHELL_FILE_HANDLE FileHandle;\r
691 EFI_FILE_INFO *FileInfo;\r
e9597b45 692 BOOLEAN StandardFormatOutput;\r
5d73d92f 693\r
e9597b45
RN
694 ShellStatus = SHELL_SUCCESS;\r
695 Package = NULL;\r
696 FileHandle = NULL;\r
697 File = NULL;\r
698 Type = DmpStoreDisplay;\r
699 StandardFormatOutput = FALSE;\r
5d73d92f 700\r
701 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
702 if (EFI_ERROR(Status)) {\r
703 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
4092a8f6 704 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"dmpstore", ProblemParam); \r
5d73d92f 705 FreePool(ProblemParam);\r
706 ShellStatus = SHELL_INVALID_PARAMETER;\r
707 } else {\r
708 ASSERT(FALSE);\r
709 }\r
710 } else {\r
3737ac2b 711 if (ShellCommandLineGetCount(Package) > 2) {\r
4092a8f6 712 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmpstore"); \r
5d73d92f 713 ShellStatus = SHELL_INVALID_PARAMETER;\r
714 } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {\r
4092a8f6 715 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-all", L"-guid"); \r
5d73d92f 716 ShellStatus = SHELL_INVALID_PARAMETER;\r
7e63fc9d 717 } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {\r
4092a8f6 718 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l", L"-s"); \r
7e63fc9d 719 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 720 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {\r
4092a8f6 721 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-d"); \r
5d73d92f 722 ShellStatus = SHELL_INVALID_PARAMETER;\r
e9597b45
RN
723 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-sfo")) {\r
724 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-sfo"); \r
725 ShellStatus = SHELL_INVALID_PARAMETER;\r
5d73d92f 726 } else {\r
9954df7b
JC
727 //\r
728 // Determine the GUID to search for based on -all and -guid parameters\r
729 //\r
5d73d92f 730 if (!ShellCommandLineGetFlag(Package, L"-all")) {\r
7e63fc9d
RN
731 GuidStr = ShellCommandLineGetValue(Package, L"-guid");\r
732 if (GuidStr != NULL) {\r
7f6511ee
RN
733 RStatus = StrToGuid (GuidStr, &GuidData);\r
734 if (RETURN_ERROR (RStatus) || (GuidStr[GUID_STRING_LENGTH] != L'\0')) {\r
4092a8f6 735 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmpstore", GuidStr); \r
5d73d92f 736 ShellStatus = SHELL_INVALID_PARAMETER;\r
737 }\r
738 Guid = &GuidData;\r
739 } else {\r
740 Guid = &gEfiGlobalVariableGuid;\r
741 }\r
5d73d92f 742 } else {\r
7e63fc9d 743 Guid = NULL;\r
5d73d92f 744 }\r
9954df7b
JC
745\r
746 //\r
747 // Get the Name of the variable to find\r
748 //\r
749 Name = ShellCommandLineGetRawValue(Package, 1);\r
750\r
5d73d92f 751 if (ShellStatus == SHELL_SUCCESS) {\r
7e63fc9d
RN
752 if (ShellCommandLineGetFlag(Package, L"-s")) {\r
753 Type = DmpStoreSave;\r
754 File = ShellCommandLineGetValue(Package, L"-s");\r
755 if (File == NULL) {\r
4092a8f6 756 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-s"); \r
7e63fc9d
RN
757 ShellStatus = SHELL_INVALID_PARAMETER;\r
758 } else {\r
759 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
760 if (!EFI_ERROR (Status)) {\r
761 //\r
762 // Delete existing file, but do not delete existing directory\r
763 //\r
764 FileInfo = ShellGetFileInfo (FileHandle);\r
765 if (FileInfo == NULL) {\r
4092a8f6 766 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
767 Status = EFI_DEVICE_ERROR;\r
768 } else {\r
769 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
4092a8f6 770 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
771 Status = EFI_INVALID_PARAMETER;\r
772 } else {\r
773 Status = ShellDeleteFile (&FileHandle);\r
774 if (EFI_ERROR (Status)) {\r
4092a8f6 775 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
776 }\r
777 }\r
778 FreePool (FileInfo);\r
779 }\r
780 } else if (Status == EFI_NOT_FOUND) {\r
781 //\r
782 // Good when file doesn't exist\r
783 //\r
784 Status = EFI_SUCCESS;\r
785 } else {\r
786 //\r
787 // Otherwise it's bad.\r
788 //\r
4092a8f6 789 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
790 }\r
791\r
792 if (!EFI_ERROR (Status)) {\r
793 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
794 if (EFI_ERROR (Status)) {\r
4092a8f6 795 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
796 }\r
797 }\r
798\r
799 if (EFI_ERROR (Status)) {\r
800 ShellStatus = SHELL_INVALID_PARAMETER;\r
801 }\r
802 }\r
803 } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
804 Type = DmpStoreLoad;\r
805 File = ShellCommandLineGetValue(Package, L"-l");\r
806 if (File == NULL) {\r
4092a8f6 807 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-l"); \r
7e63fc9d
RN
808 ShellStatus = SHELL_INVALID_PARAMETER;\r
809 } else {\r
810 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_READ, 0);\r
811 if (EFI_ERROR (Status)) {\r
4092a8f6 812 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
813 ShellStatus = SHELL_INVALID_PARAMETER;\r
814 } else {\r
815 FileInfo = ShellGetFileInfo (FileHandle);\r
816 if (FileInfo == NULL) {\r
4092a8f6 817 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
818 ShellStatus = SHELL_DEVICE_ERROR;\r
819 } else {\r
820 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
4092a8f6 821 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
7e63fc9d
RN
822 ShellStatus = SHELL_INVALID_PARAMETER;\r
823 }\r
824 FreePool (FileInfo);\r
825 }\r
826 }\r
827 }\r
828 } else if (ShellCommandLineGetFlag(Package, L"-d")) {\r
829 Type = DmpStoreDelete;\r
830 }\r
e9597b45
RN
831\r
832 if (ShellCommandLineGetFlag (Package,L"-sfo")) {\r
833 StandardFormatOutput = TRUE;\r
834 }\r
7e63fc9d
RN
835 }\r
836\r
837 if (ShellStatus == SHELL_SUCCESS) {\r
838 if (Type == DmpStoreSave) {\r
839 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_SAVE), gShellDebug1HiiHandle, File);\r
840 } else if (Type == DmpStoreLoad) {\r
841 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD), gShellDebug1HiiHandle, File);\r
842 }\r
e9597b45 843 ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle, StandardFormatOutput);\r
7e63fc9d
RN
844 if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {\r
845 ShellCloseFile (&FileHandle);\r
5d73d92f 846 }\r
847 }\r
848 }\r
849 }\r
850\r
851 if (Package != NULL) {\r
852 ShellCommandLineFreeVarList (Package);\r
853 }\r
854 return ShellStatus;\r
855}\r
856\r