From a4a455d0ff7b2c01424a5253068f1b9f7fb60ecd Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Sat, 10 Sep 2022 09:56:14 +0200 Subject: [PATCH] Add support for x86 recovery startup AP data entries in special padding files --- UEFITool/uefitool.cpp | 628 +++++++++++++++++++++--------------------- common/ffs.cpp | 5 +- common/ffs.h | 9 +- common/ffsparser.cpp | 63 +++-- common/types.cpp | 177 ++++++------ common/types.h | 40 +-- common/utility.cpp | 2 +- 7 files changed, 485 insertions(+), 439 deletions(-) diff --git a/UEFITool/uefitool.cpp b/UEFITool/uefitool.cpp index ab9a932..3d706bc 100644 --- a/UEFITool/uefitool.cpp +++ b/UEFITool/uefitool.cpp @@ -215,6 +215,7 @@ void UEFITool::populateUi(const QModelIndex ¤t) || type == Types::CpdEntry || type == Types::CpdExtension || type == Types::CpdSpiEntry + || type == Types::StartupApDataEntry ); ui->menuStoreActions->setEnabled(type == Types::VssStore || type == Types::Vss2Store @@ -441,7 +442,6 @@ void UEFITool::replaceBody() void UEFITool::replace(const UINT8 mode) { U_UNUSED_PARAMETER(mode); - } void UEFITool::extractAsIs() @@ -507,7 +507,7 @@ void UEFITool::extract(const UINT8 mode) if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey to file"), name + ".spk", tr("SLIC pubkey files (*.spk *.bin);;All files (*)")); else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker to file"), name + ".smk", tr("SLIC marker files (*.smk *.bin);;All files (*)")); break; - default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); + default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); } } else if (mode == EXTRACT_MODE_BODY || mode == EXTRACT_MODE_BODY_UNCOMPRESSED) { @@ -534,6 +534,7 @@ void UEFITool::extract(const UINT8 mode) case Types::VssEntry: case Types::EvsaEntry: case Types::FlashMapEntry: + case Types::StartupApDataEntry: case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save entry body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); break; case Types::VssStore: case Types::Vss2Store: @@ -547,10 +548,10 @@ void UEFITool::extract(const UINT8 mode) if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey body to file"), name + ".spb", tr("SLIC pubkey body files (*.spb *.bin);;All files (*)")); else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker body to file"), name + ".smb", tr("SLIC marker body files (*.smb *.bin);;All files (*)")); break; - default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); + default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); } } - else path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); + else path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); if (path.trimmed().isEmpty()) return; @@ -578,17 +579,23 @@ void UEFITool::remove() void UEFITool::about() { - QMessageBox::about(this, tr("About UEFITool"), tr( - "Copyright (c) 2019, Nikolaj Schlej.
" - "Program icon made by Alexander Zhidkov.
" - "The program uses QHexEdit2 library made by Simsys.
" - "Qt-less engine is using Bstrlib made by Paul Hsieh.

" - "The program is dedicated to RevoGirl. Rest in peace, young genius.

" - "The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License.
" - "The full text of the license may be found at OpenSource.org.

" - "THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, " - "WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, " - "EITHER EXPRESS OR IMPLIED.")); + QMessageBox::about(this, tr("About UEFITool"), + tr("Copyright (c) 2013-2022, Nikolaj Schlej.

" + "Program icon made by Alexander Zhidkov.

" + "GUI uses QHexEdit2 library made by Simsys.
" + "Qt-less engine uses Bstrlib made by Paul Hsieh.
" + "Engine uses Tiano compression code made by TianoCore developers.
" + "Engine uses LZMA compression code made by Igor Pavlov.
" + "Engine uses zlib compression code made by Mark Adler.
" + "Engine uses LibTomCrypt hashing code made by LibTom developers.
" + "Engine uses KaitaiStruct runtime made by Kaitai team.

" + "The program is dedicated to RevoGirl. Rest in peace, young genius.

" + "The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD-2-Clause License.
" + "The full text of the license may be found at OpenSource.org.

" + "THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, " + "WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, " + "EITHER EXPRESS OR IMPLIED." + )); } void UEFITool::aboutQt() @@ -801,309 +808,312 @@ void UEFITool::showParserMessages() #if QT_VERSION_MAJOR < 6 std::pair msg; - foreach (msg, messages) { + foreach (msg, messages) #else - for (const auto &msg : messages) { + for (const auto &msg : messages) #endif - QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); - item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second))); - ui->parserMessagesListWidget->addItem(item); - } + { + QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); + item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second))); + ui->parserMessagesListWidget->addItem(item); + } - ui->messagesTabWidget->setCurrentIndex(TAB_PARSER); - ui->parserMessagesListWidget->scrollToBottom(); + ui->messagesTabWidget->setCurrentIndex(TAB_PARSER); + ui->parserMessagesListWidget->scrollToBottom(); +} + +void UEFITool::showFinderMessages() +{ + ui->finderMessagesListWidget->clear(); + if (!ffsParser) + return; + + std::vector > messages = ffsFinder->getMessages(); + +#if QT_VERSION_MAJOR < 6 + std::pair msg; + + foreach (msg, messages) +#else + for (const auto &msg : messages) +#endif + { + QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); + item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second)));; + ui->finderMessagesListWidget->addItem(item); } - void UEFITool::showFinderMessages() + ui->messagesTabWidget->setTabEnabled(TAB_SEARCH, true); + ui->messagesTabWidget->setCurrentIndex(TAB_SEARCH); + ui->finderMessagesListWidget->scrollToBottom(); +} + +void UEFITool::showBuilderMessages() +{ + ui->builderMessagesListWidget->clear(); + if (!ffsBuilder) + return; + + std::vector > messages = ffsBuilder->getMessages(); + +#if QT_VERSION_MAJOR < 6 + std::pair msg; + + foreach (msg, messages) +#else + for (const auto &msg : messages) +#endif { - ui->finderMessagesListWidget->clear(); - if (!ffsParser) - return; - - std::vector > messages = ffsFinder->getMessages(); - -#if QT_VERSION_MAJOR < 6 - std::pair msg; - - foreach (msg, messages) { -#else - for (const auto &msg : messages) { -#endif - QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); - item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second)));; - ui->finderMessagesListWidget->addItem(item); - } - - ui->messagesTabWidget->setTabEnabled(TAB_SEARCH, true); - ui->messagesTabWidget->setCurrentIndex(TAB_SEARCH); - ui->finderMessagesListWidget->scrollToBottom(); - } - - void UEFITool::showBuilderMessages() - { - ui->builderMessagesListWidget->clear(); - if (!ffsBuilder) - return; - - std::vector > messages = ffsBuilder->getMessages(); - -#if QT_VERSION_MAJOR < 6 - std::pair msg; - - foreach (msg, messages) { -#else - for (const auto &msg : messages) { -#endif - QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); - item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second))); - ui->builderMessagesListWidget->addItem(item); - } - - ui->messagesTabWidget->setTabEnabled(TAB_BUILDER, true); - ui->messagesTabWidget->setCurrentIndex(TAB_BUILDER); - ui->builderMessagesListWidget->scrollToBottom(); - } - - void UEFITool::scrollTreeView(QListWidgetItem* item) - { - QByteArray second = item->data(Qt::UserRole).toByteArray(); - QModelIndex *index = (QModelIndex *)second.data(); - if (index && index->isValid()) { - ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter); - ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); - } - } - - void UEFITool::scrollTreeView(QTableWidgetItem* item) - { - QByteArray second = item->data(Qt::UserRole).toByteArray(); - QModelIndex *index = (QModelIndex *)second.data(); - if (index && index->isValid()) { - ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter); - ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); - } - } - - void UEFITool::contextMenuEvent(QContextMenuEvent* event) - { - // The checks involving underMouse do not work well enough on macOS, and result in right-click sometimes - // not showing any context menu at all. Most likely it is a bug in Qt, which does not affect other systems. - // For this reason we reimplement this manually. - if (ui->parserMessagesListWidget->rect().contains(ui->parserMessagesListWidget->mapFromGlobal(event->globalPos())) || - ui->finderMessagesListWidget->rect().contains(ui->finderMessagesListWidget->mapFromGlobal(event->globalPos())) || - ui->builderMessagesListWidget->rect().contains(ui->builderMessagesListWidget->mapFromGlobal(event->globalPos()))) { - ui->menuMessageActions->exec(event->globalPos()); - return; - } - - - if (!ui->structureTreeView->rect().contains(ui->structureTreeView->mapFromGlobal(event->globalPos()))) - return; - - QPoint pt = event->pos(); - QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt)); - if (!index.isValid()) { - return; - } - - switch (model->type(index)) - { - case Types::Capsule: ui->menuCapsuleActions->exec(event->globalPos()); break; - case Types::Image: ui->menuImageActions->exec(event->globalPos()); break; - case Types::Region: ui->menuRegionActions->exec(event->globalPos()); break; - case Types::Padding: ui->menuPaddingActions->exec(event->globalPos()); break; - case Types::Volume: ui->menuVolumeActions->exec(event->globalPos()); break; - case Types::File: ui->menuFileActions->exec(event->globalPos()); break; - case Types::Section: ui->menuSectionActions->exec(event->globalPos()); break; - case Types::VssStore: - case Types::Vss2Store: - case Types::FdcStore: - case Types::FsysStore: - case Types::EvsaStore: - case Types::FtwStore: - case Types::FlashMapStore: - case Types::CmdbStore: - case Types::FptStore: - case Types::CpdStore: - case Types::BpdtStore: ui->menuStoreActions->exec(event->globalPos()); break; - case Types::FreeSpace: break; // No menu needed for FreeSpace item - default: ui->menuEntryActions->exec(event->globalPos()); break; - } - } - - void UEFITool::readSettings() - { - QSettings settings(this); - restoreGeometry(settings.value("mainWindow/geometry").toByteArray()); - restoreState(settings.value("mainWindow/windowState").toByteArray()); - QList horList, vertList; - horList.append(settings.value("mainWindow/treeWidth", 600).toInt()); - horList.append(settings.value("mainWindow/infoWidth", 180).toInt()); - vertList.append(settings.value("mainWindow/treeHeight", 400).toInt()); - vertList.append(settings.value("mainWindow/messageHeight", 180).toInt()); - ui->infoSplitter->setSizes(horList); - ui->messagesSplitter->setSizes(vertList); - ui->structureTreeView->setColumnWidth(0, settings.value("tree/columnWidth0", ui->structureTreeView->columnWidth(0)).toInt()); - ui->structureTreeView->setColumnWidth(1, settings.value("tree/columnWidth1", ui->structureTreeView->columnWidth(1)).toInt()); - ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt()); - ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt()); - markingEnabled = settings.value("tree/markingEnabled", true).toBool(); - ui->actionToggleBootGuardMarking->setChecked(markingEnabled); - - // Set monospace font for some controls - QString fontName; - int fontSize; + QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0); + item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second))); + ui->builderMessagesListWidget->addItem(item); + } + + ui->messagesTabWidget->setTabEnabled(TAB_BUILDER, true); + ui->messagesTabWidget->setCurrentIndex(TAB_BUILDER); + ui->builderMessagesListWidget->scrollToBottom(); +} + +void UEFITool::scrollTreeView(QListWidgetItem* item) +{ + QByteArray second = item->data(Qt::UserRole).toByteArray(); + QModelIndex *index = (QModelIndex *)second.data(); + if (index && index->isValid()) { + ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter); + ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); + } +} + +void UEFITool::scrollTreeView(QTableWidgetItem* item) +{ + QByteArray second = item->data(Qt::UserRole).toByteArray(); + QModelIndex *index = (QModelIndex *)second.data(); + if (index && index->isValid()) { + ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter); + ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); + } +} + +void UEFITool::contextMenuEvent(QContextMenuEvent* event) +{ + // The checks involving underMouse do not work well enough on macOS, and result in right-click sometimes + // not showing any context menu at all. Most likely it is a bug in Qt, which does not affect other systems. + // For this reason we reimplement this manually. + if (ui->parserMessagesListWidget->rect().contains(ui->parserMessagesListWidget->mapFromGlobal(event->globalPos())) || + ui->finderMessagesListWidget->rect().contains(ui->finderMessagesListWidget->mapFromGlobal(event->globalPos())) || + ui->builderMessagesListWidget->rect().contains(ui->builderMessagesListWidget->mapFromGlobal(event->globalPos()))) { + ui->menuMessageActions->exec(event->globalPos()); + return; + } + + + if (!ui->structureTreeView->rect().contains(ui->structureTreeView->mapFromGlobal(event->globalPos()))) + return; + + QPoint pt = event->pos(); + QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt)); + if (!index.isValid()) { + return; + } + + switch (model->type(index)) + { + case Types::Capsule: ui->menuCapsuleActions->exec(event->globalPos()); break; + case Types::Image: ui->menuImageActions->exec(event->globalPos()); break; + case Types::Region: ui->menuRegionActions->exec(event->globalPos()); break; + case Types::Padding: ui->menuPaddingActions->exec(event->globalPos()); break; + case Types::Volume: ui->menuVolumeActions->exec(event->globalPos()); break; + case Types::File: ui->menuFileActions->exec(event->globalPos()); break; + case Types::Section: ui->menuSectionActions->exec(event->globalPos()); break; + case Types::VssStore: + case Types::Vss2Store: + case Types::FdcStore: + case Types::FsysStore: + case Types::EvsaStore: + case Types::FtwStore: + case Types::FlashMapStore: + case Types::CmdbStore: + case Types::FptStore: + case Types::CpdStore: + case Types::BpdtStore: ui->menuStoreActions->exec(event->globalPos()); break; + case Types::FreeSpace: break; // No menu needed for FreeSpace item + default: ui->menuEntryActions->exec(event->globalPos()); break; + } +} + +void UEFITool::readSettings() +{ + QSettings settings(this); + restoreGeometry(settings.value("mainWindow/geometry").toByteArray()); + restoreState(settings.value("mainWindow/windowState").toByteArray()); + QList horList, vertList; + horList.append(settings.value("mainWindow/treeWidth", 600).toInt()); + horList.append(settings.value("mainWindow/infoWidth", 180).toInt()); + vertList.append(settings.value("mainWindow/treeHeight", 400).toInt()); + vertList.append(settings.value("mainWindow/messageHeight", 180).toInt()); + ui->infoSplitter->setSizes(horList); + ui->messagesSplitter->setSizes(vertList); + ui->structureTreeView->setColumnWidth(0, settings.value("tree/columnWidth0", ui->structureTreeView->columnWidth(0)).toInt()); + ui->structureTreeView->setColumnWidth(1, settings.value("tree/columnWidth1", ui->structureTreeView->columnWidth(1)).toInt()); + ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt()); + ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt()); + markingEnabled = settings.value("tree/markingEnabled", true).toBool(); + ui->actionToggleBootGuardMarking->setChecked(markingEnabled); + + // Set monospace font for some controls + QString fontName; + int fontSize; #if defined Q_OS_OSX - fontName = settings.value("mainWindow/fontName", QString("Menlo")).toString(); - fontSize = settings.value("mainWindow/fontSize", 10).toInt(); + fontName = settings.value("mainWindow/fontName", QString("Menlo")).toString(); + fontSize = settings.value("mainWindow/fontSize", 10).toInt(); #elif defined Q_OS_WIN - fontName = settings.value("mainWindow/fontName", QString("Consolas")).toString(); - fontSize = settings.value("mainWindow/fontSize", 9).toInt(); + fontName = settings.value("mainWindow/fontName", QString("Consolas")).toString(); + fontSize = settings.value("mainWindow/fontSize", 9).toInt(); #else - fontName = settings.value("mainWindow/fontName", QString("Courier New")).toString(); - fontSize = settings.value("mainWindow/fontSize", 10).toInt(); + fontName = settings.value("mainWindow/fontName", QString("Courier New")).toString(); + fontSize = settings.value("mainWindow/fontSize", 10).toInt(); #endif - currentFont = QFont(fontName, fontSize); - ui->infoEdit->setFont(currentFont); - ui->parserMessagesListWidget->setFont(currentFont); - ui->finderMessagesListWidget->setFont(currentFont); - ui->builderMessagesListWidget->setFont(currentFont); - ui->fitTableWidget->setFont(currentFont); - ui->securityEdit->setFont(currentFont); - ui->structureTreeView->setFont(currentFont); - searchDialog->ui->guidEdit->setFont(currentFont); - searchDialog->ui->hexEdit->setFont(currentFont); - hexViewDialog->setFont(currentFont); - goToAddressDialog->ui->hexSpinBox->setFont(currentFont); - goToBaseDialog->ui->hexSpinBox->setFont(currentFont); - } - - void UEFITool::writeSettings() - { - QSettings settings(this); - settings.setValue("mainWindow/geometry", saveGeometry()); - settings.setValue("mainWindow/windowState", saveState()); - settings.setValue("mainWindow/treeWidth", ui->structureGroupBox->width()); - settings.setValue("mainWindow/infoWidth", ui->infoGroupBox->width()); - settings.setValue("mainWindow/treeHeight", ui->structureGroupBox->height()); - settings.setValue("mainWindow/messageHeight", ui->messagesTabWidget->height()); - settings.setValue("tree/columnWidth0", ui->structureTreeView->columnWidth(0)); - settings.setValue("tree/columnWidth1", ui->structureTreeView->columnWidth(1)); - settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2)); - settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3)); - settings.setValue("tree/markingEnabled", markingEnabled); - settings.setValue("mainWindow/fontName", currentFont.family()); - settings.setValue("mainWindow/fontSize", currentFont.pointSize()); - } - - void UEFITool::showFitTable() - { - std::vector, UModelIndex> > fitTable = ffsParser->getFitTable(); - if (fitTable.empty()) { - // Disable FIT tab - ui->messagesTabWidget->setTabEnabled(TAB_FIT, false); - return; - } - - // Enable FIT tab - ui->messagesTabWidget->setTabEnabled(TAB_FIT, true); - - // Set up the FIT table - ui->fitTableWidget->clear(); - ui->fitTableWidget->setRowCount((int)fitTable.size()); - ui->fitTableWidget->setColumnCount(6); - ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Checksum") << tr("Type") << tr("Information")); - ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->fitTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->fitTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); - ui->fitTableWidget->horizontalHeader()->setStretchLastSection(true); - - // Add all data to the table widget - for (size_t i = 0; i < fitTable.size(); i++) { - for (UINT8 j = 0; j < 6; j++) { - QTableWidgetItem* item = new QTableWidgetItem(fitTable[i].first[j]); - item->setData(Qt::UserRole, QByteArray((const char*)&fitTable[i].second, sizeof(fitTable[i].second))); - ui->fitTableWidget->setItem((int)i, j, item); - } - } - - ui->fitTableWidget->resizeColumnsToContents(); - ui->fitTableWidget->resizeRowsToContents(); - ui->messagesTabWidget->setCurrentIndex(TAB_FIT); - } - - void UEFITool::showSecurityInfo() - { - // Get security info - UString secInfo = ffsParser->getSecurityInfo(); - if (secInfo.isEmpty()) { - ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, false); - return; - } - - ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, true); - ui->securityEdit->setPlainText(secInfo); - ui->messagesTabWidget->setCurrentIndex(TAB_SECURITY); - } - - void UEFITool::currentTabChanged(int index) - { - U_UNUSED_PARAMETER(index); - - ui->menuMessageActions->setEnabled(false); - ui->actionMessagesCopy->setEnabled(false); - ui->actionMessagesCopyAll->setEnabled(false); - ui->actionMessagesClear->setEnabled(false); - } - - void UEFITool::loadGuidDatabase() - { - QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, tr("Comma-separated values files (*.csv);;All files (*)")); - if (!path.isEmpty()) { - initGuidDatabase(path); - if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("New GUID database loaded"), tr("Apply new GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) - openImageFile(currentPath); - } - } - - void UEFITool::unloadGuidDatabase() - { - initGuidDatabase(); - if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("GUID database unloaded"), tr("Apply changes on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) - openImageFile(currentPath); - } - - void UEFITool::loadDefaultGuidDatabase() - { - initGuidDatabase(":/guids.csv"); - if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("Default GUID database loaded"), tr("Apply default GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) - openImageFile(currentPath); - } - - void UEFITool::exportDiscoveredGuids() - { - GuidDatabase db = guidDatabaseFromTreeRecursive(model, model->index(0, 0)); - if (!db.empty()) { - QString path = QFileDialog::getSaveFileName(this, tr("Save parsed GUIDs to database"), currentPath + ".guids.csv", tr("Comma-separated values files (*.csv);;All files (*)")); - if (!path.isEmpty()) - guidDatabaseExportToFile(path, db); - } - } - - void UEFITool::generateReport() - { - QString path = QFileDialog::getSaveFileName(this, tr("Save report to text file"), currentPath + ".report.txt", tr("Text files (*.txt);;All files (*)")); - if (!path.isEmpty()) { - std::vector report = ffsReport->generate(); - if (report.size()) { - QFile file; - file.setFileName(path); - if (file.open(QFile::Text | QFile::WriteOnly)) { - for (size_t i = 0; i < report.size(); i++) { - file.write(report[i].toLatin1().append('\n')); - } - file.close(); - } - } + currentFont = QFont(fontName, fontSize); + ui->infoEdit->setFont(currentFont); + ui->parserMessagesListWidget->setFont(currentFont); + ui->finderMessagesListWidget->setFont(currentFont); + ui->builderMessagesListWidget->setFont(currentFont); + ui->fitTableWidget->setFont(currentFont); + ui->securityEdit->setFont(currentFont); + ui->structureTreeView->setFont(currentFont); + searchDialog->ui->guidEdit->setFont(currentFont); + searchDialog->ui->hexEdit->setFont(currentFont); + hexViewDialog->setFont(currentFont); + goToAddressDialog->ui->hexSpinBox->setFont(currentFont); + goToBaseDialog->ui->hexSpinBox->setFont(currentFont); +} + +void UEFITool::writeSettings() +{ + QSettings settings(this); + settings.setValue("mainWindow/geometry", saveGeometry()); + settings.setValue("mainWindow/windowState", saveState()); + settings.setValue("mainWindow/treeWidth", ui->structureGroupBox->width()); + settings.setValue("mainWindow/infoWidth", ui->infoGroupBox->width()); + settings.setValue("mainWindow/treeHeight", ui->structureGroupBox->height()); + settings.setValue("mainWindow/messageHeight", ui->messagesTabWidget->height()); + settings.setValue("tree/columnWidth0", ui->structureTreeView->columnWidth(0)); + settings.setValue("tree/columnWidth1", ui->structureTreeView->columnWidth(1)); + settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2)); + settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3)); + settings.setValue("tree/markingEnabled", markingEnabled); + settings.setValue("mainWindow/fontName", currentFont.family()); + settings.setValue("mainWindow/fontSize", currentFont.pointSize()); +} + +void UEFITool::showFitTable() +{ + std::vector, UModelIndex> > fitTable = ffsParser->getFitTable(); + if (fitTable.empty()) { + // Disable FIT tab + ui->messagesTabWidget->setTabEnabled(TAB_FIT, false); + return; + } + + // Enable FIT tab + ui->messagesTabWidget->setTabEnabled(TAB_FIT, true); + + // Set up the FIT table + ui->fitTableWidget->clear(); + ui->fitTableWidget->setRowCount((int)fitTable.size()); + ui->fitTableWidget->setColumnCount(6); + ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Checksum") << tr("Type") << tr("Information")); + ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->fitTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->fitTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); + ui->fitTableWidget->horizontalHeader()->setStretchLastSection(true); + + // Add all data to the table widget + for (size_t i = 0; i < fitTable.size(); i++) { + for (UINT8 j = 0; j < 6; j++) { + QTableWidgetItem* item = new QTableWidgetItem(fitTable[i].first[j]); + item->setData(Qt::UserRole, QByteArray((const char*)&fitTable[i].second, sizeof(fitTable[i].second))); + ui->fitTableWidget->setItem((int)i, j, item); + } + } + + ui->fitTableWidget->resizeColumnsToContents(); + ui->fitTableWidget->resizeRowsToContents(); + ui->messagesTabWidget->setCurrentIndex(TAB_FIT); +} + +void UEFITool::showSecurityInfo() +{ + // Get security info + UString secInfo = ffsParser->getSecurityInfo(); + if (secInfo.isEmpty()) { + ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, false); + return; + } + + ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, true); + ui->securityEdit->setPlainText(secInfo); + ui->messagesTabWidget->setCurrentIndex(TAB_SECURITY); +} + +void UEFITool::currentTabChanged(int index) +{ + U_UNUSED_PARAMETER(index); + + ui->menuMessageActions->setEnabled(false); + ui->actionMessagesCopy->setEnabled(false); + ui->actionMessagesCopyAll->setEnabled(false); + ui->actionMessagesClear->setEnabled(false); +} + +void UEFITool::loadGuidDatabase() +{ + QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, tr("Comma-separated values files (*.csv);;All files (*)")); + if (!path.isEmpty()) { + initGuidDatabase(path); + if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("New GUID database loaded"), tr("Apply new GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) + openImageFile(currentPath); + } +} + +void UEFITool::unloadGuidDatabase() +{ + initGuidDatabase(); + if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("GUID database unloaded"), tr("Apply changes on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) + openImageFile(currentPath); +} + +void UEFITool::loadDefaultGuidDatabase() +{ + initGuidDatabase(":/guids.csv"); + if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("Default GUID database loaded"), tr("Apply default GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) + openImageFile(currentPath); +} + +void UEFITool::exportDiscoveredGuids() +{ + GuidDatabase db = guidDatabaseFromTreeRecursive(model, model->index(0, 0)); + if (!db.empty()) { + QString path = QFileDialog::getSaveFileName(this, tr("Save parsed GUIDs to database"), currentPath + ".guids.csv", tr("Comma-separated values files (*.csv);;All files (*)")); + if (!path.isEmpty()) + guidDatabaseExportToFile(path, db); + } +} + +void UEFITool::generateReport() +{ + QString path = QFileDialog::getSaveFileName(this, tr("Save report to text file"), currentPath + ".report.txt", tr("Text files (*.txt);;All files (*)")); + if (!path.isEmpty()) { + std::vector report = ffsReport->generate(); + if (report.size()) { + QFile file; + file.setFileName(path); + if (file.open(QFile::Text | QFile::WriteOnly)) { + for (size_t i = 0; i < report.size(); i++) { + file.write(report[i].toLatin1().append('\n')); } + file.close(); } + } + } +} diff --git a/common/ffs.cpp b/common/ffs.cpp index 2425182..973a747 100644 --- a/common/ffs.cpp +++ b/common/ffs.cpp @@ -72,7 +72,7 @@ extern const UByteArray EFI_DXE_APRIORI_FILE_GUID // FC510EE7-FFDC-11D4-BD41-008 // Volume top file extern const UByteArray EFI_FFS_VOLUME_TOP_FILE_GUID // 1BA0062E-C779-4582-8566-336AE8F78F09 ("\x2E\x06\xA0\x1B\x79\xC7\x82\x45\x85\x66\x33\x6A\xE8\xF7\x8F\x09", 16); -// Pad file GUID +// Padding file GUID extern const UByteArray EFI_FFS_PAD_FILE_GUID // E4536585-7909-4A60-B5C6-ECDEA6EBFB5 ("\x85\x65\x53\xE4\x09\x79\x60\x4A\xB5\xC6\xEC\xDE\xA6\xEB\xFB\x54", 16); // AMI DXE core file @@ -125,6 +125,9 @@ const UINT8 ffsAlignmentTable[] = const UINT8 ffsAlignment2Table[] = { 17, 18, 19, 20, 21, 22, 23, 24 }; +extern const UByteArray RECOVERY_STARTUP_AP_DATA_X86_128K // jmp far F000:FFD0, EAD0FF00F0 +("\xEA\xD0\xFF\x00\xF0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x2D", RECOVERY_STARTUP_AP_DATA_X86_SIZE); + VOID uint32ToUint24(UINT32 size, UINT8* ffsSize) { ffsSize[2] = (UINT8)((size) >> 16U); diff --git a/common/ffs.h b/common/ffs.h index fdfbf46..c3d122a 100644 --- a/common/ffs.h +++ b/common/ffs.h @@ -348,7 +348,7 @@ extern const UByteArray EFI_DXE_APRIORI_FILE_GUID; // FC510EE7-FFDC-11D4-BD41-00 // Volume top file extern const UByteArray EFI_FFS_VOLUME_TOP_FILE_GUID; // 1BA0062E-C779-4582-8566-336AE8F78F09 -// AMI pad file GUID +// AMI padding file GUID extern const UByteArray EFI_FFS_PAD_FILE_GUID; // E4536585-7909-4A60-B5C6-ECDEA6EBFB5 // AMI DXE core file @@ -530,6 +530,13 @@ typedef struct POSTCODE_SECTION_ { /// #define EFI_DEP_SOR 0x09 +//***************************************************************************** +// X86 Startup AP Data +//***************************************************************************** +#define RECOVERY_STARTUP_AP_DATA_X86_SIZE 0x10 +extern const UByteArray RECOVERY_STARTUP_AP_DATA_X86_64K; +extern const UByteArray RECOVERY_STARTUP_AP_DATA_X86_128K; + //***************************************************************************** // X86 Reset Vector Data //***************************************************************************** diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index 6ca2560..630b68b 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -1368,7 +1368,8 @@ USTATUS FfsParser::findNextRawAreaItem(const UModelIndex & index, const UINT32 l nextItemOffset = offset - EFI_FV_SIGNATURE_OFFSET; break; } - else if (readUnaligned(currentPos) == BPDT_GREEN_SIGNATURE || readUnaligned(currentPos) == BPDT_YELLOW_SIGNATURE) { + else if (readUnaligned(currentPos) == BPDT_GREEN_SIGNATURE + || readUnaligned(currentPos) == BPDT_YELLOW_SIGNATURE) { // Check data size if (restSize < sizeof(BPDT_HEADER)) continue; @@ -1548,8 +1549,8 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index) // We aren't at the end of empty space // Check that the remaining space can still have a file in it - if (volumeBodySize - fileOffset < sizeof(EFI_FFS_FILE_HEADER) || // Remaining space is smaller than the smallest possible file - volumeBodySize - fileOffset < fileSize) { // Remaining space is smaller than non-empty file size + if (volumeBodySize - fileOffset < sizeof(EFI_FFS_FILE_HEADER) // Remaining space is smaller than the smallest possible file + || volumeBodySize - fileOffset < fileSize) { // Remaining space is smaller than non-empty file size // Parse non-UEFI data parseVolumeNonUefiData(volumeBody.mid(fileOffset), volumeHeaderSize + fileOffset, index); @@ -1573,8 +1574,9 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index) for (int i = 0; i < model->rowCount(index); i++) { UModelIndex current = index.model()->index(i, 0, index); - // Skip non-file entries and pad files - if (model->type(current) != Types::File || model->subtype(current) == EFI_FV_FILETYPE_PAD) { + // Skip non-file entries and padding files + if (model->type(current) != Types::File + || model->subtype(current) == EFI_FV_FILETYPE_PAD) { continue; } @@ -1755,7 +1757,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf if (fileHeader->Type != EFI_FV_FILETYPE_PAD) { name = guidToUString(fileHeader->Name); } else { - name = UString("Pad-file"); + name = UString("Padding file"); } info = UString("File GUID: ") + guidToUString(fileHeader->Name, false) + @@ -1864,7 +1866,7 @@ USTATUS FfsParser::parseFileBody(const UModelIndex & index) if (model->type(index) != Types::File) return U_SUCCESS; - // Parse pad-file body + // Parse padding file body if (model->subtype(index) == EFI_FV_FILETYPE_PAD) return parsePadFileBody(index); @@ -1915,7 +1917,7 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index) emptyByte = pdata->emptyByte; } - // Check if the while PAD file is empty + // Check if the while padding file is empty if (body.size() == body.count(emptyByte)) return U_SUCCESS; @@ -1950,20 +1952,39 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index) // ... and all bytes after as a padding UByteArray padding = body.mid(nonEmptyByteOffset); - // Get info - UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + // Check for that data to be recovery startup AP data for x86 + // https://github.com/tianocore/edk2/blob/stable/202011/BaseTools/Source/C/GenFv/GenFvInternalLib.c#L106 + if (padding.left(RECOVERY_STARTUP_AP_DATA_X86_SIZE) == RECOVERY_STARTUP_AP_DATA_X86_128K) { + // Get info + UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + (void)model->addItem(headerSize + nonEmptyByteOffset, Types::StartupApDataEntry, Subtypes::x86128kStartupApDataEntry, UString("Startup AP data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + + // Rename the file + model->setName(index, UString("Startup AP data padding file")); + + // Do not parse contents + return U_SUCCESS; + } + else { // Not a data array + // Get info + UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size()); + + // Add tree item + UModelIndex dataIndex = model->addItem(headerSize + nonEmptyByteOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + + // Show message + msg(usprintf("%s: non-UEFI data found in padding file", __FUNCTION__), dataIndex); + + // Rename the file + model->setName(index, UString("Non-empty padding file")); + + // Do not parse contents + return U_SUCCESS; + } - // Add tree item - UModelIndex dataIndex = model->addItem(headerSize + nonEmptyByteOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); - - // Show message - msg(usprintf("%s: non-UEFI data found in pad-file", __FUNCTION__), dataIndex); - - // Rename the file - model->setName(index, UString("Non-empty pad-file")); - - // Parse contents as RAW area - return parseRawArea(dataIndex); + return U_SUCCESS; } USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree) diff --git a/common/types.cpp b/common/types.cpp index d4fcc8d..4298337 100755 --- a/common/types.cpp +++ b/common/types.cpp @@ -42,44 +42,44 @@ UString regionTypeToUString(const UINT8 type) UString itemTypeToUString(const UINT8 type) { switch (type) { - case Types::Root: return UString("Root"); - case Types::Image: return UString("Image"); - case Types::Capsule: return UString("Capsule"); - case Types::Region: return UString("Region"); - case Types::Volume: return UString("Volume"); - case Types::Padding: return UString("Padding"); - case Types::File: return UString("File"); - case Types::Section: return UString("Section"); - case Types::FreeSpace: return UString("Free space"); - case Types::VssStore: return UString("VSS store"); - case Types::Vss2Store: return UString("VSS2 store"); - case Types::FtwStore: return UString("FTW store"); - case Types::FdcStore: return UString("FDC store"); - case Types::FsysStore: return UString("Fsys store"); - case Types::EvsaStore: return UString("EVSA store"); - case Types::CmdbStore: return UString("CMDB store"); - case Types::FlashMapStore: return UString("FlashMap store"); - case Types::NvarEntry: return UString("NVAR entry"); - case Types::VssEntry: return UString("VSS entry"); - case Types::FsysEntry: return UString("Fsys entry"); - case Types::EvsaEntry: return UString("EVSA entry"); - case Types::FlashMapEntry: return UString("FlashMap entry"); - case Types::Microcode: return UString("Microcode"); - case Types::SlicData: return UString("SLIC data"); - // ME-specific - case Types::FptStore: return UString("FPT store"); - case Types::FptEntry: return UString("FPT entry"); - case Types::IfwiHeader: return UString("IFWI header"); - case Types::IfwiPartition: return UString("IFWI partition"); - case Types::FptPartition: return UString("FPT partition"); - case Types::BpdtStore: return UString("BPDT store"); - case Types::BpdtEntry: return UString("BPDT entry"); - case Types::BpdtPartition: return UString("BPDT partition"); - case Types::CpdStore: return UString("CPD store"); - case Types::CpdEntry: return UString("CPD entry"); - case Types::CpdPartition: return UString("CPD partition"); - case Types::CpdExtension: return UString("CPD extension"); - case Types::CpdSpiEntry: return UString("CPD SPI entry"); + case Types::Root: return UString("Root"); + case Types::Image: return UString("Image"); + case Types::Capsule: return UString("Capsule"); + case Types::Region: return UString("Region"); + case Types::Volume: return UString("Volume"); + case Types::Padding: return UString("Padding"); + case Types::File: return UString("File"); + case Types::Section: return UString("Section"); + case Types::FreeSpace: return UString("Free space"); + case Types::VssStore: return UString("VSS store"); + case Types::Vss2Store: return UString("VSS2 store"); + case Types::FtwStore: return UString("FTW store"); + case Types::FdcStore: return UString("FDC store"); + case Types::FsysStore: return UString("Fsys store"); + case Types::EvsaStore: return UString("EVSA store"); + case Types::CmdbStore: return UString("CMDB store"); + case Types::FlashMapStore: return UString("FlashMap store"); + case Types::NvarEntry: return UString("NVAR entry"); + case Types::VssEntry: return UString("VSS entry"); + case Types::FsysEntry: return UString("Fsys entry"); + case Types::EvsaEntry: return UString("EVSA entry"); + case Types::FlashMapEntry: return UString("FlashMap entry"); + case Types::Microcode: return UString("Microcode"); + case Types::SlicData: return UString("SLIC data"); + case Types::FptStore: return UString("FPT store"); + case Types::FptEntry: return UString("FPT entry"); + case Types::IfwiHeader: return UString("IFWI header"); + case Types::IfwiPartition: return UString("IFWI partition"); + case Types::FptPartition: return UString("FPT partition"); + case Types::BpdtStore: return UString("BPDT store"); + case Types::BpdtEntry: return UString("BPDT entry"); + case Types::BpdtPartition: return UString("BPDT partition"); + case Types::CpdStore: return UString("CPD store"); + case Types::CpdEntry: return UString("CPD entry"); + case Types::CpdPartition: return UString("CPD partition"); + case Types::CpdExtension: return UString("CPD extension"); + case Types::CpdSpiEntry: return UString("CPD SPI entry"); + case Types::StartupApDataEntry: return UString("Startup AP data"); } return usprintf("Unknown %02Xh", type); @@ -89,82 +89,83 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype) { switch (type) { case Types::Image: - if (subtype == Subtypes::IntelImage) return UString("Intel"); - if (subtype == Subtypes::UefiImage) return UString("UEFI"); + if (subtype == Subtypes::IntelImage) return UString("Intel"); + else if (subtype == Subtypes::UefiImage) return UString("UEFI"); break; case Types::Padding: - if (subtype == Subtypes::ZeroPadding) return UString("Empty (0x00)"); - if (subtype == Subtypes::OnePadding) return UString("Empty (0xFF)"); - if (subtype == Subtypes::DataPadding) return UString("Non-empty"); + if (subtype == Subtypes::ZeroPadding) return UString("Empty (0x00)"); + else if (subtype == Subtypes::OnePadding) return UString("Empty (0xFF)"); + else if (subtype == Subtypes::DataPadding) return UString("Non-empty"); break; case Types::Volume: - if (subtype == Subtypes::UnknownVolume) return UString("Unknown"); - if (subtype == Subtypes::Ffs2Volume) return UString("FFSv2"); - if (subtype == Subtypes::Ffs3Volume) return UString("FFSv3"); - if (subtype == Subtypes::NvramVolume) return UString("NVRAM"); - if (subtype == Subtypes::MicrocodeVolume) return UString("Microcode"); + if (subtype == Subtypes::UnknownVolume) return UString("Unknown"); + else if (subtype == Subtypes::Ffs2Volume) return UString("FFSv2"); + else if (subtype == Subtypes::Ffs3Volume) return UString("FFSv3"); + else if (subtype == Subtypes::NvramVolume) return UString("NVRAM"); + else if (subtype == Subtypes::MicrocodeVolume) return UString("Microcode"); break; case Types::Capsule: - if (subtype == Subtypes::AptioSignedCapsule) return UString("Aptio signed"); - if (subtype == Subtypes::AptioUnsignedCapsule) return UString("Aptio unsigned"); - if (subtype == Subtypes::UefiCapsule) return UString("UEFI 2.0"); - if (subtype == Subtypes::ToshibaCapsule) return UString("Toshiba"); + if (subtype == Subtypes::AptioSignedCapsule) return UString("Aptio signed"); + else if (subtype == Subtypes::AptioUnsignedCapsule) return UString("Aptio unsigned"); + else if (subtype == Subtypes::UefiCapsule) return UString("UEFI 2.0"); + else if (subtype == Subtypes::ToshibaCapsule) return UString("Toshiba"); break; - case Types::Region: return regionTypeToUString(subtype); - case Types::File: return fileTypeToUString(subtype); - case Types::Section: return sectionTypeToUString(subtype); + case Types::Region: return regionTypeToUString(subtype); + case Types::File: return fileTypeToUString(subtype); + case Types::Section: return sectionTypeToUString(subtype); case Types::NvarEntry: - if (subtype == Subtypes::InvalidNvarEntry) return UString("Invalid"); - if (subtype == Subtypes::InvalidLinkNvarEntry) return UString("Invalid link"); - if (subtype == Subtypes::LinkNvarEntry) return UString("Link"); - if (subtype == Subtypes::DataNvarEntry) return UString("Data"); - if (subtype == Subtypes::FullNvarEntry) return UString("Full"); + if (subtype == Subtypes::InvalidNvarEntry) return UString("Invalid"); + else if (subtype == Subtypes::InvalidLinkNvarEntry) return UString("Invalid link"); + else if (subtype == Subtypes::LinkNvarEntry) return UString("Link"); + else if (subtype == Subtypes::DataNvarEntry) return UString("Data"); + else if (subtype == Subtypes::FullNvarEntry) return UString("Full"); break; case Types::VssEntry: - if (subtype == Subtypes::InvalidVssEntry) return UString("Invalid"); - if (subtype == Subtypes::StandardVssEntry) return UString("Standard"); - if (subtype == Subtypes::AppleVssEntry) return UString("Apple"); - if (subtype == Subtypes::AuthVssEntry) return UString("Auth"); - if (subtype == Subtypes::IntelVssEntry) return UString("Intel"); + if (subtype == Subtypes::InvalidVssEntry) return UString("Invalid"); + else if (subtype == Subtypes::StandardVssEntry) return UString("Standard"); + else if (subtype == Subtypes::AppleVssEntry) return UString("Apple"); + else if (subtype == Subtypes::AuthVssEntry) return UString("Auth"); + else if (subtype == Subtypes::IntelVssEntry) return UString("Intel"); break; case Types::FsysEntry: - if (subtype == Subtypes::InvalidFsysEntry) return UString("Invalid"); - if (subtype == Subtypes::NormalFsysEntry) return UString("Normal"); + if (subtype == Subtypes::InvalidFsysEntry) return UString("Invalid"); + else if (subtype == Subtypes::NormalFsysEntry) return UString("Normal"); break; case Types::EvsaEntry: - if (subtype == Subtypes::InvalidEvsaEntry) return UString("Invalid"); - if (subtype == Subtypes::UnknownEvsaEntry) return UString("Unknown"); - if (subtype == Subtypes::GuidEvsaEntry) return UString("GUID"); - if (subtype == Subtypes::NameEvsaEntry) return UString("Name"); - if (subtype == Subtypes::DataEvsaEntry) return UString("Data"); + if (subtype == Subtypes::InvalidEvsaEntry) return UString("Invalid"); + else if (subtype == Subtypes::UnknownEvsaEntry) return UString("Unknown"); + else if (subtype == Subtypes::GuidEvsaEntry) return UString("GUID"); + else if (subtype == Subtypes::NameEvsaEntry) return UString("Name"); + else if (subtype == Subtypes::DataEvsaEntry) return UString("Data"); break; case Types::FlashMapEntry: - if (subtype == Subtypes::VolumeFlashMapEntry) return UString("Volume"); - if (subtype == Subtypes::DataFlashMapEntry) return UString("Data"); + if (subtype == Subtypes::VolumeFlashMapEntry) return UString("Volume"); + else if (subtype == Subtypes::DataFlashMapEntry) return UString("Data"); break; case Types::Microcode: - if (subtype == Subtypes::IntelMicrocode) return UString("Intel"); - if (subtype == Subtypes::AmdMicrocode) return UString("AMD"); + if (subtype == Subtypes::IntelMicrocode) return UString("Intel"); + else if (subtype == Subtypes::AmdMicrocode) return UString("AMD"); break; - // ME-specific case Types::FptEntry: - if (subtype == Subtypes::ValidFptEntry) return UString("Valid"); - if (subtype == Subtypes::InvalidFptEntry) return UString("Invalid"); + if (subtype == Subtypes::ValidFptEntry) return UString("Valid"); + else if (subtype == Subtypes::InvalidFptEntry) return UString("Invalid"); break; case Types::FptPartition: - if (subtype == Subtypes::CodeFptPartition) return UString("Code"); - if (subtype == Subtypes::DataFptPartition) return UString("Data"); - if (subtype == Subtypes::GlutFptPartition) return UString("GLUT"); + if (subtype == Subtypes::CodeFptPartition) return UString("Code"); + else if (subtype == Subtypes::DataFptPartition) return UString("Data"); + else if (subtype == Subtypes::GlutFptPartition) return UString("GLUT"); break; case Types::IfwiPartition: - if (subtype == Subtypes::BootIfwiPartition) return UString("Boot"); - if (subtype == Subtypes::DataIfwiPartition) return UString("Data"); + if (subtype == Subtypes::BootIfwiPartition) return UString("Boot"); + else if (subtype == Subtypes::DataIfwiPartition) return UString("Data"); break; case Types::CpdPartition: - if (subtype == Subtypes::ManifestCpdPartition) return UString("Manifest"); - if (subtype == Subtypes::MetadataCpdPartition) return UString("Metadata"); - if (subtype == Subtypes::KeyCpdPartition) return UString("Key"); - if (subtype == Subtypes::CodeCpdPartition) return UString("Code"); + if (subtype == Subtypes::ManifestCpdPartition) return UString("Manifest"); + else if (subtype == Subtypes::MetadataCpdPartition) return UString("Metadata"); + else if (subtype == Subtypes::KeyCpdPartition) return UString("Key"); + else if (subtype == Subtypes::CodeCpdPartition) return UString("Code"); + case Types::StartupApDataEntry: + if (subtype == Subtypes::x86128kStartupApDataEntry) return UString("X86 128K"); break; } diff --git a/common/types.h b/common/types.h index bff89da..62c8929 100755 --- a/common/types.h +++ b/common/types.h @@ -27,7 +27,7 @@ namespace Actions Replace, Remove, Rebuild, - Rebase + Rebase, }; } @@ -58,7 +58,6 @@ namespace Types { FlashMapEntry, Microcode, SlicData, - // ME-specific IfwiHeader, IfwiPartition, FptStore, @@ -71,21 +70,22 @@ namespace Types { CpdEntry, CpdPartition, CpdExtension, - CpdSpiEntry + CpdSpiEntry, + StartupApDataEntry, }; } namespace Subtypes { enum ImageSubtypes{ IntelImage = 90, - UefiImage + UefiImage, }; enum CapsuleSubtypes { AptioSignedCapsule = 100, AptioUnsignedCapsule, UefiCapsule, - ToshibaCapsule + ToshibaCapsule, }; enum VolumeSubtypes { @@ -93,7 +93,7 @@ namespace Subtypes { Ffs2Volume, Ffs3Volume, NvramVolume, - MicrocodeVolume + MicrocodeVolume, }; enum RegionSubtypes { @@ -112,13 +112,13 @@ namespace Subtypes { Tgbe2Region, Reserved1Region, Reserved2Region, - PttRegion + PttRegion, }; enum PaddingSubtypes { ZeroPadding = 120, OnePadding, - DataPadding + DataPadding, }; enum NvarEntrySubtypes { @@ -126,7 +126,7 @@ namespace Subtypes { InvalidLinkNvarEntry, LinkNvarEntry, DataNvarEntry, - FullNvarEntry + FullNvarEntry, }; enum VssEntrySubtypes { @@ -134,12 +134,12 @@ namespace Subtypes { StandardVssEntry, AppleVssEntry, AuthVssEntry, - IntelVssEntry + IntelVssEntry, }; enum FsysEntrySubtypes { InvalidFsysEntry = 150, - NormalFsysEntry + NormalFsysEntry, }; enum EvsaEntrySubtypes { @@ -152,41 +152,45 @@ namespace Subtypes { enum FlashMapEntrySubtypes { VolumeFlashMapEntry = 170, - DataFlashMapEntry + DataFlashMapEntry, }; enum MicrocodeSubtypes { IntelMicrocode = 180, - AmdMicrocode + AmdMicrocode, }; enum SlicDataSubtypes { PubkeySlicData = 190, - MarkerSlicData + MarkerSlicData, }; // ME-specific enum IfwiPartitionSubtypes { DataIfwiPartition = 200, - BootIfwiPartition + BootIfwiPartition, }; enum FptEntrySubtypes { ValidFptEntry = 210, - InvalidFptEntry + InvalidFptEntry, }; enum FptPartitionSubtypes { CodeFptPartition = 220, DataFptPartition, - GlutFptPartition + GlutFptPartition, }; enum CpdPartitionSubtypes { ManifestCpdPartition = 230, MetadataCpdPartition, KeyCpdPartition, - CodeCpdPartition + CodeCpdPartition, + }; + + enum StartupApDataEntrySubtypes { + x86128kStartupApDataEntry = 240, }; } diff --git a/common/utility.cpp b/common/utility.cpp index f487e6c..6124d66 100755 --- a/common/utility.cpp +++ b/common/utility.cpp @@ -67,7 +67,7 @@ UString uniqueItemName(const UModelIndex & index) { // Sanity check if (!index.isValid()) - return UString("Invalid_index"); + return UString("InvalidIndex"); // Get model from index const TreeModel* model = (const TreeModel*)index.model();