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