]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
Update prints of variable attributes from 'RS' to 'RT' for 'Dmpstore' command.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / DmpStore.c
... / ...
CommitLineData
1/** @file\r
2 Main file for DmpStore shell Debug1 function.\r
3\r
4 Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellDebug1CommandsLib.h"\r
16\r
17typedef enum {\r
18 DmpStoreDisplay,\r
19 DmpStoreDelete,\r
20 DmpStoreSave,\r
21 DmpStoreLoad\r
22} DMP_STORE_TYPE;\r
23\r
24typedef struct {\r
25 UINT32 Signature;\r
26 CHAR16 *Name;\r
27 EFI_GUID Guid;\r
28 UINT32 Attributes;\r
29 UINT32 DataSize;\r
30 UINT8 *Data;\r
31 LIST_ENTRY Link;\r
32} DMP_STORE_VARIABLE;\r
33\r
34#define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's')\r
35\r
36/**\r
37 Base on the input attribute value to return the attribute string.\r
38\r
39 @param[in] Atts The input attribute value\r
40\r
41 @retval The attribute string info.\r
42**/\r
43CHAR16 *\r
44EFIAPI\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 Load the variable data from file and set to variable data base.\r
86\r
87 @param[in] FileHandle The file to be read.\r
88 @param[in] Name The name of the variables to be loaded.\r
89 @param[in] Guid The guid of the variables to be loaded.\r
90 @param[out] Found TRUE when at least one variable was loaded and set.\r
91\r
92 @retval SHELL_DEVICE_ERROR Cannot access the file.\r
93 @retval SHELL_VOLUME_CORRUPTED The file is in bad format.\r
94 @retval SHELL_OUT_OF_RESOURCES There is not enough memory to perform the operation.\r
95 @retval SHELL_SUCCESS Successfully load and set the variables.\r
96**/\r
97SHELL_STATUS\r
98LoadVariablesFromFile (\r
99 IN SHELL_FILE_HANDLE FileHandle,\r
100 IN CONST CHAR16 *Name,\r
101 IN CONST EFI_GUID *Guid,\r
102 OUT BOOLEAN *Found\r
103 )\r
104{\r
105 EFI_STATUS Status;\r
106 SHELL_STATUS ShellStatus;\r
107 UINT32 NameSize;\r
108 UINT32 DataSize;\r
109 UINTN BufferSize;\r
110 UINTN RemainingSize;\r
111 UINT64 Position;\r
112 UINT64 FileSize;\r
113 LIST_ENTRY List;\r
114 DMP_STORE_VARIABLE *Variable;\r
115 LIST_ENTRY *Link;\r
116 CHAR16 *Attributes;\r
117 UINT8 *Buffer;\r
118 UINT32 Crc32;\r
119\r
120 Status = ShellGetFileSize (FileHandle, &FileSize);\r
121 if (EFI_ERROR (Status)) {\r
122 return SHELL_DEVICE_ERROR;\r
123 }\r
124 \r
125 ShellStatus = SHELL_SUCCESS;\r
126 \r
127 InitializeListHead (&List);\r
128 \r
129 Position = 0;\r
130 while (Position < FileSize) {\r
131 //\r
132 // NameSize\r
133 //\r
134 BufferSize = sizeof (NameSize);\r
135 Status = ShellReadFile (FileHandle, &BufferSize, &NameSize);\r
136 if (EFI_ERROR (Status) || (BufferSize != sizeof (NameSize))) {\r
137 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
138 break;\r
139 }\r
140\r
141 //\r
142 // DataSize\r
143 //\r
144 BufferSize = sizeof (DataSize);\r
145 Status = ShellReadFile (FileHandle, &BufferSize, &DataSize);\r
146 if (EFI_ERROR (Status) || (BufferSize != sizeof (DataSize))) {\r
147 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
148 break;\r
149 }\r
150\r
151 //\r
152 // Name, Guid, Attributes, Data, Crc32\r
153 //\r
154 RemainingSize = NameSize + sizeof (EFI_GUID) + sizeof (UINT32) + DataSize + sizeof (Crc32);\r
155 BufferSize = sizeof (NameSize) + sizeof (DataSize) + RemainingSize;\r
156 Buffer = AllocatePool (BufferSize);\r
157 if (Buffer == NULL) {\r
158 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
159 break;\r
160 }\r
161 BufferSize = RemainingSize;\r
162 Status = ShellReadFile (FileHandle, &BufferSize, (UINT32 *) Buffer + 2);\r
163 if (EFI_ERROR (Status) || (BufferSize != RemainingSize)) {\r
164 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
165 FreePool (Buffer);\r
166 break;\r
167 }\r
168\r
169 //\r
170 // Check Crc32\r
171 //\r
172 * (UINT32 *) Buffer = NameSize;\r
173 * ((UINT32 *) Buffer + 1) = DataSize;\r
174 BufferSize = RemainingSize + sizeof (NameSize) + sizeof (DataSize) - sizeof (Crc32);\r
175 gBS->CalculateCrc32 (\r
176 Buffer,\r
177 BufferSize,\r
178 &Crc32\r
179 );\r
180 if (Crc32 != * (UINT32 *) (Buffer + BufferSize)) {\r
181 FreePool (Buffer);\r
182 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
183 break;\r
184 }\r
185\r
186 Position += BufferSize + sizeof (Crc32);\r
187 \r
188 Variable = AllocateZeroPool (sizeof (*Variable) + NameSize + DataSize);\r
189 if (Variable == NULL) {\r
190 FreePool (Buffer);\r
191 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
192 break;\r
193 }\r
194 Variable->Signature = DMP_STORE_VARIABLE_SIGNATURE;\r
195 Variable->Name = (CHAR16 *) (Variable + 1);\r
196 Variable->DataSize = DataSize;\r
197 Variable->Data = (UINT8 *) Variable->Name + NameSize;\r
198 CopyMem (Variable->Name, Buffer + sizeof (NameSize) + sizeof (DataSize), NameSize);\r
199 CopyMem (&Variable->Guid, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize, sizeof (EFI_GUID));\r
200 CopyMem (&Variable->Attributes, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID), sizeof (UINT32));\r
201 CopyMem (Variable->Data, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID) + sizeof (UINT32), DataSize);\r
202\r
203 InsertTailList (&List, &Variable->Link);\r
204 FreePool (Buffer);\r
205 }\r
206 \r
207 if ((Position != FileSize) || (ShellStatus != SHELL_SUCCESS)) {\r
208 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE), gShellDebug1HiiHandle);\r
209 if (Position != FileSize) {\r
210 ShellStatus = SHELL_VOLUME_CORRUPTED;\r
211 }\r
212 }\r
213 \r
214 for ( Link = GetFirstNode (&List)\r
215 ; !IsNull (&List, Link) && (ShellStatus == SHELL_SUCCESS)\r
216 ; Link = GetNextNode (&List, Link)\r
217 ) {\r
218 Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);\r
219 \r
220 if (((Name == NULL) || gUnicodeCollation->MetaiMatch (gUnicodeCollation, Variable->Name, (CHAR16 *) Name)) &&\r
221 ((Guid == NULL) || CompareGuid (&Variable->Guid, Guid))\r
222 ) {\r
223 Attributes = GetAttrType (Variable->Attributes);\r
224 ShellPrintHiiEx (\r
225 -1, -1, NULL, STRING_TOKEN(STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,\r
226 Attributes, &Variable->Guid, Variable->Name, Variable->DataSize\r
227 );\r
228 SHELL_FREE_NON_NULL(Attributes);\r
229\r
230 *Found = TRUE;\r
231 Status = gRT->SetVariable (\r
232 Variable->Name,\r
233 &Variable->Guid,\r
234 Variable->Attributes,\r
235 Variable->DataSize,\r
236 Variable->Data\r
237 );\r
238 if (EFI_ERROR (Status)) {\r
239 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL), gShellDebug1HiiHandle, Variable->Name, Status);\r
240 }\r
241 }\r
242 }\r
243\r
244 for (Link = GetFirstNode (&List); !IsNull (&List, Link); ) {\r
245 Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);\r
246 Link = RemoveEntryList (&Variable->Link);\r
247 FreePool (Variable);\r
248 }\r
249\r
250 return ShellStatus;\r
251}\r
252\r
253/**\r
254 Append one variable to file.\r
255\r
256 @param[in] FileHandle The file to be appended.\r
257 @param[in] Name The variable name.\r
258 @param[in] Guid The variable GUID.\r
259 @param[in] Attributes The variable attributes.\r
260 @param[in] DataSize The variable data size.\r
261 @param[in] Data The variable data.\r
262\r
263 @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation.\r
264 @retval EFI_SUCCESS The variable is appended to file successfully.\r
265 @retval others Failed to append the variable to file.\r
266**/\r
267EFI_STATUS\r
268AppendSingleVariableToFile (\r
269 IN SHELL_FILE_HANDLE FileHandle,\r
270 IN CONST CHAR16 *Name,\r
271 IN CONST EFI_GUID *Guid,\r
272 IN UINT32 Attributes,\r
273 IN UINT32 DataSize,\r
274 IN CONST UINT8 *Data\r
275 )\r
276{\r
277 UINT32 NameSize;\r
278 UINT8 *Buffer;\r
279 UINT8 *Ptr;\r
280 UINTN BufferSize;\r
281 EFI_STATUS Status;\r
282\r
283 NameSize = (UINT32) StrSize (Name);\r
284 BufferSize = sizeof (NameSize) + sizeof (DataSize)\r
285 + sizeof (*Guid)\r
286 + sizeof (Attributes)\r
287 + NameSize + DataSize\r
288 + sizeof (UINT32);\r
289\r
290 Buffer = AllocatePool (BufferSize);\r
291 if (Buffer == NULL) {\r
292 return EFI_OUT_OF_RESOURCES;\r
293 }\r
294\r
295 Ptr = Buffer;\r
296 //\r
297 // NameSize and DataSize\r
298 //\r
299 * (UINT32 *) Ptr = NameSize;\r
300 Ptr += sizeof (NameSize);\r
301 *(UINT32 *) Ptr = DataSize;\r
302 Ptr += sizeof (DataSize);\r
303\r
304 //\r
305 // Name\r
306 //\r
307 CopyMem (Ptr, Name, NameSize);\r
308 Ptr += NameSize;\r
309\r
310 //\r
311 // Guid\r
312 //\r
313 CopyMem (Ptr, Guid, sizeof (*Guid));\r
314 Ptr += sizeof (*Guid);\r
315\r
316 //\r
317 // Attributes\r
318 //\r
319 * (UINT32 *) Ptr = Attributes;\r
320 Ptr += sizeof (Attributes);\r
321\r
322 //\r
323 // Data\r
324 //\r
325 CopyMem (Ptr, Data, DataSize);\r
326 Ptr += DataSize;\r
327\r
328 //\r
329 // Crc32\r
330 //\r
331 gBS->CalculateCrc32 (Buffer, (UINTN) (Ptr - Buffer), (UINT32 *) Ptr);\r
332\r
333 Status = ShellWriteFile (FileHandle, &BufferSize, Buffer);\r
334 FreePool (Buffer);\r
335\r
336 if (!EFI_ERROR (Status) && \r
337 (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize)\r
338 ) {\r
339 Status = EFI_DEVICE_ERROR;\r
340 }\r
341 \r
342 return Status;\r
343}\r
344\r
345/**\r
346 Recursive function to display or delete variables.\r
347\r
348 This function will call itself to create a stack-based list of allt he variables to process, \r
349 then fromt he last to the first, they will do either printing or deleting.\r
350\r
351 This is necessary since once a delete happens GetNextVariableName() will work.\r
352\r
353 @param[in] Name The variable name of the EFI variable (or NULL).\r
354 @param[in] Guid The GUID of the variable set (or NULL).\r
355 @param[in] Type The operation type.\r
356 @param[in] FileHandle The file to operate on (or NULL).\r
357 @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.\r
358 @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.\r
359 @param[in] FoundOne If a VariableName or Guid was specified and one was printed or\r
360 deleted, then set this to TRUE, otherwise ignored.\r
361\r
362 @retval SHELL_SUCCESS The operation was successful.\r
363 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
364 @retval SHELL_ABORTED The abort message was received.\r
365 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
366 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
367**/\r
368SHELL_STATUS\r
369EFIAPI\r
370CascadeProcessVariables (\r
371 IN CONST CHAR16 *Name OPTIONAL,\r
372 IN CONST EFI_GUID *Guid OPTIONAL,\r
373 IN DMP_STORE_TYPE Type,\r
374 IN EFI_FILE_PROTOCOL *FileHandle OPTIONAL,\r
375 IN CONST CHAR16 * CONST PrevName,\r
376 IN EFI_GUID FoundVarGuid,\r
377 IN BOOLEAN *FoundOne\r
378 )\r
379{\r
380 EFI_STATUS Status;\r
381 CHAR16 *FoundVarName;\r
382 UINT8 *DataBuffer;\r
383 UINTN DataSize;\r
384 UINT32 Atts;\r
385 SHELL_STATUS ShellStatus;\r
386 UINTN NameSize;\r
387 CHAR16 *RetString;\r
388\r
389 if (ShellGetExecutionBreakFlag()) {\r
390 return (SHELL_ABORTED);\r
391 }\r
392\r
393 NameSize = 0;\r
394 FoundVarName = NULL;\r
395\r
396 if (PrevName!=NULL) {\r
397 StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);\r
398 } else {\r
399 FoundVarName = AllocateZeroPool(sizeof(CHAR16));\r
400 }\r
401\r
402 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
403 if (Status == EFI_BUFFER_TOO_SMALL) {\r
404 SHELL_FREE_NON_NULL(FoundVarName);\r
405 FoundVarName = AllocateZeroPool (NameSize);\r
406 if (FoundVarName != NULL) {\r
407 if (PrevName != NULL) {\r
408 StrCpy(FoundVarName, PrevName);\r
409 }\r
410\r
411 Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);\r
412 } else {\r
413 Status = EFI_OUT_OF_RESOURCES;\r
414 }\r
415 }\r
416\r
417 //\r
418 // No more is fine.\r
419 //\r
420 if (Status == EFI_NOT_FOUND) {\r
421 SHELL_FREE_NON_NULL(FoundVarName);\r
422 return (SHELL_SUCCESS);\r
423 } else if (EFI_ERROR(Status)) {\r
424 SHELL_FREE_NON_NULL(FoundVarName);\r
425 return (SHELL_DEVICE_ERROR);\r
426 }\r
427\r
428 //\r
429 // Recurse to the next iteration. We know "our" variable's name.\r
430 //\r
431 ShellStatus = CascadeProcessVariables(Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne);\r
432\r
433 //\r
434 // No matter what happened we process our own variable\r
435 // Only continue if Guid and VariableName are each either NULL or a match\r
436 //\r
437 if ( ( Name == NULL \r
438 || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) )\r
439 && ( Guid == NULL \r
440 || CompareGuid(&FoundVarGuid, Guid) )\r
441 ) {\r
442 DataSize = 0;\r
443 DataBuffer = NULL;\r
444 //\r
445 // do the print or delete\r
446 //\r
447 *FoundOne = TRUE;\r
448 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
449 if (Status == EFI_BUFFER_TOO_SMALL) {\r
450 SHELL_FREE_NON_NULL (DataBuffer);\r
451 DataBuffer = AllocatePool (DataSize);\r
452 if (DataBuffer == NULL) {\r
453 Status = EFI_OUT_OF_RESOURCES;\r
454 } else {\r
455 Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);\r
456 }\r
457 }\r
458 if ((Type == DmpStoreDisplay) || (Type == DmpStoreSave)) {\r
459 //\r
460 // Last error check then print this variable out.\r
461 //\r
462 if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {\r
463 RetString = GetAttrType(Atts);\r
464 ShellPrintHiiEx(\r
465 -1,\r
466 -1,\r
467 NULL,\r
468 STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),\r
469 gShellDebug1HiiHandle,\r
470 RetString,\r
471 &FoundVarGuid,\r
472 FoundVarName,\r
473 DataSize);\r
474 if (Type == DmpStoreDisplay) {\r
475 DumpHex(2, 0, DataSize, DataBuffer);\r
476 } else {\r
477 Status = AppendSingleVariableToFile (\r
478 FileHandle,\r
479 FoundVarName,\r
480 &FoundVarGuid,\r
481 Atts,\r
482 (UINT32) DataSize,\r
483 DataBuffer\r
484 );\r
485 }\r
486 SHELL_FREE_NON_NULL(RetString);\r
487 }\r
488 } else if (Type == DmpStoreDelete) {\r
489 //\r
490 // We only need name to delete it...\r
491 //\r
492 ShellPrintHiiEx (\r
493 -1,\r
494 -1,\r
495 NULL,\r
496 STRING_TOKEN(STR_DMPSTORE_DELETE_LINE),\r
497 gShellDebug1HiiHandle,\r
498 &FoundVarGuid,\r
499 FoundVarName,\r
500 gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL)\r
501 );\r
502 }\r
503 SHELL_FREE_NON_NULL(DataBuffer);\r
504 }\r
505\r
506 SHELL_FREE_NON_NULL(FoundVarName);\r
507\r
508 if (Status == EFI_DEVICE_ERROR) {\r
509 ShellStatus = SHELL_DEVICE_ERROR;\r
510 } else if (Status == EFI_SECURITY_VIOLATION) {\r
511 ShellStatus = SHELL_SECURITY_VIOLATION;\r
512 } else if (EFI_ERROR(Status)) {\r
513 ShellStatus = SHELL_NOT_READY;\r
514 }\r
515\r
516 return (ShellStatus);\r
517}\r
518\r
519/**\r
520 Function to display or delete variables. This will set up and call into the recursive function.\r
521\r
522 @param[in] Name The variable name of the EFI variable (or NULL).\r
523 @param[in] Guid The GUID of the variable set (or NULL).\r
524 @param[in] Type The operation type.\r
525 @param[in] FileHandle The file to save or load variables.\r
526\r
527 @retval SHELL_SUCCESS The operation was successful.\r
528 @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.\r
529 @retval SHELL_ABORTED The abort message was received.\r
530 @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.\r
531 @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.\r
532**/\r
533SHELL_STATUS\r
534EFIAPI\r
535ProcessVariables (\r
536 IN CONST CHAR16 *Name OPTIONAL,\r
537 IN CONST EFI_GUID *Guid OPTIONAL,\r
538 IN DMP_STORE_TYPE Type,\r
539 IN SHELL_FILE_HANDLE FileHandle OPTIONAL\r
540 )\r
541{\r
542 SHELL_STATUS ShellStatus;\r
543 BOOLEAN Found;\r
544 EFI_GUID FoundVarGuid;\r
545\r
546 Found = FALSE;\r
547 ShellStatus = SHELL_SUCCESS;\r
548 ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));\r
549\r
550 if (Type == DmpStoreLoad) {\r
551 ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found);\r
552 } else {\r
553 ShellStatus = CascadeProcessVariables(Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found);\r
554 }\r
555\r
556 if (!Found) {\r
557 if (ShellStatus == SHELL_OUT_OF_RESOURCES) {\r
558 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);\r
559 return (ShellStatus);\r
560 } else if (Name != NULL && Guid == NULL) {\r
561 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, Name);\r
562 } else if (Name != NULL && Guid != NULL) {\r
563 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, Guid, Name);\r
564 } else if (Name == NULL && Guid == NULL) {\r
565 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND), gShellDebug1HiiHandle);\r
566 } else if (Name == NULL && Guid != NULL) {\r
567 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G), gShellDebug1HiiHandle, Guid);\r
568 } \r
569 return (SHELL_NOT_FOUND);\r
570 }\r
571 return (ShellStatus);\r
572}\r
573\r
574STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
575 {L"-d", TypeFlag},\r
576 {L"-l", TypeValue},\r
577 {L"-s", TypeValue},\r
578 {L"-all", TypeFlag},\r
579 {L"-guid", TypeValue},\r
580 {NULL, TypeMax}\r
581 };\r
582\r
583/**\r
584 Function for 'dmpstore' command.\r
585\r
586 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
587 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
588**/\r
589SHELL_STATUS\r
590EFIAPI\r
591ShellCommandRunDmpStore (\r
592 IN EFI_HANDLE ImageHandle,\r
593 IN EFI_SYSTEM_TABLE *SystemTable\r
594 )\r
595{\r
596 EFI_STATUS Status;\r
597 LIST_ENTRY *Package;\r
598 CHAR16 *ProblemParam;\r
599 SHELL_STATUS ShellStatus;\r
600 CONST CHAR16 *GuidStr;\r
601 CONST CHAR16 *File;\r
602 EFI_GUID *Guid;\r
603 EFI_GUID GuidData;\r
604 CONST CHAR16 *Name;\r
605 DMP_STORE_TYPE Type;\r
606 SHELL_FILE_HANDLE FileHandle;\r
607 EFI_FILE_INFO *FileInfo;\r
608\r
609 ShellStatus = SHELL_SUCCESS;\r
610 Package = NULL;\r
611 FileHandle = NULL;\r
612 File = NULL;\r
613 Type = DmpStoreDisplay;\r
614\r
615 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
616 if (EFI_ERROR(Status)) {\r
617 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
618 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);\r
619 FreePool(ProblemParam);\r
620 ShellStatus = SHELL_INVALID_PARAMETER;\r
621 } else {\r
622 ASSERT(FALSE);\r
623 }\r
624 } else {\r
625 if (ShellCommandLineGetCount(Package) > 2) {\r
626 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);\r
627 ShellStatus = SHELL_INVALID_PARAMETER;\r
628 } else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {\r
629 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-all", L"-guid");\r
630 ShellStatus = SHELL_INVALID_PARAMETER;\r
631 } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {\r
632 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-l", L"-s");\r
633 ShellStatus = SHELL_INVALID_PARAMETER;\r
634 } else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {\r
635 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-l or -s", L"-d");\r
636 ShellStatus = SHELL_INVALID_PARAMETER;\r
637 } else {\r
638 if (!ShellCommandLineGetFlag(Package, L"-all")) {\r
639 GuidStr = ShellCommandLineGetValue(Package, L"-guid");\r
640 if (GuidStr != NULL) {\r
641 Status = ConvertStringToGuid(GuidStr, &GuidData);\r
642 if (EFI_ERROR(Status)) {\r
643 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, GuidStr);\r
644 ShellStatus = SHELL_INVALID_PARAMETER;\r
645 }\r
646 Guid = &GuidData;\r
647 } else {\r
648 Guid = &gEfiGlobalVariableGuid;\r
649 }\r
650 Name = ShellCommandLineGetRawValue(Package, 1);\r
651 } else {\r
652 Name = NULL;\r
653 Guid = NULL;\r
654 }\r
655 if (ShellStatus == SHELL_SUCCESS) {\r
656 if (ShellCommandLineGetFlag(Package, L"-s")) {\r
657 Type = DmpStoreSave;\r
658 File = ShellCommandLineGetValue(Package, L"-s");\r
659 if (File == NULL) {\r
660 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-s");\r
661 ShellStatus = SHELL_INVALID_PARAMETER;\r
662 } else {\r
663 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
664 if (!EFI_ERROR (Status)) {\r
665 //\r
666 // Delete existing file, but do not delete existing directory\r
667 //\r
668 FileInfo = ShellGetFileInfo (FileHandle);\r
669 if (FileInfo == NULL) {\r
670 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
671 Status = EFI_DEVICE_ERROR;\r
672 } else {\r
673 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
674 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, File);\r
675 Status = EFI_INVALID_PARAMETER;\r
676 } else {\r
677 Status = ShellDeleteFile (&FileHandle);\r
678 if (EFI_ERROR (Status)) {\r
679 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, File);\r
680 }\r
681 }\r
682 FreePool (FileInfo);\r
683 }\r
684 } else if (Status == EFI_NOT_FOUND) {\r
685 //\r
686 // Good when file doesn't exist\r
687 //\r
688 Status = EFI_SUCCESS;\r
689 } else {\r
690 //\r
691 // Otherwise it's bad.\r
692 //\r
693 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
694 }\r
695\r
696 if (!EFI_ERROR (Status)) {\r
697 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);\r
698 if (EFI_ERROR (Status)) {\r
699 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
700 }\r
701 }\r
702\r
703 if (EFI_ERROR (Status)) {\r
704 ShellStatus = SHELL_INVALID_PARAMETER;\r
705 }\r
706 }\r
707 } else if (ShellCommandLineGetFlag(Package, L"-l")) {\r
708 Type = DmpStoreLoad;\r
709 File = ShellCommandLineGetValue(Package, L"-l");\r
710 if (File == NULL) {\r
711 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-l");\r
712 ShellStatus = SHELL_INVALID_PARAMETER;\r
713 } else {\r
714 Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_READ, 0);\r
715 if (EFI_ERROR (Status)) {\r
716 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
717 ShellStatus = SHELL_INVALID_PARAMETER;\r
718 } else {\r
719 FileInfo = ShellGetFileInfo (FileHandle);\r
720 if (FileInfo == NULL) {\r
721 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);\r
722 ShellStatus = SHELL_DEVICE_ERROR;\r
723 } else {\r
724 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
725 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, File);\r
726 ShellStatus = SHELL_INVALID_PARAMETER;\r
727 }\r
728 FreePool (FileInfo);\r
729 }\r
730 }\r
731 }\r
732 } else if (ShellCommandLineGetFlag(Package, L"-d")) {\r
733 Type = DmpStoreDelete;\r
734 }\r
735 }\r
736\r
737 if (ShellStatus == SHELL_SUCCESS) {\r
738 if (Type == DmpStoreSave) {\r
739 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_SAVE), gShellDebug1HiiHandle, File);\r
740 } else if (Type == DmpStoreLoad) {\r
741 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD), gShellDebug1HiiHandle, File);\r
742 }\r
743 ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle);\r
744 if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {\r
745 ShellCloseFile (&FileHandle);\r
746 }\r
747 }\r
748 }\r
749 }\r
750\r
751 if (Package != NULL) {\r
752 ShellCommandLineFreeVarList (Package);\r
753 }\r
754 return ShellStatus;\r
755}\r
756\r