* [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