UT NE A22

- added UI for NVAR variables
- added parsing of StdDefaults and MfgDefaults nesting variables
This commit is contained in:
Nikolaj Schlej 2016-03-21 09:54:20 +01:00
parent 3cf145a3cc
commit 36c26595a0
9 changed files with 133 additions and 45 deletions

View file

@ -56,6 +56,7 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
else
name = itemName;
} break;
case Types::NvramVariableNvar:
case Types::File: {
name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_');
} break;
@ -67,7 +68,6 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
// Append section subtype name
name += QChar('_') + itemName.replace(' ', '_');
} break;
case Types::Capsule:
case Types::Image:
case Types::Region:

View file

@ -1610,7 +1610,7 @@ STATUS FfsParser::parseFileHeader(const QByteArray & file, const UINT32 parentOf
text = QObject::tr("Volume Top File");
}
// Check if the file is NVRAM storage with NVAR format
else if (guid == NVRAM_NVAR_FILE_GUID) {
else if (guid == NVRAM_NVAR_STORAGE_FILE_GUID || guid == NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID) {
// Mark the file as NVAR storage
pdata.file.format = RAW_FILE_FORMAT_NVAR_STORAGE;
}
@ -2883,7 +2883,8 @@ STATUS FfsParser::parseNvarStorage(const QByteArray & data, const QModelIndex &
UINT32 offset = 0;
UINT32 guidsInStorage = 0;
// Parse all variables
while (1) {
bool msgUnknownExtDataFormat = false;
bool msgExtHeaderTooLong = false;
@ -2919,6 +2920,7 @@ STATUS FfsParser::parseNvarStorage(const QByteArray & data, const QModelIndex &
if (unparsedSize < sizeof(NVAR_VARIABLE_HEADER) ||
variableHeader->Signature != NVRAM_NVAR_VARIABLE_SIGNATURE ||
unparsedSize < variableHeader->Size) {
// Check if the data left is a free space or a padding
QByteArray padding = data.mid(offset, unparsedSize);
UINT8 type;
@ -2930,6 +2932,12 @@ STATUS FfsParser::parseNvarStorage(const QByteArray & data, const QModelIndex &
subtype = 0;
}
else {
// Nothing is parsed yet, but the file is not empty
if (!offset) {
msg(QObject::tr("parseNvarStorage: file can't be parsed as NVAR variables storage"), index);
return ERR_INVALID_FILE;
}
// It's a padding
name = QObject::tr("Padding");
type = Types::Padding;
@ -2962,7 +2970,7 @@ STATUS FfsParser::parseNvarStorage(const QByteArray & data, const QModelIndex &
header = data.mid(offset, sizeof(NVAR_VARIABLE_HEADER));
body = data.mid(offset + sizeof(NVAR_VARIABLE_HEADER), variableHeader->Size - sizeof(NVAR_VARIABLE_HEADER));
UINT32 lastVariableFlag = pdata.emptyByte == 0 ? 0 : 0xFFFFFF;
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0;
// Set default next to predefined last value
pdata.nvram.nvar.next = lastVariableFlag;
@ -2977,7 +2985,7 @@ STATUS FfsParser::parseNvarStorage(const QByteArray & data, const QModelIndex &
// Add next node information to parsing data
if (variableHeader->Next != lastVariableFlag) {
subtype = Subtypes::LinkNvar;
pdata.nvram.nvar.next = offset + variableHeader->Next;
pdata.nvram.nvar.next = variableHeader->Next;
}
// Variable with extended header
@ -3046,7 +3054,7 @@ STATUS FfsParser::parseNvarStorage(const QByteArray & data, const QModelIndex &
for (int i = 0; i < model->rowCount(index); i++) {
nvarIndex = index.child(i, 0);
PARSING_DATA nvarPdata = parsingDataFromQModelIndex(nvarIndex);
if (nvarPdata.nvram.nvar.next == offset) { // Previous link is present and valid
if (nvarPdata.nvram.nvar.next + nvarPdata.offset - parentOffset == offset) { // Previous link is present and valid
isInvalid = false;
break;
}
@ -3102,8 +3110,14 @@ parsing_done:
QString info;
// Rename invalid variables according to their types
if (isInvalid) {
name = QObject::tr("Invalid");
subtype = Subtypes::InvalidNvar;
if (variableHeader->Next != lastVariableFlag) {
name = QObject::tr("Invalid link");
subtype = Subtypes::InvalidLinkNvar;
}
else {
name = QObject::tr("Invalid");
subtype = Subtypes::InvalidNvar;
}
}
else // Add GUID info for valid variables
info += QObject::tr("Variable GUID: %1\n").arg(name);
@ -3122,7 +3136,7 @@ parsing_done:
pdata.nvram.nvar.attributes = variableHeader->Attributes;
// Add next node info
if (variableHeader->Next != lastVariableFlag)
if (!isInvalid && variableHeader->Next != lastVariableFlag)
info += QObject::tr("\nNext node at offset: %1h").hexarg(parentOffset + offset + variableHeader->Next);
// Add extended header info
@ -3165,6 +3179,14 @@ parsing_done:
msg(QObject::tr("parseNvarStorage: extended data size (%1h) is smaller than required for timestamp and hash (0x28)")
.hexarg(extendedData.size()), varIndex);
// Check variable name to be in the list of nesting variables
for (std::vector<CHAR8*>::const_iterator iter = nestingVariableNames.cbegin(); iter != nestingVariableNames.cend(); ++iter)
if (QString(*iter) == text.toLatin1()) {
STATUS result = parseNvarStorage(body, varIndex);
if (result)
msg(QObject::tr("parseNvarStorage: parsing of nested NVAR storage failed with error \"%1\"").arg(errorCodeToQString(result)), varIndex);
}
// Move to next variable
offset += variableHeader->Size;
}

View file

@ -16,35 +16,32 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
QString variableAttributesToQstring(UINT8 attributes)
{
QString str;
if (attributes == 0x00 || attributes == 0xFF) {
if (attributes == 0x00 || attributes == 0xFF)
return QString();
}
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_RUNTIME) {
str += QObject::tr(", Runtime");
}
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_ASCII_NAME) {
str += QObject::tr(", AsciiName");
}
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_GUID) {
str += QObject::tr(", Guid");
}
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_DATA_ONLY) {
str += QObject::tr(", DataOnly");
}
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_EXT_HEADER) {
str += QObject::tr(", ExtHeader");
}
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_HW_ERROR_RECORD) {
str += QObject::tr(", HwErrorRecord");
}
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_AUTH_WRITE) {
str += QObject::tr(", AuthWrite");
}
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_VALID) {
str += QObject::tr(", Valid");
}
QString str;
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_RUNTIME)
str += QObject::tr(", Runtime");
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_ASCII_NAME)
str += QObject::tr(", AsciiName");
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_GUID)
str += QObject::tr(", Guid");
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_DATA_ONLY)
str += QObject::tr(", DataOnly");
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_EXT_HEADER)
str += QObject::tr(", ExtHeader");
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_HW_ERROR_RECORD)
str += QObject::tr(", HwErrorRecord");
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_AUTH_WRITE)
str += QObject::tr(", AuthWrite");
if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_VALID)
str += QObject::tr(", Valid");
return str.mid(2); // Remove the first comma and space
}
}
std::vector<CHAR8*> nestingVariableNames = {
"StdDefaults",
"MfgDefaults"
};

View file

@ -23,12 +23,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Let's start with NVAR storage, as the most difficult one
//
//CEF5B9A3-476D-497F-9FDC-E98143E0422C
const QByteArray NVRAM_NVAR_FILE_GUID
// CEF5B9A3-476D-497F-9FDC-E98143E0422C
const QByteArray NVRAM_NVAR_STORAGE_FILE_GUID
("\xA3\xB9\xF5\xCE\x6D\x47\x7F\x49\x9F\xDC\xE9\x81\x43\xE0\x42\x2C", 16);
// 9221315B-30BB-46B5-813E-1B1BF4712BD3
const QByteArray NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID
("\x5B\x31\x21\x92\xBB\x30\xB5\x46\x81\x3E\x1B\x1B\xF4\x71\x2B\xD3", 16);
extern QString variableAttributesToQstring(UINT8 attributes);
extern std::vector<CHAR8*> nestingVariableNames;
// Make sure we use right packing rules
#pragma pack(push,1)

View file

@ -123,6 +123,8 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
case Types::NvramVariableNvar:
if (subtype == Subtypes::InvalidNvar)
return QObject::tr("Invalid");
if (subtype == Subtypes::InvalidLinkNvar)
return QObject::tr("Invalid link");
if (subtype == Subtypes::LinkNvar)
return QObject::tr("Link");
if (subtype == Subtypes::DataNvar)

View file

@ -87,6 +87,7 @@ namespace Subtypes {
enum NvarVariableSubtypes {
InvalidNvar = 120,
InvalidLinkNvar,
LinkNvar,
DataNvar,
FullNvar