UEFIExtract 0.3.0

- added filtering by FFS file GUID, only specified files can now be
unpacked
This commit is contained in:
Nikolaj Schlej 2014-08-15 13:24:03 +02:00
parent 754f9c5b13
commit 701717c554
5 changed files with 99 additions and 64 deletions

View file

@ -24,30 +24,36 @@ UEFIExtract::~UEFIExtract()
delete ffsEngine; delete ffsEngine;
} }
UINT8 UEFIExtract::extractAll(QString path) UINT8 UEFIExtract::init(const QString & path)
{ {
QFileInfo fileInfo = QFileInfo(path); fileInfo = QFileInfo(path);
if (!fileInfo.exists()) if (!fileInfo.exists())
return ERR_FILE_OPEN; return ERR_FILE_OPEN;
QFile inputFile; QFile inputFile;
inputFile.setFileName(path); inputFile.setFileName(path);
if (!inputFile.open(QFile::ReadOnly)) if (!inputFile.open(QFile::ReadOnly))
return ERR_FILE_OPEN; return ERR_FILE_OPEN;
QByteArray buffer = inputFile.readAll(); QByteArray buffer = inputFile.readAll();
inputFile.close(); inputFile.close();
UINT8 result = ffsEngine->parseImageFile(buffer); UINT8 result = ffsEngine->parseImageFile(buffer);
if (result) if (result)
return result; return result;
return ERR_SUCCESS;
}
UINT8 UEFIExtract::extract(QString guid)
{
QModelIndex rootIndex = ffsEngine->treeModel()->index(0, 0); QModelIndex rootIndex = ffsEngine->treeModel()->index(0, 0);
result = ffsEngine->dump(rootIndex, fileInfo.fileName().append(".dump"));
if (result)
return result;
UINT8 result = ffsEngine->dump(rootIndex, fileInfo.fileName().append(".dump"), guid);
if (result)
return result;
return ERR_SUCCESS; return ERR_SUCCESS;
} }

View file

@ -31,10 +31,13 @@ public:
explicit UEFIExtract(QObject *parent = 0); explicit UEFIExtract(QObject *parent = 0);
~UEFIExtract(); ~UEFIExtract();
UINT8 extractAll(QString path); UINT8 init(const QString & path);
UINT8 extract(QString guid = QString());
private: private:
FfsEngine* ffsEngine; FfsEngine* ffsEngine;
QFileInfo fileInfo;
}; };
#endif #endif

View file

@ -25,24 +25,44 @@ int main(int argc, char *argv[])
UEFIExtract w; UEFIExtract w;
UINT8 result = ERR_SUCCESS; UINT8 result = ERR_SUCCESS;
if (a.arguments().length() > 1) { if (a.arguments().length() > 1 ) {
result = w.extractAll(a.arguments().at(1)); w.init(a.arguments().at(1));
switch (result) {
case ERR_DIR_ALREADY_EXIST: if (a.arguments().length() == 2) {
std::cout << "Dump directory already exist, please remove it" << std::endl; result = w.extract();
break; switch (result) {
case ERR_DIR_CREATE: case ERR_DIR_ALREADY_EXIST:
std::cout << "Can't create directory" << std::endl; std::cout << "Dump directory already exist, please remove it" << std::endl;
break; break;
case ERR_FILE_OPEN: case ERR_DIR_CREATE:
std::cout << "Can't create file" << std::endl; std::cout << "Can't create directory" << std::endl;
break; break;
} case ERR_FILE_OPEN:
std::cout << "Can't create file" << std::endl;
break;
}
}
else {
for (int i = 2; i < a.arguments().length(); i++) {
result = w.extract(a.arguments().at(i));
switch (result) {
case ERR_DIR_ALREADY_EXIST:
std::cout << "Dump directory already exist, please remove it" << std::endl;
break;
case ERR_DIR_CREATE:
std::cout << "Can't create directory" << std::endl;
break;
case ERR_FILE_OPEN:
std::cout << "Can't create file" << std::endl;
break;
}
}
}
} }
else { else {
result = ERR_INVALID_PARAMETER; result = ERR_INVALID_PARAMETER;
std::cout << "UEFIExtract 0.2.2" << std::endl << std::endl << std::cout << "UEFIExtract 0.3.0" << std::endl << std::endl <<
"Usage: uefiextract imagefile\n" << std::endl; "Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ...]\n" << std::endl;
} }
return result; return result;

View file

@ -3432,51 +3432,57 @@ UINT32 FfsEngine::crc32(UINT32 initial, const UINT8* buffer, UINT32 length)
return(crc32 ^ 0xFFFFFFFF); return(crc32 ^ 0xFFFFFFFF);
} }
UINT8 FfsEngine::dump(const QModelIndex & index, const QString path) UINT8 FfsEngine::dump(const QModelIndex & index, const QString & path, const QString & guid)
{ {
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
QDir dir; QDir dir;
if (dir.cd(path))
return ERR_DIR_ALREADY_EXIST; if (guid.isEmpty() ||
guidToQString(*(EFI_GUID*)model->header(index).constData()) == guid ||
guidToQString(*(EFI_GUID*)model->header(model->findParentOfType(index, Types::File)).constData()) == guid) {
if (dir.cd(path))
return ERR_DIR_ALREADY_EXIST;
if (!dir.mkpath(path)) if (!dir.mkpath(path))
return ERR_DIR_CREATE; return ERR_DIR_CREATE;
QFile file; QFile file;
if (!model->header(index).isEmpty()) { if (!model->header(index).isEmpty()) {
file.setFileName(tr("%1/header.bin").arg(path)); file.setFileName(tr("%1/header.bin").arg(path));
if (!file.open(QFile::WriteOnly)) if (!file.open(QFile::WriteOnly))
return ERR_FILE_OPEN; return ERR_FILE_OPEN;
file.write(model->header(index)); file.write(model->header(index));
file.close(); file.close();
} }
if (!model->body(index).isEmpty()) { if (!model->body(index).isEmpty()) {
file.setFileName(tr("%1/body.bin").arg(path)); file.setFileName(tr("%1/body.bin").arg(path));
if (!file.open(QFile::WriteOnly)) if (!file.open(QFile::WriteOnly))
return ERR_FILE_OPEN; return ERR_FILE_OPEN;
file.write(model->body(index)); file.write(model->body(index));
file.close(); file.close();
} }
QString info = tr("Type: %1\nSubtype: %2\n%3%4") QString info = tr("Type: %1\nSubtype: %2\n%3%4")
.arg(model->typeString(index)) .arg(model->typeString(index))
.arg(model->subtypeString(index)) .arg(model->subtypeString(index))
.arg(model->textString(index).isEmpty() ? "" : tr("Text: %1\n").arg(model->textString(index))) .arg(model->textString(index).isEmpty() ? "" : tr("Text: %1\n").arg(model->textString(index)))
.arg(model->info(index)); .arg(model->info(index));
file.setFileName(tr("%1/info.txt").arg(path)); file.setFileName(tr("%1/info.txt").arg(path));
if (!file.open(QFile::Text | QFile::WriteOnly)) if (!file.open(QFile::Text | QFile::WriteOnly))
return ERR_FILE_OPEN; return ERR_FILE_OPEN;
file.write(info.toLatin1()); file.write(info.toLatin1());
file.close(); file.close();
}
UINT8 result; UINT8 result;
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
QModelIndex childIndex = index.child(i, 0); QModelIndex childIndex = index.child(i, 0);
QString childPath = tr("%1/%2 %3").arg(path).arg(i).arg(model->textString(childIndex).isEmpty() ? model->nameString(childIndex) : model->textString(childIndex)); QString childPath = tr("%1/%2 %3").arg(path).arg(i).arg(model->textString(childIndex).isEmpty() ? model->nameString(childIndex) : model->textString(childIndex));
result = dump(childIndex, childPath); result = dump(childIndex, childPath, guid);
if (result) if (result)
return result; return result;
} }

View file

@ -94,7 +94,7 @@ public:
UINT8 replace(const QModelIndex & index, const QByteArray & object, const UINT8 mode); UINT8 replace(const QModelIndex & index, const QByteArray & object, const UINT8 mode);
UINT8 remove(const QModelIndex & index); UINT8 remove(const QModelIndex & index);
UINT8 rebuild(const QModelIndex & index); UINT8 rebuild(const QModelIndex & index);
UINT8 dump(const QModelIndex & index, const QString path); UINT8 dump(const QModelIndex & index, const QString & path, const QString & filter = QString());
UINT8 patch(const QModelIndex & index, const QVector<PatchData> & patches); UINT8 patch(const QModelIndex & index, const QVector<PatchData> & patches);
// Search routines // Search routines