mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-25 17:38:22 +08:00
UT NE A26
- NVRAM parsing code refactored - Missing entries added to NVRAM-related infos - Various small bugfixes here and there
This commit is contained in:
parent
dd0efa2410
commit
9c5818bb16
@ -299,7 +299,7 @@ void UEFITool::goToData()
|
|||||||
for (int i = index.row(); i < model->rowCount(parent); i++) {
|
for (int i = index.row(); i < model->rowCount(parent); i++) {
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||||
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0;
|
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0;
|
||||||
if (pdata.nvram.nvar.next == lastVariableFlag) {
|
if (pdata.nvar.next == lastVariableFlag) {
|
||||||
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
||||||
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ void UEFITool::goToData()
|
|||||||
for (int j = i + 1; j < model->rowCount(parent); j++) {
|
for (int j = i + 1; j < model->rowCount(parent); j++) {
|
||||||
QModelIndex currentIndex = parent.child(j, 0);
|
QModelIndex currentIndex = parent.child(j, 0);
|
||||||
PARSING_DATA currentPdata = parsingDataFromQModelIndex(currentIndex);
|
PARSING_DATA currentPdata = parsingDataFromQModelIndex(currentIndex);
|
||||||
if (currentPdata.offset == pdata.offset + pdata.nvram.nvar.next) {
|
if (currentPdata.offset == pdata.offset + pdata.nvar.next) {
|
||||||
index = currentIndex;
|
index = currentIndex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -512,11 +512,17 @@ Returns:
|
|||||||
}
|
}
|
||||||
|
|
||||||
mLevel = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mLevel));
|
mLevel = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mLevel));
|
||||||
|
if (!mLevel) return EFI_OUT_OF_RESOURCES;
|
||||||
mChildCount = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mChildCount));
|
mChildCount = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mChildCount));
|
||||||
|
if (!mChildCount) return EFI_OUT_OF_RESOURCES;
|
||||||
mPosition = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mPosition));
|
mPosition = malloc((WNDSIZ + UINT8_MAX + 1) * sizeof(*mPosition));
|
||||||
|
if (!mPosition) return EFI_OUT_OF_RESOURCES;
|
||||||
mParent = malloc(WNDSIZ * 2 * sizeof(*mParent));
|
mParent = malloc(WNDSIZ * 2 * sizeof(*mParent));
|
||||||
|
if (!mParent) return EFI_OUT_OF_RESOURCES;
|
||||||
mPrev = malloc(WNDSIZ * 2 * sizeof(*mPrev));
|
mPrev = malloc(WNDSIZ * 2 * sizeof(*mPrev));
|
||||||
|
if (!mPrev) return EFI_OUT_OF_RESOURCES;
|
||||||
mNext = malloc((MAX_HASH_VAL + 1) * sizeof(*mNext));
|
mNext = malloc((MAX_HASH_VAL + 1) * sizeof(*mNext));
|
||||||
|
if (!mNext) return EFI_OUT_OF_RESOURCES;
|
||||||
|
|
||||||
mBufSiz = 16 * 1024U;
|
mBufSiz = 16 * 1024U;
|
||||||
while ((mBuf = malloc(mBufSiz)) == NULL) {
|
while ((mBuf = malloc(mBufSiz)) == NULL) {
|
||||||
|
18
common/ffs.h
18
common/ffs.h
@ -19,17 +19,13 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include "basetypes.h"
|
#include "basetypes.h"
|
||||||
|
|
||||||
// C++ functions
|
|
||||||
// GUID to QString routine
|
|
||||||
extern QString guidToQString(const EFI_GUID& guid);
|
|
||||||
// File type to QString routine
|
|
||||||
extern QString fileTypeToQString(const UINT8 type);
|
|
||||||
// Section type to QString routine
|
|
||||||
extern QString sectionTypeToQString(const UINT8 type);
|
|
||||||
|
|
||||||
// Make sure we use right packing rules
|
// Make sure we use right packing rules
|
||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
|
|
||||||
|
extern QString guidToQString(const EFI_GUID& guid);
|
||||||
|
extern QString fileTypeToQString(const UINT8 type);
|
||||||
|
extern QString sectionTypeToQString(const UINT8 type);
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// EFI Capsule
|
// EFI Capsule
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
@ -517,7 +513,7 @@ typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION2_ {
|
|||||||
EFI_GUID SubTypeGuid;
|
EFI_GUID SubTypeGuid;
|
||||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
|
} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
|
||||||
|
|
||||||
// Phoenix SCT and HP postcode section
|
// Phoenix SCT and Insyde postcode section
|
||||||
typedef struct POSTCODE_SECTION_ {
|
typedef struct POSTCODE_SECTION_ {
|
||||||
UINT8 Size[3];
|
UINT8 Size[3];
|
||||||
UINT8 Type;
|
UINT8 Type;
|
||||||
@ -563,13 +559,13 @@ typedef EFI_COMMON_SECTION_HEADER2 EFI_USER_INTERFACE_SECTION2;
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// If present, this must be the first and only opcode,
|
/// If present, this must be the first and only opcode,
|
||||||
/// EFI_DEP_BEFORE is only used by DXE driver.
|
/// EFI_DEP_BEFORE is only used by DXE drivers
|
||||||
///
|
///
|
||||||
#define EFI_DEP_BEFORE 0x00
|
#define EFI_DEP_BEFORE 0x00
|
||||||
|
|
||||||
///
|
///
|
||||||
/// If present, this must be the first and only opcode,
|
/// If present, this must be the first and only opcode,
|
||||||
/// EFI_DEP_AFTER is only used by DXE driver.
|
/// EFI_DEP_AFTER is only used by DXE drivers
|
||||||
///
|
///
|
||||||
#define EFI_DEP_AFTER 0x01
|
#define EFI_DEP_AFTER 0x01
|
||||||
|
|
||||||
|
@ -1106,7 +1106,7 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||||||
QByteArray header = volume.left(headerSize);
|
QByteArray header = volume.left(headerSize);
|
||||||
QByteArray body = volume.mid(headerSize);
|
QByteArray body = volume.mid(headerSize);
|
||||||
QString name = guidToQString(volumeHeader->FileSystemGuid);
|
QString name = guidToQString(volumeHeader->FileSystemGuid);
|
||||||
QString info = QObject::tr("ZeroVector:\n%1 %2 %3 %4 %5 %6 %7 %8\n%9 %10 %11 %12 %13 %14 %15 %16\nFileSystem GUID: %17\nFull size: %18h (%19)\n"
|
QString info = QObject::tr("Signature: _FVH\nZeroVector:\n%1 %2 %3 %4 %5 %6 %7 %8\n%9 %10 %11 %12 %13 %14 %15 %16\nFileSystem GUID: %17\nFull size: %18h (%19)\n"
|
||||||
"Header size: %20h (%21)\nBody size: %22h (%23)\nRevision: %24\nAttributes: %25h\nErase polarity: %26\nChecksum: %27h, %28")
|
"Header size: %20h (%21)\nBody size: %22h (%23)\nRevision: %24\nAttributes: %25h\nErase polarity: %26\nChecksum: %27h, %28")
|
||||||
.hexarg2(volumeHeader->ZeroVector[0], 2).hexarg2(volumeHeader->ZeroVector[1], 2).hexarg2(volumeHeader->ZeroVector[2], 2).hexarg2(volumeHeader->ZeroVector[3], 2)
|
.hexarg2(volumeHeader->ZeroVector[0], 2).hexarg2(volumeHeader->ZeroVector[1], 2).hexarg2(volumeHeader->ZeroVector[2], 2).hexarg2(volumeHeader->ZeroVector[3], 2)
|
||||||
.hexarg2(volumeHeader->ZeroVector[4], 2).hexarg2(volumeHeader->ZeroVector[5], 2).hexarg2(volumeHeader->ZeroVector[6], 2).hexarg2(volumeHeader->ZeroVector[7], 2)
|
.hexarg2(volumeHeader->ZeroVector[4], 2).hexarg2(volumeHeader->ZeroVector[5], 2).hexarg2(volumeHeader->ZeroVector[6], 2).hexarg2(volumeHeader->ZeroVector[7], 2)
|
||||||
@ -2873,7 +2873,7 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
|
|
||||||
UINT32 offset = 0;
|
UINT32 offset = 0;
|
||||||
UINT32 guidsInStore = 0;
|
UINT32 guidsInStore = 0;
|
||||||
|
const UINT8 emptyByte = pdata.emptyByte;
|
||||||
// Parse all entries
|
// Parse all entries
|
||||||
while (1) {
|
while (1) {
|
||||||
bool msgUnknownExtDataFormat = false;
|
bool msgUnknownExtDataFormat = false;
|
||||||
@ -2881,6 +2881,7 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
bool msgExtDataTooShort = false;
|
bool msgExtDataTooShort = false;
|
||||||
|
|
||||||
bool isInvalid = false;
|
bool isInvalid = false;
|
||||||
|
bool isInvalidLink = false;
|
||||||
bool isDataOnly = false;
|
bool isDataOnly = false;
|
||||||
bool hasExtendedHeader = false;
|
bool hasExtendedHeader = false;
|
||||||
bool hasChecksum = false;
|
bool hasChecksum = false;
|
||||||
@ -2908,15 +2909,16 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
// Get entry header
|
// Get entry header
|
||||||
const NVAR_ENTRY_HEADER* entryHeader = (const NVAR_ENTRY_HEADER*)(data.constData() + offset);
|
const NVAR_ENTRY_HEADER* entryHeader = (const NVAR_ENTRY_HEADER*)(data.constData() + offset);
|
||||||
|
|
||||||
// Check header size
|
// Check header size and signature
|
||||||
if (unparsedSize < sizeof(NVAR_ENTRY_HEADER) ||
|
if (unparsedSize < sizeof(NVAR_ENTRY_HEADER) ||
|
||||||
|
entryHeader->Signature != NVRAM_NVAR_ENTRY_SIGNATURE ||
|
||||||
unparsedSize < entryHeader->Size) {
|
unparsedSize < entryHeader->Size) {
|
||||||
|
|
||||||
// Check if the data left is a free space or a padding
|
// Check if the data left is a free space or a padding
|
||||||
QByteArray padding = data.mid(offset, unparsedSize);
|
QByteArray padding = data.mid(offset, unparsedSize);
|
||||||
UINT8 type;
|
UINT8 type;
|
||||||
|
|
||||||
if (padding.count(pdata.emptyByte) == padding.size()) {
|
if (padding.count(emptyByte) == unparsedSize) {
|
||||||
// It's a free space
|
// It's a free space
|
||||||
name = QObject::tr("Free space");
|
name = QObject::tr("Free space");
|
||||||
type = Types::FreeSpace;
|
type = Types::FreeSpace;
|
||||||
@ -2964,10 +2966,10 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0;
|
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0;
|
||||||
|
|
||||||
// Set default next to predefined last value
|
// Set default next to predefined last value
|
||||||
pdata.nvram.nvar.next = lastVariableFlag;
|
pdata.nvar.next = lastVariableFlag;
|
||||||
|
|
||||||
// Entry is marked as invalid
|
// Entry is marked as invalid
|
||||||
if ((entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_VALID) == 0) { // Valid attribute is not set
|
if ((entryHeader->Attributes & NVRAM_NVAR_ENTRY_VALID) == 0) { // Valid attribute is not set
|
||||||
isInvalid = true;
|
isInvalid = true;
|
||||||
// Do not parse further
|
// Do not parse further
|
||||||
goto parsing_done;
|
goto parsing_done;
|
||||||
@ -2976,11 +2978,11 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
// Add next node information to parsing data
|
// Add next node information to parsing data
|
||||||
if (entryHeader->Next != lastVariableFlag) {
|
if (entryHeader->Next != lastVariableFlag) {
|
||||||
subtype = Subtypes::LinkNvarEntry;
|
subtype = Subtypes::LinkNvarEntry;
|
||||||
pdata.nvram.nvar.next = entryHeader->Next;
|
pdata.nvar.next = entryHeader->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exntry with extended header
|
// Entry with extended header
|
||||||
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_EXT_HEADER) {
|
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_EXT_HEADER) {
|
||||||
hasExtendedHeader = true;
|
hasExtendedHeader = true;
|
||||||
msgUnknownExtDataFormat = true;
|
msgUnknownExtDataFormat = true;
|
||||||
|
|
||||||
@ -2995,7 +2997,7 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
extendedAttributes = *(UINT8*)(body.constData() + body.size() - extendedHeaderSize);
|
extendedAttributes = *(UINT8*)(body.constData() + body.size() - extendedHeaderSize);
|
||||||
|
|
||||||
// Variable with checksum
|
// Variable with checksum
|
||||||
if (extendedAttributes & NVRAM_NVAR_ENTRY_EXT_ATTRIB_CHECKSUM) {
|
if (extendedAttributes & NVRAM_NVAR_ENTRY_EXT_CHECKSUM) {
|
||||||
// Get stored checksum
|
// Get stored checksum
|
||||||
storedChecksum = *(UINT8*)(body.constData() + body.size() - sizeof(UINT16) - sizeof(UINT8));
|
storedChecksum = *(UINT8*)(body.constData() + body.size() - sizeof(UINT16) - sizeof(UINT8));
|
||||||
|
|
||||||
@ -3022,7 +3024,7 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
body = body.left(body.size() - extendedHeaderSize);
|
body = body.left(body.size() - extendedHeaderSize);
|
||||||
|
|
||||||
// Entry with authenticated write (for SecureBoot)
|
// Entry with authenticated write (for SecureBoot)
|
||||||
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_AUTH_WRITE) {
|
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_AUTH_WRITE) {
|
||||||
if (extendedData.size() < sizeof(UINT64) + SHA256_HASH_SIZE) {
|
if (extendedData.size() < sizeof(UINT64) + SHA256_HASH_SIZE) {
|
||||||
msgExtDataTooShort = true;
|
msgExtDataTooShort = true;
|
||||||
isInvalid = true;
|
isInvalid = true;
|
||||||
@ -3038,20 +3040,20 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Entry is data-only (nameless and GUIDless entry or link)
|
// Entry is data-only (nameless and GUIDless entry or link)
|
||||||
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_DATA_ONLY) { // Data-only attribute is set
|
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_DATA_ONLY) { // Data-only attribute is set
|
||||||
isInvalid = true;
|
isInvalidLink = true;
|
||||||
QModelIndex nvarIndex;
|
QModelIndex nvarIndex;
|
||||||
// Search prevously added entries for a link to this variable //TODO:replace with linked lists
|
// Search prevously added entries for a link to this variable //TODO:replace with linked lists
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
nvarIndex = index.child(i, 0);
|
nvarIndex = index.child(i, 0);
|
||||||
PARSING_DATA nvarPdata = parsingDataFromQModelIndex(nvarIndex);
|
PARSING_DATA nvarPdata = parsingDataFromQModelIndex(nvarIndex);
|
||||||
if (nvarPdata.nvram.nvar.next + nvarPdata.offset - parentOffset == offset) { // Previous link is present and valid
|
if (nvarPdata.nvar.isValid && nvarPdata.nvar.next + nvarPdata.offset - parentOffset == offset) { // Previous link is present and valid
|
||||||
isInvalid = false;
|
isInvalidLink = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if the link is valid
|
// Check if the link is valid
|
||||||
if (!isInvalid) {
|
if (!isInvalidLink) {
|
||||||
// Use the name and text of the previous link
|
// Use the name and text of the previous link
|
||||||
name = model->name(nvarIndex);
|
name = model->name(nvarIndex);
|
||||||
text = model->text(nvarIndex);
|
text = model->text(nvarIndex);
|
||||||
@ -3067,10 +3069,10 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
|
|
||||||
// Get entry name
|
// Get entry name
|
||||||
{
|
{
|
||||||
UINT32 nameOffset = (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_GUID) ? sizeof(EFI_GUID) : 1; // GUID can be stored with the variable or in a separate store, so there will only be an index of it
|
UINT32 nameOffset = (entryHeader->Attributes & NVRAM_NVAR_ENTRY_GUID) ? sizeof(EFI_GUID) : 1; // GUID can be stored with the variable or in a separate store, so there will only be an index of it
|
||||||
CHAR8* namePtr = (CHAR8*)(entryHeader + 1) + nameOffset;
|
CHAR8* namePtr = (CHAR8*)(entryHeader + 1) + nameOffset;
|
||||||
UINT32 nameSize = 0;
|
UINT32 nameSize = 0;
|
||||||
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_ASCII_NAME) { // Name is stored as ASCII string of CHAR8s
|
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ASCII_NAME) { // Name is stored as ASCII string of CHAR8s
|
||||||
text = QString(namePtr);
|
text = QString(namePtr);
|
||||||
nameSize = text.length() + 1;
|
nameSize = text.length() + 1;
|
||||||
}
|
}
|
||||||
@ -3080,7 +3082,7 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get entry GUID
|
// Get entry GUID
|
||||||
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_GUID) { // GUID is strored in the variable itself
|
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_GUID) { // GUID is strored in the variable itself
|
||||||
name = guidToQString(*(EFI_GUID*)(entryHeader + 1));
|
name = guidToQString(*(EFI_GUID*)(entryHeader + 1));
|
||||||
}
|
}
|
||||||
// GUID is stored in GUID list at the end of the store
|
// GUID is stored in GUID list at the end of the store
|
||||||
@ -3101,16 +3103,18 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in
|
|||||||
}
|
}
|
||||||
parsing_done:
|
parsing_done:
|
||||||
QString info;
|
QString info;
|
||||||
|
|
||||||
// Rename invalid entries according to their types
|
// Rename invalid entries according to their types
|
||||||
|
pdata.nvar.isValid = TRUE;
|
||||||
if (isInvalid) {
|
if (isInvalid) {
|
||||||
if (entryHeader->Next != lastVariableFlag) {
|
|
||||||
name = QObject::tr("Invalid link");
|
|
||||||
subtype = Subtypes::InvalidLinkNvarEntry;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
name = QObject::tr("Invalid");
|
name = QObject::tr("Invalid");
|
||||||
subtype = Subtypes::InvalidNvarEntry;
|
subtype = Subtypes::InvalidNvarEntry;
|
||||||
|
pdata.nvar.isValid = FALSE;
|
||||||
}
|
}
|
||||||
|
else if (isInvalidLink) {
|
||||||
|
name = QObject::tr("Invalid link");
|
||||||
|
subtype = Subtypes::InvalidLinkNvarEntry;
|
||||||
|
pdata.nvar.isValid = FALSE;
|
||||||
}
|
}
|
||||||
else // Add GUID info for valid entries
|
else // Add GUID info for valid entries
|
||||||
info += QObject::tr("Variable GUID: %1\n").arg(name);
|
info += QObject::tr("Variable GUID: %1\n").arg(name);
|
||||||
@ -3128,9 +3132,9 @@ parsing_done:
|
|||||||
// Add attributes info
|
// Add attributes info
|
||||||
info += QObject::tr("\nAttributes: %1h").hexarg2(entryHeader->Attributes, 2);
|
info += QObject::tr("\nAttributes: %1h").hexarg2(entryHeader->Attributes, 2);
|
||||||
// Translate attributes to text
|
// Translate attributes to text
|
||||||
if (entryHeader->Attributes)
|
if (entryHeader->Attributes && entryHeader->Attributes != 0xFF)
|
||||||
info += QObject::tr("\nAttributes as text: %1").arg(nvarAttributesToQString(entryHeader->Attributes));
|
info += QObject::tr(" (%1)").arg(nvarAttributesToQString(entryHeader->Attributes));
|
||||||
pdata.nvram.nvar.attributes = entryHeader->Attributes;
|
|
||||||
|
|
||||||
// Add next node info
|
// Add next node info
|
||||||
if (!isInvalid && entryHeader->Next != lastVariableFlag)
|
if (!isInvalid && entryHeader->Next != lastVariableFlag)
|
||||||
@ -3138,10 +3142,11 @@ parsing_done:
|
|||||||
|
|
||||||
// Add extended header info
|
// Add extended header info
|
||||||
if (hasExtendedHeader) {
|
if (hasExtendedHeader) {
|
||||||
info += QObject::tr("\nExtended header size: %1h (%2)\nExtended attributes: %3h")
|
info += QObject::tr("\nExtended header size: %1h (%2)\nExtended attributes: %3h (%4)")
|
||||||
.hexarg(extendedHeaderSize).arg(extendedHeaderSize)
|
.hexarg(extendedHeaderSize).arg(extendedHeaderSize)
|
||||||
.hexarg2(extendedAttributes, 2);
|
.hexarg2(extendedAttributes, 2)
|
||||||
pdata.nvram.nvar.extendedAttributes = extendedAttributes;
|
.arg(nvarExtendedAttributesToQString(extendedAttributes));
|
||||||
|
|
||||||
// Checksum
|
// Checksum
|
||||||
if (hasChecksum)
|
if (hasChecksum)
|
||||||
info += QObject::tr("\nChecksum: %1h%2").hexarg2(storedChecksum, 2)
|
info += QObject::tr("\nChecksum: %1h%2").hexarg2(storedChecksum, 2)
|
||||||
@ -3155,8 +3160,6 @@ parsing_done:
|
|||||||
info += QObject::tr("\nTimestamp: %1h\nHash: %2")
|
info += QObject::tr("\nTimestamp: %1h\nHash: %2")
|
||||||
.hexarg2(timestamp, 16).arg(QString(hash.toHex()));
|
.hexarg2(timestamp, 16).arg(QString(hash.toHex()));
|
||||||
|
|
||||||
pdata.nvram.nvar.timestamp = timestamp;
|
|
||||||
memcpy(pdata.nvram.nvar.hash, hash.constData(), 0x20);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3198,10 +3201,9 @@ STATUS FfsParser::parseNvramVolumeBody(const QModelIndex & index)
|
|||||||
// Get item data
|
// Get item data
|
||||||
QByteArray data = model->body(index);
|
QByteArray data = model->body(index);
|
||||||
|
|
||||||
// Search for first volume
|
// Search for first store
|
||||||
STATUS result;
|
STATUS result;
|
||||||
UINT32 prevStoreOffset;
|
UINT32 prevStoreOffset;
|
||||||
|
|
||||||
result = findNextStore(index, data, parentOffset, 0, prevStoreOffset);
|
result = findNextStore(index, data, parentOffset, 0, prevStoreOffset);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
@ -3257,7 +3259,7 @@ STATUS FfsParser::parseNvramVolumeBody(const QModelIndex & index)
|
|||||||
|
|
||||||
// Check that current store is fully present in input
|
// Check that current store is fully present in input
|
||||||
if (storeSize > (UINT32)data.size() || storeOffset + storeSize > (UINT32)data.size()) {
|
if (storeSize > (UINT32)data.size() || storeOffset + storeSize > (UINT32)data.size()) {
|
||||||
// Mark the rest as padding and finish the parsing
|
// Mark the rest as padding and finish parsing
|
||||||
QByteArray padding = data.mid(storeOffset);
|
QByteArray padding = data.mid(storeOffset);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
@ -3279,20 +3281,19 @@ STATUS FfsParser::parseNvramVolumeBody(const QModelIndex & index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QByteArray store = data.mid(storeOffset, storeSize);
|
QByteArray store = data.mid(storeOffset, storeSize);
|
||||||
// Parse current volume's header
|
// Parse current store header
|
||||||
QModelIndex storeIndex;
|
QModelIndex storeIndex;
|
||||||
result = parseStoreHeader(store, parentOffset + storeOffset, index, storeIndex);
|
result = parseStoreHeader(store, parentOffset + storeOffset, index, storeIndex);
|
||||||
if (result) {
|
if (result)
|
||||||
msg(QObject::tr("parseNvramVolumeBody: store header parsing failed with error \"%1\"").arg(errorCodeToQString(result)), index);
|
msg(QObject::tr("parseNvramVolumeBody: store header parsing failed with error \"%1\"").arg(errorCodeToQString(result)), index);
|
||||||
}
|
|
||||||
|
|
||||||
// Go to next volume
|
// Go to next store
|
||||||
prevStoreOffset = storeOffset;
|
prevStoreOffset = storeOffset;
|
||||||
prevStoreSize = storeSize;
|
prevStoreSize = storeSize;
|
||||||
result = findNextStore(index, data, parentOffset, storeOffset + prevStoreSize, storeOffset);
|
result = findNextStore(index, data, parentOffset, storeOffset + prevStoreSize, storeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Padding/free space at the end of volume
|
// Padding/free space at the end
|
||||||
storeOffset = prevStoreOffset + prevStoreSize;
|
storeOffset = prevStoreOffset + prevStoreSize;
|
||||||
if ((UINT32)data.size() > storeOffset) {
|
if ((UINT32)data.size() > storeOffset) {
|
||||||
QByteArray padding = data.mid(storeOffset);
|
QByteArray padding = data.mid(storeOffset);
|
||||||
@ -3325,7 +3326,7 @@ STATUS FfsParser::parseNvramVolumeBody(const QModelIndex & index)
|
|||||||
pdata.offset = parentOffset + storeOffset;
|
pdata.offset = parentOffset + storeOffset;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, TRUE, parsingDataToQByteArray(pdata), index);
|
model->addItem(type, subtype, name, QString(), info, QByteArray(), padding, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse bodies
|
// Parse bodies
|
||||||
@ -3558,29 +3559,22 @@ STATUS FfsParser::getStoreSize(const QByteArray & data, const UINT32 storeOffset
|
|||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
STATUS FfsParser::parseVssStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
const UINT32* signature = (const UINT32*)store.constData();
|
|
||||||
if (dataSize < sizeof(UINT32)) {
|
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for store signature"), parent);
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VSS variable stores
|
// Check store size
|
||||||
if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE) {
|
|
||||||
// Check dataSize
|
|
||||||
if (dataSize < sizeof(VSS_VARIABLE_STORE_HEADER)) {
|
if (dataSize < sizeof(VSS_VARIABLE_STORE_HEADER)) {
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for VSS store header"), parent);
|
msg(QObject::tr("parseVssStoreHeader: volume body is too small even for VSS store header"), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get VSS store header
|
// Get VSS store header
|
||||||
const VSS_VARIABLE_STORE_HEADER* vssStoreHeader = (const VSS_VARIABLE_STORE_HEADER*)signature;
|
const VSS_VARIABLE_STORE_HEADER* vssStoreHeader = (const VSS_VARIABLE_STORE_HEADER*)store.constData();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
if (dataSize < vssStoreHeader->Size) {
|
if (dataSize < vssStoreHeader->Size) {
|
||||||
msg(QObject::tr("parseStoreHeader: VSS store size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseVssStoreHeader: VSS store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(vssStoreHeader->Size).arg(vssStoreHeader->Size)
|
.hexarg(vssStoreHeader->Size).arg(vssStoreHeader->Size)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -3594,9 +3588,10 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
QByteArray body = store.mid(sizeof(VSS_VARIABLE_STORE_HEADER), vssStoreHeader->Size - sizeof(VSS_VARIABLE_STORE_HEADER));
|
QByteArray body = store.mid(sizeof(VSS_VARIABLE_STORE_HEADER), vssStoreHeader->Size - sizeof(VSS_VARIABLE_STORE_HEADER));
|
||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
QString name = (*signature == NVRAM_APPLE_SVS_STORE_SIGNATURE) ? QObject::tr("SVS store") : QObject::tr("VSS store");
|
bool isSvsStore = (vssStoreHeader->Signature == NVRAM_APPLE_SVS_STORE_SIGNATURE);
|
||||||
QString info = QObject::tr("Signature: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nFormat: %8h\nState: %9h\nUnknown: %10h")
|
QString name = isSvsStore ? QObject::tr("SVS store") : QObject::tr("VSS store");
|
||||||
.hexarg2(vssStoreHeader->Signature, 8)
|
QString info = QObject::tr("Signature: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nFormat: %8h\nState: %9h\nUnknown: %10h")
|
||||||
|
.arg(isSvsStore ? QObject::tr("$SVS") : QObject::tr("$VSS"))
|
||||||
.hexarg(vssStoreHeader->Size).arg(vssStoreHeader->Size)
|
.hexarg(vssStoreHeader->Size).arg(vssStoreHeader->Size)
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
@ -3609,20 +3604,94 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::VssStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::VssStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
}
|
|
||||||
else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE) {
|
|
||||||
// Check dataSize
|
|
||||||
if (dataSize < sizeof(FDC_VOLUME_HEADER)) {
|
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for FDC store header"), parent);
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get VSS store header
|
STATUS FfsParser::parseFtwStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
const FDC_VOLUME_HEADER* fdcStoreHeader = (const FDC_VOLUME_HEADER*)signature;
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
|
// Check store size
|
||||||
|
if (dataSize < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64)) {
|
||||||
|
msg(QObject::tr("parseFtwStoreHeader: volume body is too small even for FTW store header"), parent);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get FTW block headers
|
||||||
|
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftw32BlockHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)store.constData();
|
||||||
|
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64BlockHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)store.constData();
|
||||||
|
|
||||||
|
// Check store size
|
||||||
|
UINT32 ftwBlockSize;
|
||||||
|
bool has32bitHeader;
|
||||||
|
if (ftw32BlockHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize
|
||||||
|
ftwBlockSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) + ftw32BlockHeader->WriteQueueSize;
|
||||||
|
has32bitHeader = true;
|
||||||
|
}
|
||||||
|
else { // Header with 64 bit WriteQueueSize
|
||||||
|
ftwBlockSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64) + ftw64BlockHeader->WriteQueueSize;
|
||||||
|
has32bitHeader = false;
|
||||||
|
}
|
||||||
|
if (dataSize < ftwBlockSize) {
|
||||||
|
msg(QObject::tr("parseFtwStoreHeader: FTW store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
|
.hexarg(ftwBlockSize).arg(ftwBlockSize)
|
||||||
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get parsing data
|
||||||
|
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||||
|
|
||||||
|
// Construct header and body
|
||||||
|
UINT32 headerSize = has32bitHeader ? sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) : sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64);
|
||||||
|
QByteArray header = store.left(headerSize);
|
||||||
|
QByteArray body = store.mid(headerSize, ftwBlockSize - headerSize);
|
||||||
|
|
||||||
|
// Check block header checksum
|
||||||
|
QByteArray crcHeader = header;
|
||||||
|
EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* crcFtwBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)header.data();
|
||||||
|
crcFtwBlockHeader->Crc = pdata.emptyByte ? 0xFFFFFFFF : 0;
|
||||||
|
crcFtwBlockHeader->State = pdata.emptyByte ? 0xFF : 0;
|
||||||
|
UINT32 calculatedCrc = crc32(0, (const UINT8*)crcFtwBlockHeader, headerSize);
|
||||||
|
|
||||||
|
// Add info
|
||||||
|
QString name = QObject::tr("FTW store");
|
||||||
|
QString info = QObject::tr("Signature: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nState: %8h\nHeader CRC32: %9")
|
||||||
|
.arg(guidToQString(ftw32BlockHeader->Signature))
|
||||||
|
.hexarg(ftwBlockSize).arg(ftwBlockSize)
|
||||||
|
.hexarg(headerSize).arg(headerSize)
|
||||||
|
.hexarg(body.size()).arg(body.size())
|
||||||
|
.hexarg2(ftw32BlockHeader->State, 2)
|
||||||
|
.arg(ftw32BlockHeader->Crc == calculatedCrc ?
|
||||||
|
QObject::tr("%1h, valid").hexarg2(ftw32BlockHeader->Crc, 8) :
|
||||||
|
QObject::tr("%1h, invalid, should be %2h").hexarg2(ftw32BlockHeader->Crc, 8).hexarg2(calculatedCrc, 8));
|
||||||
|
|
||||||
|
// Add correct offset
|
||||||
|
pdata.offset = parentOffset;
|
||||||
|
|
||||||
|
// Add tree item
|
||||||
|
index = model->addItem(Types::FtwStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsParser::parseFdcStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
|
// Check store size
|
||||||
|
if (dataSize < sizeof(FDC_VOLUME_HEADER)) {
|
||||||
|
msg(QObject::tr("parseFdcStoreHeader: volume body is too small even for FDC store header"), parent);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Fdc store header
|
||||||
|
const FDC_VOLUME_HEADER* fdcStoreHeader = (const FDC_VOLUME_HEADER*)store.constData();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
if (dataSize < fdcStoreHeader->Size) {
|
if (dataSize < fdcStoreHeader->Size) {
|
||||||
msg(QObject::tr("parseStoreHeader: FDC store size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseFdcStoreHeader: FDC store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(fdcStoreHeader->Size).arg(fdcStoreHeader->Size)
|
.hexarg(fdcStoreHeader->Size).arg(fdcStoreHeader->Size)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -3649,7 +3718,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Check sanity of combined header size
|
// Check sanity of combined header size
|
||||||
if (dataSize < headerSize) {
|
if (dataSize < headerSize) {
|
||||||
msg(QObject::tr("parseStoreHeader: FDC store header size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseFdcStoreHeader: FDC store header size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg2(fdcStoreHeader->Size, 8).arg(fdcStoreHeader->Size)
|
.hexarg2(fdcStoreHeader->Size, 8).arg(fdcStoreHeader->Size)
|
||||||
.hexarg2(dataSize, 8).arg(dataSize), parent);
|
.hexarg2(dataSize, 8).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -3664,8 +3733,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
QString name = QObject::tr("FDC store");
|
QString name = QObject::tr("FDC store");
|
||||||
QString info = QObject::tr("Signature: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)")
|
QString info = QObject::tr("Signature: _FDC\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: %5h (%6)")
|
||||||
.hexarg2(fdcStoreHeader->Signature, 8)
|
|
||||||
.hexarg(fdcStoreHeader->Size).arg(fdcStoreHeader->Size)
|
.hexarg(fdcStoreHeader->Size).arg(fdcStoreHeader->Size)
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size());
|
.hexarg(body.size()).arg(body.size());
|
||||||
@ -3677,20 +3745,26 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::FdcStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::FdcStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) {
|
|
||||||
// Check dataSize
|
STATUS FfsParser::parseFsysStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
|
// Check store size
|
||||||
if (dataSize < sizeof(APPLE_FSYS_STORE_HEADER)) {
|
if (dataSize < sizeof(APPLE_FSYS_STORE_HEADER)) {
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for Fsys store header"), parent);
|
msg(QObject::tr("parseFsysStoreHeader: volume body is too small even for Fsys store header"), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Fsys store header
|
// Get Fsys store header
|
||||||
const APPLE_FSYS_STORE_HEADER* fsysStoreHeader = (const APPLE_FSYS_STORE_HEADER*)signature;
|
const APPLE_FSYS_STORE_HEADER* fsysStoreHeader = (const APPLE_FSYS_STORE_HEADER*)store.constData();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
if (dataSize < fsysStoreHeader->Size) {
|
if (dataSize < fsysStoreHeader->Size) {
|
||||||
msg(QObject::tr("parseStoreHeader: Fsys store size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseFsysStoreHeader: Fsys store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(fsysStoreHeader->Size).arg(fsysStoreHeader->Size)
|
.hexarg(fsysStoreHeader->Size).arg(fsysStoreHeader->Size)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -3708,17 +3782,15 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
UINT32 calculatedCrc = calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32));
|
UINT32 calculatedCrc = calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32));
|
||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
QString name = (*signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) ? QObject::tr("Gaid store") : QObject::tr("Fsys store");
|
bool isGaidStore = (fsysStoreHeader->Signature == NVRAM_APPLE_GAID_STORE_SIGNATURE);
|
||||||
QString info = QObject::tr("Signature: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nUnknown: %9 %10 %11 %12 %13\nCRC32: %14")
|
QString name = isGaidStore ? QObject::tr("Gaid store") : QObject::tr("Fsys store");
|
||||||
.hexarg2(fsysStoreHeader->Signature, 8)
|
QString info = QObject::tr("Signature: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nUnknown0: %9h\nUnknown1: %10h\nCRC32: %11")
|
||||||
|
.arg(isGaidStore ? QObject::tr("Gaid") : QObject::tr("Fsys"))
|
||||||
.hexarg(fsysStoreHeader->Size).arg(fsysStoreHeader->Size)
|
.hexarg(fsysStoreHeader->Size).arg(fsysStoreHeader->Size)
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
.hexarg2(fsysStoreHeader->Unknown[0], 2)
|
.hexarg2(fsysStoreHeader->Unknown0, 2)
|
||||||
.hexarg2(fsysStoreHeader->Unknown[1], 2)
|
.hexarg2(fsysStoreHeader->Unknown1, 8)
|
||||||
.hexarg2(fsysStoreHeader->Unknown[2], 2)
|
|
||||||
.hexarg2(fsysStoreHeader->Unknown[3], 2)
|
|
||||||
.hexarg2(fsysStoreHeader->Unknown[4], 2)
|
|
||||||
.arg(storedCrc == calculatedCrc ? QObject::tr("%1h, valid").hexarg2(storedCrc, 8) : QObject::tr("%1h, invalid, should be %2h").hexarg2(storedCrc, 8).hexarg2(calculatedCrc, 8));
|
.arg(storedCrc == calculatedCrc ? QObject::tr("%1h, valid").hexarg2(storedCrc, 8) : QObject::tr("%1h, invalid, should be %2h").hexarg2(storedCrc, 8).hexarg2(calculatedCrc, 8));
|
||||||
|
|
||||||
// Add correct offset
|
// Add correct offset
|
||||||
@ -3726,20 +3798,26 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::FsysStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::FsysStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) {
|
|
||||||
|
STATUS FfsParser::parseEvsaStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
// Check dataSize
|
// Check dataSize
|
||||||
if (dataSize < sizeof(EVSA_STORE_ENTRY)) {
|
if (dataSize < sizeof(EVSA_STORE_ENTRY)) {
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for EVSA store header"), parent);
|
msg(QObject::tr("parseEvsaStoreHeader: volume body is too small even for EVSA store header"), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get EVSA store header
|
// Get EVSA store header
|
||||||
const EVSA_STORE_ENTRY* evsaStoreHeader = (const EVSA_STORE_ENTRY*)signature;
|
const EVSA_STORE_ENTRY* evsaStoreHeader = (const EVSA_STORE_ENTRY*)store.constData();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
if (dataSize < evsaStoreHeader->StoreSize) {
|
if (dataSize < evsaStoreHeader->StoreSize) {
|
||||||
msg(QObject::tr("parseStoreHeader: EVSA store size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseEvsaStoreHeader: EVSA store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(evsaStoreHeader->StoreSize).arg(evsaStoreHeader->StoreSize)
|
.hexarg(evsaStoreHeader->StoreSize).arg(evsaStoreHeader->StoreSize)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -3757,8 +3835,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
QString name = QObject::tr("EVSA store");
|
QString name = QObject::tr("EVSA store");
|
||||||
QString info = QObject::tr("Signature: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nType: %9h\nChecksum: %10\nAttributes: %11h")
|
QString info = QObject::tr("Signature: EVSA\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: %5h (%6)\nType: %7h\nChecksum: %8\nAttributes: %9h")
|
||||||
.hexarg2(evsaStoreHeader->Signature, 8)
|
|
||||||
.hexarg(evsaStoreHeader->StoreSize).arg(evsaStoreHeader->StoreSize)
|
.hexarg(evsaStoreHeader->StoreSize).arg(evsaStoreHeader->StoreSize)
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
@ -3773,82 +3850,27 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::EvsaStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::EvsaStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
}
|
|
||||||
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) {
|
|
||||||
// Check dataSize
|
|
||||||
if (dataSize < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64)) {
|
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for FTW block header"), parent);
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get FTW block headers
|
STATUS FfsParser::parseFlashMapStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftw32BlockHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)signature;
|
{
|
||||||
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64BlockHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)signature;
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
// Check store size
|
// Check data size
|
||||||
UINT32 ftwBlockSize;
|
|
||||||
bool has32bitHeader;
|
|
||||||
if (ftw32BlockHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize
|
|
||||||
ftwBlockSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) + ftw32BlockHeader->WriteQueueSize;
|
|
||||||
has32bitHeader = true;
|
|
||||||
}
|
|
||||||
else { // Header with 64 bit WriteQueueSize
|
|
||||||
ftwBlockSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64) + ftw64BlockHeader->WriteQueueSize;
|
|
||||||
has32bitHeader = false;
|
|
||||||
}
|
|
||||||
if (dataSize < ftwBlockSize) {
|
|
||||||
msg(QObject::tr("parseStoreHeader: FTW block size %1h (%2) is greater than volume body size %3h (%4)")
|
|
||||||
.hexarg(ftwBlockSize).arg(ftwBlockSize)
|
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get parsing data
|
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
|
||||||
|
|
||||||
// Construct header and body
|
|
||||||
UINT32 headerSize = has32bitHeader ? sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) : sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64);
|
|
||||||
QByteArray header = store.left(headerSize);
|
|
||||||
QByteArray body = store.mid(headerSize, ftwBlockSize - headerSize);
|
|
||||||
|
|
||||||
// Check block header checksum
|
|
||||||
QByteArray crcHeader = header;
|
|
||||||
EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* crcFtwBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)header.data();
|
|
||||||
crcFtwBlockHeader->Crc = pdata.emptyByte ? 0xFFFFFFFF : 0;
|
|
||||||
crcFtwBlockHeader->State = pdata.emptyByte ? 0xFF : 0;
|
|
||||||
UINT32 calculatedCrc = crc32(0, (const UINT8*)crcFtwBlockHeader, headerSize);
|
|
||||||
|
|
||||||
// Add info
|
|
||||||
QString name = QObject::tr("FTW block");
|
|
||||||
QString info = QObject::tr("Signature: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nState: %8h\nHeader CRC32: %9")
|
|
||||||
.arg(guidToQString(ftw32BlockHeader->Signature))
|
|
||||||
.hexarg(ftwBlockSize).arg(ftwBlockSize)
|
|
||||||
.hexarg(headerSize).arg(headerSize)
|
|
||||||
.hexarg(body.size()).arg(body.size())
|
|
||||||
.hexarg2(ftw32BlockHeader->State, 2)
|
|
||||||
.arg(ftw32BlockHeader->Crc == calculatedCrc ?
|
|
||||||
QObject::tr("%1h, valid").hexarg2(ftw32BlockHeader->Crc, 8) :
|
|
||||||
QObject::tr("%1h, invalid, should be %2h").hexarg2(ftw32BlockHeader->Crc, 8).hexarg2(calculatedCrc, 8));
|
|
||||||
|
|
||||||
// Add correct offset
|
|
||||||
pdata.offset = parentOffset;
|
|
||||||
|
|
||||||
// Add tree item
|
|
||||||
index = model->addItem(Types::FtwStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
|
||||||
}
|
|
||||||
else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) { // Phoenix SCT flash map
|
|
||||||
if (dataSize < sizeof(PHOENIX_FLASH_MAP_HEADER)) {
|
if (dataSize < sizeof(PHOENIX_FLASH_MAP_HEADER)) {
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for FlashMap block header"), parent);
|
msg(QObject::tr("parseFlashMapStoreHeader: volume body is too small even for FlashMap block header"), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get FlashMap block header
|
// Get FlashMap block header
|
||||||
const PHOENIX_FLASH_MAP_HEADER* flashMapHeader = (const PHOENIX_FLASH_MAP_HEADER*)signature;
|
const PHOENIX_FLASH_MAP_HEADER* flashMapHeader = (const PHOENIX_FLASH_MAP_HEADER*)store.constData();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
UINT32 flashMapSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + flashMapHeader->NumEntries * sizeof(PHOENIX_FLASH_MAP_ENTRY);
|
UINT32 flashMapSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + flashMapHeader->NumEntries * sizeof(PHOENIX_FLASH_MAP_ENTRY);
|
||||||
if (dataSize < flashMapSize) {
|
if (dataSize < flashMapSize) {
|
||||||
msg(QObject::tr("parseStoreHeader: FlashMap block size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseFlashMapStoreHeader: FlashMap block size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(flashMapSize).arg(flashMapSize)
|
.hexarg(flashMapSize).arg(flashMapSize)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -3874,24 +3896,30 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::FlashMapStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::FlashMapStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
}
|
|
||||||
else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store
|
|
||||||
if (dataSize < sizeof(PHOENIX_CMDB_HEADER)) {
|
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for CMDB store header"), parent);
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATUS FfsParser::parseCmdbStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
|
if (dataSize < sizeof(PHOENIX_CMDB_HEADER)) {
|
||||||
|
msg(QObject::tr("parseCmdbStoreHeader: volume body is too small even for CMDB store header"), parent);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
UINT32 cmdbSize = NVRAM_PHOENIX_CMDB_SIZE;
|
UINT32 cmdbSize = NVRAM_PHOENIX_CMDB_SIZE;
|
||||||
if (dataSize < cmdbSize) {
|
if (dataSize < cmdbSize) {
|
||||||
msg(QObject::tr("parseStoreHeader: CMDB store size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseCmdbStoreHeader: CMDB store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(cmdbSize).arg(cmdbSize)
|
.hexarg(cmdbSize).arg(cmdbSize)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get CMBD store header
|
// Get store header
|
||||||
const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)signature;
|
const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)store.constData();
|
||||||
|
|
||||||
// Get parsing data
|
// Get parsing data
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||||
@ -3912,19 +3940,26 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::CmdbStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::CmdbStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey
|
|
||||||
|
STATUS FfsParser::parseSlicPubkeyHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
|
// Check data size
|
||||||
if (dataSize < sizeof(OEM_ACTIVATION_PUBKEY)) {
|
if (dataSize < sizeof(OEM_ACTIVATION_PUBKEY)) {
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for SLIC pubkey header"), parent);
|
msg(QObject::tr("parseSlicPubkeyHeader: volume body is too small even for SLIC pubkey header"), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get SLIC pubkey header
|
// Get SLIC pubkey header
|
||||||
const OEM_ACTIVATION_PUBKEY* pubkeyHeader = (const OEM_ACTIVATION_PUBKEY*)signature;
|
const OEM_ACTIVATION_PUBKEY* pubkeyHeader = (const OEM_ACTIVATION_PUBKEY*)store.constData();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
if (dataSize < pubkeyHeader->Size) {
|
if (dataSize < pubkeyHeader->Size) {
|
||||||
msg(QObject::tr("parseStoreHeader: SLIC pubkey size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseSlicPubkeyHeader: SLIC pubkey size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(pubkeyHeader->Size).arg(pubkeyHeader->Size)
|
.hexarg(pubkeyHeader->Size).arg(pubkeyHeader->Size)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -3953,19 +3988,26 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::SlicData, Subtypes::PubkeySlicData, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::SlicData, Subtypes::PubkeySlicData, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) { // SLIC marker
|
|
||||||
|
STATUS FfsParser::parseSlicMarkerHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
|
// Check data size
|
||||||
if (dataSize < sizeof(OEM_ACTIVATION_MARKER)) {
|
if (dataSize < sizeof(OEM_ACTIVATION_MARKER)) {
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for SLIC marker header"), parent);
|
msg(QObject::tr("parseSlicMarkerHeader: volume body is too small even for SLIC marker header"), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get SLIC marker header
|
// Get SLIC marker header
|
||||||
const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)signature;
|
const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)store.constData();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
if (dataSize < markerHeader->Size) {
|
if (dataSize < markerHeader->Size) {
|
||||||
msg(QObject::tr("parseStoreHeader: SLIC marker size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseSlicMarkerHeader: SLIC marker size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(markerHeader->Size).arg(markerHeader->Size)
|
.hexarg(markerHeader->Size).arg(markerHeader->Size)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -3993,19 +4035,26 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::SlicData, Subtypes::MarkerSlicData, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::SlicData, Subtypes::MarkerSlicData, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (*signature == INTEL_MICROCODE_HEADER_VERSION) { // Intel microcode, , must be checked after SLIC marker because of the same *signature values
|
|
||||||
|
STATUS FfsParser::parseIntelMicrocodeHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
|
// Check data size
|
||||||
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
|
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
|
||||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for Intel microcode header"), parent);
|
msg(QObject::tr("parseIntelMicrocodeHeader: volume body is too small even for Intel microcode header"), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Intel microcode header
|
// Get Intel microcode header
|
||||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)signature;
|
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)store.constData();
|
||||||
|
|
||||||
// Check store size
|
// Check store size
|
||||||
if (dataSize < ucodeHeader->TotalSize) {
|
if (dataSize < ucodeHeader->TotalSize) {
|
||||||
msg(QObject::tr("parseStoreHeader: Intel microcode size %1h (%2) is greater than volume body size %3h (%4)")
|
msg(QObject::tr("parseIntelMicrocodeHeader: Intel microcode size %1h (%2) is greater than volume body size %3h (%4)")
|
||||||
.hexarg(ucodeHeader->TotalSize).arg(ucodeHeader->TotalSize)
|
.hexarg(ucodeHeader->TotalSize).arg(ucodeHeader->TotalSize)
|
||||||
.hexarg(dataSize).arg(dataSize), parent);
|
.hexarg(dataSize).arg(dataSize), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -4018,10 +4067,12 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
QByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER));
|
QByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER));
|
||||||
QByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
|
QByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
|
||||||
|
|
||||||
|
//TODO: recalculate checksum
|
||||||
|
|
||||||
// Add info
|
// Add info
|
||||||
QString name = QObject::tr("Intel microcode");
|
QString name = QObject::tr("Intel microcode");
|
||||||
QString info = QObject::tr("Revision: 1h\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: %5h (%6)\n"
|
QString info = QObject::tr("Revision: 1h\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: %5h (%6)\n"
|
||||||
"Date: %7\nCPU signature: %8h\nChecksum: %9h\nLoader revision: %10h\nCPU flags: %11h")
|
"Date: %7h\nCPU signature: %8h\nChecksum: %9h\nLoader revision: %10h\nCPU flags: %11h")
|
||||||
.hexarg(ucodeHeader->TotalSize).arg(ucodeHeader->TotalSize)
|
.hexarg(ucodeHeader->TotalSize).arg(ucodeHeader->TotalSize)
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
@ -4036,8 +4087,54 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Microcode, Subtypes::IntelMicrocode, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Microcode, Subtypes::IntelMicrocode, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
|
{
|
||||||
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
const UINT32* signature = (const UINT32*)store.constData();
|
||||||
|
// Check store size
|
||||||
|
if (dataSize < sizeof(UINT32)) {
|
||||||
|
msg(QObject::tr("parseStoreHeader: volume body is too small even for store signature"), parent);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check signature and run parser function needed
|
||||||
|
// VSS/SVS store
|
||||||
|
if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE)
|
||||||
|
return parseVssStoreHeader(store, parentOffset, parent, index);
|
||||||
|
// FTW store
|
||||||
|
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1)
|
||||||
|
return parseFtwStoreHeader(store, parentOffset, parent, index);
|
||||||
|
// FDC store
|
||||||
|
else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE)
|
||||||
|
return parseFdcStoreHeader(store, parentOffset, parent, index);
|
||||||
|
// Apple Fsys/Gaid store
|
||||||
|
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE)
|
||||||
|
return parseFsysStoreHeader(store, parentOffset, parent, index);
|
||||||
|
// EVSA store
|
||||||
|
else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE)
|
||||||
|
return parseEvsaStoreHeader(store, parentOffset, parent, index);
|
||||||
|
// Phoenix SCT flash map
|
||||||
|
else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1)
|
||||||
|
return parseFlashMapStoreHeader(store, parentOffset, parent, index);
|
||||||
|
// Phoenix CMDB store
|
||||||
|
else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE)
|
||||||
|
return parseCmdbStoreHeader(store, parentOffset, parent, index);
|
||||||
|
// SLIC pubkey
|
||||||
|
else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC)
|
||||||
|
return parseSlicPubkeyHeader(store, parentOffset, parent, index);
|
||||||
|
// SLIC marker
|
||||||
|
else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG)
|
||||||
|
return parseSlicMarkerHeader(store, parentOffset, parent, index);
|
||||||
|
// Intel microcode
|
||||||
|
// Must be checked after SLIC marker because of the same *signature values
|
||||||
|
else if (*signature == INTEL_MICROCODE_HEADER_VERSION)
|
||||||
|
return parseIntelMicrocodeHeader(store, parentOffset, parent, index);
|
||||||
|
|
||||||
|
msg(QObject::tr("parseStoreHeader: don't know how to parse a header with signature %1h").hexarg2(*signature, 8), parent);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4214,7 +4311,7 @@ STATUS FfsParser::parseVssStoreBody(const QModelIndex & index)
|
|||||||
info += QObject::tr("\nState: %1h").hexarg2(variableHeader->State, 2);
|
info += QObject::tr("\nState: %1h").hexarg2(variableHeader->State, 2);
|
||||||
|
|
||||||
// Add attributes info
|
// Add attributes info
|
||||||
info += QObject::tr("\nAttributes: %1h").hexarg2(variableHeader->Attributes, 8);
|
info += QObject::tr("\nAttributes: %1h (%2)").hexarg2(variableHeader->Attributes, 8).arg(vssAttributesToQString(variableHeader->Attributes));
|
||||||
|
|
||||||
// Set subtype and add related info
|
// Set subtype and add related info
|
||||||
if (isInvalid)
|
if (isInvalid)
|
||||||
@ -4227,7 +4324,7 @@ STATUS FfsParser::parseVssStoreBody(const QModelIndex & index)
|
|||||||
}
|
}
|
||||||
else if (isAppleCrc32) {
|
else if (isAppleCrc32) {
|
||||||
subtype = Subtypes::AppleVssEntry;
|
subtype = Subtypes::AppleVssEntry;
|
||||||
info += QObject::tr("\nCRC32: %1h%2").hexarg2(storedCrc32, 8)
|
info += QObject::tr("\nData checksum: %1h%2").hexarg2(storedCrc32, 8)
|
||||||
.arg(storedCrc32 == calculatedCrc32 ? QObject::tr(", valid") : QObject::tr(", invalid, should be %1h").hexarg2(calculatedCrc32,8));
|
.arg(storedCrc32 == calculatedCrc32 ? QObject::tr(", valid") : QObject::tr(", invalid, should be %1h").hexarg2(calculatedCrc32,8));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4363,14 +4460,14 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
|||||||
UINT32 parentOffset = pdata.offset + model->header(index).size();
|
UINT32 parentOffset = pdata.offset + model->header(index).size();
|
||||||
const QByteArray data = model->body(index);
|
const QByteArray data = model->body(index);
|
||||||
|
|
||||||
// Check that the is enough space for variable header
|
// Check that the is enough space for entry header
|
||||||
const UINT32 dataSize = (UINT32)data.size();
|
const UINT32 dataSize = (UINT32)data.size();
|
||||||
UINT32 offset = 0;
|
UINT32 offset = 0;
|
||||||
|
|
||||||
std::map<UINT16, EFI_GUID> guidMap;
|
std::map<UINT16, EFI_GUID> guidMap;
|
||||||
std::map<UINT16, QString> nameMap;
|
std::map<UINT16, QString> nameMap;
|
||||||
|
|
||||||
// Parse all variables
|
// Parse all entries
|
||||||
UINT32 unparsedSize = dataSize;
|
UINT32 unparsedSize = dataSize;
|
||||||
while (unparsedSize) {
|
while (unparsedSize) {
|
||||||
UINT32 variableSize = 0;
|
UINT32 variableSize = 0;
|
||||||
@ -4383,14 +4480,14 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
|||||||
|
|
||||||
const EVSA_ENTRY_HEADER* entryHeader = (const EVSA_ENTRY_HEADER*)(data.constData() + offset);
|
const EVSA_ENTRY_HEADER* entryHeader = (const EVSA_ENTRY_HEADER*)(data.constData() + offset);
|
||||||
|
|
||||||
// Check variable size
|
// Check entry size
|
||||||
variableSize = sizeof(EVSA_ENTRY_HEADER);
|
variableSize = sizeof(EVSA_ENTRY_HEADER);
|
||||||
if (unparsedSize < variableSize || unparsedSize < entryHeader->Size) {
|
if (unparsedSize < variableSize || unparsedSize < entryHeader->Size) {
|
||||||
QByteArray body = data.mid(offset);
|
QByteArray body = data.mid(offset);
|
||||||
QString info = QObject::tr("Full size: %1h (%2)")
|
QString info = QObject::tr("Full size: %1h (%2)")
|
||||||
.hexarg(body.size()).arg(body.size());
|
.hexarg(body.size()).arg(body.size());
|
||||||
|
|
||||||
// Check type
|
// Checke type
|
||||||
QString name = QObject::tr("Free space");
|
QString name = QObject::tr("Free space");
|
||||||
UINT8 type = Types::FreeSpace;
|
UINT8 type = Types::FreeSpace;
|
||||||
UINT8 subtype = 0;
|
UINT8 subtype = 0;
|
||||||
@ -4425,7 +4522,8 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
|||||||
body = data.mid(offset + sizeof(EVSA_GUID_ENTRY), guidHeader->Header.Size - sizeof(EVSA_GUID_ENTRY));
|
body = data.mid(offset + sizeof(EVSA_GUID_ENTRY), guidHeader->Header.Size - sizeof(EVSA_GUID_ENTRY));
|
||||||
EFI_GUID guid = *(EFI_GUID*)body.constData();
|
EFI_GUID guid = *(EFI_GUID*)body.constData();
|
||||||
name = guidToQString(guid);
|
name = guidToQString(guid);
|
||||||
info = QObject::tr("Full size: %1h (%2)\nHeader size %3h (%4)\nBody size: %5h (%6)\nType: %7h\nChecksum: %8\nGuidId: %9h")
|
info = QObject::tr("GUID: %1\nFull size: %2h (%3)\nHeader size %4h (%5)\nBody size: %6h (%7)\nType: %8h\nChecksum: %9\nGuidId: %10h")
|
||||||
|
.arg(name)
|
||||||
.hexarg(variableSize).arg(variableSize)
|
.hexarg(variableSize).arg(variableSize)
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
@ -4444,7 +4542,8 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
|||||||
header = data.mid(offset, sizeof(EVSA_NAME_ENTRY));
|
header = data.mid(offset, sizeof(EVSA_NAME_ENTRY));
|
||||||
body = data.mid(offset + sizeof(EVSA_NAME_ENTRY), nameHeader->Header.Size - sizeof(EVSA_NAME_ENTRY));
|
body = data.mid(offset + sizeof(EVSA_NAME_ENTRY), nameHeader->Header.Size - sizeof(EVSA_NAME_ENTRY));
|
||||||
name = QString::fromUtf16((const CHAR16*)body.constData());
|
name = QString::fromUtf16((const CHAR16*)body.constData());
|
||||||
info = QObject::tr("Full size: %1h (%2)\nHeader size %3h (%4)\nBody size: %5h (%6)\nType: %7h\nChecksum: %8\nVarId: %9h")
|
info = QObject::tr("Name: %1\nFull size: %2h (%3)\nHeader size %4h (%5)\nBody size: %6h (%7)\nType: %8h\nChecksum: %9\nVarId: %10h")
|
||||||
|
.arg(name)
|
||||||
.hexarg(variableSize).arg(variableSize)
|
.hexarg(variableSize).arg(variableSize)
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
@ -4464,7 +4563,7 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
|||||||
// Check for extended header
|
// Check for extended header
|
||||||
UINT32 headerSize = sizeof(EVSA_DATA_ENTRY);
|
UINT32 headerSize = sizeof(EVSA_DATA_ENTRY);
|
||||||
UINT32 dataSize = dataHeader->Header.Size - sizeof(EVSA_DATA_ENTRY);
|
UINT32 dataSize = dataHeader->Header.Size - sizeof(EVSA_DATA_ENTRY);
|
||||||
if (dataHeader->Attributes & NVRAM_EVSA_DATA_ATTRIBUTE_EXTENDED_HEADER) {
|
if (dataHeader->Attributes & NVRAM_EVSA_DATA_EXTENDED_HEADER) {
|
||||||
const EVSA_DATA_ENTRY_EXTENDED* dataHeaderExtended = (const EVSA_DATA_ENTRY_EXTENDED*)entryHeader;
|
const EVSA_DATA_ENTRY_EXTENDED* dataHeaderExtended = (const EVSA_DATA_ENTRY_EXTENDED*)entryHeader;
|
||||||
headerSize = sizeof(EVSA_DATA_ENTRY_EXTENDED);
|
headerSize = sizeof(EVSA_DATA_ENTRY_EXTENDED);
|
||||||
dataSize = dataHeaderExtended->DataSize;
|
dataSize = dataHeaderExtended->DataSize;
|
||||||
@ -4474,7 +4573,7 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
|||||||
header = data.mid(offset, headerSize);
|
header = data.mid(offset, headerSize);
|
||||||
body = data.mid(offset + headerSize, dataSize);
|
body = data.mid(offset + headerSize, dataSize);
|
||||||
name = QObject::tr("Data");
|
name = QObject::tr("Data");
|
||||||
info = QObject::tr("Full size: %1h (%2)\nHeader size %3h (%4)\nBody size: %5h (%6)\nType: %7h\nChecksum: %8\nVarId: %9h\nGuidId: %10h\nAttributes: %11h")
|
info = QObject::tr("Full size: %1h (%2)\nHeader size %3h (%4)\nBody size: %5h (%6)\nType: %7h\nChecksum: %8\nVarId: %9h\nGuidId: %10h\nAttributes: %11h (%12)")
|
||||||
.hexarg(variableSize).arg(variableSize)
|
.hexarg(variableSize).arg(variableSize)
|
||||||
.hexarg(headerSize).arg(headerSize)
|
.hexarg(headerSize).arg(headerSize)
|
||||||
.hexarg(dataSize).arg(dataSize)
|
.hexarg(dataSize).arg(dataSize)
|
||||||
@ -4484,7 +4583,7 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
|||||||
QObject::tr("%1h, invalid, should be %2h").hexarg2(dataHeader->Header.Checksum, 2).hexarg2(calculated, 2))
|
QObject::tr("%1h, invalid, should be %2h").hexarg2(dataHeader->Header.Checksum, 2).hexarg2(calculated, 2))
|
||||||
.hexarg2(dataHeader->VarId, 4)
|
.hexarg2(dataHeader->VarId, 4)
|
||||||
.hexarg2(dataHeader->GuidId, 4)
|
.hexarg2(dataHeader->GuidId, 4)
|
||||||
.hexarg2(dataHeader->Attributes, 8);
|
.hexarg2(dataHeader->Attributes, 8).arg(evsaAttributesToQString(dataHeader->Attributes));
|
||||||
subtype = Subtypes::DataEvsaEntry;
|
subtype = Subtypes::DataEvsaEntry;
|
||||||
}
|
}
|
||||||
// Unknown entry or free space
|
// Unknown entry or free space
|
||||||
@ -4564,6 +4663,7 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
|||||||
model->setName(current, guid);
|
model->setName(current, guid);
|
||||||
}
|
}
|
||||||
model->setText(current, name);
|
model->setText(current, name);
|
||||||
|
model->addInfo(current, QObject::tr("GUID: %1\nName: %2\n").arg(guid).arg(name), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
TreeModel *model;
|
TreeModel *model;
|
||||||
std::vector<std::pair<QString, QModelIndex> > messagesVector;
|
std::vector<std::pair<QString, QModelIndex> > messagesVector;
|
||||||
|
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
||||||
|
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||||
|
};
|
||||||
|
|
||||||
QModelIndex lastVtf;
|
QModelIndex lastVtf;
|
||||||
UINT32 capsuleOffsetFixup;
|
UINT32 capsuleOffsetFixup;
|
||||||
|
|
||||||
@ -113,25 +117,21 @@ private:
|
|||||||
STATUS parseStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
STATUS parseStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
|
|
||||||
STATUS parseNvarStore(const QByteArray & data, const QModelIndex & index);
|
STATUS parseNvarStore(const QByteArray & data, const QModelIndex & index);
|
||||||
//STATUS parseVssStore(const QByteArray & data, const QModelIndex & index);
|
STATUS parseVssStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
//STATUS parseFtwStore(const QByteArray & data, const QModelIndex & index);
|
STATUS parseFtwStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
//STATUS parseFdcStore(const QByteArray & data, const QModelIndex & index);
|
STATUS parseFdcStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
//STATUS parseFsysStore(const QByteArray & data, const QModelIndex & index);
|
STATUS parseFsysStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
//STATUS parseEvsaStore(const QByteArray & data, const QModelIndex & index);
|
STATUS parseEvsaStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
//STATUS parseFlashMapStore(const QByteArray & data, const QModelIndex & index);
|
STATUS parseFlashMapStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
//STATUS parseCmdbStore(const QByteArray & data, const QModelIndex & index);
|
STATUS parseCmdbStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
//STATUS parseSlicData(const QByteArray & data, const QModelIndex & index);
|
STATUS parseSlicPubkeyHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
//STATUS parseMicrocode(const QByteArray & data, const QModelIndex & index);
|
STATUS parseSlicMarkerHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
|
STATUS parseIntelMicrocodeHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
|
|
||||||
STATUS parseVssStoreBody(const QModelIndex & index);
|
STATUS parseVssStoreBody(const QModelIndex & index);
|
||||||
STATUS parseFsysStoreBody(const QModelIndex & index);
|
STATUS parseFsysStoreBody(const QModelIndex & index);
|
||||||
STATUS parseEvsaStoreBody(const QModelIndex & index);
|
STATUS parseEvsaStoreBody(const QModelIndex & index);
|
||||||
STATUS parseFlashMapBody(const QModelIndex & index);
|
STATUS parseFlashMapBody(const QModelIndex & index);
|
||||||
|
|
||||||
// Message helper
|
|
||||||
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
|
||||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FFSPARSER_H
|
#endif // FFSPARSER_H
|
||||||
|
@ -20,14 +20,57 @@ QString nvarAttributesToQString(const UINT8 attributes)
|
|||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
QString str;
|
QString str;
|
||||||
if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_RUNTIME) str += QObject::tr(", Runtime");
|
if (attributes & NVRAM_NVAR_ENTRY_RUNTIME) str += QObject::tr(", Runtime");
|
||||||
if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_ASCII_NAME) str += QObject::tr(", AsciiName");
|
if (attributes & NVRAM_NVAR_ENTRY_ASCII_NAME) str += QObject::tr(", AsciiName");
|
||||||
if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_GUID) str += QObject::tr(", Guid");
|
if (attributes & NVRAM_NVAR_ENTRY_GUID) str += QObject::tr(", Guid");
|
||||||
if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_DATA_ONLY) str += QObject::tr(", DataOnly");
|
if (attributes & NVRAM_NVAR_ENTRY_DATA_ONLY) str += QObject::tr(", DataOnly");
|
||||||
if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_EXT_HEADER) str += QObject::tr(", ExtHeader");
|
if (attributes & NVRAM_NVAR_ENTRY_EXT_HEADER) str += QObject::tr(", ExtHeader");
|
||||||
if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_HW_ERROR_RECORD) str += QObject::tr(", HwErrorRecord");
|
if (attributes & NVRAM_NVAR_ENTRY_HW_ERROR_RECORD) str += QObject::tr(", HwErrorRecord");
|
||||||
if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_AUTH_WRITE) str += QObject::tr(", AuthWrite");
|
if (attributes & NVRAM_NVAR_ENTRY_AUTH_WRITE) str += QObject::tr(", AuthWrite");
|
||||||
if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_VALID) str += QObject::tr(", Valid");
|
if (attributes & NVRAM_NVAR_ENTRY_VALID) str += QObject::tr(", Valid");
|
||||||
|
|
||||||
|
return str.mid(2); // Remove first comma and space
|
||||||
|
}
|
||||||
|
|
||||||
|
QString nvarExtendedAttributesToQString(const UINT8 attributes)
|
||||||
|
{
|
||||||
|
QString str;
|
||||||
|
if (attributes & NVRAM_NVAR_ENTRY_EXT_CHECKSUM) str += QObject::tr(", Checksum");
|
||||||
|
if (attributes & NVRAM_NVAR_ENTRY_EXT_AUTH_WRITE) str += QObject::tr(", AuthWrite");
|
||||||
|
if (attributes & NVRAM_NVAR_ENTRY_EXT_TIME_BASED) str += QObject::tr(", TimeBasedAuthWrite");
|
||||||
|
if (attributes & NVRAM_NVAR_ENTRY_EXT_UNKNOWN_MASK) str += QObject::tr(", Unknown");
|
||||||
|
|
||||||
|
return str.mid(2); // Remove first comma and space
|
||||||
|
}
|
||||||
|
|
||||||
|
extern QString vssAttributesToQString(const UINT32 attributes)
|
||||||
|
{
|
||||||
|
QString str;
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_NON_VOLATILE) str += QObject::tr(", NonVolatile");
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_BOOTSERVICE_ACCESS) str += QObject::tr(", BootService");
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_RUNTIME_ACCESS) str += QObject::tr(", Runtime");
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_HARDWARE_ERROR_RECORD) str += QObject::tr(", HwErrorRecord");
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_AUTHENTICATED_WRITE_ACCESS) str += QObject::tr(", AuthWrite");
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) str += QObject::tr(", TimeBasedAuthWrite");
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_APPEND_WRITE) str += QObject::tr(", AppendWrite");
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM) str += QObject::tr(", AppleChecksum");
|
||||||
|
if (attributes & NVRAM_VSS_VARIABLE_UNKNOWN_MASK) str += QObject::tr(", Unknown");
|
||||||
|
|
||||||
|
return str.mid(2); // Remove first comma and space
|
||||||
|
}
|
||||||
|
|
||||||
|
QString evsaAttributesToQString(const UINT32 attributes)
|
||||||
|
{
|
||||||
|
QString str;
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_NON_VOLATILE) str += QObject::tr(", NonVolatile");
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_BOOTSERVICE_ACCESS) str += QObject::tr(", BootService");
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_RUNTIME_ACCESS) str += QObject::tr(", Runtime");
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_HARDWARE_ERROR_RECORD) str += QObject::tr(", HwErrorRecord");
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_AUTHENTICATED_WRITE_ACCESS) str += QObject::tr(", AuthWrite");
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) str += QObject::tr(", TimeBasedAuthWrite");
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_APPEND_WRITE) str += QObject::tr(", AppendWrite");
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_EXTENDED_HEADER) str += QObject::tr(", ExtendedHeader");
|
||||||
|
if (attributes & NVRAM_EVSA_DATA_UNKNOWN_MASK) str += QObject::tr(", Unknown");
|
||||||
|
|
||||||
return str.mid(2); // Remove first comma and space
|
return str.mid(2); // Remove first comma and space
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ const QByteArray NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID
|
|||||||
("\x5B\x31\x21\x92\xBB\x30\xB5\x46\x81\x3E\x1B\x1B\xF4\x71\x2B\xD3", 16);
|
("\x5B\x31\x21\x92\xBB\x30\xB5\x46\x81\x3E\x1B\x1B\xF4\x71\x2B\xD3", 16);
|
||||||
|
|
||||||
extern QString nvarAttributesToQString(const UINT8 attributes);
|
extern QString nvarAttributesToQString(const UINT8 attributes);
|
||||||
|
extern QString nvarExtendedAttributesToQString(const UINT8 attributes);
|
||||||
extern QString efiTimeToQString(const EFI_TIME & time);
|
extern QString efiTimeToQString(const EFI_TIME & time);
|
||||||
|
|
||||||
typedef struct NVAR_ENTRY_HEADER_ {
|
typedef struct NVAR_ENTRY_HEADER_ {
|
||||||
@ -49,20 +49,20 @@ typedef struct NVAR_ENTRY_HEADER_ {
|
|||||||
#define NVRAM_NVAR_ENTRY_SIGNATURE 0x5241564E
|
#define NVRAM_NVAR_ENTRY_SIGNATURE 0x5241564E
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
#define NVRAM_NVAR_ENTRY_ATTRIB_RUNTIME 0x01
|
#define NVRAM_NVAR_ENTRY_RUNTIME 0x01
|
||||||
#define NVRAM_NVAR_ENTRY_ATTRIB_ASCII_NAME 0x02
|
#define NVRAM_NVAR_ENTRY_ASCII_NAME 0x02
|
||||||
#define NVRAM_NVAR_ENTRY_ATTRIB_GUID 0x04
|
#define NVRAM_NVAR_ENTRY_GUID 0x04
|
||||||
#define NVRAM_NVAR_ENTRY_ATTRIB_DATA_ONLY 0x08
|
#define NVRAM_NVAR_ENTRY_DATA_ONLY 0x08
|
||||||
#define NVRAM_NVAR_ENTRY_ATTRIB_EXT_HEADER 0x10
|
#define NVRAM_NVAR_ENTRY_EXT_HEADER 0x10
|
||||||
#define NVRAM_NVAR_ENTRY_ATTRIB_HW_ERROR_RECORD 0x20
|
#define NVRAM_NVAR_ENTRY_HW_ERROR_RECORD 0x20
|
||||||
#define NVRAM_NVAR_ENTRY_ATTRIB_AUTH_WRITE 0x40
|
#define NVRAM_NVAR_ENTRY_AUTH_WRITE 0x40
|
||||||
#define NVRAM_NVAR_ENTRY_ATTRIB_VALID 0x80
|
#define NVRAM_NVAR_ENTRY_VALID 0x80
|
||||||
|
|
||||||
// Extended attributes
|
// Extended attributes
|
||||||
#define NVRAM_NVAR_ENTRY_EXT_ATTRIB_CHECKSUM 0x01
|
#define NVRAM_NVAR_ENTRY_EXT_CHECKSUM 0x01
|
||||||
#define NVRAM_NVAR_ENTRY_EXT_ATTRIB_AUTH_WRITE 0x10
|
#define NVRAM_NVAR_ENTRY_EXT_AUTH_WRITE 0x10
|
||||||
#define NVRAM_NVAR_ENTRY_EXT_ATTRIB_TIME_BASED 0x20
|
#define NVRAM_NVAR_ENTRY_EXT_TIME_BASED 0x20
|
||||||
|
#define NVRAM_NVAR_ENTRY_EXT_UNKNOWN_MASK 0xCE
|
||||||
//
|
//
|
||||||
// TianoCore VSS store and variables
|
// TianoCore VSS store and variables
|
||||||
//
|
//
|
||||||
@ -107,7 +107,7 @@ typedef struct VSS_VARIABLE_HEADER_ {
|
|||||||
UINT8 State; // Variable state
|
UINT8 State; // Variable state
|
||||||
UINT8 : 8;
|
UINT8 : 8;
|
||||||
UINT32 Attributes; // Variable attributes
|
UINT32 Attributes; // Variable attributes
|
||||||
UINT32 NameSize; // Size of variable name, null-terminated UCS2 string
|
UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string
|
||||||
UINT32 DataSize; // Size of variable data without header and name
|
UINT32 DataSize; // Size of variable data without header and name
|
||||||
EFI_GUID VendorGuid; // Variable vendor GUID
|
EFI_GUID VendorGuid; // Variable vendor GUID
|
||||||
} VSS_VARIABLE_HEADER;
|
} VSS_VARIABLE_HEADER;
|
||||||
@ -118,7 +118,7 @@ typedef struct VSS_APPLE_VARIABLE_HEADER_ {
|
|||||||
UINT8 State; // Variable state
|
UINT8 State; // Variable state
|
||||||
UINT8 : 8;
|
UINT8 : 8;
|
||||||
UINT32 Attributes; // Variable attributes
|
UINT32 Attributes; // Variable attributes
|
||||||
UINT32 NameSize; // Size of variable name, null-terminated UCS2 string
|
UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string
|
||||||
UINT32 DataSize; // Size of variable data without header and name
|
UINT32 DataSize; // Size of variable data without header and name
|
||||||
EFI_GUID VendorGuid; // Variable vendor GUID
|
EFI_GUID VendorGuid; // Variable vendor GUID
|
||||||
UINT32 DataCrc32; // CRC32 of the data
|
UINT32 DataCrc32; // CRC32 of the data
|
||||||
@ -133,7 +133,7 @@ typedef struct VSS_AUTH_VARIABLE_HEADER_ {
|
|||||||
UINT64 MonotonicCounter; // Monotonic counter against replay attack
|
UINT64 MonotonicCounter; // Monotonic counter against replay attack
|
||||||
EFI_TIME Timestamp; // Time stamp against replay attack
|
EFI_TIME Timestamp; // Time stamp against replay attack
|
||||||
UINT32 PubKeyIndex; // Index in PubKey database
|
UINT32 PubKeyIndex; // Index in PubKey database
|
||||||
UINT32 NameSize; // Size of variable name, null-terminated UCS2 string
|
UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string
|
||||||
UINT32 DataSize; // Size of variable data without header and name
|
UINT32 DataSize; // Size of variable data without header and name
|
||||||
EFI_GUID VendorGuid; // Variable vendor GUID
|
EFI_GUID VendorGuid; // Variable vendor GUID
|
||||||
} VSS_AUTH_VARIABLE_HEADER;
|
} VSS_AUTH_VARIABLE_HEADER;
|
||||||
@ -154,15 +154,18 @@ typedef struct VSS_AUTH_VARIABLE_HEADER_ {
|
|||||||
#define NVRAM_VSS_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
|
#define NVRAM_VSS_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
|
||||||
#define NVRAM_VSS_VARIABLE_APPEND_WRITE 0x00000040
|
#define NVRAM_VSS_VARIABLE_APPEND_WRITE 0x00000040
|
||||||
#define NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM 0x80000000
|
#define NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM 0x80000000
|
||||||
|
#define NVRAM_VSS_VARIABLE_UNKNOWN_MASK 0x7FFFFF80
|
||||||
|
|
||||||
|
extern QString vssAttributesToQString(const UINT32 attributes);
|
||||||
|
|
||||||
//
|
//
|
||||||
// FDC region
|
// _FDC region
|
||||||
//
|
//
|
||||||
|
|
||||||
#define NVRAM_FDC_VOLUME_SIGNATURE 0x4344465F
|
#define NVRAM_FDC_VOLUME_SIGNATURE 0x4344465F
|
||||||
|
|
||||||
typedef struct FDC_VOLUME_HEADER_ {
|
typedef struct FDC_VOLUME_HEADER_ {
|
||||||
UINT32 Signature; //_FDC
|
UINT32 Signature; //_FDC signature
|
||||||
UINT32 Size; // Size of the whole region
|
UINT32 Size; // Size of the whole region
|
||||||
//EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
|
//EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
|
||||||
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2];
|
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2];
|
||||||
@ -192,7 +195,7 @@ typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32_ {
|
|||||||
} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32;
|
} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32;
|
||||||
|
|
||||||
typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64_ {
|
typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64_ {
|
||||||
EFI_GUID Signature; // NVRAM_MAIN_STORE_VOLUME_GUID
|
EFI_GUID Signature; // NVRAM_MAIN_STORE_VOLUME_GUID or EDKII_WORKING_BLOCK_SIGNATURE_GUID
|
||||||
UINT32 Crc; // Crc32 of the header with empty Crc and State fields
|
UINT32 Crc; // Crc32 of the header with empty Crc and State fields
|
||||||
UINT8 State;
|
UINT8 State;
|
||||||
UINT8 Reserved[3];
|
UINT8 Reserved[3];
|
||||||
@ -205,8 +208,9 @@ typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64_ {
|
|||||||
//
|
//
|
||||||
|
|
||||||
typedef struct APPLE_FSYS_STORE_HEADER_ {
|
typedef struct APPLE_FSYS_STORE_HEADER_ {
|
||||||
UINT32 Signature; // Fsys signature
|
UINT32 Signature; // Fsys or Gaid signature
|
||||||
UINT8 Unknown[5]; // Still unknown
|
UINT8 Unknown0; // Still unknown
|
||||||
|
UINT32 Unknown1; // Still unknown
|
||||||
UINT16 Size; // Size of variable store
|
UINT16 Size; // Size of variable store
|
||||||
} APPLE_FSYS_STORE_HEADER;
|
} APPLE_FSYS_STORE_HEADER;
|
||||||
|
|
||||||
@ -220,7 +224,7 @@ typedef struct APPLE_FSYS_STORE_HEADER_ {
|
|||||||
// Has CRC32 of the whole store without checksum field at the end
|
// Has CRC32 of the whole store without checksum field at the end
|
||||||
|
|
||||||
//
|
//
|
||||||
// EVSA store and variables
|
// EVSA store and entries
|
||||||
//
|
//
|
||||||
|
|
||||||
#define NVRAM_EVSA_STORE_SIGNATURE 0x41535645
|
#define NVRAM_EVSA_STORE_SIGNATURE 0x41535645
|
||||||
@ -242,7 +246,7 @@ typedef struct EVSA_ENTRY_HEADER_ {
|
|||||||
|
|
||||||
typedef struct EVSA_STORE_ENTRY_ {
|
typedef struct EVSA_STORE_ENTRY_ {
|
||||||
EVSA_ENTRY_HEADER Header;
|
EVSA_ENTRY_HEADER Header;
|
||||||
UINT32 Signature; // EVSA
|
UINT32 Signature; // EVSA signature
|
||||||
UINT32 Attributes;
|
UINT32 Attributes;
|
||||||
UINT32 StoreSize;
|
UINT32 StoreSize;
|
||||||
UINT32 : 32;
|
UINT32 : 32;
|
||||||
@ -268,7 +272,16 @@ typedef struct EVSA_DATA_ENTRY_ {
|
|||||||
//UINT8 Data[];
|
//UINT8 Data[];
|
||||||
} EVSA_DATA_ENTRY;
|
} EVSA_DATA_ENTRY;
|
||||||
|
|
||||||
#define NVRAM_EVSA_DATA_ATTRIBUTE_EXTENDED_HEADER 0x10000000
|
// VSS variable attributes
|
||||||
|
#define NVRAM_EVSA_DATA_NON_VOLATILE 0x00000001
|
||||||
|
#define NVRAM_EVSA_DATA_BOOTSERVICE_ACCESS 0x00000002
|
||||||
|
#define NVRAM_EVSA_DATA_RUNTIME_ACCESS 0x00000004
|
||||||
|
#define NVRAM_EVSA_DATA_HARDWARE_ERROR_RECORD 0x00000008
|
||||||
|
#define NVRAM_EVSA_DATA_AUTHENTICATED_WRITE_ACCESS 0x00000010
|
||||||
|
#define NVRAM_EVSA_DATA_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
|
||||||
|
#define NVRAM_EVSA_DATA_APPEND_WRITE 0x00000040
|
||||||
|
#define NVRAM_EVSA_DATA_EXTENDED_HEADER 0x10000000
|
||||||
|
#define NVRAM_EVSA_DATA_UNKNOWN_MASK 0xEFFFFF80
|
||||||
|
|
||||||
typedef struct EVSA_DATA_ENTRY_EXTENDED_ {
|
typedef struct EVSA_DATA_ENTRY_EXTENDED_ {
|
||||||
EVSA_ENTRY_HEADER Header;
|
EVSA_ENTRY_HEADER Header;
|
||||||
@ -279,6 +292,8 @@ typedef struct EVSA_DATA_ENTRY_EXTENDED_ {
|
|||||||
//UINT8 Data[];
|
//UINT8 Data[];
|
||||||
} EVSA_DATA_ENTRY_EXTENDED;
|
} EVSA_DATA_ENTRY_EXTENDED;
|
||||||
|
|
||||||
|
extern QString evsaAttributesToQString(const UINT32 attributes);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Phoenix SCT Flash Map
|
// Phoenix SCT Flash Map
|
||||||
//
|
//
|
||||||
@ -381,7 +396,7 @@ typedef struct OEM_ACTIVATION_PUBKEY_ {
|
|||||||
UINT8 Version;
|
UINT8 Version;
|
||||||
UINT16 Reserved;
|
UINT16 Reserved;
|
||||||
UINT32 Algorithm;
|
UINT32 Algorithm;
|
||||||
UINT32 Magic; // RSA1
|
UINT32 Magic; // RSA1 signature
|
||||||
UINT32 BitLength;
|
UINT32 BitLength;
|
||||||
UINT32 Exponent;
|
UINT32 Exponent;
|
||||||
UINT8 Modulus[128];
|
UINT8 Modulus[128];
|
||||||
@ -396,7 +411,7 @@ typedef struct OEM_ACTIVATION_MARKER_ {
|
|||||||
UINT32 Version;
|
UINT32 Version;
|
||||||
UINT8 OemId[6];
|
UINT8 OemId[6];
|
||||||
UINT8 OemTableId[8];
|
UINT8 OemTableId[8];
|
||||||
UINT64 WindowsFlag;
|
UINT64 WindowsFlag; // WINDOWS signature
|
||||||
UINT32 SlicVersion;
|
UINT32 SlicVersion;
|
||||||
UINT8 Reserved[16];
|
UINT8 Reserved[16];
|
||||||
UINT8 Signature[128];
|
UINT8 Signature[128];
|
||||||
@ -412,7 +427,7 @@ typedef struct OEM_ACTIVATION_MARKER_ {
|
|||||||
//
|
//
|
||||||
|
|
||||||
typedef struct PHOENIX_CMDB_HEADER_ {
|
typedef struct PHOENIX_CMDB_HEADER_ {
|
||||||
UINT32 Signature; // CMDB
|
UINT32 Signature; // CMDB signature
|
||||||
UINT32 HeaderSize; // Size of this header
|
UINT32 HeaderSize; // Size of this header
|
||||||
UINT32 TotalSize; // Total size of header and chunks, without strings
|
UINT32 TotalSize; // Total size of header and chunks, without strings
|
||||||
// UINT8 StartChunk[3];
|
// UINT8 StartChunk[3];
|
||||||
|
@ -82,21 +82,10 @@ typedef struct SECTION_PARSING_DATA_ {
|
|||||||
};
|
};
|
||||||
} SECTION_PARSING_DATA;
|
} SECTION_PARSING_DATA;
|
||||||
|
|
||||||
typedef struct NVRAM_NVAR_PARSING_DATA_ {
|
typedef struct NVAR_ENTRY_PARSING_DATA_ {
|
||||||
|
BOOLEAN isValid;
|
||||||
UINT32 next;
|
UINT32 next;
|
||||||
UINT8 attributes;
|
} NVAR_ENTRY_PARSING_DATA;
|
||||||
UINT8 extendedAttributes;
|
|
||||||
UINT64 timestamp;
|
|
||||||
UINT8 hash[SHA256_HASH_SIZE]; //SHA256
|
|
||||||
} NVRAM_NVAR_PARSING_DATA;
|
|
||||||
|
|
||||||
typedef struct NVRAM_PARSING_DATA_ {
|
|
||||||
//union {
|
|
||||||
NVRAM_NVAR_PARSING_DATA nvar;
|
|
||||||
//};
|
|
||||||
} NVRAM_PARSING_DATA;
|
|
||||||
|
|
||||||
// TODO: add more NVRAM-related PD
|
|
||||||
|
|
||||||
typedef struct PARSING_DATA_ {
|
typedef struct PARSING_DATA_ {
|
||||||
UINT8 emptyByte;
|
UINT8 emptyByte;
|
||||||
@ -104,14 +93,10 @@ typedef struct PARSING_DATA_ {
|
|||||||
UINT32 offset;
|
UINT32 offset;
|
||||||
UINT32 address;
|
UINT32 address;
|
||||||
union {
|
union {
|
||||||
//CAPSULE_PARSING_DATA capsule;
|
|
||||||
//IMAGE_PARSING_DATA image;
|
|
||||||
//PADDING_PARSING_DATA padding;
|
|
||||||
VOLUME_PARSING_DATA volume;
|
VOLUME_PARSING_DATA volume;
|
||||||
//FREE_SPACE_PARSING_DATA freeSpace;
|
|
||||||
FILE_PARSING_DATA file;
|
FILE_PARSING_DATA file;
|
||||||
SECTION_PARSING_DATA section;
|
SECTION_PARSING_DATA section;
|
||||||
NVRAM_PARSING_DATA nvram;
|
NVAR_ENTRY_PARSING_DATA nvar;
|
||||||
};
|
};
|
||||||
} PARSING_DATA;
|
} PARSING_DATA;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user