mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-24 17:08:23 +08:00
Fix more builder issues and perform the initial UEFIReplace port
This commit is contained in:
parent
2d02eeab6d
commit
0169c8c904
1
.gitignore
vendored
1
.gitignore
vendored
@ -240,6 +240,7 @@ UEFITool/XCBuildData
|
|||||||
UEFIDump/UEFIDump
|
UEFIDump/UEFIDump
|
||||||
UEFIExtract/UEFIExtract
|
UEFIExtract/UEFIExtract
|
||||||
UEFIFind/UEFIFind
|
UEFIFind/UEFIFind
|
||||||
|
UEFIReplace/UEFIReplace
|
||||||
.qmake.stash
|
.qmake.stash
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
|
@ -133,7 +133,7 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
|
|||||||
if (!data.isEmpty()) {
|
if (!data.isEmpty()) {
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
UString str = name + UString("_header.bin");
|
UString str = name + UString("_header.bin");
|
||||||
file.open((const char*)str, std::ios::out | std::ios::binary);
|
file.open(str.toLocal8Bit(), std::ios::out | std::ios::binary);
|
||||||
file.write(data.constData(), data.size());
|
file.write(data.constData(), data.size());
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
|
|||||||
if (!data.isEmpty()) {
|
if (!data.isEmpty()) {
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
UString str = name + UString("_body.bin");
|
UString str = name + UString("_body.bin");
|
||||||
file.open((const char*)str, std::ios::out | std::ios::binary);
|
file.open(str.toLocal8Bit(), std::ios::out | std::ios::binary);
|
||||||
file.write(data.constData(), data.size());
|
file.write(data.constData(), data.size());
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
@ -157,8 +157,8 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
|
|||||||
|
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
UString str = name + UString("_info.txt");
|
UString str = name + UString("_info.txt");
|
||||||
file.open((const char*)str, std::ios::out);
|
file.open(str.toLocal8Bit(), std::ios::out);
|
||||||
file.write((const char*)info, info.length());
|
file.write(info.toLocal8Bit(), info.length());
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
dumped = true;
|
dumped = true;
|
||||||
|
@ -36,17 +36,12 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
// Check that input file exists
|
// Check that input file exists
|
||||||
|
USTATUS result;
|
||||||
|
UByteArray buffer;
|
||||||
UString path = argv[1];
|
UString path = argv[1];
|
||||||
if (!isExistOnFs(path))
|
result = readFileIntoArray(path, buffer);
|
||||||
return U_FILE_OPEN;
|
if (result)
|
||||||
|
return result;
|
||||||
// Open the input file
|
|
||||||
std::ifstream inputFile(argv[1], std::ios::in | std::ios::binary);
|
|
||||||
if (!inputFile)
|
|
||||||
return U_FILE_OPEN;
|
|
||||||
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
|
|
||||||
(std::istreambuf_iterator<char>()));
|
|
||||||
inputFile.close();
|
|
||||||
|
|
||||||
// Hack to support legacy UEFIDump mode.
|
// Hack to support legacy UEFIDump mode.
|
||||||
if (argc == 3 && !std::strcmp(argv[2], "unpack")) {
|
if (argc == 3 && !std::strcmp(argv[2], "unpack")) {
|
||||||
@ -58,7 +53,7 @@ int main(int argc, char *argv[])
|
|||||||
TreeModel model;
|
TreeModel model;
|
||||||
FfsParser ffsParser(&model);
|
FfsParser ffsParser(&model);
|
||||||
// Parse input buffer
|
// Parse input buffer
|
||||||
USTATUS result = ffsParser.parse(buffer);
|
result = ffsParser.parse(buffer);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
@ -32,16 +32,10 @@ UEFIFind::~UEFIFind()
|
|||||||
USTATUS UEFIFind::init(const UString & path)
|
USTATUS UEFIFind::init(const UString & path)
|
||||||
{
|
{
|
||||||
USTATUS result;
|
USTATUS result;
|
||||||
|
UByteArray buffer;
|
||||||
if (!isExistOnFs(path))
|
result = readFileIntoArray(path, buffer);
|
||||||
return U_FILE_OPEN;
|
if (result)
|
||||||
|
return result;
|
||||||
std::ifstream inputFile(path.toLocal8Bit(), std::ios::in | std::ios::binary);
|
|
||||||
if (!inputFile)
|
|
||||||
return U_FILE_OPEN;
|
|
||||||
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
|
|
||||||
(std::istreambuf_iterator<char>()));
|
|
||||||
inputFile.close();
|
|
||||||
|
|
||||||
result = ffsParser->parse(buffer);
|
result = ffsParser->parse(buffer);
|
||||||
if (result)
|
if (result)
|
||||||
|
69
UEFIReplace/CMakeLists.txt
Normal file
69
UEFIReplace/CMakeLists.txt
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
|
PROJECT(UEFIReplace)
|
||||||
|
|
||||||
|
SET(PROJECT_SOURCES
|
||||||
|
uefireplace_main.cpp
|
||||||
|
uefireplace.cpp
|
||||||
|
../common/guiddatabase.cpp
|
||||||
|
../common/types.cpp
|
||||||
|
../common/descriptor.cpp
|
||||||
|
../common/ffs.cpp
|
||||||
|
../common/nvram.cpp
|
||||||
|
../common/nvramparser.cpp
|
||||||
|
../common/ffsparser.cpp
|
||||||
|
../common/ffsbuilder.cpp
|
||||||
|
../common/ffsops.cpp
|
||||||
|
../common/peimage.cpp
|
||||||
|
../common/treeitem.cpp
|
||||||
|
../common/treemodel.cpp
|
||||||
|
../common/utility.cpp
|
||||||
|
../common/LZMA/LzmaCompress.c
|
||||||
|
../common/LZMA/LzmaDecompress.c
|
||||||
|
../common/LZMA/SDK/C/LzFind.c
|
||||||
|
../common/LZMA/SDK/C/LzmaDec.c
|
||||||
|
../common/LZMA/SDK/C/LzmaEnc.c
|
||||||
|
../common/Tiano/EfiTianoDecompress.c
|
||||||
|
../common/Tiano/EfiTianoCompress.c
|
||||||
|
../common/Tiano/EfiTianoCompressLegacy.c
|
||||||
|
../common/ustring.cpp
|
||||||
|
../common/sha256.c
|
||||||
|
../common/bstrlib/bstrlib.c
|
||||||
|
../common/bstrlib/bstrwrap.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(PROJECT_HEADERS
|
||||||
|
uefireplace.h
|
||||||
|
../common/guiddatabase.h
|
||||||
|
../common/basetypes.h
|
||||||
|
../common/descriptor.h
|
||||||
|
../common/gbe.h
|
||||||
|
../common/me.h
|
||||||
|
../common/ffs.h
|
||||||
|
../common/nvram.h
|
||||||
|
../common/nvramparser.h
|
||||||
|
../common/ffsparser.h
|
||||||
|
../common/ffsbuilder.h
|
||||||
|
../common/ffsops.h
|
||||||
|
../common/peimage.h
|
||||||
|
../common/types.h
|
||||||
|
../common/treeitem.h
|
||||||
|
../common/treemodel.h
|
||||||
|
../common/utility.h
|
||||||
|
../common/LZMA/LzmaDecompress.h
|
||||||
|
../common/Tiano/EfiTianoDecompress.h
|
||||||
|
../common/LZMA/LzmaCompress.h
|
||||||
|
../common/Tiano/EfiTianoCompress.h
|
||||||
|
../common/ubytearray.h
|
||||||
|
../common/ustring.h
|
||||||
|
../common/bootguard.h
|
||||||
|
../common/sha256.h
|
||||||
|
../common/filesystem.h
|
||||||
|
../common/bstrlib/bstrlib.h
|
||||||
|
../common/bstrlib/bstrwrap.h
|
||||||
|
../version.h
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-DU_ENABLE_NVRAM_PARSING_SUPPORT -DU_ENABLE_FIT_PARSING_SUPPORT -DU_ENABLE_GUID_DATABASE_SUPPORT)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(UEFIReplace ${PROJECT_SOURCES} ${PROJECT_HEADERS})
|
113
UEFIReplace/uefireplace.cpp
Executable file
113
UEFIReplace/uefireplace.cpp
Executable file
@ -0,0 +1,113 @@
|
|||||||
|
/* uefireplace.cpp
|
||||||
|
|
||||||
|
Copyright (c) 2017, mxxxc. 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
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uefireplace.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
UEFIReplace::UEFIReplace()
|
||||||
|
{
|
||||||
|
model = new TreeModel();
|
||||||
|
ffsParser = new FfsParser(model);
|
||||||
|
ffsBuilder = new FfsBuilder(model, ffsParser);
|
||||||
|
ffsOps = new FfsOperations(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
UEFIReplace::~UEFIReplace()
|
||||||
|
{
|
||||||
|
delete ffsOps;
|
||||||
|
delete ffsBuilder;
|
||||||
|
delete ffsParser;
|
||||||
|
delete model;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS UEFIReplace::replace(const UString & inPath, const EFI_GUID & guid, const UINT8 sectionType, const UString & contentPath, const UString & outPath, bool replaceAsIs, bool replaceOnce)
|
||||||
|
{
|
||||||
|
UByteArray buffer;
|
||||||
|
USTATUS result;
|
||||||
|
|
||||||
|
result = readFileIntoArray(inPath, buffer);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = ffsParser->parse(buffer);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
UByteArray contents;
|
||||||
|
result = readFileIntoArray(contentPath, contents);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = replaceInFile(model->index(0, 0), guid, sectionType, contents,
|
||||||
|
replaceAsIs ? REPLACE_MODE_AS_IS : REPLACE_MODE_BODY, replaceOnce);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
UByteArray reconstructed;
|
||||||
|
result = ffsBuilder->build(model->index(0,0), reconstructed);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
if (reconstructed == buffer)
|
||||||
|
return U_NOTHING_TO_PATCH;
|
||||||
|
|
||||||
|
std::ofstream outputFile;
|
||||||
|
outputFile.open(outPath.toLocal8Bit(), std::ios::out | std::ios::binary);
|
||||||
|
outputFile.write(reconstructed.constData(), reconstructed.size());
|
||||||
|
outputFile.close();
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS UEFIReplace::replaceInFile(const UModelIndex & index, const EFI_GUID & guid, const UINT8 sectionType, const UByteArray & newData, const UINT8 mode, bool replaceOnce)
|
||||||
|
{
|
||||||
|
if (!model || !index.isValid())
|
||||||
|
return U_INVALID_PARAMETER;
|
||||||
|
bool patched = false;
|
||||||
|
if (model->subtype(index) == sectionType) {
|
||||||
|
UModelIndex fileIndex = index;
|
||||||
|
if (model->type(index) != Types::File)
|
||||||
|
fileIndex = model->findParentOfType(index, Types::File);
|
||||||
|
UByteArray fileGuid = model->header(fileIndex).left(sizeof(EFI_GUID));
|
||||||
|
|
||||||
|
bool guidMatch = fileGuid.size() == sizeof(EFI_GUID) &&
|
||||||
|
!std::memcmp((const EFI_GUID*)fileGuid.constData(), &guid, sizeof(EFI_GUID));
|
||||||
|
if (!guidMatch && sectionType == EFI_SECTION_FREEFORM_SUBTYPE_GUID) {
|
||||||
|
UByteArray subGuid = model->header(index).mid(sizeof(UINT32), sizeof(EFI_GUID));
|
||||||
|
guidMatch = subGuid.size() == sizeof(EFI_GUID) &&
|
||||||
|
!std::memcmp((const EFI_GUID*)subGuid.constData(), &guid, sizeof(EFI_GUID));;
|
||||||
|
}
|
||||||
|
if (guidMatch && model->action(index) != Actions::Replace) {
|
||||||
|
UByteArray newDataCopy = newData;
|
||||||
|
USTATUS result = ffsOps->replace(index, newDataCopy, mode);
|
||||||
|
if (replaceOnce || (result != U_SUCCESS && result != U_NOTHING_TO_PATCH))
|
||||||
|
return result;
|
||||||
|
patched = result == U_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model->rowCount(index) > 0) {
|
||||||
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
|
USTATUS result = replaceInFile(index.child(i, 0), guid, sectionType, newData, mode, replaceOnce);
|
||||||
|
if (result == U_SUCCESS) {
|
||||||
|
patched = true;
|
||||||
|
if (replaceOnce)
|
||||||
|
break;
|
||||||
|
} else if (result != U_NOTHING_TO_PATCH) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return patched ? U_SUCCESS : U_NOTHING_TO_PATCH;
|
||||||
|
}
|
42
UEFIReplace/uefireplace.h
Executable file
42
UEFIReplace/uefireplace.h
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
/* uefireplace.h
|
||||||
|
Copyright (c) 2017, mxxxc. 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
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UEFIREPLACE_H__
|
||||||
|
#define __UEFIREPLACE_H__
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "../common/basetypes.h"
|
||||||
|
#include "../common/ustring.h"
|
||||||
|
#include "../common/filesystem.h"
|
||||||
|
#include "../common/ffs.h"
|
||||||
|
#include "../common/ffsparser.h"
|
||||||
|
#include "../common/ffsops.h"
|
||||||
|
#include "../common/ffsbuilder.h"
|
||||||
|
#include "../common/utility.h"
|
||||||
|
|
||||||
|
class UEFIReplace
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UEFIReplace();
|
||||||
|
~UEFIReplace();
|
||||||
|
|
||||||
|
USTATUS replace(const UString & inPath, const EFI_GUID & guid, const UINT8 sectionType, const UString & contentPath, const UString & outPath, bool replaceAsIs, bool replaceOnce);
|
||||||
|
|
||||||
|
private:
|
||||||
|
USTATUS replaceInFile(const UModelIndex & index, const EFI_GUID & guid, const UINT8 sectionType, const UByteArray & contents, const UINT8 mode, bool replaceOnce);
|
||||||
|
TreeModel* model;
|
||||||
|
FfsParser* ffsParser;
|
||||||
|
FfsBuilder* ffsBuilder;
|
||||||
|
FfsOperations* ffsOps;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
93
UEFIReplace/uefireplace_main.cpp
Executable file
93
UEFIReplace/uefireplace_main.cpp
Executable file
@ -0,0 +1,93 @@
|
|||||||
|
/* uefireplace_main.cpp
|
||||||
|
|
||||||
|
Copyright (c) 2017, mxxxc. 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
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "../version.h"
|
||||||
|
#include "uefireplace.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
UEFIReplace r;
|
||||||
|
USTATUS result = U_SUCCESS;
|
||||||
|
|
||||||
|
if (argc < 5) {
|
||||||
|
std::cout << "UEFIReplace " PROGRAM_VERSION " - UEFI image file replacement utility" << std::endl << std::endl <<
|
||||||
|
"Usage: UEFIReplace image_file guid section_type contents_file [-o output] [-all] [-asis]" << std::endl;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_GUID guid;
|
||||||
|
UString uuid = UString(argv[2]);
|
||||||
|
char *converted = const_cast<char *>(argv[3]);
|
||||||
|
UINT8 sectionType = (UINT8)std::strtol(argv[3], &converted, 16);
|
||||||
|
if (converted == argv[3] || !ustringToGuid(uuid, guid)) {
|
||||||
|
result = U_INVALID_PARAMETER;
|
||||||
|
} else {
|
||||||
|
UString output = UString(argv[1]) + ".patched";
|
||||||
|
bool replaceOnce = true;
|
||||||
|
bool replaceAsIs = false;
|
||||||
|
for (int i = 5, sz = argc; i < sz; i++) {
|
||||||
|
if ((!std::strcmp(argv[i], "-o") || !std::strcmp(argv[i], "--output")) && i + 1 < sz) {
|
||||||
|
output = argv[i+1];
|
||||||
|
i++;
|
||||||
|
} else if (!std::strcmp(argv[i], "-all")) {
|
||||||
|
replaceOnce = false;
|
||||||
|
} else if (!std::strcmp(argv[i], "-asis")) {
|
||||||
|
replaceAsIs = true;
|
||||||
|
} else {
|
||||||
|
result = U_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result == U_SUCCESS) {
|
||||||
|
result = r.replace(argv[1], guid, sectionType, argv[4], output, replaceAsIs, replaceOnce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case U_SUCCESS:
|
||||||
|
std::cout << "File replaced" << std::endl;
|
||||||
|
break;
|
||||||
|
case U_INVALID_PARAMETER:
|
||||||
|
std::cout << "Function called with invalid parameter" << std::endl;
|
||||||
|
break;
|
||||||
|
case U_INVALID_FILE:
|
||||||
|
std::cout << "Invalid/corrupted file specified" << std::endl;
|
||||||
|
break;
|
||||||
|
case U_INVALID_SECTION:
|
||||||
|
std::cout << "Invalid/corrupted section specified" << std::endl;
|
||||||
|
break;
|
||||||
|
case U_NOTHING_TO_PATCH:
|
||||||
|
std::cout << "No replacements can be applied to input file" << std::endl;
|
||||||
|
break;
|
||||||
|
case U_NOT_IMPLEMENTED:
|
||||||
|
std::cout << "Can't replace body of this section type" << std::endl;
|
||||||
|
break;
|
||||||
|
case U_FILE_OPEN:
|
||||||
|
std::cout << "Input file not found" << std::endl;
|
||||||
|
break;
|
||||||
|
case U_FILE_READ:
|
||||||
|
std::cout << "Input file can't be read" << std::endl;
|
||||||
|
break;
|
||||||
|
case U_FILE_WRITE:
|
||||||
|
std::cout << "Output file can't be written" << std::endl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cout << "Error " << result << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
@ -70,6 +70,7 @@ typedef size_t USTATUS;
|
|||||||
#define U_PEI_CORE_ENTRY_POINT_NOT_FOUND 48
|
#define U_PEI_CORE_ENTRY_POINT_NOT_FOUND 48
|
||||||
#define U_INVALID_STORE_SIZE 49
|
#define U_INVALID_STORE_SIZE 49
|
||||||
#define U_UNKNOWN_COMPRESSION_ALGORITHM 50
|
#define U_UNKNOWN_COMPRESSION_ALGORITHM 50
|
||||||
|
#define U_NOTHING_TO_PATCH 51
|
||||||
#define U_NOT_IMPLEMENTED 0xFF
|
#define U_NOT_IMPLEMENTED 0xFF
|
||||||
|
|
||||||
// UDK porting definitions
|
// UDK porting definitions
|
||||||
|
@ -363,6 +363,7 @@ struct CBString : public tagbstring {
|
|||||||
|
|
||||||
// QString compatibility methods
|
// QString compatibility methods
|
||||||
const char *toLocal8Bit() const { return *this; }
|
const char *toLocal8Bit() const { return *this; }
|
||||||
|
bool contains(const char *str) { return find(str) >= 0; }
|
||||||
bool isEmpty() const { return slen == 0; }
|
bool isEmpty() const { return slen == 0; }
|
||||||
void clear() { *this = ""; }
|
void clear() { *this = ""; }
|
||||||
CBString left(int len) const { return midstr(0, len); }
|
CBString left(int len) const { return midstr(0, len); }
|
||||||
|
@ -10,6 +10,8 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|||||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
#include "ffs.h"
|
#include "ffs.h"
|
||||||
#include "guiddatabase.h"
|
#include "guiddatabase.h"
|
||||||
|
|
||||||
@ -69,6 +71,32 @@ UString guidToUString(const EFI_GUID & guid, bool convertToString)
|
|||||||
guid.Data4[7]);
|
guid.Data4[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ustringToGuid(const UString & str, EFI_GUID & guid)
|
||||||
|
{
|
||||||
|
unsigned long p0;
|
||||||
|
int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
|
||||||
|
|
||||||
|
int err = std::sscanf(str.toLocal8Bit(), "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||||
|
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10);
|
||||||
|
if (err == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
guid.Data1 = p0;
|
||||||
|
guid.Data2 = p1;
|
||||||
|
guid.Data3 = p2;
|
||||||
|
guid.Data4[0] = p3;
|
||||||
|
guid.Data4[1] = p4;
|
||||||
|
guid.Data4[2] = p5;
|
||||||
|
guid.Data4[3] = p6;
|
||||||
|
guid.Data4[4] = p7;
|
||||||
|
guid.Data4[5] = p8;
|
||||||
|
guid.Data4[6] = p9;
|
||||||
|
guid.Data4[7] = p10;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
UString fileTypeToUString(const UINT8 type)
|
UString fileTypeToUString(const UINT8 type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -23,6 +23,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
|
|
||||||
extern UString guidToUString(const EFI_GUID& guid, bool convertToString = true);
|
extern UString guidToUString(const EFI_GUID& guid, bool convertToString = true);
|
||||||
|
extern bool ustringToGuid(const UString& str, EFI_GUID& guid);
|
||||||
extern UString fileTypeToUString(const UINT8 type);
|
extern UString fileTypeToUString(const UINT8 type);
|
||||||
extern UString sectionTypeToUString(const UINT8 type);
|
extern UString sectionTypeToUString(const UINT8 type);
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ USTATUS FfsBuilder::build(const UModelIndex & index, UByteArray & reconstructed)
|
|||||||
return result;
|
return result;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
msg(usprintf("build: unknown item type %1").arg(model->type(index)), index);
|
msg(usprintf("build: unknown item type %d", model->type(index)), index);
|
||||||
return U_UNKNOWN_ITEM_TYPE;
|
return U_UNKNOWN_ITEM_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,7 +978,8 @@ USTATUS FfsBuilder::buildNvramStore(const UModelIndex & index, UByteArray & stor
|
|||||||
// Recalculate store checksum
|
// Recalculate store checksum
|
||||||
UINT32 calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32));
|
UINT32 calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32));
|
||||||
// Write new checksum
|
// Write new checksum
|
||||||
body.replace((const UINT32)body.size() - sizeof(UINT32), sizeof(UINT32), (const char *)&calculatedCrc, sizeof(UINT32));
|
UINT32 *crc = reinterpret_cast<UINT32 *>(body.data() + body.size() - sizeof(UINT32));
|
||||||
|
std::memcpy(crc, &calculatedCrc, sizeof(UINT32));
|
||||||
}
|
}
|
||||||
else if(type == Types::EvsaStore) {
|
else if(type == Types::EvsaStore) {
|
||||||
UByteArray store = header + body;
|
UByteArray store = header + body;
|
||||||
@ -1048,7 +1049,7 @@ USTATUS FfsBuilder::buildPadFile(const UByteArray & guid, const UINT32 size, con
|
|||||||
return U_INVALID_PARAMETER;
|
return U_INVALID_PARAMETER;
|
||||||
|
|
||||||
pad = UByteArray(size - guid.size(), erasePolarity == ERASE_POLARITY_TRUE ? '\xFF' : '\x00');
|
pad = UByteArray(size - guid.size(), erasePolarity == ERASE_POLARITY_TRUE ? '\xFF' : '\x00');
|
||||||
pad.prepend(guid);
|
pad = guid + pad;
|
||||||
EFI_FFS_FILE_HEADER* header = (EFI_FFS_FILE_HEADER*)pad.data();
|
EFI_FFS_FILE_HEADER* header = (EFI_FFS_FILE_HEADER*)pad.data();
|
||||||
uint32ToUint24(size, header->Size);
|
uint32ToUint24(size, header->Size);
|
||||||
header->Attributes = 0x00;
|
header->Attributes = 0x00;
|
||||||
@ -1087,7 +1088,8 @@ USTATUS FfsBuilder::buildFile(const UModelIndex & index, const UINT8 revision, c
|
|||||||
if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||||
UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
|
UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
|
||||||
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
|
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
|
||||||
reconstructed += ht + ft;
|
reconstructed += UByteArray(1, (char)ht);
|
||||||
|
reconstructed += UByteArray(1, (char)ft);
|
||||||
}
|
}
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1244,7 +1246,8 @@ USTATUS FfsBuilder::buildFile(const UModelIndex & index, const UINT8 revision, c
|
|||||||
if (revision == 1 && fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
if (revision == 1 && fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
|
||||||
UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
|
UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
|
||||||
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
|
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
|
||||||
reconstructed += ht + ft;
|
reconstructed += UByteArray(1, (char)ht);
|
||||||
|
reconstructed += UByteArray(1, (char)ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set file state
|
// Set file state
|
||||||
@ -1372,22 +1375,21 @@ USTATUS FfsBuilder::buildSection(const UModelIndex & index, const UINT32 base, U
|
|||||||
*(UINT32*)(header.data() + sizeof(EFI_GUID_DEFINED_SECTION)) = crc;
|
*(UINT32*)(header.data() + sizeof(EFI_GUID_DEFINED_SECTION)) = crc;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg(usprintf("buildSection: GUID defined section authentication info can become invalid")
|
const char *guidStr = guidToUString(guidDefinedHeader->SectionDefinitionGuid).toLocal8Bit();
|
||||||
.arg(guidToUString(guidDefinedHeader->SectionDefinitionGuid)), index);
|
msg(usprintf("buildSection: GUID defined section signature can become invalid (%s)", guidStr), index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check for Intel signed section
|
// Check for Intel signed section
|
||||||
if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED
|
if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED
|
||||||
&& UByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
&& UByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
||||||
msg(usprintf("buildSection: GUID defined section signature can become invalid")
|
const char *guidStr = guidToUString(guidDefinedHeader->SectionDefinitionGuid).toLocal8Bit();
|
||||||
.arg(guidToUString(guidDefinedHeader->SectionDefinitionGuid)), index);
|
msg(usprintf("buildSection: GUID defined section signature can become invalid (%s)", guidStr), index);
|
||||||
}
|
}
|
||||||
// Replace new section body
|
// Replace new section body
|
||||||
reconstructed = compressed;
|
reconstructed = compressed;
|
||||||
}
|
}
|
||||||
else if (compression != COMPRESSION_ALGORITHM_NONE) {
|
else if (compression != COMPRESSION_ALGORITHM_NONE) {
|
||||||
msg(usprintf("buildSection: incorrectly required compression for section of type %1")
|
msg(usprintf("buildSection: incorrectly required compression for section of type %d", model->subtype(index)), index);
|
||||||
.arg(model->subtype(index)), index);
|
|
||||||
return U_INVALID_SECTION;
|
return U_INVALID_SECTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,20 +34,20 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
|
|||||||
extracted += model->tail(index);
|
extracted += model->tail(index);
|
||||||
}
|
}
|
||||||
else if (mode == EXTRACT_MODE_BODY) {
|
else if (mode == EXTRACT_MODE_BODY) {
|
||||||
name += QObject::tr("_body");
|
name += UString("_body");
|
||||||
// Extract without header and tail
|
// Extract without header and tail
|
||||||
extracted.clear();
|
extracted.clear();
|
||||||
extracted += model->body(index);
|
extracted += model->body(index);
|
||||||
}
|
}
|
||||||
else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
|
else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
|
||||||
name += QObject::tr("_body_unc");
|
name += UString("_body_unc");
|
||||||
// Extract without header and tail, uncompressed
|
// Extract without header and tail, uncompressed
|
||||||
extracted.clear();
|
extracted.clear();
|
||||||
// There is no need to redo decompression, we can use child items
|
// There is no need to redo decompression, we can use child items
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
UModelIndex childIndex = index.child(i, 0);
|
UModelIndex childIndex = index.child(i, 0);
|
||||||
// Ensure 4-byte alignment of current section
|
// Ensure 4-byte alignment of current section
|
||||||
extracted += UByteArray('\x00', ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size());
|
extracted += UByteArray(ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size(), '\x00');
|
||||||
// Add current section header, body and tail
|
// Add current section header, body and tail
|
||||||
extracted += model->header(childIndex);
|
extracted += model->header(childIndex);
|
||||||
extracted += model->body(childIndex);
|
extracted += model->body(childIndex);
|
||||||
@ -66,7 +66,6 @@ USTATUS FfsOperations::replace(const UModelIndex & index, UByteArray & data, con
|
|||||||
return U_INVALID_PARAMETER;
|
return U_INVALID_PARAMETER;
|
||||||
|
|
||||||
USTATUS result;
|
USTATUS result;
|
||||||
UByteArray empty = "";
|
|
||||||
FfsParser parser(model);
|
FfsParser parser(model);
|
||||||
UINT32 localOffset = model->offset(index) + model->header(index).size();
|
UINT32 localOffset = model->offset(index) + model->header(index).size();
|
||||||
UModelIndex index_out;
|
UModelIndex index_out;
|
||||||
@ -98,8 +97,8 @@ USTATUS FfsOperations::replace(const UModelIndex & index, UByteArray & data, con
|
|||||||
}
|
}
|
||||||
else if (model->type(index) == Types::Padding) {
|
else if (model->type(index) == Types::Padding) {
|
||||||
// Get info
|
// Get info
|
||||||
QString name = usprintf("Padding");
|
UString name = usprintf("Padding");
|
||||||
QString info = usprintf("Full size: %Xh (%u)", data.size(), data.size());
|
UString info = usprintf("Full size: %Xh (%u)", data.size(), data.size());
|
||||||
// Add tree item
|
// Add tree item
|
||||||
//!TODO UModelIndex fileIndex = model->addItem(Types::Padding, getPaddingType(body), COMPRESSION_ALGORITHM_NONE, name, "", info, UByteArray(), body, index, mode);
|
//!TODO UModelIndex fileIndex = model->addItem(Types::Padding, getPaddingType(body), COMPRESSION_ALGORITHM_NONE, name, "", info, UByteArray(), body, index, mode);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
#include "basetypes.h"
|
#include "basetypes.h"
|
||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
|
#include "ubytearray.h"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
@ -48,4 +50,20 @@ static inline bool changeDirectory(const UString & dir) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline USTATUS readFileIntoArray(const UString & inPath, UByteArray &array) {
|
||||||
|
if (!isExistOnFs(inPath))
|
||||||
|
return U_FILE_OPEN;
|
||||||
|
|
||||||
|
std::ifstream inputFile(inPath.toLocal8Bit(), std::ios::in | std::ios::binary);
|
||||||
|
if (!inputFile)
|
||||||
|
return U_FILE_OPEN;
|
||||||
|
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
|
||||||
|
(std::istreambuf_iterator<char>()));
|
||||||
|
inputFile.close();
|
||||||
|
|
||||||
|
array = buffer;
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,6 +12,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
#include "guiddatabase.h"
|
#include "guiddatabase.h"
|
||||||
#include "ubytearray.h"
|
#include "ubytearray.h"
|
||||||
|
#include "ffs.h"
|
||||||
|
|
||||||
#if defined(U_ENABLE_GUID_DATABASE_SUPPORT)
|
#if defined(U_ENABLE_GUID_DATABASE_SUPPORT)
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -86,27 +87,9 @@ void initGuidDatabase(const UString & path, UINT32* numEntries)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
EFI_GUID guid;
|
EFI_GUID guid;
|
||||||
|
if (!ustringToGuid(lineParts[0], guid))
|
||||||
unsigned long p0;
|
|
||||||
int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
|
|
||||||
|
|
||||||
int err = std::sscanf(lineParts[0].toLocal8Bit(), "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
|
||||||
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10);
|
|
||||||
if (err == 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
guid.Data1 = p0;
|
|
||||||
guid.Data2 = p1;
|
|
||||||
guid.Data3 = p2;
|
|
||||||
guid.Data4[0] = p3;
|
|
||||||
guid.Data4[1] = p4;
|
|
||||||
guid.Data4[2] = p5;
|
|
||||||
guid.Data4[3] = p6;
|
|
||||||
guid.Data4[4] = p7;
|
|
||||||
guid.Data4[5] = p8;
|
|
||||||
guid.Data4[6] = p9;
|
|
||||||
guid.Data4[7] = p10;
|
|
||||||
|
|
||||||
gGuidToUStringMap.insert(GuidToUStringMap::value_type(guid, lineParts[1]));
|
gGuidToUStringMap.insert(GuidToUStringMap::value_type(guid, lineParts[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,5 +115,6 @@ mkdir -p dist || exit 1
|
|||||||
build_tool UEFITool "$UEFITOOL_VER" uefitool.pro
|
build_tool UEFITool "$UEFITOOL_VER" uefitool.pro
|
||||||
build_tool UEFIExtract "$UEFITOOL_VER" ""
|
build_tool UEFIExtract "$UEFITOOL_VER" ""
|
||||||
build_tool UEFIFind "$UEFITOOL_VER" ""
|
build_tool UEFIFind "$UEFITOOL_VER" ""
|
||||||
|
build_tool UEFIReplace "$UEFITOOL_VER" ""
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
Loading…
Reference in New Issue
Block a user