mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-25 17:38:22 +08:00
Implement custom LZMA dictionary size for NE
This commit is contained in:
parent
f074dfc5ca
commit
be2cdc7dfe
@ -64,7 +64,8 @@ LzmaCompress (
|
|||||||
CONST UINT8 *Source,
|
CONST UINT8 *Source,
|
||||||
UINT32 SourceSize,
|
UINT32 SourceSize,
|
||||||
UINT8 *Destination,
|
UINT8 *Destination,
|
||||||
UINT32 *DestinationSize
|
UINT32 *DestinationSize,
|
||||||
|
UINT32 DictionarySize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SRes LzmaResult;
|
SRes LzmaResult;
|
||||||
@ -79,8 +80,7 @@ LzmaCompress (
|
|||||||
}
|
}
|
||||||
|
|
||||||
LzmaEncProps_Init(&props);
|
LzmaEncProps_Init(&props);
|
||||||
// TODO: need to detect this instead of hardcoding
|
props.dictSize = DictionarySize;
|
||||||
props.dictSize = LZMA_DICTIONARY_SIZE;
|
|
||||||
props.level = 9;
|
props.level = 9;
|
||||||
props.fb = 273;
|
props.fb = 273;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LZMA_DICTIONARY_SIZE 0x800000
|
#define DEFAULT_LZMA_DICTIONARY_SIZE 0x800000
|
||||||
#define _LZMA_SIZE_OPT
|
#define _LZMA_SIZE_OPT
|
||||||
|
|
||||||
USTATUS
|
USTATUS
|
||||||
@ -30,7 +30,8 @@ extern "C" {
|
|||||||
const UINT8 *Source,
|
const UINT8 *Source,
|
||||||
UINT32 SourceSize,
|
UINT32 SourceSize,
|
||||||
UINT8 *Destination,
|
UINT8 *Destination,
|
||||||
UINT32 *DestinationSize
|
UINT32 *DestinationSize,
|
||||||
|
UINT32 DictionarySize
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -45,31 +45,32 @@ typedef size_t USTATUS;
|
|||||||
#define U_CUSTOMIZED_COMPRESSION_FAILED 23
|
#define U_CUSTOMIZED_COMPRESSION_FAILED 23
|
||||||
#define U_STANDARD_DECOMPRESSION_FAILED 24
|
#define U_STANDARD_DECOMPRESSION_FAILED 24
|
||||||
#define U_CUSTOMIZED_DECOMPRESSION_FAILED 25
|
#define U_CUSTOMIZED_DECOMPRESSION_FAILED 25
|
||||||
#define U_UNKNOWN_COMPRESSION_TYPE 26
|
#define U_GZIP_DECOMPRESSION_FAILED 26
|
||||||
#define U_DEPEX_PARSE_FAILED 27
|
#define U_UNKNOWN_COMPRESSION_TYPE 27
|
||||||
#define U_UNKNOWN_EXTRACT_MODE 28
|
#define U_DEPEX_PARSE_FAILED 28
|
||||||
#define U_UNKNOWN_REPLACE_MODE 29
|
#define U_UNKNOWN_EXTRACT_MODE 29
|
||||||
#define U_UNKNOWN_IMAGE_TYPE 30
|
#define U_UNKNOWN_REPLACE_MODE 30
|
||||||
#define U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 31
|
#define U_UNKNOWN_IMAGE_TYPE 31
|
||||||
#define U_UNKNOWN_RELOCATION_TYPE 32
|
#define U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 32
|
||||||
#define U_DIR_ALREADY_EXIST 33
|
#define U_UNKNOWN_RELOCATION_TYPE 33
|
||||||
#define U_DIR_CREATE 34
|
#define U_DIR_ALREADY_EXIST 34
|
||||||
#define U_DIR_CHANGE 35
|
#define U_DIR_CREATE 35
|
||||||
#define U_TRUNCATED_IMAGE 36
|
#define U_DIR_CHANGE 36
|
||||||
#define U_INVALID_CAPSULE 37
|
#define U_TRUNCATED_IMAGE 37
|
||||||
#define U_STORES_NOT_FOUND 38
|
#define U_INVALID_CAPSULE 38
|
||||||
#define U_INVALID_IMAGE 39
|
#define U_STORES_NOT_FOUND 39
|
||||||
#define U_INVALID_RAW_AREA 40
|
#define U_INVALID_IMAGE 40
|
||||||
#define U_INVALID_FIT 41
|
#define U_INVALID_RAW_AREA 41
|
||||||
#define U_INVALID_MICROCODE 42
|
#define U_INVALID_FIT 42
|
||||||
#define U_INVALID_ACM 43
|
#define U_INVALID_MICROCODE 43
|
||||||
#define U_INVALID_BG_KEY_MANIFEST 44
|
#define U_INVALID_ACM 44
|
||||||
#define U_INVALID_BG_BOOT_POLICY 45
|
#define U_INVALID_BG_KEY_MANIFEST 45
|
||||||
#define U_INVALID_TXT_CONF 46
|
#define U_INVALID_BG_BOOT_POLICY 46
|
||||||
#define U_ELEMENTS_NOT_FOUND 47
|
#define U_INVALID_TXT_CONF 47
|
||||||
|
#define U_ELEMENTS_NOT_FOUND 48
|
||||||
#define U_NOT_IMPLEMENTED 0xFF
|
#define U_NOT_IMPLEMENTED 0xFF
|
||||||
|
|
||||||
// UDK porting definitions
|
// EDK2 porting definitions
|
||||||
typedef uint8_t BOOLEAN;
|
typedef uint8_t BOOLEAN;
|
||||||
typedef int8_t INT8;
|
typedef int8_t INT8;
|
||||||
typedef uint8_t UINT8;
|
typedef uint8_t UINT8;
|
||||||
|
@ -1285,81 +1285,75 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
|
|||||||
|
|
||||||
while (fileOffset < volumeBodySize) {
|
while (fileOffset < volumeBodySize) {
|
||||||
UINT32 fileSize = getFileSize(volumeBody, fileOffset, ffsVersion);
|
UINT32 fileSize = getFileSize(volumeBody, fileOffset, ffsVersion);
|
||||||
// Check file size
|
|
||||||
if (fileSize < sizeof(EFI_FFS_FILE_HEADER) || fileSize > volumeBodySize - fileOffset) {
|
// Check that we are at the empty space
|
||||||
// Check that we are at the empty space
|
UByteArray header = volumeBody.mid(fileOffset, std::min(sizeof(EFI_FFS_FILE_HEADER), (size_t)volumeBodySize - fileOffset));
|
||||||
UByteArray header = volumeBody.mid(fileOffset, sizeof(EFI_FFS_FILE_HEADER));
|
if (header.count(emptyByte) == header.size()) { //Empty space
|
||||||
if (header.count(emptyByte) == header.size()) { //Empty space
|
// Check volume usedSpace entry to be valid
|
||||||
// Check volume usedSpace entry to be valid
|
if (usedSpace > 0 && usedSpace == fileOffset + volumeHeaderSize) {
|
||||||
if (usedSpace > 0 && usedSpace == fileOffset + volumeHeaderSize) {
|
if (model->hasEmptyParsingData(index) == false) {
|
||||||
if (model->hasEmptyParsingData(index) == false) {
|
UByteArray data = model->parsingData(index);
|
||||||
UByteArray data = model->parsingData(index);
|
VOLUME_PARSING_DATA* pdata = (VOLUME_PARSING_DATA*)data.data();
|
||||||
VOLUME_PARSING_DATA* pdata = (VOLUME_PARSING_DATA*)data.data();
|
pdata->hasValidUsedSpace = TRUE;
|
||||||
pdata->hasValidUsedSpace = TRUE;
|
model->setParsingData(index, data);
|
||||||
model->setParsingData(index, data);
|
model->setText(index, model->text(index) + "UsedSpace ");
|
||||||
model->setText(index, model->text(index) + "UsedSpace ");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check free space to be actually free
|
||||||
|
UByteArray freeSpace = volumeBody.mid(fileOffset);
|
||||||
|
if (freeSpace.count(emptyByte) != freeSpace.size()) {
|
||||||
|
// Search for the first non-empty byte
|
||||||
|
UINT32 i;
|
||||||
|
UINT32 size = freeSpace.size();
|
||||||
|
const UINT8* current = (UINT8*)freeSpace.constData();
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
if (*current++ != emptyByte)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check free space to be actually free
|
// Align found index to file alignment
|
||||||
UByteArray freeSpace = volumeBody.mid(fileOffset);
|
// It must be possible because minimum 16 bytes of empty were found before
|
||||||
if (freeSpace.count(emptyByte) != freeSpace.size()) {
|
if (i != ALIGN8(i)) {
|
||||||
// Search for the first non-empty byte
|
i = ALIGN8(i) - 8;
|
||||||
UINT32 i;
|
|
||||||
UINT32 size = freeSpace.size();
|
|
||||||
const UINT8* current = (UINT8*)freeSpace.constData();
|
|
||||||
for (i = 0; i < size; i++) {
|
|
||||||
if (*current++ != emptyByte)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Align found index to file alignment
|
|
||||||
// It must be possible because minimum 16 bytes of empty were found before
|
|
||||||
if (i != ALIGN8(i)) {
|
|
||||||
i = ALIGN8(i) - 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add all bytes before as free space
|
|
||||||
if (i > 0) {
|
|
||||||
UByteArray free = freeSpace.left(i);
|
|
||||||
|
|
||||||
// Get info
|
|
||||||
UString info = usprintf("Full size: %Xh (%u)", free.size(), free.size());
|
|
||||||
|
|
||||||
// Add free space item
|
|
||||||
model->addItem(model->offset(index) + volumeHeaderSize + fileOffset, Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), free, UByteArray(), Movable, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse non-UEFI data
|
|
||||||
parseVolumeNonUefiData(freeSpace.mid(i), volumeHeaderSize + fileOffset + i, index);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
// Add all bytes before as free space
|
||||||
|
if (i > 0) {
|
||||||
|
UByteArray free = freeSpace.left(i);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
UString info = usprintf("Full size: %Xh (%u)", freeSpace.size(), freeSpace.size());
|
UString info = usprintf("Full size: %Xh (%u)", free.size(), free.size());
|
||||||
|
|
||||||
// Add free space item
|
// Add free space item
|
||||||
model->addItem(model->offset(index) + volumeHeaderSize + fileOffset, Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Movable, index);
|
model->addItem(model->offset(index) + volumeHeaderSize + fileOffset, Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), free, UByteArray(), Movable, index);
|
||||||
}
|
}
|
||||||
break; // Exit from parsing loop
|
|
||||||
}
|
|
||||||
else { //File space
|
|
||||||
// Parse non-UEFI data
|
// Parse non-UEFI data
|
||||||
parseVolumeNonUefiData(volumeBody.mid(fileOffset), volumeHeaderSize + fileOffset, index);
|
parseVolumeNonUefiData(freeSpace.mid(i), volumeHeaderSize + fileOffset + i, index);
|
||||||
break; // Exit from parsing loop
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Get info
|
||||||
|
UString info = usprintf("Full size: %Xh (%u)", freeSpace.size(), freeSpace.size());
|
||||||
|
|
||||||
|
// Add free space item
|
||||||
|
model->addItem(model->offset(index) + volumeHeaderSize + fileOffset, Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Movable, index);
|
||||||
|
}
|
||||||
|
break; // Exit from parsing loop
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get file header
|
// We aren't at the end of empty space
|
||||||
UByteArray file = volumeBody.mid(fileOffset, fileSize);
|
// Check that the remaining space can still have a file in it
|
||||||
UByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER));
|
if (volumeBodySize - fileOffset < sizeof(EFI_FFS_FILE_HEADER) || // Remaining space is smaller than the smallest possible file
|
||||||
const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)header.constData();
|
volumeBodySize - fileOffset < fileSize) { // Remaining space is smaller than non-empty file size
|
||||||
if (ffsVersion == 3 && (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE)) {
|
// Parse non-UEFI data
|
||||||
header = file.left(sizeof(EFI_FFS_FILE_HEADER2));
|
parseVolumeNonUefiData(volumeBody.mid(fileOffset), volumeHeaderSize + fileOffset, index);
|
||||||
|
break; // Exit from parsing loop
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse current file's header
|
// Parse current file's header
|
||||||
UModelIndex fileIndex;
|
UModelIndex fileIndex;
|
||||||
USTATUS result = parseFileHeader(file, volumeHeaderSize + fileOffset, index, fileIndex);
|
USTATUS result = parseFileHeader(volumeBody.mid(fileOffset, fileSize), volumeHeaderSize + fileOffset, index, fileIndex);
|
||||||
if (result) {
|
if (result) {
|
||||||
msg(usprintf("%s: file header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
msg(usprintf("%s: file header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
||||||
}
|
}
|
||||||
@ -2462,9 +2456,10 @@ USTATUS FfsParser::parseCompressedSectionBody(const UModelIndex & index)
|
|||||||
|
|
||||||
// Decompress section
|
// Decompress section
|
||||||
UINT8 algorithm = COMPRESSION_ALGORITHM_NONE;
|
UINT8 algorithm = COMPRESSION_ALGORITHM_NONE;
|
||||||
|
UINT32 dictionarySize = 0;
|
||||||
UByteArray decompressed;
|
UByteArray decompressed;
|
||||||
UByteArray efiDecompressed;
|
UByteArray efiDecompressed;
|
||||||
USTATUS result = decompress(model->body(index), compressionType, algorithm, decompressed, efiDecompressed);
|
USTATUS result = decompress(model->body(index), compressionType, algorithm, dictionarySize, decompressed, efiDecompressed);
|
||||||
if (result) {
|
if (result) {
|
||||||
msg(UString("parseCompressedSectionBody: decompression failed with error ") + errorCodeToUString(result), index);
|
msg(UString("parseCompressedSectionBody: decompression failed with error ") + errorCodeToUString(result), index);
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
@ -2497,10 +2492,14 @@ USTATUS FfsParser::parseCompressedSectionBody(const UModelIndex & index)
|
|||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
model->addInfo(index, UString("\nCompression algorithm: ") + compressionTypeToUString(algorithm));
|
model->addInfo(index, UString("\nCompression algorithm: ") + compressionTypeToUString(algorithm));
|
||||||
|
if (algorithm == COMPRESSION_ALGORITHM_LZMA || algorithm == COMPRESSION_ALGORITHM_IMLZMA) {
|
||||||
|
model->addInfo(index, usprintf("\nLZMA dictionary size: %Xh", dictionarySize));
|
||||||
|
}
|
||||||
|
|
||||||
// Update parsing data
|
// Update parsing data
|
||||||
COMPRESSED_SECTION_PARSING_DATA pdata;
|
COMPRESSED_SECTION_PARSING_DATA pdata;
|
||||||
pdata.algorithm = algorithm;
|
pdata.algorithm = algorithm;
|
||||||
|
pdata.dictionarySize = dictionarySize;
|
||||||
pdata.compressionType = compressionType;
|
pdata.compressionType = compressionType;
|
||||||
pdata.uncompressedSize = uncompressedSize;
|
pdata.uncompressedSize = uncompressedSize;
|
||||||
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
|
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
|
||||||
@ -2532,10 +2531,11 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
|
|||||||
UString info;
|
UString info;
|
||||||
bool parseCurrentSection = true;
|
bool parseCurrentSection = true;
|
||||||
UINT8 algorithm = COMPRESSION_ALGORITHM_NONE;
|
UINT8 algorithm = COMPRESSION_ALGORITHM_NONE;
|
||||||
|
UINT32 dictionarySize = 0;
|
||||||
UByteArray baGuid = UByteArray((const char*)&guid, sizeof(EFI_GUID));
|
UByteArray baGuid = UByteArray((const char*)&guid, sizeof(EFI_GUID));
|
||||||
// Tiano compressed section
|
// Tiano compressed section
|
||||||
if (baGuid == EFI_GUIDED_SECTION_TIANO) {
|
if (baGuid == EFI_GUIDED_SECTION_TIANO) {
|
||||||
USTATUS result = decompress(model->body(index), EFI_STANDARD_COMPRESSION, algorithm, processed, efiDecompressed);
|
USTATUS result = decompress(model->body(index), EFI_STANDARD_COMPRESSION, algorithm, dictionarySize, processed, efiDecompressed);
|
||||||
if (result) {
|
if (result) {
|
||||||
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
@ -2563,7 +2563,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
|
|||||||
}
|
}
|
||||||
// LZMA compressed section
|
// LZMA compressed section
|
||||||
else if (baGuid == EFI_GUIDED_SECTION_LZMA || baGuid == EFI_GUIDED_SECTION_LZMAF86) {
|
else if (baGuid == EFI_GUIDED_SECTION_LZMA || baGuid == EFI_GUIDED_SECTION_LZMAF86) {
|
||||||
USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, processed, efiDecompressed);
|
USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, dictionarySize, processed, efiDecompressed);
|
||||||
if (result) {
|
if (result) {
|
||||||
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
@ -2572,6 +2572,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
|
|||||||
if (algorithm == COMPRESSION_ALGORITHM_LZMA) {
|
if (algorithm == COMPRESSION_ALGORITHM_LZMA) {
|
||||||
info += UString("\nCompression algorithm: LZMA");
|
info += UString("\nCompression algorithm: LZMA");
|
||||||
info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size());
|
info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size());
|
||||||
|
info += usprintf("\nLZMA dictionary size: %Xh", dictionarySize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
info += UString("\nCompression algorithm: unknown");
|
info += UString("\nCompression algorithm: unknown");
|
||||||
@ -2597,6 +2598,11 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
|
|||||||
if (algorithm != COMPRESSION_ALGORITHM_NONE)
|
if (algorithm != COMPRESSION_ALGORITHM_NONE)
|
||||||
model->setCompressed(index, true);
|
model->setCompressed(index, true);
|
||||||
|
|
||||||
|
// Set parsing data
|
||||||
|
GUIDED_SECTION_PARSING_DATA pdata;
|
||||||
|
pdata.dictionarySize = dictionarySize;
|
||||||
|
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
|
||||||
|
|
||||||
if (!parseCurrentSection) {
|
if (!parseCurrentSection) {
|
||||||
msg(usprintf("%s: GUID defined section can not be processed", __FUNCTION__), index);
|
msg(usprintf("%s: GUID defined section can not be processed", __FUNCTION__), index);
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
|
@ -37,14 +37,20 @@ typedef struct FILE_PARSING_DATA_ {
|
|||||||
EFI_GUID guid;
|
EFI_GUID guid;
|
||||||
} FILE_PARSING_DATA;
|
} FILE_PARSING_DATA;
|
||||||
|
|
||||||
typedef struct GUID_PARSING_DATA_ {
|
typedef struct GUIDED_SECTION_PARSING_DATA_ {
|
||||||
EFI_GUID guid;
|
EFI_GUID guid;
|
||||||
} GUIDED_SECTION_PARSING_DATA, FREEFORM_GUIDED_SECTION_PARSING_DATA;
|
UINT32 dictionarySize;
|
||||||
|
} GUIDED_SECTION_PARSING_DATA;
|
||||||
|
|
||||||
|
typedef struct FREEFORM_GUIDED_SECTION_PARSING_DATA_ {
|
||||||
|
EFI_GUID guid;
|
||||||
|
} FREEFORM_GUIDED_SECTION_PARSING_DATA;
|
||||||
|
|
||||||
typedef struct COMPRESSED_SECTION_PARSING_DATA_ {
|
typedef struct COMPRESSED_SECTION_PARSING_DATA_ {
|
||||||
UINT32 uncompressedSize;
|
UINT32 uncompressedSize;
|
||||||
UINT8 compressionType;
|
UINT8 compressionType;
|
||||||
UINT8 algorithm;
|
UINT8 algorithm;
|
||||||
|
UINT32 dictionarySize;
|
||||||
} COMPRESSED_SECTION_PARSING_DATA;
|
} COMPRESSED_SECTION_PARSING_DATA;
|
||||||
|
|
||||||
typedef struct TE_IMAGE_SECTION_PARSING_DATA_ {
|
typedef struct TE_IMAGE_SECTION_PARSING_DATA_ {
|
||||||
|
@ -296,11 +296,13 @@ void TreeModel::setFixed(const UModelIndex &index, const bool fixed)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (fixed) {
|
if (fixed) {
|
||||||
|
// Special handling for uncompressed to compressed boundary
|
||||||
if (item->compressed() && item->parent()->compressed() == FALSE) {
|
if (item->compressed() && item->parent()->compressed() == FALSE) {
|
||||||
item->setFixed(item->parent()->fixed());
|
item->setFixed(item->parent()->fixed());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Propagate fixed flag until root
|
||||||
if (item->parent()->type() != Types::Root)
|
if (item->parent()->type() != Types::Root)
|
||||||
item->parent()->setFixed(fixed);
|
item->parent()->setFixed(fixed);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ UString errorCodeToUString(USTATUS errorCode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compression routines
|
// Compression routines
|
||||||
USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionType, UINT8 & algorithm, UByteArray & decompressedData, UByteArray & efiDecompressedData)
|
USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionType, UINT8 & algorithm, UINT32 & dictionarySize, UByteArray & decompressedData, UByteArray & efiDecompressedData)
|
||||||
{
|
{
|
||||||
const UINT8* data;
|
const UINT8* data;
|
||||||
UINT32 dataSize;
|
UINT32 dataSize;
|
||||||
@ -147,6 +147,9 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
|
|||||||
UINT32 scratchSize = 0;
|
UINT32 scratchSize = 0;
|
||||||
const EFI_TIANO_HEADER* header;
|
const EFI_TIANO_HEADER* header;
|
||||||
|
|
||||||
|
// For all but LZMA dictionary size is 0
|
||||||
|
dictionarySize = 0;
|
||||||
|
|
||||||
switch (compressionType)
|
switch (compressionType)
|
||||||
{
|
{
|
||||||
case EFI_NOT_COMPRESSED:
|
case EFI_NOT_COMPRESSED:
|
||||||
@ -189,13 +192,9 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
|
|||||||
USTATUS EfiResult = EfiDecompress(data, dataSize, efiDecompressed, decompressedSize, scratch, scratchSize);
|
USTATUS EfiResult = EfiDecompress(data, dataSize, efiDecompressed, decompressedSize, scratch, scratchSize);
|
||||||
|
|
||||||
if (decompressedSize > INT32_MAX) {
|
if (decompressedSize > INT32_MAX) {
|
||||||
free(decompressed);
|
result = U_STANDARD_DECOMPRESSION_FAILED;
|
||||||
free(efiDecompressed);
|
|
||||||
free(scratch);
|
|
||||||
return U_STANDARD_DECOMPRESSION_FAILED;
|
|
||||||
}
|
}
|
||||||
|
else if (EfiResult == U_SUCCESS && TianoResult == U_SUCCESS) { // Both decompressions are OK
|
||||||
if (EfiResult == U_SUCCESS && TianoResult == U_SUCCESS) { // Both decompressions are OK
|
|
||||||
algorithm = COMPRESSION_ALGORITHM_UNDECIDED;
|
algorithm = COMPRESSION_ALGORITHM_UNDECIDED;
|
||||||
decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
|
decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
|
||||||
efiDecompressedData = UByteArray((const char*)efiDecompressed, (int)decompressedSize);
|
efiDecompressedData = UByteArray((const char*)efiDecompressed, (int)decompressedSize);
|
||||||
@ -239,6 +238,9 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
|
|||||||
if (U_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
|
if (U_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
|
||||||
// Intel modified LZMA workaround
|
// Intel modified LZMA workaround
|
||||||
// Decompress section data once again
|
// Decompress section data once again
|
||||||
|
|
||||||
|
// VERIFY: might be wrong assumption, 0.2x had a different code here
|
||||||
|
// See: https://github.com/LongSoft/UEFITool/blob/4bee991c949b458739ffa96b88dbc589192c7689/ffsengine.cpp#L2814-L2823
|
||||||
data += sizeof(UINT32);
|
data += sizeof(UINT32);
|
||||||
|
|
||||||
// Get info again
|
// Get info again
|
||||||
@ -258,6 +260,7 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
|
|||||||
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
|
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
|
||||||
}
|
}
|
||||||
algorithm = COMPRESSION_ALGORITHM_IMLZMA;
|
algorithm = COMPRESSION_ALGORITHM_IMLZMA;
|
||||||
|
dictionarySize = readUnaligned((UINT32*)(data + 1)); // LZMA dictionary size is stored in bytes 1-4 of LZMA properties header
|
||||||
decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
|
decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,6 +270,7 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
|
|||||||
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
|
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
|
||||||
}
|
}
|
||||||
algorithm = COMPRESSION_ALGORITHM_LZMA;
|
algorithm = COMPRESSION_ALGORITHM_LZMA;
|
||||||
|
dictionarySize = readUnaligned((UINT32*)(data + 1)); // LZMA dictionary size is stored in bytes 1-4 of LZMA properties header
|
||||||
decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
|
decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +418,7 @@ USTATUS gzipDecompress(const UByteArray & input, UByteArray & output)
|
|||||||
// 15 for the maximum history buffer, 16 for gzip only input.
|
// 15 for the maximum history buffer, 16 for gzip only input.
|
||||||
int ret = inflateInit2(&stream, 15U | 16U);
|
int ret = inflateInit2(&stream, 15U | 16U);
|
||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
|
return U_GZIP_DECOMPRESSION_FAILED;
|
||||||
|
|
||||||
while (ret == Z_OK) {
|
while (ret == Z_OK) {
|
||||||
Bytef out[4096];
|
Bytef out[4096];
|
||||||
@ -427,5 +431,5 @@ USTATUS gzipDecompress(const UByteArray & input, UByteArray & output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inflateEnd(&stream);
|
inflateEnd(&stream);
|
||||||
return ret == Z_STREAM_END ? U_SUCCESS : U_CUSTOMIZED_DECOMPRESSION_FAILED;
|
return ret == Z_STREAM_END ? U_SUCCESS : U_GZIP_DECOMPRESSION_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ UString uniqueItemName(const UModelIndex & index);
|
|||||||
// Converts error code to UString
|
// Converts error code to UString
|
||||||
UString errorCodeToUString(USTATUS errorCode);
|
UString errorCodeToUString(USTATUS errorCode);
|
||||||
|
|
||||||
// EFI/Tiano decompression routine
|
// EFI/Tiano/LZMA decompression routine
|
||||||
USTATUS decompress(const UByteArray & compressed, const UINT8 compressionType, UINT8 & algorithm, UByteArray & decompressed, UByteArray & efiDecompressed);
|
USTATUS decompress(const UByteArray & compressed, const UINT8 compressionType, UINT8 & algorithm, UINT32 & dictionarySize, UByteArray & decompressed, UByteArray & efiDecompressed);
|
||||||
|
|
||||||
// GZIP decompression routine
|
// GZIP decompression routine
|
||||||
USTATUS gzipDecompress(const UByteArray & compressed, UByteArray & decompressed);
|
USTATUS gzipDecompress(const UByteArray & compressed, UByteArray & decompressed);
|
||||||
|
Loading…
Reference in New Issue
Block a user