mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-26 01:48:23 +08:00
Support applying patches from terminal, closes #186
This commit is contained in:
parent
4bee991c94
commit
31ccb2a054
@ -121,6 +121,86 @@ UINT8 UEFIPatch::patchFromFile(const QString & path, const QString & patches, co
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT8 UEFIPatch::patchFromArg(const QString & path, const QString & patch, const QString & outputPath)
|
||||
{
|
||||
QFileInfo fileInfo = QFileInfo(path);
|
||||
|
||||
if (!fileInfo.exists())
|
||||
return ERR_FILE_OPEN;
|
||||
|
||||
QFile inputFile;
|
||||
inputFile.setFileName(path);
|
||||
|
||||
if (!inputFile.open(QFile::ReadOnly))
|
||||
return ERR_FILE_READ;
|
||||
|
||||
QByteArray buffer = inputFile.readAll();
|
||||
inputFile.close();
|
||||
|
||||
UINT8 result = ffsEngine->parseImageFile(buffer);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (patch != nullptr && !patch.isEmpty()) {
|
||||
QByteArray line = patch.toUtf8();
|
||||
|
||||
QList<QByteArray> list = line.split(' ');
|
||||
if (list.count() < 3)
|
||||
return ERR_INVALID_PARAMETER;
|
||||
|
||||
QUuid uuid = QUuid(list.at(0));
|
||||
QByteArray guid = QByteArray::fromRawData((const char*)&uuid.data1, sizeof(EFI_GUID));
|
||||
bool converted;
|
||||
UINT8 sectionType = (UINT8)list.at(1).toUShort(&converted, 16);
|
||||
if (!converted)
|
||||
return ERR_INVALID_PARAMETER;
|
||||
|
||||
QVector<PatchData> patches;
|
||||
|
||||
for (int i = 2; i < list.count(); i++) {
|
||||
QList<QByteArray> patchList = list.at(i).split(':');
|
||||
PatchData patch;
|
||||
patch.type = *(UINT8*)patchList.at(0).constData();
|
||||
if (patch.type == PATCH_TYPE_PATTERN) {
|
||||
patch.offset = 0xFFFFFFFF;
|
||||
patch.hexFindPattern = patchList.at(1);
|
||||
patch.hexReplacePattern = patchList.at(2);
|
||||
patches.append(patch);
|
||||
}
|
||||
else if (patch.type == PATCH_TYPE_OFFSET) {
|
||||
patch.offset = patchList.at(1).toUInt(NULL, 16);
|
||||
patch.hexReplacePattern = patchList.at(2);
|
||||
patches.append(patch);
|
||||
}
|
||||
else {
|
||||
// Ignore unknown patch type
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result = patchFile(model->index(0, 0), guid, sectionType, patches);
|
||||
if (result && result != ERR_NOTHING_TO_PATCH)
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray reconstructed;
|
||||
result = ffsEngine->reconstructImageFile(reconstructed);
|
||||
if (result)
|
||||
return result;
|
||||
if (reconstructed == buffer)
|
||||
return ERR_NOTHING_TO_PATCH;
|
||||
|
||||
QFile outputFile;
|
||||
outputFile.setFileName(outputPath);
|
||||
if (!outputFile.open(QFile::WriteOnly))
|
||||
return ERR_FILE_WRITE;
|
||||
|
||||
outputFile.resize(0);
|
||||
outputFile.write(reconstructed);
|
||||
outputFile.close();
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT8 UEFIPatch::patchFile(const QModelIndex & index, const QByteArray & fileGuid, const UINT8 sectionType, const QVector<PatchData> & patches)
|
||||
{
|
||||
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
~UEFIPatch();
|
||||
|
||||
UINT8 patchFromFile(const QString & path, const QString & patches, const QString & outputPath);
|
||||
UINT8 patchFromArg(const QString & path, const QString & patch, const QString & outputPath);
|
||||
private:
|
||||
UINT8 patchFile(const QModelIndex & index, const QByteArray & fileGuid, const UINT8 sectionType, const QVector<PatchData> & patches);
|
||||
FfsEngine* ffsEngine;
|
||||
|
@ -33,7 +33,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (argumentsCount < 2) {
|
||||
std::cout << "UEFIPatch " PROGRAM_VERSION " - UEFI image file patching utility" << std::endl << std::endl <<
|
||||
"Usage: UEFIPatch image_file [patches.txt] [-o output]" << std::endl << std::endl <<
|
||||
"Usage: UEFIPatch image_file [patches.txt] [-o output]" << std::endl <<
|
||||
"Usage: UEFIPatch image_file [-p \"Guid SectionType Patch\"] [-o output]" << std::endl << std::endl <<
|
||||
"Patches will be read from patches.txt file by default\n";
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
@ -41,8 +42,13 @@ int main(int argc, char *argv[])
|
||||
QString inputPath = a.arguments().at(1);
|
||||
QString patches = "patches.txt";
|
||||
QString outputPath = inputPath + ".patched";
|
||||
int patchFrom = PATCH_FROM_FILE;
|
||||
for (UINT32 i = 2; i < argumentsCount; i++) {
|
||||
if ((args.at(i) == "-o" || args.at(i) == "--output") && i + 1 < argumentsCount) {
|
||||
if ((args.at(i) == "-p" || args.at(i) == "--patch") && i + 1 < argumentsCount) {
|
||||
patchFrom = PATCH_FROM_ARG;
|
||||
patches = args.at(i+1);
|
||||
i++;
|
||||
} else if ((args.at(i) == "-o" || args.at(i) == "--output") && i + 1 < argumentsCount) {
|
||||
outputPath = args.at(i+1);
|
||||
i++;
|
||||
} else if (patches == "patches.txt") {
|
||||
@ -53,7 +59,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (result == ERR_SUCCESS) {
|
||||
if (patchFrom == PATCH_FROM_FILE) {
|
||||
result = w.patchFromFile(inputPath, patches, outputPath);
|
||||
} else if (patchFrom == PATCH_FROM_ARG) {
|
||||
result = w.patchFromArg(inputPath, patches, outputPath);
|
||||
}
|
||||
}
|
||||
|
||||
switch (result) {
|
||||
|
@ -127,6 +127,10 @@ typedef size_t UINTN;
|
||||
#define PATCH_MODE_HEADER 0
|
||||
#define PATCH_MODE_BODY 1
|
||||
|
||||
// Patch from
|
||||
#define PATCH_FROM_FILE 0
|
||||
#define PATCH_FROM_ARG 1
|
||||
|
||||
// Patch types
|
||||
#define PATCH_TYPE_OFFSET 'O'
|
||||
#define PATCH_TYPE_PATTERN 'P'
|
||||
|
Loading…
Reference in New Issue
Block a user