--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+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
--- /dev/null
+!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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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
--- /dev/null
+/*++\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 (