Add Include directory, Common library and the first prototype GenSec, GenFv, GenFw...
authorlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 21 Jun 2007 03:16:01 +0000 (03:16 +0000)
committerlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 21 Jun 2007 03:16:01 +0000 (03:16 +0000)
Add the related build makefiles and directory.

git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@168 7335b38e-4728-0410-8992-fb3ffe349368

78 files changed:
Source/C/Common/CommonLib.c [new file with mode: 0644]
Source/C/Common/CommonLib.h [new file with mode: 0644]
Source/C/Common/Compress.h [new file with mode: 0644]
Source/C/Common/Crc32.c [new file with mode: 0644]
Source/C/Common/Crc32.h [new file with mode: 0644]
Source/C/Common/Decompress.c [new file with mode: 0644]
Source/C/Common/Decompress.h [new file with mode: 0644]
Source/C/Common/EfiCompress.c [new file with mode: 0644]
Source/C/Common/EfiCustomizedCompress.h [new file with mode: 0644]
Source/C/Common/EfiUtilityMsgs.c [new file with mode: 0644]
Source/C/Common/EfiUtilityMsgs.h [new file with mode: 0644]
Source/C/Common/FvLib.c [new file with mode: 0644]
Source/C/Common/FvLib.h [new file with mode: 0644]
Source/C/Common/GNUmakefile [new file with mode: 0644]
Source/C/Common/Makefile [new file with mode: 0644]
Source/C/Common/MyAlloc.c [new file with mode: 0644]
Source/C/Common/MyAlloc.h [new file with mode: 0644]
Source/C/Common/ParseInf.c [new file with mode: 0644]
Source/C/Common/ParseInf.h [new file with mode: 0644]
Source/C/Common/SimpleFileParsing.c [new file with mode: 0644]
Source/C/Common/SimpleFileParsing.h [new file with mode: 0644]
Source/C/Common/TianoCompress.c [new file with mode: 0644]
Source/C/Common/WinNtInclude.h [new file with mode: 0644]
Source/C/GNUmakefile [new file with mode: 0644]
Source/C/GenFv/GNUmakefile [new file with mode: 0644]
Source/C/GenFv/GenFv.c [new file with mode: 0644]
Source/C/GenFv/GenFvInternalLib.c [new file with mode: 0644]
Source/C/GenFv/GenFvInternalLib.h [new file with mode: 0644]
Source/C/GenFv/Makefile [new file with mode: 0644]
Source/C/GenFw/GNUmakefile [new file with mode: 0644]
Source/C/GenFw/GenFw.c [new file with mode: 0644]
Source/C/GenFw/Makefile [new file with mode: 0644]
Source/C/GenSec/GNUmakefile [new file with mode: 0644]
Source/C/GenSec/GenSec.c [new file with mode: 0644]
Source/C/GenSec/Makefile [new file with mode: 0644]
Source/C/Include/Common/BaseTypes.h [new file with mode: 0644]
Source/C/Include/Common/Capsule.h [new file with mode: 0644]
Source/C/Include/Common/Dependency.h [new file with mode: 0644]
Source/C/Include/Common/EfiImage.h [new file with mode: 0644]
Source/C/Include/Common/FirmwareVolumeImageFormat.h [new file with mode: 0644]
Source/C/Include/Common/InternalFormRepresentation.h [new file with mode: 0644]
Source/C/Include/Common/MultiPhase.h [new file with mode: 0644]
Source/C/Include/Common/PiFirmwareFileSystem.h [new file with mode: 0644]
Source/C/Include/Common/PiFirmwareVolumeHeader.h [new file with mode: 0644]
Source/C/Include/Common/UefiBaseTypes.h [new file with mode: 0644]
Source/C/Include/Common/Variable.h [new file with mode: 0644]
Source/C/Include/Common/WorkingBlockHeader.h [new file with mode: 0644]
Source/C/Include/Guid/AcpiTableStorage.h [new file with mode: 0644]
Source/C/Include/Guid/Apriori.h [new file with mode: 0644]
Source/C/Include/Guid/Capsule.h [new file with mode: 0644]
Source/C/Include/Guid/PiFirmwareFileSystem.h [new file with mode: 0644]
Source/C/Include/Ia32/ProcessorBind.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/Acpi.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/Acpi1_0.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/Acpi2_0.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/Acpi3_0.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/EfiPci.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/pci22.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/pci23.h [new file with mode: 0644]
Source/C/Include/IndustryStandard/pci30.h [new file with mode: 0644]
Source/C/Include/Library/PeCoffLib.h [new file with mode: 0644]
Source/C/Include/Library/PrintLib.h [new file with mode: 0644]
Source/C/Include/Protocol/DevicePath.h [new file with mode: 0644]
Source/C/Include/Protocol/GuidedSectionExtraction.h [new file with mode: 0644]
Source/C/Include/Protocol/Hii.h [new file with mode: 0644]
Source/C/Include/Protocol/UgaDraw.h [new file with mode: 0644]
Source/C/Include/X64/ProcessorBind.h [new file with mode: 0644]
Source/C/MSmakefile.app [new file with mode: 0644]
Source/C/MSmakefile.common [new file with mode: 0644]
Source/C/MSmakefile.lib [new file with mode: 0644]
Source/C/MSmakefile.rule [new file with mode: 0644]
Source/C/Makefile [new file with mode: 0644]
Source/C/app.makefile [new file with mode: 0644]
Source/C/footer.makefile [new file with mode: 0644]
Source/C/header.makefile [new file with mode: 0644]
Source/C/lib.makefile [new file with mode: 0644]
Source/tool_setup.bat [new file with mode: 0644]

diff --git a/Source/C/Common/CommonLib.c b/Source/C/Common/CommonLib.c
new file mode 100644 (file)
index 0000000..4ae5542
--- /dev/null
@@ -0,0 +1,516 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  CommonLib.c\r
+\r
+Abstract:\r
+\r
+  Common Library Functions\r
\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include "CommonLib.h"\r
+\r
+VOID\r
+PeiZeroMem (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Size\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set Buffer to zero for Size bytes.\r
+\r
+Arguments:\r
+\r
+  Buffer  - Memory to set.\r
+\r
+  Size    - Number of bytes to set\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  INT8  *Ptr;\r
+\r
+  Ptr = Buffer;\r
+  while (Size--) {\r
+    *(Ptr++) = 0;\r
+  }\r
+}\r
+\r
+VOID\r
+PeiCopyMem (\r
+  IN VOID   *Destination,\r
+  IN VOID   *Source,\r
+  IN UINTN  Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Copy Length bytes from Source to Destination.\r
+\r
+Arguments:\r
+\r
+  Destination - Target of copy\r
+\r
+  Source      - Place to copy from\r
+\r
+  Length      - Number of bytes to copy\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  CHAR8 *Destination8;\r
+  CHAR8 *Source8;\r
+\r
+  Destination8  = Destination;\r
+  Source8       = Source;\r
+  while (Length--) {\r
+    *(Destination8++) = *(Source8++);\r
+  }\r
+}\r
+\r
+VOID\r
+ZeroMem (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Size\r
+  )\r
+{\r
+  PeiZeroMem (Buffer, Size);\r
+}\r
+\r
+VOID\r
+CopyMem (\r
+  IN VOID   *Destination,\r
+  IN VOID   *Source,\r
+  IN UINTN  Length\r
+  )\r
+{\r
+  PeiCopyMem (Destination, Source, Length);\r
+}\r
+\r
+INTN\r
+CompareGuid (\r
+  IN EFI_GUID     *Guid1,\r
+  IN EFI_GUID     *Guid2\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Compares to GUIDs\r
+\r
+Arguments:\r
+\r
+  Guid1 - guid to compare\r
+  Guid2 - guid to compare\r
+\r
+Returns:\r
+  =  0  if Guid1 == Guid2\r
+  != 0  if Guid1 != Guid2 \r
+\r
+--*/\r
+{\r
+  INT32 *g1;\r
+  INT32 *g2;\r
+  INT32 r;\r
+\r
+  //\r
+  // Compare 32 bits at a time\r
+  //\r
+  g1  = (INT32 *) Guid1;\r
+  g2  = (INT32 *) Guid2;\r
+\r
+  r   = g1[0] - g2[0];\r
+  r |= g1[1] - g2[1];\r
+  r |= g1[2] - g2[2];\r
+  r |= g1[3] - g2[3];\r
+\r
+  return r;\r
+}\r
+\r
+EFI_STATUS\r
+GetFileImage (\r
+  IN CHAR8    *InputFileName,\r
+  OUT CHAR8   **InputFileImage,\r
+  OUT UINT32  *BytesRead\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function opens a file and reads it into a memory buffer.  The function \r
+  will allocate the memory buffer and returns the size of the buffer.\r
+\r
+Arguments:\r
+\r
+  InputFileName     The name of the file to read.\r
+  InputFileImage    A pointer to the memory buffer.\r
+  BytesRead         The size of the memory buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS              The function completed successfully.\r
+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.\r
+  EFI_ABORTED              An error occurred.\r
+  EFI_OUT_OF_RESOURCES     No resource to complete operations.\r
+\r
+--*/\r
+{\r
+  FILE    *InputFile;\r
+  UINT32  FileSize;\r
+\r
+  //\r
+  // Verify input parameters.\r
+  //\r
+  if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Open the file and copy contents into a memory buffer.\r
+  //\r
+  //\r
+  // Open the file\r
+  //\r
+  InputFile = fopen (InputFileName, "rb");\r
+  if (InputFile == NULL) {\r
+    printf ("ERROR: Could not open input file \"%s\".\n", InputFileName);\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Go to the end so that we can determine the file size\r
+  //\r
+  if (fseek (InputFile, 0, SEEK_END)) {\r
+    printf ("ERROR: System error reading input file \"%s\".\n", InputFileName);\r
+    fclose (InputFile);\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Get the file size\r
+  //\r
+  FileSize = ftell (InputFile);\r
+  if (FileSize == -1) {\r
+    printf ("ERROR: System error parsing input file \"%s\".\n", InputFileName);\r
+    fclose (InputFile);\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Allocate a buffer\r
+  //\r
+  *InputFileImage = malloc (FileSize);\r
+  if (*InputFileImage == NULL) {\r
+    fclose (InputFile);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  //\r
+  // Reset to the beginning of the file\r
+  //\r
+  if (fseek (InputFile, 0, SEEK_SET)) {\r
+    printf ("ERROR: System error reading input file \"%s\".\n", InputFileName);\r
+    fclose (InputFile);\r
+    free (*InputFileImage);\r
+    *InputFileImage = NULL;\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Read all of the file contents.\r
+  //\r
+  *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile);\r
+  if (*BytesRead != sizeof (UINT8) * FileSize) {\r
+    printf ("ERROR: Reading file \"%s\"%i.\n", InputFileName);\r
+    fclose (InputFile);\r
+    free (*InputFileImage);\r
+    *InputFileImage = NULL;\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Close the file\r
+  //\r
+  fclose (InputFile);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+UINT8\r
+CalculateChecksum8 (\r
+  IN UINT8        *Buffer,\r
+  IN UINTN        Size\r
+  )\r
+/*++\r
+  \r
+Routine Description:\r
+\r
+  This function calculates the value needed for a valid UINT8 checksum\r
+\r
+Arguments:\r
+\r
+  Buffer      Pointer to buffer containing byte data of component.\r
+  Size        Size of the buffer\r
+\r
+Returns:\r
+\r
+  The 8 bit checksum value needed.\r
+\r
+--*/\r
+{\r
+  return (UINT8) (0x100 - CalculateSum8 (Buffer, Size));\r
+}\r
+\r
+UINT8\r
+CalculateSum8 (\r
+  IN UINT8  *Buffer,\r
+  IN UINTN  Size\r
+  )\r
+/*++\r
+  \r
+Routine Description::\r
+\r
+  This function calculates the UINT8 sum for the requested region.\r
+\r
+Arguments:\r
+\r
+  Buffer      Pointer to buffer containing byte data of component.\r
+  Size        Size of the buffer\r
+\r
+Returns:\r
+\r
+  The 8 bit checksum value needed.\r
+\r
+--*/\r
+{\r
+  UINTN Index;\r
+  UINT8 Sum;\r
+\r
+  Sum = 0;\r
+\r
+  //\r
+  // Perform the byte sum for buffer\r
+  //\r
+  for (Index = 0; Index < Size; Index++) {\r
+    Sum = (UINT8) (Sum + Buffer[Index]);\r
+  }\r
+\r
+  return Sum;\r
+}\r
+\r
+UINT16\r
+CalculateChecksum16 (\r
+  IN UINT16       *Buffer,\r
+  IN UINTN        Size\r
+  )\r
+/*++\r
+  \r
+Routine Description::\r
+\r
+  This function calculates the value needed for a valid UINT16 checksum\r
+\r
+Arguments:\r
+\r
+  Buffer      Pointer to buffer containing byte data of component.\r
+  Size        Size of the buffer\r
+\r
+Returns:\r
+\r
+  The 16 bit checksum value needed.\r
+\r
+--*/\r
+{\r
+  return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size));\r
+}\r
+\r
+UINT16\r
+CalculateSum16 (\r
+  IN UINT16       *Buffer,\r
+  IN UINTN        Size\r
+  )\r
+/*++\r
+  \r
+Routine Description:\r
+\r
+  This function calculates the UINT16 sum for the requested region.\r
+\r
+Arguments:\r
+\r
+  Buffer      Pointer to buffer containing byte data of component.\r
+  Size        Size of the buffer\r
+\r
+Returns:\r
+\r
+  The 16 bit checksum\r
+\r
+--*/\r
+{\r
+  UINTN   Index;\r
+  UINT16  Sum;\r
+\r
+  Sum = 0;\r
+\r
+  //\r
+  // Perform the word sum for buffer\r
+  //\r
+  for (Index = 0; Index < Size; Index++) {\r
+    Sum = (UINT16) (Sum + Buffer[Index]);\r
+  }\r
+\r
+  return (UINT16) Sum;\r
+}\r
+\r
+EFI_STATUS\r
+PrintGuid (\r
+  IN EFI_GUID *Guid\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function prints a GUID to STDOUT.\r
+\r
+Arguments:\r
+\r
+  Guid    Pointer to a GUID to print.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             The GUID was printed.\r
+  EFI_INVALID_PARAMETER   The input was NULL.\r
+\r
+--*/\r
+{\r
+  if (Guid == NULL) {\r
+    printf ("ERROR: PrintGuid called with a NULL value.\n");\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  printf (\r
+    "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",\r
+    Guid->Data1,\r
+    Guid->Data2,\r
+    Guid->Data3,\r
+    Guid->Data4[0],\r
+    Guid->Data4[1],\r
+    Guid->Data4[2],\r
+    Guid->Data4[3],\r
+    Guid->Data4[4],\r
+    Guid->Data4[5],\r
+    Guid->Data4[6],\r
+    Guid->Data4[7]\r
+    );\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PrintGuidToBuffer (\r
+  IN EFI_GUID     *Guid,\r
+  IN OUT UINT8    *Buffer,\r
+  IN UINT32       BufferLen,\r
+  IN BOOLEAN      Uppercase\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function prints a GUID to a buffer\r
+\r
+Arguments:\r
+\r
+  Guid      - Pointer to a GUID to print.\r
+  Buffer    - Pointer to a user-provided buffer to print to\r
+  BufferLen - Size of the Buffer\r
+  Uppercase - If use upper case.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             The GUID was printed.\r
+  EFI_INVALID_PARAMETER   The input was NULL.\r
+  EFI_BUFFER_TOO_SMALL    The input buffer was not big enough\r
+  \r
+--*/\r
+{\r
+  if (Guid == NULL) {\r
+    printf ("ERROR: PrintGuidToBuffer() called with a NULL value\n");\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (BufferLen < PRINTED_GUID_BUFFER_SIZE) {\r
+    printf ("ERORR: PrintGuidToBuffer() called with invalid buffer size\n");\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  if (Uppercase) {\r
+    sprintf (\r
+      Buffer,\r
+      "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",\r
+      Guid->Data1,\r
+      Guid->Data2,\r
+      Guid->Data3,\r
+      Guid->Data4[0],\r
+      Guid->Data4[1],\r
+      Guid->Data4[2],\r
+      Guid->Data4[3],\r
+      Guid->Data4[4],\r
+      Guid->Data4[5],\r
+      Guid->Data4[6],\r
+      Guid->Data4[7]\r
+      );\r
+  } else {\r
+    sprintf (\r
+      Buffer,\r
+      "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
+      Guid->Data1,\r
+      Guid->Data2,\r
+      Guid->Data3,\r
+      Guid->Data4[0],\r
+      Guid->Data4[1],\r
+      Guid->Data4[2],\r
+      Guid->Data4[3],\r
+      Guid->Data4[4],\r
+      Guid->Data4[5],\r
+      Guid->Data4[6],\r
+      Guid->Data4[7]\r
+      );\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+#ifdef __GNUC__\r
+\r
+size_t _filelength(int fd)\r
+{\r
+  struct stat stat_buf;\r
+  fstat(fd, &stat_buf);\r
+  return stat_buf.st_size;\r
+}\r
+\r
+#ifndef __CYGWIN__\r
+char *strlwr(char *s)\r
+{\r
+  char *p = s;\r
+  for(;*s;s++) {\r
+    *s = tolower(*s);\r
+  }\r
+  return p;\r
+}\r
+#endif\r
+#endif\r
diff --git a/Source/C/Common/CommonLib.h b/Source/C/Common/CommonLib.h
new file mode 100644 (file)
index 0000000..40d3535
--- /dev/null
@@ -0,0 +1,139 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  CommonLib.h\r
+\r
+Abstract:\r
+\r
+  Common library assistance routines.\r
+\r
+--*/\r
+\r
+#ifndef _EFI_COMMON_LIB_H\r
+#define _EFI_COMMON_LIB_H\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+\r
+#ifndef _MAX_PATH\r
+#define _MAX_PATH 500\r
+#endif\r
+\r
+#define PRINTED_GUID_BUFFER_SIZE  37  // including null-termination\r
+//\r
+// Function declarations\r
+//\r
+VOID\r
+PeiZeroMem (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Size\r
+  )\r
+;\r
+\r
+VOID\r
+PeiCopyMem (\r
+  IN VOID   *Destination,\r
+  IN VOID   *Source,\r
+  IN UINTN  Length\r
+  )\r
+;\r
+\r
+VOID\r
+ZeroMem (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Size\r
+  )\r
+;\r
+\r
+VOID\r
+CopyMem (\r
+  IN VOID   *Destination,\r
+  IN VOID   *Source,\r
+  IN UINTN  Length\r
+  )\r
+;\r
+\r
+INTN\r
+CompareGuid (\r
+  IN EFI_GUID     *Guid1,\r
+  IN EFI_GUID     *Guid2\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+GetFileImage (\r
+  IN CHAR8    *InputFileName,\r
+  OUT CHAR8   **InputFileImage,\r
+  OUT UINT32  *BytesRead\r
+  )\r
+;\r
+\r
+UINT8\r
+CalculateChecksum8 (\r
+  IN UINT8        *Buffer,\r
+  IN UINTN        Size\r
+  )\r
+;\r
+\r
+UINT8\r
+CalculateSum8 (\r
+  IN UINT8        *Buffer,\r
+  IN UINTN        Size\r
+  )\r
+;\r
+\r
+UINT16\r
+CalculateChecksum16 (\r
+  IN UINT16       *Buffer,\r
+  IN UINTN        Size\r
+  )\r
+;\r
+\r
+UINT16\r
+CalculateSum16 (\r
+  IN UINT16       *Buffer,\r
+  IN UINTN        Size\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+PrintGuid (\r
+  IN EFI_GUID                     *Guid\r
+  )\r
+;\r
+\r
+#define PRINTED_GUID_BUFFER_SIZE  37  // including null-termination\r
+EFI_STATUS\r
+PrintGuidToBuffer (\r
+  IN EFI_GUID     *Guid,\r
+  IN OUT UINT8    *Buffer,\r
+  IN UINT32       BufferLen,\r
+  IN BOOLEAN      Uppercase\r
+  )\r
+;\r
+\r
+#define ASSERT(x) assert(x)\r
+\r
+#ifdef __GNUC__\r
+#include <stdio.h>\r
+#include <sys/stat.h>\r
+#define stricmp strcasecmp\r
+#define _stricmp strcasecmp\r
+#define strnicmp strncasecmp\r
+#define strcmpi strcasecmp\r
+size_t _filelength(int fd);\r
+#ifndef __CYGWIN__\r
+char *strlwr(char *s);\r
+#endif\r
+#endif\r
+\r
+#endif\r
diff --git a/Source/C/Common/Compress.h b/Source/C/Common/Compress.h
new file mode 100644 (file)
index 0000000..7366e72
--- /dev/null
@@ -0,0 +1,94 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2006, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  Compress.h\r
+\r
+Abstract:\r
+\r
+  Header file for compression routine.\r
+  Providing both EFI and Tiano Compress algorithms.\r
+  \r
+--*/\r
+\r
+#ifndef _COMPRESS_H_\r
+#define _COMPRESS_H_\r
+\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Tiano compression routine.\r
+\r
+--*/\r
+EFI_STATUS\r
+TianoCompress (\r
+  IN      UINT8   *SrcBuffer,\r
+  IN      UINT32  SrcSize,\r
+  IN      UINT8   *DstBuffer,\r
+  IN OUT  UINT32  *DstSize\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Efi compression routine.\r
+\r
+--*/\r
+EFI_STATUS\r
+EfiCompress (\r
+  IN      UINT8   *SrcBuffer,\r
+  IN      UINT32  SrcSize,\r
+  IN      UINT8   *DstBuffer,\r
+  IN OUT  UINT32  *DstSize\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The compression routine.\r
+\r
+Arguments:\r
+\r
+  SrcBuffer   - The buffer storing the source data\r
+  SrcSize     - The size of source data\r
+  DstBuffer   - The buffer to store the compressed data\r
+  DstSize     - On input, the size of DstBuffer; On output,\r
+                the size of the actual compressed data.\r
+\r
+Returns:\r
+\r
+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,\r
+                DstSize contains the size needed.\r
+  EFI_SUCCESS           - Compression is successful.\r
+  EFI_OUT_OF_RESOURCES  - No resource to complete function.\r
+  EFI_INVALID_PARAMETER - Parameter supplied is wrong.\r
+\r
+--*/\r
+typedef\r
+EFI_STATUS\r
+(*COMPRESS_FUNCTION) (\r
+  IN      UINT8   *SrcBuffer,\r
+  IN      UINT32  SrcSize,\r
+  IN      UINT8   *DstBuffer,\r
+  IN OUT  UINT32  *DstSize\r
+  );\r
+\r
+#endif\r
diff --git a/Source/C/Common/Crc32.c b/Source/C/Common/Crc32.c
new file mode 100644 (file)
index 0000000..4ae5eb4
--- /dev/null
@@ -0,0 +1,326 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  crc32.c\r
+\r
+Abstract:\r
+\r
+  CalcuateCrc32 routine.\r
+  \r
+--*/\r
+\r
+#include <stdlib.h>\r
+#include "Crc32.h"\r
+\r
+UINT32  mCrcTable[256] = {\r
+  0x00000000,\r
+  0x77073096,\r
+  0xEE0E612C,\r
+  0x990951BA,\r
+  0x076DC419,\r
+  0x706AF48F,\r
+  0xE963A535,\r
+  0x9E6495A3,\r
+  0x0EDB8832,\r
+  0x79DCB8A4,\r
+  0xE0D5E91E,\r
+  0x97D2D988,\r
+  0x09B64C2B,\r
+  0x7EB17CBD,\r
+  0xE7B82D07,\r
+  0x90BF1D91,\r
+  0x1DB71064,\r
+  0x6AB020F2,\r
+  0xF3B97148,\r
+  0x84BE41DE,\r
+  0x1ADAD47D,\r
+  0x6DDDE4EB,\r
+  0xF4D4B551,\r
+  0x83D385C7,\r
+  0x136C9856,\r
+  0x646BA8C0,\r
+  0xFD62F97A,\r
+  0x8A65C9EC,\r
+  0x14015C4F,\r
+  0x63066CD9,\r
+  0xFA0F3D63,\r
+  0x8D080DF5,\r
+  0x3B6E20C8,\r
+  0x4C69105E,\r
+  0xD56041E4,\r
+  0xA2677172,\r
+  0x3C03E4D1,\r
+  0x4B04D447,\r
+  0xD20D85FD,\r
+  0xA50AB56B,\r
+  0x35B5A8FA,\r
+  0x42B2986C,\r
+  0xDBBBC9D6,\r
+  0xACBCF940,\r
+  0x32D86CE3,\r
+  0x45DF5C75,\r
+  0xDCD60DCF,\r
+  0xABD13D59,\r
+  0x26D930AC,\r
+  0x51DE003A,\r
+  0xC8D75180,\r
+  0xBFD06116,\r
+  0x21B4F4B5,\r
+  0x56B3C423,\r
+  0xCFBA9599,\r
+  0xB8BDA50F,\r
+  0x2802B89E,\r
+  0x5F058808,\r
+  0xC60CD9B2,\r
+  0xB10BE924,\r
+  0x2F6F7C87,\r
+  0x58684C11,\r
+  0xC1611DAB,\r
+  0xB6662D3D,\r
+  0x76DC4190,\r
+  0x01DB7106,\r
+  0x98D220BC,\r
+  0xEFD5102A,\r
+  0x71B18589,\r
+  0x06B6B51F,\r
+  0x9FBFE4A5,\r
+  0xE8B8D433,\r
+  0x7807C9A2,\r
+  0x0F00F934,\r
+  0x9609A88E,\r
+  0xE10E9818,\r
+  0x7F6A0DBB,\r
+  0x086D3D2D,\r
+  0x91646C97,\r
+  0xE6635C01,\r
+  0x6B6B51F4,\r
+  0x1C6C6162,\r
+  0x856530D8,\r
+  0xF262004E,\r
+  0x6C0695ED,\r
+  0x1B01A57B,\r
+  0x8208F4C1,\r
+  0xF50FC457,\r
+  0x65B0D9C6,\r
+  0x12B7E950,\r
+  0x8BBEB8EA,\r
+  0xFCB9887C,\r
+  0x62DD1DDF,\r
+  0x15DA2D49,\r
+  0x8CD37CF3,\r
+  0xFBD44C65,\r
+  0x4DB26158,\r
+  0x3AB551CE,\r
+  0xA3BC0074,\r
+  0xD4BB30E2,\r
+  0x4ADFA541,\r
+  0x3DD895D7,\r
+  0xA4D1C46D,\r
+  0xD3D6F4FB,\r
+  0x4369E96A,\r
+  0x346ED9FC,\r
+  0xAD678846,\r
+  0xDA60B8D0,\r
+  0x44042D73,\r
+  0x33031DE5,\r
+  0xAA0A4C5F,\r
+  0xDD0D7CC9,\r
+  0x5005713C,\r
+  0x270241AA,\r
+  0xBE0B1010,\r
+  0xC90C2086,\r
+  0x5768B525,\r
+  0x206F85B3,\r
+  0xB966D409,\r
+  0xCE61E49F,\r
+  0x5EDEF90E,\r
+  0x29D9C998,\r
+  0xB0D09822,\r
+  0xC7D7A8B4,\r
+  0x59B33D17,\r
+  0x2EB40D81,\r
+  0xB7BD5C3B,\r
+  0xC0BA6CAD,\r
+  0xEDB88320,\r
+  0x9ABFB3B6,\r
+  0x03B6E20C,\r
+  0x74B1D29A,\r
+  0xEAD54739,\r
+  0x9DD277AF,\r
+  0x04DB2615,\r
+  0x73DC1683,\r
+  0xE3630B12,\r
+  0x94643B84,\r
+  0x0D6D6A3E,\r
+  0x7A6A5AA8,\r
+  0xE40ECF0B,\r
+  0x9309FF9D,\r
+  0x0A00AE27,\r
+  0x7D079EB1,\r
+  0xF00F9344,\r
+  0x8708A3D2,\r
+  0x1E01F268,\r
+  0x6906C2FE,\r
+  0xF762575D,\r
+  0x806567CB,\r
+  0x196C3671,\r
+  0x6E6B06E7,\r
+  0xFED41B76,\r
+  0x89D32BE0,\r
+  0x10DA7A5A,\r
+  0x67DD4ACC,\r
+  0xF9B9DF6F,\r
+  0x8EBEEFF9,\r
+  0x17B7BE43,\r
+  0x60B08ED5,\r
+  0xD6D6A3E8,\r
+  0xA1D1937E,\r
+  0x38D8C2C4,\r
+  0x4FDFF252,\r
+  0xD1BB67F1,\r
+  0xA6BC5767,\r
+  0x3FB506DD,\r
+  0x48B2364B,\r
+  0xD80D2BDA,\r
+  0xAF0A1B4C,\r
+  0x36034AF6,\r
+  0x41047A60,\r
+  0xDF60EFC3,\r
+  0xA867DF55,\r
+  0x316E8EEF,\r
+  0x4669BE79,\r
+  0xCB61B38C,\r
+  0xBC66831A,\r
+  0x256FD2A0,\r
+  0x5268E236,\r
+  0xCC0C7795,\r
+  0xBB0B4703,\r
+  0x220216B9,\r
+  0x5505262F,\r
+  0xC5BA3BBE,\r
+  0xB2BD0B28,\r
+  0x2BB45A92,\r
+  0x5CB36A04,\r
+  0xC2D7FFA7,\r
+  0xB5D0CF31,\r
+  0x2CD99E8B,\r
+  0x5BDEAE1D,\r
+  0x9B64C2B0,\r
+  0xEC63F226,\r
+  0x756AA39C,\r
+  0x026D930A,\r
+  0x9C0906A9,\r
+  0xEB0E363F,\r
+  0x72076785,\r
+  0x05005713,\r
+  0x95BF4A82,\r
+  0xE2B87A14,\r
+  0x7BB12BAE,\r
+  0x0CB61B38,\r
+  0x92D28E9B,\r
+  0xE5D5BE0D,\r
+  0x7CDCEFB7,\r
+  0x0BDBDF21,\r
+  0x86D3D2D4,\r
+  0xF1D4E242,\r
+  0x68DDB3F8,\r
+  0x1FDA836E,\r
+  0x81BE16CD,\r
+  0xF6B9265B,\r
+  0x6FB077E1,\r
+  0x18B74777,\r
+  0x88085AE6,\r
+  0xFF0F6A70,\r
+  0x66063BCA,\r
+  0x11010B5C,\r
+  0x8F659EFF,\r
+  0xF862AE69,\r
+  0x616BFFD3,\r
+  0x166CCF45,\r
+  0xA00AE278,\r
+  0xD70DD2EE,\r
+  0x4E048354,\r
+  0x3903B3C2,\r
+  0xA7672661,\r
+  0xD06016F7,\r
+  0x4969474D,\r
+  0x3E6E77DB,\r
+  0xAED16A4A,\r
+  0xD9D65ADC,\r
+  0x40DF0B66,\r
+  0x37D83BF0,\r
+  0xA9BCAE53,\r
+  0xDEBB9EC5,\r
+  0x47B2CF7F,\r
+  0x30B5FFE9,\r
+  0xBDBDF21C,\r
+  0xCABAC28A,\r
+  0x53B39330,\r
+  0x24B4A3A6,\r
+  0xBAD03605,\r
+  0xCDD70693,\r
+  0x54DE5729,\r
+  0x23D967BF,\r
+  0xB3667A2E,\r
+  0xC4614AB8,\r
+  0x5D681B02,\r
+  0x2A6F2B94,\r
+  0xB40BBE37,\r
+  0xC30C8EA1,\r
+  0x5A05DF1B,\r
+  0x2D02EF8D\r
+};\r
+\r
+EFI_STATUS\r
+CalculateCrc32 (\r
+  IN  UINT8                             *Data,\r
+  IN  UINTN                             DataSize,\r
+  IN OUT UINT32                         *CrcOut\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The CalculateCrc32 routine.\r
+\r
+Arguments:\r
+\r
+  Data        - The buffer contaning the data to be processed\r
+  DataSize    - The size of data to be processed\r
+  CrcOut      - A pointer to the caller allocated UINT32 that on\r
+                contains the CRC32 checksum of Data\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS               - Calculation is successful.\r
+  EFI_INVALID_PARAMETER     - Data / CrcOut = NULL, or DataSize = 0\r
+\r
+--*/\r
+{\r
+  UINT32  Crc;\r
+  UINTN   Index;\r
+  UINT8   *Ptr;\r
+\r
+  if ((DataSize == 0) || (Data == NULL) || (CrcOut == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Crc = 0xffffffff;\r
+  for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {\r
+    Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];\r
+  }\r
+\r
+  *CrcOut = Crc ^ 0xffffffff;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/Source/C/Common/Crc32.h b/Source/C/Common/Crc32.h
new file mode 100644 (file)
index 0000000..ec48cdd
--- /dev/null
@@ -0,0 +1,54 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  Crc32.h\r
+\r
+Abstract:\r
+\r
+  Header file for CalcuateCrc32 routine\r
+  \r
+--*/\r
+\r
+#ifndef _CRC32_H\r
+#define _CRC32_H\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+\r
+EFI_STATUS\r
+CalculateCrc32 (\r
+  IN  UINT8                             *Data,\r
+  IN  UINTN                             DataSize,\r
+  IN OUT UINT32                         *CrcOut\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The CalculateCrc32 routine.\r
+\r
+Arguments:\r
+\r
+  Data        - The buffer contaning the data to be processed\r
+  DataSize    - The size of data to be processed\r
+  CrcOut      - A pointer to the caller allocated UINT32 that on\r
+                contains the CRC32 checksum of Data\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS               - Calculation is successful.\r
+  EFI_INVALID_PARAMETER     - Data / CrcOut = NULL, or DataSize = 0\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
diff --git a/Source/C/Common/Decompress.c b/Source/C/Common/Decompress.c
new file mode 100644 (file)
index 0000000..07b2b8c
--- /dev/null
@@ -0,0 +1,923 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+  \r
+  Decompress.c\r
+\r
+Abstract:\r
+\r
+  Decompressor. Algorithm Ported from OPSD code (Decomp.asm) \r
+  for Efi and Tiano compress algorithm.\r
+  \r
+--*/\r
+\r
+#include "Decompress.h"\r
+\r
+//\r
+// Decompression algorithm begins here\r
+//\r
+#define BITBUFSIZ 32\r
+#define MAXMATCH  256\r
+#define THRESHOLD 3\r
+#define CODE_BIT  16\r
+#define BAD_TABLE - 1\r
+\r
+//\r
+// C: Char&Len Set; P: Position Set; T: exTra Set\r
+//\r
+#define NC      (0xff + MAXMATCH + 2 - THRESHOLD)\r
+#define CBIT    9\r
+#define EFIPBIT 4\r
+#define MAXPBIT 5\r
+#define TBIT    5\r
+#define MAXNP ((1U << MAXPBIT) - 1)\r
+#define NT    (CODE_BIT + 3)\r
+#if NT > MAXNP\r
+#define NPT NT\r
+#else\r
+#define NPT MAXNP\r
+#endif\r
+\r
+typedef struct {\r
+  UINT8   *mSrcBase;  // Starting address of compressed data\r
+  UINT8   *mDstBase;  // Starting address of decompressed data\r
+  UINT32  mOutBuf;\r
+  UINT32  mInBuf;\r
+\r
+  UINT16  mBitCount;\r
+  UINT32  mBitBuf;\r
+  UINT32  mSubBitBuf;\r
+  UINT16  mBlockSize;\r
+  UINT32  mCompSize;\r
+  UINT32  mOrigSize;\r
+\r
+  UINT16  mBadTableFlag;\r
+\r
+  UINT16  mLeft[2 * NC - 1];\r
+  UINT16  mRight[2 * NC - 1];\r
+  UINT8   mCLen[NC];\r
+  UINT8   mPTLen[NPT];\r
+  UINT16  mCTable[4096];\r
+  UINT16  mPTTable[256];\r
+} SCRATCH_DATA;\r
+\r
+STATIC UINT16 mPbit = EFIPBIT;\r
+  \r
+STATIC\r
+VOID\r
+FillBuf (\r
+  IN  SCRATCH_DATA  *Sd,\r
+  IN  UINT16        NumOfBits\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.\r
+\r
+Arguments:\r
+\r
+  Sd        - The global scratch data\r
+  NumOfBit  - The number of bits to shift and read.\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);\r
+\r
+  while (NumOfBits > Sd->mBitCount) {\r
+\r
+    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
+\r
+    if (Sd->mCompSize > 0) {\r
+      //\r
+      // Get 1 byte into SubBitBuf\r
+      //\r
+      Sd->mCompSize--;\r
+      Sd->mSubBitBuf  = 0;\r
+      Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];\r
+      Sd->mBitCount   = 8;\r
+\r
+    } else {\r
+      //\r
+      // No more bits from the source, just pad zero bit.\r
+      //\r
+      Sd->mSubBitBuf  = 0;\r
+      Sd->mBitCount   = 8;\r
+\r
+    }\r
+  }\r
+\r
+  Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);\r
+  Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;\r
+}\r
+\r
+STATIC\r
+UINT32\r
+GetBits (\r
+  IN  SCRATCH_DATA  *Sd,\r
+  IN  UINT16        NumOfBits\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent \r
+  NumOfBits of bits from source. Returns NumOfBits of bits that are \r
+  popped out.\r
+\r
+Arguments:\r
+\r
+  Sd            - The global scratch data.\r
+  NumOfBits     - The number of bits to pop and read.\r
+\r
+Returns:\r
+\r
+  The bits that are popped out.\r
+\r
+--*/\r
+{\r
+  UINT32  OutBits;\r
+\r
+  OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));\r
+\r
+  FillBuf (Sd, NumOfBits);\r
+\r
+  return OutBits;\r
+}\r
+\r
+STATIC\r
+UINT16\r
+MakeTable (\r
+  IN  SCRATCH_DATA  *Sd,\r
+  IN  UINT16        NumOfChar,\r
+  IN  UINT8         *BitLen,\r
+  IN  UINT16        TableBits,\r
+  OUT UINT16        *Table\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Creates Huffman Code mapping table according to code length array.\r
+\r
+Arguments:\r
+\r
+  Sd        - The global scratch data\r
+  NumOfChar - Number of symbols in the symbol set\r
+  BitLen    - Code length array\r
+  TableBits - The width of the mapping table\r
+  Table     - The table\r
+  \r
+Returns:\r
+  \r
+  0         - OK.\r
+  BAD_TABLE - The table is corrupted.\r
+\r
+--*/\r
+{\r
+  UINT16  Count[17];\r
+  UINT16  Weight[17];\r
+  UINT16  Start[18];\r
+  UINT16  *Pointer;\r
+  UINT16  Index3;\r
+  UINT16  Index;\r
+  UINT16  Len;\r
+  UINT16  Char;\r
+  UINT16  JuBits;\r
+  UINT16  Avail;\r
+  UINT16  NextCode;\r
+  UINT16  Mask;\r
+\r
+  for (Index = 1; Index <= 16; Index++) {\r
+    Count[Index] = 0;\r
+  }\r
+\r
+  for (Index = 0; Index < NumOfChar; Index++) {\r
+    Count[BitLen[Index]]++;\r
+  }\r
+\r
+  Start[1] = 0;\r
+\r
+  for (Index = 1; Index <= 16; Index++) {\r
+    Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));\r
+  }\r
+\r
+  if (Start[17] != 0) {\r
+    /*(1U << 16)*/\r
+    return (UINT16) BAD_TABLE;\r
+  }\r
+\r
+  JuBits = (UINT16) (16 - TableBits);\r
+\r
+  for (Index = 1; Index <= TableBits; Index++) {\r
+    Start[Index] >>= JuBits;\r
+    Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
+  }\r
+\r
+  while (Index <= 16) {\r
+    Weight[Index++] = (UINT16) (1U << (16 - Index));\r
+  }\r
+\r
+  Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r
+\r
+  if (Index != 0) {\r
+    Index3 = (UINT16) (1U << TableBits);\r
+    while (Index != Index3) {\r
+      Table[Index++] = 0;\r
+    }\r
+  }\r
+\r
+  Avail = NumOfChar;\r
+  Mask  = (UINT16) (1U << (15 - TableBits));\r
+\r
+  for (Char = 0; Char < NumOfChar; Char++) {\r
+\r
+    Len = BitLen[Char];\r
+    if (Len == 0) {\r
+      continue;\r
+    }\r
+\r
+    NextCode = (UINT16) (Start[Len] + Weight[Len]);\r
+\r
+    if (Len <= TableBits) {\r
+\r
+      for (Index = Start[Len]; Index < NextCode; Index++) {\r
+        Table[Index] = Char;\r
+      }\r
+\r
+    } else {\r
+\r
+      Index3  = Start[Len];\r
+      Pointer = &Table[Index3 >> JuBits];\r
+      Index   = (UINT16) (Len - TableBits);\r
+\r
+      while (Index != 0) {\r
+        if (*Pointer == 0) {\r
+          Sd->mRight[Avail]                     = Sd->mLeft[Avail] = 0;\r
+          *Pointer = Avail++;\r
+        }\r
+\r
+        if (Index3 & Mask) {\r
+          Pointer = &Sd->mRight[*Pointer];\r
+        } else {\r
+          Pointer = &Sd->mLeft[*Pointer];\r
+        }\r
+\r
+        Index3 <<= 1;\r
+        Index--;\r
+      }\r
+\r
+      *Pointer = Char;\r
+\r
+    }\r
+\r
+    Start[Len] = NextCode;\r
+  }\r
+  //\r
+  // Succeeds\r
+  //\r
+  return 0;\r
+}\r
+\r
+STATIC\r
+UINT32\r
+DecodeP (\r
+  IN  SCRATCH_DATA  *Sd\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Decodes a position value.\r
+\r
+Arguments:\r
+\r
+  Sd      - the global scratch data\r
+\r
+Returns:\r
+\r
+  The position value decoded.\r
+\r
+--*/\r
+{\r
+  UINT16  Val;\r
+  UINT32  Mask;\r
+  UINT32  Pos;\r
+\r
+  Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
+\r
+  if (Val >= MAXNP) {\r
+    Mask = 1U << (BITBUFSIZ - 1 - 8);\r
+\r
+    do {\r
+\r
+      if (Sd->mBitBuf & Mask) {\r
+        Val = Sd->mRight[Val];\r
+      } else {\r
+        Val = Sd->mLeft[Val];\r
+      }\r
+\r
+      Mask >>= 1;\r
+    } while (Val >= MAXNP);\r
+  }\r
+  //\r
+  // Advance what we have read\r
+  //\r
+  FillBuf (Sd, Sd->mPTLen[Val]);\r
+\r
+  Pos = Val;\r
+  if (Val > 1) {\r
+    Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r
+  }\r
+\r
+  return Pos;\r
+}\r
+\r
+STATIC\r
+UINT16\r
+ReadPTLen (\r
+  IN  SCRATCH_DATA  *Sd,\r
+  IN  UINT16        nn,\r
+  IN  UINT16        nbit,\r
+  IN  UINT16        Special\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Reads code lengths for the Extra Set or the Position Set\r
+\r
+Arguments:\r
+\r
+  Sd        - The global scratch data\r
+  nn        - Number of symbols\r
+  nbit      - Number of bits needed to represent nn\r
+  Special   - The special symbol that needs to be taken care of \r
+\r
+Returns:\r
+\r
+  0         - OK.\r
+  BAD_TABLE - Table is corrupted.\r
+\r
+--*/\r
+{\r
+  UINT16  Number;\r
+  UINT16  CharC;\r
+  UINT16  Index;\r
+  UINT32  Mask;\r
+\r
+  Number = (UINT16) GetBits (Sd, nbit);\r
+\r
+  if (Number == 0) {\r
+    CharC = (UINT16) GetBits (Sd, nbit);\r
+\r
+    for (Index = 0; Index < 256; Index++) {\r
+      Sd->mPTTable[Index] = CharC;\r
+    }\r
+\r
+    for (Index = 0; Index < nn; Index++) {\r
+      Sd->mPTLen[Index] = 0;\r
+    }\r
+\r
+    return 0;\r
+  }\r
+\r
+  Index = 0;\r
+\r
+  while (Index < Number) {\r
+\r
+    CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
+\r
+    if (CharC == 7) {\r
+      Mask = 1U << (BITBUFSIZ - 1 - 3);\r
+      while (Mask & Sd->mBitBuf) {\r
+        Mask >>= 1;\r
+        CharC += 1;\r
+      }\r
+    }\r
+\r
+    FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
+\r
+    Sd->mPTLen[Index++] = (UINT8) CharC;\r
+\r
+    if (Index == Special) {\r
+      CharC = (UINT16) GetBits (Sd, 2);\r
+      CharC--;\r
+      while ((INT16) (CharC) >= 0) {\r
+        Sd->mPTLen[Index++] = 0;\r
+        CharC--;\r
+      }\r
+    }\r
+  }\r
+\r
+  while (Index < nn) {\r
+    Sd->mPTLen[Index++] = 0;\r
+  }\r
+\r
+  return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
+}\r
+\r
+STATIC\r
+VOID\r
+ReadCLen (\r
+  SCRATCH_DATA  *Sd\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Reads code lengths for Char&Len Set.\r
+\r
+Arguments:\r
+\r
+  Sd    - the global scratch data\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  UINT16  Number;\r
+  UINT16  CharC;\r
+  UINT16  Index;\r
+  UINT32  Mask;\r
+\r
+  Number = (UINT16) GetBits (Sd, CBIT);\r
+\r
+  if (Number == 0) {\r
+    CharC = (UINT16) GetBits (Sd, CBIT);\r
+\r
+    for (Index = 0; Index < NC; Index++) {\r
+      Sd->mCLen[Index] = 0;\r
+    }\r
+\r
+    for (Index = 0; Index < 4096; Index++) {\r
+      Sd->mCTable[Index] = CharC;\r
+    }\r
+\r
+    return ;\r
+  }\r
+\r
+  Index = 0;\r
+  while (Index < Number) {\r
+\r
+    CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
+    if (CharC >= NT) {\r
+      Mask = 1U << (BITBUFSIZ - 1 - 8);\r
+\r
+      do {\r
+\r
+        if (Mask & Sd->mBitBuf) {\r
+          CharC = Sd->mRight[CharC];\r
+        } else {\r
+          CharC = Sd->mLeft[CharC];\r
+        }\r
+\r
+        Mask >>= 1;\r
+\r
+      } while (CharC >= NT);\r
+    }\r
+    //\r
+    // Advance what we have read\r
+    //\r
+    FillBuf (Sd, Sd->mPTLen[CharC]);\r
+\r
+    if (CharC <= 2) {\r
+\r
+      if (CharC == 0) {\r
+        CharC = 1;\r
+      } else if (CharC == 1) {\r
+        CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
+      } else if (CharC == 2) {\r
+        CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
+      }\r
+\r
+      CharC--;\r
+      while ((INT16) (CharC) >= 0) {\r
+        Sd->mCLen[Index++] = 0;\r
+        CharC--;\r
+      }\r
+\r
+    } else {\r
+\r
+      Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
+\r
+    }\r
+  }\r
+\r
+  while (Index < NC) {\r
+    Sd->mCLen[Index++] = 0;\r
+  }\r
+\r
+  MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
+\r
+  return ;\r
+}\r
+\r
+STATIC\r
+UINT16\r
+DecodeC (\r
+  SCRATCH_DATA  *Sd\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Decode a character/length value.\r
+\r
+Arguments:\r
+\r
+  Sd    - The global scratch data.\r
+\r
+Returns:\r
+\r
+  The value decoded.\r
+\r
+--*/\r
+{\r
+  UINT16  Index2;\r
+  UINT32  Mask;\r
+\r
+  if (Sd->mBlockSize == 0) {\r
+    //\r
+    // Starting a new block\r
+    //\r
+    Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);\r
+    Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
+    if (Sd->mBadTableFlag != 0) {\r
+      return 0;\r
+    }\r
+\r
+    ReadCLen (Sd);\r
+\r
+    Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, mPbit, (UINT16) (-1));\r
+    if (Sd->mBadTableFlag != 0) {\r
+      return 0;\r
+    }\r
+  }\r
+\r
+  Sd->mBlockSize--;\r
+  Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
+\r
+  if (Index2 >= NC) {\r
+    Mask = 1U << (BITBUFSIZ - 1 - 12);\r
+\r
+    do {\r
+      if (Sd->mBitBuf & Mask) {\r
+        Index2 = Sd->mRight[Index2];\r
+      } else {\r
+        Index2 = Sd->mLeft[Index2];\r
+      }\r
+\r
+      Mask >>= 1;\r
+    } while (Index2 >= NC);\r
+  }\r
+  //\r
+  // Advance what we have read\r
+  //\r
+  FillBuf (Sd, Sd->mCLen[Index2]);\r
+\r
+  return Index2;\r
+}\r
+\r
+STATIC\r
+VOID\r
+Decode (\r
+  SCRATCH_DATA  *Sd\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Decode the source data and put the resulting data into the destination buffer.\r
+\r
+Arguments:\r
+\r
+  Sd            - The global scratch data\r
+\r
+Returns: (VOID)\r
+\r
+ --*/\r
+{\r
+  UINT16  BytesRemain;\r
+  UINT32  DataIdx;\r
+  UINT16  CharC;\r
+\r
+  BytesRemain = (UINT16) (-1);\r
+\r
+  DataIdx     = 0;\r
+\r
+  for (;;) {\r
+    CharC = DecodeC (Sd);\r
+    if (Sd->mBadTableFlag != 0) {\r
+      return ;\r
+    }\r
+\r
+    if (CharC < 256) {\r
+      //\r
+      // Process an Original character\r
+      //\r
+      Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
+      if (Sd->mOutBuf >= Sd->mOrigSize) {\r
+        return ;\r
+      }\r
+\r
+    } else {\r
+      //\r
+      // Process a Pointer\r
+      //\r
+      CharC       = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));\r
+\r
+      BytesRemain = CharC;\r
+\r
+      DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;\r
+\r
+      BytesRemain--;\r
+      while ((INT16) (BytesRemain) >= 0) {\r
+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
+        if (Sd->mOutBuf >= Sd->mOrigSize) {\r
+          return ;\r
+        }\r
+\r
+        BytesRemain--;\r
+      }\r
+    }\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+EFI_STATUS\r
+GetInfo (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  OUT     UINT32  *DstSize,\r
+  OUT     UINT32  *ScratchSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  DstSize     - The size of destination buffer.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+{\r
+  UINT8 *Src;\r
+\r
+  *ScratchSize  = sizeof (SCRATCH_DATA);\r
+\r
+  Src           = Source;\r
+  if (SrcSize < 8) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+Decompress (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  IN OUT  VOID    *Destination,\r
+  IN      UINT32  DstSize,\r
+  IN OUT  VOID    *Scratch,\r
+  IN      UINT32  ScratchSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation Efi and Tiano Decompress().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  Destination - The destination buffer to store the decompressed data\r
+  DstSize     - The size of destination buffer.\r
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+{\r
+  UINT32        Index;\r
+  UINT32        CompSize;\r
+  UINT32        OrigSize;\r
+  EFI_STATUS    Status;\r
+  SCRATCH_DATA  *Sd;\r
+  UINT8         *Src;\r
+  UINT8         *Dst;\r
+\r
+  Status  = EFI_SUCCESS;\r
+  Src     = Source;\r
+  Dst     = Destination;\r
+\r
+  if (ScratchSize < sizeof (SCRATCH_DATA)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Sd = (SCRATCH_DATA *) Scratch;\r
+\r
+  if (SrcSize < 8) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
+  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
+\r
+  if (SrcSize < CompSize + 8) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (DstSize != OrigSize) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Src = Src + 8;\r
+\r
+  for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {\r
+    ((UINT8 *) Sd)[Index] = 0;\r
+  }\r
+\r
+  Sd->mSrcBase  = Src;\r
+  Sd->mDstBase  = Dst;\r
+  Sd->mCompSize = CompSize;\r
+  Sd->mOrigSize = OrigSize;\r
+\r
+  //\r
+  // Fill the first BITBUFSIZ bits\r
+  //\r
+  FillBuf (Sd, BITBUFSIZ);\r
+\r
+  //\r
+  // Decompress it\r
+  //\r
+  Decode (Sd);\r
+\r
+  if (Sd->mBadTableFlag != 0) {\r
+    //\r
+    // Something wrong with the source\r
+    //\r
+    Status = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EfiGetInfo (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  OUT     UINT32  *DstSize,\r
+  OUT     UINT32  *ScratchSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation Efi Decompress GetInfo().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  DstSize     - The size of destination buffer.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+{\r
+  return GetInfo (Source, SrcSize, DstSize, ScratchSize);\r
+}\r
+\r
+EFI_STATUS\r
+TianoGetInfo (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  OUT     UINT32  *DstSize,\r
+  OUT     UINT32  *ScratchSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation Tiano Decompress GetInfo().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  DstSize     - The size of destination buffer.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+{\r
+  return GetInfo (Source, SrcSize, DstSize, ScratchSize);\r
+}\r
+\r
+EFI_STATUS\r
+EfiDecompress (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  IN OUT  VOID    *Destination,\r
+  IN      UINT32  DstSize,\r
+  IN OUT  VOID    *Scratch,\r
+  IN      UINT32  ScratchSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation of Efi Decompress().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  Destination - The destination buffer to store the decompressed data\r
+  DstSize     - The size of destination buffer.\r
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+{\r
+  mPbit = EFIPBIT;\r
+  return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);\r
+}\r
+\r
+EFI_STATUS\r
+TianoDecompress (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  IN OUT  VOID    *Destination,\r
+  IN      UINT32  DstSize,\r
+  IN OUT  VOID    *Scratch,\r
+  IN      UINT32  ScratchSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation of Tiano Decompress().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  Destination - The destination buffer to store the decompressed data\r
+  DstSize     - The size of destination buffer.\r
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+{\r
+  mPbit = MAXPBIT;\r
+  return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize);\r
+}\r
diff --git a/Source/C/Common/Decompress.h b/Source/C/Common/Decompress.h
new file mode 100644 (file)
index 0000000..5984e0b
--- /dev/null
@@ -0,0 +1,162 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+  \r
+  Decompress.h\r
+\r
+Abstract:\r
+\r
+  Header file for compression routine\r
+  \r
+--*/\r
+\r
+#ifndef _EFI_DECOMPRESS_H\r
+#define _EFI_DECOMPRESS_H\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+\r
+EFI_STATUS\r
+EfiGetInfo (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  OUT     UINT32  *DstSize,\r
+  OUT     UINT32  *ScratchSize\r
+  );\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation Efi Decompress GetInfo().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  DstSize     - The size of destination buffer.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+\r
+EFI_STATUS\r
+EfiDecompress (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  IN OUT  VOID    *Destination,\r
+  IN      UINT32  DstSize,\r
+  IN OUT  VOID    *Scratch,\r
+  IN      UINT32  ScratchSize\r
+  );\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation of Efi Decompress().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  Destination - The destination buffer to store the decompressed data\r
+  DstSize     - The size of destination buffer.\r
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+\r
+EFI_STATUS\r
+TianoGetInfo (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  OUT     UINT32  *DstSize,\r
+  OUT     UINT32  *ScratchSize\r
+  );\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation Tiano Decompress GetInfo().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  DstSize     - The size of destination buffer.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+\r
+EFI_STATUS\r
+TianoDecompress (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  IN OUT  VOID    *Destination,\r
+  IN      UINT32  DstSize,\r
+  IN OUT  VOID    *Scratch,\r
+  IN      UINT32  ScratchSize\r
+  );\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation of Tiano Decompress().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  Destination - The destination buffer to store the decompressed data\r
+  DstSize     - The size of destination buffer.\r
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+\r
+typedef\r
+EFI_STATUS\r
+(*GETINFO_FUNCTION) (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  OUT     UINT32  *DstSize,\r
+  OUT     UINT32  *ScratchSize\r
+  );\r
+\r
+typedef\r
+EFI_STATUS\r
+(*DECOMPRESS_FUNCTION) (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  IN OUT  VOID    *Destination,\r
+  IN      UINT32  DstSize,\r
+  IN OUT  VOID    *Scratch,\r
+  IN      UINT32  ScratchSize\r
+  );\r
+#endif\r
diff --git a/Source/C/Common/EfiCompress.c b/Source/C/Common/EfiCompress.c
new file mode 100644 (file)
index 0000000..87f52fd
--- /dev/null
@@ -0,0 +1,1597 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  EfiCompress.c\r
+\r
+Abstract:\r
+\r
+  Compression routine. The compression algorithm is a mixture of\r
+  LZ77 and Huffman coding. LZ77 transforms the source data into a\r
+  sequence of Original Characters and Pointers to repeated strings.\r
+  This sequence is further divided into Blocks and Huffman codings\r
+  are applied to each Block.\r
+\r
+--*/\r
+\r
+#include "Compress.h"\r
+\r
+\r
+//\r
+// Macro Definitions\r
+//\r
+\r
+typedef INT16             NODE;\r
+#define UINT8_MAX         0xff\r
+#define UINT8_BIT         8\r
+#define THRESHOLD         3\r
+#define INIT_CRC          0\r
+#define WNDBIT            13\r
+#define WNDSIZ            (1U << WNDBIT)\r
+#define MAXMATCH          256\r
+#define PERC_FLAG         0x8000U\r
+#define CODE_BIT          16\r
+#define NIL               0\r
+#define MAX_HASH_VAL      (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)\r
+#define HASH(p, c)        ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)\r
+#define CRCPOLY           0xA001\r
+#define UPDATE_CRC(c)     mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)\r
+\r
+//\r
+// C: the Char&Len Set; P: the Position Set; T: the exTra Set\r
+//\r
+\r
+#define NC                (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)\r
+#define CBIT              9\r
+#define NP                (WNDBIT + 1)\r
+#define PBIT              4\r
+#define NT                (CODE_BIT + 3)\r
+#define TBIT              5\r
+#if NT > NP\r
+  #define                 NPT NT\r
+#else\r
+  #define                 NPT NP\r
+#endif\r
+\r
+//\r
+// Function Prototypes\r
+//\r
+\r
+STATIC\r
+VOID \r
+PutDword(\r
+  IN UINT32 Data\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS \r
+AllocateMemory (\r
+  );\r
+\r
+STATIC\r
+VOID\r
+FreeMemory (\r
+  );\r
+\r
+STATIC \r
+VOID \r
+InitSlide (\r
+  );\r
+\r
+STATIC \r
+NODE \r
+Child (\r
+  IN NODE q, \r
+  IN UINT8 c\r
+  );\r
+\r
+STATIC \r
+VOID \r
+MakeChild (\r
+  IN NODE q, \r
+  IN UINT8 c, \r
+  IN NODE r\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+Split (\r
+  IN NODE Old\r
+  );\r
+\r
+STATIC \r
+VOID \r
+InsertNode (\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+DeleteNode (\r
+  );\r
+\r
+STATIC \r
+VOID \r
+GetNextMatch (\r
+  );\r
+  \r
+STATIC \r
+EFI_STATUS \r
+Encode (\r
+  );\r
+\r
+STATIC \r
+VOID \r
+CountTFreq (\r
+  );\r
+\r
+STATIC \r
+VOID \r
+WritePTLen (\r
+  IN INT32 n, \r
+  IN INT32 nbit, \r
+  IN INT32 Special\r
+  );\r
+\r
+STATIC \r
+VOID \r
+WriteCLen (\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+EncodeC (\r
+  IN INT32 c\r
+  );\r
+\r
+STATIC \r
+VOID \r
+EncodeP (\r
+  IN UINT32 p\r
+  );\r
+\r
+STATIC \r
+VOID \r
+SendBlock (\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+Output (\r
+  IN UINT32 c, \r
+  IN UINT32 p\r
+  );\r
+\r
+STATIC \r
+VOID \r
+HufEncodeStart (\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+HufEncodeEnd (\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+MakeCrcTable (\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+PutBits (\r
+  IN INT32 n, \r
+  IN UINT32 x\r
+  );\r
+  \r
+STATIC \r
+INT32 \r
+FreadCrc (\r
+  OUT UINT8 *p, \r
+  IN  INT32 n\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+InitPutBits (\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+CountLen (\r
+  IN INT32 i\r
+  );\r
+\r
+STATIC \r
+VOID \r
+MakeLen (\r
+  IN INT32 Root\r
+  );\r
+  \r
+STATIC \r
+VOID \r
+DownHeap (\r
+  IN INT32 i\r
+  );\r
+\r
+STATIC \r
+VOID \r
+MakeCode (\r
+  IN  INT32 n, \r
+  IN  UINT8 Len[], \r
+  OUT UINT16 Code[]\r
+  );\r
+  \r
+STATIC \r
+INT32 \r
+MakeTree (\r
+  IN  INT32   NParm, \r
+  IN  UINT16  FreqParm[], \r
+  OUT UINT8   LenParm[], \r
+  OUT UINT16  CodeParm[]\r
+  );\r
+\r
+\r
+//\r
+//  Global Variables\r
+//\r
+\r
+STATIC UINT8  *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;\r
+\r
+STATIC UINT8  *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;\r
+STATIC INT16  mHeap[NC + 1];\r
+STATIC INT32  mRemainder, mMatchLen, mBitCount, mHeapSize, mN;\r
+STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;\r
+STATIC UINT32 mCompSize, mOrigSize;\r
+\r
+STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1],\r
+              mCrcTable[UINT8_MAX + 1], mCFreq[2 * NC - 1], mCTable[4096], mCCode[NC],\r
+              mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];\r
+\r
+STATIC NODE   mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;\r
+\r
+\r
+//\r
+// functions\r
+//\r
+\r
+EFI_STATUS\r
+EfiCompress (\r
+  IN      UINT8   *SrcBuffer,\r
+  IN      UINT32  SrcSize,\r
+  IN      UINT8   *DstBuffer,\r
+  IN OUT  UINT32  *DstSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The main compression routine.\r
+\r
+Arguments:\r
+\r
+  SrcBuffer   - The buffer storing the source data\r
+  SrcSize     - The size of source data\r
+  DstBuffer   - The buffer to store the compressed data\r
+  DstSize     - On input, the size of DstBuffer; On output,\r
+                the size of the actual compressed data.\r
+\r
+Returns:\r
+\r
+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,\r
+                DstSize contains the size needed.\r
+  EFI_SUCCESS           - Compression is successful.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS Status = EFI_SUCCESS;\r
+  \r
+  //\r
+  // Initializations\r
+  //\r
+  mBufSiz = 0;\r
+  mBuf = NULL;\r
+  mText       = NULL;\r
+  mLevel      = NULL;\r
+  mChildCount = NULL;\r
+  mPosition   = NULL;\r
+  mParent     = NULL;\r
+  mPrev       = NULL;\r
+  mNext       = NULL;\r
+\r
+  \r
+  mSrc = SrcBuffer;\r
+  mSrcUpperLimit = mSrc + SrcSize;\r
+  mDst = DstBuffer;\r
+  mDstUpperLimit = mDst + *DstSize;\r
+\r
+  PutDword(0L);\r
+  PutDword(0L);\r
+  \r
+  MakeCrcTable ();\r
+\r
+  mOrigSize = mCompSize = 0;\r
+  mCrc = INIT_CRC;\r
+  \r
+  //\r
+  // Compress it\r
+  //\r
+  \r
+  Status = Encode();\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  //\r
+  // Null terminate the compressed data\r
+  //\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = 0;\r
+  }\r
+  \r
+  //\r
+  // Fill in compressed size and original size\r
+  //\r
+  mDst = DstBuffer;\r
+  PutDword(mCompSize+1);\r
+  PutDword(mOrigSize);\r
+\r
+  //\r
+  // Return\r
+  //\r
+  \r
+  if (mCompSize + 1 + 8 > *DstSize) {\r
+    *DstSize = mCompSize + 1 + 8;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  } else {\r
+    *DstSize = mCompSize + 1 + 8;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+}\r
+\r
+STATIC \r
+VOID \r
+PutDword(\r
+  IN UINT32 Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Put a dword to output stream\r
+  \r
+Arguments:\r
+\r
+  Data    - the dword to put\r
+  \r
+Returns: (VOID)\r
+  \r
+--*/\r
+{\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = (UINT8)(((UINT8)(Data        )) & 0xff);\r
+  }\r
+\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = (UINT8)(((UINT8)(Data >> 0x08)) & 0xff);\r
+  }\r
+\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = (UINT8)(((UINT8)(Data >> 0x10)) & 0xff);\r
+  }\r
+\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = (UINT8)(((UINT8)(Data >> 0x18)) & 0xff);\r
+  }\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+AllocateMemory ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocate memory spaces for data structures used in compression process\r
+  \r
+Argements: (VOID)\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Memory is allocated successfully\r
+  EFI_OUT_OF_RESOURCES  - Allocation fails\r
+\r
+--*/\r
+{\r
+  UINT32      i;\r
+  \r
+  mText       = malloc (WNDSIZ * 2 + MAXMATCH);\r
+  for (i = 0 ; i < WNDSIZ * 2 + MAXMATCH; i ++) {\r
+    mText[i] = 0;\r
+  }\r
+\r
+  mLevel      = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mLevel));\r
+  mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mChildCount));\r
+  mPosition   = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof(*mPosition));\r
+  mParent     = malloc (WNDSIZ * 2 * sizeof(*mParent));\r
+  mPrev       = malloc (WNDSIZ * 2 * sizeof(*mPrev));\r
+  mNext       = malloc ((MAX_HASH_VAL + 1) * sizeof(*mNext));\r
+  \r
+  mBufSiz = 16 * 1024U;\r
+  while ((mBuf = malloc(mBufSiz)) == NULL) {\r
+    mBufSiz = (mBufSiz / 10U) * 9U;\r
+    if (mBufSiz < 4 * 1024U) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
+  mBuf[0] = 0;\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+FreeMemory ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Called when compression is completed to free memory previously allocated.\r
+  \r
+Arguments: (VOID)\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  if (mText) {\r
+    free (mText);\r
+  }\r
+  \r
+  if (mLevel) {\r
+    free (mLevel);\r
+  }\r
+  \r
+  if (mChildCount) {\r
+    free (mChildCount);\r
+  }\r
+  \r
+  if (mPosition) {\r
+    free (mPosition);\r
+  }\r
+  \r
+  if (mParent) {\r
+    free (mParent);\r
+  }\r
+  \r
+  if (mPrev) {\r
+    free (mPrev);\r
+  }\r
+  \r
+  if (mNext) {\r
+    free (mNext);\r
+  }\r
+  \r
+  if (mBuf) {\r
+    free (mBuf);\r
+  }  \r
+\r
+  return;\r
+}\r
+\r
+\r
+STATIC \r
+VOID \r
+InitSlide ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize String Info Log data structures\r
+  \r
+Arguments: (VOID)\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  NODE i;\r
+\r
+  for (i = WNDSIZ; i <= WNDSIZ + UINT8_MAX; i++) {\r
+    mLevel[i] = 1;\r
+    mPosition[i] = NIL;  /* sentinel */\r
+  }\r
+  for (i = WNDSIZ; i < WNDSIZ * 2; i++) {\r
+    mParent[i] = NIL;\r
+  }  \r
+  mAvail = 1;\r
+  for (i = 1; i < WNDSIZ - 1; i++) {\r
+    mNext[i] = (NODE)(i + 1);\r
+  }\r
+  \r
+  mNext[WNDSIZ - 1] = NIL;\r
+  for (i = WNDSIZ * 2; i <= MAX_HASH_VAL; i++) {\r
+    mNext[i] = NIL;\r
+  }  \r
+}\r
+\r
+\r
+STATIC \r
+NODE \r
+Child (\r
+  IN NODE q, \r
+  IN UINT8 c\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Find child node given the parent node and the edge character\r
+  \r
+Arguments:\r
+\r
+  q       - the parent node\r
+  c       - the edge character\r
+  \r
+Returns:\r
+\r
+  The child node (NIL if not found)  \r
+  \r
+--*/\r
+{\r
+  NODE r;\r
+  \r
+  r = mNext[HASH(q, c)];\r
+  mParent[NIL] = q;  /* sentinel */\r
+  while (mParent[r] != q) {\r
+    r = mNext[r];\r
+  }\r
+  \r
+  return r;\r
+}\r
+\r
+STATIC \r
+VOID \r
+MakeChild (\r
+  IN NODE q, \r
+  IN UINT8 c, \r
+  IN NODE r\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create a new child for a given parent node.\r
+  \r
+Arguments:\r
+\r
+  q       - the parent node\r
+  c       - the edge character\r
+  r       - the child node\r
+  \r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  NODE h, t;\r
+  \r
+  h = (NODE)HASH(q, c);\r
+  t = mNext[h];\r
+  mNext[h] = r;\r
+  mNext[r] = t;\r
+  mPrev[t] = r;\r
+  mPrev[r] = h;\r
+  mParent[r] = q;\r
+  mChildCount[q]++;\r
+}\r
+\r
+STATIC \r
+VOID \r
+Split (\r
+  NODE Old\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Split a node.\r
+  \r
+Arguments:\r
+\r
+  Old     - the node to split\r
+  \r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  NODE New, t;\r
+\r
+  New = mAvail;\r
+  mAvail = mNext[New];\r
+  mChildCount[New] = 0;\r
+  t = mPrev[Old];\r
+  mPrev[New] = t;\r
+  mNext[t] = New;\r
+  t = mNext[Old];\r
+  mNext[New] = t;\r
+  mPrev[t] = New;\r
+  mParent[New] = mParent[Old];\r
+  mLevel[New] = (UINT8)mMatchLen;\r
+  mPosition[New] = mPos;\r
+  MakeChild(New, mText[mMatchPos + mMatchLen], Old);\r
+  MakeChild(New, mText[mPos + mMatchLen], mPos);\r
+}\r
+\r
+STATIC \r
+VOID \r
+InsertNode ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Insert string info for current position into the String Info Log\r
+  \r
+Arguments: (VOID)\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  NODE q, r, j, t;\r
+  UINT8 c, *t1, *t2;\r
+\r
+  if (mMatchLen >= 4) {\r
+    \r
+    //\r
+    // We have just got a long match, the target tree\r
+    // can be located by MatchPos + 1. Travese the tree\r
+    // from bottom up to get to a proper starting point.\r
+    // The usage of PERC_FLAG ensures proper node deletion\r
+    // in DeleteNode() later.\r
+    //\r
+    \r
+    mMatchLen--;\r
+    r = (INT16)((mMatchPos + 1) | WNDSIZ);\r
+    while ((q = mParent[r]) == NIL) {\r
+      r = mNext[r];\r
+    }\r
+    while (mLevel[q] >= mMatchLen) {\r
+      r = q;  q = mParent[q];\r
+    }\r
+    t = q;\r
+    while (mPosition[t] < 0) {\r
+      mPosition[t] = mPos;\r
+      t = mParent[t];\r
+    }\r
+    if (t < WNDSIZ) {\r
+      mPosition[t] = (NODE)(mPos | PERC_FLAG);\r
+    }    \r
+  } else {\r
+    \r
+    //\r
+    // Locate the target tree\r
+    //\r
+    \r
+    q = (INT16)(mText[mPos] + WNDSIZ);\r
+    c = mText[mPos + 1];\r
+    if ((r = Child(q, c)) == NIL) {\r
+      MakeChild(q, c, mPos);\r
+      mMatchLen = 1;\r
+      return;\r
+    }\r
+    mMatchLen = 2;\r
+  }\r
+  \r
+  //\r
+  // Traverse down the tree to find a match.\r
+  // Update Position value along the route.\r
+  // Node split or creation is involved.\r
+  //\r
+  \r
+  for ( ; ; ) {\r
+    if (r >= WNDSIZ) {\r
+      j = MAXMATCH;\r
+      mMatchPos = r;\r
+    } else {\r
+      j = mLevel[r];\r
+      mMatchPos = (NODE)(mPosition[r] & ~PERC_FLAG);\r
+    }\r
+    if (mMatchPos >= mPos) {\r
+      mMatchPos -= WNDSIZ;\r
+    }    \r
+    t1 = &mText[mPos + mMatchLen];\r
+    t2 = &mText[mMatchPos + mMatchLen];\r
+    while (mMatchLen < j) {\r
+      if (*t1 != *t2) {\r
+        Split(r);\r
+        return;\r
+      }\r
+      mMatchLen++;\r
+      t1++;\r
+      t2++;\r
+    }\r
+    if (mMatchLen >= MAXMATCH) {\r
+      break;\r
+    }\r
+    mPosition[r] = mPos;\r
+    q = r;\r
+    if ((r = Child(q, *t1)) == NIL) {\r
+      MakeChild(q, *t1, mPos);\r
+      return;\r
+    }\r
+    mMatchLen++;\r
+  }\r
+  t = mPrev[r];\r
+  mPrev[mPos] = t;\r
+  mNext[t] = mPos;\r
+  t = mNext[r];\r
+  mNext[mPos] = t;\r
+  mPrev[t] = mPos;\r
+  mParent[mPos] = q;\r
+  mParent[r] = NIL;\r
+  \r
+  //\r
+  // Special usage of 'next'\r
+  //\r
+  mNext[r] = mPos;\r
+  \r
+}\r
+\r
+STATIC \r
+VOID \r
+DeleteNode ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delete outdated string info. (The Usage of PERC_FLAG\r
+  ensures a clean deletion)\r
+  \r
+Arguments: (VOID)\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  NODE q, r, s, t, u;\r
+\r
+  if (mParent[mPos] == NIL) {\r
+    return;\r
+  }\r
+  \r
+  r = mPrev[mPos];\r
+  s = mNext[mPos];\r
+  mNext[r] = s;\r
+  mPrev[s] = r;\r
+  r = mParent[mPos];\r
+  mParent[mPos] = NIL;\r
+  if (r >= WNDSIZ || --mChildCount[r] > 1) {\r
+    return;\r
+  }\r
+  t = (NODE)(mPosition[r] & ~PERC_FLAG);\r
+  if (t >= mPos) {\r
+    t -= WNDSIZ;\r
+  }\r
+  s = t;\r
+  q = mParent[r];\r
+  while ((u = mPosition[q]) & PERC_FLAG) {\r
+    u &= ~PERC_FLAG;\r
+    if (u >= mPos) {\r
+      u -= WNDSIZ;\r
+    }\r
+    if (u > s) {\r
+      s = u;\r
+    }\r
+    mPosition[q] = (INT16)(s | WNDSIZ);\r
+    q = mParent[q];\r
+  }\r
+  if (q < WNDSIZ) {\r
+    if (u >= mPos) {\r
+      u -= WNDSIZ;\r
+    }\r
+    if (u > s) {\r
+      s = u;\r
+    }\r
+    mPosition[q] = (INT16)(s | WNDSIZ | PERC_FLAG);\r
+  }\r
+  s = Child(r, mText[t + mLevel[r]]);\r
+  t = mPrev[s];\r
+  u = mNext[s];\r
+  mNext[t] = u;\r
+  mPrev[u] = t;\r
+  t = mPrev[r];\r
+  mNext[t] = s;\r
+  mPrev[s] = t;\r
+  t = mNext[r];\r
+  mPrev[t] = s;\r
+  mNext[s] = t;\r
+  mParent[s] = mParent[r];\r
+  mParent[r] = NIL;\r
+  mNext[r] = mAvail;\r
+  mAvail = r;\r
+}\r
+\r
+STATIC \r
+VOID \r
+GetNextMatch ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Advance the current position (read in new data if needed).\r
+  Delete outdated string info. Find a match string for current position.\r
+\r
+Arguments: (VOID)\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  INT32 n;\r
+\r
+  mRemainder--;\r
+  if (++mPos == WNDSIZ * 2) {\r
+    memmove(&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH);\r
+    n = FreadCrc(&mText[WNDSIZ + MAXMATCH], WNDSIZ);\r
+    mRemainder += n;\r
+    mPos = WNDSIZ;\r
+  }\r
+  DeleteNode();\r
+  InsertNode();\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+Encode ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The main controlling routine for compression process.\r
+\r
+Arguments: (VOID)\r
+\r
+Returns:\r
+  \r
+  EFI_SUCCESS           - The compression is successful\r
+  EFI_OUT_0F_RESOURCES  - Not enough memory for compression process\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  INT32       LastMatchLen;\r
+  NODE        LastMatchPos;\r
+\r
+  Status = AllocateMemory();\r
+  if (EFI_ERROR(Status)) {\r
+    FreeMemory();\r
+    return Status;\r
+  }\r
+\r
+  InitSlide();\r
+  \r
+  HufEncodeStart();\r
+\r
+  mRemainder = FreadCrc(&mText[WNDSIZ], WNDSIZ + MAXMATCH);\r
+  \r
+  mMatchLen = 0;\r
+  mPos = WNDSIZ;\r
+  InsertNode();\r
+  if (mMatchLen > mRemainder) {\r
+    mMatchLen = mRemainder;\r
+  }\r
+  while (mRemainder > 0) {\r
+    LastMatchLen = mMatchLen;\r
+    LastMatchPos = mMatchPos;\r
+    GetNextMatch();\r
+    if (mMatchLen > mRemainder) {\r
+      mMatchLen = mRemainder;\r
+    }\r
+    \r
+    if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) {\r
+      \r
+      //\r
+      // Not enough benefits are gained by outputting a pointer,\r
+      // so just output the original character\r
+      //\r
+      \r
+      Output(mText[mPos - 1], 0);\r
+    } else {\r
+      \r
+      //\r
+      // Outputting a pointer is beneficial enough, do it.\r
+      //\r
+      \r
+      Output(LastMatchLen + (UINT8_MAX + 1 - THRESHOLD),\r
+             (mPos - LastMatchPos - 2) & (WNDSIZ - 1));\r
+      while (--LastMatchLen > 0) {\r
+        GetNextMatch();\r
+      }\r
+      if (mMatchLen > mRemainder) {\r
+        mMatchLen = mRemainder;\r
+      }\r
+    }\r
+  }\r
+  \r
+  HufEncodeEnd();\r
+  FreeMemory();\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC \r
+VOID \r
+CountTFreq ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Count the frequencies for the Extra Set\r
+  \r
+Arguments: (VOID)\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  INT32 i, k, n, Count;\r
+\r
+  for (i = 0; i < NT; i++) {\r
+    mTFreq[i] = 0;\r
+  }\r
+  n = NC;\r
+  while (n > 0 && mCLen[n - 1] == 0) {\r
+    n--;\r
+  }\r
+  i = 0;\r
+  while (i < n) {\r
+    k = mCLen[i++];\r
+    if (k == 0) {\r
+      Count = 1;\r
+      while (i < n && mCLen[i] == 0) {\r
+        i++;\r
+        Count++;\r
+      }\r
+      if (Count <= 2) {\r
+        mTFreq[0] = (UINT16)(mTFreq[0] + Count);\r
+      } else if (Count <= 18) {\r
+        mTFreq[1]++;\r
+      } else if (Count == 19) {\r
+        mTFreq[0]++;\r
+        mTFreq[1]++;\r
+      } else {\r
+        mTFreq[2]++;\r
+      }\r
+    } else {\r
+      mTFreq[k + 2]++;\r
+    }\r
+  }\r
+}\r
+\r
+STATIC \r
+VOID \r
+WritePTLen (\r
+  IN INT32 n, \r
+  IN INT32 nbit, \r
+  IN INT32 Special\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Outputs the code length array for the Extra Set or the Position Set.\r
+  \r
+Arguments:\r
+\r
+  n       - the number of symbols\r
+  nbit    - the number of bits needed to represent 'n'\r
+  Special - the special symbol that needs to be take care of\r
+  \r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  INT32 i, k;\r
+\r
+  while (n > 0 && mPTLen[n - 1] == 0) {\r
+    n--;\r
+  }\r
+  PutBits(nbit, n);\r
+  i = 0;\r
+  while (i < n) {\r
+    k = mPTLen[i++];\r
+    if (k <= 6) {\r
+      PutBits(3, k);\r
+    } else {\r
+      PutBits(k - 3, (1U << (k - 3)) - 2);\r
+    }\r
+    if (i == Special) {\r
+      while (i < 6 && mPTLen[i] == 0) {\r
+        i++;\r
+      }\r
+      PutBits(2, (i - 3) & 3);\r
+    }\r
+  }\r
+}\r
+\r
+STATIC \r
+VOID \r
+WriteCLen ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Outputs the code length array for Char&Length Set\r
+  \r
+Arguments: (VOID)\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  INT32 i, k, n, Count;\r
+\r
+  n = NC;\r
+  while (n > 0 && mCLen[n - 1] == 0) {\r
+    n--;\r
+  }\r
+  PutBits(CBIT, n);\r
+  i = 0;\r
+  while (i < n) {\r
+    k = mCLen[i++];\r
+    if (k == 0) {\r
+      Count = 1;\r
+      while (i < n && mCLen[i] == 0) {\r
+        i++;\r
+        Count++;\r
+      }\r
+      if (Count <= 2) {\r
+        for (k = 0; k < Count; k++) {\r
+          PutBits(mPTLen[0], mPTCode[0]);\r
+        }\r
+      } else if (Count <= 18) {\r
+        PutBits(mPTLen[1], mPTCode[1]);\r
+        PutBits(4, Count - 3);\r
+      } else if (Count == 19) {\r
+        PutBits(mPTLen[0], mPTCode[0]);\r
+        PutBits(mPTLen[1], mPTCode[1]);\r
+        PutBits(4, 15);\r
+      } else {\r
+        PutBits(mPTLen[2], mPTCode[2]);\r
+        PutBits(CBIT, Count - 20);\r
+      }\r
+    } else {\r
+      PutBits(mPTLen[k + 2], mPTCode[k + 2]);\r
+    }\r
+  }\r
+}\r
+\r
+STATIC \r
+VOID \r
+EncodeC (\r
+  IN INT32 c\r
+  )\r
+{\r
+  PutBits(mCLen[c], mCCode[c]);\r
+}\r
+\r
+STATIC \r
+VOID \r
+EncodeP (\r
+  IN UINT32 p\r
+  )\r
+{\r
+  UINT32 c, q;\r
+\r
+  c = 0;\r
+  q = p;\r
+  while (q) {\r
+    q >>= 1;\r
+    c++;\r
+  }\r
+  PutBits(mPTLen[c], mPTCode[c]);\r
+  if (c > 1) {\r
+    PutBits(c - 1, p & (0xFFFFU >> (17 - c)));\r
+  }\r
+}\r
+\r
+STATIC \r
+VOID \r
+SendBlock ()\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Huffman code the block and output it.\r
+  \r
+Argument: (VOID)\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  UINT32 i, k, Flags, Root, Pos, Size;\r
+  Flags = 0;\r
+\r
+  Root = MakeTree(NC, mCFreq, mCLen, mCCode);\r
+  Size = mCFreq[Root];\r
+  PutBits(16, Size);\r
+  if (Root >= NC) {\r
+    CountTFreq();\r
+    Root = MakeTree(NT, mTFreq, mPTLen, mPTCode);\r
+    if (Root >= NT) {\r
+      WritePTLen(NT, TBIT, 3);\r
+    } else {\r
+      PutBits(TBIT, 0);\r
+      PutBits(TBIT, Root);\r
+    }\r
+    WriteCLen();\r
+  } else {\r
+    PutBits(TBIT, 0);\r
+    PutBits(TBIT, 0);\r
+    PutBits(CBIT, 0);\r
+    PutBits(CBIT, Root);\r
+  }\r
+  Root = MakeTree(NP, mPFreq, mPTLen, mPTCode);\r
+  if (Root >= NP) {\r
+    WritePTLen(NP, PBIT, -1);\r
+  } else {\r
+    PutBits(PBIT, 0);\r
+    PutBits(PBIT, Root);\r
+  }\r
+  Pos = 0;\r
+  for (i = 0; i < Size; i++) {\r
+    if (i % UINT8_BIT == 0) {\r
+      Flags = mBuf[Pos++];\r
+    } else {\r
+      Flags <<= 1;\r
+    }\r
+    if (Flags & (1U << (UINT8_BIT - 1))) {\r
+      EncodeC(mBuf[Pos++] + (1U << UINT8_BIT));\r
+      k = mBuf[Pos++] << UINT8_BIT;\r
+      k += mBuf[Pos++];\r
+      EncodeP(k);\r
+    } else {\r
+      EncodeC(mBuf[Pos++]);\r
+    }\r
+  }\r
+  for (i = 0; i < NC; i++) {\r
+    mCFreq[i] = 0;\r
+  }\r
+  for (i = 0; i < NP; i++) {\r
+    mPFreq[i] = 0;\r
+  }\r
+}\r
+\r
+\r
+STATIC \r
+VOID \r
+Output (\r
+  IN UINT32 c, \r
+  IN UINT32 p\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Outputs an Original Character or a Pointer\r
+\r
+Arguments:\r
+\r
+  c     - The original character or the 'String Length' element of a Pointer\r
+  p     - The 'Position' field of a Pointer\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  STATIC UINT32 CPos;\r
+\r
+  if ((mOutputMask >>= 1) == 0) {\r
+    mOutputMask = 1U << (UINT8_BIT - 1);\r
+    if (mOutputPos >= mBufSiz - 3 * UINT8_BIT) {\r
+      SendBlock();\r
+      mOutputPos = 0;\r
+    }\r
+    CPos = mOutputPos++;  \r
+    mBuf[CPos] = 0;\r
+  }\r
+  mBuf[mOutputPos++] = (UINT8) c;\r
+  mCFreq[c]++;\r
+  if (c >= (1U << UINT8_BIT)) {\r
+    mBuf[CPos] |= mOutputMask;\r
+    mBuf[mOutputPos++] = (UINT8)(p >> UINT8_BIT);\r
+    mBuf[mOutputPos++] = (UINT8) p;\r
+    c = 0;\r
+    while (p) {\r
+      p >>= 1;\r
+      c++;\r
+    }\r
+    mPFreq[c]++;\r
+  }\r
+}\r
+\r
+STATIC\r
+VOID\r
+HufEncodeStart ()\r
+{\r
+  INT32 i;\r
+\r
+  for (i = 0; i < NC; i++) {\r
+    mCFreq[i] = 0;\r
+  }\r
+  for (i = 0; i < NP; i++) {\r
+    mPFreq[i] = 0;\r
+  }\r
+  mOutputPos = mOutputMask = 0;\r
+  InitPutBits();\r
+  return;\r
+}\r
+\r
+STATIC \r
+VOID \r
+HufEncodeEnd ()\r
+{\r
+  SendBlock();\r
+  \r
+  //\r
+  // Flush remaining bits\r
+  //\r
+  PutBits(UINT8_BIT - 1, 0);\r
+  \r
+  return;\r
+}\r
+\r
+\r
+STATIC \r
+VOID \r
+MakeCrcTable ()\r
+{\r
+  UINT32 i, j, r;\r
+\r
+  for (i = 0; i <= UINT8_MAX; i++) {\r
+    r = i;\r
+    for (j = 0; j < UINT8_BIT; j++) {\r
+      if (r & 1) {\r
+        r = (r >> 1) ^ CRCPOLY;\r
+      } else {\r
+        r >>= 1;\r
+      }\r
+    }\r
+    mCrcTable[i] = (UINT16)r;    \r
+  }\r
+}\r
+\r
+STATIC \r
+VOID \r
+PutBits (\r
+  IN INT32 n, \r
+  IN UINT32 x\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Outputs rightmost n bits of x\r
+\r
+Argments:\r
+\r
+  n   - the rightmost n bits of the data is used\r
+  x   - the data \r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  UINT8 Temp;  \r
+  \r
+  if (n < mBitCount) {\r
+    mSubBitBuf |= x << (mBitCount -= n);\r
+  } else {\r
+      \r
+    Temp = (UINT8)(mSubBitBuf | (x >> (n -= mBitCount)));\r
+    if (mDst < mDstUpperLimit) {\r
+      *mDst++ = Temp;\r
+    }\r
+    mCompSize++;\r
+\r
+    if (n < UINT8_BIT) {\r
+      mSubBitBuf = x << (mBitCount = UINT8_BIT - n);\r
+    } else {\r
+        \r
+      Temp = (UINT8)(x >> (n - UINT8_BIT));\r
+      if (mDst < mDstUpperLimit) {\r
+        *mDst++ = Temp;\r
+      }\r
+      mCompSize++;\r
+      \r
+      mSubBitBuf = x << (mBitCount = 2 * UINT8_BIT - n);\r
+    }\r
+  }\r
+}\r
+\r
+STATIC \r
+INT32 \r
+FreadCrc (\r
+  OUT UINT8 *p, \r
+  IN  INT32 n\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read in source data\r
+  \r
+Arguments:\r
+\r
+  p   - the buffer to hold the data\r
+  n   - number of bytes to read\r
+\r
+Returns:\r
+\r
+  number of bytes actually read\r
+  \r
+--*/\r
+{\r
+  INT32 i;\r
+\r
+  for (i = 0; mSrc < mSrcUpperLimit && i < n; i++) {\r
+    *p++ = *mSrc++;\r
+  }\r
+  n = i;\r
+\r
+  p -= n;\r
+  mOrigSize += n;\r
+  while (--i >= 0) {\r
+    UPDATE_CRC(*p++);\r
+  }\r
+  return n;\r
+}\r
+\r
+\r
+STATIC \r
+VOID \r
+InitPutBits ()\r
+{\r
+  mBitCount = UINT8_BIT;  \r
+  mSubBitBuf = 0;\r
+}\r
+\r
+STATIC \r
+VOID \r
+CountLen (\r
+  IN INT32 i\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Count the number of each code length for a Huffman tree.\r
+  \r
+Arguments:\r
+\r
+  i   - the top node\r
+  \r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  STATIC INT32 Depth = 0;\r
+\r
+  if (i < mN) {\r
+    mLenCnt[(Depth < 16) ? Depth : 16]++;\r
+  } else {\r
+    Depth++;\r
+    CountLen(mLeft [i]);\r
+    CountLen(mRight[i]);\r
+    Depth--;\r
+  }\r
+}\r
+\r
+STATIC \r
+VOID \r
+MakeLen (\r
+  IN INT32 Root\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create code length array for a Huffman tree\r
+  \r
+Arguments:\r
+\r
+  Root   - the root of the tree\r
+\r
+--*/\r
+{\r
+  INT32 i, k;\r
+  UINT32 Cum;\r
+\r
+  for (i = 0; i <= 16; i++) {\r
+    mLenCnt[i] = 0;\r
+  }\r
+  CountLen(Root);\r
+  \r
+  //\r
+  // Adjust the length count array so that\r
+  // no code will be generated longer than its designated length\r
+  //\r
+  \r
+  Cum = 0;\r
+  for (i = 16; i > 0; i--) {\r
+    Cum += mLenCnt[i] << (16 - i);\r
+  }\r
+  while (Cum != (1U << 16)) {\r
+    mLenCnt[16]--;\r
+    for (i = 15; i > 0; i--) {\r
+      if (mLenCnt[i] != 0) {\r
+        mLenCnt[i]--;\r
+        mLenCnt[i+1] += 2;\r
+        break;\r
+      }\r
+    }\r
+    Cum--;\r
+  }\r
+  for (i = 16; i > 0; i--) {\r
+    k = mLenCnt[i];\r
+    while (--k >= 0) {\r
+      mLen[*mSortPtr++] = (UINT8)i;\r
+    }\r
+  }\r
+}\r
+\r
+STATIC \r
+VOID \r
+DownHeap (\r
+  IN INT32 i\r
+  )\r
+{\r
+  INT32 j, k;\r
+\r
+  //\r
+  // priority queue: send i-th entry down heap\r
+  //\r
+  \r
+  k = mHeap[i];\r
+  while ((j = 2 * i) <= mHeapSize) {\r
+    if (j < mHeapSize && mFreq[mHeap[j]] > mFreq[mHeap[j + 1]]) {\r
+      j++;\r
+    }\r
+    if (mFreq[k] <= mFreq[mHeap[j]]) {\r
+      break;\r
+    }\r
+    mHeap[i] = mHeap[j];\r
+    i = j;\r
+  }\r
+  mHeap[i] = (INT16)k;\r
+}\r
+\r
+STATIC \r
+VOID \r
+MakeCode (\r
+  IN  INT32 n, \r
+  IN  UINT8 Len[], \r
+  OUT UINT16 Code[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Assign code to each symbol based on the code length array\r
+  \r
+Arguments:\r
+\r
+  n     - number of symbols\r
+  Len   - the code length array\r
+  Code  - stores codes for each symbol\r
+\r
+Returns: (VOID)\r
+\r
+--*/\r
+{\r
+  INT32    i;\r
+  UINT16   Start[18];\r
+\r
+  Start[1] = 0;\r
+  for (i = 1; i <= 16; i++) {\r
+    Start[i + 1] = (UINT16)((Start[i] + mLenCnt[i]) << 1);\r
+  }\r
+  for (i = 0; i < n; i++) {\r
+    Code[i] = Start[Len[i]]++;\r
+  }\r
+}\r
+\r
+STATIC \r
+INT32 \r
+MakeTree (\r
+  IN  INT32   NParm, \r
+  IN  UINT16  FreqParm[], \r
+  OUT UINT8   LenParm[], \r
+  OUT UINT16  CodeParm[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Generates Huffman codes given a frequency distribution of symbols\r
+  \r
+Arguments:\r
+\r
+  NParm    - number of symbols\r
+  FreqParm - frequency of each symbol\r
+  LenParm  - code length for each symbol\r
+  CodeParm - code for each symbol\r
+  \r
+Returns:\r
+\r
+  Root of the Huffman tree.\r
+  \r
+--*/\r
+{\r
+  INT32 i, j, k, Avail;\r
+  \r
+  //\r
+  // make tree, calculate len[], return root\r
+  //\r
+\r
+  mN = NParm;\r
+  mFreq = FreqParm;\r
+  mLen = LenParm;\r
+  Avail = mN;\r
+  mHeapSize = 0;\r
+  mHeap[1] = 0;\r
+  for (i = 0; i < mN; i++) {\r
+    mLen[i] = 0;\r
+    if (mFreq[i]) {\r
+      mHeap[++mHeapSize] = (INT16)i;\r
+    }    \r
+  }\r
+  if (mHeapSize < 2) {\r
+    CodeParm[mHeap[1]] = 0;\r
+    return mHeap[1];\r
+  }\r
+  for (i = mHeapSize / 2; i >= 1; i--) {\r
+    \r
+    //\r
+    // make priority queue \r
+    //\r
+    DownHeap(i);\r
+  }\r
+  mSortPtr = CodeParm;\r
+  do {\r
+    i = mHeap[1];\r
+    if (i < mN) {\r
+      *mSortPtr++ = (UINT16)i;\r
+    }\r
+    mHeap[1] = mHeap[mHeapSize--];\r
+    DownHeap(1);\r
+    j = mHeap[1];\r
+    if (j < mN) {\r
+      *mSortPtr++ = (UINT16)j;\r
+    }\r
+    k = Avail++;\r
+    mFreq[k] = (UINT16)(mFreq[i] + mFreq[j]);\r
+    mHeap[1] = (INT16)k;\r
+    DownHeap(1);\r
+    mLeft[k] = (UINT16)i;\r
+    mRight[k] = (UINT16)j;\r
+  } while (mHeapSize > 1);\r
+  \r
+  mSortPtr = CodeParm;\r
+  MakeLen(k);\r
+  MakeCode(NParm, LenParm, CodeParm);\r
+  \r
+  //\r
+  // return root\r
+  //\r
+  return k;\r
+}\r
+\r
diff --git a/Source/C/Common/EfiCustomizedCompress.h b/Source/C/Common/EfiCustomizedCompress.h
new file mode 100644 (file)
index 0000000..af26b6f
--- /dev/null
@@ -0,0 +1,141 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+  \r
+  EfiCustomizedCompress.h\r
+\r
+Abstract:\r
+\r
+  Header file for Customized compression routine\r
+  \r
+--*/\r
+\r
+#ifndef _EFICUSTOMIZEDCOMPRESS_H\r
+#define _EFICUSTOMIZEDCOMPRESS_H\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+\r
+EFI_STATUS\r
+SetCustomizedCompressionType (\r
+  IN  CHAR8   *Type\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+The implementation of Customized SetCompressionType().\r
+\r
+Arguments:\r
+  Type        - The type if compression.\r
+    \r
+Returns:\r
+    \r
+  EFI_SUCCESS           - The type has been set.\r
+  EFI_UNSUPPORTED       - This type is unsupported.\r
+\r
+    \r
+--*/\r
+EFI_STATUS\r
+CustomizedGetInfo (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  OUT     UINT32  *DstSize,\r
+  OUT     UINT32  *ScratchSize\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation of Customized GetInfo().\r
+\r
+Arguments:\r
+\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  DstSize     - The size of destination buffer.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+EFI_STATUS\r
+CustomizedDecompress (\r
+  IN      VOID    *Source,\r
+  IN      UINT32  SrcSize,\r
+  IN OUT  VOID    *Destination,\r
+  IN      UINT32  DstSize,\r
+  IN OUT  VOID    *Scratch,\r
+  IN      UINT32  ScratchSize\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The implementation of Customized Decompress().\r
+\r
+Arguments:\r
+\r
+  This        - The protocol instance pointer\r
+  Source      - The source buffer containing the compressed data.\r
+  SrcSize     - The size of source buffer\r
+  Destination - The destination buffer to store the decompressed data\r
+  DstSize     - The size of destination buffer.\r
+  Scratch     - The buffer used internally by the decompress routine. This  buffer is needed to store intermediate data.\r
+  ScratchSize - The size of scratch buffer.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_INVALID_PARAMETER - The source data is corrupted\r
+\r
+--*/\r
+EFI_STATUS\r
+CustomizedCompress (\r
+  IN      UINT8   *SrcBuffer,\r
+  IN      UINT32  SrcSize,\r
+  IN      UINT8   *DstBuffer,\r
+  IN OUT  UINT32  *DstSize\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The Customized compression routine.\r
+\r
+Arguments:\r
+\r
+  SrcBuffer   - The buffer storing the source data\r
+  SrcSize     - The size of source data\r
+  DstBuffer   - The buffer to store the compressed data\r
+  DstSize     - On input, the size of DstBuffer; On output,\r
+                the size of the actual compressed data.\r
+\r
+Returns:\r
+\r
+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,\r
+                          DstSize contains the size needed.\r
+  EFI_SUCCESS           - Compression is successful.\r
+\r
+--*/\r
+\r
+#endif\r
diff --git a/Source/C/Common/EfiUtilityMsgs.c b/Source/C/Common/EfiUtilityMsgs.c
new file mode 100644 (file)
index 0000000..566d214
--- /dev/null
@@ -0,0 +1,755 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:  \r
+\r
+  EfiUtilityMsgs.c\r
+  \r
+Abstract:\r
+\r
+  EFI tools utility functions to display warning, error, and informational\r
+  messages.\r
+  \r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <stdarg.h>\r
+\r
+#include "EfiUtilityMsgs.h"\r
+\r
+#define MAX_LINE_LEN  200\r
+\r
+//\r
+// Declare module globals for keeping track of the the utility's\r
+// name and other settings.\r
+//\r
+static STATUS mStatus                 = STATUS_SUCCESS;\r
+static CHAR8  mUtilityName[50]        = { 0 };\r
+static UINT32 mDebugMsgMask           = 0;\r
+static CHAR8  *mSourceFileName        = NULL;\r
+static UINT32 mSourceFileLineNum      = 0;\r
+static UINT32 mErrorCount             = 0;\r
+static UINT32 mWarningCount           = 0;\r
+static UINT32 mMaxErrors              = 0;\r
+static UINT32 mMaxWarnings            = 0;\r
+static UINT32 mMaxWarningsPlusErrors  = 0;\r
+static INT8   mPrintLimitsSet         = 0;\r
+\r
+static\r
+void\r
+PrintMessage (\r
+  CHAR8   *Type,\r
+  CHAR8   *FileName,\r
+  UINT32  LineNumber,\r
+  UINT32  MessageCode,\r
+  CHAR8   *Text,\r
+  CHAR8   *MsgFmt,\r
+  va_list List\r
+  );\r
+\r
+static\r
+void\r
+PrintLimitExceeded (\r
+  VOID\r
+  );\r
+\r
+void\r
+Error (\r
+  CHAR8   *FileName,\r
+  UINT32  LineNumber,\r
+  UINT32  MessageCode,\r
+  CHAR8   *Text,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Prints an error message.\r
+  \r
+Arguments:\r
+  All arguments are optional, though the printed message may be useless if\r
+  at least something valid is not specified.\r
+  \r
+  FileName - name of the file or application. If not specified, then the\r
+             utilty name (as set by the utility calling SetUtilityName()\r
+             earlier) is used. Otherwise "Unknown utility" is used.\r
+  \r
+  LineNumber - the line number of error, typically used by parsers. If the\r
+               utility is not a parser, then 0 should be specified. Otherwise\r
+               the FileName and LineNumber info can be used to cause\r
+               MS Visual Studio to jump to the error.\r
+               \r
+  MessageCode - an application-specific error code that can be referenced in\r
+              other documentation. \r
+\r
+  Text        - the text in question, typically used by parsers.\r
+  \r
+  MsgFmt - the format string for the error message. Can contain formatting\r
+           controls for use with the varargs.\r
+           \r
+Returns:\r
+  None.\r
+  \r
+Notes:\r
+  We print the following (similar to the Warn() and Debug() \r
+  W\r
+  Typical error/warning message format:\r
+\r
+  bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters\r
+\r
+  BUGBUG -- these three utility functions are almost identical, and\r
+  should be modified to share code.\r
+\r
+  Visual Studio does not find error messages with:\r
+  \r
+     " error :"\r
+     " error 1:"\r
+     " error c1:"\r
+     " error 1000:"\r
+     " error c100:"\r
+\r
+  It does find:\r
+     " error c1000:"     \r
+--*/\r
+{\r
+  va_list List;\r
+  //\r
+  // If limits have been set, then check that we have not exceeded them\r
+  //\r
+  if (mPrintLimitsSet) {\r
+    //\r
+    // See if we've exceeded our total count\r
+    //\r
+    if (mMaxWarningsPlusErrors != 0) {\r
+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {\r
+        PrintLimitExceeded ();\r
+        return ;\r
+      }\r
+    }\r
+    //\r
+    // See if we've exceeded our error count\r
+    //\r
+    if (mMaxErrors != 0) {\r
+      if (mErrorCount > mMaxErrors) {\r
+        PrintLimitExceeded ();\r
+        return ;\r
+      }\r
+    }\r
+  }\r
+\r
+  mErrorCount++;\r
+  va_start (List, MsgFmt);\r
+  PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List);\r
+  va_end (List);\r
+  //\r
+  // Set status accordingly\r
+  //\r
+  if (mStatus < STATUS_ERROR) {\r
+    mStatus = STATUS_ERROR;\r
+  }\r
+}\r
+\r
+void\r
+ParserError (\r
+  UINT32  MessageCode,\r
+  CHAR8   *Text,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Print a parser error, using the source file name and line number\r
+  set by a previous call to SetParserPosition().\r
+\r
+Arguments:\r
+  MessageCode   - application-specific error code\r
+  Text          - text to print in the error message\r
+  MsgFmt        - format string to print at the end of the error message\r
+\r
+Returns:\r
+  NA\r
+\r
+--*/\r
+{\r
+  va_list List;\r
+  //\r
+  // If limits have been set, then check them\r
+  //\r
+  if (mPrintLimitsSet) {\r
+    //\r
+    // See if we've exceeded our total count\r
+    //\r
+    if (mMaxWarningsPlusErrors != 0) {\r
+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {\r
+        PrintLimitExceeded ();\r
+        return ;\r
+      }\r
+    }\r
+    //\r
+    // See if we've exceeded our error count\r
+    //\r
+    if (mMaxErrors != 0) {\r
+      if (mErrorCount > mMaxErrors) {\r
+        PrintLimitExceeded ();\r
+        return ;\r
+      }\r
+    }\r
+  }\r
+\r
+  mErrorCount++;\r
+  va_start (List, MsgFmt);\r
+  PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List);\r
+  va_end (List);\r
+  //\r
+  // Set status accordingly\r
+  //\r
+  if (mStatus < STATUS_ERROR) {\r
+    mStatus = STATUS_ERROR;\r
+  }\r
+}\r
+\r
+void\r
+ParserWarning (\r
+  UINT32  ErrorCode,\r
+  CHAR8   *OffendingText,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Print a parser warning, using the source file name and line number\r
+  set by a previous call to SetParserPosition().\r
+\r
+Arguments:\r
+  ErrorCode     - application-specific error code\r
+  OffendingText - text to print in the warning message\r
+  MsgFmt        - format string to print at the end of the warning message\r
+\r
+Returns:\r
+  NA\r
+\r
+--*/\r
+{\r
+  va_list List;\r
+  //\r
+  // If limits have been set, then check them\r
+  //\r
+  if (mPrintLimitsSet) {\r
+    //\r
+    // See if we've exceeded our total count\r
+    //\r
+    if (mMaxWarningsPlusErrors != 0) {\r
+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {\r
+        PrintLimitExceeded ();\r
+        return ;\r
+      }\r
+    }\r
+    //\r
+    // See if we've exceeded our warning count\r
+    //\r
+    if (mMaxWarnings != 0) {\r
+      if (mWarningCount > mMaxWarnings) {\r
+        PrintLimitExceeded ();\r
+        return ;\r
+      }\r
+    }\r
+  }\r
+\r
+  mWarningCount++;\r
+  va_start (List, MsgFmt);\r
+  PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List);\r
+  va_end (List);\r
+  //\r
+  // Set status accordingly\r
+  //\r
+  if (mStatus < STATUS_WARNING) {\r
+    mStatus = STATUS_WARNING;\r
+  }\r
+}\r
+\r
+void\r
+Warning (\r
+  CHAR8   *FileName,\r
+  UINT32  LineNumber,\r
+  UINT32  MessageCode,\r
+  CHAR8   *Text,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Print a warning message.\r
+\r
+Arguments:\r
+  FileName    - name of the file where the warning was detected, or the name\r
+                of the application that detected the warning\r
+  \r
+  LineNumber  - the line number where the warning was detected (parsers).\r
+                0 should be specified if the utility is not a parser.\r
+               \r
+  MessageCode - an application-specific warning code that can be referenced in\r
+                other documentation. \r
+\r
+  Text        - the text in question (parsers)\r
+  \r
+  MsgFmt      - the format string for the warning message. Can contain formatting\r
+                controls for use with varargs.\r
+           \r
+Returns:\r
+  None.\r
+\r
+--*/\r
+{\r
+  va_list List;\r
+  //\r
+  // If limits have been set, then check them\r
+  //\r
+  if (mPrintLimitsSet) {\r
+    //\r
+    // See if we've exceeded our total count\r
+    //\r
+    if (mMaxWarningsPlusErrors != 0) {\r
+      if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {\r
+        PrintLimitExceeded ();\r
+        return ;\r
+      }\r
+    }\r
+    //\r
+    // See if we've exceeded our warning count\r
+    //\r
+    if (mMaxWarnings != 0) {\r
+      if (mWarningCount > mMaxWarnings) {\r
+        PrintLimitExceeded ();\r
+        return ;\r
+      }\r
+    }\r
+  }\r
+\r
+  mWarningCount++;\r
+  va_start (List, MsgFmt);\r
+  PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List);\r
+  va_end (List);\r
+  //\r
+  // Set status accordingly\r
+  //\r
+  if (mStatus < STATUS_WARNING) {\r
+    mStatus = STATUS_WARNING;\r
+  }\r
+}\r
+\r
+void\r
+DebugMsg (\r
+  CHAR8   *FileName,\r
+  UINT32  LineNumber,\r
+  UINT32  MsgMask,\r
+  CHAR8   *Text,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Print a warning message.\r
+\r
+Arguments:\r
+  FileName    - typically the name of the utility printing the debug message, but\r
+                can be the name of a file being parsed.\r
+  \r
+  LineNumber  - the line number in FileName (parsers) \r
+               \r
+  MsgMask     - an application-specific bitmask that, in combination with mDebugMsgMask,\r
+                determines if the debug message gets printed.\r
+\r
+  Text        - the text in question (parsers)\r
+  \r
+  MsgFmt      - the format string for the debug message. Can contain formatting\r
+                controls for use with varargs.\r
+           \r
+Returns:\r
+  None.\r
+\r
+--*/\r
+{\r
+  va_list List;\r
+  //\r
+  // If the debug mask is not applicable, then do nothing.\r
+  //\r
+  if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) {\r
+    return ;\r
+  }\r
+\r
+  va_start (List, MsgFmt);\r
+  PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List);\r
+  va_end (List);\r
+}\r
+\r
+static\r
+void\r
+PrintMessage (\r
+  CHAR8   *Type,\r
+  CHAR8   *FileName,\r
+  UINT32  LineNumber,\r
+  UINT32  MessageCode,\r
+  CHAR8   *Text,\r
+  CHAR8   *MsgFmt,\r
+  va_list List\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Worker routine for all the utility printing services. Prints the message in\r
+  a format that Visual Studio will find when scanning build outputs for\r
+  errors or warnings.\r
+\r
+Arguments:\r
+  Type        - "warning" or "error" string to insert into the message to be\r
+                printed. The first character of this string (converted to uppercase)\r
+                is used to preceed the MessageCode value in the output string.\r
+\r
+  FileName    - name of the file where the warning was detected, or the name\r
+                of the application that detected the warning\r
+  \r
+  LineNumber  - the line number where the warning was detected (parsers).\r
+                0 should be specified if the utility is not a parser.\r
+               \r
+  MessageCode - an application-specific warning code that can be referenced in\r
+                other documentation. \r
+\r
+  Text        - part of the message to print\r
+  \r
+  MsgFmt      - the format string for the message. Can contain formatting\r
+                controls for use with varargs.\r
+  List        - the variable list.\r
+           \r
+Returns:\r
+  None.\r
+\r
+Notes:\r
+  If FileName == NULL then this utility will use the string passed into SetUtilityName(). \r
+  \r
+  LineNumber is only used if the caller is a parser, in which case FileName refers to the\r
+  file being parsed.\r
+\r
+  Text and MsgFmt are both optional, though it would be of little use calling this function with\r
+  them both NULL.\r
+\r
+  Output will typically be of the form:\r
+    <FileName>(<LineNumber>) : <Type> <Type[0]><MessageCode>: <Text> : <MsgFmt>\r
+\r
+    Parser (LineNumber != 0)\r
+      VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters\r
+    Generic utility (LineNumber == 0) \r
+      UtilityName : error E1234 : Text string : MsgFmt string and args\r
+\r
+--*/\r
+{\r
+  CHAR8 Line[MAX_LINE_LEN];\r
+  CHAR8 Line2[MAX_LINE_LEN];\r
+  CHAR8 *Cptr;\r
+  //\r
+  // If given a filename, then add it (and the line number) to the string.\r
+  // If there's no filename, then use the program name if provided.\r
+  //\r
+  if (FileName != NULL) {\r
+    Cptr = FileName;\r
+  } else if (mUtilityName[0] != 0) {\r
+    Cptr = mUtilityName;\r
+  } else {\r
+    Cptr = "Unknown utility";\r
+  }\r
+\r
+  strcpy (Line, Cptr);\r
+  if (LineNumber != 0) {\r
+    sprintf (Line2, "(%d)", LineNumber);\r
+    strcat (Line, Line2);\r
+  }\r
+  //\r
+  // Have to print an error code or Visual Studio won't find the\r
+  // message for you. It has to be decimal digits too.\r
+  //\r
+  sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode);\r
+  strcat (Line, Line2);\r
+  fprintf (stdout, "%s", Line);\r
+  //\r
+  // If offending text was provided, then print it\r
+  //\r
+  if (Text != NULL) {\r
+    fprintf (stdout, ": %s ", Text);\r
+  }\r
+  //\r
+  // Print formatted message if provided\r
+  //\r
+  if (MsgFmt != NULL) {\r
+    vsprintf (Line2, MsgFmt, List);\r
+    fprintf (stdout, ": %s", Line2);\r
+  }\r
+\r
+  fprintf (stdout, "\n");\r
+}\r
+\r
+void\r
+ParserSetPosition (\r
+  CHAR8   *SourceFileName,\r
+  UINT32  LineNum\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Set the position in a file being parsed. This can be used to \r
+  print error messages deeper down in a parser.\r
+\r
+Arguments:\r
+  SourceFileName - name of the source file being parsed\r
+  LineNum        - line number of the source file being parsed\r
+\r
+Returns:\r
+  NA\r
+\r
+--*/\r
+{\r
+  mSourceFileName     = SourceFileName;\r
+  mSourceFileLineNum  = LineNum;\r
+}\r
+\r
+void\r
+SetUtilityName (\r
+  CHAR8   *UtilityName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  All printed error/warning/debug messages follow the same format, and\r
+  typically will print a filename or utility name followed by the error\r
+  text. However if a filename is not passed to the print routines, then\r
+  they'll print the utility name if you call this function early in your\r
+  app to set the utility name.\r
+  \r
+Arguments:\r
+  UtilityName  -  name of the utility, which will be printed with all\r
+                  error/warning/debug messags.\r
+\r
+Returns:\r
+  NA\r
+  \r
+--*/\r
+{\r
+  //\r
+  // Save the name of the utility in our local variable. Make sure its\r
+  // length does not exceed our buffer.\r
+  //\r
+  if (UtilityName != NULL) {\r
+    if (strlen (UtilityName) >= sizeof (mUtilityName)) {\r
+      Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");\r
+      strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);\r
+      mUtilityName[sizeof (mUtilityName) - 1] = 0;\r
+      return ;\r
+    } else {\r
+      strcpy (mUtilityName, UtilityName);\r
+    }\r
+  } else {\r
+    Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");\r
+  }\r
+}\r
+\r
+STATUS\r
+GetUtilityStatus (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  When you call Error() or Warning(), this module keeps track of it and\r
+  sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility\r
+  exits, it can call this function to get the status and use it as a return\r
+  value.\r
+  \r
+Arguments:\r
+  None.\r
+\r
+Returns:\r
+  Worst-case status reported, as defined by which print function was called.\r
+  \r
+--*/\r
+{\r
+  return mStatus;\r
+}\r
+\r
+void\r
+SetDebugMsgMask (\r
+  UINT32  DebugMask\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Set the debug printing mask. This is used by the DebugMsg() function\r
+  to determine when/if a debug message should be printed.\r
+\r
+Arguments:\r
+  DebugMask  - bitmask, specific to the calling application\r
+\r
+Returns:\r
+  NA\r
+\r
+--*/\r
+{\r
+  mDebugMsgMask = DebugMask;\r
+}\r
+\r
+void\r
+SetPrintLimits (\r
+  UINT32  MaxErrors,\r
+  UINT32  MaxWarnings,\r
+  UINT32  MaxWarningsPlusErrors\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Set the limits of how many errors, warnings, and errors+warnings\r
+  we will print.\r
+\r
+Arguments:\r
+  MaxErrors       - maximum number of error messages to print\r
+  MaxWarnings     - maximum number of warning messages to print\r
+  MaxWarningsPlusErrors \r
+                  - maximum number of errors+warnings to print\r
+\r
+Returns:\r
+  NA\r
+\r
+--*/\r
+{\r
+  mMaxErrors              = MaxErrors;\r
+  mMaxWarnings            = MaxWarnings;\r
+  mMaxWarningsPlusErrors  = MaxWarningsPlusErrors;\r
+  mPrintLimitsSet         = 1;\r
+}\r
+\r
+static\r
+void\r
+PrintLimitExceeded (\r
+  VOID\r
+  )\r
+{\r
+  static INT8 mPrintLimitExceeded = 0;\r
+  //\r
+  // If we've already printed the message, do nothing. Otherwise\r
+  // temporarily increase our print limits so we can pass one\r
+  // more message through.\r
+  //\r
+  if (mPrintLimitExceeded == 0) {\r
+    mPrintLimitExceeded++;\r
+    mMaxErrors++;\r
+    mMaxWarnings++;\r
+    mMaxWarningsPlusErrors++;\r
+    Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);\r
+    mMaxErrors--;\r
+    mMaxWarnings--;\r
+    mMaxWarningsPlusErrors--;\r
+  }\r
+}\r
+\r
+#if 0\r
+void\r
+TestUtilityMessages (\r
+  VOID\r
+  )\r
+{\r
+  char *ArgStr = "ArgString";\r
+  int  ArgInt;\r
+\r
+  ArgInt  = 0x12345678;\r
+  //\r
+  // Test without setting utility name\r
+  //\r
+  fprintf (stdout, "* Testing without setting utility name\n");\r
+  fprintf (stdout, "** Test debug message not printed\n");\r
+  DebugMsg (NULL, 0, 0x00000001, NULL, NULL);\r
+  fprintf (stdout, "** Test warning with two strings and two args\n");\r
+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
+  fprintf (stdout, "** Test error with two strings and two args\n");\r
+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
+  fprintf (stdout, "** Test parser warning with nothing\n");\r
+  ParserWarning (0, NULL, NULL);\r
+  fprintf (stdout, "** Test parser error with nothing\n");\r
+  ParserError (0, NULL, NULL);\r
+  //\r
+  // Test with utility name set now\r
+  //\r
+  fprintf (stdout, "** Testingin with utility name set\n");\r
+  SetUtilityName ("MyUtilityName");\r
+  //\r
+  // Test debug prints\r
+  //\r
+  SetDebugMsgMask (2);\r
+  fprintf (stdout, "** Test debug message with one string\n");\r
+  DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);\r
+  fprintf (stdout, "** Test debug message with one string\n");\r
+  DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");\r
+  fprintf (stdout, "** Test debug message with two strings\n");\r
+  DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");\r
+  fprintf (stdout, "** Test debug message with two strings and two args\n");\r
+  DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
+  //\r
+  // Test warning prints\r
+  //\r
+  fprintf (stdout, "** Test warning with no strings\n");\r
+  Warning (NULL, 0, 1234, NULL, NULL);\r
+  fprintf (stdout, "** Test warning with one string\n");\r
+  Warning (NULL, 0, 1234, "Text1", NULL);\r
+  fprintf (stdout, "** Test warning with one string\n");\r
+  Warning (NULL, 0, 1234, NULL, "Text2");\r
+  fprintf (stdout, "** Test warning with two strings and two args\n");\r
+  Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
+  //\r
+  // Test error prints\r
+  //\r
+  fprintf (stdout, "** Test error with no strings\n");\r
+  Error (NULL, 0, 1234, NULL, NULL);\r
+  fprintf (stdout, "** Test error with one string\n");\r
+  Error (NULL, 0, 1234, "Text1", NULL);\r
+  fprintf (stdout, "** Test error with one string\n");\r
+  Error (NULL, 0, 1234, NULL, "Text2");\r
+  fprintf (stdout, "** Test error with two strings and two args\n");\r
+  Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
+  //\r
+  // Test parser prints\r
+  //\r
+  fprintf (stdout, "** Test parser errors\n");\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserError (1234, NULL, NULL);\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserError (1234, "Text1", NULL);\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserError (1234, NULL, "Text2");\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserError (1234, "Text1", "Text2");\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
+\r
+  fprintf (stdout, "** Test parser warnings\n");\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserWarning (4321, NULL, NULL);\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserWarning (4321, "Text1", NULL);\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserWarning (4321, NULL, "Text2");\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserWarning (4321, "Text1", "Text2");\r
+  ParserSetPosition (__FILE__, __LINE__ + 1);\r
+  ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
+}\r
+#endif\r
diff --git a/Source/C/Common/EfiUtilityMsgs.h b/Source/C/Common/EfiUtilityMsgs.h
new file mode 100644 (file)
index 0000000..a76b822
--- /dev/null
@@ -0,0 +1,137 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  EfiUtilityMsgs.h\r
+\r
+Abstract:\r
+\r
+  Defines and prototypes for common EFI utility error and debug messages.\r
+  \r
+--*/\r
+\r
+#ifndef _EFI_UTILITY_MSGS_H_\r
+#define _EFI_UTILITY_MSGS_H_\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+\r
+//\r
+// Status codes returned by EFI utility programs and functions\r
+//\r
+#define STATUS_SUCCESS  0\r
+#define STATUS_WARNING  1\r
+#define STATUS_ERROR    2\r
+#define VOID void \r
+\r
+typedef int STATUS;\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+//\r
+// When we call Error() or Warning(), the module keeps track of the worst\r
+// case reported. GetUtilityStatus() will get the worst-case results, which\r
+// can be used as the return value from the app.\r
+//\r
+STATUS\r
+GetUtilityStatus (\r
+  void\r
+  );\r
+\r
+//\r
+// If someone prints an error message and didn't specify a source file name,\r
+// then we print the utility name instead. However they must tell us the\r
+// utility name early on via this function.\r
+//\r
+void\r
+SetUtilityName (\r
+  CHAR8 *ProgramName\r
+  )\r
+;\r
+\r
+void\r
+Error (\r
+  CHAR8   *FileName,\r
+  UINT32  LineNumber,\r
+  UINT32  ErrorCode,\r
+  CHAR8   *OffendingText,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+;\r
+\r
+void\r
+Warning (\r
+  CHAR8   *FileName,\r
+  UINT32  LineNumber,\r
+  UINT32  ErrorCode,\r
+  CHAR8   *OffendingText,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+;\r
+\r
+void\r
+DebugMsg (\r
+  CHAR8   *FileName,\r
+  UINT32  LineNumber,\r
+  UINT32  MsgLevel,\r
+  CHAR8   *OffendingText,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+;\r
+\r
+void\r
+SetDebugMsgMask (\r
+  UINT32    MsgMask\r
+  )\r
+;\r
+\r
+void\r
+ParserSetPosition (\r
+  CHAR8   *SourceFileName,\r
+  UINT32  LineNum\r
+  )\r
+;\r
+\r
+void\r
+ParserError (\r
+  UINT32  ErrorCode,\r
+  CHAR8   *OffendingText,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+;\r
+\r
+void\r
+ParserWarning (\r
+  UINT32  ErrorCode,\r
+  CHAR8   *OffendingText,\r
+  CHAR8   *MsgFmt,\r
+  ...\r
+  )\r
+;\r
+\r
+void\r
+SetPrintLimits (\r
+  UINT32  NumErrors,\r
+  UINT32  NumWarnings,\r
+  UINT32  NumWarningsPlusErrors\r
+  )\r
+;\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // #ifndef _EFI_UTILITY_MSGS_H_\r
diff --git a/Source/C/Common/FvLib.c b/Source/C/Common/FvLib.c
new file mode 100644 (file)
index 0000000..a208172
--- /dev/null
@@ -0,0 +1,760 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2006, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  FvLib.c\r
+\r
+Abstract:\r
+\r
+  These functions assist in parsing and manipulating a Firmware Volume.\r
+\r
+--*/\r
+\r
+//\r
+// Include files\r
+//\r
+#include "FvLib.h"\r
+#include "CommonLib.h"\r
+#include "EfiUtilityMsgs.h"\r
+\r
+//\r
+// Module global variables\r
+//\r
+EFI_FIRMWARE_VOLUME_HEADER  *mFvHeader  = NULL;\r
+UINT32                      mFvLength   = 0;\r
+\r
+//\r
+// External function implementations\r
+//\r
+EFI_STATUS\r
+InitializeFvLib (\r
+  IN VOID                         *Fv,\r
+  IN UINT32                       FvLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This initializes the FV lib with a pointer to the FV and length.  It does not\r
+  verify the FV in any way.\r
+\r
+Arguments:\r
+\r
+  Fv            Buffer containing the FV.\r
+  FvLength      Length of the FV\r
+    \r
+Returns:\r
\r
+  EFI_SUCCESS             Function Completed successfully.\r
+  EFI_INVALID_PARAMETER   A required parameter was NULL.\r
+\r
+--*/\r
+{\r
+  //\r
+  // Verify input arguments\r
+  //\r
+  if (Fv == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  mFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Fv;\r
+  mFvLength = FvLength;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetFvHeader (\r
+  OUT EFI_FIRMWARE_VOLUME_HEADER  **FvHeader,\r
+  OUT UINT32                      *FvLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function returns a pointer to the current FV and the size.\r
+\r
+Arguments:\r
+\r
+  FvHeader      Pointer to the FV buffer.\r
+  FvLength      Length of the FV\r
+    \r
+Returns:\r
\r
+  EFI_SUCCESS             Function Completed successfully.\r
+  EFI_INVALID_PARAMETER   A required parameter was NULL.\r
+  EFI_ABORTED             The library needs to be initialized.\r
+\r
+--*/\r
+{\r
+  //\r
+  // Verify library has been initialized.\r
+  //\r
+  if (mFvHeader == NULL || mFvLength == 0) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Verify input arguments\r
+  //\r
+  if (FvHeader == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *FvHeader = mFvHeader;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetNextFile (\r
+  IN EFI_FFS_FILE_HEADER          *CurrentFile,\r
+  OUT EFI_FFS_FILE_HEADER         **NextFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function returns the next file.  If the current file is NULL, it returns\r
+  the first file in the FV.  If the function returns EFI_SUCCESS and the file \r
+  pointer is NULL, then there are no more files in the FV.\r
+\r
+Arguments:\r
+\r
+  CurrentFile   Pointer to the current file, must be within the current FV.\r
+  NextFile      Pointer to the next file in the FV.\r
+    \r
+Returns:\r
\r
+  EFI_SUCCESS             Function completed successfully.\r
+  EFI_INVALID_PARAMETER   A required parameter was NULL or is out of range.\r
+  EFI_ABORTED             The library needs to be initialized.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Verify library has been initialized.\r
+  //\r
+  if (mFvHeader == NULL || mFvLength == 0) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Verify input arguments\r
+  //\r
+  if (NextFile == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Verify FV header\r
+  //\r
+  Status = VerifyFv (mFvHeader);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Get first file\r
+  //\r
+  if (CurrentFile == NULL) {\r
+    CurrentFile = (EFI_FFS_FILE_HEADER *) ((UINTN) mFvHeader + mFvHeader->HeaderLength);\r
+\r
+    //\r
+    // Verify file is valid\r
+    //\r
+    Status = VerifyFfsFile (CurrentFile);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // no files in this FV\r
+      //\r
+      *NextFile = NULL;\r
+      return EFI_SUCCESS;\r
+    } else {\r
+      //\r
+      // Verify file is in this FV.\r
+      //\r
+      if ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength) {\r
+        *NextFile = NULL;\r
+        return EFI_SUCCESS;\r
+      }\r
+\r
+      *NextFile = CurrentFile;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  //\r
+  // Verify current file is in range\r
+  //\r
+  if (((UINTN) CurrentFile < (UINTN) mFvHeader + mFvHeader->HeaderLength) ||\r
+      ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength)\r
+     ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Get next file, compensate for 8 byte alignment if necessary.\r
+  //\r
+  *NextFile = (EFI_FFS_FILE_HEADER *) (((UINTN) CurrentFile + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3));\r
+\r
+  //\r
+  // Verify file is in this FV.\r
+  //\r
+  if (((UINTN) *NextFile + sizeof (EFI_FFS_FILE_HEADER) >= (UINTN) mFvHeader + mFvLength) ||\r
+      ((UINTN) *NextFile + GetLength ((*NextFile)->Size) > (UINTN) mFvHeader + mFvLength)\r
+     ) {\r
+    *NextFile = NULL;\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // Verify file is valid\r
+  //\r
+  Status = VerifyFfsFile (*NextFile);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // no more files in this FV\r
+    //\r
+    *NextFile = NULL;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetFileByName (\r
+  IN EFI_GUID                     *FileName,\r
+  OUT EFI_FFS_FILE_HEADER         **File\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Find a file by name.  The function will return NULL if the file is not found.\r
+\r
+Arguments:\r
+\r
+  FileName    The GUID file name of the file to search for.\r
+  File        Return pointer.  In the case of an error, contents are undefined.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             The function completed successfully.\r
+  EFI_ABORTED             An error was encountered.\r
+  EFI_INVALID_PARAMETER   One of the parameters was NULL.\r
+\r
+--*/\r
+{\r
+  EFI_FFS_FILE_HEADER *CurrentFile;\r
+  EFI_STATUS          Status;\r
+\r
+  //\r
+  // Verify library has been initialized.\r
+  //\r
+  if (mFvHeader == NULL || mFvLength == 0) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Verify input parameters\r
+  //\r
+  if (FileName == NULL || File == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Verify FV header\r
+  //\r
+  Status = VerifyFv (mFvHeader);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Get the first file\r
+  //\r
+  Status = GetNextFile (NULL, &CurrentFile);\r
+  if (EFI_ERROR (Status)) {\r
+    Error (NULL, 0, 0, "error parsing the FV", NULL);\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Loop as long as we have a valid file\r
+  //\r
+  while (CurrentFile) {\r
+    if (!CompareGuid (&CurrentFile->Name, FileName)) {\r
+      *File = CurrentFile;\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    Status = GetNextFile (CurrentFile, &CurrentFile);\r
+    if (EFI_ERROR (Status)) {\r
+      Error (NULL, 0, 0, "error parsing the FV", NULL);\r
+      return EFI_ABORTED;\r
+    }\r
+  }\r
+  //\r
+  // File not found in this FV.\r
+  //\r
+  *File = NULL;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetFileByType (\r
+  IN EFI_FV_FILETYPE              FileType,\r
+  IN UINTN                        Instance,\r
+  OUT EFI_FFS_FILE_HEADER         **File\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Find a file by type and instance.  An instance of 1 is the first instance.\r
+  The function will return NULL if a matching file cannot be found.\r
+  File type EFI_FV_FILETYPE_ALL means any file type is valid.\r
+\r
+Arguments:\r
+\r
+  FileType    Type of file to search for.\r
+  Instance    Instace of the file type to return.\r
+  File        Return pointer.  In the case of an error, contents are undefined.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             The function completed successfully.\r
+  EFI_ABORTED             An error was encountered.\r
+  EFI_INVALID_PARAMETER   One of the parameters was NULL.\r
+\r
+--*/\r
+{\r
+  EFI_FFS_FILE_HEADER *CurrentFile;\r
+  EFI_STATUS          Status;\r
+  UINTN               FileCount;\r
+\r
+  //\r
+  // Verify library has been initialized.\r
+  //\r
+  if (mFvHeader == NULL || mFvLength == 0) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Verify input parameters\r
+  //\r
+  if (File == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Verify FV header\r
+  //\r
+  Status = VerifyFv (mFvHeader);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Initialize the number of matching files found.\r
+  //\r
+  FileCount = 0;\r
+\r
+  //\r
+  // Get the first file\r
+  //\r
+  Status = GetNextFile (NULL, &CurrentFile);\r
+  if (EFI_ERROR (Status)) {\r
+    Error (NULL, 0, 0, "error parsing FV", NULL);\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Loop as long as we have a valid file\r
+  //\r
+  while (CurrentFile) {\r
+    if (FileType == EFI_FV_FILETYPE_ALL || CurrentFile->Type == FileType) {\r
+      FileCount++;\r
+    }\r
+\r
+    if (FileCount == Instance) {\r
+      *File = CurrentFile;\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    Status = GetNextFile (CurrentFile, &CurrentFile);\r
+    if (EFI_ERROR (Status)) {\r
+      Error (NULL, 0, 0, "error parsing the FV", NULL);\r
+      return EFI_ABORTED;\r
+    }\r
+  }\r
+\r
+  *File = NULL;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetSectionByType (\r
+  IN EFI_FFS_FILE_HEADER          *File,\r
+  IN EFI_SECTION_TYPE             SectionType,\r
+  IN UINTN                        Instance,\r
+  OUT EFI_FILE_SECTION_POINTER    *Section\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Find a section in a file by type and instance.  An instance of 1 is the first \r
+  instance.  The function will return NULL if a matching section cannot be found.\r
+  The function will not handle encapsulating sections.\r
+\r
+Arguments:\r
+\r
+  File        The file to search.\r
+  SectionType Type of file to search for.\r
+  Instance    Instace of the section to return.\r
+  Section     Return pointer.  In the case of an error, contents are undefined.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             The function completed successfully.\r
+  EFI_ABORTED             An error was encountered.\r
+  EFI_INVALID_PARAMETER   One of the parameters was NULL.\r
+  EFI_NOT_FOUND           No found.\r
+--*/\r
+{\r
+  EFI_FILE_SECTION_POINTER  CurrentSection;\r
+  EFI_STATUS                Status;\r
+  UINTN                     SectionCount;\r
+\r
+  //\r
+  // Verify input parameters\r
+  //\r
+  if (File == NULL || Instance == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Verify FFS header\r
+  //\r
+  Status = VerifyFfsFile (File);\r
+  if (EFI_ERROR (Status)) {\r
+    Error (NULL, 0, 0, "invalid FFS file", NULL);\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Initialize the number of matching sections found.\r
+  //\r
+  SectionCount = 0;\r
+\r
+  //\r
+  // Get the first section\r
+  //\r
+  CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER));\r
+\r
+  //\r
+  // Loop as long as we have a valid file\r
+  //\r
+  while ((UINTN) CurrentSection.CommonHeader < (UINTN) File + GetLength (File->Size)) {\r
+    if (CurrentSection.CommonHeader->Type == SectionType) {\r
+      SectionCount++;\r
+    }\r
+\r
+    if (SectionCount == Instance) {\r
+      *Section = CurrentSection;\r
+      return EFI_SUCCESS;\r
+    }\r
+    //\r
+    // Find next section (including compensating for alignment issues.\r
+    //\r
+    CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));\r
+  }\r
+  //\r
+  // Section not found\r
+  //\r
+  (*Section).Code16Section = NULL;\r
+  return EFI_NOT_FOUND;\r
+}\r
+//\r
+// will not parse compressed sections\r
+//\r
+EFI_STATUS\r
+VerifyFv (\r
+  IN EFI_FIRMWARE_VOLUME_HEADER   *FvHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Verify the current pointer points to a valid FV header.\r
+\r
+Arguments:\r
+\r
+  FvHeader     Pointer to an alleged FV file.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             The FV header is valid.\r
+  EFI_VOLUME_CORRUPTED    The FV header is not valid.\r
+  EFI_INVALID_PARAMETER   A required parameter was NULL.\r
+  EFI_ABORTED             Operation aborted.\r
+\r
+--*/\r
+{\r
+  UINT16  Checksum;\r
+\r
+  //\r
+  // Verify input parameters\r
+  //\r
+  if (FvHeader == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (FvHeader->Signature != EFI_FVH_SIGNATURE) {\r
+    Error (NULL, 0, 0, "invalid FV header signature", NULL);\r
+    return EFI_VOLUME_CORRUPTED;\r
+  }\r
+  //\r
+  // Verify header checksum\r
+  //\r
+  Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));\r
+\r
+  if (Checksum != 0) {\r
+    Error (NULL, 0, 0, "invalid FV header checksum", NULL);\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+VerifyFfsFile (\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Verify the current pointer points to a FFS file header.\r
+\r
+Arguments:\r
+\r
+  FfsHeader     Pointer to an alleged FFS file.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           The Ffs header is valid.\r
+  EFI_NOT_FOUND         This "file" is the beginning of free space.\r
+  EFI_VOLUME_CORRUPTED  The Ffs header is not valid.\r
+  EFI_ABORTED           The erase polarity is not known.\r
+\r
+--*/\r
+{\r
+  BOOLEAN             ErasePolarity;\r
+  EFI_STATUS          Status;\r
+  EFI_FFS_FILE_HEADER BlankHeader;\r
+  UINT8               Checksum;\r
+  UINT32              FileLength;\r
+  UINT8               SavedChecksum;\r
+  UINT8               SavedState;\r
+  UINT8               FileGuidString[80];\r
+  //\r
+  // Verify library has been initialized.\r
+  //\r
+  if (mFvHeader == NULL || mFvLength == 0) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Verify FV header\r
+  //\r
+  Status = VerifyFv (mFvHeader);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Get the erase polarity.\r
+  //\r
+  Status = GetErasePolarity (&ErasePolarity);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Check if we have free space\r
+  //\r
+  if (ErasePolarity) {\r
+    memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER));\r
+  } else {\r
+    memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER));\r
+  }\r
+\r
+  if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  //\r
+  // Convert the GUID to a string so we can at least report which file\r
+  // if we find an error.\r
+  //\r
+  PrintGuidToBuffer (&FfsHeader->Name, FileGuidString, sizeof (FileGuidString), TRUE);\r
+  //\r
+  // Verify file header checksum\r
+  //\r
+  SavedState = FfsHeader->State;\r
+  FfsHeader->State = 0;\r
+  SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File;\r
+  FfsHeader->IntegrityCheck.Checksum.File = 0;\r
+  Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));\r
+  FfsHeader->State = SavedState;\r
+  FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum;\r
+  if (Checksum != 0) {\r
+    Error (NULL, 0, 0, FileGuidString, "invalid FFS file header checksum");\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Verify file checksum\r
+  //\r
+  if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
+    //\r
+    // Verify file data checksum\r
+    //\r
+    FileLength          = GetLength (FfsHeader->Size);\r
+    Checksum            = CalculateSum8 ((UINT8 *) FfsHeader, FileLength);\r
+    Checksum            = (UINT8) (Checksum - FfsHeader->State);\r
+    if (Checksum != 0) {\r
+      Error (NULL, 0, 0, FileGuidString, "invalid FFS file checksum");\r
+      return EFI_ABORTED;\r
+    }\r
+  } else {\r
+    //\r
+    // File does not have a checksum\r
+    // Verify contents are 0x5A as spec'd\r
+    //\r
+    if (FfsHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
+      Error (NULL, 0, 0, FileGuidString, "invalid fixed FFS file header checksum");\r
+      return EFI_ABORTED;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+UINT32\r
+GetLength (\r
+  UINT8     *ThreeByteLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Converts a three byte length value into a UINT32.\r
+\r
+Arguments:\r
+\r
+  ThreeByteLength   Pointer to the first of the 3 byte length.\r
+\r
+Returns:\r
+\r
+  UINT32      Size of the section\r
+\r
+--*/\r
+{\r
+  UINT32  Length;\r
+\r
+  if (ThreeByteLength == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  Length  = *((UINT32 *) ThreeByteLength);\r
+  Length  = Length & 0x00FFFFFF;\r
+\r
+  return Length;\r
+}\r
+\r
+EFI_STATUS\r
+GetErasePolarity (\r
+  OUT BOOLEAN   *ErasePolarity\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function returns with the FV erase polarity.  If the erase polarity\r
+  for a bit is 1, the function return TRUE.\r
+\r
+Arguments:\r
+\r
+  ErasePolarity   A pointer to the erase polarity.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS              The function completed successfully.\r
+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.\r
+  EFI_ABORTED              Operation aborted.\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Verify library has been initialized.\r
+  //\r
+  if (mFvHeader == NULL || mFvLength == 0) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Verify FV header\r
+  //\r
+  Status = VerifyFv (mFvHeader);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Verify input parameters.\r
+  //\r
+  if (ErasePolarity == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (mFvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {\r
+    *ErasePolarity = TRUE;\r
+  } else {\r
+    *ErasePolarity = FALSE;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+UINT8\r
+GetFileState (\r
+  IN BOOLEAN              ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function returns a the highest state bit in the FFS that is set.\r
+  It in no way validate the FFS file.\r
+\r
+Arguments:\r
+  \r
+  ErasePolarity The erase polarity for the file state bits.\r
+  FfsHeader     Pointer to a FFS file.\r
+\r
+Returns:\r
+\r
+  UINT8   The hightest set state of the file.\r
+\r
+--*/\r
+{\r
+  UINT8 FileState;\r
+  UINT8 HighestBit;\r
+\r
+  FileState = FfsHeader->State;\r
+\r
+  if (ErasePolarity) {\r
+    FileState = (UINT8)~FileState;\r
+  }\r
+\r
+  HighestBit = 0x80;\r
+  while (HighestBit != 0 && (HighestBit & FileState) == 0) {\r
+    HighestBit >>= 1;\r
+  }\r
+\r
+  return HighestBit;\r
+}\r
diff --git a/Source/C/Common/FvLib.h b/Source/C/Common/FvLib.h
new file mode 100644 (file)
index 0000000..3096f70
--- /dev/null
@@ -0,0 +1,181 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  FvLib.h\r
+\r
+Abstract:\r
+\r
+  These functions assist in parsing and manipulating a Firmware Volume.\r
+\r
+--*/\r
+\r
+#ifndef _EFI_FV_LIB_H\r
+#define _EFI_FV_LIB_H\r
+\r
+//\r
+// Include files\r
+//\r
+#include <string.h>\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+#include <Common/EfiImage.h>\r
+#include <Common/FirmwareVolumeImageFormat.h>\r
+#include <Common/PiFirmwareFileSystem.h>\r
+#include <Common/PiFirmwareVolumeHeader.h>\r
+#include <Common/MultiPhase.h>\r
+\r
+EFI_STATUS\r
+InitializeFvLib (\r
+  IN VOID                         *Fv,\r
+  IN UINT32                       FvLength\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+GetFvHeader (\r
+  OUT EFI_FIRMWARE_VOLUME_HEADER  **FvHeader,\r
+  OUT UINT32                      *FvLength\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+GetNextFile (\r
+  IN EFI_FFS_FILE_HEADER          *CurrentFile,\r
+  OUT EFI_FFS_FILE_HEADER         **NextFile\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+GetFileByName (\r
+  IN EFI_GUID                     *FileName,\r
+  OUT EFI_FFS_FILE_HEADER         **File\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+GetFileByType (\r
+  IN EFI_FV_FILETYPE              FileType,\r
+  IN UINTN                        Instance,\r
+  OUT EFI_FFS_FILE_HEADER         **File\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+GetSectionByType (\r
+  IN EFI_FFS_FILE_HEADER          *File,\r
+  IN EFI_SECTION_TYPE             SectionType,\r
+  IN UINTN                        Instance,\r
+  OUT EFI_FILE_SECTION_POINTER    *Section\r
+  )\r
+;\r
+//\r
+// will not parse compressed sections\r
+//\r
+EFI_STATUS\r
+VerifyFv (\r
+  IN EFI_FIRMWARE_VOLUME_HEADER   *FvHeader\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+VerifyFfsFile (\r
+  IN EFI_FFS_FILE_HEADER          *FfsHeader\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Verify the current pointer points to a FFS file header.\r
+\r
+Arguments:\r
+\r
+  FfsHeader     Pointer to an alleged FFS file.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           The Ffs header is valid.\r
+  EFI_NOT_FOUND         This "file" is the beginning of free space.\r
+  EFI_VOLUME_CORRUPTED  The Ffs header is not valid.\r
+\r
+--*/\r
+UINT32\r
+GetLength (\r
+  UINT8                           *ThreeByteLength\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Converts a three byte length value into a UINT32.\r
+\r
+Arguments:\r
+\r
+  ThreeByteLength   Pointer to the first of the 3 byte length.\r
+\r
+Returns:\r
+\r
+  UINT32      Size of the section\r
+\r
+--*/\r
+EFI_STATUS\r
+GetErasePolarity (\r
+  OUT BOOLEAN   *ErasePolarity\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function returns with the FV erase polarity.  If the erase polarity\r
+  for a bit is 1, the function return TRUE.\r
+\r
+Arguments:\r
+\r
+  ErasePolarity   A pointer to the erase polarity.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS              The function completed successfully.\r
+  EFI_INVALID_PARAMETER    One of the input parameters was invalid.\r
+\r
+--*/\r
+UINT8\r
+GetFileState (\r
+  IN BOOLEAN              ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function returns a the highest state bit in the FFS that is set.\r
+  It in no way validate the FFS file.\r
+\r
+Arguments:\r
+  \r
+  ErasePolarity The erase polarity for the file state bits.\r
+  FfsHeader     Pointer to a FFS file.\r
+\r
+Returns:\r
+\r
+  UINT8   The hightest set state of the file.\r
+\r
+--*/\r
+#endif\r
diff --git a/Source/C/Common/GNUmakefile b/Source/C/Common/GNUmakefile
new file mode 100644 (file)
index 0000000..a1f6cb9
--- /dev/null
@@ -0,0 +1,10 @@
+ARCH ?= IA32
+MAKEROOT ?= ..
+
+# VPATH = ..
+
+LIBNAME = Common
+
+OBJECTS = CommonLib.o Decompress.o EfiUtilityMsgs.o MyAlloc.o SimpleFileParsing.o Crc32.o EfiCompress.o FvLib.o ParseInf.o TianoCompress.o
+
+include $(MAKEROOT)/lib.makefile
diff --git a/Source/C/Common/Makefile b/Source/C/Common/Makefile
new file mode 100644 (file)
index 0000000..bc9ac3a
--- /dev/null
@@ -0,0 +1,10 @@
+!INCLUDE ..\MSmakefile.common\r
+\r
+# VPATH = ..\r
+\r
+LIBNAME = Common\r
+\r
+OBJECTS = CommonLib.obj Decompress.obj EfiUtilityMsgs.obj MyAlloc.obj SimpleFileParsing.obj Crc32.obj EfiCompress.obj FvLib.obj ParseInf.obj TianoCompress.obj\r
+\r
+!INCLUDE ..\MSmakefile.lib\r
+\r
diff --git a/Source/C/Common/MyAlloc.c b/Source/C/Common/MyAlloc.c
new file mode 100644 (file)
index 0000000..39fddf7
--- /dev/null
@@ -0,0 +1,516 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  MyAlloc.c\r
+\r
+Abstract:\r
+\r
+  File for memory allocation tracking functions.\r
+\r
+--*/\r
+\r
+#include "MyAlloc.h"\r
+\r
+#if USE_MYALLOC\r
+//\r
+// Get back to original alloc/free calls.\r
+//\r
+#undef malloc\r
+#undef calloc\r
+#undef realloc\r
+#undef free\r
+//\r
+// Start of allocation list.\r
+//\r
+static MY_ALLOC_STRUCT  *MyAllocData = NULL;\r
+\r
+//\r
+//\r
+//\r
+static UINT32           MyAllocHeadMagik  = MYALLOC_HEAD_MAGIK;\r
+static UINT32           MyAllocTailMagik  = MYALLOC_TAIL_MAGIK;\r
+\r
+//\r
+// ////////////////////////////////////////////////////////////////////////////\r
+//\r
+//\r
+VOID\r
+MyCheck (\r
+  BOOLEAN      Final,\r
+  UINT8        File[],\r
+  UINTN        Line\r
+  )\r
+// *++\r
+// Description:\r
+//\r
+//  Check for corruptions in the allocated memory chain.  If a corruption\r
+//  is detection program operation stops w/ an exit(1) call.\r
+//\r
+// Parameters:\r
+//\r
+//  Final := When FALSE, MyCheck() returns if the allocated memory chain\r
+//           has not been corrupted.  When TRUE, MyCheck() returns if there\r
+//           are no un-freed allocations.  If there are un-freed allocations,\r
+//           they are displayed and exit(1) is called.\r
+//\r
+//\r
+//  File := Set to __FILE__ by macro expansion.\r
+//\r
+//  Line := Set to __LINE__ by macro expansion.\r
+//\r
+// Returns:\r
+//\r
+//  n/a\r
+//\r
+// --*/\r
+//\r
+{\r
+  MY_ALLOC_STRUCT *Tmp;\r
+\r
+  //\r
+  // Check parameters.\r
+  //\r
+  if (File == NULL || Line == 0) {\r
+    printf (\r
+      "\nMyCheck(Final=%u, File=%xh, Line=%u)"\r
+      "Invalid parameter(s).\n",\r
+      Final,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+\r
+  if (strlen (File) == 0) {\r
+    printf (\r
+      "\nMyCheck(Final=%u, File=%s, Line=%u)"\r
+      "Invalid parameter.\n",\r
+      Final,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+  //\r
+  // Check structure contents.\r
+  //\r
+  for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {\r
+    if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) ||\r
+        memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) {\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // If Tmp is not NULL, the structure is corrupt.\r
+  //\r
+  if (Tmp != NULL) {\r
+    printf (\r
+      "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!"\r
+      "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",\r
+      Final,\r
+      File,\r
+      Line,\r
+      Tmp->File,\r
+      Tmp->Line,\r
+      Tmp->Size,\r
+      *(UINT32 *) (Tmp->Buffer),\r
+      *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+  //\r
+  // If Final is TRUE, display the state of the structure chain.\r
+  //\r
+  if (Final) {\r
+    if (MyAllocData != NULL) {\r
+      printf (\r
+        "\nMyCheck(Final=%u, File=%s, Line=%u)"\r
+        "\nSome allocated items have not been freed.\n",\r
+        Final,\r
+        File,\r
+        Line\r
+        );\r
+\r
+      for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {\r
+        printf (\r
+          "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",\r
+          Tmp->File,\r
+          Tmp->Line,\r
+          Tmp->Size,\r
+          *(UINT32 *) (Tmp->Buffer),\r
+          *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])\r
+          );\r
+      }\r
+    }\r
+  }\r
+}\r
+//\r
+// ////////////////////////////////////////////////////////////////////////////\r
+//\r
+//\r
+VOID *\r
+MyAlloc (\r
+  UINTN      Size,\r
+  UINT8 File[],\r
+  UINTN      Line\r
+  )\r
+// *++\r
+// Description:\r
+//\r
+//  Allocate a new link in the allocation chain along with enough storage\r
+//  for the File[] string, requested Size and alignment overhead.  If\r
+//  memory cannot be allocated or the allocation chain has been corrupted,\r
+//  exit(1) will be called.\r
+//\r
+// Parameters:\r
+//\r
+//  Size := Number of bytes (UINT8) requested by the called.\r
+//          Size cannot be zero.\r
+//\r
+//  File := Set to __FILE__ by macro expansion.\r
+//\r
+//  Line := Set to __LINE__ by macro expansion.\r
+//\r
+// Returns:\r
+//\r
+//  Pointer to the caller's buffer.\r
+//\r
+// --*/\r
+//\r
+{\r
+  MY_ALLOC_STRUCT *Tmp;\r
+  UINTN           Len;\r
+\r
+  //\r
+  // Check for invalid parameters.\r
+  //\r
+  if (Size == 0 || File == NULL || Line == 0) {\r
+    printf (\r
+      "\nMyAlloc(Size=%u, File=%xh, Line=%u)"\r
+      "\nInvalid parameter(s).\n",\r
+      Size,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+\r
+  Len = strlen (File);\r
+  if (Len == 0) {\r
+    printf (\r
+      "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
+      "\nInvalid parameter.\n",\r
+      Size,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+  //\r
+  // Check the allocation list for corruption.\r
+  //\r
+  MyCheck (0, __FILE__, __LINE__);\r
+\r
+  //\r
+  // Allocate a new entry.\r
+  //\r
+  Tmp = calloc (\r
+          1,\r
+          sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik)\r
+          );\r
+\r
+  if (Tmp == NULL) {\r
+    printf (\r
+      "\nMyAlloc(Size=%u, File=%s, Line=%u)"\r
+      "\nOut of memory.\n",\r
+      Size,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+  //\r
+  // Fill in the new entry.\r
+  //\r
+  Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT);\r
+  strcpy (Tmp->File, File);\r
+  Tmp->Line   = Line;\r
+  Tmp->Size   = Size;\r
+  Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7);\r
+\r
+  memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik);\r
+\r
+  memcpy (\r
+    &Tmp->Buffer[Size + sizeof (UINT32)],\r
+    &MyAllocTailMagik,\r
+    sizeof MyAllocTailMagik\r
+    );\r
+\r
+  Tmp->Next   = MyAllocData;\r
+  Tmp->Cksum  = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer);\r
+\r
+  MyAllocData = Tmp;\r
+\r
+  return Tmp->Buffer + sizeof (UINT32);\r
+}\r
+//\r
+// ////////////////////////////////////////////////////////////////////////////\r
+//\r
+//\r
+VOID *\r
+MyRealloc (\r
+  VOID       *Ptr,\r
+  UINTN      Size,\r
+  UINT8 File[],\r
+  UINTN      Line\r
+  )\r
+// *++\r
+// Description:\r
+//\r
+//  This does a MyAlloc(), memcpy() and MyFree().  There is no optimization\r
+//  for shrinking or expanding buffers.  An invalid parameter will cause\r
+//  MyRealloc() to fail with a call to exit(1).\r
+//\r
+// Parameters:\r
+//\r
+//  Ptr := Pointer to the caller's buffer to be re-allocated.\r
+//\r
+//  Size := Size of new buffer.  Size cannot be zero.\r
+//\r
+//  File := Set to __FILE__ by macro expansion.\r
+//\r
+//  Line := Set to __LINE__ by macro expansion.\r
+//\r
+// Returns:\r
+//\r
+//  Pointer to new caller's buffer.\r
+//\r
+// --*/\r
+//\r
+{\r
+  MY_ALLOC_STRUCT *Tmp;\r
+  VOID            *Buffer;\r
+\r
+  //\r
+  // Check for invalid parameter(s).\r
+  //\r
+  if (Size == 0 || File == NULL || Line == 0) {\r
+    printf (\r
+      "\nMyRealloc(Ptr=%xh, Size=%u, File=%xh, Line=%u)"\r
+      "\nInvalid parameter(s).\n",\r
+      Ptr,\r
+      Size,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+\r
+  if (strlen (File) == 0) {\r
+    printf (\r
+      "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)"\r
+      "\nInvalid parameter.\n",\r
+      Ptr,\r
+      Size,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+  //\r
+  // Find existing buffer in allocation list.\r
+  //\r
+  if (Ptr == NULL) {\r
+    Tmp = NULL;\r
+  } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {\r
+    Tmp = MyAllocData;\r
+  } else {\r
+    for (Tmp = MyAllocData;; Tmp = Tmp->Next) {\r
+      if (Tmp->Next == NULL) {\r
+        printf (\r
+          "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)"\r
+          "\nCould not find buffer.\n",\r
+          Ptr,\r
+          Size,\r
+          File,\r
+          Line\r
+          );\r
+\r
+        exit (1);\r
+      }\r
+\r
+      Tmp = Tmp->Next;\r
+    }\r
+  }\r
+  //\r
+  // Allocate new buffer, copy old data, free old buffer.\r
+  //\r
+  Buffer = MyAlloc (Size, File, Line);\r
+\r
+  if (Buffer != NULL && Tmp != NULL) {\r
+    memcpy (\r
+      Buffer,\r
+      &Tmp->Buffer[sizeof (UINT32)],\r
+      ((Size <= Tmp->Size) ? Size : Tmp->Size)\r
+      );\r
+\r
+    MyFree (Ptr, __FILE__, __LINE__);\r
+  }\r
+\r
+  return Buffer;\r
+}\r
+//\r
+// ////////////////////////////////////////////////////////////////////////////\r
+//\r
+//\r
+VOID\r
+MyFree (\r
+  VOID       *Ptr,\r
+  UINT8 File[],\r
+  UINTN      Line\r
+  )\r
+// *++\r
+// Description:\r
+//\r
+//  Release a previously allocated buffer.  Invalid parameters will cause\r
+//  MyFree() to fail with an exit(1) call.\r
+//\r
+// Parameters:\r
+//\r
+//  Ptr := Pointer to the caller's buffer to be freed.\r
+//         A NULL pointer will be ignored.\r
+//\r
+//  File := Set to __FILE__ by macro expansion.\r
+//\r
+//  Line := Set to __LINE__ by macro expansion.\r
+//\r
+// Returns:\r
+//\r
+//  n/a\r
+//\r
+// --*/\r
+//\r
+{\r
+  MY_ALLOC_STRUCT *Tmp;\r
+  MY_ALLOC_STRUCT *Tmp2;\r
+\r
+  //\r
+  // Check for invalid parameter(s).\r
+  //\r
+  if (File == NULL || Line == 0) {\r
+    printf (\r
+      "\nMyFree(Ptr=%xh, File=%xh, Line=%u)"\r
+      "\nInvalid parameter(s).\n",\r
+      Ptr,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+\r
+  if (strlen (File) == 0) {\r
+    printf (\r
+      "\nMyFree(Ptr=%xh, File=%s, Line=%u)"\r
+      "\nInvalid parameter.\n",\r
+      Ptr,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+  //\r
+  // Freeing NULL is always valid.\r
+  //\r
+  if (Ptr == NULL) {\r
+    return ;\r
+  }\r
+  //\r
+  // Fail if nothing is allocated.\r
+  //\r
+  if (MyAllocData == NULL) {\r
+    printf (\r
+      "\nMyFree(Ptr=%xh, File=%s, Line=%u)"\r
+      "\nCalled before memory allocated.\n",\r
+      Ptr,\r
+      File,\r
+      Line\r
+      );\r
+\r
+    exit (1);\r
+  }\r
+  //\r
+  // Check for corrupted allocation list.\r
+  //\r
+  MyCheck (0, __FILE__, __LINE__);\r
+\r
+  //\r
+  // Need special check for first item in list.\r
+  //\r
+  if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) {\r
+    //\r
+    // Unlink first item in list.\r
+    //\r
+    Tmp         = MyAllocData;\r
+    MyAllocData = MyAllocData->Next;\r
+  } else {\r
+    //\r
+    // Walk list looking for matching item.\r
+    //\r
+    for (Tmp = MyAllocData;; Tmp = Tmp->Next) {\r
+      //\r
+      // Fail if end of list is reached.\r
+      //\r
+      if (Tmp->Next == NULL) {\r
+        printf (\r
+          "\nMyFree(Ptr=%xh, File=%s, Line=%u)\n"\r
+          "\nNot found.\n",\r
+          Ptr,\r
+          File,\r
+          Line\r
+          );\r
+\r
+        exit (1);\r
+      }\r
+      //\r
+      // Leave loop when match is found.\r
+      //\r
+      if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) {\r
+        break;\r
+      }\r
+    }\r
+    //\r
+    // Unlink item from list.\r
+    //\r
+    Tmp2      = Tmp->Next;\r
+    Tmp->Next = Tmp->Next->Next;\r
+    Tmp       = Tmp2;\r
+  }\r
+  //\r
+  // Release item.\r
+  //\r
+  free (Tmp);\r
+}\r
+\r
+#endif /* USE_MYALLOC */\r
+\r
+/* eof - MyAlloc.c */\r
diff --git a/Source/C/Common/MyAlloc.h b/Source/C/Common/MyAlloc.h
new file mode 100644 (file)
index 0000000..9697012
--- /dev/null
@@ -0,0 +1,222 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  MyAlloc.h\r
+\r
+Abstract:\r
+\r
+  Header file for memory allocation tracking functions.\r
+\r
+--*/\r
+\r
+#ifndef _MYALLOC_H_\r
+#define _MYALLOC_H_\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include <Common/BaseTypes.h>\r
+\r
+//\r
+// Default operation is to use the memory allocation tracking functions.\r
+// To over-ride add "#define USE_MYALLOC 0" to your program header and/or\r
+// source files as needed.  Or, just do not include this header file in\r
+// your project.\r
+//\r
+#ifndef USE_MYALLOC\r
+#define USE_MYALLOC 1\r
+#endif\r
+\r
+#if USE_MYALLOC\r
+//\r
+// Replace C library allocation routines with MyAlloc routines.\r
+//\r
+#define malloc(size)        MyAlloc ((size), __FILE__, __LINE__)\r
+#define calloc(count, size) MyAlloc ((count) * (size), __FILE__, __LINE__)\r
+#define realloc(ptr, size)  MyRealloc ((ptr), (size), __FILE__, __LINE__)\r
+#define free(ptr)           MyFree ((ptr), __FILE__, __LINE__)\r
+#define alloc_check(final)  MyCheck ((final), __FILE__, __LINE__)\r
+\r
+//\r
+// Structure for checking/tracking memory allocations.\r
+//\r
+typedef struct MyAllocStruct {\r
+  UINTN                 Cksum;\r
+  struct MyAllocStruct  *Next;\r
+  UINTN                 Line;\r
+  UINTN                 Size;\r
+  UINT8                 *File;\r
+  UINT8                 *Buffer;\r
+} MY_ALLOC_STRUCT;\r
+//\r
+// Cksum := (UINTN)This + (UINTN)Next + Line + Size + (UINTN)File +\r
+//          (UINTN)Buffer;\r
+//\r
+// Next := Pointer to next allocation structure in the list.\r
+//\r
+// Line := __LINE__\r
+//\r
+// Size := Size of allocation request.\r
+//\r
+// File := Pointer to __FILE__ string stored immediately following\r
+//         MY_ALLOC_STRUCT in memory.\r
+//\r
+// Buffer := Pointer to UINT32 aligned storage immediately following\r
+//           the NULL terminated __FILE__ string.  This is UINT32\r
+//           aligned because the underflow signature is 32-bits and\r
+//           this will place the first caller address on a 64-bit\r
+//           boundary.\r
+//\r
+//\r
+// Signatures used to check for buffer overflow/underflow conditions.\r
+//\r
+#define MYALLOC_HEAD_MAGIK  0xBADFACED\r
+#define MYALLOC_TAIL_MAGIK  0xDEADBEEF\r
+\r
+VOID\r
+MyCheck (\r
+  BOOLEAN      Final,\r
+  UINT8        File[],\r
+  UINTN        Line\r
+  )\r
+;\r
+//\r
+// *++\r
+// Description:\r
+//\r
+//  Check for corruptions in the allocated memory chain.  If a corruption\r
+//  is detection program operation stops w/ an exit(1) call.\r
+//\r
+// Parameters:\r
+//\r
+//  Final := When FALSE, MyCheck() returns if the allocated memory chain\r
+//           has not been corrupted.  When TRUE, MyCheck() returns if there\r
+//           are no un-freed allocations.  If there are un-freed allocations,\r
+//           they are displayed and exit(1) is called.\r
+//\r
+//\r
+//  File := Set to __FILE__ by macro expansion.\r
+//\r
+//  Line := Set to __LINE__ by macro expansion.\r
+//\r
+// Returns:\r
+//\r
+//  n/a\r
+//\r
+// --*/\r
+//\r
+VOID  *\r
+MyAlloc (\r
+  UINTN      Size,\r
+  UINT8      File[],\r
+  UINTN      Line\r
+  )\r
+;\r
+//\r
+// *++\r
+// Description:\r
+//\r
+//  Allocate a new link in the allocation chain along with enough storage\r
+//  for the File[] string, requested Size and alignment overhead.  If\r
+//  memory cannot be allocated or the allocation chain has been corrupted,\r
+//  exit(1) will be called.\r
+//\r
+// Parameters:\r
+//\r
+//  Size := Number of bytes (UINT8) requested by the called.\r
+//          Size cannot be zero.\r
+//\r
+//  File := Set to __FILE__ by macro expansion.\r
+//\r
+//  Line := Set to __LINE__ by macro expansion.\r
+//\r
+// Returns:\r
+//\r
+//  Pointer to the caller's buffer.\r
+//\r
+// --*/\r
+//\r
+VOID  *\r
+MyRealloc (\r
+  VOID       *Ptr,\r
+  UINTN      Size,\r
+  UINT8      File[],\r
+  UINTN      Line\r
+  )\r
+;\r
+//\r
+// *++\r
+// Description:\r
+//\r
+//  This does a MyAlloc(), memcpy() and MyFree().  There is no optimization\r
+//  for shrinking or expanding buffers.  An invalid parameter will cause\r
+//  MyRealloc() to fail with a call to exit(1).\r
+//\r
+// Parameters:\r
+//\r
+//  Ptr := Pointer to the caller's buffer to be re-allocated.\r
+//         Ptr cannot be NULL.\r
+//\r
+//  Size := Size of new buffer.  Size cannot be zero.\r
+//\r
+//  File := Set to __FILE__ by macro expansion.\r
+//\r
+//  Line := Set to __LINE__ by macro expansion.\r
+//\r
+// Returns:\r
+//\r
+//  Pointer to new caller's buffer.\r
+//\r
+// --*/\r
+//\r
+VOID\r
+MyFree (\r
+  VOID       *Ptr,\r
+  UINT8      File[],\r
+  UINTN      Line\r
+  )\r
+;\r
+//\r
+// *++\r
+// Description:\r
+//\r
+//  Release a previously allocated buffer.  Invalid parameters will cause\r
+//  MyFree() to fail with an exit(1) call.\r
+//\r
+// Parameters:\r
+//\r
+//  Ptr := Pointer to the caller's buffer to be freed.\r
+//         A NULL pointer will be ignored.\r
+//\r
+//  File := Set to __FILE__ by macro expansion.\r
+//\r
+//  Line := Set to __LINE__ by macro expansion.\r
+//\r
+// Returns:\r
+//\r
+//  n/a\r
+//\r
+// --*/\r
+//\r
+#else /* USE_MYALLOC */\r
+\r
+//\r
+// Nothing to do when USE_MYALLOC is zero.\r
+//\r
+#define alloc_check(final)\r
+\r
+#endif /* USE_MYALLOC */\r
+#endif /* _MYALLOC_H_ */\r
+\r
+/* eof - MyAlloc.h */\r
diff --git a/Source/C/Common/ParseInf.c b/Source/C/Common/ParseInf.c
new file mode 100644 (file)
index 0000000..6f5900e
--- /dev/null
@@ -0,0 +1,638 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  ParseInf.c\r
+\r
+Abstract:\r
+\r
+  This contains some useful functions for parsing INF files.\r
+\r
+--*/\r
+\r
+#include <assert.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <stdlib.h>\r
+#include "ParseInf.h"\r
+\r
+#ifndef _MAX_PATH\r
+#define _MAX_PATH 500\r
+#endif\r
+\r
+CHAR8 *\r
+ReadLine (\r
+  IN MEMORY_FILE    *InputFile,\r
+  IN OUT CHAR8      *InputBuffer,\r
+  IN UINTN          MaxLength\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function reads a line, stripping any comments.\r
+  The function reads a string from the input stream argument and stores it in \r
+  the input string. ReadLine reads characters from the current file position \r
+  to and including the first newline character, to the end of the stream, or \r
+  until the number of characters read is equal to MaxLength - 1, whichever \r
+  comes first.  The newline character, if read, is replaced with a \0. \r
+\r
+Arguments:\r
+\r
+  InputFile     Memory file image.\r
+  InputBuffer   Buffer to read into, must be _MAX_PATH size.\r
+  MaxLength     The maximum size of the input buffer.\r
+\r
+Returns:\r
+\r
+  NULL if error or EOF\r
+  InputBuffer otherwise\r
+\r
+--*/\r
+{\r
+  CHAR8 *CharPtr;\r
+  CHAR8 *EndOfLine;\r
+  UINTN CharsToCopy;\r
+\r
+  //\r
+  // Verify input parameters are not null\r
+  //\r
+  assert (InputBuffer);\r
+  assert (InputFile->FileImage);\r
+  assert (InputFile->Eof);\r
+  assert (InputFile->CurrentFilePointer);\r
+\r
+  //\r
+  // Check for end of file condition\r
+  //\r
+  if (InputFile->CurrentFilePointer >= InputFile->Eof) {\r
+    return NULL;\r
+  }\r
+  //\r
+  // Find the next newline char\r
+  //\r
+  EndOfLine = strchr (InputFile->CurrentFilePointer, '\n');\r
+\r
+  //\r
+  // Determine the number of characters to copy.\r
+  //\r
+  if (EndOfLine == 0) {\r
+    //\r
+    // If no newline found, copy to the end of the file.\r
+    //\r
+    CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;\r
+  } else if (EndOfLine >= InputFile->Eof) {\r
+    //\r
+    // If the newline found was beyond the end of file, copy to the eof.\r
+    //\r
+    CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer;\r
+  } else {\r
+    //\r
+    // Newline found in the file.\r
+    //\r
+    CharsToCopy = EndOfLine - InputFile->CurrentFilePointer;\r
+  }\r
+  //\r
+  // If the end of line is too big for the current buffer, set it to the max\r
+  // size of the buffer (leaving room for the \0.\r
+  //\r
+  if (CharsToCopy > MaxLength - 1) {\r
+    CharsToCopy = MaxLength - 1;\r
+  }\r
+  //\r
+  // Copy the line.\r
+  //\r
+  memcpy (InputBuffer, InputFile->CurrentFilePointer, CharsToCopy);\r
+\r
+  //\r
+  // Add the null termination over the 0x0D\r
+  //\r
+  if (InputBuffer[CharsToCopy - 1] == '\r') {\r
+\r
+    InputBuffer[CharsToCopy - 1] = '\0';\r
+\r
+  } else {\r
+\r
+    InputBuffer[CharsToCopy] = '\0';\r
+\r
+  }\r
+\r
+  //\r
+  // Increment the current file pointer (include the 0x0A)\r
+  //\r
+  InputFile->CurrentFilePointer += CharsToCopy + 1;\r
+\r
+  //\r
+  // Strip any comments\r
+  //\r
+  CharPtr = strstr (InputBuffer, "//");\r
+  if (CharPtr != 0) {\r
+    CharPtr[0] = 0;\r
+  }\r
+  //\r
+  // Return the string\r
+  //\r
+  return InputBuffer;\r
+}\r
+\r
+BOOLEAN\r
+FindSection (\r
+  IN MEMORY_FILE    *InputFile,\r
+  IN CHAR8          *Section\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function parses a file from the beginning to find a section.\r
+  The section string may be anywhere within a line.\r
+\r
+Arguments:\r
+\r
+  InputFile     Memory file image.\r
+  Section       Section to search for\r
+\r
+Returns:\r
+\r
+  FALSE if error or EOF\r
+  TRUE if section found\r
+\r
+--*/\r
+{\r
+  CHAR8 InputBuffer[_MAX_PATH];\r
+  CHAR8 *CurrentToken;\r
+\r
+  //\r
+  // Verify input is not NULL\r
+  //\r
+  assert (InputFile->FileImage);\r
+  assert (InputFile->Eof);\r
+  assert (InputFile->CurrentFilePointer);\r
+  assert (Section);\r
+\r
+  //\r
+  // Rewind to beginning of file\r
+  //\r
+  InputFile->CurrentFilePointer = InputFile->FileImage;\r
+\r
+  //\r
+  // Read lines until the section is found\r
+  //\r
+  while (InputFile->CurrentFilePointer < InputFile->Eof) {\r
+    //\r
+    // Read a line\r
+    //\r
+    ReadLine (InputFile, InputBuffer, _MAX_PATH);\r
+\r
+    //\r
+    // Check if the section is found\r
+    //\r
+    CurrentToken = strstr (InputBuffer, Section);\r
+    if (CurrentToken != NULL) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+FindToken (\r
+  IN MEMORY_FILE    *InputFile,\r
+  IN CHAR8          *Section,\r
+  IN CHAR8          *Token,\r
+  IN UINTN          Instance,\r
+  OUT CHAR8         *Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Finds a token value given the section and token to search for.\r
+\r
+Arguments:\r
+\r
+  InputFile Memory file image.\r
+  Section   The section to search for, a string within [].\r
+  Token     The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.\r
+  Instance  The instance of the token to search for.  Zero is the first instance.\r
+  Value     The string that holds the value following the =.  Must be _MAX_PATH in size.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             Value found.\r
+  EFI_ABORTED             Format error detected in INF file.\r
+  EFI_INVALID_PARAMETER   Input argument was null.\r
+  EFI_LOAD_ERROR          Error reading from the file.\r
+  EFI_NOT_FOUND           Section/Token/Value not found.\r
+\r
+--*/\r
+{\r
+  CHAR8   InputBuffer[_MAX_PATH];\r
+  CHAR8   *CurrentToken;\r
+  BOOLEAN ParseError;\r
+  BOOLEAN ReadError;\r
+  UINTN   Occurrance;\r
+\r
+  //\r
+  // Check input parameters\r
+  //\r
+  if (InputFile->FileImage == NULL ||\r
+      InputFile->Eof == NULL ||\r
+      InputFile->CurrentFilePointer == NULL ||\r
+      Section == NULL ||\r
+      strlen (Section) == 0 ||\r
+      Token == NULL ||\r
+      strlen (Token) == 0 ||\r
+      Value == NULL\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Initialize error codes\r
+  //\r
+  ParseError  = FALSE;\r
+  ReadError   = FALSE;\r
+\r
+  //\r
+  // Initialize our instance counter for the search token\r
+  //\r
+  Occurrance = 0;\r
+\r
+  if (FindSection (InputFile, Section)) {\r
+    //\r
+    // Found the desired section, find and read the desired token\r
+    //\r
+    do {\r
+      //\r
+      // Read a line from the file\r
+      //\r
+      if (ReadLine (InputFile, InputBuffer, _MAX_PATH) == NULL) {\r
+        //\r
+        // Error reading from input file\r
+        //\r
+        ReadError = TRUE;\r
+        break;\r
+      }\r
+      //\r
+      // Get the first non-whitespace string\r
+      //\r
+      CurrentToken = strtok (InputBuffer, " \t\n");\r
+      if (CurrentToken == NULL) {\r
+        //\r
+        // Whitespace line found (or comment) so continue\r
+        //\r
+        CurrentToken = InputBuffer;\r
+        continue;\r
+      }\r
+      //\r
+      // Make sure we have not reached the end of the current section\r
+      //\r
+      if (CurrentToken[0] == '[') {\r
+        break;\r
+      }\r
+      //\r
+      // Compare the current token with the desired token\r
+      //\r
+      if (strcmp (CurrentToken, Token) == 0) {\r
+        //\r
+        // Found it\r
+        //\r
+        //\r
+        // Check if it is the correct instance\r
+        //\r
+        if (Instance == Occurrance) {\r
+          //\r
+          // Copy the contents following the =\r
+          //\r
+          CurrentToken = strtok (NULL, "= \t\n");\r
+          if (CurrentToken == NULL) {\r
+            //\r
+            // Nothing found, parsing error\r
+            //\r
+            ParseError = TRUE;\r
+          } else {\r
+            //\r
+            // Copy the current token to the output value\r
+            //\r
+            strcpy (Value, CurrentToken);\r
+            return EFI_SUCCESS;\r
+          }\r
+        } else {\r
+          //\r
+          // Increment the occurrance found\r
+          //\r
+          Occurrance++;\r
+        }\r
+      }\r
+    } while (\r
+      !ParseError &&\r
+      !ReadError &&\r
+      InputFile->CurrentFilePointer < InputFile->Eof &&\r
+      CurrentToken[0] != '[' &&\r
+      Occurrance <= Instance\r
+    );\r
+  }\r
+  //\r
+  // Distinguish between read errors and INF file format errors.\r
+  //\r
+  if (ReadError) {\r
+    return EFI_LOAD_ERROR;\r
+  }\r
+\r
+  if (ParseError) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+EFI_STATUS\r
+StringToGuid (\r
+  IN CHAR8      *AsciiGuidBuffer,\r
+  OUT EFI_GUID  *GuidBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description: \r
+\r
+  Converts a string to an EFI_GUID.  The string must be in the \r
+  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.\r
+\r
+Arguments:  \r
+\r
+  AsciiGuidBuffer - pointer to ascii string\r
+  GuidBuffer      - pointer to destination Guid\r
+\r
+Returns:  \r
+\r
+  EFI_ABORTED             Could not convert the string\r
+  EFI_SUCCESS             The string was successfully converted\r
+  EFI_INVALID_PARAMETER   Input parameter is invalid.\r
+\r
+--*/\r
+{\r
+  INT32 Index;\r
+  UINTN Data1;\r
+  UINTN Data2;\r
+  UINTN Data3;\r
+  UINTN Data4[8];\r
+\r
+  if (AsciiGuidBuffer == NULL || GuidBuffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Scan the guid string into the buffer\r
+  //\r
+  Index = sscanf (\r
+            AsciiGuidBuffer,\r
+            "%08x-%04x-%04x-%02x%02x-%02hx%02hx%02hx%02hx%02hx%02hx",\r
+            &Data1,\r
+            &Data2,\r
+            &Data3,\r
+            &Data4[0],\r
+            &Data4[1],\r
+            &Data4[2],\r
+            &Data4[3],\r
+            &Data4[4],\r
+            &Data4[5],\r
+            &Data4[6],\r
+            &Data4[7]\r
+            );\r
+\r
+  //\r
+  // Verify the correct number of items were scanned.\r
+  //\r
+  if (Index != 11) {\r
+    printf ("ERROR: Malformed GUID \"%s\".\n\n", AsciiGuidBuffer);\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Copy the data into our GUID.\r
+  //\r
+  GuidBuffer->Data1     = (UINT32) Data1;\r
+  GuidBuffer->Data2     = (UINT16) Data2;\r
+  GuidBuffer->Data3     = (UINT16) Data3;\r
+  GuidBuffer->Data4[0]  = (UINT8) Data4[0];\r
+  GuidBuffer->Data4[1]  = (UINT8) Data4[1];\r
+  GuidBuffer->Data4[2]  = (UINT8) Data4[2];\r
+  GuidBuffer->Data4[3]  = (UINT8) Data4[3];\r
+  GuidBuffer->Data4[4]  = (UINT8) Data4[4];\r
+  GuidBuffer->Data4[5]  = (UINT8) Data4[5];\r
+  GuidBuffer->Data4[6]  = (UINT8) Data4[6];\r
+  GuidBuffer->Data4[7]  = (UINT8) Data4[7];\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+AsciiStringToUint64 (\r
+  IN CONST CHAR8  *AsciiString,\r
+  IN BOOLEAN      IsHex,\r
+  OUT UINT64      *ReturnValue\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Converts a null terminated ascii string that represents a number into a \r
+  UINT64 value.  A hex number may be preceeded by a 0x, but may not be \r
+  succeeded by an h.  A number without 0x or 0X is considered to be base 10 \r
+  unless the IsHex input is true.\r
+\r
+Arguments:\r
+\r
+  AsciiString   The string to convert.\r
+  IsHex         Force the string to be treated as a hex number.\r
+  ReturnValue   The return value.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   Number successfully converted.\r
+  EFI_ABORTED   Invalid character encountered.\r
+\r
+--*/\r
+{\r
+  UINT8   Index;\r
+  UINT64  HexNumber;\r
+  CHAR8   CurrentChar;\r
+\r
+  //\r
+  // Initialize the result\r
+  //\r
+  HexNumber = 0;\r
+\r
+  //\r
+  // Add each character to the result\r
+  //\r
+  if (IsHex || (AsciiString[0] == '0' && (AsciiString[1] == 'x' || AsciiString[1] == 'X'))) {\r
+    //\r
+    // Verify string is a hex number\r
+    //\r
+    for (Index = 2; Index < strlen (AsciiString); Index++) {\r
+      if (isxdigit (AsciiString[Index]) == 0) {\r
+        return EFI_ABORTED;\r
+      }\r
+    }\r
+    //\r
+    // Convert the hex string.\r
+    //\r
+    for (Index = 2; AsciiString[Index] != '\0'; Index++) {\r
+      CurrentChar = AsciiString[Index];\r
+      HexNumber *= 16;\r
+      if (CurrentChar >= '0' && CurrentChar <= '9') {\r
+        HexNumber += CurrentChar - '0';\r
+      } else if (CurrentChar >= 'a' && CurrentChar <= 'f') {\r
+        HexNumber += CurrentChar - 'a' + 10;\r
+      } else if (CurrentChar >= 'A' && CurrentChar <= 'F') {\r
+        HexNumber += CurrentChar - 'A' + 10;\r
+      } else {\r
+        //\r
+        // Unrecognized character\r
+        //\r
+        return EFI_ABORTED;\r
+      }\r
+    }\r
+\r
+    *ReturnValue = HexNumber;\r
+  } else {\r
+    //\r
+    // Verify string is a number\r
+    //\r
+    for (Index = 0; Index < strlen (AsciiString); Index++) {\r
+      if (isdigit (AsciiString[Index]) == 0) {\r
+        return EFI_ABORTED;\r
+      }\r
+    }\r
+\r
+    *ReturnValue = atol (AsciiString);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+};\r
+\r
+CHAR8 *\r
+ReadLineInStream (\r
+  IN FILE       *InputFile,\r
+  IN OUT CHAR8  *InputBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function reads a line, stripping any comments.\r
+  // BUGBUG:  This is obsolete once genmake goes away...\r
+\r
+Arguments:\r
+\r
+  InputFile     Stream pointer.\r
+  InputBuffer   Buffer to read into, must be _MAX_PATH size.\r
+\r
+Returns:\r
+\r
+  NULL if error or EOF\r
+  InputBuffer otherwise\r
+\r
+--*/\r
+{\r
+  CHAR8 *CharPtr;\r
+\r
+  //\r
+  // Verify input parameters are not null\r
+  //\r
+  assert (InputFile);\r
+  assert (InputBuffer);\r
+\r
+  //\r
+  // Read a line\r
+  //\r
+  if (fgets (InputBuffer, _MAX_PATH, InputFile) == NULL) {\r
+    return NULL;\r
+  }\r
+  //\r
+  // Strip any comments\r
+  //\r
+  CharPtr = strstr (InputBuffer, "//");\r
+  if (CharPtr != 0) {\r
+    CharPtr[0] = 0;\r
+  }\r
+\r
+  CharPtr = strstr (InputBuffer, "#");\r
+  if (CharPtr != 0) {\r
+    CharPtr[0] = 0;\r
+  }\r
+  //\r
+  // Return the string\r
+  //\r
+  return InputBuffer;\r
+}\r
+\r
+BOOLEAN\r
+FindSectionInStream (\r
+  IN FILE       *InputFile,\r
+  IN CHAR8      *Section\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function parses a stream file from the beginning to find a section.\r
+  The section string may be anywhere within a line.\r
+  // BUGBUG:  This is obsolete once genmake goes away...\r
+\r
+Arguments:\r
+\r
+  InputFile     Stream pointer.\r
+  Section       Section to search for\r
+\r
+Returns:\r
+\r
+  FALSE if error or EOF\r
+  TRUE if section found\r
+\r
+--*/\r
+{\r
+  CHAR8 InputBuffer[_MAX_PATH];\r
+  CHAR8 *CurrentToken;\r
+\r
+  //\r
+  // Verify input is not NULL\r
+  //\r
+  assert (InputFile);\r
+  assert (Section);\r
+\r
+  //\r
+  // Rewind to beginning of file\r
+  //\r
+  if (fseek (InputFile, 0, SEEK_SET) != 0) {\r
+    return FALSE;\r
+  }\r
+  //\r
+  // Read lines until the section is found\r
+  //\r
+  while (feof (InputFile) == 0) {\r
+    //\r
+    // Read a line\r
+    //\r
+    ReadLineInStream (InputFile, InputBuffer);\r
+\r
+    //\r
+    // Check if the section is found\r
+    //\r
+    CurrentToken = strstr (InputBuffer, Section);\r
+    if (CurrentToken != NULL) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
diff --git a/Source/C/Common/ParseInf.h b/Source/C/Common/ParseInf.h
new file mode 100644 (file)
index 0000000..ff98635
--- /dev/null
@@ -0,0 +1,234 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  ParseInf.h\r
+\r
+Abstract:\r
+\r
+  Header file for helper functions useful for parsing INF files.\r
+\r
+--*/\r
+\r
+#ifndef _EFI_PARSE_INF_H\r
+#define _EFI_PARSE_INF_H\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+\r
+//\r
+// Common data structures\r
+//\r
+typedef struct {\r
+  CHAR8 *FileImage;\r
+  CHAR8 *Eof;\r
+  CHAR8 *CurrentFilePointer;\r
+} MEMORY_FILE;\r
+\r
+//\r
+// Functions declarations\r
+//\r
+CHAR8 *\r
+ReadLine (\r
+  IN MEMORY_FILE    *InputFile,\r
+  IN OUT CHAR8      *InputBuffer,\r
+  IN UINTN          MaxLength\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function reads a line, stripping any comments.\r
+  The function reads a string from the input stream argument and stores it in \r
+  the input string. ReadLine reads characters from the current file position \r
+  to and including the first newline character, to the end of the stream, or \r
+  until the number of characters read is equal to MaxLength - 1, whichever \r
+  comes first.  The newline character, if read, is replaced with a \0. \r
+\r
+Arguments:\r
+\r
+  InputFile     Memory file image.\r
+  InputBuffer   Buffer to read into, must be _MAX_PATH size.\r
+  MaxLength     The maximum size of the input buffer.\r
+\r
+Returns:\r
+\r
+  NULL if error or EOF\r
+  InputBuffer otherwise\r
+\r
+--*/\r
+BOOLEAN\r
+FindSection (\r
+  IN MEMORY_FILE    *InputFile,\r
+  IN CHAR8          *Section\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function parses a file from the beginning to find a section.\r
+  The section string may be anywhere within a line.\r
+\r
+Arguments:\r
+\r
+  InputFile     Memory file image.\r
+  Section       Section to search for\r
+\r
+Returns:\r
+\r
+  FALSE if error or EOF\r
+  TRUE if section found\r
+\r
+--*/\r
+EFI_STATUS\r
+FindToken (\r
+  IN MEMORY_FILE    *InputFile,\r
+  IN CHAR8          *Section,\r
+  IN CHAR8          *Token,\r
+  IN UINTN          Instance,\r
+  OUT CHAR8         *Value\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Finds a token value given the section and token to search for.\r
+\r
+Arguments:\r
+\r
+  InputFile Memory file image.\r
+  Section   The section to search for, a string within [].\r
+  Token     The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file.\r
+  Instance  The instance of the token to search for.  Zero is the first instance.\r
+  Value     The string that holds the value following the =.  Must be _MAX_PATH in size.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             Value found.\r
+  EFI_ABORTED             Format error detected in INF file.\r
+  EFI_INVALID_PARAMETER   Input argument was null.\r
+  EFI_LOAD_ERROR          Error reading from the file.\r
+  EFI_NOT_FOUND           Section/Token/Value not found.\r
+\r
+--*/\r
+EFI_STATUS\r
+StringToGuid (\r
+  IN CHAR8        *AsciiGuidBuffer,\r
+  OUT EFI_GUID    *GuidBuffer\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description: \r
+\r
+  Converts a string to an EFI_GUID.  The string must be in the \r
+  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format.\r
+\r
+Arguments:  \r
+\r
+  GuidBuffer      - pointer to destination Guid\r
+  AsciiGuidBuffer - pointer to ascii string\r
+\r
+Returns:  \r
+\r
+  EFI_ABORTED    Could not convert the string\r
+  EFI_SUCCESS    The string was successfully converted\r
+\r
+--*/\r
+EFI_STATUS\r
+AsciiStringToUint64 (\r
+  IN CONST CHAR8  *AsciiString,\r
+  IN BOOLEAN      IsHex,\r
+  OUT UINT64      *ReturnValue\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Converts a null terminated ascii string that represents a number into a \r
+  UINT64 value.  A hex number may be preceeded by a 0x, but may not be \r
+  succeeded by an h.  A number without 0x or 0X is considered to be base 10 \r
+  unless the IsHex input is true.\r
+\r
+Arguments:\r
+\r
+  AsciiString   The string to convert.\r
+  IsHex         Force the string to be treated as a hex number.\r
+  ReturnValue   The return value.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   Number successfully converted.\r
+  EFI_ABORTED   Invalid character encountered.\r
+\r
+--*/\r
+CHAR8 *\r
+ReadLineInStream (\r
+  IN FILE       *InputFile,\r
+  IN OUT CHAR8  *InputBuffer\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function reads a line, stripping any comments.\r
+\r
+Arguments:\r
+\r
+  InputFile     Stream pointer.\r
+  InputBuffer   Buffer to read into, must be _MAX_PATH size.\r
+\r
+Returns:\r
+\r
+  NULL if error or EOF\r
+  InputBuffer otherwise\r
+\r
+--*/\r
+BOOLEAN\r
+FindSectionInStream (\r
+  IN FILE       *InputFile,\r
+  IN CHAR8      *Section\r
+  )\r
+;\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function parses a stream file from the beginning to find a section.\r
+  The section string may be anywhere within a line.\r
+\r
+Arguments:\r
+\r
+  InputFile     Stream pointer.\r
+  Section       Section to search for\r
+\r
+Returns:\r
+\r
+  FALSE if error or EOF\r
+  TRUE if section found\r
+\r
+--*/\r
+#endif\r
diff --git a/Source/C/Common/SimpleFileParsing.c b/Source/C/Common/SimpleFileParsing.c
new file mode 100644 (file)
index 0000000..73b74cd
--- /dev/null
@@ -0,0 +1,1457 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  SimpleFileParsing.c  \r
+\r
+Abstract:\r
+\r
+  Generic but simple file parsing routines.\r
+\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <ctype.h>\r
+\r
+#include "EfiUtilityMsgs.h"\r
+#include "SimpleFileParsing.h"\r
+\r
+#ifndef MAX_PATH\r
+#define MAX_PATH  255\r
+#endif\r
+//\r
+// just in case we get in an endless loop.\r
+//\r
+#define MAX_NEST_DEPTH  20\r
+//\r
+// number of wchars\r
+//\r
+#define MAX_STRING_IDENTIFIER_NAME  100\r
+\r
+#define MAX_LINE_LEN                400\r
+\r
+#define T_CHAR_SPACE                ' '\r
+#define T_CHAR_NULL                 0\r
+#define T_CHAR_CR                   '\r'\r
+#define T_CHAR_TAB                  '\t'\r
+#define T_CHAR_LF                   '\n'\r
+#define T_CHAR_SLASH                '/'\r
+#define T_CHAR_BACKSLASH            '\\'\r
+#define T_CHAR_DOUBLE_QUOTE         '"'\r
+#define T_CHAR_LC_X                 'x'\r
+#define T_CHAR_0                    '0'\r
+#define T_CHAR_STAR                 '*'\r
+\r
+//\r
+// We keep a linked list of these for the source files we process\r
+//\r
+typedef struct _SOURCE_FILE {\r
+  FILE                *Fptr;\r
+  T_CHAR              *FileBuffer;\r
+  T_CHAR              *FileBufferPtr;\r
+  unsigned int        FileSize;\r
+  char                FileName[MAX_PATH];\r
+  unsigned int        LineNum;\r
+  BOOLEAN             EndOfFile;\r
+  BOOLEAN             SkipToHash;\r
+  struct _SOURCE_FILE *Previous;\r
+  struct _SOURCE_FILE *Next;\r
+  T_CHAR              ControlCharacter;\r
+} SOURCE_FILE;\r
+\r
+typedef struct {\r
+  T_CHAR  *FileBufferPtr;\r
+} FILE_POSITION;\r
+\r
+//\r
+// Keep all our module globals in this structure\r
+//\r
+static struct {\r
+  SOURCE_FILE SourceFile;\r
+  BOOLEAN     VerboseFile;\r
+  BOOLEAN     VerboseToken;\r
+} mGlobals;\r
+\r
+static\r
+unsigned int\r
+t_strcmp (\r
+  T_CHAR *Buffer,\r
+  T_CHAR *Str\r
+  );\r
+\r
+static\r
+unsigned int\r
+t_strncmp (\r
+  T_CHAR *Str1,\r
+  T_CHAR *Str2,\r
+  int    Len\r
+  );\r
+\r
+static\r
+unsigned int\r
+t_strlen (\r
+  T_CHAR *Str\r
+  );\r
+\r
+static\r
+void\r
+RewindFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+BOOLEAN\r
+IsWhiteSpace (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+unsigned int\r
+SkipWhiteSpace (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+BOOLEAN\r
+EndOfFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+void\r
+PreprocessFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+T_CHAR  *\r
+t_strcpy (\r
+  T_CHAR *Dest,\r
+  T_CHAR *Src\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessIncludeFile (\r
+  SOURCE_FILE *SourceFile,\r
+  SOURCE_FILE *ParentSourceFile\r
+  );\r
+\r
+static\r
+STATUS\r
+ParseFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+FILE    *\r
+FindFile (\r
+  char          *FileName,\r
+  char          *FoundFileName,\r
+  unsigned int  FoundFileNameLen\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessFile (\r
+  SOURCE_FILE *SourceFile\r
+  );\r
+\r
+static\r
+STATUS\r
+GetFilePosition (\r
+  FILE_POSITION *Fpos\r
+  );\r
+\r
+static\r
+STATUS\r
+SetFilePosition (\r
+  FILE_POSITION *Fpos\r
+  );\r
+\r
+STATUS\r
+SFPInit (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+  None.\r
+\r
+Returns:\r
+  STATUS_SUCCESS always\r
+\r
+--*/\r
+{\r
+  memset ((void *) &mGlobals, 0, sizeof (mGlobals));\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+unsigned\r
+int\r
+SFPGetLineNumber (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Return the line number of the file we're parsing. Used\r
+  for error reporting purposes.\r
+\r
+Arguments:\r
+  None.\r
+\r
+Returns:\r
+  The line number, or 0 if no file is being processed\r
+\r
+--*/\r
+{\r
+  return mGlobals.SourceFile.LineNum;\r
+}\r
+\r
+T_CHAR *\r
+SFPGetFileName (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Return the name of the file we're parsing. Used\r
+  for error reporting purposes.\r
+\r
+Arguments:\r
+  None.\r
+\r
+Returns:\r
+  A pointer to the file name. Null if no file is being\r
+  processed.\r
+\r
+--*/\r
+{\r
+  if (mGlobals.SourceFile.FileName[0]) {\r
+    return mGlobals.SourceFile.FileName;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+STATUS\r
+SFPOpenFile (\r
+  char      *FileName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Open a file for parsing.\r
+\r
+Arguments:\r
+  FileName  - name of the file to parse\r
+\r
+Returns:\r
+  \r
+\r
+--*/\r
+{\r
+  STATUS  Status;\r
+  t_strcpy (mGlobals.SourceFile.FileName, FileName);\r
+  Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL);\r
+  return Status;\r
+}\r
+\r
+BOOLEAN\r
+SFPIsToken (\r
+  T_CHAR *Str\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check to see if the specified token is found at\r
+  the current position in the input file.\r
+\r
+Arguments:\r
+  Str - the token to look for\r
+\r
+Returns:\r
+  TRUE - the token is next\r
+  FALSE - the token is not next\r
+\r
+Notes:\r
+  We do a simple string comparison on this function. It is\r
+  the responsibility of the caller to ensure that the token\r
+  is not a subset of some other token.\r
+\r
+  The file pointer is advanced past the token in the input file.\r
+\r
+--*/\r
+{\r
+  unsigned int  Len;\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  if (EndOfFile (&mGlobals.SourceFile)) {\r
+    return FALSE;\r
+  }\r
+\r
+  if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {\r
+    mGlobals.SourceFile.FileBufferPtr += Len;\r
+    if (mGlobals.VerboseToken) {\r
+      printf ("Token: '%s'\n", Str);\r
+    }\r
+\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+SFPIsKeyword (\r
+  T_CHAR *Str\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check to see if the specified keyword is found at\r
+  the current position in the input file.\r
+\r
+Arguments:\r
+  Str - keyword to look for\r
+\r
+Returns:\r
+  TRUE - the keyword is next\r
+  FALSE - the keyword is not next\r
+\r
+Notes:\r
+  A keyword is defined as a "special" string that has a non-alphanumeric\r
+  character following it.\r
+\r
+--*/\r
+{\r
+  unsigned int  Len;\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  if (EndOfFile (&mGlobals.SourceFile)) {\r
+    return FALSE;\r
+  }\r
+\r
+  if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) {\r
+    if (isalnum (mGlobals.SourceFile.FileBufferPtr[Len])) {\r
+      return FALSE;\r
+    }\r
+\r
+    mGlobals.SourceFile.FileBufferPtr += Len;\r
+    if (mGlobals.VerboseToken) {\r
+      printf ("Token: '%s'\n", Str);\r
+    }\r
+\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+SFPGetNextToken (\r
+  T_CHAR        *Str,\r
+  unsigned int  Len\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Get the next token from the input stream. \r
+\r
+Arguments:\r
+  Str - pointer to a copy of the next token\r
+  Len - size of buffer pointed to by Str\r
+\r
+Returns:\r
+  TRUE  - next token successfully returned\r
+  FALSE - otherwise\r
+\r
+Notes:\r
+  Preceeding white space is ignored. \r
+  The parser's buffer pointer is advanced past the end of the\r
+  token.\r
+\r
+--*/\r
+{\r
+  unsigned int  Index;\r
+  T_CHAR        TempChar;\r
+\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  if (EndOfFile (&mGlobals.SourceFile)) {\r
+    return FALSE;\r
+  }\r
+  //\r
+  // Have to have enough string for at least one char and a null-terminator\r
+  //\r
+  if (Len < 2) {\r
+    return FALSE;\r
+  }\r
+  //\r
+  // Look at the first character. If it's an identifier, then treat it\r
+  // as such\r
+  //\r
+  TempChar = mGlobals.SourceFile.FileBufferPtr[0];\r
+  if (((TempChar >= 'a') && (TempChar <= 'z')) || ((TempChar >= 'A') && (TempChar <= 'Z')) || (TempChar == '_')) {\r
+    Str[0] = TempChar;\r
+    mGlobals.SourceFile.FileBufferPtr++;\r
+    Index = 1;\r
+    while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {\r
+      TempChar = mGlobals.SourceFile.FileBufferPtr[0];\r
+      if (((TempChar >= 'a') && (TempChar <= 'z')) ||\r
+          ((TempChar >= 'A') && (TempChar <= 'Z')) ||\r
+          ((TempChar >= '0') && (TempChar <= '9')) ||\r
+          (TempChar == '_')\r
+          ) {\r
+        Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];\r
+        mGlobals.SourceFile.FileBufferPtr++;\r
+        Index++;\r
+      } else {\r
+        //\r
+        // Invalid character for symbol name, so break out\r
+        //\r
+        break;\r
+      }\r
+    }\r
+    //\r
+    // Null terminate and return success\r
+    //\r
+    Str[Index] = 0;\r
+    return TRUE;\r
+  } else if ((TempChar == ')') || (TempChar == '(') || (TempChar == '*')) {\r
+    Str[0] = mGlobals.SourceFile.FileBufferPtr[0];\r
+    mGlobals.SourceFile.FileBufferPtr++;\r
+    Str[1] = 0;\r
+    return TRUE;\r
+  } else {\r
+    //\r
+    // Everything else is white-space (or EOF) separated\r
+    //\r
+    Index = 0;\r
+    while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {\r
+      if (IsWhiteSpace (&mGlobals.SourceFile)) {\r
+        if (Index > 0) {\r
+          Str[Index] = 0;\r
+          return TRUE;\r
+        }\r
+\r
+        return FALSE;\r
+      } else {\r
+        Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];\r
+        mGlobals.SourceFile.FileBufferPtr++;\r
+        Index++;\r
+      }\r
+    }\r
+    //\r
+    // See if we just ran out of file contents, but did find a token\r
+    //\r
+    if ((Index > 0) && EndOfFile (&mGlobals.SourceFile)) {\r
+      Str[Index] = 0;\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+SFPGetGuidToken (\r
+  T_CHAR *Str,\r
+  UINT32 Len\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Parse a GUID from the input stream. Stop when you discover white space.\r
+\r
+Arguments:\r
+  Str - pointer to a copy of the next token\r
+  Len - size of buffer pointed to by Str\r
+\r
+Returns:\r
+  TRUE  - GUID string returned successfully\r
+  FALSE - otherwise\r
+\r
+--*/\r
+{\r
+  UINT32  Index;\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  if (EndOfFile (&mGlobals.SourceFile)) {\r
+    return FALSE;\r
+  }\r
+\r
+  Index = 0;\r
+  while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) {\r
+    if (IsWhiteSpace (&mGlobals.SourceFile)) {\r
+      if (Index > 0) {\r
+        Str[Index] = 0;\r
+        return TRUE;\r
+      }\r
+\r
+      return FALSE;\r
+    } else {\r
+      Str[Index] = mGlobals.SourceFile.FileBufferPtr[0];\r
+      mGlobals.SourceFile.FileBufferPtr++;\r
+      Index++;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+SFPSkipToToken (\r
+  T_CHAR *Str\r
+  )\r
+{\r
+  unsigned int  Len;\r
+  T_CHAR        *SavePos;\r
+  Len     = t_strlen (Str);\r
+  SavePos = mGlobals.SourceFile.FileBufferPtr;\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  while (!EndOfFile (&mGlobals.SourceFile)) {\r
+    if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) {\r
+      mGlobals.SourceFile.FileBufferPtr += Len;\r
+      return TRUE;\r
+    }\r
+\r
+    mGlobals.SourceFile.FileBufferPtr++;\r
+    SkipWhiteSpace (&mGlobals.SourceFile);\r
+  }\r
+\r
+  mGlobals.SourceFile.FileBufferPtr = SavePos;\r
+  return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+SFPGetNumber (\r
+  unsigned int *Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check the token at the current file position for a numeric value.\r
+  May be either decimal or hex.\r
+\r
+Arguments:\r
+  Value  - pointer where to store the value\r
+\r
+Returns:\r
+  FALSE    - current token is not a number\r
+  TRUE     - current token is a number\r
+\r
+--*/\r
+{\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  if (EndOfFile (&mGlobals.SourceFile)) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) {\r
+    //\r
+    // Check for hex value\r
+    //\r
+    if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) {\r
+      if (!isxdigit (mGlobals.SourceFile.FileBufferPtr[2])) {\r
+        return FALSE;\r
+      }\r
+\r
+      mGlobals.SourceFile.FileBufferPtr += 2;\r
+      sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", Value);\r
+      while (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) {\r
+        mGlobals.SourceFile.FileBufferPtr++;\r
+      }\r
+\r
+      return TRUE;\r
+    } else {\r
+      *Value = atoi (mGlobals.SourceFile.FileBufferPtr);\r
+      while (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) {\r
+        mGlobals.SourceFile.FileBufferPtr++;\r
+      }\r
+\r
+      return TRUE;\r
+    }\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+STATUS\r
+SFPCloseFile (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Close the file being parsed.\r
+\r
+Arguments:\r
+  None.\r
+\r
+Returns:\r
+  STATUS_SUCCESS - the file was closed \r
+  STATUS_ERROR   - no file is currently open\r
+\r
+--*/\r
+{\r
+  if (mGlobals.SourceFile.FileBuffer != NULL) {\r
+    free (mGlobals.SourceFile.FileBuffer);\r
+    memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile));\r
+    return STATUS_SUCCESS;\r
+  }\r
+\r
+  return STATUS_ERROR;\r
+}\r
+\r
+static\r
+STATUS\r
+ProcessIncludeFile (\r
+  SOURCE_FILE *SourceFile,\r
+  SOURCE_FILE *ParentSourceFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a source file, open the file and parse it\r
+  \r
+Arguments:\r
+\r
+  SourceFile        - name of file to parse\r
+  ParentSourceFile  - for error reporting purposes, the file that #included SourceFile.\r
+\r
+Returns:\r
+\r
+  Standard status.\r
+  \r
+--*/\r
+{\r
+  static unsigned int NestDepth = 0;\r
+  char                FoundFileName[MAX_PATH];\r
+  STATUS              Status;\r
+\r
+  Status = STATUS_SUCCESS;\r
+  NestDepth++;\r
+  //\r
+  // Print the file being processed. Indent so you can tell the include nesting\r
+  // depth.\r
+  //\r
+  if (mGlobals.VerboseFile) {\r
+    fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName);\r
+    fprintf (stdout, "Parent source file = '%s'\n", ParentSourceFile);\r
+  }\r
+\r
+  //\r
+  // Make sure we didn't exceed our maximum nesting depth\r
+  //\r
+  if (NestDepth > MAX_NEST_DEPTH) {\r
+    Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth);\r
+    Status = STATUS_ERROR;\r
+    goto Finish;\r
+  }\r
+  //\r
+  // Try to open the file locally, and if that fails try along our include paths.\r
+  //\r
+  strcpy (FoundFileName, SourceFile->FileName);\r
+  if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // Process the file found\r
+  //\r
+  ProcessFile (SourceFile);\r
+Finish:\r
+  //\r
+  // Close open files and return status\r
+  //\r
+  if (SourceFile->Fptr != NULL) {\r
+    fclose (SourceFile->Fptr);\r
+    SourceFile->Fptr = NULL;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+static\r
+STATUS\r
+ProcessFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a source file that's been opened, read the contents into an internal\r
+  buffer and pre-process it to remove comments.\r
+  \r
+Arguments:\r
+\r
+  SourceFile        - structure containing info on the file to process\r
+\r
+Returns:\r
+\r
+  Standard status.\r
+  \r
+--*/\r
+{\r
+  //\r
+  // Get the file size, and then read the entire thing into memory.\r
+  // Allocate extra space for a terminator character.\r
+  //\r
+  fseek (SourceFile->Fptr, 0, SEEK_END);\r
+  SourceFile->FileSize = ftell (SourceFile->Fptr);\r
+  if (mGlobals.VerboseFile) {\r
+    printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize);\r
+  }\r
+\r
+  fseek (SourceFile->Fptr, 0, SEEK_SET);\r
+  SourceFile->FileBuffer = (T_CHAR *) malloc (SourceFile->FileSize + sizeof (T_CHAR));\r
+  if (SourceFile->FileBuffer == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  fread ((void *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr);\r
+  SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (T_CHAR))] = T_CHAR_NULL;\r
+  //\r
+  // Pre-process the file to replace comments with spaces\r
+  //\r
+  PreprocessFile (SourceFile);\r
+  SourceFile->LineNum = 1;\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+void\r
+PreprocessFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Preprocess a file to replace all carriage returns with NULLs so\r
+  we can print lines (as part of error messages) from the file to the screen.\r
+  \r
+Arguments:\r
+  SourceFile - structure that we use to keep track of an input file.\r
+\r
+Returns:\r
+  Nothing.\r
+  \r
+--*/\r
+{\r
+  BOOLEAN InComment;\r
+  BOOLEAN SlashSlashComment;\r
+  int     LineNum;\r
+\r
+  RewindFile (SourceFile);\r
+  InComment         = FALSE;\r
+  SlashSlashComment = FALSE;\r
+  while (!EndOfFile (SourceFile)) {\r
+    //\r
+    // If a line-feed, then no longer in a comment if we're in a // comment\r
+    //\r
+    if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {\r
+      SourceFile->FileBufferPtr++;\r
+      SourceFile->LineNum++;\r
+      if (InComment && SlashSlashComment) {\r
+        InComment         = FALSE;\r
+        SlashSlashComment = FALSE;\r
+      }\r
+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {\r
+      //\r
+      // Replace all carriage returns with a NULL so we can print stuff\r
+      //\r
+      SourceFile->FileBufferPtr[0] = 0;\r
+      SourceFile->FileBufferPtr++;\r
+      //\r
+      // Check for */ comment end\r
+      //\r
+    } else if (InComment &&\r
+             !SlashSlashComment &&\r
+             (SourceFile->FileBufferPtr[0] == T_CHAR_STAR) &&\r
+             (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)\r
+            ) {\r
+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
+      SourceFile->FileBufferPtr++;\r
+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
+      SourceFile->FileBufferPtr++;\r
+      InComment = FALSE;\r
+    } else if (InComment) {\r
+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
+      SourceFile->FileBufferPtr++;\r
+      //\r
+      // Check for // comments\r
+      //\r
+    } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) {\r
+      InComment         = TRUE;\r
+      SlashSlashComment = TRUE;\r
+      //\r
+      // Check for /* comment start\r
+      //\r
+    } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_STAR)) {\r
+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
+      SourceFile->FileBufferPtr++;\r
+      SourceFile->FileBufferPtr[0] = T_CHAR_SPACE;\r
+      SourceFile->FileBufferPtr++;\r
+      SlashSlashComment = FALSE;\r
+      InComment         = TRUE;\r
+    } else {\r
+      SourceFile->FileBufferPtr++;\r
+    }\r
+  }\r
+  //\r
+  // Could check for end-of-file and still in a comment, but\r
+  // should not be necessary. So just restore the file pointers.\r
+  //\r
+  RewindFile (SourceFile);\r
+  //\r
+  // Dump the reformatted file if verbose mode\r
+  //\r
+  if (mGlobals.VerboseFile) {\r
+    LineNum = 1;\r
+    printf ("%04d: ", LineNum);\r
+    while (!EndOfFile (SourceFile)) {\r
+      if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) {\r
+        printf ("'\n%04d: '", ++LineNum);\r
+      } else {\r
+        printf ("%c", SourceFile->FileBufferPtr[0]);\r
+      }\r
+\r
+      SourceFile->FileBufferPtr++;\r
+    }\r
+\r
+    printf ("'\n");\r
+    printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize);\r
+    RewindFile (SourceFile);\r
+  }\r
+}\r
+\r
+BOOLEAN\r
+SFPGetQuotedString (\r
+  T_CHAR      *Str,\r
+  int         Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Retrieve a quoted-string from the input file. \r
+  \r
+Arguments:\r
+  Str    - pointer to a copy of the quoted string parsed\r
+  Length - size of buffer pointed to by Str\r
+\r
+Returns:\r
+  TRUE    - next token in input stream was a quoted string, and\r
+            the string value was returned in Str\r
+  FALSE   - otherwise\r
+  \r
+--*/\r
+{\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  if (EndOfFile (&mGlobals.SourceFile)) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {\r
+    mGlobals.SourceFile.FileBufferPtr++;\r
+    while (Length > 0) {\r
+      if (EndOfFile (&mGlobals.SourceFile)) {\r
+        return FALSE;\r
+      }\r
+      //\r
+      // Check for closing quote\r
+      //\r
+      if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {\r
+        mGlobals.SourceFile.FileBufferPtr++;\r
+        *Str = 0;\r
+        return TRUE;\r
+      }\r
+\r
+      *Str = mGlobals.SourceFile.FileBufferPtr[0];\r
+      Str++;\r
+      Length--;\r
+      mGlobals.SourceFile.FileBufferPtr++;\r
+    }\r
+  }\r
+  //\r
+  // First character was not a quote, or the input string length was\r
+  // insufficient to contain the quoted string, so return failure code.\r
+  //\r
+  return FALSE;\r
+}\r
+\r
+BOOLEAN\r
+SFPIsEOF (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Return TRUE of FALSE to indicate whether or not we've reached the end of the\r
+  file we're parsing.\r
+  \r
+Arguments:\r
+  NA\r
+\r
+Returns:\r
+  TRUE    - EOF reached\r
+  FALSE   - otherwise\r
+  \r
+--*/\r
+{\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  return EndOfFile (&mGlobals.SourceFile);\r
+}\r
+\r
+#if 0\r
+static\r
+T_CHAR *\r
+GetQuotedString (\r
+  SOURCE_FILE *SourceFile,\r
+  BOOLEAN     Optional\r
+  )\r
+{\r
+  T_CHAR        *String;\r
+  T_CHAR        *Start;\r
+  T_CHAR        *Ptr;\r
+  unsigned int  Len;\r
+  BOOLEAN       PreviousBackslash;\r
+\r
+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {\r
+    if (Optional == FALSE) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr);\r
+    }\r
+\r
+    return NULL;\r
+  }\r
+\r
+  Len = 0;\r
+  SourceFile->FileBufferPtr++;\r
+  Start             = Ptr = SourceFile->FileBufferPtr;\r
+  PreviousBackslash = FALSE;\r
+  while (!EndOfFile (SourceFile)) {\r
+    if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (PreviousBackslash == FALSE)) {\r
+      break;\r
+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) {\r
+      Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start);\r
+      PreviousBackslash = FALSE;\r
+    } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) {\r
+      PreviousBackslash = TRUE;\r
+    } else {\r
+      PreviousBackslash = FALSE;\r
+    }\r
+\r
+    SourceFile->FileBufferPtr++;\r
+    Len++;\r
+  }\r
+\r
+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {\r
+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start);\r
+  } else {\r
+    SourceFile->FileBufferPtr++;\r
+  }\r
+  //\r
+  // Now allocate memory for the string and save it off\r
+  //\r
+  String = (T_CHAR *) malloc ((Len + 1) * sizeof (T_CHAR));\r
+  if (String == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failed", NULL);\r
+    return NULL;\r
+  }\r
+  //\r
+  // Copy the string from the file buffer to the local copy.\r
+  // We do no reformatting of it whatsoever at this point.\r
+  //\r
+  Ptr = String;\r
+  while (Len > 0) {\r
+    *Ptr = *Start;\r
+    Start++;\r
+    Ptr++;\r
+    Len--;\r
+  }\r
+\r
+  *Ptr = 0;\r
+  return String;\r
+}\r
+#endif\r
+static\r
+BOOLEAN\r
+EndOfFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  //\r
+  // The file buffer pointer will typically get updated before the End-of-file flag in the\r
+  // source file structure, so check it first.\r
+  //\r
+  if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (T_CHAR)) {\r
+    SourceFile->EndOfFile = TRUE;\r
+    return TRUE;\r
+  }\r
+\r
+  if (SourceFile->EndOfFile) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+#if 0\r
+static\r
+void\r
+ProcessTokenInclude (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  char          IncludeFileName[MAX_PATH];\r
+  char          *To;\r
+  unsigned int  Len;\r
+  BOOLEAN       ReportedError;\r
+  SOURCE_FILE   IncludedSourceFile;\r
+\r
+  ReportedError = FALSE;\r
+  if (SkipWhiteSpace (SourceFile) == 0) {\r
+    Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL);\r
+  }\r
+  //\r
+  // Should be quoted file name\r
+  //\r
+  if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) {\r
+    Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL);\r
+    goto FailDone;\r
+  }\r
+\r
+  SourceFile->FileBufferPtr++;\r
+  //\r
+  // Copy the filename as ascii to our local string\r
+  //\r
+  To  = IncludeFileName;\r
+  Len = 0;\r
+  while (!EndOfFile (SourceFile)) {\r
+    if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL);\r
+      goto FailDone;\r
+    }\r
+\r
+    if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) {\r
+      SourceFile->FileBufferPtr++;\r
+      break;\r
+    }\r
+    //\r
+    // If too long, then report the error once and process until the closing quote\r
+    //\r
+    Len++;\r
+    if (!ReportedError && (Len >= sizeof (IncludeFileName))) {\r
+      Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL);\r
+      ReportedError = TRUE;\r
+    }\r
+\r
+    if (!ReportedError) {\r
+      *To = (T_CHAR) SourceFile->FileBufferPtr[0];\r
+      To++;\r
+    }\r
+\r
+    SourceFile->FileBufferPtr++;\r
+  }\r
+\r
+  if (!ReportedError) {\r
+    *To = 0;\r
+    memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE));\r
+    strcpy (IncludedSourceFile.FileName, IncludeFileName);\r
+    ProcessIncludeFile (&IncludedSourceFile, SourceFile);\r
+  }\r
+\r
+  return ;\r
+FailDone:\r
+  //\r
+  // Error recovery -- skip to next #\r
+  //\r
+  SourceFile->SkipToHash = TRUE;\r
+}\r
+#endif\r
+static\r
+BOOLEAN\r
+IsWhiteSpace (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  switch (*SourceFile->FileBufferPtr) {\r
+  case T_CHAR_NULL:\r
+  case T_CHAR_CR:\r
+  case T_CHAR_SPACE:\r
+  case T_CHAR_TAB:\r
+  case T_CHAR_LF:\r
+    return TRUE;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+unsigned int\r
+SkipWhiteSpace (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  unsigned int  Count;\r
+\r
+  Count = 0;\r
+  while (!EndOfFile (SourceFile)) {\r
+    Count++;\r
+    switch (*SourceFile->FileBufferPtr) {\r
+    case T_CHAR_NULL:\r
+    case T_CHAR_CR:\r
+    case T_CHAR_SPACE:\r
+    case T_CHAR_TAB:\r
+      SourceFile->FileBufferPtr++;\r
+      break;\r
+\r
+    case T_CHAR_LF:\r
+      SourceFile->FileBufferPtr++;\r
+      SourceFile->LineNum++;\r
+      break;\r
+\r
+    default:\r
+      return Count - 1;\r
+    }\r
+  }\r
+  //\r
+  // Some tokens require trailing whitespace. If we're at the end of the\r
+  // file, then we count that as well.\r
+  //\r
+  if ((Count == 0) && (EndOfFile (SourceFile))) {\r
+    Count++;\r
+  }\r
+\r
+  return Count;\r
+}\r
+\r
+static\r
+unsigned int\r
+t_strcmp (\r
+  T_CHAR *Buffer,\r
+  T_CHAR *Str\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated,\r
+  so only compare up to the length of Str.\r
+\r
+Arguments:\r
+  Buffer  - pointer to first (possibly not null-terminated) string\r
+  Str     - pointer to null-terminated string to compare to Buffer\r
+\r
+Returns:\r
+  Number of bytes matched if exact match\r
+  0 if Buffer does not start with Str\r
+\r
+--*/\r
+{\r
+  unsigned int  Len;\r
+\r
+  Len = 0;\r
+  while (*Str && (*Str == *Buffer)) {\r
+    Buffer++;\r
+    Str++;\r
+    Len++;\r
+  }\r
+\r
+  if (*Str) {\r
+    return 0;\r
+  }\r
+\r
+  return Len;\r
+}\r
+\r
+static\r
+unsigned int\r
+t_strlen (\r
+  T_CHAR *Str\r
+  )\r
+{\r
+  unsigned int  Len;\r
+  Len = 0;\r
+  while (*Str) {\r
+    Len++;\r
+    Str++;\r
+  }\r
+\r
+  return Len;\r
+}\r
+\r
+static\r
+unsigned int\r
+t_strncmp (\r
+  T_CHAR *Str1,\r
+  T_CHAR *Str2,\r
+  int    Len\r
+  )\r
+{\r
+  while (Len > 0) {\r
+    if (*Str1 != *Str2) {\r
+      return Len;\r
+    }\r
+\r
+    Len--;\r
+    Str1++;\r
+    Str2++;\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+static\r
+T_CHAR *\r
+t_strcpy (\r
+  T_CHAR *Dest,\r
+  T_CHAR *Src\r
+  )\r
+{\r
+  T_CHAR  *SaveDest;\r
+  SaveDest = Dest;\r
+  while (*Src) {\r
+    *Dest = *Src;\r
+    Dest++;\r
+    Src++;\r
+  }\r
+\r
+  *Dest = 0;\r
+  return SaveDest;\r
+}\r
+\r
+static\r
+void\r
+RewindFile (\r
+  SOURCE_FILE *SourceFile\r
+  )\r
+{\r
+  SourceFile->LineNum       = 1;\r
+  SourceFile->FileBufferPtr = SourceFile->FileBuffer;\r
+  SourceFile->EndOfFile     = 0;\r
+}\r
+\r
+static\r
+UINT32\r
+GetHexChars (\r
+  T_CHAR      *Buffer,\r
+  UINT32      BufferLen\r
+  )\r
+{\r
+  UINT32  Len;\r
+  Len = 0;\r
+  while (!EndOfFile (&mGlobals.SourceFile) && (BufferLen > 0)) {\r
+    if (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) {\r
+      *Buffer = mGlobals.SourceFile.FileBufferPtr[0];\r
+      Buffer++;\r
+      Len++;\r
+      BufferLen--;\r
+      mGlobals.SourceFile.FileBufferPtr++;\r
+    } else {\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // Null terminate if we can\r
+  //\r
+  if ((Len > 0) && (BufferLen > 0)) {\r
+    *Buffer = 0;\r
+  }\r
+\r
+  return Len;\r
+}\r
+\r
+BOOLEAN\r
+SFPGetGuid (\r
+  int         GuidStyle,\r
+  EFI_GUID    *Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Parse a GUID from the input stream. Stop when you discover white space.\r
+\r
+Arguments:\r
+  GuidStyle - Style of the following GUID token\r
+  Value     - pointer to EFI_GUID struct for output\r
+\r
+Returns:\r
+  TRUE  - GUID string parsed successfully\r
+  FALSE - otherwise\r
+\r
+  GUID styles\r
+    Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD\r
+\r
+--*/\r
+{\r
+  UINT32        Value32;\r
+  UINT32        Index;\r
+  FILE_POSITION FPos;\r
+  T_CHAR        TempString[20];\r
+  T_CHAR        TempString2[3];\r
+  T_CHAR        *From;\r
+  T_CHAR        *To;\r
+  UINT32        Len;\r
+  BOOLEAN       Status;\r
+\r
+  Status = FALSE;\r
+  //\r
+  // Skip white space, then start parsing\r
+  //\r
+  SkipWhiteSpace (&mGlobals.SourceFile);\r
+  GetFilePosition (&FPos);\r
+  if (EndOfFile (&mGlobals.SourceFile)) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (GuidStyle == PARSE_GUID_STYLE_5_FIELDS) {\r
+    //\r
+    // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD\r
+    //\r
+    Len = GetHexChars (TempString, sizeof (TempString));\r
+    if ((Len == 0) || (Len > 8)) {\r
+      goto Done;\r
+    }\r
+\r
+    sscanf (TempString, "%x", &Value32);\r
+    Value->Data1 = Value32;\r
+    //\r
+    // Next two UINT16 fields\r
+    //\r
+    if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {\r
+      goto Done;\r
+    }\r
+\r
+    mGlobals.SourceFile.FileBufferPtr++;\r
+    Len = GetHexChars (TempString, sizeof (TempString));\r
+    if ((Len == 0) || (Len > 4)) {\r
+      goto Done;\r
+    }\r
+\r
+    sscanf (TempString, "%x", &Value32);\r
+    Value->Data2 = (UINT16) Value32;\r
+\r
+    if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {\r
+      goto Done;\r
+    }\r
+\r
+    mGlobals.SourceFile.FileBufferPtr++;\r
+    Len = GetHexChars (TempString, sizeof (TempString));\r
+    if ((Len == 0) || (Len > 4)) {\r
+      goto Done;\r
+    }\r
+\r
+    sscanf (TempString, "%x", &Value32);\r
+    Value->Data3 = (UINT16) Value32;\r
+    //\r
+    // Parse the "AAAA" as two bytes\r
+    //\r
+    if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {\r
+      goto Done;\r
+    }\r
+\r
+    mGlobals.SourceFile.FileBufferPtr++;\r
+    Len = GetHexChars (TempString, sizeof (TempString));\r
+    if ((Len == 0) || (Len > 4)) {\r
+      goto Done;\r
+    }\r
+\r
+    sscanf (TempString, "%x", &Value32);\r
+    Value->Data4[0] = (UINT8) (Value32 >> 8);\r
+    Value->Data4[1] = (UINT8) Value32;\r
+    if (mGlobals.SourceFile.FileBufferPtr[0] != '-') {\r
+      goto Done;\r
+    }\r
+\r
+    mGlobals.SourceFile.FileBufferPtr++;\r
+    //\r
+    // Read the last 6 bytes of the GUID\r
+    //\r
+    //\r
+    Len = GetHexChars (TempString, sizeof (TempString));\r
+    if ((Len == 0) || (Len > 12)) {\r
+      goto Done;\r
+    }\r
+    //\r
+    // Insert leading 0's to make life easier\r
+    //\r
+    if (Len != 12) {\r
+      From            = TempString + Len - 1;\r
+      To              = TempString + 11;\r
+      TempString[12]  = 0;\r
+      while (From >= TempString) {\r
+        *To = *From;\r
+        To--;\r
+        From--;\r
+      }\r
+\r
+      while (To >= TempString) {\r
+        *To = '0';\r
+        To--;\r
+      }\r
+    }\r
+    //\r
+    // Now parse each byte\r
+    //\r
+    TempString2[2] = 0;\r
+    for (Index = 0; Index < 6; Index++) {\r
+      //\r
+      // Copy the two characters from the input string to something\r
+      // we can parse.\r
+      //\r
+      TempString2[0]  = TempString[Index * 2];\r
+      TempString2[1]  = TempString[Index * 2 + 1];\r
+      sscanf (TempString2, "%x", &Value32);\r
+      Value->Data4[Index + 2] = (UINT8) Value32;\r
+    }\r
+\r
+    Status = TRUE;\r
+  } else {\r
+    //\r
+    // Unsupported GUID style\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+Done:\r
+  if (Status == FALSE) {\r
+    SetFilePosition (&FPos);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+static\r
+STATUS\r
+GetFilePosition (\r
+  FILE_POSITION *Fpos\r
+  )\r
+{\r
+  Fpos->FileBufferPtr = mGlobals.SourceFile.FileBufferPtr;\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+SetFilePosition (\r
+  FILE_POSITION *Fpos\r
+  )\r
+{\r
+  //\r
+  // Should check range of pointer\r
+  //\r
+  mGlobals.SourceFile.FileBufferPtr = Fpos->FileBufferPtr;\r
+  return STATUS_SUCCESS;\r
+}\r
diff --git a/Source/C/Common/SimpleFileParsing.h b/Source/C/Common/SimpleFileParsing.h
new file mode 100644 (file)
index 0000000..7cf25a6
--- /dev/null
@@ -0,0 +1,120 @@
+/*++\r
+\r
+Copyright (c) 2004, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  SimpleFileParsing.h\r
+\r
+Abstract:\r
+\r
+  Function prototypes and defines for the simple file parsing routines.\r
+\r
+--*/\r
+\r
+#ifndef _SIMPLE_FILE_PARSING_H_\r
+#define _SIMPLE_FILE_PARSING_H_\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+\r
+#define T_CHAR  char\r
+\r
+STATUS\r
+SFPInit (\r
+  VOID\r
+  )\r
+;\r
+\r
+STATUS\r
+SFPOpenFile (\r
+  char    *FileName\r
+  )\r
+;\r
+\r
+BOOLEAN\r
+SFPIsKeyword (\r
+  T_CHAR *Str\r
+  )\r
+;\r
+\r
+BOOLEAN\r
+SFPIsToken (\r
+  T_CHAR *Str\r
+  )\r
+;\r
+\r
+BOOLEAN\r
+SFPGetNextToken (\r
+  T_CHAR        *Str,\r
+  unsigned int  Len\r
+  )\r
+;\r
+\r
+BOOLEAN\r
+SFPGetGuidToken (\r
+  T_CHAR *Str,\r
+  UINT32 Len\r
+  )\r
+;\r
+\r
+#define PARSE_GUID_STYLE_5_FIELDS 0\r
+\r
+BOOLEAN\r
+SFPGetGuid (\r
+  int         GuidStyle,\r
+  EFI_GUID    *Value\r
+  )\r
+;\r
+\r
+BOOLEAN\r
+SFPSkipToToken (\r
+  T_CHAR *Str\r
+  )\r
+;\r
+\r
+BOOLEAN\r
+SFPGetNumber (\r
+  unsigned int   *Value\r
+  )\r
+;\r
+\r
+BOOLEAN\r
+SFPGetQuotedString (\r
+  T_CHAR      *Str,\r
+  int         Length\r
+  )\r
+;\r
+\r
+BOOLEAN\r
+SFPIsEOF (\r
+  VOID\r
+  )\r
+;\r
+\r
+STATUS\r
+SFPCloseFile (\r
+  VOID\r
+  )\r
+;\r
+\r
+unsigned\r
+int\r
+SFPGetLineNumber (\r
+  VOID\r
+  )\r
+;\r
+\r
+T_CHAR  *\r
+SFPGetFileName (\r
+  VOID\r
+  )\r
+;\r
+\r
+#endif // #ifndef _SIMPLE_FILE_PARSING_H_\r
diff --git a/Source/C/Common/TianoCompress.c b/Source/C/Common/TianoCompress.c
new file mode 100644 (file)
index 0000000..dc78e7a
--- /dev/null
@@ -0,0 +1,1752 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  TianoCompress.c\r
+\r
+Abstract:\r
+\r
+  Compression routine. The compression algorithm is a mixture of\r
+  LZ77 and Huffman coding. LZ77 transforms the source data into a\r
+  sequence of Original Characters and Pointers to repeated strings.\r
+  This sequence is further divided into Blocks and Huffman codings\r
+  are applied to each Block.\r
+\r
+--*/\r
+\r
+#include "Compress.h"\r
+\r
+//\r
+// Macro Definitions\r
+//\r
+typedef INT32 NODE;\r
+#define UINT8_MAX     0xff\r
+#define UINT8_BIT     8\r
+#define THRESHOLD     3\r
+#define INIT_CRC      0\r
+#define WNDBIT        19\r
+#define WNDSIZ        (1U << WNDBIT)\r
+#define MAXMATCH      256\r
+#define BLKSIZ        (1U << 14)  // 16 * 1024U\r
+#define PERC_FLAG     0x80000000U\r
+#define CODE_BIT      16\r
+#define NIL           0\r
+#define MAX_HASH_VAL  (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX)\r
+#define HASH(p, c)    ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2)\r
+#define CRCPOLY       0xA001\r
+#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT)\r
+\r
+//\r
+// C: the Char&Len Set; P: the Position Set; T: the exTra Set\r
+//\r
+#define NC    (UINT8_MAX + MAXMATCH + 2 - THRESHOLD)\r
+#define CBIT  9\r
+#define NP    (WNDBIT + 1)\r
+#define PBIT  5\r
+#define NT    (CODE_BIT + 3)\r
+#define TBIT  5\r
+#if NT > NP\r
+#define NPT NT\r
+#else\r
+#define NPT NP\r
+#endif\r
+//\r
+// Function Prototypes\r
+//\r
+\r
+STATIC\r
+VOID\r
+PutDword(\r
+  IN UINT32 Data\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS\r
+AllocateMemory (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+FreeMemory (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+InitSlide (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+NODE\r
+Child (\r
+  IN NODE   NodeQ,\r
+  IN UINT8  CharC\r
+  );\r
+\r
+STATIC\r
+VOID\r
+MakeChild (\r
+  IN NODE  NodeQ,\r
+  IN UINT8 CharC,\r
+  IN NODE  NodeR\r
+  );\r
+\r
+STATIC\r
+VOID\r
+Split (\r
+  IN NODE Old\r
+  );\r
+\r
+STATIC\r
+VOID\r
+InsertNode (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+DeleteNode (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+GetNextMatch (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS\r
+Encode (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+CountTFreq (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+WritePTLen (\r
+  IN INT32 Number,\r
+  IN INT32 nbit,\r
+  IN INT32 Special\r
+  );\r
+\r
+STATIC\r
+VOID\r
+WriteCLen (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+EncodeC (\r
+  IN INT32 Value\r
+  );\r
+\r
+STATIC\r
+VOID\r
+EncodeP (\r
+  IN UINT32 Value\r
+  );\r
+\r
+STATIC\r
+VOID\r
+SendBlock (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+Output (\r
+  IN UINT32 c,\r
+  IN UINT32 p\r
+  );\r
+\r
+STATIC\r
+VOID\r
+HufEncodeStart (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+HufEncodeEnd (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+MakeCrcTable (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+PutBits (\r
+  IN INT32  Number,\r
+  IN UINT32 Value\r
+  );\r
+\r
+STATIC\r
+INT32\r
+FreadCrc (\r
+  OUT UINT8 *Pointer,\r
+  IN  INT32 Number\r
+  );\r
+\r
+STATIC\r
+VOID\r
+InitPutBits (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+VOID\r
+CountLen (\r
+  IN INT32 Index\r
+  );\r
+\r
+STATIC\r
+VOID\r
+MakeLen (\r
+  IN INT32 Root\r
+  );\r
+\r
+STATIC\r
+VOID\r
+DownHeap (\r
+  IN INT32 Index\r
+  );\r
+\r
+STATIC\r
+VOID\r
+MakeCode (\r
+  IN  INT32       Number,\r
+  IN  UINT8 Len[  ],\r
+  OUT UINT16 Code[]\r
+  );\r
+\r
+STATIC\r
+INT32\r
+MakeTree (\r
+  IN  INT32            NParm,\r
+  IN  UINT16  FreqParm[],\r
+  OUT UINT8   LenParm[ ],\r
+  OUT UINT16  CodeParm[]\r
+  );\r
+\r
+//\r
+//  Global Variables\r
+//\r
+STATIC UINT8  *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;\r
+\r
+STATIC UINT8  *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;\r
+STATIC INT16  mHeap[NC + 1];\r
+STATIC INT32  mRemainder, mMatchLen, mBitCount, mHeapSize, mN;\r
+STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc;\r
+STATIC UINT32 mCompSize, mOrigSize;\r
+\r
+STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1],\r
+  mCFreq[2 * NC - 1], mCTable[4096], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1];\r
+\r
+STATIC NODE   mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL;\r
+\r
+//\r
+// functions\r
+//\r
+EFI_STATUS\r
+TianoCompress (\r
+  IN      UINT8   *SrcBuffer,\r
+  IN      UINT32  SrcSize,\r
+  IN      UINT8   *DstBuffer,\r
+  IN OUT  UINT32  *DstSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  The internal implementation of [Efi/Tiano]Compress().\r
+\r
+Arguments:\r
+\r
+  SrcBuffer   - The buffer storing the source data\r
+  SrcSize     - The size of source data\r
+  DstBuffer   - The buffer to store the compressed data\r
+  DstSize     - On input, the size of DstBuffer; On output,\r
+                the size of the actual compressed data.\r
+  Version     - The version of de/compression algorithm.\r
+                Version 1 for EFI 1.1 de/compression algorithm.\r
+                Version 2 for Tiano de/compression algorithm.\r
+\r
+Returns:\r
+\r
+  EFI_BUFFER_TOO_SMALL  - The DstBuffer is too small. In this case,\r
+                DstSize contains the size needed.\r
+  EFI_SUCCESS           - Compression is successful.\r
+  EFI_OUT_OF_RESOURCES  - No resource to complete function.\r
+  EFI_INVALID_PARAMETER - Parameter supplied is wrong.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Initializations\r
+  //\r
+  mBufSiz         = 0;\r
+  mBuf            = NULL;\r
+  mText           = NULL;\r
+  mLevel          = NULL;\r
+  mChildCount     = NULL;\r
+  mPosition       = NULL;\r
+  mParent         = NULL;\r
+  mPrev           = NULL;\r
+  mNext           = NULL;\r
+\r
+  mSrc            = SrcBuffer;\r
+  mSrcUpperLimit  = mSrc + SrcSize;\r
+  mDst            = DstBuffer;\r
+  mDstUpperLimit  = mDst +*DstSize;\r
+\r
+  PutDword (0L);\r
+  PutDword (0L);\r
+\r
+  MakeCrcTable ();\r
+\r
+  mOrigSize             = mCompSize = 0;\r
+  mCrc                  = INIT_CRC;\r
+\r
+  //\r
+  // Compress it\r
+  //\r
+  Status = Encode ();\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  //\r
+  // Null terminate the compressed data\r
+  //\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = 0;\r
+  }\r
+  //\r
+  // Fill in compressed size and original size\r
+  //\r
+  mDst = DstBuffer;\r
+  PutDword (mCompSize + 1);\r
+  PutDword (mOrigSize);\r
+\r
+  //\r
+  // Return\r
+  //\r
+  if (mCompSize + 1 + 8 > *DstSize) {\r
+    *DstSize = mCompSize + 1 + 8;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  } else {\r
+    *DstSize = mCompSize + 1 + 8;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+}\r
+\r
+STATIC\r
+VOID\r
+PutDword (\r
+  IN UINT32 Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Put a dword to output stream\r
+  \r
+Arguments:\r
+\r
+  Data    - the dword to put\r
+  \r
+Returns: (VOID)\r
+  \r
+--*/\r
+{\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff);\r
+  }\r
+\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff);\r
+  }\r
+\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff);\r
+  }\r
+\r
+  if (mDst < mDstUpperLimit) {\r
+    *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff);\r
+  }\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+AllocateMemory (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocate memory spaces for data structures used in compression process\r
+  \r
+Argements: \r
+  VOID\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Memory is allocated successfully\r
+  EFI_OUT_OF_RESOURCES  - Allocation fails\r
+\r
+--*/\r
+{\r
+  UINT32  Index;\r
+\r
+  mText = malloc (WNDSIZ * 2 + MAXMATCH);\r
+  for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {\r
+    mText[Index] = 0;\r
+  }\r
+\r
+  mLevel      = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel));\r
+  mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (