├── README ├── LZMA ├── Sdk │ └── C │ │ ├── 7zVersion.h │ │ ├── Bra.h │ │ ├── LzHash.h │ │ ├── Bra86.c │ │ ├── LzmaEnc.h │ │ ├── LzFind.h │ │ ├── CpuArch.h │ │ ├── Types.h │ │ ├── LzmaDec.h │ │ ├── LzFind.c │ │ └── LzmaDec.c ├── UefiLzma.h ├── LzmaCompress.h ├── LzmaCompress.c ├── LzmaDecompress.h └── LzmaDecompress.c ├── CMakeLists.txt ├── .gitattributes ├── patch.h ├── Common ├── BaseTypes.h └── ProcessorBind.h ├── Tiano ├── TianoCompress.h ├── TianoDecompress.h ├── TianoDecompress.c └── TianoCompress.c ├── main.c ├── patch_int.h └── patch.c /README: -------------------------------------------------------------------------------- 1 | Utility to patch UEFI BIOS PowerManagement modules to be compatible with MacOS X SpeedStep implementation. 2 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/7zVersion.h: -------------------------------------------------------------------------------- 1 | #define MY_VER_MAJOR 9 2 | #define MY_VER_MINOR 20 3 | #define MY_VER_BUILD 0 4 | #define MY_VERSION "9.20" 5 | #define MY_DATE "2010-11-18" 6 | #define MY_COPYRIGHT ": Igor Pavlov : Public domain" 7 | #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE 8 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(PMPatch) 2 | SET(PMPatch_SOURCES main.c patch.c Tiano/TianoCompress.c Tiano/TianoDecompress.c LZMA/LzmaCompress.c LZMA/LzmaDecompress.c LZMA/Sdk/C/LzmaDec.c LZMA/Sdk/C/LzmaEnc.c LZMA/Sdk/C/LzFind.c) 3 | SET(PMPatch_HEADERS patch.h patch_int.h Tiano/TianoCompress.h Tiano/TianoDecompress.h LZMA/LzmaCompress.h LZMA/LzmaDecompress.h LZMA/UefiLzma.h) 4 | ADD_EXECUTABLE(PMPatch ${PMPatch_SOURCES} ${PMPatch_HEADERS}) -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /patch.h: -------------------------------------------------------------------------------- 1 | /* Patch Header 2 | 3 | Copyright (c) 2012, Nikolaj Schlej. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #ifndef __PATCH_H__ 15 | #define __PATCH_H__ 16 | 17 | #include "Common/BaseTypes.h" 18 | 19 | // Patches BIOS 20 | BOOLEAN patch_bios(UINT8* bios, UINT32 size); 21 | 22 | #endif // __PATCH_H__ 23 | -------------------------------------------------------------------------------- /LZMA/UefiLzma.h: -------------------------------------------------------------------------------- 1 | /* LZMA UEFI header file 2 | 3 | Copyright (c) 2009, Intel Corporation. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #ifndef __UEFILZMA_H__ 15 | #define __UEFILZMA_H__ 16 | 17 | #include "../Common/BaseTypes.h" 18 | 19 | #ifdef _WIN32 20 | #undef _WIN32 21 | #endif 22 | 23 | #ifdef _WIN64 24 | #undef _WIN64 25 | #endif 26 | 27 | #define _LZMA_SIZE_OPT 28 | #define _7ZIP_ST 29 | 30 | #endif // __UEFILZMA_H__ 31 | 32 | -------------------------------------------------------------------------------- /LZMA/LzmaCompress.h: -------------------------------------------------------------------------------- 1 | /* LZMA Compress Header 2 | 3 | Copyright (c) 2012, Nikolaj Schlej. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #ifndef __LZMACOMPRESS_H__ 15 | #define __LZMACOMPRESS_H__ 16 | 17 | #include "Sdk/C/Types.h" 18 | #include "../Common/BaseTypes.h" 19 | 20 | #define LZMA_DICTIONARY_SIZE 0x800000 21 | 22 | INT32 23 | EFIAPI 24 | LzmaCompress ( 25 | CONST VOID *Source, 26 | UINT32 SourceSize, 27 | VOID *Destination, 28 | UINT32 *DestinationSize 29 | ); 30 | 31 | #endif -------------------------------------------------------------------------------- /Common/BaseTypes.h: -------------------------------------------------------------------------------- 1 | /* Processor or Compiler specific defines for all supported processors. 2 | 3 | This file is stand alone self consistent set of definitions. 4 | 5 | Copyright (c) 2006, Intel Corporation. All rights reserved.
6 | This program and the accompanying materials 7 | are licensed and made available under the terms and conditions of the BSD License 8 | which accompanies this distribution. The full text of the license may be found at 9 | http://opensource.org/licenses/bsd-license.php 10 | 11 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 | 14 | File Name: BaseTypes.h 15 | 16 | */ 17 | 18 | #ifndef __BASE_TYPES_H__ 19 | #define __BASE_TYPES_H__ 20 | 21 | // 22 | // Include processor specific binding 23 | // 24 | #include "ProcessorBind.h" 25 | #include 26 | 27 | #define CONST const 28 | #define STATIC static 29 | #define VOID void 30 | 31 | #ifndef TRUE 32 | #define TRUE ((BOOLEAN)(1==1)) 33 | #endif 34 | 35 | #ifndef FALSE 36 | #define FALSE ((BOOLEAN)(0==1)) 37 | #endif 38 | 39 | #ifndef NULL 40 | #define NULL ((VOID *) 0) 41 | #endif 42 | 43 | #define ERR_SUCCESS 0 44 | #define ERR_INVALID_PARAMETER 1 45 | #define ERR_BUFFER_TOO_SMALL 2 46 | #define ERR_OUT_OF_RESOURCES 3 47 | #define ERR_OUT_OF_MEMORY 4 48 | #define ERR_NOT_PATCHED 5 49 | #define ERR_FILE_OPEN 6 50 | #define ERR_FILE_READ 7 51 | #define ERR_FILE_WRITE 8 52 | 53 | #include 54 | #define ASSERT(x) assert(x) 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /Common/ProcessorBind.h: -------------------------------------------------------------------------------- 1 | /* Processor or Compiler specific defines and types. 2 | 3 | Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved. 4 | 5 | This program and the accompanying materials are licensed and made available 6 | under the terms and conditions of the BSD License which accompanies this 7 | distribution. The full text of the license may be found at: 8 | http://opensource.org/licenses/bsd-license.php 9 | 10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 | 13 | File Name: ProcessorBind.h 14 | 15 | */ 16 | 17 | #ifndef __PROCESSOR_BIND_H__ 18 | #define __PROCESSOR_BIND_H__ 19 | 20 | // 21 | // Make sure we are useing the correct packing rules 22 | // 23 | #ifndef __GNUC__ 24 | #pragma pack() 25 | #endif 26 | 27 | #include "stdint.h" 28 | typedef uint8_t BOOLEAN; 29 | typedef int8_t INT8; 30 | typedef uint8_t UINT8; 31 | typedef int16_t INT16; 32 | typedef uint16_t UINT16; 33 | typedef int32_t INT32; 34 | typedef uint32_t UINT32; 35 | typedef int64_t INT64; 36 | typedef uint64_t UINT64; 37 | typedef char CHAR8; 38 | typedef uint16_t CHAR16; 39 | 40 | #if _MSC_EXTENSIONS 41 | // 42 | // Microsoft* compiler requires _EFIAPI useage, __cdecl is Microsoft* specific C. 43 | // 44 | #define EFIAPI __cdecl 45 | #endif 46 | 47 | #if __GNUC__ 48 | #define EFIAPI __attribute__((cdecl)) 49 | #endif 50 | 51 | // 52 | // The Microsoft* C compiler can removed references to unreferenced data items 53 | // if the /OPT:REF linker option is used. We defined a macro as this is a 54 | // a non standard extension 55 | // 56 | #if _MSC_EXTENSIONS 57 | #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany) 58 | #else 59 | #define GLOBAL_REMOVE_IF_UNREFERENCED 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /Tiano/TianoCompress.h: -------------------------------------------------------------------------------- 1 | /* Tiano Compress Header 2 | 3 | Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | Module Name: 13 | 14 | TianoCompress.h 15 | 16 | Abstract: 17 | 18 | Header file for compression routine. 19 | 20 | */ 21 | 22 | #ifndef _TIANOCOMPRESS_H_ 23 | #define _TIANOCOMPRESS_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "../Common/BaseTypes.h" 29 | 30 | /*++ 31 | 32 | Routine Description: 33 | 34 | Tiano compression routine. 35 | 36 | Arguments: 37 | 38 | SrcBuffer - The buffer storing the source data 39 | SrcSize - The size of source data 40 | DstBuffer - The buffer to store the compressed data 41 | DstSize - On input, the size of DstBuffer; On output, 42 | the size of the actual compressed data. 43 | 44 | Returns: 45 | 46 | EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. this case, 47 | DstSize contains the size needed. 48 | EFI_SUCCESS - Compression is successful. 49 | EFI_OUT_OF_RESOURCES - No resource to complete function. 50 | EFI_INVALID_PARAMETER - Parameter supplied is wrong. 51 | 52 | --*/ 53 | INT32 54 | TianoCompress ( 55 | UINT8 *SrcBuffer, 56 | UINT32 SrcSize, 57 | UINT8 *DstBuffer, 58 | UINT32 *DstSize 59 | ) 60 | ; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/Bra.h: -------------------------------------------------------------------------------- 1 | /* Bra.h -- Branch converters for executables 2 | 2009-02-07 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __BRA_H 5 | #define __BRA_H 6 | 7 | #include "Types.h" 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | /* 14 | These functions convert relative addresses to absolute addresses 15 | in CALL instructions to increase the compression ratio. 16 | 17 | In: 18 | data - data buffer 19 | size - size of data 20 | ip - current virtual Instruction Pinter (IP) value 21 | state - state variable for x86 converter 22 | encoding - 0 (for decoding), 1 (for encoding) 23 | 24 | Out: 25 | state - state variable for x86 converter 26 | 27 | Returns: 28 | The number of processed bytes. If you call these functions with multiple calls, 29 | you must start next call with first byte after block of processed bytes. 30 | 31 | Type Endian Alignment LookAhead 32 | 33 | x86 little 1 4 34 | ARMT little 2 2 35 | ARM little 4 0 36 | PPC big 4 0 37 | SPARC big 4 0 38 | IA64 little 16 0 39 | 40 | size must be >= Alignment + LookAhead, if it's not last block. 41 | If (size < Alignment + LookAhead), converter returns 0. 42 | 43 | Example: 44 | 45 | UInt32 ip = 0; 46 | for () 47 | { 48 | ; size must be >= Alignment + LookAhead, if it's not last block 49 | SizeT processed = Convert(data, size, ip, 1); 50 | data += processed; 51 | size -= processed; 52 | ip += processed; 53 | } 54 | */ 55 | 56 | #define x86_Convert_Init(state) { state = 0; } 57 | SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); 58 | SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 59 | SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 60 | SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 61 | SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 62 | SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/LzHash.h: -------------------------------------------------------------------------------- 1 | /* LzHash.h -- HASH functions for LZ algorithms 2 | 2009-02-07 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZ_HASH_H 5 | #define __LZ_HASH_H 6 | 7 | #define kHash2Size (1 << 10) 8 | #define kHash3Size (1 << 16) 9 | #define kHash4Size (1 << 20) 10 | 11 | #define kFix3HashSize (kHash2Size) 12 | #define kFix4HashSize (kHash2Size + kHash3Size) 13 | #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) 14 | 15 | #define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); 16 | 17 | #define HASH3_CALC { \ 18 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 19 | hash2Value = temp & (kHash2Size - 1); \ 20 | hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } 21 | 22 | #define HASH4_CALC { \ 23 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 24 | hash2Value = temp & (kHash2Size - 1); \ 25 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 26 | hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } 27 | 28 | #define HASH5_CALC { \ 29 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 30 | hash2Value = temp & (kHash2Size - 1); \ 31 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 32 | hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ 33 | hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ 34 | hash4Value &= (kHash4Size - 1); } 35 | 36 | /* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ 37 | #define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; 38 | 39 | 40 | #define MT_HASH2_CALC \ 41 | hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); 42 | 43 | #define MT_HASH3_CALC { \ 44 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 45 | hash2Value = temp & (kHash2Size - 1); \ 46 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } 47 | 48 | #define MT_HASH4_CALC { \ 49 | UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 50 | hash2Value = temp & (kHash2Size - 1); \ 51 | hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 52 | hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/Bra86.c: -------------------------------------------------------------------------------- 1 | /* Bra86.c -- Converter for x86 code (BCJ) 2 | 2008-10-04 : Igor Pavlov : Public domain */ 3 | 4 | #include "Bra.h" 5 | 6 | #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) 7 | 8 | const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; 9 | const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; 10 | 11 | SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) 12 | { 13 | SizeT bufferPos = 0, prevPosT; 14 | UInt32 prevMask = *state & 0x7; 15 | if (size < 5) 16 | return 0; 17 | ip += 5; 18 | prevPosT = (SizeT)0 - 1; 19 | 20 | for (;;) 21 | { 22 | Byte *p = data + bufferPos; 23 | Byte *limit = data + size - 4; 24 | for (; p < limit; p++) 25 | if ((*p & 0xFE) == 0xE8) 26 | break; 27 | bufferPos = (SizeT)(p - data); 28 | if (p >= limit) 29 | break; 30 | prevPosT = bufferPos - prevPosT; 31 | if (prevPosT > 3) 32 | prevMask = 0; 33 | else 34 | { 35 | prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; 36 | if (prevMask != 0) 37 | { 38 | Byte b = p[4 - kMaskToBitNumber[prevMask]]; 39 | if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) 40 | { 41 | prevPosT = bufferPos; 42 | prevMask = ((prevMask << 1) & 0x7) | 1; 43 | bufferPos++; 44 | continue; 45 | } 46 | } 47 | } 48 | prevPosT = bufferPos; 49 | 50 | if (Test86MSByte(p[4])) 51 | { 52 | UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); 53 | UInt32 dest; 54 | for (;;) 55 | { 56 | Byte b; 57 | int index; 58 | if (encoding) 59 | dest = (ip + (UInt32)bufferPos) + src; 60 | else 61 | dest = src - (ip + (UInt32)bufferPos); 62 | if (prevMask == 0) 63 | break; 64 | index = kMaskToBitNumber[prevMask] * 8; 65 | b = (Byte)(dest >> (24 - index)); 66 | if (!Test86MSByte(b)) 67 | break; 68 | src = dest ^ ((1 << (32 - index)) - 1); 69 | } 70 | p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); 71 | p[3] = (Byte)(dest >> 16); 72 | p[2] = (Byte)(dest >> 8); 73 | p[1] = (Byte)dest; 74 | bufferPos += 5; 75 | } 76 | else 77 | { 78 | prevMask = ((prevMask << 1) & 0x7) | 1; 79 | bufferPos++; 80 | } 81 | } 82 | prevPosT = bufferPos - prevPosT; 83 | *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); 84 | return bufferPos; 85 | } 86 | -------------------------------------------------------------------------------- /Tiano/TianoDecompress.h: -------------------------------------------------------------------------------- 1 | /* Tiano Decompress Header 2 | 3 | Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | Module Name: 13 | 14 | TianoDecompress.h 15 | 16 | Abstract: 17 | 18 | Header file for compression routine 19 | 20 | */ 21 | 22 | #ifndef _TIANODECOMPRESS_H 23 | #define _TIANODECOMPRESS_H 24 | 25 | #include "../Common/BaseTypes.h" 26 | 27 | INT32 28 | TianoGetInfo ( 29 | VOID *Source, 30 | UINT32 SrcSize, 31 | UINT32 *DstSize, 32 | UINT32 *ScratchSize 33 | ); 34 | /* 35 | 36 | Routine Description: 37 | 38 | The implementation Tiano Decompress GetInfo(). 39 | 40 | Arguments: 41 | 42 | Source - The source buffer containing the compressed data. 43 | SrcSize - The size of source buffer 44 | DstSize - The size of destination buffer. 45 | ScratchSize - The size of scratch buffer. 46 | 47 | Returns: 48 | 49 | EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. 50 | EFI_INVALID_PARAMETER - The source data is corrupted 51 | 52 | */ 53 | 54 | INT32 55 | TianoDecompress ( 56 | VOID *Source, 57 | UINT32 SrcSize, 58 | VOID *Destination, 59 | UINT32 DstSize, 60 | VOID *Scratch, 61 | UINT32 ScratchSize 62 | ); 63 | /* 64 | 65 | Routine Description: 66 | 67 | The implementation of Tiano Decompress(). 68 | 69 | Arguments: 70 | 71 | Source - The source buffer containing the compressed data. 72 | SrcSize - The size of source buffer 73 | Destination - The destination buffer to store the decompressed data 74 | DstSize - The size of destination buffer. 75 | Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. 76 | ScratchSize - The size of scratch buffer. 77 | 78 | Returns: 79 | 80 | EFI_SUCCESS - Decompression is successfull 81 | EFI_INVALID_PARAMETER - The source data is corrupted 82 | 83 | */ 84 | #endif 85 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* PMPatch 2 | 3 | Copyright (c) 2012, Nikolaj Schlej. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include "patch.h" 18 | 19 | int main(int argc, char* argv[]) 20 | { 21 | FILE* file; 22 | char* inputfile; 23 | char* outputfile; 24 | UINT8* buffer; 25 | size_t filesize; 26 | size_t read; 27 | 28 | printf("PMPatch 0.5.14\n"); 29 | if(argc < 3) 30 | { 31 | printf("This program patches UEFI BIOS files\nto be compatible with Mac OS X SpeedStep implementation\n\n" 32 | "Usage: PMPatch INFILE OUTFILE\n\n"); 33 | return ERR_INVALID_PARAMETER; 34 | } 35 | 36 | inputfile = argv[1]; 37 | outputfile = argv[2]; 38 | 39 | // Opening input file 40 | file = fopen(inputfile, "rb"); 41 | if (!file) 42 | { 43 | perror("Can't open input file.\n"); 44 | return ERR_FILE_OPEN; 45 | } 46 | 47 | // Determining file size 48 | fseek(file, 0, SEEK_END); 49 | filesize = ftell(file); 50 | fseek(file, 0, SEEK_SET); 51 | 52 | // Allocating memory for buffer 53 | buffer = (UINT8*)malloc(filesize); 54 | if (!buffer) 55 | { 56 | fprintf(stderr, "Can't allocate memory for buffer.\n"); 57 | return ERR_OUT_OF_MEMORY; 58 | } 59 | 60 | // Reading whole file to buffer 61 | read = fread((void*)buffer, sizeof(char), filesize, file); 62 | if (read != filesize) 63 | { 64 | perror("Can't read input file.\n"); 65 | return ERR_FILE_READ; 66 | } 67 | 68 | // Closing input file 69 | fclose(file); 70 | 71 | // Patching BIOS 72 | if(!patch_bios(buffer, (UINT32)filesize)) 73 | return ERR_NOT_PATCHED; 74 | 75 | 76 | // Creating output file 77 | file = fopen(outputfile, "wb"); 78 | if (!file) 79 | { 80 | perror("Can't create output file.\n"); 81 | return ERR_FILE_OPEN; 82 | } 83 | 84 | // Writing modified BIOS file 85 | if(fwrite(buffer, sizeof(char), filesize, file) != filesize) 86 | { 87 | perror("Can't write output file.\n"); 88 | return ERR_FILE_WRITE; 89 | } 90 | 91 | // Closing output file 92 | fclose(file); 93 | printf("Output file generated.\n"); 94 | 95 | return ERR_SUCCESS; 96 | } 97 | -------------------------------------------------------------------------------- /LZMA/LzmaCompress.c: -------------------------------------------------------------------------------- 1 | /* LZMA Compress Implementation 2 | 3 | Copyright (c) 2012, Nikolaj Schlej. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #include "LzmaCompress.h" 15 | #include "Sdk/C/7zVersion.h" 16 | #include "Sdk/C/LzmaEnc.h" 17 | 18 | #include 19 | 20 | #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) 21 | 22 | static void * AllocForLzma(void *p, size_t size) { return malloc(size); } 23 | static void FreeForLzma(void *p, void *address) { free(address); } 24 | static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma }; 25 | 26 | SRes OnProgress(void *p, UInt64 inSize, UInt64 outSize) 27 | { 28 | return SZ_OK; 29 | } 30 | 31 | static ICompressProgress g_ProgressCallback = { &OnProgress }; 32 | 33 | STATIC 34 | UINT64 35 | EFIAPI 36 | RShiftU64 ( 37 | UINT64 Operand, 38 | UINT32 Count 39 | ) 40 | { 41 | return Operand >> Count; 42 | } 43 | 44 | VOID 45 | SetEncodedSizeOfBuf( 46 | UINT64 EncodedSize, 47 | UINT8 *EncodedData 48 | ) 49 | { 50 | INT32 Index; 51 | 52 | EncodedData[LZMA_PROPS_SIZE] = EncodedSize & 0xFF; 53 | for (Index = LZMA_PROPS_SIZE+1; Index <= LZMA_PROPS_SIZE + 7; Index++) 54 | { 55 | EncodedSize = RShiftU64(EncodedSize, 8); 56 | EncodedData[Index] = EncodedSize & 0xFF; 57 | } 58 | } 59 | 60 | INT32 61 | EFIAPI 62 | LzmaCompress ( 63 | CONST VOID *Source, 64 | UINT32 SourceSize, 65 | VOID *Destination, 66 | UINT32 *DestinationSize 67 | ) 68 | { 69 | SRes LzmaResult; 70 | CLzmaEncProps props; 71 | SizeT propsSize = LZMA_PROPS_SIZE; 72 | SizeT destLen = SourceSize + SourceSize / 3 + 128; 73 | 74 | if (*DestinationSize < destLen) 75 | { 76 | *DestinationSize = destLen; 77 | return ERR_BUFFER_TOO_SMALL; 78 | } 79 | 80 | LzmaEncProps_Init(&props); 81 | props.dictSize = LZMA_DICTIONARY_SIZE; 82 | props.level = 9; 83 | props.fb = 273; 84 | 85 | LzmaResult = LzmaEncode( 86 | (Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE), 87 | &destLen, 88 | Source, 89 | SourceSize, 90 | &props, 91 | (UINT8*)Destination, 92 | &propsSize, 93 | props.writeEndMark, 94 | &g_ProgressCallback, 95 | &SzAllocForLzma, 96 | &SzAllocForLzma); 97 | 98 | *DestinationSize = destLen + LZMA_HEADER_SIZE; 99 | 100 | SetEncodedSizeOfBuf((UINT64)SourceSize, Destination); 101 | 102 | if (LzmaResult == SZ_OK) { 103 | return ERR_SUCCESS; 104 | } else { 105 | return ERR_INVALID_PARAMETER; 106 | } 107 | } 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/LzmaEnc.h: -------------------------------------------------------------------------------- 1 | /* LzmaEnc.h -- LZMA Encoder 2 | 2009-02-07 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZMA_ENC_H 5 | #define __LZMA_ENC_H 6 | 7 | #include "Types.h" 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #define LZMA_PROPS_SIZE 5 14 | 15 | typedef struct _CLzmaEncProps 16 | { 17 | int level; /* 0 <= level <= 9 */ 18 | UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version 19 | (1 << 12) <= dictSize <= (1 << 30) for 64-bit version 20 | default = (1 << 24) */ 21 | int lc; /* 0 <= lc <= 8, default = 3 */ 22 | int lp; /* 0 <= lp <= 4, default = 0 */ 23 | int pb; /* 0 <= pb <= 4, default = 2 */ 24 | int algo; /* 0 - fast, 1 - normal, default = 1 */ 25 | int fb; /* 5 <= fb <= 273, default = 32 */ 26 | int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ 27 | int numHashBytes; /* 2, 3 or 4, default = 4 */ 28 | UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ 29 | unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ 30 | int numThreads; /* 1 or 2, default = 2 */ 31 | } CLzmaEncProps; 32 | 33 | void LzmaEncProps_Init(CLzmaEncProps *p); 34 | void LzmaEncProps_Normalize(CLzmaEncProps *p); 35 | UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); 36 | 37 | 38 | /* ---------- CLzmaEncHandle Interface ---------- */ 39 | 40 | /* LzmaEnc_* functions can return the following exit codes: 41 | Returns: 42 | SZ_OK - OK 43 | SZ_ERROR_MEM - Memory allocation error 44 | SZ_ERROR_PARAM - Incorrect paramater in props 45 | SZ_ERROR_WRITE - Write callback error. 46 | SZ_ERROR_PROGRESS - some break from progress callback 47 | SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) 48 | */ 49 | 50 | typedef void * CLzmaEncHandle; 51 | 52 | CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); 53 | void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); 54 | SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); 55 | SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); 56 | SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, 57 | ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 58 | SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 59 | int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 60 | 61 | /* ---------- One Call Interface ---------- */ 62 | 63 | /* LzmaEncode 64 | Return code: 65 | SZ_OK - OK 66 | SZ_ERROR_MEM - Memory allocation error 67 | SZ_ERROR_PARAM - Incorrect paramater 68 | SZ_ERROR_OUTPUT_EOF - output buffer overflow 69 | SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) 70 | */ 71 | 72 | SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 73 | const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, 74 | ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /LZMA/LzmaDecompress.h: -------------------------------------------------------------------------------- 1 | /* LZMA Decompress Header 2 | 3 | Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #ifndef __LZMADECOMPRESS_H__ 15 | #define __LZMADECOMPRESS_H__ 16 | 17 | #include "../Common/BaseTypes.h" 18 | 19 | UINT64 20 | EFIAPI 21 | LShiftU64 ( 22 | UINT64 Operand, 23 | UINT32 Count 24 | ); 25 | 26 | /* 27 | Given a Lzma compressed source buffer, this function retrieves the size of 28 | the uncompressed buffer and the size of the scratch buffer required 29 | to decompress the compressed source buffer. 30 | 31 | Retrieves the size of the uncompressed buffer and the temporary scratch buffer 32 | required to decompress the buffer specified by Source and SourceSize. 33 | The size of the uncompressed buffer is returned DestinationSize, 34 | the size of the scratch buffer is returned ScratchSize, and RETURN_SUCCESS is returned. 35 | This function does not have scratch buffer available to perform a thorough 36 | checking of the validity of the source data. It just retrieves the "Original Size" 37 | field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize. 38 | And ScratchSize is specific to the decompression implementation. 39 | 40 | If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT(). 41 | 42 | @param Source The source buffer containing the compressed data. 43 | @param SourceSize The size, bytes, of the source buffer. 44 | @param DestinationSize A pointer to the size, bytes, of the uncompressed buffer 45 | that will be generated when the compressed buffer specified 46 | by Source and SourceSize is decompressed. 47 | 48 | @retval EFI_SUCCESS The size of the uncompressed data was returned 49 | DestinationSize and the size of the scratch 50 | buffer was returned ScratchSize. 51 | 52 | */ 53 | INT32 54 | EFIAPI 55 | LzmaGetInfo ( 56 | CONST VOID *Source, 57 | UINT32 SourceSize, 58 | UINT32 *DestinationSize 59 | ); 60 | 61 | /* 62 | Decompresses a Lzma compressed source buffer. 63 | 64 | Extracts decompressed data to its original form. 65 | If the compressed source data specified by Source is successfully decompressed 66 | into Destination, then RETURN_SUCCESS is returned. If the compressed source data 67 | specified by Source is not a valid compressed data format, 68 | then RETURN_INVALID_PARAMETER is returned. 69 | 70 | @param Source The source buffer containing the compressed data. 71 | @param SourceSize The size of source buffer. 72 | @param Destination The destination buffer to store the decompressed data 73 | 74 | @retval EFI_SUCCESS Decompression completed successfully, and 75 | the uncompressed buffer is returned Destination. 76 | @retval EFI_INVALID_PARAMETER 77 | The source buffer specified by Source is corrupted 78 | (not a valid compressed format). 79 | */ 80 | INT32 81 | EFIAPI 82 | LzmaDecompress ( 83 | CONST VOID *Source, 84 | UINT32 SourceSize, 85 | VOID *Destination 86 | ); 87 | 88 | #endif 89 | 90 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/LzFind.h: -------------------------------------------------------------------------------- 1 | /* LzFind.h -- Match finder for LZ algorithms 2 | 2009-04-22 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZ_FIND_H 5 | #define __LZ_FIND_H 6 | 7 | #include "Types.h" 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | typedef UInt32 CLzRef; 14 | 15 | typedef struct _CMatchFinder 16 | { 17 | Byte *buffer; 18 | UInt32 pos; 19 | UInt32 posLimit; 20 | UInt32 streamPos; 21 | UInt32 lenLimit; 22 | 23 | UInt32 cyclicBufferPos; 24 | UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ 25 | 26 | UInt32 matchMaxLen; 27 | CLzRef *hash; 28 | CLzRef *son; 29 | UInt32 hashMask; 30 | UInt32 cutValue; 31 | 32 | Byte *bufferBase; 33 | ISeqInStream *stream; 34 | int streamEndWasReached; 35 | 36 | UInt32 blockSize; 37 | UInt32 keepSizeBefore; 38 | UInt32 keepSizeAfter; 39 | 40 | UInt32 numHashBytes; 41 | int directInput; 42 | size_t directInputRem; 43 | int btMode; 44 | int bigHash; 45 | UInt32 historySize; 46 | UInt32 fixedHashSize; 47 | UInt32 hashSizeSum; 48 | UInt32 numSons; 49 | SRes result; 50 | UInt32 crc[256]; 51 | } CMatchFinder; 52 | 53 | #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) 54 | #define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) 55 | 56 | #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) 57 | 58 | int MatchFinder_NeedMove(CMatchFinder *p); 59 | Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); 60 | void MatchFinder_MoveBlock(CMatchFinder *p); 61 | void MatchFinder_ReadIfRequired(CMatchFinder *p); 62 | 63 | void MatchFinder_Construct(CMatchFinder *p); 64 | 65 | /* Conditions: 66 | historySize <= 3 GB 67 | keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB 68 | */ 69 | int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, 70 | UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, 71 | ISzAlloc *alloc); 72 | void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); 73 | void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); 74 | void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); 75 | 76 | UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, 77 | UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, 78 | UInt32 *distances, UInt32 maxLen); 79 | 80 | /* 81 | Conditions: 82 | Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. 83 | Mf_GetPointerToCurrentPos_Func's result must be used only before any other function 84 | */ 85 | 86 | typedef void (*Mf_Init_Func)(void *object); 87 | typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); 88 | typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); 89 | typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); 90 | typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); 91 | typedef void (*Mf_Skip_Func)(void *object, UInt32); 92 | 93 | typedef struct _IMatchFinder 94 | { 95 | Mf_Init_Func Init; 96 | Mf_GetIndexByte_Func GetIndexByte; 97 | Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; 98 | Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; 99 | Mf_GetMatches_Func GetMatches; 100 | Mf_Skip_Func Skip; 101 | } IMatchFinder; 102 | 103 | void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); 104 | 105 | void MatchFinder_Init(CMatchFinder *p); 106 | UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); 107 | UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); 108 | void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); 109 | void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); 110 | 111 | #ifdef __cplusplus 112 | } 113 | #endif 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/CpuArch.h: -------------------------------------------------------------------------------- 1 | /* CpuArch.h -- CPU specific code 2 | 2010-10-26: Igor Pavlov : Public domain */ 3 | 4 | #ifndef __CPU_ARCH_H 5 | #define __CPU_ARCH_H 6 | 7 | #include "Types.h" 8 | 9 | EXTERN_C_BEGIN 10 | 11 | /* 12 | MY_CPU_LE means that CPU is LITTLE ENDIAN. 13 | If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). 14 | 15 | MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. 16 | If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. 17 | */ 18 | 19 | #if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) 20 | #define MY_CPU_AMD64 21 | #endif 22 | 23 | #if defined(MY_CPU_AMD64) || defined(_M_IA64) 24 | #define MY_CPU_64BIT 25 | #endif 26 | 27 | #if defined(_M_IX86) || defined(__i386__) 28 | #define MY_CPU_X86 29 | #endif 30 | 31 | #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) 32 | #define MY_CPU_X86_OR_AMD64 33 | #endif 34 | 35 | #if defined(MY_CPU_X86) || defined(_M_ARM) 36 | #define MY_CPU_32BIT 37 | #endif 38 | 39 | #if defined(_WIN32) && defined(_M_ARM) 40 | #define MY_CPU_ARM_LE 41 | #endif 42 | 43 | #if defined(_WIN32) && defined(_M_IA64) 44 | #define MY_CPU_IA64_LE 45 | #endif 46 | 47 | #if defined(MY_CPU_X86_OR_AMD64) 48 | #define MY_CPU_LE_UNALIGN 49 | #endif 50 | 51 | #if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) 52 | #define MY_CPU_LE 53 | #endif 54 | 55 | #if defined(__BIG_ENDIAN__) 56 | #define MY_CPU_BE 57 | #endif 58 | 59 | #if defined(MY_CPU_LE) && defined(MY_CPU_BE) 60 | Stop_Compiling_Bad_Endian 61 | #endif 62 | 63 | #ifdef MY_CPU_LE_UNALIGN 64 | 65 | #define GetUi16(p) (*(const UInt16 *)(p)) 66 | #define GetUi32(p) (*(const UInt32 *)(p)) 67 | #define GetUi64(p) (*(const UInt64 *)(p)) 68 | #define SetUi16(p, d) *(UInt16 *)(p) = (d); 69 | #define SetUi32(p, d) *(UInt32 *)(p) = (d); 70 | #define SetUi64(p, d) *(UInt64 *)(p) = (d); 71 | 72 | #else 73 | 74 | #define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) 75 | 76 | #define GetUi32(p) ( \ 77 | ((const Byte *)(p))[0] | \ 78 | ((UInt32)((const Byte *)(p))[1] << 8) | \ 79 | ((UInt32)((const Byte *)(p))[2] << 16) | \ 80 | ((UInt32)((const Byte *)(p))[3] << 24)) 81 | 82 | #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) 83 | 84 | #define SetUi16(p, d) { UInt32 _x_ = (d); \ 85 | ((Byte *)(p))[0] = (Byte)_x_; \ 86 | ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } 87 | 88 | #define SetUi32(p, d) { UInt32 _x_ = (d); \ 89 | ((Byte *)(p))[0] = (Byte)_x_; \ 90 | ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ 91 | ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ 92 | ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } 93 | 94 | #define SetUi64(p, d) { UInt64 _x64_ = (d); \ 95 | SetUi32(p, (UInt32)_x64_); \ 96 | SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } 97 | 98 | #endif 99 | 100 | #if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) 101 | 102 | #pragma intrinsic(_byteswap_ulong) 103 | #pragma intrinsic(_byteswap_uint64) 104 | #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) 105 | #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) 106 | 107 | #else 108 | 109 | #define GetBe32(p) ( \ 110 | ((UInt32)((const Byte *)(p))[0] << 24) | \ 111 | ((UInt32)((const Byte *)(p))[1] << 16) | \ 112 | ((UInt32)((const Byte *)(p))[2] << 8) | \ 113 | ((const Byte *)(p))[3] ) 114 | 115 | #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) 116 | 117 | #endif 118 | 119 | #define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) 120 | 121 | 122 | #ifdef MY_CPU_X86_OR_AMD64 123 | 124 | typedef struct 125 | { 126 | UInt32 maxFunc; 127 | UInt32 vendor[3]; 128 | UInt32 ver; 129 | UInt32 b; 130 | UInt32 c; 131 | UInt32 d; 132 | } Cx86cpuid; 133 | 134 | enum 135 | { 136 | CPU_FIRM_INTEL, 137 | CPU_FIRM_AMD, 138 | CPU_FIRM_VIA 139 | }; 140 | 141 | Bool x86cpuid_CheckAndRead(Cx86cpuid *p); 142 | int x86cpuid_GetFirm(const Cx86cpuid *p); 143 | 144 | #define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) 145 | #define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) 146 | #define x86cpuid_GetStepping(p) ((p)->ver & 0xF) 147 | 148 | Bool CPU_Is_InOrder(); 149 | Bool CPU_Is_Aes_Supported(); 150 | 151 | #endif 152 | 153 | EXTERN_C_END 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /LZMA/LzmaDecompress.c: -------------------------------------------------------------------------------- 1 | /* LZMA Decompress Implementation 2 | 3 | Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #include "LzmaDecompress.h" 15 | #include "Sdk/C/Types.h" 16 | #include "Sdk/C/7zVersion.h" 17 | #include "Sdk/C/LzmaDec.h" 18 | 19 | #include 20 | 21 | UINT64 22 | EFIAPI 23 | LShiftU64 ( 24 | UINT64 Operand, 25 | UINT32 Count 26 | ) 27 | { 28 | return Operand << Count; 29 | } 30 | 31 | static void * AllocForLzma(void *p, size_t size) { return malloc(size); } 32 | static void FreeForLzma(void *p, void *address) { free(address); } 33 | static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma }; 34 | 35 | #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) 36 | 37 | /* 38 | Get the size of the uncompressed buffer by parsing EncodeData header. 39 | 40 | @param EncodedData Pointer to the compressed data. 41 | 42 | @return The size of the uncompressed buffer. 43 | */ 44 | UINT64 45 | GetDecodedSizeOfBuf( 46 | UINT8 *EncodedData 47 | ) 48 | { 49 | UINT64 DecodedSize; 50 | INT32 Index; 51 | 52 | // Parse header 53 | DecodedSize = 0; 54 | for (Index = LZMA_PROPS_SIZE + 7; Index >= LZMA_PROPS_SIZE; Index--) 55 | DecodedSize = LShiftU64(DecodedSize, 8) + EncodedData[Index]; 56 | 57 | return DecodedSize; 58 | } 59 | 60 | // 61 | // LZMA functions and data as defined local LzmaDecompressLibInternal.h 62 | // 63 | 64 | /* 65 | Given a Lzma compressed source buffer, this function retrieves the size of 66 | the uncompressed buffer and the size of the scratch buffer required 67 | to decompress the compressed source buffer. 68 | 69 | Retrieves the size of the uncompressed buffer and the temporary scratch buffer 70 | required to decompress the buffer specified by Source and SourceSize. 71 | The size of the uncompressed buffer is returned DestinationSize, 72 | the size of the scratch buffer is returned ScratchSize, and RETURN_SUCCESS is returned. 73 | This function does not have scratch buffer available to perform a thorough 74 | checking of the validity of the source data. It just retrieves the "Original Size" 75 | field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize. 76 | And ScratchSize is specific to the decompression implementation. 77 | 78 | If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT(). 79 | 80 | @param Source The source buffer containing the compressed data. 81 | @param SourceSize The size, bytes, of the source buffer. 82 | @param DestinationSize A pointer to the size, bytes, of the uncompressed buffer 83 | that will be generated when the compressed buffer specified 84 | by Source and SourceSize is decompressed. 85 | 86 | @retval EFI_SUCCESS The size of the uncompressed data was returned 87 | DestinationSize and the size of the scratch 88 | buffer was returned ScratchSize. 89 | 90 | */ 91 | INT32 92 | EFIAPI 93 | LzmaGetInfo ( 94 | CONST VOID *Source, 95 | UINT32 SourceSize, 96 | UINT32 *DestinationSize 97 | ) 98 | { 99 | UInt64 DecodedSize; 100 | 101 | ASSERT(SourceSize >= LZMA_HEADER_SIZE); 102 | 103 | DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source); 104 | 105 | *DestinationSize = (UINT32)DecodedSize; 106 | return ERR_SUCCESS; 107 | } 108 | 109 | /* 110 | Decompresses a Lzma compressed source buffer. 111 | 112 | Extracts decompressed data to its original form. 113 | If the compressed source data specified by Source is successfully decompressed 114 | into Destination, then RETURN_SUCCESS is returned. If the compressed source data 115 | specified by Source is not a valid compressed data format, 116 | then RETURN_INVALID_PARAMETER is returned. 117 | 118 | @param Source The source buffer containing the compressed data. 119 | @param SourceSize The size of source buffer. 120 | @param Destination The destination buffer to store the decompressed data 121 | 122 | @retval EFI_SUCCESS Decompression completed successfully, and 123 | the uncompressed buffer is returned Destination. 124 | @retval EFI_INVALID_PARAMETER 125 | The source buffer specified by Source is corrupted 126 | (not a valid compressed format). 127 | */ 128 | INT32 129 | EFIAPI 130 | LzmaDecompress ( 131 | CONST VOID *Source, 132 | UINT32 SourceSize, 133 | VOID *Destination 134 | ) 135 | { 136 | SRes LzmaResult; 137 | ELzmaStatus Status; 138 | SizeT DecodedBufSize; 139 | SizeT EncodedDataSize; 140 | 141 | DecodedBufSize = (SizeT)GetDecodedSizeOfBuf((UINT8*)Source); 142 | EncodedDataSize = (SizeT) (SourceSize - LZMA_HEADER_SIZE); 143 | 144 | LzmaResult = LzmaDecode( 145 | Destination, 146 | &DecodedBufSize, 147 | (Byte*)((UINT8*)Source + LZMA_HEADER_SIZE), 148 | &EncodedDataSize, 149 | Source, 150 | LZMA_PROPS_SIZE, 151 | LZMA_FINISH_END, 152 | &Status, 153 | &SzAllocForLzma 154 | ); 155 | 156 | if (LzmaResult == SZ_OK) { 157 | return ERR_SUCCESS; 158 | } else { 159 | return ERR_INVALID_PARAMETER; 160 | } 161 | } 162 | 163 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/Types.h: -------------------------------------------------------------------------------- 1 | /* Types.h -- Basic types 2 | 2010-10-09 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __7Z_TYPES_H 5 | #define __7Z_TYPES_H 6 | 7 | #include "../../UefiLzma.h" 8 | 9 | #include 10 | 11 | #ifdef _WIN32 12 | #include 13 | #endif 14 | 15 | #ifndef EXTERN_C_BEGIN 16 | #ifdef __cplusplus 17 | #define EXTERN_C_BEGIN extern "C" { 18 | #define EXTERN_C_END } 19 | #else 20 | #define EXTERN_C_BEGIN 21 | #define EXTERN_C_END 22 | #endif 23 | #endif 24 | 25 | EXTERN_C_BEGIN 26 | 27 | #define SZ_OK 0 28 | 29 | #define SZ_ERROR_DATA 1 30 | #define SZ_ERROR_MEM 2 31 | #define SZ_ERROR_CRC 3 32 | #define SZ_ERROR_UNSUPPORTED 4 33 | #define SZ_ERROR_PARAM 5 34 | #define SZ_ERROR_INPUT_EOF 6 35 | #define SZ_ERROR_OUTPUT_EOF 7 36 | #define SZ_ERROR_READ 8 37 | #define SZ_ERROR_WRITE 9 38 | #define SZ_ERROR_PROGRESS 10 39 | #define SZ_ERROR_FAIL 11 40 | #define SZ_ERROR_THREAD 12 41 | 42 | #define SZ_ERROR_ARCHIVE 16 43 | #define SZ_ERROR_NO_ARCHIVE 17 44 | 45 | typedef int SRes; 46 | 47 | #ifdef _WIN32 48 | typedef DWORD WRes; 49 | #else 50 | typedef int WRes; 51 | #endif 52 | 53 | #ifndef RINOK 54 | #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } 55 | #endif 56 | 57 | typedef unsigned char Byte; 58 | typedef short Int16; 59 | typedef unsigned short UInt16; 60 | 61 | #ifdef _LZMA_UINT32_IS_ULONG 62 | typedef long Int32; 63 | typedef unsigned long UInt32; 64 | #else 65 | typedef int Int32; 66 | typedef unsigned int UInt32; 67 | #endif 68 | 69 | #ifdef _SZ_NO_INT_64 70 | 71 | /* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. 72 | NOTES: Some code will work incorrectly in that case! */ 73 | 74 | typedef long Int64; 75 | typedef unsigned long UInt64; 76 | 77 | #else 78 | 79 | #if defined(_MSC_VER) || defined(__BORLANDC__) 80 | typedef __int64 Int64; 81 | typedef unsigned __int64 UInt64; 82 | #define UINT64_CONST(n) n 83 | #else 84 | typedef long long int Int64; 85 | typedef unsigned long long int UInt64; 86 | #define UINT64_CONST(n) n ## ULL 87 | #endif 88 | 89 | #endif 90 | 91 | #ifdef _LZMA_NO_SYSTEM_SIZE_T 92 | typedef UInt32 SizeT; 93 | #else 94 | typedef size_t SizeT; 95 | #endif 96 | 97 | typedef int Bool; 98 | #define True 1 99 | #define False 0 100 | 101 | 102 | #ifdef _WIN32 103 | #define MY_STD_CALL __stdcall 104 | #else 105 | #define MY_STD_CALL 106 | #endif 107 | 108 | #ifdef _MSC_VER 109 | 110 | #if _MSC_VER >= 1300 111 | #define MY_NO_INLINE __declspec(noinline) 112 | #else 113 | #define MY_NO_INLINE 114 | #endif 115 | 116 | #define MY_CDECL __cdecl 117 | #define MY_FAST_CALL __fastcall 118 | 119 | #else 120 | 121 | #define MY_CDECL 122 | #define MY_FAST_CALL 123 | 124 | #endif 125 | 126 | 127 | /* The following interfaces use first parameter as pointer to structure */ 128 | 129 | typedef struct 130 | { 131 | Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ 132 | } IByteIn; 133 | 134 | typedef struct 135 | { 136 | void (*Write)(void *p, Byte b); 137 | } IByteOut; 138 | 139 | typedef struct 140 | { 141 | SRes (*Read)(void *p, void *buf, size_t *size); 142 | /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. 143 | (output(*size) < input(*size)) is allowed */ 144 | } ISeqInStream; 145 | 146 | /* it can return SZ_ERROR_INPUT_EOF */ 147 | SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); 148 | SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); 149 | SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); 150 | 151 | typedef struct 152 | { 153 | size_t (*Write)(void *p, const void *buf, size_t size); 154 | /* Returns: result - the number of actually written bytes. 155 | (result < size) means error */ 156 | } ISeqOutStream; 157 | 158 | typedef enum 159 | { 160 | SZ_SEEK_SET = 0, 161 | SZ_SEEK_CUR = 1, 162 | SZ_SEEK_END = 2 163 | } ESzSeek; 164 | 165 | typedef struct 166 | { 167 | SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ 168 | SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); 169 | } ISeekInStream; 170 | 171 | typedef struct 172 | { 173 | SRes (*Look)(void *p, const void **buf, size_t *size); 174 | /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. 175 | (output(*size) > input(*size)) is not allowed 176 | (output(*size) < input(*size)) is allowed */ 177 | SRes (*Skip)(void *p, size_t offset); 178 | /* offset must be <= output(*size) of Look */ 179 | 180 | SRes (*Read)(void *p, void *buf, size_t *size); 181 | /* reads directly (without buffer). It's same as ISeqInStream::Read */ 182 | SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); 183 | } ILookInStream; 184 | 185 | SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); 186 | SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); 187 | 188 | /* reads via ILookInStream::Read */ 189 | SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); 190 | SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); 191 | 192 | #define LookToRead_BUF_SIZE (1 << 14) 193 | 194 | typedef struct 195 | { 196 | ILookInStream s; 197 | ISeekInStream *realStream; 198 | size_t pos; 199 | size_t size; 200 | Byte buf[LookToRead_BUF_SIZE]; 201 | } CLookToRead; 202 | 203 | void LookToRead_CreateVTable(CLookToRead *p, int lookahead); 204 | void LookToRead_Init(CLookToRead *p); 205 | 206 | typedef struct 207 | { 208 | ISeqInStream s; 209 | ILookInStream *realStream; 210 | } CSecToLook; 211 | 212 | void SecToLook_CreateVTable(CSecToLook *p); 213 | 214 | typedef struct 215 | { 216 | ISeqInStream s; 217 | ILookInStream *realStream; 218 | } CSecToRead; 219 | 220 | void SecToRead_CreateVTable(CSecToRead *p); 221 | 222 | typedef struct 223 | { 224 | SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); 225 | /* Returns: result. (result != SZ_OK) means break. 226 | Value (UInt64)(Int64)-1 for size means unknown value. */ 227 | } ICompressProgress; 228 | 229 | typedef struct 230 | { 231 | void *(*Alloc)(void *p, size_t size); 232 | void (*Free)(void *p, void *address); /* address can be 0 */ 233 | } ISzAlloc; 234 | 235 | #define IAlloc_Alloc(p, size) (p)->Alloc((p), size) 236 | #define IAlloc_Free(p, a) (p)->Free((p), a) 237 | 238 | #ifdef _WIN32 239 | 240 | #define CHAR_PATH_SEPARATOR '\\' 241 | #define WCHAR_PATH_SEPARATOR L'\\' 242 | #define STRING_PATH_SEPARATOR "\\" 243 | #define WSTRING_PATH_SEPARATOR L"\\" 244 | 245 | #else 246 | 247 | #define CHAR_PATH_SEPARATOR '/' 248 | #define WCHAR_PATH_SEPARATOR L'/' 249 | #define STRING_PATH_SEPARATOR "/" 250 | #define WSTRING_PATH_SEPARATOR L"/" 251 | 252 | #endif 253 | 254 | EXTERN_C_END 255 | 256 | #endif 257 | -------------------------------------------------------------------------------- /patch_int.h: -------------------------------------------------------------------------------- 1 | /* Patch Internal Header 2 | 3 | Copyright (c) 2012, Nikolaj Schlej. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #ifndef __PATCH_INT_H__ 15 | #define __PATCH_INT_H__ 16 | 17 | #include 18 | #include 19 | #include "Common/BaseTypes.h" 20 | #include "Tiano/TianoCompress.h" 21 | #include "Tiano/TianoDecompress.h" 22 | #include "LZMA/LzmaCompress.h" 23 | #include "LZMA/LzmaDecompress.h" 24 | #include "patch.h" 25 | 26 | #define UUID_LENGTH 16 27 | #define MODULE_ALLIGNMENT 8 28 | #define SECTION_ALLIGNMENT 4 29 | 30 | // Data structures 31 | #pragma pack(push, 1) 32 | // Common UEFI module header 33 | typedef struct { 34 | UINT8 guid[UUID_LENGTH]; 35 | UINT8 header_checksum; 36 | UINT8 data_checksum; 37 | UINT8 type; 38 | UINT8 attributes; 39 | UINT8 size[3]; 40 | UINT8 state; 41 | } module_header; 42 | // Gap module type, attributes and state 43 | #define TYPE_GAP 0xF0 44 | #define ATTRIBUTES_GAP 0x00 45 | #define STATE_STD 0xF8 46 | 47 | // Common section header 48 | typedef struct { 49 | UINT8 size[3]; 50 | UINT8 type; 51 | } common_section_header; 52 | // Compressed section type for nest module 53 | #define SECTION_COMPRESSED 0x01 54 | // GUID-defined section type for PowerManagement2.efi and SmmPlatform modules 55 | #define SECTION_GUID_DEFINED 0x02 56 | // DXE driver section type for PowerManagement and SmmPlatform modules 57 | #define SECTION_DXE_DEPEX 0x13 58 | 59 | // GUID-defined section header 60 | typedef struct { 61 | UINT8 size[3]; 62 | UINT8 type; 63 | UINT8 guid[16]; 64 | UINT16 data_offset; 65 | UINT16 attributes; 66 | } guid_section_header; 67 | 68 | // Compressed section header 69 | typedef struct { 70 | UINT8 size[3]; 71 | UINT8 type; 72 | UINT32 decompressed_size; 73 | UINT8 compression_type; 74 | } compressed_section_header; 75 | // Uncompressed data type 76 | #define COMPRESSION_NONE 0x00 77 | // Tiano compressed data type 78 | #define COMPRESSION_TIANO 0x01 79 | // LZMA compressed data type 80 | #define COMPRESSION_LZMA 0x02 81 | #pragma pack(pop) 82 | 83 | // Error codes 84 | #define ERR_PATCHED 0x00 85 | #define ERR_INVALID_ARGUMENT 0x01 86 | #define ERR_NOT_MODULE 0x02 87 | #define ERR_UNKNOWN_MODULE 0x03 88 | #define ERR_UNKNOWN_COMPRESSION_TYPE 0x04 89 | #define ERR_TIANO_DECOMPRESSION_FAILED 0x05 90 | #define ERR_LZMA_DECOMPRESSION_FAILED 0x06 91 | #define ERR_PATCH_STRING_NOT_FOUND 0x07 92 | #define ERR_TIANO_COMPRESSION_FAILED 0x08 93 | #define ERR_LZMA_COMPRESSION_FAILED 0x09 94 | #define ERR_PATCHED_MODULE_INSERTION_FAILED 0x0A 95 | #define ERR_MODULE_NOT_FOUND 0x0B 96 | #define ERR_MEMORY_ALLOCATION_FAILED 0x0C 97 | 98 | // UUIDs 99 | CONST UINT8 AMI_NEST_UUID[] = 100 | {0x2F,0x7C,0x71,0xAE,0x42,0x1A,0x2B,0x4F,0x88,0x61,0x78,0xB7,0x9C,0xA0,0x7E,0x07}; 101 | CONST UINT8 PHOENIX_NEST_UUID[] = 102 | {0x18,0x88,0x53,0x4A,0xE0,0x5A,0xB2,0x4E,0xB2,0xEB,0x48,0x8B,0x23,0x65,0x70,0x22}; 103 | CONST UINT8 POWERMANAGEMENT_UUID[] = 104 | {0x70,0x39,0x78,0x8C,0x2A,0xF0,0x4D,0x4A,0xAF,0x09,0x87,0x97,0xA5,0x1E,0xEC,0x8D}; 105 | CONST UINT8 POWERMGMTDXE_UUID[] = 106 | {0x4C,0x1B,0x73,0xF7,0xA2,0x58,0xF4,0x4D,0x89,0x80,0x56,0x45,0xD3,0x9E,0xCE,0x58}; 107 | CONST UINT8 SMMPLATFORM_UUID[] = 108 | {0x37,0x0A,0xC2,0x99,0x2A,0x04,0xE2,0x46,0x80,0xF4,0xE4,0x02,0x7F,0xDB,0xC8,0x6F}; 109 | CONST UINT8 CPUPEI_UUID[] = 110 | {0xA9,0xAF,0xB5,0x2B,0x33,0xFF,0x7B,0x41,0x84,0x97,0xCB,0x77,0x3C,0x2B,0x93,0xBF}; 111 | CONST UINT8 PLATFORMSETUPADVANCED_UUID[] = 112 | {0xC4,0x94,0xEF,0xCF,0x67,0x41,0x6A,0x46,0x88,0x93,0x87,0x79,0x45,0x9D,0xFA,0x86}; 113 | CONST UINT8 PHOENIX_RAW_FILE_UUID[] = 114 | {0x7F,0x36,0x3E,0xF3,0xD2,0x41,0x01,0x42,0x9C,0xB7,0xAF,0xA6,0x3D,0xCC,0xEE,0xC9}; 115 | CONST UINT8 GAP_UUID[] = 116 | {0x85,0x65,0x53,0xE4,0x09,0x79,0x60,0x4A,0xB5,0xC6,0xEC,0xDE,0xA6,0xEB,0xFB,0x54}; 117 | 118 | // PowerManagement patch 119 | CONST UINT8 POWERMANAGEMENT_PATCH_PATTERN[] = 120 | {0x75,0x08,0x0F,0xBA,0xE8,0x0F,0x89,0x44,0x24,0x30}; 121 | CONST UINT8 POWERMANAGEMENT_PATCH_PATTERN_80FB01[] = 122 | {0x80,0xFB,0x01,0x75,0x08,0x0F,0xBA,0xE8,0x0F,0x89,0x44,0x24,0x30}; 123 | CONST UINT8 POWERMANAGEMENT_PATCHED_PATTERNS[][10] = { 124 | {0xEB,0x08,0x0F,0xBA,0xE8,0x0F,0x89,0x44,0x24,0x30}, 125 | {0xEB,0x08,0x0F,0xBA,0xE8,0x0F,0x90,0x90,0x90,0x90}, 126 | {0xEB,0x08,0x90,0x90,0x90,0x90,0x89,0x44,0x24,0x30}, 127 | {0xEB,0x08,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}, 128 | {0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}, 129 | }; 130 | CONST UINT8 PATCHED_PATTERNS_COUNT = 131 | sizeof(POWERMANAGEMENT_PATCHED_PATTERNS)/sizeof(POWERMANAGEMENT_PATCHED_PATTERNS[0]); 132 | 133 | // SmmPlatform patch 134 | CONST UINT8 SMMPLATFORM_PATCH_PATTERN[] = 135 | {0x48,0x0F,0xBA,0xE0,0x0F,0x72,0x12,0x48,0x0F,0xBA,0xE8,0x0F,0xB9,0xE2,0x00,0x00,0x00}; 136 | CONST UINT8 SMMPLATFORM_PATCHED_PATTERN[] = 137 | {0x48,0x0F,0xBA,0xE0,0x0F,0xEB,0x12,0x48,0x0F,0xBA,0xE8,0x0F,0xB9,0xE2,0x00,0x00,0x00}; 138 | 139 | // CpuPei patch 140 | CONST UINT8 CPUPEI_PATCH_PATTERN[] = 141 | {0x80,0x00,0x18,0xEB,0x05,0x0D,0x00,0x80}; 142 | CONST UINT8 CPUPEI_PATCHED_PATTERN[] = 143 | {0x00,0x00,0x18,0xEB,0x05,0x0D,0x00,0x00}; 144 | 145 | // Phoenix SCT 2.0 PlatformSetupAdvancedDxe patch to unlock additional BIOS settings 146 | CONST UINT8 PLATFORMSETUPADVANCED_PATCH_PATTERN[] = 147 | {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x0A}; 148 | CONST UINT8 PLATFORMSETUPADVANCED_PATCHED_PATTERN[] = 149 | {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0x0A}; 150 | CONST UINT8 PLATFORMSETUPADVANCED_UNICODE_PATCH_PATTERN[] = 151 | {0x00,0x14,0x42,0x00,0x65,0x00,0x6C,0x00,0x6F,0x00,0x77,0x00,0x20,0x00,0x69,0x00, 152 | 0x73,0x00,0x20,0x00,0x72,0x00,0x65,0x00,0x73,0x00,0x65,0x00,0x72,0x00,0x76,0x00, 153 | 0x65,0x00,0x64,0x00,0x20,0x00,0x66,0x00,0x6F,0x00,0x72,0x00,0x20,0x00,0x52,0x00, 154 | 0x44,0x00,0x2C,0x00,0x20,0x00,0x6E,0x00,0x6F,0x00,0x74,0x00,0x20,0x00,0x44,0x00, 155 | 0x45,0x00,0x4C,0x00,0x4C,0x00,0x4F,0x00,0x49,0x00,0x4C,0x00,0x20,0x00,0x72,0x00, 156 | 0x65,0x00,0x71,0x00,0x75,0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x2E,0x00,0x00,0x00}; 157 | CONST UINT8 PLATFORMSETUPADVANCED_UNICODE_PATCHED_PATTERN[] = 158 | {0x00,0x14,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00, 159 | 0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00, 160 | 0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00, 161 | 0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00, 162 | 0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00, 163 | 0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00}; 164 | 165 | #endif -------------------------------------------------------------------------------- /LZMA/Sdk/C/LzmaDec.h: -------------------------------------------------------------------------------- 1 | /* LzmaDec.h -- LZMA Decoder 2 | 2009-02-07 : Igor Pavlov : Public domain */ 3 | 4 | #ifndef __LZMA_DEC_H 5 | #define __LZMA_DEC_H 6 | 7 | #include "Types.h" 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | /* #define _LZMA_PROB32 */ 14 | /* _LZMA_PROB32 can increase the speed on some CPUs, 15 | but memory usage for CLzmaDec::probs will be doubled in that case */ 16 | 17 | #ifdef _LZMA_PROB32 18 | #define CLzmaProb UInt32 19 | #else 20 | #define CLzmaProb UInt16 21 | #endif 22 | 23 | 24 | /* ---------- LZMA Properties ---------- */ 25 | 26 | #define LZMA_PROPS_SIZE 5 27 | 28 | typedef struct _CLzmaProps 29 | { 30 | unsigned lc, lp, pb; 31 | UInt32 dicSize; 32 | } CLzmaProps; 33 | 34 | /* LzmaProps_Decode - decodes properties 35 | Returns: 36 | SZ_OK 37 | SZ_ERROR_UNSUPPORTED - Unsupported properties 38 | */ 39 | 40 | SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); 41 | 42 | 43 | /* ---------- LZMA Decoder state ---------- */ 44 | 45 | /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. 46 | Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ 47 | 48 | #define LZMA_REQUIRED_INPUT_MAX 20 49 | 50 | typedef struct 51 | { 52 | CLzmaProps prop; 53 | CLzmaProb *probs; 54 | Byte *dic; 55 | const Byte *buf; 56 | UInt32 range, code; 57 | SizeT dicPos; 58 | SizeT dicBufSize; 59 | UInt32 processedPos; 60 | UInt32 checkDicSize; 61 | unsigned state; 62 | UInt32 reps[4]; 63 | unsigned remainLen; 64 | int needFlush; 65 | int needInitState; 66 | UInt32 numProbs; 67 | unsigned tempBufSize; 68 | Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; 69 | } CLzmaDec; 70 | 71 | #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } 72 | 73 | void LzmaDec_Init(CLzmaDec *p); 74 | 75 | /* There are two types of LZMA streams: 76 | 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. 77 | 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ 78 | 79 | typedef enum 80 | { 81 | LZMA_FINISH_ANY, /* finish at any point */ 82 | LZMA_FINISH_END /* block must be finished at the end */ 83 | } ELzmaFinishMode; 84 | 85 | /* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! 86 | 87 | You must use LZMA_FINISH_END, when you know that current output buffer 88 | covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. 89 | 90 | If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, 91 | and output value of destLen will be less than output buffer size limit. 92 | You can check status result also. 93 | 94 | You can use multiple checks to test data integrity after full decompression: 95 | 1) Check Result and "status" variable. 96 | 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. 97 | 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. 98 | You must use correct finish mode in that case. */ 99 | 100 | typedef enum 101 | { 102 | LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ 103 | LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ 104 | LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ 105 | LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ 106 | LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ 107 | } ELzmaStatus; 108 | 109 | /* ELzmaStatus is used only as output value for function call */ 110 | 111 | 112 | /* ---------- Interfaces ---------- */ 113 | 114 | /* There are 3 levels of interfaces: 115 | 1) Dictionary Interface 116 | 2) Buffer Interface 117 | 3) One Call Interface 118 | You can select any of these interfaces, but don't mix functions from different 119 | groups for same object. */ 120 | 121 | 122 | /* There are two variants to allocate state for Dictionary Interface: 123 | 1) LzmaDec_Allocate / LzmaDec_Free 124 | 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs 125 | You can use variant 2, if you set dictionary buffer manually. 126 | For Buffer Interface you must always use variant 1. 127 | 128 | LzmaDec_Allocate* can return: 129 | SZ_OK 130 | SZ_ERROR_MEM - Memory allocation error 131 | SZ_ERROR_UNSUPPORTED - Unsupported properties 132 | */ 133 | 134 | SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); 135 | void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); 136 | 137 | SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); 138 | void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); 139 | 140 | /* ---------- Dictionary Interface ---------- */ 141 | 142 | /* You can use it, if you want to eliminate the overhead for data copying from 143 | dictionary to some other external buffer. 144 | You must work with CLzmaDec variables directly in this interface. 145 | 146 | STEPS: 147 | LzmaDec_Constr() 148 | LzmaDec_Allocate() 149 | for (each new stream) 150 | { 151 | LzmaDec_Init() 152 | while (it needs more decompression) 153 | { 154 | LzmaDec_DecodeToDic() 155 | use data from CLzmaDec::dic and update CLzmaDec::dicPos 156 | } 157 | } 158 | LzmaDec_Free() 159 | */ 160 | 161 | /* LzmaDec_DecodeToDic 162 | 163 | The decoding to internal dictionary buffer (CLzmaDec::dic). 164 | You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! 165 | 166 | finishMode: 167 | It has meaning only if the decoding reaches output limit (dicLimit). 168 | LZMA_FINISH_ANY - Decode just dicLimit bytes. 169 | LZMA_FINISH_END - Stream must be finished after dicLimit. 170 | 171 | Returns: 172 | SZ_OK 173 | status: 174 | LZMA_STATUS_FINISHED_WITH_MARK 175 | LZMA_STATUS_NOT_FINISHED 176 | LZMA_STATUS_NEEDS_MORE_INPUT 177 | LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 178 | SZ_ERROR_DATA - Data error 179 | */ 180 | 181 | SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, 182 | const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); 183 | 184 | 185 | /* ---------- Buffer Interface ---------- */ 186 | 187 | /* It's zlib-like interface. 188 | See LzmaDec_DecodeToDic description for information about STEPS and return results, 189 | but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need 190 | to work with CLzmaDec variables manually. 191 | 192 | finishMode: 193 | It has meaning only if the decoding reaches output limit (*destLen). 194 | LZMA_FINISH_ANY - Decode just destLen bytes. 195 | LZMA_FINISH_END - Stream must be finished after (*destLen). 196 | */ 197 | 198 | SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, 199 | const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); 200 | 201 | 202 | /* ---------- One Call Interface ---------- */ 203 | 204 | /* LzmaDecode 205 | 206 | finishMode: 207 | It has meaning only if the decoding reaches output limit (*destLen). 208 | LZMA_FINISH_ANY - Decode just destLen bytes. 209 | LZMA_FINISH_END - Stream must be finished after (*destLen). 210 | 211 | Returns: 212 | SZ_OK 213 | status: 214 | LZMA_STATUS_FINISHED_WITH_MARK 215 | LZMA_STATUS_NOT_FINISHED 216 | LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 217 | SZ_ERROR_DATA - Data error 218 | SZ_ERROR_MEM - Memory allocation error 219 | SZ_ERROR_UNSUPPORTED - Unsupported properties 220 | SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). 221 | */ 222 | 223 | SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 224 | const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 225 | ELzmaStatus *status, ISzAlloc *alloc); 226 | 227 | #ifdef __cplusplus 228 | } 229 | #endif 230 | 231 | #endif 232 | -------------------------------------------------------------------------------- /Tiano/TianoDecompress.c: -------------------------------------------------------------------------------- 1 | /* Tiano Decompress Implementation 2 | 3 | Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | Module Name: 13 | 14 | TianoDecompress.c 15 | 16 | Abstract: 17 | 18 | Decompressor. Algorithm Ported from OPSD code (Decomp.asm) 19 | for Tiano compress algorithm. 20 | 21 | --*/ 22 | 23 | #include 24 | #include 25 | #include "TianoDecompress.h" 26 | 27 | // 28 | // Decompression algorithm begins here 29 | // 30 | #define BITBUFSIZ 32 31 | #define MAXMATCH 256 32 | #define THRESHOLD 3 33 | #define CODE_BIT 16 34 | #define BAD_TABLE - 1 35 | 36 | // 37 | // C: Char&Len Set; P: Position Set; T: exTra Set 38 | // 39 | #define NC (0xff + MAXMATCH + 2 - THRESHOLD) 40 | #define CBIT 9 41 | #define EFIPBIT 4 42 | #define MAXPBIT 5 43 | #define TBIT 5 44 | #define MAXNP ((1U << MAXPBIT) - 1) 45 | #define NT (CODE_BIT + 3) 46 | #if NT > MAXNP 47 | #define NPT NT 48 | #else 49 | #define NPT MAXNP 50 | #endif 51 | 52 | typedef struct { 53 | UINT8 *mSrcBase; // Starting address of compressed data 54 | UINT8 *mDstBase; // Starting address of decompressed data 55 | UINT32 mOutBuf; 56 | UINT32 mInBuf; 57 | 58 | UINT16 mBitCount; 59 | UINT32 mBitBuf; 60 | UINT32 mSubBitBuf; 61 | UINT16 mBlockSize; 62 | UINT32 mCompSize; 63 | UINT32 mOrigSize; 64 | 65 | UINT16 mBadTableFlag; 66 | 67 | UINT16 mLeft[2 * NC - 1]; 68 | UINT16 mRight[2 * NC - 1]; 69 | UINT8 mCLen[NC]; 70 | UINT8 mPTLen[NPT]; 71 | UINT16 mCTable[4096]; 72 | UINT16 mPTTable[256]; 73 | } SCRATCH_DATA; 74 | 75 | STATIC UINT16 mPbit = EFIPBIT; 76 | 77 | STATIC 78 | VOID 79 | FillBuf ( 80 | SCRATCH_DATA *Sd, 81 | UINT16 NumOfBits 82 | ) 83 | /*++ 84 | 85 | Routine Description: 86 | 87 | Shift mBitBuf NumOfBits left. Read NumOfBits of bits from source. 88 | 89 | Arguments: 90 | 91 | Sd - The global scratch data 92 | NumOfBit - The number of bits to shift and read. 93 | 94 | Returns: (VOID) 95 | 96 | --*/ 97 | { 98 | Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits); 99 | 100 | while (NumOfBits > Sd->mBitCount) { 101 | 102 | Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount))); 103 | 104 | if (Sd->mCompSize > 0) { 105 | // 106 | // Get 1 byte into SubBitBuf 107 | // 108 | Sd->mCompSize--; 109 | Sd->mSubBitBuf = 0; 110 | Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++]; 111 | Sd->mBitCount = 8; 112 | 113 | } else { 114 | // 115 | // No more bits from the source, just pad zero bit. 116 | // 117 | Sd->mSubBitBuf = 0; 118 | Sd->mBitCount = 8; 119 | 120 | } 121 | } 122 | 123 | Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits); 124 | Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount; 125 | } 126 | 127 | STATIC 128 | UINT32 129 | GetBits ( 130 | SCRATCH_DATA *Sd, 131 | UINT16 NumOfBits 132 | ) 133 | /*++ 134 | 135 | Routine Description: 136 | 137 | Get NumOfBits of bits from mBitBuf. Fill mBitBuf with subsequent 138 | NumOfBits of bits from source. Returns NumOfBits of bits that are 139 | popped out. 140 | 141 | Arguments: 142 | 143 | Sd - The global scratch data. 144 | NumOfBits - The number of bits to pop and read. 145 | 146 | Returns: 147 | 148 | The bits that are popped out. 149 | 150 | --*/ 151 | { 152 | UINT32 OutBits; 153 | 154 | OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits)); 155 | 156 | FillBuf (Sd, NumOfBits); 157 | 158 | return OutBits; 159 | } 160 | 161 | STATIC 162 | UINT16 163 | MakeTable ( 164 | SCRATCH_DATA *Sd, 165 | UINT16 NumOfChar, 166 | UINT8 *BitLen, 167 | UINT16 TableBits, 168 | UINT16 *Table 169 | ) 170 | /*++ 171 | 172 | Routine Description: 173 | 174 | Creates Huffman Code mapping table according to code length array. 175 | 176 | Arguments: 177 | 178 | Sd - The global scratch data 179 | NumOfChar - Number of symbols the symbol set 180 | BitLen - Code length array 181 | TableBits - The width of the mapping table 182 | Table - The table 183 | 184 | Returns: 185 | 186 | 0 - OK. 187 | BAD_TABLE - The table is corrupted. 188 | 189 | --*/ 190 | { 191 | UINT16 Count[17]; 192 | UINT16 Weight[17]; 193 | UINT16 Start[18]; 194 | UINT16 *Pointer; 195 | UINT16 Index3; 196 | UINT16 Index; 197 | UINT16 Len; 198 | UINT16 Char; 199 | UINT16 JuBits; 200 | UINT16 Avail; 201 | UINT16 NextCode; 202 | UINT16 Mask; 203 | 204 | for (Index = 1; Index <= 16; Index++) { 205 | Count[Index] = 0; 206 | } 207 | 208 | for (Index = 0; Index < NumOfChar; Index++) { 209 | Count[BitLen[Index]]++; 210 | } 211 | 212 | Start[1] = 0; 213 | 214 | for (Index = 1; Index <= 16; Index++) { 215 | Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index))); 216 | } 217 | 218 | if (Start[17] != 0) { 219 | //(1U << 16) 220 | return (UINT16) BAD_TABLE; 221 | } 222 | 223 | JuBits = (UINT16) (16 - TableBits); 224 | 225 | for (Index = 1; Index <= TableBits; Index++) { 226 | Start[Index] >>= JuBits; 227 | Weight[Index] = (UINT16) (1U << (TableBits - Index)); 228 | } 229 | 230 | while (Index <= 16) { 231 | Weight[Index] = (UINT16) (1U << (16 - Index)); 232 | Index++; 233 | } 234 | 235 | Index = (UINT16) (Start[TableBits + 1] >> JuBits); 236 | 237 | if (Index != 0) { 238 | Index3 = (UINT16) (1U << TableBits); 239 | while (Index != Index3) { 240 | Table[Index++] = 0; 241 | } 242 | } 243 | 244 | Avail = NumOfChar; 245 | Mask = (UINT16) (1U << (15 - TableBits)); 246 | 247 | for (Char = 0; Char < NumOfChar; Char++) { 248 | 249 | Len = BitLen[Char]; 250 | if (Len == 0) { 251 | continue; 252 | } 253 | 254 | NextCode = (UINT16) (Start[Len] + Weight[Len]); 255 | 256 | if (Len <= TableBits) { 257 | 258 | for (Index = Start[Len]; Index < NextCode; Index++) { 259 | Table[Index] = Char; 260 | } 261 | 262 | } else { 263 | 264 | Index3 = Start[Len]; 265 | Pointer = &Table[Index3 >> JuBits]; 266 | Index = (UINT16) (Len - TableBits); 267 | 268 | while (Index != 0) { 269 | if (*Pointer == 0) { 270 | Sd->mRight[Avail] = Sd->mLeft[Avail] = 0; 271 | *Pointer = Avail++; 272 | } 273 | 274 | if (Index3 & Mask) { 275 | Pointer = &Sd->mRight[*Pointer]; 276 | } else { 277 | Pointer = &Sd->mLeft[*Pointer]; 278 | } 279 | 280 | Index3 <<= 1; 281 | Index--; 282 | } 283 | 284 | *Pointer = Char; 285 | 286 | } 287 | 288 | Start[Len] = NextCode; 289 | } 290 | // 291 | // Succeeds 292 | // 293 | return 0; 294 | } 295 | 296 | STATIC 297 | UINT32 298 | DecodeP ( 299 | SCRATCH_DATA *Sd 300 | ) 301 | /*++ 302 | 303 | Routine Description: 304 | 305 | Decodes a position value. 306 | 307 | Arguments: 308 | 309 | Sd - the global scratch data 310 | 311 | Returns: 312 | 313 | The position value decoded. 314 | 315 | --*/ 316 | { 317 | UINT16 Val; 318 | UINT32 Mask; 319 | UINT32 Pos; 320 | 321 | Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; 322 | 323 | if (Val >= MAXNP) { 324 | Mask = 1U << (BITBUFSIZ - 1 - 8); 325 | 326 | do { 327 | 328 | if (Sd->mBitBuf & Mask) { 329 | Val = Sd->mRight[Val]; 330 | } else { 331 | Val = Sd->mLeft[Val]; 332 | } 333 | 334 | Mask >>= 1; 335 | } while (Val >= MAXNP); 336 | } 337 | // 338 | // Advance what we have read 339 | // 340 | FillBuf (Sd, Sd->mPTLen[Val]); 341 | 342 | Pos = Val; 343 | if (Val > 1) { 344 | Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1))); 345 | } 346 | 347 | return Pos; 348 | } 349 | 350 | STATIC 351 | UINT16 352 | ReadPTLen ( 353 | SCRATCH_DATA *Sd, 354 | UINT16 nn, 355 | UINT16 nbit, 356 | UINT16 Special 357 | ) 358 | /*++ 359 | 360 | Routine Description: 361 | 362 | Reads code lengths for the Extra Set or the Position Set 363 | 364 | Arguments: 365 | 366 | Sd - The global scratch data 367 | nn - Number of symbols 368 | nbit - Number of bits needed to represent nn 369 | Special - The special symbol that needs to be taken care of 370 | 371 | Returns: 372 | 373 | 0 - OK. 374 | BAD_TABLE - Table is corrupted. 375 | 376 | --*/ 377 | { 378 | UINT16 Number; 379 | UINT16 CharC; 380 | UINT16 Index; 381 | UINT32 Mask; 382 | 383 | Number = (UINT16) GetBits (Sd, nbit); 384 | 385 | if (Number == 0) { 386 | CharC = (UINT16) GetBits (Sd, nbit); 387 | 388 | for (Index = 0; Index < 256; Index++) { 389 | Sd->mPTTable[Index] = CharC; 390 | } 391 | 392 | for (Index = 0; Index < nn; Index++) { 393 | Sd->mPTLen[Index] = 0; 394 | } 395 | 396 | return 0; 397 | } 398 | 399 | Index = 0; 400 | 401 | while (Index < Number) { 402 | 403 | CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3)); 404 | 405 | if (CharC == 7) { 406 | Mask = 1U << (BITBUFSIZ - 1 - 3); 407 | while (Mask & Sd->mBitBuf) { 408 | Mask >>= 1; 409 | CharC += 1; 410 | } 411 | } 412 | 413 | FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3)); 414 | 415 | Sd->mPTLen[Index++] = (UINT8) CharC; 416 | 417 | if (Index == Special) { 418 | CharC = (UINT16) GetBits (Sd, 2); 419 | CharC--; 420 | while ((INT16) (CharC) >= 0) { 421 | Sd->mPTLen[Index++] = 0; 422 | CharC--; 423 | } 424 | } 425 | } 426 | 427 | while (Index < nn) { 428 | Sd->mPTLen[Index++] = 0; 429 | } 430 | 431 | return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable); 432 | } 433 | 434 | STATIC 435 | VOID 436 | ReadCLen ( 437 | SCRATCH_DATA *Sd 438 | ) 439 | /*++ 440 | 441 | Routine Description: 442 | 443 | Reads code lengths for Char&Len Set. 444 | 445 | Arguments: 446 | 447 | Sd - the global scratch data 448 | 449 | Returns: (VOID) 450 | 451 | --*/ 452 | { 453 | UINT16 Number; 454 | UINT16 CharC; 455 | UINT16 Index; 456 | UINT32 Mask; 457 | 458 | Number = (UINT16) GetBits (Sd, CBIT); 459 | 460 | if (Number == 0) { 461 | CharC = (UINT16) GetBits (Sd, CBIT); 462 | 463 | for (Index = 0; Index < NC; Index++) { 464 | Sd->mCLen[Index] = 0; 465 | } 466 | 467 | for (Index = 0; Index < 4096; Index++) { 468 | Sd->mCTable[Index] = CharC; 469 | } 470 | 471 | return ; 472 | } 473 | 474 | Index = 0; 475 | while (Index < Number) { 476 | 477 | CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; 478 | if (CharC >= NT) { 479 | Mask = 1U << (BITBUFSIZ - 1 - 8); 480 | 481 | do { 482 | 483 | if (Mask & Sd->mBitBuf) { 484 | CharC = Sd->mRight[CharC]; 485 | } else { 486 | CharC = Sd->mLeft[CharC]; 487 | } 488 | 489 | Mask >>= 1; 490 | 491 | } while (CharC >= NT); 492 | } 493 | // 494 | // Advance what we have read 495 | // 496 | FillBuf (Sd, Sd->mPTLen[CharC]); 497 | 498 | if (CharC <= 2) { 499 | 500 | if (CharC == 0) { 501 | CharC = 1; 502 | } else if (CharC == 1) { 503 | CharC = (UINT16) (GetBits (Sd, 4) + 3); 504 | } else if (CharC == 2) { 505 | CharC = (UINT16) (GetBits (Sd, CBIT) + 20); 506 | } 507 | 508 | CharC--; 509 | while ((INT16) (CharC) >= 0) { 510 | Sd->mCLen[Index++] = 0; 511 | CharC--; 512 | } 513 | 514 | } else { 515 | 516 | Sd->mCLen[Index++] = (UINT8) (CharC - 2); 517 | 518 | } 519 | } 520 | 521 | while (Index < NC) { 522 | Sd->mCLen[Index++] = 0; 523 | } 524 | 525 | MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable); 526 | 527 | return ; 528 | } 529 | 530 | STATIC 531 | UINT16 532 | DecodeC ( 533 | SCRATCH_DATA *Sd 534 | ) 535 | /*++ 536 | 537 | Routine Description: 538 | 539 | Decode a character/length value. 540 | 541 | Arguments: 542 | 543 | Sd - The global scratch data. 544 | 545 | Returns: 546 | 547 | The value decoded. 548 | 549 | --*/ 550 | { 551 | UINT16 Index2; 552 | UINT32 Mask; 553 | 554 | if (Sd->mBlockSize == 0) { 555 | // 556 | // Starting a new block 557 | // 558 | Sd->mBlockSize = (UINT16) GetBits (Sd, 16); 559 | Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3); 560 | if (Sd->mBadTableFlag != 0) { 561 | return 0; 562 | } 563 | 564 | ReadCLen (Sd); 565 | 566 | Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, mPbit, (UINT16) (-1)); 567 | if (Sd->mBadTableFlag != 0) { 568 | return 0; 569 | } 570 | } 571 | 572 | Sd->mBlockSize--; 573 | Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)]; 574 | 575 | if (Index2 >= NC) { 576 | Mask = 1U << (BITBUFSIZ - 1 - 12); 577 | 578 | do { 579 | if (Sd->mBitBuf & Mask) { 580 | Index2 = Sd->mRight[Index2]; 581 | } else { 582 | Index2 = Sd->mLeft[Index2]; 583 | } 584 | 585 | Mask >>= 1; 586 | } while (Index2 >= NC); 587 | } 588 | // 589 | // Advance what we have read 590 | // 591 | FillBuf (Sd, Sd->mCLen[Index2]); 592 | 593 | return Index2; 594 | } 595 | 596 | STATIC 597 | VOID 598 | Decode ( 599 | SCRATCH_DATA *Sd 600 | ) 601 | /*++ 602 | 603 | Routine Description: 604 | 605 | Decode the source data and put the resulting data into the destination buffer. 606 | 607 | Arguments: 608 | 609 | Sd - The global scratch data 610 | 611 | Returns: (VOID) 612 | 613 | --*/ 614 | { 615 | UINT16 BytesRemain; 616 | UINT32 DataIdx; 617 | UINT16 CharC; 618 | 619 | for (;;) { 620 | CharC = DecodeC (Sd); 621 | if (Sd->mBadTableFlag != 0) { 622 | return ; 623 | } 624 | 625 | if (CharC < 256) { 626 | // 627 | // Process an Original character 628 | // 629 | Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC; 630 | if (Sd->mOutBuf >= Sd->mOrigSize) { 631 | return ; 632 | } 633 | 634 | } else { 635 | // 636 | // Process a Pointer 637 | // 638 | CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD)); 639 | 640 | BytesRemain= CharC; 641 | 642 | DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1; 643 | 644 | BytesRemain--; 645 | while ((INT16) (BytesRemain) >= 0) { 646 | Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++]; 647 | if (Sd->mOutBuf >= Sd->mOrigSize) { 648 | return ; 649 | } 650 | 651 | BytesRemain--; 652 | } 653 | } 654 | } 655 | 656 | return ; 657 | } 658 | 659 | INT32 660 | GetInfo ( 661 | VOID *Source, 662 | UINT32 SrcSize, 663 | UINT32 *DstSize, 664 | UINT32 *ScratchSize 665 | ) 666 | /*++ 667 | 668 | Routine Description: 669 | 670 | The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo(). 671 | 672 | Arguments: 673 | 674 | Source - The source buffer containing the compressed data. 675 | SrcSize - The size of source buffer 676 | DstSize - The size of destination buffer. 677 | ScratchSize - The size of scratch buffer. 678 | 679 | Returns: 680 | 681 | EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. 682 | EFI_INVALID_PARAMETER - The source data is corrupted 683 | 684 | --*/ 685 | { 686 | UINT8 *Src; 687 | 688 | *ScratchSize = sizeof (SCRATCH_DATA); 689 | 690 | Src = Source; 691 | if (SrcSize < 8) { 692 | return ERR_INVALID_PARAMETER; 693 | } 694 | 695 | *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); 696 | return ERR_SUCCESS; 697 | } 698 | 699 | INT32 700 | Decompress ( 701 | VOID *Source, 702 | UINT32 SrcSize, 703 | VOID *Destination, 704 | UINT32 DstSize, 705 | VOID *Scratch, 706 | UINT32 ScratchSize 707 | ) 708 | /*++ 709 | 710 | Routine Description: 711 | 712 | The implementation Efi and Tiano Decompress(). 713 | 714 | Arguments: 715 | 716 | Source - The source buffer containing the compressed data. 717 | SrcSize - The size of source buffer 718 | Destination - The destination buffer to store the decompressed data 719 | DstSize - The size of destination buffer. 720 | Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. 721 | ScratchSize - The size of scratch buffer. 722 | 723 | Returns: 724 | 725 | EFI_SUCCESS - Decompression is successfull 726 | EFI_INVALID_PARAMETER - The source data is corrupted 727 | 728 | --*/ 729 | { 730 | UINT32 Index; 731 | UINT32 CompSize; 732 | UINT32 OrigSize; 733 | INT32 Status; 734 | SCRATCH_DATA *Sd; 735 | UINT8 *Src; 736 | UINT8 *Dst; 737 | 738 | Status = ERR_SUCCESS; 739 | Src = Source; 740 | Dst = Destination; 741 | 742 | if (ScratchSize < sizeof (SCRATCH_DATA)) { 743 | return ERR_INVALID_PARAMETER; 744 | } 745 | 746 | Sd = (SCRATCH_DATA *) Scratch; 747 | 748 | if (SrcSize < 8) { 749 | return ERR_INVALID_PARAMETER; 750 | } 751 | 752 | CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24); 753 | OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); 754 | 755 | if (SrcSize < CompSize + 8) { 756 | return ERR_INVALID_PARAMETER; 757 | } 758 | 759 | if (DstSize != OrigSize) { 760 | return ERR_INVALID_PARAMETER; 761 | } 762 | 763 | Src = Src + 8; 764 | 765 | for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) { 766 | ((UINT8 *) Sd)[Index] = 0; 767 | } 768 | 769 | Sd->mSrcBase = Src; 770 | Sd->mDstBase = Dst; 771 | Sd->mCompSize = CompSize; 772 | Sd->mOrigSize = OrigSize; 773 | 774 | // 775 | // Fill the first BITBUFSIZ bits 776 | // 777 | FillBuf (Sd, BITBUFSIZ); 778 | 779 | // 780 | // Decompress it 781 | // 782 | Decode (Sd); 783 | 784 | if (Sd->mBadTableFlag != 0) { 785 | // 786 | // Something wrong with the source 787 | // 788 | Status = ERR_INVALID_PARAMETER; 789 | } 790 | 791 | return Status; 792 | } 793 | 794 | INT32 795 | TianoGetInfo ( 796 | VOID *Source, 797 | UINT32 SrcSize, 798 | UINT32 *DstSize, 799 | UINT32 *ScratchSize 800 | ) 801 | /*++ 802 | 803 | Routine Description: 804 | 805 | The implementation Tiano Decompress GetInfo(). 806 | 807 | Arguments: 808 | 809 | Source - The source buffer containing the compressed data. 810 | SrcSize - The size of source buffer 811 | DstSize - The size of destination buffer. 812 | ScratchSize - The size of scratch buffer. 813 | 814 | Returns: 815 | 816 | EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. 817 | EFI_INVALID_PARAMETER - The source data is corrupted 818 | 819 | --*/ 820 | { 821 | return GetInfo (Source, SrcSize, DstSize, ScratchSize); 822 | } 823 | 824 | 825 | INT32 826 | TianoDecompress ( 827 | VOID *Source, 828 | UINT32 SrcSize, 829 | VOID *Destination, 830 | UINT32 DstSize, 831 | VOID *Scratch, 832 | UINT32 ScratchSize 833 | ) 834 | /*++ 835 | 836 | Routine Description: 837 | 838 | The implementation of Tiano Decompress(). 839 | 840 | Arguments: 841 | 842 | Source - The source buffer containing the compressed data. 843 | SrcSize - The size of source buffer 844 | Destination - The destination buffer to store the decompressed data 845 | DstSize - The size of destination buffer. 846 | Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. 847 | ScratchSize - The size of scratch buffer. 848 | 849 | Returns: 850 | 851 | EFI_SUCCESS - Decompression is successfull 852 | EFI_INVALID_PARAMETER - The source data is corrupted 853 | 854 | --*/ 855 | { 856 | mPbit = MAXPBIT; 857 | return Decompress (Source, SrcSize, Destination, DstSize, Scratch, ScratchSize); 858 | } 859 | 860 | 861 | 862 | 863 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/LzFind.c: -------------------------------------------------------------------------------- 1 | /* LzFind.c -- Match finder for LZ algorithms 2 | 2009-04-22 : Igor Pavlov : Public doma*/ 3 | 4 | #include 5 | 6 | #include "LzFind.h" 7 | #include "LzHash.h" 8 | 9 | #define kEmptyHashValue 0 10 | #define kMaxValForNormalize ((UInt32)0xFFFFFFFF) 11 | #define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ 12 | #define kNormalizeMask (~(kNormalizeStepMin - 1)) 13 | #define kMaxHistorySize ((UInt32)3 << 30) 14 | 15 | #define kStartMaxLen 3 16 | 17 | static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) 18 | { 19 | if (!p->directInput) 20 | { 21 | alloc->Free(alloc, p->bufferBase); 22 | p->bufferBase = 0; 23 | } 24 | } 25 | 26 | /* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ 27 | 28 | static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) 29 | { 30 | UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; 31 | if (p->directInput) 32 | { 33 | p->blockSize = blockSize; 34 | return 1; 35 | } 36 | if (p->bufferBase == 0 || p->blockSize != blockSize) 37 | { 38 | LzInWindow_Free(p, alloc); 39 | p->blockSize = blockSize; 40 | p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); 41 | } 42 | return (p->bufferBase != 0); 43 | } 44 | 45 | Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } 46 | Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } 47 | 48 | UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } 49 | 50 | void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) 51 | { 52 | p->posLimit -= subValue; 53 | p->pos -= subValue; 54 | p->streamPos -= subValue; 55 | } 56 | 57 | static void MatchFinder_ReadBlock(CMatchFinder *p) 58 | { 59 | if (p->streamEndWasReached || p->result != SZ_OK) 60 | return; 61 | if (p->directInput) 62 | { 63 | UInt32 curSize = 0xFFFFFFFF - p->streamPos; 64 | if (curSize > p->directInputRem) 65 | curSize = (UInt32)p->directInputRem; 66 | p->directInputRem -= curSize; 67 | p->streamPos += curSize; 68 | if (p->directInputRem == 0) 69 | p->streamEndWasReached = 1; 70 | return; 71 | } 72 | for (;;) 73 | { 74 | Byte *dest = p->buffer + (p->streamPos - p->pos); 75 | size_t size = (p->bufferBase + p->blockSize - dest); 76 | if (size == 0) 77 | return; 78 | p->result = p->stream->Read(p->stream, dest, &size); 79 | if (p->result != SZ_OK) 80 | return; 81 | if (size == 0) 82 | { 83 | p->streamEndWasReached = 1; 84 | return; 85 | } 86 | p->streamPos += (UInt32)size; 87 | if (p->streamPos - p->pos > p->keepSizeAfter) 88 | return; 89 | } 90 | } 91 | 92 | void MatchFinder_MoveBlock(CMatchFinder *p) 93 | { 94 | memmove(p->bufferBase, 95 | p->buffer - p->keepSizeBefore, 96 | (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); 97 | p->buffer = p->bufferBase + p->keepSizeBefore; 98 | } 99 | 100 | int MatchFinder_NeedMove(CMatchFinder *p) 101 | { 102 | if (p->directInput) 103 | return 0; 104 | /* if (p->streamEndWasReached) return 0; */ 105 | return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); 106 | } 107 | 108 | void MatchFinder_ReadIfRequired(CMatchFinder *p) 109 | { 110 | if (p->streamEndWasReached) 111 | return; 112 | if (p->keepSizeAfter >= p->streamPos - p->pos) 113 | MatchFinder_ReadBlock(p); 114 | } 115 | 116 | static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) 117 | { 118 | if (MatchFinder_NeedMove(p)) 119 | MatchFinder_MoveBlock(p); 120 | MatchFinder_ReadBlock(p); 121 | } 122 | 123 | static void MatchFinder_SetDefaultSettings(CMatchFinder *p) 124 | { 125 | p->cutValue = 32; 126 | p->btMode = 1; 127 | p->numHashBytes = 4; 128 | p->bigHash = 0; 129 | } 130 | 131 | #define kCrcPoly 0xEDB88320 132 | 133 | void MatchFinder_Construct(CMatchFinder *p) 134 | { 135 | UInt32 i; 136 | p->bufferBase = 0; 137 | p->directInput = 0; 138 | p->hash = 0; 139 | MatchFinder_SetDefaultSettings(p); 140 | 141 | for (i = 0; i < 256; i++) 142 | { 143 | UInt32 r = i; 144 | int j; 145 | for (j = 0; j < 8; j++) 146 | r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); 147 | p->crc[i] = r; 148 | } 149 | } 150 | 151 | static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) 152 | { 153 | alloc->Free(alloc, p->hash); 154 | p->hash = 0; 155 | } 156 | 157 | void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) 158 | { 159 | MatchFinder_FreeThisClassMemory(p, alloc); 160 | LzInWindow_Free(p, alloc); 161 | } 162 | 163 | static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) 164 | { 165 | size_t sizeInBytes = (size_t)num * sizeof(CLzRef); 166 | if (sizeInBytes / sizeof(CLzRef) != num) 167 | return 0; 168 | return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); 169 | } 170 | 171 | int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, 172 | UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, 173 | ISzAlloc *alloc) 174 | { 175 | UInt32 sizeReserv; 176 | if (historySize > kMaxHistorySize) 177 | { 178 | MatchFinder_Free(p, alloc); 179 | return 0; 180 | } 181 | sizeReserv = historySize >> 1; 182 | if (historySize > ((UInt32)2 << 30)) 183 | sizeReserv = historySize >> 2; 184 | sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); 185 | 186 | p->keepSizeBefore = historySize + keepAddBufferBefore + 1; 187 | p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; 188 | /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ 189 | if (LzInWindow_Create(p, sizeReserv, alloc)) 190 | { 191 | UInt32 newCyclicBufferSize = historySize + 1; 192 | UInt32 hs; 193 | p->matchMaxLen = matchMaxLen; 194 | { 195 | p->fixedHashSize = 0; 196 | if (p->numHashBytes == 2) 197 | hs = (1 << 16) - 1; 198 | else 199 | { 200 | hs = historySize - 1; 201 | hs |= (hs >> 1); 202 | hs |= (hs >> 2); 203 | hs |= (hs >> 4); 204 | hs |= (hs >> 8); 205 | hs >>= 1; 206 | hs |= 0xFFFF; /* don't change it! It's required for Deflate */ 207 | if (hs > (1 << 24)) 208 | { 209 | if (p->numHashBytes == 3) 210 | hs = (1 << 24) - 1; 211 | else 212 | hs >>= 1; 213 | } 214 | } 215 | p->hashMask = hs; 216 | hs++; 217 | if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; 218 | if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; 219 | if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; 220 | hs += p->fixedHashSize; 221 | } 222 | 223 | { 224 | UInt32 prevSize = p->hashSizeSum + p->numSons; 225 | UInt32 newSize; 226 | p->historySize = historySize; 227 | p->hashSizeSum = hs; 228 | p->cyclicBufferSize = newCyclicBufferSize; 229 | p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); 230 | newSize = p->hashSizeSum + p->numSons; 231 | if (p->hash != 0 && prevSize == newSize) 232 | return 1; 233 | MatchFinder_FreeThisClassMemory(p, alloc); 234 | p->hash = AllocRefs(newSize, alloc); 235 | if (p->hash != 0) 236 | { 237 | p->son = p->hash + p->hashSizeSum; 238 | return 1; 239 | } 240 | } 241 | } 242 | MatchFinder_Free(p, alloc); 243 | return 0; 244 | } 245 | 246 | static void MatchFinder_SetLimits(CMatchFinder *p) 247 | { 248 | UInt32 limit = kMaxValForNormalize - p->pos; 249 | UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; 250 | if (limit2 < limit) 251 | limit = limit2; 252 | limit2 = p->streamPos - p->pos; 253 | if (limit2 <= p->keepSizeAfter) 254 | { 255 | if (limit2 > 0) 256 | limit2 = 1; 257 | } 258 | else 259 | limit2 -= p->keepSizeAfter; 260 | if (limit2 < limit) 261 | limit = limit2; 262 | { 263 | UInt32 lenLimit = p->streamPos - p->pos; 264 | if (lenLimit > p->matchMaxLen) 265 | lenLimit = p->matchMaxLen; 266 | p->lenLimit = lenLimit; 267 | } 268 | p->posLimit = p->pos + limit; 269 | } 270 | 271 | void MatchFinder_Init(CMatchFinder *p) 272 | { 273 | UInt32 i; 274 | for (i = 0; i < p->hashSizeSum; i++) 275 | p->hash[i] = kEmptyHashValue; 276 | p->cyclicBufferPos = 0; 277 | p->buffer = p->bufferBase; 278 | p->pos = p->streamPos = p->cyclicBufferSize; 279 | p->result = SZ_OK; 280 | p->streamEndWasReached = 0; 281 | MatchFinder_ReadBlock(p); 282 | MatchFinder_SetLimits(p); 283 | } 284 | 285 | static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) 286 | { 287 | return (p->pos - p->historySize - 1) & kNormalizeMask; 288 | } 289 | 290 | void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) 291 | { 292 | UInt32 i; 293 | for (i = 0; i < numItems; i++) 294 | { 295 | UInt32 value = items[i]; 296 | if (value <= subValue) 297 | value = kEmptyHashValue; 298 | else 299 | value -= subValue; 300 | items[i] = value; 301 | } 302 | } 303 | 304 | static void MatchFinder_Normalize(CMatchFinder *p) 305 | { 306 | UInt32 subValue = MatchFinder_GetSubValue(p); 307 | MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); 308 | MatchFinder_ReduceOffsets(p, subValue); 309 | } 310 | 311 | static void MatchFinder_CheckLimits(CMatchFinder *p) 312 | { 313 | if (p->pos == kMaxValForNormalize) 314 | MatchFinder_Normalize(p); 315 | if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) 316 | MatchFinder_CheckAndMoveAndRead(p); 317 | if (p->cyclicBufferPos == p->cyclicBufferSize) 318 | p->cyclicBufferPos = 0; 319 | MatchFinder_SetLimits(p); 320 | } 321 | 322 | static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, 323 | UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, 324 | UInt32 *distances, UInt32 maxLen) 325 | { 326 | son[_cyclicBufferPos] = curMatch; 327 | for (;;) 328 | { 329 | UInt32 delta = pos - curMatch; 330 | if (cutValue-- == 0 || delta >= _cyclicBufferSize) 331 | return distances; 332 | { 333 | const Byte *pb = cur - delta; 334 | curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; 335 | if (pb[maxLen] == cur[maxLen] && *pb == *cur) 336 | { 337 | UInt32 len = 0; 338 | while (++len != lenLimit) 339 | if (pb[len] != cur[len]) 340 | break; 341 | if (maxLen < len) 342 | { 343 | *distances++ = maxLen = len; 344 | *distances++ = delta - 1; 345 | if (len == lenLimit) 346 | return distances; 347 | } 348 | } 349 | } 350 | } 351 | } 352 | 353 | UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, 354 | UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, 355 | UInt32 *distances, UInt32 maxLen) 356 | { 357 | CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; 358 | CLzRef *ptr1 = son + (_cyclicBufferPos << 1); 359 | UInt32 len0 = 0, len1 = 0; 360 | for (;;) 361 | { 362 | UInt32 delta = pos - curMatch; 363 | if (cutValue-- == 0 || delta >= _cyclicBufferSize) 364 | { 365 | *ptr0 = *ptr1 = kEmptyHashValue; 366 | return distances; 367 | } 368 | { 369 | CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); 370 | const Byte *pb = cur - delta; 371 | UInt32 len = (len0 < len1 ? len0 : len1); 372 | if (pb[len] == cur[len]) 373 | { 374 | if (++len != lenLimit && pb[len] == cur[len]) 375 | while (++len != lenLimit) 376 | if (pb[len] != cur[len]) 377 | break; 378 | if (maxLen < len) 379 | { 380 | *distances++ = maxLen = len; 381 | *distances++ = delta - 1; 382 | if (len == lenLimit) 383 | { 384 | *ptr1 = pair[0]; 385 | *ptr0 = pair[1]; 386 | return distances; 387 | } 388 | } 389 | } 390 | if (pb[len] < cur[len]) 391 | { 392 | *ptr1 = curMatch; 393 | ptr1 = pair + 1; 394 | curMatch = *ptr1; 395 | len1 = len; 396 | } 397 | else 398 | { 399 | *ptr0 = curMatch; 400 | ptr0 = pair; 401 | curMatch = *ptr0; 402 | len0 = len; 403 | } 404 | } 405 | } 406 | } 407 | 408 | static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, 409 | UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) 410 | { 411 | CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; 412 | CLzRef *ptr1 = son + (_cyclicBufferPos << 1); 413 | UInt32 len0 = 0, len1 = 0; 414 | for (;;) 415 | { 416 | UInt32 delta = pos - curMatch; 417 | if (cutValue-- == 0 || delta >= _cyclicBufferSize) 418 | { 419 | *ptr0 = *ptr1 = kEmptyHashValue; 420 | return; 421 | } 422 | { 423 | CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); 424 | const Byte *pb = cur - delta; 425 | UInt32 len = (len0 < len1 ? len0 : len1); 426 | if (pb[len] == cur[len]) 427 | { 428 | while (++len != lenLimit) 429 | if (pb[len] != cur[len]) 430 | break; 431 | { 432 | if (len == lenLimit) 433 | { 434 | *ptr1 = pair[0]; 435 | *ptr0 = pair[1]; 436 | return; 437 | } 438 | } 439 | } 440 | if (pb[len] < cur[len]) 441 | { 442 | *ptr1 = curMatch; 443 | ptr1 = pair + 1; 444 | curMatch = *ptr1; 445 | len1 = len; 446 | } 447 | else 448 | { 449 | *ptr0 = curMatch; 450 | ptr0 = pair; 451 | curMatch = *ptr0; 452 | len0 = len; 453 | } 454 | } 455 | } 456 | } 457 | 458 | #define MOVE_POS \ 459 | ++p->cyclicBufferPos; \ 460 | p->buffer++; \ 461 | if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); 462 | 463 | #define MOVE_POS_RET MOVE_POS return offset; 464 | 465 | static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } 466 | 467 | #define GET_MATCHES_HEADER2(minLen, ret_op) \ 468 | UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ 469 | lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ 470 | cur = p->buffer; 471 | 472 | #define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) 473 | #define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) 474 | 475 | #define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue 476 | 477 | #define GET_MATCHES_FOOTER(offset, maxLen) \ 478 | offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ 479 | distances + offset, maxLen) - distances); MOVE_POS_RET; 480 | 481 | #define SKIP_FOOTER \ 482 | SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; 483 | 484 | static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 485 | { 486 | UInt32 offset; 487 | GET_MATCHES_HEADER(2) 488 | HASH2_CALC; 489 | curMatch = p->hash[hashValue]; 490 | p->hash[hashValue] = p->pos; 491 | offset = 0; 492 | GET_MATCHES_FOOTER(offset, 1) 493 | } 494 | 495 | UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 496 | { 497 | UInt32 offset; 498 | GET_MATCHES_HEADER(3) 499 | HASH_ZIP_CALC; 500 | curMatch = p->hash[hashValue]; 501 | p->hash[hashValue] = p->pos; 502 | offset = 0; 503 | GET_MATCHES_FOOTER(offset, 2) 504 | } 505 | 506 | static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 507 | { 508 | UInt32 hash2Value, delta2, maxLen, offset; 509 | GET_MATCHES_HEADER(3) 510 | 511 | HASH3_CALC; 512 | 513 | delta2 = p->pos - p->hash[hash2Value]; 514 | curMatch = p->hash[kFix3HashSize + hashValue]; 515 | 516 | p->hash[hash2Value] = 517 | p->hash[kFix3HashSize + hashValue] = p->pos; 518 | 519 | 520 | maxLen = 2; 521 | offset = 0; 522 | if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) 523 | { 524 | for (; maxLen != lenLimit; maxLen++) 525 | if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) 526 | break; 527 | distances[0] = maxLen; 528 | distances[1] = delta2 - 1; 529 | offset = 2; 530 | if (maxLen == lenLimit) 531 | { 532 | SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); 533 | MOVE_POS_RET; 534 | } 535 | } 536 | GET_MATCHES_FOOTER(offset, maxLen) 537 | } 538 | 539 | static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 540 | { 541 | UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; 542 | GET_MATCHES_HEADER(4) 543 | 544 | HASH4_CALC; 545 | 546 | delta2 = p->pos - p->hash[ hash2Value]; 547 | delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; 548 | curMatch = p->hash[kFix4HashSize + hashValue]; 549 | 550 | p->hash[ hash2Value] = 551 | p->hash[kFix3HashSize + hash3Value] = 552 | p->hash[kFix4HashSize + hashValue] = p->pos; 553 | 554 | maxLen = 1; 555 | offset = 0; 556 | if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) 557 | { 558 | distances[0] = maxLen = 2; 559 | distances[1] = delta2 - 1; 560 | offset = 2; 561 | } 562 | if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) 563 | { 564 | maxLen = 3; 565 | distances[offset + 1] = delta3 - 1; 566 | offset += 2; 567 | delta2 = delta3; 568 | } 569 | if (offset != 0) 570 | { 571 | for (; maxLen != lenLimit; maxLen++) 572 | if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) 573 | break; 574 | distances[offset - 2] = maxLen; 575 | if (maxLen == lenLimit) 576 | { 577 | SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); 578 | MOVE_POS_RET; 579 | } 580 | } 581 | if (maxLen < 3) 582 | maxLen = 3; 583 | GET_MATCHES_FOOTER(offset, maxLen) 584 | } 585 | 586 | static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 587 | { 588 | UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; 589 | GET_MATCHES_HEADER(4) 590 | 591 | HASH4_CALC; 592 | 593 | delta2 = p->pos - p->hash[ hash2Value]; 594 | delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; 595 | curMatch = p->hash[kFix4HashSize + hashValue]; 596 | 597 | p->hash[ hash2Value] = 598 | p->hash[kFix3HashSize + hash3Value] = 599 | p->hash[kFix4HashSize + hashValue] = p->pos; 600 | 601 | maxLen = 1; 602 | offset = 0; 603 | if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) 604 | { 605 | distances[0] = maxLen = 2; 606 | distances[1] = delta2 - 1; 607 | offset = 2; 608 | } 609 | if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) 610 | { 611 | maxLen = 3; 612 | distances[offset + 1] = delta3 - 1; 613 | offset += 2; 614 | delta2 = delta3; 615 | } 616 | if (offset != 0) 617 | { 618 | for (; maxLen != lenLimit; maxLen++) 619 | if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) 620 | break; 621 | distances[offset - 2] = maxLen; 622 | if (maxLen == lenLimit) 623 | { 624 | p->son[p->cyclicBufferPos] = curMatch; 625 | MOVE_POS_RET; 626 | } 627 | } 628 | if (maxLen < 3) 629 | maxLen = 3; 630 | offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), 631 | distances + offset, maxLen) - (distances)); 632 | MOVE_POS_RET 633 | } 634 | 635 | UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 636 | { 637 | UInt32 offset; 638 | GET_MATCHES_HEADER(3) 639 | HASH_ZIP_CALC; 640 | curMatch = p->hash[hashValue]; 641 | p->hash[hashValue] = p->pos; 642 | offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), 643 | distances, 2) - (distances)); 644 | MOVE_POS_RET 645 | } 646 | 647 | static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 648 | { 649 | do 650 | { 651 | SKIP_HEADER(2) 652 | HASH2_CALC; 653 | curMatch = p->hash[hashValue]; 654 | p->hash[hashValue] = p->pos; 655 | SKIP_FOOTER 656 | } 657 | while (--num != 0); 658 | } 659 | 660 | void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 661 | { 662 | do 663 | { 664 | SKIP_HEADER(3) 665 | HASH_ZIP_CALC; 666 | curMatch = p->hash[hashValue]; 667 | p->hash[hashValue] = p->pos; 668 | SKIP_FOOTER 669 | } 670 | while (--num != 0); 671 | } 672 | 673 | static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 674 | { 675 | do 676 | { 677 | UInt32 hash2Value; 678 | SKIP_HEADER(3) 679 | HASH3_CALC; 680 | curMatch = p->hash[kFix3HashSize + hashValue]; 681 | p->hash[hash2Value] = 682 | p->hash[kFix3HashSize + hashValue] = p->pos; 683 | SKIP_FOOTER 684 | } 685 | while (--num != 0); 686 | } 687 | 688 | static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 689 | { 690 | do 691 | { 692 | UInt32 hash2Value, hash3Value; 693 | SKIP_HEADER(4) 694 | HASH4_CALC; 695 | curMatch = p->hash[kFix4HashSize + hashValue]; 696 | p->hash[ hash2Value] = 697 | p->hash[kFix3HashSize + hash3Value] = p->pos; 698 | p->hash[kFix4HashSize + hashValue] = p->pos; 699 | SKIP_FOOTER 700 | } 701 | while (--num != 0); 702 | } 703 | 704 | static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 705 | { 706 | do 707 | { 708 | UInt32 hash2Value, hash3Value; 709 | SKIP_HEADER(4) 710 | HASH4_CALC; 711 | curMatch = p->hash[kFix4HashSize + hashValue]; 712 | p->hash[ hash2Value] = 713 | p->hash[kFix3HashSize + hash3Value] = 714 | p->hash[kFix4HashSize + hashValue] = p->pos; 715 | p->son[p->cyclicBufferPos] = curMatch; 716 | MOVE_POS 717 | } 718 | while (--num != 0); 719 | } 720 | 721 | void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 722 | { 723 | do 724 | { 725 | SKIP_HEADER(3) 726 | HASH_ZIP_CALC; 727 | curMatch = p->hash[hashValue]; 728 | p->hash[hashValue] = p->pos; 729 | p->son[p->cyclicBufferPos] = curMatch; 730 | MOVE_POS 731 | } 732 | while (--num != 0); 733 | } 734 | 735 | void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) 736 | { 737 | vTable->Init = (Mf_Init_Func)MatchFinder_Init; 738 | vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; 739 | vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; 740 | vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; 741 | if (!p->btMode) 742 | { 743 | vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; 744 | vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; 745 | } 746 | else if (p->numHashBytes == 2) 747 | { 748 | vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; 749 | vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; 750 | } 751 | else if (p->numHashBytes == 3) 752 | { 753 | vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; 754 | vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; 755 | } 756 | else 757 | { 758 | vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; 759 | vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; 760 | } 761 | } 762 | -------------------------------------------------------------------------------- /LZMA/Sdk/C/LzmaDec.c: -------------------------------------------------------------------------------- 1 | /* LzmaDec.c -- LZMA Decoder 2 | 2009-09-20 : Igor Pavlov : Public doma*/ 3 | 4 | #include "LzmaDec.h" 5 | 6 | #include 7 | 8 | #define kNumTopBits 24 9 | #define kTopValue ((UInt32)1 << kNumTopBits) 10 | 11 | #define kNumBitModelTotalBits 11 12 | #define kBitModelTotal (1 << kNumBitModelTotalBits) 13 | #define kNumMoveBits 5 14 | 15 | #define RC_INIT_SIZE 5 16 | 17 | #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } 18 | 19 | #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 20 | #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); 21 | #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); 22 | #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ 23 | { UPDATE_0(p); i = (i + i); A0; } else \ 24 | { UPDATE_1(p); i = (i + i) + 1; A1; } 25 | #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) 26 | 27 | #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } 28 | #define TREE_DECODE(probs, limit, i) \ 29 | { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } 30 | 31 | /* #define _LZMA_SIZE_OPT */ 32 | 33 | #ifdef _LZMA_SIZE_OPT 34 | #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) 35 | #else 36 | #define TREE_6_DECODE(probs, i) \ 37 | { i = 1; \ 38 | TREE_GET_BIT(probs, i); \ 39 | TREE_GET_BIT(probs, i); \ 40 | TREE_GET_BIT(probs, i); \ 41 | TREE_GET_BIT(probs, i); \ 42 | TREE_GET_BIT(probs, i); \ 43 | TREE_GET_BIT(probs, i); \ 44 | i -= 0x40; } 45 | #endif 46 | 47 | #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } 48 | 49 | #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 50 | #define UPDATE_0_CHECK range = bound; 51 | #define UPDATE_1_CHECK range -= bound; code -= bound; 52 | #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ 53 | { UPDATE_0_CHECK; i = (i + i); A0; } else \ 54 | { UPDATE_1_CHECK; i = (i + i) + 1; A1; } 55 | #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) 56 | #define TREE_DECODE_CHECK(probs, limit, i) \ 57 | { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } 58 | 59 | 60 | #define kNumPosBitsMax 4 61 | #define kNumPosStatesMax (1 << kNumPosBitsMax) 62 | 63 | #define kLenNumLowBits 3 64 | #define kLenNumLowSymbols (1 << kLenNumLowBits) 65 | #define kLenNumMidBits 3 66 | #define kLenNumMidSymbols (1 << kLenNumMidBits) 67 | #define kLenNumHighBits 8 68 | #define kLenNumHighSymbols (1 << kLenNumHighBits) 69 | 70 | #define LenChoice 0 71 | #define LenChoice2 (LenChoice + 1) 72 | #define LenLow (LenChoice2 + 1) 73 | #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) 74 | #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) 75 | #define kNumLenProbs (LenHigh + kLenNumHighSymbols) 76 | 77 | 78 | #define kNumStates 12 79 | #define kNumLitStates 7 80 | 81 | #define kStartPosModelIndex 4 82 | #define kEndPosModelIndex 14 83 | #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) 84 | 85 | #define kNumPosSlotBits 6 86 | #define kNumLenToPosStates 4 87 | 88 | #define kNumAlignBits 4 89 | #define kAlignTableSize (1 << kNumAlignBits) 90 | 91 | #define kMatchMinLen 2 92 | #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) 93 | 94 | #define IsMatch 0 95 | #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) 96 | #define IsRepG0 (IsRep + kNumStates) 97 | #define IsRepG1 (IsRepG0 + kNumStates) 98 | #define IsRepG2 (IsRepG1 + kNumStates) 99 | #define IsRep0Long (IsRepG2 + kNumStates) 100 | #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) 101 | #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) 102 | #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) 103 | #define LenCoder (Align + kAlignTableSize) 104 | #define RepLenCoder (LenCoder + kNumLenProbs) 105 | #define Literal (RepLenCoder + kNumLenProbs) 106 | 107 | #define LZMA_BASE_SIZE 1846 108 | #define LZMA_LIT_SIZE 768 109 | 110 | #define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) 111 | 112 | #if Literal != LZMA_BASE_SIZE 113 | StopCompilingDueBUG 114 | #endif 115 | 116 | #define LZMA_DIC_MIN (1 << 12) 117 | 118 | /* First LZMA-symbol is always decoded. 119 | And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is withlast normalization 120 | Out: 121 | Result: 122 | SZ_OK - OK 123 | SZ_ERROR_DATA - Error 124 | p->remainLen: 125 | < kMatchSpecLenStart : normal remain 126 | = kMatchSpecLenStart : finished 127 | = kMatchSpecLenStart + 1 : Flush marker 128 | = kMatchSpecLenStart + 2 : State Init Marker 129 | */ 130 | 131 | static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 132 | { 133 | CLzmaProb *probs = p->probs; 134 | 135 | unsigned state = p->state; 136 | UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; 137 | unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; 138 | unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; 139 | unsigned lc = p->prop.lc; 140 | 141 | Byte *dic = p->dic; 142 | SizeT dicBufSize = p->dicBufSize; 143 | SizeT dicPos = p->dicPos; 144 | 145 | UInt32 processedPos = p->processedPos; 146 | UInt32 checkDicSize = p->checkDicSize; 147 | unsigned len = 0; 148 | 149 | const Byte *buf = p->buf; 150 | UInt32 range = p->range; 151 | UInt32 code = p->code; 152 | 153 | do 154 | { 155 | CLzmaProb *prob; 156 | UInt32 bound; 157 | unsigned ttt; 158 | unsigned posState = processedPos & pbMask; 159 | 160 | prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 161 | IF_BIT_0(prob) 162 | { 163 | unsigned symbol; 164 | UPDATE_0(prob); 165 | prob = probs + Literal; 166 | if (checkDicSize != 0 || processedPos != 0) 167 | prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + 168 | (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); 169 | 170 | if (state < kNumLitStates) 171 | { 172 | state -= (state < 4) ? state : 3; 173 | symbol = 1; 174 | do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); 175 | } 176 | else 177 | { 178 | unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 179 | unsigned offs = 0x100; 180 | state -= (state < 10) ? 3 : 6; 181 | symbol = 1; 182 | do 183 | { 184 | unsigned bit; 185 | CLzmaProb *probLit; 186 | matchByte <<= 1; 187 | bit = (matchByte & offs); 188 | probLit = prob + offs + bit + symbol; 189 | GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) 190 | } 191 | while (symbol < 0x100); 192 | } 193 | dic[dicPos++] = (Byte)symbol; 194 | processedPos++; 195 | continue; 196 | } 197 | else 198 | { 199 | UPDATE_1(prob); 200 | prob = probs + IsRep + state; 201 | IF_BIT_0(prob) 202 | { 203 | UPDATE_0(prob); 204 | state += kNumStates; 205 | prob = probs + LenCoder; 206 | } 207 | else 208 | { 209 | UPDATE_1(prob); 210 | if (checkDicSize == 0 && processedPos == 0) 211 | return SZ_ERROR_DATA; 212 | prob = probs + IsRepG0 + state; 213 | IF_BIT_0(prob) 214 | { 215 | UPDATE_0(prob); 216 | prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; 217 | IF_BIT_0(prob) 218 | { 219 | UPDATE_0(prob); 220 | dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 221 | dicPos++; 222 | processedPos++; 223 | state = state < kNumLitStates ? 9 : 11; 224 | continue; 225 | } 226 | UPDATE_1(prob); 227 | } 228 | else 229 | { 230 | UInt32 distance; 231 | UPDATE_1(prob); 232 | prob = probs + IsRepG1 + state; 233 | IF_BIT_0(prob) 234 | { 235 | UPDATE_0(prob); 236 | distance = rep1; 237 | } 238 | else 239 | { 240 | UPDATE_1(prob); 241 | prob = probs + IsRepG2 + state; 242 | IF_BIT_0(prob) 243 | { 244 | UPDATE_0(prob); 245 | distance = rep2; 246 | } 247 | else 248 | { 249 | UPDATE_1(prob); 250 | distance = rep3; 251 | rep3 = rep2; 252 | } 253 | rep2 = rep1; 254 | } 255 | rep1 = rep0; 256 | rep0 = distance; 257 | } 258 | state = state < kNumLitStates ? 8 : 11; 259 | prob = probs + RepLenCoder; 260 | } 261 | { 262 | unsigned limit, offset; 263 | CLzmaProb *probLen = prob + LenChoice; 264 | IF_BIT_0(probLen) 265 | { 266 | UPDATE_0(probLen); 267 | probLen = prob + LenLow + (posState << kLenNumLowBits); 268 | offset = 0; 269 | limit = (1 << kLenNumLowBits); 270 | } 271 | else 272 | { 273 | UPDATE_1(probLen); 274 | probLen = prob + LenChoice2; 275 | IF_BIT_0(probLen) 276 | { 277 | UPDATE_0(probLen); 278 | probLen = prob + LenMid + (posState << kLenNumMidBits); 279 | offset = kLenNumLowSymbols; 280 | limit = (1 << kLenNumMidBits); 281 | } 282 | else 283 | { 284 | UPDATE_1(probLen); 285 | probLen = prob + LenHigh; 286 | offset = kLenNumLowSymbols + kLenNumMidSymbols; 287 | limit = (1 << kLenNumHighBits); 288 | } 289 | } 290 | TREE_DECODE(probLen, limit, len); 291 | len += offset; 292 | } 293 | 294 | if (state >= kNumStates) 295 | { 296 | UInt32 distance; 297 | prob = probs + PosSlot + 298 | ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); 299 | TREE_6_DECODE(prob, distance); 300 | if (distance >= kStartPosModelIndex) 301 | { 302 | unsigned posSlot = (unsigned)distance; 303 | int numDirectBits = (int)(((distance >> 1) - 1)); 304 | distance = (2 | (distance & 1)); 305 | if (posSlot < kEndPosModelIndex) 306 | { 307 | distance <<= numDirectBits; 308 | prob = probs + SpecPos + distance - posSlot - 1; 309 | { 310 | UInt32 mask = 1; 311 | unsigned i = 1; 312 | do 313 | { 314 | GET_BIT2(prob + i, i, ; , distance |= mask); 315 | mask <<= 1; 316 | } 317 | while (--numDirectBits != 0); 318 | } 319 | } 320 | else 321 | { 322 | numDirectBits -= kNumAlignBits; 323 | do 324 | { 325 | NORMALIZE 326 | range >>= 1; 327 | 328 | { 329 | UInt32 t; 330 | code -= range; 331 | t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ 332 | distance = (distance << 1) + (t + 1); 333 | code += range & t; 334 | } 335 | /* 336 | distance <<= 1; 337 | if (code >= range) 338 | { 339 | code -= range; 340 | distance |= 1; 341 | } 342 | */ 343 | } 344 | while (--numDirectBits != 0); 345 | prob = probs + Align; 346 | distance <<= kNumAlignBits; 347 | { 348 | unsigned i = 1; 349 | GET_BIT2(prob + i, i, ; , distance |= 1); 350 | GET_BIT2(prob + i, i, ; , distance |= 2); 351 | GET_BIT2(prob + i, i, ; , distance |= 4); 352 | GET_BIT2(prob + i, i, ; , distance |= 8); 353 | } 354 | if (distance == (UInt32)0xFFFFFFFF) 355 | { 356 | len += kMatchSpecLenStart; 357 | state -= kNumStates; 358 | break; 359 | } 360 | } 361 | } 362 | rep3 = rep2; 363 | rep2 = rep1; 364 | rep1 = rep0; 365 | rep0 = distance + 1; 366 | if (checkDicSize == 0) 367 | { 368 | if (distance >= processedPos) 369 | return SZ_ERROR_DATA; 370 | } 371 | else if (distance >= checkDicSize) 372 | return SZ_ERROR_DATA; 373 | state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; 374 | } 375 | 376 | len += kMatchMinLen; 377 | 378 | if (limit == dicPos) 379 | return SZ_ERROR_DATA; 380 | { 381 | SizeT rem = limit - dicPos; 382 | unsigned curLen = ((rem < len) ? (unsigned)rem : len); 383 | SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); 384 | 385 | processedPos += curLen; 386 | 387 | len -= curLen; 388 | if (pos + curLen <= dicBufSize) 389 | { 390 | Byte *dest = dic + dicPos; 391 | ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; 392 | const Byte *lim = dest + curLen; 393 | dicPos += curLen; 394 | do 395 | *(dest) = (Byte)*(dest + src); 396 | while (++dest != lim); 397 | } 398 | else 399 | { 400 | do 401 | { 402 | dic[dicPos++] = dic[pos]; 403 | if (++pos == dicBufSize) 404 | pos = 0; 405 | } 406 | while (--curLen != 0); 407 | } 408 | } 409 | } 410 | } 411 | while (dicPos < limit && buf < bufLimit); 412 | NORMALIZE; 413 | p->buf = buf; 414 | p->range = range; 415 | p->code = code; 416 | p->remainLen = len; 417 | p->dicPos = dicPos; 418 | p->processedPos = processedPos; 419 | p->reps[0] = rep0; 420 | p->reps[1] = rep1; 421 | p->reps[2] = rep2; 422 | p->reps[3] = rep3; 423 | p->state = state; 424 | 425 | return SZ_OK; 426 | } 427 | 428 | static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) 429 | { 430 | if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) 431 | { 432 | Byte *dic = p->dic; 433 | SizeT dicPos = p->dicPos; 434 | SizeT dicBufSize = p->dicBufSize; 435 | unsigned len = p->remainLen; 436 | UInt32 rep0 = p->reps[0]; 437 | if (limit - dicPos < len) 438 | len = (unsigned)(limit - dicPos); 439 | 440 | if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) 441 | p->checkDicSize = p->prop.dicSize; 442 | 443 | p->processedPos += len; 444 | p->remainLen -= len; 445 | while (len-- != 0) 446 | { 447 | dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 448 | dicPos++; 449 | } 450 | p->dicPos = dicPos; 451 | } 452 | } 453 | 454 | static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 455 | { 456 | do 457 | { 458 | SizeT limit2 = limit; 459 | if (p->checkDicSize == 0) 460 | { 461 | UInt32 rem = p->prop.dicSize - p->processedPos; 462 | if (limit - p->dicPos > rem) 463 | limit2 = p->dicPos + rem; 464 | } 465 | RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); 466 | if (p->processedPos >= p->prop.dicSize) 467 | p->checkDicSize = p->prop.dicSize; 468 | LzmaDec_WriteRem(p, limit); 469 | } 470 | while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); 471 | 472 | if (p->remainLen > kMatchSpecLenStart) 473 | { 474 | p->remainLen = kMatchSpecLenStart; 475 | } 476 | return 0; 477 | } 478 | 479 | typedef enum 480 | { 481 | DUMMY_ERROR, /* unexpected end of input stream */ 482 | DUMMY_LIT, 483 | DUMMY_MATCH, 484 | DUMMY_REP 485 | } ELzmaDummy; 486 | 487 | static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) 488 | { 489 | UInt32 range = p->range; 490 | UInt32 code = p->code; 491 | const Byte *bufLimit = buf + inSize; 492 | CLzmaProb *probs = p->probs; 493 | unsigned state = p->state; 494 | ELzmaDummy res; 495 | 496 | { 497 | CLzmaProb *prob; 498 | UInt32 bound; 499 | unsigned ttt; 500 | unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); 501 | 502 | prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 503 | IF_BIT_0_CHECK(prob) 504 | { 505 | UPDATE_0_CHECK 506 | 507 | /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ 508 | 509 | prob = probs + Literal; 510 | if (p->checkDicSize != 0 || p->processedPos != 0) 511 | prob += (LZMA_LIT_SIZE * 512 | ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + 513 | (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); 514 | 515 | if (state < kNumLitStates) 516 | { 517 | unsigned symbol = 1; 518 | do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); 519 | } 520 | else 521 | { 522 | unsigned matchByte = p->dic[p->dicPos - p->reps[0] + 523 | ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; 524 | unsigned offs = 0x100; 525 | unsigned symbol = 1; 526 | do 527 | { 528 | unsigned bit; 529 | CLzmaProb *probLit; 530 | matchByte <<= 1; 531 | bit = (matchByte & offs); 532 | probLit = prob + offs + bit + symbol; 533 | GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) 534 | } 535 | while (symbol < 0x100); 536 | } 537 | res = DUMMY_LIT; 538 | } 539 | else 540 | { 541 | unsigned len; 542 | UPDATE_1_CHECK; 543 | 544 | prob = probs + IsRep + state; 545 | IF_BIT_0_CHECK(prob) 546 | { 547 | UPDATE_0_CHECK; 548 | state = 0; 549 | prob = probs + LenCoder; 550 | res = DUMMY_MATCH; 551 | } 552 | else 553 | { 554 | UPDATE_1_CHECK; 555 | res = DUMMY_REP; 556 | prob = probs + IsRepG0 + state; 557 | IF_BIT_0_CHECK(prob) 558 | { 559 | UPDATE_0_CHECK; 560 | prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; 561 | IF_BIT_0_CHECK(prob) 562 | { 563 | UPDATE_0_CHECK; 564 | NORMALIZE_CHECK; 565 | return DUMMY_REP; 566 | } 567 | else 568 | { 569 | UPDATE_1_CHECK; 570 | } 571 | } 572 | else 573 | { 574 | UPDATE_1_CHECK; 575 | prob = probs + IsRepG1 + state; 576 | IF_BIT_0_CHECK(prob) 577 | { 578 | UPDATE_0_CHECK; 579 | } 580 | else 581 | { 582 | UPDATE_1_CHECK; 583 | prob = probs + IsRepG2 + state; 584 | IF_BIT_0_CHECK(prob) 585 | { 586 | UPDATE_0_CHECK; 587 | } 588 | else 589 | { 590 | UPDATE_1_CHECK; 591 | } 592 | } 593 | } 594 | state = kNumStates; 595 | prob = probs + RepLenCoder; 596 | } 597 | { 598 | unsigned limit, offset; 599 | CLzmaProb *probLen = prob + LenChoice; 600 | IF_BIT_0_CHECK(probLen) 601 | { 602 | UPDATE_0_CHECK; 603 | probLen = prob + LenLow + (posState << kLenNumLowBits); 604 | offset = 0; 605 | limit = 1 << kLenNumLowBits; 606 | } 607 | else 608 | { 609 | UPDATE_1_CHECK; 610 | probLen = prob + LenChoice2; 611 | IF_BIT_0_CHECK(probLen) 612 | { 613 | UPDATE_0_CHECK; 614 | probLen = prob + LenMid + (posState << kLenNumMidBits); 615 | offset = kLenNumLowSymbols; 616 | limit = 1 << kLenNumMidBits; 617 | } 618 | else 619 | { 620 | UPDATE_1_CHECK; 621 | probLen = prob + LenHigh; 622 | offset = kLenNumLowSymbols + kLenNumMidSymbols; 623 | limit = 1 << kLenNumHighBits; 624 | } 625 | } 626 | TREE_DECODE_CHECK(probLen, limit, len); 627 | len += offset; 628 | } 629 | 630 | if (state < 4) 631 | { 632 | unsigned posSlot; 633 | prob = probs + PosSlot + 634 | ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 635 | kNumPosSlotBits); 636 | TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); 637 | if (posSlot >= kStartPosModelIndex) 638 | { 639 | int numDirectBits = ((posSlot >> 1) - 1); 640 | 641 | /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ 642 | 643 | if (posSlot < kEndPosModelIndex) 644 | { 645 | prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; 646 | } 647 | else 648 | { 649 | numDirectBits -= kNumAlignBits; 650 | do 651 | { 652 | NORMALIZE_CHECK 653 | range >>= 1; 654 | code -= range & (((code - range) >> 31) - 1); 655 | /* if (code >= range) code -= range; */ 656 | } 657 | while (--numDirectBits != 0); 658 | prob = probs + Align; 659 | numDirectBits = kNumAlignBits; 660 | } 661 | { 662 | unsigned i = 1; 663 | do 664 | { 665 | GET_BIT_CHECK(prob + i, i); 666 | } 667 | while (--numDirectBits != 0); 668 | } 669 | } 670 | } 671 | } 672 | } 673 | NORMALIZE_CHECK; 674 | return res; 675 | } 676 | 677 | 678 | static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) 679 | { 680 | p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); 681 | p->range = 0xFFFFFFFF; 682 | p->needFlush = 0; 683 | } 684 | 685 | void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) 686 | { 687 | p->needFlush = 1; 688 | p->remainLen = 0; 689 | p->tempBufSize = 0; 690 | 691 | if (initDic) 692 | { 693 | p->processedPos = 0; 694 | p->checkDicSize = 0; 695 | p->needInitState = 1; 696 | } 697 | if (initState) 698 | p->needInitState = 1; 699 | } 700 | 701 | void LzmaDec_Init(CLzmaDec *p) 702 | { 703 | p->dicPos = 0; 704 | LzmaDec_InitDicAndState(p, True, True); 705 | } 706 | 707 | static void LzmaDec_InitStateReal(CLzmaDec *p) 708 | { 709 | UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); 710 | UInt32 i; 711 | CLzmaProb *probs = p->probs; 712 | for (i = 0; i < numProbs; i++) 713 | probs[i] = kBitModelTotal >> 1; 714 | p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; 715 | p->state = 0; 716 | p->needInitState = 0; 717 | } 718 | 719 | SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, 720 | ELzmaFinishMode finishMode, ELzmaStatus *status) 721 | { 722 | SizeT inSize = *srcLen; 723 | (*srcLen) = 0; 724 | LzmaDec_WriteRem(p, dicLimit); 725 | 726 | *status = LZMA_STATUS_NOT_SPECIFIED; 727 | 728 | while (p->remainLen != kMatchSpecLenStart) 729 | { 730 | int checkEndMarkNow; 731 | 732 | if (p->needFlush != 0) 733 | { 734 | for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) 735 | p->tempBuf[p->tempBufSize++] = *src++; 736 | if (p->tempBufSize < RC_INIT_SIZE) 737 | { 738 | *status = LZMA_STATUS_NEEDS_MORE_INPUT; 739 | return SZ_OK; 740 | } 741 | if (p->tempBuf[0] != 0) 742 | return SZ_ERROR_DATA; 743 | 744 | LzmaDec_InitRc(p, p->tempBuf); 745 | p->tempBufSize = 0; 746 | } 747 | 748 | checkEndMarkNow = 0; 749 | if (p->dicPos >= dicLimit) 750 | { 751 | if (p->remainLen == 0 && p->code == 0) 752 | { 753 | *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; 754 | return SZ_OK; 755 | } 756 | if (finishMode == LZMA_FINISH_ANY) 757 | { 758 | *status = LZMA_STATUS_NOT_FINISHED; 759 | return SZ_OK; 760 | } 761 | if (p->remainLen != 0) 762 | { 763 | *status = LZMA_STATUS_NOT_FINISHED; 764 | return SZ_ERROR_DATA; 765 | } 766 | checkEndMarkNow = 1; 767 | } 768 | 769 | if (p->needInitState) 770 | LzmaDec_InitStateReal(p); 771 | 772 | if (p->tempBufSize == 0) 773 | { 774 | SizeT processed; 775 | const Byte *bufLimit; 776 | if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 777 | { 778 | int dummyRes = LzmaDec_TryDummy(p, src, inSize); 779 | if (dummyRes == DUMMY_ERROR) 780 | { 781 | memcpy(p->tempBuf, src, inSize); 782 | p->tempBufSize = (unsigned)inSize; 783 | (*srcLen) += inSize; 784 | *status = LZMA_STATUS_NEEDS_MORE_INPUT; 785 | return SZ_OK; 786 | } 787 | if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 788 | { 789 | *status = LZMA_STATUS_NOT_FINISHED; 790 | return SZ_ERROR_DATA; 791 | } 792 | bufLimit = src; 793 | } 794 | else 795 | bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; 796 | p->buf = src; 797 | if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) 798 | return SZ_ERROR_DATA; 799 | processed = (SizeT)(p->buf - src); 800 | (*srcLen) += processed; 801 | src += processed; 802 | inSize -= processed; 803 | } 804 | else 805 | { 806 | unsigned rem = p->tempBufSize, lookAhead = 0; 807 | while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) 808 | p->tempBuf[rem++] = src[lookAhead++]; 809 | p->tempBufSize = rem; 810 | if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 811 | { 812 | int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); 813 | if (dummyRes == DUMMY_ERROR) 814 | { 815 | (*srcLen) += lookAhead; 816 | *status = LZMA_STATUS_NEEDS_MORE_INPUT; 817 | return SZ_OK; 818 | } 819 | if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 820 | { 821 | *status = LZMA_STATUS_NOT_FINISHED; 822 | return SZ_ERROR_DATA; 823 | } 824 | } 825 | p->buf = p->tempBuf; 826 | if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) 827 | return SZ_ERROR_DATA; 828 | lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); 829 | (*srcLen) += lookAhead; 830 | src += lookAhead; 831 | inSize -= lookAhead; 832 | p->tempBufSize = 0; 833 | } 834 | } 835 | if (p->code == 0) 836 | *status = LZMA_STATUS_FINISHED_WITH_MARK; 837 | return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; 838 | } 839 | 840 | SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 841 | { 842 | SizeT outSize = *destLen; 843 | SizeT inSize = *srcLen; 844 | *srcLen = *destLen = 0; 845 | for (;;) 846 | { 847 | SizeT inSizeCur = inSize, outSizeCur, dicPos; 848 | ELzmaFinishMode curFinishMode; 849 | SRes res; 850 | if (p->dicPos == p->dicBufSize) 851 | p->dicPos = 0; 852 | dicPos = p->dicPos; 853 | if (outSize > p->dicBufSize - dicPos) 854 | { 855 | outSizeCur = p->dicBufSize; 856 | curFinishMode = LZMA_FINISH_ANY; 857 | } 858 | else 859 | { 860 | outSizeCur = dicPos + outSize; 861 | curFinishMode = finishMode; 862 | } 863 | 864 | res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); 865 | src += inSizeCur; 866 | inSize -= inSizeCur; 867 | *srcLen += inSizeCur; 868 | outSizeCur = p->dicPos - dicPos; 869 | memcpy(dest, p->dic + dicPos, outSizeCur); 870 | dest += outSizeCur; 871 | outSize -= outSizeCur; 872 | *destLen += outSizeCur; 873 | if (res != 0) 874 | return res; 875 | if (outSizeCur == 0 || outSize == 0) 876 | return SZ_OK; 877 | } 878 | } 879 | 880 | void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) 881 | { 882 | alloc->Free(alloc, p->probs); 883 | p->probs = 0; 884 | } 885 | 886 | static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) 887 | { 888 | alloc->Free(alloc, p->dic); 889 | p->dic = 0; 890 | } 891 | 892 | void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) 893 | { 894 | LzmaDec_FreeProbs(p, alloc); 895 | LzmaDec_FreeDict(p, alloc); 896 | } 897 | 898 | SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) 899 | { 900 | UInt32 dicSize; 901 | Byte d; 902 | 903 | if (size < LZMA_PROPS_SIZE) 904 | return SZ_ERROR_UNSUPPORTED; 905 | else 906 | dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); 907 | 908 | if (dicSize < LZMA_DIC_MIN) 909 | dicSize = LZMA_DIC_MIN; 910 | p->dicSize = dicSize; 911 | 912 | d = data[0]; 913 | if (d >= (9 * 5 * 5)) 914 | return SZ_ERROR_UNSUPPORTED; 915 | 916 | p->lc = d % 9; 917 | d /= 9; 918 | p->pb = d / 5; 919 | p->lp = d % 5; 920 | 921 | return SZ_OK; 922 | } 923 | 924 | static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) 925 | { 926 | UInt32 numProbs = LzmaProps_GetNumProbs(propNew); 927 | if (p->probs == 0 || numProbs != p->numProbs) 928 | { 929 | LzmaDec_FreeProbs(p, alloc); 930 | p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); 931 | p->numProbs = numProbs; 932 | if (p->probs == 0) 933 | return SZ_ERROR_MEM; 934 | } 935 | return SZ_OK; 936 | } 937 | 938 | SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) 939 | { 940 | CLzmaProps propNew; 941 | RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 942 | RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 943 | p->prop = propNew; 944 | return SZ_OK; 945 | } 946 | 947 | SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) 948 | { 949 | CLzmaProps propNew; 950 | SizeT dicBufSize; 951 | RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 952 | RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 953 | dicBufSize = propNew.dicSize; 954 | if (p->dic == 0 || dicBufSize != p->dicBufSize) 955 | { 956 | LzmaDec_FreeDict(p, alloc); 957 | p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); 958 | if (p->dic == 0) 959 | { 960 | LzmaDec_FreeProbs(p, alloc); 961 | return SZ_ERROR_MEM; 962 | } 963 | } 964 | p->dicBufSize = dicBufSize; 965 | p->prop = propNew; 966 | return SZ_OK; 967 | } 968 | 969 | SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 970 | const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 971 | ELzmaStatus *status, ISzAlloc *alloc) 972 | { 973 | CLzmaDec p; 974 | SRes res; 975 | SizeT inSize = *srcLen; 976 | SizeT outSize = *destLen; 977 | *srcLen = *destLen = 0; 978 | if (inSize < RC_INIT_SIZE) 979 | return SZ_ERROR_INPUT_EOF; 980 | 981 | LzmaDec_Construct(&p); 982 | res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); 983 | if (res != 0) 984 | return res; 985 | p.dic = dest; 986 | p.dicBufSize = outSize; 987 | 988 | LzmaDec_Init(&p); 989 | 990 | *srcLen = inSize; 991 | res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); 992 | 993 | if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) 994 | res = SZ_ERROR_INPUT_EOF; 995 | 996 | (*destLen) = p.dicPos; 997 | LzmaDec_FreeProbs(&p, alloc); 998 | return res; 999 | } 1000 | -------------------------------------------------------------------------------- /Tiano/TianoCompress.c: -------------------------------------------------------------------------------- 1 | /* Tiano Compress Implementation 2 | 3 | Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | Module Name: 13 | 14 | TianoCompress.c 15 | 16 | Abstract: 17 | 18 | Compression routine. The compression algorithm is a mixture of 19 | LZ77 and Huffman coding. LZ77 transforms the source data into a 20 | sequence of Original Characters and Pointers to repeated strings. 21 | This sequence is further divided into Blocks and Huffman codings 22 | are applied to each Block. 23 | 24 | */ 25 | 26 | #include "TianoCompress.h" 27 | 28 | // 29 | // Macro Definitions 30 | // 31 | #undef UINT8_MAX 32 | typedef INT32 NODE; 33 | #define UINT8_MAX 0xff 34 | #define UINT8_BIT 8 35 | #define THRESHOLD 3 36 | #define INIT_CRC 0 37 | #define WNDBIT 19 38 | #define WNDSIZ (1U << WNDBIT) 39 | #define MAXMATCH 256 40 | #define BLKSIZ (1U << 14) // 16 * 1024U 41 | #define PERC_FLAG 0x80000000U 42 | #define CODE_BIT 16 43 | #define NIL 0 44 | #define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX) 45 | #define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2) 46 | #define CRCPOLY 0xA001 47 | #define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT) 48 | 49 | // 50 | // C: the Char&Len Set; P: the Position Set; T: the exTra Set 51 | // 52 | #define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD) 53 | #define CBIT 9 54 | #define NP (WNDBIT + 1) 55 | #define PBIT 5 56 | #define NT (CODE_BIT + 3) 57 | #define TBIT 5 58 | #if NT > NP 59 | #define NPT NT 60 | #else 61 | #define NPT NP 62 | #endif 63 | // 64 | // Function Prototypes 65 | // 66 | 67 | STATIC 68 | VOID 69 | PutDword( 70 | UINT32 Data 71 | ); 72 | 73 | STATIC 74 | INT32 75 | AllocateMemory ( 76 | VOID 77 | ); 78 | 79 | STATIC 80 | VOID 81 | FreeMemory ( 82 | VOID 83 | ); 84 | 85 | STATIC 86 | VOID 87 | InitSlide ( 88 | VOID 89 | ); 90 | 91 | STATIC 92 | NODE 93 | Child ( 94 | NODE NodeQ, 95 | UINT8 CharC 96 | ); 97 | 98 | STATIC 99 | VOID 100 | MakeChild ( 101 | NODE NodeQ, 102 | UINT8 CharC, 103 | NODE NodeR 104 | ); 105 | 106 | STATIC 107 | VOID 108 | Split ( 109 | NODE Old 110 | ); 111 | 112 | STATIC 113 | VOID 114 | InsertNode ( 115 | VOID 116 | ); 117 | 118 | STATIC 119 | VOID 120 | DeleteNode ( 121 | VOID 122 | ); 123 | 124 | STATIC 125 | VOID 126 | GetNextMatch ( 127 | VOID 128 | ); 129 | 130 | STATIC 131 | INT32 132 | Encode ( 133 | VOID 134 | ); 135 | 136 | STATIC 137 | VOID 138 | CountTFreq ( 139 | VOID 140 | ); 141 | 142 | STATIC 143 | VOID 144 | WritePTLen ( 145 | INT32 Number, 146 | INT32 nbit, 147 | INT32 Special 148 | ); 149 | 150 | STATIC 151 | VOID 152 | WriteCLen ( 153 | VOID 154 | ); 155 | 156 | STATIC 157 | VOID 158 | EncodeC ( 159 | INT32 Value 160 | ); 161 | 162 | STATIC 163 | VOID 164 | EncodeP ( 165 | UINT32 Value 166 | ); 167 | 168 | STATIC 169 | VOID 170 | SendBlock ( 171 | VOID 172 | ); 173 | 174 | STATIC 175 | VOID 176 | Output ( 177 | UINT32 c, 178 | UINT32 p 179 | ); 180 | 181 | STATIC 182 | VOID 183 | HufEncodeStart ( 184 | VOID 185 | ); 186 | 187 | STATIC 188 | VOID 189 | HufEncodeEnd ( 190 | VOID 191 | ); 192 | 193 | STATIC 194 | VOID 195 | MakeCrcTable ( 196 | VOID 197 | ); 198 | 199 | STATIC 200 | VOID 201 | PutBits ( 202 | INT32 Number, 203 | UINT32 Value 204 | ); 205 | 206 | STATIC 207 | INT32 208 | FreadCrc ( 209 | UINT8 *Pointer, 210 | INT32 Number 211 | ); 212 | 213 | STATIC 214 | VOID 215 | InitPutBits ( 216 | VOID 217 | ); 218 | 219 | STATIC 220 | VOID 221 | CountLen ( 222 | INT32 Index 223 | ); 224 | 225 | STATIC 226 | VOID 227 | MakeLen ( 228 | INT32 Root 229 | ); 230 | 231 | STATIC 232 | VOID 233 | DownHeap ( 234 | INT32 Index 235 | ); 236 | 237 | STATIC 238 | VOID 239 | MakeCode ( 240 | INT32 Number, 241 | UINT8 Len[ ], 242 | UINT16 Code[] 243 | ); 244 | 245 | STATIC 246 | INT32 247 | MakeTree ( 248 | INT32 NParm, 249 | UINT16 FreqParm[], 250 | UINT8 LenParm[ ], 251 | UINT16 CodeParm[] 252 | ); 253 | 254 | // 255 | // Global Variables 256 | // 257 | STATIC UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit; 258 | 259 | STATIC UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen; 260 | STATIC INT16 mHeap[NC + 1]; 261 | STATIC INT32 mRemainder, mMatchLen, mBitCount, mHeapSize, mN; 262 | STATIC UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc; 263 | STATIC UINT32 mCompSize, mOrigSize; 264 | 265 | STATIC UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1], 266 | mCFreq[2 * NC - 1], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1]; 267 | 268 | STATIC NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL; 269 | 270 | // 271 | // functions 272 | // 273 | INT32 274 | TianoCompress ( 275 | UINT8 *SrcBuffer, 276 | UINT32 SrcSize, 277 | UINT8 *DstBuffer, 278 | UINT32 *DstSize 279 | ) 280 | /*++ 281 | 282 | Routine Description: 283 | 284 | The internal implementation of [Efi/Tiano]Compress(). 285 | 286 | Arguments: 287 | 288 | SrcBuffer - The buffer storing the source data 289 | SrcSize - The size of source data 290 | DstBuffer - The buffer to store the compressed data 291 | DstSize - On input, the size of DstBuffer; On output, 292 | the size of the actual compressed data. 293 | Version - The version of de/compression algorithm. 294 | Version 1 for UEFI 2.0 de/compression algorithm. 295 | Version 2 for Tiano de/compression algorithm. 296 | 297 | Returns: 298 | 299 | EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. this case, 300 | DstSize contains the size needed. 301 | EFI_SUCCESS - Compression is successful. 302 | EFI_OUT_OF_RESOURCES - No resource to complete function. 303 | EFI_INVALID_PARAMETER - Parameter supplied is wrong. 304 | 305 | --*/ 306 | { 307 | INT32 Status; 308 | 309 | // 310 | // Initializations 311 | // 312 | mBufSiz = 0; 313 | mBuf = NULL; 314 | mText = NULL; 315 | mLevel = NULL; 316 | mChildCount = NULL; 317 | mPosition = NULL; 318 | mParent = NULL; 319 | mPrev = NULL; 320 | mNext = NULL; 321 | 322 | mSrc = SrcBuffer; 323 | mSrcUpperLimit = mSrc + SrcSize; 324 | mDst = DstBuffer; 325 | mDstUpperLimit = mDst +*DstSize; 326 | 327 | PutDword (0L); 328 | PutDword (0L); 329 | 330 | MakeCrcTable (); 331 | 332 | mOrigSize = mCompSize = 0; 333 | mCrc = INIT_CRC; 334 | 335 | // 336 | // Compress it 337 | // 338 | Status = Encode (); 339 | if (Status) { 340 | return ERR_OUT_OF_RESOURCES; 341 | } 342 | // 343 | // Null terminate the compressed data 344 | // 345 | if (mDst < mDstUpperLimit) { 346 | *mDst++ = 0; 347 | } 348 | // 349 | // Fill compressed size and original size 350 | // 351 | mDst = DstBuffer; 352 | PutDword (mCompSize + 1); 353 | PutDword (mOrigSize); 354 | 355 | // 356 | // Return 357 | // 358 | if (mCompSize + 1 + 8 > *DstSize) { 359 | *DstSize = mCompSize + 1 + 8; 360 | return ERR_BUFFER_TOO_SMALL; 361 | } else { 362 | *DstSize = mCompSize + 1 + 8; 363 | return ERR_SUCCESS; 364 | } 365 | 366 | } 367 | 368 | STATIC 369 | VOID 370 | PutDword ( 371 | UINT32 Data 372 | ) 373 | /*++ 374 | 375 | Routine Description: 376 | 377 | Put a dword to output stream 378 | 379 | Arguments: 380 | 381 | Data - the dword to put 382 | 383 | Returns: (VOID) 384 | 385 | --*/ 386 | { 387 | if (mDst < mDstUpperLimit) { 388 | *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff); 389 | } 390 | 391 | if (mDst < mDstUpperLimit) { 392 | *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff); 393 | } 394 | 395 | if (mDst < mDstUpperLimit) { 396 | *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff); 397 | } 398 | 399 | if (mDst < mDstUpperLimit) { 400 | *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff); 401 | } 402 | } 403 | 404 | STATIC 405 | INT32 406 | AllocateMemory ( 407 | VOID 408 | ) 409 | /*++ 410 | 411 | Routine Description: 412 | 413 | Allocate memory spaces for data structures used compression process 414 | 415 | Argements: 416 | VOID 417 | 418 | Returns: 419 | 420 | EFI_SUCCESS - Memory is allocated successfully 421 | EFI_OUT_OF_RESOURCES - Allocation fails 422 | 423 | --*/ 424 | { 425 | UINT32 Index; 426 | 427 | mText = malloc (WNDSIZ * 2 + MAXMATCH); 428 | for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) { 429 | mText[Index] = 0; 430 | } 431 | 432 | mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel)); 433 | mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount)); 434 | mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition)); 435 | mParent = malloc (WNDSIZ * 2 * sizeof (*mParent)); 436 | mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev)); 437 | mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext)); 438 | 439 | mBufSiz = BLKSIZ; 440 | mBuf = malloc (mBufSiz); 441 | while (mBuf == NULL) { 442 | mBufSiz = (mBufSiz / 10U) * 9U; 443 | if (mBufSiz < 4 * 1024U) { 444 | return ERR_OUT_OF_RESOURCES; 445 | } 446 | 447 | mBuf = malloc (mBufSiz); 448 | } 449 | 450 | mBuf[0] = 0; 451 | 452 | return ERR_SUCCESS; 453 | } 454 | 455 | VOID 456 | FreeMemory ( 457 | VOID 458 | ) 459 | /*++ 460 | 461 | Routine Description: 462 | 463 | Called when compression is completed to free memory previously allocated. 464 | 465 | Arguments: (VOID) 466 | 467 | Returns: (VOID) 468 | 469 | --*/ 470 | { 471 | if (mText != NULL) { 472 | free (mText); 473 | } 474 | 475 | if (mLevel != NULL) { 476 | free (mLevel); 477 | } 478 | 479 | if (mChildCount != NULL) { 480 | free (mChildCount); 481 | } 482 | 483 | if (mPosition != NULL) { 484 | free (mPosition); 485 | } 486 | 487 | if (mParent != NULL) { 488 | free (mParent); 489 | } 490 | 491 | if (mPrev != NULL) { 492 | free (mPrev); 493 | } 494 | 495 | if (mNext != NULL) { 496 | free (mNext); 497 | } 498 | 499 | if (mBuf != NULL) { 500 | free (mBuf); 501 | } 502 | 503 | return ; 504 | } 505 | 506 | STATIC 507 | VOID 508 | InitSlide ( 509 | VOID 510 | ) 511 | /*++ 512 | 513 | Routine Description: 514 | 515 | Initialize String Info Log data structures 516 | 517 | Arguments: (VOID) 518 | 519 | Returns: (VOID) 520 | 521 | --*/ 522 | { 523 | NODE Index; 524 | 525 | for (Index = WNDSIZ; Index <= WNDSIZ + UINT8_MAX; Index++) { 526 | mLevel[Index] = 1; 527 | mPosition[Index] = NIL; // sentinel 528 | } 529 | 530 | for (Index = WNDSIZ; Index < WNDSIZ * 2; Index++) { 531 | mParent[Index] = NIL; 532 | } 533 | 534 | mAvail = 1; 535 | for (Index = 1; Index < WNDSIZ - 1; Index++) { 536 | mNext[Index] = (NODE) (Index + 1); 537 | } 538 | 539 | mNext[WNDSIZ - 1] = NIL; 540 | for (Index = WNDSIZ * 2; Index <= MAX_HASH_VAL; Index++) { 541 | mNext[Index] = NIL; 542 | } 543 | } 544 | 545 | STATIC 546 | NODE 547 | Child ( 548 | NODE NodeQ, 549 | UINT8 CharC 550 | ) 551 | /*++ 552 | 553 | Routine Description: 554 | 555 | Find child node given the parent node and the edge character 556 | 557 | Arguments: 558 | 559 | NodeQ - the parent node 560 | CharC - the edge character 561 | 562 | Returns: 563 | 564 | The child node (NIL if not found) 565 | 566 | --*/ 567 | { 568 | NODE NodeR; 569 | 570 | NodeR = mNext[HASH (NodeQ, CharC)]; 571 | // 572 | // sentinel 573 | // 574 | mParent[NIL] = NodeQ; 575 | while (mParent[NodeR] != NodeQ) { 576 | NodeR = mNext[NodeR]; 577 | } 578 | 579 | return NodeR; 580 | } 581 | 582 | STATIC 583 | VOID 584 | MakeChild ( 585 | NODE Parent, 586 | UINT8 CharC, 587 | NODE Child 588 | ) 589 | /*++ 590 | 591 | Routine Description: 592 | 593 | Create a new child for a given parent node. 594 | 595 | Arguments: 596 | 597 | Parent - the parent node 598 | CharC - the edge character 599 | Child - the child node 600 | 601 | Returns: (VOID) 602 | 603 | --*/ 604 | { 605 | NODE Node1; 606 | NODE Node2; 607 | 608 | Node1 = (NODE) HASH (Parent, CharC); 609 | Node2 = mNext[Node1]; 610 | mNext[Node1] = Child; 611 | mNext[Child] = Node2; 612 | mPrev[Node2] = Child; 613 | mPrev[Child] = Node1; 614 | mParent[Child] = Parent; 615 | mChildCount[Parent]++; 616 | } 617 | 618 | STATIC 619 | VOID 620 | Split ( 621 | NODE Old 622 | ) 623 | /*++ 624 | 625 | Routine Description: 626 | 627 | Split a node. 628 | 629 | Arguments: 630 | 631 | Old - the node to split 632 | 633 | Returns: (VOID) 634 | 635 | --*/ 636 | { 637 | NODE New; 638 | NODE TempNode; 639 | 640 | New = mAvail; 641 | mAvail = mNext[New]; 642 | mChildCount[New] = 0; 643 | TempNode = mPrev[Old]; 644 | mPrev[New] = TempNode; 645 | mNext[TempNode] = New; 646 | TempNode = mNext[Old]; 647 | mNext[New] = TempNode; 648 | mPrev[TempNode] = New; 649 | mParent[New] = mParent[Old]; 650 | mLevel[New] = (UINT8) mMatchLen; 651 | mPosition[New] = mPos; 652 | MakeChild (New, mText[mMatchPos + mMatchLen], Old); 653 | MakeChild (New, mText[mPos + mMatchLen], mPos); 654 | } 655 | 656 | STATIC 657 | VOID 658 | InsertNode ( 659 | VOID 660 | ) 661 | /*++ 662 | 663 | Routine Description: 664 | 665 | Insert string info for current position into the String Info Log 666 | 667 | Arguments: (VOID) 668 | 669 | Returns: (VOID) 670 | 671 | --*/ 672 | { 673 | NODE NodeQ; 674 | NODE NodeR; 675 | NODE Index2; 676 | NODE NodeT; 677 | UINT8 CharC; 678 | UINT8 *t1; 679 | UINT8 *t2; 680 | 681 | if (mMatchLen >= 4) { 682 | // 683 | // We have just got a long match, the target tree 684 | // can be located by MatchPos + 1. Travese the tree 685 | // from bottom up to get to a proper starting point. 686 | // The usage of PERC_FLAG ensures proper node deletion 687 | // DeleteNode() later. 688 | // 689 | mMatchLen--; 690 | NodeR = (NODE) ((mMatchPos + 1) | WNDSIZ); 691 | NodeQ = mParent[NodeR]; 692 | while (NodeQ == NIL) { 693 | NodeR = mNext[NodeR]; 694 | NodeQ = mParent[NodeR]; 695 | } 696 | 697 | while (mLevel[NodeQ] >= mMatchLen) { 698 | NodeR = NodeQ; 699 | NodeQ = mParent[NodeQ]; 700 | } 701 | 702 | NodeT = NodeQ; 703 | while (mPosition[NodeT] < 0) { 704 | mPosition[NodeT] = mPos; 705 | NodeT = mParent[NodeT]; 706 | } 707 | 708 | if (NodeT < WNDSIZ) { 709 | mPosition[NodeT] = (NODE) (mPos | (UINT32) PERC_FLAG); 710 | } 711 | } else { 712 | // 713 | // Locate the target tree 714 | // 715 | NodeQ = (NODE) (mText[mPos] + WNDSIZ); 716 | CharC = mText[mPos + 1]; 717 | NodeR = Child (NodeQ, CharC); 718 | if (NodeR == NIL) { 719 | MakeChild (NodeQ, CharC, mPos); 720 | mMatchLen = 1; 721 | return ; 722 | } 723 | 724 | mMatchLen = 2; 725 | } 726 | // 727 | // Traverse down the tree to find a match. 728 | // Update Position value along the route. 729 | // Node split or creation is involved. 730 | // 731 | for (;;) { 732 | if (NodeR >= WNDSIZ) { 733 | Index2 = MAXMATCH; 734 | mMatchPos = NodeR; 735 | } else { 736 | Index2 = mLevel[NodeR]; 737 | mMatchPos = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG); 738 | } 739 | 740 | if (mMatchPos >= mPos) { 741 | mMatchPos -= WNDSIZ; 742 | } 743 | 744 | t1 = &mText[mPos + mMatchLen]; 745 | t2 = &mText[mMatchPos + mMatchLen]; 746 | while (mMatchLen < Index2) { 747 | if (*t1 != *t2) { 748 | Split (NodeR); 749 | return ; 750 | } 751 | 752 | mMatchLen++; 753 | t1++; 754 | t2++; 755 | } 756 | 757 | if (mMatchLen >= MAXMATCH) { 758 | break; 759 | } 760 | 761 | mPosition[NodeR] = mPos; 762 | NodeQ = NodeR; 763 | NodeR = Child (NodeQ, *t1); 764 | if (NodeR == NIL) { 765 | MakeChild (NodeQ, *t1, mPos); 766 | return ; 767 | } 768 | 769 | mMatchLen++; 770 | } 771 | 772 | NodeT = mPrev[NodeR]; 773 | mPrev[mPos] = NodeT; 774 | mNext[NodeT] = mPos; 775 | NodeT = mNext[NodeR]; 776 | mNext[mPos] = NodeT; 777 | mPrev[NodeT] = mPos; 778 | mParent[mPos] = NodeQ; 779 | mParent[NodeR] = NIL; 780 | 781 | // 782 | // Special usage of 'next' 783 | // 784 | mNext[NodeR] = mPos; 785 | 786 | } 787 | 788 | STATIC 789 | VOID 790 | DeleteNode ( 791 | VOID 792 | ) 793 | /*++ 794 | 795 | Routine Description: 796 | 797 | Delete outdated string info. (The Usage of PERC_FLAG 798 | ensures a clean deletion) 799 | 800 | Arguments: (VOID) 801 | 802 | Returns: (VOID) 803 | 804 | --*/ 805 | { 806 | NODE NodeQ; 807 | NODE NodeR; 808 | NODE NodeS; 809 | NODE NodeT; 810 | NODE NodeU; 811 | 812 | if (mParent[mPos] == NIL) { 813 | return ; 814 | } 815 | 816 | NodeR = mPrev[mPos]; 817 | NodeS = mNext[mPos]; 818 | mNext[NodeR] = NodeS; 819 | mPrev[NodeS] = NodeR; 820 | NodeR = mParent[mPos]; 821 | mParent[mPos] = NIL; 822 | if (NodeR >= WNDSIZ) { 823 | return ; 824 | } 825 | 826 | mChildCount[NodeR]--; 827 | if (mChildCount[NodeR] > 1) { 828 | return ; 829 | } 830 | 831 | NodeT = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG); 832 | if (NodeT >= mPos) { 833 | NodeT -= WNDSIZ; 834 | } 835 | 836 | NodeS = NodeT; 837 | NodeQ = mParent[NodeR]; 838 | NodeU = mPosition[NodeQ]; 839 | while (NodeU & (UINT32) PERC_FLAG) { 840 | NodeU &= (UINT32)~PERC_FLAG; 841 | if (NodeU >= mPos) { 842 | NodeU -= WNDSIZ; 843 | } 844 | 845 | if (NodeU > NodeS) { 846 | NodeS = NodeU; 847 | } 848 | 849 | mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ); 850 | NodeQ = mParent[NodeQ]; 851 | NodeU = mPosition[NodeQ]; 852 | } 853 | 854 | if (NodeQ < WNDSIZ) { 855 | if (NodeU >= mPos) { 856 | NodeU -= WNDSIZ; 857 | } 858 | 859 | if (NodeU > NodeS) { 860 | NodeS = NodeU; 861 | } 862 | 863 | mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ | (UINT32) PERC_FLAG); 864 | } 865 | 866 | NodeS = Child (NodeR, mText[NodeT + mLevel[NodeR]]); 867 | NodeT = mPrev[NodeS]; 868 | NodeU = mNext[NodeS]; 869 | mNext[NodeT] = NodeU; 870 | mPrev[NodeU] = NodeT; 871 | NodeT = mPrev[NodeR]; 872 | mNext[NodeT] = NodeS; 873 | mPrev[NodeS] = NodeT; 874 | NodeT = mNext[NodeR]; 875 | mPrev[NodeT] = NodeS; 876 | mNext[NodeS] = NodeT; 877 | mParent[NodeS] = mParent[NodeR]; 878 | mParent[NodeR] = NIL; 879 | mNext[NodeR] = mAvail; 880 | mAvail = NodeR; 881 | } 882 | 883 | STATIC 884 | VOID 885 | GetNextMatch ( 886 | VOID 887 | ) 888 | /*++ 889 | 890 | Routine Description: 891 | 892 | Advance the current position (read new data if needed). 893 | Delete outdated string info. Find a match string for current position. 894 | 895 | Arguments: (VOID) 896 | 897 | Returns: (VOID) 898 | 899 | --*/ 900 | { 901 | INT32 Number; 902 | 903 | mRemainder--; 904 | mPos++; 905 | if (mPos == WNDSIZ * 2) { 906 | memmove (&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH); 907 | Number = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ); 908 | mRemainder += Number; 909 | mPos = WNDSIZ; 910 | } 911 | 912 | DeleteNode (); 913 | InsertNode (); 914 | } 915 | 916 | STATIC 917 | INT32 918 | Encode ( 919 | VOID 920 | ) 921 | /*++ 922 | 923 | Routine Description: 924 | 925 | The macontrolling routine for compression process. 926 | 927 | Arguments: (VOID) 928 | 929 | Returns: 930 | 931 | EFI_SUCCESS - The compression is successful 932 | EFI_OUT_0F_RESOURCES - Not enough memory for compression process 933 | 934 | --*/ 935 | { 936 | INT32 Status; 937 | INT32 LastMatchLen; 938 | NODE LastMatchPos; 939 | 940 | Status = AllocateMemory (); 941 | if (Status) { 942 | FreeMemory (); 943 | return Status; 944 | } 945 | 946 | InitSlide (); 947 | 948 | HufEncodeStart (); 949 | 950 | mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH); 951 | 952 | mMatchLen = 0; 953 | mPos = WNDSIZ; 954 | InsertNode (); 955 | if (mMatchLen > mRemainder) { 956 | mMatchLen = mRemainder; 957 | } 958 | 959 | while (mRemainder > 0) { 960 | LastMatchLen = mMatchLen; 961 | LastMatchPos = mMatchPos; 962 | GetNextMatch (); 963 | if (mMatchLen > mRemainder) { 964 | mMatchLen = mRemainder; 965 | } 966 | 967 | if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) { 968 | // 969 | // Not enough benefits are gained by outputting a pointer, 970 | // so just output the original character 971 | // 972 | Output (mText[mPos - 1], 0); 973 | 974 | } else { 975 | 976 | if (LastMatchLen == THRESHOLD) { 977 | if (((mPos - LastMatchPos - 2) & (WNDSIZ - 1)) > (1U << 11)) { 978 | Output (mText[mPos - 1], 0); 979 | continue; 980 | } 981 | } 982 | // 983 | // Outputting a pointer is beneficial enough, do it. 984 | // 985 | Output ( 986 | LastMatchLen + (UINT8_MAX + 1 - THRESHOLD), 987 | (mPos - LastMatchPos - 2) & (WNDSIZ - 1) 988 | ); 989 | LastMatchLen--; 990 | while (LastMatchLen > 0) { 991 | GetNextMatch (); 992 | LastMatchLen--; 993 | } 994 | 995 | if (mMatchLen > mRemainder) { 996 | mMatchLen = mRemainder; 997 | } 998 | } 999 | } 1000 | 1001 | HufEncodeEnd (); 1002 | FreeMemory (); 1003 | return ERR_SUCCESS; 1004 | } 1005 | 1006 | STATIC 1007 | VOID 1008 | CountTFreq ( 1009 | VOID 1010 | ) 1011 | /*++ 1012 | 1013 | Routine Description: 1014 | 1015 | Count the frequencies for the Extra Set 1016 | 1017 | Arguments: (VOID) 1018 | 1019 | Returns: (VOID) 1020 | 1021 | --*/ 1022 | { 1023 | INT32 Index; 1024 | INT32 Index3; 1025 | INT32 Number; 1026 | INT32 Count; 1027 | 1028 | for (Index = 0; Index < NT; Index++) { 1029 | mTFreq[Index] = 0; 1030 | } 1031 | 1032 | Number = NC; 1033 | while (Number > 0 && mCLen[Number - 1] == 0) { 1034 | Number--; 1035 | } 1036 | 1037 | Index = 0; 1038 | while (Index < Number) { 1039 | Index3 = mCLen[Index++]; 1040 | if (Index3 == 0) { 1041 | Count = 1; 1042 | while (Index < Number && mCLen[Index] == 0) { 1043 | Index++; 1044 | Count++; 1045 | } 1046 | 1047 | if (Count <= 2) { 1048 | mTFreq[0] = (UINT16) (mTFreq[0] + Count); 1049 | } else if (Count <= 18) { 1050 | mTFreq[1]++; 1051 | } else if (Count == 19) { 1052 | mTFreq[0]++; 1053 | mTFreq[1]++; 1054 | } else { 1055 | mTFreq[2]++; 1056 | } 1057 | } else { 1058 | mTFreq[Index3 + 2]++; 1059 | } 1060 | } 1061 | } 1062 | 1063 | STATIC 1064 | VOID 1065 | WritePTLen ( 1066 | INT32 Number, 1067 | INT32 nbit, 1068 | INT32 Special 1069 | ) 1070 | /*++ 1071 | 1072 | Routine Description: 1073 | 1074 | Outputs the code length array for the Extra Set or the Position Set. 1075 | 1076 | Arguments: 1077 | 1078 | Number - the number of symbols 1079 | nbit - the number of bits needed to represent 'n' 1080 | Special - the special symbol that needs to be take care of 1081 | 1082 | Returns: (VOID) 1083 | 1084 | --*/ 1085 | { 1086 | INT32 Index; 1087 | INT32 Index3; 1088 | 1089 | while (Number > 0 && mPTLen[Number - 1] == 0) { 1090 | Number--; 1091 | } 1092 | 1093 | PutBits (nbit, Number); 1094 | Index = 0; 1095 | while (Index < Number) { 1096 | Index3 = mPTLen[Index++]; 1097 | if (Index3 <= 6) { 1098 | PutBits (3, Index3); 1099 | } else { 1100 | PutBits (Index3 - 3, (1U << (Index3 - 3)) - 2); 1101 | } 1102 | 1103 | if (Index == Special) { 1104 | while (Index < 6 && mPTLen[Index] == 0) { 1105 | Index++; 1106 | } 1107 | 1108 | PutBits (2, (Index - 3) & 3); 1109 | } 1110 | } 1111 | } 1112 | 1113 | STATIC 1114 | VOID 1115 | WriteCLen ( 1116 | VOID 1117 | ) 1118 | /*++ 1119 | 1120 | Routine Description: 1121 | 1122 | Outputs the code length array for Char&Length Set 1123 | 1124 | Arguments: (VOID) 1125 | 1126 | Returns: (VOID) 1127 | 1128 | --*/ 1129 | { 1130 | INT32 Index; 1131 | INT32 Index3; 1132 | INT32 Number; 1133 | INT32 Count; 1134 | 1135 | Number = NC; 1136 | while (Number > 0 && mCLen[Number - 1] == 0) { 1137 | Number--; 1138 | } 1139 | 1140 | PutBits (CBIT, Number); 1141 | Index = 0; 1142 | while (Index < Number) { 1143 | Index3 = mCLen[Index++]; 1144 | if (Index3 == 0) { 1145 | Count = 1; 1146 | while (Index < Number && mCLen[Index] == 0) { 1147 | Index++; 1148 | Count++; 1149 | } 1150 | 1151 | if (Count <= 2) { 1152 | for (Index3 = 0; Index3 < Count; Index3++) { 1153 | PutBits (mPTLen[0], mPTCode[0]); 1154 | } 1155 | } else if (Count <= 18) { 1156 | PutBits (mPTLen[1], mPTCode[1]); 1157 | PutBits (4, Count - 3); 1158 | } else if (Count == 19) { 1159 | PutBits (mPTLen[0], mPTCode[0]); 1160 | PutBits (mPTLen[1], mPTCode[1]); 1161 | PutBits (4, 15); 1162 | } else { 1163 | PutBits (mPTLen[2], mPTCode[2]); 1164 | PutBits (CBIT, Count - 20); 1165 | } 1166 | } else { 1167 | PutBits (mPTLen[Index3 + 2], mPTCode[Index3 + 2]); 1168 | } 1169 | } 1170 | } 1171 | 1172 | STATIC 1173 | VOID 1174 | EncodeC ( 1175 | INT32 Value 1176 | ) 1177 | { 1178 | PutBits (mCLen[Value], mCCode[Value]); 1179 | } 1180 | 1181 | STATIC 1182 | VOID 1183 | EncodeP ( 1184 | UINT32 Value 1185 | ) 1186 | { 1187 | UINT32 Index; 1188 | UINT32 NodeQ; 1189 | 1190 | Index = 0; 1191 | NodeQ = Value; 1192 | while (NodeQ) { 1193 | NodeQ >>= 1; 1194 | Index++; 1195 | } 1196 | 1197 | PutBits (mPTLen[Index], mPTCode[Index]); 1198 | if (Index > 1) { 1199 | PutBits (Index - 1, Value & (0xFFFFFFFFU >> (32 - Index + 1))); 1200 | } 1201 | } 1202 | 1203 | STATIC 1204 | VOID 1205 | SendBlock ( 1206 | VOID 1207 | ) 1208 | /*++ 1209 | 1210 | Routine Description: 1211 | 1212 | Huffman code the block and output it. 1213 | 1214 | Arguments: 1215 | (VOID) 1216 | 1217 | Returns: 1218 | (VOID) 1219 | 1220 | --*/ 1221 | { 1222 | UINT32 Index; 1223 | UINT32 Index2; 1224 | UINT32 Index3; 1225 | UINT32 Flags; 1226 | UINT32 Root; 1227 | UINT32 Pos; 1228 | UINT32 Size; 1229 | Flags = 0; 1230 | 1231 | Root = MakeTree (NC, mCFreq, mCLen, mCCode); 1232 | Size = mCFreq[Root]; 1233 | PutBits (16, Size); 1234 | if (Root >= NC) { 1235 | CountTFreq (); 1236 | Root = MakeTree (NT, mTFreq, mPTLen, mPTCode); 1237 | if (Root >= NT) { 1238 | WritePTLen (NT, TBIT, 3); 1239 | } else { 1240 | PutBits (TBIT, 0); 1241 | PutBits (TBIT, Root); 1242 | } 1243 | 1244 | WriteCLen (); 1245 | } else { 1246 | PutBits (TBIT, 0); 1247 | PutBits (TBIT, 0); 1248 | PutBits (CBIT, 0); 1249 | PutBits (CBIT, Root); 1250 | } 1251 | 1252 | Root = MakeTree (NP, mPFreq, mPTLen, mPTCode); 1253 | if (Root >= NP) { 1254 | WritePTLen (NP, PBIT, -1); 1255 | } else { 1256 | PutBits (PBIT, 0); 1257 | PutBits (PBIT, Root); 1258 | } 1259 | 1260 | Pos = 0; 1261 | for (Index = 0; Index < Size; Index++) { 1262 | if (Index % UINT8_BIT == 0) { 1263 | Flags = mBuf[Pos++]; 1264 | } else { 1265 | Flags <<= 1; 1266 | } 1267 | 1268 | if (Flags & (1U << (UINT8_BIT - 1))) { 1269 | EncodeC (mBuf[Pos++] + (1U << UINT8_BIT)); 1270 | Index3 = mBuf[Pos++]; 1271 | for (Index2 = 0; Index2 < 3; Index2++) { 1272 | Index3 <<= UINT8_BIT; 1273 | Index3 += mBuf[Pos++]; 1274 | } 1275 | 1276 | EncodeP (Index3); 1277 | } else { 1278 | EncodeC (mBuf[Pos++]); 1279 | } 1280 | } 1281 | 1282 | for (Index = 0; Index < NC; Index++) { 1283 | mCFreq[Index] = 0; 1284 | } 1285 | 1286 | for (Index = 0; Index < NP; Index++) { 1287 | mPFreq[Index] = 0; 1288 | } 1289 | } 1290 | 1291 | STATIC 1292 | VOID 1293 | Output ( 1294 | UINT32 CharC, 1295 | UINT32 Pos 1296 | ) 1297 | /*++ 1298 | 1299 | Routine Description: 1300 | 1301 | Outputs an Original Character or a Pointer 1302 | 1303 | Arguments: 1304 | 1305 | CharC - The original character or the 'String Length' element of a Pointer 1306 | Pos - The 'Position' field of a Pointer 1307 | 1308 | Returns: (VOID) 1309 | 1310 | --*/ 1311 | { 1312 | STATIC UINT32 CPos; 1313 | 1314 | if ((mOutputMask >>= 1) == 0) { 1315 | mOutputMask = 1U << (UINT8_BIT - 1); 1316 | // 1317 | // Check the buffer overflow per outputing UINT8_BIT symbols 1318 | // which is an Original Character or a Pointer. The biggest 1319 | // symbol is a Pointer which occupies 5 bytes. 1320 | // 1321 | if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) { 1322 | SendBlock (); 1323 | mOutputPos = 0; 1324 | } 1325 | 1326 | CPos = mOutputPos++; 1327 | mBuf[CPos] = 0; 1328 | } 1329 | 1330 | mBuf[mOutputPos++] = (UINT8) CharC; 1331 | mCFreq[CharC]++; 1332 | if (CharC >= (1U << UINT8_BIT)) { 1333 | mBuf[CPos] |= mOutputMask; 1334 | mBuf[mOutputPos++] = (UINT8) (Pos >> 24); 1335 | mBuf[mOutputPos++] = (UINT8) (Pos >> 16); 1336 | mBuf[mOutputPos++] = (UINT8) (Pos >> (UINT8_BIT)); 1337 | mBuf[mOutputPos++] = (UINT8) Pos; 1338 | CharC = 0; 1339 | while (Pos) { 1340 | Pos >>= 1; 1341 | CharC++; 1342 | } 1343 | 1344 | mPFreq[CharC]++; 1345 | } 1346 | } 1347 | 1348 | STATIC 1349 | VOID 1350 | HufEncodeStart ( 1351 | VOID 1352 | ) 1353 | { 1354 | INT32 Index; 1355 | 1356 | for (Index = 0; Index < NC; Index++) { 1357 | mCFreq[Index] = 0; 1358 | } 1359 | 1360 | for (Index = 0; Index < NP; Index++) { 1361 | mPFreq[Index] = 0; 1362 | } 1363 | 1364 | mOutputPos = mOutputMask = 0; 1365 | InitPutBits (); 1366 | return ; 1367 | } 1368 | 1369 | STATIC 1370 | VOID 1371 | HufEncodeEnd ( 1372 | VOID 1373 | ) 1374 | { 1375 | SendBlock (); 1376 | 1377 | // 1378 | // Flush remaining bits 1379 | // 1380 | PutBits (UINT8_BIT - 1, 0); 1381 | 1382 | return ; 1383 | } 1384 | 1385 | STATIC 1386 | VOID 1387 | MakeCrcTable ( 1388 | VOID 1389 | ) 1390 | { 1391 | UINT32 Index; 1392 | UINT32 Index2; 1393 | UINT32 Temp; 1394 | 1395 | for (Index = 0; Index <= UINT8_MAX; Index++) { 1396 | Temp = Index; 1397 | for (Index2 = 0; Index2 < UINT8_BIT; Index2++) { 1398 | if (Temp & 1) { 1399 | Temp = (Temp >> 1) ^ CRCPOLY; 1400 | } else { 1401 | Temp >>= 1; 1402 | } 1403 | } 1404 | 1405 | mCrcTable[Index] = (UINT16) Temp; 1406 | } 1407 | } 1408 | 1409 | STATIC 1410 | VOID 1411 | PutBits ( 1412 | INT32 Number, 1413 | UINT32 Value 1414 | ) 1415 | /*++ 1416 | 1417 | Routine Description: 1418 | 1419 | Outputs rightmost n bits of x 1420 | 1421 | Arguments: 1422 | 1423 | Number - the rightmost n bits of the data is used 1424 | x - the data 1425 | 1426 | Returns: (VOID) 1427 | 1428 | --*/ 1429 | { 1430 | UINT8 Temp; 1431 | 1432 | while (Number >= mBitCount) { 1433 | // 1434 | // Number -= mBitCount should never equal to 32 1435 | // 1436 | Temp = (UINT8) (mSubBitBuf | (Value >> (Number -= mBitCount))); 1437 | if (mDst < mDstUpperLimit) { 1438 | *mDst++ = Temp; 1439 | } 1440 | 1441 | mCompSize++; 1442 | mSubBitBuf = 0; 1443 | mBitCount = UINT8_BIT; 1444 | } 1445 | 1446 | mSubBitBuf |= Value << (mBitCount -= Number); 1447 | } 1448 | 1449 | STATIC 1450 | INT32 1451 | FreadCrc ( 1452 | UINT8 *Pointer, 1453 | INT32 Number 1454 | ) 1455 | /*++ 1456 | 1457 | Routine Description: 1458 | 1459 | Read source data 1460 | 1461 | Arguments: 1462 | 1463 | Pointer - the buffer to hold the data 1464 | Number - number of bytes to read 1465 | 1466 | Returns: 1467 | 1468 | number of bytes actually read 1469 | 1470 | --*/ 1471 | { 1472 | INT32 Index; 1473 | 1474 | for (Index = 0; mSrc < mSrcUpperLimit && Index < Number; Index++) { 1475 | *Pointer++ = *mSrc++; 1476 | } 1477 | 1478 | Number = Index; 1479 | 1480 | Pointer -= Number; 1481 | mOrigSize += Number; 1482 | Index--; 1483 | while (Index >= 0) { 1484 | UPDATE_CRC (*Pointer++); 1485 | Index--; 1486 | } 1487 | 1488 | return Number; 1489 | } 1490 | 1491 | STATIC 1492 | VOID 1493 | InitPutBits ( 1494 | VOID 1495 | ) 1496 | { 1497 | mBitCount = UINT8_BIT; 1498 | mSubBitBuf = 0; 1499 | } 1500 | 1501 | STATIC 1502 | VOID 1503 | CountLen ( 1504 | INT32 Index 1505 | ) 1506 | /*++ 1507 | 1508 | Routine Description: 1509 | 1510 | Count the number of each code length for a Huffman tree. 1511 | 1512 | Arguments: 1513 | 1514 | Index - the top node 1515 | 1516 | Returns: (VOID) 1517 | 1518 | --*/ 1519 | { 1520 | STATIC INT32 Depth = 0; 1521 | 1522 | if (Index < mN) { 1523 | mLenCnt[(Depth < 16) ? Depth : 16]++; 1524 | } else { 1525 | Depth++; 1526 | CountLen (mLeft[Index]); 1527 | CountLen (mRight[Index]); 1528 | Depth--; 1529 | } 1530 | } 1531 | 1532 | STATIC 1533 | VOID 1534 | MakeLen ( 1535 | INT32 Root 1536 | ) 1537 | /*++ 1538 | 1539 | Routine Description: 1540 | 1541 | Create code length array for a Huffman tree 1542 | 1543 | Arguments: 1544 | 1545 | Root - the root of the tree 1546 | 1547 | Returns: 1548 | 1549 | VOID 1550 | 1551 | --*/ 1552 | { 1553 | INT32 Index; 1554 | INT32 Index3; 1555 | UINT32 Cum; 1556 | 1557 | for (Index = 0; Index <= 16; Index++) { 1558 | mLenCnt[Index] = 0; 1559 | } 1560 | 1561 | CountLen (Root); 1562 | 1563 | // 1564 | // Adjust the length count array so that 1565 | // no code will be generated longer than its designated length 1566 | // 1567 | Cum = 0; 1568 | for (Index = 16; Index > 0; Index--) { 1569 | Cum += mLenCnt[Index] << (16 - Index); 1570 | } 1571 | 1572 | while (Cum != (1U << 16)) { 1573 | mLenCnt[16]--; 1574 | for (Index = 15; Index > 0; Index--) { 1575 | if (mLenCnt[Index] != 0) { 1576 | mLenCnt[Index]--; 1577 | mLenCnt[Index + 1] += 2; 1578 | break; 1579 | } 1580 | } 1581 | 1582 | Cum--; 1583 | } 1584 | 1585 | for (Index = 16; Index > 0; Index--) { 1586 | Index3 = mLenCnt[Index]; 1587 | Index3--; 1588 | while (Index3 >= 0) { 1589 | mLen[*mSortPtr++] = (UINT8) Index; 1590 | Index3--; 1591 | } 1592 | } 1593 | } 1594 | 1595 | STATIC 1596 | VOID 1597 | DownHeap ( 1598 | INT32 Index 1599 | ) 1600 | { 1601 | INT32 Index2; 1602 | INT32 Index3; 1603 | 1604 | // 1605 | // priority queue: send Index-th entry down heap 1606 | // 1607 | Index3 = mHeap[Index]; 1608 | Index2 = 2 * Index; 1609 | while (Index2 <= mHeapSize) { 1610 | if (Index2 < mHeapSize && mFreq[mHeap[Index2]] > mFreq[mHeap[Index2 + 1]]) { 1611 | Index2++; 1612 | } 1613 | 1614 | if (mFreq[Index3] <= mFreq[mHeap[Index2]]) { 1615 | break; 1616 | } 1617 | 1618 | mHeap[Index] = mHeap[Index2]; 1619 | Index = Index2; 1620 | Index2 = 2 * Index; 1621 | } 1622 | 1623 | mHeap[Index] = (INT16) Index3; 1624 | } 1625 | 1626 | STATIC 1627 | VOID 1628 | MakeCode ( 1629 | INT32 Number, 1630 | UINT8 Len[ ], 1631 | UINT16 Code[] 1632 | ) 1633 | /*++ 1634 | 1635 | Routine Description: 1636 | 1637 | Assign code to each symbol based on the code length array 1638 | 1639 | Arguments: 1640 | 1641 | Number - number of symbols 1642 | Len - the code length array 1643 | Code - stores codes for each symbol 1644 | 1645 | Returns: (VOID) 1646 | 1647 | --*/ 1648 | { 1649 | INT32 Index; 1650 | UINT16 Start[18]; 1651 | 1652 | Start[1] = 0; 1653 | for (Index = 1; Index <= 16; Index++) { 1654 | Start[Index + 1] = (UINT16) ((Start[Index] + mLenCnt[Index]) << 1); 1655 | } 1656 | 1657 | for (Index = 0; Index < Number; Index++) { 1658 | Code[Index] = Start[Len[Index]]++; 1659 | } 1660 | } 1661 | 1662 | STATIC 1663 | INT32 1664 | MakeTree ( 1665 | INT32 NParm, 1666 | UINT16 FreqParm[], 1667 | UINT8 LenParm[ ], 1668 | UINT16 CodeParm[] 1669 | ) 1670 | /*++ 1671 | 1672 | Routine Description: 1673 | 1674 | Generates Huffman codes given a frequency distribution of symbols 1675 | 1676 | Arguments: 1677 | 1678 | NParm - number of symbols 1679 | FreqParm - frequency of each symbol 1680 | LenParm - code length for each symbol 1681 | CodeParm - code for each symbol 1682 | 1683 | Returns: 1684 | 1685 | Root of the Huffman tree. 1686 | 1687 | --*/ 1688 | { 1689 | INT32 Index; 1690 | INT32 Index2; 1691 | INT32 Index3; 1692 | INT32 Avail; 1693 | 1694 | // 1695 | // make tree, calculate len[], return root 1696 | // 1697 | mN = NParm; 1698 | mFreq = FreqParm; 1699 | mLen = LenParm; 1700 | Avail = mN; 1701 | mHeapSize = 0; 1702 | mHeap[1] = 0; 1703 | for (Index = 0; Index < mN; Index++) { 1704 | mLen[Index] = 0; 1705 | if (mFreq[Index]) { 1706 | mHeapSize++; 1707 | mHeap[mHeapSize] = (INT16) Index; 1708 | } 1709 | } 1710 | 1711 | if (mHeapSize < 2) { 1712 | CodeParm[mHeap[1]] = 0; 1713 | return mHeap[1]; 1714 | } 1715 | 1716 | for (Index = mHeapSize / 2; Index >= 1; Index--) { 1717 | // 1718 | // make priority queue 1719 | // 1720 | DownHeap (Index); 1721 | } 1722 | 1723 | mSortPtr = CodeParm; 1724 | do { 1725 | Index = mHeap[1]; 1726 | if (Index < mN) { 1727 | *mSortPtr++ = (UINT16) Index; 1728 | } 1729 | 1730 | mHeap[1] = mHeap[mHeapSize--]; 1731 | DownHeap (1); 1732 | Index2 = mHeap[1]; 1733 | if (Index2 < mN) { 1734 | *mSortPtr++ = (UINT16) Index2; 1735 | } 1736 | 1737 | Index3 = Avail++; 1738 | mFreq[Index3] = (UINT16) (mFreq[Index] + mFreq[Index2]); 1739 | mHeap[1] = (INT16) Index3; 1740 | DownHeap (1); 1741 | mLeft[Index3] = (UINT16) Index; 1742 | mRight[Index3] = (UINT16) Index2; 1743 | } while (mHeapSize > 1); 1744 | 1745 | mSortPtr = CodeParm; 1746 | MakeLen (Index3); 1747 | MakeCode (NParm, LenParm, CodeParm); 1748 | 1749 | // 1750 | // return root 1751 | // 1752 | return Index3; 1753 | } 1754 | -------------------------------------------------------------------------------- /patch.c: -------------------------------------------------------------------------------- 1 | /* Patch Implementation 2 | 3 | Copyright (c) 2012, Nikolaj Schlej. All rights reserved. 4 | This program and the accompanying materials 5 | are licensed and made available under the terms and conditions of the BSD License 6 | which accompanies this distribution. The full text of the license may be found at 7 | http://opensource.org/licenses/bsd-license.php 8 | 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 | 12 | */ 13 | 14 | #include "patch_int.h" 15 | 16 | // Implementation of GNU memmem function using Boyer-Moore-Horspool algorithm 17 | UINT8* find_pattern(UINT8* string, UINT32 slen, CONST UINT8* pattern, UINT32 plen) 18 | { 19 | UINT32 scan = 0; 20 | UINT32 bad_char_skip[256]; 21 | UINT32 last; 22 | 23 | if (plen == 0 || !string || !pattern) 24 | return NULL; 25 | 26 | for (scan = 0; scan <= 255; scan++) 27 | bad_char_skip[scan] = plen; 28 | 29 | last = plen - 1; 30 | 31 | for (scan = 0; scan < last; scan++) 32 | bad_char_skip[pattern[scan]] = last - scan; 33 | 34 | while (slen >= plen) 35 | { 36 | for (scan = last; string[scan] == pattern[scan]; scan--) 37 | if (scan == 0) 38 | return string; 39 | 40 | slen -= bad_char_skip[string[last]]; 41 | string += bad_char_skip[string[last]]; 42 | } 43 | 44 | return NULL; 45 | } 46 | 47 | UINT8 calculate_checksum(UINT8* data, UINT32 length) 48 | { 49 | UINT8 counter = 0; 50 | while(length--) 51 | counter += data[length]; 52 | return ~counter + 1; 53 | } 54 | 55 | VOID int2size(UINT32 size, UINT8* module_size) 56 | { 57 | module_size[2] = (UINT8) ((size) >> 16); 58 | module_size[1] = (UINT8) ((size) >> 8); 59 | module_size[0] = (UINT8) ((size) ); 60 | } 61 | 62 | UINT32 size2int(UINT8* module_size) 63 | { 64 | return (module_size[2] << 16) + 65 | (module_size[1] << 8) + 66 | module_size[0]; 67 | } 68 | 69 | UINT8 correct_checksums(UINT8* module) 70 | { 71 | module_header *header; 72 | 73 | if(!module) 74 | return ERR_INVALID_ARGUMENT; 75 | 76 | header = (module_header*) module; 77 | 78 | // Calculating new module checksums 79 | header->header_checksum = 0; 80 | header->data_checksum = 0; 81 | header->header_checksum = calculate_checksum(module, sizeof(module_header) - 1); 82 | header->data_checksum = calculate_checksum(module + sizeof(module_header), size2int(header->size) - sizeof(module_header)); 83 | 84 | return ERR_PATCHED; 85 | } 86 | 87 | UINT8 insert_gap_after(UINT8* module, UINT8* end, UINT32 gap_size) 88 | { 89 | UINT8 *gap; 90 | module_header *header; 91 | module_header *gap_header; 92 | UINT32 size; 93 | UINT32 allignment; 94 | 95 | if (!module || !end || end <= module) 96 | return ERR_INVALID_ARGUMENT; 97 | 98 | // Checking for existing GAP module 99 | // Determining next module position 100 | header = (module_header *) module; 101 | gap = module + size2int(header->size); 102 | size = gap - module; 103 | if (size % MODULE_ALLIGNMENT) 104 | allignment = MODULE_ALLIGNMENT - size % MODULE_ALLIGNMENT; 105 | else 106 | allignment = 0; 107 | gap += allignment; 108 | // Checking for next module to be GAP 109 | if (find_pattern(gap, sizeof(GAP_UUID), GAP_UUID, sizeof(GAP_UUID))) 110 | { 111 | header = (module_header *) gap; 112 | // Using found GAP module as free space 113 | gap_size += size2int(header->size) + allignment; 114 | } 115 | 116 | size = end - module; 117 | if (size % MODULE_ALLIGNMENT) 118 | allignment = MODULE_ALLIGNMENT - size % MODULE_ALLIGNMENT; 119 | else 120 | allignment = 0; 121 | 122 | gap_size -= allignment; 123 | 124 | if (gap_size < sizeof(module_header)) 125 | return ERR_INVALID_ARGUMENT; 126 | 127 | memset(end, 0xFF, allignment); 128 | 129 | gap = end + allignment; 130 | gap_header = (module_header*) gap; 131 | 132 | // Constructing gap header 133 | memcpy(gap_header->guid, GAP_UUID, sizeof(GAP_UUID)); 134 | gap_header->type = TYPE_GAP; 135 | gap_header->attributes = ATTRIBUTES_GAP; 136 | gap_header->state = STATE_STD; 137 | int2size(gap_size, gap_header->size); 138 | 139 | // Filling gap with 0xFF byte 140 | memset(gap + sizeof(module_header), 0xFF, gap_size - sizeof(module_header)); 141 | 142 | // Calculating checksums 143 | gap_header->header_checksum = 0; 144 | gap_header->data_checksum = 0; 145 | gap_header->header_checksum = calculate_checksum(gap, sizeof(module_header) - 1); 146 | gap_header->data_checksum = 0xAA; 147 | 148 | printf("Gap module inserted after repacked module.\n"); 149 | 150 | return ERR_PATCHED; 151 | } 152 | 153 | UINT8 patch_powermanagement_module(UINT8* module, UINT8 start_patch) 154 | { 155 | module_header *header; 156 | common_section_header *common_header; 157 | compressed_section_header *compressed_header; 158 | guid_section_header *guid_header; 159 | UINT8* data; 160 | UINT32 data_size; 161 | UINT8* compressed; 162 | UINT32 compressed_size; 163 | UINT8* decompressed; 164 | UINT32 decompressed_size; 165 | UINT8* scratch; 166 | UINT32 scratch_size; 167 | UINT8* string; 168 | UINT8 current_patch; 169 | BOOLEAN is_patched; 170 | INT32 module_size_change; 171 | UINT32 grow; 172 | UINT32 freespace_length; 173 | UINT8* end; 174 | UINT8 allignment; 175 | 176 | if(!module || start_patch >= PATCHED_PATTERNS_COUNT) 177 | return ERR_INVALID_ARGUMENT; 178 | 179 | header = (module_header*) module; 180 | if (header->state != STATE_STD) 181 | return ERR_NOT_MODULE; 182 | 183 | data = module + sizeof(module_header); 184 | 185 | common_header = (common_section_header*) data; 186 | // PowerManagement and PowerMgmtDxe modules, continue execution 187 | if (common_header->type == SECTION_DXE_DEPEX) 188 | data += size2int(common_header->size); 189 | // PowerManagement2.efi module special case 190 | else if (common_header->type == SECTION_GUID_DEFINED) 191 | { 192 | guid_header = (guid_section_header*) data; 193 | data += guid_header->data_offset; 194 | 195 | // Searching for specific patch patterns first 196 | string = find_pattern(data, size2int(guid_header->size), POWERMANAGEMENT_PATCH_PATTERN_80FB01, sizeof(POWERMANAGEMENT_PATCH_PATTERN_80FB01)); 197 | if(string) 198 | { 199 | // Patching first 3 bytes with 0x90 200 | memset(string, 0x90, 3); 201 | string += 3; 202 | } 203 | else 204 | // Searching for generic patch pattern 205 | string = find_pattern(data, size2int(guid_header->size), POWERMANAGEMENT_PATCH_PATTERN, sizeof(POWERMANAGEMENT_PATCH_PATTERN)); 206 | if (!string) 207 | return ERR_PATCH_STRING_NOT_FOUND; 208 | 209 | // Patching 210 | memcpy(string, POWERMANAGEMENT_PATCHED_PATTERNS[start_patch], sizeof(POWERMANAGEMENT_PATCH_PATTERN)); 211 | 212 | // Correcting checksums 213 | return correct_checksums(module); 214 | } 215 | else 216 | return ERR_UNKNOWN_MODULE; 217 | 218 | // Skipping section allignment bytes 219 | allignment = (data - module) % SECTION_ALLIGNMENT; 220 | if (allignment) 221 | data += SECTION_ALLIGNMENT - allignment; 222 | 223 | // Reading compressed header 224 | compressed_header = (compressed_section_header*) data; 225 | if (compressed_header->type == SECTION_COMPRESSED) 226 | { 227 | data += sizeof(compressed_section_header); 228 | data_size = size2int(compressed_header->size) - sizeof(compressed_section_header); 229 | } 230 | else 231 | return ERR_UNKNOWN_MODULE; 232 | 233 | // Decompressing module data 234 | compressed = NULL; 235 | switch (compressed_header->compression_type) 236 | { 237 | case COMPRESSION_TIANO: 238 | if (TianoGetInfo(data, data_size, &decompressed_size, &scratch_size) != ERR_SUCCESS 239 | || decompressed_size != compressed_header->decompressed_size) 240 | return ERR_TIANO_DECOMPRESSION_FAILED; 241 | 242 | decompressed = (UINT8*)malloc(decompressed_size); 243 | scratch = (UINT8*)malloc(scratch_size); 244 | 245 | if (TianoDecompress(data, data_size, decompressed, decompressed_size, scratch, scratch_size) != ERR_SUCCESS) 246 | return ERR_TIANO_DECOMPRESSION_FAILED; 247 | free(scratch); 248 | break; 249 | case COMPRESSION_LZMA: 250 | if (LzmaGetInfo(data, data_size, &decompressed_size) != ERR_SUCCESS 251 | || decompressed_size != compressed_header->decompressed_size) 252 | return ERR_LZMA_DECOMPRESSION_FAILED; 253 | 254 | decompressed = (UINT8*)malloc(decompressed_size); 255 | if (!decompressed) 256 | return ERR_MEMORY_ALLOCATION_FAILED; 257 | 258 | if (LzmaDecompress(data, data_size, decompressed) != ERR_SUCCESS) 259 | return ERR_LZMA_DECOMPRESSION_FAILED; 260 | break; 261 | case COMPRESSION_NONE: 262 | decompressed = data; 263 | decompressed_size = data_size; 264 | break; 265 | default: 266 | return ERR_UNKNOWN_COMPRESSION_TYPE; 267 | } 268 | 269 | // Searching for specific patch patterns first 270 | string = find_pattern(decompressed, decompressed_size, POWERMANAGEMENT_PATCH_PATTERN_80FB01, sizeof(POWERMANAGEMENT_PATCH_PATTERN_80FB01)); 271 | if(string) 272 | { 273 | // Patching first 3 bytes with 0x90 274 | memset(string, 0x90, 3); 275 | string += 3; 276 | } 277 | else 278 | // Searching for generic patch pattern 279 | string = find_pattern(decompressed, decompressed_size, POWERMANAGEMENT_PATCH_PATTERN, sizeof(POWERMANAGEMENT_PATCH_PATTERN)); 280 | if (!string) 281 | return ERR_PATCH_STRING_NOT_FOUND; 282 | 283 | // Trying all patched strings beginning from start_patch 284 | is_patched = FALSE; 285 | for(current_patch = start_patch; current_patch < PATCHED_PATTERNS_COUNT; current_patch++) 286 | { 287 | // Patching found string with current patch 288 | memcpy(string, POWERMANAGEMENT_PATCHED_PATTERNS[current_patch], sizeof(POWERMANAGEMENT_PATCH_PATTERN)); 289 | 290 | // Compressing patched module 291 | switch(compressed_header->compression_type) 292 | { 293 | case COMPRESSION_TIANO: 294 | compressed_size = 0; 295 | if (TianoCompress(decompressed, decompressed_size, compressed, &compressed_size) != ERR_BUFFER_TOO_SMALL) 296 | return ERR_TIANO_COMPRESSION_FAILED; 297 | compressed = (UINT8*)malloc(compressed_size); 298 | if (!compressed) 299 | return ERR_MEMORY_ALLOCATION_FAILED; 300 | if (TianoCompress(decompressed, decompressed_size, compressed, &compressed_size) != ERR_SUCCESS) 301 | return ERR_TIANO_COMPRESSION_FAILED; 302 | break; 303 | case COMPRESSION_LZMA: 304 | compressed_size = 0; 305 | if(LzmaCompress(decompressed, decompressed_size, compressed, &compressed_size) != ERR_BUFFER_TOO_SMALL) 306 | return ERR_LZMA_COMPRESSION_FAILED; 307 | compressed = (UINT8*)malloc(compressed_size); 308 | if (!compressed) 309 | return ERR_MEMORY_ALLOCATION_FAILED; 310 | if (LzmaCompress(decompressed, decompressed_size, compressed, &compressed_size) != ERR_SUCCESS) 311 | return ERR_TIANO_COMPRESSION_FAILED; 312 | break; 313 | case COMPRESSION_NONE: 314 | compressed = decompressed; 315 | compressed_size = decompressed_size; 316 | break; 317 | default: 318 | return ERR_UNKNOWN_COMPRESSION_TYPE; 319 | } 320 | 321 | // Checking compressed data size 322 | if (data_size < compressed_size) 323 | { 324 | grow = compressed_size - data_size; 325 | end = data + data_size; 326 | for (freespace_length = 0; *end++ == 0xFF; freespace_length++); 327 | if (grow > freespace_length) 328 | continue; 329 | } 330 | else if (data_size > compressed_size) 331 | { 332 | grow = data_size - compressed_size; 333 | end = data + data_size; 334 | for (freespace_length = 0; *end++ == 0xFF; freespace_length++); 335 | if (grow + freespace_length >= 8) 336 | if (insert_gap_after(module, data + compressed_size, grow)) 337 | continue; 338 | } 339 | 340 | is_patched = TRUE; 341 | break; 342 | } 343 | 344 | if (!is_patched) 345 | return ERR_PATCHED_MODULE_INSERTION_FAILED; 346 | 347 | // Writing new module 348 | if (data_size > compressed_size) 349 | memset(data + compressed_size, 0xFF, data_size - compressed_size); 350 | if (compressed_header->compression_type != COMPRESSION_NONE) 351 | { 352 | memcpy(data, compressed, compressed_size); 353 | // Writing new compressed section size 354 | int2size(compressed_size + sizeof(compressed_section_header), compressed_header->size); 355 | // Writing new module size 356 | module_size_change = compressed_size - data_size; 357 | int2size(size2int(header->size) + module_size_change, header->size); 358 | } 359 | 360 | // Correcting checksums 361 | return correct_checksums(module); 362 | } 363 | 364 | UINT8 patch_smmplatform_module(UINT8* module) 365 | { 366 | module_header* header; 367 | UINT8* string; 368 | UINT8* data; 369 | guid_section_header *guid_header; 370 | common_section_header *depex_header; 371 | UINT8 allignment; 372 | 373 | if(!module) 374 | return ERR_INVALID_ARGUMENT; 375 | 376 | header = (module_header*) module; 377 | if (header->state != STATE_STD) 378 | return ERR_NOT_MODULE; 379 | 380 | data = module + sizeof(module_header); 381 | 382 | guid_header = (guid_section_header*) data; 383 | // Skipping GUID definition section in the beginning of SmmPlatform module 384 | if (guid_header->type == SECTION_GUID_DEFINED) 385 | data += guid_header->data_offset; 386 | else 387 | return ERR_UNKNOWN_MODULE; 388 | 389 | // Skipping section allignment bytes 390 | allignment = (data - module) % SECTION_ALLIGNMENT; 391 | if (allignment) 392 | data += SECTION_ALLIGNMENT - allignment; 393 | 394 | depex_header = (common_section_header*) data; 395 | // Skipping DXE dependency section in the beginning of SmmPlatform module 396 | if (depex_header->type == SECTION_DXE_DEPEX) 397 | data += size2int(depex_header->size); 398 | else 399 | return ERR_UNKNOWN_MODULE; 400 | 401 | // Searching for patch pattern 402 | string = find_pattern(data, size2int(guid_header->size) - size2int(depex_header->size), SMMPLATFORM_PATCH_PATTERN, sizeof(SMMPLATFORM_PATCH_PATTERN)); 403 | if (!string) 404 | return ERR_PATCH_STRING_NOT_FOUND; 405 | 406 | // Patching 407 | memcpy(string, SMMPLATFORM_PATCHED_PATTERN, sizeof(SMMPLATFORM_PATCHED_PATTERN)); 408 | 409 | // Correcting checksums 410 | return correct_checksums(module); 411 | } 412 | 413 | UINT8 patch_platformsetupadvanced_module(UINT8* module) 414 | { 415 | module_header* header; 416 | UINT8* string; 417 | UINT8* data; 418 | guid_section_header *guid_header; 419 | BOOLEAN is_found; 420 | 421 | if(!module) 422 | return ERR_INVALID_ARGUMENT; 423 | 424 | header = (module_header*) module; 425 | if (header->state != STATE_STD) 426 | return ERR_NOT_MODULE; 427 | 428 | data = module + sizeof(module_header); 429 | 430 | guid_header = (guid_section_header*) data; 431 | // Skipping GUID definition section in the beginning of PlatformSetupAdvancedDxe.efi module 432 | if (guid_header->type == SECTION_GUID_DEFINED) 433 | data += guid_header->data_offset; 434 | else 435 | return ERR_UNKNOWN_MODULE; 436 | 437 | // Searching for Unicode patch string 438 | string = find_pattern(data, size2int(guid_header->size), PLATFORMSETUPADVANCED_UNICODE_PATCH_PATTERN, sizeof(PLATFORMSETUPADVANCED_UNICODE_PATCH_PATTERN)); 439 | if(string) 440 | { 441 | memcpy(string, PLATFORMSETUPADVANCED_UNICODE_PATCHED_PATTERN, sizeof(PLATFORMSETUPADVANCED_UNICODE_PATCH_PATTERN)); 442 | } 443 | else 444 | return ERR_PATCH_STRING_NOT_FOUND; // TIP: Remove this line to make more BIOSes patchable 445 | 446 | // Searching for all patch strings 447 | is_found = FALSE; 448 | for (string = find_pattern(data, size2int(guid_header->size), PLATFORMSETUPADVANCED_PATCH_PATTERN, sizeof(PLATFORMSETUPADVANCED_PATCH_PATTERN)); 449 | string; 450 | string = find_pattern(data, size2int(guid_header->size), PLATFORMSETUPADVANCED_PATCH_PATTERN, sizeof(PLATFORMSETUPADVANCED_PATCH_PATTERN))) 451 | { 452 | is_found = TRUE; 453 | // Patching 454 | memcpy(string, PLATFORMSETUPADVANCED_PATCHED_PATTERN, sizeof(PLATFORMSETUPADVANCED_PATCH_PATTERN)); 455 | } 456 | if(!is_found) 457 | return ERR_PATCH_STRING_NOT_FOUND; 458 | 459 | // Correcting checksums 460 | return correct_checksums(module); 461 | } 462 | 463 | UINT8 patch_cpupei_module(UINT8* module) 464 | { 465 | module_header* header; 466 | UINT8* string; 467 | 468 | if(!module) 469 | return ERR_INVALID_ARGUMENT; 470 | 471 | header = (module_header*) module; 472 | if (header->state != STATE_STD) 473 | return ERR_NOT_MODULE; 474 | 475 | header = (module_header*) module; 476 | 477 | // Searching for patch string 478 | string = find_pattern(module, size2int(header->size), CPUPEI_PATCH_PATTERN, sizeof(CPUPEI_PATCH_PATTERN)); 479 | if(!string) 480 | return ERR_PATCH_STRING_NOT_FOUND; 481 | 482 | // Patching 483 | memcpy(string, CPUPEI_PATCHED_PATTERN, sizeof(CPUPEI_PATCH_PATTERN)); 484 | 485 | // Correcting checksums 486 | return correct_checksums(module); 487 | } 488 | 489 | UINT8 patch_nested_module(UINT8* module) 490 | { 491 | module_header *header; 492 | compressed_section_header *compressed_header; 493 | UINT8* data; 494 | UINT32 data_size; 495 | UINT8* compressed; 496 | UINT32 compressed_size; 497 | UINT8* decompressed; 498 | UINT32 decompressed_size; 499 | UINT8* scratch; 500 | UINT32 scratch_size; 501 | UINT8* string; 502 | INT32 module_size_change; 503 | UINT8 current_patch; 504 | UINT8 result; 505 | BOOLEAN is_patched; 506 | BOOLEAN is_module_patched; 507 | 508 | if(!module) 509 | return ERR_INVALID_ARGUMENT; 510 | 511 | header = (module_header*) module; 512 | if (header->state != STATE_STD) 513 | return ERR_NOT_MODULE; 514 | 515 | data = module + sizeof(module_header); 516 | 517 | compressed_header = (compressed_section_header*) data; 518 | if(compressed_header->type != SECTION_COMPRESSED) 519 | return ERR_UNKNOWN_MODULE; 520 | 521 | data += sizeof(compressed_section_header); 522 | data_size = size2int(compressed_header->size) - sizeof(compressed_section_header); 523 | 524 | // Decompressing module data 525 | switch (compressed_header->compression_type) 526 | { 527 | case COMPRESSION_TIANO: 528 | if (TianoGetInfo(data, data_size, &decompressed_size, &scratch_size) != ERR_SUCCESS 529 | || decompressed_size != compressed_header->decompressed_size) 530 | return ERR_TIANO_DECOMPRESSION_FAILED; 531 | 532 | decompressed = (UINT8*)malloc(decompressed_size); 533 | scratch = (UINT8*)malloc(scratch_size); 534 | if (!decompressed || !scratch) 535 | return ERR_MEMORY_ALLOCATION_FAILED; 536 | 537 | if (TianoDecompress(data, data_size, decompressed, decompressed_size, scratch, scratch_size) != ERR_SUCCESS) 538 | return ERR_TIANO_DECOMPRESSION_FAILED; 539 | free(scratch); 540 | break; 541 | case COMPRESSION_LZMA: 542 | if (LzmaGetInfo(data, data_size, &decompressed_size) != ERR_SUCCESS 543 | || decompressed_size != compressed_header->decompressed_size) 544 | return ERR_LZMA_DECOMPRESSION_FAILED; 545 | 546 | decompressed = (UINT8*)malloc(decompressed_size); 547 | if (!decompressed) 548 | return ERR_MEMORY_ALLOCATION_FAILED; 549 | 550 | if (LzmaDecompress(data, data_size, decompressed) != ERR_SUCCESS) 551 | return ERR_LZMA_DECOMPRESSION_FAILED; 552 | break; 553 | case COMPRESSION_NONE: 554 | decompressed = data; 555 | decompressed_size = data_size; 556 | break; 557 | default: 558 | return ERR_UNKNOWN_COMPRESSION_TYPE; 559 | } 560 | 561 | // Searching for PlatformSetupAdvancedDxe.efi module 562 | string = find_pattern(decompressed, decompressed_size, PLATFORMSETUPADVANCED_UUID, UUID_LENGTH); 563 | if (string) 564 | { 565 | result = patch_platformsetupadvanced_module(string); 566 | if (!result) 567 | printf("Nested PlatformSetupAdvancedDxe.efi at %08X patched.\n", (UINT32)(string - module)); 568 | } 569 | 570 | // Trying to patch PowerManagement modules with all patch patterns 571 | is_patched = FALSE; 572 | scratch = (UINT8*)malloc(decompressed_size); 573 | if (!scratch) 574 | return ERR_MEMORY_ALLOCATION_FAILED; 575 | 576 | for (current_patch = 0; current_patch < PATCHED_PATTERNS_COUNT; current_patch++) 577 | { 578 | printf("Trying to apply patch #%d\n", current_patch + 1); 579 | 580 | // Making a copy of decompressed module 581 | memcpy(scratch, decompressed, decompressed_size); 582 | 583 | is_module_patched = FALSE; 584 | 585 | // Searching for all PowerManagement modules 586 | for (string = find_pattern(scratch, decompressed_size, POWERMANAGEMENT_UUID, UUID_LENGTH); 587 | string; 588 | string = find_pattern(string + UUID_LENGTH, decompressed_size - (string - scratch) - UUID_LENGTH, POWERMANAGEMENT_UUID, UUID_LENGTH)) 589 | { 590 | // Patching PowerManagement module 591 | result = patch_powermanagement_module(string, current_patch); 592 | 593 | if (!result) 594 | { 595 | printf("Nested PowerManagement module at %08X patched.\n", (UINT32)(string - scratch)); 596 | is_module_patched = TRUE; 597 | continue; 598 | } 599 | 600 | printf("Nested PowerManagement module at %08X not patched: ", (UINT32)(string - scratch)); 601 | switch (result) 602 | { 603 | case ERR_INVALID_ARGUMENT: 604 | printf("Invalid parameter.\n"); 605 | break; 606 | case ERR_NOT_MODULE: 607 | printf("Unknown module state.\n"); 608 | break; 609 | case ERR_UNKNOWN_MODULE: 610 | printf("Unknown module structure.\n"); 611 | break; 612 | case ERR_UNKNOWN_COMPRESSION_TYPE: 613 | printf("Unknown compression type.\n"); 614 | break; 615 | case ERR_TIANO_DECOMPRESSION_FAILED: 616 | printf("Tiano decompression failed.\n"); 617 | break; 618 | case ERR_LZMA_DECOMPRESSION_FAILED: 619 | printf("LZMA decompression failed.\n"); 620 | break; 621 | case ERR_PATCH_STRING_NOT_FOUND: 622 | printf("Patch pattern not found.\n"); 623 | break; 624 | case ERR_TIANO_COMPRESSION_FAILED: 625 | printf("Tiano compression failed.\n"); 626 | break; 627 | case ERR_LZMA_COMPRESSION_FAILED: 628 | printf("LZMA compression failed.\n"); 629 | break; 630 | case ERR_MEMORY_ALLOCATION_FAILED: 631 | printf("Memory allocation failed.\n"); 632 | break; 633 | default: 634 | printf("Unknown error.\n"); 635 | break; 636 | } 637 | } 638 | 639 | // Searching for all PowerMgmtDxe modules 640 | for (string = find_pattern(scratch, decompressed_size, POWERMGMTDXE_UUID, UUID_LENGTH); 641 | string; 642 | string = find_pattern(string + UUID_LENGTH, decompressed_size - (string - scratch) - UUID_LENGTH, POWERMGMTDXE_UUID, UUID_LENGTH)) 643 | { 644 | // Patching PowerMgmtDxe module 645 | result = patch_powermanagement_module(string, current_patch); 646 | 647 | if (!result) 648 | { 649 | printf("Nested PowerMgmtDxe/PowerManagement2.efi module at %08X patched.\n", (UINT32)(string - scratch)); 650 | is_module_patched = TRUE; 651 | continue; 652 | } 653 | 654 | printf("Nested PowerMgmtDxe/PowerManagement2.efi module at %08X not patched: ", (UINT32)(string - scratch)); 655 | switch (result) 656 | { 657 | case ERR_INVALID_ARGUMENT: 658 | printf("Invalid parameter.\n"); 659 | break; 660 | case ERR_NOT_MODULE: 661 | printf("Unknown module state.\n"); 662 | break; 663 | case ERR_UNKNOWN_MODULE: 664 | printf("Unknown module structure.\n"); 665 | break; 666 | case ERR_UNKNOWN_COMPRESSION_TYPE: 667 | printf("Unknown compression type.\n"); 668 | break; 669 | case ERR_TIANO_DECOMPRESSION_FAILED: 670 | printf("Tiano decompression failed.\n"); 671 | break; 672 | case ERR_LZMA_DECOMPRESSION_FAILED: 673 | printf("LZMA decompression failed.\n"); 674 | break; 675 | case ERR_PATCH_STRING_NOT_FOUND: 676 | printf("Patch pattern not found.\n"); 677 | break; 678 | case ERR_TIANO_COMPRESSION_FAILED: 679 | printf("Tiano compression failed.\n"); 680 | break; 681 | case ERR_LZMA_COMPRESSION_FAILED: 682 | printf("LZMA compression failed.\n"); 683 | break; 684 | case ERR_MEMORY_ALLOCATION_FAILED: 685 | printf("Memory allocation failed.\n"); 686 | break; 687 | default: 688 | printf("Unknown error.\n"); 689 | break; 690 | } 691 | } 692 | 693 | // Searching for all SmmPlatform modules 694 | for (string = find_pattern(scratch, decompressed_size, SMMPLATFORM_UUID, UUID_LENGTH); 695 | string; 696 | string = find_pattern(string + UUID_LENGTH, decompressed_size - (string - scratch) - UUID_LENGTH, SMMPLATFORM_UUID, UUID_LENGTH)) 697 | { 698 | // Patching SmmPlatform module 699 | result = patch_smmplatform_module(string); 700 | 701 | if (!result) 702 | { 703 | printf("Nested SmmPlatform module at %08X patched.\n", (UINT32)(string - scratch)); 704 | is_module_patched = TRUE; 705 | continue; 706 | } 707 | 708 | printf("Nested SmmPlatform module at %08X not patched: ", (UINT32)(string - scratch)); 709 | switch (result) 710 | { 711 | case ERR_INVALID_ARGUMENT: 712 | printf("Invalid parameter.\n"); 713 | break; 714 | case ERR_NOT_MODULE: 715 | printf("Unknown module state.\n"); 716 | break; 717 | case ERR_UNKNOWN_MODULE: 718 | printf("Unknown module structure.\n"); 719 | break; 720 | case ERR_UNKNOWN_COMPRESSION_TYPE: 721 | printf("Unknown compression type.\n"); 722 | break; 723 | case ERR_TIANO_DECOMPRESSION_FAILED: 724 | printf("Tiano decompression failed.\n"); 725 | break; 726 | case ERR_LZMA_DECOMPRESSION_FAILED: 727 | printf("LZMA decompression failed.\n"); 728 | break; 729 | case ERR_PATCH_STRING_NOT_FOUND: 730 | printf("Patch pattern not found.\n"); 731 | break; 732 | case ERR_TIANO_COMPRESSION_FAILED: 733 | printf("Tiano compression failed.\n"); 734 | break; 735 | case ERR_LZMA_COMPRESSION_FAILED: 736 | printf("LZMA compression failed.\n"); 737 | break; 738 | case ERR_MEMORY_ALLOCATION_FAILED: 739 | printf("Memory allocation failed.\n"); 740 | break; 741 | default: 742 | printf("Unknown error.\n"); 743 | break; 744 | } 745 | } 746 | 747 | if (!is_module_patched) 748 | return ERR_MODULE_NOT_FOUND; 749 | 750 | // Compressing patched module 751 | switch(compressed_header->compression_type) 752 | { 753 | case COMPRESSION_TIANO: 754 | compressed = 0; 755 | compressed_size = 0; 756 | if (TianoCompress(scratch, decompressed_size, compressed, &compressed_size) != ERR_BUFFER_TOO_SMALL) 757 | return ERR_TIANO_COMPRESSION_FAILED; 758 | compressed = (UINT8*)malloc(compressed_size); 759 | if(!compressed) 760 | return ERR_MEMORY_ALLOCATION_FAILED; 761 | if (TianoCompress(scratch, decompressed_size, compressed, &compressed_size) != ERR_SUCCESS) 762 | return ERR_TIANO_COMPRESSION_FAILED; 763 | break; 764 | case COMPRESSION_LZMA: 765 | compressed = 0; 766 | compressed_size = 0; 767 | if(LzmaCompress(scratch, decompressed_size, compressed, &compressed_size) != ERR_BUFFER_TOO_SMALL) 768 | return ERR_LZMA_COMPRESSION_FAILED; 769 | compressed = (UINT8*)malloc(compressed_size); 770 | if(!compressed) 771 | return ERR_MEMORY_ALLOCATION_FAILED; 772 | if (LzmaCompress(scratch, decompressed_size, compressed, &compressed_size) != ERR_SUCCESS) 773 | return ERR_TIANO_COMPRESSION_FAILED; 774 | break; 775 | case COMPRESSION_NONE: 776 | compressed = scratch; 777 | compressed_size = decompressed_size; 778 | break; 779 | default: 780 | return ERR_UNKNOWN_COMPRESSION_TYPE; 781 | } 782 | 783 | module_size_change = compressed_size - data_size; 784 | // Checking that new compressed module can be inserted 785 | if (module_size_change > 0) // Compressed module is bigger then original 786 | { 787 | INT32 pos; 788 | for(pos = 0; data[data_size+pos] == 0xFF; pos++); 789 | if(pos < module_size_change) 790 | { 791 | printf ("Patched module too big after compression.\n"); 792 | continue; 793 | } 794 | } 795 | else if (module_size_change < 0) // Compressed module is smaller then original 796 | { 797 | // Checking if there is another module after this one 798 | INT32 pos; 799 | for(pos = 0; data[data_size+pos] == 0xFF; pos++); 800 | if (pos < 8 && -module_size_change + pos > 7) 801 | { 802 | if (insert_gap_after(module, data + compressed_size, data_size - compressed_size)) 803 | { 804 | printf ("Patched module is smaller then original after compression, but gap module can't be inserted.\n"); 805 | continue; 806 | } 807 | } 808 | else 809 | memset(data + compressed_size, 0xFF, data_size - compressed_size); 810 | } 811 | is_patched = TRUE; 812 | break; 813 | } 814 | free(scratch); 815 | 816 | if(!is_patched) 817 | return ERR_PATCHED_MODULE_INSERTION_FAILED; 818 | 819 | // Writing new module 820 | if (compressed_header->compression_type != COMPRESSION_NONE) 821 | { 822 | memcpy(data, compressed, compressed_size); 823 | // Writing new compressed section size 824 | int2size(compressed_size + sizeof(compressed_section_header), compressed_header->size); 825 | // Writing new module size 826 | int2size(size2int(header->size) + module_size_change, header->size); 827 | } 828 | 829 | // Correcting checksums 830 | return correct_checksums(module); 831 | } 832 | 833 | BOOLEAN patch_bios(UINT8* bios, UINT32 size) 834 | { 835 | UINT8* module; 836 | UINT8* raw_file; 837 | UINT8* bios_end; 838 | UINT8 patch_result; 839 | BOOLEAN is_found; 840 | BOOLEAN is_patched; 841 | 842 | if (!bios || !size) 843 | return ERR_INVALID_ARGUMENT; 844 | 845 | bios_end = bios + size; 846 | 847 | is_patched = FALSE; 848 | 849 | // Searching for all PowerManagement modules 850 | is_found = FALSE; 851 | for (module = find_pattern(bios, size, POWERMANAGEMENT_UUID, UUID_LENGTH); 852 | module; 853 | module = find_pattern(module+UUID_LENGTH, bios_end-module-UUID_LENGTH, POWERMANAGEMENT_UUID, UUID_LENGTH)) 854 | { 855 | is_found = TRUE; 856 | patch_result = patch_powermanagement_module(module, 0); 857 | if (!patch_result) 858 | { 859 | printf("PowerManagement module at %08X patched.\n", (UINT32)(module - bios)); 860 | is_patched = TRUE; 861 | continue; 862 | } 863 | 864 | printf("PowerManagement module at %08X not patched: ", (UINT32)(module - bios)); 865 | switch (patch_result) 866 | { 867 | case ERR_INVALID_ARGUMENT: 868 | printf("Invalid parameter.\n"); 869 | break; 870 | case ERR_UNKNOWN_MODULE: 871 | printf("Unknown module structure.\n"); 872 | break; 873 | case ERR_UNKNOWN_COMPRESSION_TYPE: 874 | printf("Unknown compression type.\n"); 875 | break; 876 | case ERR_TIANO_DECOMPRESSION_FAILED: 877 | printf("Tiano decompression failed.\n"); 878 | break; 879 | case ERR_LZMA_DECOMPRESSION_FAILED: 880 | printf("LZMA decompression failed.\n"); 881 | break; 882 | case ERR_PATCH_STRING_NOT_FOUND: 883 | printf("Patch pattern not found.\n"); 884 | break; 885 | case ERR_TIANO_COMPRESSION_FAILED: 886 | printf("Tiano compression failed.\n"); 887 | break; 888 | case ERR_LZMA_COMPRESSION_FAILED: 889 | printf("LZMA compression failed.\n"); 890 | break; 891 | case ERR_PATCHED_MODULE_INSERTION_FAILED: 892 | printf("Repacked module can't be inserted.\n"); 893 | break; 894 | case ERR_MEMORY_ALLOCATION_FAILED: 895 | printf("Memory allocation failed.\n"); 896 | break; 897 | default: 898 | printf("Unknown error.\n"); 899 | break; 900 | } 901 | } 902 | if (!is_found) 903 | printf("PowerManagement modules not found.\n"); 904 | 905 | // Searching for all PowerManagement modules 906 | is_found = FALSE; 907 | for (module = find_pattern(bios, size, POWERMGMTDXE_UUID, UUID_LENGTH); 908 | module; 909 | module = find_pattern(module+UUID_LENGTH, bios_end-module-UUID_LENGTH, POWERMGMTDXE_UUID, UUID_LENGTH)) 910 | { 911 | is_found = TRUE; 912 | patch_result = patch_powermanagement_module(module, 0); 913 | if (!patch_result) 914 | { 915 | printf("PowerMgmtDxe/PowerManagement2.efi module at %08X patched.\n", (UINT32)(module - bios)); 916 | is_patched = TRUE; 917 | continue; 918 | } 919 | 920 | printf("PowerMgmtDxe/PowerManagement2.efi module at %08X not patched: ", (UINT32)(module - bios)); 921 | switch (patch_result) 922 | { 923 | case ERR_INVALID_ARGUMENT: 924 | printf("Invalid parameter.\n"); 925 | break; 926 | case ERR_UNKNOWN_MODULE: 927 | printf("Unknown module structure.\n"); 928 | break; 929 | case ERR_UNKNOWN_COMPRESSION_TYPE: 930 | printf("Unknown compression type.\n"); 931 | break; 932 | case ERR_TIANO_DECOMPRESSION_FAILED: 933 | printf("Tiano decompression failed.\n"); 934 | break; 935 | case ERR_LZMA_DECOMPRESSION_FAILED: 936 | printf("LZMA decompression failed.\n"); 937 | break; 938 | case ERR_PATCH_STRING_NOT_FOUND: 939 | printf("Patch pattern not found.\n"); 940 | break; 941 | case ERR_TIANO_COMPRESSION_FAILED: 942 | printf("Tiano compression failed.\n"); 943 | break; 944 | case ERR_LZMA_COMPRESSION_FAILED: 945 | printf("LZMA compression failed.\n"); 946 | break; 947 | case ERR_PATCHED_MODULE_INSERTION_FAILED: 948 | printf("Repacked module can't be inserted.\n"); 949 | break; 950 | case ERR_MEMORY_ALLOCATION_FAILED: 951 | printf("Memory allocation failed.\n"); 952 | break; 953 | default: 954 | printf("Unknown error.\n"); 955 | break; 956 | } 957 | } 958 | if (!is_found) 959 | printf("PowerMgmtDxe/PowerManagement2.efi modules not found.\n"); 960 | 961 | // Searching for all AMI nest modules 962 | is_found = FALSE; 963 | for (module = find_pattern(bios, size, AMI_NEST_UUID, UUID_LENGTH); 964 | module; 965 | module = find_pattern(module+UUID_LENGTH, bios_end-module-UUID_LENGTH, AMI_NEST_UUID, UUID_LENGTH)) 966 | { 967 | is_found = TRUE; 968 | patch_result = patch_nested_module(module); 969 | 970 | if (!patch_result) 971 | { 972 | printf("AMI nest module at %08X patched.\n", (UINT32)(module - bios)); 973 | is_patched = TRUE; 974 | continue; 975 | } 976 | 977 | printf("AMI nest module at %08X not patched: ", (UINT32)(module - bios)); 978 | switch (patch_result) 979 | { 980 | case ERR_INVALID_ARGUMENT: 981 | printf("Invalid argument.\n"); 982 | break; 983 | case ERR_UNKNOWN_MODULE: 984 | printf("Unknown module structure.\n"); 985 | break; 986 | case ERR_UNKNOWN_COMPRESSION_TYPE: 987 | printf("Unknown compression type.\n"); 988 | break; 989 | case ERR_TIANO_DECOMPRESSION_FAILED: 990 | printf("Tiano decompression failed.\n"); 991 | break; 992 | case ERR_LZMA_DECOMPRESSION_FAILED: 993 | printf("LZMA decompression failed.\n"); 994 | break; 995 | case ERR_PATCH_STRING_NOT_FOUND: 996 | printf("Patch pattern not found.\n"); 997 | break; 998 | case ERR_TIANO_COMPRESSION_FAILED: 999 | printf("Tiano compression failed.\n"); 1000 | break; 1001 | case ERR_LZMA_COMPRESSION_FAILED: 1002 | printf("LZMA compression failed.\n"); 1003 | break; 1004 | case ERR_PATCHED_MODULE_INSERTION_FAILED: 1005 | printf("Repacked module can't be inserted.\n"); 1006 | break; 1007 | case ERR_MODULE_NOT_FOUND: 1008 | printf("PowerManagement modules not found in nested module.\n"); 1009 | break; 1010 | case ERR_MEMORY_ALLOCATION_FAILED: 1011 | printf("Memory allocation failed.\n"); 1012 | break; 1013 | default: 1014 | printf("Unknown error.\n"); 1015 | break; 1016 | } 1017 | } 1018 | if (!is_found) 1019 | printf("AMI nest modules not found.\n"); 1020 | 1021 | // Searching for all Phoenix nest modules 1022 | is_found = FALSE; 1023 | for (module = find_pattern(bios, size, PHOENIX_NEST_UUID, UUID_LENGTH); 1024 | module; 1025 | module = find_pattern(module+UUID_LENGTH, bios_end-module-UUID_LENGTH, PHOENIX_NEST_UUID, UUID_LENGTH)) 1026 | { 1027 | is_found = TRUE; 1028 | patch_result = patch_nested_module(module); 1029 | 1030 | if (!patch_result) 1031 | { 1032 | printf("Phoenix nest module at %08X patched.\n", (UINT32)(module - bios)); 1033 | is_patched = TRUE; 1034 | 1035 | // Fixing RAW file checksum in Dell BIOSes 1036 | raw_file = find_pattern(bios, size, PHOENIX_RAW_FILE_UUID, UUID_LENGTH); 1037 | if(raw_file) 1038 | if(!correct_checksums(raw_file)) 1039 | printf("Phoenix RAW file checksums corrected.\n"); 1040 | continue; 1041 | } 1042 | 1043 | printf("Phoenix nest module at %08X not patched: ", (UINT32)(module - bios)); 1044 | switch (patch_result) 1045 | { 1046 | case ERR_INVALID_ARGUMENT: 1047 | printf("Invalid argument.\n"); 1048 | break; 1049 | case ERR_UNKNOWN_MODULE: 1050 | printf("Unknown module structure.\n"); 1051 | break; 1052 | case ERR_UNKNOWN_COMPRESSION_TYPE: 1053 | printf("Unknown compression type.\n"); 1054 | break; 1055 | case ERR_TIANO_DECOMPRESSION_FAILED: 1056 | printf("Tiano decompression failed.\n"); 1057 | break; 1058 | case ERR_LZMA_DECOMPRESSION_FAILED: 1059 | printf("LZMA decompression failed.\n"); 1060 | break; 1061 | case ERR_PATCH_STRING_NOT_FOUND: 1062 | printf("Patch pattern not found.\n"); 1063 | break; 1064 | case ERR_TIANO_COMPRESSION_FAILED: 1065 | printf("Tiano compression failed.\n"); 1066 | break; 1067 | case ERR_LZMA_COMPRESSION_FAILED: 1068 | printf("LZMA compression failed.\n"); 1069 | break; 1070 | case ERR_PATCHED_MODULE_INSERTION_FAILED: 1071 | printf("Repacked module can't be inserted.\n"); 1072 | break; 1073 | case ERR_MODULE_NOT_FOUND: 1074 | printf("PowerManagement modules not found in nested module.\n"); 1075 | break; 1076 | case ERR_MEMORY_ALLOCATION_FAILED: 1077 | printf("Memory allocation failed.\n"); 1078 | break; 1079 | default: 1080 | printf("Unknown error.\n"); 1081 | break; 1082 | } 1083 | } 1084 | if (!is_found) 1085 | printf("Phoenix nest modules not found.\n"); 1086 | 1087 | // Searching for all CpuPei modules 1088 | is_found = FALSE; 1089 | for (module = find_pattern(bios, size, CPUPEI_UUID, UUID_LENGTH); 1090 | module; 1091 | module = find_pattern(module+UUID_LENGTH, bios_end-module-UUID_LENGTH, CPUPEI_UUID, UUID_LENGTH)) 1092 | { 1093 | is_found = TRUE; 1094 | patch_result = patch_cpupei_module(module); 1095 | 1096 | if (!patch_result) 1097 | { 1098 | printf("CpuPei module at %08X patched.\n", (UINT32)(module - bios)); 1099 | is_patched = TRUE; 1100 | continue; 1101 | } 1102 | 1103 | printf("CpuPei module at %08X not patched: ", (UINT32)(module - bios)); 1104 | switch (patch_result) 1105 | { 1106 | case ERR_INVALID_ARGUMENT: 1107 | printf("Invalid argument.\n"); 1108 | break; 1109 | case ERR_PATCH_STRING_NOT_FOUND: 1110 | printf("Patch pattern not found.\n"); 1111 | break; 1112 | default: 1113 | printf("Unknown error.\n"); 1114 | break; 1115 | } 1116 | } 1117 | if (!is_found) 1118 | printf("CpuPei modules not found.\n"); 1119 | 1120 | return is_patched; 1121 | } --------------------------------------------------------------------------------