]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
ShellPkg DmpStore: Make NameSize to be consistent with name buffer
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / DmpStore.c
... / ...
CommitLineData
1/** @file\r
2 Main file for DmpStore shell Debug1 function.\r
3 \r
4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
5 Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "UefiShellDebug1CommandsLib.h"\r
17\r
18typedef enum {\r
19 DmpStoreDisplay,\r
20 DmpStoreDelete,\r
21 DmpStoreSave,\r
22 DmpStoreLoad\r
23} DMP_STORE_TYPE;\r
24\r
25typedef struct {\r
26 UINT32 Signature;\r
27 CHAR16 *Name;\r
28 EFI_GUID Guid;\r
29 UINT32 Attributes;\r
30 UINT32 DataSize;\r
31 UINT8 *Data;\r
32 LIST_ENTRY Link;\r
33} DMP_STORE_VARIABLE;\r
34\r
35#define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's')\r
36\r
37/**\r
38 Base on the input attribute value to return the attribute string.\r
39\r
40 @param[in] Atts The input attribute value\r
41\r
42 @retval The attribute string info.\r
43**/\r
44CHAR16 *\r
45GetAttrType (\r
46 IN CONST UINT32 Atts\r
47 )\r
48{\r
49 UINTN BufLen;\r
50 CHAR16 *RetString;\r
51\r
52 BufLen = 0;\r
53 RetString = NULL;\r
54 \r
55 if ((Atts & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
56 StrnCatGrow (&RetString, &BufLen, L"+NV", 0);\r
57 }\r
58 if ((Atts & EFI_VARIABLE_RUNTIME_ACCESS) != 0) {\r
59 StrnCatGrow (&RetString, &BufLen, L"+RT+BS", 0);\r
60 } else if ((Atts & EFI_VARIABLE_BOOTSERVICE_ACCESS) != 0) {\r
61 StrnCatGrow (&RetString, &BufLen, L"+BS", 0);\r
62 }\r
63 if ((Atts & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) {\r
64 StrnCatGrow (&RetString, &BufLen, L"+HR", 0);\r
65 }\r
66 if ((Atts & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
67 StrnCatGrow (&RetString, &BufLen, L"+AW", 0);\r
68 }\r
69 if ((Atts & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
70 StrnCatGrow (&RetString, &BufLen, L"+AT", 0);\r
71 }\r
72\r
73 if (RetString == NULL) {\r
74 RetString = StrnCatGrow(&RetString, &BufLen, L"Invalid", 0);\r
75 }\r
76\r
77 if ((RetString != NULL) && (RetString[0] == L'+')) {\r
78 CopyMem(RetString, RetString + 1, StrSize(RetString + 1));\r
79 }\r
80\r
81 return RetString;\r
82}\r
83\r
84/**\r
85 Convert binary to hex format string.\r
86\r
87 @param[in] Buffer The binary data.\r
88 @param[in] BufferSize The size in bytes of the binary data.\r
89 @param[in, out] HexString Hex format string.\r
90 @param[in] HexStringSize The size in bytes of the string.\r
91\r
92 @return The hex format string.\r
93**/\r
94CHAR16*\r
95BinaryToHexString (\r
96 IN VOID *Buffer,\r
97 IN UINTN BufferSize,\r
98 IN OUT CHAR16 *HexString,\r
99 IN UINTN HexStringSize\r
100 )\r
101{\r
102 UINTN Index;\r
103 UINTN StringIndex;\r
104\r
105 ASSERT (Buffer != NULL);\r
106 ASSERT ((BufferSize * 2 + 1) * sizeof (CHAR16) <= HexStringSize);\r
107\r
108 for (Index = 0, StringIndex = 0; Index < BufferSize; Index += 1) {\r
109 StringIndex +=\r
110 UnicodeSPrint (\r
111 &HexString[StringIndex],\r
112 HexStringSize - StringIndex * sizeof (CHAR16),\r
113 L"%02x",\r
114 ((UINT8 *) Buffer)[Index]\r
115 );\r
116 }\r
117 return HexString;\r
118}\r
119\r
120/**\r
121 Load the variable data from file and set to variable data base.\r
122\r
123 @param[in] FileHandle The file to be read.\r
124 @param[in] Name The name of the variables to be loaded.\r
125 @param[in] Guid The guid of the variables to be loaded.\r
126 @param[out] Found TRUE when at least one variable was loaded and set.\r
127\r
128 @retval SHELL_DEVICE_ERROR Cannot access the file.\r
129 @retval SHELL_VOLUME_CORRUPTED The file is in bad format.\r
130 @retval SHELL_OUT_OF_RESOURCES There is not enough memory to perform the operation.\r
131 @retval SHELL_SUCCESS Successfully load and set the variables.\r
132**/\r
133SHELL_STATUS\r
134LoadVariablesFromFile (\r
135 IN SHELL_FILE_HANDLE FileHandle,\r
136 IN CONST CHAR16 *Name,\r
137 IN CONST EFI_GUID *Guid,\r
138 OUT BOOLEAN *Found\r
139 )\r
140{\r
141 EFI_STATUS Status;\r
142 SHELL_STATUS ShellStatus;\r
143 UINT32 NameSize;\r
144 UINT32 DataSize;\r
145 UINTN BufferSize;\r
146 UINTN RemainingSize;\r
147 UINT64 Position;\r
148 UINT64 FileSize;\r
149 LIST_ENTRY List;\r
150 DMP_STORE_VARIABLE *Variable;\r
151 LIST_ENTRY *Link;\r
152 CHAR16 *Attributes;\r
153 UINT8 *Buffer;\r
154 UINT32 Crc32;\r
155\r
156 Status = ShellGetFileSize (FileHandle, &FileSize);\r
157 if (EFI_ERROR (Status)) {\r
158 return SHELL_DEVICE_ERROR;\r
159 }\r
160 \r
161 ShellStatus = SHELL_SUCCESS;\r
162 \r
163 InitializeListHead (&List);\r
164 \r
165 Position = 0;\r
166 while (Position < FileSize) {\r
167 //\r
168 // NameSize\r
169 //\r
170 BufferSize = sizeof (NameSize);\r
171 Status = ShellReadFile (FileHandle, &BufferSize, &NameSize);\r
172 if (EFI_ERROR (Status) || (BufferSize != sizeof (NameSize))) {\r
173 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
174 break;\r
175 }\r
176\r
177 //\r
178 // DataSize\r
179 //\r
180 BufferSize = sizeof (DataSize);\r
181 Status = ShellReadFile (FileHandle, &BufferSize, &DataSize);\r
182 if (EFI_ERROR (Status) || (BufferSize != sizeof (DataSize))) {\r
183 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
184 break;\r
185 }\r
186\r
187 //\r
188 // Name, Guid, Attributes, Data, Crc32\r
189 //\r
190 RemainingSize = NameSize + sizeof (EFI_GUID) + sizeof (UINT32) + DataSize + sizeof (Crc32);\r
191 BufferSize = sizeof (NameSize) + sizeof (DataSize) + RemainingSize;\r
192 Buffer = AllocatePool (BufferSize);\r
193 if (Buffer == NULL) {\r
194 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
195 break;\r
196 }\r
197 BufferSize = RemainingSize;\r
198 Status = ShellReadFile (FileHandle, &BufferSize, (UINT32 *) Buffer + 2);\r
199 if (EFI_ERROR (Status) || (BufferSize != RemainingSize)) {\r
200 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
201 FreePool (Buffer);\r
202 break;\r
203 }\r
204\r
205 //\r
206 // Check Crc32\r
207 //\r
208 * (UINT32 *) Buffer = NameSize;\r
209 * ((UINT32 *) Buffer + 1) = DataSize;\r
210 BufferSize = RemainingSize + sizeof (NameSize) + sizeof (DataSize) - sizeof (Crc32);\r
211 gBS->CalculateCrc32 (\r
212 Buffer,\r
213 BufferSize,\r
214 &Crc32\r
215 );\r
216 if (Crc32 != * (UINT32 *) (Buffer + BufferSize)) {\r
217 FreePool (Buffer);\r
218 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
219 break;\r
220 }\r
221\r
222 Position += BufferSize + sizeof (Crc32);\r
223 \r
224 Variable = AllocateZeroPool (sizeof (*Variable) + NameSize + DataSize);\r
225 if (Variable == NULL) {\r
226 FreePool (Buffer);\r
227 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
228 break;\r
229 }\r
230 Variable->Signature = DMP_STORE_VARIABLE_SIGNATURE;\r
231 Variable->Name = (CHAR16 *) (Variable + 1);\r
232 Variable->DataSize = DataSize;\r
233 Variable->Data = (UINT8 *) Variable->Name + NameSize;\r
234 CopyMem (Variable->Name, Buffer + sizeof (NameSize) + sizeof (DataSize), NameSize);\r
235 CopyMem (&Variable->Guid, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize, sizeof (EFI_GUID));\r
236 CopyMem (&Variable->Attributes, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID), sizeof (UINT32));\r
237 CopyMem (Variable->Data, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID) + sizeof (UINT32), DataSize);\r
238\r
239 InsertTailList (&List, &Variable->Link);\r
240 FreePool (Buffer);\r
241 }\r
242 \r
243 if ((Position != FileSize) || (ShellStatus != SHELL_SUCCESS)) {\r
244 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE), gShellDebug1HiiHandle, L"dmpstore"); \r
245 if (Position != FileSize) {\r
246 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
247 }\r
248 }\r
249 \r
250 for ( Link = GetFirstNode (&List)\r
251 ; !IsNull (&List, Link) && (ShellStatus == SHELL_SUCCESS)\r
252 ; Link = GetNextNode (&List, Link)\r
253 ) {\r
254 Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);\r
255 \r
256 if (((Name == NULL) || gUnicodeCollation->MetaiMatch (gUnicodeCollation, Variable->Name, (CHAR16 *) Name)) &&\r
257 ((Guid == NULL) || CompareGuid (&Variable->Guid, Guid))\r
258 ) {\r
259 Attributes = GetAttrType (Variable->Attributes);\r
260 ShellPrintHiiEx (\r
261 -1, -1, NULL, STRING_TOKEN(STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,\r
262 Attributes, &Variable->Guid, Variable->Name, Variable->DataSize\r
263 );\r
264 SHELL_FREE_NON_NULL(Attributes);\r
265\r
266 *Found = TRUE;\r
267 Status = gRT->SetVariable (\r
268 Variable->Name,\r
269 &Variable->Guid,\r
270 Variable->Attributes,\r
271 Variable->DataSize,\r
272 Variable->Data\r
273 );\r
274 if (EFI_ERROR (Status)) {\r
275 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", Variable->Name, Status); \r
276 }\r
277 }\r
278 }\r
279\r
280 for (Link = GetFirstNode (&List); !IsNull (&List, Link); ) {\r
281 Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);\r
282 Link = RemoveEntryList (&Variable->Link);\r
283 FreePool (Variable);\r
284 }\r
285\r
286 return ShellStatus;\r
287}\r
288\r
289/**\r
290 Append one variable to file.\r
291\r
292 @param[in] FileHandle The file to be appended.\r
293 @param[in] Name The variable name.\r
294 @param[in] Guid The variable GUID.\r
295 @param[in] Attributes The variable attributes.\r
296 @param[in] DataSize The variable data size.\r
297 @param[in] Data The variable data.\r
298\r
299 @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation.\r
300 @retval EFI_SUCCESS The variable is appended to file successfully.\r
301 @retval others Failed to append the variable to file.\r
302**/\r
303EFI_STATUS\r
304AppendSingleVariableToFile (\r
305 IN SHELL_FILE_HANDLE FileHandle,\r
306 IN CONST CHAR16 *Name,\r
307 IN CONST EFI_GUID *Guid,\r
308 IN UINT32 Attributes,\r
309 IN UINT32 DataSize,\r
310 IN CONST UINT8 *Data\r
311 )\r
312{\r
313 UINT32 NameSize;\r
314 UINT8 *Buffer;\r
315 UINT8 *Ptr;\r
316 UINTN BufferSize;\r
317 EFI_STATUS Status;\r
318\r
319 NameSize = (UINT32) StrSize (Name);\r
320 BufferSize = sizeof (NameSize) + sizeof (DataSize)\r
321 + sizeof (*Guid)\r
322 + sizeof (Attributes)\r
323 + NameSize + DataSize\r
324 + sizeof (UINT32);\r
325\r
326 Buffer = AllocatePool (BufferSize);\r
327 if (Buffer == NULL) {\r
328 return EFI_OUT_OF_RESOURCES;\r
329 }\r
330\r
331 Ptr = Buffer;\r
332 //\r
333 // NameSize and DataSize\r
334 //\r
335 * (UINT32 *) Ptr = NameSize;\r
336 Ptr += sizeof (NameSize);\r
337 *(UINT32 *) Ptr = DataSize;\r
338 Ptr += sizeof (DataSize);\r
339\r
340 //\r
341 // Name\r
342 //\r
343 CopyMem (Ptr, Name, NameSize);\r
344 Ptr += NameSize;\r
345\r
346 //\r
347 // Guid\r
348 //\r
349 CopyMem (Ptr, Guid, sizeof (*Guid));\r
350 Ptr += sizeof (*Guid);\r
351\r
352 //\r
353 // Attributes\r
354 //\r
355 * (UINT32 *) Ptr = Attributes;\r
356 Ptr += sizeof (Attributes);\r
357\r
358 //\r
359 // Data\r
360 //\r
361 CopyMem (Ptr, Data, DataSize);\r
362 Ptr += DataSize;\r
363\r
364 //\r
365 // Crc32\r
366 //\r
367 gBS->CalculateCrc32 (Buffer, (UINTN) Ptr - (UINTN) Buffer, (UINT32 *) Ptr);\r
368\r
369 Status = ShellWriteFile (FileHandle, &BufferSize, Buffer);\r
370 FreePool (Buffer);\r
371\r
372 if (!EFI_ERROR (Status) && \r
373 (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize + sizeof (UINT32))\r
374 ) {\r
375 Status = EFI_DEVICE_ERROR;\r
376 }\r
377 \r
378 return Status;\r
379}\r
380\r
381/**\r
382 Recursive function to display or delete variables.\r
383\r
384 This function will call itself to create a stack-based list of allt he variables to process, \r
385 then fromt he last to the first, they will do either printing or deleting.\r
386\r
387 This is necessary since once a delete happens GetNextVariableName() will work.\r
388\r
389 @param[in] Name The variable name of the EFI variable (or NULL).\r
390 @param[in] Guid The GUID of the variable set (or NULL).\r
391 @param[in] Type The operation type.\r
392 @param[in] FileHandle The file to operate on (or NULL).\r
393 @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.\r
394 @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.\r
395 @param[in] FoundOne If a VariableName or Guid was specified and one was printed or\r
396 deleted, then set this to TRUE, otherwise ignored.\r
397 @param[in] StandardFormatOutput TRUE indicates Standard-Format Output.\r
398\r
399 @retval SHELL_SUCCESS The operation was successful.\r
400 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
401 @retval SHELL_ABORTED The abort message was received.\r
402 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
403 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
404**/\r
405SHELL_STATUS\r
406CascadeProcessVariables (\r
407 IN CONST CHAR16 *Name OPTIONAL,\r
408 IN CONST EFI_GUID *Guid OPTIONAL,\r
409 IN DMP_STORE_TYPE Type,\r
410 IN EFI_FILE_PROTOCOL *FileHandle OPTIONAL,\r
411 IN CONST CHAR16 * CONST PrevName,\r
412 IN EFI_GUID FoundVarGuid,\r
413 IN BOOLEAN *FoundOne,\r
414 IN BOOLEAN StandardFormatOutput\r
415 )\r
416{\r
417 EFI_STATUS Status;\r
418 CHAR16 *FoundVarName;\r
419 UINT8 *DataBuffer;\r
420 UINTN DataSize;\r
421 UINT32 Atts;\r
422 SHELL_STATUS ShellStatus;\r
423 UINTN NameSize;\r
424 CHAR16 *AttrString;\r
425 CHAR16 *HexString;\r
426 EFI_STATUS SetStatus;\r
427\r
428 if (ShellGetExecutionBreakFlag()) {\r
429 return (SHELL_ABORTED);\r
430 }\r
431\r
432 NameSize = 0;\r
433 FoundVarName = NULL;\r
434\r
435 if (PrevName!=NULL) {\r
436 StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);\r
437 } else {\r
438 FoundVarName = AllocateZeroPool(sizeof(CHAR16));\r
439 NameSize = sizeof(CHAR16);\r
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
446 if (FoundVarName != NULL) {\r
447 if (PrevName != NULL) {\r
448 StrnCpyS(FoundVarName, NameSize/sizeof(CHAR16), PrevName, NameSize/sizeof(CHAR16) - 1);\r
449 }\r
450\r
451 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
452 } else {\r
453 Status = EFI_OUT_OF_RESOURCES;\r
454 }\r
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
471 ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne, StandardFormatOutput);\r
472\r
473 if (ShellGetExecutionBreakFlag() || (ShellStatus == SHELL_ABORTED)) {\r
474 SHELL_FREE_NON_NULL(FoundVarName);\r
475 return (SHELL_ABORTED);\r
476 }\r
477\r
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
482 if ( ( Name == NULL \r
483 || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) )\r
484 && ( Guid == NULL \r
485 || CompareGuid(&FoundVarGuid, Guid) )\r
486 ) {\r
487 DataSize = 0;\r
488 DataBuffer = NULL;\r
489 //\r
490 // do the print or delete\r
491 //\r
492 *FoundOne = TRUE;\r
493 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
494 if (Status == EFI_BUFFER_TOO_SMALL) {\r
495 SHELL_FREE_NON_NULL (DataBuffer);\r
496 DataBuffer = AllocatePool (DataSize);\r
497 if (DataBuffer == NULL) {\r
498 Status = EFI_OUT_OF_RESOURCES;\r
499 } else {\r
500 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
501 }\r
502 }\r
503 //\r
504 // Last error check then print this variable out.\r
505 //\r
506 if (Type == DmpStoreDisplay) {\r
507 if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
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
523 } else {\r
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
529 }\r
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
548 }\r
549 } else if (Type == DmpStoreDelete) {\r
550 //\r
551 // We only need name to delete it...\r
552 //\r
553 SetStatus = gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL);\r
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
567 }\r
568 SHELL_FREE_NON_NULL(DataBuffer);\r
569 }\r
570\r
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
579 }\r
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
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
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
600ProcessVariables (\r
601 IN CONST CHAR16 *Name OPTIONAL,\r
602 IN CONST EFI_GUID *Guid OPTIONAL,\r
603 IN DMP_STORE_TYPE Type,\r
604 IN SHELL_FILE_HANDLE FileHandle OPTIONAL,\r
605 IN BOOLEAN StandardFormatOutput\r
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
616 if (StandardFormatOutput) {\r
617 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_SFO_HEADER), gShellDebug1HiiHandle, L"dmpstore");\r
618 }\r
619\r
620 if (Type == DmpStoreLoad) {\r
621 ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found);\r
622 } else {\r
623 ShellStatus = CascadeProcessVariables (Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found, StandardFormatOutput);\r
624 }\r
625\r
626 if (!Found) {\r
627 if (ShellStatus == SHELL_OUT_OF_RESOURCES) {\r
628 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"dmpstore"); \r
629 return (ShellStatus);\r
630 } else if (Name != NULL && Guid == NULL) {\r
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
636 } else if (Name != NULL && Guid != NULL) {\r
637 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, L"dmpstore", Guid, Name); \r
638 } else if (Name == NULL && Guid == NULL) {\r
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
644 } else if (Name == NULL && Guid != NULL) {\r
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
650 } \r
651 return (SHELL_NOT_FOUND);\r
652 }\r
653 return (ShellStatus);\r
654}\r
655\r
656STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
657 {L"-d", TypeFlag},\r
658 {L"-l", TypeValue},\r
659 {L"-s", TypeValue},\r
660 {L"-all", TypeFlag},\r
661 {L"-guid", TypeValue},\r
662 {L"-sfo", TypeFlag},\r
663 {NULL, TypeMax}\r
664 };\r
665\r
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
672SHELL_STATUS\r
673EFIAPI\r
674ShellCommandRunDmpStore (\r
675 IN EFI_HANDLE ImageHandle,\r
676 IN EFI_SYSTEM_TABLE *SystemTable\r
677 )\r
678{\r
679 EFI_STATUS Status;\r
680 RETURN_STATUS RStatus;\r
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
692 BOOLEAN StandardFormatOutput;\r
693\r
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
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
704 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"dmpstore", ProblemParam); \r
705 FreePool(ProblemParam);\r
706 ShellStatus = SHELL_INVALID_PARAMETER;\r
707 } else {\r
708 ASSERT(FALSE);\r
709 }\r
710 } else {\r
711 if (ShellCommandLineGetCount(Package) > 2) {\r
712 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"dmpstore"); \r
713 ShellStatus = SHELL_INVALID_PARAMETER;\r
714 } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {\r
715 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-all", L"-guid"); \r
716 ShellStatus = SHELL_INVALID_PARAMETER;\r
717 } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {\r
718 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l", L"-s"); \r
719 ShellStatus = SHELL_INVALID_PARAMETER;\r
720 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {\r
721 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"dmpstore", L"-l or -s", L"-d"); \r
722 ShellStatus = SHELL_INVALID_PARAMETER;\r
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
726 } else {\r
727 //\r
728 // Determine the GUID to search for based on -all and -guid parameters\r
729 //\r
730 if (!ShellCommandLineGetFlag(Package, L"-all")) {\r
731 GuidStr = ShellCommandLineGetValue(Package, L"-guid");\r
732 if (GuidStr != NULL) {\r
733 RStatus = StrToGuid (GuidStr, &GuidData);\r
734 if (RETURN_ERROR (RStatus) || (GuidStr[GUID_STRING_LENGTH] != L'\0')) {\r
735 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmpstore", GuidStr); \r
736 ShellStatus = SHELL_INVALID_PARAMETER;\r
737 }\r
738 Guid = &GuidData;\r
739 } else {\r
740 Guid = &gEfiGlobalVariableGuid;\r
741 }\r
742 } else {\r
743 Guid = NULL;\r
744 }\r
745\r
746 //\r
747 // Get the Name of the variable to find\r
748 //\r
749 Name = ShellCommandLineGetRawValue(Package, 1);\r
750\r
751 if (ShellStatus == SHELL_SUCCESS) {\r
752 if (ShellCommandLineGetFlag(Package, L"-s")) {\r
753 Type = DmpStoreSave;\r
754 File = ShellCommandLineGetValue(Package, L"-s");\r
755 if (File == NULL) {\r
756 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-s"); \r
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
766 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
767 Status = EFI_DEVICE_ERROR;\r
768 } else {\r
769 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
770 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
771 Status = EFI_INVALID_PARAMETER;\r
772 } else {\r
773 Status = ShellDeleteFile (&FileHandle);\r
774 if (EFI_ERROR (Status)) {\r
775 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
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
789 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
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
795 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
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
807 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"dmpstore", L"-l"); \r
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
812 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
813 ShellStatus = SHELL_INVALID_PARAMETER;\r
814 } else {\r
815 FileInfo = ShellGetFileInfo (FileHandle);\r
816 if (FileInfo == NULL) {\r
817 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"dmpstore", File); \r
818 ShellStatus = SHELL_DEVICE_ERROR;\r
819 } else {\r
820 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
821 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, L"dmpstore", File); \r
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
831\r
832 if (ShellCommandLineGetFlag (Package,L"-sfo")) {\r
833 StandardFormatOutput = TRUE;\r
834 }\r
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
843 ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle, StandardFormatOutput);\r
844 if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {\r
845 ShellCloseFile (&FileHandle);\r
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