mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-22 07:58:22 +08:00
Merge Qt/non-Qt codebase
- added UEFIDump tool, which is now Windows-only UEFIExtract with some limitations, made as PoC for non-Qt engine usage - ensured that Qt classes will be used, if available - checked build of UT and UE - porting of UEFIFind to non-Qt engine TBD
This commit is contained in:
parent
12029c768c
commit
9045fc6cc0
49
UEFIDump/CMakeLists.txt
Normal file
49
UEFIDump/CMakeLists.txt
Normal file
@ -0,0 +1,49 @@
|
||||
PROJECT(UEFIDump)
|
||||
|
||||
SET(PROJECT_SOURCES
|
||||
uefidump_main.cpp
|
||||
uefidump.cpp
|
||||
../common/types.cpp
|
||||
../common/descriptor.cpp
|
||||
../common/ffs.cpp
|
||||
../common/nvram.cpp
|
||||
../common/ffsparser.cpp
|
||||
../common/ffsreport.cpp
|
||||
../common/fitparser.cpp
|
||||
../common/peimage.cpp
|
||||
../common/treeitem.cpp
|
||||
../common/treemodel.cpp
|
||||
../common/utility.cpp
|
||||
../common/LZMA/LzmaDecompress.c
|
||||
../common/LZMA/SDK/C/LzmaDec.c
|
||||
../common/Tiano/EfiTianoDecompress.c
|
||||
../common/ustring.cpp
|
||||
../bstrlib/bstrlib.c
|
||||
../bstrlib/bstrwrap.cpp
|
||||
)
|
||||
|
||||
SET(PROJECT_HEADERS
|
||||
uefidump.h
|
||||
../common/basetypes.h
|
||||
../common/descriptor.h
|
||||
../common/gbe.h
|
||||
../common/me.h
|
||||
../common/ffs.h
|
||||
../common/nvram.h
|
||||
../common/ffsparser.h
|
||||
../common/ffsreport.h
|
||||
../common/fitparser.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/ubytearray.h
|
||||
../common/ustring.h
|
||||
../bstrlib/bstrlib.h
|
||||
../bstrlib/bstrwrap.h
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(UEFIDump ${PROJECT_SOURCES} ${PROJECT_HEADERS})
|
234
UEFIDump/uefidump.cpp
Normal file
234
UEFIDump/uefidump.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
/* ffsdumper.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. 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 <windows.h>
|
||||
|
||||
#include "uefidump.h"
|
||||
#include "../common/ffs.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
USTATUS UEFIDumper::dump(const UByteArray & buffer, const std::wstring & inPath, const std::wstring & guid)
|
||||
{
|
||||
//TODO: rework to support relative paths
|
||||
std::wstring path = std::wstring(inPath).append(L".dump2");
|
||||
path = L"\\\\?\\" + path;
|
||||
std::wstring reportPath = std::wstring(inPath).append(L".report2.txt");
|
||||
reportPath = L"\\\\?\\" + reportPath;
|
||||
std::wcout << L"Dump path: " << path << std::endl;
|
||||
std::wcout << L"Report path: " << reportPath << std::endl;
|
||||
|
||||
|
||||
if (initialized) {
|
||||
// Check if called with a different buffer as before
|
||||
if (buffer != currentBuffer) {
|
||||
// Reinitalize if so
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
// Fill currentBuffer
|
||||
currentBuffer = buffer;
|
||||
|
||||
// Parse FFS structure
|
||||
USTATUS result = ffsParser.parse(buffer);
|
||||
if (result)
|
||||
return result;
|
||||
// Show ffsParser messages
|
||||
std::vector<std::pair<UString, UModelIndex> > messages = ffsParser.getMessages();
|
||||
for (size_t i = 0; i < messages.size(); i++) {
|
||||
std::cout << messages[i].first << std::endl;
|
||||
}
|
||||
|
||||
// Get last VTF
|
||||
UModelIndex lastVtf = ffsParser.getLastVtf();
|
||||
if (lastVtf.isValid()) {
|
||||
// Create fitParser
|
||||
FitParser fitParser(&model);
|
||||
// Find and parse FIT table
|
||||
result = fitParser.parse(model.index(0, 0), lastVtf);
|
||||
if (U_SUCCESS == result) {
|
||||
// Show fitParser's messages
|
||||
std::vector<std::pair<UString, UModelIndex> > fitMessages = fitParser.getMessages();
|
||||
for (size_t i = 0; i < fitMessages.size(); i++) {
|
||||
std::cout << (const char*)fitMessages[i].first.toLocal8Bit() << std::endl;
|
||||
}
|
||||
|
||||
// Show FIT table
|
||||
std::vector<std::vector<UString> > fitTable = fitParser.getFitTable();
|
||||
if (fitTable.size()) {
|
||||
std::cout << "-------------------------------------------------------------------" << std::endl;
|
||||
std::cout << " Address | Size | Ver | Type | CS " << std::endl;
|
||||
std::cout << "-------------------------------------------------------------------" << std::endl;
|
||||
for (size_t i = 0; i < fitTable.size(); i++) {
|
||||
std::cout << (const char*)fitTable[i][0].toLocal8Bit() << " | "
|
||||
<< (const char*)fitTable[i][1].toLocal8Bit() << " | "
|
||||
<< (const char*)fitTable[i][2].toLocal8Bit() << " | "
|
||||
<< (const char*)fitTable[i][3].toLocal8Bit() << " | "
|
||||
<< (const char*)fitTable[i][4].toLocal8Bit() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create ffsReport
|
||||
FfsReport ffsReport(&model);
|
||||
std::vector<UString> report = ffsReport.generate();
|
||||
if (report.size()) {
|
||||
std::ofstream ofs;
|
||||
ofs.open(reportPath, std::ofstream::out);
|
||||
for (size_t i = 0; i < report.size(); i++) {
|
||||
ofs << (const char*)report[i].toLocal8Bit() << std::endl;
|
||||
}
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
dumped = false;
|
||||
UINT8 result = recursiveDump(model.index(0,0), path, guid);
|
||||
if (result)
|
||||
return result;
|
||||
else if (!dumped)
|
||||
return U_ITEM_NOT_FOUND;
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
std::wstring UEFIDumper::guidToWstring(const EFI_GUID & guid)
|
||||
{
|
||||
std::wstringstream ws;
|
||||
|
||||
ws << std::hex << std::uppercase << std::setfill(L'0');
|
||||
ws << std::setw(8) << *(const UINT32*)&guid.Data[0] << L"-";
|
||||
ws << std::setw(4) << *(const UINT16*)&guid.Data[4] << L"-";
|
||||
ws << std::setw(4) << *(const UINT16*)&guid.Data[6] << L"-";
|
||||
ws << std::setw(2) << guid.Data[8];
|
||||
ws << std::setw(2) << guid.Data[9] << L"-";
|
||||
ws << std::setw(2) << guid.Data[10];
|
||||
ws << std::setw(2) << guid.Data[11];
|
||||
ws << std::setw(2) << guid.Data[12];
|
||||
ws << std::setw(2) << guid.Data[13];
|
||||
ws << std::setw(2) << guid.Data[14];
|
||||
ws << std::setw(2) << guid.Data[15];
|
||||
|
||||
return ws.str();
|
||||
}
|
||||
|
||||
bool UEFIDumper::createFullPath(const std::wstring & path) {
|
||||
|
||||
// Break the path into parent\current, assuming the path is already full and converted into Windows native "\\?\" format
|
||||
size_t pos = path.find_last_of(L'\\');
|
||||
|
||||
// Slash is not found, it's a bug
|
||||
if (pos == path.npos)
|
||||
return FALSE;
|
||||
|
||||
std::wstring parent = path.substr(0, pos);
|
||||
std::wstring current = path.substr(pos + 1);
|
||||
|
||||
// Check if first exist, if so, create last and return true
|
||||
UINT32 attributes = GetFileAttributesW(parent.c_str());
|
||||
if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
// first is already exist, just create last
|
||||
return CreateDirectoryW(path.c_str(), NULL) != 0;
|
||||
}
|
||||
|
||||
// Perform recursive call
|
||||
if (createFullPath(parent))
|
||||
return CreateDirectoryW(path.c_str(), NULL) != 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
USTATUS UEFIDumper::recursiveDump(const UModelIndex & index, const std::wstring & path, const std::wstring & guid)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
UByteArray itemHeader = model.header(index);
|
||||
UByteArray fileHeader = model.header(model.findParentOfType(index, Types::File));
|
||||
|
||||
if (guid.length() == 0 ||
|
||||
(itemHeader.size() >= sizeof (EFI_GUID) && guidToWstring(*(const EFI_GUID*)itemHeader.constData()) == guid) ||
|
||||
(fileHeader.size() >= sizeof(EFI_GUID) && guidToWstring(*(const EFI_GUID*)fileHeader.constData()) == guid)) {
|
||||
|
||||
if (SetCurrentDirectoryW(path.c_str()))
|
||||
return U_DIR_ALREADY_EXIST;
|
||||
|
||||
if (!createFullPath(path))
|
||||
return U_DIR_CREATE;
|
||||
|
||||
//if (model.rowCount(index) == 0) {
|
||||
// Header
|
||||
UByteArray data = model.header(index);
|
||||
if (!data.isEmpty()) {
|
||||
std::ofstream file;
|
||||
std::wstring name = path + std::wstring(L"\\header.bin");
|
||||
file.open(name, std::ios::out | std::ios::binary);
|
||||
file.write(data.constData(), data.size());
|
||||
file.close();
|
||||
}
|
||||
|
||||
// Body
|
||||
data = model.body(index);
|
||||
if (!data.isEmpty()) {
|
||||
std::ofstream file;
|
||||
std::wstring name = path + std::wstring(L"\\body.bin");
|
||||
file.open(name, std::ios::out | std::ios::binary);
|
||||
file.write(data.constData(), data.size());
|
||||
file.close();
|
||||
}
|
||||
//}
|
||||
// Info
|
||||
UString info = "Type: " + itemTypeToUString(model.type(index)) + "\n" +
|
||||
"Subtype: " + itemSubtypeToUString(model.type(index), model.subtype(index)) + "\n";
|
||||
if (model.text(index).length() > 0)
|
||||
info += "Text: " + model.text(index) + "\n";
|
||||
info += model.info(index) + "\n";
|
||||
|
||||
std::ofstream file;
|
||||
std::wstring name = path + std::wstring(L"\\info.txt");
|
||||
file.open(name, std::ios::out);
|
||||
file.write((const char*)info, info.length());
|
||||
file.close();
|
||||
|
||||
dumped = true;
|
||||
}
|
||||
|
||||
UINT8 result;
|
||||
for (int i = 0; i < model.rowCount(index); i++) {
|
||||
UModelIndex childIndex = index.child(i, 0);
|
||||
bool useText = false;
|
||||
if (model.type(childIndex) != Types::Volume)
|
||||
useText = (model.text(childIndex).length() > 0);
|
||||
|
||||
UString name = useText ? (const char *)model.text(childIndex) : (const char *)model.name(childIndex);
|
||||
std::string sName = std::string((const char*)name, name.length());
|
||||
std::wstring childPath = path + std::wstring(L"\\") + std::to_wstring(i) + std::wstring(L" ") + std::wstring(sName.begin(), sName.end());
|
||||
|
||||
// Workaround for paths with dot at the end, just add remove it
|
||||
if (childPath.at(childPath.length() - 1) == L'.')
|
||||
childPath.pop_back();
|
||||
|
||||
result = recursiveDump(childIndex, childPath, guid);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
50
UEFIDump/uefidump.h
Normal file
50
UEFIDump/uefidump.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* uefidump.h
|
||||
|
||||
Copyright (c) 2016, Nikolaj Schlej. 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 UEFIDUMP_H
|
||||
#define UEFIDUMP_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../common/basetypes.h"
|
||||
#include "../common/ustring.h"
|
||||
#include "../common/treemodel.h"
|
||||
#include "../common/ffsparser.h"
|
||||
#include "../common/ffsreport.h"
|
||||
#include "../common/fitparser.h"
|
||||
|
||||
|
||||
class UEFIDumper
|
||||
{
|
||||
public:
|
||||
explicit UEFIDumper() : model(), ffsParser(&model), ffsReport(&model), fitParser(&model), currentBuffer(), initialized(false), dumped(false) {}
|
||||
~UEFIDumper() {}
|
||||
|
||||
USTATUS dump(const UByteArray & buffer, const std::wstring & path, const std::wstring & guid = std::wstring());
|
||||
|
||||
private:
|
||||
USTATUS recursiveDump(const UModelIndex & root, const std::wstring & path, const std::wstring & guid);
|
||||
std::wstring guidToWstring(const EFI_GUID & guid);
|
||||
bool createFullPath(const std::wstring & path);
|
||||
|
||||
TreeModel model;
|
||||
FfsParser ffsParser;
|
||||
FfsReport ffsReport;
|
||||
FitParser fitParser;
|
||||
|
||||
UByteArray currentBuffer;
|
||||
bool initialized;
|
||||
bool dumped;
|
||||
};
|
||||
|
||||
#endif
|
43
UEFIDump/uefidump_main.cpp
Normal file
43
UEFIDump/uefidump_main.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/* uefidump_main.cpp
|
||||
|
||||
Copyright (c) 2016, Nikolaj Schlej. 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 "uefidump.h"
|
||||
|
||||
int wmain(int argc, wchar_t *argv[])
|
||||
{
|
||||
if (argc > 32) {
|
||||
std::cout << "Too many arguments" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
std::ifstream inputFile;
|
||||
inputFile.open(argv[1], std::ios::in | std::ios::binary);
|
||||
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
|
||||
(std::istreambuf_iterator<char>()));
|
||||
inputFile.close();
|
||||
|
||||
UEFIDumper uefidumper;
|
||||
return (uefidumper.dump(buffer, std::wstring(argv[1])) != U_SUCCESS);
|
||||
}
|
||||
else {
|
||||
std::cout << "UEFIDump 0.1.0" << std::endl << std::endl
|
||||
<< "Usage: UEFIExtract imagefile " << std::endl
|
||||
<< "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
@ -23,9 +23,7 @@ SOURCES += \
|
||||
../common/LZMA/LzmaDecompress.c \
|
||||
../common/LZMA/SDK/C/LzmaDec.c \
|
||||
../common/Tiano/EfiTianoDecompress.c \
|
||||
../common/ustring.cpp \
|
||||
../bstrlib/bstrlib.c \
|
||||
../bstrlib/bstrwrap.cpp
|
||||
../common/ustring.cpp
|
||||
|
||||
HEADERS += \
|
||||
ffsdumper.h \
|
||||
@ -46,7 +44,5 @@ HEADERS += \
|
||||
../common/LZMA/LzmaDecompress.h \
|
||||
../common/Tiano/EfiTianoDecompress.h \
|
||||
../common/ubytearray.h \
|
||||
../common/ustring.h \
|
||||
../bstrlib/bstrlib.h \
|
||||
../bstrlib/bstrwrap.h
|
||||
../common/ustring.h
|
||||
|
||||
|
@ -20,6 +20,7 @@ SOURCES += uefifind_main.cpp \
|
||||
../common/LZMA/LzmaDecompress.c \
|
||||
../common/LZMA/SDK/C/LzmaDec.c \
|
||||
../common/Tiano/EfiTianoDecompress.c \
|
||||
../common/ustring.cpp
|
||||
|
||||
HEADERS += uefifind.h \
|
||||
../common/basetypes.h \
|
||||
@ -35,5 +36,7 @@ HEADERS += uefifind.h \
|
||||
../common/treemodel.h \
|
||||
../common/utility.h \
|
||||
../common/LZMA/LzmaDecompress.h \
|
||||
../common/Tiano/EfiTianoDecompress.h
|
||||
../common/Tiano/EfiTianoDecompress.h \
|
||||
../common/ustring.h \
|
||||
../common/ubytearray.h
|
||||
|
||||
|
@ -13,24 +13,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include "ffsfinder.h"
|
||||
|
||||
STATUS FfsFinder::findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode)
|
||||
USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
|
||||
if (hexPattern.isEmpty())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// Check for "all substrings" pattern
|
||||
if (hexPattern.count('.') == hexPattern.length())
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
|
||||
bool hasChildren = (model->rowCount(index) > 0);
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
findHexPattern(index.child(i, index.column()), hexPattern, mode);
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
UByteArray data;
|
||||
if (hasChildren) {
|
||||
if (mode != SEARCH_MODE_BODY)
|
||||
data = model->header(index);
|
||||
@ -44,39 +44,37 @@ STATUS FfsFinder::findHexPattern(const QModelIndex & index, const QByteArray & h
|
||||
data.append(model->header(index)).append(model->body(index));
|
||||
}
|
||||
|
||||
QString hexBody = QString(data.toHex());
|
||||
QRegExp regexp = QRegExp(QString(hexPattern), Qt::CaseInsensitive);
|
||||
UString hexBody = UString(data.toHex());
|
||||
QRegExp regexp = QRegExp(UString(hexPattern), Qt::CaseInsensitive);
|
||||
INT32 offset = regexp.indexIn(hexBody);
|
||||
while (offset >= 0) {
|
||||
if (offset % 2 == 0) {
|
||||
msg(QObject::tr("Hex pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h")
|
||||
.arg(QString(hexPattern))
|
||||
.arg(hexBody.mid(offset, hexPattern.length()).toUpper())
|
||||
.arg(model->name(index))
|
||||
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
|
||||
.hexarg(offset / 2),
|
||||
msg(UString("Hex pattern \"") + UString(hexPattern)
|
||||
+ UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper()
|
||||
+ UString("\" in ") + model->name(index)
|
||||
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
|
||||
index);
|
||||
}
|
||||
offset = regexp.indexIn(hexBody, offset + 1);
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
STATUS FfsFinder::findGuidPattern(const QModelIndex & index, const QByteArray & guidPattern, const UINT8 mode)
|
||||
USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode)
|
||||
{
|
||||
if (guidPattern.isEmpty())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
if (!index.isValid())
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
|
||||
bool hasChildren = (model->rowCount(index) > 0);
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
findGuidPattern(index.child(i, index.column()), guidPattern, mode);
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
UByteArray data;
|
||||
if (hasChildren) {
|
||||
if (mode != SEARCH_MODE_BODY)
|
||||
data = model->header(index);
|
||||
@ -90,12 +88,12 @@ STATUS FfsFinder::findGuidPattern(const QModelIndex & index, const QByteArray &
|
||||
data.append(model->header(index)).append(model->body(index));
|
||||
}
|
||||
|
||||
QString hexBody = QString(data.toHex());
|
||||
QList<QByteArray> list = guidPattern.split('-');
|
||||
UString hexBody = UString(data.toHex());
|
||||
QList<UByteArray> list = guidPattern.split('-');
|
||||
if (list.count() != 5)
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
QByteArray hexPattern;
|
||||
UByteArray hexPattern;
|
||||
// Reverse first GUID block
|
||||
hexPattern.append(list.at(0).mid(6, 2));
|
||||
hexPattern.append(list.at(0).mid(4, 2));
|
||||
@ -112,40 +110,38 @@ STATUS FfsFinder::findGuidPattern(const QModelIndex & index, const QByteArray &
|
||||
|
||||
// Check for "all substrings" pattern
|
||||
if (hexPattern.count('.') == hexPattern.length())
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
|
||||
QRegExp regexp(QString(hexPattern), Qt::CaseInsensitive);
|
||||
QRegExp regexp(UString(hexPattern), Qt::CaseInsensitive);
|
||||
INT32 offset = regexp.indexIn(hexBody);
|
||||
while (offset >= 0) {
|
||||
if (offset % 2 == 0) {
|
||||
msg(QObject::tr("GUID pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h")
|
||||
.arg(QString(guidPattern))
|
||||
.arg(hexBody.mid(offset, hexPattern.length()).toUpper())
|
||||
.arg(model->name(index))
|
||||
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
|
||||
.hexarg(offset / 2),
|
||||
msg(UString("GUID pattern \"") + UString(guidPattern)
|
||||
+ UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper()
|
||||
+ UString("\" in ") + model->name(index)
|
||||
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
|
||||
index);
|
||||
}
|
||||
offset = regexp.indexIn(hexBody, offset + 1);
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
STATUS FfsFinder::findTextPattern(const QModelIndex & index, const QString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive)
|
||||
USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive)
|
||||
{
|
||||
if (pattern.isEmpty())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
if (!index.isValid())
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
|
||||
bool hasChildren = (model->rowCount(index) > 0);
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
findTextPattern(index.child(i, index.column()), pattern, mode, unicode, caseSensitive);
|
||||
}
|
||||
|
||||
QByteArray body;
|
||||
UByteArray body;
|
||||
if (hasChildren) {
|
||||
if (mode != SEARCH_MODE_BODY)
|
||||
body = model->header(index);
|
||||
@ -159,22 +155,20 @@ STATUS FfsFinder::findTextPattern(const QModelIndex & index, const QString & pat
|
||||
body.append(model->header(index)).append(model->body(index));
|
||||
}
|
||||
|
||||
QString data;
|
||||
UString data;
|
||||
if (unicode)
|
||||
data = QString::fromUtf16((const ushort*)body.constData(), body.length() / 2);
|
||||
data = UString::fromUtf16((const ushort*)body.constData(), body.length() / 2);
|
||||
else
|
||||
data = QString::fromLatin1((const char*)body.constData(), body.length());
|
||||
data = UString::fromLatin1((const char*)body.constData(), body.length());
|
||||
|
||||
int offset = -1;
|
||||
while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) {
|
||||
msg(QObject::tr("%1 text \"%2\" found in %3 at %4-offset %5h")
|
||||
.arg(unicode ? "Unicode" : "ASCII")
|
||||
.arg(pattern)
|
||||
.arg(model->name(index))
|
||||
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
|
||||
.hexarg(unicode ? offset * 2 : offset),
|
||||
|
||||
msg((unicode ? UString("Unicode") : UString("ASCII")) + UString(" text \"") + UString(pattern)
|
||||
+ UString("\" found in ") + model->name(index)
|
||||
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", (unicode ? offset * 2 : offset)),
|
||||
index);
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
@ -15,13 +15,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#define FFSFINDER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QModelIndex>
|
||||
#include <QRegExp>
|
||||
|
||||
#include "../common/ubytearray.h"
|
||||
#include "../common/ustring.h"
|
||||
#include "../common/basetypes.h"
|
||||
#include "../common/treemodel.h"
|
||||
|
||||
@ -31,19 +28,19 @@ public:
|
||||
FfsFinder(const TreeModel * treeModel) : model(treeModel) {}
|
||||
~FfsFinder() {}
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
|
||||
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
|
||||
void clearMessages() { messagesVector.clear(); }
|
||||
|
||||
STATUS findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode);
|
||||
STATUS findGuidPattern(const QModelIndex & index, const QByteArray & guidPattern, const UINT8 mode);
|
||||
STATUS findTextPattern(const QModelIndex & index, const QString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive);
|
||||
USTATUS findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode);
|
||||
USTATUS findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode);
|
||||
USTATUS findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive);
|
||||
|
||||
private:
|
||||
const TreeModel* model;
|
||||
std::vector<std::pair<QString, QModelIndex> > messagesVector;
|
||||
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
||||
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
||||
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
UEFITool::UEFITool(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::UEFITool),
|
||||
version(tr("0.30.0_alpha28"))
|
||||
version(tr("0.30.0_alpha29"))
|
||||
{
|
||||
clipboard = QApplication::clipboard();
|
||||
|
||||
@ -211,7 +211,7 @@ bool UEFITool::enableExtractBodyUncompressed(const QModelIndex ¤t)
|
||||
if (current.isValid() && model->type(current) == Types::Section &&
|
||||
(model->subtype(current) == EFI_SECTION_COMPRESSION || model->subtype(current) == EFI_SECTION_GUID_DEFINED)) {
|
||||
// Get parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(current);
|
||||
PARSING_DATA pdata = parsingDataFromUModelIndex(current);
|
||||
|
||||
if (model->subtype(current) == EFI_SECTION_COMPRESSION &&
|
||||
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_NONE &&
|
||||
@ -297,7 +297,7 @@ void UEFITool::goToData()
|
||||
QModelIndex parent = model->parent(index);
|
||||
|
||||
for (int i = index.row(); i < model->rowCount(parent); i++) {
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
|
||||
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0;
|
||||
if (pdata.nvar.next == lastVariableFlag) {
|
||||
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
||||
@ -306,7 +306,7 @@ void UEFITool::goToData()
|
||||
|
||||
for (int j = i + 1; j < model->rowCount(parent); j++) {
|
||||
QModelIndex currentIndex = parent.child(j, 0);
|
||||
PARSING_DATA currentPdata = parsingDataFromQModelIndex(currentIndex);
|
||||
PARSING_DATA currentPdata = parsingDataFromUModelIndex(currentIndex);
|
||||
if (currentPdata.offset == pdata.offset + pdata.nvar.next) {
|
||||
index = currentIndex;
|
||||
break;
|
||||
@ -481,7 +481,7 @@ void UEFITool::replace(const UINT8 mode)
|
||||
|
||||
UINT8 result = ffsOps->replace(index, buffer, mode);
|
||||
if (result) {
|
||||
QMessageBox::critical(this, tr("Replacing failed"), errorCodeToQString(result), QMessageBox::Ok);
|
||||
QMessageBox::critical(this, tr("Replacing failed"), errorCodeToUString(result), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
ui->actionSaveImageFile->setEnabled(true);
|
||||
@ -512,7 +512,7 @@ void UEFITool::extract(const UINT8 mode)
|
||||
QString name;
|
||||
UINT8 result = ffsOps->extract(index, name, extracted, mode);
|
||||
if (result) {
|
||||
QMessageBox::critical(this, tr("Extraction failed"), errorCodeToQString(result), QMessageBox::Ok);
|
||||
QMessageBox::critical(this, tr("Extraction failed"), errorCodeToUString(result), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -609,21 +609,21 @@ void UEFITool::extract(const UINT8 mode)
|
||||
|
||||
void UEFITool::rebuild()
|
||||
{
|
||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (ERR_SUCCESS == ffsOps->rebuild(index))
|
||||
if (U_SUCCESS == ffsOps->rebuild(index))
|
||||
ui->actionSaveImageFile->setEnabled(true);
|
||||
}
|
||||
|
||||
void UEFITool::remove()
|
||||
{
|
||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (ERR_SUCCESS == ffsOps->remove(index))
|
||||
if (U_SUCCESS == ffsOps->remove(index))
|
||||
ui->actionSaveImageFile->setEnabled(true);
|
||||
}
|
||||
|
||||
@ -661,10 +661,10 @@ void UEFITool::saveImageFile()
|
||||
// Create ffsBuilder
|
||||
delete ffsBuilder;
|
||||
ffsBuilder = new FfsBuilder(model);
|
||||
STATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
|
||||
USTATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
|
||||
showBuilderMessages();
|
||||
if (result) {
|
||||
QMessageBox::critical(this, tr("Image build failed"), errorCodeToQString(result), QMessageBox::Ok);
|
||||
QMessageBox::critical(this, tr("Image build failed"), errorCodeToUString(result), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -725,7 +725,7 @@ void UEFITool::openImageFile(QString path)
|
||||
UINT8 result = ffsParser->parse(buffer);
|
||||
showParserMessages();
|
||||
if (result) {
|
||||
QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToQString(result), QMessageBox::Ok);
|
||||
QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToUString(result), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -29,7 +29,8 @@ SOURCES += uefitool_main.cpp \
|
||||
../common/LZMA/SDK/C/LzmaEnc.c \
|
||||
../common/Tiano/EfiTianoDecompress.c \
|
||||
../common/Tiano/EfiTianoCompress.c \
|
||||
../common/Tiano/EfiTianoCompressLegacy.c
|
||||
../common/Tiano/EfiTianoCompressLegacy.c \
|
||||
../common/ustring.cpp \
|
||||
|
||||
HEADERS += uefitool.h \
|
||||
searchdialog.h \
|
||||
@ -56,7 +57,9 @@ HEADERS += uefitool.h \
|
||||
../common/LZMA/LzmaCompress.h \
|
||||
../common/LZMA/LzmaDecompress.h \
|
||||
../common/Tiano/EfiTianoDecompress.h \
|
||||
../common/Tiano/EfiTianoCompress.h
|
||||
../common/Tiano/EfiTianoCompress.h \
|
||||
../common/ustring.h \
|
||||
../common/ubytearray.h \
|
||||
|
||||
FORMS += uefitool.ui \
|
||||
searchdialog.ui
|
||||
|
@ -75,7 +75,7 @@ UINT32 *DestinationSize
|
||||
if (*DestinationSize < destLen)
|
||||
{
|
||||
*DestinationSize = destLen;
|
||||
return ERR_BUFFER_TOO_SMALL;
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
LzmaEncProps_Init(&props);
|
||||
@ -101,9 +101,9 @@ UINT32 *DestinationSize
|
||||
SetEncodedSizeOfBuf((UINT64)SourceSize, Destination);
|
||||
|
||||
if (LzmaResult == SZ_OK) {
|
||||
return ERR_SUCCESS;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
@ -12,22 +12,22 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
#include "ffsbuilder.h"
|
||||
|
||||
STATUS FfsBuilder::erase(const QModelIndex & index, QByteArray & erased)
|
||||
USTATUS FfsBuilder::erase(const UModelIndex & index, UByteArray & erased)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
|
||||
erased.fill(pdata.emptyByte);
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
|
||||
USTATUS FfsBuilder::build(const UModelIndex & root, UByteArray & image)
|
||||
{
|
||||
// Sanity check
|
||||
if (!root.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
if (model->type(root) == Types::Capsule) {
|
||||
return buildCapsule(root, image);
|
||||
@ -41,44 +41,44 @@ STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
||||
USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// No action required
|
||||
if (model->action(index) == Actions::NoAction) {
|
||||
// Use original item data
|
||||
capsule = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Rebuild or Replace
|
||||
else if (model->action(index) == Actions::Rebuild
|
||||
|| model->action(index) == Actions::Replace) {
|
||||
if (model->rowCount(index)) {
|
||||
// Clear the supplied QByteArray
|
||||
// Clear the supplied UByteArray
|
||||
capsule.clear();
|
||||
|
||||
// Right now there is only one capsule image element supported
|
||||
if (model->rowCount(index) != 1) {
|
||||
msg(QObject::tr("buildCapsule: building of capsules with %1 elements are not supported, original item data is used").arg(model->rowCount(index)), index);
|
||||
//msg(UString("buildCapsule: building of capsules with %1 elements are not supported, original item data is used").arg(model->rowCount(index)), index);
|
||||
// Use original item data
|
||||
capsule = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Build image
|
||||
QModelIndex imageIndex = index.child(0, 0);
|
||||
QByteArray imageData;
|
||||
UModelIndex imageIndex = index.child(0, 0);
|
||||
UByteArray imageData;
|
||||
|
||||
// Check image type
|
||||
if (model->type(imageIndex) == Types::Image) {
|
||||
STATUS result = ERR_SUCCESS;
|
||||
USTATUS result = U_SUCCESS;
|
||||
if (model->subtype(imageIndex) == Subtypes::IntelImage) {
|
||||
result = buildIntelImage(imageIndex, imageData);
|
||||
}
|
||||
@ -86,20 +86,20 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
||||
result = buildRawArea(imageIndex, imageData);
|
||||
}
|
||||
else {
|
||||
msg(QObject::tr("buildCapsule: unexpected item of subtype %1 can't be processed, original item data is used").arg(model->subtype(imageIndex)), imageIndex);
|
||||
//msg(UString("buildCapsule: unexpected item of subtype %1 can't be processed, original item data is used").arg(model->subtype(imageIndex)), imageIndex);
|
||||
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
|
||||
}
|
||||
|
||||
// Check build result
|
||||
if (result) {
|
||||
msg(QObject::tr("buildCapsule: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(imageIndex)).arg(errorCodeToQString(result)), imageIndex);
|
||||
//msg(UString("buildCapsule: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(imageIndex)).arg(errorCodeToUString(result)), imageIndex);
|
||||
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
|
||||
}
|
||||
else
|
||||
capsule.append(imageData);
|
||||
}
|
||||
else {
|
||||
msg(QObject::tr("buildCapsule: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(imageIndex)), imageIndex);
|
||||
//msg(UString("buildCapsule: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(imageIndex)), imageIndex);
|
||||
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
|
||||
}
|
||||
|
||||
@ -107,14 +107,14 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
||||
UINT32 newSize = capsule.size();
|
||||
UINT32 oldSize = model->body(index).size();
|
||||
if (newSize > oldSize) {
|
||||
msg(QObject::tr("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
//msg(UString("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)")
|
||||
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
|
||||
return U_INVALID_PARAMETER;
|
||||
}
|
||||
else if (newSize < oldSize) {
|
||||
msg(QObject::tr("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
//msg(UString("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)")
|
||||
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return U_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -122,23 +122,23 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
||||
|
||||
// Build successful, append header
|
||||
capsule = model->header(index).append(capsule);
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
msg(QObject::tr("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
//msg(UString("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intelImage)
|
||||
USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & intelImage)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
|
||||
// No action
|
||||
if (model->action(index) == Actions::NoAction) {
|
||||
intelImage = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Rebuild
|
||||
@ -150,7 +150,7 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
|
||||
|
||||
// Process other regions
|
||||
for (int i = 1; i < model->rowCount(index); i++) {
|
||||
QModelIndex currentRegion = index.child(i, 0);
|
||||
UModelIndex currentRegion = index.child(i, 0);
|
||||
|
||||
// Skip regions with Remove action
|
||||
if (model->action(currentRegion) == Actions::Remove)
|
||||
@ -165,15 +165,15 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
|
||||
}
|
||||
|
||||
// Check region subtype
|
||||
STATUS result;
|
||||
QByteArray region;
|
||||
USTATUS result;
|
||||
UByteArray region;
|
||||
UINT8 regionType = model->subtype(currentRegion);
|
||||
switch (regionType) {
|
||||
case Subtypes::BiosRegion:
|
||||
case Subtypes::PdrRegion:
|
||||
result = buildRawArea(currentRegion, region);
|
||||
if (result) {
|
||||
msg(QObject::tr("buildIntelImage: building of %1 region failed with error \"%2\", original item data is used").arg(regionTypeToQString(regionType)).arg(errorCodeToQString(result)), currentRegion);
|
||||
//msg(UString("buildIntelImage: building of %1 region failed with error \"%2\", original item data is used").arg(regionTypeToQString(regionType)).arg(errorCodeToQString(result)), currentRegion);
|
||||
region = model->header(currentRegion).append(model->body(currentRegion));
|
||||
}
|
||||
break;
|
||||
@ -188,8 +188,8 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
|
||||
region = model->header(currentRegion).append(model->body(currentRegion));
|
||||
break;
|
||||
default:
|
||||
msg(QObject::tr("buildIntelImage: don't know how to build region of unknown type"), index);
|
||||
return ERR_UNKNOWN_ITEM_TYPE;
|
||||
msg(UString("buildIntelImage: don't know how to build region of unknown type"), index);
|
||||
return U_UNKNOWN_ITEM_TYPE;
|
||||
}
|
||||
|
||||
// Append the resulting region
|
||||
@ -200,48 +200,48 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
|
||||
UINT32 newSize = intelImage.size();
|
||||
UINT32 oldSize = model->body(index).size();
|
||||
if (newSize > oldSize) {
|
||||
msg(QObject::tr("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
//msg(UString("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)")
|
||||
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return U_INVALID_PARAMETER;
|
||||
}
|
||||
else if (newSize < oldSize) {
|
||||
msg(QObject::tr("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
//msg(UString("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)")
|
||||
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return U_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Reconstruction successful
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
msg(QObject::tr("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
//msg(UString("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader)
|
||||
USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// No action required
|
||||
if (model->action(index) == Actions::NoAction) {
|
||||
rawArea = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Rebuild or Replace
|
||||
else if (model->action(index) == Actions::Rebuild
|
||||
|| model->action(index) == Actions::Replace) {
|
||||
if (model->rowCount(index)) {
|
||||
// Clear the supplied QByteArray
|
||||
// Clear the supplied UByteArray
|
||||
rawArea.clear();
|
||||
|
||||
// Build children
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
STATUS result = ERR_SUCCESS;
|
||||
QModelIndex currentChild = index.child(i, 0);
|
||||
QByteArray currentData;
|
||||
USTATUS result = U_SUCCESS;
|
||||
UModelIndex currentChild = index.child(i, 0);
|
||||
UByteArray currentData;
|
||||
// Check child type
|
||||
if (model->type(currentChild) == Types::Volume) {
|
||||
result = buildVolume(currentChild, currentData);
|
||||
@ -250,12 +250,12 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
|
||||
result = buildPadding(currentChild, currentData);
|
||||
}
|
||||
else {
|
||||
msg(QObject::tr("buildRawArea: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(currentChild)), currentChild);
|
||||
//msg(UString("buildRawArea: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(currentChild)), currentChild);
|
||||
currentData = model->header(currentChild).append(model->body(currentChild));
|
||||
}
|
||||
// Check build result
|
||||
if (result) {
|
||||
msg(QObject::tr("buildRawArea: building of %1 failed with error \"%2\", original item data is used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
|
||||
//msg(UString("buildRawArea: building of %1 failed with error \"%2\", original item data is used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
|
||||
currentData = model->header(currentChild).append(model->body(currentChild));
|
||||
}
|
||||
// Append current data
|
||||
@ -266,14 +266,14 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
|
||||
UINT32 newSize = rawArea.size();
|
||||
UINT32 oldSize = model->body(index).size();
|
||||
if (newSize > oldSize) {
|
||||
msg(QObject::tr("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
//msg(UString("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)")
|
||||
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return U_INVALID_PARAMETER;
|
||||
}
|
||||
else if (newSize < oldSize) {
|
||||
msg(QObject::tr("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)")
|
||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return ERR_INVALID_PARAMETER;
|
||||
//msg(UString("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)")
|
||||
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||
return U_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -282,95 +282,95 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
|
||||
// Build successful, add header if needed
|
||||
if (addHeader)
|
||||
rawArea = model->header(index).append(rawArea);
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
msg(QObject::tr("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
//msg(UString("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildPadding(const QModelIndex & index, QByteArray & padding)
|
||||
USTATUS FfsBuilder::buildPadding(const UModelIndex & index, UByteArray & padding)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// No action required
|
||||
if (model->action(index) == Actions::NoAction) {
|
||||
padding = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Erase
|
||||
else if (model->action(index) == Actions::Erase) {
|
||||
padding = model->header(index).append(model->body(index));
|
||||
if(erase(index, padding))
|
||||
msg(QObject::tr("buildPadding: erase failed, original item data is used"), index);
|
||||
return ERR_SUCCESS;
|
||||
msg(UString("buildPadding: erase failed, original item data is used"), index);
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
msg(QObject::tr("buildPadding: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
//msg(UString("buildPadding: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index);
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildNonUefiData(const QModelIndex & index, QByteArray & data)
|
||||
USTATUS FfsBuilder::buildNonUefiData(const UModelIndex & index, UByteArray & data)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// No action required
|
||||
if (model->action(index) == Actions::NoAction) {
|
||||
data = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Erase
|
||||
else if (model->action(index) == Actions::Erase) {
|
||||
data = model->header(index).append(model->body(index));
|
||||
if (erase(index, data))
|
||||
msg(QObject::tr("buildNonUefiData: erase failed, original item data is used"), index);
|
||||
return ERR_SUCCESS;
|
||||
msg(UString("buildNonUefiData: erase failed, original item data is used"), index);
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
msg(QObject::tr("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
//msg(UString("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index);
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildFreeSpace(const QModelIndex & index, QByteArray & freeSpace)
|
||||
USTATUS FfsBuilder::buildFreeSpace(const UModelIndex & index, UByteArray & freeSpace)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// No action required
|
||||
if (model->action(index) == Actions::NoAction) {
|
||||
freeSpace = model->header(index).append(model->body(index));
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
msg(QObject::tr("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
//msg(UString("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildVolume(const QModelIndex & index, QByteArray & volume)
|
||||
USTATUS FfsBuilder::buildVolume(const UModelIndex & index, UByteArray & volume)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildPadFile(const QModelIndex & index, QByteArray & padFile)
|
||||
USTATUS FfsBuilder::buildPadFile(const UModelIndex & index, UByteArray & padFile)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildFile(const QModelIndex & index, QByteArray & file)
|
||||
USTATUS FfsBuilder::buildFile(const UModelIndex & index, UByteArray & file)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::buildSection(const QModelIndex & index, QByteArray & section)
|
||||
USTATUS FfsBuilder::buildSection(const UModelIndex & index, UByteArray & section)
|
||||
{
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,11 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include "ubytearray.h"
|
||||
#include "ustring.h"
|
||||
#include "basetypes.h"
|
||||
#include "treemodel.h"
|
||||
#include "descriptor.h"
|
||||
@ -33,31 +30,31 @@ public:
|
||||
FfsBuilder(const TreeModel * treeModel) : model(treeModel) {}
|
||||
~FfsBuilder() {}
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
|
||||
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
|
||||
void clearMessages() { messagesVector.clear(); }
|
||||
|
||||
STATUS build(const QModelIndex & root, QByteArray & image);
|
||||
USTATUS build(const UModelIndex & root, UByteArray & image);
|
||||
|
||||
private:
|
||||
const TreeModel* model;
|
||||
std::vector<std::pair<QString, QModelIndex> > messagesVector;
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
||||
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
||||
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
|
||||
}
|
||||
|
||||
STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule);
|
||||
STATUS buildIntelImage(const QModelIndex & index, QByteArray & intelImage);
|
||||
STATUS buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader = true);
|
||||
STATUS buildPadding(const QModelIndex & index, QByteArray & padding);
|
||||
STATUS buildVolume(const QModelIndex & index, QByteArray & volume);
|
||||
STATUS buildNonUefiData(const QModelIndex & index, QByteArray & data);
|
||||
STATUS buildFreeSpace(const QModelIndex & index, QByteArray & freeSpace);
|
||||
STATUS buildPadFile(const QModelIndex & index, QByteArray & padFile);
|
||||
STATUS buildFile(const QModelIndex & index, QByteArray & file);
|
||||
STATUS buildSection(const QModelIndex & index, QByteArray & section);
|
||||
USTATUS buildCapsule(const UModelIndex & index, UByteArray & capsule);
|
||||
USTATUS buildIntelImage(const UModelIndex & index, UByteArray & intelImage);
|
||||
USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader = true);
|
||||
USTATUS buildPadding(const UModelIndex & index, UByteArray & padding);
|
||||
USTATUS buildVolume(const UModelIndex & index, UByteArray & volume);
|
||||
USTATUS buildNonUefiData(const UModelIndex & index, UByteArray & data);
|
||||
USTATUS buildFreeSpace(const UModelIndex & index, UByteArray & freeSpace);
|
||||
USTATUS buildPadFile(const UModelIndex & index, UByteArray & padFile);
|
||||
USTATUS buildFile(const UModelIndex & index, UByteArray & file);
|
||||
USTATUS buildSection(const UModelIndex & index, UByteArray & section);
|
||||
|
||||
// Utility functions
|
||||
STATUS erase(const QModelIndex & index, QByteArray & erased);
|
||||
USTATUS erase(const UModelIndex & index, UByteArray & erased);
|
||||
};
|
||||
|
||||
#endif // FFSBUILDER_H
|
||||
|
@ -13,24 +13,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include "ffsops.h"
|
||||
|
||||
STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode)
|
||||
USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// Get data from parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
|
||||
|
||||
// Construct a name for extracted data
|
||||
QString itemName = model->name(index);
|
||||
QString itemText = model->text(index);
|
||||
UString itemName = model->name(index);
|
||||
UString itemText = model->text(index);
|
||||
|
||||
// Default name
|
||||
name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_');
|
||||
|
||||
switch (model->type(index)) {
|
||||
case Types::Volume: if (pdata.volume.hasExtendedHeader) name = guidToQString(pdata.volume.extendedHeaderGuid).replace('-', '_'); break;
|
||||
case Types::Volume: if (pdata.volume.hasExtendedHeader) name = guidToUString(pdata.volume.extendedHeaderGuid).replace('-', '_'); break;
|
||||
case Types::NvarEntry:
|
||||
case Types::VssEntry:
|
||||
case Types::FsysEntry:
|
||||
@ -39,11 +39,11 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
|
||||
case Types::File: name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_').replace('-', '_'); break;
|
||||
case Types::Section: {
|
||||
// Get parent file name
|
||||
QModelIndex fileIndex = model->findParentOfType(index, Types::File);
|
||||
QString fileText = model->text(fileIndex);
|
||||
UModelIndex fileIndex = model->findParentOfType(index, Types::File);
|
||||
UString fileText = model->text(fileIndex);
|
||||
name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_').replace('-', '_');
|
||||
// Append section subtype name
|
||||
name += QChar('_') + itemName.replace(' ', '_');
|
||||
name += '_' + itemName.replace(' ', '_');
|
||||
} break;
|
||||
}
|
||||
|
||||
@ -67,9 +67,9 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
|
||||
extracted.clear();
|
||||
// There is no need to redo decompression, we can use child items
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
QModelIndex childIndex = index.child(i, 0);
|
||||
UModelIndex childIndex = index.child(i, 0);
|
||||
// Ensure 4-byte alignment of current section
|
||||
extracted.append(QByteArray('\x00', ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size()));
|
||||
extracted.append(UByteArray('\x00', ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size()));
|
||||
// Add current section header, body and tail
|
||||
extracted.append(model->header(childIndex));
|
||||
extracted.append(model->body(childIndex));
|
||||
@ -77,49 +77,49 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
|
||||
}
|
||||
}
|
||||
else
|
||||
return ERR_UNKNOWN_EXTRACT_MODE;
|
||||
return U_UNKNOWN_EXTRACT_MODE;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
STATUS FfsOperations::replace(const QModelIndex & index, const QString & data, const UINT8 mode)
|
||||
USTATUS FfsOperations::replace(const UModelIndex & index, const UString & data, const UINT8 mode)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// Get data from parsing data
|
||||
//PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||
|
||||
if (mode == REPLACE_MODE_AS_IS) {
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
else if (mode == REPLACE_MODE_BODY) {
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
else
|
||||
return ERR_UNKNOWN_REPLACE_MODE;
|
||||
return U_UNKNOWN_REPLACE_MODE;
|
||||
|
||||
return ERR_NOT_IMPLEMENTED;
|
||||
return U_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
STATUS FfsOperations::remove(const QModelIndex & index)
|
||||
USTATUS FfsOperations::remove(const UModelIndex & index)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// Set remove action
|
||||
model->setAction(index, Actions::Remove);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
STATUS FfsOperations::rebuild(const QModelIndex & index)
|
||||
USTATUS FfsOperations::rebuild(const UModelIndex & index)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
return U_INVALID_PARAMETER;
|
||||
|
||||
// On insert action, set insert action for children
|
||||
//if (action == Actions::Insert)
|
||||
@ -130,10 +130,10 @@ STATUS FfsOperations::rebuild(const QModelIndex & index)
|
||||
model->setAction(index, Actions::Rebuild);
|
||||
|
||||
// Rebuild parent, if it has no action now
|
||||
QModelIndex parent = index.parent();
|
||||
UModelIndex parent = index.parent();
|
||||
if (parent.isValid() && model->type(parent) != Types::Root
|
||||
&& model->action(parent) == Actions::NoAction)
|
||||
rebuild(parent);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
@ -16,11 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include "ubytearray.h"
|
||||
#include "ustring.h"
|
||||
#include "basetypes.h"
|
||||
#include "treemodel.h"
|
||||
#include "ffs.h"
|
||||
@ -33,21 +30,21 @@ public:
|
||||
FfsOperations(TreeModel * treeModel) : model(treeModel) {}
|
||||
~FfsOperations() {};
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
|
||||
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
|
||||
void clearMessages() { messagesVector.clear(); }
|
||||
|
||||
STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode);
|
||||
STATUS replace(const QModelIndex & index, const QString & data, const UINT8 mode);
|
||||
USTATUS extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode);
|
||||
USTATUS replace(const UModelIndex & index, const UString & data, const UINT8 mode);
|
||||
|
||||
STATUS remove(const QModelIndex & index);
|
||||
STATUS rebuild(const QModelIndex & index);
|
||||
USTATUS remove(const UModelIndex & index);
|
||||
USTATUS rebuild(const UModelIndex & index);
|
||||
|
||||
private:
|
||||
TreeModel* model;
|
||||
std::vector<std::pair<QString, QModelIndex> > messagesVector;
|
||||
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
||||
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
||||
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1605,7 +1605,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 parentO
|
||||
}
|
||||
|
||||
// Construct parsing data
|
||||
bool fixed(fileHeader->Attributes & FFS_ATTRIB_FIXED);
|
||||
bool fixed = (fileHeader->Attributes & FFS_ATTRIB_FIXED) != 0;
|
||||
pdata.offset += parentOffset;
|
||||
|
||||
|
||||
@ -4543,7 +4543,7 @@ USTATUS FfsParser::parseFsysStoreBody(const UModelIndex & index)
|
||||
pdata.offset = parentOffset + offset;
|
||||
|
||||
// Add tree item
|
||||
model->addItem(Types::FsysEntry, 0, UString(name.constData(), name.size()), UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index);
|
||||
model->addItem(Types::FsysEntry, 0, UString(name.constData()), UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index);
|
||||
|
||||
// Move to next variable
|
||||
offset += variableSize;
|
||||
|
@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include "treeitem.h"
|
||||
#include "treemodel.h"
|
||||
|
||||
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL)
|
||||
#if defined(QT_CORE_LIB)
|
||||
QVariant TreeModel::data(const UModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
|
@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#ifndef TREEMODEL_H
|
||||
#define TREEMODEL_H
|
||||
|
||||
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL)
|
||||
#if defined(QT_CORE_LIB)
|
||||
// Use Qt classes
|
||||
#include <QAbstractItemModel>
|
||||
#include <QModelIndex>
|
||||
@ -73,7 +73,7 @@ private:
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL)
|
||||
#if defined(QT_CORE_LIB)
|
||||
class TreeModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -165,7 +165,7 @@ public:
|
||||
UModelIndex findParentOfType(const UModelIndex & index, UINT8 type) const;
|
||||
};
|
||||
|
||||
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL)
|
||||
#if defined(QT_CORE_LIB)
|
||||
// Nothing required here
|
||||
#else
|
||||
inline UModelIndex UModelIndex::parent() const { return m ? m->parent(*this) : UModelIndex(); }
|
||||
|
@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#ifndef UBYTEARRAY_H
|
||||
#define UBYTEARRAY_H
|
||||
|
||||
#if defined(QT_CORE_LIB) && defined(U_USE_QBYTEARRAY)
|
||||
#if defined(QT_CORE_LIB)
|
||||
// Use Qt class, if Qt is available
|
||||
#include <QByteArray>
|
||||
#define UByteArray QByteArray
|
||||
@ -61,13 +61,13 @@ public:
|
||||
inline void swap(UByteArray &other) { std::swap(d, other.d); }
|
||||
UByteArray toHex() {
|
||||
std::basic_string<char> hex(size() * 2, '\x00');
|
||||
for (int32_t i = 0; i < size(); ++i) {
|
||||
for (int32_t i = 0; i < size(); i++) {
|
||||
uint8_t low = d[i] & 0x0F;
|
||||
uint8_t high = (d[i] & 0xF0) >> 4;
|
||||
low += (low < 10 ? 'a' : '0');
|
||||
high += (high < 10 ? 'a' : '0');
|
||||
hex[i] = low;
|
||||
hex[i + 1] = high;
|
||||
low += (low < 10 ? '0' : 'a');
|
||||
high += (high < 10 ? '0' : 'a');
|
||||
hex[2*i] = low;
|
||||
hex[2*i + 1] = high;
|
||||
}
|
||||
std::reverse(hex.begin(), hex.end());
|
||||
return UByteArray(hex);
|
||||
|
@ -13,9 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include "ustring.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
//TODO: modify properly
|
||||
|
||||
#if defined(QT_CORE_LIB) && defined (U_USE_QSTRING)
|
||||
#if defined(QT_CORE_LIB)
|
||||
UString usprintf(const char* fmt, ...)
|
||||
{
|
||||
UString msg;
|
||||
|
@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#ifndef USTRING_H
|
||||
#define USTRING_H
|
||||
|
||||
#if defined (QT_CORE_LIB) && defined(U_USE_QSTRING)
|
||||
#if defined (QT_CORE_LIB)
|
||||
// Use Qt class, if Qt is available
|
||||
#include <QString>
|
||||
#define UString QString
|
||||
|
@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#define UTILITY_H
|
||||
|
||||
#include "ustring.h"
|
||||
#include "treemodel.h"
|
||||
#include "basetypes.h"
|
||||
#include "parsingdata.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user