UEFITool 0.18.1

- descriptor parsing enabled for Gigabyte boards
- search dialog UI reworked (GUID search to be added in next release)
- added MAN$ signature check for old ME firmware versions
This commit is contained in:
Nikolaj Schlej 2014-07-09 09:20:13 +02:00
parent e50d6763e0
commit f529fdd20d
7 changed files with 132 additions and 155 deletions

View File

@ -41,7 +41,7 @@ int main(int argc, char *argv[])
} }
else { else {
result = ERR_INVALID_PARAMETER; result = ERR_INVALID_PARAMETER;
std::cout << "UEFIExtract 0.2" << std::endl << std::endl << std::cout << "UEFIExtract 0.2.1" << std::endl << std::endl <<
"Usage: uefiextract imagefile\n" << std::endl; "Usage: uefiextract imagefile\n" << std::endl;
} }

View File

@ -31,7 +31,7 @@ int main(int argc, char *argv[])
result = w.patchFromFile(a.arguments().at(1)); result = w.patchFromFile(a.arguments().at(1));
} }
else { else {
std::cout << "UEFIPatch 0.2.0 - UEFI image file patching utility" << std::endl << std::endl << std::cout << "UEFIPatch 0.2.1 - UEFI image file patching utility" << std::endl << std::endl <<
"Usage: UEFIPatch image_file" << std::endl << std::endl << "Usage: UEFIPatch image_file" << std::endl << std::endl <<
"Patches will be read from patches.txt file\n"; "Patches will be read from patches.txt file\n";
return ERR_SUCCESS; return ERR_SUCCESS;

View File

@ -169,7 +169,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
// Check for buffer size to be greater or equal to descriptor region size // Check for buffer size to be greater or equal to descriptor region size
if (intelImage.size() < FLASH_DESCRIPTOR_SIZE) { if (intelImage.size() < FLASH_DESCRIPTOR_SIZE) {
msg(tr("parseInputFile: Input file is smaller then minimum descriptor size of %1 bytes").arg(FLASH_DESCRIPTOR_SIZE)); msg(tr("parseIntelImage: Input file is smaller then minimum descriptor size of %1 bytes").arg(FLASH_DESCRIPTOR_SIZE));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
@ -215,53 +215,63 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
if (regionSection->BiosLimit) { if (regionSection->BiosLimit) {
biosBegin = calculateRegionOffset(regionSection->BiosBase); biosBegin = calculateRegionOffset(regionSection->BiosBase);
biosEnd = calculateRegionSize(regionSection->BiosBase, regionSection->BiosLimit); biosEnd = calculateRegionSize(regionSection->BiosBase, regionSection->BiosLimit);
// Check for Gigabyte specific descriptor map
if (biosEnd - biosBegin == intelImage.size()) {
if (!meEnd) {
msg(tr("parseIntelImage: can determine BIOS region start on Gigabyte-specific descriptor"));
return ERR_INVALID_FLASH_DESCRIPTOR;
}
biosBegin = meEnd;
}
bios = intelImage.mid(biosBegin, biosEnd); bios = intelImage.mid(biosBegin, biosEnd);
biosEnd += biosBegin; biosEnd += biosBegin;
} }
else { else {
msg(tr("parseInputFile: descriptor parsing failed, BIOS region not found in descriptor")); msg(tr("parseIntelImage: descriptor parsing failed, BIOS region not found in descriptor"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
// Check for intersections between regions // Check for intersections between regions
if (hasIntersection(descriptorBegin, descriptorEnd, gbeBegin, gbeEnd)) { if (hasIntersection(descriptorBegin, descriptorEnd, gbeBegin, gbeEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, descriptor region has intersection with GbE region")); msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with GbE region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(descriptorBegin, descriptorEnd, meBegin, meEnd)) { if (hasIntersection(descriptorBegin, descriptorEnd, meBegin, meEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, descriptor region has intersection with ME region")); msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with ME region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(descriptorBegin, descriptorEnd, biosBegin, biosEnd)) { if (hasIntersection(descriptorBegin, descriptorEnd, biosBegin, biosEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, descriptor region has intersection with BIOS region")); msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with BIOS region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(descriptorBegin, descriptorEnd, pdrBegin, pdrEnd)) { if (hasIntersection(descriptorBegin, descriptorEnd, pdrBegin, pdrEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, descriptor region has intersection with PDR region")); msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with PDR region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(gbeBegin, gbeEnd, meBegin, meEnd)) { if (hasIntersection(gbeBegin, gbeEnd, meBegin, meEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, GbE region has intersection with ME region")); msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with ME region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(gbeBegin, gbeEnd, biosBegin, biosEnd)) { if (hasIntersection(gbeBegin, gbeEnd, biosBegin, biosEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, GbE region has intersection with BIOS region")); msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with BIOS region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(gbeBegin, gbeEnd, pdrBegin, pdrEnd)) { if (hasIntersection(gbeBegin, gbeEnd, pdrBegin, pdrEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, GbE region has intersection with PDR region")); msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with PDR region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(meBegin, meEnd, biosBegin, biosEnd)) { if (hasIntersection(meBegin, meEnd, biosBegin, biosEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, ME region has intersection with BIOS region")); msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with BIOS region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(meBegin, meEnd, pdrBegin, pdrEnd)) { if (hasIntersection(meBegin, meEnd, pdrBegin, pdrEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, ME region has intersection with PDR region")); msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with PDR region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
if (hasIntersection(biosBegin, biosEnd, pdrBegin, pdrEnd)) { if (hasIntersection(biosBegin, biosEnd, pdrBegin, pdrEnd)) {
msg(tr("parseInputFile: descriptor parsing failed, BIOS region has intersection with PDR region")); msg(tr("parseIntelImage: descriptor parsing failed, BIOS region has intersection with PDR region"));
return ERR_INVALID_FLASH_DESCRIPTOR; return ERR_INVALID_FLASH_DESCRIPTOR;
} }
@ -409,12 +419,21 @@ UINT8 FfsEngine::parseMeRegion(const QByteArray & me, QModelIndex & index, const
QString info = tr("Size: %1"). QString info = tr("Size: %1").
arg(me.size(), 8, 16, QChar('0')); arg(me.size(), 8, 16, QChar('0'));
INT32 versionOffset = me.indexOf(ME_VERSION_SIGNATURE); // Search for new signature
if (versionOffset < 0){ INT32 versionOffset = me.indexOf(ME_VERSION_SIGNATURE2);
info += tr("\nVersion: unknown"); bool versionFound = true;
msg(tr("parseRegion: ME region version is unknown, it can be damaged"), parent); if (versionOffset < 0){ // New signature not found
// Search for old signature
versionOffset = me.indexOf(ME_VERSION_SIGNATURE);
if (versionOffset < 0){
info += tr("\nVersion: unknown");
msg(tr("parseRegion: ME region version is unknown, it can be damaged"), parent);
versionFound = false;
}
} }
else {
// Add version information
if (versionFound) {
ME_VERSION* version = (ME_VERSION*)(me.constData() + versionOffset); ME_VERSION* version = (ME_VERSION*)(me.constData() + versionOffset);
info += tr("\nVersion: %1.%2.%3.%4") info += tr("\nVersion: %1.%2.%3.%4")
.arg(version->major) .arg(version->major)
@ -2772,12 +2791,7 @@ UINT8 FfsEngine::reconstructImageFile(QByteArray & reconstructed)
} }
// Search routines // Search routines
UINT8 FfsEngine::findHexPattern(const QByteArray & pattern, const UINT8 mode) UINT8 FfsEngine::findHexPattern(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode)
{
return findHexPatternIn(model->index(0, 0), pattern, mode);
}
UINT8 FfsEngine::findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode)
{ {
if (pattern.isEmpty()) if (pattern.isEmpty())
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
@ -2787,7 +2801,7 @@ UINT8 FfsEngine::findHexPatternIn(const QModelIndex & index, const QByteArray &
bool hasChildren = (model->rowCount(index) > 0); bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
findHexPatternIn(index.child(i, index.column()), pattern, mode); findHexPattern(index.child(i, index.column()), pattern, mode);
} }
QByteArray data; QByteArray data;
@ -2816,12 +2830,7 @@ UINT8 FfsEngine::findHexPatternIn(const QModelIndex & index, const QByteArray &
return ERR_SUCCESS; return ERR_SUCCESS;
} }
UINT8 FfsEngine::findTextPattern(const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive) UINT8 FfsEngine::findTextPattern(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive)
{
return findTextPatternIn(model->index(0, 0), pattern, unicode, caseSensitive);
}
UINT8 FfsEngine::findTextPatternIn(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive)
{ {
if (pattern.isEmpty()) if (pattern.isEmpty())
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
@ -2831,7 +2840,7 @@ UINT8 FfsEngine::findTextPatternIn(const QModelIndex & index, const QString & pa
bool hasChildren = (model->rowCount(index) > 0); bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
findTextPatternIn(index.child(i, index.column()), pattern, unicode, caseSensitive); findTextPattern(index.child(i, index.column()), pattern, unicode, caseSensitive);
} }
if (hasChildren) if (hasChildren)
@ -2845,7 +2854,7 @@ UINT8 FfsEngine::findTextPatternIn(const QModelIndex & index, const QString & pa
int offset = -1; int offset = -1;
while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) { while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) {
msg(tr("%1 text pattern \"%2\" found in %3 at offset %4") msg(tr("%1 text \"%2\" found in %3 at offset %4")
.arg(unicode ? "Unicode" : "ASCII") .arg(unicode ? "Unicode" : "ASCII")
.arg(pattern) .arg(pattern)
.arg(model->nameString(index)) .arg(model->nameString(index))

View File

@ -96,10 +96,8 @@ public:
UINT8 patch(const QModelIndex & index, const QVector<PatchData> & patches); UINT8 patch(const QModelIndex & index, const QVector<PatchData> & patches);
// Search routines // Search routines
UINT8 findHexPattern(const QByteArray & pattern, const UINT8 mode); UINT8 findHexPattern(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode);
UINT8 findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode); UINT8 findTextPattern(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive);
UINT8 findTextPattern(const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive);
UINT8 findTextPatternIn(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive);
private: private:
TreeModel *model; TreeModel *model;

3
me.h
View File

@ -18,7 +18,8 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Make sure we use right packing rules // Make sure we use right packing rules
#pragma pack(push,1) #pragma pack(push,1)
const QByteArray ME_VERSION_SIGNATURE("\x24\x4D\x4E\x32", 4); const QByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN
const QByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2
typedef struct { typedef struct {
UINT32 signature; UINT32 signature;

View File

@ -6,96 +6,71 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>290</width> <width>340</width>
<height>195</height> <height>214</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Search</string> <string>Search</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <property name="modal">
<item row="0" column="0"> <bool>false</bool>
<widget class="QLabel" name="searchForLabel"> </property>
<property name="text"> <layout class="QVBoxLayout" name="verticalLayout">
<string>Search for:</string> <item>
</property> <widget class="QTabWidget" name="tabWidget">
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="dataTypeLabel">
<property name="text">
<string>Data type:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="searchEdit"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="dataTypeComboBox">
<item>
<property name="text">
<string>Hex pattern</string>
</property>
</item>
<item>
<property name="text">
<string>Text string</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="hexPage"> <widget class="QWidget" name="hexTab">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <attribute name="title">
<property name="spacing"> <string>Hex pattern</string>
<number>0</number> </attribute>
</property> <layout class="QGridLayout" name="gridLayout_2">
<property name="margin"> <item row="0" column="0">
<number>0</number> <widget class="QLabel" name="hexLabel">
</property> <property name="text">
<item> <string>Hex pattern:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="hexEdit"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="hexGroupBox"> <widget class="QGroupBox" name="hexGroupBox">
<property name="title"> <property name="title">
<string>Hex pattern search scope</string> <string>Search scope</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
</property>
<item> <item>
<widget class="QRadioButton" name="allRadioButton"> <widget class="QRadioButton" name="hexScopeFullRadioButton">
<property name="text"> <property name="text">
<string>Header and body</string> <string>Header and body</string>
</property> </property>
<property name="checked">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="headerOnlyRadioButton"> <widget class="QRadioButton" name="hexScopeHeaderRadioButton">
<property name="text"> <property name="text">
<string>Header only</string> <string>Header only</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="bodyOnlyRadioButton"> <widget class="QRadioButton" name="hexScopeBodyRadioButton">
<property name="text"> <property name="text">
<string>Body only</string> <string>Body only</string>
</property> </property>
<property name="checked">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -103,22 +78,29 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="textPage"> <widget class="QWidget" name="textTab">
<layout class="QHBoxLayout" name="horizontalLayout"> <attribute name="title">
<property name="spacing"> <string>Text</string>
<number>0</number> </attribute>
</property> <layout class="QGridLayout" name="gridLayout_3">
<property name="margin"> <item row="0" column="0">
<number>0</number> <widget class="QLabel" name="textLabel">
</property> <property name="text">
<item> <string>Text:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="textEdit"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="textGroupBox"> <widget class="QGroupBox" name="textGroupBox">
<property name="title"> <property name="title">
<string>Text string options</string> <string>Text search options</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item> <item>
<widget class="QCheckBox" name="unicodeCheckBox"> <widget class="QCheckBox" name="textUnicodeCheckBox">
<property name="text"> <property name="text">
<string>Unicode</string> <string>Unicode</string>
</property> </property>
@ -128,7 +110,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="caseSensitiveCheckBox"> <widget class="QCheckBox" name="textCaseSensitiveCheckBox">
<property name="text"> <property name="text">
<string>Case sensitive</string> <string>Case sensitive</string>
</property> </property>
@ -141,15 +123,19 @@
</widget> </widget>
</widget> </widget>
</item> </item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<tabstops> <tabstops>
<tabstop>searchEdit</tabstop>
<tabstop>dataTypeComboBox</tabstop>
<tabstop>allRadioButton</tabstop>
<tabstop>bodyOnlyRadioButton</tabstop>
<tabstop>unicodeCheckBox</tabstop>
<tabstop>caseSensitiveCheckBox</tabstop>
<tabstop>buttonBox</tabstop> <tabstop>buttonBox</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
@ -161,12 +147,12 @@
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>173</x> <x>182</x>
<y>162</y> <y>185</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>157</x> <x>157</x>
<y>216</y> <y>194</y>
</hint> </hint>
</hints> </hints>
</connection> </connection>
@ -177,28 +163,12 @@
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>173</x> <x>182</x>
<y>162</y> <y>185</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>286</x> <x>286</x>
<y>216</y> <y>194</y>
</hint>
</hints>
</connection>
<connection>
<sender>dataTypeComboBox</sender>
<signal>activated(int)</signal>
<receiver>stackedWidget</receiver>
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
<x>151</x>
<y>42</y>
</hint>
<hint type="destinationlabel">
<x>88</x>
<y>68</y>
</hint> </hint>
</hints> </hints>
</connection> </connection>

View File

@ -123,33 +123,32 @@ void UEFITool::populateUi(const QModelIndex &current)
void UEFITool::search() void UEFITool::search()
{ {
// Set focus to edit box
searchDialog->ui->searchEdit->setFocus();
if (searchDialog->exec() != QDialog::Accepted) if (searchDialog->exec() != QDialog::Accepted)
return; return;
int index = searchDialog->ui->dataTypeComboBox->currentIndex(); QModelIndex rootIndex = ffsEngine->treeModel()->index(0, 0);
int index = searchDialog->ui->tabWidget->currentIndex();
if (index == 0) { // Hex pattern if (index == 0) { // Hex pattern
QByteArray pattern = QByteArray::fromHex(searchDialog->ui->searchEdit->text().toLatin1()); QByteArray pattern = QByteArray::fromHex(searchDialog->ui->hexEdit->text().toLatin1());
if (pattern.isEmpty()) if (pattern.isEmpty())
return; return;
UINT8 mode; UINT8 mode;
if (searchDialog->ui->headerOnlyRadioButton->isChecked()) if (searchDialog->ui->hexScopeHeaderRadioButton->isChecked())
mode = SEARCH_MODE_HEADER; mode = SEARCH_MODE_HEADER;
else if (searchDialog->ui->bodyOnlyRadioButton->isChecked()) else if (searchDialog->ui->hexScopeBodyRadioButton->isChecked())
mode = SEARCH_MODE_BODY; mode = SEARCH_MODE_BODY;
else else
mode = SEARCH_MODE_ALL; mode = SEARCH_MODE_ALL;
ffsEngine->findHexPattern(pattern, mode); ffsEngine->findHexPattern(rootIndex, pattern, mode);
showMessages(); showMessages();
} }
else if (index == 1) { // Text string else if (index == 1) { // Text string
QString pattern = searchDialog->ui->searchEdit->text(); QString pattern = searchDialog->ui->textEdit->text();
if (pattern.isEmpty()) if (pattern.isEmpty())
return; return;
ffsEngine->findTextPattern(pattern, searchDialog->ui->unicodeCheckBox->isChecked(), ffsEngine->findTextPattern(rootIndex, pattern, searchDialog->ui->textUnicodeCheckBox->isChecked(),
(Qt::CaseSensitivity) searchDialog->ui->caseSensitiveCheckBox->isChecked()); (Qt::CaseSensitivity) searchDialog->ui->textCaseSensitiveCheckBox->isChecked());
showMessages(); showMessages();
} }
} }