NE Alpha 34

This commit is contained in:
Cr4sh 2016-10-27 23:31:15 +07:00
parent cb430456bf
commit 52c7a56f68
18 changed files with 731 additions and 854 deletions

View File

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) : UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::UEFITool), ui(new Ui::UEFITool),
version(tr("NE Alpha33")) version(tr("NE Alpha34"))
{ {
clipboard = QApplication::clipboard(); clipboard = QApplication::clipboard();
@ -205,7 +205,9 @@ void UEFITool::populateUi(const QModelIndex &current)
bool UEFITool::enableExtractBodyUncompressed(const QModelIndex &current) bool UEFITool::enableExtractBodyUncompressed(const QModelIndex &current)
{ {
if (current.isValid() && model->type(current) == Types::Section && // TODO: rewrite based on model->compressed()
U_UNUSED_PARAMETER(current);
/*if (current.isValid() && model->type(current) == Types::Section &&
(model->subtype(current) == EFI_SECTION_COMPRESSION || model->subtype(current) == EFI_SECTION_GUID_DEFINED)) { (model->subtype(current) == EFI_SECTION_COMPRESSION || model->subtype(current) == EFI_SECTION_GUID_DEFINED)) {
// Get parsing data // Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(current); PARSING_DATA pdata = parsingDataFromUModelIndex(current);
@ -222,7 +224,7 @@ bool UEFITool::enableExtractBodyUncompressed(const QModelIndex &current)
return true; return true;
} }
} }
} }*/
return false; return false;
} }
@ -304,17 +306,24 @@ void UEFITool::goToData()
QModelIndex parent = model->parent(index); QModelIndex parent = model->parent(index);
for (int i = index.row(); i < model->rowCount(parent); i++) { for (int i = index.row(); i < model->rowCount(parent); i++) {
PARSING_DATA pdata = parsingDataFromUModelIndex(index); if (model->hasEmptyParsingData(index))
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0; continue;
if (pdata.nvar.next == lastVariableFlag) {
UByteArray data = model->parsingData(index);
const NVAR_ENTRY_PARSING_DATA* pdata = (const NVAR_ENTRY_PARSING_DATA*)data.constData();
UINT32 lastVariableFlag = pdata->emptyByte ? 0xFFFFFF : 0;
UINT32 offset = model->offset(index);
if (pdata->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);
} }
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 = parsingDataFromUModelIndex(currentIndex); if (model->hasEmptyParsingData(currentIndex))
if (currentPdata.offset == pdata.offset + pdata.nvar.next) { continue;
if (model->offset(currentIndex) == offset + pdata->next) {
index = currentIndex; index = currentIndex;
break; break;
} }
@ -324,6 +333,7 @@ void UEFITool::goToData()
void UEFITool::insert(const UINT8 mode) void UEFITool::insert(const UINT8 mode)
{ {
U_UNUSED_PARAMETER(mode);
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); /*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid()) if (!index.isValid())
return; return;

0
UEFITool/uefitool.desktop Executable file → Normal file
View File

View File

@ -139,7 +139,10 @@ typedef unsigned int UINTN;
// EFI GUID // EFI GUID
typedef struct EFI_GUID_ { typedef struct EFI_GUID_ {
UINT8 Data[16]; UINT32 Data1;
UINT16 Data2;
UINT16 Data3;
UINT8 Data4[8];
} EFI_GUID; } EFI_GUID;
// EFI Time // EFI Time
@ -157,9 +160,14 @@ typedef struct EFI_TIME_ {
UINT8 : 8; UINT8 : 8;
} EFI_TIME; } EFI_TIME;
// Aling to 4 or 8 bytes
#define ALIGN4(Value) (((Value)+3) & ~3) #define ALIGN4(Value) (((Value)+3) & ~3)
#define ALIGN8(Value) (((Value)+7) & ~7) #define ALIGN8(Value) (((Value)+7) & ~7)
// Unused parameter declaration
#define U_UNUSED_PARAMETER(x) ((void)x)
// Assert macro
#include <assert.h> #include <assert.h>
#define ASSERT(x) assert(x) #define ASSERT(x) assert(x)

View File

@ -46,17 +46,17 @@ UINT32 uint24ToUint32(const UINT8* ffsSize)
UString guidToUString(const EFI_GUID & guid) UString guidToUString(const EFI_GUID & guid)
{ {
return usprintf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", return usprintf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
*(const UINT32*)&guid.Data[0], guid.Data1,
*(const UINT16*)&guid.Data[4], guid.Data2,
*(const UINT16*)&guid.Data[6], guid.Data3,
guid.Data[8], guid.Data4[0],
guid.Data[9], guid.Data4[1],
guid.Data[10], guid.Data4[2],
guid.Data[11], guid.Data4[3],
guid.Data[12], guid.Data4[4],
guid.Data[13], guid.Data4[5],
guid.Data[14], guid.Data4[6],
guid.Data[15]); guid.Data4[7]);
} }
UString fileTypeToUString(const UINT8 type) UString fileTypeToUString(const UINT8 type)
@ -72,10 +72,12 @@ UString fileTypeToUString(const UINT8 type)
case EFI_FV_FILETYPE_DRIVER: return UString("DXE driver"); case EFI_FV_FILETYPE_DRIVER: return UString("DXE driver");
case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: return UString("Combined PEI/DXE"); case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: return UString("Combined PEI/DXE");
case EFI_FV_FILETYPE_APPLICATION: return UString("Application"); case EFI_FV_FILETYPE_APPLICATION: return UString("Application");
case EFI_FV_FILETYPE_SMM: return UString("SMM module"); case EFI_FV_FILETYPE_MM: return UString("SMM module");
case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: return UString("Volume image"); case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: return UString("Volume image");
case EFI_FV_FILETYPE_COMBINED_SMM_DXE: return UString("Combined SMM/DXE"); case EFI_FV_FILETYPE_COMBINED_MM_DXE: return UString("Combined SMM/DXE");
case EFI_FV_FILETYPE_SMM_CORE: return UString("SMM core"); case EFI_FV_FILETYPE_MM_CORE: return UString("SMM core");
case EFI_FV_FILETYPE_MM_STANDALONE: return UString("MM standalone module");
case EFI_FV_FILETYPE_MM_CORE_STANDALONE: return UString("MM standalone core");
case EFI_FV_FILETYPE_PAD: return UString("Pad"); case EFI_FV_FILETYPE_PAD: return UString("Pad");
default: return UString("Unknown"); default: return UString("Unknown");
}; };
@ -99,7 +101,7 @@ UString sectionTypeToUString(const UINT8 type)
case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return UString("Freeform subtype GUID"); case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return UString("Freeform subtype GUID");
case EFI_SECTION_RAW: return UString("Raw"); case EFI_SECTION_RAW: return UString("Raw");
case EFI_SECTION_PEI_DEPEX: return UString("PEI dependency"); case EFI_SECTION_PEI_DEPEX: return UString("PEI dependency");
case EFI_SECTION_SMM_DEPEX: return UString("SMM dependency"); case EFI_SECTION_MM_DEPEX: return UString("MM dependency");
case INSYDE_SECTION_POSTCODE: return UString("Insyde postcode"); case INSYDE_SECTION_POSTCODE: return UString("Insyde postcode");
case PHOENIX_SECTION_POSTCODE: return UString("Phoenix postcode"); case PHOENIX_SECTION_POSTCODE: return UString("Phoenix postcode");
default: return UString("Unknown"); default: return UString("Unknown");

View File

@ -306,10 +306,12 @@ UINT32 ExtendedSize;
#define EFI_FV_FILETYPE_DRIVER 0x07 #define EFI_FV_FILETYPE_DRIVER 0x07
#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 #define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08
#define EFI_FV_FILETYPE_APPLICATION 0x09 #define EFI_FV_FILETYPE_APPLICATION 0x09
#define EFI_FV_FILETYPE_SMM 0x0A #define EFI_FV_FILETYPE_MM 0x0A
#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B #define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B
#define EFI_FV_FILETYPE_COMBINED_SMM_DXE 0x0C #define EFI_FV_FILETYPE_COMBINED_MM_DXE 0x0C
#define EFI_FV_FILETYPE_SMM_CORE 0x0D #define EFI_FV_FILETYPE_MM_CORE 0x0D
#define EFI_FV_FILETYPE_MM_STANDALONE 0x0E
#define EFI_FV_FILETYPE_MM_CORE_STANDALONE 0x0F
#define EFI_FV_FILETYPE_OEM_MIN 0xC0 #define EFI_FV_FILETYPE_OEM_MIN 0xC0
#define EFI_FV_FILETYPE_OEM_MAX 0xDF #define EFI_FV_FILETYPE_OEM_MAX 0xDF
#define EFI_FV_FILETYPE_DEBUG_MIN 0xE0 #define EFI_FV_FILETYPE_DEBUG_MIN 0xE0
@ -336,7 +338,7 @@ extern const UINT8 ffsAlignmentTable[];
#define EFI_FILE_MARKED_FOR_UPDATE 0x08 #define EFI_FILE_MARKED_FOR_UPDATE 0x08
#define EFI_FILE_DELETED 0x10 #define EFI_FILE_DELETED 0x10
#define EFI_FILE_HEADER_INVALID 0x20 #define EFI_FILE_HEADER_INVALID 0x20
#define EFI_FILE_ERASE_POLARITY 0x80 // Defined as "all other bits must be set to ERASE_POLARITY" in UEFI PI Vol3
// PEI apriori file // PEI apriori file
const UByteArray EFI_PEI_APRIORI_FILE_GUID const UByteArray EFI_PEI_APRIORI_FILE_GUID
("\x0A\xCC\x45\x1B\x6A\x15\x8A\x42\xAF\x62\x49\x86\x4D\xA0\xE6\xE6", 16); ("\x0A\xCC\x45\x1B\x6A\x15\x8A\x42\xAF\x62\x49\x86\x4D\xA0\xE6\xE6", 16);
@ -406,7 +408,7 @@ typedef struct EFI_COMMON_SECTION_HEADER_APPLE {
#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 #define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18
#define EFI_SECTION_RAW 0x19 #define EFI_SECTION_RAW 0x19
#define EFI_SECTION_PEI_DEPEX 0x1B #define EFI_SECTION_PEI_DEPEX 0x1B
#define EFI_SECTION_SMM_DEPEX 0x1C #define EFI_SECTION_MM_DEPEX 0x1C
#define PHOENIX_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images #define PHOENIX_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images
#define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde H2O images #define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde H2O images

View File

@ -23,9 +23,7 @@ USTATUS FfsBuilder::erase(const UModelIndex & index, UByteArray & erased)
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
PARSING_DATA pdata = parsingDataFromUModelIndex(index); return U_NOT_IMPLEMENTED;
erased.fill(pdata.emptyByte);
return U_SUCCESS;
} }
USTATUS FfsBuilder::build(const UModelIndex & root, UByteArray & image) USTATUS FfsBuilder::build(const UModelIndex & root, UByteArray & image)

View File

@ -21,33 +21,12 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get data from parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
// Construct a name for extracted data // Construct a name for extracted data
UString itemName = model->name(index); UString itemName = model->name(index);
UString itemText = model->text(index); UString itemText = model->text(index);
// Default name // Default name
name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_'); name = uniqueItemName(index);
switch (model->type(index)) {
case Types::Volume: if (pdata.volume.hasExtendedHeader) name = guidToUString(pdata.volume.extendedHeaderGuid).replace('-', '_'); break;
case Types::NvarEntry:
case Types::VssEntry:
case Types::FsysEntry:
case Types::EvsaEntry:
case Types::FlashMapEntry:
case Types::File: name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_').replace('-', '_'); break;
case Types::Section: {
// Get parent file name
UModelIndex fileIndex = model->findParentOfType(index, Types::File);
UString fileText = model->text(fileIndex);
name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_').replace('-', '_');
// Append section subtype name
name += '_' + itemName.replace(' ', '_');
} break;
}
// Get extracted data // Get extracted data
if (mode == EXTRACT_MODE_AS_IS) { if (mode == EXTRACT_MODE_AS_IS) {
@ -90,9 +69,6 @@ USTATUS FfsOperations::replace(const UModelIndex & index, const UString & data,
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get data from parsing data
//PARSING_DATA pdata = parsingDataFromQModelIndex(index);
if (mode == REPLACE_MODE_AS_IS) { if (mode == REPLACE_MODE_AS_IS) {
return U_NOT_IMPLEMENTED; return U_NOT_IMPLEMENTED;
} }

File diff suppressed because it is too large Load Diff

View File

@ -62,30 +62,30 @@ private:
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index); USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
USTATUS parseRawArea(const UModelIndex & index); USTATUS parseRawArea(const UModelIndex & index);
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseVolumeBody(const UModelIndex & index); USTATUS parseVolumeBody(const UModelIndex & index);
USTATUS parseFileHeader(const UByteArray & file, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseFileBody(const UModelIndex & index); USTATUS parseFileBody(const UModelIndex & index);
USTATUS parseSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
USTATUS parseSectionBody(const UModelIndex & index); USTATUS parseSectionBody(const UModelIndex & index);
USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & root); USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & root);
USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseMeRegion(const UByteArray & me, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parsePdrRegion(const UByteArray & pdr, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parsePdrRegion(const UByteArray & pdr, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseGeneralRegion(const UINT8 subtype, const UByteArray & region, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseGeneralRegion(const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parsePadFileBody(const UModelIndex & index); USTATUS parsePadFileBody(const UModelIndex & index);
USTATUS parseVolumeNonUefiData(const UByteArray & data, const UINT32 parentOffset, const UModelIndex & index); USTATUS parseVolumeNonUefiData(const UByteArray & data, const UINT32 localOffset, const UModelIndex & index);
USTATUS parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree); USTATUS parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree);
USTATUS parseCommonSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
USTATUS parseCompressedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseCompressedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
USTATUS parseGuidedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
USTATUS parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
USTATUS parseVersionSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseVersionSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
USTATUS parsePostcodeSectionHeader(const UByteArray & section, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parsePostcodeSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
USTATUS parseCompressedSectionBody(const UModelIndex & index); USTATUS parseCompressedSectionBody(const UModelIndex & index);
USTATUS parseGuidedSectionBody(const UModelIndex & index); USTATUS parseGuidedSectionBody(const UModelIndex & index);
@ -97,7 +97,7 @@ private:
USTATUS parseTeImageSectionBody(const UModelIndex & index); USTATUS parseTeImageSectionBody(const UModelIndex & index);
USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed); USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed);
USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 parentOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset); USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 localOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize); USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion); UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion); UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);

View File

@ -28,20 +28,27 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get parsing data for the current item // Obtain required information from parent file
PARSING_DATA pdata = parsingDataFromUModelIndex(index); UINT8 emptyByte = 0xFF;
UINT32 parentOffset = pdata.offset + model->header(index).size(); UModelIndex parentFileIndex = model->findParentOfType(index, Types::File);
if (parentFileIndex.isValid() && model->hasEmptyParsingData(parentFileIndex) == false) {
UByteArray data = model->parsingData(index);
const FILE_PARSING_DATA* pdata = (const FILE_PARSING_DATA*)data.constData();
emptyByte = pdata->emptyByte;
}
// Rename parent file
model->setText(parentFileIndex, UString("NVAR store"));
// Get local offset
UINT32 localOffset = model->offset(index) + model->header(index).size();
// Get item data // Get item data
const UByteArray data = model->body(index); const UByteArray data = model->body(index);
// Rename parent file // Parse all entries
model->setText(model->findParentOfType(index, Types::File), UString("NVAR store"));
UINT32 offset = 0; UINT32 offset = 0;
UINT32 guidsInStore = 0; UINT32 guidsInStore = 0;
const UINT8 emptyByte = pdata.emptyByte;
// Parse all entries
while (1) { while (1) {
bool msgUnknownExtDataFormat = false; bool msgUnknownExtDataFormat = false;
bool msgExtHeaderTooLong = false; bool msgExtHeaderTooLong = false;
@ -81,16 +88,15 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
if (unparsedSize < sizeof(NVAR_ENTRY_HEADER) || if (unparsedSize < sizeof(NVAR_ENTRY_HEADER) ||
entryHeader->Signature != NVRAM_NVAR_ENTRY_SIGNATURE || 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
UByteArray padding = data.mid(offset, unparsedSize); UByteArray padding = data.mid(offset, unparsedSize);
UINT8 type;
// Get info
if ((UINT32)padding.count(emptyByte) == unparsedSize) { UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// It's a free space
name = ("Free space"); if ((UINT32)padding.count(emptyByte) == unparsedSize) { // Free space
type = Types::FreeSpace; // Add tree item
subtype = 0; model->addItem(localOffset + offset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Movable, index);
} }
else { else {
// Nothing is parsed yet, but the file is not empty // Nothing is parsed yet, but the file is not empty
@ -99,18 +105,10 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
return U_SUCCESS; return U_SUCCESS;
} }
// It's a padding // Add tree item
name = UString("Padding"); model->addItem(localOffset + offset, Types::Padding, getPaddingType(padding), UString("Padding"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
type = Types::Padding;
subtype = getPaddingType(padding);
} }
// Get info
UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Construct parsing data
pdata.offset = parentOffset + offset;
// Add tree item
model->addItem(type, subtype, name, UString(), info, UByteArray(), padding, UByteArray(), false, parsingDataToUByteArray(pdata), index);
// Add GUID store area // Add GUID store area
UByteArray guidArea = data.right(guidAreaSize); UByteArray guidArea = data.right(guidAreaSize);
// Get info // Get info
@ -118,10 +116,8 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
info = usprintf("Full size: %Xh (%u)\nGUIDs in store: %u", info = usprintf("Full size: %Xh (%u)\nGUIDs in store: %u",
guidArea.size(), guidArea.size(), guidArea.size(), guidArea.size(),
guidsInStore); guidsInStore);
// Construct parsing data
pdata.offset = parentOffset + offset + padding.size();
// Add tree item // Add tree item
model->addItem(Types::Padding, getPaddingType(guidArea), name, UString(), info, UByteArray(), guidArea, UByteArray(), false, parsingDataToUByteArray(pdata), index); model->addItem(localOffset + offset + padding.size(), Types::Padding, getPaddingType(guidArea), name, UString(), info, UByteArray(), guidArea, UByteArray(), Fixed, index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -130,10 +126,12 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
header = data.mid(offset, sizeof(NVAR_ENTRY_HEADER)); header = data.mid(offset, sizeof(NVAR_ENTRY_HEADER));
body = data.mid(offset + sizeof(NVAR_ENTRY_HEADER), entryHeader->Size - sizeof(NVAR_ENTRY_HEADER)); body = data.mid(offset + sizeof(NVAR_ENTRY_HEADER), entryHeader->Size - sizeof(NVAR_ENTRY_HEADER));
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0; UINT32 lastVariableFlag = emptyByte ? 0xFFFFFF : 0;
// Set default next to predefined last value // Set default next to predefined last value
pdata.nvar.next = lastVariableFlag; NVAR_ENTRY_PARSING_DATA pdata;
pdata.emptyByte = emptyByte;
pdata.next = lastVariableFlag;
// Entry is marked as invalid // Entry is marked as invalid
if ((entryHeader->Attributes & NVRAM_NVAR_ENTRY_VALID) == 0) { // Valid attribute is not set if ((entryHeader->Attributes & NVRAM_NVAR_ENTRY_VALID) == 0) { // Valid attribute is not set
@ -145,7 +143,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
// 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.nvar.next = entryHeader->Next; pdata.next = entryHeader->Next;
} }
// Entry with extended header // Entry with extended header
@ -228,10 +226,13 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
// Search prevously added entries for a link to this variable // Search prevously added entries for a link to this variable
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 = parsingDataFromUModelIndex(nvarIndex); if (model->hasEmptyParsingData(nvarIndex) == false) {
if (nvarPdata.nvar.isValid && nvarPdata.nvar.next + nvarPdata.offset - parentOffset == offset) { // Previous link is present and valid UByteArray nvarData = model->parsingData(nvarIndex);
isInvalidLink = false; const NVAR_ENTRY_PARSING_DATA* nvarPdata = (const NVAR_ENTRY_PARSING_DATA*)nvarData.constData();
break; if (nvarPdata->isValid && nvarPdata->next + model->offset(nvarIndex) - localOffset == offset) { // Previous link is present and valid
isInvalidLink = false;
break;
}
} }
} }
// Check if the link is valid // Check if the link is valid
@ -287,16 +288,16 @@ parsing_done:
UString info; UString info;
// Rename invalid entries according to their types // Rename invalid entries according to their types
pdata.nvar.isValid = TRUE; pdata.isValid = TRUE;
if (isInvalid) { if (isInvalid) {
name = UString("Invalid"); name = UString("Invalid");
subtype = Subtypes::InvalidNvarEntry; subtype = Subtypes::InvalidNvarEntry;
pdata.nvar.isValid = FALSE; pdata.isValid = FALSE;
} }
else if (isInvalidLink) { else if (isInvalidLink) {
name = UString("Invalid link"); name = UString("Invalid link");
subtype = Subtypes::InvalidLinkNvarEntry; subtype = Subtypes::InvalidLinkNvarEntry;
pdata.nvar.isValid = FALSE; pdata.isValid = FALSE;
} }
else // Add GUID info for valid entries else // Add GUID info for valid entries
info += UString("Variable GUID: ") + name + UString("\n"); info += UString("Variable GUID: ") + name + UString("\n");
@ -319,7 +320,7 @@ parsing_done:
// Add next node info // Add next node info
if (!isInvalid && entryHeader->Next != lastVariableFlag) if (!isInvalid && entryHeader->Next != lastVariableFlag)
info += usprintf("\nNext node at offset: %Xh", parentOffset + offset + entryHeader->Next); info += usprintf("\nNext node at offset: %Xh", localOffset + offset + entryHeader->Next);
// Add extended header info // Add extended header info
if (hasExtendedHeader) { if (hasExtendedHeader) {
@ -341,11 +342,11 @@ parsing_done:
info += UString("\nHash: ") + UString(hash.toHex().constData()); info += UString("\nHash: ") + UString(hash.toHex().constData());
} }
// Add correct offset to parsing data
pdata.offset = parentOffset + offset;
// Add tree item // Add tree item
UModelIndex varIndex = model->addItem(Types::NvarEntry, subtype, name, text, info, header, body, tail, false, parsingDataToUByteArray(pdata), index); UModelIndex varIndex = model->addItem(localOffset + offset, Types::NvarEntry, subtype, name, text, info, header, body, tail, Movable, index);
// Set parsing data for created entry
model->setParsingData(varIndex, UByteArray((const char*)&pdata, sizeof(pdata)));
// Show messages // Show messages
if (msgUnknownExtDataFormat) msg(UString("parseNvarStore: unknown extended data format"), varIndex); if (msgUnknownExtDataFormat) msg(UString("parseNvarStore: unknown extended data format"), varIndex);
@ -372,9 +373,16 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get parsing data // Obtain required fields from parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(index); UINT8 emptyByte = 0xFF;
UINT32 parentOffset = pdata.offset + model->header(index).size(); if (model->hasEmptyParsingData(index) == false) {
UByteArray data = model->parsingData(index);
const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData();
emptyByte = pdata->emptyByte;
}
// Get local offset
UINT32 localOffset = model->offset(index) + model->header(index).size();
// Get item data // Get item data
UByteArray data = model->body(index); UByteArray data = model->body(index);
@ -382,7 +390,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
// Search for first store // Search for first store
USTATUS result; USTATUS result;
UINT32 prevStoreOffset; UINT32 prevStoreOffset;
result = findNextStore(index, data, parentOffset, 0, prevStoreOffset); result = findNextStore(index, data, localOffset, 0, prevStoreOffset);
if (result) if (result)
return result; return result;
@ -395,11 +403,8 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
name = UString("Padding"); name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Construct parsing data
pdata.offset = parentOffset;
// Add tree item // Add tree item
model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); model->addItem(localOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
} }
// Search for and parse all stores // Search for and parse all stores
@ -418,11 +423,8 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
name = UString("Padding"); name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Construct parsing data
pdata.offset = parentOffset + paddingOffset;
// Add tree item // Add tree item
model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); model->addItem(localOffset + paddingOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
} }
// Get store size // Get store size
@ -442,11 +444,8 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
name = UString("Padding"); name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size()); info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Construct parsing data
pdata.offset = parentOffset + storeOffset;
// Add tree item // Add tree item
UModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index); UModelIndex paddingIndex = model->addItem(localOffset + storeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
msg(UString("parseNvramVolumeBody: one of stores inside overlaps the end of data"), paddingIndex); msg(UString("parseNvramVolumeBody: one of stores inside overlaps the end of data"), paddingIndex);
// Update variables // Update variables
@ -455,30 +454,30 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
break; break;
} }
UByteArray store = data.mid(storeOffset, storeSize);
// Parse current store header // Parse current store header
UModelIndex storeIndex; UModelIndex storeIndex;
result = parseStoreHeader(store, parentOffset + storeOffset, index, storeIndex); UByteArray store = data.mid(storeOffset, storeSize);
result = parseStoreHeader(store, localOffset + storeOffset, index, storeIndex);
if (result) if (result)
msg(UString("parseNvramVolumeBody: store header parsing failed with error ") + errorCodeToUString(result), index); msg(UString("parseNvramVolumeBody: store header parsing failed with error ") + errorCodeToUString(result), index);
// Go to next store // Go to next store
prevStoreOffset = storeOffset; prevStoreOffset = storeOffset;
prevStoreSize = storeSize; prevStoreSize = storeSize;
result = findNextStore(index, data, parentOffset, storeOffset + prevStoreSize, storeOffset); result = findNextStore(index, data, localOffset, storeOffset + prevStoreSize, storeOffset);
} }
// Padding/free space at the end // Padding/free space at the end
storeOffset = prevStoreOffset + prevStoreSize; storeOffset = prevStoreOffset + prevStoreSize;
if ((UINT32)data.size() > storeOffset) { if ((UINT32)data.size() > storeOffset) {
UByteArray padding = data.mid(storeOffset); UByteArray padding = data.mid(storeOffset);
UINT8 type; // Add info
UINT8 subtype; info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
if (padding.count(pdata.emptyByte) == padding.size()) {
// It's a free space if (padding.count(emptyByte) == padding.size()) { // Free space
name = UString("Free space");
type = Types::FreeSpace; // Add tree item
subtype = 0; model->addItem(localOffset + storeOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Movable, index);
} }
else { else {
// Nothing is parsed yet, but the file is not empty // Nothing is parsed yet, but the file is not empty
@ -487,20 +486,9 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
return U_SUCCESS; return U_SUCCESS;
} }
// It's a padding // Add tree item
name = UString("Padding"); model->addItem(localOffset + storeOffset, Types::Padding, getPaddingType(padding), UString("Padding"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
type = Types::Padding;
subtype = getPaddingType(padding);
} }
// Add info
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Construct parsing data
pdata.offset = parentOffset + storeOffset;
// Add tree item
model->addItem(type, subtype, name, UString(), info, UByteArray(), padding, UByteArray(), true, parsingDataToUByteArray(pdata), index);
} }
// Parse bodies // Parse bodies
@ -518,7 +506,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset) USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 localOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset)
{ {
UINT32 dataSize = volume.size(); UINT32 dataSize = volume.size();
@ -531,11 +519,11 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
if (*currentPos == NVRAM_VSS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_SVS_STORE_SIGNATURE) { //$VSS or $SVS signatures found, perform checks if (*currentPos == NVRAM_VSS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_SVS_STORE_SIGNATURE) { //$VSS or $SVS signatures found, perform checks
const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)currentPos; const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)currentPos;
if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) { if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) {
msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", parentOffset + offset, vssHeader->Format), index); msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", localOffset + offset, vssHeader->Format), index);
continue; continue;
} }
if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) { if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) {
msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid size %Xh", parentOffset + offset, vssHeader->Size), index); msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, vssHeader->Size), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -544,7 +532,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
else if (*currentPos == NVRAM_FDC_VOLUME_SIGNATURE) { //FDC signature found else if (*currentPos == NVRAM_FDC_VOLUME_SIGNATURE) { //FDC signature found
const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)currentPos; const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)currentPos;
if (fdcHeader->Size == 0 || fdcHeader->Size == 0xFFFFFFFF) { if (fdcHeader->Size == 0 || fdcHeader->Size == 0xFFFFFFFF) {
msg(usprintf("findNextStore: FDC store candidate at offset %Xh skipped, has invalid size %Xh", parentOffset + offset, fdcHeader->Size), index); msg(usprintf("findNextStore: FDC store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, fdcHeader->Size), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -553,7 +541,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_GAID_STORE_SIGNATURE) { //Fsys or Gaid signature found else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_GAID_STORE_SIGNATURE) { //Fsys or Gaid signature found
const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos; const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos;
if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) { if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) {
msg(usprintf("findNextStore: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", parentOffset + offset, fsysHeader->Size), index); msg(usprintf("findNextStore: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, fsysHeader->Size), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -565,11 +553,11 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)(currentPos - 1); const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)(currentPos - 1);
if (evsaHeader->Header.Type != NVRAM_EVSA_ENTRY_TYPE_STORE) { if (evsaHeader->Header.Type != NVRAM_EVSA_ENTRY_TYPE_STORE) {
msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid type %02Xh", parentOffset + offset - 4, evsaHeader->Header.Type), index); msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid type %02Xh", localOffset + offset - 4, evsaHeader->Header.Type), index);
continue; continue;
} }
if (evsaHeader->StoreSize == 0 || evsaHeader->StoreSize == 0xFFFFFFFF) { if (evsaHeader->StoreSize == 0 || evsaHeader->StoreSize == 0xFFFFFFFF) {
msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid size %Xh", parentOffset + offset, evsaHeader->StoreSize), index); msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, evsaHeader->StoreSize), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -585,14 +573,14 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftwHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)currentPos; const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftwHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)currentPos;
if (ftwHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize if (ftwHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize
if (ftwHeader->WriteQueueSize == 0 || ftwHeader->WriteQueueSize == 0xFFFFFFFF) { if (ftwHeader->WriteQueueSize == 0 || ftwHeader->WriteQueueSize == 0xFFFFFFFF) {
msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", parentOffset + offset, ftwHeader->WriteQueueSize), index); msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", localOffset + offset, ftwHeader->WriteQueueSize), index);
continue; continue;
} }
} }
else if (ftwHeader->WriteQueueSize % 0x10 == 0x00) { // Header with 64 bit WriteQueueSize else if (ftwHeader->WriteQueueSize % 0x10 == 0x00) { // Header with 64 bit WriteQueueSize
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64Header = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)currentPos; const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64Header = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)currentPos;
if (ftw64Header->WriteQueueSize == 0 || ftw64Header->WriteQueueSize >= 0xFFFFFFFF) { if (ftw64Header->WriteQueueSize == 0 || ftw64Header->WriteQueueSize >= 0xFFFFFFFF) {
msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", parentOffset + offset, ftw64Header->WriteQueueSize), index); msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", localOffset + offset, ftw64Header->WriteQueueSize), index);
continue; continue;
} }
} }
@ -733,7 +721,7 @@ USTATUS NvramParser::getStoreSize(const UByteArray & data, const UINT32 storeOff
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -754,9 +742,6 @@ USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(sizeof(VSS_VARIABLE_STORE_HEADER)); UByteArray header = store.left(sizeof(VSS_VARIABLE_STORE_HEADER));
UByteArray body = store.mid(sizeof(VSS_VARIABLE_STORE_HEADER), vssStoreHeader->Size - sizeof(VSS_VARIABLE_STORE_HEADER)); UByteArray body = store.mid(sizeof(VSS_VARIABLE_STORE_HEADER), vssStoreHeader->Size - sizeof(VSS_VARIABLE_STORE_HEADER));
@ -773,16 +758,13 @@ USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32
vssStoreHeader->State, vssStoreHeader->State,
vssStoreHeader->Unknown); vssStoreHeader->Unknown);
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::VssStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::VssStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -792,6 +774,15 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
return U_SUCCESS; return U_SUCCESS;
} }
// Obtain required information from parent volume
UINT8 emptyByte = 0xFF;
UModelIndex parentVolumeIndex = model->findParentOfType(index, Types::Volume);
if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) {
UByteArray data = model->parsingData(parentVolumeIndex);
const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData();
emptyByte = pdata->ffsVersion;
}
// Get FTW block headers // 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_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(); const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64BlockHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)store.constData();
@ -814,9 +805,6 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UINT32 headerSize = has32bitHeader ? sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) : sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64); UINT32 headerSize = has32bitHeader ? sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) : sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64);
UByteArray header = store.left(headerSize); UByteArray header = store.left(headerSize);
@ -825,8 +813,8 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
// Check block header checksum // Check block header checksum
UByteArray crcHeader = header; UByteArray crcHeader = header;
EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* crcFtwBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)header.data(); EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* crcFtwBlockHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)header.data();
crcFtwBlockHeader->Crc = pdata.emptyByte ? 0xFFFFFFFF : 0; crcFtwBlockHeader->Crc = emptyByte ? 0xFFFFFFFF : 0;
crcFtwBlockHeader->State = pdata.emptyByte ? 0xFF : 0; crcFtwBlockHeader->State = emptyByte ? 0xFF : 0;
UINT32 calculatedCrc = crc32(0, (const UINT8*)crcFtwBlockHeader, headerSize); UINT32 calculatedCrc = crc32(0, (const UINT8*)crcFtwBlockHeader, headerSize);
// Add info // Add info
@ -840,16 +828,13 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
ftw32BlockHeader->Crc) + ftw32BlockHeader->Crc) +
(ftw32BlockHeader->Crc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid")); (ftw32BlockHeader->Crc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid"));
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::FtwStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::FtwStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -897,9 +882,6 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(headerSize); UByteArray header = store.left(headerSize);
UByteArray body = store.mid(headerSize, fdcStoreHeader->Size - headerSize); UByteArray body = store.mid(headerSize, fdcStoreHeader->Size - headerSize);
@ -913,16 +895,13 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32
// TODO: add internal headers info // TODO: add internal headers info
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::FdcStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::FdcStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -943,9 +922,6 @@ USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(sizeof(APPLE_FSYS_STORE_HEADER)); UByteArray header = store.left(sizeof(APPLE_FSYS_STORE_HEADER));
UByteArray body = store.mid(sizeof(APPLE_FSYS_STORE_HEADER), fsysStoreHeader->Size - sizeof(APPLE_FSYS_STORE_HEADER) - sizeof(UINT32)); UByteArray body = store.mid(sizeof(APPLE_FSYS_STORE_HEADER), fsysStoreHeader->Size - sizeof(APPLE_FSYS_STORE_HEADER) - sizeof(UINT32));
@ -966,16 +942,13 @@ USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32
fsysStoreHeader->Unknown1) fsysStoreHeader->Unknown1)
+ (storedCrc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid")); + (storedCrc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid"));
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::FsysStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::FsysStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -996,9 +969,6 @@ USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(evsaStoreHeader->Header.Size); UByteArray header = store.left(evsaStoreHeader->Header.Size);
UByteArray body = store.mid(evsaStoreHeader->Header.Size, evsaStoreHeader->StoreSize - evsaStoreHeader->Header.Size); UByteArray body = store.mid(evsaStoreHeader->Header.Size, evsaStoreHeader->StoreSize - evsaStoreHeader->Header.Size);
@ -1017,16 +987,13 @@ USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32
evsaStoreHeader->Header.Checksum) + evsaStoreHeader->Header.Checksum) +
(evsaStoreHeader->Header.Checksum != calculated ? usprintf("%, invalid, should be %02Xh", calculated) : UString(", valid")); (evsaStoreHeader->Header.Checksum != calculated ? usprintf("%, invalid, should be %02Xh", calculated) : UString(", valid"));
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::EvsaStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::EvsaStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -1048,9 +1015,6 @@ USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UI
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(sizeof(PHOENIX_FLASH_MAP_HEADER)); UByteArray header = store.left(sizeof(PHOENIX_FLASH_MAP_HEADER));
UByteArray body = store.mid(sizeof(PHOENIX_FLASH_MAP_HEADER), flashMapSize - sizeof(PHOENIX_FLASH_MAP_HEADER)); UByteArray body = store.mid(sizeof(PHOENIX_FLASH_MAP_HEADER), flashMapSize - sizeof(PHOENIX_FLASH_MAP_HEADER));
@ -1063,16 +1027,13 @@ USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UI
body.size(), body.size(), body.size(), body.size(),
flashMapHeader->NumEntries); flashMapHeader->NumEntries);
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::FlashMapStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::FlashMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -1093,9 +1054,6 @@ USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32
// Get store header // Get store header
const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)store.constData(); const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)store.constData();
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(cmdbHeader->TotalSize); UByteArray header = store.left(cmdbHeader->TotalSize);
UByteArray body = store.mid(cmdbHeader->TotalSize, cmdbSize - cmdbHeader->TotalSize); UByteArray body = store.mid(cmdbHeader->TotalSize, cmdbSize - cmdbHeader->TotalSize);
@ -1107,16 +1065,13 @@ USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32
header.size(), header.size(), header.size(), header.size(),
body.size(), body.size()); body.size(), body.size());
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::CmdbStore, 0, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::CmdbStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -1137,9 +1092,6 @@ USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT3
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(sizeof(OEM_ACTIVATION_PUBKEY)); UByteArray header = store.left(sizeof(OEM_ACTIVATION_PUBKEY));
@ -1155,16 +1107,13 @@ USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT3
pubkeyHeader->BitLength, pubkeyHeader->BitLength,
pubkeyHeader->Exponent); pubkeyHeader->Exponent);
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::SlicData, Subtypes::PubkeySlicData, name, UString(), info, header, UByteArray(), UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::SlicData, Subtypes::PubkeySlicData, name, UString(), info, header, UByteArray(), UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -1185,9 +1134,6 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(sizeof(OEM_ACTIVATION_MARKER)); UByteArray header = store.left(sizeof(OEM_ACTIVATION_MARKER));
@ -1202,16 +1148,14 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
(const char*)UString((const char*)&(markerHeader->OemTableId)).left(8).toLocal8Bit(), (const char*)UString((const char*)&(markerHeader->OemTableId)).left(8).toLocal8Bit(),
markerHeader->SlicVersion); markerHeader->SlicVersion);
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::SlicData, Subtypes::MarkerSlicData, name, UString(), info, header, UByteArray(), UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::SlicData, Subtypes::MarkerSlicData, name, UString(), info, header, UByteArray(), UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
@ -1232,14 +1176,11 @@ USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const U
return U_SUCCESS; return U_SUCCESS;
} }
// Get parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(parent);
// Construct header and body // Construct header and body
UByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER)); UByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER));
UByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize); UByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
//TODO: recalculate checksum //TODO: recalculate microcode checksum
// Add info // Add info
UString name("Intel microcode"); UString name("Intel microcode");
@ -1254,16 +1195,13 @@ USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const U
ucodeHeader->LoaderRevision, ucodeHeader->LoaderRevision,
ucodeHeader->CpuFlags); ucodeHeader->CpuFlags);
// Add correct offset
pdata.offset = parentOffset;
// Add tree item // Add tree item
index = model->addItem(Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), true, parsingDataToUByteArray(pdata), parent); index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), Fixed, parent);
return U_SUCCESS; return U_SUCCESS;
} }
USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index) USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{ {
const UINT32 dataSize = (const UINT32)store.size(); const UINT32 dataSize = (const UINT32)store.size();
const UINT32* signature = (const UINT32*)store.constData(); const UINT32* signature = (const UINT32*)store.constData();
@ -1276,35 +1214,35 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 par
// Check signature and run parser function needed // Check signature and run parser function needed
// VSS/SVS store // VSS/SVS store
if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE) if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE)
return parseVssStoreHeader(store, parentOffset, parent, index); return parseVssStoreHeader(store, localOffset, parent, index);
// FTW store // FTW store
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1)
return parseFtwStoreHeader(store, parentOffset, parent, index); return parseFtwStoreHeader(store, localOffset, parent, index);
// FDC store // FDC store
else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE) else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE)
return parseFdcStoreHeader(store, parentOffset, parent, index); return parseFdcStoreHeader(store, localOffset, parent, index);
// Apple Fsys/Gaid store // Apple Fsys/Gaid store
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE)
return parseFsysStoreHeader(store, parentOffset, parent, index); return parseFsysStoreHeader(store, localOffset, parent, index);
// EVSA store // EVSA store
else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE)
return parseEvsaStoreHeader(store, parentOffset, parent, index); return parseEvsaStoreHeader(store, localOffset, parent, index);
// Phoenix SCT flash map // Phoenix SCT flash map
else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1)
return parseFlashMapStoreHeader(store, parentOffset, parent, index); return parseFlashMapStoreHeader(store, localOffset, parent, index);
// Phoenix CMDB store // Phoenix CMDB store
else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE)
return parseCmdbStoreHeader(store, parentOffset, parent, index); return parseCmdbStoreHeader(store, localOffset, parent, index);
// SLIC pubkey // SLIC pubkey
else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC)
return parseSlicPubkeyHeader(store, parentOffset, parent, index); return parseSlicPubkeyHeader(store, localOffset, parent, index);
// SLIC marker // SLIC marker
else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG)
return parseSlicMarkerHeader(store, parentOffset, parent, index); return parseSlicMarkerHeader(store, localOffset, parent, index);
// Intel microcode // Intel microcode
// Must be checked after SLIC marker because of the same *signature values // Must be checked after SLIC marker because of the same *signature values
else if (*signature == INTEL_MICROCODE_HEADER_VERSION) else if (*signature == INTEL_MICROCODE_HEADER_VERSION)
return parseIntelMicrocodeHeader(store, parentOffset, parent, index); return parseIntelMicrocodeHeader(store, localOffset, parent, index);
msg(usprintf("parseStoreHeader: don't know how to parse a header with signature %08Xh", *signature), parent); msg(usprintf("parseStoreHeader: don't know how to parse a header with signature %08Xh", *signature), parent);
return U_SUCCESS; return U_SUCCESS;
@ -1316,9 +1254,19 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index)
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get parsing data for the current item // Obtain required information from parent volume
PARSING_DATA pdata = parsingDataFromUModelIndex(index); UINT8 emptyByte = 0xFF;
UINT32 parentOffset = pdata.offset + model->header(index).size(); UModelIndex parentVolumeIndex = model->findParentOfType(index, Types::Volume);
if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) {
UByteArray data = model->parsingData(parentVolumeIndex);
const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData();
emptyByte = pdata->ffsVersion;
}
// Get local offset
UINT32 localOffset = model->offset(index) + model->header(index).size();
// Get item data
const UByteArray data = model->body(index); const UByteArray data = model->body(index);
// Check that the is enough space for variable header // Check that the is enough space for variable header
@ -1432,36 +1380,24 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index)
if (!variableSize) { if (!variableSize) {
// Check if the data left is a free space or a padding // Check if the data left is a free space or a padding
UByteArray padding = data.mid(offset, unparsedSize); UByteArray padding = data.mid(offset, unparsedSize);
UINT8 type; // Get info
UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
if (padding.count(pdata.emptyByte) == padding.size()) { if (padding.count(emptyByte) == padding.size()) { // Free space
// It's a free space // Add tree item
name = UString("Free space"); model->addItem(localOffset + offset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Movable, index);
type = Types::FreeSpace;
subtype = 0;
} }
else { else { // Padding
// Nothing is parsed yet, but the store is not empty // Nothing is parsed yet, but the store is not empty
if (!offset) { if (!offset) {
msg(UString("parseVssStoreBody: store can't be parsed as VSS store"), index); msg(UString("parseVssStoreBody: store can't be parsed as VSS store"), index);
return U_SUCCESS; return U_SUCCESS;
} }
// It's a padding // Add tree item
name = UString("Padding"); model->addItem(localOffset + offset, Types::Padding, getPaddingType(padding), UString("Padding"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
type = Types::Padding;
subtype = getPaddingType(padding);
} }
// Get info
UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Construct parsing data
pdata.offset = parentOffset + offset;
// Add tree item
model->addItem(type, subtype, name, UString(), info, UByteArray(), padding, UByteArray(), false, parsingDataToUByteArray(pdata), index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1501,11 +1437,8 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index)
else else
subtype = Subtypes::StandardVssEntry; subtype = Subtypes::StandardVssEntry;
// Add correct offset to parsing data
pdata.offset = parentOffset + offset;
// Add tree item // Add tree item
model->addItem(Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index); model->addItem(localOffset + offset, Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), Movable, index);
// Move to next variable // Move to next variable
offset += variableSize; offset += variableSize;
@ -1520,9 +1453,10 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get parsing data for the current item // Get local offset
PARSING_DATA pdata = parsingDataFromUModelIndex(index); UINT32 localOffset = model->offset(index) + model->header(index).size();
UINT32 parentOffset = pdata.offset + model->header(index).size();
// Get item data
const UByteArray data = model->body(index); const UByteArray data = model->body(index);
// Check that the is enough space for variable header // Check that the is enough space for variable header
@ -1549,12 +1483,9 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
// There is no data afterward, add EOF variable and free space and return // There is no data afterward, add EOF variable and free space and return
UByteArray header = data.mid(offset, sizeof(UINT8) + nameSize); UByteArray header = data.mid(offset, sizeof(UINT8) + nameSize);
UString info = usprintf("Full size: %Xh (%u)", header.size(), header.size()); UString info = usprintf("Full size: %Xh (%u)", header.size(), header.size());
// Add correct offset to parsing data
pdata.offset = parentOffset + offset;
// Add EOF tree item // Add EOF tree item
model->addItem(Types::FsysEntry, 0, UString("EOF"), UString(), info, header, UByteArray(), UByteArray(), false, parsingDataToUByteArray(pdata), index); model->addItem(localOffset + offset, Types::FsysEntry, 0, UString("EOF"), UString(), info, header, UByteArray(), UByteArray(), Fixed, index);
// Add free space // Add free space
offset += header.size(); offset += header.size();
@ -1562,11 +1493,8 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
UByteArray body = data.mid(offset); UByteArray body = data.mid(offset);
info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
// Add correct offset to parsing data
pdata.offset = parentOffset + offset;
// Add free space tree item // Add free space tree item
model->addItem(Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index); model->addItem(localOffset + offset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), body, UByteArray(), Movable, index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1582,11 +1510,8 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
UByteArray body = data.mid(offset); UByteArray body = data.mid(offset);
UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
// Add correct offset to parsing data // Add padding tree item
pdata.offset = parentOffset + offset; model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
// Add free space tree item
model->addItem(Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index);
// Show message // Show message
msg(UString("parseFsysStoreBody: next variable appears too big, added as padding"), index); msg(UString("parseFsysStoreBody: next variable appears too big, added as padding"), index);
@ -1604,11 +1529,8 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
header.size(), header.size(), header.size(), header.size(),
body.size(), body.size()); body.size(), body.size());
// Add correct offset to parsing data
pdata.offset = parentOffset + offset;
// Add tree item // Add tree item
model->addItem(Types::FsysEntry, 0, UString(name.constData()), UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index); model->addItem(localOffset + offset, Types::FsysEntry, 0, UString(name.constData()), UString(), info, header, body, UByteArray(), Movable, index);
// Move to next variable // Move to next variable
offset += variableSize; offset += variableSize;
@ -1623,9 +1545,19 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get parsing data for the current item // Obtain required information from parent volume
PARSING_DATA pdata = parsingDataFromUModelIndex(index); UINT8 emptyByte = 0xFF;
UINT32 parentOffset = pdata.offset + model->header(index).size(); UModelIndex parentVolumeIndex = model->findParentOfType(index, Types::Volume);
if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) {
UByteArray data = model->parsingData(parentVolumeIndex);
const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData();
emptyByte = pdata->ffsVersion;
}
// Get local offset
UINT32 localOffset = model->offset(index) + model->header(index).size();
// Get item data
const UByteArray data = model->body(index); const UByteArray data = model->body(index);
// Check that the is enough space for entry header // Check that the is enough space for entry header
@ -1654,26 +1586,18 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
UByteArray body = data.mid(offset); UByteArray body = data.mid(offset);
UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
// Checke type if (body.count(emptyByte) == body.size()) { // Free space
UString name("Free space"); // Add free space tree item
UINT8 type = Types::FreeSpace; UModelIndex itemIndex = model->addItem(localOffset + offset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), body, UByteArray(), Movable, index);
UINT8 subtype = 0;
if (getPaddingType(body) == Subtypes::DataPadding) {
name = UString("Padding");
type = Types::Padding;
subtype = Subtypes::DataPadding;
} }
else {
// Add padding tree item
UModelIndex itemIndex = model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
// Add correct offset to parsing data // Show message
pdata.offset = parentOffset + offset;
// Add free space tree item
UModelIndex itemIndex = model->addItem(type, subtype, name, UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index);
// Show message
if (type == Types::Padding)
msg(UString("parseEvsaStoreBody: variable parsing failed, the rest of unparsed store added as padding"), itemIndex); msg(UString("parseEvsaStoreBody: variable parsing failed, the rest of unparsed store added as padding"), itemIndex);
}
break; break;
} }
variableSize = entryHeader->Size; variableSize = entryHeader->Size;
@ -1755,33 +1679,22 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
UByteArray body = data.mid(offset); UByteArray body = data.mid(offset);
UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
// Check type if (body.count(emptyByte) == body.size()) { // Free space
UString name("Free space"); // Add free space tree item
UINT8 type = Types::FreeSpace; UModelIndex itemIndex = model->addItem(localOffset + offset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), body, UByteArray(), Movable, index);
UINT8 subtype = 0;
if (getPaddingType(body) == Subtypes::DataPadding) {
name = UString("Padding");
type = Types::Padding;
subtype = Subtypes::DataPadding;
} }
else {
// Add padding tree item
UModelIndex itemIndex = model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
// Add correct offset to parsing data // Show message
pdata.offset = parentOffset + offset; msg(usprintf("parseEvsaStoreBody: unknown variable of type %02Xh found at offset %Xh, the rest of unparsed store added as padding", entryHeader->Type, offset), itemIndex);
}
// Add free space tree item
UModelIndex itemIndex = model->addItem(type, subtype, name, UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index);
// Show message
if (type == Types::Padding)
msg(usprintf("parseEvsaStoreBody: unknown variable of type %02Xh found at offset %Xh, the rest of unparsed store added as padding",entryHeader->Type, offset), itemIndex);
break; break;
} }
// Add correct offset to parsing data
pdata.offset = parentOffset + offset;
// Add tree item // Add tree item
model->addItem(Types::EvsaEntry, subtype, name, UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index); model->addItem(localOffset + offset, Types::EvsaEntry, subtype, name, UString(), info, header, body, UByteArray(), Movable, index);
// Move to next variable // Move to next variable
offset += variableSize; offset += variableSize;
@ -1842,8 +1755,7 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index)
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get parsing data for the current item // Get parsing data for the current item
PARSING_DATA pdata = parsingDataFromUModelIndex(index); UINT32 localOffset = model->offset(index) + model->header(index).size();
UINT32 parentOffset = pdata.offset + model->header(index).size();
const UByteArray data = model->body(index); const UByteArray data = model->body(index);
@ -1860,11 +1772,8 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index)
UByteArray body = data.mid(offset); UByteArray body = data.mid(offset);
UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
// Add correct offset to parsing data // Add padding tree item
pdata.offset = parentOffset + offset; model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
// Add free space tree item
model->addItem(Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), false, parsingDataToUByteArray(pdata), index);
// Show message // Show message
if (unparsedSize < entryHeader->Size) if (unparsedSize < entryHeader->Size)
@ -1887,9 +1796,6 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index)
entryHeader->Size, entryHeader->Size,
entryHeader->Offset); entryHeader->Offset);
// Add correct offset to parsing data
pdata.offset = parentOffset + offset;
// Determine subtype // Determine subtype
UINT8 subtype = 0; UINT8 subtype = 0;
switch (entryHeader->DataType) { switch (entryHeader->DataType) {
@ -1902,7 +1808,7 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index)
} }
// Add tree item // Add tree item
model->addItem(Types::FlashMapEntry, subtype, name, flashMapGuidToUString(entryHeader->Guid), info, header, UByteArray(), UByteArray(), true, parsingDataToUByteArray(pdata), index); model->addItem(localOffset + offset, Types::FlashMapEntry, subtype, name, flashMapGuidToUString(entryHeader->Guid), info, header, UByteArray(), UByteArray(), Movable, index);
// Move to next variable // Move to next variable
offset += sizeof(PHOENIX_FLASH_MAP_ENTRY); offset += sizeof(PHOENIX_FLASH_MAP_ENTRY);

View File

@ -46,20 +46,20 @@ private:
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index)); messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
}; };
USTATUS findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset); USTATUS findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 localOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset);
USTATUS getStoreSize(const UByteArray & data, const UINT32 storeOffset, UINT32 & storeSize); USTATUS getStoreSize(const UByteArray & data, const UINT32 storeOffset, UINT32 & storeSize);
USTATUS parseStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseVssStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseVssStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseFtwStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseFtwStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseFdcStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseFdcStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseFsysStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseFsysStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseEvsaStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseEvsaStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseFlashMapStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseFlashMapStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseCmdbStoreHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseSlicPubkeyHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseSlicMarkerHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseVssStoreBody(const UModelIndex & index); USTATUS parseVssStoreBody(const UModelIndex & index);
USTATUS parseFsysStoreBody(const UModelIndex & index); USTATUS parseFsysStoreBody(const UModelIndex & index);
@ -71,20 +71,17 @@ class NvramParser
{ {
public: public:
// Default constructor and destructor // Default constructor and destructor
NvramParser(TreeModel* treeModel) : model(treeModel) {} NvramParser(TreeModel* treeModel) { U_UNUSED_PARAMETER(treeModel); }
~NvramParser() {} ~NvramParser() {}
// Returns messages // Returns messages
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; } std::vector<std::pair<UString, UModelIndex> > getMessages() const { return std::vector<std::pair<UString, UModelIndex> >(); }
// Clears messages // Clears messages
void clearMessages() { messagesVector.clear(); } void clearMessages() {}
// NVRAM parsing // NVRAM parsing
USTATUS parseNvramVolumeBody(const UModelIndex &) { return U_SUCCESS; } USTATUS parseNvramVolumeBody(const UModelIndex &) { return U_SUCCESS; }
USTATUS parseNvarStore(const UModelIndex &) { return U_SUCCESS; } USTATUS parseNvarStore(const UModelIndex &) { return U_SUCCESS; }
private:
TreeModel *model;
std::vector<std::pair<UString, UModelIndex> > messagesVector;
}; };
#endif // U_ENABLE_NVRAM_PARSING_SUPPORT #endif // U_ENABLE_NVRAM_PARSING_SUPPORT
#endif // NVRAMPARSER_H #endif // NVRAMPARSER_H

View File

@ -20,6 +20,8 @@ routines without the need of backward traversal
#include "basetypes.h" #include "basetypes.h"
typedef struct VOLUME_PARSING_DATA_ { typedef struct VOLUME_PARSING_DATA_ {
UINT8 ffsVersion;
UINT8 emptyByte;
EFI_GUID extendedHeaderGuid; EFI_GUID extendedHeaderGuid;
UINT32 alignment; UINT32 alignment;
UINT8 revision; UINT8 revision;
@ -30,54 +32,30 @@ typedef struct VOLUME_PARSING_DATA_ {
} VOLUME_PARSING_DATA; } VOLUME_PARSING_DATA;
typedef struct FILE_PARSING_DATA_ { typedef struct FILE_PARSING_DATA_ {
UINT8 emptyByte;
EFI_GUID guid; EFI_GUID guid;
} FILE_PARSING_DATA; } FILE_PARSING_DATA;
typedef struct GUID_PARSING_DATA_ {
EFI_GUID guid;
} GUIDED_SECTION_PARSING_DATA, FREEFORM_GUIDED_SECTION_PARSING_DATA;
typedef struct COMPRESSED_SECTION_PARSING_DATA_ { typedef struct COMPRESSED_SECTION_PARSING_DATA_ {
UINT32 uncompressedSize; UINT32 uncompressedSize;
UINT8 compressionType; UINT8 compressionType;
UINT8 algorithm; UINT8 algorithm;
} COMPRESSED_SECTION_PARSING_DATA; } COMPRESSED_SECTION_PARSING_DATA;
typedef struct GUIDED_SECTION_PARSING_DATA_ {
EFI_GUID guid;
} GUIDED_SECTION_PARSING_DATA;
typedef struct FREEFORM_GUIDED_SECTION_PARSING_DATA_ {
EFI_GUID guid;
} FREEFORM_GUIDED_SECTION_PARSING_DATA;
typedef struct TE_IMAGE_SECTION_PARSING_DATA_ { typedef struct TE_IMAGE_SECTION_PARSING_DATA_ {
UINT32 imageBase; UINT32 imageBase;
UINT32 adjustedImageBase; UINT32 adjustedImageBase;
UINT8 imageBaseType; UINT8 imageBaseType;
} TE_IMAGE_SECTION_PARSING_DATA; } TE_IMAGE_SECTION_PARSING_DATA;
typedef struct SECTION_PARSING_DATA_ {
union {
COMPRESSED_SECTION_PARSING_DATA compressed;
GUIDED_SECTION_PARSING_DATA guidDefined;
FREEFORM_GUIDED_SECTION_PARSING_DATA freeformSubtypeGuid;
TE_IMAGE_SECTION_PARSING_DATA teImage;
};
} SECTION_PARSING_DATA;
typedef struct NVAR_ENTRY_PARSING_DATA_ { typedef struct NVAR_ENTRY_PARSING_DATA_ {
UINT32 next; UINT8 emptyByte;
BOOLEAN isValid; BOOLEAN isValid;
UINT32 next;
} NVAR_ENTRY_PARSING_DATA; } NVAR_ENTRY_PARSING_DATA;
typedef struct PARSING_DATA_ { #endif // PARSINGDATA_H
UINT8 emptyByte;
UINT8 ffsVersion;
UINT32 offset;
UINT32 address;
union {
VOLUME_PARSING_DATA volume;
FILE_PARSING_DATA file;
SECTION_PARSING_DATA section;
NVAR_ENTRY_PARSING_DATA nvar;
};
} PARSING_DATA;
#endif // NVRAM_H

View File

@ -14,12 +14,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treeitem.h" #include "treeitem.h"
#include "types.h" #include "types.h"
TreeItem::TreeItem(const UINT8 type, const UINT8 subtype, TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
const UString & name, const UString & text, const UString & info, const UString & name, const UString & text, const UString & info,
const UByteArray & header, const UByteArray & body, const UByteArray & tail, const UByteArray & header, const UByteArray & body, const UByteArray & tail,
const bool fixed, const bool compressed, const UByteArray & parsingData, const bool fixed, const bool compressed,
TreeItem *parent) : TreeItem *parent) :
itemAction(Actions::NoAction), itemAction(Actions::NoAction),
itemOffset(offset),
itemType(type), itemType(type),
itemSubtype(subtype), itemSubtype(subtype),
itemName(name), itemName(name),
@ -28,7 +29,6 @@ TreeItem::TreeItem(const UINT8 type, const UINT8 subtype,
itemHeader(header), itemHeader(header),
itemBody(body), itemBody(body),
itemTail(tail), itemTail(tail),
itemParsingData(parsingData),
itemFixed(fixed), itemFixed(fixed),
itemCompressed(compressed), itemCompressed(compressed),
parentItem(parent) parentItem(parent)

View File

@ -24,9 +24,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
class TreeItem class TreeItem
{ {
public: public:
TreeItem(const UINT8 type, const UINT8 subtype, const UString &name, const UString &text, const UString &info, TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype, const UString &name, const UString &text, const UString &info,
const UByteArray & header, const UByteArray & body, const UByteArray & tail, const UByteArray & header, const UByteArray & body, const UByteArray & tail,
const bool fixed, const bool compressed, const UByteArray & parsingData, const bool fixed, const bool compressed,
TreeItem *parent = 0); TreeItem *parent = 0);
~TreeItem(); // Non-trivial implementation in CPP file ~TreeItem(); // Non-trivial implementation in CPP file
@ -45,8 +45,8 @@ public:
TreeItem *parent() { return parentItem; } TreeItem *parent() { return parentItem; }
// Getters and setters for item parameters // Getters and setters for item parameters
UString name() const { return itemName; } UINT32 offset() const { return itemOffset; }
void setName(const UString &text) { itemName = text; } void setOffset(const UINT32 offset) { itemOffset = offset; }
UINT8 type() const { return itemType; } UINT8 type() const { return itemType; }
void setType(const UINT8 type) { itemType = type; } void setType(const UINT8 type) { itemType = type; }
@ -54,6 +54,9 @@ public:
UINT8 subtype() const { return itemSubtype; } UINT8 subtype() const { return itemSubtype; }
void setSubtype(const UINT8 subtype) { itemSubtype = subtype; } void setSubtype(const UINT8 subtype) { itemSubtype = subtype; }
UString name() const { return itemName; }
void setName(const UString &text) { itemName = text; }
UString text() const { return itemText; } UString text() const { return itemText; }
void setText(const UString &text) { itemText = text; } void setText(const UString &text) { itemText = text; }
@ -66,10 +69,6 @@ public:
UByteArray tail() const { return itemTail; }; UByteArray tail() const { return itemTail; };
bool hasEmptyTail() const { return itemTail.isEmpty(); } bool hasEmptyTail() const { return itemTail.isEmpty(); }
UByteArray parsingData() const { return itemParsingData; }
bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); }
void setParsingData(const UByteArray & data) { itemParsingData = data; }
UString info() const { return itemInfo; } UString info() const { return itemInfo; }
void addInfo(const UString &info, const bool append) { if (append) itemInfo += info; else itemInfo = info + itemInfo; } void addInfo(const UString &info, const bool append) { if (append) itemInfo += info; else itemInfo = info + itemInfo; }
void setInfo(const UString &info) { itemInfo = info; } void setInfo(const UString &info) { itemInfo = info; }
@ -83,8 +82,13 @@ public:
bool compressed() const { return itemCompressed; } bool compressed() const { return itemCompressed; }
void setCompressed(const bool compressed) { itemCompressed = compressed; } void setCompressed(const bool compressed) { itemCompressed = compressed; }
UByteArray parsingData() const { return itemParsingData; };
bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); }
void setParsingData(const UByteArray & pdata) { itemParsingData = pdata; }
private: private:
std::list<TreeItem*> childItems; std::list<TreeItem*> childItems;
UINT32 itemOffset;
UINT8 itemAction; UINT8 itemAction;
UINT8 itemType; UINT8 itemType;
UINT8 itemSubtype; UINT8 itemSubtype;
@ -94,9 +98,9 @@ private:
UByteArray itemHeader; UByteArray itemHeader;
UByteArray itemBody; UByteArray itemBody;
UByteArray itemTail; UByteArray itemTail;
UByteArray itemParsingData;
bool itemFixed; bool itemFixed;
bool itemCompressed; bool itemCompressed;
UByteArray itemParsingData;
TreeItem* parentItem; TreeItem* parentItem;
}; };

View File

@ -157,6 +157,14 @@ int TreeModel::rowCount(const UModelIndex &parent) const
return parentItem->childCount(); return parentItem->childCount();
} }
UINT32 TreeModel::offset(const UModelIndex &index) const
{
if (!index.isValid())
return 0;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->offset();
}
UINT8 TreeModel::type(const UModelIndex &index) const UINT8 TreeModel::type(const UModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
@ -221,22 +229,6 @@ bool TreeModel::hasEmptyTail(const UModelIndex &index) const
return item->hasEmptyTail(); return item->hasEmptyTail();
} }
UByteArray TreeModel::parsingData(const UModelIndex &index) const
{
if (!index.isValid())
return UByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->parsingData();
}
bool TreeModel::hasEmptyParsingData(const UModelIndex &index) const
{
if (!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyParsingData();
}
UString TreeModel::name(const UModelIndex &index) const UString TreeModel::name(const UModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
@ -320,6 +312,25 @@ void TreeModel::setCompressed(const UModelIndex &index, const bool compressed)
emit dataChanged(index, index); emit dataChanged(index, index);
} }
void TreeModel::setOffset(const UModelIndex &index, const UINT32 offset)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setOffset(offset);
emit dataChanged(index, index);
}
void TreeModel::setType(const UModelIndex &index, const UINT8 data)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setType(data);
emit dataChanged(index, index);
}
void TreeModel::setSubtype(const UModelIndex & index, const UINT8 subtype) void TreeModel::setSubtype(const UModelIndex & index, const UINT8 subtype)
{ {
@ -341,16 +352,6 @@ void TreeModel::setName(const UModelIndex &index, const UString &data)
emit dataChanged(index, index); emit dataChanged(index, index);
} }
void TreeModel::setType(const UModelIndex &index, const UINT8 data)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setType(data);
emit dataChanged(index, index);
}
void TreeModel::setText(const UModelIndex &index, const UString &data) void TreeModel::setText(const UModelIndex &index, const UString &data)
{ {
if (!index.isValid()) if (!index.isValid())
@ -391,6 +392,24 @@ void TreeModel::setAction(const UModelIndex &index, const UINT8 action)
emit dataChanged(index, index); emit dataChanged(index, index);
} }
UByteArray TreeModel::parsingData(const UModelIndex &index) const
{
if (!index.isValid())
return UByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->parsingData();
}
bool TreeModel::hasEmptyParsingData(const UModelIndex &index) const
{
if (!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyParsingData();
}
void TreeModel::setParsingData(const UModelIndex &index, const UByteArray &data) void TreeModel::setParsingData(const UModelIndex &index, const UByteArray &data)
{ {
if (!index.isValid()) if (!index.isValid())
@ -401,10 +420,10 @@ void TreeModel::setParsingData(const UModelIndex &index, const UByteArray &data)
emit dataChanged(this->index(0, 0), index); emit dataChanged(this->index(0, 0), index);
} }
UModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, UModelIndex TreeModel::addItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
const UString & name, const UString & text, const UString & info, const UString & name, const UString & text, const UString & info,
const UByteArray & header, const UByteArray & body, const UByteArray & tail, const UByteArray & header, const UByteArray & body, const UByteArray & tail,
const bool fixed, const UByteArray & parsingData, const ItemFixedState fixed,
const UModelIndex & parent, const UINT8 mode) const UModelIndex & parent, const UINT8 mode)
{ {
TreeItem *item = 0; TreeItem *item = 0;
@ -426,7 +445,7 @@ UModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype,
} }
} }
TreeItem *newItem = new TreeItem(type, subtype, name, text, info, header, body, tail, fixed, this->compressed(parent), parsingData, parentItem); TreeItem *newItem = new TreeItem(offset, type, subtype, name, text, info, header, body, tail, Movable, this->compressed(parent), parentItem);
if (mode == CREATE_MODE_APPEND) { if (mode == CREATE_MODE_APPEND) {
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();

View File

@ -14,6 +14,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef TREEMODEL_H #ifndef TREEMODEL_H
#define TREEMODEL_H #define TREEMODEL_H
enum ItemFixedState {
Movable,
Fixed
};
#if defined(QT_CORE_LIB) #if defined(QT_CORE_LIB)
// Use Qt classes // Use Qt classes
#include <QAbstractItemModel> #include <QAbstractItemModel>
@ -88,7 +93,7 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const; int role = Qt::DisplayRole) const;
TreeModel(QObject *parent = 0) : QAbstractItemModel(parent) { TreeModel(QObject *parent = 0) : QAbstractItemModel(parent) {
rootItem = new TreeItem(Types::Root, 0, UString(), UString(), UString(), UByteArray(), UByteArray(), UByteArray(), TRUE, FALSE, UByteArray()); rootItem = new TreeItem(0, Types::Root, 0, UString(), UString(), UString(), UByteArray(), UByteArray(), UByteArray(), TRUE, FALSE);
} }
#else #else
@ -107,7 +112,7 @@ public:
UString headerData(int section, int orientation, int role = 0) const; UString headerData(int section, int orientation, int role = 0) const;
TreeModel() { TreeModel() {
rootItem = new TreeItem(Types::Root, 0, UString(), UString(), UString(), UByteArray(), UByteArray(), UByteArray(), TRUE, FALSE, UByteArray()); rootItem = new TreeItem(0, Types::Root, 0, UString(), UString(), UString(), UByteArray(), UByteArray(), UByteArray(), TRUE, FALSE);
} }
bool hasIndex(int row, int column, const UModelIndex &parent = UModelIndex()) const { bool hasIndex(int row, int column, const UModelIndex &parent = UModelIndex()) const {
@ -131,37 +136,41 @@ public:
int columnCount(const UModelIndex &parent = UModelIndex()) const; int columnCount(const UModelIndex &parent = UModelIndex()) const;
void setAction(const UModelIndex &index, const UINT8 action); void setAction(const UModelIndex &index, const UINT8 action);
void setOffset(const UModelIndex &index, const UINT32 offset);
void setType(const UModelIndex &index, const UINT8 type); void setType(const UModelIndex &index, const UINT8 type);
void setSubtype(const UModelIndex &index, const UINT8 subtype); void setSubtype(const UModelIndex &index, const UINT8 subtype);
void setName(const UModelIndex &index, const UString &name); void setName(const UModelIndex &index, const UString &name);
void setText(const UModelIndex &index, const UString &text); void setText(const UModelIndex &index, const UString &text);
void setInfo(const UModelIndex &index, const UString &info); void setInfo(const UModelIndex &index, const UString &info);
void addInfo(const UModelIndex &index, const UString &info, const bool append = TRUE); void addInfo(const UModelIndex &index, const UString &info, const bool append = TRUE);
void setParsingData(const UModelIndex &index, const UByteArray &data);
void setFixed(const UModelIndex &index, const bool fixed); void setFixed(const UModelIndex &index, const bool fixed);
void setCompressed(const UModelIndex &index, const bool compressed); void setCompressed(const UModelIndex &index, const bool compressed);
UINT32 offset(const UModelIndex &index) const;
UINT8 type(const UModelIndex &index) const;
UINT8 subtype(const UModelIndex &index) const;
UString name(const UModelIndex &index) const; UString name(const UModelIndex &index) const;
UString text(const UModelIndex &index) const; UString text(const UModelIndex &index) const;
UString info(const UModelIndex &index) const; UString info(const UModelIndex &index) const;
UINT8 type(const UModelIndex &index) const;
UINT8 subtype(const UModelIndex &index) const;
UByteArray header(const UModelIndex &index) const; UByteArray header(const UModelIndex &index) const;
bool hasEmptyHeader(const UModelIndex &index) const; bool hasEmptyHeader(const UModelIndex &index) const;
UByteArray body(const UModelIndex &index) const; UByteArray body(const UModelIndex &index) const;
bool hasEmptyBody(const UModelIndex &index) const; bool hasEmptyBody(const UModelIndex &index) const;
UByteArray tail(const UModelIndex &index) const; UByteArray tail(const UModelIndex &index) const;
bool hasEmptyTail(const UModelIndex &index) const; bool hasEmptyTail(const UModelIndex &index) const;
UByteArray parsingData(const UModelIndex &index) const;
bool hasEmptyParsingData(const UModelIndex &index) const;
UINT8 action(const UModelIndex &index) const;
bool fixed(const UModelIndex &index) const; bool fixed(const UModelIndex &index) const;
bool compressed(const UModelIndex &index) const; bool compressed(const UModelIndex &index) const;
UModelIndex addItem(const UINT8 type, const UINT8 subtype, UINT8 action(const UModelIndex &index) const;
UByteArray parsingData(const UModelIndex &index) const;
bool hasEmptyParsingData(const UModelIndex &index) const;
void setParsingData(const UModelIndex &index, const UByteArray &pdata);
UModelIndex addItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
const UString & name, const UString & text, const UString & info, const UString & name, const UString & text, const UString & info,
const UByteArray & header, const UByteArray & body, const UByteArray & tail, const UByteArray & header, const UByteArray & body, const UByteArray & tail,
const bool fixed, const UByteArray & parsingData = UByteArray(), const ItemFixedState fixed,
const UModelIndex & parent = UModelIndex(), const UINT8 mode = CREATE_MODE_APPEND); const UModelIndex & parent = UModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
UModelIndex findParentOfType(const UModelIndex & index, UINT8 type) const; UModelIndex findParentOfType(const UModelIndex & index, UINT8 type) const;

View File

@ -19,31 +19,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "LZMA/LzmaCompress.h" #include "LZMA/LzmaCompress.h"
#include "LZMA/LzmaDecompress.h" #include "LZMA/LzmaDecompress.h"
// Returns either new parsing data instance or obtains it from index
PARSING_DATA parsingDataFromUModelIndex(const UModelIndex & index)
{
if (index.isValid()) {
TreeModel* model = (TreeModel*)index.model();
if (!model->hasEmptyParsingData(index))
return *(PARSING_DATA*)model->parsingData(index).data();
}
PARSING_DATA data;
data.offset = 0;
data.address = 0;
data.ffsVersion = 0; // Unknown by default
data.emptyByte = 0xFF; // Default value for SPI flash
// Type-specific parts remain unitialized
return data;
}
// Converts parsing data to byte array
UByteArray parsingDataToUByteArray(const PARSING_DATA & pdata)
{
return UByteArray((const char*)&pdata, sizeof(PARSING_DATA));
}
// Returns unique name string based for tree item // Returns unique name string based for tree item
UString uniqueItemName(const UModelIndex & index) UString uniqueItemName(const UModelIndex & index)
{ {
@ -53,9 +28,6 @@ UString uniqueItemName(const UModelIndex & index)
// Get model from index // Get model from index
const TreeModel* model = (const TreeModel*)index.model(); const TreeModel* model = (const TreeModel*)index.model();
// Get data from parsing data
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
// Construct the name // Construct the name
UString itemName = model->name(index); UString itemName = model->name(index);
@ -64,9 +36,19 @@ UString uniqueItemName(const UModelIndex & index)
// Default name // Default name
UString name = itemName; UString name = itemName;
switch (model->type(index)) { switch (model->type(index)) {
case Types::Volume: case Types::Volume: {
if (pdata.volume.hasExtendedHeader) name = guidToUString(pdata.volume.extendedHeaderGuid); UINT8 hasExtendedHeader = FALSE;
break; EFI_GUID extendedHeaderGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
if (model->hasEmptyParsingData(index) == false) {
UByteArray data = model->parsingData(index);
const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData();
hasExtendedHeader = pdata->hasExtendedHeader;
extendedHeaderGuid = pdata->extendedHeaderGuid;
}
if (hasExtendedHeader)
name = guidToUString(extendedHeaderGuid).replace('-', '_');
} break;
case Types::NvarEntry: case Types::NvarEntry:
case Types::VssEntry: case Types::VssEntry:
case Types::FsysEntry: case Types::FsysEntry:
@ -204,7 +186,7 @@ UINT32 crc32(UINT32 initial, const UINT8* buffer, const UINT32 length)
} }
// Compression routines // Compression routines
USTATUS decompress(const UByteArray & compressedData, UINT8 & algorithm, UByteArray & decompressedData, UByteArray & efiDecompressedData) USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionType, UINT8 & algorithm, UByteArray & decompressedData, UByteArray & efiDecompressedData)
{ {
const UINT8* data; const UINT8* data;
UINT32 dataSize; UINT32 dataSize;
@ -215,7 +197,7 @@ USTATUS decompress(const UByteArray & compressedData, UINT8 & algorithm, UByteAr
UINT32 scratchSize = 0; UINT32 scratchSize = 0;
const EFI_TIANO_HEADER* header; const EFI_TIANO_HEADER* header;
switch (algorithm) switch (compressionType)
{ {
case EFI_NOT_COMPRESSED: case EFI_NOT_COMPRESSED:
decompressedData = compressedData; decompressedData = compressedData;

View File

@ -19,12 +19,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treemodel.h" #include "treemodel.h"
#include "parsingdata.h" #include "parsingdata.h"
// Returns either new parsing data instance or obtains it from index
PARSING_DATA parsingDataFromUModelIndex(const UModelIndex & index);
// Converts parsing data to byte array
UByteArray parsingDataToUByteArray(const PARSING_DATA & pdata);
// Returns unique name string based for tree item // Returns unique name string based for tree item
UString uniqueItemName(const UModelIndex & index); UString uniqueItemName(const UModelIndex & index);
@ -32,7 +26,7 @@ UString uniqueItemName(const UModelIndex & index);
UString errorCodeToUString(UINT8 errorCode); UString errorCodeToUString(UINT8 errorCode);
// Decompression routine // Decompression routine
USTATUS decompress(const UByteArray & compressed, UINT8 & algorithm, UByteArray & decompressed, UByteArray & efiDecompressed); USTATUS decompress(const UByteArray & compressed, const UINT8 compressionType, UINT8 & algorithm, UByteArray & decompressed, UByteArray & efiDecompressed);
// Compression routine // Compression routine
//USTATUS compress(const UByteArray & decompressed, UByteArray & compressed, const UINT8 & algorithm); //USTATUS compress(const UByteArray & decompressed, UByteArray & compressed, const UINT8 & algorithm);