mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-22 16:08: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;
|
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)
|
UINT8 UEFIPatch::patchFile(const QModelIndex & index, const QByteArray & fileGuid, const UINT8 sectionType, const QVector<PatchData> & patches)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ public:
|
|||||||
~UEFIPatch();
|
~UEFIPatch();
|
||||||
|
|
||||||
UINT8 patchFromFile(const QString & path, const QString & patches, const QString & outputPath);
|
UINT8 patchFromFile(const QString & path, const QString & patches, const QString & outputPath);
|
||||||
|
UINT8 patchFromArg(const QString & path, const QString & patch, const QString & outputPath);
|
||||||
private:
|
private:
|
||||||
UINT8 patchFile(const QModelIndex & index, const QByteArray & fileGuid, const UINT8 sectionType, const QVector<PatchData> & patches);
|
UINT8 patchFile(const QModelIndex & index, const QByteArray & fileGuid, const UINT8 sectionType, const QVector<PatchData> & patches);
|
||||||
FfsEngine* ffsEngine;
|
FfsEngine* ffsEngine;
|
||||||
|
@ -33,7 +33,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (argumentsCount < 2) {
|
if (argumentsCount < 2) {
|
||||||
std::cout << "UEFIPatch " PROGRAM_VERSION " - UEFI image file patching utility" << std::endl << std::endl <<
|
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";
|
"Patches will be read from patches.txt file by default\n";
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -41,8 +42,13 @@ int main(int argc, char *argv[])
|
|||||||
QString inputPath = a.arguments().at(1);
|
QString inputPath = a.arguments().at(1);
|
||||||
QString patches = "patches.txt";
|
QString patches = "patches.txt";
|
||||||
QString outputPath = inputPath + ".patched";
|
QString outputPath = inputPath + ".patched";
|
||||||
|
int patchFrom = PATCH_FROM_FILE;
|
||||||
for (UINT32 i = 2; i < argumentsCount; i++) {
|
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);
|
outputPath = args.at(i+1);
|
||||||
i++;
|
i++;
|
||||||
} else if (patches == "patches.txt") {
|
} else if (patches == "patches.txt") {
|
||||||
@ -53,7 +59,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == ERR_SUCCESS) {
|
if (result == ERR_SUCCESS) {
|
||||||
result = w.patchFromFile(inputPath, patches, outputPath);
|
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) {
|
switch (result) {
|
||||||
|
@ -127,6 +127,10 @@ typedef size_t UINTN;
|
|||||||
#define PATCH_MODE_HEADER 0
|
#define PATCH_MODE_HEADER 0
|
||||||
#define PATCH_MODE_BODY 1
|
#define PATCH_MODE_BODY 1
|
||||||
|
|
||||||
|
// Patch from
|
||||||
|
#define PATCH_FROM_FILE 0
|
||||||
|
#define PATCH_FROM_ARG 1
|
||||||
|
|
||||||
// Patch types
|
// Patch types
|
||||||
#define PATCH_TYPE_OFFSET 'O'
|
#define PATCH_TYPE_OFFSET 'O'
|
||||||
#define PATCH_TYPE_PATTERN 'P'
|
#define PATCH_TYPE_PATTERN 'P'
|
||||||
|
Loading…
Reference in New Issue
Block a user