* [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
@ 2019-01-25 6:13 Chen A Chen
2019-01-25 6:24 ` Yao, Jiewen
0 siblings, 1 reply; 6+ messages in thread
From: Chen A Chen @ 2019-01-25 6:13 UTC (permalink / raw)
To: edk2-devel; +Cc: Chen A Chen, Jian J Wang, Hao Wu, Zhang Chao B
BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1482
No change functionality, use ShellLib to parsing command line.
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Zhang Chao B <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
---
MdeModulePkg/Application/CapsuleApp/CapsuleApp.c | 433 +++++++++++----------
MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf | 2 +
2 files changed, 236 insertions(+), 199 deletions(-)
diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
index 4d907242f3..acae0fe261 100644
--- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
+++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
@@ -27,6 +27,7 @@
#include <Guid/SystemResourceTable.h>
#include <Guid/FmpCapsule.h>
#include <IndustryStandard/WindowsUxCapsule.h>
+#include <Library/ShellLib.h>
#define CAPSULE_HEADER_SIZE 0x20
@@ -39,15 +40,27 @@
#define MAX_CAPSULE_NUM 10
-extern UINTN Argc;
-extern CHAR16 **Argv;
-
//
// Define how many block descriptors we want to test with.
//
UINTN NumberOfDescriptors = 1;
-UINTN CapsuleFirstIndex;
-UINTN CapsuleLastIndex;
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"-C", TypeFlag},
+ {L"-E", TypeFlag},
+ {L"-S", TypeFlag},
+
+ {L"-NR", TypeFlag},
+
+ {L"-G", TypeValue},
+ {L"-O", TypeValue},
+ {L"-N", TypeValue},
+ {L"-D", TypeValue},
+ {L"-P", TypeValue},
+ {L"-I", TypeValue},
+
+ {NULL, TypeMax}
+ };
/**
Dump capsule information
@@ -161,13 +174,12 @@ GetArg (
**/
EFI_STATUS
CreateBmpFmp (
- VOID
+ IN CHAR16 *BmpName,
+ IN CHAR16 *OutputCapsuleName
)
{
- CHAR16 *OutputCapsuleName;
VOID *BmpBuffer;
UINTN FileSize;
- CHAR16 *BmpName;
UINT8 *FullCapsuleBuffer;
UINTN FullCapsuleBufferSize;
EFI_DISPLAY_CAPSULE *DisplayCapsule;
@@ -191,22 +203,10 @@ CreateBmpFmp (
// HorizontalResolution >= BMP_IMAGE_HEADER.PixelWidth
// VerticalResolution >= BMP_IMAGE_HEADER.PixelHeight
- if (Argc != 5) {
- Print(L"CapsuleApp: Incorrect parameter count.\n");
- return EFI_UNSUPPORTED;
- }
-
- if (StrCmp(Argv[3], L"-O") != 0) {
- Print(L"CapsuleApp: NO output capsule name.\n");
- return EFI_UNSUPPORTED;
- }
- OutputCapsuleName = Argv[4];
-
BmpBuffer = NULL;
FileSize = 0;
FullCapsuleBuffer = NULL;
- BmpName = Argv[2];
Status = ReadFileToBuffer(BmpName, &FileSize, &BmpBuffer);
if (EFI_ERROR(Status)) {
Print(L"CapsuleApp: BMP image (%s) is not found.\n", BmpName);
@@ -425,13 +425,12 @@ IsFmpCapsuleGuid (
**/
EFI_STATUS
CreateNestedFmp (
- VOID
+ IN CHAR16 *CapsuleName,
+ IN CHAR16 *OutputCapsuleName
)
{
- CHAR16 *OutputCapsuleName;
VOID *CapsuleBuffer;
UINTN FileSize;
- CHAR16 *CapsuleName;
UINT8 *FullCapsuleBuffer;
UINTN FullCapsuleBufferSize;
EFI_CAPSULE_HEADER *NestedCapsuleHeader;
@@ -439,22 +438,10 @@ CreateNestedFmp (
UINT32 FwType;
EFI_STATUS Status;
- if (Argc != 5) {
- Print(L"CapsuleApp: Incorrect parameter count.\n");
- return EFI_UNSUPPORTED;
- }
-
- if (StrCmp(Argv[3], L"-O") != 0) {
- Print(L"CapsuleApp: NO output capsule name.\n");
- return EFI_UNSUPPORTED;
- }
- OutputCapsuleName = Argv[4];
-
CapsuleBuffer = NULL;
FileSize = 0;
FullCapsuleBuffer = NULL;
- CapsuleName = Argv[2];
Status = ReadFileToBuffer(CapsuleName, &FileSize, &CapsuleBuffer);
if (EFI_ERROR(Status)) {
Print(L"CapsuleApp: Capsule image (%s) is not found.\n", CapsuleName);
@@ -807,7 +794,7 @@ PrintUsage (
Print(L" CapsuleApp -G <BMP> -O <Capsule>\n");
Print(L" CapsuleApp -N <Capsule> -O <NestedCapsule>\n");
Print(L" CapsuleApp -D <Capsule>\n");
- Print(L" CapsuleApp -P GET <ImageTypeId> <Index> -O <FileName>\n");
+ Print(L" CapsuleApp -P <ImageTypeId> -I <Index> -O <FileName>\n");
Print(L"Parameter:\n");
Print(L" -NR: No reset will be triggered for the capsule with\n");
Print(L" CAPSULE_FLAGS_PERSIST_ACROSS_RESET and without\n");
@@ -817,8 +804,7 @@ PrintUsage (
Print(L" -C: Clear capsule report variable (EFI_CAPSULE_REPORT_GUID),\n");
Print(L" which is defined in UEFI specification.\n");
Print(L" -P: Dump UEFI FMP protocol info, or get image with specified\n");
- Print(L" ImageTypeId and Index (decimal format) to a file if 'GET'\n");
- Print(L" option is used.\n");
+ Print(L" ImageTypeId and Index (decimal format) to a file\n");
Print(L" -E: Dump UEFI ESRT table info.\n");
Print(L" -G: Convert a BMP file to be an UX capsule,\n");
Print(L" according to Windows Firmware Update document\n");
@@ -851,206 +837,255 @@ UefiMain (
{
EFI_STATUS Status;
RETURN_STATUS RStatus;
- UINTN FileSize[MAX_CAPSULE_NUM];
VOID *CapsuleBuffer[MAX_CAPSULE_NUM];
- EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
EFI_CAPSULE_HEADER *CapsuleHeaderArray[MAX_CAPSULE_NUM + 1];
- UINT64 MaxCapsuleSize;
+ EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
EFI_RESET_TYPE ResetType;
+ UINT64 MaxCapsuleSize;
+ LIST_ENTRY *Package;
+ CHAR16 *ProblemParam;
+ CHAR16 *BmpFileName;
+ CHAR16 *CapsuleFileName;
+ CHAR16 *OutputFileName;
+ CHAR16 *GuidStr;
+ CHAR16 *IndexStr;
+ EFI_GUID ImageTypeGuid;
+ BOOLEAN NoResetFlag;
BOOLEAN NeedReset;
- BOOLEAN NoReset;
- CHAR16 *CapsuleName;
+ UINTN CapsuleBufferSize[MAX_CAPSULE_NUM];
UINTN CapsuleNum;
- UINTN Index;
- EFI_GUID ImageTypeId;
UINTN ImageIndex;
+ UINTN FlagCount;
+ UINTN Index;
- Status = GetArg();
- if (EFI_ERROR(Status)) {
- Print(L"Please use UEFI SHELL to run this application!\n", Status);
- return Status;
- }
- if (Argc < 2) {
- PrintUsage();
- return EFI_UNSUPPORTED;
+ Status = EFI_SUCCESS;
+ NoResetFlag = FALSE;
+ FlagCount = 0;
+
+ ZeroMem (&CapsuleBuffer, sizeof (CapsuleBuffer));
+ ZeroMem (&CapsuleBufferSize, sizeof (CapsuleBufferSize));
+
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
+ if (EFI_ERROR (Status)) {
+ PrintUsage ();
+ Status = EFI_UNSUPPORTED;
+ goto Done;
}
- if (StrCmp(Argv[1], L"-D") == 0) {
- if (Argc != 3) {
- Print(L"CapsuleApp: Incorrect parameter count.\n");
- return EFI_UNSUPPORTED;
+
+ for (Index = 0; ParamList[Index].Type != TypeMax; Index++) {
+ if (ShellCommandLineGetFlag (Package, ParamList[Index].Name)) {
+ FlagCount++;
}
- Status = DumpCapsule(Argv[2]);
- return Status;
- }
- if (StrCmp(Argv[1], L"-G") == 0) {
- Status = CreateBmpFmp();
- return Status;
- }
- if (StrCmp(Argv[1], L"-N") == 0) {
- Status = CreateNestedFmp();
- return Status;
}
- if (StrCmp(Argv[1], L"-S") == 0) {
- Status = DumpCapsuleStatusVariable();
- return EFI_SUCCESS;
- }
- if (StrCmp(Argv[1], L"-C") == 0) {
- Status = ClearCapsuleStatusVariable();
- return Status;
- }
- if (StrCmp(Argv[1], L"-P") == 0) {
- if (Argc == 2) {
- DumpFmpData();
- }
- if (Argc >= 3) {
- if (StrCmp(Argv[2], L"GET") != 0) {
- Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[2]);
- return EFI_UNSUPPORTED;
- } else {
- if (Argc != 7) {
- Print(L"CapsuleApp: Incorrect parameter count.\n");
- return EFI_UNSUPPORTED;
- }
- //
- // FMP->GetImage()
- //
- RStatus = StrToGuid (Argv[3], &ImageTypeId);
- if (RETURN_ERROR (RStatus) || (Argv[3][GUID_STRING_LENGTH] != L'\0')) {
- Print (L"Invalid ImageTypeId - %s\n", Argv[3]);
- return EFI_INVALID_PARAMETER;
- }
- ImageIndex = StrDecimalToUintn(Argv[4]);
- if (StrCmp(Argv[5], L"-O") != 0) {
- Print(L"CapsuleApp: NO output file name.\n");
- return EFI_UNSUPPORTED;
+ CapsuleNum = ShellCommandLineGetCount (Package) - 1;
+
+ if (CapsuleNum == 0) {
+ if (FlagCount == 1) {
+ //
+ // CapsuleApp -C
+ //
+ if (ShellCommandLineGetFlag (Package, L"-C")) {
+ Status = ClearCapsuleStatusVariable();
+ }
+
+ //
+ // CapsuleApp -D <CapsuleFile>
+ //
+ if (ShellCommandLineGetFlag (Package, L"-D")) {
+ CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue (Package, L"-D");
+ if (CapsuleFileName != NULL) {
+ Status = DumpCapsule (CapsuleFileName);
+ } else {
+ Print (L"CapsuleApp: Incorrect Parameter Count.\n");
+ Status = EFI_UNSUPPORTED;
}
- DumpFmpImage(&ImageTypeId, ImageIndex, Argv[6]);
}
- }
- return EFI_SUCCESS;
- }
- if (StrCmp(Argv[1], L"-E") == 0) {
- DumpEsrtData();
- return EFI_SUCCESS;
- }
+ //
+ // CapsuleApp -E
+ //
+ if (ShellCommandLineGetFlag (Package, L"-E")) {
+ DumpEsrtData ();
+ }
- if (Argv[1][0] == L'-') {
- Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[1]);
- return EFI_UNSUPPORTED;
- }
+ //
+ // CapsuleApp -P
+ //
+ if (ShellCommandLineGetFlag (Package, L"-P")) {
+ DumpFmpData ();
+ }
- CapsuleFirstIndex = 1;
- NoReset = FALSE;
- if ((Argc > 1) && (StrCmp(Argv[Argc - 1], L"-NR") == 0)) {
- NoReset = TRUE;
- CapsuleLastIndex = Argc - 2;
- } else {
- CapsuleLastIndex = Argc - 1;
- }
- CapsuleNum = CapsuleLastIndex - CapsuleFirstIndex + 1;
+ //
+ // CapsuleApp -S
+ //
+ if (ShellCommandLineGetFlag (Package, L"-S")) {
+ Status = DumpCapsuleStatusVariable ();
+ }
+ }
- if (CapsuleFirstIndex > CapsuleLastIndex) {
- Print(L"CapsuleApp: NO capsule image.\n");
- return EFI_UNSUPPORTED;
- }
- if (CapsuleNum > MAX_CAPSULE_NUM) {
- Print(L"CapsuleApp: Too many capsule images.\n");
- return EFI_UNSUPPORTED;
- }
+ if (FlagCount == 2) {
+ //
+ // CapsuleApp -G <BMP> -O <OutputFileName>
+ //
+ if (ShellCommandLineGetFlag (Package, L"-G") && ShellCommandLineGetFlag (Package, L"-O")) {
+ BmpFileName = (CHAR16 *)ShellCommandLineGetValue (Package, L"-G");
+ OutputFileName = (CHAR16 *)ShellCommandLineGetValue (Package, L"-O");
+ if (BmpFileName != NULL && OutputFileName != NULL) {
+ Status = CreateBmpFmp (BmpFileName, OutputFileName);
+ } else {
+ Print (L"CapsuleApp: Incorrect Parameter Count.\n");
+ Status = EFI_UNSUPPORTED;
+ }
+ }
- ZeroMem(&CapsuleBuffer, sizeof(CapsuleBuffer));
- ZeroMem(&FileSize, sizeof(FileSize));
- BlockDescriptors = NULL;
+ //
+ // CapsuleApp -N <CapsuleFile> -O <OutputFileName>
+ //
+ if (ShellCommandLineGetFlag (Package, L"-N") && ShellCommandLineGetFlag (Package ,L"-O")) {
+ CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue (Package, L"-N");
+ OutputFileName = (CHAR16 *)ShellCommandLineGetValue (Package, L"-O");
+ if (CapsuleFileName != NULL && OutputFileName != NULL) {
+ Status = CreateNestedFmp (CapsuleFileName, OutputFileName);
+ } else {
+ Print (L"CapsuleApp: Incorrect Parameter Count.\n");
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+ }
- for (Index = 0; Index < CapsuleNum; Index++) {
- CapsuleName = Argv[CapsuleFirstIndex + Index];
- Status = ReadFileToBuffer(CapsuleName, &FileSize[Index], &CapsuleBuffer[Index]);
- if (EFI_ERROR(Status)) {
- Print(L"CapsuleApp: capsule image (%s) is not found.\n", CapsuleName);
+ if (FlagCount == 3) {
+ //
+ // CapsuleApp -P <ImageTypeGuid> -I <ImageIndex> -O <OutputFile>
+ //
+ if ( ShellCommandLineGetFlag (Package, L"-P") &&
+ ShellCommandLineGetFlag (Package, L"-I") &&
+ ShellCommandLineGetFlag (Package, L"-O")
+ ) {
+ GuidStr = (CHAR16 *)ShellCommandLineGetValue (Package, L"-P");
+ IndexStr = (CHAR16 *)ShellCommandLineGetValue (Package, L"-I");
+ OutputFileName = (CHAR16 *)ShellCommandLineGetValue (Package, L"-O");
+ if (GuidStr != NULL && IndexStr != NULL && OutputFileName != NULL) {
+ RStatus = StrToGuid (GuidStr, &ImageTypeGuid);
+ if (EFI_ERROR (RStatus) || GuidStr[GUID_STRING_LENGTH] != L'\0') {
+ Print (L"Invalid ImageTypeId - %s\n", GuidStr);
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+ ImageIndex = StrDecimalToUintn (IndexStr);
+ DumpFmpImage (&ImageTypeGuid, ImageIndex, OutputFileName);
+ } else {
+ Print (L"CapsuleApp: Incorrect Parameter Count.\n");
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+ }
+ } else {
+ if (CapsuleNum > MAX_CAPSULE_NUM) {
+ Print(L"CapsuleApp: Too many capsule images.\n");
+ Status = EFI_UNSUPPORTED;
goto Done;
}
- if (!IsValidCapsuleHeader (CapsuleBuffer[Index], FileSize[Index])) {
- Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n", CapsuleName);
- return EFI_INVALID_PARAMETER;
+
+ if (ShellCommandLineGetFlag (Package, L"-NR")) {
+ NoResetFlag = TRUE;
}
- }
- //
- // Every capsule use 2 descriptor 1 for data 1 for end
- //
- Status = BuildGatherList(CapsuleBuffer, FileSize, CapsuleNum, &BlockDescriptors);
- if (EFI_ERROR(Status)) {
- goto Done;
- }
+ for (Index = 0; Index < CapsuleNum; Index++) {
+ CapsuleFileName = (CHAR16 *)ShellCommandLineGetRawValue (Package, Index + 1);
+ Status = ReadFileToBuffer (CapsuleFileName, &CapsuleBufferSize[Index], &CapsuleBuffer[Index]);
+ if (EFI_ERROR (Status)) {
+ Print (L"CapsuleApp: capsule image (%s) is not found.\n", CapsuleFileName);
+ goto Done;
+ }
+ if (!IsValidCapsuleHeader (CapsuleBuffer[Index], CapsuleBufferSize[Index])) {
+ Print (L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n", CapsuleFileName);
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+ }
- //
- // Call the runtime service capsule.
- //
- NeedReset = FALSE;
- for (Index = 0; Index < CapsuleNum; Index++) {
- CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *) CapsuleBuffer[Index];
- if ((CapsuleHeaderArray[Index]->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
- NeedReset = TRUE;
+ //
+ // Every capsule use 2 descriptor 1 for data 1 for end
+ //
+ BlockDescriptors = NULL;
+ Status = BuildGatherList (CapsuleBuffer, CapsuleBufferSize, CapsuleNum, &BlockDescriptors);
+ if (EFI_ERROR (Status)) {
+ Print (L"Build Gather List Fail, %r\n", Status);
+ goto Done;
}
- }
- CapsuleHeaderArray[CapsuleNum] = NULL;
- //
- // Inquire platform capability of UpdateCapsule.
- //
- Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray, CapsuleNum, &MaxCapsuleSize, &ResetType);
- if (EFI_ERROR(Status)) {
- Print (L"CapsuleApp: failed to query capsule capability - %r\n", Status);
- goto Done;
- }
+ //
+ // Call the runtime service capsule.
+ //
+ NeedReset = FALSE;
+ for (Index = 0; Index < CapsuleNum; Index++) {
+ CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *) CapsuleBuffer[Index];
+ if ((CapsuleHeaderArray[Index]->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
+ NeedReset = TRUE;
+ }
+ }
+ CapsuleHeaderArray[CapsuleNum] = NULL;
- for (Index = 0; Index < CapsuleNum; Index++) {
- if (FileSize[Index] > MaxCapsuleSize) {
- Print (L"CapsuleApp: capsule is too large to update, %ld is allowed\n", MaxCapsuleSize);
- Status = EFI_UNSUPPORTED;
+ //
+ // Inquire platform capability of UpdateCapsule.
+ //
+ Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray, CapsuleNum, &MaxCapsuleSize, &ResetType);
+ if (EFI_ERROR (Status)) {
+ Print (L"CapsuleApp: failed to query capsule capability - %r\n", Status);
goto Done;
}
- }
- //
- // Check whether the input capsule image has the flag of persist across system reset.
- //
- if (NeedReset) {
- Status = gRT->UpdateCapsule(CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
- if (Status != EFI_SUCCESS) {
- Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
- goto Done;
+ for (Index = 0; Index < CapsuleNum; Index++) {
+ if (CapsuleBufferSize[Index] > MaxCapsuleSize) {
+ Print (L"CapsuleApp: capsule is too large to update, %ld is allowed\n", MaxCapsuleSize);
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
}
+
//
- // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET + CAPSULE_FLAGS_INITIATE_RESET,
- // a system reset should have been triggered by gRT->UpdateCapsule() calling above.
- //
- // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and without CAPSULE_FLAGS_INITIATE_RESET,
- // check if -NR (no-reset) has been specified or not.
+ // Check whether the input capsule image has the flag of persist across system reset.
//
- if (!NoReset) {
+ if (NeedReset) {
+ Status = gRT->UpdateCapsule (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
+ if (Status != EFI_SUCCESS) {
+ Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
+ goto Done;
+ }
//
- // For capsule who has reset flag and no -NR (no-reset) has been specified, after calling UpdateCapsule service,
- // trigger a system reset to process capsule persist across a system reset.
+ // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET + CAPSULE_FLAGS_INITIATE_RESET,
+ // a system reset should have been triggered by gRT->UpdateCapsule() calling above.
//
- gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
- }
- } else {
- //
- // For capsule who has no reset flag, only call UpdateCapsule Service without a
- // system reset. The service will process the capsule immediately.
- //
- Status = gRT->UpdateCapsule (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
- if (Status != EFI_SUCCESS) {
- Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
+ // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and without CAPSULE_FLAGS_INITIATE_RESET,
+ // check if -NR (no-reset) has been specified or not.
+ //
+ if (!NoResetFlag) {
+ //
+ // For capsule who has reset flag and no -NR (no-reset) has been specified, after calling UpdateCapsule service,
+ // trigger a system reset to process capsule persist across a system reset.
+ //
+ gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
+ }
+ } else {
+ //
+ // For capsule who has no reset flag, only call UpdateCapsule Service without a
+ // system reset. The service will process the capsule immediately.
+ //
+ Status = gRT->UpdateCapsule (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
+ if (Status != EFI_SUCCESS) {
+ Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
+ }
}
- }
- Status = EFI_SUCCESS;
+ Status = EFI_SUCCESS;
+ }
Done:
+ if (Package != NULL) {
+ ShellCommandLineFreeVarList (Package);
+ }
+
for (Index = 0; Index < CapsuleNum; Index++) {
if (CapsuleBuffer[Index] != NULL) {
FreePool (CapsuleBuffer[Index]);
diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
index 8a21875286..d4edc539cc 100644
--- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
+++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
@@ -38,6 +38,7 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
[Guids]
gEfiCapsuleReportGuid ## CONSUMES ## GUID
@@ -61,6 +62,7 @@
UefiLib
PrintLib
BmpSupportLib
+ ShellLib
[UserExtensions.TianoCore."ExtraFiles"]
CapsuleAppExtra.uni
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
2019-01-25 6:13 [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter Chen A Chen
@ 2019-01-25 6:24 ` Yao, Jiewen
2019-01-25 7:23 ` Zhang, Chao B
0 siblings, 1 reply; 6+ messages in thread
From: Yao, Jiewen @ 2019-01-25 6:24 UTC (permalink / raw)
To: Chen, Chen A, edk2-devel@lists.01.org; +Cc: Wu, Hao A, Zhang, Chao B
Hey
I don't think MdeModulePkg can depend on ShellPkg.
That is why we do not use ShellLib in the first version.
Do we change the package dependency rule?
Thank you
Yao Jiewen
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Chen A Chen
> Sent: Friday, January 25, 2019 2:14 PM
> To: edk2-devel@lists.01.org
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Zhang, Chao B
> <chao.b.zhang@intel.com>
> Subject: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic
> of parsing parameter.
>
> BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1482
>
> No change functionality, use ShellLib to parsing command line.
>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Hao Wu <hao.a.wu@intel.com>
> Cc: Zhang Chao B <chao.b.zhang@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
> ---
> MdeModulePkg/Application/CapsuleApp/CapsuleApp.c | 433
> +++++++++++----------
> MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf | 2 +
> 2 files changed, 236 insertions(+), 199 deletions(-)
>
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> index 4d907242f3..acae0fe261 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> @@ -27,6 +27,7 @@
> #include <Guid/SystemResourceTable.h>
> #include <Guid/FmpCapsule.h>
> #include <IndustryStandard/WindowsUxCapsule.h>
> +#include <Library/ShellLib.h>
>
> #define CAPSULE_HEADER_SIZE 0x20
>
> @@ -39,15 +40,27 @@
>
> #define MAX_CAPSULE_NUM 10
>
> -extern UINTN Argc;
> -extern CHAR16 **Argv;
> -
> //
> // Define how many block descriptors we want to test with.
> //
> UINTN NumberOfDescriptors = 1;
> -UINTN CapsuleFirstIndex;
> -UINTN CapsuleLastIndex;
> +
> +STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
> + {L"-C", TypeFlag},
> + {L"-E", TypeFlag},
> + {L"-S", TypeFlag},
> +
> + {L"-NR", TypeFlag},
> +
> + {L"-G", TypeValue},
> + {L"-O", TypeValue},
> + {L"-N", TypeValue},
> + {L"-D", TypeValue},
> + {L"-P", TypeValue},
> + {L"-I", TypeValue},
> +
> + {NULL, TypeMax}
> + };
>
> /**
> Dump capsule information
> @@ -161,13 +174,12 @@ GetArg (
> **/
> EFI_STATUS
> CreateBmpFmp (
> - VOID
> + IN CHAR16 *BmpName,
> + IN CHAR16
> *OutputCapsuleName
> )
> {
> - CHAR16
> *OutputCapsuleName;
> VOID *BmpBuffer;
> UINTN FileSize;
> - CHAR16 *BmpName;
> UINT8
> *FullCapsuleBuffer;
> UINTN
> FullCapsuleBufferSize;
> EFI_DISPLAY_CAPSULE *DisplayCapsule;
> @@ -191,22 +203,10 @@ CreateBmpFmp (
> // HorizontalResolution >= BMP_IMAGE_HEADER.PixelWidth
> // VerticalResolution >= BMP_IMAGE_HEADER.PixelHeight
>
> - if (Argc != 5) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (StrCmp(Argv[3], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output capsule name.\n");
> - return EFI_UNSUPPORTED;
> - }
> - OutputCapsuleName = Argv[4];
> -
> BmpBuffer = NULL;
> FileSize = 0;
> FullCapsuleBuffer = NULL;
>
> - BmpName = Argv[2];
> Status = ReadFileToBuffer(BmpName, &FileSize, &BmpBuffer);
> if (EFI_ERROR(Status)) {
> Print(L"CapsuleApp: BMP image (%s) is not found.\n", BmpName);
> @@ -425,13 +425,12 @@ IsFmpCapsuleGuid (
> **/
> EFI_STATUS
> CreateNestedFmp (
> - VOID
> + IN CHAR16 *CapsuleName,
> + IN CHAR16
> *OutputCapsuleName
> )
> {
> - CHAR16
> *OutputCapsuleName;
> VOID *CapsuleBuffer;
> UINTN FileSize;
> - CHAR16 *CapsuleName;
> UINT8
> *FullCapsuleBuffer;
> UINTN
> FullCapsuleBufferSize;
> EFI_CAPSULE_HEADER
> *NestedCapsuleHeader;
> @@ -439,22 +438,10 @@ CreateNestedFmp (
> UINT32 FwType;
> EFI_STATUS Status;
>
> - if (Argc != 5) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (StrCmp(Argv[3], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output capsule name.\n");
> - return EFI_UNSUPPORTED;
> - }
> - OutputCapsuleName = Argv[4];
> -
> CapsuleBuffer = NULL;
> FileSize = 0;
> FullCapsuleBuffer = NULL;
>
> - CapsuleName = Argv[2];
> Status = ReadFileToBuffer(CapsuleName, &FileSize, &CapsuleBuffer);
> if (EFI_ERROR(Status)) {
> Print(L"CapsuleApp: Capsule image (%s) is not found.\n",
> CapsuleName);
> @@ -807,7 +794,7 @@ PrintUsage (
> Print(L" CapsuleApp -G <BMP> -O <Capsule>\n");
> Print(L" CapsuleApp -N <Capsule> -O <NestedCapsule>\n");
> Print(L" CapsuleApp -D <Capsule>\n");
> - Print(L" CapsuleApp -P GET <ImageTypeId> <Index> -O <FileName>\n");
> + Print(L" CapsuleApp -P <ImageTypeId> -I <Index> -O <FileName>\n");
> Print(L"Parameter:\n");
> Print(L" -NR: No reset will be triggered for the capsule with\n");
> Print(L" CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without\n");
> @@ -817,8 +804,7 @@ PrintUsage (
> Print(L" -C: Clear capsule report variable
> (EFI_CAPSULE_REPORT_GUID),\n");
> Print(L" which is defined in UEFI specification.\n");
> Print(L" -P: Dump UEFI FMP protocol info, or get image with
> specified\n");
> - Print(L" ImageTypeId and Index (decimal format) to a file if
> 'GET'\n");
> - Print(L" option is used.\n");
> + Print(L" ImageTypeId and Index (decimal format) to a file\n");
> Print(L" -E: Dump UEFI ESRT table info.\n");
> Print(L" -G: Convert a BMP file to be an UX capsule,\n");
> Print(L" according to Windows Firmware Update document\n");
> @@ -851,206 +837,255 @@ UefiMain (
> {
> EFI_STATUS Status;
> RETURN_STATUS RStatus;
> - UINTN FileSize[MAX_CAPSULE_NUM];
> VOID
> *CapsuleBuffer[MAX_CAPSULE_NUM];
> - EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> EFI_CAPSULE_HEADER
> *CapsuleHeaderArray[MAX_CAPSULE_NUM + 1];
> - UINT64 MaxCapsuleSize;
> + EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> EFI_RESET_TYPE ResetType;
> + UINT64 MaxCapsuleSize;
> + LIST_ENTRY *Package;
> + CHAR16 *ProblemParam;
> + CHAR16 *BmpFileName;
> + CHAR16 *CapsuleFileName;
> + CHAR16 *OutputFileName;
> + CHAR16 *GuidStr;
> + CHAR16 *IndexStr;
> + EFI_GUID ImageTypeGuid;
> + BOOLEAN NoResetFlag;
> BOOLEAN NeedReset;
> - BOOLEAN NoReset;
> - CHAR16 *CapsuleName;
> + UINTN
> CapsuleBufferSize[MAX_CAPSULE_NUM];
> UINTN CapsuleNum;
> - UINTN Index;
> - EFI_GUID ImageTypeId;
> UINTN ImageIndex;
> + UINTN FlagCount;
> + UINTN Index;
>
> - Status = GetArg();
> - if (EFI_ERROR(Status)) {
> - Print(L"Please use UEFI SHELL to run this application!\n", Status);
> - return Status;
> - }
> - if (Argc < 2) {
> - PrintUsage();
> - return EFI_UNSUPPORTED;
> + Status = EFI_SUCCESS;
> + NoResetFlag = FALSE;
> + FlagCount = 0;
> +
> + ZeroMem (&CapsuleBuffer, sizeof (CapsuleBuffer));
> + ZeroMem (&CapsuleBufferSize, sizeof (CapsuleBufferSize));
> +
> + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam,
> TRUE);
> + if (EFI_ERROR (Status)) {
> + PrintUsage ();
> + Status = EFI_UNSUPPORTED;
> + goto Done;
> }
> - if (StrCmp(Argv[1], L"-D") == 0) {
> - if (Argc != 3) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> +
> + for (Index = 0; ParamList[Index].Type != TypeMax; Index++) {
> + if (ShellCommandLineGetFlag (Package, ParamList[Index].Name)) {
> + FlagCount++;
> }
> - Status = DumpCapsule(Argv[2]);
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-G") == 0) {
> - Status = CreateBmpFmp();
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-N") == 0) {
> - Status = CreateNestedFmp();
> - return Status;
> }
> - if (StrCmp(Argv[1], L"-S") == 0) {
> - Status = DumpCapsuleStatusVariable();
> - return EFI_SUCCESS;
> - }
> - if (StrCmp(Argv[1], L"-C") == 0) {
> - Status = ClearCapsuleStatusVariable();
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-P") == 0) {
> - if (Argc == 2) {
> - DumpFmpData();
> - }
> - if (Argc >= 3) {
> - if (StrCmp(Argv[2], L"GET") != 0) {
> - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[2]);
> - return EFI_UNSUPPORTED;
> - } else {
> - if (Argc != 7) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
>
> - //
> - // FMP->GetImage()
> - //
> - RStatus = StrToGuid (Argv[3], &ImageTypeId);
> - if (RETURN_ERROR (RStatus) ||
> (Argv[3][GUID_STRING_LENGTH] != L'\0')) {
> - Print (L"Invalid ImageTypeId - %s\n", Argv[3]);
> - return EFI_INVALID_PARAMETER;
> - }
> - ImageIndex = StrDecimalToUintn(Argv[4]);
> - if (StrCmp(Argv[5], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output file name.\n");
> - return EFI_UNSUPPORTED;
> + CapsuleNum = ShellCommandLineGetCount (Package) - 1;
> +
> + if (CapsuleNum == 0) {
> + if (FlagCount == 1) {
> + //
> + // CapsuleApp -C
> + //
> + if (ShellCommandLineGetFlag (Package, L"-C")) {
> + Status = ClearCapsuleStatusVariable();
> + }
> +
> + //
> + // CapsuleApp -D <CapsuleFile>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-D")) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-D");
> + if (CapsuleFileName != NULL) {
> + Status = DumpCapsule (CapsuleFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> }
> - DumpFmpImage(&ImageTypeId, ImageIndex, Argv[6]);
> }
> - }
> - return EFI_SUCCESS;
> - }
>
> - if (StrCmp(Argv[1], L"-E") == 0) {
> - DumpEsrtData();
> - return EFI_SUCCESS;
> - }
> + //
> + // CapsuleApp -E
> + //
> + if (ShellCommandLineGetFlag (Package, L"-E")) {
> + DumpEsrtData ();
> + }
>
> - if (Argv[1][0] == L'-') {
> - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[1]);
> - return EFI_UNSUPPORTED;
> - }
> + //
> + // CapsuleApp -P
> + //
> + if (ShellCommandLineGetFlag (Package, L"-P")) {
> + DumpFmpData ();
> + }
>
> - CapsuleFirstIndex = 1;
> - NoReset = FALSE;
> - if ((Argc > 1) && (StrCmp(Argv[Argc - 1], L"-NR") == 0)) {
> - NoReset = TRUE;
> - CapsuleLastIndex = Argc - 2;
> - } else {
> - CapsuleLastIndex = Argc - 1;
> - }
> - CapsuleNum = CapsuleLastIndex - CapsuleFirstIndex + 1;
> + //
> + // CapsuleApp -S
> + //
> + if (ShellCommandLineGetFlag (Package, L"-S")) {
> + Status = DumpCapsuleStatusVariable ();
> + }
> + }
>
> - if (CapsuleFirstIndex > CapsuleLastIndex) {
> - Print(L"CapsuleApp: NO capsule image.\n");
> - return EFI_UNSUPPORTED;
> - }
> - if (CapsuleNum > MAX_CAPSULE_NUM) {
> - Print(L"CapsuleApp: Too many capsule images.\n");
> - return EFI_UNSUPPORTED;
> - }
> + if (FlagCount == 2) {
> + //
> + // CapsuleApp -G <BMP> -O <OutputFileName>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-G") &&
> ShellCommandLineGetFlag (Package, L"-O")) {
> + BmpFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-G");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (BmpFileName != NULL && OutputFileName != NULL) {
> + Status = CreateBmpFmp (BmpFileName, OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
>
> - ZeroMem(&CapsuleBuffer, sizeof(CapsuleBuffer));
> - ZeroMem(&FileSize, sizeof(FileSize));
> - BlockDescriptors = NULL;
> + //
> + // CapsuleApp -N <CapsuleFile> -O <OutputFileName>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-N") &&
> ShellCommandLineGetFlag (Package ,L"-O")) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-N");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (CapsuleFileName != NULL && OutputFileName != NULL) {
> + Status = CreateNestedFmp (CapsuleFileName,
> OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> + }
>
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - CapsuleName = Argv[CapsuleFirstIndex + Index];
> - Status = ReadFileToBuffer(CapsuleName, &FileSize[Index],
> &CapsuleBuffer[Index]);
> - if (EFI_ERROR(Status)) {
> - Print(L"CapsuleApp: capsule image (%s) is not found.\n",
> CapsuleName);
> + if (FlagCount == 3) {
> + //
> + // CapsuleApp -P <ImageTypeGuid> -I <ImageIndex> -O
> <OutputFile>
> + //
> + if ( ShellCommandLineGetFlag (Package, L"-P") &&
> + ShellCommandLineGetFlag (Package, L"-I") &&
> + ShellCommandLineGetFlag (Package, L"-O")
> + ) {
> + GuidStr = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-P");
> + IndexStr = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-I");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (GuidStr != NULL && IndexStr != NULL && OutputFileName !=
> NULL) {
> + RStatus = StrToGuid (GuidStr, &ImageTypeGuid);
> + if (EFI_ERROR (RStatus) || GuidStr[GUID_STRING_LENGTH] !=
> L'\0') {
> + Print (L"Invalid ImageTypeId - %s\n", GuidStr);
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> + ImageIndex = StrDecimalToUintn (IndexStr);
> + DumpFmpImage (&ImageTypeGuid, ImageIndex,
> OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> + }
> + } else {
> + if (CapsuleNum > MAX_CAPSULE_NUM) {
> + Print(L"CapsuleApp: Too many capsule images.\n");
> + Status = EFI_UNSUPPORTED;
> goto Done;
> }
> - if (!IsValidCapsuleHeader (CapsuleBuffer[Index], FileSize[Index])) {
> - Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> CapsuleName);
> - return EFI_INVALID_PARAMETER;
> +
> + if (ShellCommandLineGetFlag (Package, L"-NR")) {
> + NoResetFlag = TRUE;
> }
> - }
>
> - //
> - // Every capsule use 2 descriptor 1 for data 1 for end
> - //
> - Status = BuildGatherList(CapsuleBuffer, FileSize, CapsuleNum,
> &BlockDescriptors);
> - if (EFI_ERROR(Status)) {
> - goto Done;
> - }
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetRawValue
> (Package, Index + 1);
> + Status = ReadFileToBuffer (CapsuleFileName,
> &CapsuleBufferSize[Index], &CapsuleBuffer[Index]);
> + if (EFI_ERROR (Status)) {
> + Print (L"CapsuleApp: capsule image (%s) is not found.\n",
> CapsuleFileName);
> + goto Done;
> + }
> + if (!IsValidCapsuleHeader (CapsuleBuffer[Index],
> CapsuleBufferSize[Index])) {
> + Print (L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> CapsuleFileName);
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> + }
>
> - //
> - // Call the runtime service capsule.
> - //
> - NeedReset = FALSE;
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> CapsuleBuffer[Index];
> - if ((CapsuleHeaderArray[Index]->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> - NeedReset = TRUE;
> + //
> + // Every capsule use 2 descriptor 1 for data 1 for end
> + //
> + BlockDescriptors = NULL;
> + Status = BuildGatherList (CapsuleBuffer, CapsuleBufferSize,
> CapsuleNum, &BlockDescriptors);
> + if (EFI_ERROR (Status)) {
> + Print (L"Build Gather List Fail, %r\n", Status);
> + goto Done;
> }
> - }
> - CapsuleHeaderArray[CapsuleNum] = NULL;
>
> - //
> - // Inquire platform capability of UpdateCapsule.
> - //
> - Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> CapsuleNum, &MaxCapsuleSize, &ResetType);
> - if (EFI_ERROR(Status)) {
> - Print (L"CapsuleApp: failed to query capsule capability - %r\n", Status);
> - goto Done;
> - }
> + //
> + // Call the runtime service capsule.
> + //
> + NeedReset = FALSE;
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> CapsuleBuffer[Index];
> + if ((CapsuleHeaderArray[Index]->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> + NeedReset = TRUE;
> + }
> + }
> + CapsuleHeaderArray[CapsuleNum] = NULL;
>
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - if (FileSize[Index] > MaxCapsuleSize) {
> - Print (L"CapsuleApp: capsule is too large to update, %ld is
> allowed\n", MaxCapsuleSize);
> - Status = EFI_UNSUPPORTED;
> + //
> + // Inquire platform capability of UpdateCapsule.
> + //
> + Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> CapsuleNum, &MaxCapsuleSize, &ResetType);
> + if (EFI_ERROR (Status)) {
> + Print (L"CapsuleApp: failed to query capsule capability - %r\n",
> Status);
> goto Done;
> }
> - }
>
> - //
> - // Check whether the input capsule image has the flag of persist across
> system reset.
> - //
> - if (NeedReset) {
> - Status =
> gRT->UpdateCapsule(CapsuleHeaderArray,CapsuleNum,(UINTN)
> BlockDescriptors);
> - if (Status != EFI_SUCCESS) {
> - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> - goto Done;
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + if (CapsuleBufferSize[Index] > MaxCapsuleSize) {
> + Print (L"CapsuleApp: capsule is too large to update, %ld is
> allowed\n", MaxCapsuleSize);
> + Status = EFI_UNSUPPORTED;
> + goto Done;
> + }
> }
> +
> //
> - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> CAPSULE_FLAGS_INITIATE_RESET,
> - // a system reset should have been triggered by gRT->UpdateCapsule()
> calling above.
> - //
> - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without CAPSULE_FLAGS_INITIATE_RESET,
> - // check if -NR (no-reset) has been specified or not.
> + // Check whether the input capsule image has the flag of persist across
> system reset.
> //
> - if (!NoReset) {
> + if (NeedReset) {
> + Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> + if (Status != EFI_SUCCESS) {
> + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + goto Done;
> + }
> //
> - // For capsule who has reset flag and no -NR (no-reset) has been
> specified, after calling UpdateCapsule service,
> - // trigger a system reset to process capsule persist across a system
> reset.
> + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> CAPSULE_FLAGS_INITIATE_RESET,
> + // a system reset should have been triggered by
> gRT->UpdateCapsule() calling above.
> //
> - gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> - }
> - } else {
> - //
> - // For capsule who has no reset flag, only call UpdateCapsule Service
> without a
> - // system reset. The service will process the capsule immediately.
> - //
> - Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> - if (Status != EFI_SUCCESS) {
> - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without CAPSULE_FLAGS_INITIATE_RESET,
> + // check if -NR (no-reset) has been specified or not.
> + //
> + if (!NoResetFlag) {
> + //
> + // For capsule who has reset flag and no -NR (no-reset) has been
> specified, after calling UpdateCapsule service,
> + // trigger a system reset to process capsule persist across a
> system reset.
> + //
> + gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> + }
> + } else {
> + //
> + // For capsule who has no reset flag, only call UpdateCapsule
> Service without a
> + // system reset. The service will process the capsule immediately.
> + //
> + Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> + if (Status != EFI_SUCCESS) {
> + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + }
> }
> - }
>
> - Status = EFI_SUCCESS;
> + Status = EFI_SUCCESS;
> + }
>
> Done:
> + if (Package != NULL) {
> + ShellCommandLineFreeVarList (Package);
> + }
> +
> for (Index = 0; Index < CapsuleNum; Index++) {
> if (CapsuleBuffer[Index] != NULL) {
> FreePool (CapsuleBuffer[Index]);
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> index 8a21875286..d4edc539cc 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> @@ -38,6 +38,7 @@
> [Packages]
> MdePkg/MdePkg.dec
> MdeModulePkg/MdeModulePkg.dec
> + ShellPkg/ShellPkg.dec
>
> [Guids]
> gEfiCapsuleReportGuid ## CONSUMES ## GUID
> @@ -61,6 +62,7 @@
> UefiLib
> PrintLib
> BmpSupportLib
> + ShellLib
>
> [UserExtensions.TianoCore."ExtraFiles"]
> CapsuleAppExtra.uni
> --
> 2.16.2.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
2019-01-25 6:24 ` Yao, Jiewen
@ 2019-01-25 7:23 ` Zhang, Chao B
2019-01-25 9:24 ` Gao, Liming
0 siblings, 1 reply; 6+ messages in thread
From: Zhang, Chao B @ 2019-01-25 7:23 UTC (permalink / raw)
To: Yao, Jiewen, edk2-devel@lists.01.org, Gao, Liming; +Cc: Wu, Hao A, Chen, Chen A
Jiewen & Liming:
It is a problem. Unlike UiApp. CapsuleApp is supposed to run in Shell. ShellLib provides standard parameter parsing support.
Any suggestion on this?
From: Yao, Jiewen
Sent: Friday, January 25, 2019 2:25 PM
To: Chen, Chen A <chen.a.chen@intel.com>; edk2-devel@lists.01.org
Cc: Wu, Hao A <hao.a.wu@intel.com>; Zhang, Chao B <chao.b.zhang@intel.com>
Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
Hey
I don't think MdeModulePkg can depend on ShellPkg.
That is why we do not use ShellLib in the first version.
Do we change the package dependency rule?
Thank you
Yao Jiewen
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Chen A Chen
> Sent: Friday, January 25, 2019 2:14 PM
> To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Wu, Hao A <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>; Zhang, Chao B
> <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> Subject: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic
> of parsing parameter.
>
> BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1482
>
> No change functionality, use ShellLib to parsing command line.
>
> Cc: Jian J Wang <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>
> Cc: Hao Wu <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>
> Cc: Zhang Chao B <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Chen A Chen <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>
> ---
> MdeModulePkg/Application/CapsuleApp/CapsuleApp.c | 433
> +++++++++++----------
> MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf | 2 +
> 2 files changed, 236 insertions(+), 199 deletions(-)
>
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> index 4d907242f3..acae0fe261 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> @@ -27,6 +27,7 @@
> #include <Guid/SystemResourceTable.h>
> #include <Guid/FmpCapsule.h>
> #include <IndustryStandard/WindowsUxCapsule.h>
> +#include <Library/ShellLib.h>
>
> #define CAPSULE_HEADER_SIZE 0x20
>
> @@ -39,15 +40,27 @@
>
> #define MAX_CAPSULE_NUM 10
>
> -extern UINTN Argc;
> -extern CHAR16 **Argv;
> -
> //
> // Define how many block descriptors we want to test with.
> //
> UINTN NumberOfDescriptors = 1;
> -UINTN CapsuleFirstIndex;
> -UINTN CapsuleLastIndex;
> +
> +STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
> + {L"-C", TypeFlag},
> + {L"-E", TypeFlag},
> + {L"-S", TypeFlag},
> +
> + {L"-NR", TypeFlag},
> +
> + {L"-G", TypeValue},
> + {L"-O", TypeValue},
> + {L"-N", TypeValue},
> + {L"-D", TypeValue},
> + {L"-P", TypeValue},
> + {L"-I", TypeValue},
> +
> + {NULL, TypeMax}
> + };
>
> /**
> Dump capsule information
> @@ -161,13 +174,12 @@ GetArg (
> **/
> EFI_STATUS
> CreateBmpFmp (
> - VOID
> + IN CHAR16 *BmpName,
> + IN CHAR16
> *OutputCapsuleName
> )
> {
> - CHAR16
> *OutputCapsuleName;
> VOID *BmpBuffer;
> UINTN FileSize;
> - CHAR16 *BmpName;
> UINT8
> *FullCapsuleBuffer;
> UINTN
> FullCapsuleBufferSize;
> EFI_DISPLAY_CAPSULE *DisplayCapsule;
> @@ -191,22 +203,10 @@ CreateBmpFmp (
> // HorizontalResolution >= BMP_IMAGE_HEADER.PixelWidth
> // VerticalResolution >= BMP_IMAGE_HEADER.PixelHeight
>
> - if (Argc != 5) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (StrCmp(Argv[3], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output capsule name.\n");
> - return EFI_UNSUPPORTED;
> - }
> - OutputCapsuleName = Argv[4];
> -
> BmpBuffer = NULL;
> FileSize = 0;
> FullCapsuleBuffer = NULL;
>
> - BmpName = Argv[2];
> Status = ReadFileToBuffer(BmpName, &FileSize, &BmpBuffer);
> if (EFI_ERROR(Status)) {
> Print(L"CapsuleApp: BMP image (%s) is not found.\n", BmpName);
> @@ -425,13 +425,12 @@ IsFmpCapsuleGuid (
> **/
> EFI_STATUS
> CreateNestedFmp (
> - VOID
> + IN CHAR16 *CapsuleName,
> + IN CHAR16
> *OutputCapsuleName
> )
> {
> - CHAR16
> *OutputCapsuleName;
> VOID *CapsuleBuffer;
> UINTN FileSize;
> - CHAR16 *CapsuleName;
> UINT8
> *FullCapsuleBuffer;
> UINTN
> FullCapsuleBufferSize;
> EFI_CAPSULE_HEADER
> *NestedCapsuleHeader;
> @@ -439,22 +438,10 @@ CreateNestedFmp (
> UINT32 FwType;
> EFI_STATUS Status;
>
> - if (Argc != 5) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (StrCmp(Argv[3], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output capsule name.\n");
> - return EFI_UNSUPPORTED;
> - }
> - OutputCapsuleName = Argv[4];
> -
> CapsuleBuffer = NULL;
> FileSize = 0;
> FullCapsuleBuffer = NULL;
>
> - CapsuleName = Argv[2];
> Status = ReadFileToBuffer(CapsuleName, &FileSize, &CapsuleBuffer);
> if (EFI_ERROR(Status)) {
> Print(L"CapsuleApp: Capsule image (%s) is not found.\n",
> CapsuleName);
> @@ -807,7 +794,7 @@ PrintUsage (
> Print(L" CapsuleApp -G <BMP> -O <Capsule>\n");
> Print(L" CapsuleApp -N <Capsule> -O <NestedCapsule>\n");
> Print(L" CapsuleApp -D <Capsule>\n");
> - Print(L" CapsuleApp -P GET <ImageTypeId> <Index> -O <FileName>\n");
> + Print(L" CapsuleApp -P <ImageTypeId> -I <Index> -O <FileName>\n");
> Print(L"Parameter:\n");
> Print(L" -NR: No reset will be triggered for the capsule with\n");
> Print(L" CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without\n");
> @@ -817,8 +804,7 @@ PrintUsage (
> Print(L" -C: Clear capsule report variable
> (EFI_CAPSULE_REPORT_GUID),\n");
> Print(L" which is defined in UEFI specification.\n");
> Print(L" -P: Dump UEFI FMP protocol info, or get image with
> specified\n");
> - Print(L" ImageTypeId and Index (decimal format) to a file if
> 'GET'\n");
> - Print(L" option is used.\n");
> + Print(L" ImageTypeId and Index (decimal format) to a file\n");
> Print(L" -E: Dump UEFI ESRT table info.\n");
> Print(L" -G: Convert a BMP file to be an UX capsule,\n");
> Print(L" according to Windows Firmware Update document\n");
> @@ -851,206 +837,255 @@ UefiMain (
> {
> EFI_STATUS Status;
> RETURN_STATUS RStatus;
> - UINTN FileSize[MAX_CAPSULE_NUM];
> VOID
> *CapsuleBuffer[MAX_CAPSULE_NUM];
> - EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> EFI_CAPSULE_HEADER
> *CapsuleHeaderArray[MAX_CAPSULE_NUM + 1];
> - UINT64 MaxCapsuleSize;
> + EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> EFI_RESET_TYPE ResetType;
> + UINT64 MaxCapsuleSize;
> + LIST_ENTRY *Package;
> + CHAR16 *ProblemParam;
> + CHAR16 *BmpFileName;
> + CHAR16 *CapsuleFileName;
> + CHAR16 *OutputFileName;
> + CHAR16 *GuidStr;
> + CHAR16 *IndexStr;
> + EFI_GUID ImageTypeGuid;
> + BOOLEAN NoResetFlag;
> BOOLEAN NeedReset;
> - BOOLEAN NoReset;
> - CHAR16 *CapsuleName;
> + UINTN
> CapsuleBufferSize[MAX_CAPSULE_NUM];
> UINTN CapsuleNum;
> - UINTN Index;
> - EFI_GUID ImageTypeId;
> UINTN ImageIndex;
> + UINTN FlagCount;
> + UINTN Index;
>
> - Status = GetArg();
> - if (EFI_ERROR(Status)) {
> - Print(L"Please use UEFI SHELL to run this application!\n", Status);
> - return Status;
> - }
> - if (Argc < 2) {
> - PrintUsage();
> - return EFI_UNSUPPORTED;
> + Status = EFI_SUCCESS;
> + NoResetFlag = FALSE;
> + FlagCount = 0;
> +
> + ZeroMem (&CapsuleBuffer, sizeof (CapsuleBuffer));
> + ZeroMem (&CapsuleBufferSize, sizeof (CapsuleBufferSize));
> +
> + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam,
> TRUE);
> + if (EFI_ERROR (Status)) {
> + PrintUsage ();
> + Status = EFI_UNSUPPORTED;
> + goto Done;
> }
> - if (StrCmp(Argv[1], L"-D") == 0) {
> - if (Argc != 3) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> +
> + for (Index = 0; ParamList[Index].Type != TypeMax; Index++) {
> + if (ShellCommandLineGetFlag (Package, ParamList[Index].Name)) {
> + FlagCount++;
> }
> - Status = DumpCapsule(Argv[2]);
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-G") == 0) {
> - Status = CreateBmpFmp();
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-N") == 0) {
> - Status = CreateNestedFmp();
> - return Status;
> }
> - if (StrCmp(Argv[1], L"-S") == 0) {
> - Status = DumpCapsuleStatusVariable();
> - return EFI_SUCCESS;
> - }
> - if (StrCmp(Argv[1], L"-C") == 0) {
> - Status = ClearCapsuleStatusVariable();
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-P") == 0) {
> - if (Argc == 2) {
> - DumpFmpData();
> - }
> - if (Argc >= 3) {
> - if (StrCmp(Argv[2], L"GET") != 0) {
> - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[2]);
> - return EFI_UNSUPPORTED;
> - } else {
> - if (Argc != 7) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
>
> - //
> - // FMP->GetImage()
> - //
> - RStatus = StrToGuid (Argv[3], &ImageTypeId);
> - if (RETURN_ERROR (RStatus) ||
> (Argv[3][GUID_STRING_LENGTH] != L'\0')) {
> - Print (L"Invalid ImageTypeId - %s\n", Argv[3]);
> - return EFI_INVALID_PARAMETER;
> - }
> - ImageIndex = StrDecimalToUintn(Argv[4]);
> - if (StrCmp(Argv[5], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output file name.\n");
> - return EFI_UNSUPPORTED;
> + CapsuleNum = ShellCommandLineGetCount (Package) - 1;
> +
> + if (CapsuleNum == 0) {
> + if (FlagCount == 1) {
> + //
> + // CapsuleApp -C
> + //
> + if (ShellCommandLineGetFlag (Package, L"-C")) {
> + Status = ClearCapsuleStatusVariable();
> + }
> +
> + //
> + // CapsuleApp -D <CapsuleFile>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-D")) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-D");
> + if (CapsuleFileName != NULL) {
> + Status = DumpCapsule (CapsuleFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> }
> - DumpFmpImage(&ImageTypeId, ImageIndex, Argv[6]);
> }
> - }
> - return EFI_SUCCESS;
> - }
>
> - if (StrCmp(Argv[1], L"-E") == 0) {
> - DumpEsrtData();
> - return EFI_SUCCESS;
> - }
> + //
> + // CapsuleApp -E
> + //
> + if (ShellCommandLineGetFlag (Package, L"-E")) {
> + DumpEsrtData ();
> + }
>
> - if (Argv[1][0] == L'-') {
> - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[1]);
> - return EFI_UNSUPPORTED;
> - }
> + //
> + // CapsuleApp -P
> + //
> + if (ShellCommandLineGetFlag (Package, L"-P")) {
> + DumpFmpData ();
> + }
>
> - CapsuleFirstIndex = 1;
> - NoReset = FALSE;
> - if ((Argc > 1) && (StrCmp(Argv[Argc - 1], L"-NR") == 0)) {
> - NoReset = TRUE;
> - CapsuleLastIndex = Argc - 2;
> - } else {
> - CapsuleLastIndex = Argc - 1;
> - }
> - CapsuleNum = CapsuleLastIndex - CapsuleFirstIndex + 1;
> + //
> + // CapsuleApp -S
> + //
> + if (ShellCommandLineGetFlag (Package, L"-S")) {
> + Status = DumpCapsuleStatusVariable ();
> + }
> + }
>
> - if (CapsuleFirstIndex > CapsuleLastIndex) {
> - Print(L"CapsuleApp: NO capsule image.\n");
> - return EFI_UNSUPPORTED;
> - }
> - if (CapsuleNum > MAX_CAPSULE_NUM) {
> - Print(L"CapsuleApp: Too many capsule images.\n");
> - return EFI_UNSUPPORTED;
> - }
> + if (FlagCount == 2) {
> + //
> + // CapsuleApp -G <BMP> -O <OutputFileName>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-G") &&
> ShellCommandLineGetFlag (Package, L"-O")) {
> + BmpFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-G");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (BmpFileName != NULL && OutputFileName != NULL) {
> + Status = CreateBmpFmp (BmpFileName, OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
>
> - ZeroMem(&CapsuleBuffer, sizeof(CapsuleBuffer));
> - ZeroMem(&FileSize, sizeof(FileSize));
> - BlockDescriptors = NULL;
> + //
> + // CapsuleApp -N <CapsuleFile> -O <OutputFileName>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-N") &&
> ShellCommandLineGetFlag (Package ,L"-O")) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-N");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (CapsuleFileName != NULL && OutputFileName != NULL) {
> + Status = CreateNestedFmp (CapsuleFileName,
> OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> + }
>
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - CapsuleName = Argv[CapsuleFirstIndex + Index];
> - Status = ReadFileToBuffer(CapsuleName, &FileSize[Index],
> &CapsuleBuffer[Index]);
> - if (EFI_ERROR(Status)) {
> - Print(L"CapsuleApp: capsule image (%s) is not found.\n",
> CapsuleName);
> + if (FlagCount == 3) {
> + //
> + // CapsuleApp -P <ImageTypeGuid> -I <ImageIndex> -O
> <OutputFile>
> + //
> + if ( ShellCommandLineGetFlag (Package, L"-P") &&
> + ShellCommandLineGetFlag (Package, L"-I") &&
> + ShellCommandLineGetFlag (Package, L"-O")
> + ) {
> + GuidStr = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-P");
> + IndexStr = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-I");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (GuidStr != NULL && IndexStr != NULL && OutputFileName !=
> NULL) {
> + RStatus = StrToGuid (GuidStr, &ImageTypeGuid);
> + if (EFI_ERROR (RStatus) || GuidStr[GUID_STRING_LENGTH] !=
> L'\0') {
> + Print (L"Invalid ImageTypeId - %s\n", GuidStr);
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> + ImageIndex = StrDecimalToUintn (IndexStr);
> + DumpFmpImage (&ImageTypeGuid, ImageIndex,
> OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> + }
> + } else {
> + if (CapsuleNum > MAX_CAPSULE_NUM) {
> + Print(L"CapsuleApp: Too many capsule images.\n");
> + Status = EFI_UNSUPPORTED;
> goto Done;
> }
> - if (!IsValidCapsuleHeader (CapsuleBuffer[Index], FileSize[Index])) {
> - Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> CapsuleName);
> - return EFI_INVALID_PARAMETER;
> +
> + if (ShellCommandLineGetFlag (Package, L"-NR")) {
> + NoResetFlag = TRUE;
> }
> - }
>
> - //
> - // Every capsule use 2 descriptor 1 for data 1 for end
> - //
> - Status = BuildGatherList(CapsuleBuffer, FileSize, CapsuleNum,
> &BlockDescriptors);
> - if (EFI_ERROR(Status)) {
> - goto Done;
> - }
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetRawValue
> (Package, Index + 1);
> + Status = ReadFileToBuffer (CapsuleFileName,
> &CapsuleBufferSize[Index], &CapsuleBuffer[Index]);
> + if (EFI_ERROR (Status)) {
> + Print (L"CapsuleApp: capsule image (%s) is not found.\n",
> CapsuleFileName);
> + goto Done;
> + }
> + if (!IsValidCapsuleHeader (CapsuleBuffer[Index],
> CapsuleBufferSize[Index])) {
> + Print (L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> CapsuleFileName);
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> + }
>
> - //
> - // Call the runtime service capsule.
> - //
> - NeedReset = FALSE;
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> CapsuleBuffer[Index];
> - if ((CapsuleHeaderArray[Index]->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> - NeedReset = TRUE;
> + //
> + // Every capsule use 2 descriptor 1 for data 1 for end
> + //
> + BlockDescriptors = NULL;
> + Status = BuildGatherList (CapsuleBuffer, CapsuleBufferSize,
> CapsuleNum, &BlockDescriptors);
> + if (EFI_ERROR (Status)) {
> + Print (L"Build Gather List Fail, %r\n", Status);
> + goto Done;
> }
> - }
> - CapsuleHeaderArray[CapsuleNum] = NULL;
>
> - //
> - // Inquire platform capability of UpdateCapsule.
> - //
> - Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> CapsuleNum, &MaxCapsuleSize, &ResetType);
> - if (EFI_ERROR(Status)) {
> - Print (L"CapsuleApp: failed to query capsule capability - %r\n", Status);
> - goto Done;
> - }
> + //
> + // Call the runtime service capsule.
> + //
> + NeedReset = FALSE;
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> CapsuleBuffer[Index];
> + if ((CapsuleHeaderArray[Index]->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> + NeedReset = TRUE;
> + }
> + }
> + CapsuleHeaderArray[CapsuleNum] = NULL;
>
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - if (FileSize[Index] > MaxCapsuleSize) {
> - Print (L"CapsuleApp: capsule is too large to update, %ld is
> allowed\n", MaxCapsuleSize);
> - Status = EFI_UNSUPPORTED;
> + //
> + // Inquire platform capability of UpdateCapsule.
> + //
> + Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> CapsuleNum, &MaxCapsuleSize, &ResetType);
> + if (EFI_ERROR (Status)) {
> + Print (L"CapsuleApp: failed to query capsule capability - %r\n",
> Status);
> goto Done;
> }
> - }
>
> - //
> - // Check whether the input capsule image has the flag of persist across
> system reset.
> - //
> - if (NeedReset) {
> - Status =
> gRT->UpdateCapsule(CapsuleHeaderArray,CapsuleNum,(UINTN)
> BlockDescriptors);
> - if (Status != EFI_SUCCESS) {
> - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> - goto Done;
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + if (CapsuleBufferSize[Index] > MaxCapsuleSize) {
> + Print (L"CapsuleApp: capsule is too large to update, %ld is
> allowed\n", MaxCapsuleSize);
> + Status = EFI_UNSUPPORTED;
> + goto Done;
> + }
> }
> +
> //
> - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> CAPSULE_FLAGS_INITIATE_RESET,
> - // a system reset should have been triggered by gRT->UpdateCapsule()
> calling above.
> - //
> - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without CAPSULE_FLAGS_INITIATE_RESET,
> - // check if -NR (no-reset) has been specified or not.
> + // Check whether the input capsule image has the flag of persist across
> system reset.
> //
> - if (!NoReset) {
> + if (NeedReset) {
> + Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> + if (Status != EFI_SUCCESS) {
> + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + goto Done;
> + }
> //
> - // For capsule who has reset flag and no -NR (no-reset) has been
> specified, after calling UpdateCapsule service,
> - // trigger a system reset to process capsule persist across a system
> reset.
> + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> CAPSULE_FLAGS_INITIATE_RESET,
> + // a system reset should have been triggered by
> gRT->UpdateCapsule() calling above.
> //
> - gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> - }
> - } else {
> - //
> - // For capsule who has no reset flag, only call UpdateCapsule Service
> without a
> - // system reset. The service will process the capsule immediately.
> - //
> - Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> - if (Status != EFI_SUCCESS) {
> - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without CAPSULE_FLAGS_INITIATE_RESET,
> + // check if -NR (no-reset) has been specified or not.
> + //
> + if (!NoResetFlag) {
> + //
> + // For capsule who has reset flag and no -NR (no-reset) has been
> specified, after calling UpdateCapsule service,
> + // trigger a system reset to process capsule persist across a
> system reset.
> + //
> + gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> + }
> + } else {
> + //
> + // For capsule who has no reset flag, only call UpdateCapsule
> Service without a
> + // system reset. The service will process the capsule immediately.
> + //
> + Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> + if (Status != EFI_SUCCESS) {
> + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + }
> }
> - }
>
> - Status = EFI_SUCCESS;
> + Status = EFI_SUCCESS;
> + }
>
> Done:
> + if (Package != NULL) {
> + ShellCommandLineFreeVarList (Package);
> + }
> +
> for (Index = 0; Index < CapsuleNum; Index++) {
> if (CapsuleBuffer[Index] != NULL) {
> FreePool (CapsuleBuffer[Index]);
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> index 8a21875286..d4edc539cc 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> @@ -38,6 +38,7 @@
> [Packages]
> MdePkg/MdePkg.dec
> MdeModulePkg/MdeModulePkg.dec
> + ShellPkg/ShellPkg.dec
>
> [Guids]
> gEfiCapsuleReportGuid ## CONSUMES ## GUID
> @@ -61,6 +62,7 @@
> UefiLib
> PrintLib
> BmpSupportLib
> + ShellLib
>
> [UserExtensions.TianoCore."ExtraFiles"]
> CapsuleAppExtra.uni
> --
> 2.16.2.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
2019-01-25 7:23 ` Zhang, Chao B
@ 2019-01-25 9:24 ` Gao, Liming
2019-01-25 15:36 ` Carsey, Jaben
2019-01-25 22:50 ` Yao, Jiewen
0 siblings, 2 replies; 6+ messages in thread
From: Gao, Liming @ 2019-01-25 9:24 UTC (permalink / raw)
To: Zhang, Chao B, Yao, Jiewen, edk2-devel@lists.01.org
Cc: Wu, Hao A, Chen, Chen A, Gao, Liming
Chao:
CapsuleApp can base on gEfiShellProtocolGuid and gEfiShellParametersProtocolGuid to do it. Current CapsuleApp bases on these two protocols to parse the parameters.
Thanks
Liming
From: Zhang, Chao B
Sent: Friday, January 25, 2019 3:24 PM
To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org; Gao, Liming <liming.gao@intel.com>
Cc: Wu, Hao A <hao.a.wu@intel.com>; Chen, Chen A <chen.a.chen@intel.com>
Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
Jiewen & Liming:
It is a problem. Unlike UiApp. CapsuleApp is supposed to run in Shell. ShellLib provides standard parameter parsing support.
Any suggestion on this?
From: Yao, Jiewen
Sent: Friday, January 25, 2019 2:25 PM
To: Chen, Chen A <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>; edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
Cc: Wu, Hao A <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>; Zhang, Chao B <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
Hey
I don't think MdeModulePkg can depend on ShellPkg.
That is why we do not use ShellLib in the first version.
Do we change the package dependency rule?
Thank you
Yao Jiewen
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Chen A Chen
> Sent: Friday, January 25, 2019 2:14 PM
> To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Wu, Hao A <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>; Zhang, Chao B
> <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> Subject: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic
> of parsing parameter.
>
> BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1482
>
> No change functionality, use ShellLib to parsing command line.
>
> Cc: Jian J Wang <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>
> Cc: Hao Wu <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>
> Cc: Zhang Chao B <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Chen A Chen <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>
> ---
> MdeModulePkg/Application/CapsuleApp/CapsuleApp.c | 433
> +++++++++++----------
> MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf | 2 +
> 2 files changed, 236 insertions(+), 199 deletions(-)
>
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> index 4d907242f3..acae0fe261 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> @@ -27,6 +27,7 @@
> #include <Guid/SystemResourceTable.h>
> #include <Guid/FmpCapsule.h>
> #include <IndustryStandard/WindowsUxCapsule.h>
> +#include <Library/ShellLib.h>
>
> #define CAPSULE_HEADER_SIZE 0x20
>
> @@ -39,15 +40,27 @@
>
> #define MAX_CAPSULE_NUM 10
>
> -extern UINTN Argc;
> -extern CHAR16 **Argv;
> -
> //
> // Define how many block descriptors we want to test with.
> //
> UINTN NumberOfDescriptors = 1;
> -UINTN CapsuleFirstIndex;
> -UINTN CapsuleLastIndex;
> +
> +STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
> + {L"-C", TypeFlag},
> + {L"-E", TypeFlag},
> + {L"-S", TypeFlag},
> +
> + {L"-NR", TypeFlag},
> +
> + {L"-G", TypeValue},
> + {L"-O", TypeValue},
> + {L"-N", TypeValue},
> + {L"-D", TypeValue},
> + {L"-P", TypeValue},
> + {L"-I", TypeValue},
> +
> + {NULL, TypeMax}
> + };
>
> /**
> Dump capsule information
> @@ -161,13 +174,12 @@ GetArg (
> **/
> EFI_STATUS
> CreateBmpFmp (
> - VOID
> + IN CHAR16 *BmpName,
> + IN CHAR16
> *OutputCapsuleName
> )
> {
> - CHAR16
> *OutputCapsuleName;
> VOID *BmpBuffer;
> UINTN FileSize;
> - CHAR16 *BmpName;
> UINT8
> *FullCapsuleBuffer;
> UINTN
> FullCapsuleBufferSize;
> EFI_DISPLAY_CAPSULE *DisplayCapsule;
> @@ -191,22 +203,10 @@ CreateBmpFmp (
> // HorizontalResolution >= BMP_IMAGE_HEADER.PixelWidth
> // VerticalResolution >= BMP_IMAGE_HEADER.PixelHeight
>
> - if (Argc != 5) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (StrCmp(Argv[3], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output capsule name.\n");
> - return EFI_UNSUPPORTED;
> - }
> - OutputCapsuleName = Argv[4];
> -
> BmpBuffer = NULL;
> FileSize = 0;
> FullCapsuleBuffer = NULL;
>
> - BmpName = Argv[2];
> Status = ReadFileToBuffer(BmpName, &FileSize, &BmpBuffer);
> if (EFI_ERROR(Status)) {
> Print(L"CapsuleApp: BMP image (%s) is not found.\n", BmpName);
> @@ -425,13 +425,12 @@ IsFmpCapsuleGuid (
> **/
> EFI_STATUS
> CreateNestedFmp (
> - VOID
> + IN CHAR16 *CapsuleName,
> + IN CHAR16
> *OutputCapsuleName
> )
> {
> - CHAR16
> *OutputCapsuleName;
> VOID *CapsuleBuffer;
> UINTN FileSize;
> - CHAR16 *CapsuleName;
> UINT8
> *FullCapsuleBuffer;
> UINTN
> FullCapsuleBufferSize;
> EFI_CAPSULE_HEADER
> *NestedCapsuleHeader;
> @@ -439,22 +438,10 @@ CreateNestedFmp (
> UINT32 FwType;
> EFI_STATUS Status;
>
> - if (Argc != 5) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (StrCmp(Argv[3], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output capsule name.\n");
> - return EFI_UNSUPPORTED;
> - }
> - OutputCapsuleName = Argv[4];
> -
> CapsuleBuffer = NULL;
> FileSize = 0;
> FullCapsuleBuffer = NULL;
>
> - CapsuleName = Argv[2];
> Status = ReadFileToBuffer(CapsuleName, &FileSize, &CapsuleBuffer);
> if (EFI_ERROR(Status)) {
> Print(L"CapsuleApp: Capsule image (%s) is not found.\n",
> CapsuleName);
> @@ -807,7 +794,7 @@ PrintUsage (
> Print(L" CapsuleApp -G <BMP> -O <Capsule>\n");
> Print(L" CapsuleApp -N <Capsule> -O <NestedCapsule>\n");
> Print(L" CapsuleApp -D <Capsule>\n");
> - Print(L" CapsuleApp -P GET <ImageTypeId> <Index> -O <FileName>\n");
> + Print(L" CapsuleApp -P <ImageTypeId> -I <Index> -O <FileName>\n");
> Print(L"Parameter:\n");
> Print(L" -NR: No reset will be triggered for the capsule with\n");
> Print(L" CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without\n");
> @@ -817,8 +804,7 @@ PrintUsage (
> Print(L" -C: Clear capsule report variable
> (EFI_CAPSULE_REPORT_GUID),\n");
> Print(L" which is defined in UEFI specification.\n");
> Print(L" -P: Dump UEFI FMP protocol info, or get image with
> specified\n");
> - Print(L" ImageTypeId and Index (decimal format) to a file if
> 'GET'\n");
> - Print(L" option is used.\n");
> + Print(L" ImageTypeId and Index (decimal format) to a file\n");
> Print(L" -E: Dump UEFI ESRT table info.\n");
> Print(L" -G: Convert a BMP file to be an UX capsule,\n");
> Print(L" according to Windows Firmware Update document\n");
> @@ -851,206 +837,255 @@ UefiMain (
> {
> EFI_STATUS Status;
> RETURN_STATUS RStatus;
> - UINTN FileSize[MAX_CAPSULE_NUM];
> VOID
> *CapsuleBuffer[MAX_CAPSULE_NUM];
> - EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> EFI_CAPSULE_HEADER
> *CapsuleHeaderArray[MAX_CAPSULE_NUM + 1];
> - UINT64 MaxCapsuleSize;
> + EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> EFI_RESET_TYPE ResetType;
> + UINT64 MaxCapsuleSize;
> + LIST_ENTRY *Package;
> + CHAR16 *ProblemParam;
> + CHAR16 *BmpFileName;
> + CHAR16 *CapsuleFileName;
> + CHAR16 *OutputFileName;
> + CHAR16 *GuidStr;
> + CHAR16 *IndexStr;
> + EFI_GUID ImageTypeGuid;
> + BOOLEAN NoResetFlag;
> BOOLEAN NeedReset;
> - BOOLEAN NoReset;
> - CHAR16 *CapsuleName;
> + UINTN
> CapsuleBufferSize[MAX_CAPSULE_NUM];
> UINTN CapsuleNum;
> - UINTN Index;
> - EFI_GUID ImageTypeId;
> UINTN ImageIndex;
> + UINTN FlagCount;
> + UINTN Index;
>
> - Status = GetArg();
> - if (EFI_ERROR(Status)) {
> - Print(L"Please use UEFI SHELL to run this application!\n", Status);
> - return Status;
> - }
> - if (Argc < 2) {
> - PrintUsage();
> - return EFI_UNSUPPORTED;
> + Status = EFI_SUCCESS;
> + NoResetFlag = FALSE;
> + FlagCount = 0;
> +
> + ZeroMem (&CapsuleBuffer, sizeof (CapsuleBuffer));
> + ZeroMem (&CapsuleBufferSize, sizeof (CapsuleBufferSize));
> +
> + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam,
> TRUE);
> + if (EFI_ERROR (Status)) {
> + PrintUsage ();
> + Status = EFI_UNSUPPORTED;
> + goto Done;
> }
> - if (StrCmp(Argv[1], L"-D") == 0) {
> - if (Argc != 3) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> +
> + for (Index = 0; ParamList[Index].Type != TypeMax; Index++) {
> + if (ShellCommandLineGetFlag (Package, ParamList[Index].Name)) {
> + FlagCount++;
> }
> - Status = DumpCapsule(Argv[2]);
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-G") == 0) {
> - Status = CreateBmpFmp();
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-N") == 0) {
> - Status = CreateNestedFmp();
> - return Status;
> }
> - if (StrCmp(Argv[1], L"-S") == 0) {
> - Status = DumpCapsuleStatusVariable();
> - return EFI_SUCCESS;
> - }
> - if (StrCmp(Argv[1], L"-C") == 0) {
> - Status = ClearCapsuleStatusVariable();
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-P") == 0) {
> - if (Argc == 2) {
> - DumpFmpData();
> - }
> - if (Argc >= 3) {
> - if (StrCmp(Argv[2], L"GET") != 0) {
> - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[2]);
> - return EFI_UNSUPPORTED;
> - } else {
> - if (Argc != 7) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
>
> - //
> - // FMP->GetImage()
> - //
> - RStatus = StrToGuid (Argv[3], &ImageTypeId);
> - if (RETURN_ERROR (RStatus) ||
> (Argv[3][GUID_STRING_LENGTH] != L'\0')) {
> - Print (L"Invalid ImageTypeId - %s\n", Argv[3]);
> - return EFI_INVALID_PARAMETER;
> - }
> - ImageIndex = StrDecimalToUintn(Argv[4]);
> - if (StrCmp(Argv[5], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output file name.\n");
> - return EFI_UNSUPPORTED;
> + CapsuleNum = ShellCommandLineGetCount (Package) - 1;
> +
> + if (CapsuleNum == 0) {
> + if (FlagCount == 1) {
> + //
> + // CapsuleApp -C
> + //
> + if (ShellCommandLineGetFlag (Package, L"-C")) {
> + Status = ClearCapsuleStatusVariable();
> + }
> +
> + //
> + // CapsuleApp -D <CapsuleFile>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-D")) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-D");
> + if (CapsuleFileName != NULL) {
> + Status = DumpCapsule (CapsuleFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> }
> - DumpFmpImage(&ImageTypeId, ImageIndex, Argv[6]);
> }
> - }
> - return EFI_SUCCESS;
> - }
>
> - if (StrCmp(Argv[1], L"-E") == 0) {
> - DumpEsrtData();
> - return EFI_SUCCESS;
> - }
> + //
> + // CapsuleApp -E
> + //
> + if (ShellCommandLineGetFlag (Package, L"-E")) {
> + DumpEsrtData ();
> + }
>
> - if (Argv[1][0] == L'-') {
> - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[1]);
> - return EFI_UNSUPPORTED;
> - }
> + //
> + // CapsuleApp -P
> + //
> + if (ShellCommandLineGetFlag (Package, L"-P")) {
> + DumpFmpData ();
> + }
>
> - CapsuleFirstIndex = 1;
> - NoReset = FALSE;
> - if ((Argc > 1) && (StrCmp(Argv[Argc - 1], L"-NR") == 0)) {
> - NoReset = TRUE;
> - CapsuleLastIndex = Argc - 2;
> - } else {
> - CapsuleLastIndex = Argc - 1;
> - }
> - CapsuleNum = CapsuleLastIndex - CapsuleFirstIndex + 1;
> + //
> + // CapsuleApp -S
> + //
> + if (ShellCommandLineGetFlag (Package, L"-S")) {
> + Status = DumpCapsuleStatusVariable ();
> + }
> + }
>
> - if (CapsuleFirstIndex > CapsuleLastIndex) {
> - Print(L"CapsuleApp: NO capsule image.\n");
> - return EFI_UNSUPPORTED;
> - }
> - if (CapsuleNum > MAX_CAPSULE_NUM) {
> - Print(L"CapsuleApp: Too many capsule images.\n");
> - return EFI_UNSUPPORTED;
> - }
> + if (FlagCount == 2) {
> + //
> + // CapsuleApp -G <BMP> -O <OutputFileName>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-G") &&
> ShellCommandLineGetFlag (Package, L"-O")) {
> + BmpFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-G");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (BmpFileName != NULL && OutputFileName != NULL) {
> + Status = CreateBmpFmp (BmpFileName, OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
>
> - ZeroMem(&CapsuleBuffer, sizeof(CapsuleBuffer));
> - ZeroMem(&FileSize, sizeof(FileSize));
> - BlockDescriptors = NULL;
> + //
> + // CapsuleApp -N <CapsuleFile> -O <OutputFileName>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-N") &&
> ShellCommandLineGetFlag (Package ,L"-O")) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-N");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (CapsuleFileName != NULL && OutputFileName != NULL) {
> + Status = CreateNestedFmp (CapsuleFileName,
> OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> + }
>
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - CapsuleName = Argv[CapsuleFirstIndex + Index];
> - Status = ReadFileToBuffer(CapsuleName, &FileSize[Index],
> &CapsuleBuffer[Index]);
> - if (EFI_ERROR(Status)) {
> - Print(L"CapsuleApp: capsule image (%s) is not found.\n",
> CapsuleName);
> + if (FlagCount == 3) {
> + //
> + // CapsuleApp -P <ImageTypeGuid> -I <ImageIndex> -O
> <OutputFile>
> + //
> + if ( ShellCommandLineGetFlag (Package, L"-P") &&
> + ShellCommandLineGetFlag (Package, L"-I") &&
> + ShellCommandLineGetFlag (Package, L"-O")
> + ) {
> + GuidStr = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-P");
> + IndexStr = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-I");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (GuidStr != NULL && IndexStr != NULL && OutputFileName !=
> NULL) {
> + RStatus = StrToGuid (GuidStr, &ImageTypeGuid);
> + if (EFI_ERROR (RStatus) || GuidStr[GUID_STRING_LENGTH] !=
> L'\0') {
> + Print (L"Invalid ImageTypeId - %s\n", GuidStr);
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> + ImageIndex = StrDecimalToUintn (IndexStr);
> + DumpFmpImage (&ImageTypeGuid, ImageIndex,
> OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> + }
> + } else {
> + if (CapsuleNum > MAX_CAPSULE_NUM) {
> + Print(L"CapsuleApp: Too many capsule images.\n");
> + Status = EFI_UNSUPPORTED;
> goto Done;
> }
> - if (!IsValidCapsuleHeader (CapsuleBuffer[Index], FileSize[Index])) {
> - Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> CapsuleName);
> - return EFI_INVALID_PARAMETER;
> +
> + if (ShellCommandLineGetFlag (Package, L"-NR")) {
> + NoResetFlag = TRUE;
> }
> - }
>
> - //
> - // Every capsule use 2 descriptor 1 for data 1 for end
> - //
> - Status = BuildGatherList(CapsuleBuffer, FileSize, CapsuleNum,
> &BlockDescriptors);
> - if (EFI_ERROR(Status)) {
> - goto Done;
> - }
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetRawValue
> (Package, Index + 1);
> + Status = ReadFileToBuffer (CapsuleFileName,
> &CapsuleBufferSize[Index], &CapsuleBuffer[Index]);
> + if (EFI_ERROR (Status)) {
> + Print (L"CapsuleApp: capsule image (%s) is not found.\n",
> CapsuleFileName);
> + goto Done;
> + }
> + if (!IsValidCapsuleHeader (CapsuleBuffer[Index],
> CapsuleBufferSize[Index])) {
> + Print (L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> CapsuleFileName);
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> + }
>
> - //
> - // Call the runtime service capsule.
> - //
> - NeedReset = FALSE;
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> CapsuleBuffer[Index];
> - if ((CapsuleHeaderArray[Index]->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> - NeedReset = TRUE;
> + //
> + // Every capsule use 2 descriptor 1 for data 1 for end
> + //
> + BlockDescriptors = NULL;
> + Status = BuildGatherList (CapsuleBuffer, CapsuleBufferSize,
> CapsuleNum, &BlockDescriptors);
> + if (EFI_ERROR (Status)) {
> + Print (L"Build Gather List Fail, %r\n", Status);
> + goto Done;
> }
> - }
> - CapsuleHeaderArray[CapsuleNum] = NULL;
>
> - //
> - // Inquire platform capability of UpdateCapsule.
> - //
> - Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> CapsuleNum, &MaxCapsuleSize, &ResetType);
> - if (EFI_ERROR(Status)) {
> - Print (L"CapsuleApp: failed to query capsule capability - %r\n", Status);
> - goto Done;
> - }
> + //
> + // Call the runtime service capsule.
> + //
> + NeedReset = FALSE;
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> CapsuleBuffer[Index];
> + if ((CapsuleHeaderArray[Index]->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> + NeedReset = TRUE;
> + }
> + }
> + CapsuleHeaderArray[CapsuleNum] = NULL;
>
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - if (FileSize[Index] > MaxCapsuleSize) {
> - Print (L"CapsuleApp: capsule is too large to update, %ld is
> allowed\n", MaxCapsuleSize);
> - Status = EFI_UNSUPPORTED;
> + //
> + // Inquire platform capability of UpdateCapsule.
> + //
> + Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> CapsuleNum, &MaxCapsuleSize, &ResetType);
> + if (EFI_ERROR (Status)) {
> + Print (L"CapsuleApp: failed to query capsule capability - %r\n",
> Status);
> goto Done;
> }
> - }
>
> - //
> - // Check whether the input capsule image has the flag of persist across
> system reset.
> - //
> - if (NeedReset) {
> - Status =
> gRT->UpdateCapsule(CapsuleHeaderArray,CapsuleNum,(UINTN)
> BlockDescriptors);
> - if (Status != EFI_SUCCESS) {
> - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> - goto Done;
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + if (CapsuleBufferSize[Index] > MaxCapsuleSize) {
> + Print (L"CapsuleApp: capsule is too large to update, %ld is
> allowed\n", MaxCapsuleSize);
> + Status = EFI_UNSUPPORTED;
> + goto Done;
> + }
> }
> +
> //
> - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> CAPSULE_FLAGS_INITIATE_RESET,
> - // a system reset should have been triggered by gRT->UpdateCapsule()
> calling above.
> - //
> - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without CAPSULE_FLAGS_INITIATE_RESET,
> - // check if -NR (no-reset) has been specified or not.
> + // Check whether the input capsule image has the flag of persist across
> system reset.
> //
> - if (!NoReset) {
> + if (NeedReset) {
> + Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> + if (Status != EFI_SUCCESS) {
> + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + goto Done;
> + }
> //
> - // For capsule who has reset flag and no -NR (no-reset) has been
> specified, after calling UpdateCapsule service,
> - // trigger a system reset to process capsule persist across a system
> reset.
> + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> CAPSULE_FLAGS_INITIATE_RESET,
> + // a system reset should have been triggered by
> gRT->UpdateCapsule() calling above.
> //
> - gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> - }
> - } else {
> - //
> - // For capsule who has no reset flag, only call UpdateCapsule Service
> without a
> - // system reset. The service will process the capsule immediately.
> - //
> - Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> - if (Status != EFI_SUCCESS) {
> - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without CAPSULE_FLAGS_INITIATE_RESET,
> + // check if -NR (no-reset) has been specified or not.
> + //
> + if (!NoResetFlag) {
> + //
> + // For capsule who has reset flag and no -NR (no-reset) has been
> specified, after calling UpdateCapsule service,
> + // trigger a system reset to process capsule persist across a
> system reset.
> + //
> + gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> + }
> + } else {
> + //
> + // For capsule who has no reset flag, only call UpdateCapsule
> Service without a
> + // system reset. The service will process the capsule immediately.
> + //
> + Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> + if (Status != EFI_SUCCESS) {
> + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + }
> }
> - }
>
> - Status = EFI_SUCCESS;
> + Status = EFI_SUCCESS;
> + }
>
> Done:
> + if (Package != NULL) {
> + ShellCommandLineFreeVarList (Package);
> + }
> +
> for (Index = 0; Index < CapsuleNum; Index++) {
> if (CapsuleBuffer[Index] != NULL) {
> FreePool (CapsuleBuffer[Index]);
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> index 8a21875286..d4edc539cc 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> @@ -38,6 +38,7 @@
> [Packages]
> MdePkg/MdePkg.dec
> MdeModulePkg/MdeModulePkg.dec
> + ShellPkg/ShellPkg.dec
>
> [Guids]
> gEfiCapsuleReportGuid ## CONSUMES ## GUID
> @@ -61,6 +62,7 @@
> UefiLib
> PrintLib
> BmpSupportLib
> + ShellLib
>
> [UserExtensions.TianoCore."ExtraFiles"]
> CapsuleAppExtra.uni
> --
> 2.16.2.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
2019-01-25 9:24 ` Gao, Liming
@ 2019-01-25 15:36 ` Carsey, Jaben
2019-01-25 22:50 ` Yao, Jiewen
1 sibling, 0 replies; 6+ messages in thread
From: Carsey, Jaben @ 2019-01-25 15:36 UTC (permalink / raw)
To: Gao, Liming, Zhang, Chao B, Yao, Jiewen, edk2-devel@lists.01.org
Cc: Wu, Hao A, Gao, Liming
I think that if the application wants to depend on the libs, then we should discuss moving the application to the ShellPkg.
-Jaben
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Gao, Liming
> Sent: Friday, January 25, 2019 1:25 AM
> To: Zhang, Chao B <chao.b.zhang@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; edk2-devel@lists.01.org
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>
> Subject: Re: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code
> logic of parsing parameter.
> Importance: High
>
> Chao:
> CapsuleApp can base on gEfiShellProtocolGuid and
> gEfiShellParametersProtocolGuid to do it. Current CapsuleApp bases on
> these two protocols to parse the parameters.
>
> Thanks
> Liming
> From: Zhang, Chao B
> Sent: Friday, January 25, 2019 3:24 PM
> To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org; Gao,
> Liming <liming.gao@intel.com>
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Chen, Chen A
> <chen.a.chen@intel.com>
> Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code
> logic of parsing parameter.
>
> Jiewen & Liming:
> It is a problem. Unlike UiApp. CapsuleApp is supposed to run in Shell.
> ShellLib provides standard parameter parsing support.
> Any suggestion on this?
>
> From: Yao, Jiewen
> Sent: Friday, January 25, 2019 2:25 PM
> To: Chen, Chen A
> <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>; edk2-
> devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Wu, Hao A <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>; Zhang,
> Chao B <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code
> logic of parsing parameter.
>
> Hey
> I don't think MdeModulePkg can depend on ShellPkg.
>
> That is why we do not use ShellLib in the first version.
>
> Do we change the package dependency rule?
>
> Thank you
> Yao Jiewen
>
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Chen A Chen
> > Sent: Friday, January 25, 2019 2:14 PM
> > To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> > Cc: Wu, Hao A <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>;
> Zhang, Chao B
> > <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> > Subject: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code
> logic
> > of parsing parameter.
> >
> > BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1482
> >
> > No change functionality, use ShellLib to parsing command line.
> >
> > Cc: Jian J Wang <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>
> > Cc: Hao Wu <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>
> > Cc: Zhang Chao B
> <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Chen A Chen
> <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>
> > ---
> > MdeModulePkg/Application/CapsuleApp/CapsuleApp.c | 433
> > +++++++++++----------
> > MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf | 2 +
> > 2 files changed, 236 insertions(+), 199 deletions(-)
> >
> > diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> > b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> > index 4d907242f3..acae0fe261 100644
> > --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> > +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> > @@ -27,6 +27,7 @@
> > #include <Guid/SystemResourceTable.h>
> > #include <Guid/FmpCapsule.h>
> > #include <IndustryStandard/WindowsUxCapsule.h>
> > +#include <Library/ShellLib.h>
> >
> > #define CAPSULE_HEADER_SIZE 0x20
> >
> > @@ -39,15 +40,27 @@
> >
> > #define MAX_CAPSULE_NUM 10
> >
> > -extern UINTN Argc;
> > -extern CHAR16 **Argv;
> > -
> > //
> > // Define how many block descriptors we want to test with.
> > //
> > UINTN NumberOfDescriptors = 1;
> > -UINTN CapsuleFirstIndex;
> > -UINTN CapsuleLastIndex;
> > +
> > +STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
> > + {L"-C", TypeFlag},
> > + {L"-E", TypeFlag},
> > + {L"-S", TypeFlag},
> > +
> > + {L"-NR", TypeFlag},
> > +
> > + {L"-G", TypeValue},
> > + {L"-O", TypeValue},
> > + {L"-N", TypeValue},
> > + {L"-D", TypeValue},
> > + {L"-P", TypeValue},
> > + {L"-I", TypeValue},
> > +
> > + {NULL, TypeMax}
> > + };
> >
> > /**
> > Dump capsule information
> > @@ -161,13 +174,12 @@ GetArg (
> > **/
> > EFI_STATUS
> > CreateBmpFmp (
> > - VOID
> > + IN CHAR16 *BmpName,
> > + IN CHAR16
> > *OutputCapsuleName
> > )
> > {
> > - CHAR16
> > *OutputCapsuleName;
> > VOID *BmpBuffer;
> > UINTN FileSize;
> > - CHAR16 *BmpName;
> > UINT8
> > *FullCapsuleBuffer;
> > UINTN
> > FullCapsuleBufferSize;
> > EFI_DISPLAY_CAPSULE *DisplayCapsule;
> > @@ -191,22 +203,10 @@ CreateBmpFmp (
> > // HorizontalResolution >= BMP_IMAGE_HEADER.PixelWidth
> > // VerticalResolution >= BMP_IMAGE_HEADER.PixelHeight
> >
> > - if (Argc != 5) {
> > - Print(L"CapsuleApp: Incorrect parameter count.\n");
> > - return EFI_UNSUPPORTED;
> > - }
> > -
> > - if (StrCmp(Argv[3], L"-O") != 0) {
> > - Print(L"CapsuleApp: NO output capsule name.\n");
> > - return EFI_UNSUPPORTED;
> > - }
> > - OutputCapsuleName = Argv[4];
> > -
> > BmpBuffer = NULL;
> > FileSize = 0;
> > FullCapsuleBuffer = NULL;
> >
> > - BmpName = Argv[2];
> > Status = ReadFileToBuffer(BmpName, &FileSize, &BmpBuffer);
> > if (EFI_ERROR(Status)) {
> > Print(L"CapsuleApp: BMP image (%s) is not found.\n", BmpName);
> > @@ -425,13 +425,12 @@ IsFmpCapsuleGuid (
> > **/
> > EFI_STATUS
> > CreateNestedFmp (
> > - VOID
> > + IN CHAR16 *CapsuleName,
> > + IN CHAR16
> > *OutputCapsuleName
> > )
> > {
> > - CHAR16
> > *OutputCapsuleName;
> > VOID *CapsuleBuffer;
> > UINTN FileSize;
> > - CHAR16 *CapsuleName;
> > UINT8
> > *FullCapsuleBuffer;
> > UINTN
> > FullCapsuleBufferSize;
> > EFI_CAPSULE_HEADER
> > *NestedCapsuleHeader;
> > @@ -439,22 +438,10 @@ CreateNestedFmp (
> > UINT32 FwType;
> > EFI_STATUS Status;
> >
> > - if (Argc != 5) {
> > - Print(L"CapsuleApp: Incorrect parameter count.\n");
> > - return EFI_UNSUPPORTED;
> > - }
> > -
> > - if (StrCmp(Argv[3], L"-O") != 0) {
> > - Print(L"CapsuleApp: NO output capsule name.\n");
> > - return EFI_UNSUPPORTED;
> > - }
> > - OutputCapsuleName = Argv[4];
> > -
> > CapsuleBuffer = NULL;
> > FileSize = 0;
> > FullCapsuleBuffer = NULL;
> >
> > - CapsuleName = Argv[2];
> > Status = ReadFileToBuffer(CapsuleName, &FileSize, &CapsuleBuffer);
> > if (EFI_ERROR(Status)) {
> > Print(L"CapsuleApp: Capsule image (%s) is not found.\n",
> > CapsuleName);
> > @@ -807,7 +794,7 @@ PrintUsage (
> > Print(L" CapsuleApp -G <BMP> -O <Capsule>\n");
> > Print(L" CapsuleApp -N <Capsule> -O <NestedCapsule>\n");
> > Print(L" CapsuleApp -D <Capsule>\n");
> > - Print(L" CapsuleApp -P GET <ImageTypeId> <Index> -O <FileName>\n");
> > + Print(L" CapsuleApp -P <ImageTypeId> -I <Index> -O <FileName>\n");
> > Print(L"Parameter:\n");
> > Print(L" -NR: No reset will be triggered for the capsule with\n");
> > Print(L" CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> > without\n");
> > @@ -817,8 +804,7 @@ PrintUsage (
> > Print(L" -C: Clear capsule report variable
> > (EFI_CAPSULE_REPORT_GUID),\n");
> > Print(L" which is defined in UEFI specification.\n");
> > Print(L" -P: Dump UEFI FMP protocol info, or get image with
> > specified\n");
> > - Print(L" ImageTypeId and Index (decimal format) to a file if
> > 'GET'\n");
> > - Print(L" option is used.\n");
> > + Print(L" ImageTypeId and Index (decimal format) to a file\n");
> > Print(L" -E: Dump UEFI ESRT table info.\n");
> > Print(L" -G: Convert a BMP file to be an UX capsule,\n");
> > Print(L" according to Windows Firmware Update document\n");
> > @@ -851,206 +837,255 @@ UefiMain (
> > {
> > EFI_STATUS Status;
> > RETURN_STATUS RStatus;
> > - UINTN FileSize[MAX_CAPSULE_NUM];
> > VOID
> > *CapsuleBuffer[MAX_CAPSULE_NUM];
> > - EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> > EFI_CAPSULE_HEADER
> > *CapsuleHeaderArray[MAX_CAPSULE_NUM + 1];
> > - UINT64 MaxCapsuleSize;
> > + EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> > EFI_RESET_TYPE ResetType;
> > + UINT64 MaxCapsuleSize;
> > + LIST_ENTRY *Package;
> > + CHAR16 *ProblemParam;
> > + CHAR16 *BmpFileName;
> > + CHAR16 *CapsuleFileName;
> > + CHAR16 *OutputFileName;
> > + CHAR16 *GuidStr;
> > + CHAR16 *IndexStr;
> > + EFI_GUID ImageTypeGuid;
> > + BOOLEAN NoResetFlag;
> > BOOLEAN NeedReset;
> > - BOOLEAN NoReset;
> > - CHAR16 *CapsuleName;
> > + UINTN
> > CapsuleBufferSize[MAX_CAPSULE_NUM];
> > UINTN CapsuleNum;
> > - UINTN Index;
> > - EFI_GUID ImageTypeId;
> > UINTN ImageIndex;
> > + UINTN FlagCount;
> > + UINTN Index;
> >
> > - Status = GetArg();
> > - if (EFI_ERROR(Status)) {
> > - Print(L"Please use UEFI SHELL to run this application!\n", Status);
> > - return Status;
> > - }
> > - if (Argc < 2) {
> > - PrintUsage();
> > - return EFI_UNSUPPORTED;
> > + Status = EFI_SUCCESS;
> > + NoResetFlag = FALSE;
> > + FlagCount = 0;
> > +
> > + ZeroMem (&CapsuleBuffer, sizeof (CapsuleBuffer));
> > + ZeroMem (&CapsuleBufferSize, sizeof (CapsuleBufferSize));
> > +
> > + Status = ShellCommandLineParse (ParamList, &Package,
> &ProblemParam,
> > TRUE);
> > + if (EFI_ERROR (Status)) {
> > + PrintUsage ();
> > + Status = EFI_UNSUPPORTED;
> > + goto Done;
> > }
> > - if (StrCmp(Argv[1], L"-D") == 0) {
> > - if (Argc != 3) {
> > - Print(L"CapsuleApp: Incorrect parameter count.\n");
> > - return EFI_UNSUPPORTED;
> > +
> > + for (Index = 0; ParamList[Index].Type != TypeMax; Index++) {
> > + if (ShellCommandLineGetFlag (Package, ParamList[Index].Name)) {
> > + FlagCount++;
> > }
> > - Status = DumpCapsule(Argv[2]);
> > - return Status;
> > - }
> > - if (StrCmp(Argv[1], L"-G") == 0) {
> > - Status = CreateBmpFmp();
> > - return Status;
> > - }
> > - if (StrCmp(Argv[1], L"-N") == 0) {
> > - Status = CreateNestedFmp();
> > - return Status;
> > }
> > - if (StrCmp(Argv[1], L"-S") == 0) {
> > - Status = DumpCapsuleStatusVariable();
> > - return EFI_SUCCESS;
> > - }
> > - if (StrCmp(Argv[1], L"-C") == 0) {
> > - Status = ClearCapsuleStatusVariable();
> > - return Status;
> > - }
> > - if (StrCmp(Argv[1], L"-P") == 0) {
> > - if (Argc == 2) {
> > - DumpFmpData();
> > - }
> > - if (Argc >= 3) {
> > - if (StrCmp(Argv[2], L"GET") != 0) {
> > - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[2]);
> > - return EFI_UNSUPPORTED;
> > - } else {
> > - if (Argc != 7) {
> > - Print(L"CapsuleApp: Incorrect parameter count.\n");
> > - return EFI_UNSUPPORTED;
> > - }
> >
> > - //
> > - // FMP->GetImage()
> > - //
> > - RStatus = StrToGuid (Argv[3], &ImageTypeId);
> > - if (RETURN_ERROR (RStatus) ||
> > (Argv[3][GUID_STRING_LENGTH] != L'\0')) {
> > - Print (L"Invalid ImageTypeId - %s\n", Argv[3]);
> > - return EFI_INVALID_PARAMETER;
> > - }
> > - ImageIndex = StrDecimalToUintn(Argv[4]);
> > - if (StrCmp(Argv[5], L"-O") != 0) {
> > - Print(L"CapsuleApp: NO output file name.\n");
> > - return EFI_UNSUPPORTED;
> > + CapsuleNum = ShellCommandLineGetCount (Package) - 1;
> > +
> > + if (CapsuleNum == 0) {
> > + if (FlagCount == 1) {
> > + //
> > + // CapsuleApp -C
> > + //
> > + if (ShellCommandLineGetFlag (Package, L"-C")) {
> > + Status = ClearCapsuleStatusVariable();
> > + }
> > +
> > + //
> > + // CapsuleApp -D <CapsuleFile>
> > + //
> > + if (ShellCommandLineGetFlag (Package, L"-D")) {
> > + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> > (Package, L"-D");
> > + if (CapsuleFileName != NULL) {
> > + Status = DumpCapsule (CapsuleFileName);
> > + } else {
> > + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> > + Status = EFI_UNSUPPORTED;
> > }
> > - DumpFmpImage(&ImageTypeId, ImageIndex, Argv[6]);
> > }
> > - }
> > - return EFI_SUCCESS;
> > - }
> >
> > - if (StrCmp(Argv[1], L"-E") == 0) {
> > - DumpEsrtData();
> > - return EFI_SUCCESS;
> > - }
> > + //
> > + // CapsuleApp -E
> > + //
> > + if (ShellCommandLineGetFlag (Package, L"-E")) {
> > + DumpEsrtData ();
> > + }
> >
> > - if (Argv[1][0] == L'-') {
> > - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[1]);
> > - return EFI_UNSUPPORTED;
> > - }
> > + //
> > + // CapsuleApp -P
> > + //
> > + if (ShellCommandLineGetFlag (Package, L"-P")) {
> > + DumpFmpData ();
> > + }
> >
> > - CapsuleFirstIndex = 1;
> > - NoReset = FALSE;
> > - if ((Argc > 1) && (StrCmp(Argv[Argc - 1], L"-NR") == 0)) {
> > - NoReset = TRUE;
> > - CapsuleLastIndex = Argc - 2;
> > - } else {
> > - CapsuleLastIndex = Argc - 1;
> > - }
> > - CapsuleNum = CapsuleLastIndex - CapsuleFirstIndex + 1;
> > + //
> > + // CapsuleApp -S
> > + //
> > + if (ShellCommandLineGetFlag (Package, L"-S")) {
> > + Status = DumpCapsuleStatusVariable ();
> > + }
> > + }
> >
> > - if (CapsuleFirstIndex > CapsuleLastIndex) {
> > - Print(L"CapsuleApp: NO capsule image.\n");
> > - return EFI_UNSUPPORTED;
> > - }
> > - if (CapsuleNum > MAX_CAPSULE_NUM) {
> > - Print(L"CapsuleApp: Too many capsule images.\n");
> > - return EFI_UNSUPPORTED;
> > - }
> > + if (FlagCount == 2) {
> > + //
> > + // CapsuleApp -G <BMP> -O <OutputFileName>
> > + //
> > + if (ShellCommandLineGetFlag (Package, L"-G") &&
> > ShellCommandLineGetFlag (Package, L"-O")) {
> > + BmpFileName = (CHAR16 *)ShellCommandLineGetValue
> > (Package, L"-G");
> > + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> > (Package, L"-O");
> > + if (BmpFileName != NULL && OutputFileName != NULL) {
> > + Status = CreateBmpFmp (BmpFileName, OutputFileName);
> > + } else {
> > + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> > + Status = EFI_UNSUPPORTED;
> > + }
> > + }
> >
> > - ZeroMem(&CapsuleBuffer, sizeof(CapsuleBuffer));
> > - ZeroMem(&FileSize, sizeof(FileSize));
> > - BlockDescriptors = NULL;
> > + //
> > + // CapsuleApp -N <CapsuleFile> -O <OutputFileName>
> > + //
> > + if (ShellCommandLineGetFlag (Package, L"-N") &&
> > ShellCommandLineGetFlag (Package ,L"-O")) {
> > + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> > (Package, L"-N");
> > + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> > (Package, L"-O");
> > + if (CapsuleFileName != NULL && OutputFileName != NULL) {
> > + Status = CreateNestedFmp (CapsuleFileName,
> > OutputFileName);
> > + } else {
> > + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> > + Status = EFI_UNSUPPORTED;
> > + }
> > + }
> > + }
> >
> > - for (Index = 0; Index < CapsuleNum; Index++) {
> > - CapsuleName = Argv[CapsuleFirstIndex + Index];
> > - Status = ReadFileToBuffer(CapsuleName, &FileSize[Index],
> > &CapsuleBuffer[Index]);
> > - if (EFI_ERROR(Status)) {
> > - Print(L"CapsuleApp: capsule image (%s) is not found.\n",
> > CapsuleName);
> > + if (FlagCount == 3) {
> > + //
> > + // CapsuleApp -P <ImageTypeGuid> -I <ImageIndex> -O
> > <OutputFile>
> > + //
> > + if ( ShellCommandLineGetFlag (Package, L"-P") &&
> > + ShellCommandLineGetFlag (Package, L"-I") &&
> > + ShellCommandLineGetFlag (Package, L"-O")
> > + ) {
> > + GuidStr = (CHAR16 *)ShellCommandLineGetValue
> > (Package, L"-P");
> > + IndexStr = (CHAR16 *)ShellCommandLineGetValue
> > (Package, L"-I");
> > + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> > (Package, L"-O");
> > + if (GuidStr != NULL && IndexStr != NULL && OutputFileName !=
> > NULL) {
> > + RStatus = StrToGuid (GuidStr, &ImageTypeGuid);
> > + if (EFI_ERROR (RStatus) || GuidStr[GUID_STRING_LENGTH] !=
> > L'\0') {
> > + Print (L"Invalid ImageTypeId - %s\n", GuidStr);
> > + Status = EFI_INVALID_PARAMETER;
> > + goto Done;
> > + }
> > + ImageIndex = StrDecimalToUintn (IndexStr);
> > + DumpFmpImage (&ImageTypeGuid, ImageIndex,
> > OutputFileName);
> > + } else {
> > + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> > + Status = EFI_UNSUPPORTED;
> > + }
> > + }
> > + }
> > + } else {
> > + if (CapsuleNum > MAX_CAPSULE_NUM) {
> > + Print(L"CapsuleApp: Too many capsule images.\n");
> > + Status = EFI_UNSUPPORTED;
> > goto Done;
> > }
> > - if (!IsValidCapsuleHeader (CapsuleBuffer[Index], FileSize[Index])) {
> > - Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> > CapsuleName);
> > - return EFI_INVALID_PARAMETER;
> > +
> > + if (ShellCommandLineGetFlag (Package, L"-NR")) {
> > + NoResetFlag = TRUE;
> > }
> > - }
> >
> > - //
> > - // Every capsule use 2 descriptor 1 for data 1 for end
> > - //
> > - Status = BuildGatherList(CapsuleBuffer, FileSize, CapsuleNum,
> > &BlockDescriptors);
> > - if (EFI_ERROR(Status)) {
> > - goto Done;
> > - }
> > + for (Index = 0; Index < CapsuleNum; Index++) {
> > + CapsuleFileName = (CHAR16 *)ShellCommandLineGetRawValue
> > (Package, Index + 1);
> > + Status = ReadFileToBuffer (CapsuleFileName,
> > &CapsuleBufferSize[Index], &CapsuleBuffer[Index]);
> > + if (EFI_ERROR (Status)) {
> > + Print (L"CapsuleApp: capsule image (%s) is not found.\n",
> > CapsuleFileName);
> > + goto Done;
> > + }
> > + if (!IsValidCapsuleHeader (CapsuleBuffer[Index],
> > CapsuleBufferSize[Index])) {
> > + Print (L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> > CapsuleFileName);
> > + Status = EFI_INVALID_PARAMETER;
> > + goto Done;
> > + }
> > + }
> >
> > - //
> > - // Call the runtime service capsule.
> > - //
> > - NeedReset = FALSE;
> > - for (Index = 0; Index < CapsuleNum; Index++) {
> > - CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> > CapsuleBuffer[Index];
> > - if ((CapsuleHeaderArray[Index]->Flags &
> > CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> > - NeedReset = TRUE;
> > + //
> > + // Every capsule use 2 descriptor 1 for data 1 for end
> > + //
> > + BlockDescriptors = NULL;
> > + Status = BuildGatherList (CapsuleBuffer, CapsuleBufferSize,
> > CapsuleNum, &BlockDescriptors);
> > + if (EFI_ERROR (Status)) {
> > + Print (L"Build Gather List Fail, %r\n", Status);
> > + goto Done;
> > }
> > - }
> > - CapsuleHeaderArray[CapsuleNum] = NULL;
> >
> > - //
> > - // Inquire platform capability of UpdateCapsule.
> > - //
> > - Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> > CapsuleNum, &MaxCapsuleSize, &ResetType);
> > - if (EFI_ERROR(Status)) {
> > - Print (L"CapsuleApp: failed to query capsule capability - %r\n", Status);
> > - goto Done;
> > - }
> > + //
> > + // Call the runtime service capsule.
> > + //
> > + NeedReset = FALSE;
> > + for (Index = 0; Index < CapsuleNum; Index++) {
> > + CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> > CapsuleBuffer[Index];
> > + if ((CapsuleHeaderArray[Index]->Flags &
> > CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> > + NeedReset = TRUE;
> > + }
> > + }
> > + CapsuleHeaderArray[CapsuleNum] = NULL;
> >
> > - for (Index = 0; Index < CapsuleNum; Index++) {
> > - if (FileSize[Index] > MaxCapsuleSize) {
> > - Print (L"CapsuleApp: capsule is too large to update, %ld is
> > allowed\n", MaxCapsuleSize);
> > - Status = EFI_UNSUPPORTED;
> > + //
> > + // Inquire platform capability of UpdateCapsule.
> > + //
> > + Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> > CapsuleNum, &MaxCapsuleSize, &ResetType);
> > + if (EFI_ERROR (Status)) {
> > + Print (L"CapsuleApp: failed to query capsule capability - %r\n",
> > Status);
> > goto Done;
> > }
> > - }
> >
> > - //
> > - // Check whether the input capsule image has the flag of persist across
> > system reset.
> > - //
> > - if (NeedReset) {
> > - Status =
> > gRT->UpdateCapsule(CapsuleHeaderArray,CapsuleNum,(UINTN)
> > BlockDescriptors);
> > - if (Status != EFI_SUCCESS) {
> > - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> > - goto Done;
> > + for (Index = 0; Index < CapsuleNum; Index++) {
> > + if (CapsuleBufferSize[Index] > MaxCapsuleSize) {
> > + Print (L"CapsuleApp: capsule is too large to update, %ld is
> > allowed\n", MaxCapsuleSize);
> > + Status = EFI_UNSUPPORTED;
> > + goto Done;
> > + }
> > }
> > +
> > //
> > - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> > CAPSULE_FLAGS_INITIATE_RESET,
> > - // a system reset should have been triggered by gRT->UpdateCapsule()
> > calling above.
> > - //
> > - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> > without CAPSULE_FLAGS_INITIATE_RESET,
> > - // check if -NR (no-reset) has been specified or not.
> > + // Check whether the input capsule image has the flag of persist across
> > system reset.
> > //
> > - if (!NoReset) {
> > + if (NeedReset) {
> > + Status = gRT->UpdateCapsule
> > (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> > + if (Status != EFI_SUCCESS) {
> > + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> > + goto Done;
> > + }
> > //
> > - // For capsule who has reset flag and no -NR (no-reset) has been
> > specified, after calling UpdateCapsule service,
> > - // trigger a system reset to process capsule persist across a system
> > reset.
> > + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> > CAPSULE_FLAGS_INITIATE_RESET,
> > + // a system reset should have been triggered by
> > gRT->UpdateCapsule() calling above.
> > //
> > - gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> > - }
> > - } else {
> > - //
> > - // For capsule who has no reset flag, only call UpdateCapsule Service
> > without a
> > - // system reset. The service will process the capsule immediately.
> > - //
> > - Status = gRT->UpdateCapsule
> > (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> > - if (Status != EFI_SUCCESS) {
> > - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> > + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> > without CAPSULE_FLAGS_INITIATE_RESET,
> > + // check if -NR (no-reset) has been specified or not.
> > + //
> > + if (!NoResetFlag) {
> > + //
> > + // For capsule who has reset flag and no -NR (no-reset) has been
> > specified, after calling UpdateCapsule service,
> > + // trigger a system reset to process capsule persist across a
> > system reset.
> > + //
> > + gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> > + }
> > + } else {
> > + //
> > + // For capsule who has no reset flag, only call UpdateCapsule
> > Service without a
> > + // system reset. The service will process the capsule immediately.
> > + //
> > + Status = gRT->UpdateCapsule
> > (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> > + if (Status != EFI_SUCCESS) {
> > + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> > + }
> > }
> > - }
> >
> > - Status = EFI_SUCCESS;
> > + Status = EFI_SUCCESS;
> > + }
> >
> > Done:
> > + if (Package != NULL) {
> > + ShellCommandLineFreeVarList (Package);
> > + }
> > +
> > for (Index = 0; Index < CapsuleNum; Index++) {
> > if (CapsuleBuffer[Index] != NULL) {
> > FreePool (CapsuleBuffer[Index]);
> > diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> > b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> > index 8a21875286..d4edc539cc 100644
> > --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> > +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> > @@ -38,6 +38,7 @@
> > [Packages]
> > MdePkg/MdePkg.dec
> > MdeModulePkg/MdeModulePkg.dec
> > + ShellPkg/ShellPkg.dec
> >
> > [Guids]
> > gEfiCapsuleReportGuid ## CONSUMES ## GUID
> > @@ -61,6 +62,7 @@
> > UefiLib
> > PrintLib
> > BmpSupportLib
> > + ShellLib
> >
> > [UserExtensions.TianoCore."ExtraFiles"]
> > CapsuleAppExtra.uni
> > --
> > 2.16.2.windows.1
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> > https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
2019-01-25 9:24 ` Gao, Liming
2019-01-25 15:36 ` Carsey, Jaben
@ 2019-01-25 22:50 ` Yao, Jiewen
1 sibling, 0 replies; 6+ messages in thread
From: Yao, Jiewen @ 2019-01-25 22:50 UTC (permalink / raw)
To: Gao, Liming, Zhang, Chao B, edk2-devel@lists.01.org
Cc: Wu, Hao A, Chen, Chen A
Exactly. Currently APP is using that to parse parameter.
Would you please clarify why we cannot use the same way?
Thank you
Yao Jiewen
From: Gao, Liming
Sent: Friday, January 25, 2019 5:25 PM
To: Zhang, Chao B <chao.b.zhang@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
Cc: Wu, Hao A <hao.a.wu@intel.com>; Chen, Chen A <chen.a.chen@intel.com>; Gao, Liming <liming.gao@intel.com>
Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
Chao:
CapsuleApp can base on gEfiShellProtocolGuid and gEfiShellParametersProtocolGuid to do it. Current CapsuleApp bases on these two protocols to parse the parameters.
Thanks
Liming
From: Zhang, Chao B
Sent: Friday, January 25, 2019 3:24 PM
To: Yao, Jiewen <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>; edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>; Gao, Liming <liming.gao@intel.com<mailto:liming.gao@intel.com>>
Cc: Wu, Hao A <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>; Chen, Chen A <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>
Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
Jiewen & Liming:
It is a problem. Unlike UiApp. CapsuleApp is supposed to run in Shell. ShellLib provides standard parameter parsing support.
Any suggestion on this?
From: Yao, Jiewen
Sent: Friday, January 25, 2019 2:25 PM
To: Chen, Chen A <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>; edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
Cc: Wu, Hao A <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>; Zhang, Chao B <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
Subject: RE: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter.
Hey
I don't think MdeModulePkg can depend on ShellPkg.
That is why we do not use ShellLib in the first version.
Do we change the package dependency rule?
Thank you
Yao Jiewen
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Chen A Chen
> Sent: Friday, January 25, 2019 2:14 PM
> To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Wu, Hao A <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>; Zhang, Chao B
> <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> Subject: [edk2] [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic
> of parsing parameter.
>
> BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1482
>
> No change functionality, use ShellLib to parsing command line.
>
> Cc: Jian J Wang <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>
> Cc: Hao Wu <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>
> Cc: Zhang Chao B <chao.b.zhang@intel.com<mailto:chao.b.zhang@intel.com>>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Chen A Chen <chen.a.chen@intel.com<mailto:chen.a.chen@intel.com>>
> ---
> MdeModulePkg/Application/CapsuleApp/CapsuleApp.c | 433
> +++++++++++----------
> MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf | 2 +
> 2 files changed, 236 insertions(+), 199 deletions(-)
>
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> index 4d907242f3..acae0fe261 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
> @@ -27,6 +27,7 @@
> #include <Guid/SystemResourceTable.h>
> #include <Guid/FmpCapsule.h>
> #include <IndustryStandard/WindowsUxCapsule.h>
> +#include <Library/ShellLib.h>
>
> #define CAPSULE_HEADER_SIZE 0x20
>
> @@ -39,15 +40,27 @@
>
> #define MAX_CAPSULE_NUM 10
>
> -extern UINTN Argc;
> -extern CHAR16 **Argv;
> -
> //
> // Define how many block descriptors we want to test with.
> //
> UINTN NumberOfDescriptors = 1;
> -UINTN CapsuleFirstIndex;
> -UINTN CapsuleLastIndex;
> +
> +STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
> + {L"-C", TypeFlag},
> + {L"-E", TypeFlag},
> + {L"-S", TypeFlag},
> +
> + {L"-NR", TypeFlag},
> +
> + {L"-G", TypeValue},
> + {L"-O", TypeValue},
> + {L"-N", TypeValue},
> + {L"-D", TypeValue},
> + {L"-P", TypeValue},
> + {L"-I", TypeValue},
> +
> + {NULL, TypeMax}
> + };
>
> /**
> Dump capsule information
> @@ -161,13 +174,12 @@ GetArg (
> **/
> EFI_STATUS
> CreateBmpFmp (
> - VOID
> + IN CHAR16 *BmpName,
> + IN CHAR16
> *OutputCapsuleName
> )
> {
> - CHAR16
> *OutputCapsuleName;
> VOID *BmpBuffer;
> UINTN FileSize;
> - CHAR16 *BmpName;
> UINT8
> *FullCapsuleBuffer;
> UINTN
> FullCapsuleBufferSize;
> EFI_DISPLAY_CAPSULE *DisplayCapsule;
> @@ -191,22 +203,10 @@ CreateBmpFmp (
> // HorizontalResolution >= BMP_IMAGE_HEADER.PixelWidth
> // VerticalResolution >= BMP_IMAGE_HEADER.PixelHeight
>
> - if (Argc != 5) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (StrCmp(Argv[3], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output capsule name.\n");
> - return EFI_UNSUPPORTED;
> - }
> - OutputCapsuleName = Argv[4];
> -
> BmpBuffer = NULL;
> FileSize = 0;
> FullCapsuleBuffer = NULL;
>
> - BmpName = Argv[2];
> Status = ReadFileToBuffer(BmpName, &FileSize, &BmpBuffer);
> if (EFI_ERROR(Status)) {
> Print(L"CapsuleApp: BMP image (%s) is not found.\n", BmpName);
> @@ -425,13 +425,12 @@ IsFmpCapsuleGuid (
> **/
> EFI_STATUS
> CreateNestedFmp (
> - VOID
> + IN CHAR16 *CapsuleName,
> + IN CHAR16
> *OutputCapsuleName
> )
> {
> - CHAR16
> *OutputCapsuleName;
> VOID *CapsuleBuffer;
> UINTN FileSize;
> - CHAR16 *CapsuleName;
> UINT8
> *FullCapsuleBuffer;
> UINTN
> FullCapsuleBufferSize;
> EFI_CAPSULE_HEADER
> *NestedCapsuleHeader;
> @@ -439,22 +438,10 @@ CreateNestedFmp (
> UINT32 FwType;
> EFI_STATUS Status;
>
> - if (Argc != 5) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
> -
> - if (StrCmp(Argv[3], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output capsule name.\n");
> - return EFI_UNSUPPORTED;
> - }
> - OutputCapsuleName = Argv[4];
> -
> CapsuleBuffer = NULL;
> FileSize = 0;
> FullCapsuleBuffer = NULL;
>
> - CapsuleName = Argv[2];
> Status = ReadFileToBuffer(CapsuleName, &FileSize, &CapsuleBuffer);
> if (EFI_ERROR(Status)) {
> Print(L"CapsuleApp: Capsule image (%s) is not found.\n",
> CapsuleName);
> @@ -807,7 +794,7 @@ PrintUsage (
> Print(L" CapsuleApp -G <BMP> -O <Capsule>\n");
> Print(L" CapsuleApp -N <Capsule> -O <NestedCapsule>\n");
> Print(L" CapsuleApp -D <Capsule>\n");
> - Print(L" CapsuleApp -P GET <ImageTypeId> <Index> -O <FileName>\n");
> + Print(L" CapsuleApp -P <ImageTypeId> -I <Index> -O <FileName>\n");
> Print(L"Parameter:\n");
> Print(L" -NR: No reset will be triggered for the capsule with\n");
> Print(L" CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without\n");
> @@ -817,8 +804,7 @@ PrintUsage (
> Print(L" -C: Clear capsule report variable
> (EFI_CAPSULE_REPORT_GUID),\n");
> Print(L" which is defined in UEFI specification.\n");
> Print(L" -P: Dump UEFI FMP protocol info, or get image with
> specified\n");
> - Print(L" ImageTypeId and Index (decimal format) to a file if
> 'GET'\n");
> - Print(L" option is used.\n");
> + Print(L" ImageTypeId and Index (decimal format) to a file\n");
> Print(L" -E: Dump UEFI ESRT table info.\n");
> Print(L" -G: Convert a BMP file to be an UX capsule,\n");
> Print(L" according to Windows Firmware Update document\n");
> @@ -851,206 +837,255 @@ UefiMain (
> {
> EFI_STATUS Status;
> RETURN_STATUS RStatus;
> - UINTN FileSize[MAX_CAPSULE_NUM];
> VOID
> *CapsuleBuffer[MAX_CAPSULE_NUM];
> - EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> EFI_CAPSULE_HEADER
> *CapsuleHeaderArray[MAX_CAPSULE_NUM + 1];
> - UINT64 MaxCapsuleSize;
> + EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockDescriptors;
> EFI_RESET_TYPE ResetType;
> + UINT64 MaxCapsuleSize;
> + LIST_ENTRY *Package;
> + CHAR16 *ProblemParam;
> + CHAR16 *BmpFileName;
> + CHAR16 *CapsuleFileName;
> + CHAR16 *OutputFileName;
> + CHAR16 *GuidStr;
> + CHAR16 *IndexStr;
> + EFI_GUID ImageTypeGuid;
> + BOOLEAN NoResetFlag;
> BOOLEAN NeedReset;
> - BOOLEAN NoReset;
> - CHAR16 *CapsuleName;
> + UINTN
> CapsuleBufferSize[MAX_CAPSULE_NUM];
> UINTN CapsuleNum;
> - UINTN Index;
> - EFI_GUID ImageTypeId;
> UINTN ImageIndex;
> + UINTN FlagCount;
> + UINTN Index;
>
> - Status = GetArg();
> - if (EFI_ERROR(Status)) {
> - Print(L"Please use UEFI SHELL to run this application!\n", Status);
> - return Status;
> - }
> - if (Argc < 2) {
> - PrintUsage();
> - return EFI_UNSUPPORTED;
> + Status = EFI_SUCCESS;
> + NoResetFlag = FALSE;
> + FlagCount = 0;
> +
> + ZeroMem (&CapsuleBuffer, sizeof (CapsuleBuffer));
> + ZeroMem (&CapsuleBufferSize, sizeof (CapsuleBufferSize));
> +
> + Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam,
> TRUE);
> + if (EFI_ERROR (Status)) {
> + PrintUsage ();
> + Status = EFI_UNSUPPORTED;
> + goto Done;
> }
> - if (StrCmp(Argv[1], L"-D") == 0) {
> - if (Argc != 3) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> +
> + for (Index = 0; ParamList[Index].Type != TypeMax; Index++) {
> + if (ShellCommandLineGetFlag (Package, ParamList[Index].Name)) {
> + FlagCount++;
> }
> - Status = DumpCapsule(Argv[2]);
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-G") == 0) {
> - Status = CreateBmpFmp();
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-N") == 0) {
> - Status = CreateNestedFmp();
> - return Status;
> }
> - if (StrCmp(Argv[1], L"-S") == 0) {
> - Status = DumpCapsuleStatusVariable();
> - return EFI_SUCCESS;
> - }
> - if (StrCmp(Argv[1], L"-C") == 0) {
> - Status = ClearCapsuleStatusVariable();
> - return Status;
> - }
> - if (StrCmp(Argv[1], L"-P") == 0) {
> - if (Argc == 2) {
> - DumpFmpData();
> - }
> - if (Argc >= 3) {
> - if (StrCmp(Argv[2], L"GET") != 0) {
> - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[2]);
> - return EFI_UNSUPPORTED;
> - } else {
> - if (Argc != 7) {
> - Print(L"CapsuleApp: Incorrect parameter count.\n");
> - return EFI_UNSUPPORTED;
> - }
>
> - //
> - // FMP->GetImage()
> - //
> - RStatus = StrToGuid (Argv[3], &ImageTypeId);
> - if (RETURN_ERROR (RStatus) ||
> (Argv[3][GUID_STRING_LENGTH] != L'\0')) {
> - Print (L"Invalid ImageTypeId - %s\n", Argv[3]);
> - return EFI_INVALID_PARAMETER;
> - }
> - ImageIndex = StrDecimalToUintn(Argv[4]);
> - if (StrCmp(Argv[5], L"-O") != 0) {
> - Print(L"CapsuleApp: NO output file name.\n");
> - return EFI_UNSUPPORTED;
> + CapsuleNum = ShellCommandLineGetCount (Package) - 1;
> +
> + if (CapsuleNum == 0) {
> + if (FlagCount == 1) {
> + //
> + // CapsuleApp -C
> + //
> + if (ShellCommandLineGetFlag (Package, L"-C")) {
> + Status = ClearCapsuleStatusVariable();
> + }
> +
> + //
> + // CapsuleApp -D <CapsuleFile>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-D")) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-D");
> + if (CapsuleFileName != NULL) {
> + Status = DumpCapsule (CapsuleFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> }
> - DumpFmpImage(&ImageTypeId, ImageIndex, Argv[6]);
> }
> - }
> - return EFI_SUCCESS;
> - }
>
> - if (StrCmp(Argv[1], L"-E") == 0) {
> - DumpEsrtData();
> - return EFI_SUCCESS;
> - }
> + //
> + // CapsuleApp -E
> + //
> + if (ShellCommandLineGetFlag (Package, L"-E")) {
> + DumpEsrtData ();
> + }
>
> - if (Argv[1][0] == L'-') {
> - Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[1]);
> - return EFI_UNSUPPORTED;
> - }
> + //
> + // CapsuleApp -P
> + //
> + if (ShellCommandLineGetFlag (Package, L"-P")) {
> + DumpFmpData ();
> + }
>
> - CapsuleFirstIndex = 1;
> - NoReset = FALSE;
> - if ((Argc > 1) && (StrCmp(Argv[Argc - 1], L"-NR") == 0)) {
> - NoReset = TRUE;
> - CapsuleLastIndex = Argc - 2;
> - } else {
> - CapsuleLastIndex = Argc - 1;
> - }
> - CapsuleNum = CapsuleLastIndex - CapsuleFirstIndex + 1;
> + //
> + // CapsuleApp -S
> + //
> + if (ShellCommandLineGetFlag (Package, L"-S")) {
> + Status = DumpCapsuleStatusVariable ();
> + }
> + }
>
> - if (CapsuleFirstIndex > CapsuleLastIndex) {
> - Print(L"CapsuleApp: NO capsule image.\n");
> - return EFI_UNSUPPORTED;
> - }
> - if (CapsuleNum > MAX_CAPSULE_NUM) {
> - Print(L"CapsuleApp: Too many capsule images.\n");
> - return EFI_UNSUPPORTED;
> - }
> + if (FlagCount == 2) {
> + //
> + // CapsuleApp -G <BMP> -O <OutputFileName>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-G") &&
> ShellCommandLineGetFlag (Package, L"-O")) {
> + BmpFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-G");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (BmpFileName != NULL && OutputFileName != NULL) {
> + Status = CreateBmpFmp (BmpFileName, OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
>
> - ZeroMem(&CapsuleBuffer, sizeof(CapsuleBuffer));
> - ZeroMem(&FileSize, sizeof(FileSize));
> - BlockDescriptors = NULL;
> + //
> + // CapsuleApp -N <CapsuleFile> -O <OutputFileName>
> + //
> + if (ShellCommandLineGetFlag (Package, L"-N") &&
> ShellCommandLineGetFlag (Package ,L"-O")) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-N");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (CapsuleFileName != NULL && OutputFileName != NULL) {
> + Status = CreateNestedFmp (CapsuleFileName,
> OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> + }
>
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - CapsuleName = Argv[CapsuleFirstIndex + Index];
> - Status = ReadFileToBuffer(CapsuleName, &FileSize[Index],
> &CapsuleBuffer[Index]);
> - if (EFI_ERROR(Status)) {
> - Print(L"CapsuleApp: capsule image (%s) is not found.\n",
> CapsuleName);
> + if (FlagCount == 3) {
> + //
> + // CapsuleApp -P <ImageTypeGuid> -I <ImageIndex> -O
> <OutputFile>
> + //
> + if ( ShellCommandLineGetFlag (Package, L"-P") &&
> + ShellCommandLineGetFlag (Package, L"-I") &&
> + ShellCommandLineGetFlag (Package, L"-O")
> + ) {
> + GuidStr = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-P");
> + IndexStr = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-I");
> + OutputFileName = (CHAR16 *)ShellCommandLineGetValue
> (Package, L"-O");
> + if (GuidStr != NULL && IndexStr != NULL && OutputFileName !=
> NULL) {
> + RStatus = StrToGuid (GuidStr, &ImageTypeGuid);
> + if (EFI_ERROR (RStatus) || GuidStr[GUID_STRING_LENGTH] !=
> L'\0') {
> + Print (L"Invalid ImageTypeId - %s\n", GuidStr);
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> + ImageIndex = StrDecimalToUintn (IndexStr);
> + DumpFmpImage (&ImageTypeGuid, ImageIndex,
> OutputFileName);
> + } else {
> + Print (L"CapsuleApp: Incorrect Parameter Count.\n");
> + Status = EFI_UNSUPPORTED;
> + }
> + }
> + }
> + } else {
> + if (CapsuleNum > MAX_CAPSULE_NUM) {
> + Print(L"CapsuleApp: Too many capsule images.\n");
> + Status = EFI_UNSUPPORTED;
> goto Done;
> }
> - if (!IsValidCapsuleHeader (CapsuleBuffer[Index], FileSize[Index])) {
> - Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> CapsuleName);
> - return EFI_INVALID_PARAMETER;
> +
> + if (ShellCommandLineGetFlag (Package, L"-NR")) {
> + NoResetFlag = TRUE;
> }
> - }
>
> - //
> - // Every capsule use 2 descriptor 1 for data 1 for end
> - //
> - Status = BuildGatherList(CapsuleBuffer, FileSize, CapsuleNum,
> &BlockDescriptors);
> - if (EFI_ERROR(Status)) {
> - goto Done;
> - }
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + CapsuleFileName = (CHAR16 *)ShellCommandLineGetRawValue
> (Package, Index + 1);
> + Status = ReadFileToBuffer (CapsuleFileName,
> &CapsuleBufferSize[Index], &CapsuleBuffer[Index]);
> + if (EFI_ERROR (Status)) {
> + Print (L"CapsuleApp: capsule image (%s) is not found.\n",
> CapsuleFileName);
> + goto Done;
> + }
> + if (!IsValidCapsuleHeader (CapsuleBuffer[Index],
> CapsuleBufferSize[Index])) {
> + Print (L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n",
> CapsuleFileName);
> + Status = EFI_INVALID_PARAMETER;
> + goto Done;
> + }
> + }
>
> - //
> - // Call the runtime service capsule.
> - //
> - NeedReset = FALSE;
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> CapsuleBuffer[Index];
> - if ((CapsuleHeaderArray[Index]->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> - NeedReset = TRUE;
> + //
> + // Every capsule use 2 descriptor 1 for data 1 for end
> + //
> + BlockDescriptors = NULL;
> + Status = BuildGatherList (CapsuleBuffer, CapsuleBufferSize,
> CapsuleNum, &BlockDescriptors);
> + if (EFI_ERROR (Status)) {
> + Print (L"Build Gather List Fail, %r\n", Status);
> + goto Done;
> }
> - }
> - CapsuleHeaderArray[CapsuleNum] = NULL;
>
> - //
> - // Inquire platform capability of UpdateCapsule.
> - //
> - Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> CapsuleNum, &MaxCapsuleSize, &ResetType);
> - if (EFI_ERROR(Status)) {
> - Print (L"CapsuleApp: failed to query capsule capability - %r\n", Status);
> - goto Done;
> - }
> + //
> + // Call the runtime service capsule.
> + //
> + NeedReset = FALSE;
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + CapsuleHeaderArray[Index] = (EFI_CAPSULE_HEADER *)
> CapsuleBuffer[Index];
> + if ((CapsuleHeaderArray[Index]->Flags &
> CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
> + NeedReset = TRUE;
> + }
> + }
> + CapsuleHeaderArray[CapsuleNum] = NULL;
>
> - for (Index = 0; Index < CapsuleNum; Index++) {
> - if (FileSize[Index] > MaxCapsuleSize) {
> - Print (L"CapsuleApp: capsule is too large to update, %ld is
> allowed\n", MaxCapsuleSize);
> - Status = EFI_UNSUPPORTED;
> + //
> + // Inquire platform capability of UpdateCapsule.
> + //
> + Status = gRT->QueryCapsuleCapabilities (CapsuleHeaderArray,
> CapsuleNum, &MaxCapsuleSize, &ResetType);
> + if (EFI_ERROR (Status)) {
> + Print (L"CapsuleApp: failed to query capsule capability - %r\n",
> Status);
> goto Done;
> }
> - }
>
> - //
> - // Check whether the input capsule image has the flag of persist across
> system reset.
> - //
> - if (NeedReset) {
> - Status =
> gRT->UpdateCapsule(CapsuleHeaderArray,CapsuleNum,(UINTN)
> BlockDescriptors);
> - if (Status != EFI_SUCCESS) {
> - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> - goto Done;
> + for (Index = 0; Index < CapsuleNum; Index++) {
> + if (CapsuleBufferSize[Index] > MaxCapsuleSize) {
> + Print (L"CapsuleApp: capsule is too large to update, %ld is
> allowed\n", MaxCapsuleSize);
> + Status = EFI_UNSUPPORTED;
> + goto Done;
> + }
> }
> +
> //
> - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> CAPSULE_FLAGS_INITIATE_RESET,
> - // a system reset should have been triggered by gRT->UpdateCapsule()
> calling above.
> - //
> - // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without CAPSULE_FLAGS_INITIATE_RESET,
> - // check if -NR (no-reset) has been specified or not.
> + // Check whether the input capsule image has the flag of persist across
> system reset.
> //
> - if (!NoReset) {
> + if (NeedReset) {
> + Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> + if (Status != EFI_SUCCESS) {
> + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + goto Done;
> + }
> //
> - // For capsule who has reset flag and no -NR (no-reset) has been
> specified, after calling UpdateCapsule service,
> - // trigger a system reset to process capsule persist across a system
> reset.
> + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET +
> CAPSULE_FLAGS_INITIATE_RESET,
> + // a system reset should have been triggered by
> gRT->UpdateCapsule() calling above.
> //
> - gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> - }
> - } else {
> - //
> - // For capsule who has no reset flag, only call UpdateCapsule Service
> without a
> - // system reset. The service will process the capsule immediately.
> - //
> - Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> - if (Status != EFI_SUCCESS) {
> - Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + // For capsule with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and
> without CAPSULE_FLAGS_INITIATE_RESET,
> + // check if -NR (no-reset) has been specified or not.
> + //
> + if (!NoResetFlag) {
> + //
> + // For capsule who has reset flag and no -NR (no-reset) has been
> specified, after calling UpdateCapsule service,
> + // trigger a system reset to process capsule persist across a
> system reset.
> + //
> + gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);
> + }
> + } else {
> + //
> + // For capsule who has no reset flag, only call UpdateCapsule
> Service without a
> + // system reset. The service will process the capsule immediately.
> + //
> + Status = gRT->UpdateCapsule
> (CapsuleHeaderArray,CapsuleNum,(UINTN) BlockDescriptors);
> + if (Status != EFI_SUCCESS) {
> + Print (L"CapsuleApp: failed to update capsule - %r\n", Status);
> + }
> }
> - }
>
> - Status = EFI_SUCCESS;
> + Status = EFI_SUCCESS;
> + }
>
> Done:
> + if (Package != NULL) {
> + ShellCommandLineFreeVarList (Package);
> + }
> +
> for (Index = 0; Index < CapsuleNum; Index++) {
> if (CapsuleBuffer[Index] != NULL) {
> FreePool (CapsuleBuffer[Index]);
> diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> index 8a21875286..d4edc539cc 100644
> --- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf
> @@ -38,6 +38,7 @@
> [Packages]
> MdePkg/MdePkg.dec
> MdeModulePkg/MdeModulePkg.dec
> + ShellPkg/ShellPkg.dec
>
> [Guids]
> gEfiCapsuleReportGuid ## CONSUMES ## GUID
> @@ -61,6 +62,7 @@
> UefiLib
> PrintLib
> BmpSupportLib
> + ShellLib
>
> [UserExtensions.TianoCore."ExtraFiles"]
> CapsuleAppExtra.uni
> --
> 2.16.2.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-01-25 22:50 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-25 6:13 [PATCH 1/3] MdeModulePkg/CapsuleApp: Refine code logic of parsing parameter Chen A Chen
2019-01-25 6:24 ` Yao, Jiewen
2019-01-25 7:23 ` Zhang, Chao B
2019-01-25 9:24 ` Gao, Liming
2019-01-25 15:36 ` Carsey, Jaben
2019-01-25 22:50 ` Yao, Jiewen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox