mirror of
https://github.com/LongSoft/UEFITool.git
synced 2025-05-09 13:52:01 -04:00
NE_alpha4
- second pass of parsing to add physical memory addresses to all uncompressed items in the tree - TE image revisions can be detected now - more builder routines, but still not ready for enabling - PE and TE header info is back
This commit is contained in:
parent
129819314d
commit
87bd80b72c
6 changed files with 411 additions and 158 deletions
|
@ -37,9 +37,15 @@ void FfsBuilder::clearMessages()
|
|||
messagesVector.clear();
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
|
||||
STATUS FfsBuilder::erase(const QModelIndex & index, QByteArray & erased)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
|
||||
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||
erased.fill(pdata.emptyByte);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
||||
|
@ -63,20 +69,24 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
|||
// Clear the supplied QByteArray
|
||||
capsule.clear();
|
||||
|
||||
// Reconstruct children
|
||||
// Build children
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
QModelIndex currentChild = index.child(i, 0);
|
||||
QByteArray currentData;
|
||||
// Check child type
|
||||
if (model->type(currentChild) == Types::Image) {
|
||||
result = buildImage(currentChild, currentData);
|
||||
if (!result) {
|
||||
capsule.append(currentData);
|
||||
}
|
||||
else {
|
||||
if (model->subtype(currentChild) == Subtypes::IntelImage)
|
||||
result = buildIntelImage(currentChild, currentData);
|
||||
else
|
||||
result = buildRawArea(currentChild, currentData);
|
||||
|
||||
// Check build result
|
||||
if (result) {
|
||||
msg(tr("buildCapsule: building of \"%1\" failed with error \"%2\", original item data used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
|
||||
capsule.append(model->header(currentChild)).append(model->body(currentChild));
|
||||
}
|
||||
else
|
||||
capsule.append(currentData);
|
||||
}
|
||||
else {
|
||||
msg(tr("buildCapsule: unexpected child item of type \"%1\" can't be processed, original item data used").arg(itemTypeToQString(model->type(currentChild))), currentChild);
|
||||
|
@ -85,18 +95,16 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
|||
}
|
||||
|
||||
// Check size of reconstructed capsule, it must remain the same
|
||||
if (capsule.size() > model->body(index).size()) {
|
||||
UINT32 newSize = capsule.size();
|
||||
UINT32 oldSize = model->body(index).size();
|
||||
if (newSize > oldSize) {
|
||||
msg(tr("buildCapsule: new capsule size %1h (%2) is bigger than the original %3h (%4)")
|
||||
.hexarg(capsule.size()).arg(capsule.size())
|
||||
.hexarg(model->body(index).size()).arg(model->body(index).size()),
|
||||
index);
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
else if (capsule.size() < model->body(index).size()) {
|
||||
else if (newSize < oldSize) {
|
||||
msg(tr("buildCapsule: new capsule size %1h (%2) is smaller than the original %3h (%4)")
|
||||
.hexarg(capsule.size()).arg(capsule.size())
|
||||
.hexarg(model->body(index).size()).arg(model->body(index).size()),
|
||||
index);
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
@ -107,16 +115,197 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
|||
capsule = model->header(index).append(capsule);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
msg(tr("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildImage(const QModelIndex & index, QByteArray & intelImage)
|
||||
STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intelImage)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return ERR_SUCCESS;
|
||||
|
||||
UINT8 result;
|
||||
|
||||
// No action
|
||||
if (model->action(index) == Actions::NoAction) {
|
||||
intelImage = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Other supported actions
|
||||
else if (model->action(index) == Actions::Rebuild) {
|
||||
intelImage.clear();
|
||||
// First child will always be descriptor for this type of image
|
||||
QByteArray descriptor;
|
||||
result = buildRegion(index.child(0, 0), descriptor);
|
||||
if (result)
|
||||
return result;
|
||||
intelImage.append(descriptor);
|
||||
|
||||
const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor.constData() + sizeof(FLASH_DESCRIPTOR_HEADER));
|
||||
const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8((const UINT8*)descriptor.constData(), descriptorMap->RegionBase);
|
||||
QByteArray gbe;
|
||||
UINT32 gbeBegin = calculateRegionOffset(regionSection->GbeBase);
|
||||
UINT32 gbeEnd = gbeBegin + calculateRegionSize(regionSection->GbeBase, regionSection->GbeLimit);
|
||||
QByteArray me;
|
||||
UINT32 meBegin = calculateRegionOffset(regionSection->MeBase);
|
||||
UINT32 meEnd = meBegin + calculateRegionSize(regionSection->MeBase, regionSection->MeLimit);
|
||||
QByteArray bios;
|
||||
UINT32 biosBegin = calculateRegionOffset(regionSection->BiosBase);
|
||||
UINT32 biosEnd = biosBegin + calculateRegionSize(regionSection->BiosBase, regionSection->BiosLimit);
|
||||
QByteArray pdr;
|
||||
UINT32 pdrBegin = calculateRegionOffset(regionSection->PdrBase);
|
||||
UINT32 pdrEnd = pdrBegin + calculateRegionSize(regionSection->PdrBase, regionSection->PdrLimit);
|
||||
|
||||
UINT32 offset = descriptor.size();
|
||||
// Reconstruct other regions
|
||||
char empty = '\xFF';
|
||||
for (int i = 1; i < model->rowCount(index); i++) {
|
||||
QByteArray region;
|
||||
result = buildRegion(index.child(i, 0), region);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
UINT8 type = model->subtype(index.child(i, 0));
|
||||
switch (type)
|
||||
{
|
||||
case Subtypes::GbeRegion:
|
||||
gbe = region;
|
||||
if (gbeBegin > offset)
|
||||
intelImage.append(QByteArray(gbeBegin - offset, empty));
|
||||
intelImage.append(gbe);
|
||||
offset = gbeEnd;
|
||||
break;
|
||||
case Subtypes::MeRegion:
|
||||
me = region;
|
||||
if (meBegin > offset)
|
||||
intelImage.append(QByteArray(meBegin - offset, empty));
|
||||
intelImage.append(me);
|
||||
offset = meEnd;
|
||||
break;
|
||||
case Subtypes::BiosRegion:
|
||||
bios = region;
|
||||
if (biosBegin > offset)
|
||||
intelImage.append(QByteArray(biosBegin - offset, empty));
|
||||
intelImage.append(bios);
|
||||
offset = biosEnd;
|
||||
break;
|
||||
case Subtypes::PdrRegion:
|
||||
pdr = region;
|
||||
if (pdrBegin > offset)
|
||||
intelImage.append(QByteArray(pdrBegin - offset, empty));
|
||||
intelImage.append(pdr);
|
||||
offset = pdrEnd;
|
||||
break;
|
||||
default:
|
||||
msg(tr("buildIntelImage: unknown region type found"), index);
|
||||
return ERR_INVALID_REGION;
|
||||
}
|
||||
}
|
||||
if ((UINT32)model->body(index).size() > offset)
|
||||
intelImage.append(QByteArray((UINT32)model->body(index).size() - offset, empty));
|
||||
|
||||
// Check size of new image, it must be same as old one
|
||||
UINT32 newSize = intelImage.size();
|
||||
UINT32 oldSize = model->body(index).size();
|
||||
if (newSize > oldSize) {
|
||||
msg(tr("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
else if (newSize < oldSize) {
|
||||
msg(tr("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Reconstruction successful
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
msg(tr("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea)
|
||||
STATUS FfsBuilder::buildRegion(const QModelIndex & index, QByteArray & region)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return ERR_SUCCESS;
|
||||
|
||||
UINT8 result;
|
||||
|
||||
// No action required
|
||||
if (model->action(index) == Actions::NoAction) {
|
||||
region = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Erase
|
||||
else if (model->action(index) == Actions::Erase) {
|
||||
region = model->header(index).append(model->body(index));
|
||||
if (erase(index, region))
|
||||
msg(tr("buildRegion: erase failed, original item data used"), index);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Rebuild or replace
|
||||
else if (model->action(index) == Actions::Rebuild ||
|
||||
model->action(index) == Actions::Replace) {
|
||||
if (model->rowCount(index)) {
|
||||
region.clear();
|
||||
// Build children
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
QModelIndex currentChild = index.child(i, 0);
|
||||
QByteArray currentData;
|
||||
// Check child type
|
||||
if (model->type(currentChild) == Types::Volume) {
|
||||
result = buildVolume(currentChild, currentData);
|
||||
}
|
||||
else if (model->type(currentChild) == Types::Padding) {
|
||||
result = buildPadding(currentChild, currentData);
|
||||
}
|
||||
else {
|
||||
msg(tr("buildRegion: unexpected child item of type \"%1\" can't be processed, original item data used").arg(itemTypeToQString(model->type(currentChild))), currentChild);
|
||||
result = ERR_SUCCESS;
|
||||
currentData = model->header(currentChild).append(model->body(currentChild));
|
||||
}
|
||||
// Check build result
|
||||
if (result) {
|
||||
msg(tr("buildRegion: building of \"%1\" failed with error \"%2\", original item data used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
|
||||
currentData = model->header(currentChild).append(model->body(currentChild));
|
||||
}
|
||||
// Append current data
|
||||
region.append(currentData);
|
||||
}
|
||||
}
|
||||
else
|
||||
region = model->body(index);
|
||||
|
||||
// Check size of new region, it must be same as original one
|
||||
UINT32 newSize = region.size();
|
||||
UINT32 oldSize = model->body(index).size();
|
||||
if (newSize > oldSize) {
|
||||
msg(tr("buildRegion: new region size %1h (%2) is bigger than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
else if (newSize < oldSize) {
|
||||
msg(tr("buildRegion: new region size %1h (%2) is smaller than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Build successful
|
||||
region = model->header(index).append(region);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
msg(tr("buildRegion: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
|
@ -137,7 +326,7 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea)
|
|||
// Clear the supplied QByteArray
|
||||
rawArea.clear();
|
||||
|
||||
// Reconstruct children
|
||||
// Build children
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
QModelIndex currentChild = index.child(i, 0);
|
||||
QByteArray currentData;
|
||||
|
@ -162,27 +351,26 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea)
|
|||
rawArea.append(currentData);
|
||||
}
|
||||
|
||||
// Check size of reconstructed raw area, it must remain the same
|
||||
if (rawArea.size() > model->body(index).size()) {
|
||||
msg(tr("buildRawArea: new raw area size %1h (%2) is bigger than the original %3h (%4)")
|
||||
.hexarg(rawArea.size()).arg(rawArea.size())
|
||||
.hexarg(model->body(index).size()).arg(model->body(index).size()),
|
||||
index);
|
||||
// Check size of new raw area, it must be same as original one
|
||||
UINT32 newSize = rawArea.size();
|
||||
UINT32 oldSize = model->body(index).size();
|
||||
if (newSize > oldSize) {
|
||||
msg(tr("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
else if (rawArea.size() < model->body(index).size()) {
|
||||
msg(tr("buildRawArea: new raw area size %1h (%2) is smaller than the original %3h (%4)")
|
||||
.hexarg(rawArea.size()).arg(rawArea.size())
|
||||
.hexarg(model->body(index).size()).arg(model->body(index).size()),
|
||||
index);
|
||||
else if (newSize < oldSize) {
|
||||
msg(tr("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
rawArea = model->body(index);
|
||||
|
||||
// Build successful, append header
|
||||
rawArea = model->header(index).append(rawArea);
|
||||
// Build successful, add header if needed
|
||||
if (addHeader)
|
||||
rawArea = model->header(index).append(rawArea);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -190,11 +378,6 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea)
|
|||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildVolume(const QModelIndex & index, QByteArray & volume)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildPadding(const QModelIndex & index, QByteArray & padding)
|
||||
{
|
||||
// Sanity check
|
||||
|
@ -209,7 +392,9 @@ STATUS FfsBuilder::buildPadding(const QModelIndex & index, QByteArray & padding)
|
|||
|
||||
// Erase
|
||||
else if (model->action(index) == Actions::Erase) {
|
||||
padding.fill('\xFF', model->header(index).size() + model->body(index).size());
|
||||
padding = model->header(index).append(model->body(index));
|
||||
if(erase(index, padding))
|
||||
msg(tr("buildPadding: erase failed, original item data used"), index);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -231,7 +416,9 @@ STATUS FfsBuilder::buildNonUefiData(const QModelIndex & index, QByteArray & data
|
|||
|
||||
// Erase
|
||||
else if (model->action(index) == Actions::Erase) {
|
||||
data.fill('\xFF', model->header(index).size() + model->body(index).size());
|
||||
data = model->header(index).append(model->body(index));
|
||||
if (erase(index, data))
|
||||
msg(tr("buildNonUefiData: erase failed, original item data used"), index);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -255,6 +442,11 @@ STATUS FfsBuilder::buildFreeSpace(const QModelIndex & index, QByteArray & freeSp
|
|||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildVolume(const QModelIndex & index, QByteArray & volume)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildPadFile(const QModelIndex & index, QByteArray & padFile)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
|
@ -270,3 +462,7 @@ STATUS FfsBuilder::buildSection(const QModelIndex & index, QByteArray & section)
|
|||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue