mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-24 17:08:23 +08:00
Display microcode in the tree
This commit is contained in:
parent
717821de2b
commit
2d02eeab6d
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
#################
|
||||
moc_*.*
|
||||
ui_*.*
|
||||
qrc_*.*
|
||||
|
||||
#################
|
||||
## Qt Creator
|
||||
@ -234,6 +235,8 @@ Makefile
|
||||
|
||||
uefitool_plugin_import.cpp
|
||||
UEFITool.app/
|
||||
UEFITool/Info.plist
|
||||
UEFITool/XCBuildData
|
||||
UEFIDump/UEFIDump
|
||||
UEFIExtract/UEFIExtract
|
||||
UEFIFind/UEFIFind
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ffsdumper.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2018, LongSoft. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* uefidump.h
|
||||
|
||||
Copyright (c) 2016, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2018, LongSoft. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
0
UEFITool/ffsfinder.cpp
Normal file → Executable file
0
UEFITool/ffsfinder.cpp
Normal file → Executable file
0
UEFITool/ffsfinder.h
Normal file → Executable file
0
UEFITool/ffsfinder.h
Normal file → Executable file
@ -112,7 +112,7 @@ int QHexEdit::addressWidth()
|
||||
if (size > Q_INT64_C(0x100000000)){ n += 8; size /= Q_INT64_C(0x100000000);}
|
||||
if (size > 0x10000){ n += 4; size /= 0x10000;}
|
||||
if (size > 0x100){ n += 2; size /= 0x100;}
|
||||
if (size > 0x10){ n += 1; size /= 0x10;}
|
||||
if (size > 0x10){ n += 1; }
|
||||
|
||||
if (n > _addressWidth)
|
||||
return n;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -114,7 +114,6 @@ void UEFITool::init()
|
||||
ui->infoEdit->clear();
|
||||
ui->bootGuardEdit->clear();
|
||||
ui->txtEdit->clear();
|
||||
ui->microcodeEdit->clear();
|
||||
ui->messagesTabWidget->setTabEnabled(1, false);
|
||||
ui->messagesTabWidget->setTabEnabled(2, false);
|
||||
ui->messagesTabWidget->setTabEnabled(3, false);
|
||||
@ -201,7 +200,8 @@ void UEFITool::populateUi(const UModelIndex ¤t)
|
||||
ui->menuVolumeActions->setEnabled(type == Types::Volume);
|
||||
ui->menuFileActions->setEnabled(type == Types::File);
|
||||
ui->menuSectionActions->setEnabled(type == Types::Section);
|
||||
ui->menuEntryActions->setEnabled(type == Types::NvarEntry
|
||||
ui->menuEntryActions->setEnabled(type == Types::Microcode
|
||||
|| type == Types::NvarEntry
|
||||
|| type == Types::VssEntry
|
||||
|| type == Types::FsysEntry
|
||||
|| type == Types::EvsaEntry
|
||||
@ -214,8 +214,8 @@ void UEFITool::populateUi(const UModelIndex ¤t)
|
||||
|| type == Types::FtwStore
|
||||
|| type == Types::FlashMapStore
|
||||
|| type == Types::CmdbStore
|
||||
|| type == Types::Microcode
|
||||
|| type == Types::SlicData);
|
||||
|| type == Types::SlicData
|
||||
);
|
||||
|
||||
// Enable actions
|
||||
ui->actionHexView->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
|
||||
@ -700,18 +700,6 @@ void UEFITool::extract(const UINT8 mode, UString* pathOut)
|
||||
|| subtype == EFI_SECTION_PIC) path = QFileDialog::getSaveFileName(this, tr("Save section body to EFI executable file"), name + ".efi", tr("EFI executable files (*.efi *.bin);;All files (*)"));
|
||||
else path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)"));
|
||||
break;
|
||||
case Types::NvarEntry:
|
||||
case Types::VssEntry:
|
||||
case Types::EvsaEntry:
|
||||
case Types::FlashMapEntry:
|
||||
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:
|
||||
case Types::FtwStore:
|
||||
case Types::FdcStore:
|
||||
case Types::FsysStore:
|
||||
case Types::FlashMapStore:
|
||||
case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save store body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); break;
|
||||
case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode body to file"), name + ".ucb", tr("Microcode body files (*.ucb *.bin);;All files (*)")); break;
|
||||
case Types::SlicData:
|
||||
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 (*)"));
|
||||
@ -1151,11 +1139,6 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||
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::NvarEntry:
|
||||
case Types::VssEntry:
|
||||
case Types::FsysEntry:
|
||||
case Types::EvsaEntry:
|
||||
case Types::FlashMapEntry: ui->menuEntryActions->exec(event->globalPos()); break;
|
||||
case Types::VssStore:
|
||||
case Types::Vss2Store:
|
||||
case Types::FdcStore:
|
||||
@ -1163,9 +1146,8 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||
case Types::EvsaStore:
|
||||
case Types::FtwStore:
|
||||
case Types::FlashMapStore:
|
||||
case Types::CmdbStore:
|
||||
case Types::Microcode:
|
||||
case Types::SlicData: ui->menuStoreActions->exec(event->globalPos()); break;
|
||||
case Types::CmdbStore: ui->menuStoreActions->exec(event->globalPos()); break;
|
||||
default: ui->menuEntryActions->exec(event->globalPos()); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1213,7 +1195,6 @@ void UEFITool::readSettings()
|
||||
ui->fitTableWidget->setFont(currentFont);
|
||||
ui->bootGuardEdit->setFont(currentFont);
|
||||
ui->txtEdit->setFont(currentFont);
|
||||
ui->microcodeEdit->setFont(currentFont);
|
||||
ui->structureTreeView->setFont(currentFont);
|
||||
searchDialog->ui->guidEdit->setFont(currentFont);
|
||||
searchDialog->ui->hexEdit->setFont(currentFont);
|
||||
@ -1287,14 +1268,6 @@ void UEFITool::showFitTable()
|
||||
ui->messagesTabWidget->setCurrentIndex(2);
|
||||
}
|
||||
|
||||
// Get Microcode info
|
||||
UString microcodeInfo = ffsParser->getMicrocodeInfo();
|
||||
if (!microcodeInfo.isEmpty()) {
|
||||
ui->messagesTabWidget->setTabEnabled(4, true);
|
||||
ui->microcodeEdit->setPlainText(microcodeInfo);
|
||||
ui->messagesTabWidget->setCurrentIndex(4);
|
||||
}
|
||||
|
||||
// Get TXT ACM info
|
||||
UString txtInfo = ffsParser->getTxtInfo();
|
||||
if (!txtInfo.isEmpty()) {
|
||||
|
@ -279,44 +279,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="microcodeTab">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Microcode</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="microcodeEdit">
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="undoRedoEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="finderTab">
|
||||
<attribute name="title">
|
||||
<string>Search</string>
|
||||
|
@ -17,8 +17,8 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
const UByteArray FFSv2VolumesInt[] = {
|
||||
EFI_FIRMWARE_FILE_SYSTEM_GUID,
|
||||
EFI_FIRMWARE_FILE_SYSTEM2_GUID,
|
||||
EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID,
|
||||
EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID,
|
||||
EFI_APPLE_AUTHENTICATION_FV_GUID,
|
||||
EFI_APPLE_IMMUTABLE_FV_GUID,
|
||||
EFI_INTEL_FILE_SYSTEM_GUID,
|
||||
EFI_INTEL_FILE_SYSTEM2_GUID,
|
||||
EFI_SONY_FILE_SYSTEM_GUID
|
||||
|
49
common/ffs.h
49
common/ffs.h
@ -114,38 +114,43 @@ typedef struct EFI_FIRMWARE_VOLUME_HEADER_ {
|
||||
} EFI_FIRMWARE_VOLUME_HEADER;
|
||||
|
||||
// Standard file system GUIDs
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID // 7A9354D9-0468-444A-81CE-0BF617D890DF
|
||||
("\xD9\x54\x93\x7A\x68\x04\x4A\x44\x81\xCE\x0B\xF6\x17\xD8\x90\xDF", 16);
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID
|
||||
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID // 8C8CE578-8A3D-4F1C-9935-896185C32DD3
|
||||
("\x78\xE5\x8C\x8C\x3D\x8A\x1C\x4F\x99\x35\x89\x61\x85\xC3\x2D\xD3", 16);
|
||||
// Vendor-specific file system GUIDs
|
||||
const UByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID
|
||||
("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16);
|
||||
const UByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID
|
||||
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
|
||||
|
||||
// AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 // Intel 1
|
||||
const UByteArray EFI_INTEL_FILE_SYSTEM_GUID
|
||||
("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
|
||||
// D6A1CD70-4B33-4994-A6EA-375F2CCC5437 // Intel 2
|
||||
const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID
|
||||
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
|
||||
// 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1
|
||||
const UByteArray EFI_SONY_FILE_SYSTEM_GUID
|
||||
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
|
||||
|
||||
|
||||
// Vector of volume GUIDs with FFSv2-compatible files
|
||||
extern const std::vector<UByteArray> FFSv2Volumes;
|
||||
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A
|
||||
("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16);
|
||||
|
||||
// Vendor-specific file system GUIDs
|
||||
const UByteArray EFI_APPLE_IMMUTABLE_FV_GUID // 04ADEEAD-61FF-4D31-B6BA-64F8BF901F5A
|
||||
("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16);
|
||||
|
||||
const UByteArray EFI_APPLE_AUTHENTICATION_FV_GUID // BD001B8C-6A71-487B-A14F-0C2A2DCF7A5D
|
||||
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
|
||||
|
||||
const UByteArray EFI_APPLE_MICROCODE_VOLUME_GUID // 153D2197-29BD-44DC-AC59-887F70E41A6B
|
||||
("\x97\x21\x3D\x15\xBD\x29\xDC\x44\xAC\x59\x88\x7F\x70\xE4\x1A\x6B", 16);
|
||||
#define EFI_APPLE_MICROCODE_VOLUME_HEADER_SIZE 0x100
|
||||
|
||||
const UByteArray EFI_INTEL_FILE_SYSTEM_GUID // AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0
|
||||
("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
|
||||
|
||||
const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID // D6A1CD70-4B33-4994-A6EA-375F2CCC5437
|
||||
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
|
||||
|
||||
const UByteArray EFI_SONY_FILE_SYSTEM_GUID // 4F494156-AED6-4D64-A537-B8A5557BCEEC
|
||||
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
|
||||
|
||||
// Vector of volume GUIDs with FFSv2-compatible files
|
||||
extern const std::vector<UByteArray> FFSv2Volumes;
|
||||
|
||||
// Vector of volume GUIDs with FFSv3-compatible files
|
||||
extern const std::vector<UByteArray> FFSv3Volumes;
|
||||
|
||||
// Firmware volume signature
|
||||
const UByteArray EFI_FV_SIGNATURE("_FVH", 4);
|
||||
#define EFI_FV_SIGNATURE 0x4856465F // _FVH
|
||||
#define EFI_FV_SIGNATURE_OFFSET 0x28
|
||||
|
||||
// Firmware volume attributes
|
||||
|
@ -109,8 +109,10 @@ USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & ind
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
USTATUS result;
|
||||
|
||||
// Try parsing as UEFI Capsule
|
||||
USTATUS result = parseCapsule(buffer, index);
|
||||
result = parseCapsule(buffer, 0, UModelIndex(), index);;
|
||||
if (result != U_ITEM_NOT_FOUND) {
|
||||
return result;
|
||||
}
|
||||
@ -122,6 +124,7 @@ USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & ind
|
||||
}
|
||||
|
||||
// Parse as generic image
|
||||
imageBase = 0;
|
||||
return parseGenericImage(buffer, 0, UModelIndex(), index);
|
||||
}
|
||||
|
||||
@ -138,7 +141,7 @@ USTATUS FfsParser::parseGenericImage(const UByteArray & buffer, const UINT32 loc
|
||||
return parseRawArea(index);
|
||||
}
|
||||
|
||||
USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
|
||||
USTATUS FfsParser::parseCapsule(const UByteArray & capsule, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
||||
{
|
||||
// Check buffer size to be more than or equal to size of EFI_CAPSULE_HEADER
|
||||
if ((UINT32)capsule.size() < sizeof(EFI_CAPSULE_HEADER)) {
|
||||
@ -181,7 +184,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
|
||||
capsuleHeader->Flags);
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(0, Types::Capsule, Subtypes::UefiCapsule, name, UString(), info, header, body, UByteArray(), Fixed);
|
||||
index = model->addItem(model->offset(parent) + localOffset, Types::Capsule, Subtypes::UefiCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
||||
}
|
||||
// Check buffer for being Toshiba capsule header
|
||||
else if (capsule.startsWith(TOSHIBA_CAPSULE_GUID)) {
|
||||
@ -213,7 +216,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
|
||||
capsuleHeader->Flags);
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(0, Types::Capsule, Subtypes::ToshibaCapsule, name, UString(), info, header, body, UByteArray(), Fixed);
|
||||
index = model->addItem(model->offset(parent) + localOffset, Types::Capsule, Subtypes::ToshibaCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
||||
}
|
||||
// Check buffer for being extended Aptio capsule header
|
||||
else if (capsule.startsWith(APTIO_SIGNED_CAPSULE_GUID)
|
||||
@ -255,7 +258,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
|
||||
capsuleHeader->CapsuleHeader.Flags);
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(0, Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, UString(), info, header, body, UByteArray(), Fixed);
|
||||
index = model->addItem(model->offset(parent) + localOffset, Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
||||
|
||||
// Show message about possible Aptio signature break
|
||||
if (signedCapsule) {
|
||||
@ -265,9 +268,6 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
|
||||
|
||||
// Capsule present
|
||||
if (capsuleHeaderSize > 0) {
|
||||
// Set imageBase for proper alignment calculation
|
||||
imageBase = capsuleHeaderSize;
|
||||
|
||||
UByteArray image = capsule.mid(capsuleHeaderSize);
|
||||
UModelIndex imageIndex;
|
||||
|
||||
@ -574,6 +574,9 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
|
||||
// Add descriptor tree item
|
||||
UModelIndex regionIndex = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::DescriptorRegion, name, UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
|
||||
|
||||
// Set image base
|
||||
imageBase = model->offset(parent) + localOffset;
|
||||
|
||||
// Parse regions
|
||||
USTATUS result = U_SUCCESS;
|
||||
USTATUS parseResult = U_SUCCESS;
|
||||
@ -697,10 +700,10 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset
|
||||
if (versionFound) {
|
||||
const ME_VERSION* version = (const ME_VERSION*)(me.constData() + versionOffset);
|
||||
info += usprintf("\nVersion: %u.%u.%u.%u",
|
||||
version->major,
|
||||
version->minor,
|
||||
version->bugfix,
|
||||
version->build);
|
||||
version->Major,
|
||||
version->Minor,
|
||||
version->Bugfix,
|
||||
version->Build);
|
||||
}
|
||||
}
|
||||
|
||||
@ -780,30 +783,32 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
|
||||
if (!index.isValid())
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// Get parsing data
|
||||
// Get item data
|
||||
UByteArray data = model->body(index);
|
||||
UINT32 headerSize = model->header(index).size();
|
||||
UINT32 offset = model->offset(index) + headerSize;
|
||||
|
||||
// Get item data
|
||||
UByteArray data = model->body(index);
|
||||
|
||||
// Search for first volume
|
||||
USTATUS result;
|
||||
UINT32 prevVolumeOffset;
|
||||
UString name;
|
||||
UString info;
|
||||
|
||||
result = findNextVolume(index, data, offset, 0, prevVolumeOffset);
|
||||
// Search for the first item
|
||||
UINT8 prevItemType;
|
||||
UINT32 prevItemOffset;
|
||||
UINT32 prevItemSize;
|
||||
UINT32 prevItemAltSize;
|
||||
|
||||
result = findNextRawAreaItem(index, 0, prevItemType, prevItemOffset, prevItemSize, prevItemAltSize);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (bgFirstVolumeOffset == 0x100000000ULL)
|
||||
bgFirstVolumeOffset = model->offset(index) + prevVolumeOffset;
|
||||
bgFirstVolumeOffset = model->offset(index) + prevItemOffset;
|
||||
|
||||
// First volume is not at the beginning of RAW area
|
||||
UString name;
|
||||
UString info;
|
||||
if (prevVolumeOffset > 0) {
|
||||
// First item is not at the beginning of this raw area
|
||||
if (prevItemOffset > 0) {
|
||||
// Get info
|
||||
UByteArray padding = data.left(prevVolumeOffset);
|
||||
UByteArray padding = data.left(prevItemOffset);
|
||||
name = UString("Padding");
|
||||
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
|
||||
|
||||
@ -811,16 +816,17 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
|
||||
model->addItem(offset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
|
||||
}
|
||||
|
||||
// Search for and parse all volumes
|
||||
UINT32 volumeOffset = prevVolumeOffset;
|
||||
UINT32 prevVolumeSize = 0;
|
||||
// Search for and parse all items
|
||||
UINT8 itemType = prevItemType;
|
||||
UINT32 itemOffset = prevItemOffset;
|
||||
UINT32 itemSize = prevItemSize;
|
||||
UINT32 itemAltSize = prevItemAltSize;
|
||||
|
||||
while (!result)
|
||||
{
|
||||
// Padding between volumes
|
||||
if (volumeOffset > prevVolumeOffset + prevVolumeSize) {
|
||||
UINT32 paddingOffset = prevVolumeOffset + prevVolumeSize;
|
||||
UINT32 paddingSize = volumeOffset - paddingOffset;
|
||||
while (!result) {
|
||||
// Padding between items
|
||||
if (itemOffset > prevItemOffset + prevItemSize) {
|
||||
UINT32 paddingOffset = prevItemOffset + prevItemSize;
|
||||
UINT32 paddingSize = itemOffset - paddingOffset;
|
||||
UByteArray padding = data.mid(paddingOffset, paddingSize);
|
||||
|
||||
// Get info
|
||||
@ -831,65 +837,73 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
|
||||
model->addItem(offset + paddingOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
|
||||
}
|
||||
|
||||
// Get volume size
|
||||
UINT32 volumeSize = 0;
|
||||
UINT32 bmVolumeSize = 0;
|
||||
result = getVolumeSize(data, volumeOffset, volumeSize, bmVolumeSize);
|
||||
if (result) {
|
||||
msg(usprintf("%s: getVolumeSize failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check that volume is fully present in input
|
||||
if (volumeSize > (UINT32)data.size() || volumeOffset + volumeSize > (UINT32)data.size()) {
|
||||
// Mark the rest as padding and finish the parsing
|
||||
UByteArray padding = data.mid(volumeOffset);
|
||||
// Check that item is fully present in input
|
||||
if (itemSize > (UINT32)data.size() || itemOffset + itemSize > (UINT32)data.size()) {
|
||||
// Mark the rest as padding and finish parsing
|
||||
UByteArray padding = data.mid(itemOffset);
|
||||
|
||||
// Get info
|
||||
name = UString("Padding");
|
||||
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
|
||||
|
||||
// Add tree item
|
||||
UModelIndex paddingIndex = model->addItem(offset + volumeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
|
||||
UModelIndex paddingIndex = model->addItem(offset + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
|
||||
msg(usprintf("%s: one of volumes inside overlaps the end of data", __FUNCTION__), paddingIndex);
|
||||
|
||||
// Update variables
|
||||
prevVolumeOffset = volumeOffset;
|
||||
prevVolumeSize = padding.size();
|
||||
prevItemOffset = itemOffset;
|
||||
prevItemSize = padding.size();
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse current volume's header
|
||||
if (itemType == Types::Volume) {
|
||||
UModelIndex volumeIndex;
|
||||
UByteArray volume = data.mid(volumeOffset, volumeSize);
|
||||
result = parseVolumeHeader(volume, headerSize + volumeOffset, index, volumeIndex);
|
||||
UByteArray volume = data.mid(itemOffset, itemSize);
|
||||
result = parseVolumeHeader(volume, headerSize + itemOffset, index, volumeIndex);
|
||||
if (result) {
|
||||
msg(usprintf("%s: volume header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
||||
} else {
|
||||
// Show messages
|
||||
if (volumeSize != bmVolumeSize)
|
||||
if (itemSize != itemAltSize)
|
||||
msg(usprintf("%s: volume size stored in header %Xh differs from calculated using block map %Xh", __FUNCTION__,
|
||||
volumeSize, bmVolumeSize),
|
||||
itemSize, itemAltSize),
|
||||
volumeIndex);
|
||||
}
|
||||
|
||||
// Go to next volume
|
||||
prevVolumeOffset = volumeOffset;
|
||||
prevVolumeSize = volumeSize;
|
||||
result = findNextVolume(index, data, offset, volumeOffset + prevVolumeSize, volumeOffset);
|
||||
}
|
||||
else if (itemType == Types::Microcode) {
|
||||
UModelIndex microcodeIndex;
|
||||
UByteArray microcode = data.mid(itemOffset, itemSize);
|
||||
result = parseIntelMicrocodeHeader(microcode, headerSize + itemOffset, index, microcodeIndex);
|
||||
if (result) {
|
||||
msg(usprintf("%s: microcode header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return U_UNKNOWN_ITEM_TYPE;
|
||||
}
|
||||
|
||||
// Go to next item
|
||||
prevItemOffset = itemOffset;
|
||||
prevItemSize = itemSize;
|
||||
prevItemType = itemType;
|
||||
result = findNextRawAreaItem(index, itemOffset + prevItemSize, itemType, itemOffset, itemSize, itemAltSize);
|
||||
}
|
||||
|
||||
// Fixes clang analyzer warning
|
||||
(void)prevItemType;
|
||||
|
||||
// Padding at the end of RAW area
|
||||
volumeOffset = prevVolumeOffset + prevVolumeSize;
|
||||
if ((UINT32)data.size() > volumeOffset) {
|
||||
UByteArray padding = data.mid(volumeOffset);
|
||||
itemOffset = prevItemOffset + prevItemSize;
|
||||
if ((UINT32)data.size() > itemOffset) {
|
||||
UByteArray padding = data.mid(itemOffset);
|
||||
|
||||
// Get info
|
||||
name = UString("Padding");
|
||||
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
|
||||
|
||||
// Add tree item
|
||||
model->addItem(offset + volumeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
|
||||
model->addItem(offset + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
|
||||
}
|
||||
|
||||
// Parse bodies
|
||||
@ -899,6 +913,9 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
|
||||
case Types::Volume:
|
||||
parseVolumeBody(current);
|
||||
break;
|
||||
case Types::Microcode:
|
||||
// Parsing already done
|
||||
break;
|
||||
case Types::Padding:
|
||||
// No parsing required
|
||||
break;
|
||||
@ -947,8 +964,9 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
|
||||
headerSize = volumeHeader->ExtHeaderOffset + extendedHeader->ExtHeaderSize;
|
||||
extendedHeaderGuid = extendedHeader->FvName;
|
||||
}
|
||||
else
|
||||
else {
|
||||
headerSize = volumeHeader->HeaderLength;
|
||||
}
|
||||
|
||||
// Extended header end can be unaligned
|
||||
headerSize = ALIGN8(headerSize);
|
||||
@ -956,6 +974,7 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
|
||||
// Check for volume structure to be known
|
||||
bool isUnknown = true;
|
||||
bool isNvramVolume = false;
|
||||
bool isMicrocodeVolume = false;
|
||||
UINT8 ffsVersion = 0;
|
||||
|
||||
// Check for FFS v2 volume
|
||||
@ -977,6 +996,13 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
|
||||
isNvramVolume = true;
|
||||
}
|
||||
|
||||
// Check for Microcode volume
|
||||
if (guid == EFI_APPLE_MICROCODE_VOLUME_GUID) {
|
||||
isUnknown = false;
|
||||
isMicrocodeVolume = true;
|
||||
headerSize = EFI_APPLE_MICROCODE_VOLUME_HEADER_SIZE;
|
||||
}
|
||||
|
||||
// Check volume revision and alignment
|
||||
bool msgAlignmentBitsSet = false;
|
||||
bool msgUnaligned = false;
|
||||
@ -1071,6 +1097,8 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
|
||||
subtype = Subtypes::Ffs3Volume;
|
||||
else if (isNvramVolume)
|
||||
subtype = Subtypes::NvramVolume;
|
||||
else if (isMicrocodeVolume)
|
||||
subtype = Subtypes::MicrocodeVolume;
|
||||
}
|
||||
index = model->addItem(model->offset(parent) + localOffset, Types::Volume, subtype, name, text, info, header, body, UByteArray(), Fixed, parent, mode);
|
||||
|
||||
@ -1103,67 +1131,82 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 globalOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset)
|
||||
USTATUS FfsParser::findNextRawAreaItem(const UModelIndex & index, const UINT32 localOffset, UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize)
|
||||
{
|
||||
int nextIndex = bios.indexOf(EFI_FV_SIGNATURE, volumeOffset);
|
||||
if (nextIndex < EFI_FV_SIGNATURE_OFFSET)
|
||||
return U_VOLUMES_NOT_FOUND;
|
||||
UByteArray data = model->body(index);
|
||||
UINT32 dataSize = data.size();
|
||||
|
||||
// Check volume header to be sane
|
||||
for (; nextIndex > 0; nextIndex = bios.indexOf(EFI_FV_SIGNATURE, nextIndex + 1)) {
|
||||
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + nextIndex - EFI_FV_SIGNATURE_OFFSET);
|
||||
if (dataSize < sizeof(UINT32))
|
||||
return U_STORES_NOT_FOUND;
|
||||
|
||||
UINT32 offset = localOffset;
|
||||
for (; offset < dataSize - sizeof(UINT32); offset++) {
|
||||
const UINT32* currentPos = (const UINT32*)(data.constData() + offset);
|
||||
const UINT32 restSize = dataSize - offset;
|
||||
UINT32 magic;
|
||||
memcpy(&magic, currentPos, sizeof(UINT32));
|
||||
if (magic == INTEL_MICROCODE_HEADER_VERSION) {// Intel microcode
|
||||
// Check data size
|
||||
if (restSize < sizeof(INTEL_MICROCODE_HEADER))
|
||||
continue;
|
||||
|
||||
// Check microcode size
|
||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos;
|
||||
if (!INTEL_MICROCODE_HEADER_SIZES_VALID(currentPos) || restSize < ucodeHeader->TotalSize) //TODO: needs a separate checking function
|
||||
continue;
|
||||
|
||||
// Check reserved bytes
|
||||
bool reservedBytesValid = true;
|
||||
for (UINT32 i = 0; i < sizeof(ucodeHeader->Reserved); i++)
|
||||
if (ucodeHeader->Reserved[i] != INTEL_MICROCODE_HEADER_RESERVED_BYTE) {
|
||||
reservedBytesValid = false;
|
||||
break;
|
||||
}
|
||||
if (!reservedBytesValid)
|
||||
continue;
|
||||
|
||||
// All checks passed, microcode found
|
||||
nextItemType = Types::Microcode;
|
||||
nextItemSize = ucodeHeader->TotalSize;
|
||||
nextItemAlternativeSize = ucodeHeader->TotalSize;
|
||||
nextItemOffset = offset;
|
||||
break;
|
||||
}
|
||||
else if (magic == EFI_FV_SIGNATURE) {
|
||||
if (offset < EFI_FV_SIGNATURE_OFFSET)
|
||||
continue;
|
||||
offset -= EFI_FV_SIGNATURE_OFFSET;
|
||||
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(data.constData() + offset);
|
||||
if (volumeHeader->FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY) || volumeHeader->FvLength >= 0xFFFFFFFFUL) {
|
||||
msg(usprintf("%s: volume candidate at offset %Xh skipped, has invalid FvLength %" PRIX64 "h", __FUNCTION__,
|
||||
globalOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET),
|
||||
volumeHeader->FvLength), index);
|
||||
continue;
|
||||
}
|
||||
if (volumeHeader->Revision != 1 && volumeHeader->Revision != 2) {
|
||||
msg(usprintf("%s: volume candidate at offset %Xh skipped, has invalid Revision byte value %02Xh", __FUNCTION__,
|
||||
globalOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET),
|
||||
volumeHeader->Revision), index);
|
||||
continue;
|
||||
}
|
||||
// All checks passed, volume found
|
||||
break;
|
||||
}
|
||||
// No more volumes found
|
||||
if (nextIndex < EFI_FV_SIGNATURE_OFFSET)
|
||||
return U_VOLUMES_NOT_FOUND;
|
||||
|
||||
nextVolumeOffset = nextIndex - EFI_FV_SIGNATURE_OFFSET;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize)
|
||||
{
|
||||
// Check that there is space for the volume header and at least two block map entries.
|
||||
if ((UINT32)bios.size() < volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY))
|
||||
return U_INVALID_VOLUME;
|
||||
|
||||
// Populate volume header
|
||||
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + volumeOffset);
|
||||
|
||||
// Check volume signature
|
||||
if (UByteArray((const char*)&volumeHeader->Signature, sizeof(volumeHeader->Signature)) != EFI_FV_SIGNATURE)
|
||||
return U_INVALID_VOLUME;
|
||||
|
||||
// Calculate volume size using BlockMap
|
||||
const EFI_FV_BLOCK_MAP_ENTRY* entry = (const EFI_FV_BLOCK_MAP_ENTRY*)(bios.constData() + volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
|
||||
UINT32 calcVolumeSize = 0;
|
||||
// Calculate alternative volume size using it's BlockMap
|
||||
nextItemAlternativeSize = 0;
|
||||
const EFI_FV_BLOCK_MAP_ENTRY* entry = (const EFI_FV_BLOCK_MAP_ENTRY*)(data.constData() + offset + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
|
||||
while (entry->NumBlocks != 0 && entry->Length != 0) {
|
||||
if ((void*)entry > bios.constData() + bios.size())
|
||||
return U_INVALID_VOLUME;
|
||||
if ((void*)entry >= data.constData() + data.size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
calcVolumeSize += entry->NumBlocks * entry->Length;
|
||||
nextItemAlternativeSize += entry->NumBlocks * entry->Length;
|
||||
entry += 1;
|
||||
}
|
||||
|
||||
volumeSize = (UINT32)volumeHeader->FvLength;
|
||||
bmVolumeSize = calcVolumeSize;
|
||||
// All checks passed, volume found
|
||||
nextItemType = Types::Volume;
|
||||
nextItemSize = volumeHeader->FvLength;
|
||||
nextItemOffset = offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (volumeSize == 0)
|
||||
return U_INVALID_VOLUME;
|
||||
// No more stores found
|
||||
if (offset >= dataSize - sizeof(UINT32))
|
||||
return U_STORES_NOT_FOUND;
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
||||
@ -1199,6 +1242,10 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
|
||||
if (model->subtype(index) == Subtypes::NvramVolume)
|
||||
return nvramParser->parseNvramVolumeBody(index);
|
||||
|
||||
// Parse Microcode volume with a dedicated function
|
||||
if (model->subtype(index) == Subtypes::MicrocodeVolume)
|
||||
return parseMicrocodeVolumeBody(index);
|
||||
|
||||
// Get required values from parsing data
|
||||
UINT8 emptyByte = 0xFF;
|
||||
UINT8 ffsVersion = 2;
|
||||
@ -1732,7 +1779,8 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index)
|
||||
// Rename the file
|
||||
model->setName(index, UString("Non-empty pad-file"));
|
||||
|
||||
return U_SUCCESS;
|
||||
// Parse contents as RAW area
|
||||
return parseRawArea(dataIndex);
|
||||
}
|
||||
|
||||
USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree)
|
||||
@ -3484,7 +3532,7 @@ USTATUS FfsParser::parseFit(const UModelIndex & index)
|
||||
}
|
||||
|
||||
if (currentEntry->Type == FIT_TYPE_TXT_CONF_POLICY)
|
||||
parseTxtConfigurationPolicy(currentEntry, info);
|
||||
parseFitEntryTxtConfigurationPolicy(currentEntry, info);
|
||||
|
||||
// Set item index
|
||||
if (currentEntry->Address > addressDiff && currentEntry->Address < 0xFFFFFFFFUL) { // Only elements in the image need to be parsed
|
||||
@ -3497,21 +3545,21 @@ USTATUS FfsParser::parseFit(const UModelIndex & index)
|
||||
|
||||
switch (currentEntry->Type) {
|
||||
case FIT_TYPE_MICROCODE:
|
||||
status = parseIntelMicrocode(item, localOffset, itemIndex, info, currentEntrySize);
|
||||
status = parseFitEntryMicrocode(item, localOffset, itemIndex, info, currentEntrySize);
|
||||
break;
|
||||
|
||||
case FIT_TYPE_BIOS_AC_MODULE:
|
||||
status = parseIntelAcm(item, localOffset, itemIndex, info, currentEntrySize);
|
||||
status = parseFitEntryAcm(item, localOffset, itemIndex, info, currentEntrySize);
|
||||
acmIndex = itemIndex;
|
||||
break;
|
||||
|
||||
case FIT_TYPE_AC_KEY_MANIFEST:
|
||||
status = parseIntelBootGuardKeyManifest(item, localOffset, itemIndex, info, currentEntrySize);
|
||||
status = parseFitEntryBootGuardKeyManifest(item, localOffset, itemIndex, info, currentEntrySize);
|
||||
kmIndex = itemIndex;
|
||||
break;
|
||||
|
||||
case FIT_TYPE_AC_BOOT_POLICY:
|
||||
status = parseIntelBootGuardBootPolicy(item, localOffset, itemIndex, info, currentEntrySize);
|
||||
status = parseFitEntryBootGuardBootPolicy(item, localOffset, itemIndex, info, currentEntrySize);
|
||||
bpIndex = itemIndex;
|
||||
break;
|
||||
|
||||
@ -3596,7 +3644,7 @@ USTATUS FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & fou
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::parseIntelMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
|
||||
USTATUS FfsParser::parseFitEntryMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
|
||||
{
|
||||
U_UNUSED_PARAMETER(parent);
|
||||
if ((UINT32)microcode.size() < localOffset + sizeof(INTEL_MICROCODE_HEADER)) {
|
||||
@ -3633,33 +3681,10 @@ USTATUS FfsParser::parseIntelMicrocode(const UByteArray & microcode, const UINT3
|
||||
header->DateYear
|
||||
);
|
||||
realSize = mcSize;
|
||||
|
||||
// Add Microcode header info
|
||||
microcodeInfo += usprintf(
|
||||
"Microcode Update Capsule found at offset %Xh\n"
|
||||
"Checksum: %08Xh CPU Flags: %08Xh CPU Signature: %08Xh\n"
|
||||
"Data Size: %08Xh Date: %02X.%02X.%04X Loader Revision: %08Xh\n"
|
||||
"Date: %02X.%02X.%04X ModuleSize: %08Xh EntryPoint: %08Xh\n"
|
||||
"Reserved: %02Xh Revision: %08Xh TotalSize: %08Xh\n"
|
||||
"Version: %08Xh"
|
||||
"\n------------------------------------------------------------------------\n\n",
|
||||
model->offset(parent) + localOffset,
|
||||
header->Checksum,
|
||||
header->CpuFlags,
|
||||
header->CpuSignature,
|
||||
header->DataSize,
|
||||
header->DateDay, header->DateMonth, header->DateYear,
|
||||
header->LoaderRevision,
|
||||
header->Reserved,
|
||||
header->Revision,
|
||||
header->TotalSize,
|
||||
header->Version
|
||||
);
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::parseTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info)
|
||||
USTATUS FfsParser::parseFitEntryTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info)
|
||||
{
|
||||
U_UNUSED_PARAMETER(info);
|
||||
const TXT_CONFIG_POLICY* txtCfg = (const TXT_CONFIG_POLICY*)entry;
|
||||
@ -3694,7 +3719,7 @@ USTATUS FfsParser::parseTxtConfigurationPolicy(const FIT_ENTRY* entry, UString &
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::parseIntelAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
|
||||
USTATUS FfsParser::parseFitEntryAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
|
||||
{
|
||||
if ((UINT32)acm.size() < localOffset + sizeof(INTEL_ACM_HEADER)) {
|
||||
return U_INVALID_ACM;
|
||||
@ -3778,7 +3803,7 @@ USTATUS FfsParser::parseIntelAcm(const UByteArray & acm, const UINT32 localOffse
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::parseIntelBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
|
||||
USTATUS FfsParser::parseFitEntryBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
|
||||
{
|
||||
U_UNUSED_PARAMETER(realSize);
|
||||
if ((UINT32)keyManifest.size() < localOffset + sizeof(BG_KEY_MANIFEST)) {
|
||||
@ -3844,7 +3869,7 @@ USTATUS FfsParser::parseIntelBootGuardKeyManifest(const UByteArray & keyManifest
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::findNextElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize)
|
||||
USTATUS FfsParser::findNextBootGuardBootPolicyElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize)
|
||||
{
|
||||
UINT32 dataSize = bootPolicy.size();
|
||||
if (dataSize < sizeof(UINT64)) {
|
||||
@ -3882,7 +3907,7 @@ USTATUS FfsParser::findNextElement(const UByteArray & bootPolicy, const UINT32 e
|
||||
return U_ELEMENTS_NOT_FOUND;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
|
||||
USTATUS FfsParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
|
||||
{
|
||||
U_UNUSED_PARAMETER(realSize);
|
||||
if ((UINT32)bootPolicy.size() < localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER)) {
|
||||
@ -3923,7 +3948,7 @@ USTATUS FfsParser::parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy,
|
||||
// Iterate over elements to get them all
|
||||
UINT32 elementOffset = 0;
|
||||
UINT32 elementSize = 0;
|
||||
USTATUS status = findNextElement(bootPolicy, localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER), elementOffset, elementSize);
|
||||
USTATUS status = findNextBootGuardBootPolicyElement(bootPolicy, localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER), elementOffset, elementSize);
|
||||
while (status == U_SUCCESS) {
|
||||
const UINT64* currentPos = (const UINT64*)(bootPolicy.constData() + elementOffset);
|
||||
if (*currentPos == BG_BOOT_POLICY_MANIFEST_IBB_ELEMENT_TAG) {
|
||||
@ -4062,13 +4087,119 @@ USTATUS FfsParser::parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy,
|
||||
bootGuardInfo += usprintf("%02X", elementHeader->KeySignature.Signature.Signature[i]);
|
||||
}
|
||||
}
|
||||
status = findNextElement(bootPolicy, elementOffset + elementSize, elementOffset, elementSize);
|
||||
status = findNextBootGuardBootPolicyElement(bootPolicy, elementOffset + elementSize, elementOffset, elementSize);
|
||||
}
|
||||
|
||||
bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n");
|
||||
bgBootPolicyFound = true;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
USTATUS FfsParser::parseMicrocodeVolumeBody(const UModelIndex & index)
|
||||
{
|
||||
const UINT32 headerSize = (UINT32)model->header(index).size();
|
||||
const UINT32 bodySize = (UINT32)model->body(index).size();
|
||||
UINT32 offset = 0;
|
||||
USTATUS result = U_SUCCESS;
|
||||
|
||||
while(true) {
|
||||
// Parse current microcode
|
||||
UModelIndex currentMicrocode;
|
||||
UByteArray ucode = model->body(index).mid(offset);
|
||||
|
||||
// Check for empty area
|
||||
if (ucode.size() == ucode.count('\xFF') || ucode.size() == ucode.count('\x00')) {
|
||||
result = U_INVALID_MICROCODE;
|
||||
}
|
||||
else {
|
||||
result = parseIntelMicrocodeHeader(ucode, headerSize + offset, index, currentMicrocode);
|
||||
}
|
||||
|
||||
// Add the rest as padding
|
||||
if (result) {
|
||||
if (offset < bodySize) {
|
||||
// Get info
|
||||
UString name = UString("Padding");
|
||||
UString info = usprintf("Full size: %Xh (%u)", ucode.size(), ucode.size());
|
||||
|
||||
// Add tree item
|
||||
model->addItem(model->offset(index) + headerSize + offset, Types::Padding, getPaddingType(ucode), name, UString(), info, UByteArray(), ucode, UByteArray(), Fixed, index);
|
||||
}
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Get to next candidate
|
||||
offset += model->header(currentMicrocode).size() + model->body(currentMicrocode).size() + model->tail(currentMicrocode).size();
|
||||
if (offset >= bodySize)
|
||||
break;
|
||||
}
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, UINT8 mode)
|
||||
{
|
||||
const UINT32 dataSize = (const UINT32)microcode.size();
|
||||
|
||||
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
|
||||
//msg(usprintf("%s: input is too small even for Intel microcode header", __FUNCTION__), parent);
|
||||
return U_INVALID_MICROCODE;
|
||||
}
|
||||
|
||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)microcode.constData();
|
||||
if (ucodeHeader->Version != INTEL_MICROCODE_HEADER_VERSION) {
|
||||
//msg(usprintf("%s: input has invalid Intel microcode header", __FUNCTION__), parent);
|
||||
return U_INVALID_MICROCODE;
|
||||
}
|
||||
|
||||
if (!INTEL_MICROCODE_HEADER_SIZES_VALID(ucodeHeader)) {
|
||||
//msg(usprintf("%s: input has invalid Intel microcode header", __FUNCTION__), parent);
|
||||
return U_INVALID_MICROCODE;
|
||||
}
|
||||
|
||||
bool reservedBytesValid = true;
|
||||
for (UINT8 i = 0; i < sizeof(ucodeHeader->Reserved); i++)
|
||||
if (ucodeHeader->Reserved[i] != INTEL_MICROCODE_HEADER_RESERVED_BYTE) {
|
||||
reservedBytesValid = false;
|
||||
break;
|
||||
}
|
||||
if (!reservedBytesValid) {
|
||||
//msg(usprintf("%s: input has invalid Intel microcode header", __FUNCTION__), parent);
|
||||
return U_INVALID_MICROCODE;
|
||||
}
|
||||
|
||||
if (dataSize < ucodeHeader->TotalSize) {
|
||||
//msg(usprintf("%s: input is too small for the whole Intel microcode", __FUNCTION__), parent);
|
||||
return U_INVALID_MICROCODE;
|
||||
}
|
||||
|
||||
// Valid microcode found
|
||||
// Construct header and body
|
||||
UByteArray header = microcode.left(sizeof(INTEL_MICROCODE_HEADER));
|
||||
UByteArray body = microcode.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
|
||||
|
||||
//TODO: recalculate microcode checksum
|
||||
|
||||
// Add info
|
||||
UString name("Intel microcode");
|
||||
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n"
|
||||
"Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nChecksum: %08Xh\nLoader revision: %08Xh\nCPU flags: %08Xh",
|
||||
ucodeHeader->TotalSize, ucodeHeader->TotalSize,
|
||||
header.size(), header.size(),
|
||||
body.size(), body.size(),
|
||||
ucodeHeader->DateDay,
|
||||
ucodeHeader->DateMonth,
|
||||
ucodeHeader->DateYear,
|
||||
ucodeHeader->CpuSignature,
|
||||
ucodeHeader->Revision,
|
||||
ucodeHeader->Checksum,
|
||||
ucodeHeader->LoaderRevision,
|
||||
ucodeHeader->CpuFlags);
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(model->offset(parent) + localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||
|
||||
// No need to parse body further for now
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
@ -64,9 +64,6 @@ public:
|
||||
// Obtain TXT ACM Info
|
||||
UString getTxtInfo() const { return txtInfo; }
|
||||
|
||||
// Obtain Microcode Info
|
||||
UString getMicrocodeInfo() const { return microcodeInfo; }
|
||||
|
||||
// Obtain offset/address difference
|
||||
UINT64 getAddressDiff() { return addressDiff; }
|
||||
|
||||
@ -102,18 +99,18 @@ private:
|
||||
UModelIndex bgDxeCoreIndex;
|
||||
|
||||
UString txtInfo;
|
||||
UString microcodeInfo;
|
||||
|
||||
// First pass
|
||||
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
|
||||
|
||||
USTATUS parseCapsule(const UByteArray & capsule, UModelIndex & index);
|
||||
USTATUS parseCapsule(const UByteArray & capsule, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseGenericImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
|
||||
USTATUS parseRawArea(const UModelIndex & index);
|
||||
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||
USTATUS parseVolumeBody(const UModelIndex & index);
|
||||
USTATUS parseMicrocodeVolumeBody(const UModelIndex & index);
|
||||
USTATUS parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||
USTATUS parseFileBody(const UModelIndex & index);
|
||||
USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
|
||||
@ -146,8 +143,8 @@ private:
|
||||
USTATUS parseTeImageSectionBody(const UModelIndex & index);
|
||||
|
||||
USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed);
|
||||
USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 globalOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
|
||||
USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
|
||||
USTATUS findNextRawAreaItem(const UModelIndex & index, const UINT32 localOffset,
|
||||
UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize);
|
||||
UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
|
||||
UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
|
||||
|
||||
@ -161,17 +158,18 @@ private:
|
||||
|
||||
USTATUS parseFit(const UModelIndex & index);
|
||||
USTATUS parseVendorHashFile(const UByteArray & fileGuid, const UModelIndex & index);
|
||||
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, UINT8 mode = CREATE_MODE_APPEND);
|
||||
|
||||
#ifdef U_ENABLE_FIT_PARSING_SUPPORT
|
||||
USTATUS findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset);
|
||||
|
||||
// FIT entries
|
||||
USTATUS parseIntelMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseIntelAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseIntelBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info);
|
||||
USTATUS findNextElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
|
||||
USTATUS parseFitEntryMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseFitEntryAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseFitEntryBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseFitEntryTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info);
|
||||
USTATUS findNextBootGuardBootPolicyElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
|
||||
#endif
|
||||
|
||||
#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT
|
||||
|
@ -18,8 +18,8 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
struct OperatorLessForGuids : public std::binary_function<EFI_GUID, EFI_GUID, bool>
|
||||
{
|
||||
|
12
common/me.h
12
common/me.h
@ -22,12 +22,12 @@ const UByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN
|
||||
const UByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2
|
||||
|
||||
typedef struct ME_VERSION_ {
|
||||
UINT32 signature;
|
||||
UINT32 reserved;
|
||||
UINT16 major;
|
||||
UINT16 minor;
|
||||
UINT16 bugfix;
|
||||
UINT16 build;
|
||||
UINT32 Signature;
|
||||
UINT32 Reserved;
|
||||
UINT16 Major;
|
||||
UINT16 Minor;
|
||||
UINT16 Bugfix;
|
||||
UINT16 Build;
|
||||
} ME_VERSION;
|
||||
|
||||
// Restore previous packing rules
|
||||
|
@ -108,6 +108,6 @@ UString flashMapGuidToUString(const EFI_GUID & guid)
|
||||
|| baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID
|
||||
|| baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID) return UString("EVSA store");
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_SELF_GUID) return UString("Flash map");
|
||||
return UString();
|
||||
return UString("Unknown");
|
||||
}
|
||||
|
||||
|
@ -1225,55 +1225,6 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||
{
|
||||
const UINT32 dataSize = (const UINT32)store.size();
|
||||
|
||||
// Check data size
|
||||
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
|
||||
msg(usprintf("%s: volume body is too small even for Intel microcode header", __FUNCTION__), parent);
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Get Intel microcode header
|
||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)store.constData();
|
||||
|
||||
// Check store size
|
||||
if (dataSize < ucodeHeader->TotalSize) {
|
||||
msg(usprintf("%s: Intel microcode size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
|
||||
ucodeHeader->TotalSize, ucodeHeader->TotalSize,
|
||||
dataSize, dataSize), parent);
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Construct header and body
|
||||
UByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER));
|
||||
UByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
|
||||
|
||||
//TODO: recalculate microcode checksum
|
||||
|
||||
// Add info
|
||||
UString name("Intel microcode");
|
||||
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n"
|
||||
"Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nChecksum: %08Xh\nLoader revision: %08Xh\nCPU flags: %08Xh",
|
||||
ucodeHeader->TotalSize, ucodeHeader->TotalSize,
|
||||
header.size(), header.size(),
|
||||
body.size(), body.size(),
|
||||
ucodeHeader->DateDay,
|
||||
ucodeHeader->DateMonth,
|
||||
ucodeHeader->DateYear,
|
||||
ucodeHeader->CpuSignature,
|
||||
ucodeHeader->Revision,
|
||||
ucodeHeader->Checksum,
|
||||
ucodeHeader->LoaderRevision,
|
||||
ucodeHeader->CpuFlags);
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||
{
|
||||
const UINT32 dataSize = (const UINT32)store.size();
|
||||
@ -1318,7 +1269,7 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc
|
||||
// Intel microcode
|
||||
// Must be checked after SLIC marker because of the same *signature values
|
||||
else if (*signature == INTEL_MICROCODE_HEADER_VERSION)
|
||||
return parseIntelMicrocodeHeader(store, localOffset, parent, index, mode);
|
||||
return ffsParser->parseIntelMicrocodeHeader(store, localOffset, parent, index, mode);
|
||||
|
||||
msg(usprintf("parseStoreHeader: don't know how to parse a header with signature %08Xh", *signature), parent);
|
||||
return U_SUCCESS;
|
||||
|
@ -62,7 +62,6 @@ private:
|
||||
USTATUS parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||
USTATUS parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||
USTATUS parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||
|
||||
USTATUS parseFdcStoreBody(const UModelIndex & index);
|
||||
USTATUS parseVssStoreBody(const UModelIndex & index, const UINT8 alignment);
|
||||
|
@ -74,17 +74,6 @@ UString itemTypeToUString(const UINT8 type)
|
||||
UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
|
||||
{
|
||||
switch (type) {
|
||||
case Types::Root:
|
||||
case Types::FreeSpace:
|
||||
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::SlicData: return UString();
|
||||
case Types::Image:
|
||||
if (subtype == Subtypes::IntelImage) return UString("Intel");
|
||||
if (subtype == Subtypes::UefiImage) return UString("UEFI");
|
||||
@ -99,6 +88,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
|
||||
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");
|
||||
break;
|
||||
case Types::Capsule:
|
||||
if (subtype == Subtypes::AptioSignedCapsule) return UString("Aptio signed");
|
||||
@ -144,7 +134,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
|
||||
break;
|
||||
}
|
||||
|
||||
return UString("Unknown");
|
||||
return UString();
|
||||
}
|
||||
|
||||
UString compressionTypeToUString(const UINT8 algorithm)
|
||||
|
@ -78,7 +78,8 @@ namespace Subtypes {
|
||||
UnknownVolume = 110,
|
||||
Ffs2Volume,
|
||||
Ffs3Volume,
|
||||
NvramVolume
|
||||
NvramVolume,
|
||||
MicrocodeVolume
|
||||
};
|
||||
|
||||
enum RegionSubtypes {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* types.h
|
||||
/* version.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2018, LongSoft. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -14,6 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#ifndef __VERSION_H__
|
||||
#define __VERSION_H__
|
||||
|
||||
#define PROGRAM_VERSION "NE alpha 51"
|
||||
#define PROGRAM_VERSION "NE alpha 52"
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user