mirror of
https://github.com/LongSoft/UEFITool.git
synced 2025-05-27 13:34:33 -04:00
Big structure update
- files split into common and app-specific ones - messages from parser and finder separated - ffsEngine split into multiple classes to reduce complexity - still no image rebuild
This commit is contained in:
parent
1f0a80d035
commit
2e788a8a1a
64 changed files with 477 additions and 2469 deletions
109
common/LZMA/LzmaCompress.c
Normal file
109
common/LZMA/LzmaCompress.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* LZMA Compress Implementation
|
||||
|
||||
Copyright (c) 2012, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#include "LzmaCompress.h"
|
||||
#include "SDK/C/7zVersion.h"
|
||||
#include "SDK/C/LzmaEnc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
|
||||
|
||||
static void * AllocForLzma(void *p, size_t size) { (void)p; return malloc(size); }
|
||||
static void FreeForLzma(void *p, void *address) { (void)p; free(address); }
|
||||
static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma };
|
||||
|
||||
SRes OnProgress(void *p, UInt64 inSize, UInt64 outSize)
|
||||
{
|
||||
(void)p; (void) inSize; (void) outSize;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static ICompressProgress g_ProgressCallback = { &OnProgress };
|
||||
|
||||
STATIC
|
||||
UINT64
|
||||
EFIAPI
|
||||
RShiftU64(
|
||||
UINT64 Operand,
|
||||
UINT32 Count
|
||||
)
|
||||
{
|
||||
return Operand >> Count;
|
||||
}
|
||||
|
||||
VOID
|
||||
SetEncodedSizeOfBuf(
|
||||
UINT64 EncodedSize,
|
||||
UINT8 *EncodedData
|
||||
)
|
||||
{
|
||||
INT32 Index;
|
||||
|
||||
EncodedData[LZMA_PROPS_SIZE] = EncodedSize & 0xFF;
|
||||
for (Index = LZMA_PROPS_SIZE + 1; Index <= LZMA_PROPS_SIZE + 7; Index++)
|
||||
{
|
||||
EncodedSize = RShiftU64(EncodedSize, 8);
|
||||
EncodedData[Index] = EncodedSize & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
INT32
|
||||
EFIAPI
|
||||
LzmaCompress(
|
||||
CONST UINT8 *Source,
|
||||
UINT32 SourceSize,
|
||||
UINT8 *Destination,
|
||||
UINT32 *DestinationSize
|
||||
)
|
||||
{
|
||||
SRes LzmaResult;
|
||||
CLzmaEncProps props;
|
||||
SizeT propsSize = LZMA_PROPS_SIZE;
|
||||
SizeT destLen = SourceSize + SourceSize / 3 + 128;
|
||||
|
||||
if (*DestinationSize < destLen)
|
||||
{
|
||||
*DestinationSize = destLen;
|
||||
return ERR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
LzmaEncProps_Init(&props);
|
||||
props.dictSize = LZMA_DICTIONARY_SIZE;
|
||||
props.level = 9;
|
||||
props.fb = 273;
|
||||
|
||||
LzmaResult = LzmaEncode(
|
||||
(Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE),
|
||||
&destLen,
|
||||
Source,
|
||||
SourceSize,
|
||||
&props,
|
||||
(UINT8*)Destination,
|
||||
&propsSize,
|
||||
props.writeEndMark,
|
||||
&g_ProgressCallback,
|
||||
&SzAllocForLzma,
|
||||
&SzAllocForLzma);
|
||||
|
||||
*DestinationSize = destLen + LZMA_HEADER_SIZE;
|
||||
|
||||
SetEncodedSizeOfBuf((UINT64)SourceSize, Destination);
|
||||
|
||||
if (LzmaResult == SZ_OK) {
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
39
common/LZMA/LzmaCompress.h
Normal file
39
common/LZMA/LzmaCompress.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* LZMA Compress Header
|
||||
|
||||
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __LZMACOMPRESS_H__
|
||||
#define __LZMACOMPRESS_H__
|
||||
|
||||
#include "SDK/C/Types.h"
|
||||
#include "../basetypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LZMA_DICTIONARY_SIZE 0x800000
|
||||
#define _LZMA_SIZE_OPT
|
||||
|
||||
INT32
|
||||
EFIAPI
|
||||
LzmaCompress(
|
||||
const UINT8 *Source,
|
||||
UINT32 SourceSize,
|
||||
UINT8 *Destination,
|
||||
UINT32 *DestinationSize
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
159
common/LZMA/LzmaDecompress.c
Normal file
159
common/LZMA/LzmaDecompress.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/* LZMA Decompress Implementation
|
||||
|
||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#include "LzmaDecompress.h"
|
||||
#include "SDK/C/Types.h"
|
||||
#include "SDK/C/7zVersion.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
UINT64
|
||||
EFIAPI
|
||||
LShiftU64(
|
||||
UINT64 Operand,
|
||||
UINT32 Count
|
||||
)
|
||||
{
|
||||
return Operand << Count;
|
||||
}
|
||||
|
||||
static void * AllocForLzma(void *p, size_t size) { (void)p; return malloc(size); }
|
||||
static void FreeForLzma(void *p, void *address) { (void)p; free(address); }
|
||||
static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma };
|
||||
|
||||
/*
|
||||
Get the size of the uncompressed buffer by parsing EncodeData header.
|
||||
|
||||
@param EncodedData Pointer to the compressed data.
|
||||
|
||||
@return The size of the uncompressed buffer.
|
||||
*/
|
||||
UINT64
|
||||
GetDecodedSizeOfBuf(
|
||||
UINT8 *EncodedData
|
||||
)
|
||||
{
|
||||
UINT64 DecodedSize;
|
||||
INT32 Index;
|
||||
|
||||
// Parse header
|
||||
DecodedSize = 0;
|
||||
for (Index = LZMA_PROPS_SIZE + 7; Index >= LZMA_PROPS_SIZE; Index--)
|
||||
DecodedSize = LShiftU64(DecodedSize, 8) + EncodedData[Index];
|
||||
|
||||
return DecodedSize;
|
||||
}
|
||||
|
||||
//
|
||||
// LZMA functions and data as defined local LzmaDecompressLibInternal.h
|
||||
//
|
||||
|
||||
/*
|
||||
Given a Lzma compressed source buffer, this function retrieves the size of
|
||||
the uncompressed buffer and the size of the scratch buffer required
|
||||
to decompress the compressed source buffer.
|
||||
|
||||
Retrieves the size of the uncompressed buffer and the temporary scratch buffer
|
||||
required to decompress the buffer specified by Source and SourceSize.
|
||||
The size of the uncompressed buffer is returned DestinationSize,
|
||||
the size of the scratch buffer is returned ScratchSize, and RETURN_SUCCESS is returned.
|
||||
This function does not have scratch buffer available to perform a thorough
|
||||
checking of the validity of the source data. It just retrieves the "Original Size"
|
||||
field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize.
|
||||
And ScratchSize is specific to the decompression implementation.
|
||||
|
||||
If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT().
|
||||
|
||||
@param Source The source buffer containing the compressed data.
|
||||
@param SourceSize The size, bytes, of the source buffer.
|
||||
@param DestinationSize A pointer to the size, bytes, of the uncompressed buffer
|
||||
that will be generated when the compressed buffer specified
|
||||
by Source and SourceSize is decompressed.
|
||||
|
||||
@retval EFI_SUCCESS The size of the uncompressed data was returned
|
||||
DestinationSize and the size of the scratch
|
||||
buffer was returned ScratchSize.
|
||||
|
||||
*/
|
||||
INT32
|
||||
EFIAPI
|
||||
LzmaGetInfo(
|
||||
CONST VOID *Source,
|
||||
UINT32 SourceSize,
|
||||
UINT32 *DestinationSize
|
||||
)
|
||||
{
|
||||
UInt64 DecodedSize;
|
||||
|
||||
ASSERT(SourceSize >= LZMA_HEADER_SIZE); (void)SourceSize;
|
||||
|
||||
DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);
|
||||
|
||||
*DestinationSize = (UINT32)DecodedSize;
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Decompresses a Lzma compressed source buffer.
|
||||
|
||||
Extracts decompressed data to its original form.
|
||||
If the compressed source data specified by Source is successfully decompressed
|
||||
into Destination, then RETURN_SUCCESS is returned. If the compressed source data
|
||||
specified by Source is not a valid compressed data format,
|
||||
then RETURN_INVALID_PARAMETER is returned.
|
||||
|
||||
@param Source The source buffer containing the compressed data.
|
||||
@param SourceSize The size of source buffer.
|
||||
@param Destination The destination buffer to store the decompressed data
|
||||
|
||||
@retval EFI_SUCCESS Decompression completed successfully, and
|
||||
the uncompressed buffer is returned Destination.
|
||||
@retval EFI_INVALID_PARAMETER
|
||||
The source buffer specified by Source is corrupted
|
||||
(not a valid compressed format).
|
||||
*/
|
||||
INT32
|
||||
EFIAPI
|
||||
LzmaDecompress(
|
||||
CONST VOID *Source,
|
||||
UINT32 SourceSize,
|
||||
VOID *Destination
|
||||
)
|
||||
{
|
||||
SRes LzmaResult;
|
||||
ELzmaStatus Status;
|
||||
SizeT DecodedBufSize;
|
||||
SizeT EncodedDataSize;
|
||||
|
||||
DecodedBufSize = (SizeT)GetDecodedSizeOfBuf((UINT8*)Source);
|
||||
EncodedDataSize = (SizeT)(SourceSize - LZMA_HEADER_SIZE);
|
||||
|
||||
LzmaResult = LzmaDecode(
|
||||
(Byte*)Destination,
|
||||
&DecodedBufSize,
|
||||
(Byte*)((UINT8*)Source + LZMA_HEADER_SIZE),
|
||||
&EncodedDataSize,
|
||||
(CONST Byte*) Source,
|
||||
LZMA_PROPS_SIZE,
|
||||
LZMA_FINISH_END,
|
||||
&Status,
|
||||
&SzAllocForLzma
|
||||
);
|
||||
|
||||
if (LzmaResult == SZ_OK) {
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
98
common/LZMA/LzmaDecompress.h
Normal file
98
common/LZMA/LzmaDecompress.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* LZMA Decompress Header
|
||||
|
||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __LZMADECOMPRESS_H__
|
||||
#define __LZMADECOMPRESS_H__
|
||||
|
||||
#include "../basetypes.h"
|
||||
#include "SDK/C/LzmaDec.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
|
||||
|
||||
UINT64
|
||||
EFIAPI
|
||||
LShiftU64(
|
||||
UINT64 Operand,
|
||||
UINT32 Count
|
||||
);
|
||||
|
||||
/*
|
||||
Given a Lzma compressed source buffer, this function retrieves the size of
|
||||
the uncompressed buffer and the size of the scratch buffer required
|
||||
to decompress the compressed source buffer.
|
||||
|
||||
Retrieves the size of the uncompressed buffer and the temporary scratch buffer
|
||||
required to decompress the buffer specified by Source and SourceSize.
|
||||
The size of the uncompressed buffer is returned DestinationSize,
|
||||
the size of the scratch buffer is returned ScratchSize, and RETURN_SUCCESS is returned.
|
||||
This function does not have scratch buffer available to perform a thorough
|
||||
checking of the validity of the source data. It just retrieves the "Original Size"
|
||||
field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize.
|
||||
And ScratchSize is specific to the decompression implementation.
|
||||
|
||||
If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT().
|
||||
|
||||
@param Source The source buffer containing the compressed data.
|
||||
@param SourceSize The size, bytes, of the source buffer.
|
||||
@param DestinationSize A pointer to the size, bytes, of the uncompressed buffer
|
||||
that will be generated when the compressed buffer specified
|
||||
by Source and SourceSize is decompressed.
|
||||
|
||||
@retval EFI_SUCCESS The size of the uncompressed data was returned
|
||||
DestinationSize and the size of the scratch
|
||||
buffer was returned ScratchSize.
|
||||
|
||||
*/
|
||||
INT32
|
||||
EFIAPI
|
||||
LzmaGetInfo(
|
||||
const VOID *Source,
|
||||
UINT32 SourceSize,
|
||||
UINT32 *DestinationSize
|
||||
);
|
||||
|
||||
/*
|
||||
Decompresses a Lzma compressed source buffer.
|
||||
|
||||
Extracts decompressed data to its original form.
|
||||
If the compressed source data specified by Source is successfully decompressed
|
||||
into Destination, then RETURN_SUCCESS is returned. If the compressed source data
|
||||
specified by Source is not a valid compressed data format,
|
||||
then RETURN_INVALID_PARAMETER is returned.
|
||||
|
||||
@param Source The source buffer containing the compressed data.
|
||||
@param SourceSize The size of source buffer.
|
||||
@param Destination The destination buffer to store the decompressed data
|
||||
|
||||
@retval EFI_SUCCESS Decompression completed successfully, and
|
||||
the uncompressed buffer is returned Destination.
|
||||
@retval EFI_INVALID_PARAMETER
|
||||
The source buffer specified by Source is corrupted
|
||||
(not a valid compressed format).
|
||||
*/
|
||||
INT32
|
||||
EFIAPI
|
||||
LzmaDecompress(
|
||||
const VOID *Source,
|
||||
UINT32 SourceSize,
|
||||
VOID *Destination
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
7
common/LZMA/SDK/C/7zVersion.h
Normal file
7
common/LZMA/SDK/C/7zVersion.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#define MY_VER_MAJOR 9
|
||||
#define MY_VER_MINOR 20
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION "9.20"
|
||||
#define MY_DATE "2010-11-18"
|
||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
68
common/LZMA/SDK/C/Bra.h
Normal file
68
common/LZMA/SDK/C/Bra.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* Bra.h -- Branch converters for executables
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __BRA_H
|
||||
#define __BRA_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
These functions convert relative addresses to absolute addresses
|
||||
in CALL instructions to increase the compression ratio.
|
||||
|
||||
In:
|
||||
data - data buffer
|
||||
size - size of data
|
||||
ip - current virtual Instruction Pinter (IP) value
|
||||
state - state variable for x86 converter
|
||||
encoding - 0 (for decoding), 1 (for encoding)
|
||||
|
||||
Out:
|
||||
state - state variable for x86 converter
|
||||
|
||||
Returns:
|
||||
The number of processed bytes. If you call these functions with multiple calls,
|
||||
you must start next call with first byte after block of processed bytes.
|
||||
|
||||
Type Endian Alignment LookAhead
|
||||
|
||||
x86 little 1 4
|
||||
ARMT little 2 2
|
||||
ARM little 4 0
|
||||
PPC big 4 0
|
||||
SPARC big 4 0
|
||||
IA64 little 16 0
|
||||
|
||||
size must be >= Alignment + LookAhead, if it's not last block.
|
||||
If (size < Alignment + LookAhead), converter returns 0.
|
||||
|
||||
Example:
|
||||
|
||||
UInt32 ip = 0;
|
||||
for ()
|
||||
{
|
||||
; size must be >= Alignment + LookAhead, if it's not last block
|
||||
SizeT processed = Convert(data, size, ip, 1);
|
||||
data += processed;
|
||||
size -= processed;
|
||||
ip += processed;
|
||||
}
|
||||
*/
|
||||
|
||||
#define x86_Convert_Init(state) { state = 0; }
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
85
common/LZMA/SDK/C/Bra86.c
Normal file
85
common/LZMA/SDK/C/Bra86.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* Bra86.c -- Converter for x86 code (BCJ)
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
||||
|
||||
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||
{
|
||||
SizeT bufferPos = 0, prevPosT;
|
||||
UInt32 prevMask = *state & 0x7;
|
||||
if (size < 5)
|
||||
return 0;
|
||||
ip += 5;
|
||||
prevPosT = (SizeT)0 - 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *p = data + bufferPos;
|
||||
Byte *limit = data + size - 4;
|
||||
for (; p < limit; p++)
|
||||
if ((*p & 0xFE) == 0xE8)
|
||||
break;
|
||||
bufferPos = (SizeT)(p - data);
|
||||
if (p >= limit)
|
||||
break;
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
if (prevPosT > 3)
|
||||
prevMask = 0;
|
||||
else
|
||||
{
|
||||
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
||||
if (prevMask != 0)
|
||||
{
|
||||
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
||||
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
||||
{
|
||||
prevPosT = bufferPos;
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos;
|
||||
|
||||
if (Test86MSByte(p[4]))
|
||||
{
|
||||
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||
UInt32 dest;
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
int index;
|
||||
if (encoding)
|
||||
dest = (ip + (UInt32)bufferPos) + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)bufferPos);
|
||||
if (prevMask == 0)
|
||||
break;
|
||||
index = kMaskToBitNumber[prevMask] * 8;
|
||||
b = (Byte)(dest >> (24 - index));
|
||||
if (!Test86MSByte(b))
|
||||
break;
|
||||
src = dest ^ ((1 << (32 - index)) - 1);
|
||||
}
|
||||
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||
p[3] = (Byte)(dest >> 16);
|
||||
p[2] = (Byte)(dest >> 8);
|
||||
p[1] = (Byte)dest;
|
||||
bufferPos += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
||||
return bufferPos;
|
||||
}
|
155
common/LZMA/SDK/C/CpuArch.h
Normal file
155
common/LZMA/SDK/C/CpuArch.h
Normal file
|
@ -0,0 +1,155 @@
|
|||
/* CpuArch.h -- CPU specific code
|
||||
2010-10-26: Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __CPU_ARCH_H
|
||||
#define __CPU_ARCH_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/*
|
||||
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||||
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
|
||||
|
||||
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||||
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
|
||||
*/
|
||||
|
||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
||||
#define MY_CPU_AMD64
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
|
||||
#define MY_CPU_64BIT
|
||||
#endif
|
||||
|
||||
#if defined(_M_IX86) || defined(__i386__)
|
||||
#define MY_CPU_X86
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||||
#define MY_CPU_X86_OR_AMD64
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) || defined(_M_ARM)
|
||||
#define MY_CPU_32BIT
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_ARM)
|
||||
#define MY_CPU_ARM_LE
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_IA64)
|
||||
#define MY_CPU_IA64_LE
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86_OR_AMD64)
|
||||
#define MY_CPU_LE_UNALIGN
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
|
||||
#define MY_CPU_LE
|
||||
#endif
|
||||
|
||||
#if defined(__BIG_ENDIAN__)
|
||||
#define MY_CPU_BE
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||||
Stop_Compiling_Bad_Endian
|
||||
#endif
|
||||
|
||||
#ifdef MY_CPU_LE_UNALIGN
|
||||
|
||||
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
|
||||
|
||||
#else
|
||||
|
||||
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||
|
||||
#define GetUi32(p) ( \
|
||||
((const Byte *)(p))[0] | \
|
||||
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[3] << 24))
|
||||
|
||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||
|
||||
#define SetUi16(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
|
||||
|
||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||
|
||||
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
||||
SetUi32(p, (UInt32)_x64_); \
|
||||
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||
|
||||
#else
|
||||
|
||||
#define GetBe32(p) ( \
|
||||
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||
((const Byte *)(p))[3] )
|
||||
|
||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||
|
||||
#endif
|
||||
|
||||
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 maxFunc;
|
||||
UInt32 vendor[3];
|
||||
UInt32 ver;
|
||||
UInt32 b;
|
||||
UInt32 c;
|
||||
UInt32 d;
|
||||
} Cx86cpuid;
|
||||
|
||||
enum
|
||||
{
|
||||
CPU_FIRM_INTEL,
|
||||
CPU_FIRM_AMD,
|
||||
CPU_FIRM_VIA
|
||||
};
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||
|
||||
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
|
||||
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
|
||||
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
|
||||
|
||||
Bool CPU_Is_InOrder();
|
||||
Bool CPU_Is_Aes_Supported();
|
||||
|
||||
#endif
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
754
common/LZMA/SDK/C/LzFind.c
Normal file
754
common/LZMA/SDK/C/LzFind.c
Normal file
|
@ -0,0 +1,754 @@
|
|||
/* LzFind.c -- Match finder for LZ algorithms
|
||||
2009-04-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "LzFind.h"
|
||||
#include "LzHash.h"
|
||||
|
||||
#define kEmptyHashValue 0
|
||||
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
||||
#define kMaxHistorySize ((UInt32)3 << 30)
|
||||
|
||||
#define kStartMaxLen 3
|
||||
|
||||
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
if (!p->directInput)
|
||||
{
|
||||
alloc->Free(alloc, p->bufferBase);
|
||||
p->bufferBase = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
||||
|
||||
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
||||
if (p->directInput)
|
||||
{
|
||||
p->blockSize = blockSize;
|
||||
return 1;
|
||||
}
|
||||
if (p->bufferBase == 0 || p->blockSize != blockSize)
|
||||
{
|
||||
LzInWindow_Free(p, alloc);
|
||||
p->blockSize = blockSize;
|
||||
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
||||
}
|
||||
return (p->bufferBase != 0);
|
||||
}
|
||||
|
||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
||||
Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
|
||||
|
||||
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
||||
|
||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
|
||||
{
|
||||
p->posLimit -= subValue;
|
||||
p->pos -= subValue;
|
||||
p->streamPos -= subValue;
|
||||
}
|
||||
|
||||
static void MatchFinder_ReadBlock(CMatchFinder *p)
|
||||
{
|
||||
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||
return;
|
||||
if (p->directInput)
|
||||
{
|
||||
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
|
||||
if (curSize > p->directInputRem)
|
||||
curSize = (UInt32)p->directInputRem;
|
||||
p->directInputRem -= curSize;
|
||||
p->streamPos += curSize;
|
||||
if (p->directInputRem == 0)
|
||||
p->streamEndWasReached = 1;
|
||||
return;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
||||
size_t size = (p->bufferBase + p->blockSize - dest);
|
||||
if (size == 0)
|
||||
return;
|
||||
p->result = p->stream->Read(p->stream, dest, &size);
|
||||
if (p->result != SZ_OK)
|
||||
return;
|
||||
if (size == 0)
|
||||
{
|
||||
p->streamEndWasReached = 1;
|
||||
return;
|
||||
}
|
||||
p->streamPos += (UInt32)size;
|
||||
if (p->streamPos - p->pos > p->keepSizeAfter)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MatchFinder_MoveBlock(CMatchFinder *p)
|
||||
{
|
||||
memmove(p->bufferBase,
|
||||
p->buffer - p->keepSizeBefore,
|
||||
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
||||
p->buffer = p->bufferBase + p->keepSizeBefore;
|
||||
}
|
||||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p)
|
||||
{
|
||||
if (p->directInput)
|
||||
return 0;
|
||||
/* if (p->streamEndWasReached) return 0; */
|
||||
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
|
||||
}
|
||||
|
||||
void MatchFinder_ReadIfRequired(CMatchFinder *p)
|
||||
{
|
||||
if (p->streamEndWasReached)
|
||||
return;
|
||||
if (p->keepSizeAfter >= p->streamPos - p->pos)
|
||||
MatchFinder_ReadBlock(p);
|
||||
}
|
||||
|
||||
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
|
||||
{
|
||||
if (MatchFinder_NeedMove(p))
|
||||
MatchFinder_MoveBlock(p);
|
||||
MatchFinder_ReadBlock(p);
|
||||
}
|
||||
|
||||
static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
||||
{
|
||||
p->cutValue = 32;
|
||||
p->btMode = 1;
|
||||
p->numHashBytes = 4;
|
||||
p->bigHash = 0;
|
||||
}
|
||||
|
||||
#define kCrcPoly 0xEDB88320
|
||||
|
||||
void MatchFinder_Construct(CMatchFinder *p)
|
||||
{
|
||||
UInt32 i;
|
||||
p->bufferBase = 0;
|
||||
p->directInput = 0;
|
||||
p->hash = 0;
|
||||
MatchFinder_SetDefaultSettings(p);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = i;
|
||||
int j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
p->crc[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->hash);
|
||||
p->hash = 0;
|
||||
}
|
||||
|
||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||
LzInWindow_Free(p, alloc);
|
||||
}
|
||||
|
||||
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
|
||||
{
|
||||
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
||||
if (sizeInBytes / sizeof(CLzRef) != num)
|
||||
return 0;
|
||||
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
||||
}
|
||||
|
||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||
ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 sizeReserv;
|
||||
if (historySize > kMaxHistorySize)
|
||||
{
|
||||
MatchFinder_Free(p, alloc);
|
||||
return 0;
|
||||
}
|
||||
sizeReserv = historySize >> 1;
|
||||
if (historySize > ((UInt32)2 << 30))
|
||||
sizeReserv = historySize >> 2;
|
||||
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
||||
|
||||
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
||||
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
||||
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||
{
|
||||
UInt32 newCyclicBufferSize = historySize + 1;
|
||||
UInt32 hs;
|
||||
p->matchMaxLen = matchMaxLen;
|
||||
{
|
||||
p->fixedHashSize = 0;
|
||||
if (p->numHashBytes == 2)
|
||||
hs = (1 << 16) - 1;
|
||||
else
|
||||
{
|
||||
hs = historySize - 1;
|
||||
hs |= (hs >> 1);
|
||||
hs |= (hs >> 2);
|
||||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
||||
if (hs > (1 << 24))
|
||||
{
|
||||
if (p->numHashBytes == 3)
|
||||
hs = (1 << 24) - 1;
|
||||
else
|
||||
hs >>= 1;
|
||||
}
|
||||
}
|
||||
p->hashMask = hs;
|
||||
hs++;
|
||||
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
|
||||
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
|
||||
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
|
||||
hs += p->fixedHashSize;
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 prevSize = p->hashSizeSum + p->numSons;
|
||||
UInt32 newSize;
|
||||
p->historySize = historySize;
|
||||
p->hashSizeSum = hs;
|
||||
p->cyclicBufferSize = newCyclicBufferSize;
|
||||
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
|
||||
newSize = p->hashSizeSum + p->numSons;
|
||||
if (p->hash != 0 && prevSize == newSize)
|
||||
return 1;
|
||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||
p->hash = AllocRefs(newSize, alloc);
|
||||
if (p->hash != 0)
|
||||
{
|
||||
p->son = p->hash + p->hashSizeSum;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
MatchFinder_Free(p, alloc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||
{
|
||||
UInt32 limit = kMaxValForNormalize - p->pos;
|
||||
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
||||
if (limit2 < limit)
|
||||
limit = limit2;
|
||||
limit2 = p->streamPos - p->pos;
|
||||
if (limit2 <= p->keepSizeAfter)
|
||||
{
|
||||
if (limit2 > 0)
|
||||
limit2 = 1;
|
||||
}
|
||||
else
|
||||
limit2 -= p->keepSizeAfter;
|
||||
if (limit2 < limit)
|
||||
limit = limit2;
|
||||
{
|
||||
UInt32 lenLimit = p->streamPos - p->pos;
|
||||
if (lenLimit > p->matchMaxLen)
|
||||
lenLimit = p->matchMaxLen;
|
||||
p->lenLimit = lenLimit;
|
||||
}
|
||||
p->posLimit = p->pos + limit;
|
||||
}
|
||||
|
||||
void MatchFinder_Init(CMatchFinder *p)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->hashSizeSum; i++)
|
||||
p->hash[i] = kEmptyHashValue;
|
||||
p->cyclicBufferPos = 0;
|
||||
p->buffer = p->bufferBase;
|
||||
p->pos = p->streamPos = p->cyclicBufferSize;
|
||||
p->result = SZ_OK;
|
||||
p->streamEndWasReached = 0;
|
||||
MatchFinder_ReadBlock(p);
|
||||
MatchFinder_SetLimits(p);
|
||||
}
|
||||
|
||||
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||
{
|
||||
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
||||
}
|
||||
|
||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 value = items[i];
|
||||
if (value <= subValue)
|
||||
value = kEmptyHashValue;
|
||||
else
|
||||
value -= subValue;
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
static void MatchFinder_Normalize(CMatchFinder *p)
|
||||
{
|
||||
UInt32 subValue = MatchFinder_GetSubValue(p);
|
||||
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
|
||||
MatchFinder_ReduceOffsets(p, subValue);
|
||||
}
|
||||
|
||||
static void MatchFinder_CheckLimits(CMatchFinder *p)
|
||||
{
|
||||
if (p->pos == kMaxValForNormalize)
|
||||
MatchFinder_Normalize(p);
|
||||
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
|
||||
MatchFinder_CheckAndMoveAndRead(p);
|
||||
if (p->cyclicBufferPos == p->cyclicBufferSize)
|
||||
p->cyclicBufferPos = 0;
|
||||
MatchFinder_SetLimits(p);
|
||||
}
|
||||
|
||||
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
{
|
||||
son[_cyclicBufferPos] = curMatch;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
return distances;
|
||||
{
|
||||
const Byte *pb = cur - delta;
|
||||
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
|
||||
if (pb[maxLen] == cur[maxLen] && *pb == *cur)
|
||||
{
|
||||
UInt32 len = 0;
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
return distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
{
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
return distances;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
if (++len != lenLimit && pb[len] == cur[len])
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
return distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
||||
{
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
return;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
{
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MOVE_POS \
|
||||
++p->cyclicBufferPos; \
|
||||
p->buffer++; \
|
||||
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
|
||||
|
||||
#define MOVE_POS_RET MOVE_POS return offset;
|
||||
|
||||
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||
|
||||
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
||||
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
|
||||
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||
cur = p->buffer;
|
||||
|
||||
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
|
||||
#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
|
||||
|
||||
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
|
||||
|
||||
#define GET_MATCHES_FOOTER(offset, maxLen) \
|
||||
offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
|
||||
distances + offset, maxLen) - distances); MOVE_POS_RET;
|
||||
|
||||
#define SKIP_FOOTER \
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
||||
|
||||
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(2)
|
||||
HASH2_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = 0;
|
||||
GET_MATCHES_FOOTER(offset, 1)
|
||||
}
|
||||
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = 0;
|
||||
GET_MATCHES_FOOTER(offset, 2)
|
||||
}
|
||||
|
||||
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, delta2, maxLen, offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
|
||||
HASH3_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[hash2Value];
|
||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||
|
||||
maxLen = 2;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[0] = maxLen;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
GET_MATCHES_FOOTER(offset, maxLen)
|
||||
}
|
||||
|
||||
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||
GET_MATCHES_HEADER(4)
|
||||
|
||||
HASH4_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[hash2Value];
|
||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
|
||||
maxLen = 1;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
distances[0] = maxLen = 2;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
}
|
||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||
{
|
||||
maxLen = 3;
|
||||
distances[offset + 1] = delta3 - 1;
|
||||
offset += 2;
|
||||
delta2 = delta3;
|
||||
}
|
||||
if (offset != 0)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[offset - 2] = maxLen;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
if (maxLen < 3)
|
||||
maxLen = 3;
|
||||
GET_MATCHES_FOOTER(offset, maxLen)
|
||||
}
|
||||
|
||||
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||
GET_MATCHES_HEADER(4)
|
||||
|
||||
HASH4_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[hash2Value];
|
||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
|
||||
maxLen = 1;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
distances[0] = maxLen = 2;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
}
|
||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||
{
|
||||
maxLen = 3;
|
||||
distances[offset + 1] = delta3 - 1;
|
||||
offset += 2;
|
||||
delta2 = delta3;
|
||||
}
|
||||
if (offset != 0)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[offset - 2] = maxLen;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
if (maxLen < 3)
|
||||
maxLen = 3;
|
||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
distances + offset, maxLen) - (distances));
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
distances, 2) - (distances));
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
||||
static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(2)
|
||||
HASH2_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
} while (--num != 0);
|
||||
}
|
||||
|
||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
} while (--num != 0);
|
||||
}
|
||||
|
||||
static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value;
|
||||
SKIP_HEADER(3)
|
||||
HASH3_CALC;
|
||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
} while (--num != 0);
|
||||
}
|
||||
|
||||
static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value, hash3Value;
|
||||
SKIP_HEADER(4)
|
||||
HASH4_CALC;
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] = p->pos;
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
} while (--num != 0);
|
||||
}
|
||||
|
||||
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value, hash3Value;
|
||||
SKIP_HEADER(4)
|
||||
HASH4_CALC;
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS
|
||||
} while (--num != 0);
|
||||
}
|
||||
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS
|
||||
} while (--num != 0);
|
||||
}
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
||||
{
|
||||
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
|
||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
||||
if (!p->btMode)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
|
||||
}
|
||||
else if (p->numHashBytes == 2)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
|
||||
}
|
||||
else if (p->numHashBytes == 3)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
||||
}
|
||||
else
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
|
||||
}
|
||||
}
|
115
common/LZMA/SDK/C/LzFind.h
Normal file
115
common/LZMA/SDK/C/LzFind.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* LzFind.h -- Match finder for LZ algorithms
|
||||
2009-04-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZ_FIND_H
|
||||
#define __LZ_FIND_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef UInt32 CLzRef;
|
||||
|
||||
typedef struct _CMatchFinder
|
||||
{
|
||||
Byte *buffer;
|
||||
UInt32 pos;
|
||||
UInt32 posLimit;
|
||||
UInt32 streamPos;
|
||||
UInt32 lenLimit;
|
||||
|
||||
UInt32 cyclicBufferPos;
|
||||
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
||||
|
||||
UInt32 matchMaxLen;
|
||||
CLzRef *hash;
|
||||
CLzRef *son;
|
||||
UInt32 hashMask;
|
||||
UInt32 cutValue;
|
||||
|
||||
Byte *bufferBase;
|
||||
ISeqInStream *stream;
|
||||
int streamEndWasReached;
|
||||
|
||||
UInt32 blockSize;
|
||||
UInt32 keepSizeBefore;
|
||||
UInt32 keepSizeAfter;
|
||||
|
||||
UInt32 numHashBytes;
|
||||
int directInput;
|
||||
size_t directInputRem;
|
||||
int btMode;
|
||||
int bigHash;
|
||||
UInt32 historySize;
|
||||
UInt32 fixedHashSize;
|
||||
UInt32 hashSizeSum;
|
||||
UInt32 numSons;
|
||||
SRes result;
|
||||
UInt32 crc[256];
|
||||
} CMatchFinder;
|
||||
|
||||
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
||||
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
|
||||
|
||||
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||
void MatchFinder_ReadIfRequired(CMatchFinder *p);
|
||||
|
||||
void MatchFinder_Construct(CMatchFinder *p);
|
||||
|
||||
/* Conditions:
|
||||
historySize <= 3 GB
|
||||
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
||||
*/
|
||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||
ISzAlloc *alloc);
|
||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
|
||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||
|
||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
UInt32 *distances, UInt32 maxLen);
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
|
||||
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
|
||||
*/
|
||||
|
||||
typedef void (*Mf_Init_Func)(void *object);
|
||||
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
|
||||
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
||||
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||
typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
||||
|
||||
typedef struct _IMatchFinder
|
||||
{
|
||||
Mf_Init_Func Init;
|
||||
Mf_GetIndexByte_Func GetIndexByte;
|
||||
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
||||
Mf_GetMatches_Func GetMatches;
|
||||
Mf_Skip_Func Skip;
|
||||
} IMatchFinder;
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||
|
||||
void MatchFinder_Init(CMatchFinder *p);
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
54
common/LZMA/SDK/C/LzHash.h
Normal file
54
common/LZMA/SDK/C/LzHash.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* LzHash.h -- HASH functions for LZ algorithms
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZ_HASH_H
|
||||
#define __LZ_HASH_H
|
||||
|
||||
#define kHash2Size (1 << 10)
|
||||
#define kHash3Size (1 << 16)
|
||||
#define kHash4Size (1 << 20)
|
||||
|
||||
#define kFix3HashSize (kHash2Size)
|
||||
#define kFix4HashSize (kHash2Size + kHash3Size)
|
||||
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
|
||||
|
||||
#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
|
||||
|
||||
#define HASH3_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
||||
|
||||
#define HASH4_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
||||
|
||||
#define HASH5_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
|
||||
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
|
||||
hash4Value &= (kHash4Size - 1); }
|
||||
|
||||
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
|
||||
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
|
||||
|
||||
|
||||
#define MT_HASH2_CALC \
|
||||
hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
|
||||
|
||||
#define MT_HASH3_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
||||
|
||||
#define MT_HASH4_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
||||
|
||||
#endif
|
987
common/LZMA/SDK/C/LzmaDec.c
Normal file
987
common/LZMA/SDK/C/LzmaDec.c
Normal file
|
@ -0,0 +1,987 @@
|
|||
/* LzmaDec.c -- LZMA Decoder
|
||||
2009-09-20 : Igor Pavlov : Public domain*/
|
||||
|
||||
#include "LzmaDec.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define kNumTopBits 24
|
||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||
|
||||
#define kNumBitModelTotalBits 11
|
||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||
#define kNumMoveBits 5
|
||||
|
||||
#define RC_INIT_SIZE 5
|
||||
|
||||
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
|
||||
|
||||
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
|
||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
|
||||
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
||||
{ UPDATE_0(p); i = (i + i); A0; } else \
|
||||
{ UPDATE_1(p); i = (i + i) + 1; A1; }
|
||||
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
|
||||
|
||||
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
|
||||
#define TREE_DECODE(probs, limit, i) \
|
||||
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
|
||||
|
||||
/* #define _LZMA_SIZE_OPT */
|
||||
|
||||
#ifdef _LZMA_SIZE_OPT
|
||||
#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
|
||||
#else
|
||||
#define TREE_6_DECODE(probs, i) \
|
||||
{ i = 1; \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
i -= 0x40; }
|
||||
#endif
|
||||
|
||||
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
|
||||
|
||||
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||
#define UPDATE_0_CHECK range = bound;
|
||||
#define UPDATE_1_CHECK range -= bound; code -= bound;
|
||||
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
|
||||
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
|
||||
{ UPDATE_1_CHECK; i = (i + i) + 1; A1; }
|
||||
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
|
||||
#define TREE_DECODE_CHECK(probs, limit, i) \
|
||||
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
|
||||
|
||||
#define kNumPosBitsMax 4
|
||||
#define kNumPosStatesMax (1 << kNumPosBitsMax)
|
||||
|
||||
#define kLenNumLowBits 3
|
||||
#define kLenNumLowSymbols (1 << kLenNumLowBits)
|
||||
#define kLenNumMidBits 3
|
||||
#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
||||
#define kLenNumHighBits 8
|
||||
#define kLenNumHighSymbols (1 << kLenNumHighBits)
|
||||
|
||||
#define LenChoice 0
|
||||
#define LenChoice2 (LenChoice + 1)
|
||||
#define LenLow (LenChoice2 + 1)
|
||||
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
||||
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
||||
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
||||
|
||||
#define kNumStates 12
|
||||
#define kNumLitStates 7
|
||||
|
||||
#define kStartPosModelIndex 4
|
||||
#define kEndPosModelIndex 14
|
||||
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
||||
|
||||
#define kNumPosSlotBits 6
|
||||
#define kNumLenToPosStates 4
|
||||
|
||||
#define kNumAlignBits 4
|
||||
#define kAlignTableSize (1 << kNumAlignBits)
|
||||
|
||||
#define kMatchMinLen 2
|
||||
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
|
||||
|
||||
#define IsMatch 0
|
||||
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
||||
#define IsRepG0 (IsRep + kNumStates)
|
||||
#define IsRepG1 (IsRepG0 + kNumStates)
|
||||
#define IsRepG2 (IsRepG1 + kNumStates)
|
||||
#define IsRep0Long (IsRepG2 + kNumStates)
|
||||
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
||||
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
||||
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
||||
#define LenCoder (Align + kAlignTableSize)
|
||||
#define RepLenCoder (LenCoder + kNumLenProbs)
|
||||
#define Literal (RepLenCoder + kNumLenProbs)
|
||||
|
||||
#define LZMA_BASE_SIZE 1846
|
||||
#define LZMA_LIT_SIZE 768
|
||||
|
||||
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
|
||||
|
||||
#if Literal != LZMA_BASE_SIZE
|
||||
StopCompilingDueBUG
|
||||
#endif
|
||||
|
||||
#define LZMA_DIC_MIN (1 << 12)
|
||||
|
||||
/* First LZMA-symbol is always decoded.
|
||||
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is with last normalization
|
||||
Out:
|
||||
Result:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_DATA - Error
|
||||
p->remainLen:
|
||||
< kMatchSpecLenStart : normal remain
|
||||
= kMatchSpecLenStart : finished
|
||||
= kMatchSpecLenStart + 1 : Flush marker
|
||||
= kMatchSpecLenStart + 2 : State Init Marker
|
||||
*/
|
||||
|
||||
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||
{
|
||||
CLzmaProb *probs = p->probs;
|
||||
|
||||
unsigned state = p->state;
|
||||
UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
|
||||
unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
|
||||
unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
|
||||
unsigned lc = p->prop.lc;
|
||||
|
||||
Byte *dic = p->dic;
|
||||
SizeT dicBufSize = p->dicBufSize;
|
||||
SizeT dicPos = p->dicPos;
|
||||
|
||||
UInt32 processedPos = p->processedPos;
|
||||
UInt32 checkDicSize = p->checkDicSize;
|
||||
unsigned len = 0;
|
||||
|
||||
const Byte *buf = p->buf;
|
||||
UInt32 range = p->range;
|
||||
UInt32 code = p->code;
|
||||
|
||||
do
|
||||
{
|
||||
CLzmaProb *prob;
|
||||
UInt32 bound;
|
||||
unsigned ttt;
|
||||
unsigned posState = processedPos & pbMask;
|
||||
|
||||
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
unsigned symbol;
|
||||
UPDATE_0(prob);
|
||||
prob = probs + Literal;
|
||||
if (checkDicSize != 0 || processedPos != 0)
|
||||
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
||||
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
||||
|
||||
if (state < kNumLitStates)
|
||||
{
|
||||
state -= (state < 4) ? state : 3;
|
||||
symbol = 1;
|
||||
do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||
unsigned offs = 0x100;
|
||||
state -= (state < 10) ? 3 : 6;
|
||||
symbol = 1;
|
||||
do
|
||||
{
|
||||
unsigned bit;
|
||||
CLzmaProb *probLit;
|
||||
matchByte <<= 1;
|
||||
bit = (matchByte & offs);
|
||||
probLit = prob + offs + bit + symbol;
|
||||
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
|
||||
} while (symbol < 0x100);
|
||||
}
|
||||
dic[dicPos++] = (Byte)symbol;
|
||||
processedPos++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
prob = probs + IsRep + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
state += kNumStates;
|
||||
prob = probs + LenCoder;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
if (checkDicSize == 0 && processedPos == 0)
|
||||
return SZ_ERROR_DATA;
|
||||
prob = probs + IsRepG0 + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||
dicPos++;
|
||||
processedPos++;
|
||||
state = state < kNumLitStates ? 9 : 11;
|
||||
continue;
|
||||
}
|
||||
UPDATE_1(prob);
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 distance;
|
||||
UPDATE_1(prob);
|
||||
prob = probs + IsRepG1 + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
distance = rep1;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
prob = probs + IsRepG2 + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
distance = rep2;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
state = state < kNumLitStates ? 8 : 11;
|
||||
prob = probs + RepLenCoder;
|
||||
}
|
||||
{
|
||||
unsigned limit, offset;
|
||||
CLzmaProb *probLen = prob + LenChoice;
|
||||
IF_BIT_0(probLen)
|
||||
{
|
||||
UPDATE_0(probLen);
|
||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||
offset = 0;
|
||||
limit = (1 << kLenNumLowBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(probLen);
|
||||
probLen = prob + LenChoice2;
|
||||
IF_BIT_0(probLen)
|
||||
{
|
||||
UPDATE_0(probLen);
|
||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||
offset = kLenNumLowSymbols;
|
||||
limit = (1 << kLenNumMidBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(probLen);
|
||||
probLen = prob + LenHigh;
|
||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||
limit = (1 << kLenNumHighBits);
|
||||
}
|
||||
}
|
||||
TREE_DECODE(probLen, limit, len);
|
||||
len += offset;
|
||||
}
|
||||
|
||||
if (state >= kNumStates)
|
||||
{
|
||||
UInt32 distance;
|
||||
prob = probs + PosSlot +
|
||||
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
|
||||
TREE_6_DECODE(prob, distance);
|
||||
if (distance >= kStartPosModelIndex)
|
||||
{
|
||||
unsigned posSlot = (unsigned)distance;
|
||||
int numDirectBits = (int)(((distance >> 1) - 1));
|
||||
distance = (2 | (distance & 1));
|
||||
if (posSlot < kEndPosModelIndex)
|
||||
{
|
||||
distance <<= numDirectBits;
|
||||
prob = probs + SpecPos + distance - posSlot - 1;
|
||||
{
|
||||
UInt32 mask = 1;
|
||||
unsigned i = 1;
|
||||
do
|
||||
{
|
||||
GET_BIT2(prob + i, i, ;, distance |= mask);
|
||||
mask <<= 1;
|
||||
} while (--numDirectBits != 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numDirectBits -= kNumAlignBits;
|
||||
do
|
||||
{
|
||||
NORMALIZE
|
||||
range >>= 1;
|
||||
|
||||
{
|
||||
UInt32 t;
|
||||
code -= range;
|
||||
t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
|
||||
distance = (distance << 1) + (t + 1);
|
||||
code += range & t;
|
||||
}
|
||||
/*
|
||||
distance <<= 1;
|
||||
if (code >= range)
|
||||
{
|
||||
code -= range;
|
||||
distance |= 1;
|
||||
}
|
||||
*/
|
||||
} while (--numDirectBits != 0);
|
||||
prob = probs + Align;
|
||||
distance <<= kNumAlignBits;
|
||||
{
|
||||
unsigned i = 1;
|
||||
GET_BIT2(prob + i, i, ;, distance |= 1);
|
||||
GET_BIT2(prob + i, i, ;, distance |= 2);
|
||||
GET_BIT2(prob + i, i, ;, distance |= 4);
|
||||
GET_BIT2(prob + i, i, ;, distance |= 8);
|
||||
}
|
||||
if (distance == (UInt32)0xFFFFFFFF)
|
||||
{
|
||||
len += kMatchSpecLenStart;
|
||||
state -= kNumStates;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
rep0 = distance + 1;
|
||||
if (checkDicSize == 0)
|
||||
{
|
||||
if (distance >= processedPos)
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
else if (distance >= checkDicSize)
|
||||
return SZ_ERROR_DATA;
|
||||
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
||||
}
|
||||
|
||||
len += kMatchMinLen;
|
||||
|
||||
if (limit == dicPos)
|
||||
return SZ_ERROR_DATA;
|
||||
{
|
||||
SizeT rem = limit - dicPos;
|
||||
unsigned curLen = ((rem < len) ? (unsigned)rem : len);
|
||||
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
|
||||
|
||||
processedPos += curLen;
|
||||
|
||||
len -= curLen;
|
||||
if (pos + curLen <= dicBufSize)
|
||||
{
|
||||
Byte *dest = dic + dicPos;
|
||||
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
|
||||
const Byte *lim = dest + curLen;
|
||||
dicPos += curLen;
|
||||
do
|
||||
*(dest) = (Byte)*(dest + src);
|
||||
while (++dest != lim);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
dic[dicPos++] = dic[pos];
|
||||
if (++pos == dicBufSize)
|
||||
pos = 0;
|
||||
} while (--curLen != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (dicPos < limit && buf < bufLimit);
|
||||
NORMALIZE;
|
||||
p->buf = buf;
|
||||
p->range = range;
|
||||
p->code = code;
|
||||
p->remainLen = len;
|
||||
p->dicPos = dicPos;
|
||||
p->processedPos = processedPos;
|
||||
p->reps[0] = rep0;
|
||||
p->reps[1] = rep1;
|
||||
p->reps[2] = rep2;
|
||||
p->reps[3] = rep3;
|
||||
p->state = state;
|
||||
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
||||
{
|
||||
if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
|
||||
{
|
||||
Byte *dic = p->dic;
|
||||
SizeT dicPos = p->dicPos;
|
||||
SizeT dicBufSize = p->dicBufSize;
|
||||
unsigned len = p->remainLen;
|
||||
UInt32 rep0 = p->reps[0];
|
||||
if (limit - dicPos < len)
|
||||
len = (unsigned)(limit - dicPos);
|
||||
|
||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
|
||||
p->processedPos += len;
|
||||
p->remainLen -= len;
|
||||
while (len-- != 0)
|
||||
{
|
||||
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||
dicPos++;
|
||||
}
|
||||
p->dicPos = dicPos;
|
||||
}
|
||||
}
|
||||
|
||||
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||
{
|
||||
do
|
||||
{
|
||||
SizeT limit2 = limit;
|
||||
if (p->checkDicSize == 0)
|
||||
{
|
||||
UInt32 rem = p->prop.dicSize - p->processedPos;
|
||||
if (limit - p->dicPos > rem)
|
||||
limit2 = p->dicPos + rem;
|
||||
}
|
||||
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
|
||||
if (p->processedPos >= p->prop.dicSize)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
LzmaDec_WriteRem(p, limit);
|
||||
} while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
|
||||
|
||||
if (p->remainLen > kMatchSpecLenStart)
|
||||
{
|
||||
p->remainLen = kMatchSpecLenStart;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DUMMY_ERROR, /* unexpected end of input stream */
|
||||
DUMMY_LIT,
|
||||
DUMMY_MATCH,
|
||||
DUMMY_REP
|
||||
} ELzmaDummy;
|
||||
|
||||
static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
|
||||
{
|
||||
UInt32 range = p->range;
|
||||
UInt32 code = p->code;
|
||||
const Byte *bufLimit = buf + inSize;
|
||||
CLzmaProb *probs = p->probs;
|
||||
unsigned state = p->state;
|
||||
ELzmaDummy res;
|
||||
|
||||
{
|
||||
CLzmaProb *prob;
|
||||
UInt32 bound;
|
||||
unsigned ttt;
|
||||
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
|
||||
|
||||
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK
|
||||
|
||||
/* if (bufLimit - buf >= 7) return DUMMY_LIT; */
|
||||
|
||||
prob = probs + Literal;
|
||||
if (p->checkDicSize != 0 || p->processedPos != 0)
|
||||
prob += (LZMA_LIT_SIZE *
|
||||
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
||||
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
||||
|
||||
if (state < kNumLitStates)
|
||||
{
|
||||
unsigned symbol = 1;
|
||||
do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
|
||||
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
|
||||
unsigned offs = 0x100;
|
||||
unsigned symbol = 1;
|
||||
do
|
||||
{
|
||||
unsigned bit;
|
||||
CLzmaProb *probLit;
|
||||
matchByte <<= 1;
|
||||
bit = (matchByte & offs);
|
||||
probLit = prob + offs + bit + symbol;
|
||||
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
|
||||
} while (symbol < 0x100);
|
||||
}
|
||||
res = DUMMY_LIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned len;
|
||||
UPDATE_1_CHECK;
|
||||
|
||||
prob = probs + IsRep + state;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
state = 0;
|
||||
prob = probs + LenCoder;
|
||||
res = DUMMY_MATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
res = DUMMY_REP;
|
||||
prob = probs + IsRepG0 + state;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
NORMALIZE_CHECK;
|
||||
return DUMMY_REP;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
prob = probs + IsRepG1 + state;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
prob = probs + IsRepG2 + state;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
}
|
||||
}
|
||||
}
|
||||
state = kNumStates;
|
||||
prob = probs + RepLenCoder;
|
||||
}
|
||||
{
|
||||
unsigned limit, offset;
|
||||
CLzmaProb *probLen = prob + LenChoice;
|
||||
IF_BIT_0_CHECK(probLen)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||
offset = 0;
|
||||
limit = 1 << kLenNumLowBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
probLen = prob + LenChoice2;
|
||||
IF_BIT_0_CHECK(probLen)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||
offset = kLenNumLowSymbols;
|
||||
limit = 1 << kLenNumMidBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
probLen = prob + LenHigh;
|
||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||
limit = 1 << kLenNumHighBits;
|
||||
}
|
||||
}
|
||||
TREE_DECODE_CHECK(probLen, limit, len);
|
||||
len += offset;
|
||||
}
|
||||
|
||||
if (state < 4)
|
||||
{
|
||||
unsigned posSlot;
|
||||
prob = probs + PosSlot +
|
||||
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
||||
kNumPosSlotBits);
|
||||
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
||||
if (posSlot >= kStartPosModelIndex)
|
||||
{
|
||||
int numDirectBits = ((posSlot >> 1) - 1);
|
||||
|
||||
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
|
||||
|
||||
if (posSlot < kEndPosModelIndex)
|
||||
{
|
||||
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
numDirectBits -= kNumAlignBits;
|
||||
do
|
||||
{
|
||||
NORMALIZE_CHECK
|
||||
range >>= 1;
|
||||
code -= range & (((code - range) >> 31) - 1);
|
||||
/* if (code >= range) code -= range; */
|
||||
} while (--numDirectBits != 0);
|
||||
prob = probs + Align;
|
||||
numDirectBits = kNumAlignBits;
|
||||
}
|
||||
{
|
||||
unsigned i = 1;
|
||||
do
|
||||
{
|
||||
GET_BIT_CHECK(prob + i, i);
|
||||
} while (--numDirectBits != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NORMALIZE_CHECK;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
|
||||
{
|
||||
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
|
||||
p->range = 0xFFFFFFFF;
|
||||
p->needFlush = 0;
|
||||
}
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||
{
|
||||
p->needFlush = 1;
|
||||
p->remainLen = 0;
|
||||
p->tempBufSize = 0;
|
||||
|
||||
if (initDic)
|
||||
{
|
||||
p->processedPos = 0;
|
||||
p->checkDicSize = 0;
|
||||
p->needInitState = 1;
|
||||
}
|
||||
if (initState)
|
||||
p->needInitState = 1;
|
||||
}
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p)
|
||||
{
|
||||
p->dicPos = 0;
|
||||
LzmaDec_InitDicAndState(p, True, True);
|
||||
}
|
||||
|
||||
static void LzmaDec_InitStateReal(CLzmaDec *p)
|
||||
{
|
||||
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
|
||||
UInt32 i;
|
||||
CLzmaProb *probs = p->probs;
|
||||
for (i = 0; i < numProbs; i++)
|
||||
probs[i] = kBitModelTotal >> 1;
|
||||
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
|
||||
p->state = 0;
|
||||
p->needInitState = 0;
|
||||
}
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT inSize = *srcLen;
|
||||
(*srcLen) = 0;
|
||||
LzmaDec_WriteRem(p, dicLimit);
|
||||
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
|
||||
while (p->remainLen != kMatchSpecLenStart)
|
||||
{
|
||||
int checkEndMarkNow;
|
||||
|
||||
if (p->needFlush != 0)
|
||||
{
|
||||
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
||||
p->tempBuf[p->tempBufSize++] = *src++;
|
||||
if (p->tempBufSize < RC_INIT_SIZE)
|
||||
{
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (p->tempBuf[0] != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_InitRc(p, p->tempBuf);
|
||||
p->tempBufSize = 0;
|
||||
}
|
||||
|
||||
checkEndMarkNow = 0;
|
||||
if (p->dicPos >= dicLimit)
|
||||
{
|
||||
if (p->remainLen == 0 && p->code == 0)
|
||||
{
|
||||
*status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (finishMode == LZMA_FINISH_ANY)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (p->remainLen != 0)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
checkEndMarkNow = 1;
|
||||
}
|
||||
|
||||
if (p->needInitState)
|
||||
LzmaDec_InitStateReal(p);
|
||||
|
||||
if (p->tempBufSize == 0)
|
||||
{
|
||||
SizeT processed;
|
||||
const Byte *bufLimit;
|
||||
if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||
{
|
||||
int dummyRes = LzmaDec_TryDummy(p, src, inSize);
|
||||
if (dummyRes == DUMMY_ERROR)
|
||||
{
|
||||
memcpy(p->tempBuf, src, inSize);
|
||||
p->tempBufSize = (unsigned)inSize;
|
||||
(*srcLen) += inSize;
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
bufLimit = src;
|
||||
}
|
||||
else
|
||||
bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
|
||||
p->buf = src;
|
||||
if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
processed = (SizeT)(p->buf - src);
|
||||
(*srcLen) += processed;
|
||||
src += processed;
|
||||
inSize -= processed;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned rem = p->tempBufSize, lookAhead = 0;
|
||||
while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
|
||||
p->tempBuf[rem++] = src[lookAhead++];
|
||||
p->tempBufSize = rem;
|
||||
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||
{
|
||||
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
|
||||
if (dummyRes == DUMMY_ERROR)
|
||||
{
|
||||
(*srcLen) += lookAhead;
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
p->buf = p->tempBuf;
|
||||
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
|
||||
(*srcLen) += lookAhead;
|
||||
src += lookAhead;
|
||||
inSize -= lookAhead;
|
||||
p->tempBufSize = 0;
|
||||
}
|
||||
}
|
||||
if (p->code == 0)
|
||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
|
||||
}
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen;
|
||||
SizeT inSize = *srcLen;
|
||||
*srcLen = *destLen = 0;
|
||||
for (;;)
|
||||
{
|
||||
SizeT inSizeCur = inSize, outSizeCur, dicPos;
|
||||
ELzmaFinishMode curFinishMode;
|
||||
SRes res;
|
||||
if (p->dicPos == p->dicBufSize)
|
||||
p->dicPos = 0;
|
||||
dicPos = p->dicPos;
|
||||
if (outSize > p->dicBufSize - dicPos)
|
||||
{
|
||||
outSizeCur = p->dicBufSize;
|
||||
curFinishMode = LZMA_FINISH_ANY;
|
||||
}
|
||||
else
|
||||
{
|
||||
outSizeCur = dicPos + outSize;
|
||||
curFinishMode = finishMode;
|
||||
}
|
||||
|
||||
res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
|
||||
src += inSizeCur;
|
||||
inSize -= inSizeCur;
|
||||
*srcLen += inSizeCur;
|
||||
outSizeCur = p->dicPos - dicPos;
|
||||
memcpy(dest, p->dic + dicPos, outSizeCur);
|
||||
dest += outSizeCur;
|
||||
outSize -= outSizeCur;
|
||||
*destLen += outSizeCur;
|
||||
if (res != 0)
|
||||
return res;
|
||||
if (outSizeCur == 0 || outSize == 0)
|
||||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->probs);
|
||||
p->probs = 0;
|
||||
}
|
||||
|
||||
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->dic);
|
||||
p->dic = 0;
|
||||
}
|
||||
|
||||
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
LzmaDec_FreeProbs(p, alloc);
|
||||
LzmaDec_FreeDict(p, alloc);
|
||||
}
|
||||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
Byte d;
|
||||
|
||||
if (size < LZMA_PROPS_SIZE)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
else
|
||||
dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
|
||||
|
||||
if (dicSize < LZMA_DIC_MIN)
|
||||
dicSize = LZMA_DIC_MIN;
|
||||
p->dicSize = dicSize;
|
||||
|
||||
d = data[0];
|
||||
if (d >= (9 * 5 * 5))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
p->lc = d % 9;
|
||||
d /= 9;
|
||||
p->pb = d / 5;
|
||||
p->lp = d % 5;
|
||||
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
||||
if (p->probs == 0 || numProbs != p->numProbs)
|
||||
{
|
||||
LzmaDec_FreeProbs(p, alloc);
|
||||
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
||||
p->numProbs = numProbs;
|
||||
if (p->probs == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||
{
|
||||
CLzmaProps propNew;
|
||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
||||
p->prop = propNew;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||
{
|
||||
CLzmaProps propNew;
|
||||
SizeT dicBufSize;
|
||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
||||
dicBufSize = propNew.dicSize;
|
||||
if (p->dic == 0 || dicBufSize != p->dicBufSize)
|
||||
{
|
||||
LzmaDec_FreeDict(p, alloc);
|
||||
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
||||
if (p->dic == 0)
|
||||
{
|
||||
LzmaDec_FreeProbs(p, alloc);
|
||||
return SZ_ERROR_MEM;
|
||||
}
|
||||
}
|
||||
p->dicBufSize = dicBufSize;
|
||||
p->prop = propNew;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc)
|
||||
{
|
||||
CLzmaDec p;
|
||||
SRes res;
|
||||
SizeT inSize = *srcLen;
|
||||
SizeT outSize = *destLen;
|
||||
*srcLen = *destLen = 0;
|
||||
if (inSize < RC_INIT_SIZE)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
|
||||
LzmaDec_Construct(&p);
|
||||
res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
|
||||
if (res != 0)
|
||||
return res;
|
||||
p.dic = dest;
|
||||
p.dicBufSize = outSize;
|
||||
|
||||
LzmaDec_Init(&p);
|
||||
|
||||
*srcLen = inSize;
|
||||
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
|
||||
|
||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
res = SZ_ERROR_INPUT_EOF;
|
||||
|
||||
(*destLen) = p.dicPos;
|
||||
LzmaDec_FreeProbs(&p, alloc);
|
||||
return res;
|
||||
}
|
231
common/LZMA/SDK/C/LzmaDec.h
Normal file
231
common/LZMA/SDK/C/LzmaDec.h
Normal file
|
@ -0,0 +1,231 @@
|
|||
/* LzmaDec.h -- LZMA Decoder
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA_DEC_H
|
||||
#define __LZMA_DEC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* #define _LZMA_PROB32 */
|
||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CLzmaProb UInt32
|
||||
#else
|
||||
#define CLzmaProb UInt16
|
||||
#endif
|
||||
|
||||
|
||||
/* ---------- LZMA Properties ---------- */
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaProps
|
||||
{
|
||||
unsigned lc, lp, pb;
|
||||
UInt32 dicSize;
|
||||
} CLzmaProps;
|
||||
|
||||
/* LzmaProps_Decode - decodes properties
|
||||
Returns:
|
||||
SZ_OK
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||
|
||||
|
||||
/* ---------- LZMA Decoder state ---------- */
|
||||
|
||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||
|
||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaProps prop;
|
||||
CLzmaProb *probs;
|
||||
Byte *dic;
|
||||
const Byte *buf;
|
||||
UInt32 range, code;
|
||||
SizeT dicPos;
|
||||
SizeT dicBufSize;
|
||||
UInt32 processedPos;
|
||||
UInt32 checkDicSize;
|
||||
unsigned state;
|
||||
UInt32 reps[4];
|
||||
unsigned remainLen;
|
||||
int needFlush;
|
||||
int needInitState;
|
||||
UInt32 numProbs;
|
||||
unsigned tempBufSize;
|
||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||
} CLzmaDec;
|
||||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p);
|
||||
|
||||
/* There are two types of LZMA streams:
|
||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_FINISH_ANY, /* finish at any point */
|
||||
LZMA_FINISH_END /* block must be finished at the end */
|
||||
} ELzmaFinishMode;
|
||||
|
||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||
|
||||
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||
|
||||
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||
and output value of destLen will be less than output buffer size limit.
|
||||
You can check status result also.
|
||||
|
||||
You can use multiple checks to test data integrity after full decompression:
|
||||
1) Check Result and "status" variable.
|
||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||
You must use correct finish mode in that case. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||
} ELzmaStatus;
|
||||
|
||||
/* ELzmaStatus is used only as output value for function call */
|
||||
|
||||
|
||||
/* ---------- Interfaces ---------- */
|
||||
|
||||
/* There are 3 levels of interfaces:
|
||||
1) Dictionary Interface
|
||||
2) Buffer Interface
|
||||
3) One Call Interface
|
||||
You can select any of these interfaces, but don't mix functions from different
|
||||
groups for same object. */
|
||||
|
||||
|
||||
/* There are two variants to allocate state for Dictionary Interface:
|
||||
1) LzmaDec_Allocate / LzmaDec_Free
|
||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||
You can use variant 2, if you set dictionary buffer manually.
|
||||
For Buffer Interface you must always use variant 1.
|
||||
|
||||
LzmaDec_Allocate* can return:
|
||||
SZ_OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
|
||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||
|
||||
/* ---------- Dictionary Interface ---------- */
|
||||
|
||||
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||
dictionary to some other external buffer.
|
||||
You must work with CLzmaDec variables directly in this interface.
|
||||
|
||||
STEPS:
|
||||
LzmaDec_Constr()
|
||||
LzmaDec_Allocate()
|
||||
for (each new stream)
|
||||
{
|
||||
LzmaDec_Init()
|
||||
while (it needs more decompression)
|
||||
{
|
||||
LzmaDec_DecodeToDic()
|
||||
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||
}
|
||||
}
|
||||
LzmaDec_Free()
|
||||
*/
|
||||
|
||||
/* LzmaDec_DecodeToDic
|
||||
|
||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- Buffer Interface ---------- */
|
||||
|
||||
/* It's zlib-like interface.
|
||||
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||
to work with CLzmaDec variables manually.
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaDecode
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
2248
common/LZMA/SDK/C/LzmaEnc.c
Normal file
2248
common/LZMA/SDK/C/LzmaEnc.c
Normal file
File diff suppressed because it is too large
Load diff
80
common/LZMA/SDK/C/LzmaEnc.h
Normal file
80
common/LZMA/SDK/C/LzmaEnc.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* LzmaEnc.h -- LZMA Encoder
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA_ENC_H
|
||||
#define __LZMA_ENC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaEncProps
|
||||
{
|
||||
int level; /* 0 <= level <= 9 */
|
||||
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
||||
default = (1 << 24) */
|
||||
int lc; /* 0 <= lc <= 8, default = 3 */
|
||||
int lp; /* 0 <= lp <= 4, default = 0 */
|
||||
int pb; /* 0 <= pb <= 4, default = 2 */
|
||||
int algo; /* 0 - fast, 1 - normal, default = 1 */
|
||||
int fb; /* 5 <= fb <= 273, default = 32 */
|
||||
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
||||
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
||||
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
||||
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
||||
int numThreads; /* 1 or 2, default = 2 */
|
||||
} CLzmaEncProps;
|
||||
|
||||
void LzmaEncProps_Init(CLzmaEncProps *p);
|
||||
void LzmaEncProps_Normalize(CLzmaEncProps *p);
|
||||
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
|
||||
|
||||
|
||||
/* ---------- CLzmaEncHandle Interface ---------- */
|
||||
|
||||
/* LzmaEnc_* functions can return the following exit codes:
|
||||
Returns:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||
SZ_ERROR_WRITE - Write callback error.
|
||||
SZ_ERROR_PROGRESS - some break from progress callback
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
typedef void * CLzmaEncHandle;
|
||||
|
||||
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
|
||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaEncode
|
||||
Return code:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater
|
||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
256
common/LZMA/SDK/C/Types.h
Normal file
256
common/LZMA/SDK/C/Types.h
Normal file
|
@ -0,0 +1,256 @@
|
|||
/* Types.h -- Basic types
|
||||
2010-10-09 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
|
||||
#include "../../UefiLzma.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef EXTERN_C_BEGIN
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C_BEGIN extern "C" {
|
||||
#define EXTERN_C_END }
|
||||
#else
|
||||
#define EXTERN_C_BEGIN
|
||||
#define EXTERN_C_END
|
||||
#endif
|
||||
#endif
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define SZ_OK 0
|
||||
|
||||
#define SZ_ERROR_DATA 1
|
||||
#define SZ_ERROR_MEM 2
|
||||
#define SZ_ERROR_CRC 3
|
||||
#define SZ_ERROR_UNSUPPORTED 4
|
||||
#define SZ_ERROR_PARAM 5
|
||||
#define SZ_ERROR_INPUT_EOF 6
|
||||
#define SZ_ERROR_OUTPUT_EOF 7
|
||||
#define SZ_ERROR_READ 8
|
||||
#define SZ_ERROR_WRITE 9
|
||||
#define SZ_ERROR_PROGRESS 10
|
||||
#define SZ_ERROR_FAIL 11
|
||||
#define SZ_ERROR_THREAD 12
|
||||
|
||||
#define SZ_ERROR_ARCHIVE 16
|
||||
#define SZ_ERROR_NO_ARCHIVE 17
|
||||
|
||||
typedef int SRes;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef DWORD WRes;
|
||||
#else
|
||||
typedef int WRes;
|
||||
#endif
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#ifdef _LZMA_UINT32_IS_ULONG
|
||||
typedef long Int32;
|
||||
typedef unsigned long UInt32;
|
||||
#else
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
|
||||
#ifdef _SZ_NO_INT_64
|
||||
|
||||
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||
NOTES: Some code will work incorrectly in that case! */
|
||||
|
||||
typedef long Int64;
|
||||
typedef unsigned long UInt64;
|
||||
|
||||
#else
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#define UINT64_CONST(n) n
|
||||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#define UINT64_CONST(n) n ## ULL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||
typedef UInt32 SizeT;
|
||||
#else
|
||||
typedef size_t SizeT;
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define MY_STD_CALL __stdcall
|
||||
#else
|
||||
#define MY_STD_CALL
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define MY_NO_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define MY_NO_INLINE
|
||||
#endif
|
||||
|
||||
#define MY_CDECL __cdecl
|
||||
#define MY_FAST_CALL __fastcall
|
||||
|
||||
#else
|
||||
|
||||
#define MY_CDECL
|
||||
#define MY_FAST_CALL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||
} IByteIn;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*Write)(void *p, Byte b);
|
||||
} IByteOut;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
} ISeqInStream;
|
||||
|
||||
/* it can return SZ_ERROR_INPUT_EOF */
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||
/* Returns: result - the number of actually written bytes.
|
||||
(result < size) means error */
|
||||
} ISeqOutStream;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SZ_SEEK_SET = 0,
|
||||
SZ_SEEK_CUR = 1,
|
||||
SZ_SEEK_END = 2
|
||||
} ESzSeek;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ISeekInStream;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Look)(void *p, const void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
SRes (*Skip)(void *p, size_t offset);
|
||||
/* offset must be <= output(*size) of Look */
|
||||
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ILookInStream;
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
||||
|
||||
/* reads via ILookInStream::Read */
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
||||
|
||||
#define LookToRead_BUF_SIZE (1 << 14)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ILookInStream s;
|
||||
ISeekInStream *realStream;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
Byte buf[LookToRead_BUF_SIZE];
|
||||
} CLookToRead;
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||
void LookToRead_Init(CLookToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToLook;
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToRead;
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||
/* Returns: result. (result != SZ_OK) means break.
|
||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||
} ICompressProgress;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
} ISzAlloc;
|
||||
|
||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define CHAR_PATH_SEPARATOR '\\'
|
||||
#define WCHAR_PATH_SEPARATOR L'\\'
|
||||
#define STRING_PATH_SEPARATOR "\\"
|
||||
#define WSTRING_PATH_SEPARATOR L"\\"
|
||||
|
||||
#else
|
||||
|
||||
#define CHAR_PATH_SEPARATOR '/'
|
||||
#define WCHAR_PATH_SEPARATOR L'/'
|
||||
#define STRING_PATH_SEPARATOR "/"
|
||||
#define WSTRING_PATH_SEPARATOR L"/"
|
||||
|
||||
#endif
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
31
common/LZMA/UefiLzma.h
Normal file
31
common/LZMA/UefiLzma.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* LZMA UEFI header file
|
||||
|
||||
Copyright (c) 2009, Intel Corporation. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __UEFILZMA_H__
|
||||
#define __UEFILZMA_H__
|
||||
|
||||
#include "../basetypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef _WIN32
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
#undef _WIN64
|
||||
#endif
|
||||
|
||||
#define _LZMA_SIZE_OPT
|
||||
#define _7ZIP_ST
|
||||
|
||||
#endif // __UEFILZMA_H__
|
||||
|
1688
common/Tiano/EfiTianoCompress.c
Normal file
1688
common/Tiano/EfiTianoCompress.c
Normal file
File diff suppressed because it is too large
Load diff
118
common/Tiano/EfiTianoCompress.h
Normal file
118
common/Tiano/EfiTianoCompress.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* EfiTianoCompress.h
|
||||
|
||||
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.<BR>
|
||||
Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
TianoCompress.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Header file for compression routine.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __EFITIANOCOMPRESS_H__
|
||||
#define __EFITIANOCOMPRESS_H__
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../basetypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Tiano compression routine.
|
||||
|
||||
Arguments:
|
||||
|
||||
SrcBuffer - The buffer storing the source data
|
||||
SrcSize - The size of source data
|
||||
DstBuffer - The buffer to store the compressed data
|
||||
DstSize - On input, the size of DstBuffer; On output,
|
||||
the size of the actual compressed data.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. this case,
|
||||
DstSize contains the size needed.
|
||||
EFI_SUCCESS - Compression is successful.
|
||||
EFI_OUT_OF_RESOURCES - No resource to complete function.
|
||||
EFI_INVALID_PARAMETER - Parameter supplied is wrong.
|
||||
|
||||
--*/
|
||||
EFI_STATUS
|
||||
TianoCompress(
|
||||
CONST VOID *SrcBuffer,
|
||||
UINT32 SrcSize,
|
||||
VOID *DstBuffer,
|
||||
UINT32 *DstSize
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
TianoCompressLegacy(
|
||||
CONST VOID *SrcBuffer,
|
||||
UINT32 SrcSize,
|
||||
VOID *DstBuffer,
|
||||
UINT32 *DstSize
|
||||
)
|
||||
;
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
EFI 1.1 compression routine.
|
||||
|
||||
Arguments:
|
||||
|
||||
SrcBuffer - The buffer storing the source data
|
||||
SrcSize - The size of source data
|
||||
DstBuffer - The buffer to store the compressed data
|
||||
DstSize - On input, the size of DstBuffer; On output,
|
||||
the size of the actual compressed data.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. this case,
|
||||
DstSize contains the size needed.
|
||||
EFI_SUCCESS - Compression is successful.
|
||||
EFI_OUT_OF_RESOURCES - No resource to complete function.
|
||||
EFI_INVALID_PARAMETER - Parameter supplied is wrong.
|
||||
|
||||
--*/
|
||||
EFI_STATUS
|
||||
EfiCompress(
|
||||
CONST VOID *SrcBuffer,
|
||||
UINT32 SrcSize,
|
||||
VOID *DstBuffer,
|
||||
UINT32 *DstSize
|
||||
)
|
||||
;
|
||||
EFI_STATUS
|
||||
EfiCompressLegacy(
|
||||
CONST VOID *SrcBuffer,
|
||||
UINT32 SrcSize,
|
||||
VOID *DstBuffer,
|
||||
UINT32 *DstSize
|
||||
)
|
||||
;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
1858
common/Tiano/EfiTianoCompressLegacy.c
Normal file
1858
common/Tiano/EfiTianoCompressLegacy.c
Normal file
File diff suppressed because it is too large
Load diff
998
common/Tiano/EfiTianoDecompress.c
Normal file
998
common/Tiano/EfiTianoDecompress.c
Normal file
|
@ -0,0 +1,998 @@
|
|||
/*++ EfiTianoDecompress.c
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.<BR>
|
||||
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Decompress.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Decompressor. Algorithm Ported from OPSD code (Decomp.asm)
|
||||
|
||||
--*/
|
||||
|
||||
#include "EfiTianoDecompress.h"
|
||||
|
||||
//
|
||||
// Decompression algorithm begins here
|
||||
//
|
||||
#define BITBUFSIZ 32
|
||||
#define MAXMATCH 256
|
||||
#define THRESHOLD 3
|
||||
#define CODE_BIT 16
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX 0xff
|
||||
#endif
|
||||
#define BAD_TABLE - 1
|
||||
|
||||
//
|
||||
// C: Char&Len Set; P: Position Set; T: exTra Set
|
||||
//
|
||||
#define NC (0xff + MAXMATCH + 2 - THRESHOLD)
|
||||
#define CBIT 9
|
||||
#define MAXPBIT 5
|
||||
#define TBIT 5
|
||||
#define MAXNP ((1U << MAXPBIT) - 1)
|
||||
#define NT (CODE_BIT + 3)
|
||||
#if NT > MAXNP
|
||||
#define NPT NT
|
||||
#else
|
||||
#define NPT MAXNP
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
UINT8 *mSrcBase; // Starting address of compressed data
|
||||
UINT8 *mDstBase; // Starting address of decompressed data
|
||||
UINT32 mOutBuf;
|
||||
UINT32 mInBuf;
|
||||
|
||||
UINT16 mBitCount;
|
||||
UINT32 mBitBuf;
|
||||
UINT32 mSubBitBuf;
|
||||
UINT16 mBlockSize;
|
||||
UINT32 mCompSize;
|
||||
UINT32 mOrigSize;
|
||||
|
||||
UINT16 mBadTableFlag;
|
||||
|
||||
UINT16 mLeft[2 * NC - 1];
|
||||
UINT16 mRight[2 * NC - 1];
|
||||
UINT8 mCLen[NC];
|
||||
UINT8 mPTLen[NPT];
|
||||
UINT16 mCTable[4096];
|
||||
UINT16 mPTTable[256];
|
||||
|
||||
//
|
||||
// The length of the field 'Position Set Code Length Array Size' in Block Header.
|
||||
// For EFI 1.1 de/compression algorithm, mPBit = 4
|
||||
// For Tiano de/compression algorithm, mPBit = 5
|
||||
//
|
||||
UINT8 mPBit;
|
||||
} SCRATCH_DATA;
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
FillBuf(
|
||||
IN SCRATCH_DATA *Sd,
|
||||
IN UINT16 NumOfBits
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
|
||||
|
||||
Arguments:
|
||||
|
||||
Sd - The global scratch data
|
||||
NumOfBits - The number of bits to shift and read.
|
||||
|
||||
Returns: (VOID)
|
||||
|
||||
--*/
|
||||
{
|
||||
Sd->mBitBuf = (UINT32)(Sd->mBitBuf << NumOfBits);
|
||||
|
||||
while (NumOfBits > Sd->mBitCount) {
|
||||
Sd->mBitBuf |= (UINT32)(Sd->mSubBitBuf << (NumOfBits = (UINT16)(NumOfBits - Sd->mBitCount)));
|
||||
|
||||
if (Sd->mCompSize > 0) {
|
||||
//
|
||||
// Get 1 byte into SubBitBuf
|
||||
//
|
||||
Sd->mCompSize--;
|
||||
Sd->mSubBitBuf = 0;
|
||||
Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
|
||||
Sd->mBitCount = 8;
|
||||
}
|
||||
else {
|
||||
//
|
||||
// No more bits from the source, just pad zero bit.
|
||||
//
|
||||
Sd->mSubBitBuf = 0;
|
||||
Sd->mBitCount = 8;
|
||||
}
|
||||
}
|
||||
|
||||
Sd->mBitCount = (UINT16)(Sd->mBitCount - NumOfBits);
|
||||
Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
GetBits(
|
||||
IN SCRATCH_DATA *Sd,
|
||||
IN UINT16 NumOfBits
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
|
||||
NumOfBits of bits from source. Returns NumOfBits of bits that are
|
||||
popped out.
|
||||
|
||||
Arguments:
|
||||
|
||||
Sd - The global scratch data.
|
||||
NumOfBits - The number of bits to pop and read.
|
||||
|
||||
Returns:
|
||||
|
||||
The bits that are popped out.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 OutBits;
|
||||
|
||||
OutBits = (UINT32)(Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
|
||||
|
||||
FillBuf(Sd, NumOfBits);
|
||||
|
||||
return OutBits;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT16
|
||||
MakeTable(
|
||||
IN SCRATCH_DATA *Sd,
|
||||
IN UINT16 NumOfChar,
|
||||
IN UINT8 *BitLen,
|
||||
IN UINT16 TableBits,
|
||||
OUT UINT16 *Table
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Creates Huffman Code mapping table according to code length array.
|
||||
|
||||
Arguments:
|
||||
|
||||
Sd - The global scratch data
|
||||
NumOfChar - Number of symbols in the symbol set
|
||||
BitLen - Code length array
|
||||
TableBits - The width of the mapping table
|
||||
Table - The table
|
||||
|
||||
Returns:
|
||||
|
||||
0 - OK.
|
||||
BAD_TABLE - The table is corrupted.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT16 Count[17];
|
||||
UINT16 Weight[17];
|
||||
UINT16 Start[18];
|
||||
UINT16 *Pointer;
|
||||
UINT16 Index3;
|
||||
UINT16 Index;
|
||||
UINT16 Len;
|
||||
UINT16 Char;
|
||||
UINT16 JuBits;
|
||||
UINT16 Avail;
|
||||
UINT16 NextCode;
|
||||
UINT16 Mask;
|
||||
|
||||
//
|
||||
// TableBits should not be greater than 16.
|
||||
//
|
||||
if (TableBits >= (sizeof(Count) / sizeof(UINT16))) {
|
||||
return (UINT16)BAD_TABLE;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize Count array starting from Index 0, as there is a possibility of Count array being uninitialized.
|
||||
//
|
||||
for (Index = 0; Index <= 16; Index++) {
|
||||
Count[Index] = 0;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumOfChar; Index++) {
|
||||
//
|
||||
// Count array index should not be greater than or equal to its size.
|
||||
//
|
||||
if (BitLen[Index] < (sizeof(Count) / sizeof(UINT16))) {
|
||||
Count[BitLen[Index]]++;
|
||||
}
|
||||
else {
|
||||
return (UINT16)BAD_TABLE;
|
||||
}
|
||||
}
|
||||
|
||||
Start[0] = 0;
|
||||
Start[1] = 0;
|
||||
|
||||
for (Index = 1; Index <= 16; Index++) {
|
||||
Start[Index + 1] = (UINT16)(Start[Index] + (Count[Index] << (16 - Index)));
|
||||
}
|
||||
|
||||
if (Start[17] != 0) {
|
||||
/*(1U << 16)*/
|
||||
return (UINT16)BAD_TABLE;
|
||||
}
|
||||
|
||||
JuBits = (UINT16)(16 - TableBits);
|
||||
|
||||
for (Index = 1; Index <= TableBits; Index++) {
|
||||
Start[Index] >>= JuBits;
|
||||
Weight[Index] = (UINT16)(1U << (TableBits - Index));
|
||||
}
|
||||
|
||||
while (Index <= 16) {
|
||||
Weight[Index] = (UINT16)(1U << (16 - Index));
|
||||
Index++;
|
||||
}
|
||||
|
||||
Index = (UINT16)(Start[TableBits + 1] >> JuBits);
|
||||
|
||||
if (Index != 0) {
|
||||
Index3 = (UINT16)(1U << TableBits);
|
||||
while (Index != Index3) {
|
||||
Table[Index++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Avail = NumOfChar;
|
||||
Mask = (UINT16)(1U << (15 - TableBits));
|
||||
|
||||
for (Char = 0; Char < NumOfChar; Char++) {
|
||||
Len = BitLen[Char];
|
||||
if (Len == 0 || Len >= 17) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NextCode = (UINT16)(Start[Len] + Weight[Len]);
|
||||
|
||||
if (Len <= TableBits) {
|
||||
for (Index = Start[Len]; Index < NextCode; Index++) {
|
||||
// Check to prevent possible heap corruption
|
||||
if (Index >= (UINT16)(1U << TableBits))
|
||||
return (UINT16)BAD_TABLE;
|
||||
Table[Index] = Char;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Index3 = Start[Len];
|
||||
Pointer = &Table[Index3 >> JuBits];
|
||||
Index = (UINT16)(Len - TableBits);
|
||||
|
||||
while (Index != 0) {
|
||||
//
|
||||
// Avail should be lesser than size of mRight and mLeft to prevent buffer overflow.
|
||||
//
|
||||
if ((*Pointer == 0) && (Avail < sizeof(Sd->mRight) / sizeof(UINT16)) && (Avail < sizeof(Sd->mLeft) / sizeof(UINT16))) {
|
||||
Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
|
||||
*Pointer = Avail++;
|
||||
}
|
||||
|
||||
//
|
||||
// *Pointer should be lesser than size of mRight and mLeft to prevent buffer overflow.
|
||||
//
|
||||
if ((Index3 & Mask) && (*Pointer < (sizeof(Sd->mRight) / sizeof(UINT16)))) {
|
||||
Pointer = &Sd->mRight[*Pointer];
|
||||
}
|
||||
else if (*Pointer < (sizeof(Sd->mLeft) / sizeof(UINT16))) {
|
||||
Pointer = &Sd->mLeft[*Pointer];
|
||||
}
|
||||
|
||||
Index3 <<= 1;
|
||||
Index--;
|
||||
}
|
||||
|
||||
*Pointer = Char;
|
||||
}
|
||||
|
||||
Start[Len] = NextCode;
|
||||
}
|
||||
//
|
||||
// Succeeds
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
DecodeP(
|
||||
IN SCRATCH_DATA *Sd
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Decodes a position value.
|
||||
|
||||
Arguments:
|
||||
|
||||
Sd - the global scratch data
|
||||
|
||||
Returns:
|
||||
|
||||
The position value decoded.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT16 Val;
|
||||
UINT32 Mask;
|
||||
UINT32 Pos;
|
||||
|
||||
Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
|
||||
|
||||
if (Val >= MAXNP) {
|
||||
Mask = 1U << (BITBUFSIZ - 1 - 8);
|
||||
|
||||
do {
|
||||
if (Sd->mBitBuf & Mask) {
|
||||
Val = Sd->mRight[Val];
|
||||
}
|
||||
else {
|
||||
Val = Sd->mLeft[Val];
|
||||
}
|
||||
|
||||
Mask >>= 1;
|
||||
} while (Val >= MAXNP);
|
||||
}
|
||||
//
|
||||
// Advance what we have read
|
||||
//
|
||||
FillBuf(Sd, Sd->mPTLen[Val]);
|
||||
|
||||
Pos = Val;
|
||||
if (Val > 1) {
|
||||
Pos = (UINT32)((1U << (Val - 1)) + GetBits(Sd, (UINT16)(Val - 1)));
|
||||
}
|
||||
|
||||
return Pos;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT16
|
||||
ReadPTLen(
|
||||
IN SCRATCH_DATA *Sd,
|
||||
IN UINT16 nn,
|
||||
IN UINT16 nbit,
|
||||
IN UINT16 Special
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Reads code lengths for the Extra Set or the Position Set
|
||||
|
||||
Arguments:
|
||||
|
||||
Sd - The global scratch data
|
||||
nn - Number of symbols
|
||||
nbit - Number of bits needed to represent nn
|
||||
Special - The special symbol that needs to be taken care of
|
||||
|
||||
Returns:
|
||||
|
||||
0 - OK.
|
||||
BAD_TABLE - Table is corrupted.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT16 Number;
|
||||
UINT16 CharC;
|
||||
UINT16 Index;
|
||||
UINT32 Mask;
|
||||
|
||||
Number = (UINT16)GetBits(Sd, nbit);
|
||||
|
||||
if ((Number > sizeof(Sd->mPTLen)) || (nn > sizeof(Sd->mPTLen))) {
|
||||
//
|
||||
// Fail if Number or nn is greater than size of mPTLen
|
||||
//
|
||||
return (UINT16)BAD_TABLE;
|
||||
}
|
||||
|
||||
if (Number == 0) {
|
||||
CharC = (UINT16)GetBits(Sd, nbit);
|
||||
|
||||
for (Index = 0; Index < 256; Index++) {
|
||||
Sd->mPTTable[Index] = CharC;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < nn; Index++) {
|
||||
Sd->mPTLen[Index] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
|
||||
while (Index < Number) {
|
||||
CharC = (UINT16)(Sd->mBitBuf >> (BITBUFSIZ - 3));
|
||||
|
||||
if (CharC == 7) {
|
||||
Mask = 1U << (BITBUFSIZ - 1 - 3);
|
||||
while (Mask & Sd->mBitBuf) {
|
||||
Mask >>= 1;
|
||||
CharC += 1;
|
||||
}
|
||||
}
|
||||
|
||||
FillBuf(Sd, (UINT16)((CharC < 7) ? 3 : CharC - 3));
|
||||
|
||||
Sd->mPTLen[Index++] = (UINT8)CharC;
|
||||
|
||||
if (Index == Special) {
|
||||
CharC = (UINT16)GetBits(Sd, 2);
|
||||
while ((INT16)(--CharC) >= 0) {
|
||||
if (Index >= sizeof(Sd->mPTLen)) {
|
||||
//
|
||||
// Fail if Index is greater than or equal to mPTLen
|
||||
//
|
||||
return (UINT16)BAD_TABLE;
|
||||
}
|
||||
Sd->mPTLen[Index++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (Index < nn) {
|
||||
Sd->mPTLen[Index++] = 0;
|
||||
}
|
||||
|
||||
return MakeTable(Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
ReadCLen(
|
||||
SCRATCH_DATA *Sd
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Reads code lengths for Char&Len Set.
|
||||
|
||||
Arguments:
|
||||
|
||||
Sd - the global scratch data
|
||||
|
||||
Returns: (VOID)
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT16 Number;
|
||||
UINT16 CharC;
|
||||
UINT16 Index;
|
||||
UINT32 Mask;
|
||||
|
||||
Number = (UINT16)GetBits(Sd, CBIT);
|
||||
|
||||
if (Number == 0) {
|
||||
CharC = (UINT16)GetBits(Sd, CBIT);
|
||||
|
||||
for (Index = 0; Index < NC; Index++) {
|
||||
Sd->mCLen[Index] = 0;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < 4096; Index++) {
|
||||
Sd->mCTable[Index] = CharC;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
while (Index < Number) {
|
||||
CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
|
||||
if (CharC >= NT) {
|
||||
Mask = 1U << (BITBUFSIZ - 1 - 8);
|
||||
|
||||
do {
|
||||
if (Mask & Sd->mBitBuf) {
|
||||
CharC = Sd->mRight[CharC];
|
||||
}
|
||||
else {
|
||||
CharC = Sd->mLeft[CharC];
|
||||
}
|
||||
|
||||
Mask >>= 1;
|
||||
} while (CharC >= NT);
|
||||
}
|
||||
//
|
||||
// Advance what we have read
|
||||
//
|
||||
FillBuf(Sd, Sd->mPTLen[CharC]);
|
||||
|
||||
if (CharC <= 2) {
|
||||
if (CharC == 0) {
|
||||
CharC = 1;
|
||||
}
|
||||
else if (CharC == 1) {
|
||||
CharC = (UINT16)(GetBits(Sd, 4) + 3);
|
||||
}
|
||||
else if (CharC == 2) {
|
||||
CharC = (UINT16)(GetBits(Sd, CBIT) + 20);
|
||||
}
|
||||
|
||||
while ((INT16)(--CharC) >= 0) {
|
||||
Sd->mCLen[Index++] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Sd->mCLen[Index++] = (UINT8)(CharC - 2);
|
||||
}
|
||||
}
|
||||
|
||||
while (Index < NC) {
|
||||
Sd->mCLen[Index++] = 0;
|
||||
}
|
||||
|
||||
MakeTable(Sd, NC, Sd->mCLen, 12, Sd->mCTable);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT16
|
||||
DecodeC(
|
||||
SCRATCH_DATA *Sd
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Decode a character/length value.
|
||||
|
||||
Arguments:
|
||||
|
||||
Sd - The global scratch data.
|
||||
|
||||
Returns:
|
||||
|
||||
The value decoded.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT16 Index2;
|
||||
UINT32 Mask;
|
||||
|
||||
if (Sd->mBlockSize == 0) {
|
||||
//
|
||||
// Starting a new block
|
||||
//
|
||||
Sd->mBlockSize = (UINT16)GetBits(Sd, 16);
|
||||
Sd->mBadTableFlag = ReadPTLen(Sd, NT, TBIT, 3);
|
||||
if (Sd->mBadTableFlag != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReadCLen(Sd);
|
||||
|
||||
Sd->mBadTableFlag = ReadPTLen(Sd, MAXNP, Sd->mPBit, (UINT16)(-1));
|
||||
if (Sd->mBadTableFlag != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Sd->mBlockSize--;
|
||||
Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
|
||||
|
||||
if (Index2 >= NC) {
|
||||
Mask = 1U << (BITBUFSIZ - 1 - 12);
|
||||
|
||||
do {
|
||||
if (Sd->mBitBuf & Mask) {
|
||||
Index2 = Sd->mRight[Index2];
|
||||
}
|
||||
else {
|
||||
Index2 = Sd->mLeft[Index2];
|
||||
}
|
||||
|
||||
Mask >>= 1;
|
||||
} while (Index2 >= NC);
|
||||
}
|
||||
//
|
||||
// Advance what we have read
|
||||
//
|
||||
FillBuf(Sd, Sd->mCLen[Index2]);
|
||||
|
||||
return Index2;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
Decode(
|
||||
SCRATCH_DATA *Sd
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Decode the source data and put the resulting data into the destination buffer.
|
||||
|
||||
Arguments:
|
||||
|
||||
Sd - The global scratch data
|
||||
|
||||
Returns: (VOID)
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT16 BytesRemain;
|
||||
UINT32 DataIdx;
|
||||
UINT16 CharC;
|
||||
|
||||
BytesRemain = (UINT16)(-1);
|
||||
|
||||
DataIdx = 0;
|
||||
|
||||
for (;;) {
|
||||
CharC = DecodeC(Sd);
|
||||
if (Sd->mBadTableFlag != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CharC < 256) {
|
||||
//
|
||||
// Process an Original character
|
||||
//
|
||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
Sd->mDstBase[Sd->mOutBuf++] = (UINT8)CharC;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Process a Pointer
|
||||
//
|
||||
CharC = (UINT16)(CharC - (UINT8_MAX + 1 - THRESHOLD));
|
||||
|
||||
BytesRemain = CharC;
|
||||
|
||||
DataIdx = Sd->mOutBuf - DecodeP(Sd) - 1;
|
||||
|
||||
// Check to prevent possible heap corruption
|
||||
if (DataIdx >= Sd->mOrigSize - BytesRemain) {
|
||||
Sd->mBadTableFlag = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
BytesRemain--;
|
||||
while ((INT16)(BytesRemain) >= 0) {
|
||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
BytesRemain--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
GetInfo(
|
||||
IN const VOID *Source,
|
||||
IN UINT32 SrcSize,
|
||||
OUT UINT32 *DstSize,
|
||||
OUT UINT32 *ScratchSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
|
||||
|
||||
Arguments:
|
||||
|
||||
Source - The source buffer containing the compressed data.
|
||||
SrcSize - The size of source buffer
|
||||
DstSize - The size of destination buffer.
|
||||
ScratchSize - The size of scratch buffer.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
|
||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||
|
||||
--*/
|
||||
{
|
||||
const UINT8 *Src;
|
||||
|
||||
*ScratchSize = sizeof(SCRATCH_DATA);
|
||||
|
||||
Src = Source;
|
||||
if (SrcSize < 8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
Decompress(
|
||||
IN const VOID *Source,
|
||||
IN UINT32 SrcSize,
|
||||
IN OUT VOID *Destination,
|
||||
IN UINT32 DstSize,
|
||||
IN OUT VOID *Scratch,
|
||||
IN UINT32 ScratchSize,
|
||||
IN UINT8 Version
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
|
||||
|
||||
Arguments:
|
||||
|
||||
Source - The source buffer containing the compressed data.
|
||||
SrcSize - The size of source buffer
|
||||
Destination - The destination buffer to store the decompressed data
|
||||
DstSize - The size of destination buffer.
|
||||
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||
ScratchSize - The size of scratch buffer.
|
||||
Version - The version of de/compression algorithm.
|
||||
Version 1 for EFI 1.1 de/compression algorithm.
|
||||
Version 2 for Tiano de/compression algorithm.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Decompression is successful
|
||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT32 CompSize;
|
||||
UINT32 OrigSize;
|
||||
EFI_STATUS Status;
|
||||
SCRATCH_DATA *Sd;
|
||||
const UINT8 *Src;
|
||||
UINT8 *Dst;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
Src = Source;
|
||||
Dst = Destination;
|
||||
|
||||
if (ScratchSize < sizeof(SCRATCH_DATA)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Sd = (SCRATCH_DATA *)Scratch;
|
||||
|
||||
if (SrcSize < 8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
|
||||
OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
|
||||
|
||||
//
|
||||
// If compressed file size is 0, return
|
||||
//
|
||||
if (OrigSize == 0) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (SrcSize < CompSize + 8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (DstSize != OrigSize) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Src = Src + 8;
|
||||
|
||||
for (Index = 0; Index < sizeof(SCRATCH_DATA); Index++) {
|
||||
((UINT8 *)Sd)[Index] = 0;
|
||||
}
|
||||
//
|
||||
// The length of the field 'Position Set Code Length Array Size' in Block Header.
|
||||
// For EFI 1.1 de/compression algorithm(Version 1), mPBit = 4
|
||||
// For Tiano de/compression algorithm(Version 2), mPBit = 5
|
||||
//
|
||||
switch (Version) {
|
||||
case 1:
|
||||
Sd->mPBit = 4;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Sd->mPBit = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Currently, only have 2 versions
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Sd->mSrcBase = (UINT8*)Src;
|
||||
Sd->mDstBase = Dst;
|
||||
Sd->mCompSize = CompSize;
|
||||
Sd->mOrigSize = OrigSize;
|
||||
|
||||
//
|
||||
// Fill the first BITBUFSIZ bits
|
||||
//
|
||||
FillBuf(Sd, BITBUFSIZ);
|
||||
|
||||
//
|
||||
// Decompress it
|
||||
//
|
||||
Decode(Sd);
|
||||
|
||||
if (Sd->mBadTableFlag != 0) {
|
||||
//
|
||||
// Something wrong with the source
|
||||
//
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiTianoGetInfo(
|
||||
IN const VOID *Source,
|
||||
IN UINT32 SrcSize,
|
||||
OUT UINT32 *DstSize,
|
||||
OUT UINT32 *ScratchSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - The protocol instance pointer
|
||||
Source - The source buffer containing the compressed data.
|
||||
SrcSize - The size of source buffer
|
||||
DstSize - The size of destination buffer.
|
||||
ScratchSize - The size of scratch buffer.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successful retrieved.
|
||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||
|
||||
--*/
|
||||
{
|
||||
return GetInfo(
|
||||
Source,
|
||||
SrcSize,
|
||||
DstSize,
|
||||
ScratchSize
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDecompress(
|
||||
IN const VOID *Source,
|
||||
IN UINT32 SrcSize,
|
||||
IN OUT VOID *Destination,
|
||||
IN UINT32 DstSize,
|
||||
IN OUT VOID *Scratch,
|
||||
IN UINT32 ScratchSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - The protocol instance pointer
|
||||
Source - The source buffer containing the compressed data.
|
||||
SrcSize - The size of source buffer
|
||||
Destination - The destination buffer to store the decompressed data
|
||||
DstSize - The size of destination buffer.
|
||||
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||
ScratchSize - The size of scratch buffer.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Decompression is successful
|
||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// For EFI 1.1 de/compression algorithm, the version is 1.
|
||||
//
|
||||
return Decompress(
|
||||
Source,
|
||||
SrcSize,
|
||||
Destination,
|
||||
DstSize,
|
||||
Scratch,
|
||||
ScratchSize,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TianoDecompress(
|
||||
IN const VOID *Source,
|
||||
IN UINT32 SrcSize,
|
||||
IN OUT VOID *Destination,
|
||||
IN UINT32 DstSize,
|
||||
IN OUT VOID *Scratch,
|
||||
IN UINT32 ScratchSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The implementation of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - The protocol instance pointer
|
||||
Source - The source buffer containing the compressed data.
|
||||
SrcSize - The size of source buffer
|
||||
Destination - The destination buffer to store the decompressed data
|
||||
DstSize - The size of destination buffer.
|
||||
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||
ScratchSize - The size of scratch buffer.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Decompression is successful
|
||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// For Tiano de/compression algorithm, the version is 2.
|
||||
//
|
||||
return Decompress(
|
||||
Source,
|
||||
SrcSize,
|
||||
Destination,
|
||||
DstSize,
|
||||
Scratch,
|
||||
ScratchSize,
|
||||
2
|
||||
);
|
||||
}
|
141
common/Tiano/EfiTianoDecompress.h
Normal file
141
common/Tiano/EfiTianoDecompress.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* EfiTianoDecompress.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.<BR>
|
||||
Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Decompress.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Header file for decompression routine.
|
||||
Providing both EFI and Tiano decompress algorithms.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef __EFITIANODECOMPRESS_H__
|
||||
#define __EFITIANODECOMPRESS_H__
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../basetypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
UINT32 CompSize;
|
||||
UINT32 OrigSize;
|
||||
} EFI_TIANO_HEADER;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiTianoGetInfo(
|
||||
const VOID *Source,
|
||||
UINT32 SrcSize,
|
||||
UINT32 *DstSize,
|
||||
UINT32 *ScratchSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.GetInfo().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - The protocol instance pointer
|
||||
Source - The source buffer containing the compressed data.
|
||||
SrcSize - The size of source buffer
|
||||
DstSize - The size of destination buffer.
|
||||
ScratchSize - The size of scratch buffer.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
|
||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDecompress(
|
||||
const VOID *Source,
|
||||
UINT32 SrcSize,
|
||||
VOID *Destination,
|
||||
UINT32 DstSize,
|
||||
VOID *Scratch,
|
||||
UINT32 ScratchSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.Decompress().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - The protocol instance pointer
|
||||
Source - The source buffer containing the compressed data.
|
||||
SrcSize - The size of source buffer
|
||||
Destination - The destination buffer to store the decompressed data
|
||||
DstSize - The size of destination buffer.
|
||||
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||
ScratchSize - The size of scratch buffer.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Decompression is successful
|
||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TianoDecompress(
|
||||
const VOID *Source,
|
||||
UINT32 SrcSize,
|
||||
VOID *Destination,
|
||||
UINT32 DstSize,
|
||||
VOID *Scratch,
|
||||
UINT32 ScratchSize
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The implementation is same as that of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - The protocol instance pointer
|
||||
Source - The source buffer containing the compressed data.
|
||||
SrcSize - The size of source buffer
|
||||
Destination - The destination buffer to store the decompressed data
|
||||
DstSize - The size of destination buffer.
|
||||
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||
ScratchSize - The size of scratch buffer.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Decompression is successful
|
||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
149
common/basetypes.h
Normal file
149
common/basetypes.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* basetypes.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __BASETYPES_H__
|
||||
#define __BASETYPES_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t BOOLEAN;
|
||||
typedef int8_t INT8;
|
||||
typedef uint8_t UINT8;
|
||||
typedef int16_t INT16;
|
||||
typedef uint16_t UINT16;
|
||||
typedef int32_t INT32;
|
||||
typedef uint32_t UINT32;
|
||||
typedef int64_t INT64;
|
||||
typedef uint64_t UINT64;
|
||||
typedef char CHAR8;
|
||||
typedef uint16_t CHAR16;
|
||||
typedef unsigned int UINTN;
|
||||
|
||||
#define CONST const
|
||||
#define VOID void
|
||||
#define STATIC static
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE ((BOOLEAN)(1==1))
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE ((BOOLEAN)(0==1))
|
||||
#endif
|
||||
|
||||
typedef UINT8 STATUS;
|
||||
#define ERR_SUCCESS 0
|
||||
#define ERR_INVALID_PARAMETER 1
|
||||
#define ERR_BUFFER_TOO_SMALL 2
|
||||
#define ERR_OUT_OF_RESOURCES 3
|
||||
#define ERR_OUT_OF_MEMORY 4
|
||||
#define ERR_FILE_OPEN 5
|
||||
#define ERR_FILE_READ 6
|
||||
#define ERR_FILE_WRITE 7
|
||||
#define ERR_ITEM_NOT_FOUND 8
|
||||
#define ERR_UNKNOWN_ITEM_TYPE 9
|
||||
#define ERR_INVALID_FLASH_DESCRIPTOR 10
|
||||
#define ERR_INVALID_REGION 11
|
||||
#define ERR_EMPTY_REGION 12
|
||||
#define ERR_BIOS_REGION_NOT_FOUND 13
|
||||
#define ERR_VOLUMES_NOT_FOUND 14
|
||||
#define ERR_INVALID_VOLUME 15
|
||||
#define ERR_VOLUME_REVISION_NOT_SUPPORTED 16
|
||||
#define ERR_COMPLEX_BLOCK_MAP 17
|
||||
#define ERR_UNKNOWN_FFS 18
|
||||
#define ERR_INVALID_FILE 19
|
||||
#define ERR_INVALID_SECTION 20
|
||||
#define ERR_UNKNOWN_SECTION 21
|
||||
#define ERR_STANDARD_COMPRESSION_FAILED 22
|
||||
#define ERR_CUSTOMIZED_COMPRESSION_FAILED 23
|
||||
#define ERR_STANDARD_DECOMPRESSION_FAILED 24
|
||||
#define ERR_CUSTOMIZED_DECOMPRESSION_FAILED 25
|
||||
#define ERR_UNKNOWN_COMPRESSION_TYPE 26
|
||||
#define ERR_DEPEX_PARSE_FAILED 27
|
||||
#define ERR_UNKNOWN_EXTRACT_MODE 28
|
||||
#define ERR_UNKNOWN_IMAGE_TYPE 29
|
||||
#define ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 30
|
||||
#define ERR_UNKNOWN_RELOCATION_TYPE 31
|
||||
#define ERR_DIR_ALREADY_EXIST 32
|
||||
#define ERR_DIR_CREATE 33
|
||||
#define ERR_NOT_IMPLEMENTED 0xFF
|
||||
|
||||
// UDK porting definitions
|
||||
#define IN
|
||||
#define OUT
|
||||
#define EFIAPI
|
||||
#define EFI_STATUS UINTN
|
||||
#define EFI_SUCCESS ERR_SUCCESS
|
||||
#define EFI_INVALID_PARAMETER ERR_INVALID_PARAMETER
|
||||
#define EFI_OUT_OF_RESOURCES ERR_OUT_OF_RESOURCES
|
||||
#define EFI_BUFFER_TOO_SMALL ERR_BUFFER_TOO_SMALL
|
||||
#define EFI_ERROR(X) (X)
|
||||
|
||||
// Compression algorithms
|
||||
#define COMPRESSION_ALGORITHM_UNKNOWN 0
|
||||
#define COMPRESSION_ALGORITHM_NONE 1
|
||||
#define COMPRESSION_ALGORITHM_EFI11 2
|
||||
#define COMPRESSION_ALGORITHM_TIANO 3
|
||||
#define COMPRESSION_ALGORITHM_LZMA 4
|
||||
#define COMPRESSION_ALGORITHM_IMLZMA 5
|
||||
|
||||
// Item create modes
|
||||
#define CREATE_MODE_APPEND 0
|
||||
#define CREATE_MODE_PREPEND 1
|
||||
#define CREATE_MODE_BEFORE 2
|
||||
#define CREATE_MODE_AFTER 3
|
||||
|
||||
// Item extract modes
|
||||
#define EXTRACT_MODE_AS_IS 0
|
||||
#define EXTRACT_MODE_BODY 1
|
||||
|
||||
// Item replace modes
|
||||
#define REPLACE_MODE_AS_IS 0
|
||||
#define REPLACE_MODE_BODY 1
|
||||
|
||||
// Item patch modes
|
||||
#define PATCH_MODE_HEADER 0
|
||||
#define PATCH_MODE_BODY 1
|
||||
|
||||
// Patch types
|
||||
#define PATCH_TYPE_OFFSET 'O'
|
||||
#define PATCH_TYPE_PATTERN 'P'
|
||||
|
||||
// Erase polarity types
|
||||
#define ERASE_POLARITY_FALSE 0
|
||||
#define ERASE_POLARITY_TRUE 1
|
||||
#define ERASE_POLARITY_UNKNOWN 0xFF
|
||||
|
||||
// Search modes
|
||||
#define SEARCH_MODE_HEADER 1
|
||||
#define SEARCH_MODE_BODY 2
|
||||
#define SEARCH_MODE_ALL 3
|
||||
|
||||
// EFI GUID
|
||||
typedef struct _EFI_GUID {
|
||||
UINT8 Data[16];
|
||||
} EFI_GUID;
|
||||
|
||||
#define ALIGN4(Value) (((Value)+3) & ~3)
|
||||
#define ALIGN8(Value) (((Value)+7) & ~7)
|
||||
|
||||
#include <assert.h>
|
||||
#define ASSERT(x) assert(x)
|
||||
|
||||
//Hexarg macros
|
||||
#define hexarg(X) arg(QString("%1").arg((X),0,16).toUpper())
|
||||
#define hexarg2(X, Y) arg(QString("%1").arg((X),(Y),16,QChar('0')).toUpper())
|
||||
|
||||
|
||||
#endif
|
41
common/descriptor.cpp
Normal file
41
common/descriptor.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* descriptor.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
#include "descriptor.h"
|
||||
|
||||
// Calculate address of data structure addressed by descriptor address format
|
||||
// 8 bit base or limit
|
||||
const UINT8* calculateAddress8(const UINT8* baseAddress, const UINT8 baseOrLimit)
|
||||
{
|
||||
return baseAddress + baseOrLimit * 0x10;
|
||||
}
|
||||
|
||||
// 16 bit base or limit
|
||||
const UINT8* calculateAddress16(const UINT8* baseAddress, const UINT16 baseOrLimit)
|
||||
{
|
||||
return baseAddress + baseOrLimit * 0x1000;
|
||||
}
|
||||
|
||||
// Calculate offset of region using its base
|
||||
UINT32 calculateRegionOffset(const UINT16 base)
|
||||
{
|
||||
return base * 0x1000;
|
||||
}
|
||||
|
||||
//Calculate size of region using its base and limit
|
||||
UINT32 calculateRegionSize(const UINT16 base, const UINT16 limit)
|
||||
{
|
||||
if (limit)
|
||||
return (limit + 1 - base) * 0x1000;
|
||||
return 0;
|
||||
}
|
173
common/descriptor.h
Normal file
173
common/descriptor.h
Normal file
|
@ -0,0 +1,173 @@
|
|||
/* descriptor.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#ifndef __DESCRIPTOR_H__
|
||||
#define __DESCRIPTOR_H__
|
||||
|
||||
#include <QString>
|
||||
#include "basetypes.h"
|
||||
|
||||
// Make sure we use right packing rules
|
||||
#pragma pack(push,1)
|
||||
|
||||
// Flash descriptor header
|
||||
typedef struct _FLASH_DESCRIPTOR_HEADER {
|
||||
UINT8 FfVector[16]; // Must be 16 0xFFs
|
||||
UINT32 Signature; // 0x0FF0A55A
|
||||
} FLASH_DESCRIPTOR_HEADER;
|
||||
|
||||
// Flash descriptor signature
|
||||
#define FLASH_DESCRIPTOR_SIGNATURE 0x0FF0A55A
|
||||
|
||||
// Descriptor region size
|
||||
#define FLASH_DESCRIPTOR_SIZE 0x1000
|
||||
|
||||
// Descriptor map
|
||||
// Base fields are storing bits [11:4] of actual base addresses, all other bits are 0
|
||||
typedef struct _FLASH_DESCRIPTOR_MAP {
|
||||
UINT8 ComponentBase; // 0x03 on most machines
|
||||
UINT8 NumberOfFlashChips; // Zero-based number of flash chips installed on board
|
||||
UINT8 RegionBase; // 0x04 on most machines
|
||||
UINT8 NumberOfRegions; // Zero-based number of flash regions (descriptor is always included)
|
||||
UINT8 MasterBase; // 0x06 on most machines
|
||||
UINT8 NumberOfMasters; // Zero-based number of flash masters
|
||||
UINT8 PchStrapsBase; // 0x10 on most machines
|
||||
UINT8 NumberOfPchStraps; // One-based number of UINT32s to read as PCH Straps, min=0, max=255 (1 Kb)
|
||||
UINT8 ProcStrapsBase; // 0x20 on most machines
|
||||
UINT8 NumberOfProcStraps; // Number of PROC straps to be read, can be 0 or 1
|
||||
UINT8 IccTableBase; // 0x21 on most machines
|
||||
UINT8 NumberOfIccTableEntries; // 0x00 on most machines
|
||||
UINT8 DmiTableBase; // 0x25 on most machines
|
||||
UINT8 NumberOfDmiTableEntries; // 0x00 on most machines
|
||||
UINT16 ReservedZero; // Still unknown, zeros in all descriptors I have seen
|
||||
} FLASH_DESCRIPTOR_MAP;
|
||||
|
||||
// Component section
|
||||
// Flash parameters DWORD structure
|
||||
typedef struct _FLASH_PARAMETERS {
|
||||
UINT8 FirstChipDensity : 3;
|
||||
UINT8 SecondChipDensity : 3;
|
||||
UINT8 ReservedZero0 : 2; // Still unknown, zeros in all descriptors I have seen
|
||||
UINT8 ReservedZero1 : 8; // Still unknown, zeros in all descriptors I have seen
|
||||
UINT8 ReservedZero2 : 4; // Still unknown, zeros in all descriptors I have seen
|
||||
UINT8 FastReadEnabled : 1;
|
||||
UINT8 FastReadFreqency : 3;
|
||||
UINT8 FlashReadStatusFrequency : 3;
|
||||
UINT8 FlashWriteFrequency : 3;
|
||||
UINT8 DualOutputFastReadSupported : 1;
|
||||
UINT8 ReservedZero3 : 1; // Still unknown, zero in all descriptors I have seen
|
||||
} FLASH_PARAMETERS;
|
||||
|
||||
// Flash densities
|
||||
#define FLASH_DENSITY_512KB 0x00
|
||||
#define FLASH_DENSITY_1MB 0x01
|
||||
#define FLASH_DENSITY_2MB 0x02
|
||||
#define FLASH_DENSITY_4MB 0x03
|
||||
#define FLASH_DENSITY_8MB 0x04
|
||||
#define FLASH_DENSITY_16MB 0x05
|
||||
|
||||
// Flash frequencies
|
||||
#define FLASH_FREQUENCY_20MHZ 0x00
|
||||
#define FLASH_FREQUENCY_33MHZ 0x01
|
||||
#define FLASH_FREQUENCY_50MHZ 0x04
|
||||
|
||||
// Component section structure
|
||||
typedef struct _FLASH_DESCRIPTOR_COMPONENT_SECTION {
|
||||
FLASH_PARAMETERS FlashParameters;
|
||||
UINT8 InvalidInstruction0; // Instructions for SPI chip, that must not be executed, like FLASH ERASE
|
||||
UINT8 InvalidInstruction1; //
|
||||
UINT8 InvalidInstruction2; //
|
||||
UINT8 InvalidInstruction3; //
|
||||
UINT16 PartitionBoundary; // Upper 16 bit of partition boundary address. Default is 0x0000, which makes the boundary to be 0x00001000
|
||||
UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen
|
||||
} FLASH_DESCRIPTOR_COMPONENT_SECTION;
|
||||
|
||||
// Region section
|
||||
// All base and limit register are storing upper part of actual UINT32 base and limit
|
||||
// If limit is zero - region is not present
|
||||
typedef struct _FLASH_DESCRIPTOR_REGION_SECTION {
|
||||
UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen
|
||||
UINT16 FlashBlockEraseSize; // Size of block erased by single BLOCK ERASE command
|
||||
UINT16 BiosBase;
|
||||
UINT16 BiosLimit;
|
||||
UINT16 MeBase;
|
||||
UINT16 MeLimit;
|
||||
UINT16 GbeBase;
|
||||
UINT16 GbeLimit;
|
||||
UINT16 PdrBase;
|
||||
UINT16 PdrLimit;
|
||||
} FLASH_DESCRIPTOR_REGION_SECTION;
|
||||
|
||||
// Flash block erase sizes
|
||||
#define FLASH_BLOCK_ERASE_SIZE_4KB 0x0000
|
||||
#define FLASH_BLOCK_ERASE_SIZE_8KB 0x0001
|
||||
#define FLASH_BLOCK_ERASE_SIZE_64KB 0x000F
|
||||
|
||||
// Master section
|
||||
typedef struct _FLASH_DESCRIPTOR_MASTER_SECTION {
|
||||
UINT16 BiosId;
|
||||
UINT8 BiosRead;
|
||||
UINT8 BiosWrite;
|
||||
UINT16 MeId;
|
||||
UINT8 MeRead;
|
||||
UINT8 MeWrite;
|
||||
UINT16 GbeId;
|
||||
UINT8 GbeRead;
|
||||
UINT8 GbeWrite;
|
||||
} FLASH_DESCRIPTOR_MASTER_SECTION;
|
||||
|
||||
// Region access bits in master section
|
||||
#define FLASH_DESCRIPTOR_REGION_ACCESS_DESC 0x01
|
||||
#define FLASH_DESCRIPTOR_REGION_ACCESS_BIOS 0x02
|
||||
#define FLASH_DESCRIPTOR_REGION_ACCESS_ME 0x04
|
||||
#define FLASH_DESCRIPTOR_REGION_ACCESS_GBE 0x08
|
||||
#define FLASH_DESCRIPTOR_REGION_ACCESS_PDR 0x10
|
||||
|
||||
//!TODO: Describe PCH and PROC straps sections, as well as ICC and DMI tables
|
||||
|
||||
// Base address of descriptor upper map
|
||||
#define FLASH_DESCRIPTOR_UPPER_MAP_BASE 0x0EFC
|
||||
|
||||
// Descriptor upper map structure
|
||||
typedef struct _FLASH_DESCRIPTOR_UPPER_MAP {
|
||||
UINT8 VsccTableBase; // Base address of VSCC Table for ME, bits [11:4]
|
||||
UINT8 VsccTableSize; // Counted in UINT32s
|
||||
UINT16 ReservedZero; // Still unknown, zero in all descriptors I have seen
|
||||
} FLASH_DESCRIPTOR_UPPER_MAP;
|
||||
|
||||
// VSCC table entry structure
|
||||
typedef struct _VSCC_TABLE_ENTRY {
|
||||
UINT8 VendorId; // JEDEC VendorID byte
|
||||
UINT8 DeviceId0; // JEDEC DeviceID first byte
|
||||
UINT8 DeviceId1; // JEDEC DeviceID second byte
|
||||
UINT8 ReservedZero; // Reserved, must be zero
|
||||
UINT32 VsccRegisterValue; // VSCC register value
|
||||
} VSCC_TABLE_ENTRY;
|
||||
|
||||
// Base address and size of OEM section
|
||||
#define FLASH_DESCRIPTOR_OEM_SECTION_BASE 0x0F00
|
||||
#define FLASH_DESCRIPTOR_OEM_SECTION_SIZE 0xFF
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
|
||||
// Calculate address of data structure addressed by descriptor address format
|
||||
// 8 bit base or limit
|
||||
extern const UINT8* calculateAddress8(const UINT8* baseAddress, const UINT8 baseOrLimit);
|
||||
// 16 bit base or limit
|
||||
extern const UINT8* calculateAddress16(const UINT8* baseAddress, const UINT16 baseOrLimit);
|
||||
|
||||
// Calculate offset of region using it's base
|
||||
extern UINT32 calculateRegionOffset(const UINT16 base);
|
||||
// Calculate size of region using it's base and limit
|
||||
extern UINT32 calculateRegionSize(const UINT16 base, const UINT16 limit);
|
||||
#endif
|
137
common/ffs.cpp
Normal file
137
common/ffs.cpp
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* ffs.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
#include "ffs.h"
|
||||
|
||||
const QVector<QByteArray> FFSv2Volumes =
|
||||
QVector<QByteArray>()
|
||||
<< EFI_FIRMWARE_FILE_SYSTEM_GUID
|
||||
<< EFI_FIRMWARE_FILE_SYSTEM2_GUID
|
||||
<< EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID
|
||||
<< EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID
|
||||
<< EFI_INTEL_FILE_SYSTEM_GUID
|
||||
<< EFI_INTEL_FILE_SYSTEM2_GUID
|
||||
<< EFI_SONY_FILE_SYSTEM_GUID;
|
||||
|
||||
const QVector<QByteArray> FFSv3Volumes =
|
||||
QVector<QByteArray>()
|
||||
<< EFI_FIRMWARE_FILE_SYSTEM3_GUID;
|
||||
|
||||
const UINT8 ffsAlignmentTable[] =
|
||||
{ 0, 4, 7, 9, 10, 12, 15, 16 };
|
||||
|
||||
UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize)
|
||||
{
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
UINT8 counter = 0;
|
||||
|
||||
while (bufferSize--)
|
||||
counter += buffer[bufferSize];
|
||||
|
||||
return (UINT8)(0x100 - counter);
|
||||
}
|
||||
|
||||
UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize)
|
||||
{
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
UINT16 counter = 0;
|
||||
UINT32 index = 0;
|
||||
|
||||
bufferSize /= sizeof(UINT16);
|
||||
|
||||
for (; index < bufferSize; index++) {
|
||||
counter = (UINT16)(counter + buffer[index]);
|
||||
}
|
||||
|
||||
return (UINT16)(0x10000 - counter);
|
||||
}
|
||||
|
||||
VOID uint32ToUint24(UINT32 size, UINT8* ffsSize)
|
||||
{
|
||||
ffsSize[2] = (UINT8)((size) >> 16);
|
||||
ffsSize[1] = (UINT8)((size) >> 8);
|
||||
ffsSize[0] = (UINT8)((size));
|
||||
}
|
||||
|
||||
UINT32 uint24ToUint32(const UINT8* ffsSize)
|
||||
{
|
||||
return *(UINT32*)ffsSize & 0x00FFFFFF;
|
||||
}
|
||||
|
||||
QString guidToQString(const EFI_GUID & guid)
|
||||
{
|
||||
return QString("%1-%2-%3-%4%5-%6%7%8%9%10%11")
|
||||
.arg(*(const UINT32*)&guid.Data[0], 8, 16, QChar('0'))
|
||||
.arg(*(const UINT16*)&guid.Data[4], 4, 16, QChar('0'))
|
||||
.arg(*(const UINT16*)&guid.Data[6], 4, 16, QChar('0'))
|
||||
.arg(guid.Data[8], 2, 16, QChar('0'))
|
||||
.arg(guid.Data[9], 2, 16, QChar('0'))
|
||||
.arg(guid.Data[10], 2, 16, QChar('0'))
|
||||
.arg(guid.Data[11], 2, 16, QChar('0'))
|
||||
.arg(guid.Data[12], 2, 16, QChar('0'))
|
||||
.arg(guid.Data[13], 2, 16, QChar('0'))
|
||||
.arg(guid.Data[14], 2, 16, QChar('0'))
|
||||
.arg(guid.Data[15], 2, 16, QChar('0')).toUpper();
|
||||
}
|
||||
|
||||
QString fileTypeToQString(const UINT8 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EFI_FV_FILETYPE_RAW: return QObject::tr("Raw");
|
||||
case EFI_FV_FILETYPE_FREEFORM: return QObject::tr("Freeform");
|
||||
case EFI_FV_FILETYPE_SECURITY_CORE: return QObject::tr("SEC core");
|
||||
case EFI_FV_FILETYPE_PEI_CORE: return QObject::tr("PEI core");
|
||||
case EFI_FV_FILETYPE_DXE_CORE: return QObject::tr("DXE core");
|
||||
case EFI_FV_FILETYPE_PEIM: return QObject::tr("PEI module");
|
||||
case EFI_FV_FILETYPE_DRIVER: return QObject::tr("DXE driver");
|
||||
case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: return QObject::tr("Combined PEI/DXE");
|
||||
case EFI_FV_FILETYPE_APPLICATION: return QObject::tr("Application");
|
||||
case EFI_FV_FILETYPE_SMM: return QObject::tr("SMM module");
|
||||
case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: return QObject::tr("Volume image");
|
||||
case EFI_FV_FILETYPE_COMBINED_SMM_DXE: return QObject::tr("Combined SMM/DXE");
|
||||
case EFI_FV_FILETYPE_SMM_CORE: return QObject::tr("SMM core");
|
||||
case EFI_FV_FILETYPE_PAD: return QObject::tr("Pad");
|
||||
default: return QObject::tr("Unknown");
|
||||
};
|
||||
}
|
||||
|
||||
QString sectionTypeToQString(const UINT8 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EFI_SECTION_COMPRESSION: return QObject::tr("Compressed");
|
||||
case EFI_SECTION_GUID_DEFINED: return QObject::tr("GUID defined");
|
||||
case EFI_SECTION_DISPOSABLE: return QObject::tr("Disposable");
|
||||
case EFI_SECTION_PE32: return QObject::tr("PE32 image");
|
||||
case EFI_SECTION_PIC: return QObject::tr("PIC image");
|
||||
case EFI_SECTION_TE: return QObject::tr("TE image");
|
||||
case EFI_SECTION_DXE_DEPEX: return QObject::tr("DXE dependency");
|
||||
case EFI_SECTION_VERSION: return QObject::tr("Version");
|
||||
case EFI_SECTION_USER_INTERFACE: return QObject::tr("UI");
|
||||
case EFI_SECTION_COMPATIBILITY16: return QObject::tr("16-bit image");
|
||||
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return QObject::tr("Volume image");
|
||||
case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return QObject::tr("Freeform subtype GUID");
|
||||
case EFI_SECTION_RAW: return QObject::tr("Raw");
|
||||
case EFI_SECTION_PEI_DEPEX: return QObject::tr("PEI dependency");
|
||||
case EFI_SECTION_SMM_DEPEX: return QObject::tr("SMM dependency");
|
||||
case INSYDE_SECTION_POSTCODE: return QObject::tr("Insyde postcode");
|
||||
case SCT_SECTION_POSTCODE: return QObject::tr("SCT postcode");
|
||||
default: return QObject::tr("Unknown");
|
||||
}
|
||||
}
|
||||
|
581
common/ffs.h
Normal file
581
common/ffs.h
Normal file
|
@ -0,0 +1,581 @@
|
|||
/* ffs.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#ifndef __FFS_H__
|
||||
#define __FFS_H__
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include "basetypes.h"
|
||||
|
||||
// C++ functions
|
||||
// GUID to QString routine
|
||||
extern QString guidToQString(const EFI_GUID& guid);
|
||||
// File type to QString routine
|
||||
extern QString fileTypeToQString(const UINT8 type);
|
||||
// Section type to QString routine
|
||||
extern QString sectionTypeToQString(const UINT8 type);
|
||||
|
||||
// Make sure we use right packing rules
|
||||
#pragma pack(push,1)
|
||||
|
||||
//*****************************************************************************
|
||||
// EFI Capsule
|
||||
//*****************************************************************************
|
||||
// Capsule header
|
||||
typedef struct _EFI_CAPSULE_HEADER {
|
||||
EFI_GUID CapsuleGuid;
|
||||
UINT32 HeaderSize;
|
||||
UINT32 Flags;
|
||||
UINT32 CapsuleImageSize;
|
||||
} EFI_CAPSULE_HEADER;
|
||||
|
||||
// Capsule flags
|
||||
#define EFI_CAPSULE_HEADER_FLAG_SETUP 0x00000001
|
||||
#define EFI_CAPSULE_HEADER_FLAG_PERSIST_ACROSS_RESET 0x00010000
|
||||
#define EFI_CAPSULE_HEADER_FLAG_POPULATE_SYSTEM_TABLE 0x00020000
|
||||
|
||||
// Standard EFI capsule GUID
|
||||
const QByteArray EFI_CAPSULE_GUID
|
||||
("\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0", 16);
|
||||
|
||||
// AMI Aptio extended capsule header
|
||||
typedef struct _APTIO_CAPSULE_HEADER {
|
||||
EFI_CAPSULE_HEADER CapsuleHeader;
|
||||
UINT16 RomImageOffset; // offset in bytes from the beginning of the capsule header to the start of
|
||||
// the capsule volume
|
||||
//!TODO: Enable certificate and ROM layout reading
|
||||
//UINT16 RomLayoutOffset; // offset to the table of the module descriptors in the capsule's volume
|
||||
// that are included in the signature calculation
|
||||
//FW_CERTIFICATE FWCert;
|
||||
//ROM_AREA RomAreaMap[1];
|
||||
} APTIO_CAPSULE_HEADER;
|
||||
|
||||
// AMI Aptio signed extended capsule GUID
|
||||
const QByteArray APTIO_SIGNED_CAPSULE_GUID
|
||||
("\x8B\xA6\x3C\x4A\x23\x77\xFB\x48\x80\x3D\x57\x8C\xC1\xFE\xC4\x4D", 16);
|
||||
|
||||
// AMI Aptio unsigned extended capsule GUID
|
||||
const QByteArray APTIO_UNSIGNED_CAPSULE_GUID
|
||||
("\x90\xBB\xEE\x14\x0A\x89\xDB\x43\xAE\xD1\x5D\x3C\x45\x88\xA4\x18", 16);
|
||||
|
||||
//14EEBB90-890A-43DB-AED1-5D3C4588A418
|
||||
|
||||
//*****************************************************************************
|
||||
// EFI Firmware Volume
|
||||
//*****************************************************************************
|
||||
// Firmware block map entry
|
||||
// FvBlockMap ends with an entry {0x00000000, 0x00000000}
|
||||
typedef struct _EFI_FV_BLOCK_MAP_ENTRY {
|
||||
UINT32 NumBlocks;
|
||||
UINT32 Length;
|
||||
} EFI_FV_BLOCK_MAP_ENTRY;
|
||||
|
||||
// Volume header
|
||||
typedef struct _EFI_FIRMWARE_VOLUME_HEADER {
|
||||
UINT8 ZeroVector[16];
|
||||
EFI_GUID FileSystemGuid;
|
||||
UINT64 FvLength;
|
||||
UINT32 Signature;
|
||||
UINT32 Attributes;
|
||||
UINT16 HeaderLength;
|
||||
UINT16 Checksum;
|
||||
UINT16 ExtHeaderOffset; //Reserved in Revision 1
|
||||
UINT8 Reserved;
|
||||
UINT8 Revision;
|
||||
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1];
|
||||
} EFI_FIRMWARE_VOLUME_HEADER;
|
||||
|
||||
// Standard file system GUIDs
|
||||
const QByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID
|
||||
("\xD9\x54\x93\x7A\x68\x04\x4A\x44\x81\xCE\x0B\xF6\x17\xD8\x90\xDF", 16);
|
||||
const QByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID
|
||||
("\x78\xE5\x8C\x8C\x3D\x8A\x1C\x4F\x99\x35\x89\x61\x85\xC3\x2D\xD3", 16);
|
||||
// Vendor-specific file system GUIDs
|
||||
const QByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID
|
||||
("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16);
|
||||
const QByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID
|
||||
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
|
||||
const QByteArray EFI_INTEL_FILE_SYSTEM_GUID
|
||||
("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
|
||||
// AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 // Intel 1
|
||||
const QByteArray EFI_INTEL_FILE_SYSTEM2_GUID
|
||||
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
|
||||
// D6A1CD70-4B33-4994-A6EA-375F2CCC5437 // Intel 2
|
||||
const QByteArray EFI_SONY_FILE_SYSTEM_GUID
|
||||
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
|
||||
// 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1
|
||||
|
||||
// Vector of volume GUIDs with FFSv2-compatible files
|
||||
extern const QVector<QByteArray> FFSv2Volumes;
|
||||
|
||||
const QByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4dca-BD6F-1E9689E7349A
|
||||
("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16);
|
||||
|
||||
// Vector of volume GUIDs with FFSv3-compatible files
|
||||
extern const QVector<QByteArray> FFSv3Volumes;
|
||||
|
||||
// Firmware volume signature
|
||||
const QByteArray EFI_FV_SIGNATURE("_FVH", 4);
|
||||
#define EFI_FV_SIGNATURE_OFFSET 0x28
|
||||
|
||||
// Firmware volume attributes
|
||||
// Revision 1
|
||||
#define EFI_FVB_READ_DISABLED_CAP 0x00000001
|
||||
#define EFI_FVB_READ_ENABLED_CAP 0x00000002
|
||||
#define EFI_FVB_READ_STATUS 0x00000004
|
||||
#define EFI_FVB_WRITE_DISABLED_CAP 0x00000008
|
||||
#define EFI_FVB_WRITE_ENABLED_CAP 0x00000010
|
||||
#define EFI_FVB_WRITE_STATUS 0x00000020
|
||||
#define EFI_FVB_LOCK_CAP 0x00000040
|
||||
#define EFI_FVB_LOCK_STATUS 0x00000080
|
||||
#define EFI_FVB_STICKY_WRITE 0x00000200
|
||||
#define EFI_FVB_MEMORY_MAPPED 0x00000400
|
||||
#define EFI_FVB_ERASE_POLARITY 0x00000800
|
||||
#define EFI_FVB_ALIGNMENT_CAP 0x00008000
|
||||
#define EFI_FVB_ALIGNMENT_2 0x00010000
|
||||
#define EFI_FVB_ALIGNMENT_4 0x00020000
|
||||
#define EFI_FVB_ALIGNMENT_8 0x00040000
|
||||
#define EFI_FVB_ALIGNMENT_16 0x00080000
|
||||
#define EFI_FVB_ALIGNMENT_32 0x00100000
|
||||
#define EFI_FVB_ALIGNMENT_64 0x00200000
|
||||
#define EFI_FVB_ALIGNMENT_128 0x00400000
|
||||
#define EFI_FVB_ALIGNMENT_256 0x00800000
|
||||
#define EFI_FVB_ALIGNMENT_512 0x01000000
|
||||
#define EFI_FVB_ALIGNMENT_1K 0x02000000
|
||||
#define EFI_FVB_ALIGNMENT_2K 0x04000000
|
||||
#define EFI_FVB_ALIGNMENT_4K 0x08000000
|
||||
#define EFI_FVB_ALIGNMENT_8K 0x10000000
|
||||
#define EFI_FVB_ALIGNMENT_16K 0x20000000
|
||||
#define EFI_FVB_ALIGNMENT_32K 0x40000000
|
||||
#define EFI_FVB_ALIGNMENT_64K 0x80000000
|
||||
// Revision 2
|
||||
#define EFI_FVB2_READ_DISABLED_CAP 0x00000001
|
||||
#define EFI_FVB2_READ_ENABLED_CAP 0x00000002
|
||||
#define EFI_FVB2_READ_STATUS 0x00000004
|
||||
#define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008
|
||||
#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010
|
||||
#define EFI_FVB2_WRITE_STATUS 0x00000020
|
||||
#define EFI_FVB2_LOCK_CAP 0x00000040
|
||||
#define EFI_FVB2_LOCK_STATUS 0x00000080
|
||||
#define EFI_FVB2_STICKY_WRITE 0x00000200
|
||||
#define EFI_FVB2_MEMORY_MAPPED 0x00000400
|
||||
#define EFI_FVB2_ERASE_POLARITY 0x00000800
|
||||
#define EFI_FVB2_READ_LOCK_CAP 0x00001000
|
||||
#define EFI_FVB2_READ_LOCK_STATUS 0x00002000
|
||||
#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000
|
||||
#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000
|
||||
#define EFI_FVB2_ALIGNMENT 0x001F0000
|
||||
#define EFI_FVB2_ALIGNMENT_1 0x00000000
|
||||
#define EFI_FVB2_ALIGNMENT_2 0x00010000
|
||||
#define EFI_FVB2_ALIGNMENT_4 0x00020000
|
||||
#define EFI_FVB2_ALIGNMENT_8 0x00030000
|
||||
#define EFI_FVB2_ALIGNMENT_16 0x00040000
|
||||
#define EFI_FVB2_ALIGNMENT_32 0x00050000
|
||||
#define EFI_FVB2_ALIGNMENT_64 0x00060000
|
||||
#define EFI_FVB2_ALIGNMENT_128 0x00070000
|
||||
#define EFI_FVB2_ALIGNMENT_256 0x00080000
|
||||
#define EFI_FVB2_ALIGNMENT_512 0x00090000
|
||||
#define EFI_FVB2_ALIGNMENT_1K 0x000A0000
|
||||
#define EFI_FVB2_ALIGNMENT_2K 0x000B0000
|
||||
#define EFI_FVB2_ALIGNMENT_4K 0x000C0000
|
||||
#define EFI_FVB2_ALIGNMENT_8K 0x000D0000
|
||||
#define EFI_FVB2_ALIGNMENT_16K 0x000E0000
|
||||
#define EFI_FVB2_ALIGNMENT_32K 0x000F0000
|
||||
#define EFI_FVB2_ALIGNMENT_64K 0x00100000
|
||||
#define EFI_FVB2_ALIGNMENT_128K 0x00110000
|
||||
#define EFI_FVB2_ALIGNMENT_256K 0x00120000
|
||||
#define EFI_FVB2_ALIGNMENT_512K 0x00130000
|
||||
#define EFI_FVB2_ALIGNMENT_1M 0x00140000
|
||||
#define EFI_FVB2_ALIGNMENT_2M 0x00150000
|
||||
#define EFI_FVB2_ALIGNMENT_4M 0x00160000
|
||||
#define EFI_FVB2_ALIGNMENT_8M 0x00170000
|
||||
#define EFI_FVB2_ALIGNMENT_16M 0x00180000
|
||||
#define EFI_FVB2_ALIGNMENT_32M 0x00190000
|
||||
#define EFI_FVB2_ALIGNMENT_64M 0x001A0000
|
||||
#define EFI_FVB2_ALIGNMENT_128M 0x001B0000
|
||||
#define EFI_FVB2_ALIGNMENT_256M 0x001C0000
|
||||
#define EFI_FVB2_ALIGNMENT_512M 0x001D0000
|
||||
#define EFI_FVB2_ALIGNMENT_1G 0x001E0000
|
||||
#define EFI_FVB2_ALIGNMENT_2G 0x001F0000
|
||||
#define EFI_FVB2_WEAK_ALIGNMENT 0x80000000
|
||||
|
||||
// Extended firmware volume header
|
||||
typedef struct _EFI_FIRMWARE_VOLUME_EXT_HEADER {
|
||||
EFI_GUID FvName;
|
||||
UINT32 ExtHeaderSize;
|
||||
} EFI_FIRMWARE_VOLUME_EXT_HEADER;
|
||||
|
||||
// Extended header entry
|
||||
// The extended header entries follow each other and are
|
||||
// terminated by ExtHeaderType EFI_FV_EXT_TYPE_END
|
||||
#define EFI_FV_EXT_TYPE_END 0x0000
|
||||
typedef struct _EFI_FIRMWARE_VOLUME_EXT_ENTRY {
|
||||
UINT16 ExtEntrySize;
|
||||
UINT16 ExtEntryType;
|
||||
} EFI_FIRMWARE_VOLUME_EXT_ENTRY;
|
||||
|
||||
// GUID that maps OEM file types to GUIDs
|
||||
#define EFI_FV_EXT_TYPE_OEM_TYPE 0x0001
|
||||
typedef struct _EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE {
|
||||
EFI_FIRMWARE_VOLUME_EXT_ENTRY Header;
|
||||
UINT32 TypeMask;
|
||||
//EFI_GUID Types[1];
|
||||
} EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE;
|
||||
|
||||
#define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002
|
||||
typedef struct _EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE {
|
||||
EFI_FIRMWARE_VOLUME_EXT_ENTRY Header;
|
||||
EFI_GUID FormatType;
|
||||
//UINT8 Data[];
|
||||
} EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE;
|
||||
|
||||
// Volume header 16bit checksum calculation routine
|
||||
extern UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize);
|
||||
|
||||
//*****************************************************************************
|
||||
// EFI FFS File
|
||||
//*****************************************************************************
|
||||
// Integrity check
|
||||
typedef union {
|
||||
struct {
|
||||
UINT8 Header;
|
||||
UINT8 File;
|
||||
} Checksum;
|
||||
UINT16 TailReference; // Revision 1
|
||||
UINT16 Checksum16; // Revision 2
|
||||
} EFI_FFS_INTEGRITY_CHECK;
|
||||
// File header
|
||||
typedef struct _EFI_FFS_FILE_HEADER {
|
||||
EFI_GUID Name;
|
||||
EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
|
||||
UINT8 Type;
|
||||
UINT8 Attributes;
|
||||
UINT8 Size[3];
|
||||
UINT8 State;
|
||||
} EFI_FFS_FILE_HEADER;
|
||||
|
||||
// Large file header
|
||||
typedef struct _EFI_FFS_FILE_HEADER2 {
|
||||
EFI_GUID Name;
|
||||
EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
|
||||
UINT8 Type;
|
||||
UINT8 Attributes;
|
||||
UINT8 Size[3]; // Set to 0xFFFFFF
|
||||
UINT8 State;
|
||||
UINT32 ExtendedSize;
|
||||
} EFI_FFS_FILE_HEADER2;
|
||||
|
||||
// Standard data checksum, used if FFS_ATTRIB_CHECKSUM is clear
|
||||
#define FFS_FIXED_CHECKSUM 0x5A
|
||||
#define FFS_FIXED_CHECKSUM2 0xAA
|
||||
|
||||
// File types
|
||||
#define EFI_FV_FILETYPE_ALL 0x00
|
||||
#define EFI_FV_FILETYPE_RAW 0x01
|
||||
#define EFI_FV_FILETYPE_FREEFORM 0x02
|
||||
#define EFI_FV_FILETYPE_SECURITY_CORE 0x03
|
||||
#define EFI_FV_FILETYPE_PEI_CORE 0x04
|
||||
#define EFI_FV_FILETYPE_DXE_CORE 0x05
|
||||
#define EFI_FV_FILETYPE_PEIM 0x06
|
||||
#define EFI_FV_FILETYPE_DRIVER 0x07
|
||||
#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08
|
||||
#define EFI_FV_FILETYPE_APPLICATION 0x09
|
||||
#define EFI_FV_FILETYPE_SMM 0x0A
|
||||
#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B
|
||||
#define EFI_FV_FILETYPE_COMBINED_SMM_DXE 0x0C
|
||||
#define EFI_FV_FILETYPE_SMM_CORE 0x0D
|
||||
#define EFI_FV_FILETYPE_OEM_MIN 0xC0
|
||||
#define EFI_FV_FILETYPE_OEM_MAX 0xDF
|
||||
#define EFI_FV_FILETYPE_DEBUG_MIN 0xE0
|
||||
#define EFI_FV_FILETYPE_DEBUG_MAX 0xEF
|
||||
#define EFI_FV_FILETYPE_PAD 0xF0
|
||||
#define EFI_FV_FILETYPE_FFS_MIN 0xF0
|
||||
#define EFI_FV_FILETYPE_FFS_MAX 0xFF
|
||||
|
||||
// File attributes
|
||||
#define FFS_ATTRIB_TAIL_PRESENT 0x01 // Valid only for revision 1 volumes
|
||||
#define FFS_ATTRIB_RECOVERY 0x02 // Valid only for revision 1 volumes
|
||||
#define FFS_ATTRIB_LARGE_FILE 0x01 // Valid only for FFSv3 volumes
|
||||
#define FFS_ATTRIB_FIXED 0x04
|
||||
#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
|
||||
#define FFS_ATTRIB_CHECKSUM 0x40
|
||||
|
||||
// FFS alignment table
|
||||
extern const UINT8 ffsAlignmentTable[];
|
||||
|
||||
// File states
|
||||
#define EFI_FILE_HEADER_CONSTRUCTION 0x01
|
||||
#define EFI_FILE_HEADER_VALID 0x02
|
||||
#define EFI_FILE_DATA_VALID 0x04
|
||||
#define EFI_FILE_MARKED_FOR_UPDATE 0x08
|
||||
#define EFI_FILE_DELETED 0x10
|
||||
#define EFI_FILE_HEADER_INVALID 0x20
|
||||
|
||||
// PEI apriori file
|
||||
const QByteArray EFI_PEI_APRIORI_FILE_GUID
|
||||
("\x0A\xCC\x45\x1B\x6A\x15\x8A\x42\xAF\x62\x49\x86\x4D\xA0\xE6\xE6", 16);
|
||||
|
||||
// DXE apriori file
|
||||
const QByteArray EFI_DXE_APRIORI_FILE_GUID
|
||||
("\xE7\x0E\x51\xFC\xDC\xFF\xD4\x11\xBD\x41\x00\x80\xC7\x3C\x88\x81", 16);
|
||||
|
||||
// Volume top file
|
||||
const QByteArray EFI_FFS_VOLUME_TOP_FILE_GUID
|
||||
("\x2E\x06\xA0\x1B\x79\xC7\x82\x45\x85\x66\x33\x6A\xE8\xF7\x8F\x09", 16);
|
||||
|
||||
// Pad file GUID
|
||||
const QByteArray EFI_FFS_PAD_FILE_GUID
|
||||
("\x85\x65\x53\xE4\x09\x79\x60\x4A\xB5\xC6\xEC\xDE\xA6\xEB\xFB\x54", 16);
|
||||
|
||||
// FFS size conversion routines
|
||||
extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize);
|
||||
extern UINT32 uint24ToUint32(const UINT8* ffsSize);
|
||||
// FFS file 8bit checksum calculation routine
|
||||
extern UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize);
|
||||
|
||||
//*****************************************************************************
|
||||
// EFI FFS File Section
|
||||
//*****************************************************************************
|
||||
// Common section header
|
||||
typedef struct _EFI_COMMON_SECTION_HEADER {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
} EFI_COMMON_SECTION_HEADER;
|
||||
|
||||
// Large file common section header
|
||||
typedef struct _EFI_COMMON_SECTION_HEADER2 {
|
||||
UINT8 Size[3]; //Must be 0xFFFFFF for this header to be used
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
} EFI_COMMON_SECTION_HEADER2;
|
||||
|
||||
// Section2 usage indicator
|
||||
#define EFI_SECTION2_IS_USED 0xFFFFFF
|
||||
|
||||
// File section types
|
||||
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
|
||||
|
||||
// Encapsulation section types
|
||||
#define EFI_SECTION_COMPRESSION 0x01
|
||||
#define EFI_SECTION_GUID_DEFINED 0x02
|
||||
#define EFI_SECTION_DISPOSABLE 0x03
|
||||
|
||||
// Leaf section types
|
||||
#define EFI_SECTION_PE32 0x10
|
||||
#define EFI_SECTION_PIC 0x11
|
||||
#define EFI_SECTION_TE 0x12
|
||||
#define EFI_SECTION_DXE_DEPEX 0x13
|
||||
#define EFI_SECTION_VERSION 0x14
|
||||
#define EFI_SECTION_USER_INTERFACE 0x15
|
||||
#define EFI_SECTION_COMPATIBILITY16 0x16
|
||||
#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17
|
||||
#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18
|
||||
#define EFI_SECTION_RAW 0x19
|
||||
#define EFI_SECTION_PEI_DEPEX 0x1B
|
||||
#define EFI_SECTION_SMM_DEPEX 0x1C
|
||||
#define SCT_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images
|
||||
#define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde images
|
||||
|
||||
// Compression section
|
||||
typedef struct _EFI_COMPRESSION_SECTION {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 UncompressedLength;
|
||||
UINT8 CompressionType;
|
||||
} EFI_COMPRESSION_SECTION;
|
||||
|
||||
typedef struct _EFI_COMPRESSION_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
UINT32 UncompressedLength;
|
||||
UINT8 CompressionType;
|
||||
} EFI_COMPRESSION_SECTION2;
|
||||
|
||||
// Compression types
|
||||
#define EFI_NOT_COMPRESSED 0x00
|
||||
#define EFI_STANDARD_COMPRESSION 0x01
|
||||
#define EFI_CUSTOMIZED_COMPRESSION 0x02
|
||||
|
||||
//GUID defined section
|
||||
typedef struct _EFI_GUID_DEFINED_SECTION {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
EFI_GUID SectionDefinitionGuid;
|
||||
UINT16 DataOffset;
|
||||
UINT16 Attributes;
|
||||
} EFI_GUID_DEFINED_SECTION;
|
||||
|
||||
typedef struct _EFI_GUID_DEFINED_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
EFI_GUID SectionDefinitionGuid;
|
||||
UINT16 DataOffset;
|
||||
UINT16 Attributes;
|
||||
} EFI_GUID_DEFINED_SECTION2;
|
||||
|
||||
// Attributes for GUID defined section
|
||||
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01
|
||||
#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02
|
||||
|
||||
// GUIDs of GUID-defined sections
|
||||
const QByteArray EFI_GUIDED_SECTION_CRC32 // FC1BCDB0-7D31-49AA-936A-A4600D9DD083
|
||||
("\xB0\xCD\x1B\xFC\x31\x7D\xAA\x49\x93\x6A\xA4\x60\x0D\x9D\xD0\x83", 16);
|
||||
|
||||
const QByteArray EFI_GUIDED_SECTION_TIANO // A31280AD-481E-41B6-95E8-127F4C984779
|
||||
("\xAD\x80\x12\xA3\x1E\x48\xB6\x41\x95\xE8\x12\x7F\x4C\x98\x47\x79", 16);
|
||||
|
||||
const QByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF
|
||||
("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16);
|
||||
|
||||
const QByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID //0F9D89E8-9259-4F76-A5AF-0C89E34023DF
|
||||
("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16);
|
||||
|
||||
// Version section
|
||||
typedef struct _EFI_VERSION_SECTION {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT16 BuildNumber;
|
||||
} EFI_VERSION_SECTION;
|
||||
|
||||
typedef struct _EFI_VERSION_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
UINT16 BuildNumber;
|
||||
} EFI_VERSION_SECTION2;
|
||||
|
||||
// Freeform subtype GUID section
|
||||
typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
EFI_GUID SubTypeGuid;
|
||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
|
||||
|
||||
typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
EFI_GUID SubTypeGuid;
|
||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
|
||||
|
||||
// Phoenix SCT and HP postcode section
|
||||
typedef struct _POSTCODE_SECTION {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 Postcode;
|
||||
} POSTCODE_SECTION;
|
||||
|
||||
typedef struct _POSTCODE_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
UINT32 Postcode;
|
||||
} POSTCODE_SECTION2;
|
||||
|
||||
// Other sections
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_USER_INTERFACE_SECTION2;
|
||||
|
||||
//*****************************************************************************
|
||||
// EFI Dependency Expression
|
||||
//*****************************************************************************
|
||||
|
||||
#define EFI_DEP_OPCODE_SIZE 1
|
||||
|
||||
///
|
||||
/// If present, this must be the first and only opcode,
|
||||
/// EFI_DEP_BEFORE is only used by DXE driver.
|
||||
///
|
||||
#define EFI_DEP_BEFORE 0x00
|
||||
|
||||
///
|
||||
/// If present, this must be the first and only opcode,
|
||||
/// EFI_DEP_AFTER is only used by DXE driver.
|
||||
///
|
||||
#define EFI_DEP_AFTER 0x01
|
||||
|
||||
#define EFI_DEP_PUSH 0x02
|
||||
#define EFI_DEP_AND 0x03
|
||||
#define EFI_DEP_OR 0x04
|
||||
#define EFI_DEP_NOT 0x05
|
||||
#define EFI_DEP_TRUE 0x06
|
||||
#define EFI_DEP_FALSE 0x07
|
||||
#define EFI_DEP_END 0x08
|
||||
|
||||
|
||||
///
|
||||
/// If present, this must be the first opcode,
|
||||
/// EFI_DEP_SOR is only used by DXE driver.
|
||||
///
|
||||
#define EFI_DEP_SOR 0x09
|
||||
|
||||
//*****************************************************************************
|
||||
// UEFI Crypto-signed Stuff
|
||||
//*****************************************************************************
|
||||
|
||||
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||||
#define WIN_CERT_TYPE_EFI_GUID 0x0EF1
|
||||
|
||||
typedef struct _WIN_CERTIFICATE {
|
||||
UINT32 Length;
|
||||
UINT16 Revision;
|
||||
UINT16 CertificateType;
|
||||
//UINT8 CertData[];
|
||||
} WIN_CERTIFICATE;
|
||||
|
||||
typedef struct _WIN_CERTIFICATE_UEFI_GUID {
|
||||
WIN_CERTIFICATE Header; // Standard WIN_CERTIFICATE
|
||||
EFI_GUID CertType; // Determines format of CertData
|
||||
// UINT8 CertData[]; // Certificate data follows
|
||||
} WIN_CERTIFICATE_UEFI_GUID;
|
||||
|
||||
// WIN_CERTIFICATE_UEFI_GUID.CertType
|
||||
const QByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID
|
||||
("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF");
|
||||
const QByteArray EFI_CERT_TYPE_PKCS7_GUID
|
||||
("\x9D\xD2\xAF\x4A\xDF\x68\xEE\x49\x8A\xA9\x34\x7D\x37\x56\x65\xA7");
|
||||
|
||||
// WIN_CERTIFICATE_UEFI_GUID.CertData
|
||||
typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 {
|
||||
UINT32 HashType;
|
||||
UINT8 PublicKey[256];
|
||||
UINT8 Signature[256];
|
||||
} EFI_CERT_BLOCK_RSA_2048_SHA256;
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
13
common/ffsbuilder.cpp
Normal file
13
common/ffsbuilder.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* fssbuilder.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
17
common/ffsbuilder.h
Normal file
17
common/ffsbuilder.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* fssbuilder.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __FFSBUILDER_H__
|
||||
#define __FFSBUILDER_H__
|
||||
|
||||
#endif
|
2287
common/ffsparser.cpp
Normal file
2287
common/ffsparser.cpp
Normal file
File diff suppressed because it is too large
Load diff
102
common/ffsparser.h
Normal file
102
common/ffsparser.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/* ffsparser.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#ifndef __FFSPARSER_H__
|
||||
#define __FFSPARSER_H__
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QObject>
|
||||
#include <QModelIndex>
|
||||
#include <QByteArray>
|
||||
#include <QVector>
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "treemodel.h"
|
||||
#include "utility.h"
|
||||
#include "peimage.h"
|
||||
#include "parsingdata.h"
|
||||
|
||||
class TreeModel;
|
||||
|
||||
class FfsParser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Default constructor and destructor
|
||||
FfsParser(TreeModel* treeModel, QObject *parent = 0);
|
||||
~FfsParser();
|
||||
|
||||
// Returns messages
|
||||
QVector<QPair<QString, QModelIndex> > getMessages() const;
|
||||
// Clears messages
|
||||
void clearMessages();
|
||||
|
||||
// Firmware image parsing
|
||||
STATUS parseImageFile(const QByteArray & imageFile, const QModelIndex & index);
|
||||
STATUS parseRawArea(const QByteArray & data, const QModelIndex & index);
|
||||
STATUS parseVolumeHeader(const QByteArray & volume, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseVolumeBody(const QModelIndex & index);
|
||||
STATUS parseFileHeader(const QByteArray & file, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseFileBody(const QModelIndex & index);
|
||||
STATUS parseSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseSectionBody(const QModelIndex & index);
|
||||
|
||||
/*// Search routines TODO: move to another class
|
||||
// Extract routine TODO: move to another class
|
||||
STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode);*/
|
||||
|
||||
private:
|
||||
TreeModel *model;
|
||||
QVector<QPair<QString, QModelIndex> > messagesVector;
|
||||
|
||||
STATUS parseIntelImage(const QByteArray & intelImage, const QModelIndex & parent, QModelIndex & root = QModelIndex());
|
||||
STATUS parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseMeRegion(const QByteArray & me, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseBiosRegion(const QByteArray & bios, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parsePdrRegion(const QByteArray & pdr, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
|
||||
STATUS parsePadFileBody(const QModelIndex & index);
|
||||
STATUS parseSections(QByteArray sections, const QModelIndex & index);
|
||||
|
||||
STATUS parseCommonSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseFreeformGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parseVersionSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
STATUS parsePostcodeSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||
|
||||
STATUS parseCompressedSectionBody(const QModelIndex & index);
|
||||
STATUS parseGuidedSectionBody(const QModelIndex & index);
|
||||
STATUS parseVersionSectionBody(const QModelIndex & index);
|
||||
STATUS parseDepexSectionBody(const QModelIndex & index);
|
||||
STATUS parseUiSectionBody(const QModelIndex & index);
|
||||
STATUS parseRawSectionBody(const QModelIndex & index);
|
||||
|
||||
UINT8 getPaddingType(const QByteArray & padding);
|
||||
STATUS parseAprioriRawSection(const QByteArray & body, QString & parsed);
|
||||
STATUS findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
|
||||
STATUS getVolumeSize(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
|
||||
UINT32 getFileSize(const QByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
|
||||
UINT32 getSectionSize(const QByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
|
||||
|
||||
// Internal operations
|
||||
BOOLEAN hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2);
|
||||
|
||||
// Message helper
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
||||
|
||||
};
|
||||
|
||||
#endif
|
36
common/gbe.h
Normal file
36
common/gbe.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* gbe.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#ifndef __GBE_H__
|
||||
#define __GBE_H__
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
// Make sure we use right packing rules
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct _GBE_MAC_ADDRESS {
|
||||
UINT8 vendor[3];
|
||||
UINT8 device[3];
|
||||
} GBE_MAC_ADDRESS;
|
||||
|
||||
#define GBE_VERSION_OFFSET 10
|
||||
|
||||
typedef struct _GBE_VERSION {
|
||||
UINT8 id : 4;
|
||||
UINT8 minor : 4;
|
||||
UINT8 major;
|
||||
} GBE_VERSION;
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
#endif
|
35
common/me.h
Normal file
35
common/me.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* me.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#ifndef __ME_H__
|
||||
#define __ME_H__
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
// Make sure we use right packing rules
|
||||
#pragma pack(push,1)
|
||||
|
||||
const QByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN
|
||||
const QByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2
|
||||
|
||||
typedef struct _ME_VERSION {
|
||||
UINT32 signature;
|
||||
UINT32 reserved; // Unknown for me
|
||||
UINT16 major;
|
||||
UINT16 minor;
|
||||
UINT16 bugfix;
|
||||
UINT16 build;
|
||||
} ME_VERSION;
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
#endif
|
90
common/parsingdata.h
Normal file
90
common/parsingdata.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* ffsparser.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
|
||||
Parsing data is an information needed for each level of image reconstruction
|
||||
routines without the need of backward traversal
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __PARSINGDATA_H__
|
||||
#define __PARSINGDATA_H__
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
//typedef struct _CAPSULE_PARSING_DATA {
|
||||
//} CAPSULE_PARSING_DATA;
|
||||
|
||||
//typedef struct _IMAGE_PARSING_DATA {
|
||||
//} IMAGE_PARSING_DATA;
|
||||
|
||||
//typedef struct _PADDING_PARSING_DATA {
|
||||
//} PADDING_PARSING_DATA;
|
||||
|
||||
typedef struct _VOLUME_PARSING_DATA {
|
||||
EFI_GUID extendedHeaderGuid;
|
||||
UINT32 alignment;
|
||||
UINT8 revision;
|
||||
BOOLEAN hasExtendedHeader;
|
||||
BOOLEAN hasZeroVectorCRC32;
|
||||
BOOLEAN isWeakAligned;
|
||||
} VOLUME_PARSING_DATA;
|
||||
|
||||
//typedef struct _FREE_SPACE_PARSING_DATA {
|
||||
//} FREE_SPACE_PARSING_DATA;
|
||||
|
||||
typedef struct _FILE_PARSING_DATA {
|
||||
UINT16 tail;
|
||||
BOOLEAN hasTail;
|
||||
} FILE_PARSING_DATA;
|
||||
|
||||
typedef struct _COMPRESSED_SECTION_PARSING_DATA {
|
||||
UINT32 uncompressedSize;
|
||||
UINT8 compressionType;
|
||||
UINT8 algorithm;
|
||||
} COMPRESSED_SECTION_PARSING_DATA;
|
||||
|
||||
typedef struct _GUIDED_SECTION_PARSING_DATA {
|
||||
EFI_GUID guid;
|
||||
UINT32 attributes;
|
||||
} GUIDED_SECTION_PARSING_DATA;
|
||||
|
||||
typedef struct _FREEFORM_GUIDED_SECTION_PARSING_DATA {
|
||||
EFI_GUID guid;
|
||||
} FREEFORM_GUIDED_SECTION_PARSING_DATA;
|
||||
|
||||
typedef struct _SECTION_PARSING_DATA {
|
||||
union {
|
||||
COMPRESSED_SECTION_PARSING_DATA compressed;
|
||||
GUIDED_SECTION_PARSING_DATA guidDefined;
|
||||
FREEFORM_GUIDED_SECTION_PARSING_DATA freeformSubtypeGuid;
|
||||
};
|
||||
} SECTION_PARSING_DATA;
|
||||
|
||||
typedef struct _PARSING_DATA {
|
||||
BOOLEAN fixed;
|
||||
BOOLEAN isOnFlash;
|
||||
UINT8 emptyByte;
|
||||
UINT8 ffsVersion;
|
||||
UINT32 offset;
|
||||
UINT64 address;
|
||||
union {
|
||||
//CAPSULE_PARSING_DATA capsule;
|
||||
//IMAGE_PARSING_DATA image;
|
||||
//PADDING_PARSING_DATA padding;
|
||||
VOLUME_PARSING_DATA volume;
|
||||
//FREE_SPACE_PARSING_DATA freeSpace;
|
||||
FILE_PARSING_DATA file;
|
||||
SECTION_PARSING_DATA section;
|
||||
};
|
||||
} PARSING_DATA;
|
||||
|
||||
#endif
|
30
common/peimage.cpp
Normal file
30
common/peimage.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* peimage.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "peimage.h"
|
||||
|
||||
QString machineTypeToQString(UINT16 machineType)
|
||||
{
|
||||
switch (machineType){
|
||||
case IMAGE_FILE_MACHINE_AMD64: return QObject::tr("x86-64");
|
||||
case IMAGE_FILE_MACHINE_ARM: return QObject::tr("ARM");
|
||||
case IMAGE_FILE_MACHINE_ARMV7: return QObject::tr("ARMv7");
|
||||
case IMAGE_FILE_MACHINE_EBC: return QObject::tr("EBC");
|
||||
case IMAGE_FILE_MACHINE_I386: return QObject::tr("x86");
|
||||
case IMAGE_FILE_MACHINE_IA64: return QObject::tr("IA64");
|
||||
case IMAGE_FILE_MACHINE_THUMB: return QObject::tr("Thumb");
|
||||
default: return QObject::tr("Unknown %1h").hexarg2(machineType, 4);
|
||||
}
|
||||
}
|
724
common/peimage.h
Normal file
724
common/peimage.h
Normal file
|
@ -0,0 +1,724 @@
|
|||
/* peimage.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
|
||||
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __PE_IMAGE_H__
|
||||
#define __PE_IMAGE_H__
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
// Make sure we use right packing rules
|
||||
#pragma pack(push,1)
|
||||
|
||||
extern QString machineTypeToQString(UINT16 machineType);
|
||||
|
||||
//
|
||||
// PE32+ Subsystem type for EFI images
|
||||
//
|
||||
#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10
|
||||
#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
|
||||
#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
|
||||
#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13
|
||||
|
||||
//
|
||||
// PE32+ Machine type for EFI images
|
||||
//
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define IMAGE_FILE_MACHINE_ARM 0x01c0
|
||||
#define IMAGE_FILE_MACHINE_ARMV7 0x01c4
|
||||
#define IMAGE_FILE_MACHINE_EBC 0x0ebc
|
||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||
#define IMAGE_FILE_MACHINE_IA64 0x0200
|
||||
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
|
||||
|
||||
//
|
||||
// EXE file formats
|
||||
//
|
||||
#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ
|
||||
#define EFI_IMAGE_PE_SIGNATURE 0x00004550 // PE
|
||||
|
||||
//
|
||||
// PE images can start with an optional DOS header, so if an image is run
|
||||
// under DOS it can print an error message.
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 e_magic; // Magic number
|
||||
UINT16 e_cblp; // Bytes on last page of file
|
||||
UINT16 e_cp; // Pages in file
|
||||
UINT16 e_crlc; // Relocations
|
||||
UINT16 e_cparhdr; // Size of header in paragraphs
|
||||
UINT16 e_minalloc; // Minimum extra paragraphs needed
|
||||
UINT16 e_maxalloc; // Maximum extra paragraphs needed
|
||||
UINT16 e_ss; // Initial (relative) SS value
|
||||
UINT16 e_sp; // Initial SP value
|
||||
UINT16 e_csum; // Checksum
|
||||
UINT16 e_ip; // Initial IP value
|
||||
UINT16 e_cs; // Initial (relative) CS value
|
||||
UINT16 e_lfarlc; // File address of relocation table
|
||||
UINT16 e_ovno; // Overlay number
|
||||
UINT16 e_res[4]; // Reserved words
|
||||
UINT16 e_oemid; // OEM identifier (for e_oeminfo)
|
||||
UINT16 e_oeminfo; // OEM information; e_oemid specific
|
||||
UINT16 e_res2[10]; // Reserved words
|
||||
UINT32 e_lfanew; // File address of new header
|
||||
} EFI_IMAGE_DOS_HEADER;
|
||||
|
||||
//
|
||||
// COFF File Header (Object and Image)
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 Machine;
|
||||
UINT16 NumberOfSections;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT32 PointerToSymbolTable;
|
||||
UINT32 NumberOfSymbols;
|
||||
UINT16 SizeOfOptionalHeader;
|
||||
UINT16 Characteristics;
|
||||
} EFI_IMAGE_FILE_HEADER;
|
||||
|
||||
//
|
||||
// Size of EFI_IMAGE_FILE_HEADER.
|
||||
//
|
||||
#define EFI_IMAGE_SIZEOF_FILE_HEADER 20
|
||||
|
||||
//
|
||||
// Characteristics
|
||||
//
|
||||
#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file
|
||||
#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved external references)
|
||||
#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line numbers stripped from file
|
||||
#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file
|
||||
#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed
|
||||
#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine
|
||||
#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
|
||||
#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File
|
||||
#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL
|
||||
#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed
|
||||
|
||||
//
|
||||
// Header Data Directories.
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 Size;
|
||||
} EFI_IMAGE_DATA_DIRECTORY;
|
||||
|
||||
//
|
||||
// Directory Entries
|
||||
//
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9
|
||||
#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
|
||||
|
||||
#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
|
||||
|
||||
//
|
||||
// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and
|
||||
// EFI_IMAGE_OPTIONAL_HEADER32 must be used.
|
||||
// The data structures only vary after NT additional fields
|
||||
//
|
||||
#define EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC 0x10b
|
||||
|
||||
//
|
||||
// Optional Header Standard Fields for PE32
|
||||
//
|
||||
typedef struct {
|
||||
//
|
||||
// Standard fields.
|
||||
//
|
||||
UINT16 Magic;
|
||||
UINT8 MajorLinkerVersion;
|
||||
UINT8 MinorLinkerVersion;
|
||||
UINT32 SizeOfCode;
|
||||
UINT32 SizeOfInitializedData;
|
||||
UINT32 SizeOfUninitializedData;
|
||||
UINT32 AddressOfEntryPoint;
|
||||
UINT32 BaseOfCode;
|
||||
UINT32 BaseOfData; // PE32 contains this additional field, which is absent in PE32+.
|
||||
//
|
||||
// Optional Header Windows-Specific Fields.
|
||||
//
|
||||
UINT32 ImageBase;
|
||||
UINT32 SectionAlignment;
|
||||
UINT32 FileAlignment;
|
||||
UINT16 MajorOperatingSystemVersion;
|
||||
UINT16 MinorOperatingSystemVersion;
|
||||
UINT16 MajorImageVersion;
|
||||
UINT16 MinorImageVersion;
|
||||
UINT16 MajorSubsystemVersion;
|
||||
UINT16 MinorSubsystemVersion;
|
||||
UINT32 Win32VersionValue;
|
||||
UINT32 SizeOfImage;
|
||||
UINT32 SizeOfHeaders;
|
||||
UINT32 CheckSum;
|
||||
UINT16 Subsystem;
|
||||
UINT16 DllCharacteristics;
|
||||
UINT32 SizeOfStackReserve;
|
||||
UINT32 SizeOfStackCommit;
|
||||
UINT32 SizeOfHeapReserve;
|
||||
UINT32 SizeOfHeapCommit;
|
||||
UINT32 LoaderFlags;
|
||||
UINT32 NumberOfRvaAndSizes;
|
||||
EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
|
||||
} EFI_IMAGE_OPTIONAL_HEADER32;
|
||||
|
||||
//
|
||||
// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and
|
||||
// EFI_IMAGE_OPTIONAL_HEADER64 must be used.
|
||||
// The data structures only vary after NT additional fields
|
||||
//
|
||||
#define EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC 0x20b
|
||||
|
||||
//
|
||||
// Optional Header Standard Fields for PE32+.
|
||||
//
|
||||
typedef struct {
|
||||
//
|
||||
// Standard fields.
|
||||
//
|
||||
UINT16 Magic;
|
||||
UINT8 MajorLinkerVersion;
|
||||
UINT8 MinorLinkerVersion;
|
||||
UINT32 SizeOfCode;
|
||||
UINT32 SizeOfInitializedData;
|
||||
UINT32 SizeOfUninitializedData;
|
||||
UINT32 AddressOfEntryPoint;
|
||||
UINT32 BaseOfCode;
|
||||
//
|
||||
// Optional Header Windows-Specific Fields.
|
||||
//
|
||||
UINT64 ImageBase;
|
||||
UINT32 SectionAlignment;
|
||||
UINT32 FileAlignment;
|
||||
UINT16 MajorOperatingSystemVersion;
|
||||
UINT16 MinorOperatingSystemVersion;
|
||||
UINT16 MajorImageVersion;
|
||||
UINT16 MinorImageVersion;
|
||||
UINT16 MajorSubsystemVersion;
|
||||
UINT16 MinorSubsystemVersion;
|
||||
UINT32 Win32VersionValue;
|
||||
UINT32 SizeOfImage;
|
||||
UINT32 SizeOfHeaders;
|
||||
UINT32 CheckSum;
|
||||
UINT16 Subsystem;
|
||||
UINT16 DllCharacteristics;
|
||||
UINT64 SizeOfStackReserve;
|
||||
UINT64 SizeOfStackCommit;
|
||||
UINT64 SizeOfHeapReserve;
|
||||
UINT64 SizeOfHeapCommit;
|
||||
UINT32 LoaderFlags;
|
||||
UINT32 NumberOfRvaAndSizes;
|
||||
EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
|
||||
} EFI_IMAGE_OPTIONAL_HEADER64;
|
||||
|
||||
// Union for pointers to either PE32 or PE32+ headers
|
||||
typedef union _EFI_IMAGE_OPTIONAL_HEADER_POINTERS_UNION {
|
||||
const EFI_IMAGE_OPTIONAL_HEADER32* H32;
|
||||
const EFI_IMAGE_OPTIONAL_HEADER64* H64;
|
||||
} EFI_IMAGE_OPTIONAL_HEADER_POINTERS_UNION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 Signature;
|
||||
//EFI_IMAGE_FILE_HEADER FileHeader;
|
||||
//EFI_IMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||
} EFI_IMAGE_PE_HEADER;
|
||||
|
||||
//
|
||||
// Other Windows Subsystem Values
|
||||
//
|
||||
#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0
|
||||
#define EFI_IMAGE_SUBSYSTEM_NATIVE 1
|
||||
#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2
|
||||
#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3
|
||||
#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5
|
||||
#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7
|
||||
|
||||
//
|
||||
// Length of ShortName
|
||||
//
|
||||
#define EFI_IMAGE_SIZEOF_SHORT_NAME 8
|
||||
|
||||
//
|
||||
// Section Table. This table immediately follows the optional header.
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];
|
||||
union {
|
||||
UINT32 PhysicalAddress;
|
||||
UINT32 VirtualSize;
|
||||
} Misc;
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 SizeOfRawData;
|
||||
UINT32 PointerToRawData;
|
||||
UINT32 PointerToRelocations;
|
||||
UINT32 PointerToLinenumbers;
|
||||
UINT16 NumberOfRelocations;
|
||||
UINT16 NumberOfLinenumbers;
|
||||
UINT32 Characteristics;
|
||||
} EFI_IMAGE_SECTION_HEADER;
|
||||
|
||||
//
|
||||
// Size of EFI_IMAGE_SECTION_HEADER
|
||||
//
|
||||
#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40
|
||||
|
||||
//
|
||||
// Section Flags Values
|
||||
//
|
||||
#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved
|
||||
#define EFI_IMAGE_SCN_CNT_CODE 0x00000020
|
||||
#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
|
||||
#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
|
||||
|
||||
#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved
|
||||
#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information
|
||||
#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image
|
||||
#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000
|
||||
|
||||
#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000
|
||||
#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000
|
||||
#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000
|
||||
#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000
|
||||
#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000
|
||||
#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000
|
||||
#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000
|
||||
|
||||
#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000
|
||||
#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000
|
||||
#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000
|
||||
#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000
|
||||
#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||
#define EFI_IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
|
||||
//
|
||||
// Size of a Symbol Table Record
|
||||
//
|
||||
#define EFI_IMAGE_SIZEOF_SYMBOL 18
|
||||
|
||||
//
|
||||
// Symbols have a section number of the section in which they are
|
||||
// defined. Otherwise, section numbers have the following meanings:
|
||||
//
|
||||
#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 ///< Symbol is undefined or is common
|
||||
#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 ///< Symbol is an absolute value
|
||||
#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 ///< Symbol is a special debug item
|
||||
|
||||
//
|
||||
// Symbol Type (fundamental) values.
|
||||
//
|
||||
#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type
|
||||
#define EFI_IMAGE_SYM_TYPE_VOID 1 // no valid type
|
||||
#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character
|
||||
#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer
|
||||
#define EFI_IMAGE_SYM_TYPE_INT 4
|
||||
#define EFI_IMAGE_SYM_TYPE_LONG 5
|
||||
#define EFI_IMAGE_SYM_TYPE_FLOAT 6
|
||||
#define EFI_IMAGE_SYM_TYPE_DOUBLE 7
|
||||
#define EFI_IMAGE_SYM_TYPE_STRUCT 8
|
||||
#define EFI_IMAGE_SYM_TYPE_UNION 9
|
||||
#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration
|
||||
#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration
|
||||
#define EFI_IMAGE_SYM_TYPE_BYTE 12
|
||||
#define EFI_IMAGE_SYM_TYPE_WORD 13
|
||||
#define EFI_IMAGE_SYM_TYPE_UINT 14
|
||||
#define EFI_IMAGE_SYM_TYPE_DWORD 15
|
||||
|
||||
//
|
||||
// Symbol Type (derived) values
|
||||
//
|
||||
#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type
|
||||
#define EFI_IMAGE_SYM_DTYPE_POINTER 1
|
||||
#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2
|
||||
#define EFI_IMAGE_SYM_DTYPE_ARRAY 3
|
||||
|
||||
//
|
||||
// Storage classes
|
||||
//
|
||||
#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION ((UINT8) -1)
|
||||
#define EFI_IMAGE_SYM_CLASS_NULL 0
|
||||
#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1
|
||||
#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2
|
||||
#define EFI_IMAGE_SYM_CLASS_STATIC 3
|
||||
#define EFI_IMAGE_SYM_CLASS_REGISTER 4
|
||||
#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5
|
||||
#define EFI_IMAGE_SYM_CLASS_LABEL 6
|
||||
#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
|
||||
#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
|
||||
#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9
|
||||
#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10
|
||||
#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
|
||||
#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12
|
||||
#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13
|
||||
#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
|
||||
#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15
|
||||
#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
|
||||
#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17
|
||||
#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18
|
||||
#define EFI_IMAGE_SYM_CLASS_BLOCK 100
|
||||
#define EFI_IMAGE_SYM_CLASS_FUNCTION 101
|
||||
#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102
|
||||
#define EFI_IMAGE_SYM_CLASS_FILE 103
|
||||
#define EFI_IMAGE_SYM_CLASS_SECTION 104
|
||||
#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
|
||||
|
||||
//
|
||||
// Type packing constants
|
||||
//
|
||||
#define EFI_IMAGE_N_BTMASK 017
|
||||
#define EFI_IMAGE_N_TMASK 060
|
||||
#define EFI_IMAGE_N_TMASK1 0300
|
||||
#define EFI_IMAGE_N_TMASK2 0360
|
||||
#define EFI_IMAGE_N_BTSHFT 4
|
||||
#define EFI_IMAGE_N_TSHIFT 2
|
||||
|
||||
//
|
||||
// Communal selection types
|
||||
//
|
||||
#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1
|
||||
#define EFI_IMAGE_COMDAT_SELECT_ANY 2
|
||||
#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3
|
||||
#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4
|
||||
#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
|
||||
|
||||
//
|
||||
// The following values only be referred in PeCoff, not defined in PECOFF
|
||||
//
|
||||
#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
|
||||
#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
|
||||
#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
|
||||
|
||||
//
|
||||
// Relocation format
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 SymbolTableIndex;
|
||||
UINT16 Type;
|
||||
} EFI_IMAGE_RELOCATION;
|
||||
|
||||
//
|
||||
// Size of EFI_IMAGE_RELOCATION
|
||||
//
|
||||
#define EFI_IMAGE_SIZEOF_RELOCATION 10
|
||||
|
||||
//
|
||||
// I386 relocation types
|
||||
//
|
||||
#define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000 // Reference is absolute, no relocation is necessary
|
||||
#define EFI_IMAGE_REL_I386_DIR16 0x0001 // Direct 16-bit reference to the symbols virtual address
|
||||
#define EFI_IMAGE_REL_I386_REL16 0x0002 // PC-relative 16-bit reference to the symbols virtual address
|
||||
#define EFI_IMAGE_REL_I386_DIR32 0x0006 // Direct 32-bit reference to the symbols virtual address
|
||||
#define EFI_IMAGE_REL_I386_DIR32NB 0x0007 // Direct 32-bit reference to the symbols virtual address, base not included
|
||||
#define EFI_IMAGE_REL_I386_SEG12 0x0009 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
|
||||
#define EFI_IMAGE_REL_I386_SECTION 0x000A
|
||||
#define EFI_IMAGE_REL_I386_SECREL 0x000B
|
||||
#define EFI_IMAGE_REL_I386_REL32 0x0014 // PC-relative 32-bit reference to the symbols virtual address
|
||||
|
||||
//
|
||||
// x64 processor relocation types.
|
||||
//
|
||||
#define IMAGE_REL_AMD64_ABSOLUTE 0x0000
|
||||
#define IMAGE_REL_AMD64_ADDR64 0x0001
|
||||
#define IMAGE_REL_AMD64_ADDR32 0x0002
|
||||
#define IMAGE_REL_AMD64_ADDR32NB 0x0003
|
||||
#define IMAGE_REL_AMD64_REL32 0x0004
|
||||
#define IMAGE_REL_AMD64_REL32_1 0x0005
|
||||
#define IMAGE_REL_AMD64_REL32_2 0x0006
|
||||
#define IMAGE_REL_AMD64_REL32_3 0x0007
|
||||
#define IMAGE_REL_AMD64_REL32_4 0x0008
|
||||
#define IMAGE_REL_AMD64_REL32_5 0x0009
|
||||
#define IMAGE_REL_AMD64_SECTION 0x000A
|
||||
#define IMAGE_REL_AMD64_SECREL 0x000B
|
||||
#define IMAGE_REL_AMD64_SECREL7 0x000C
|
||||
#define IMAGE_REL_AMD64_TOKEN 0x000D
|
||||
#define IMAGE_REL_AMD64_SREL32 0x000E
|
||||
#define IMAGE_REL_AMD64_PAIR 0x000F
|
||||
#define IMAGE_REL_AMD64_SSPAN32 0x0010
|
||||
|
||||
//
|
||||
// Based relocation format
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 SizeOfBlock;
|
||||
} EFI_IMAGE_BASE_RELOCATION;
|
||||
|
||||
//
|
||||
// Size of EFI_IMAGE_BASE_RELOCATION
|
||||
//
|
||||
#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8
|
||||
|
||||
//
|
||||
// Based relocation types
|
||||
//
|
||||
#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
|
||||
#define EFI_IMAGE_REL_BASED_HIGH 1
|
||||
#define EFI_IMAGE_REL_BASED_LOW 2
|
||||
#define EFI_IMAGE_REL_BASED_HIGHLOW 3
|
||||
#define EFI_IMAGE_REL_BASED_HIGHADJ 4
|
||||
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
|
||||
#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
|
||||
#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
|
||||
#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
|
||||
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9
|
||||
#define EFI_IMAGE_REL_BASED_DIR64 10
|
||||
|
||||
//
|
||||
// Line number format
|
||||
//
|
||||
typedef struct {
|
||||
union {
|
||||
UINT32 SymbolTableIndex; // Symbol table index of function name if line number is 0
|
||||
UINT32 VirtualAddress; // Virtual address of line number
|
||||
} Type;
|
||||
UINT16 Linenumber; // Line number
|
||||
} EFI_IMAGE_LINENUMBER;
|
||||
|
||||
//
|
||||
// Size of EFI_IMAGE_LINENUMBER
|
||||
//
|
||||
#define EFI_IMAGE_SIZEOF_LINENUMBER 6
|
||||
|
||||
//
|
||||
// Archive format
|
||||
//
|
||||
#define EFI_IMAGE_ARCHIVE_START_SIZE 8
|
||||
#define EFI_IMAGE_ARCHIVE_START "!<arch>\n"
|
||||
#define EFI_IMAGE_ARCHIVE_END "`\n"
|
||||
#define EFI_IMAGE_ARCHIVE_PAD "\n"
|
||||
#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ "
|
||||
#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
|
||||
|
||||
//
|
||||
// Archive Member Headers
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 Name[16]; // File member name - `/' terminated
|
||||
UINT8 Date[12]; // File member date - decimal
|
||||
UINT8 UserID[6]; // File member user id - decimal
|
||||
UINT8 GroupID[6]; // File member group id - decimal
|
||||
UINT8 Mode[8]; // File member mode - octal
|
||||
UINT8 Size[10]; // File member size - decimal
|
||||
UINT8 EndHeader[2]; // String to end header. (0x60 0x0A)
|
||||
} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;
|
||||
|
||||
//
|
||||
// Size of EFI_IMAGE_ARCHIVE_MEMBER_HEADER
|
||||
//
|
||||
#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
|
||||
|
||||
//
|
||||
// DLL Support
|
||||
//
|
||||
|
||||
//
|
||||
// Export Directory Table
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Characteristics;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT16 MajorVersion;
|
||||
UINT16 MinorVersion;
|
||||
UINT32 Name;
|
||||
UINT32 Base;
|
||||
UINT32 NumberOfFunctions;
|
||||
UINT32 NumberOfNames;
|
||||
UINT32 AddressOfFunctions;
|
||||
UINT32 AddressOfNames;
|
||||
UINT32 AddressOfNameOrdinals;
|
||||
} EFI_IMAGE_EXPORT_DIRECTORY;
|
||||
|
||||
//
|
||||
// Hint/Name Table
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 Hint;
|
||||
UINT8 Name[1];
|
||||
} EFI_IMAGE_IMPORT_BY_NAME;
|
||||
|
||||
//
|
||||
// Import Address Table RVA (Thunk Table)
|
||||
//
|
||||
typedef struct {
|
||||
union {
|
||||
UINT32 Function;
|
||||
UINT32 Ordinal;
|
||||
EFI_IMAGE_IMPORT_BY_NAME *AddressOfData;
|
||||
} u1;
|
||||
} EFI_IMAGE_THUNK_DATA;
|
||||
|
||||
#define EFI_IMAGE_ORDINAL_FLAG 0x80000000 // Flag for PE32.
|
||||
#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)
|
||||
#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
|
||||
|
||||
//
|
||||
// Import Directory Table
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Characteristics;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT32 ForwarderChain;
|
||||
UINT32 Name;
|
||||
EFI_IMAGE_THUNK_DATA *FirstThunk;
|
||||
} EFI_IMAGE_IMPORT_DESCRIPTOR;
|
||||
|
||||
//
|
||||
// Debug Directory Format
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Characteristics;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT16 MajorVersion;
|
||||
UINT16 MinorVersion;
|
||||
UINT32 Type;
|
||||
UINT32 SizeOfData;
|
||||
UINT32 RVA; // The address of the debug data when loaded, relative to the image base
|
||||
UINT32 FileOffset; // The file pointer to the debug data
|
||||
} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
|
||||
|
||||
#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 // The Visual C++ debug information.
|
||||
|
||||
//
|
||||
// Debug Data Structure defined in Microsoft C++
|
||||
//
|
||||
#define CODEVIEW_SIGNATURE_NB10 0x3031424E // NB10
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT32 Unknown;
|
||||
UINT32 Unknown2;
|
||||
UINT32 Unknown3;
|
||||
//
|
||||
// Filename of .PDB goes here
|
||||
//
|
||||
} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
|
||||
|
||||
//
|
||||
// Debug Data Structure defined in Microsoft C++
|
||||
//
|
||||
#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // RSDS
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT32 Unknown;
|
||||
UINT32 Unknown2;
|
||||
UINT32 Unknown3;
|
||||
UINT32 Unknown4;
|
||||
UINT32 Unknown5;
|
||||
//
|
||||
// Filename of .PDB goes here
|
||||
//
|
||||
} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
|
||||
|
||||
//
|
||||
// Debug Data Structure defined by Apple Mach-O to COFF utility.
|
||||
//
|
||||
#define CODEVIEW_SIGNATURE_MTOC 0x434F544D // MTOC
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT8 MachOUuid[16];
|
||||
//
|
||||
// Filename of .DLL (Mach-O with debug info) goes here
|
||||
//
|
||||
} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;
|
||||
|
||||
//
|
||||
// Resource format
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Characteristics;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT16 MajorVersion;
|
||||
UINT16 MinorVersion;
|
||||
UINT16 NumberOfNamedEntries;
|
||||
UINT16 NumberOfIdEntries;
|
||||
//
|
||||
// Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here
|
||||
//
|
||||
} EFI_IMAGE_RESOURCE_DIRECTORY;
|
||||
|
||||
//
|
||||
// Resource directory entry format
|
||||
//
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
UINT32 NameOffset : 31;
|
||||
UINT32 NameIsString : 1;
|
||||
} s;
|
||||
UINT32 Id;
|
||||
} u1;
|
||||
union {
|
||||
UINT32 OffsetToData;
|
||||
struct {
|
||||
UINT32 OffsetToDirectory : 31;
|
||||
UINT32 DataIsDirectory : 1;
|
||||
} s;
|
||||
} u2;
|
||||
} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
|
||||
//
|
||||
// Resource directory entry for string
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 Length;
|
||||
CHAR16 String[1];
|
||||
} EFI_IMAGE_RESOURCE_DIRECTORY_STRING;
|
||||
|
||||
//
|
||||
// Resource directory entry for data array
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 OffsetToData;
|
||||
UINT32 Size;
|
||||
UINT32 CodePage;
|
||||
UINT32 Reserved;
|
||||
} EFI_IMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
//
|
||||
// Header format for TE images, defined in the PI Specification 1.0.
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 Signature; // The signature for TE format = "VZ"
|
||||
UINT16 Machine; // From original file header
|
||||
UINT8 NumberOfSections; // From original file header
|
||||
UINT8 Subsystem; // From original optional header
|
||||
UINT16 StrippedSize; // Number of bytes we removed from header
|
||||
UINT32 AddressOfEntryPoint; // Offset to entry point -- from original optional header
|
||||
UINT32 BaseOfCode; // From original image -- required for ITP debug
|
||||
UINT64 ImageBase; // From original file header
|
||||
EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // Only base relocation and debug directory
|
||||
} EFI_IMAGE_TE_HEADER;
|
||||
|
||||
#define EFI_IMAGE_TE_SIGNATURE 0x5A56 // VZ
|
||||
|
||||
//
|
||||
// Data directory indexes in our TE image header
|
||||
//
|
||||
#define EFI_IMAGE_TE_DIRECTORY_ENTRY_BASERELOC 0
|
||||
#define EFI_IMAGE_TE_DIRECTORY_ENTRY_DEBUG 1
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
#endif
|
224
common/treeitem.cpp
Normal file
224
common/treeitem.cpp
Normal file
|
@ -0,0 +1,224 @@
|
|||
/* treeitem.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
#include "treeitem.h"
|
||||
#include "types.h"
|
||||
|
||||
TreeItem::TreeItem(const UINT8 type, const UINT8 subtype,
|
||||
const QString & name, const QString & text, const QString & info,
|
||||
const QByteArray & header, const QByteArray & body, const QByteArray & parsingData,
|
||||
TreeItem *parent) :
|
||||
itemAction(Actions::NoAction),
|
||||
itemType(type),
|
||||
itemSubtype(subtype),
|
||||
itemName(name),
|
||||
itemText(text),
|
||||
itemInfo(info),
|
||||
itemHeader(header),
|
||||
itemBody(body),
|
||||
itemParsingData(parsingData),
|
||||
parentItem(parent)
|
||||
{
|
||||
}
|
||||
|
||||
TreeItem::~TreeItem()
|
||||
{
|
||||
qDeleteAll(childItems);
|
||||
}
|
||||
|
||||
void TreeItem::appendChild(TreeItem *item)
|
||||
{
|
||||
childItems.append(item);
|
||||
}
|
||||
|
||||
void TreeItem::prependChild(TreeItem *item)
|
||||
{
|
||||
childItems.prepend(item);
|
||||
}
|
||||
|
||||
UINT8 TreeItem::insertChildBefore(TreeItem *item, TreeItem *newItem)
|
||||
{
|
||||
int index = childItems.indexOf(item);
|
||||
if (index == -1)
|
||||
return ERR_ITEM_NOT_FOUND;
|
||||
childItems.insert(index, newItem);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT8 TreeItem::insertChildAfter(TreeItem *item, TreeItem *newItem)
|
||||
{
|
||||
int index = childItems.indexOf(item);
|
||||
if (index == -1)
|
||||
return ERR_ITEM_NOT_FOUND;
|
||||
childItems.insert(index + 1, newItem);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::child(int row)
|
||||
{
|
||||
return childItems.value(row, NULL);
|
||||
}
|
||||
|
||||
int TreeItem::childCount() const
|
||||
{
|
||||
return childItems.count();
|
||||
}
|
||||
|
||||
int TreeItem::columnCount() const
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
QVariant TreeItem::data(int column) const
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0: // Name
|
||||
return itemName;
|
||||
case 1: // Action
|
||||
return actionTypeToQString(itemAction);
|
||||
case 2: // Type
|
||||
return itemTypeToQString(itemType);
|
||||
case 3: // Subtype
|
||||
return itemSubtypeToQString(itemType, itemSubtype);
|
||||
case 4: // Text
|
||||
return itemText;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::parent()
|
||||
{
|
||||
return parentItem;
|
||||
}
|
||||
|
||||
QString TreeItem::name() const
|
||||
{
|
||||
return itemName;
|
||||
}
|
||||
|
||||
void TreeItem::setName(const QString &name)
|
||||
{
|
||||
itemName = name;
|
||||
}
|
||||
|
||||
QString TreeItem::text() const
|
||||
{
|
||||
return itemText;
|
||||
}
|
||||
|
||||
void TreeItem::setText(const QString &text)
|
||||
{
|
||||
itemText = text;
|
||||
}
|
||||
|
||||
QString TreeItem::info() const
|
||||
{
|
||||
return itemInfo;
|
||||
}
|
||||
|
||||
void TreeItem::addInfo(const QString &info)
|
||||
{
|
||||
itemInfo += info;
|
||||
}
|
||||
|
||||
void TreeItem::setInfo(const QString &info)
|
||||
{
|
||||
itemInfo = info;
|
||||
}
|
||||
|
||||
int TreeItem::row() const
|
||||
{
|
||||
if (parentItem)
|
||||
return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT8 TreeItem::type() const
|
||||
{
|
||||
return itemType;
|
||||
}
|
||||
|
||||
void TreeItem::setType(const UINT8 type)
|
||||
{
|
||||
itemType = type;
|
||||
}
|
||||
|
||||
UINT8 TreeItem::subtype() const
|
||||
{
|
||||
return itemSubtype;
|
||||
}
|
||||
|
||||
void TreeItem::setSubtype(const UINT8 subtype)
|
||||
{
|
||||
itemSubtype = subtype;
|
||||
}
|
||||
|
||||
QByteArray TreeItem::header() const
|
||||
{
|
||||
return itemHeader;
|
||||
}
|
||||
|
||||
QByteArray TreeItem::body() const
|
||||
{
|
||||
return itemBody;
|
||||
}
|
||||
|
||||
QByteArray TreeItem::parsingData() const
|
||||
{
|
||||
return itemParsingData;
|
||||
}
|
||||
|
||||
bool TreeItem::hasEmptyHeader() const
|
||||
{
|
||||
return itemHeader.isEmpty();
|
||||
}
|
||||
|
||||
bool TreeItem::hasEmptyBody() const
|
||||
{
|
||||
return itemBody.isEmpty();
|
||||
}
|
||||
|
||||
bool TreeItem::hasEmptyParsingData() const
|
||||
{
|
||||
return itemParsingData.isEmpty();
|
||||
}
|
||||
|
||||
void TreeItem::setParsingData(const QByteArray & data)
|
||||
{
|
||||
itemParsingData = data;
|
||||
}
|
||||
|
||||
UINT8 TreeItem::action() const
|
||||
{
|
||||
return itemAction;
|
||||
}
|
||||
|
||||
void TreeItem::setAction(const UINT8 action)
|
||||
{
|
||||
itemAction = action;
|
||||
|
||||
// On insert action, set insert action for children
|
||||
if (action == Actions::Insert)
|
||||
for (int i = 0; i < childCount(); i++)
|
||||
child(i)->setAction(Actions::Insert);
|
||||
|
||||
// Set rebuild action for parent, if it has no action now
|
||||
if (parentItem && parentItem->type() != Types::Root
|
||||
&& parentItem->action() == Actions::NoAction)
|
||||
parentItem->setAction(Actions::Rebuild);
|
||||
}
|
||||
|
90
common/treeitem.h
Normal file
90
common/treeitem.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* treeitem.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __TREEITEM_H__
|
||||
#define __TREEITEM_H__
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
class TreeItem
|
||||
{
|
||||
public:
|
||||
TreeItem(const UINT8 type, const UINT8 subtype = 0, const QString &name = QString(), const QString &text = QString(), const QString &info = QString(),
|
||||
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & parsingData = QByteArray(),
|
||||
TreeItem *parent = 0);
|
||||
~TreeItem();
|
||||
|
||||
// Operations with items
|
||||
void appendChild(TreeItem *item);
|
||||
void prependChild(TreeItem *item);
|
||||
UINT8 insertChildBefore(TreeItem *item, TreeItem *newItem);
|
||||
UINT8 insertChildAfter(TreeItem *item, TreeItem *newItem);
|
||||
|
||||
// Model support operations
|
||||
TreeItem *child(int row);
|
||||
int childCount() const;
|
||||
int columnCount() const;
|
||||
QVariant data(int column) const;
|
||||
int row() const;
|
||||
TreeItem *parent();
|
||||
|
||||
// Reading operations for item parameters
|
||||
QString name() const;
|
||||
void setName(const QString &text);
|
||||
|
||||
UINT8 type() const;
|
||||
void setType(const UINT8 type);
|
||||
|
||||
UINT8 subtype() const;
|
||||
void setSubtype(const UINT8 subtype);
|
||||
|
||||
QString text() const;
|
||||
void setText(const QString &text);
|
||||
|
||||
QByteArray header() const;
|
||||
bool hasEmptyHeader() const;
|
||||
|
||||
QByteArray body() const;
|
||||
bool hasEmptyBody() const;
|
||||
|
||||
QByteArray parsingData() const;
|
||||
bool hasEmptyParsingData() const;
|
||||
void setParsingData(const QByteArray & data);
|
||||
|
||||
QString info() const;
|
||||
void addInfo(const QString &info);
|
||||
void setInfo(const QString &info);
|
||||
|
||||
UINT8 action() const;
|
||||
void setAction(const UINT8 action);
|
||||
|
||||
private:
|
||||
QList<TreeItem*> childItems;
|
||||
UINT8 itemAction;
|
||||
UINT8 itemType;
|
||||
UINT8 itemSubtype;
|
||||
QString itemName;
|
||||
QString itemText;
|
||||
QString itemInfo;
|
||||
QByteArray itemHeader;
|
||||
QByteArray itemBody;
|
||||
QByteArray itemParsingData;
|
||||
TreeItem *parentItem;
|
||||
};
|
||||
|
||||
#endif
|
376
common/treemodel.cpp
Normal file
376
common/treemodel.cpp
Normal file
|
@ -0,0 +1,376 @@
|
|||
/* treemodel.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#include "treeitem.h"
|
||||
#include "treemodel.h"
|
||||
|
||||
TreeModel::TreeModel(QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
rootItem = new TreeItem(Types::Root);
|
||||
}
|
||||
|
||||
TreeModel::~TreeModel()
|
||||
{
|
||||
delete rootItem;
|
||||
}
|
||||
|
||||
int TreeModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
|
||||
else
|
||||
return rootItem->columnCount();
|
||||
}
|
||||
|
||||
QVariant TreeModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role != Qt::DisplayRole && role != Qt::UserRole)
|
||||
return QVariant();
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
return item->data(index.column());
|
||||
else
|
||||
return item->info();
|
||||
}
|
||||
|
||||
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
switch (section)
|
||||
{
|
||||
case 0:
|
||||
return tr("Name");
|
||||
case 1:
|
||||
return tr("Action");
|
||||
case 2:
|
||||
return tr("Type");
|
||||
case 3:
|
||||
return tr("Subtype");
|
||||
case 4:
|
||||
return tr("Text");
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
|
||||
const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = rootItem;
|
||||
else
|
||||
parentItem = static_cast<TreeItem*>(parent.internalPointer());
|
||||
|
||||
TreeItem *childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
return createIndex(row, column, childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
|
||||
if (childItem == rootItem)
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *parentItem = childItem->parent();
|
||||
|
||||
if (parentItem == rootItem)
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
|
||||
int TreeModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
TreeItem *parentItem;
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = rootItem;
|
||||
else
|
||||
parentItem = static_cast<TreeItem*>(parent.internalPointer());
|
||||
|
||||
return parentItem->childCount();
|
||||
}
|
||||
|
||||
UINT8 TreeModel::type(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->type();
|
||||
}
|
||||
|
||||
UINT8 TreeModel::subtype(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->subtype();
|
||||
}
|
||||
|
||||
QByteArray TreeModel::header(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QByteArray();
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->header();
|
||||
}
|
||||
|
||||
bool TreeModel::hasEmptyHeader(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return true;
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->hasEmptyHeader();
|
||||
}
|
||||
|
||||
QByteArray TreeModel::body(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QByteArray();
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->body();
|
||||
}
|
||||
|
||||
bool TreeModel::hasEmptyBody(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return true;
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->hasEmptyBody();
|
||||
}
|
||||
|
||||
QByteArray TreeModel::parsingData(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QByteArray();
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->parsingData();
|
||||
}
|
||||
|
||||
bool TreeModel::hasEmptyParsingData(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return true;
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->hasEmptyParsingData();
|
||||
}
|
||||
|
||||
QString TreeModel::name(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QString();
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->name();
|
||||
}
|
||||
|
||||
QString TreeModel::text(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QString();
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->text();
|
||||
}
|
||||
|
||||
QString TreeModel::info(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QString();
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->info();
|
||||
}
|
||||
|
||||
UINT8 TreeModel::action(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Actions::NoAction;
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
return item->action();
|
||||
}
|
||||
|
||||
void TreeModel::setSubtype(const QModelIndex & index, const UINT8 subtype)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
item->setSubtype(subtype);
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
void TreeModel::setName(const QModelIndex &index, const QString &data)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
item->setName(data);
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
void TreeModel::setType(const QModelIndex &index, const UINT8 data)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
item->setType(data);
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
void TreeModel::setText(const QModelIndex &index, const QString &data)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
item->setText(data);
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
void TreeModel::setInfo(const QModelIndex &index, const QString &data)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
item->setInfo(data);
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
void TreeModel::addInfo(const QModelIndex &index, const QString &data)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
item->addInfo(data);
|
||||
emit dataChanged(index, index);
|
||||
}
|
||||
|
||||
void TreeModel::setAction(const QModelIndex &index, const UINT8 action)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
item->setAction(action);
|
||||
emit dataChanged(this->index(0, 0), index);
|
||||
}
|
||||
|
||||
void TreeModel::setParsingData(const QModelIndex &index, const QByteArray &data)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
item->setParsingData(data);
|
||||
emit dataChanged(this->index(0, 0), index);
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype,
|
||||
const QString & name, const QString & text, const QString & info,
|
||||
const QByteArray & header, const QByteArray & body, const QByteArray & parsingData,
|
||||
const QModelIndex & parent, const UINT8 mode)
|
||||
{
|
||||
TreeItem *item = 0;
|
||||
TreeItem *parentItem = 0;
|
||||
int parentColumn = 0;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = rootItem;
|
||||
else
|
||||
{
|
||||
if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER) {
|
||||
item = static_cast<TreeItem*>(parent.internalPointer());
|
||||
parentItem = item->parent();
|
||||
parentColumn = parent.parent().column();
|
||||
}
|
||||
else {
|
||||
parentItem = static_cast<TreeItem*>(parent.internalPointer());
|
||||
parentColumn = parent.column();
|
||||
}
|
||||
}
|
||||
|
||||
TreeItem *newItem = new TreeItem(type, subtype, name, text, info, header, body, parsingData, parentItem);
|
||||
if (mode == CREATE_MODE_APPEND) {
|
||||
emit layoutAboutToBeChanged();
|
||||
parentItem->appendChild(newItem);
|
||||
}
|
||||
else if (mode == CREATE_MODE_PREPEND) {
|
||||
emit layoutAboutToBeChanged();
|
||||
parentItem->prependChild(newItem);
|
||||
}
|
||||
else if (mode == CREATE_MODE_BEFORE) {
|
||||
emit layoutAboutToBeChanged();
|
||||
parentItem->insertChildBefore(item, newItem);
|
||||
}
|
||||
else if (mode == CREATE_MODE_AFTER) {
|
||||
emit layoutAboutToBeChanged();
|
||||
parentItem->insertChildAfter(item, newItem);
|
||||
}
|
||||
else {
|
||||
delete newItem;
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
emit layoutChanged();
|
||||
|
||||
return createIndex(newItem->row(), parentColumn, newItem);
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::findParentOfType(const QModelIndex& index, UINT8 type) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *item;
|
||||
QModelIndex parent = index;
|
||||
|
||||
for (item = static_cast<TreeItem*>(parent.internalPointer());
|
||||
item != NULL && item != rootItem && item->type() != type;
|
||||
item = static_cast<TreeItem*>(parent.internalPointer()))
|
||||
parent = parent.parent();
|
||||
if (item != NULL && item != rootItem)
|
||||
return parent;
|
||||
|
||||
return QModelIndex();
|
||||
}
|
78
common/treemodel.h
Normal file
78
common/treemodel.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* treemodel.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __TREEMODEL_H__
|
||||
#define __TREEMODEL_H__
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QModelIndex>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "types.h"
|
||||
|
||||
class TreeItem;
|
||||
|
||||
class TreeModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TreeModel(QObject *parent = 0);
|
||||
~TreeModel();
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
|
||||
void setAction(const QModelIndex &index, const UINT8 action);
|
||||
void setType(const QModelIndex &index, const UINT8 type);
|
||||
void setSubtype(const QModelIndex &index, const UINT8 subtype);
|
||||
void setName(const QModelIndex &index, const QString &name);
|
||||
void setText(const QModelIndex &index, const QString &text);
|
||||
void setInfo(const QModelIndex &index, const QString &info);
|
||||
void addInfo(const QModelIndex &index, const QString &info);
|
||||
void setParsingData(const QModelIndex &index, const QByteArray &data);
|
||||
|
||||
QString name(const QModelIndex &index) const;
|
||||
QString text(const QModelIndex &index) const;
|
||||
QString info(const QModelIndex &index) const;
|
||||
UINT8 type(const QModelIndex &index) const;
|
||||
UINT8 subtype(const QModelIndex &index) const;
|
||||
QByteArray header(const QModelIndex &index) const;
|
||||
bool hasEmptyHeader(const QModelIndex &index) const;
|
||||
QByteArray body(const QModelIndex &index) const;
|
||||
bool hasEmptyBody(const QModelIndex &index) const;
|
||||
QByteArray parsingData(const QModelIndex &index) const;
|
||||
bool hasEmptyParsingData(const QModelIndex &index) const;
|
||||
UINT8 action(const QModelIndex &index) const;
|
||||
|
||||
QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0,
|
||||
const QString & name = QString(), const QString & text = QString(), const QString & info = QString(),
|
||||
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & parsingData = QByteArray(),
|
||||
const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
|
||||
|
||||
QModelIndex findParentOfType(const QModelIndex & index, UINT8 type) const;
|
||||
|
||||
private:
|
||||
TreeItem *rootItem;
|
||||
};
|
||||
|
||||
#endif
|
152
common/types.cpp
Normal file
152
common/types.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* types.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include "types.h"
|
||||
#include "ffs.h"
|
||||
|
||||
QString regionTypeToQString(const UINT8 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Subtypes::DescriptorRegion:
|
||||
return QObject::tr("Descriptor");
|
||||
case Subtypes::GbeRegion:
|
||||
return QObject::tr("GbE");
|
||||
case Subtypes::MeRegion:
|
||||
return QObject::tr("ME");
|
||||
case Subtypes::BiosRegion:
|
||||
return QObject::tr("BIOS");
|
||||
case Subtypes::PdrRegion:
|
||||
return QObject::tr("PDR");
|
||||
default:
|
||||
return QObject::tr("Unknown");
|
||||
};
|
||||
}
|
||||
|
||||
QString itemTypeToQString(const UINT8 type)
|
||||
{
|
||||
switch (type) {
|
||||
case Types::Root:
|
||||
return QObject::tr("Root");
|
||||
case Types::Image:
|
||||
return QObject::tr("Image");
|
||||
case Types::Capsule:
|
||||
return QObject::tr("Capsule");
|
||||
case Types::Region:
|
||||
return QObject::tr("Region");
|
||||
case Types::Volume:
|
||||
return QObject::tr("Volume");
|
||||
case Types::Padding:
|
||||
return QObject::tr("Padding");
|
||||
case Types::File:
|
||||
return QObject::tr("File");
|
||||
case Types::Section:
|
||||
return QObject::tr("Section");
|
||||
case Types::FreeSpace:
|
||||
return QObject::tr("Free space");
|
||||
default:
|
||||
return QObject::tr("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
||||
{
|
||||
switch (type) {
|
||||
case Types::Root:
|
||||
case Types::Image:
|
||||
if (subtype == Subtypes::IntelImage)
|
||||
return QObject::tr("Intel");
|
||||
else if (Subtypes::UefiImage)
|
||||
return QObject::tr("UEFI");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Padding:
|
||||
if (subtype == Subtypes::ZeroPadding)
|
||||
return QObject::tr("Empty (0x00)");
|
||||
else if (subtype == Subtypes::OnePadding)
|
||||
return QObject::tr("Empty (0xFF)");
|
||||
else if (subtype == Subtypes::DataPadding)
|
||||
return QObject::tr("Non-empty");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Volume:
|
||||
if (subtype == Subtypes::UnknownVolume)
|
||||
return QObject::tr("Unknown");
|
||||
else if (subtype == Subtypes::Ffs2Volume)
|
||||
return QObject::tr("FFSv2");
|
||||
else if (subtype == Subtypes::Ffs3Volume)
|
||||
return QObject::tr("FFSv3");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Capsule:
|
||||
if (subtype == Subtypes::AptioSignedCapsule)
|
||||
return QObject::tr("Aptio signed");
|
||||
else if (subtype == Subtypes::AptioUnsignedCapsule)
|
||||
return QObject::tr("Aptio unsigned");
|
||||
else if (subtype == Subtypes::UefiCapsule)
|
||||
return QObject::tr("UEFI 2.0 ");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Region:
|
||||
return regionTypeToQString(subtype);
|
||||
case Types::File:
|
||||
return fileTypeToQString(subtype);
|
||||
case Types::Section:
|
||||
return sectionTypeToQString(subtype);
|
||||
case Types::FreeSpace:
|
||||
return QString();
|
||||
default:
|
||||
return QObject::tr("Unknown subtype");
|
||||
}
|
||||
}
|
||||
|
||||
QString compressionTypeToQString(const UINT8 algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case COMPRESSION_ALGORITHM_NONE:
|
||||
return QObject::tr("None");
|
||||
case COMPRESSION_ALGORITHM_EFI11:
|
||||
return QObject::tr("EFI 1.1");
|
||||
case COMPRESSION_ALGORITHM_TIANO:
|
||||
return QObject::tr("Tiano");
|
||||
case COMPRESSION_ALGORITHM_LZMA:
|
||||
return QObject::tr("LZMA");
|
||||
case COMPRESSION_ALGORITHM_IMLZMA:
|
||||
return QObject::tr("Intel modified LZMA");
|
||||
default:
|
||||
return QObject::tr("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
QString actionTypeToQString(const UINT8 action)
|
||||
{
|
||||
switch (action) {
|
||||
case Actions::NoAction:
|
||||
return "";
|
||||
case Actions::Create:
|
||||
return QObject::tr("Create");
|
||||
case Actions::Insert:
|
||||
return QObject::tr("Insert");
|
||||
case Actions::Replace:
|
||||
return QObject::tr("Replace");
|
||||
case Actions::Remove:
|
||||
return QObject::tr("Remove");
|
||||
case Actions::Rebuild:
|
||||
return QObject::tr("Rebuild");
|
||||
case Actions::Rebase:
|
||||
return QObject::tr("Rebase");
|
||||
default:
|
||||
return QObject::tr("Unknown");
|
||||
}
|
||||
}
|
88
common/types.h
Normal file
88
common/types.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* types.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
// Actions
|
||||
namespace Actions
|
||||
{
|
||||
enum ActionTypes {
|
||||
NoAction = 50,
|
||||
Create,
|
||||
Insert,
|
||||
Replace,
|
||||
Remove,
|
||||
Rebuild,
|
||||
Rebase
|
||||
};
|
||||
}
|
||||
|
||||
// Types
|
||||
namespace Types {
|
||||
enum ItemTypes {
|
||||
Root = 60,
|
||||
Capsule,
|
||||
Image,
|
||||
Region,
|
||||
Padding,
|
||||
Volume,
|
||||
File,
|
||||
Section,
|
||||
FreeSpace
|
||||
};
|
||||
}
|
||||
|
||||
namespace Subtypes {
|
||||
enum ImageSubtypes{
|
||||
IntelImage = 70,
|
||||
UefiImage
|
||||
};
|
||||
|
||||
enum CapsuleSubtypes {
|
||||
AptioSignedCapsule = 80,
|
||||
AptioUnsignedCapsule,
|
||||
UefiCapsule
|
||||
};
|
||||
|
||||
enum VolumeSubtypes {
|
||||
UnknownVolume = 90,
|
||||
Ffs2Volume,
|
||||
Ffs3Volume
|
||||
};
|
||||
|
||||
enum RegionSubtypes {
|
||||
DescriptorRegion = 100,
|
||||
GbeRegion,
|
||||
MeRegion,
|
||||
BiosRegion,
|
||||
PdrRegion
|
||||
};
|
||||
|
||||
enum PaddingSubtypes {
|
||||
ZeroPadding = 110,
|
||||
OnePadding,
|
||||
DataPadding
|
||||
};
|
||||
};
|
||||
|
||||
// *ToQString conversion routines
|
||||
extern QString actionTypeToQString(const UINT8 action);
|
||||
extern QString itemTypeToQString(const UINT8 type);
|
||||
extern QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype);
|
||||
extern QString compressionTypeToQString(const UINT8 algorithm);
|
||||
extern QString regionTypeToQString(const UINT8 type);
|
||||
|
||||
#endif
|
259
common/utility.cpp
Normal file
259
common/utility.cpp
Normal file
|
@ -0,0 +1,259 @@
|
|||
/* utility.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
#include <QObject>
|
||||
#include "treemodel.h"
|
||||
#include "utility.h"
|
||||
#include "ffs.h"
|
||||
#include "Tiano/EfiTianoCompress.h"
|
||||
#include "Tiano/EfiTianoDecompress.h"
|
||||
#include "LZMA/LzmaCompress.h"
|
||||
#include "LZMA/LzmaDecompress.h"
|
||||
|
||||
// Returns either new parsing data instance or obtains it from index
|
||||
PARSING_DATA getParsingData(const QModelIndex & index)
|
||||
{
|
||||
if (index.isValid()) {
|
||||
TreeModel* model = (TreeModel*)index.model();
|
||||
return *(PARSING_DATA*)model->parsingData(index).data();
|
||||
}
|
||||
|
||||
PARSING_DATA data;
|
||||
data.fixed = FALSE; // Item is not fixed by default
|
||||
data.isOnFlash = TRUE; // Data is on flash by default
|
||||
data.offset = 0;
|
||||
data.address = 0;
|
||||
data.ffsVersion = 0; // Unknown by default
|
||||
|
||||
// Type-specific parts remain unitialized
|
||||
return data;
|
||||
}
|
||||
|
||||
// Converts parsing data to byte array
|
||||
QByteArray convertParsingData(const PARSING_DATA & pdata)
|
||||
{
|
||||
return QByteArray((const char*)&pdata, sizeof(PARSING_DATA));
|
||||
}
|
||||
|
||||
// Returns text representation of error code
|
||||
QString errorCodeToQString(UINT8 errorCode)
|
||||
{
|
||||
switch (errorCode) {
|
||||
case ERR_SUCCESS: return QObject::tr("Success");
|
||||
case ERR_NOT_IMPLEMENTED: return QObject::tr("Not implemented");
|
||||
case ERR_INVALID_PARAMETER: return QObject::tr("Function called with invalid parameter");
|
||||
case ERR_BUFFER_TOO_SMALL: return QObject::tr("Buffer too small");
|
||||
case ERR_OUT_OF_RESOURCES: return QObject::tr("Out of resources");
|
||||
case ERR_OUT_OF_MEMORY: return QObject::tr("Out of memory");
|
||||
case ERR_FILE_OPEN: return QObject::tr("File can't be opened");
|
||||
case ERR_FILE_READ: return QObject::tr("File can't be read");
|
||||
case ERR_FILE_WRITE: return QObject::tr("File can't be written");
|
||||
case ERR_ITEM_NOT_FOUND: return QObject::tr("Item not found");
|
||||
case ERR_UNKNOWN_ITEM_TYPE: return QObject::tr("Unknown item type");
|
||||
case ERR_INVALID_FLASH_DESCRIPTOR: return QObject::tr("Invalid flash descriptor");
|
||||
case ERR_INVALID_REGION: return QObject::tr("Invalid region");
|
||||
case ERR_EMPTY_REGION: return QObject::tr("Empty region");
|
||||
case ERR_BIOS_REGION_NOT_FOUND: return QObject::tr("BIOS region not found");
|
||||
case ERR_VOLUMES_NOT_FOUND: return QObject::tr("UEFI volumes not found");
|
||||
case ERR_INVALID_VOLUME: return QObject::tr("Invalid UEFI volume");
|
||||
case ERR_VOLUME_REVISION_NOT_SUPPORTED: return QObject::tr("Volume revision not supported");
|
||||
//case ERR_VOLUME_GROW_FAILED: return QObject::tr("Volume grow failed");
|
||||
case ERR_UNKNOWN_FFS: return QObject::tr("Unknown file system");
|
||||
case ERR_INVALID_FILE: return QObject::tr("Invalid file");
|
||||
case ERR_INVALID_SECTION: return QObject::tr("Invalid section");
|
||||
case ERR_UNKNOWN_SECTION: return QObject::tr("Unknown section");
|
||||
case ERR_STANDARD_COMPRESSION_FAILED: return QObject::tr("Standard compression failed");
|
||||
case ERR_CUSTOMIZED_COMPRESSION_FAILED: return QObject::tr("Customized compression failed");
|
||||
case ERR_STANDARD_DECOMPRESSION_FAILED: return QObject::tr("Standard decompression failed");
|
||||
case ERR_CUSTOMIZED_DECOMPRESSION_FAILED: return QObject::tr("Customized compression failed");
|
||||
case ERR_UNKNOWN_COMPRESSION_TYPE: return QObject::tr("Unknown compression type");
|
||||
case ERR_UNKNOWN_EXTRACT_MODE: return QObject::tr("Unknown extract mode");
|
||||
//case ERR_UNKNOWN_INSERT_MODE: return QObject::tr("Unknown insert mode");
|
||||
case ERR_UNKNOWN_IMAGE_TYPE: return QObject::tr("Unknown executable image type");
|
||||
case ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE: return QObject::tr("Unknown PE optional header type");
|
||||
case ERR_UNKNOWN_RELOCATION_TYPE: return QObject::tr("Unknown relocation type");
|
||||
//case ERR_GENERIC_CALL_NOT_SUPPORTED: return QObject::tr("Generic call not supported");
|
||||
//case ERR_VOLUME_BASE_NOT_FOUND: return QObject::tr("Volume base address not found");
|
||||
//case ERR_PEI_CORE_ENTRY_POINT_NOT_FOUND: return QObject::tr("PEI core entry point not found");
|
||||
case ERR_COMPLEX_BLOCK_MAP: return QObject::tr("Block map structure too complex for correct analysis");
|
||||
case ERR_DIR_ALREADY_EXIST: return QObject::tr("Directory already exists");
|
||||
case ERR_DIR_CREATE: return QObject::tr("Directory can't be created");
|
||||
//case ERR_UNKNOWN_PATCH_TYPE: return QObject::tr("Unknown patch type");
|
||||
//case ERR_PATCH_OFFSET_OUT_OF_BOUNDS: return QObject::tr("Patch offset out of bounds");
|
||||
//case ERR_INVALID_SYMBOL: return QObject::tr("Invalid symbol");
|
||||
//case ERR_NOTHING_TO_PATCH: return QObject::tr("Nothing to patch");
|
||||
case ERR_DEPEX_PARSE_FAILED: return QObject::tr("Dependency expression parsing failed");
|
||||
default: return QObject::tr("Unknown error %1").arg(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
// CRC32 implementation
|
||||
UINT32 crc32(UINT32 initial, const UINT8* buffer, UINT32 length)
|
||||
{
|
||||
static const UINT32 crcTable[256] = {
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
|
||||
0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
|
||||
0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
|
||||
0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
||||
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
|
||||
0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
|
||||
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
|
||||
0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
|
||||
0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
|
||||
0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
|
||||
0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
|
||||
0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
|
||||
0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
|
||||
0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
|
||||
0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
|
||||
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
|
||||
0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
|
||||
0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
|
||||
0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
|
||||
0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
|
||||
0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
|
||||
0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
|
||||
0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
||||
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
|
||||
0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
|
||||
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
|
||||
0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
|
||||
0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
|
||||
0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
|
||||
0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
|
||||
UINT32 crc32;
|
||||
UINT32 i;
|
||||
|
||||
// Accumulate crc32 for buffer
|
||||
crc32 = initial ^ 0xFFFFFFFF;
|
||||
for (i = 0; i < length; i++) {
|
||||
crc32 = (crc32 >> 8) ^ crcTable[(crc32 ^ buffer[i]) & 0xFF];
|
||||
}
|
||||
|
||||
return(crc32 ^ 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// Compression routines
|
||||
STATUS decompress(const QByteArray & compressedData, UINT8 & algorithm, QByteArray & decompressedData)
|
||||
{
|
||||
const UINT8* data;
|
||||
UINT32 dataSize;
|
||||
UINT8* decompressed;
|
||||
UINT32 decompressedSize = 0;
|
||||
UINT8* scratch;
|
||||
UINT32 scratchSize = 0;
|
||||
const EFI_TIANO_HEADER* header;
|
||||
|
||||
switch (algorithm)
|
||||
{
|
||||
case EFI_NOT_COMPRESSED:
|
||||
decompressedData = compressedData;
|
||||
algorithm = COMPRESSION_ALGORITHM_NONE;
|
||||
return ERR_SUCCESS;
|
||||
case EFI_STANDARD_COMPRESSION:
|
||||
// Set default algorithm to unknown
|
||||
algorithm = COMPRESSION_ALGORITHM_UNKNOWN;
|
||||
|
||||
// Get buffer sizes
|
||||
data = (UINT8*)compressedData.data();
|
||||
dataSize = compressedData.size();
|
||||
|
||||
// Check header to be valid
|
||||
header = (const EFI_TIANO_HEADER*)data;
|
||||
if (header->CompSize + sizeof(EFI_TIANO_HEADER) != dataSize)
|
||||
return ERR_STANDARD_DECOMPRESSION_FAILED;
|
||||
|
||||
// Get info function is the same for both algorithms
|
||||
if (ERR_SUCCESS != EfiTianoGetInfo(data, dataSize, &decompressedSize, &scratchSize))
|
||||
return ERR_STANDARD_DECOMPRESSION_FAILED;
|
||||
|
||||
// Allocate memory
|
||||
decompressed = new UINT8[decompressedSize];
|
||||
scratch = new UINT8[scratchSize];
|
||||
|
||||
// Decompress section data
|
||||
|
||||
//TODO: separate EFI1.1 from Tiano another way
|
||||
// Try Tiano decompression first
|
||||
if (ERR_SUCCESS != TianoDecompress(data, dataSize, decompressed, decompressedSize, scratch, scratchSize)) {
|
||||
// Not Tiano, try EFI 1.1
|
||||
if (ERR_SUCCESS != EfiDecompress(data, dataSize, decompressed, decompressedSize, scratch, scratchSize)) {
|
||||
delete[] decompressed;
|
||||
delete[] scratch;
|
||||
return ERR_STANDARD_DECOMPRESSION_FAILED;
|
||||
}
|
||||
else algorithm = COMPRESSION_ALGORITHM_EFI11;
|
||||
}
|
||||
else algorithm = COMPRESSION_ALGORITHM_TIANO;
|
||||
|
||||
decompressedData = QByteArray((const char*)decompressed, decompressedSize);
|
||||
|
||||
delete[] decompressed;
|
||||
delete[] scratch;
|
||||
return ERR_SUCCESS;
|
||||
case EFI_CUSTOMIZED_COMPRESSION:
|
||||
// Set default algorithm to unknown
|
||||
algorithm = COMPRESSION_ALGORITHM_UNKNOWN;
|
||||
|
||||
// Get buffer sizes
|
||||
data = (const UINT8*)compressedData.constData();
|
||||
dataSize = compressedData.size();
|
||||
|
||||
// Get info
|
||||
if (ERR_SUCCESS != LzmaGetInfo(data, dataSize, &decompressedSize))
|
||||
return ERR_CUSTOMIZED_DECOMPRESSION_FAILED;
|
||||
|
||||
// Allocate memory
|
||||
decompressed = new UINT8[decompressedSize];
|
||||
|
||||
// Decompress section data
|
||||
if (ERR_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
|
||||
// Intel modified LZMA workaround
|
||||
// Decompress section data once again
|
||||
data += sizeof(UINT32);
|
||||
|
||||
// Get info again
|
||||
if (ERR_SUCCESS != LzmaGetInfo(data, dataSize, &decompressedSize)) {
|
||||
delete[] decompressed;
|
||||
return ERR_CUSTOMIZED_DECOMPRESSION_FAILED;
|
||||
}
|
||||
|
||||
// Decompress section data again
|
||||
if (ERR_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
|
||||
delete[] decompressed;
|
||||
return ERR_CUSTOMIZED_DECOMPRESSION_FAILED;
|
||||
}
|
||||
else {
|
||||
algorithm = COMPRESSION_ALGORITHM_IMLZMA;
|
||||
decompressedData = QByteArray((const char*)decompressed, decompressedSize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
algorithm = COMPRESSION_ALGORITHM_LZMA;
|
||||
decompressedData = QByteArray((const char*)decompressed, decompressedSize);
|
||||
}
|
||||
|
||||
delete[] decompressed;
|
||||
return ERR_SUCCESS;
|
||||
default:
|
||||
algorithm = COMPRESSION_ALGORITHM_UNKNOWN;
|
||||
return ERR_UNKNOWN_COMPRESSION_TYPE;
|
||||
}
|
||||
}
|
||||
|
40
common/utility.h
Normal file
40
common/utility.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* utility.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __UTILITY_H__
|
||||
#define __UTILITY_H__
|
||||
|
||||
#include <QString>
|
||||
#include <QModelIndex>
|
||||
#include "basetypes.h"
|
||||
#include "parsingdata.h"
|
||||
|
||||
// Returns either new parsing data instance or obtains it from index
|
||||
PARSING_DATA getParsingData(const QModelIndex & index);
|
||||
|
||||
// Converts parsing data to byte array
|
||||
QByteArray convertParsingData(const PARSING_DATA & pdata);
|
||||
|
||||
// Converts error code to QString
|
||||
extern QString errorCodeToQString(UINT8 errorCode);
|
||||
|
||||
// Decompression routine
|
||||
extern STATUS decompress(const QByteArray & compressed, UINT8 & algorithm, QByteArray & decompressed);
|
||||
|
||||
// Compression routine
|
||||
//STATUS compress(const QByteArray & decompressed, QByteArray & compressed, const UINT8 & algorithm);
|
||||
|
||||
// CRC32
|
||||
extern UINT32 crc32(UINT32 initial, const UINT8* buffer, UINT32 length);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue