]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
MdeModulePkg/CapsuleApp: Enhance CapsuleApp to support Capsule-on-Disk
[mirror_edk2.git] / MdeModulePkg / Application / CapsuleApp / CapsuleApp.c
index e1e48befc2de8895142af8d1cd9a0b95c0d358eb..896acd3304c90e11b8fdac33c1cd0d5aa51c91df 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   A shell application that triggers capsule update process.\r
 \r
-  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -70,7 +70,7 @@ DumpCapsule (
   @retval EFI_UNSUPPORTED        Input parameter is not valid.\r
 **/\r
 EFI_STATUS\r
-DmpCapsuleStatusVariable (\r
+DumpCapsuleStatusVariable (\r
   VOID\r
   );\r
 \r
@@ -106,6 +106,46 @@ DumpEsrtData (
   VOID\r
   );\r
 \r
+/**\r
+  Dump Provisioned Capsule.\r
+\r
+  @param[in]  DumpCapsuleInfo  The flag to indicate whether to dump the capsule inforomation.\r
+**/\r
+VOID\r
+DumpProvisionedCapsule (\r
+  IN BOOLEAN                      DumpCapsuleInfo\r
+  );\r
+\r
+/**\r
+  Dump all EFI System Partition.\r
+**/\r
+VOID\r
+DumpAllEfiSysPartition (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Process Capsule On Disk.\r
+\r
+  @param[in]  CapsuleBuffer       An array of pointer to capsule images\r
+  @param[in]  CapsuleBufferSize   An array of UINTN to capsule images size\r
+  @param[in]  FilePath            An array of capsule images file path\r
+  @param[in]  Map                 File system mapping string\r
+  @param[in]  CapsuleNum          The count of capsule images\r
+\r
+  @retval EFI_SUCCESS       Capsule on disk success.\r
+  @retval others            Capsule on disk fail.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessCapsuleOnDisk (\r
+  IN VOID                          **CapsuleBuffer,\r
+  IN UINTN                         *CapsuleBufferSize,\r
+  IN CHAR16                        **FilePath,\r
+  IN CHAR16                        *Map,\r
+  IN UINTN                         CapsuleNum\r
+  );\r
+\r
 /**\r
   Read a file.\r
 \r
@@ -193,7 +233,7 @@ CreateBmpFmp (
   // VerticalResolution   >= BMP_IMAGE_HEADER.PixelHeight\r
 \r
   if (Argc != 5) {\r
-    Print(L"CapsuleApp: Invalid Parameter.\n");\r
+    Print(L"CapsuleApp: Incorrect parameter count.\n");\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -362,6 +402,60 @@ GetEsrtFwType (
   return ESRT_FW_TYPE_UNKNOWN;\r
 }\r
 \r
+/**\r
+  Validate if it is valid capsule header\r
+\r
+  This function assumes the caller provided correct CapsuleHeader pointer\r
+  and CapsuleSize.\r
+\r
+  This function validates the fields in EFI_CAPSULE_HEADER.\r
+\r
+  @param[in] CapsuleHeader  Points to a capsule header.\r
+  @param[in] CapsuleSize    Size of the whole capsule image.\r
+\r
+**/\r
+BOOLEAN\r
+IsValidCapsuleHeader (\r
+  IN EFI_CAPSULE_HEADER     *CapsuleHeader,\r
+  IN UINT64                 CapsuleSize\r
+  )\r
+{\r
+  if (CapsuleSize < sizeof (EFI_CAPSULE_HEADER)) {\r
+    return FALSE;\r
+  }\r
+  if (CapsuleHeader->CapsuleImageSize != CapsuleSize) {\r
+    return FALSE;\r
+  }\r
+  if (CapsuleHeader->HeaderSize > CapsuleHeader->CapsuleImageSize) {\r
+    return FALSE;\r
+  }\r
+  if (CapsuleHeader->HeaderSize < sizeof (EFI_CAPSULE_HEADER)) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Return if this CapsuleGuid is a FMP capsule GUID or not.\r
+\r
+  @param[in] CapsuleGuid A pointer to EFI_GUID\r
+\r
+  @retval TRUE  It is a FMP capsule GUID.\r
+  @retval FALSE It is not a FMP capsule GUID.\r
+**/\r
+BOOLEAN\r
+IsFmpCapsuleGuid (\r
+  IN EFI_GUID  *CapsuleGuid\r
+  )\r
+{\r
+  if (CompareGuid(&gEfiFmpCapsuleGuid, CapsuleGuid)) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   Append a capsule header on top of current image.\r
   This function follows Windows UEFI Firmware Update Platform document.\r
@@ -387,7 +481,7 @@ CreateNestedFmp (
   EFI_STATUS                                    Status;\r
 \r
   if (Argc != 5) {\r
-    Print(L"CapsuleApp: Invalid Parameter.\n");\r
+    Print(L"CapsuleApp: Incorrect parameter count.\n");\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -407,15 +501,28 @@ CreateNestedFmp (
     Print(L"CapsuleApp: Capsule image (%s) is not found.\n", CapsuleName);\r
     goto Done;\r
   }\r
+  if (!IsValidCapsuleHeader (CapsuleBuffer, FileSize)) {\r
+    Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n", CapsuleName);\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  }\r
+\r
+  if (!IsFmpCapsuleGuid (&((EFI_CAPSULE_HEADER *) CapsuleBuffer)->CapsuleGuid)) {\r
+    Print(L"CapsuleApp: Capsule image (%s) is not a FMP capsule.\n", CapsuleName);\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  }\r
 \r
   ImageTypeId = GetCapsuleImageTypeId(CapsuleBuffer);\r
   if (ImageTypeId == NULL) {\r
     Print(L"CapsuleApp: Capsule ImageTypeId is not found.\n");\r
+    Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
   }\r
   FwType = GetEsrtFwType(ImageTypeId);\r
   if ((FwType != ESRT_FW_TYPE_SYSTEMFIRMWARE) && (FwType != ESRT_FW_TYPE_DEVICEFIRMWARE)) {\r
     Print(L"CapsuleApp: Capsule FwType is invalid.\n");\r
+    Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
   }\r
 \r
@@ -431,7 +538,7 @@ CreateNestedFmp (
   ZeroMem(NestedCapsuleHeader, NESTED_CAPSULE_HEADER_SIZE);\r
   CopyGuid(&NestedCapsuleHeader->CapsuleGuid, ImageTypeId);\r
   NestedCapsuleHeader->HeaderSize = NESTED_CAPSULE_HEADER_SIZE;\r
-  NestedCapsuleHeader->Flags = (FwType == ESRT_FW_TYPE_DEVICEFIRMWARE) ? SYSTEM_FIRMWARE_FLAG : DEVICE_FIRMWARE_FLAG;\r
+  NestedCapsuleHeader->Flags = (FwType == ESRT_FW_TYPE_SYSTEMFIRMWARE) ? SYSTEM_FIRMWARE_FLAG : DEVICE_FIRMWARE_FLAG;\r
   NestedCapsuleHeader->CapsuleImageSize = (UINT32)FullCapsuleBufferSize;\r
 \r
   CopyMem((UINT8 *)NestedCapsuleHeader + NestedCapsuleHeader->HeaderSize, CapsuleBuffer, FileSize);\r
@@ -466,11 +573,13 @@ ClearCapsuleStatusVariable (
   UINT32                              Index;\r
   CHAR16                              CapsuleVarName[20];\r
   CHAR16                              *TempVarName;\r
+  BOOLEAN                             Found;\r
 \r
   StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule");\r
   TempVarName = CapsuleVarName + StrLen (CapsuleVarName);\r
   Index = 0;\r
 \r
+  Found = FALSE;\r
   while (TRUE) {\r
     UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index);\r
 \r
@@ -481,12 +590,15 @@ ClearCapsuleStatusVariable (
                     0,\r
                     (VOID *)NULL\r
                     );\r
-    if (EFI_ERROR(Status)) {\r
+    if (Status == EFI_NOT_FOUND) {\r
       //\r
-      // There is no capsule variables, quit\r
+      // There is no more capsule variables, quit\r
       //\r
       break;\r
     }\r
+    Found = TRUE;\r
+\r
+    Print (L"Clear %s %r\n", CapsuleVarName, Status);\r
 \r
     Index++;\r
     if (Index > 0xFFFF) {\r
@@ -494,6 +606,10 @@ ClearCapsuleStatusVariable (
     }\r
   }\r
 \r
+  if (!Found) {\r
+    Print (L"No any Capsule#### variable found\n");\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -724,11 +840,14 @@ PrintUsage (
   )\r
 {\r
   Print(L"CapsuleApp:  usage\n");\r
-  Print(L"  CapsuleApp <Capsule...> [-NR]\n");\r
+  Print(L"  CapsuleApp <Capsule...> [-NR] [-OD [FSx]]\n");\r
   Print(L"  CapsuleApp -S\n");\r
   Print(L"  CapsuleApp -C\n");\r
   Print(L"  CapsuleApp -P\n");\r
   Print(L"  CapsuleApp -E\n");\r
+  Print(L"  CapsuleApp -L\n");\r
+  Print(L"  CapsuleApp -L INFO\n");\r
+  Print(L"  CapsuleApp -F\n");\r
   Print(L"  CapsuleApp -G <BMP> -O <Capsule>\n");\r
   Print(L"  CapsuleApp -N <Capsule> -O <NestedCapsule>\n");\r
   Print(L"  CapsuleApp -D <Capsule>\n");\r
@@ -736,19 +855,26 @@ PrintUsage (
   Print(L"Parameter:\n");\r
   Print(L"  -NR: No reset will be triggered for the capsule\n");\r
   Print(L"       with CAPSULE_FLAGS_PERSIST_ACROSS_RESET and without CAPSULE_FLAGS_INITIATE_RESET.\n");\r
+  Print(L"  -OD: Delivery of Capsules via file on Mass Storage device.");\r
   Print(L"  -S:  Dump capsule report variable (EFI_CAPSULE_REPORT_GUID),\n");\r
   Print(L"       which is defined in UEFI specification.\n");\r
-  Print(L"  -C:  Clear capsule report variable (EFI_CAPSULE_RPORT_GUID),\n");\r
+  Print(L"  -C:  Clear capsule report variable (EFI_CAPSULE_REPORT_GUID),\n");\r
   Print(L"       which is defined in UEFI specification.\n");\r
-  Print(L"  -P:  Dump UEFI FMP protocol info.\n");\r
+  Print(L"  -P:  Dump UEFI FMP protocol info, or get image with specified\n");\r
+  Print(L"       ImageTypeId and Index (decimal format) to a file if 'GET'\n");\r
+  Print(L"       option is used.\n");\r
   Print(L"  -E:  Dump UEFI ESRT table info.\n");\r
-  Print(L"  -G:  Convert a BMP file to be a UX capsule,\n");\r
+  Print(L"  -L:  Dump provisioned capsule image information.\n");\r
+  Print(L"  -F:  Dump all EFI System Partition.\n");\r
+  Print(L"  -G:  Convert a BMP file to be an UX capsule,\n");\r
   Print(L"       according to Windows Firmware Update document\n");\r
-  Print(L"  -N:  Append a Capsule Header to an existing capsule image,\n");\r
+  Print(L"  -N:  Append a Capsule Header to an existing FMP capsule image\n");\r
+  Print(L"       with its ImageTypeId supported by the system,\n");\r
   Print(L"       according to Windows Firmware Update document\n");\r
   Print(L"  -O:  Output new Capsule file name\n");\r
-  Print(L"  -D:  Dump Capsule image header information and FMP header information,\n");\r
-  Print(L"       if it is an FMP capsule.\n");\r
+  Print(L"  -D:  Dump Capsule image header information, image payload\n");\r
+  Print(L"       information if it is an UX capsule and FMP header\n");\r
+  Print(L"       information if it is a FMP capsule.\n");\r
 }\r
 \r
 /**\r
@@ -758,7 +884,8 @@ PrintUsage (
   @param[in]  SystemTable     The system table.\r
 \r
   @retval EFI_SUCCESS            Command completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  Command usage error.\r
+  @retval EFI_UNSUPPORTED        Command usage unsupported.\r
+  @retval EFI_INVALID_PARAMETER  Command usage invalid.\r
   @retval EFI_NOT_FOUND          The input file can't be found.\r
 **/\r
 EFI_STATUS\r
@@ -770,17 +897,27 @@ UefiMain (
 {\r
   EFI_STATUS                    Status;\r
   RETURN_STATUS                 RStatus;\r
-  UINTN                         FileSize[MAX_CAPSULE_NUM];\r
+  UINTN                         CapsuleBufferSize[MAX_CAPSULE_NUM];\r
   VOID                          *CapsuleBuffer[MAX_CAPSULE_NUM];\r
   EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockDescriptors;\r
-  EFI_CAPSULE_HEADER             *CapsuleHeaderArray[MAX_CAPSULE_NUM + 1];\r
-  UINT64                         MaxCapsuleSize;\r
-  EFI_RESET_TYPE                 ResetType;\r
-  BOOLEAN                        NeedReset;\r
-  BOOLEAN                        NoReset;\r
-  CHAR16                         *CapsuleName;\r
-  UINTN                          CapsuleNum;\r
-  UINTN                          Index;\r
+  EFI_CAPSULE_HEADER            *CapsuleHeaderArray[MAX_CAPSULE_NUM + 1];\r
+  UINT64                        MaxCapsuleSize;\r
+  EFI_RESET_TYPE                ResetType;\r
+  BOOLEAN                       NeedReset;\r
+  BOOLEAN                       NoReset;\r
+  BOOLEAN                       CapsuleOnDisk;\r
+  CHAR16                        *CapsuleName;\r
+  CHAR16                        *CapsuleNames[MAX_CAPSULE_NUM];\r
+  CHAR16                        *MapFsStr;\r
+  UINTN                         CapsuleNum;\r
+  UINTN                         Index;\r
+  UINTN                         ParaOdIndex;\r
+  UINTN                         ParaNrIndex;\r
+  EFI_GUID                      ImageTypeId;\r
+  UINTN                         ImageIndex;\r
+\r
+  MapFsStr = NULL;\r
+  CapsuleNum = 0;\r
 \r
   Status = GetArg();\r
   if (EFI_ERROR(Status)) {\r
@@ -789,9 +926,13 @@ UefiMain (
   }\r
   if (Argc < 2) {\r
     PrintUsage();\r
-    return EFI_INVALID_PARAMETER;\r
+    return EFI_UNSUPPORTED;\r
   }\r
   if (StrCmp(Argv[1], L"-D") == 0) {\r
+    if (Argc != 3) {\r
+      Print(L"CapsuleApp: Incorrect parameter count.\n");\r
+      return EFI_UNSUPPORTED;\r
+    }\r
     Status = DumpCapsule(Argv[2]);\r
     return Status;\r
   }\r
@@ -804,7 +945,7 @@ UefiMain (
     return Status;\r
   }\r
   if (StrCmp(Argv[1], L"-S") == 0) {\r
-    Status = DmpCapsuleStatusVariable();\r
+    Status = DumpCapsuleStatusVariable();\r
     return EFI_SUCCESS;\r
   }\r
   if (StrCmp(Argv[1], L"-C") == 0) {\r
@@ -816,9 +957,15 @@ UefiMain (
       DumpFmpData();\r
     }\r
     if (Argc >= 3) {\r
-      if (StrCmp(Argv[2], L"GET") == 0) {\r
-        EFI_GUID  ImageTypeId;\r
-        UINTN     ImageIndex;\r
+      if (StrCmp(Argv[2], L"GET") != 0) {\r
+        Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[2]);\r
+        return EFI_UNSUPPORTED;\r
+      } else {\r
+        if (Argc != 7) {\r
+          Print(L"CapsuleApp: Incorrect parameter count.\n");\r
+          return EFI_UNSUPPORTED;\r
+        }\r
+\r
         //\r
         // FMP->GetImage()\r
         //\r
@@ -828,25 +975,92 @@ UefiMain (
           return EFI_INVALID_PARAMETER;\r
         }\r
         ImageIndex = StrDecimalToUintn(Argv[4]);\r
-        if (StrCmp(Argv[5], L"-O") == 0) {\r
-          DumpFmpImage(&ImageTypeId, ImageIndex, Argv[6]);\r
+        if (StrCmp(Argv[5], L"-O") != 0) {\r
+          Print(L"CapsuleApp: NO output file name.\n");\r
+          return EFI_UNSUPPORTED;\r
         }\r
+        DumpFmpImage(&ImageTypeId, ImageIndex, Argv[6]);\r
       }\r
     }\r
     return EFI_SUCCESS;\r
   }\r
+\r
   if (StrCmp(Argv[1], L"-E") == 0) {\r
     DumpEsrtData();\r
     return EFI_SUCCESS;\r
   }\r
+\r
+  if (StrCmp(Argv[1], L"-L") == 0) {\r
+    if (Argc >= 3 && StrCmp(Argv[2], L"INFO") == 0) {\r
+      DumpProvisionedCapsule(TRUE);\r
+    } else {\r
+      DumpProvisionedCapsule(FALSE);\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (StrCmp(Argv[1], L"-F") == 0) {\r
+    DumpAllEfiSysPartition();\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (Argv[1][0] == L'-') {\r
+    Print(L"CapsuleApp: Unrecognized option(%s).\n", Argv[1]);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   CapsuleFirstIndex = 1;\r
   NoReset = FALSE;\r
-  if ((Argc > 1) && (StrCmp(Argv[Argc - 1], L"-NR") == 0)) {\r
-    NoReset = TRUE;\r
-    CapsuleLastIndex = Argc - 2;\r
+  CapsuleOnDisk = FALSE;\r
+  ParaOdIndex = 0;\r
+  ParaNrIndex = 0;\r
+\r
+  for (Index = 1; Index < Argc; Index++) {\r
+    if (StrCmp(Argv[Index], L"-OD") == 0) {\r
+      ParaOdIndex = Index;\r
+      CapsuleOnDisk = TRUE;\r
+    } else if (StrCmp(Argv[Index], L"-NR") == 0) {\r
+      ParaNrIndex = Index;\r
+      NoReset = TRUE;\r
+    }\r
+  }\r
+\r
+  if (ParaOdIndex != 0) {\r
+    if (ParaOdIndex == Argc - 1) {\r
+      MapFsStr = NULL;\r
+    } else if (ParaOdIndex == Argc - 2) {\r
+      MapFsStr = Argv[Argc-1];\r
+    } else {\r
+      Print (L"CapsuleApp: Invalid Position for -OD Options\n");\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (ParaNrIndex != 0) {\r
+      if (ParaNrIndex + 1 == ParaOdIndex) {\r
+        CapsuleLastIndex = ParaNrIndex - 1;\r
+      } else {\r
+        Print (L"CapsuleApp: Invalid Position for -NR Options\n");\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+    } else {\r
+      CapsuleLastIndex = ParaOdIndex - 1;\r
+    }\r
   } else {\r
-    CapsuleLastIndex = Argc - 1;\r
+    if (ParaNrIndex != 0) {\r
+      if (ParaNrIndex == Argc -1) {\r
+        CapsuleLastIndex = ParaNrIndex - 1;\r
+      } else {\r
+        Print (L"CapsuleApp: Invalid Position for -NR Options\n");\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+    } else {\r
+      CapsuleLastIndex = Argc - 1;\r
+    }\r
   }\r
+\r
   CapsuleNum = CapsuleLastIndex - CapsuleFirstIndex + 1;\r
 \r
   if (CapsuleFirstIndex > CapsuleLastIndex) {\r
@@ -859,22 +1073,27 @@ UefiMain (
   }\r
 \r
   ZeroMem(&CapsuleBuffer, sizeof(CapsuleBuffer));\r
-  ZeroMem(&FileSize, sizeof(FileSize));\r
+  ZeroMem(&CapsuleBufferSize, sizeof(CapsuleBufferSize));\r
   BlockDescriptors = NULL;\r
 \r
   for (Index = 0; Index < CapsuleNum; Index++) {\r
     CapsuleName = Argv[CapsuleFirstIndex + Index];\r
-    Status = ReadFileToBuffer(CapsuleName, &FileSize[Index], &CapsuleBuffer[Index]);\r
+    Status = ReadFileToBuffer(CapsuleName, &CapsuleBufferSize[Index], &CapsuleBuffer[Index]);\r
     if (EFI_ERROR(Status)) {\r
       Print(L"CapsuleApp: capsule image (%s) is not found.\n", CapsuleName);\r
       goto Done;\r
     }\r
+    if (!IsValidCapsuleHeader (CapsuleBuffer[Index], CapsuleBufferSize[Index])) {\r
+      Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n", CapsuleName);\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    CapsuleNames[Index] = CapsuleName;\r
   }\r
 \r
   //\r
   // Every capsule use 2 descriptor 1 for data 1 for end\r
   //\r
-  Status = BuildGatherList(CapsuleBuffer, FileSize, CapsuleNum, &BlockDescriptors);\r
+  Status = BuildGatherList(CapsuleBuffer, CapsuleBufferSize, CapsuleNum, &BlockDescriptors);\r
   if (EFI_ERROR(Status)) {\r
     goto Done;\r
   }\r
@@ -901,13 +1120,30 @@ UefiMain (
   }\r
 \r
   for (Index = 0; Index < CapsuleNum; Index++) {\r
-    if (FileSize[Index] > MaxCapsuleSize) {\r
+    if (CapsuleBufferSize[Index] > MaxCapsuleSize) {\r
       Print (L"CapsuleApp: capsule is too large to update, %ld is allowed\n", MaxCapsuleSize);\r
       Status = EFI_UNSUPPORTED;\r
       goto Done;\r
     }\r
   }\r
 \r
+  //\r
+  // Check whether is capsule on disk.\r
+  //\r
+  if (CapsuleOnDisk) {\r
+    Status = ProcessCapsuleOnDisk (CapsuleBuffer, CapsuleBufferSize, CapsuleNames, MapFsStr, CapsuleNum);\r
+    if (Status != EFI_SUCCESS) {\r
+      Print (L"CapsuleApp: failed to update capsule - %r\n", Status);\r
+      goto Done;\r
+    } else {\r
+      if (!NoReset) {\r
+        gRT->ResetSystem (ResetType, EFI_SUCCESS, 0, NULL);\r
+      } else {\r
+        goto Done;\r
+      }\r
+    }\r
+  }\r
+\r
   //\r
   // Check whether the input capsule image has the flag of persist across system reset.\r
   //\r