Fix the bug to support PI not compressed compression section.
[efi/basetools/.git] / Source / C / GenSec / GenSec.c
index 92b4bd9..8c4f874 100644 (file)
@@ -1,6 +1,6 @@
-/*++\r
+/** @file\r
 \r
-Copyright (c) 2004, Intel Corporation                                                         \r
+Copyright (c) 2004 - 2010, Intel Corporation                                                         \r
 All rights reserved. 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
@@ -15,34 +15,36 @@ Module Name:
 \r
 Abstract:\r
 \r
-  Creates output file that is a properly formed section per the FV spec.\r
+  Creates output file that is a properly formed section per the PI spec.\r
 \r
---*/\r
+**/\r
 \r
 #include <stdio.h>\r
 #include <stdlib.h>\r
 #include <string.h>\r
+#include <ctype.h>\r
 \r
 #include <Common/UefiBaseTypes.h>\r
-#include <Common/FirmwareVolumeImageFormat.h>\r
+#include <Common/PiFirmwareFile.h>\r
 #include <Protocol/GuidedSectionExtraction.h>\r
+#include <IndustryStandard/PeImage.h>\r
 \r
 #include "CommonLib.h"\r
 #include "Compress.h"\r
 #include "Crc32.h"\r
 #include "EfiUtilityMsgs.h"\r
+#include "ParseInf.h"\r
 \r
 //\r
 // GenSec Tool Information\r
 //\r
 #define UTILITY_NAME            "GenSec"\r
-#define UTILITY_MAJOR_VERSION   1\r
-#define UTILITY_MINOR_VERSION   0\r
+#define UTILITY_MAJOR_VERSION   0\r
+#define UTILITY_MINOR_VERSION   1\r
 \r
-#define MAXIMUM_INPUT_FILE_NUM  10\r
 #define MAX_SECTION_SIZE        0x1000000\r
 \r
-CHAR8      *SectionTypeName[] = {\r
+STATIC CHAR8      *mSectionTypeName[] = {\r
   NULL,                                 // 0x00 - reserved\r
   "EFI_SECTION_COMPRESSION",            // 0x01\r
   "EFI_SECTION_GUID_DEFINED",           // 0x02\r
@@ -70,11 +72,19 @@ CHAR8      *SectionTypeName[] = {
   "EFI_SECTION_FREEFORM_SUBTYPE_GUID",  // 0x18\r
   "EFI_SECTION_RAW",                    // 0x19\r
   NULL,                                 // 0x1A\r
-  "EFI_SECTION_PEI_DEPEX"               // 0x1B\r
+  "EFI_SECTION_PEI_DEPEX",              // 0x1B\r
+  "EFI_SECTION_SMM_DEPEX"               // 0x1C\r
 };\r
 \r
-CHAR8      *CompressionTypeName[]    = { "PI_NONE", "PI_STD" };\r
-CHAR8      *GUIDedSectionAttribue[]  = { NULL, "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};\r
+STATIC CHAR8      *mCompressionTypeName[]    = { "PI_NONE", "PI_STD" };\r
+\r
+#define EFI_GUIDED_SECTION_NONE 0x80\r
+STATIC CHAR8      *mGUIDedSectionAttribue[]  = { "NONE", "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};\r
+\r
+STATIC CHAR8 *mAlignName[] = {\r
+  "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",\r
+  "1K", "2K", "4K", "8K", "16K", "32K", "64K"\r
+};\r
 \r
 //\r
 // Crc32 GUID section related definitions.\r
@@ -84,12 +94,12 @@ typedef struct {
   UINT32                    CRC32Checksum;\r
 } CRC32_SECTION_HEADER;\r
 \r
-EFI_GUID  gZeroGuid                 = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
-EFI_GUID  gEfiCrc32SectionGuid      = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
+STATIC EFI_GUID  mZeroGuid                 = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
+STATIC EFI_GUID  mEfiCrc32SectionGuid      = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
 \r
 STATIC\r
 VOID \r
-Version(\r
+Version (\r
   VOID\r
   )\r
 /*++\r
@@ -108,8 +118,7 @@ Returns:
   \r
 --*/ \r
 {\r
-  printf ("%s v%d.%d - EDKII Utility to create output file with formed section per the PI spec.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
-  printf ("Copyright (c) 2007 Intel Corporation. All rights reserved.\n");\r
+  fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
 }\r
 \r
 STATIC\r
@@ -117,60 +126,114 @@ VOID
 Usage (\r
   VOID\r
   )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Print Help message.\r
+\r
+Arguments:\r
+\r
+  VOID\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
 {\r
-  Version();\r
-\r
-  printf ("\nUsage: " UTILITY_NAME " [inputfilename]\n\\r
-        -o, --outputfile [FileName]\n\\r
-        -s, --SectionType <EFI_SECTION_COMPRESSION|\n\\r
-                          EFI_SECTION_GUID_DEFINED|\n\\r
-                          EFI_SECTION_PE32|\n\\r
-                          EFI_SECTION_PIC|\n\\r
-                          EFI_SECTION_TE|\n\\r
-                          EFI_SECTION_DXE_DEPEX|\n\\r
-                          EFI_SECTION_VERSION|\n\\r
-                          EFI_SECTION_USER_INTERFACE|\n\\r
-                          EFI_SECTION_COMPATIBILITY16|\n\\r
-                          EFI_SECTION_FIRMWARE_VOLUME_IMAGE|\n\\r
-                          EFI_SECTION_FREEFORM_SUBTYPE_GUID|\n\\r
-                          EFI_SECTION_RAW|\n\\r
-                          EFI_SECTION_PEI_DEPEX>\n\\r
-        -c, --compress <PI_NONE|PI_STD>\n\\r
-        -g, --vendorguid [GuidValue (########-####-####-####-############)]\n\\r
-        -r, --attributes <PROCESSING_REQUIRED|AUTH_STATUS_VALID>\n\\r
-        -n, --name \"string\"\n\\r
-        -j, --buildnumber #### (0000~9999)\n\\r
-        -h, --help\n\\r
-        -V, --version\n");\r
+  //\r
+  // Summary usage\r
+  //\r
+  fprintf (stdout, "\nUsage: %s [options] [input_file]\n\n", UTILITY_NAME);\r
+  \r
+  //\r
+  // Copyright declaration\r
+  // \r
+  fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");\r
+\r
+  //\r
+  // Details Option\r
+  //\r
+  fprintf (stdout, "Options:\n");\r
+  fprintf (stdout, "  -o FileName, --outputfile FileName\n\\r
+                        File is the SectionFile to be created.\n");\r
+  fprintf (stdout, "  -s [SectionType], --sectiontype [SectionType]\n\\r
+                        SectionType defined in PI spec is one type of\n\\r
+                        EFI_SECTION_COMPRESSION, EFI_SECTION_GUID_DEFINED,\n\\r
+                        EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE,\n\\r
+                        EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16,\n\\r
+                        EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION,\n\\r
+                        EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW,\n\\r
+                        EFI_SECTION_FREEFORM_SUBTYPE_GUID,\n\\r
+                        EFI_SECTION_PEI_DEPEX, EFI_SECTION_SMM_DEPEX.\n\\r
+                        if -s option is not given, \n\\r
+                        EFI_SECTION_ALL is default section type.\n");\r
+  fprintf (stdout, "  -c [Type], --compress [Type]\n\\r
+                        Compress method type can be PI_NONE or PI_STD.\n\\r
+                        if -c option is not given, PI_STD is default type.\n"); \r
+  fprintf (stdout, "  -g GuidValue, --vendor GuidValue\n\\r
+                        GuidValue is one specific vendor guid value.\n\\r
+                        Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
+  fprintf (stdout, "  -l GuidHeaderLength, --HeaderLength GuidHeaderLength\n\\r
+                        GuidHeaderLength is the size of header of guided data\n");\r
+  fprintf (stdout, "  -r GuidAttr, --attributes GuidAttr\n\\r
+                        GuidAttr is guid section atttributes, which may be\n\\r
+                        PROCESSING_REQUIRED, AUTH_STATUS_VALID and NONE. \n\\r
+                        if -r option is not given, default PROCESSING_REQUIRED\n");\r
+  fprintf (stdout, "  -n String, --name String\n\\r
+                        String is a NULL terminated string used in Ui section.\n");\r
+  fprintf (stdout, "  -j Number, --buildnumber Number\n\\r
+                        Number is an integer value between 0000 and 9999\n\\r
+                        used in Ver section.\n");\r
+  fprintf (stdout, "  --sectionalign SectionAlign\n\\r
+                        SectionAlign points to section alignment, which support\n\\r
+                        the alignment scope 1~64K. It is specified in same\n\\r
+                        order that the section file is input.\n");\r
+  fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");\r
+  fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");\r
+  fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");\r
+  fprintf (stdout, "  --version             Show program's version number and exit.\n");\r
+  fprintf (stdout, "  -h, --help            Show this help message and exit.\n");\r
 }\r
 \r
 VOID\r
-Ascii2UnicodeWriteString (\r
+Ascii2UnicodeString (\r
   CHAR8    *String,\r
-  FILE     *OutFile\r
+  CHAR16   *UniString\r
   )\r
-{\r
-  UINT32 Index;\r
-  UINT8  AsciiNull;\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write ascii string as unicode string format to FILE \r
+\r
+Arguments:\r
+\r
+  String      - Pointer to string that is written to FILE.\r
+  UniString   - Pointer to unicode string\r
 \r
-  AsciiNull = 0;\r
+Returns:\r
+\r
+  NULL\r
 \r
+--*/\r
+{\r
+  while (*String != '\0') {\r
+    *(UniString++) = (CHAR16) *(String++);\r
+  }\r
   //\r
-  // Next, write out the string... Convert ASCII to Unicode in the process.\r
+  // End the UniString with a NULL.\r
   //\r
-  Index = 0;\r
-  do {\r
-    fwrite (&String[Index], 1, 1, OutFile);\r
-    fwrite (&AsciiNull, 1, 1, OutFile);\r
-  } while (String[Index++] != 0);\r
-}\r
+  *UniString = '\0';\r
+} \r
 \r
 STATUS\r
 GenSectionCommonLeafSection (\r
   CHAR8   **InputFileName,\r
   UINT32  InputFileNum,\r
   UINT8   SectionType,\r
-  FILE    *OutFile\r
+  UINT8   **OutFileBuffer\r
   )\r
 /*++\r
         \r
@@ -190,7 +253,7 @@ Arguments:
 \r
   SectionType    - A valid section type string\r
 \r
-  OutFile        - Output file handle\r
+  OutFileBuffer  - Buffer pointer to Output file contents\r
 \r
 Returns:\r
                        \r
@@ -203,14 +266,14 @@ Returns:
   FILE                      *InFile;\r
   UINT8                     *Buffer;\r
   UINT32                    TotalLength;\r
-  EFI_COMMON_SECTION_HEADER CommonSect;\r
+  EFI_COMMON_SECTION_HEADER *CommonSect;\r
   STATUS                    Status;\r
 \r
   if (InputFileNum > 1) {\r
-    Error (NULL, 0, 0, "invalid parameter", "more than one input file specified");\r
+    Error (NULL, 0, 2000, "Invalid paramter", "more than one input file specified");\r
     return STATUS_ERROR;\r
   } else if (InputFileNum < 1) {\r
-    Error (NULL, 0, 0, "no input file specified", NULL);\r
+    Error (NULL, 0, 2000, "Invalid paramter", "no input file specified");\r
     return STATUS_ERROR;\r
   }\r
   //\r
@@ -218,7 +281,7 @@ Returns:
   //\r
   InFile = fopen (InputFileName[0], "rb");\r
   if (InFile == NULL) {\r
-    Error (NULL, 0, 0, InputFileName[0], "failed to open input file");\r
+    Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
     return STATUS_ERROR;\r
   }\r
 \r
@@ -230,59 +293,96 @@ Returns:
   fseek (InFile, 0, SEEK_END);\r
   InputFileLength = ftell (InFile);\r
   fseek (InFile, 0, SEEK_SET);\r
-  //\r
-  // Fill in the fields in the local section header structure\r
-  //\r
-  CommonSect.Type = (EFI_SECTION_TYPE) SectionType;\r
-  TotalLength     = sizeof (CommonSect) + InputFileLength;\r
+  DebugMsg (NULL, 0, 9, "Input file", "File name is %s and File size is %u bytes", InputFileName[0], (unsigned) InputFileLength);\r
+  TotalLength     = sizeof (EFI_COMMON_SECTION_HEADER) + InputFileLength;\r
   //\r
   // Size must fit in 3 bytes\r
   //\r
   if (TotalLength >= MAX_SECTION_SIZE) {\r
-    Error (NULL, 0, 0, InputFileName[0], "file size (0x%X) exceeds section size limit(%dM).", TotalLength, MAX_SECTION_SIZE>>20);\r
+    Error (NULL, 0, 2000, "Invalid paramter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);\r
     goto Done;\r
   }\r
+  VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
   //\r
-  // Now copy the size into the section header and write out the section header\r
+  // Fill in the fields in the local section header structure\r
   //\r
-  memcpy (&CommonSect.Size, &TotalLength, 3);\r
-  fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
+  Buffer = (UINT8 *) malloc ((size_t) TotalLength);\r
+  if (Buffer == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); \r
+    goto Done;\r
+  }\r
+  CommonSect = (EFI_COMMON_SECTION_HEADER *) Buffer;\r
+  CommonSect->Type     = SectionType;\r
+  CommonSect->Size[0]  = (UINT8) (TotalLength & 0xff);\r
+  CommonSect->Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+  CommonSect->Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+  \r
   //\r
-  // Allocate a buffer to read in the contents of the input file. Then\r
-  // read it in as one block and write it to the output file.\r
+  // read data from the input file.\r
   //\r
   if (InputFileLength != 0) {\r
-    Buffer = (UINT8 *) malloc ((size_t) InputFileLength);\r
-    if (Buffer == NULL) {\r
-      Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL);\r
-      goto Done;\r
-    }\r
-\r
-    if (fread (Buffer, (size_t) InputFileLength, 1, InFile) != 1) {\r
-      Error (NULL, 0, 0, InputFileName[0], "failed to read contents of file");\r
-      goto Done;\r
-    }\r
-\r
-    if (fwrite (Buffer, (size_t) InputFileLength, 1, OutFile) != 1) {\r
-      Error (NULL, 0, 0, "failed to write to output file", NULL);\r
+    if (fread (Buffer + sizeof (EFI_COMMON_SECTION_HEADER), (size_t) InputFileLength, 1, InFile) != 1) {\r
+      Error (NULL, 0, 0004, "Error reading file", InputFileName[0]);\r
       goto Done;\r
     }\r
   }\r
 \r
+  //\r
+  // Set OutFileBuffer \r
+  //\r
+  *OutFileBuffer = Buffer;\r
   Status = STATUS_SUCCESS;\r
 \r
 Done:\r
   fclose (InFile);\r
-  if (Buffer != NULL) {\r
-    free (Buffer);\r
-  }\r
 \r
   return Status;\r
 }\r
 \r
+STATIC\r
+EFI_STATUS\r
+StringtoAlignment (\r
+  IN  CHAR8  *AlignBuffer,\r
+  OUT UINT32 *AlignNumber\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Converts Align String to align value (1~64K). \r
+\r
+Arguments:\r
+\r
+  AlignBuffer    - Pointer to Align string.\r
+  AlignNumber    - Pointer to Align value.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             Successfully convert align string to align value.\r
+  EFI_INVALID_PARAMETER   Align string is invalid or align value is not in scope.\r
+\r
+--*/\r
+{\r
+  UINT32 Index = 0;\r
+  //\r
+  // Check AlignBuffer\r
+  //\r
+  if (AlignBuffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  for (Index = 0; Index < sizeof (mAlignName) / sizeof (CHAR8 *); Index ++) {\r
+    if (stricmp (AlignBuffer, mAlignName [Index]) == 0) {\r
+      *AlignNumber = 1 << Index;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  return EFI_INVALID_PARAMETER;\r
+}\r
+\r
 EFI_STATUS\r
 GetSectionContents (\r
   CHAR8   **InputFileName,\r
+  UINT32  *InputFileAlign,\r
   UINT32  InputFileNum,\r
   UINT8   *FileBuffer,\r
   UINT32  *BufferLength\r
@@ -297,7 +397,9 @@ Routine Description:
 Arguments:\r
                \r
   InputFileName  - Name of the input file.\r
-                \r
+\r
+  InputFileAlign - Alignment required by the input file data.\r
+\r
   InputFileNum   - Number of input files. Should be at least 1.\r
 \r
   FileBuffer     - Output buffer to contain data\r
@@ -313,22 +415,31 @@ Returns:
   EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.\r
 --*/\r
 {\r
-  UINT32   Size;\r
-  UINT32   FileSize;\r
-  UINT32   Index;\r
-  FILE    *InFile;\r
+  UINT32                     Size;\r
+  UINT32                     Offset;\r
+  UINT32                     FileSize;\r
+  UINT32                     Index;\r
+  FILE                       *InFile;\r
+  EFI_COMMON_SECTION_HEADER  *SectHeader;\r
+  EFI_COMMON_SECTION_HEADER  TempSectHeader;\r
+  EFI_TE_IMAGE_HEADER        TeHeader;\r
+  UINT32                     TeOffset;\r
+  EFI_GUID_DEFINED_SECTION   GuidSectHeader;\r
+  UINT32                     HeaderSize;\r
 \r
   if (InputFileNum < 1) {\r
-    Error (NULL, 0, 0, "must specify at least one input file", NULL);\r
+    Error (NULL, 0, 2000, "Invalid paramter", "must specify at least one input file");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   if (BufferLength == NULL) {\r
-    Error (NULL, 0, 0, "BufferLength can't be NULL", NULL);\r
+    Error (NULL, 0, 2000, "Invalid paramter", "BufferLength can't be NULL");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Size = 0;\r
+  Size          = 0;\r
+  Offset        = 0;\r
+  TeOffset      = 0;\r
   //\r
   // Go through our array of file names and copy their contents\r
   // to the output buffer.\r
@@ -349,20 +460,76 @@ Returns:
     //\r
     InFile = fopen (InputFileName[Index], "rb");\r
     if (InFile == NULL) {\r
-      Error (NULL, 0, 0, InputFileName[Index], "failed to open input file");\r
+      Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);\r
       return EFI_ABORTED;\r
     }\r
 \r
     fseek (InFile, 0, SEEK_END);\r
     FileSize = ftell (InFile);\r
     fseek (InFile, 0, SEEK_SET);\r
+    DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize); \r
+    //\r
+    // Adjust section buffer when section alignment is required.\r
+    //\r
+    if (InputFileAlign != NULL) {\r
+      //\r
+      // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.\r
+      //\r
+      TeOffset = 0;\r
+      HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
+      fread (&TempSectHeader, 1, sizeof (TempSectHeader), InFile);\r
+      if (TempSectHeader.Type == EFI_SECTION_TE) {\r
+        fread (&TeHeader, 1, sizeof (TeHeader), InFile);\r
+        if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+          TeOffset = TeHeader.StrippedSize - sizeof (TeHeader);\r
+        }\r
+      } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {\r
+        fseek (InFile, 0, SEEK_SET);\r
+        fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);\r
+        if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
+          HeaderSize = GuidSectHeader.DataOffset;\r
+        }\r
+      } \r
+\r
+      fseek (InFile, 0, SEEK_SET);\r
+\r
+      //\r
+      // Revert TeOffset to the converse value relative to Alignment\r
+      // This is to assure the original PeImage Header at Alignment.\r
+      //\r
+      if (TeOffset != 0) {\r
+        TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);\r
+        TeOffset = TeOffset % InputFileAlign [Index];\r
+      }\r
+\r
+      //\r
+      // make sure section data meet its alignment requirement by adding one raw pad section.\r
+      //\r
+      if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {\r
+        Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);\r
+        Offset = Offset - Size - HeaderSize - TeOffset;\r
+         \r
+        if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {\r
+          memset (FileBuffer + Size, 0, Offset);\r
+          SectHeader          = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);\r
+          SectHeader->Type    = EFI_SECTION_RAW;\r
+          SectHeader->Size[0] = (UINT8) (Offset & 0xff);\r
+          SectHeader->Size[1] = (UINT8) ((Offset & 0xff00) >> 8);\r
+          SectHeader->Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);\r
+        }\r
+        DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment", "Pad Raw section size is %u", (unsigned) Offset);\r
+\r
+        Size = Size + Offset;\r
+      }\r
+    }\r
+\r
     //\r
     // Now read the contents of the file into the buffer\r
     // Buffer must be enough to contain the file content.\r
     //\r
-    if (FileSize > 0 && FileBuffer != NULL && (Size + FileSize) <= *BufferLength) {\r
+    if ((FileSize > 0) && (FileBuffer != NULL) && ((Size + FileSize) <= *BufferLength)) {\r
       if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {\r
-        Error (NULL, 0, 0, InputFileName[Index], "failed to read contents of input file");\r
+        Error (NULL, 0, 0004, "Error reading file", InputFileName[Index]);\r
         fclose (InFile);\r
         return EFI_ABORTED;\r
       }\r
@@ -372,6 +539,9 @@ Returns:
     Size += FileSize;\r
   }\r
   \r
+  //\r
+  // Set the real required buffer size.\r
+  //\r
   if (Size > *BufferLength) {\r
     *BufferLength = Size;\r
     return EFI_BUFFER_TOO_SMALL;\r
@@ -383,10 +553,11 @@ Returns:
 \r
 EFI_STATUS\r
 GenSectionCompressionSection (\r
-  CHAR8    **InputFileName,\r
+  CHAR8   **InputFileName,\r
+  UINT32  *InputFileAlign,\r
   UINT32  InputFileNum,\r
   UINT8   SectCompSubType,\r
-  FILE    *OutFile\r
+  UINT8   **OutFileBuffer\r
   )\r
 /*++\r
         \r
@@ -400,12 +571,14 @@ Routine Description:
 Arguments:\r
                \r
   InputFileName  - Name of the input file.\r
-                \r
+\r
+  InputFileAlign - Alignment required by the input file data.\r
+\r
   InputFileNum   - Number of input files. Should be at least 1.\r
 \r
   SectCompSubType - Specify the compression algorithm requested. \r
   \r
-  OutFile        - Output file handle\r
+  OutFileBuffer   - Buffer pointer to Output file contents\r
 \r
 Returns:\r
                        \r
@@ -421,7 +594,7 @@ Returns:
   UINT8                   *FileBuffer;\r
   UINT8                   *OutputBuffer;\r
   EFI_STATUS              Status;\r
-  EFI_COMPRESSION_SECTION CompressionSect;\r
+  EFI_COMPRESSION_SECTION *CompressionSect;\r
   COMPRESS_FUNCTION       CompressFunction;\r
 \r
   InputLength       = 0;\r
@@ -434,6 +607,7 @@ Returns:
   //\r
   Status = GetSectionContents (\r
             InputFileName,\r
+            InputFileAlign,\r
             InputFileNum,\r
             FileBuffer,\r
             &InputLength\r
@@ -442,7 +616,7 @@ Returns:
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
     FileBuffer = (UINT8 *) malloc (InputLength);\r
     if (FileBuffer == NULL) {\r
-      Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
@@ -450,6 +624,7 @@ Returns:
     //\r
     Status = GetSectionContents (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
               FileBuffer,\r
               &InputLength\r
@@ -471,6 +646,16 @@ Returns:
   switch (SectCompSubType) {\r
   case EFI_NOT_COMPRESSED:\r
     CompressedLength = InputLength;\r
+    //\r
+    // Copy file buffer to the none compressed data.\r
+    //\r
+    OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));\r
+    if (OutputBuffer == NULL) {\r
+      free (FileBuffer);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    memcpy (OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), FileBuffer, CompressedLength);\r
+    FileBuffer = OutputBuffer;\r
     break;\r
 \r
   case EFI_STANDARD_COMPRESSION:\r
@@ -478,7 +663,7 @@ Returns:
     break;\r
 \r
   default:\r
-    Error (NULL, 0, 0, "unknown compression type", NULL);\r
+    Error (NULL, 0, 2000, "Invalid paramter", "unknown compression type");\r
     free (FileBuffer);\r
     return EFI_ABORTED;\r
   }\r
@@ -487,13 +672,13 @@ Returns:
 \r
     Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
     if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      OutputBuffer = malloc (CompressedLength);\r
+      OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));\r
       if (!OutputBuffer) {\r
         free (FileBuffer);\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
 \r
-      Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
+      Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), &CompressedLength);\r
     }\r
 \r
     free (FileBuffer);\r
@@ -508,9 +693,11 @@ Returns:
     }\r
   }\r
 \r
+  DebugMsg (NULL, 0, 9, "comprss file size", \r
+            "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength, (unsigned) CompressedLength);\r
   TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);\r
   if (TotalLength >= MAX_SECTION_SIZE) {\r
-    Error (__FILE__, __LINE__, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE>>20);\r
+    Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
     if (FileBuffer != NULL) {\r
       free (FileBuffer);\r
     }\r
@@ -519,30 +706,37 @@ Returns:
     }\r
     return STATUS_ERROR;\r
   }\r
+  VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
 \r
   //\r
   // Add the section header for the compressed data\r
   //\r
-  CompressionSect.CommonHeader.Type     = EFI_SECTION_COMPRESSION;\r
-  CompressionSect.CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
-  CompressionSect.CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
-  CompressionSect.CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
-  CompressionSect.CompressionType       = SectCompSubType;\r
-  CompressionSect.UncompressedLength    = InputLength;\r
-\r
-  fwrite (&CompressionSect, sizeof (CompressionSect), 1, OutFile);\r
-  fwrite (FileBuffer, CompressedLength, 1, OutFile);\r
-  free (FileBuffer);\r
+  CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;\r
+  \r
+  CompressionSect->CommonHeader.Type     = EFI_SECTION_COMPRESSION;\r
+  CompressionSect->CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
+  CompressionSect->CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+  CompressionSect->CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+  CompressionSect->CompressionType       = SectCompSubType;\r
+  CompressionSect->UncompressedLength    = InputLength;\r
+\r
+  //\r
+  // Set OutFileBuffer \r
+  //\r
+  *OutFileBuffer = FileBuffer;\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 EFI_STATUS\r
 GenSectionGuidDefinedSection (\r
   CHAR8    **InputFileName,\r
+  UINT32   *InputFileAlign,\r
   UINT32   InputFileNum,\r
   EFI_GUID *VendorGuid,\r
   UINT16   DataAttribute,\r
-  FILE     *OutFile\r
+  UINT32   DataHeaderSize,\r
+  UINT8    **OutFileBuffer\r
   )\r
 /*++\r
         \r
@@ -557,13 +751,17 @@ Arguments:
                \r
   InputFileName - Name of the input file.\r
                 \r
+  InputFileAlign - Alignment required by the input file data.\r
+\r
   InputFileNum  - Number of input files. Should be at least 1.\r
 \r
   VendorGuid    - Specify vendor guid value.\r
 \r
   DataAttribute - Specify attribute for the vendor guid data. \r
   \r
-  OutFile       - Output file handle\r
+  DataHeaderSize- Guided Data Header Size\r
+  \r
+  OutFileBuffer   - Buffer pointer to Output file contents\r
 \r
 Returns:\r
                        \r
@@ -576,29 +774,39 @@ Returns:
 {\r
   UINT32                TotalLength;\r
   UINT32                InputLength;\r
+  UINT32                Offset;\r
   UINT8                 *FileBuffer;\r
   UINT32                Crc32Checksum;\r
   EFI_STATUS            Status;\r
-  CRC32_SECTION_HEADER  Crc32GuidSect;\r
-  EFI_GUID_DEFINED_SECTION  VendorGuidSect;\r
+  CRC32_SECTION_HEADER  *Crc32GuidSect;\r
+  EFI_GUID_DEFINED_SECTION  *VendorGuidSect;\r
 \r
   InputLength = 0;\r
+  Offset      = 0;\r
   FileBuffer  = NULL;\r
+\r
+  if (CompareGuid (VendorGuid, &mEfiCrc32SectionGuid) == 0) {\r
+    Offset = sizeof (CRC32_SECTION_HEADER);\r
+  } else {\r
+    Offset = sizeof (EFI_GUID_DEFINED_SECTION);\r
+  }\r
+\r
   //\r
   // read all input file contents into a buffer\r
   // first get the size of all file contents\r
   //\r
   Status = GetSectionContents (\r
             InputFileName,\r
+            InputFileAlign,\r
             InputFileNum,\r
             FileBuffer,\r
             &InputLength\r
             );\r
 \r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    FileBuffer = (UINT8 *) malloc (InputLength);\r
+    FileBuffer = (UINT8 *) malloc (InputLength + Offset);\r
     if (FileBuffer == NULL) {\r
-      Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
@@ -606,8 +814,9 @@ Returns:
     //\r
     Status = GetSectionContents (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
-              FileBuffer,\r
+              FileBuffer + Offset,\r
               &InputLength\r
               );\r
   }\r
@@ -616,56 +825,67 @@ Returns:
     if (FileBuffer != NULL) {\r
       free (FileBuffer);\r
     }\r
+    Error (NULL, 0, 0001, "Error opening file for reading", InputFileName[0]);\r
     return Status;\r
   }\r
 \r
+  if (InputLength == 0) {\r
+    Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
   //\r
-  // Now data is in FileBuffer\r
+  // Now data is in FileBuffer + Offset\r
   //\r
-  if (CompareGuid (VendorGuid, &gEfiCrc32SectionGuid) == 0) {\r
+  if (CompareGuid (VendorGuid, &mEfiCrc32SectionGuid) == 0) {\r
     //\r
     // Default Guid section is CRC32.\r
     //\r
     Crc32Checksum = 0;\r
-    CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum);\r
+    CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);\r
 \r
     TotalLength = InputLength + sizeof (CRC32_SECTION_HEADER);\r
     if (TotalLength >= MAX_SECTION_SIZE) {\r
-      Error (__FILE__, __LINE__, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE>>20);\r
+      Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
       free (FileBuffer);\r
       return STATUS_ERROR;\r
     }\r
-\r
-    Crc32GuidSect.GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
-    Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
-    Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
-    Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
-    memcpy (&(Crc32GuidSect.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
-    Crc32GuidSect.GuidSectionHeader.Attributes  = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
-    Crc32GuidSect.GuidSectionHeader.DataOffset  = sizeof (CRC32_SECTION_HEADER);\r
-    Crc32GuidSect.CRC32Checksum                 = Crc32Checksum;\r
-    fwrite (&Crc32GuidSect, sizeof (Crc32GuidSect), 1, OutFile);  \r
+    \r
+    Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;\r
+    Crc32GuidSect->GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
+    Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
+    Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+    Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+    memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
+    Crc32GuidSect->GuidSectionHeader.Attributes  = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
+    Crc32GuidSect->GuidSectionHeader.DataOffset  = sizeof (CRC32_SECTION_HEADER);\r
+    Crc32GuidSect->CRC32Checksum                 = Crc32Checksum;\r
+    DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);\r
 \r
   } else {\r
     TotalLength = InputLength + sizeof (EFI_GUID_DEFINED_SECTION);\r
     if (TotalLength >= MAX_SECTION_SIZE) {\r
-      Error (__FILE__, __LINE__, 0, "input error", "The size of all files exceeds section size limit(%dM).", MAX_SECTION_SIZE>>20);\r
+      Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
       free (FileBuffer);\r
       return STATUS_ERROR;\r
     }\r
 \r
-    VendorGuidSect.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
-    VendorGuidSect.CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
-    VendorGuidSect.CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
-    VendorGuidSect.CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
-    memcpy (&(VendorGuidSect.SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
-    VendorGuidSect.Attributes  = DataAttribute;\r
-    VendorGuidSect.DataOffset  = sizeof (EFI_GUID_DEFINED_SECTION);\r
-    fwrite (&VendorGuidSect, sizeof (EFI_GUID_DEFINED_SECTION), 1, OutFile);  \r
+    VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;\r
+    VendorGuidSect->CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
+    VendorGuidSect->CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
+    VendorGuidSect->CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+    VendorGuidSect->CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+    memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
+    VendorGuidSect->Attributes  = DataAttribute;\r
+    VendorGuidSect->DataOffset  = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);\r
+    DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);\r
   }\r
-\r
-  fwrite (FileBuffer, InputLength, 1, OutFile);\r
-  free (FileBuffer);\r
+  VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
+  \r
+  //\r
+  // Set OutFileBuffer \r
+  //\r
+  *OutFileBuffer = FileBuffer;\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -702,39 +922,47 @@ Returns:
   CHAR8                     *SectionName;\r
   CHAR8                     *CompressionName;\r
   CHAR8                     *StringBuffer;\r
-  EFI_GUID                  VendorGuid = gZeroGuid;\r
-  INT32                     VersionNumber;\r
+  EFI_GUID                  VendorGuid = mZeroGuid;\r
+  int                       VersionNumber;\r
   UINT8                     SectType;\r
   UINT8                     SectCompSubType;\r
   UINT16                    SectGuidAttribute; \r
-  EFI_COMMON_SECTION_HEADER CommonSect;\r
+  UINT64                    SectGuidHeaderLength;\r
+  EFI_VERSION_SECTION       *VersionSect;\r
+  EFI_USER_INTERFACE_SECTION *UiSect;\r
   UINT32                    InputLength;\r
-  UINT8                     *FileBuffer;\r
-  BOOLEAN                   AllocatedFlag;\r
+  UINT8                     *OutFileBuffer;\r
   EFI_STATUS                Status;\r
\r
+  UINT64                    LogLevel;\r
+  UINT32                    *InputFileAlign;\r
+  UINT32                    InputFileAlignNum;\r
+\r
+  InputFileAlign        = NULL;\r
+  InputFileAlignNum     = 0;\r
   InputFileName         = NULL;\r
   OutputFileName        = NULL;\r
   SectionName           = NULL;\r
   CompressionName       = NULL;\r
   StringBuffer          = "";\r
-\r
   InFile                = NULL;\r
   OutFile               = NULL;\r
   VersionNumber         = 0;\r
   InputFileNum          = 0;\r
   SectType              = EFI_SECTION_ALL;\r
   SectCompSubType       = 0;\r
-  SectGuidAttribute     = 0;\r
-  FileBuffer            = NULL;\r
+  SectGuidAttribute     = EFI_GUIDED_SECTION_NONE;\r
+  OutFileBuffer         = NULL;\r
   InputLength           = 0;\r
-  AllocatedFlag         = FALSE;\r
   Status                = STATUS_SUCCESS;\r
+  LogLevel              = 0;\r
+  SectGuidHeaderLength  = 0;\r
+  VersionSect           = NULL;\r
+  UiSect                = NULL;\r
   \r
-\r
   SetUtilityName (UTILITY_NAME);\r
   \r
   if (argc == 1) {\r
+    Error (NULL, 0, 1001, "Missing options", "No options input");\r
     Usage ();\r
     return STATUS_ERROR;\r
   }\r
@@ -746,18 +974,23 @@ Returns:
   argv ++;\r
 \r
   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
-    Usage();\r
-    return STATUS_ERROR;    \r
+    Version ();\r
+    Usage ();\r
+    return STATUS_SUCCESS;    \r
   }\r
 \r
-  if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--version") == 0)) {\r
-    Version();\r
-    return STATUS_ERROR;    \r
+  if (stricmp (argv[0], "--version") == 0) {\r
+    Version ();\r
+    return STATUS_SUCCESS;    \r
   }\r
 \r
   while (argc > 0) {\r
     if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--SectionType") == 0)) {\r
       SectionName = argv[1];\r
+      if (SectionName == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Section Type can't be NULL");\r
+        goto Finish;\r
+      }\r
       argc -= 2;\r
       argv += 2;\r
       continue; \r
@@ -765,6 +998,10 @@ Returns:
 \r
     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
       OutputFileName = argv[1];\r
+      if (OutputFileName == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Output file can't be NULL");\r
+        goto Finish;\r
+      }\r
       argc -= 2;\r
       argv += 2;\r
       continue; \r
@@ -772,26 +1009,49 @@ Returns:
 \r
     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--compress") == 0)) {\r
       CompressionName = argv[1];\r
+      if (CompressionName == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Compression Type can't be NULL");\r
+        goto Finish;\r
+      }\r
       argc -= 2;\r
       argv += 2;\r
       continue;\r
     }\r
 \r
-    if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--vendorguid") == 0)) {\r
-      StringToGuid (argv[1], &VendorGuid);\r
+    if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--vendor") == 0)) {\r
+      Status = StringToGuid (argv[1], &VendorGuid);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        goto Finish;\r
+      }\r
       argc -= 2;\r
       argv += 2;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {\r
-      if (stricmp (argv[1], GUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {\r
+      if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {\r
         SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
-      } else if (stricmp (argv[1], GUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
+      } else if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
         SectGuidAttribute |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
+      } else if (stricmp (argv[1], mGUIDedSectionAttribue[0]) == 0) {\r
+        //\r
+        // NONE attribute\r
+        //\r
+        SectGuidAttribute |= EFI_GUIDED_SECTION_NONE;\r
       } else {\r
-        Error (NULL, 0, 0, argv[1], "unknown Guid Section Attribute");\r
-        Usage ();\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        goto Finish;\r
+      }\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
+\r
+    if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--HeaderLength") == 0)) {\r
+      Status = AsciiStringToUint64 (argv[1], FALSE, &SectGuidHeaderLength);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value for GuidHeaderLength", "%s = %s", argv[0], argv[1]);\r
         goto Finish;\r
       }\r
       argc -= 2;\r
@@ -801,19 +1061,26 @@ Returns:
 \r
     if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--name") == 0)) {\r
       StringBuffer = argv[1];\r
+      if (StringBuffer == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Name can't be NULL");\r
+        goto Finish;\r
+      }\r
       argc -= 2;\r
       argv += 2;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--buildnumber") == 0)) {\r
+      if (argv[1] == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "build number can't be NULL");\r
+        goto Finish;\r
+      }\r
       //\r
       // Verify string is a integrator number\r
       //\r
       for (Index = 0; Index < strlen (argv[1]); Index++) {\r
-        if ((argv[1][Index] != '-') && (isdigit (argv[1][Index]) == 0)) {\r
-          Error (NULL, 0, 0, NULL, "ERROR: %s is not a valid integer.", argv[1]);\r
-          Status = EFI_ABORTED;\r
+        if ((argv[1][Index] != '-') && (isdigit ((int)argv[1][Index]) == 0)) {\r
+          Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
           goto Finish;\r
         }\r
       }\r
@@ -823,17 +1090,84 @@ Returns:
       argv += 2;\r
       continue;\r
     }\r
-    \r
+\r
+    if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
+      SetPrintLevel (VERBOSE_LOG_LEVEL);\r
+      VerboseMsg ("Verbose output Mode Set!");\r
+      argc --;\r
+      argv ++;\r
+      continue;\r
+    }\r
+\r
+    if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
+      SetPrintLevel (KEY_LOG_LEVEL);\r
+      KeyMsg ("Quiet output Mode Set!");\r
+      argc --;\r
+      argv ++;\r
+      continue;\r
+    }\r
+\r
+    if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
+      Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        goto Finish;\r
+      }\r
+      if (LogLevel > 9) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0~9, currnt input level is %d", (int) LogLevel);\r
+        goto Finish;\r
+      }\r
+      SetPrintLevel (LogLevel);\r
+      DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Section File alignment requirement\r
+    //\r
+    if (stricmp (argv[0], "--sectionalign") == 0) {\r
+      if (InputFileAlignNum == 0) {\r
+        InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
+        if (InputFileAlign == NULL) {\r
+          Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+          return 1;\r
+        }\r
+        memset (InputFileAlign, 1, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
+      } else if (InputFileAlignNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
+        InputFileAlign = (UINT32 *) realloc (\r
+          InputFileAlign,\r
+          (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (UINT32)\r
+          );\r
+\r
+        if (InputFileAlign == NULL) {\r
+          Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+          return 1;\r
+        }\r
+        memset (&(InputFileAlign[InputFileNum]), 1, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));\r
+      }\r
+      \r
+      Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        goto Finish;\r
+      }\r
+      argc -= 2;\r
+      argv += 2;\r
+      InputFileAlignNum ++;\r
+      continue; \r
+    }\r
+\r
     //\r
     // Get Input file name\r
     //\r
     if ((InputFileNum == 0) && (InputFileName == NULL)) {\r
       InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
       if (InputFileName == NULL) {\r
-        Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
-        return EFI_OUT_OF_RESOURCES;\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+        return 1;\r
       }\r
-\r
       memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
     } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
       //\r
@@ -845,10 +1179,9 @@ Returns:
                                   );\r
 \r
       if (InputFileName == NULL) {\r
-        Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
-        return EFI_OUT_OF_RESOURCES;\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+        return 1;\r
       }\r
-\r
       memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
     }\r
 \r
@@ -857,149 +1190,143 @@ Returns:
     argv ++;\r
   }\r
 \r
+  if (InputFileAlignNum > 0 && InputFileAlignNum != InputFileNum) {\r
+    Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section");\r
+    goto Finish;\r
+  }\r
+\r
+  VerboseMsg ("%s tool start.", UTILITY_NAME);\r
+\r
   //\r
   // Parse all command line parameters to get the corresponding section type.\r
   //\r
+  VerboseMsg ("Section type is %s", SectionName);\r
   if (SectionName == NULL) {\r
     //\r
     // No specified Section type, default is SECTION_ALL.\r
     //\r
     SectType = EFI_SECTION_ALL;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_COMPRESSION]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_COMPRESSION]) == 0) {\r
     SectType     = EFI_SECTION_COMPRESSION;\r
     if (CompressionName == NULL) {\r
       //\r
       // Default is PI_STD compression algorithm.\r
       //\r
       SectCompSubType = EFI_STANDARD_COMPRESSION;\r
-    } else if (stricmp (CompressionName, CompressionTypeName[EFI_NOT_COMPRESSED]) == 0) {\r
+    } else if (stricmp (CompressionName, mCompressionTypeName[EFI_NOT_COMPRESSED]) == 0) {\r
       SectCompSubType = EFI_NOT_COMPRESSED;\r
-    } else if (stricmp (CompressionName, CompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) {\r
+    } else if (stricmp (CompressionName, mCompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) {\r
       SectCompSubType = EFI_STANDARD_COMPRESSION;\r
     } else {\r
-      Error (NULL, 0, 0, CompressionName, "unknown compression type");\r
-      Usage ();\r
+      Error (NULL, 0, 1003, "Invalid option value", "--compress = %s", CompressionName);\r
       goto Finish;\r
     }\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {\r
+    VerboseMsg ("Compress method is %s", mCompressionTypeName [SectCompSubType]);\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {\r
     SectType     = EFI_SECTION_GUID_DEFINED;\r
 \r
-    if (CompareGuid (&VendorGuid, &gZeroGuid) == 0) {\r
-      memcpy (&VendorGuid, &gEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
+    if (CompareGuid (&VendorGuid, &mZeroGuid) == 0) {\r
+      memcpy (&VendorGuid, &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
     }\r
     \r
-    if (SectGuidAttribute == 0) {\r
-      SectGuidAttribute = EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
+    if ((SectGuidAttribute & EFI_GUIDED_SECTION_NONE) != 0) {\r
+      //\r
+      // NONE attribute, clear attribute value.\r
+      //\r
+      SectGuidAttribute = SectGuidAttribute & ~EFI_GUIDED_SECTION_NONE;\r
+    }\r
+    VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
+                (unsigned) VendorGuid.Data1,\r
+                VendorGuid.Data2,\r
+                VendorGuid.Data3,\r
+                VendorGuid.Data4[0],\r
+                VendorGuid.Data4[1],\r
+                VendorGuid.Data4[2],\r
+                VendorGuid.Data4[3],\r
+                VendorGuid.Data4[4],\r
+                VendorGuid.Data4[5],\r
+                VendorGuid.Data4[6],\r
+                VendorGuid.Data4[7]);\r
+    if ((SectGuidAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {\r
+      VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]);\r
+    }\r
+    if ((SectGuidAttribute & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) {\r
+      VerboseMsg ("Guid Attribute is %s", mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]);\r
     }\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_PE32]) == 0) {\r
+    if (SectGuidHeaderLength != 0) {\r
+      VerboseMsg ("Guid Data Header size is 0x%llx", (unsigned long long) SectGuidHeaderLength);\r
+    }\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PE32]) == 0) {\r
     SectType = EFI_SECTION_PE32;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_PIC]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PIC]) == 0) {\r
     SectType = EFI_SECTION_PIC;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_TE]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_TE]) == 0) {\r
     SectType = EFI_SECTION_TE;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) {\r
     SectType = EFI_SECTION_DXE_DEPEX;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_VERSION]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_SMM_DEPEX]) == 0) {\r
+    SectType = EFI_SECTION_SMM_DEPEX;\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_VERSION]) == 0) {\r
     SectType = EFI_SECTION_VERSION;\r
     if (VersionNumber < 0 || VersionNumber > 9999) {\r
-      Error (NULL, 0, 0, NULL, "%d is illegal version number\n", VersionNumber);\r
-      Usage ();\r
+      Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~9999", VersionNumber);\r
       goto Finish;\r
     }\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) {\r
+    VerboseMsg ("Version section number is %d", VersionNumber);\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) {\r
     SectType = EFI_SECTION_USER_INTERFACE;\r
     if (StringBuffer[0] == '\0') {\r
-      Error (NULL, 0, 0, "user interface string not specified", NULL);\r
-      Usage ();\r
+      Error (NULL, 0, 1001, "Missing option", "user interface string");\r
       goto Finish;\r
     }\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) {\r
+    VerboseMsg ("UI section string name is %s", StringBuffer);\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) {\r
     SectType = EFI_SECTION_COMPATIBILITY16;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) {\r
     SectType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) {\r
     SectType = EFI_SECTION_FREEFORM_SUBTYPE_GUID;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_RAW]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_RAW]) == 0) {\r
     SectType = EFI_SECTION_RAW;\r
-  } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) {\r
+  } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) {\r
     SectType = EFI_SECTION_PEI_DEPEX;\r
   } else {\r
-    Error (NULL, 0, 0, SectionName, "unknown section type");\r
-    Usage ();\r
+    Error (NULL, 0, 1003, "Invalid option value", "SectionType = %s", SectionName);\r
     goto Finish;\r
   }\r
   \r
+  //\r
+  // GuidValue is only required by Guided section.\r
+  //\r
+  if ((SectType != EFI_SECTION_GUID_DEFINED) && (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
+    fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);\r
+  }\r
+  \r
+  //\r
+  // Check whether there is input file\r
+  //  \r
   if ((SectType != EFI_SECTION_VERSION) && (SectType != EFI_SECTION_USER_INTERFACE)) {\r
     //\r
-    // The input file are required for those section type.\r
-    // The file are from stdin.\r
+    // The input file are required for other section type.\r
     //\r
     if (InputFileNum == 0) {\r
-\r
-      AllocatedFlag = TRUE;\r
-\r
-      //\r
-      // Init InputFileName pointer list\r
-      //\r
-      InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
-      if (InputFileName == NULL) {\r
-        Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-      memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
-\r
-      do {\r
-        if ((InputFileNum != 0) && (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0)) {\r
-          //\r
-          // InputFileName buffer too small, need to realloc\r
-          //\r
-          InputFileName = (CHAR8 **) realloc (\r
-                                      InputFileName,\r
-                                      (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)\r
-                                      );\r
-    \r
-          if (InputFileName == NULL) {\r
-            for (Index = 0; Index < InputFileNum; Index ++) {\r
-              free (InputFileName [InputFileNum]);\r
-            }\r
-            Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
-            return EFI_OUT_OF_RESOURCES;\r
-          }\r
-          memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
-        }\r
-\r
-        InputFileName [InputFileNum] = (CHAR8 *) malloc (_MAX_PATH); \r
-        if (InputFileName == NULL) {\r
-          Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
-          for (Index = 0; Index < InputFileNum; Index ++) {\r
-            free (InputFileName [InputFileNum]);\r
-          }\r
-          free (InputFileName);\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-      } while (fscanf (stdin, "%s", InputFileName[InputFileNum++]) != EOF);\r
-      //\r
-      // Free the last memory space because it doesn't have data.\r
-      //\r
-      InputFileNum --;\r
-      free (InputFileName[InputFileNum]);\r
+      Error (NULL, 0, 1001, "Missing options", "Input files");\r
+      goto Finish;\r
     }\r
   }\r
-  \r
   //\r
-  // Open output file\r
+  // Check whether there is output file\r
   //\r
-  if (OutputFileName == NULL) {\r
-    OutFile = stdout;\r
-  } else {\r
-    OutFile = fopen (OutputFileName, "wb");\r
+  for (Index = 0; Index < InputFileNum; Index ++) {\r
+    VerboseMsg ("the %uth input file name is %s", (unsigned) Index, InputFileName[Index]);\r
   }\r
-\r
-  if (OutFile == NULL) {\r
-    Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");\r
+  if (OutputFileName == NULL) {\r
+    Error (NULL, 0, 1001, "Missing options", "Output file");\r
     goto Finish;\r
+    // OutFile = stdout;\r
   }\r
-  \r
+  VerboseMsg ("Output file name is %s", OutputFileName);\r
+\r
   //\r
   // At this point, we've fully validated the command line, and opened appropriate\r
   // files, so let's go and do what we've been asked to do...\r
@@ -1010,28 +1337,41 @@ Returns:
   //\r
   switch (SectType) {\r
   case EFI_SECTION_COMPRESSION:\r
+    if (InputFileAlign != NULL) {\r
+      free (InputFileAlign);\r
+      InputFileAlign = NULL;\r
+    }\r
     Status = GenSectionCompressionSection (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
               SectCompSubType,\r
-              OutFile\r
+              &OutFileBuffer\r
               );\r
     break;\r
 \r
   case EFI_SECTION_GUID_DEFINED:\r
+    if (InputFileAlign != NULL && (CompareGuid (&VendorGuid, &mEfiCrc32SectionGuid) != 0)) {\r
+      //\r
+      // Only process alignment for the default known CRC32 guided section.\r
+      // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated.\r
+      //\r
+      free (InputFileAlign);\r
+      InputFileAlign = NULL;\r
+    }\r
     Status = GenSectionGuidDefinedSection (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
               &VendorGuid,\r
               SectGuidAttribute,\r
-              OutFile\r
+              (UINT32) SectGuidHeaderLength,\r
+              &OutFileBuffer\r
               );\r
     break;\r
 \r
   case EFI_SECTION_VERSION:\r
-    CommonSect.Type = (EFI_SECTION_TYPE) SectType;\r
-\r
-    Index           = sizeof (CommonSect);\r
+    Index           = sizeof (EFI_COMMON_SECTION_HEADER);\r
     //\r
     // 2 bytes for the build number UINT16\r
     //\r
@@ -1040,23 +1380,40 @@ Returns:
     // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
     //\r
     Index += (strlen (StringBuffer) * 2) + 2;\r
-    memcpy (&CommonSect.Size, &Index, 3);\r
-    fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
-    fwrite (&VersionNumber, sizeof (UINT16), 1, OutFile);\r
-    Ascii2UnicodeWriteString (StringBuffer, OutFile);\r
+    OutFileBuffer = (UINT8 *) malloc (Index);\r
+    if (OutFileBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+      goto Finish;\r
+    }\r
+    VersionSect = (EFI_VERSION_SECTION *) OutFileBuffer;\r
+    VersionSect->CommonHeader.Type     = SectType;\r
+    VersionSect->CommonHeader.Size[0]  = (UINT8) (Index & 0xff);\r
+    VersionSect->CommonHeader.Size[1]  = (UINT8) ((Index & 0xff00) >> 8);\r
+    VersionSect->CommonHeader.Size[2]  = (UINT8) ((Index & 0xff0000) >> 16);\r
+    VersionSect->BuildNumber           = (UINT16) VersionNumber;\r
+    Ascii2UnicodeString (StringBuffer, VersionSect->VersionString);\r
+    VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index);\r
     break;\r
 \r
   case EFI_SECTION_USER_INTERFACE:\r
-    CommonSect.Type = (EFI_SECTION_TYPE) SectType;\r
-    Index           = sizeof (CommonSect);\r
+    Index           = sizeof (EFI_COMMON_SECTION_HEADER);\r
     //\r
     // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
     //\r
     Index += (strlen (StringBuffer) * 2) + 2;\r
-    memcpy (&CommonSect.Size, &Index, 3);\r
-    fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
-    Ascii2UnicodeWriteString (StringBuffer, OutFile);\r
-    break;\r
+    OutFileBuffer = (UINT8 *) malloc (Index);\r
+    if (OutFileBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+      goto Finish;\r
+    }\r
+    UiSect = (EFI_USER_INTERFACE_SECTION *) OutFileBuffer;\r
+    UiSect->CommonHeader.Type     = SectType;\r
+    UiSect->CommonHeader.Size[0]  = (UINT8) (Index & 0xff);\r
+    UiSect->CommonHeader.Size[1]  = (UINT8) ((Index & 0xff00) >> 8);\r
+    UiSect->CommonHeader.Size[2]  = (UINT8) ((Index & 0xff0000) >> 16);\r
+    Ascii2UnicodeString (StringBuffer, UiSect->FileNameString);\r
+    VerboseMsg ("the size of the created section file is %u bytes", (unsigned) Index);\r
+   break;\r
 \r
   case EFI_SECTION_ALL:\r
     //\r
@@ -1065,15 +1422,16 @@ Returns:
     //\r
     Status = GetSectionContents (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
-              FileBuffer,\r
+              OutFileBuffer,\r
               &InputLength\r
               );\r
   \r
     if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      FileBuffer = (UINT8 *) malloc (InputLength);\r
-      if (FileBuffer == NULL) {\r
-        Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
+      OutFileBuffer = (UINT8 *) malloc (InputLength);\r
+      if (OutFileBuffer == NULL) {\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
         goto Finish;\r
       }\r
       //\r
@@ -1081,20 +1439,13 @@ Returns:
       //\r
       Status = GetSectionContents (\r
                 InputFileName,\r
+                InputFileAlign,\r
                 InputFileNum,\r
-                FileBuffer,\r
+                OutFileBuffer,\r
                 &InputLength\r
                 );\r
     }\r
-  \r
-    if (Status == EFI_SUCCESS) {\r
-      fwrite (FileBuffer, InputLength, 1, OutFile);\r
-    }\r
-\r
-    if (FileBuffer != NULL) {\r
-      free (FileBuffer);\r
-    }\r
-    \r
+    VerboseMsg ("the size of the created section file is %u bytes", (unsigned) InputLength);\r
     break;\r
   default:\r
     //\r
@@ -1104,31 +1455,52 @@ Returns:
               InputFileName,\r
               InputFileNum,\r
               SectType,\r
-              OutFile\r
+              &OutFileBuffer\r
               );\r
     break;\r
   }\r
+  \r
+  if (Status != EFI_SUCCESS || OutFileBuffer == NULL) {\r
+    Error (NULL, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status);\r
+         goto Finish;\r
+  }\r
 \r
-Finish:\r
-  if (AllocatedFlag == TRUE) {\r
-    for (Index = 0; Index < InputFileNum; Index ++) {\r
-      free (InputFileName[Index]);\r
-    }\r
+  //\r
+  // Get output file length\r
+  //\r
+  if (SectType != EFI_SECTION_ALL) {\r
+    InputLength = SECTION_SIZE (OutFileBuffer);\r
+  }\r
+  \r
+  //\r
+  // Write the output file\r
+  //\r
+  OutFile = fopen (OutputFileName, "wb");\r
+  if (OutFile == NULL) {\r
+    Error (NULL, 0, 0001, "Error opening file for writing", OutputFileName);\r
+    goto Finish;\r
   }\r
 \r
+  fwrite (OutFileBuffer, InputLength, 1, OutFile);\r
+\r
+Finish:\r
   if (InputFileName != NULL) {\r
     free (InputFileName);\r
   }\r
 \r
+  if (InputFileAlign != NULL) {\r
+    free (InputFileAlign);\r
+  }\r
+\r
+  if (OutFileBuffer != NULL) {\r
+    free (OutFileBuffer);\r
+  }\r
+\r
   if (OutFile != NULL) {\r
     fclose (OutFile);\r
-    //\r
-    // If we had errors, then delete the output file\r
-    //\r
-    if (GetUtilityStatus () == STATUS_ERROR) {\r
-      remove (OutputFileName);\r
-    }\r
   }\r
+  \r
+  VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
 \r
   return GetUtilityStatus ();\r
 }\r