├── 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 | }
--------------------------------------------------------------------------------