]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
ShellPkg/AcpiView: Move table count reset
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / AcpiView.c
CommitLineData
a6eaba4d 1/** @file\r
ee4dc24f 2\r
8af507c1 3 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.\r
56ba3746 4 SPDX-License-Identifier: BSD-2-Clause-Patent\r
faef5a36
KK
5\r
6 @par Glossary:\r
7 - Sbbr or SBBR - Server Base Boot Requirements\r
8\r
9 @par Reference(s):\r
10 - Arm Server Base Boot Requirements 1.2, September 2019\r
ee4dc24f
RN
11**/\r
12\r
13#include <Library/PrintLib.h>\r
14#include <Library/UefiLib.h>\r
15#include <Library/ShellLib.h>\r
16#include <Library/UefiBootServicesTableLib.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/DebugLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include "AcpiParser.h"\r
21#include "AcpiTableParser.h"\r
22#include "AcpiView.h"\r
e18ac66d 23#include "AcpiViewConfig.h"\r
ee4dc24f
RN
24#include "UefiShellAcpiViewCommandLib.h"\r
25\r
faef5a36
KK
26#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
27#include "Arm/SbbrValidator.h"\r
28#endif\r
29\r
ee4dc24f
RN
30EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;\r
31\r
ee4dc24f
RN
32STATIC UINT32 mTableCount;\r
33STATIC UINT32 mBinTableCount;\r
ee4dc24f 34\r
a6eaba4d
DB
35/**\r
36 An array of acpiview command line parameters.\r
37**/\r
ee4dc24f 38STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
f73843d5 39 {L"-q", TypeFlag},\r
ee4dc24f 40 {L"-d", TypeFlag},\r
4286eb22 41 {L"-h", TypeFlag},\r
ee4dc24f
RN
42 {L"-l", TypeFlag},\r
43 {L"-s", TypeValue},\r
8af507c1 44 {L"-r", TypeValue},\r
ee4dc24f
RN
45 {NULL, TypeMax}\r
46};\r
47\r
a6eaba4d
DB
48/**\r
49 This function dumps the ACPI table to a file.\r
50\r
ee4dc24f
RN
51 @param [in] Ptr Pointer to the ACPI table data.\r
52 @param [in] Length The length of the ACPI table.\r
53\r
54 @retval TRUE Success.\r
55 @retval FALSE Failure.\r
a6eaba4d 56**/\r
ee4dc24f
RN
57STATIC\r
58BOOLEAN\r
59DumpAcpiTableToFile (\r
60 IN CONST UINT8* Ptr,\r
61 IN CONST UINTN Length\r
62 )\r
63{\r
e18ac66d
TP
64 EFI_STATUS Status;\r
65 CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];\r
66 SHELL_FILE_HANDLE DumpFileHandle;\r
67 UINTN TransferBytes;\r
68 SELECTED_ACPI_TABLE *SelectedTable;\r
f75c7478
DB
69\r
70 DumpFileHandle = NULL;\r
71 TransferBytes = Length;\r
e18ac66d 72 GetSelectedAcpiTable (&SelectedTable);\r
ee4dc24f
RN
73\r
74 UnicodeSPrint (\r
75 FileNameBuffer,\r
76 sizeof (FileNameBuffer),\r
77 L".\\%s%04d.bin",\r
e18ac66d 78 SelectedTable->Name,\r
ee4dc24f
RN
79 mBinTableCount++\r
80 );\r
81\r
82 Status = ShellOpenFileByName (\r
83 FileNameBuffer,\r
84 &DumpFileHandle,\r
85 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,\r
86 0\r
87 );\r
88 if (EFI_ERROR (Status)) {\r
89 ShellPrintHiiEx (\r
90 -1,\r
91 -1,\r
92 NULL,\r
93 STRING_TOKEN (STR_GEN_READONLY_MEDIA),\r
94 gShellAcpiViewHiiHandle,\r
95 L"acpiview"\r
96 );\r
97 return FALSE;\r
98 }\r
99\r
100 Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer);\r
101\r
102 Status = ShellWriteFile (\r
103 DumpFileHandle,\r
104 &TransferBytes,\r
105 (VOID*)Ptr\r
106 );\r
107 if (EFI_ERROR (Status)) {\r
108 Print (L"ERROR: Failed to dump table to binary file.\n");\r
109 TransferBytes = 0;\r
110 } else {\r
111 Print (L"DONE.\n");\r
112 }\r
113\r
114 ShellCloseFile (&DumpFileHandle);\r
115 return (Length == TransferBytes);\r
116}\r
117\r
a6eaba4d
DB
118/**\r
119 This function processes the table reporting options for the ACPI table.\r
ee4dc24f
RN
120\r
121 @param [in] Signature The ACPI table Signature.\r
122 @param [in] TablePtr Pointer to the ACPI table data.\r
123 @param [in] Length The length fo the ACPI table.\r
124\r
125 @retval Returns TRUE if the ACPI table should be traced.\r
a6eaba4d 126**/\r
ee4dc24f
RN
127BOOLEAN\r
128ProcessTableReportOptions (\r
129 IN CONST UINT32 Signature,\r
130 IN CONST UINT8* TablePtr,\r
131 IN CONST UINT32 Length\r
132 )\r
133{\r
e18ac66d
TP
134 UINTN OriginalAttribute;\r
135 UINT8 *SignaturePtr;\r
136 BOOLEAN Log;\r
137 BOOLEAN HighLight;\r
138 SELECTED_ACPI_TABLE *SelectedTable;\r
f75c7478 139\r
0154e02d
SZ
140 //\r
141 // set local variables to suppress incorrect compiler/analyzer warnings\r
142 //\r
143 OriginalAttribute = 0;\r
f75c7478
DB
144 SignaturePtr = (UINT8*)(UINTN)&Signature;\r
145 Log = FALSE;\r
146 HighLight = GetColourHighlighting ();\r
e18ac66d 147 GetSelectedAcpiTable (&SelectedTable);\r
f75c7478 148\r
ee4dc24f 149 switch (GetReportOption ()) {\r
f75c7478 150 case ReportAll:\r
ee4dc24f
RN
151 Log = TRUE;\r
152 break;\r
f75c7478 153 case ReportSelected:\r
e18ac66d 154 if (Signature == SelectedTable->Type) {\r
ee4dc24f 155 Log = TRUE;\r
e18ac66d 156 SelectedTable->Found = TRUE;\r
ee4dc24f
RN
157 }\r
158 break;\r
f75c7478 159 case ReportTableList:\r
ee4dc24f
RN
160 if (mTableCount == 0) {\r
161 if (HighLight) {\r
162 OriginalAttribute = gST->ConOut->Mode->Attribute;\r
163 gST->ConOut->SetAttribute (\r
164 gST->ConOut,\r
165 EFI_TEXT_ATTR(EFI_CYAN,\r
166 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
167 );\r
168 }\r
169 Print (L"\nInstalled Table(s):\n");\r
170 if (HighLight) {\r
171 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);\r
172 }\r
173 }\r
174 Print (\r
175 L"\t%4d. %c%c%c%c\n",\r
176 ++mTableCount,\r
177 SignaturePtr[0],\r
178 SignaturePtr[1],\r
179 SignaturePtr[2],\r
180 SignaturePtr[3]\r
181 );\r
182 break;\r
f75c7478 183 case ReportDumpBinFile:\r
e18ac66d
TP
184 if (Signature == SelectedTable->Type) {\r
185 SelectedTable->Found = TRUE;\r
ee4dc24f
RN
186 DumpAcpiTableToFile (TablePtr, Length);\r
187 }\r
188 break;\r
f75c7478 189 case ReportMax:\r
ee4dc24f
RN
190 // We should never be here.\r
191 // This case is only present to prevent compiler warning.\r
192 break;\r
193 } // switch\r
194\r
195 if (Log) {\r
196 if (HighLight) {\r
197 OriginalAttribute = gST->ConOut->Mode->Attribute;\r
198 gST->ConOut->SetAttribute (\r
199 gST->ConOut,\r
200 EFI_TEXT_ATTR(EFI_LIGHTBLUE,\r
201 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
202 );\r
203 }\r
204 Print (\r
205 L"\n\n --------------- %c%c%c%c Table --------------- \n\n",\r
206 SignaturePtr[0],\r
207 SignaturePtr[1],\r
208 SignaturePtr[2],\r
209 SignaturePtr[3]\r
210 );\r
211 if (HighLight) {\r
212 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);\r
213 }\r
214 }\r
215\r
216 return Log;\r
217}\r
218\r
ee4dc24f 219\r
ee4dc24f 220\r
a6eaba4d
DB
221/**\r
222 This function iterates the configuration table entries in the\r
223 system table, retrieves the RSDP pointer and starts parsing the ACPI tables.\r
ee4dc24f
RN
224\r
225 @param [in] SystemTable Pointer to the EFI system table.\r
226\r
227 @retval Returns EFI_NOT_FOUND if the RSDP pointer is not found.\r
228 Returns EFI_UNSUPPORTED if the RSDP version is less than 2.\r
229 Returns EFI_SUCCESS if successful.\r
a6eaba4d 230**/\r
ee4dc24f
RN
231STATIC\r
232EFI_STATUS\r
233EFIAPI\r
234AcpiView (\r
235 IN EFI_SYSTEM_TABLE* SystemTable\r
236 )\r
237{\r
238 EFI_STATUS Status;\r
239 UINTN Index;\r
240 EFI_CONFIGURATION_TABLE* EfiConfigurationTable;\r
241 BOOLEAN FoundAcpiTable;\r
242 UINTN OriginalAttribute;\r
243 UINTN PrintAttribute;\r
244 EREPORT_OPTION ReportOption;\r
245 UINT8* RsdpPtr;\r
246 UINT32 RsdpLength;\r
247 UINT8 RsdpRevision;\r
248 PARSE_ACPI_TABLE_PROC RsdpParserProc;\r
249 BOOLEAN Trace;\r
e18ac66d 250 SELECTED_ACPI_TABLE *SelectedTable;\r
ee4dc24f 251\r
0154e02d
SZ
252 //\r
253 // set local variables to suppress incorrect compiler/analyzer warnings\r
254 //\r
255 EfiConfigurationTable = NULL;\r
256 OriginalAttribute = 0;\r
257\r
e46e3040
TP
258 // Reset Table counts\r
259 mTableCount = 0;\r
260 mBinTableCount = 0;\r
261\r
cae974be
TP
262 // Reset The error/warning counters\r
263 ResetErrorCount ();\r
264 ResetWarningCount ();\r
265\r
e18ac66d
TP
266 // Retrieve the user selection of ACPI table to process\r
267 GetSelectedAcpiTable (&SelectedTable);\r
268\r
ee4dc24f
RN
269 // Search the table for an entry that matches the ACPI Table Guid\r
270 FoundAcpiTable = FALSE;\r
271 for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {\r
272 if (CompareGuid (&gEfiAcpiTableGuid,\r
273 &(SystemTable->ConfigurationTable[Index].VendorGuid))) {\r
274 EfiConfigurationTable = &SystemTable->ConfigurationTable[Index];\r
275 FoundAcpiTable = TRUE;\r
276 break;\r
277 }\r
278 }\r
279\r
280 if (FoundAcpiTable) {\r
281 RsdpPtr = (UINT8*)EfiConfigurationTable->VendorTable;\r
282\r
283 // The RSDP revision is 1 byte starting at offset 15\r
284 RsdpRevision = *(RsdpPtr + RSDP_REVISION_OFFSET);\r
285\r
286 if (RsdpRevision < 2) {\r
287 Print (\r
288 L"ERROR: RSDP version less than 2 is not supported.\n"\r
289 );\r
290 return EFI_UNSUPPORTED;\r
291 }\r
292\r
faef5a36
KK
293#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
294 if (GetMandatoryTableValidate ()) {\r
295 ArmSbbrResetTableCounts ();\r
296 }\r
297#endif\r
298\r
ee4dc24f
RN
299 // The RSDP length is 4 bytes starting at offset 20\r
300 RsdpLength = *(UINT32*)(RsdpPtr + RSDP_LENGTH_OFFSET);\r
301\r
302 Trace = ProcessTableReportOptions (RSDP_TABLE_INFO, RsdpPtr, RsdpLength);\r
303\r
304 Status = GetParser (RSDP_TABLE_INFO, &RsdpParserProc);\r
305 if (EFI_ERROR (Status)) {\r
306 Print (\r
307 L"ERROR: No registered parser found for RSDP.\n"\r
308 );\r
309 return Status;\r
310 }\r
311\r
312 RsdpParserProc (\r
313 Trace,\r
314 RsdpPtr,\r
315 RsdpLength,\r
316 RsdpRevision\r
317 );\r
318\r
319 } else {\r
320 IncrementErrorCount ();\r
321 Print (\r
322 L"ERROR: Failed to find ACPI Table Guid in System Configuration Table.\n"\r
323 );\r
324 return EFI_NOT_FOUND;\r
325 }\r
326\r
faef5a36
KK
327#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
328 if (GetMandatoryTableValidate ()) {\r
329 ArmSbbrReqsValidate ((ARM_SBBR_VERSION)GetMandatoryTableSpec ());\r
330 }\r
331#endif\r
332\r
ee4dc24f 333 ReportOption = GetReportOption ();\r
f75c7478
DB
334 if (ReportTableList != ReportOption) {\r
335 if (((ReportSelected == ReportOption) ||\r
336 (ReportDumpBinFile == ReportOption)) &&\r
e18ac66d 337 (!SelectedTable->Found)) {\r
ee4dc24f 338 Print (L"\nRequested ACPI Table not found.\n");\r
f73843d5
KK
339 } else if (GetConsistencyChecking () &&\r
340 (ReportDumpBinFile != ReportOption)) {\r
ee4dc24f
RN
341 OriginalAttribute = gST->ConOut->Mode->Attribute;\r
342\r
343 Print (L"\nTable Statistics:\n");\r
344\r
345 if (GetColourHighlighting ()) {\r
346 PrintAttribute = (GetErrorCount () > 0) ?\r
347 EFI_TEXT_ATTR (\r
348 EFI_RED,\r
349 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)\r
350 ) :\r
351 OriginalAttribute;\r
352 gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);\r
353 }\r
354 Print (L"\t%d Error(s)\n", GetErrorCount ());\r
355\r
356 if (GetColourHighlighting ()) {\r
357 PrintAttribute = (GetWarningCount () > 0) ?\r
358 EFI_TEXT_ATTR (\r
359 EFI_RED,\r
360 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)\r
361 ) :\r
362 OriginalAttribute;\r
363\r
364 gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);\r
365 }\r
366 Print (L"\t%d Warning(s)\n", GetWarningCount ());\r
367\r
368 if (GetColourHighlighting ()) {\r
369 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);\r
370 }\r
371 }\r
372 }\r
373 return EFI_SUCCESS;\r
374}\r
375\r
376/**\r
377 Function for 'acpiview' command.\r
378\r
379 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
380 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
a6eaba4d 381**/\r
ee4dc24f
RN
382SHELL_STATUS\r
383EFIAPI\r
384ShellCommandRunAcpiView (\r
385 IN EFI_HANDLE ImageHandle,\r
386 IN EFI_SYSTEM_TABLE* SystemTable\r
387 )\r
388{\r
389 EFI_STATUS Status;\r
f75c7478
DB
390 SHELL_STATUS ShellStatus;\r
391 LIST_ENTRY* Package;\r
ee4dc24f 392 CHAR16* ProblemParam;\r
f75c7478 393 SHELL_FILE_HANDLE TmpDumpFileHandle;\r
8af507c1 394 CONST CHAR16* MandatoryTableSpecStr;\r
e18ac66d 395 CONST CHAR16 *SelectedTableName;\r
ee4dc24f 396\r
e46e3040 397 // Set configuration defaults\r
e18ac66d 398 AcpiConfigSetDefaults ();\r
ee4dc24f 399\r
f75c7478
DB
400 ShellStatus = SHELL_SUCCESS;\r
401 Package = NULL;\r
402 TmpDumpFileHandle = NULL;\r
403\r
ee4dc24f
RN
404 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
405 if (EFI_ERROR (Status)) {\r
406 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
407 ShellPrintHiiEx (\r
408 -1,\r
409 -1,\r
410 NULL,\r
411 STRING_TOKEN (STR_GEN_PROBLEM),\r
412 gShellAcpiViewHiiHandle,\r
413 L"acpiview",\r
414 ProblemParam\r
415 );\r
416 FreePool (ProblemParam);\r
417 } else {\r
418 Print (L"acpiview: Error processing input parameter(s)\n");\r
419 }\r
420 ShellStatus = SHELL_INVALID_PARAMETER;\r
421 } else {\r
422 if (ShellCommandLineGetCount (Package) > 1) {\r
423 ShellPrintHiiEx (\r
424 -1,\r
425 -1,\r
426 NULL,\r
427 STRING_TOKEN (STR_GEN_TOO_MANY),\r
428 gShellAcpiViewHiiHandle,\r
429 L"acpiview"\r
430 );\r
431 ShellStatus = SHELL_INVALID_PARAMETER;\r
432 } else if (ShellCommandLineGetFlag (Package, L"-?")) {\r
433 ShellPrintHiiEx (\r
434 -1,\r
435 -1,\r
436 NULL,\r
437 STRING_TOKEN (STR_GET_HELP_ACPIVIEW),\r
438 gShellAcpiViewHiiHandle,\r
439 L"acpiview"\r
440 );\r
441 } else if (ShellCommandLineGetFlag (Package, L"-s") &&\r
442 ShellCommandLineGetValue (Package, L"-s") == NULL) {\r
443 ShellPrintHiiEx (\r
444 -1,\r
445 -1,\r
446 NULL,\r
447 STRING_TOKEN (STR_GEN_NO_VALUE),\r
448 gShellAcpiViewHiiHandle,\r
449 L"acpiview",\r
450 L"-s"\r
451 );\r
452 ShellStatus = SHELL_INVALID_PARAMETER;\r
8af507c1
KK
453 } else if (ShellCommandLineGetFlag (Package, L"-r") &&\r
454 ShellCommandLineGetValue (Package, L"-r") == NULL) {\r
455 ShellPrintHiiEx (\r
456 -1,\r
457 -1,\r
458 NULL,\r
459 STRING_TOKEN (STR_GEN_NO_VALUE),\r
460 gShellAcpiViewHiiHandle,\r
461 L"acpiview",\r
462 L"-r"\r
463 );\r
464 ShellStatus = SHELL_INVALID_PARAMETER;\r
ee4dc24f
RN
465 } else if ((ShellCommandLineGetFlag (Package, L"-s") &&\r
466 ShellCommandLineGetFlag (Package, L"-l"))) {\r
467 ShellPrintHiiEx (\r
468 -1,\r
469 -1,\r
470 NULL,\r
471 STRING_TOKEN (STR_GEN_TOO_MANY),\r
472 gShellAcpiViewHiiHandle,\r
473 L"acpiview"\r
474 );\r
475 ShellStatus = SHELL_INVALID_PARAMETER;\r
ee4dc24f
RN
476 } else if (ShellCommandLineGetFlag (Package, L"-d") &&\r
477 !ShellCommandLineGetFlag (Package, L"-s")) {\r
478 ShellPrintHiiEx (\r
479 -1,\r
480 -1,\r
481 NULL,\r
482 STRING_TOKEN (STR_GEN_MISSING_OPTION),\r
483 gShellAcpiViewHiiHandle,\r
484 L"acpiview",\r
485 L"-s",\r
486 L"-d"\r
487 );\r
488 ShellStatus = SHELL_INVALID_PARAMETER;\r
489 } else {\r
4286eb22
KK
490 // Turn on colour highlighting if requested\r
491 SetColourHighlighting (ShellCommandLineGetFlag (Package, L"-h"));\r
ee4dc24f 492\r
f73843d5
KK
493 // Surpress consistency checking if requested\r
494 SetConsistencyChecking (!ShellCommandLineGetFlag (Package, L"-q"));\r
495\r
8af507c1
KK
496 // Evaluate the parameters for mandatory ACPI table presence checks\r
497 SetMandatoryTableValidate (ShellCommandLineGetFlag (Package, L"-r"));\r
498 MandatoryTableSpecStr = ShellCommandLineGetValue (Package, L"-r");\r
499\r
500 if (MandatoryTableSpecStr != NULL) {\r
501 SetMandatoryTableSpec (ShellHexStrToUintn (MandatoryTableSpecStr));\r
502 }\r
503\r
ee4dc24f 504 if (ShellCommandLineGetFlag (Package, L"-l")) {\r
e18ac66d 505 SetReportOption (ReportTableList);\r
ee4dc24f 506 } else {\r
e18ac66d
TP
507 SelectedTableName = ShellCommandLineGetValue (Package, L"-s");\r
508 if (SelectedTableName != NULL) {\r
509 SelectAcpiTable (SelectedTableName);\r
510 SetReportOption (ReportSelected);\r
ee4dc24f
RN
511\r
512 if (ShellCommandLineGetFlag (Package, L"-d")) {\r
513 // Create a temporary file to check if the media is writable.\r
514 CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];\r
e18ac66d 515 SetReportOption (ReportDumpBinFile);\r
ee4dc24f
RN
516\r
517 UnicodeSPrint (\r
518 FileNameBuffer,\r
519 sizeof (FileNameBuffer),\r
520 L".\\%s%04d.tmp",\r
e18ac66d 521 SelectedTableName,\r
ee4dc24f
RN
522 mBinTableCount\r
523 );\r
524\r
525 Status = ShellOpenFileByName (\r
526 FileNameBuffer,\r
527 &TmpDumpFileHandle,\r
528 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |\r
529 EFI_FILE_MODE_CREATE,\r
530 0\r
531 );\r
532\r
533 if (EFI_ERROR (Status)) {\r
534 ShellStatus = SHELL_INVALID_PARAMETER;\r
535 TmpDumpFileHandle = NULL;\r
536 ShellPrintHiiEx (\r
537 -1,\r
538 -1,\r
539 NULL,\r
540 STRING_TOKEN (STR_GEN_READONLY_MEDIA),\r
541 gShellAcpiViewHiiHandle,\r
542 L"acpiview"\r
543 );\r
544 goto Done;\r
545 }\r
546 // Delete Temporary file.\r
547 ShellDeleteFile (&TmpDumpFileHandle);\r
548 } // -d\r
549 } // -s\r
550 }\r
551\r
552 // Parse ACPI Table information\r
553 Status = AcpiView (SystemTable);\r
554 if (EFI_ERROR (Status)) {\r
555 ShellStatus = SHELL_NOT_FOUND;\r
556 }\r
557 }\r
558 }\r
559\r
560Done:\r
561 if (Package != NULL) {\r
562 ShellCommandLineFreeVarList (Package);\r
563 }\r
564 return ShellStatus;\r
565}\r