Version 0.11.0

- UI reworked once again
- Hex pattern and text string search implemented
- Code slightly refactored
This commit is contained in:
Nikolaj Schlej 2013-12-04 21:27:12 +01:00
parent 7d8b5fbc20
commit bb6f58f509
26 changed files with 4697 additions and 4327 deletions

View file

@ -25,85 +25,85 @@ static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma };
SRes OnProgress(void *p, UInt64 inSize, UInt64 outSize)
{
return SZ_OK;
return SZ_OK;
}
static ICompressProgress g_ProgressCallback = { &OnProgress };
STATIC
UINT64
EFIAPI
RShiftU64 (
UINT64 Operand,
UINT32 Count
)
UINT64
EFIAPI
RShiftU64 (
UINT64 Operand,
UINT32 Count
)
{
return Operand >> Count;
return Operand >> Count;
}
VOID
SetEncodedSizeOfBuf(
UINT64 EncodedSize,
UINT8 *EncodedData
)
SetEncodedSizeOfBuf(
UINT64 EncodedSize,
UINT8 *EncodedData
)
{
INT32 Index;
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;
}
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
)
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;
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;
}
if (*DestinationSize < destLen)
{
*DestinationSize = destLen;
return ERR_BUFFER_TOO_SMALL;
}
LzmaEncProps_Init(&props);
props.dictSize = LZMA_DICTIONARY_SIZE;
props.level = 9;
props.fb = 273;
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);
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;
*DestinationSize = destLen + LZMA_HEADER_SIZE;
SetEncodedSizeOfBuf((UINT64)SourceSize, Destination);
SetEncodedSizeOfBuf((UINT64)SourceSize, Destination);
if (LzmaResult == SZ_OK) {
return ERR_SUCCESS;
} else {
return ERR_INVALID_PARAMETER;
}
if (LzmaResult == SZ_OK) {
return ERR_SUCCESS;
} else {
return ERR_INVALID_PARAMETER;
}
}

View file

@ -18,13 +18,13 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <stdlib.h>
UINT64
EFIAPI
LShiftU64 (
UINT64 Operand,
UINT32 Count
)
EFIAPI
LShiftU64 (
UINT64 Operand,
UINT32 Count
)
{
return Operand << Count;
return Operand << Count;
}
static void * AllocForLzma(void *p, size_t size) { return malloc(size); }
@ -39,19 +39,19 @@ Get the size of the uncompressed buffer by parsing EncodeData header.
@return The size of the uncompressed buffer.
*/
UINT64
GetDecodedSizeOfBuf(
UINT8 *EncodedData
)
GetDecodedSizeOfBuf(
UINT8 *EncodedData
)
{
UINT64 DecodedSize;
INT32 Index;
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];
// Parse header
DecodedSize = 0;
for (Index = LZMA_PROPS_SIZE + 7; Index >= LZMA_PROPS_SIZE; Index--)
DecodedSize = LShiftU64(DecodedSize, 8) + EncodedData[Index];
return DecodedSize;
return DecodedSize;
}
//
@ -86,21 +86,21 @@ buffer was returned ScratchSize.
*/
INT32
EFIAPI
LzmaGetInfo (
CONST VOID *Source,
UINT32 SourceSize,
UINT32 *DestinationSize
)
EFIAPI
LzmaGetInfo (
CONST VOID *Source,
UINT32 SourceSize,
UINT32 *DestinationSize
)
{
UInt64 DecodedSize;
UInt64 DecodedSize;
ASSERT(SourceSize >= LZMA_HEADER_SIZE);
ASSERT(SourceSize >= LZMA_HEADER_SIZE);
DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);
DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);
*DestinationSize = (UINT32)DecodedSize;
return ERR_SUCCESS;
*DestinationSize = (UINT32)DecodedSize;
return ERR_SUCCESS;
}
/*
@ -123,37 +123,37 @@ The source buffer specified by Source is corrupted
(not a valid compressed format).
*/
INT32
EFIAPI
LzmaDecompress (
CONST VOID *Source,
UINT32 SourceSize,
VOID *Destination
)
EFIAPI
LzmaDecompress (
CONST VOID *Source,
UINT32 SourceSize,
VOID *Destination
)
{
SRes LzmaResult;
ELzmaStatus Status;
SizeT DecodedBufSize;
SizeT EncodedDataSize;
SRes LzmaResult;
ELzmaStatus Status;
SizeT DecodedBufSize;
SizeT EncodedDataSize;
DecodedBufSize = (SizeT)GetDecodedSizeOfBuf((UINT8*)Source);
EncodedDataSize = (SizeT) (SourceSize - LZMA_HEADER_SIZE);
DecodedBufSize = (SizeT)GetDecodedSizeOfBuf((UINT8*)Source);
EncodedDataSize = (SizeT) (SourceSize - LZMA_HEADER_SIZE);
LzmaResult = LzmaDecode(
Destination,
&DecodedBufSize,
(Byte*)((UINT8*)Source + LZMA_HEADER_SIZE),
&EncodedDataSize,
Source,
LZMA_PROPS_SIZE,
LZMA_FINISH_END,
&Status,
&SzAllocForLzma
);
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;
}
if (LzmaResult == SZ_OK) {
return ERR_SUCCESS;
} else {
return ERR_INVALID_PARAMETER;
}
}

View file

@ -49,12 +49,12 @@ LShiftU64 (
@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.
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.
DestinationSize and the size of the scratch
buffer was returned ScratchSize.
*/
INT32
@ -77,12 +77,12 @@ LzmaGetInfo (
@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.
the uncompressed buffer is returned Destination.
@retval EFI_INVALID_PARAMETER
The source buffer specified by Source is corrupted
(not a valid compressed format).
The source buffer specified by Source is corrupted
(not a valid compressed format).
*/
INT32
EFIAPI

View file

@ -18,8 +18,8 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
{
if (!p->directInput)
{
alloc->Free(alloc, p->bufferBase);
p->bufferBase = 0;
alloc->Free(alloc, p->bufferBase);
p->bufferBase = 0;
}
}
@ -30,14 +30,14 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
if (p->directInput)
{
p->blockSize = blockSize;
return 1;
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);
LzInWindow_Free(p, alloc);
p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
}
return (p->bufferBase != 0);
}
@ -57,50 +57,50 @@ void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
static void MatchFinder_ReadBlock(CMatchFinder *p)
{
if (p->streamEndWasReached || p->result != SZ_OK)
return;
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;
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;
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->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;
return 0;
/* if (p->streamEndWasReached) return 0; */
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
}
@ -108,15 +108,15 @@ int MatchFinder_NeedMove(CMatchFinder *p)
void MatchFinder_ReadIfRequired(CMatchFinder *p)
{
if (p->streamEndWasReached)
return;
return;
if (p->keepSizeAfter >= p->streamPos - p->pos)
MatchFinder_ReadBlock(p);
MatchFinder_ReadBlock(p);
}
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
{
if (MatchFinder_NeedMove(p))
MatchFinder_MoveBlock(p);
MatchFinder_MoveBlock(p);
MatchFinder_ReadBlock(p);
}
@ -140,11 +140,11 @@ void MatchFinder_Construct(CMatchFinder *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;
UInt32 r = i;
int j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
p->crc[i] = r;
}
}
@ -164,23 +164,23 @@ static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
{
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num)
return 0;
return 0;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
}
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc)
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc)
{
UInt32 sizeReserv;
if (historySize > kMaxHistorySize)
{
MatchFinder_Free(p, alloc);
return 0;
MatchFinder_Free(p, alloc);
return 0;
}
sizeReserv = historySize >> 1;
if (historySize > ((UInt32)2 << 30))
sizeReserv = historySize >> 2;
sizeReserv = historySize >> 2;
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
@ -188,56 +188,56 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
/* 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 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;
}
}
{
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;
@ -248,22 +248,22 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
UInt32 limit = kMaxValForNormalize - p->pos;
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
if (limit2 < limit)
limit = limit2;
limit = limit2;
limit2 = p->streamPos - p->pos;
if (limit2 <= p->keepSizeAfter)
{
if (limit2 > 0)
limit2 = 1;
if (limit2 > 0)
limit2 = 1;
}
else
limit2 -= p->keepSizeAfter;
limit2 -= p->keepSizeAfter;
if (limit2 < limit)
limit = limit2;
limit = limit2;
{
UInt32 lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen)
lenLimit = p->matchMaxLen;
p->lenLimit = lenLimit;
UInt32 lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen)
lenLimit = p->matchMaxLen;
p->lenLimit = lenLimit;
}
p->posLimit = p->pos + limit;
}
@ -272,7 +272,7 @@ void MatchFinder_Init(CMatchFinder *p)
{
UInt32 i;
for (i = 0; i < p->hashSizeSum; i++)
p->hash[i] = kEmptyHashValue;
p->hash[i] = kEmptyHashValue;
p->cyclicBufferPos = 0;
p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize;
@ -292,12 +292,12 @@ 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;
UInt32 value = items[i];
if (value <= subValue)
value = kEmptyHashValue;
else
value -= subValue;
items[i] = value;
}
}
@ -311,147 +311,147 @@ static void MatchFinder_Normalize(CMatchFinder *p)
static void MatchFinder_CheckLimits(CMatchFinder *p)
{
if (p->pos == kMaxValForNormalize)
MatchFinder_Normalize(p);
MatchFinder_Normalize(p);
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
MatchFinder_CheckAndMoveAndRead(p);
MatchFinder_CheckAndMoveAndRead(p);
if (p->cyclicBufferPos == p->cyclicBufferSize)
p->cyclicBufferPos = 0;
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)
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 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)
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;
}
}
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)
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;
}
}
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;
}
}
}
}
@ -521,17 +521,17 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
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;
}
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)
}
@ -555,31 +555,31 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = delta2 - 1;
offset = 2;
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;
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;
}
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;
maxLen = 3;
GET_MATCHES_FOOTER(offset, maxLen)
}
@ -602,33 +602,33 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = delta2 - 1;
offset = 2;
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;
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;
}
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;
maxLen = 3;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances + offset, maxLen) - (distances));
distances + offset, maxLen) - (distances));
MOVE_POS_RET
}
@ -640,7 +640,7 @@ UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances, 2) - (distances));
distances, 2) - (distances));
MOVE_POS_RET
}
@ -648,11 +648,11 @@ 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
SKIP_HEADER(2)
HASH2_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
@ -661,11 +661,11 @@ 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
SKIP_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
@ -674,13 +674,13 @@ 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
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);
}
@ -689,14 +689,14 @@ 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
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);
}
@ -705,15 +705,15 @@ 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
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);
}
@ -722,12 +722,12 @@ 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
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);
}
@ -740,22 +740,22 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
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;
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;
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;
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;
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ 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.
@ -43,12 +43,12 @@ Arguments:
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.
the size of the actual compressed data.
Returns:
EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. this case,
DstSize contains the size needed.
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.
@ -75,12 +75,12 @@ Arguments:
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.
the size of the actual compressed data.
Returns:
EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. this case,
DstSize contains the size needed.
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.

View file

@ -101,25 +101,25 @@ Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
while (NumOfBits > Sd->mBitCount) {
Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (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;
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;
} else {
//
// No more bits from the source, just pad zero bit.
//
Sd->mSubBitBuf = 0;
Sd->mBitCount = 8;
}
}
}
Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
@ -204,43 +204,43 @@ UINT16 NextCode;
UINT16 Mask;
for (Index = 1; Index <= 16; Index++) {
Count[Index] = 0;
Count[Index] = 0;
}
for (Index = 0; Index < NumOfChar; Index++) {
Count[BitLen[Index]]++;
Count[BitLen[Index]]++;
}
Start[1] = 0;
for (Index = 1; Index <= 16; Index++) {
Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));
}
if (Start[17] != 0) {
/*(1U << 16)*/
return (UINT16) BAD_TABLE;
/*(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));
Start[Index] >>= JuBits;
Weight[Index] = (UINT16) (1U << (TableBits - Index));
}
while (Index <= 16) {
Weight[Index] = (UINT16) (1U << (16 - Index));
Index++;
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;
}
Index3 = (UINT16) (1U << TableBits);
while (Index != Index3) {
Table[Index++] = 0;
}
}
Avail = NumOfChar;
@ -248,46 +248,46 @@ Mask = (UINT16) (1U << (15 - TableBits));
for (Char = 0; Char < NumOfChar; Char++) {
Len = BitLen[Char];
if (Len == 0) {
continue;
}
Len = BitLen[Char];
if (Len == 0) {
continue;
}
NextCode = (UINT16) (Start[Len] + Weight[Len]);
NextCode = (UINT16) (Start[Len] + Weight[Len]);
if (Len <= TableBits) {
if (Len <= TableBits) {
for (Index = Start[Len]; Index < NextCode; Index++) {
Table[Index] = Char;
}
for (Index = Start[Len]; Index < NextCode; Index++) {
Table[Index] = Char;
}
} else {
} else {
Index3 = Start[Len];
Pointer = &Table[Index3 >> JuBits];
Index = (UINT16) (Len - TableBits);
Index3 = Start[Len];
Pointer = &Table[Index3 >> JuBits];
Index = (UINT16) (Len - TableBits);
while (Index != 0) {
if (*Pointer == 0) {
Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
*Pointer = Avail++;
}
while (Index != 0) {
if (*Pointer == 0) {
Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
*Pointer = Avail++;
}
if (Index3 & Mask) {
Pointer = &Sd->mRight[*Pointer];
} else {
Pointer = &Sd->mLeft[*Pointer];
}
if (Index3 & Mask) {
Pointer = &Sd->mRight[*Pointer];
} else {
Pointer = &Sd->mLeft[*Pointer];
}
Index3 <<= 1;
Index--;
}
Index3 <<= 1;
Index--;
}
*Pointer = Char;
*Pointer = Char;
}
}
Start[Len] = NextCode;
Start[Len] = NextCode;
}
//
// Succeeds
@ -323,18 +323,18 @@ UINT32 Pos;
Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
if (Val >= MAXNP) {
Mask = 1U << (BITBUFSIZ - 1 - 8);
Mask = 1U << (BITBUFSIZ - 1 - 8);
do {
do {
if (Sd->mBitBuf & Mask) {
Val = Sd->mRight[Val];
} else {
Val = Sd->mLeft[Val];
}
if (Sd->mBitBuf & Mask) {
Val = Sd->mRight[Val];
} else {
Val = Sd->mLeft[Val];
}
Mask >>= 1;
} while (Val >= MAXNP);
Mask >>= 1;
} while (Val >= MAXNP);
}
//
// Advance what we have read
@ -343,7 +343,7 @@ FillBuf (Sd, Sd->mPTLen[Val]);
Pos = Val;
if (Val > 1) {
Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
}
return Pos;
@ -385,47 +385,47 @@ UINT32 Mask;
Number = (UINT16) GetBits (Sd, nbit);
if (Number == 0) {
CharC = (UINT16) GetBits (Sd, nbit);
CharC = (UINT16) GetBits (Sd, nbit);
for (Index = 0; Index < 256; Index++) {
Sd->mPTTable[Index] = CharC;
}
for (Index = 0; Index < 256; Index++) {
Sd->mPTTable[Index] = CharC;
}
for (Index = 0; Index < nn; Index++) {
Sd->mPTLen[Index] = 0;
}
for (Index = 0; Index < nn; Index++) {
Sd->mPTLen[Index] = 0;
}
return 0;
return 0;
}
Index = 0;
while (Index < Number) {
CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
if (CharC == 7) {
Mask = 1U << (BITBUFSIZ - 1 - 3);
while (Mask & Sd->mBitBuf) {
Mask >>= 1;
CharC += 1;
}
}
if (CharC == 7) {
Mask = 1U << (BITBUFSIZ - 1 - 3);
while (Mask & Sd->mBitBuf) {
Mask >>= 1;
CharC += 1;
}
}
FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
Sd->mPTLen[Index++] = (UINT8) CharC;
Sd->mPTLen[Index++] = (UINT8) CharC;
if (Index == Special) {
CharC = (UINT16) GetBits (Sd, 2);
while ((INT16) (--CharC) >= 0) {
Sd->mPTLen[Index++] = 0;
}
}
if (Index == Special) {
CharC = (UINT16) GetBits (Sd, 2);
while ((INT16) (--CharC) >= 0) {
Sd->mPTLen[Index++] = 0;
}
}
}
while (Index < nn) {
Sd->mPTLen[Index++] = 0;
Sd->mPTLen[Index++] = 0;
}
return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
@ -458,66 +458,66 @@ UINT32 Mask;
Number = (UINT16) GetBits (Sd, CBIT);
if (Number == 0) {
CharC = (UINT16) GetBits (Sd, CBIT);
CharC = (UINT16) GetBits (Sd, CBIT);
for (Index = 0; Index < NC; Index++) {
Sd->mCLen[Index] = 0;
}
for (Index = 0; Index < NC; Index++) {
Sd->mCLen[Index] = 0;
}
for (Index = 0; Index < 4096; Index++) {
Sd->mCTable[Index] = CharC;
}
for (Index = 0; Index < 4096; Index++) {
Sd->mCTable[Index] = CharC;
}
return ;
return ;
}
Index = 0;
while (Index < Number) {
CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
if (CharC >= NT) {
Mask = 1U << (BITBUFSIZ - 1 - 8);
CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
if (CharC >= NT) {
Mask = 1U << (BITBUFSIZ - 1 - 8);
do {
do {
if (Mask & Sd->mBitBuf) {
CharC = Sd->mRight[CharC];
} else {
CharC = Sd->mLeft[CharC];
}
if (Mask & Sd->mBitBuf) {
CharC = Sd->mRight[CharC];
} else {
CharC = Sd->mLeft[CharC];
}
Mask >>= 1;
Mask >>= 1;
} while (CharC >= NT);
}
//
// Advance what we have read
//
FillBuf (Sd, Sd->mPTLen[CharC]);
} while (CharC >= NT);
}
//
// Advance what we have read
//
FillBuf (Sd, Sd->mPTLen[CharC]);
if (CharC <= 2) {
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);
}
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;
}
while ((INT16) (--CharC) >= 0) {
Sd->mCLen[Index++] = 0;
}
} else {
} else {
Sd->mCLen[Index++] = (UINT8) (CharC - 2);
Sd->mCLen[Index++] = (UINT8) (CharC - 2);
}
}
}
while (Index < NC) {
Sd->mCLen[Index++] = 0;
Sd->mCLen[Index++] = 0;
}
MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
@ -550,38 +550,38 @@ 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;
}
//
// 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);
ReadCLen (Sd);
Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
if (Sd->mBadTableFlag != 0) {
return 0;
}
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);
Mask = 1U << (BITBUFSIZ - 1 - 12);
do {
if (Sd->mBitBuf & Mask) {
Index2 = Sd->mRight[Index2];
} else {
Index2 = Sd->mLeft[Index2];
}
do {
if (Sd->mBitBuf & Mask) {
Index2 = Sd->mRight[Index2];
} else {
Index2 = Sd->mLeft[Index2];
}
Mask >>= 1;
} while (Index2 >= NC);
Mask >>= 1;
} while (Index2 >= NC);
}
//
// Advance what we have read
@ -619,41 +619,41 @@ BytesRemain = (UINT16) (-1);
DataIdx = 0;
for (;;) {
CharC = DecodeC (Sd);
if (Sd->mBadTableFlag != 0) {
return ;
}
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;
}
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));
} else {
//
// Process a Pointer
//
CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));
BytesRemain = CharC;
BytesRemain = CharC;
DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
BytesRemain--;
while ((INT16) (BytesRemain) >= 0) {
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
if (Sd->mOutBuf >= Sd->mOrigSize) {
return ;
}
BytesRemain--;
while ((INT16) (BytesRemain) >= 0) {
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
if (Sd->mOutBuf >= Sd->mOrigSize) {
return ;
}
BytesRemain--;
}
}
BytesRemain--;
}
}
}
return ;
@ -692,7 +692,7 @@ UINT8 *Src;
Src = Source;
if (SrcSize < 8) {
return ERR_INVALID_PARAMETER;
return ERR_INVALID_PARAMETER;
}
*DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
@ -747,13 +747,13 @@ Src = Source;
Dst = Destination;
if (ScratchSize < sizeof (SCRATCH_DATA)) {
return ERR_INVALID_PARAMETER;
return ERR_INVALID_PARAMETER;
}
Sd = (SCRATCH_DATA *) Scratch;
if (SrcSize < 8) {
return ERR_INVALID_PARAMETER;
return ERR_INVALID_PARAMETER;
}
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
@ -763,21 +763,21 @@ OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
// If compressed file size is 0, return
//
if (OrigSize == 0) {
return Status;
return Status;
}
if (SrcSize < CompSize + 8) {
return ERR_INVALID_PARAMETER;
return ERR_INVALID_PARAMETER;
}
if (DstSize != OrigSize) {
return ERR_INVALID_PARAMETER;
return ERR_INVALID_PARAMETER;
}
Src = Src + 8;
for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
((UINT8 *) Sd)[Index] = 0;
((UINT8 *) Sd)[Index] = 0;
}
//
// The length of the field 'Position Set Code Length Array Size'Block Header.
@ -786,18 +786,18 @@ for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {
//
switch (Version) {
case 1:
Sd->mPBit = 4;
break;
Sd->mPBit = 4;
break;
case 2:
Sd->mPBit = 5;
break;
Sd->mPBit = 5;
break;
default:
//
// Currently, only have 2 versions
//
return ERR_INVALID_PARAMETER;
//
// Currently, only have 2 versions
//
return ERR_INVALID_PARAMETER;
}
Sd->mSrcBase = Src;
@ -816,10 +816,10 @@ FillBuf (Sd, BITBUFSIZ);
Decode (Sd);
if (Sd->mBadTableFlag != 0) {
//
// Something wrong with the source
//
Status = ERR_INVALID_PARAMETER;
//
// Something wrong with the source
//
Status = ERR_INVALID_PARAMETER;
}
return Status;
@ -862,14 +862,14 @@ 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
);
Source,
SrcSize,
Destination,
DstSize,
Scratch,
ScratchSize,
1
);
}
UINT32
@ -909,13 +909,13 @@ 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
);
Source,
SrcSize,
Destination,
DstSize,
Scratch,
ScratchSize,
2
);
}

View file

@ -31,8 +31,8 @@ Providing both EFI and Tiano decompress algorithms.
extern "C" {
#endif
typedef struct {
UINT32 CompSize;
UINT32 OrigSize;
UINT32 CompSize;
UINT32 OrigSize;
} EFI_TIANO_HEADER;
UINT32

File diff suppressed because it is too large Load diff

View file

@ -111,6 +111,11 @@ typedef uint16_t CHAR16;
#define ERASE_POLARITY_TRUE 1
#define ERASE_POLARITY_UNKNOWN 0xFF
// Search modes
#define SEARCH_MODE_HEX 0
#define SEARCH_MODE_ASCII 1
#define SEARCH_MODE_UNICODE 2
// EFI GUID
typedef struct{
UINT8 Data[16];

22
ffs.cpp
View file

@ -19,9 +19,9 @@ const UINT8 ffsAlignmentTable[] =
UINT8 calculateChecksum8(UINT8* buffer, UINT32 bufferSize)
{
if(!buffer)
return 0;
UINT8 counter = 0;
return 0;
UINT8 counter = 0;
while(bufferSize--)
counter += buffer[bufferSize];
@ -32,16 +32,16 @@ UINT8 calculateChecksum8(UINT8* buffer, UINT32 bufferSize)
UINT16 calculateChecksum16(UINT16* buffer, UINT32 bufferSize)
{
if(!buffer)
return 0;
return 0;
UINT16 counter = 0;
UINT32 index = 0;
UINT16 counter = 0;
UINT32 index = 0;
bufferSize /= sizeof(UINT16);
bufferSize /= sizeof(UINT16);
for (; index < bufferSize; index++) {
counter = (UINT16) (counter + buffer[index]);
}
for (; index < bufferSize; index++) {
counter = (UINT16) (counter + buffer[index]);
}
return (UINT16) 0x10000 - counter;
}
@ -167,7 +167,7 @@ QString sectionTypeToQString(const UINT8 type)
UINT32 sizeOfSectionHeaderOfType(const UINT8 type)
{
switch (type)
switch (type)
{
case EFI_SECTION_COMPRESSION:
return sizeof(EFI_COMMON_SECTION_HEADER);

30
ffs.h
View file

@ -56,7 +56,7 @@ typedef struct {
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
//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];
@ -77,17 +77,17 @@ typedef struct {
// Volume header
typedef struct {
UINT8 ZeroVector[16];
EFI_GUID FileSystemGuid;
UINT64 FvLength;
UINT32 Signature;
UINT32 Attributes;
UINT16 HeaderLength;
UINT16 Checksum;
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];
UINT8 Revision;
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1];
} EFI_FIRMWARE_VOLUME_HEADER;
// Filesystem GUIDs
@ -229,12 +229,12 @@ typedef union {
} EFI_FFS_INTEGRITY_CHECK;
// File header
typedef struct {
EFI_GUID Name;
EFI_GUID Name;
EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
UINT8 Type;
UINT8 Attributes;
UINT8 Size[3];
UINT8 State;
UINT8 Type;
UINT8 Attributes;
UINT8 Size[3];
UINT8 State;
} EFI_FFS_FILE_HEADER;
// Large file header

View file

@ -51,11 +51,16 @@ void FfsEngine::msg(const QString & message, const QModelIndex index)
messageItems.enqueue(MessageListItem(message, NULL, 0, index));
}
QQueue<MessageListItem> FfsEngine::message()
QQueue<MessageListItem> FfsEngine::messages()
{
return messageItems;
}
void FfsEngine::clearMessages()
{
messageItems.clear();
}
QModelIndex FfsEngine::findParentOfType(UINT8 type, const QModelIndex& index) const
{
if(!index.isValid())
@ -911,7 +916,7 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, UINT8 revision, const UINT8
// Add tree item
QModelIndex index = treeModel->addItem(TreeItem::File, fileHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, tail, parent, mode);
if (!parseCurrentFile)
return ERR_SUCCESS;
@ -1298,7 +1303,7 @@ UINT8 FfsEngine::changeCompression(const QModelIndex & index, const UINT8 algori
// Set compression for the item
treeModel->setItemCompression(algorithm, index);
// Set action for the item
// Set action for the item
treeModel->setItemAction(TreeItem::Modify, index);
return ERR_SUCCESS;
@ -1341,46 +1346,20 @@ UINT8 FfsEngine::decompress(const QByteArray & compressedData, const UINT8 compr
scratch = new UINT8[scratchSize];
// Decompress section data
//!TODO: better check needed
// Try EFI1.1 decompression first
if (ERR_SUCCESS != EfiDecompress(data, dataSize, decompressed, decompressedSize, scratch, scratchSize)) {
// Not EFI 1.1, try Tiano
if (ERR_SUCCESS != TianoDecompress(data, dataSize, decompressed, decompressedSize, scratch, scratchSize)) {
// 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)) {
if (algorithm)
*algorithm = COMPRESSION_ALGORITHM_UNKNOWN;
return ERR_STANDARD_DECOMPRESSION_FAILED;
}
else if (algorithm)
*algorithm = COMPRESSION_ALGORITHM_TIANO;
}
else {
// Possible EFI 1.1
// Try decompressing it as Tiano
UINT8* tianoDecompressed = new UINT8[decompressedSize];
UINT8* tianoScratch = new UINT8[scratchSize];
if (ERR_SUCCESS != TianoDecompress(data, dataSize, tianoDecompressed, decompressedSize, tianoScratch, scratchSize)) {
// Not Tiano, definitely EFI 1.1
if (algorithm)
*algorithm = COMPRESSION_ALGORITHM_EFI11;
}
else {
// Both algorithms work
if(memcmp(decompressed, tianoDecompressed, decompressedSize)) {
// If decompressed data are different - it's Tiano for sure
delete[] decompressed;
delete[] scratch;
decompressed = tianoDecompressed;
scratch = tianoScratch;
if (algorithm)
*algorithm = COMPRESSION_ALGORITHM_TIANO;
}
else {
// Data are same - it's EFI 1.1
if (algorithm)
*algorithm = COMPRESSION_ALGORITHM_EFI11;
}
}
*algorithm = COMPRESSION_ALGORITHM_EFI11;
}
else if (algorithm)
*algorithm = COMPRESSION_ALGORITHM_TIANO;
decompressedData = QByteArray((const char*) decompressed, decompressedSize);
// Free allocated memory
@ -1572,7 +1551,7 @@ UINT8 FfsEngine::reconstruct(const QModelIndex & index, QQueue<QByteArray> & que
QByteArray reconstructed;
UINT8 result;
// No action is needed, just return header + body
// No action is needed, just return header + body + tail
if (item->action() == TreeItem::NoAction) {
reconstructed = item->header().append(item->body()).append(item->tail());
queue.enqueue(reconstructed);
@ -1872,7 +1851,7 @@ UINT8 FfsEngine::reconstruct(const QModelIndex & index, QQueue<QByteArray> & que
}
}
// Append last file and fill the rest with empty char
// Append last file and fill the rest with empty char
else {
reconstructed.append(file);
UINT32 volumeBodySize = volumeSize - header.size();
@ -1903,7 +1882,7 @@ UINT8 FfsEngine::reconstruct(const QModelIndex & index, QQueue<QByteArray> & que
// Append current file to new volume body
reconstructed.append(file);
// Change current file offset
// Change current file offset
offset += file.size();
}
@ -2188,85 +2167,93 @@ UINT8 FfsEngine::growVolume(QByteArray & header, const UINT32 size, UINT32 & new
return ERR_SUCCESS;
}
// Will be refactored later
/*QByteArray FfsEngine::decompressFile(const QModelIndex& index) const
// Search routines
UINT8 FfsEngine::findHexPattern(const QByteArray & pattern, const bool bodyOnly)
{
if (!index.isValid())
return QByteArray();
// Check index item to be FFS file
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if(item->type() != TreeItem::File)
return QByteArray();
QByteArray file;
UINT32 offset = 0;
// Construct new item body
for (int i = 0; i < item->childCount(); i++) {
// If section is not compressed, add it to new body as is
TreeItem* sectionItem = item->child(i);
if (sectionItem->subtype() != EFI_SECTION_COMPRESSION) {
QByteArray section = sectionItem->header().append(sectionItem->body());
UINT32 align = ALIGN4(offset) - offset;
file.append(QByteArray(align, '\x00')).append(section);
offset += align + section.size();
return findHexPatternIn(treeModel->index(0,0), pattern, bodyOnly);
}
else {
// Construct new section body by adding all child sections to this new section
QByteArray section;
UINT32 subOffset = 0;
for (int j = 0; j < sectionItem->childCount(); j++)
UINT8 FfsEngine::findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const bool bodyOnly)
{
TreeItem* subSectionItem = sectionItem->child(j);
QByteArray subSection = subSectionItem->header().append(subSectionItem->body());
UINT32 align = ALIGN4(subOffset) - subOffset;
section.append(QByteArray(align, '\x00')).append(subSection);
subOffset += align + subSection.size();
}
// Add newly constructed section to file body
if (pattern.isEmpty())
return ERR_INVALID_PARAMETER;
if (!index.isValid())
return ERR_SUCCESS;
EFI_COMPRESSION_SECTION sectionHeader;
sectionHeader.Type = EFI_SECTION_COMPRESSION;
sectionHeader.CompressionType = EFI_NOT_COMPRESSED;
sectionHeader.UncompressedLength = section.size();
uint32ToUint24(section.size() + sizeof(EFI_COMPRESSION_SECTION), sectionHeader.Size);
UINT32 align = ALIGN4(offset) - offset;
file.append(QByteArray(align, '\x00'))
.append(QByteArray((const char*) &sectionHeader, sizeof(EFI_COMPRESSION_SECTION)))
.append(section);
offset += align + section.size();
}
TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
if (item == rootItem)
return ERR_SUCCESS;
bool hasChildren = (item->childCount() > 0);
for (int i = 0; i < item->childCount(); i++) {
findHexPatternIn(index.child(i, index.column()), pattern, bodyOnly);
}
QByteArray data;
if (hasChildren) {
if(!bodyOnly)
data = item->header();
}
else {
if (bodyOnly)
data = item->body();
else
data = item->header().append(item->body()).append(item->tail());
}
int offset = -1;
while ((offset = data.indexOf(pattern, offset + 1)) >= 0) {
msg(tr("Hex pattern \"%1\" found in %2 at offset %3")
.arg(QString(pattern.toHex()))
.arg(item->data(0).toString())
.arg(offset, 8, 16, QChar('0')),
index);
}
return ERR_SUCCESS;
}
QByteArray header = item->header();
EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*) header.data();
// Correct file data checksum, if needed
if (fileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
UINT32 bufferSize = file.size() - sizeof(EFI_FFS_FILE_HEADER);
fileHeader->IntegrityCheck.Checksum.File = calculateChecksum8((UINT8*)(file.data() + sizeof(EFI_FFS_FILE_HEADER)), bufferSize);
}
// Add file tail, if needed
if(fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT)
file.append(!fileHeader->IntegrityCheck.TailReference);
return header.append(file);
}*/
/*bool FfsEngine::isCompressedFile(const QModelIndex& index) const
UINT8 FfsEngine::findTextPattern(const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive)
{
if (!index.isValid())
return false;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if(item->type() != TreeItem::File)
return false;
for (int i = 0; i < item->childCount(); i++) {
if (item->child(i)->subtype() == EFI_SECTION_COMPRESSION)
return true;
return findTextPatternIn(treeModel->index(0,0), pattern, unicode, caseSensitive);
}
return false;
}*/
UINT8 FfsEngine::findTextPatternIn(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive)
{
if (pattern.isEmpty())
return ERR_INVALID_PARAMETER;
if (!index.isValid())
return ERR_SUCCESS;
TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
if (item == rootItem)
return ERR_SUCCESS;
bool hasChildren = (item->childCount() > 0);
for (int i = 0; i < item->childCount(); i++) {
findTextPatternIn(index.child(i, index.column()), pattern, unicode, caseSensitive);
}
if (hasChildren)
return ERR_SUCCESS;
QString data;
if (unicode)
data = QString::fromUtf16((const ushort*) item->body().data(), item->body().length()/2);
else
data = QString::fromAscii((const char*) item->body().data(), item->body().length());
int offset = -1;
while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) {
msg(tr("%1 text pattern \"%2\" found in %3 at offset %4")
.arg(unicode ? "Unicode" : "ASCII")
.arg(pattern)
.arg(item->data(0).toString())
.arg(unicode ? offset*2 : offset, 8, 16, QChar('0')),
index);
}
return ERR_SUCCESS;
}

View file

@ -38,7 +38,10 @@ public:
TreeModel* model() const;
// Returns message items queue
QQueue<MessageListItem> message();
QQueue<MessageListItem> messages();
// Clears message items queue
void clearMessages();
// Firmware image parsing
UINT8 parseInputFile(const QByteArray & buffer);
@ -74,6 +77,11 @@ public:
UINT8 rebuild(const QModelIndex & index);
UINT8 changeCompression(const QModelIndex & index, const UINT8 algorithm);
// Search routines
UINT8 findHexPattern(const QByteArray & pattern, const bool bodyOnly);
UINT8 findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const bool bodyOnly);
UINT8 findTextPattern(const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive);
UINT8 findTextPatternIn(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive);
private:
TreeItem *rootItem;
TreeModel *treeModel;

View file

@ -20,6 +20,10 @@ int main(int argc, char *argv[])
QApplication a(argc, argv);
UEFITool w;
QCoreApplication::setOrganizationName("CodeRush");
QCoreApplication::setOrganizationDomain("coderush.me");
QCoreApplication::setApplicationName("UEFITool");
if (a.arguments().length() > 1)
w.openImageFile(a.arguments().at(1));
w.show();

48
searchdialog.cpp Normal file
View file

@ -0,0 +1,48 @@
/* searchdialog.cpp
Copyright (c) 2013, 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 "searchdialog.h"
SearchDialog::SearchDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SearchDialog)
{
// Create UI
ui->setupUi(this);
// Connect
//connect(ui->dataTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setEditMask()));
//connect(ui->translateFromHexCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setEditMask()));
}
SearchDialog::~SearchDialog()
{
delete ui;
}
/*void SearchDialog::setEditMask()
{
int index = ui->dataTypeComboBox->currentIndex();
QString mask;
if (index == 0) // Hex pattern, max 48 bytes long
mask = "";
else if (index == 1) {
if (ui->translateFromHexCheckBox->isChecked())
mask = "<HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH;_";
else
mask = "<HHHHHHHH-HHHH-HHHH-HHHHHHHHHHHHHHHH;_";
}
else
mask = "";
ui->searchEdit->setInputMask(mask);
}*/

34
searchdialog.h Normal file
View file

@ -0,0 +1,34 @@
/* searchdialog.h
Copyright (c) 2013, 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 SEARCHDIALOG_H
#define SEARCHDIALOG_H
#include <QDialog>
#include "ui_searchdialog.h"
class SearchDialog : public QDialog
{
Q_OBJECT
public:
SearchDialog(QWidget *parent = 0);
~SearchDialog();
Ui::SearchDialog* ui;
private slots:
//void setEditMask();
};
#endif

199
searchdialog.ui Normal file
View file

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SearchDialog</class>
<widget class="QDialog" name="SearchDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>290</width>
<height>172</height>
</rect>
</property>
<property name="windowTitle">
<string>Search</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="searchForLabel">
<property name="text">
<string>Search for:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="dataTypeLabel">
<property name="text">
<string>Data type:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="searchEdit"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="dataTypeComboBox">
<item>
<property name="text">
<string>Hex pattern</string>
</property>
</item>
<item>
<property name="text">
<string>Text string</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="hexPage">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="hexGroupBox">
<property name="title">
<string>Hex pattern search scope</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="allRadioButton">
<property name="text">
<string>Header, data and footer</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="dataOnlyRadioButton">
<property name="text">
<string>Data only</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="textPage">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="textGroupBox">
<property name="title">
<string>Text string options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="unicodeCheckBox">
<property name="text">
<string>Unicode</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="caseSensitiveCheckBox">
<property name="text">
<string>Case sensitive</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>searchEdit</tabstop>
<tabstop>dataTypeComboBox</tabstop>
<tabstop>allRadioButton</tabstop>
<tabstop>dataOnlyRadioButton</tabstop>
<tabstop>unicodeCheckBox</tabstop>
<tabstop>caseSensitiveCheckBox</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SearchDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>173</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>216</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SearchDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>173</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>216</y>
</hint>
</hints>
</connection>
<connection>
<sender>dataTypeComboBox</sender>
<signal>activated(int)</signal>
<receiver>stackedWidget</receiver>
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
<x>151</x>
<y>42</y>
</hint>
<hint type="destinationlabel">
<x>88</x>
<y>68</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -172,7 +172,7 @@ QVariant TreeItem::data(int column) const
case 0: //Name
return itemName;
case 1: //Action
if (itemAction == TreeItem::Modify)
if (itemAction == TreeItem::Modify)
return "M";
if (itemAction == TreeItem::Remove)
return "X";

View file

@ -31,7 +31,7 @@ public:
// Action types
enum ActionTypes {
NoAction = 50,
Modify,
Modify,
Remove,
Rebuild
};

View file

@ -18,11 +18,15 @@ UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::UEFITool)
{
// Create UI
ui->setupUi(this);
ffsEngine = NULL;
//Connect
searchDialog = new SearchDialog(this);
ffsEngine = NULL;
// Connect signals to slots
connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile()));
connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile()));
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
connect(ui->actionExtract, SIGNAL(triggered()), this, SLOT(extractAsIs()));
connect(ui->actionExtractBody, SIGNAL(triggered()), this, SLOT(extractBody()));
connect(ui->actionExtractUncompressed, SIGNAL(triggered()), this, SLOT(extractUncompressed()));
@ -32,120 +36,51 @@ UEFITool::UEFITool(QWidget *parent) :
connect(ui->actionReplace, SIGNAL(triggered()), this, SLOT(replace()));
connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(remove()));
connect(ui->actionRebuild, SIGNAL(triggered()), this, SLOT(rebuild()));
connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile()));
connect(ui->actionChangeToNone, SIGNAL(triggered()), this, SLOT(changeToNone()));
connect(ui->actionChangeToNone, SIGNAL(triggered()), this, SLOT(changeToNone()));
connect(ui->actionChangeToEfi11, SIGNAL(triggered()), this, SLOT(changeToEfi11()));
connect(ui->actionChangeToTiano, SIGNAL(triggered()), this, SLOT(changeToTiano()));
connect(ui->actionChangeToLzma, SIGNAL(triggered()), this, SLOT(changeToLzma()));
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
connect(ui->actionMessagesClear, SIGNAL(triggered()), this, SLOT(clearMessages()));
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
connect(ui->actionAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt()));
connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(exit()));
// Enable Drag-and-Drop actions
this->setAcceptDrops(true);
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings()));
// Create menus
createMenus();
// Enable Drag-and-Drop actions
this->setAcceptDrops(true);
// Initialize non-persistent data
init();
}
void UEFITool::createMenus()
{
// Capsule
capsuleMenu.clear();
capsuleMenu.addAction(ui->actionExtract);
capsuleMenu.addAction(ui->actionExtractBody);
capsuleMenu.addSeparator();
capsuleMenu.addAction(ui->actionRebuild);
// Image
imageMenu.clear();
imageMenu.addAction(ui->actionExtract);
imageMenu.addSeparator();
imageMenu.addAction(ui->actionRebuild);
// Region
regionMenu.clear();
regionMenu.addAction(ui->actionExtract);
regionMenu.addSeparator();
regionMenu.addAction(ui->actionRebuild);
// Padding
paddingMenu.clear();
paddingMenu.addAction(ui->actionExtract);
// Volume
volumeMenu.clear();
volumeMenu.addAction(ui->actionExtract);
volumeMenu.addAction(ui->actionExtractBody);
volumeMenu.addSeparator();
volumeMenu.addAction(ui->actionRebuild);
volumeMenu.addSeparator();
volumeMenu.addAction(ui->actionInsertInto);
volumeMenu.addSeparator();
volumeMenu.addAction(ui->actionRemove);
// File
fileMenu.clear();
fileMenu.addAction(ui->actionExtract);
fileMenu.addAction(ui->actionExtractBody);
//fileMenu.addAction(ui->actionExtractUncompressed);
fileMenu.addSeparator();
fileMenu.addAction(ui->actionRebuild);
fileMenu.addSeparator();
fileMenu.addAction(ui->actionInsertInto);
fileMenu.addAction(ui->actionInsertBefore);
fileMenu.addAction(ui->actionInsertAfter);
fileMenu.addSeparator();
fileMenu.addAction(ui->actionRemove);
// Section
sectionMenu.clear();
sectionMenu.addAction(ui->actionExtract);
sectionMenu.addAction(ui->actionExtractBody);
//sectionMenu.addAction(ui->actionExtractUncompressed);
sectionMenu.addSeparator();
sectionMenu.addAction(ui->actionRebuild);
sectionMenu.addSeparator();
sectionMenu.addAction(ui->actionInsertInto);
sectionMenu.addAction(ui->actionInsertBefore);
sectionMenu.addAction(ui->actionInsertAfter);
sectionMenu.addSeparator();
sectionMenu.addAction(ui->actionRemove);
sectionMenu.addSeparator();
sectionMenu.addMenu(ui->menuChangeCompressionTo);
// Read stored settings
readSettings();
}
UEFITool::~UEFITool()
{
delete ui;
delete ffsEngine;
delete searchDialog;
}
void UEFITool::init()
{
// Clear components
// Clear components
ui->messageListWidget->clear();
ui->infoEdit->clear();
// Disable actions and menus
ui->actionExtract->setDisabled(true);
ui->actionExtractBody->setDisabled(true);
ui->actionExtractUncompressed->setDisabled(true);
ui->actionReplace->setDisabled(true);
ui->actionRemove->setDisabled(true);
ui->actionRebuild->setDisabled(true);
ui->actionInsertInto->setDisabled(true);
ui->actionInsertBefore->setDisabled(true);
ui->actionInsertAfter->setDisabled(true);
ui->actionSaveImageFile->setDisabled(true);
ui->menuChangeCompressionTo->setDisabled(true);
// Disable menus
ui->menuCapsuleActions->setDisabled(true);
ui->menuImageActions->setDisabled(true);
ui->menuRegionActions->setDisabled(true);
ui->menuPaddingActions->setDisabled(true);
ui->menuVolumeActions->setDisabled(true);
ui->menuFileActions->setDisabled(true);
ui->menuSectionActions->setDisabled(true);
// Make new ffsEngine
if (ffsEngine)
delete ffsEngine;
if (ffsEngine)
delete ffsEngine;
ffsEngine = new FfsEngine(this);
ui->structureTreeView->setModel(ffsEngine->model());
@ -155,8 +90,6 @@ void UEFITool::init()
connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
this, SLOT(populateUi(const QModelIndex &)));
connect(ui->messageListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
resizeTreeViewColums();
}
void UEFITool::populateUi(const QModelIndex &current)
@ -168,8 +101,20 @@ void UEFITool::populateUi(const QModelIndex &current)
UINT8 type = item->type();
UINT8 subtype = item->subtype();
UINT8 algorithm = item->compression();
// Set info text
ui->infoEdit->setPlainText(item->info());
// Enable menus
ui->menuCapsuleActions->setEnabled(type == TreeItem::Capsule);
ui->menuImageActions->setEnabled(type == TreeItem::Image);
ui->menuRegionActions->setEnabled(type == TreeItem::Region);
ui->menuPaddingActions->setEnabled(type == TreeItem::Padding);
ui->menuVolumeActions->setEnabled(type == TreeItem::Volume);
ui->menuFileActions->setEnabled(type == TreeItem::File);
ui->menuSectionActions->setEnabled(type == TreeItem::Section);
// Enable actions
ui->actionExtract->setDisabled(item->hasEmptyHeader() && item->hasEmptyBody() && item->hasEmptyTail());
ui->actionRebuild->setDisabled(item->hasEmptyHeader() && item->hasEmptyBody() && item->hasEmptyTail());
ui->actionExtractBody->setDisabled(item->hasEmptyHeader());
@ -178,10 +123,33 @@ void UEFITool::populateUi(const QModelIndex &current)
|| (type == TreeItem::Section && (subtype == EFI_SECTION_COMPRESSION || subtype == EFI_SECTION_GUID_DEFINED || subtype == EFI_SECTION_DISPOSABLE)));
ui->actionInsertBefore->setEnabled(type == TreeItem::File || type == TreeItem::Section);
ui->actionInsertAfter->setEnabled(type == TreeItem::File || type == TreeItem::Section);
ui->menuChangeCompressionTo->setEnabled(type == TreeItem::Section && subtype == EFI_SECTION_COMPRESSION &&
ui->menuChangeCompressionTo->setEnabled(type == TreeItem::Section && subtype == EFI_SECTION_COMPRESSION &&
(algorithm == COMPRESSION_ALGORITHM_NONE || COMPRESSION_ALGORITHM_EFI11 || algorithm == COMPRESSION_ALGORITHM_TIANO || algorithm == COMPRESSION_ALGORITHM_LZMA));
}
void UEFITool::search()
{
if (searchDialog->exec() != QDialog::Accepted)
return;
int index = searchDialog->ui->dataTypeComboBox->currentIndex();
if (index == 0) { // Hex pattern
QByteArray pattern = QByteArray::fromHex(searchDialog->ui->searchEdit->text().toAscii());
if (pattern.isEmpty())
return;
ffsEngine->findHexPattern(pattern, searchDialog->ui->dataOnlyRadioButton->isChecked());
showMessages();
}
else if (index == 1) { // Text string
QString pattern = searchDialog->ui->searchEdit->text();
if (pattern.isEmpty())
return;
ffsEngine->findTextPattern(pattern, searchDialog->ui->unicodeCheckBox->isChecked(),
(Qt::CaseSensitivity) searchDialog->ui->caseSensitiveCheckBox->isChecked());
showMessages();
}
}
void UEFITool::rebuild()
{
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
@ -214,7 +182,7 @@ void UEFITool::insert(const UINT8 mode)
TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
UINT8 type;
UINT8 objectType;
UINT8 objectType;
if (mode == INSERT_MODE_BEFORE || mode == INSERT_MODE_AFTER)
type = item->parent()->type();
@ -225,12 +193,12 @@ void UEFITool::insert(const UINT8 mode)
switch (type) {
case TreeItem::Volume:
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"),".","FFS files (*.ffs *.bin);;All files (*.*)");
objectType = TreeItem::File;
objectType = TreeItem::File;
break;
case TreeItem::File:
case TreeItem::Section:
path = QFileDialog::getOpenFileName(this, tr("Select section file to insert"),".","Section files (*.sct *.bin);;All files (*.*)");
objectType = TreeItem::Section;
objectType = TreeItem::Section;
break;
default:
return;
@ -327,14 +295,14 @@ void UEFITool::changeToNone()
void UEFITool::about()
{
QMessageBox::about(this, tr("About UEFITool"), tr(
"Copyright (c) 2013, Nikolaj Schlej aka <b>CodeRush</b>.<br><br>"
"The program is dedicated to <b>RevoGirl</b>. Rest in peace, young genius.<br><br>"
"The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License.<br>"
"The full text of the license may be found at <a href=http://opensource.org/licenses/bsd-license.php>OpenSource.org</a>.<br><br>"
"<b>THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, "
"WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, "
"EITHER EXPRESS OR IMPLIED.</b>"));
QMessageBox::about(this, tr("About UEFITool"), tr(
"Copyright (c) 2013, Nikolaj Schlej aka <b>CodeRush</b>.<br><br>"
"The program is dedicated to <b>RevoGirl</b>. Rest in peace, young genius.<br><br>"
"The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License.<br>"
"The full text of the license may be found at <a href=http://opensource.org/licenses/bsd-license.php>OpenSource.org</a>.<br><br>"
"<b>THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, "
"WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, "
"EITHER EXPRESS OR IMPLIED.</b>"));
}
void UEFITool::aboutQt()
@ -344,7 +312,7 @@ void UEFITool::aboutQt()
void UEFITool::exit()
{
QCoreApplication::exit(0);
QCoreApplication::exit(0);
}
void UEFITool::saveImageFile()
@ -360,7 +328,7 @@ void UEFITool::saveImageFile()
QByteArray reconstructed;
UINT8 result = ffsEngine->reconstructImage(reconstructed);
showMessage();
showMessages();
if (result) {
ui->statusBar->showMessage(tr("Reconstruction failed (%1)").arg(result));
return;
@ -372,7 +340,7 @@ void UEFITool::saveImageFile()
ui->statusBar->showMessage(tr("Reconstructed image written"));
}
void UEFITool::resizeTreeViewColums()
void UEFITool::resizeTreeViewColumns()
{
int count = ffsEngine->model()->columnCount();
for(int i = 0; i < count; i++)
@ -406,13 +374,21 @@ void UEFITool::openImageFile(QString path)
init();
UINT8 result = ffsEngine->parseInputFile(buffer);
showMessage();
if (result)
showMessages();
if (result)
ui->statusBar->showMessage(tr("Opened file can't be parsed (%1)").arg(result));
else
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
resizeTreeViewColums();
// Enable search
ui->actionSearch->setEnabled(true);
}
void UEFITool::clearMessages()
{
ffsEngine->clearMessages();
messageItems.clear();
ui->messageListWidget->clear();
}
void UEFITool::extract(const UINT8 mode)
@ -425,35 +401,35 @@ void UEFITool::extract(const UINT8 mode)
UINT8 type = item->type();
QString path;
if(mode == EXTRACT_MODE_AS_IS) {
switch (type) {
case TreeItem::Capsule:
path = QFileDialog::getSaveFileName(this, tr("Save capsule to binary file"),".","Capsule files (*.cap *.bin);;All files (*.*)");
break;
case TreeItem::Image:
path = QFileDialog::getSaveFileName(this, tr("Save image to binary file"),".","Image files (*.rom *.bin);;All files (*.*)");
break;
case TreeItem::Region:
path = QFileDialog::getSaveFileName(this, tr("Save region to binary file"),".","Region files (*.rgn *.bin);;All files (*.*)");
break;
case TreeItem::Padding:
path = QFileDialog::getSaveFileName(this, tr("Save padding to binary file"),".","Padding files (*.pad *.bin);;All files (*.*)");
break;
case TreeItem::Volume:
path = QFileDialog::getSaveFileName(this, tr("Save volume to binary file"),".","Volume files (*.vol *.bin);;All files (*.*)");
break;
case TreeItem::File:
path = QFileDialog::getSaveFileName(this, tr("Save FFS file to binary file"),".","FFS files (*.ffs *.bin);;All files (*.*)");
break;
case TreeItem::Section:
path = QFileDialog::getSaveFileName(this, tr("Save section file to binary file"),".","Section files (*.sct *.bin);;All files (*.*)");
break;
default:
return;
}
}
else
path = QFileDialog::getSaveFileName(this, tr("Save object to binary file"),".","Binary files (*.bin);;All files (*.*)");
if(mode == EXTRACT_MODE_AS_IS) {
switch (type) {
case TreeItem::Capsule:
path = QFileDialog::getSaveFileName(this, tr("Save capsule to binary file"),".","Capsule files (*.cap *.bin);;All files (*.*)");
break;
case TreeItem::Image:
path = QFileDialog::getSaveFileName(this, tr("Save image to binary file"),".","Image files (*.rom *.bin);;All files (*.*)");
break;
case TreeItem::Region:
path = QFileDialog::getSaveFileName(this, tr("Save region to binary file"),".","Region files (*.rgn *.bin);;All files (*.*)");
break;
case TreeItem::Padding:
path = QFileDialog::getSaveFileName(this, tr("Save padding to binary file"),".","Padding files (*.pad *.bin);;All files (*.*)");
break;
case TreeItem::Volume:
path = QFileDialog::getSaveFileName(this, tr("Save volume to binary file"),".","Volume files (*.vol *.bin);;All files (*.*)");
break;
case TreeItem::File:
path = QFileDialog::getSaveFileName(this, tr("Save FFS file to binary file"),".","FFS files (*.ffs *.bin);;All files (*.*)");
break;
case TreeItem::Section:
path = QFileDialog::getSaveFileName(this, tr("Save section file to binary file"),".","Section files (*.sct *.bin);;All files (*.*)");
break;
default:
return;
}
}
else
path = QFileDialog::getSaveFileName(this, tr("Save object to binary file"),".","Binary files (*.bin);;All files (*.*)");
QFile outputFile;
outputFile.setFileName(path);
@ -500,13 +476,13 @@ void UEFITool::dropEvent(QDropEvent* event)
openImageFile(path);
}
void UEFITool::showMessage()
void UEFITool::showMessages()
{
ui->messageListWidget->clear();
if (!ffsEngine)
return;
if (!ffsEngine)
return;
messageItems = ffsEngine->message();
messageItems = ffsEngine->messages();
for (int i = 0; i < messageItems.count(); i++) {
ui->messageListWidget->addItem(new MessageListItem(messageItems.at(i)));
}
@ -516,46 +492,87 @@ void UEFITool::scrollTreeView(QListWidgetItem* item)
{
MessageListItem* messageItem = (MessageListItem*) item;
QModelIndex index = messageItem->index();
if (index.isValid()) {
ui->structureTreeView->scrollTo(index);
if (index.isValid()) {
ui->structureTreeView->scrollTo(index);
ui->structureTreeView->selectionModel()->clearSelection();
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select);
}
}
void UEFITool::contextMenuEvent (QContextMenuEvent* event)
void UEFITool::contextMenuEvent(QContextMenuEvent* event)
{
if(!ui->structureTreeView->underMouse())
if (ui->messageListWidget->underMouse()) {
ui->menuMessages->exec(event->globalPos());
return;
QPoint pt = event->pos();
QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt));
if(!index.isValid())
return;
TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
switch(item->type())
{
case TreeItem::Capsule:
capsuleMenu.exec(event->globalPos());
break;
case TreeItem::Image:
imageMenu.exec(event->globalPos());
break;
case TreeItem::Region:
regionMenu.exec(event->globalPos());
break;
case TreeItem::Padding:
paddingMenu.exec(event->globalPos());
break;
case TreeItem::Volume:
volumeMenu.exec(event->globalPos());
break;
case TreeItem::File:
fileMenu.exec(event->globalPos());
break;
case TreeItem::Section:
sectionMenu.exec(event->globalPos());
break;
}
if(!ui->structureTreeView->underMouse())
return;
QPoint pt = event->pos();
QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt));
if(!index.isValid())
return;
TreeItem* item = static_cast<TreeItem*>(index.internalPointer());
switch(item->type())
{
case TreeItem::Capsule:
ui->menuCapsuleActions->exec(event->globalPos());
break;
case TreeItem::Image:
ui->menuImageActions->exec(event->globalPos());
break;
case TreeItem::Region:
ui->menuRegionActions->exec(event->globalPos());
break;
case TreeItem::Padding:
ui->menuPaddingActions->exec(event->globalPos());
break;
case TreeItem::Volume:
ui->menuVolumeActions->exec(event->globalPos());
break;
case TreeItem::File:
ui->menuFileActions->exec(event->globalPos());
break;
case TreeItem::Section:
ui->menuSectionActions->exec(event->globalPos());
break;
}
}
void UEFITool::readSettings()
{
QSettings settings("UEFITool.ini", QSettings::IniFormat, this);
resize(settings.value("mainWindow/size", QSize(800, 600)).toSize());
move(settings.value("mainWindow/position", QPoint(0, 0)).toPoint());
QList<int> horList, vertList;
horList.append(settings.value("mainWindow/treeWidth", 600).toInt());
horList.append(settings.value("mainWindow/infoWidth", 180).toInt());
vertList.append(settings.value("mainWindow/treeHeight", 400).toInt());
vertList.append(settings.value("mainWindow/messageHeight", 180).toInt());
ui->infoSplitter->setSizes(horList);
ui->messagesSplitter->setSizes(vertList);
resizeTreeViewColumns();
ui->structureTreeView->setColumnWidth(0, settings.value("tree/columnWidth0", ui->structureTreeView->columnWidth(0)).toInt());
ui->structureTreeView->setColumnWidth(1, settings.value("tree/columnWidth1", ui->structureTreeView->columnWidth(1)).toInt());
ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt());
ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt());
//ui->structureTreeView->setColumnWidth(4, settings.value("tree/columnWidth4", 10).toInt());
}
void UEFITool::writeSettings()
{
QSettings settings("UEFITool.ini", QSettings::IniFormat, this);
settings.setValue("mainWindow/size", size());
settings.setValue("mainWindow/position", pos());
settings.setValue("mainWindow/treeWidth", ui->structureGroupBox->width());
settings.setValue("mainWindow/infoWidth", ui->infoGroupBox->width());
settings.setValue("mainWindow/treeHeight", ui->structureGroupBox->height());
settings.setValue("mainWindow/messageHeight", ui->messageGroupBox->height());
settings.setValue("tree/columnWidth0", ui->structureTreeView->columnWidth(0));
settings.setValue("tree/columnWidth1", ui->structureTreeView->columnWidth(1));
settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2));
settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3));
//settings.setValue("tree/columnWidth4", ui->structureTreeView->columnWidth(4));
}

View file

@ -21,18 +21,24 @@
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QListWidget>
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
#include <QPlainTextEdit>
#include <QSettings>
#include <QSplitter>
#include <QString>
#include <QTreeView>
#include <QUrl>
#include "basetypes.h"
#include "ffs.h"
#include "ffsengine.h"
#include "searchdialog.h"
namespace Ui {
class UEFITool;
class UEFITool;
}
class UEFITool : public QMainWindow
@ -47,58 +53,55 @@ public:
private slots:
void init();
void populateUi(const QModelIndex &current);
void openImageFile();
void saveImageFile();
void resizeTreeViewColums();
void populateUi(const QModelIndex &current);
void resizeTreeViewColumns();
void scrollTreeView(QListWidgetItem* item);
void extract(const UINT8 mode);
void openImageFile();
void saveImageFile();
void search();
void extract(const UINT8 mode);
void extractAsIs();
void extractBody();
void extractUncompressed();
void insert(const UINT8 mode);
void insert(const UINT8 mode);
void insertInto();
void insertBefore();
void insertAfter();
void replace();
void replace();
void remove();
void remove();
void rebuild();
void changeToNone();
void rebuild();
void changeToNone();
void changeToEfi11();
void changeToTiano();
void changeToLzma();
void about();
void clearMessages();
void about();
void aboutQt();
void exit();
void writeSettings();
private:
Ui::UEFITool * ui;
Ui::UEFITool* ui;
FfsEngine* ffsEngine;
QQueue<MessageListItem> messageItems;
void showMessage();
SearchDialog* searchDialog;
QMenu capsuleMenu;
QMenu imageMenu;
QMenu regionMenu;
QMenu paddingMenu;
QMenu volumeMenu;
QMenu fileMenu;
QMenu sectionMenu;
void createMenus();
QQueue<MessageListItem> messageItems;
void showMessages();
void dragEnterEvent(QDragEnterEvent* event);
void dropEvent(QDropEvent* event);
void contextMenuEvent (QContextMenuEvent* event);
void contextMenuEvent(QContextMenuEvent* event);
void readSettings();
};
#endif

View file

@ -6,6 +6,7 @@ TEMPLATE = app
SOURCES += main.cpp \
uefitool.cpp \
searchdialog.cpp \
descriptor.cpp \
ffs.cpp \
ffsengine.cpp \
@ -20,7 +21,9 @@ SOURCES += main.cpp \
Tiano/EfiTianoDecompress.c \
Tiano/EfiCompress.c \
Tiano/TianoCompress.c
HEADERS += uefitool.h \
searchdialog.h \
basetypes.h \
descriptor.h \
gbe.h \
@ -34,6 +37,10 @@ HEADERS += uefitool.h \
LZMA/LzmaDecompress.h \
Tiano/EfiTianoDecompress.h \
Tiano/EfiTianoCompress.h
FORMS += uefitool.ui
FORMS += uefitool.ui \
searchdialog.ui
RC_FILE = uefitool.rc
ICON = uefitool.icns

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
<width>834</width>
<height>499</height>
</rect>
</property>
<property name="sizePolicy">
@ -20,7 +20,7 @@
<bool>true</bool>
</property>
<property name="windowTitle">
<string>UEFITool 0.10.0</string>
<string>UEFITool 0.11.0</string>
</property>
<widget class="QWidget" name="centralWidget">
<property name="sizePolicy">
@ -29,51 +29,106 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>5</number>
<number>0</number>
</property>
<property name="margin">
<number>8</number>
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Structure</string>
<widget class="QSplitter" name="messagesSplitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>5</number>
<widget class="QSplitter" name="infoSplitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="margin">
<number>8</number>
<widget class="QGroupBox" name="structureGroupBox">
<property name="title">
<string>Structure</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>5</number>
</property>
<item>
<widget class="QTreeView" name="structureTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="indentation">
<number>10</number>
</property>
<property name="headerHidden">
<bool>false</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="headerDefaultSectionSize">
<number>200</number>
</attribute>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="infoGroupBox">
<property name="title">
<string>Information</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>5</number>
</property>
<item>
<widget class="QPlainTextEdit" name="infoEdit">
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="centerOnScroll">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QGroupBox" name="messageGroupBox">
<property name="title">
<string>Messages</string>
</property>
<item>
<widget class="QTreeView" name="structureTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="indentation">
<number>10</number>
</property>
<property name="headerHidden">
<bool>false</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="headerDefaultSectionSize">
<number>200</number>
</attribute>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
</layout>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>5</number>
</property>
<item>
<widget class="QListWidget" name="messageListWidget"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
@ -84,7 +139,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<width>834</width>
<height>21</height>
</rect>
</property>
@ -95,40 +150,10 @@
<addaction name="actionOpenImageFile"/>
<addaction name="actionSaveImageFile"/>
<addaction name="separator"/>
<addaction name="actionSearch"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuAction">
<property name="title">
<string>A&amp;ction</string>
</property>
<widget class="QMenu" name="menuChangeCompressionTo">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Change &amp;compression to</string>
</property>
<addaction name="actionChangeToNone"/>
<addaction name="actionChangeToTiano"/>
<addaction name="actionChangeToEfi11"/>
<addaction name="actionChangeToLzma"/>
</widget>
<addaction name="actionRebuild"/>
<addaction name="separator"/>
<addaction name="actionRemove"/>
<addaction name="separator"/>
<addaction name="actionExtract"/>
<addaction name="actionExtractBody"/>
<addaction name="actionExtractUncompressed"/>
<addaction name="separator"/>
<addaction name="actionInsertInto"/>
<addaction name="actionInsertAfter"/>
<addaction name="actionInsertBefore"/>
<addaction name="separator"/>
<addaction name="actionReplace"/>
<addaction name="separator"/>
<addaction name="menuChangeCompressionTo"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>H&amp;elp</string>
@ -136,101 +161,115 @@
<addaction name="actionAbout"/>
<addaction name="actionAboutQt"/>
</widget>
<widget class="QMenu" name="menuAction">
<property name="title">
<string>&amp;Action</string>
</property>
<widget class="QMenu" name="menuCapsuleActions">
<property name="title">
<string>&amp;Capsule</string>
</property>
<addaction name="actionExtract"/>
<addaction name="actionExtractBody"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
</widget>
<widget class="QMenu" name="menuImageActions">
<property name="title">
<string>&amp;Image</string>
</property>
<addaction name="actionExtract"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
</widget>
<widget class="QMenu" name="menuRegionActions">
<property name="title">
<string>&amp;Region</string>
</property>
<addaction name="actionExtract"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
</widget>
<widget class="QMenu" name="menuPaddingActions">
<property name="title">
<string>&amp;Padding</string>
</property>
<addaction name="actionExtract"/>
</widget>
<widget class="QMenu" name="menuVolumeActions">
<property name="title">
<string>&amp;Volume</string>
</property>
<addaction name="actionExtract"/>
<addaction name="actionExtractBody"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
<addaction name="separator"/>
<addaction name="actionInsertInto"/>
<addaction name="separator"/>
<addaction name="actionRemove"/>
</widget>
<widget class="QMenu" name="menuFileActions">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="actionExtract"/>
<addaction name="actionExtractBody"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
<addaction name="separator"/>
<addaction name="actionInsertInto"/>
<addaction name="actionInsertBefore"/>
<addaction name="actionInsertAfter"/>
<addaction name="separator"/>
<addaction name="actionRemove"/>
</widget>
<widget class="QMenu" name="menuSectionActions">
<property name="title">
<string>&amp;Section</string>
</property>
<widget class="QMenu" name="menuChangeCompressionTo">
<property name="title">
<string>Change compression to</string>
</property>
<addaction name="actionChangeToNone"/>
<addaction name="actionChangeToTiano"/>
<addaction name="actionChangeToEfi11"/>
<addaction name="actionChangeToLzma"/>
</widget>
<addaction name="actionExtract"/>
<addaction name="actionExtractBody"/>
<addaction name="separator"/>
<addaction name="actionRebuild"/>
<addaction name="separator"/>
<addaction name="actionInsertInto"/>
<addaction name="actionInsertBefore"/>
<addaction name="actionInsertAfter"/>
<addaction name="separator"/>
<addaction name="actionRemove"/>
<addaction name="separator"/>
<addaction name="menuChangeCompressionTo"/>
</widget>
<widget class="QMenu" name="menuMessages">
<property name="title">
<string>&amp;Messages</string>
</property>
<addaction name="actionMessagesClear"/>
</widget>
<addaction name="menuCapsuleActions"/>
<addaction name="menuImageActions"/>
<addaction name="menuRegionActions"/>
<addaction name="menuPaddingActions"/>
<addaction name="menuVolumeActions"/>
<addaction name="menuFileActions"/>
<addaction name="menuSectionActions"/>
<addaction name="separator"/>
<addaction name="menuMessages"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuAction"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QDockWidget" name="infoDockWidget">
<property name="minimumSize">
<size>
<width>89</width>
<height>111</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>180</width>
<height>524287</height>
</size>
</property>
<property name="features">
<set>QDockWidget::DockWidgetMovable</set>
</property>
<property name="allowedAreas">
<set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Information</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>5</number>
</property>
<property name="margin">
<number>8</number>
</property>
<item>
<widget class="QPlainTextEdit" name="infoEdit">
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="centerOnScroll">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="messageDockWidget">
<property name="minimumSize">
<size>
<width>91</width>
<height>113</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>524287</width>
<height>113</height>
</size>
</property>
<property name="features">
<set>QDockWidget::DockWidgetMovable</set>
</property>
<property name="allowedAreas">
<set>Qt::BottomDockWidgetArea|Qt::TopDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Messages</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>5</number>
</property>
<property name="margin">
<number>8</number>
</property>
<item>
<widget class="QListWidget" name="messageListWidget"/>
</item>
</layout>
</widget>
</widget>
<action name="actionInsertAfter">
<property name="enabled">
<bool>false</bool>
@ -441,6 +480,25 @@
<string>Ctrl+U</string>
</property>
</action>
<action name="actionSearch">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Sear&amp;ch...</string>
</property>
<property name="shortcut">
<string>Ctrl+F</string>
</property>
</action>
<action name="actionMessagesClear">
<property name="text">
<string>&amp;Clear</string>
</property>
<property name="shortcut">
<string>Ctrl+Backspace</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>