QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype) { switch (type) { case Root: case Image: if (subtype == IntelImage) return QObject::tr("Intel"); else if (subtype == BiosImage) return QObject::tr("BIOS"); else return QObject::tr("Unknown"); case Padding: return ""; case Volume: if (subtype == BootVolume) return QObject::tr("Boot"); else if (subtype == UnknownVolume) return QObject::tr("Unknown"); else if (subtype == NvramVolume) return QObject::tr("NVRAM"); else return ""; case Capsule: if (subtype == AptioCapsule) return QObject::tr("AMI Aptio"); else if (subtype == UefiCapsule) return QObject::tr("UEFI 2.0"); else return QObject::tr("Unknown"); case Region: return regionTypeToQString(subtype); case File: return fileTypeToQString(subtype); case Section: return sectionTypeToQString(subtype); default: return QObject::tr("Unknown"); } }
STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intelImage) { // Sanity check if (!index.isValid()) return ERR_SUCCESS; // No action if (model->action(index) == Actions::NoAction) { intelImage = model->header(index).append(model->body(index)); return ERR_SUCCESS; } // Rebuild else if (model->action(index) == Actions::Rebuild) { intelImage.clear(); // First child will always be descriptor for this type of image, and it's read only intelImage.append(model->header(index.child(0, 0)).append(model->body(index.child(0, 0)))); // Process other regions for (int i = 1; i < model->rowCount(index); i++) { QModelIndex currentRegion = index.child(i, 0); // Skip regions with Remove action if (model->action(currentRegion) == Actions::Remove) continue; // Check item type to be either region or padding UINT8 type = model->type(currentRegion); if (type == Types::Padding) { // Add padding as is intelImage.append(model->header(currentRegion).append(model->body(currentRegion))); continue; } // Check region subtype STATUS result; QByteArray region; UINT8 regionType = model->subtype(currentRegion); switch (regionType) { case Subtypes::BiosRegion: case Subtypes::PdrRegion: result = buildRawArea(currentRegion, region); if (result) { msg(QObject::tr("buildIntelImage: building of %1 region failed with error \"%2\", original item data is used").arg(regionTypeToQString(regionType)).arg(errorCodeToQString(result)), currentRegion); region = model->header(currentRegion).append(model->body(currentRegion)); } break; case Subtypes::GbeRegion: case Subtypes::MeRegion: case Subtypes::EcRegion: case Subtypes::Reserved1Region: case Subtypes::Reserved2Region: case Subtypes::Reserved3Region: case Subtypes::Reserved4Region: // Add region as is region = model->header(currentRegion).append(model->body(currentRegion)); break; default: msg(QObject::tr("buildIntelImage: don't know how to build region of unknown type"), index); return ERR_UNKNOWN_ITEM_TYPE; } // Append the resulting region intelImage.append(region); } // 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(QObject::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(QObject::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(QObject::tr("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); return ERR_NOT_IMPLEMENTED; }