mirror of
https://github.com/LongSoft/UEFITool.git
synced 2025-05-15 23:54:45 -04:00
NE_alpha7
- ported cumulative changes from 0.20.8 - added "Extract body uncompressed" action for compressed and GUID-defined sections
This commit is contained in:
parent
41f46631a7
commit
8283ee9f29
11 changed files with 201 additions and 11 deletions
|
@ -77,6 +77,7 @@ typedef UINT8 STATUS;
|
|||
#define ERR_UNKNOWN_RELOCATION_TYPE 31
|
||||
#define ERR_DIR_ALREADY_EXIST 32
|
||||
#define ERR_DIR_CREATE 33
|
||||
#define ERR_TRUNCATED_IMAGE 34
|
||||
#define ERR_NOT_IMPLEMENTED 0xFF
|
||||
|
||||
// UDK porting definitions
|
||||
|
@ -105,8 +106,9 @@ typedef UINT8 STATUS;
|
|||
#define CREATE_MODE_AFTER 3
|
||||
|
||||
// Item extract modes
|
||||
#define EXTRACT_MODE_AS_IS 0
|
||||
#define EXTRACT_MODE_BODY 1
|
||||
#define EXTRACT_MODE_AS_IS 0
|
||||
#define EXTRACT_MODE_BODY 1
|
||||
#define EXTRACT_MODE_BODY_UNCOMPRESSED 2
|
||||
|
||||
// Item replace modes
|
||||
#define REPLACE_MODE_AS_IS 0
|
||||
|
|
20
common/ffs.h
20
common/ffs.h
|
@ -49,6 +49,26 @@ typedef struct _EFI_CAPSULE_HEADER {
|
|||
const QByteArray EFI_CAPSULE_GUID
|
||||
("\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0", 16);
|
||||
|
||||
// Intel capsule GUID
|
||||
const QByteArray INTEL_CAPSULE_GUID
|
||||
("\xB9\x82\x91\x53\xB5\xAB\x91\x43\xB6\x9A\xE3\xA9\x43\xF7\x2F\xCC", 16);
|
||||
|
||||
// Lenovo capsule GUID
|
||||
const QByteArray LENOVO_CAPSULE_GUID
|
||||
("\x8B\xA6\x3C\x4A\x23\x77\xFB\x48\x80\x3D\x57\x8C\xC1\xFE\xC4\x4D", 16);
|
||||
|
||||
// Toshiba EFI Capsule header
|
||||
typedef struct _TOSHIBA_CAPSULE_HEADER {
|
||||
EFI_GUID CapsuleGuid;
|
||||
UINT32 HeaderSize;
|
||||
UINT32 FullSize;
|
||||
UINT32 Flags;
|
||||
} TOSHIBA_CAPSULE_HEADER;
|
||||
|
||||
// Toshiba capsule GUID
|
||||
const QByteArray TOSHIBA_CAPSULE_GUID
|
||||
("\x62\x70\xE0\x3B\x51\x1D\xD2\x45\x83\x2B\xF0\x93\x25\x7E\xD4\x61", 16);
|
||||
|
||||
// AMI Aptio extended capsule header
|
||||
typedef struct _APTIO_CAPSULE_HEADER {
|
||||
EFI_CAPSULE_HEADER CapsuleHeader;
|
||||
|
|
|
@ -70,7 +70,9 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||
// Check buffer for being normal EFI capsule header
|
||||
UINT32 capsuleHeaderSize = 0;
|
||||
QModelIndex index;
|
||||
if (buffer.startsWith(EFI_CAPSULE_GUID)) {
|
||||
if (buffer.startsWith(EFI_CAPSULE_GUID)
|
||||
|| buffer.startsWith(INTEL_CAPSULE_GUID)
|
||||
|| buffer.startsWith(LENOVO_CAPSULE_GUID)) {
|
||||
// Get info
|
||||
const EFI_CAPSULE_HEADER* capsuleHeader = (const EFI_CAPSULE_HEADER*)buffer.constData();
|
||||
capsuleHeaderSize = capsuleHeader->HeaderSize;
|
||||
|
@ -91,6 +93,28 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||
// Add tree item
|
||||
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
||||
}
|
||||
// Check buffer for being Toshiba capsule header
|
||||
else if (buffer.startsWith(TOSHIBA_CAPSULE_GUID)) {
|
||||
// Get info
|
||||
const TOSHIBA_CAPSULE_HEADER* capsuleHeader = (const TOSHIBA_CAPSULE_HEADER*)buffer.constData();
|
||||
capsuleHeaderSize = capsuleHeader->HeaderSize;
|
||||
QByteArray header = buffer.left(capsuleHeaderSize);
|
||||
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
|
||||
QString name = tr("UEFI capsule");
|
||||
QString info = tr("Offset: 0h\nCapsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
|
||||
.arg(guidToQString(capsuleHeader->CapsuleGuid))
|
||||
.hexarg(buffer.size()).arg(buffer.size())
|
||||
.hexarg(capsuleHeader->HeaderSize).arg(capsuleHeader->HeaderSize)
|
||||
.hexarg(capsuleHeader->FullSize - capsuleHeader->HeaderSize).arg(capsuleHeader->FullSize - capsuleHeader->HeaderSize)
|
||||
.hexarg2(capsuleHeader->Flags, 8);
|
||||
|
||||
// Construct parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
||||
pdata.fixed = TRUE;
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(Types::Capsule, Subtypes::ToshibaCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
||||
}
|
||||
// Check buffer for being extended Aptio signed capsule header
|
||||
else if (buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID) || buffer.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) {
|
||||
bool signedCapsule = buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID);
|
||||
|
@ -411,6 +435,44 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa
|
|||
return result;
|
||||
}
|
||||
|
||||
// Add the data after the last region as padding
|
||||
UINT32 IntelDataEnd = 0;
|
||||
UINT32 LastRegionOffset = offsets.last();
|
||||
if (LastRegionOffset == gbeBegin)
|
||||
IntelDataEnd = gbeEnd;
|
||||
else if (LastRegionOffset == meBegin)
|
||||
IntelDataEnd = meEnd;
|
||||
else if (LastRegionOffset == biosBegin)
|
||||
IntelDataEnd = biosEnd;
|
||||
else if (LastRegionOffset == pdrBegin)
|
||||
IntelDataEnd = pdrEnd;
|
||||
|
||||
if (IntelDataEnd > (UINT32)intelImage.size()) { // Image file is truncated
|
||||
msg(tr("parseIntelImage: image size %1 (%2) is smaller than the end of last region %3 (%4), may be damaged")
|
||||
.hexarg(intelImage.size()).arg(intelImage.size())
|
||||
.hexarg(IntelDataEnd).arg(IntelDataEnd), index);
|
||||
return ERR_TRUNCATED_IMAGE;
|
||||
}
|
||||
else if (IntelDataEnd < (UINT32)intelImage.size()) { // Insert padding
|
||||
QByteArray padding = bios.right(intelImage.size() - IntelDataEnd);
|
||||
|
||||
// Get parent's parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||
|
||||
// Get info
|
||||
name = tr("Padding");
|
||||
info = tr("Full size: %1h (%2)")
|
||||
.hexarg(padding.size()).arg(padding.size());
|
||||
|
||||
// Construct parsing data
|
||||
pdata.fixed = TRUE;
|
||||
pdata.offset = IntelDataEnd;
|
||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||
|
||||
// Add tree item
|
||||
QModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||
}
|
||||
|
||||
// Check if the last VTF is found
|
||||
if (!lastVtf.isValid()) {
|
||||
msg(tr("parseIntelImage: not a single Volume Top File is found, the image may be corrupted"), index);
|
||||
|
@ -831,16 +893,23 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||
// Determine value of empty byte
|
||||
UINT8 emptyByte = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00';
|
||||
|
||||
// Check for Apple CRC32 in ZeroVector
|
||||
// Check for AppleCRC32 and AppleFreeSpaceOffset in ZeroVector
|
||||
bool hasAppleCrc32 = false;
|
||||
bool hasAppleFSO = false;
|
||||
UINT32 volumeSize = volume.size();
|
||||
UINT32 appleCrc32 = *(UINT32*)(volume.constData() + 8);
|
||||
UINT32 appleFSO = *(UINT32*)(volume.constData() + 12);
|
||||
if (appleCrc32 != 0) {
|
||||
// Calculate CRC32 of the volume body
|
||||
UINT32 crc = crc32(0, (const UINT8*)(volume.constData() + volumeHeader->HeaderLength), volumeSize - volumeHeader->HeaderLength);
|
||||
if (crc == appleCrc32) {
|
||||
hasAppleCrc32 = true;
|
||||
}
|
||||
|
||||
// Check if FreeSpaceOffset is non-zero
|
||||
if (appleFSO != 0) {
|
||||
hasAppleFSO = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check header checksum by recalculating it
|
||||
|
@ -884,6 +953,7 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||
pdata.volume.alignment = alignment;
|
||||
pdata.volume.revision = volumeHeader->Revision;
|
||||
pdata.volume.hasAppleCrc32 = hasAppleCrc32;
|
||||
pdata.volume.hasAppleFSO = hasAppleFSO;
|
||||
pdata.volume.isWeakAligned = (volumeHeader->Revision > 1 && (volumeHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT));
|
||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||
|
||||
|
@ -891,6 +961,8 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||
QString text;
|
||||
if (hasAppleCrc32)
|
||||
text += tr("AppleCRC32 ");
|
||||
if (hasAppleFSO)
|
||||
text += tr("AppleFSO ");
|
||||
|
||||
// Add tree item
|
||||
UINT8 subtype = Subtypes::UnknownVolume;
|
||||
|
|
|
@ -97,7 +97,9 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
|||
else if (subtype == Subtypes::AptioUnsignedCapsule)
|
||||
return QObject::tr("Aptio unsigned");
|
||||
else if (subtype == Subtypes::UefiCapsule)
|
||||
return QObject::tr("UEFI 2.0 ");
|
||||
return QObject::tr("UEFI 2.0");
|
||||
else if (subtype == Subtypes::ToshibaCapsule)
|
||||
return QObject::tr("Toshiba");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Region:
|
||||
|
|
|
@ -56,7 +56,8 @@ namespace Subtypes {
|
|||
enum CapsuleSubtypes {
|
||||
AptioSignedCapsule = 80,
|
||||
AptioUnsignedCapsule,
|
||||
UefiCapsule
|
||||
UefiCapsule,
|
||||
ToshibaCapsule
|
||||
};
|
||||
|
||||
enum VolumeSubtypes {
|
||||
|
|
|
@ -92,6 +92,7 @@ QString errorCodeToQString(UINT8 errorCode)
|
|||
//case ERR_INVALID_SYMBOL: return QObject::tr("Invalid symbol");
|
||||
//case ERR_NOTHING_TO_PATCH: return QObject::tr("Nothing to patch");
|
||||
case ERR_DEPEX_PARSE_FAILED: return QObject::tr("Dependency expression parsing failed");
|
||||
case ERR_TRUNCATED_IMAGE: return QObject::tr("Image is truncated");
|
||||
default: return QObject::tr("Unknown error %1").arg(errorCode);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue