public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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