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:
Nikolaj Schlej 2016-07-07 07:57:45 +02:00
parent 12029c768c
commit 9045fc6cc0
22 changed files with 612 additions and 250 deletions

49
UEFIDump/CMakeLists.txt Normal file
View 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
View 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
View 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

View 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;
}

View File

@ -23,9 +23,7 @@ SOURCES += \
../common/LZMA/LzmaDecompress.c \ ../common/LZMA/LzmaDecompress.c \
../common/LZMA/SDK/C/LzmaDec.c \ ../common/LZMA/SDK/C/LzmaDec.c \
../common/Tiano/EfiTianoDecompress.c \ ../common/Tiano/EfiTianoDecompress.c \
../common/ustring.cpp \ ../common/ustring.cpp
../bstrlib/bstrlib.c \
../bstrlib/bstrwrap.cpp
HEADERS += \ HEADERS += \
ffsdumper.h \ ffsdumper.h \
@ -46,7 +44,5 @@ HEADERS += \
../common/LZMA/LzmaDecompress.h \ ../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h \ ../common/Tiano/EfiTianoDecompress.h \
../common/ubytearray.h \ ../common/ubytearray.h \
../common/ustring.h \ ../common/ustring.h
../bstrlib/bstrlib.h \
../bstrlib/bstrwrap.h

View File

@ -20,6 +20,7 @@ SOURCES += uefifind_main.cpp \
../common/LZMA/LzmaDecompress.c \ ../common/LZMA/LzmaDecompress.c \
../common/LZMA/SDK/C/LzmaDec.c \ ../common/LZMA/SDK/C/LzmaDec.c \
../common/Tiano/EfiTianoDecompress.c \ ../common/Tiano/EfiTianoDecompress.c \
../common/ustring.cpp
HEADERS += uefifind.h \ HEADERS += uefifind.h \
../common/basetypes.h \ ../common/basetypes.h \
@ -35,5 +36,7 @@ HEADERS += uefifind.h \
../common/treemodel.h \ ../common/treemodel.h \
../common/utility.h \ ../common/utility.h \
../common/LZMA/LzmaDecompress.h \ ../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h ../common/Tiano/EfiTianoDecompress.h \
../common/ustring.h \
../common/ubytearray.h

View File

@ -13,24 +13,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsfinder.h" #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()) if (!index.isValid())
return ERR_SUCCESS; return U_SUCCESS;
if (hexPattern.isEmpty()) if (hexPattern.isEmpty())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Check for "all substrings" pattern // Check for "all substrings" pattern
if (hexPattern.count('.') == hexPattern.length()) if (hexPattern.count('.') == hexPattern.length())
return ERR_SUCCESS; return U_SUCCESS;
bool hasChildren = (model->rowCount(index) > 0); bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
findHexPattern(index.child(i, index.column()), hexPattern, mode); findHexPattern(index.child(i, index.column()), hexPattern, mode);
} }
QByteArray data; UByteArray data;
if (hasChildren) { if (hasChildren) {
if (mode != SEARCH_MODE_BODY) if (mode != SEARCH_MODE_BODY)
data = model->header(index); 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)); data.append(model->header(index)).append(model->body(index));
} }
QString hexBody = QString(data.toHex()); UString hexBody = UString(data.toHex());
QRegExp regexp = QRegExp(QString(hexPattern), Qt::CaseInsensitive); QRegExp regexp = QRegExp(UString(hexPattern), Qt::CaseInsensitive);
INT32 offset = regexp.indexIn(hexBody); INT32 offset = regexp.indexIn(hexBody);
while (offset >= 0) { while (offset >= 0) {
if (offset % 2 == 0) { if (offset % 2 == 0) {
msg(QObject::tr("Hex pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h") msg(UString("Hex pattern \"") + UString(hexPattern)
.arg(QString(hexPattern)) + UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper()
.arg(hexBody.mid(offset, hexPattern.length()).toUpper()) + UString("\" in ") + model->name(index)
.arg(model->name(index)) + usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
.hexarg(offset / 2),
index); index);
} }
offset = regexp.indexIn(hexBody, offset + 1); 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()) if (guidPattern.isEmpty())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
if (!index.isValid()) if (!index.isValid())
return ERR_SUCCESS; return U_SUCCESS;
bool hasChildren = (model->rowCount(index) > 0); bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
findGuidPattern(index.child(i, index.column()), guidPattern, mode); findGuidPattern(index.child(i, index.column()), guidPattern, mode);
} }
QByteArray data; UByteArray data;
if (hasChildren) { if (hasChildren) {
if (mode != SEARCH_MODE_BODY) if (mode != SEARCH_MODE_BODY)
data = model->header(index); 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)); data.append(model->header(index)).append(model->body(index));
} }
QString hexBody = QString(data.toHex()); UString hexBody = UString(data.toHex());
QList<QByteArray> list = guidPattern.split('-'); QList<UByteArray> list = guidPattern.split('-');
if (list.count() != 5) if (list.count() != 5)
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
QByteArray hexPattern; UByteArray hexPattern;
// Reverse first GUID block // Reverse first GUID block
hexPattern.append(list.at(0).mid(6, 2)); hexPattern.append(list.at(0).mid(6, 2));
hexPattern.append(list.at(0).mid(4, 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 // Check for "all substrings" pattern
if (hexPattern.count('.') == hexPattern.length()) 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); INT32 offset = regexp.indexIn(hexBody);
while (offset >= 0) { while (offset >= 0) {
if (offset % 2 == 0) { if (offset % 2 == 0) {
msg(QObject::tr("GUID pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h") msg(UString("GUID pattern \"") + UString(guidPattern)
.arg(QString(guidPattern)) + UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper()
.arg(hexBody.mid(offset, hexPattern.length()).toUpper()) + UString("\" in ") + model->name(index)
.arg(model->name(index)) + usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
.hexarg(offset / 2),
index); index);
} }
offset = regexp.indexIn(hexBody, offset + 1); 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()) if (pattern.isEmpty())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
if (!index.isValid()) if (!index.isValid())
return ERR_SUCCESS; return U_SUCCESS;
bool hasChildren = (model->rowCount(index) > 0); bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
findTextPattern(index.child(i, index.column()), pattern, mode, unicode, caseSensitive); findTextPattern(index.child(i, index.column()), pattern, mode, unicode, caseSensitive);
} }
QByteArray body; UByteArray body;
if (hasChildren) { if (hasChildren) {
if (mode != SEARCH_MODE_BODY) if (mode != SEARCH_MODE_BODY)
body = model->header(index); 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)); body.append(model->header(index)).append(model->body(index));
} }
QString data; UString data;
if (unicode) if (unicode)
data = QString::fromUtf16((const ushort*)body.constData(), body.length() / 2); data = UString::fromUtf16((const ushort*)body.constData(), body.length() / 2);
else else
data = QString::fromLatin1((const char*)body.constData(), body.length()); data = UString::fromLatin1((const char*)body.constData(), body.length());
int offset = -1; int offset = -1;
while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) { 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") msg((unicode ? UString("Unicode") : UString("ASCII")) + UString(" text \"") + UString(pattern)
.arg(pattern) + UString("\" found in ") + model->name(index)
.arg(model->name(index)) + usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", (unicode ? offset * 2 : offset)),
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
.hexarg(unicode ? offset * 2 : offset),
index); index);
} }
return ERR_SUCCESS; return U_SUCCESS;
} }

View File

@ -15,13 +15,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define FFSFINDER_H #define FFSFINDER_H
#include <vector> #include <vector>
#include <QObject>
#include <QByteArray>
#include <QString>
#include <QModelIndex>
#include <QRegExp> #include <QRegExp>
#include "../common/ubytearray.h"
#include "../common/ustring.h"
#include "../common/basetypes.h" #include "../common/basetypes.h"
#include "../common/treemodel.h" #include "../common/treemodel.h"
@ -31,19 +28,19 @@ public:
FfsFinder(const TreeModel * treeModel) : model(treeModel) {} FfsFinder(const TreeModel * treeModel) : model(treeModel) {}
~FfsFinder() {} ~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(); } void clearMessages() { messagesVector.clear(); }
STATUS findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode); USTATUS findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode);
STATUS findGuidPattern(const QModelIndex & index, const QByteArray & guidPattern, const UINT8 mode); USTATUS findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode);
STATUS findTextPattern(const QModelIndex & index, const QString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive); USTATUS findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive);
private: private:
const TreeModel* model; 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()) { void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index)); messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
} }
}; };

View File

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) : UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::UEFITool), ui(new Ui::UEFITool),
version(tr("0.30.0_alpha28")) version(tr("0.30.0_alpha29"))
{ {
clipboard = QApplication::clipboard(); clipboard = QApplication::clipboard();
@ -211,7 +211,7 @@ bool UEFITool::enableExtractBodyUncompressed(const QModelIndex &current)
if (current.isValid() && model->type(current) == Types::Section && if (current.isValid() && model->type(current) == Types::Section &&
(model->subtype(current) == EFI_SECTION_COMPRESSION || model->subtype(current) == EFI_SECTION_GUID_DEFINED)) { (model->subtype(current) == EFI_SECTION_COMPRESSION || model->subtype(current) == EFI_SECTION_GUID_DEFINED)) {
// Get parsing data // Get parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(current); PARSING_DATA pdata = parsingDataFromUModelIndex(current);
if (model->subtype(current) == EFI_SECTION_COMPRESSION && if (model->subtype(current) == EFI_SECTION_COMPRESSION &&
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_NONE && pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_NONE &&
@ -297,7 +297,7 @@ void UEFITool::goToData()
QModelIndex parent = model->parent(index); QModelIndex parent = model->parent(index);
for (int i = index.row(); i < model->rowCount(parent); i++) { 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; UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0;
if (pdata.nvar.next == lastVariableFlag) { if (pdata.nvar.next == lastVariableFlag) {
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter); ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
@ -306,7 +306,7 @@ void UEFITool::goToData()
for (int j = i + 1; j < model->rowCount(parent); j++) { for (int j = i + 1; j < model->rowCount(parent); j++) {
QModelIndex currentIndex = parent.child(j, 0); QModelIndex currentIndex = parent.child(j, 0);
PARSING_DATA currentPdata = parsingDataFromQModelIndex(currentIndex); PARSING_DATA currentPdata = parsingDataFromUModelIndex(currentIndex);
if (currentPdata.offset == pdata.offset + pdata.nvar.next) { if (currentPdata.offset == pdata.offset + pdata.nvar.next) {
index = currentIndex; index = currentIndex;
break; break;
@ -481,7 +481,7 @@ void UEFITool::replace(const UINT8 mode)
UINT8 result = ffsOps->replace(index, buffer, mode); UINT8 result = ffsOps->replace(index, buffer, mode);
if (result) { if (result) {
QMessageBox::critical(this, tr("Replacing failed"), errorCodeToQString(result), QMessageBox::Ok); QMessageBox::critical(this, tr("Replacing failed"), errorCodeToUString(result), QMessageBox::Ok);
return; return;
} }
ui->actionSaveImageFile->setEnabled(true); ui->actionSaveImageFile->setEnabled(true);
@ -512,7 +512,7 @@ void UEFITool::extract(const UINT8 mode)
QString name; QString name;
UINT8 result = ffsOps->extract(index, name, extracted, mode); UINT8 result = ffsOps->extract(index, name, extracted, mode);
if (result) { if (result) {
QMessageBox::critical(this, tr("Extraction failed"), errorCodeToQString(result), QMessageBox::Ok); QMessageBox::critical(this, tr("Extraction failed"), errorCodeToUString(result), QMessageBox::Ok);
return; return;
} }
@ -609,21 +609,21 @@ void UEFITool::extract(const UINT8 mode)
void UEFITool::rebuild() void UEFITool::rebuild()
{ {
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid()) if (!index.isValid())
return; return;
if (ERR_SUCCESS == ffsOps->rebuild(index)) if (U_SUCCESS == ffsOps->rebuild(index))
ui->actionSaveImageFile->setEnabled(true); ui->actionSaveImageFile->setEnabled(true);
} }
void UEFITool::remove() void UEFITool::remove()
{ {
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid()) if (!index.isValid())
return; return;
if (ERR_SUCCESS == ffsOps->remove(index)) if (U_SUCCESS == ffsOps->remove(index))
ui->actionSaveImageFile->setEnabled(true); ui->actionSaveImageFile->setEnabled(true);
} }
@ -661,10 +661,10 @@ void UEFITool::saveImageFile()
// Create ffsBuilder // Create ffsBuilder
delete ffsBuilder; delete ffsBuilder;
ffsBuilder = new FfsBuilder(model); ffsBuilder = new FfsBuilder(model);
STATUS result = ffsBuilder->build(model->index(0,0), reconstructed); USTATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
showBuilderMessages(); showBuilderMessages();
if (result) { 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; return;
} }
@ -725,7 +725,7 @@ void UEFITool::openImageFile(QString path)
UINT8 result = ffsParser->parse(buffer); UINT8 result = ffsParser->parse(buffer);
showParserMessages(); showParserMessages();
if (result) { 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; return;
} }
else else

View File

@ -29,7 +29,8 @@ SOURCES += uefitool_main.cpp \
../common/LZMA/SDK/C/LzmaEnc.c \ ../common/LZMA/SDK/C/LzmaEnc.c \
../common/Tiano/EfiTianoDecompress.c \ ../common/Tiano/EfiTianoDecompress.c \
../common/Tiano/EfiTianoCompress.c \ ../common/Tiano/EfiTianoCompress.c \
../common/Tiano/EfiTianoCompressLegacy.c ../common/Tiano/EfiTianoCompressLegacy.c \
../common/ustring.cpp \
HEADERS += uefitool.h \ HEADERS += uefitool.h \
searchdialog.h \ searchdialog.h \
@ -56,7 +57,9 @@ HEADERS += uefitool.h \
../common/LZMA/LzmaCompress.h \ ../common/LZMA/LzmaCompress.h \
../common/LZMA/LzmaDecompress.h \ ../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h \ ../common/Tiano/EfiTianoDecompress.h \
../common/Tiano/EfiTianoCompress.h ../common/Tiano/EfiTianoCompress.h \
../common/ustring.h \
../common/ubytearray.h \
FORMS += uefitool.ui \ FORMS += uefitool.ui \
searchdialog.ui searchdialog.ui

View File

@ -75,7 +75,7 @@ UINT32 *DestinationSize
if (*DestinationSize < destLen) if (*DestinationSize < destLen)
{ {
*DestinationSize = destLen; *DestinationSize = destLen;
return ERR_BUFFER_TOO_SMALL; return EFI_BUFFER_TOO_SMALL;
} }
LzmaEncProps_Init(&props); LzmaEncProps_Init(&props);
@ -101,9 +101,9 @@ UINT32 *DestinationSize
SetEncodedSizeOfBuf((UINT64)SourceSize, Destination); SetEncodedSizeOfBuf((UINT64)SourceSize, Destination);
if (LzmaResult == SZ_OK) { if (LzmaResult == SZ_OK) {
return ERR_SUCCESS; return EFI_SUCCESS;
} }
else { else {
return ERR_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
} }

View File

@ -12,22 +12,22 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
#include "ffsbuilder.h" #include "ffsbuilder.h"
STATUS FfsBuilder::erase(const QModelIndex & index, QByteArray & erased) USTATUS FfsBuilder::erase(const UModelIndex & index, UByteArray & erased)
{ {
// Sanity check // Sanity check
if (!index.isValid()) 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); 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 // Sanity check
if (!root.isValid()) if (!root.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
if (model->type(root) == Types::Capsule) { if (model->type(root) == Types::Capsule) {
return buildCapsule(root, image); 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 // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// No action required // No action required
if (model->action(index) == Actions::NoAction) { if (model->action(index) == Actions::NoAction) {
// Use original item data // Use original item data
capsule = model->header(index).append(model->body(index)); capsule = model->header(index).append(model->body(index));
return ERR_SUCCESS; return U_SUCCESS;
} }
// Rebuild or Replace // Rebuild or Replace
else if (model->action(index) == Actions::Rebuild else if (model->action(index) == Actions::Rebuild
|| model->action(index) == Actions::Replace) { || model->action(index) == Actions::Replace) {
if (model->rowCount(index)) { if (model->rowCount(index)) {
// Clear the supplied QByteArray // Clear the supplied UByteArray
capsule.clear(); capsule.clear();
// Right now there is only one capsule image element supported // Right now there is only one capsule image element supported
if (model->rowCount(index) != 1) { 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 // Use original item data
capsule = model->header(index).append(model->body(index)); capsule = model->header(index).append(model->body(index));
return ERR_SUCCESS; return U_SUCCESS;
} }
// Build image // Build image
QModelIndex imageIndex = index.child(0, 0); UModelIndex imageIndex = index.child(0, 0);
QByteArray imageData; UByteArray imageData;
// Check image type // Check image type
if (model->type(imageIndex) == Types::Image) { if (model->type(imageIndex) == Types::Image) {
STATUS result = ERR_SUCCESS; USTATUS result = U_SUCCESS;
if (model->subtype(imageIndex) == Subtypes::IntelImage) { if (model->subtype(imageIndex) == Subtypes::IntelImage) {
result = buildIntelImage(imageIndex, imageData); result = buildIntelImage(imageIndex, imageData);
} }
@ -86,20 +86,20 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
result = buildRawArea(imageIndex, imageData); result = buildRawArea(imageIndex, imageData);
} }
else { 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)); capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
} }
// Check build result // Check build result
if (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)); capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
} }
else else
capsule.append(imageData); capsule.append(imageData);
} }
else { 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)); 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 newSize = capsule.size();
UINT32 oldSize = model->body(index).size(); UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) { if (newSize > oldSize) {
msg(QObject::tr("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)") //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); // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
} }
else if (newSize < oldSize) { else if (newSize < oldSize) {
msg(QObject::tr("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)") //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); // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
} }
} }
else else
@ -122,23 +122,23 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
// Build successful, append header // Build successful, append header
capsule = model->header(index).append(capsule); 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); //msg(UString("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return U_NOT_IMPLEMENTED;
} }
STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intelImage) USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & intelImage)
{ {
// Sanity check // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_SUCCESS; return U_SUCCESS;
// No action // No action
if (model->action(index) == Actions::NoAction) { if (model->action(index) == Actions::NoAction) {
intelImage = model->header(index).append(model->body(index)); intelImage = model->header(index).append(model->body(index));
return ERR_SUCCESS; return U_SUCCESS;
} }
// Rebuild // Rebuild
@ -150,7 +150,7 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
// Process other regions // Process other regions
for (int i = 1; i < model->rowCount(index); i++) { 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 // Skip regions with Remove action
if (model->action(currentRegion) == Actions::Remove) if (model->action(currentRegion) == Actions::Remove)
@ -165,15 +165,15 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
} }
// Check region subtype // Check region subtype
STATUS result; USTATUS result;
QByteArray region; UByteArray region;
UINT8 regionType = model->subtype(currentRegion); UINT8 regionType = model->subtype(currentRegion);
switch (regionType) { switch (regionType) {
case Subtypes::BiosRegion: case Subtypes::BiosRegion:
case Subtypes::PdrRegion: case Subtypes::PdrRegion:
result = buildRawArea(currentRegion, region); result = buildRawArea(currentRegion, region);
if (result) { 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)); region = model->header(currentRegion).append(model->body(currentRegion));
} }
break; break;
@ -188,8 +188,8 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
region = model->header(currentRegion).append(model->body(currentRegion)); region = model->header(currentRegion).append(model->body(currentRegion));
break; break;
default: default:
msg(QObject::tr("buildIntelImage: don't know how to build region of unknown type"), index); msg(UString("buildIntelImage: don't know how to build region of unknown type"), index);
return ERR_UNKNOWN_ITEM_TYPE; return U_UNKNOWN_ITEM_TYPE;
} }
// Append the resulting region // Append the resulting region
@ -200,48 +200,48 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
UINT32 newSize = intelImage.size(); UINT32 newSize = intelImage.size();
UINT32 oldSize = model->body(index).size(); UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) { if (newSize > oldSize) {
msg(QObject::tr("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)") //msg(UString("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
} }
else if (newSize < oldSize) { else if (newSize < oldSize) {
msg(QObject::tr("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)") //msg(UString("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
} }
// Reconstruction successful // Reconstruction successful
return ERR_SUCCESS; return U_SUCCESS;
} }
msg(QObject::tr("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); //msg(UString("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; 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 // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// No action required // No action required
if (model->action(index) == Actions::NoAction) { if (model->action(index) == Actions::NoAction) {
rawArea = model->header(index).append(model->body(index)); rawArea = model->header(index).append(model->body(index));
return ERR_SUCCESS; return U_SUCCESS;
} }
// Rebuild or Replace // Rebuild or Replace
else if (model->action(index) == Actions::Rebuild else if (model->action(index) == Actions::Rebuild
|| model->action(index) == Actions::Replace) { || model->action(index) == Actions::Replace) {
if (model->rowCount(index)) { if (model->rowCount(index)) {
// Clear the supplied QByteArray // Clear the supplied UByteArray
rawArea.clear(); rawArea.clear();
// Build children // Build children
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
STATUS result = ERR_SUCCESS; USTATUS result = U_SUCCESS;
QModelIndex currentChild = index.child(i, 0); UModelIndex currentChild = index.child(i, 0);
QByteArray currentData; UByteArray currentData;
// Check child type // Check child type
if (model->type(currentChild) == Types::Volume) { if (model->type(currentChild) == Types::Volume) {
result = buildVolume(currentChild, currentData); result = buildVolume(currentChild, currentData);
@ -250,12 +250,12 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
result = buildPadding(currentChild, currentData); result = buildPadding(currentChild, currentData);
} }
else { 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)); currentData = model->header(currentChild).append(model->body(currentChild));
} }
// Check build result // Check build result
if (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)); currentData = model->header(currentChild).append(model->body(currentChild));
} }
// Append current data // Append current data
@ -266,14 +266,14 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
UINT32 newSize = rawArea.size(); UINT32 newSize = rawArea.size();
UINT32 oldSize = model->body(index).size(); UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) { if (newSize > oldSize) {
msg(QObject::tr("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)") //msg(UString("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
} }
else if (newSize < oldSize) { else if (newSize < oldSize) {
msg(QObject::tr("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)") //msg(UString("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
} }
} }
else else
@ -282,95 +282,95 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
// Build successful, add header if needed // Build successful, add header if needed
if (addHeader) if (addHeader)
rawArea = model->header(index).append(rawArea); 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); //msg(UString("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return U_NOT_IMPLEMENTED;
} }
STATUS FfsBuilder::buildPadding(const QModelIndex & index, QByteArray & padding) USTATUS FfsBuilder::buildPadding(const UModelIndex & index, UByteArray & padding)
{ {
// Sanity check // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// No action required // No action required
if (model->action(index) == Actions::NoAction) { if (model->action(index) == Actions::NoAction) {
padding = model->header(index).append(model->body(index)); padding = model->header(index).append(model->body(index));
return ERR_SUCCESS; return U_SUCCESS;
} }
// Erase // Erase
else if (model->action(index) == Actions::Erase) { else if (model->action(index) == Actions::Erase) {
padding = model->header(index).append(model->body(index)); padding = model->header(index).append(model->body(index));
if(erase(index, padding)) if(erase(index, padding))
msg(QObject::tr("buildPadding: erase failed, original item data is used"), index); msg(UString("buildPadding: erase failed, original item data is used"), index);
return ERR_SUCCESS; return U_SUCCESS;
} }
msg(QObject::tr("buildPadding: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); //msg(UString("buildPadding: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return U_NOT_IMPLEMENTED;
} }
STATUS FfsBuilder::buildNonUefiData(const QModelIndex & index, QByteArray & data) USTATUS FfsBuilder::buildNonUefiData(const UModelIndex & index, UByteArray & data)
{ {
// Sanity check // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// No action required // No action required
if (model->action(index) == Actions::NoAction) { if (model->action(index) == Actions::NoAction) {
data = model->header(index).append(model->body(index)); data = model->header(index).append(model->body(index));
return ERR_SUCCESS; return U_SUCCESS;
} }
// Erase // Erase
else if (model->action(index) == Actions::Erase) { else if (model->action(index) == Actions::Erase) {
data = model->header(index).append(model->body(index)); data = model->header(index).append(model->body(index));
if (erase(index, data)) if (erase(index, data))
msg(QObject::tr("buildNonUefiData: erase failed, original item data is used"), index); msg(UString("buildNonUefiData: erase failed, original item data is used"), index);
return ERR_SUCCESS; return U_SUCCESS;
} }
msg(QObject::tr("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); //msg(UString("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return U_NOT_IMPLEMENTED;
} }
STATUS FfsBuilder::buildFreeSpace(const QModelIndex & index, QByteArray & freeSpace) USTATUS FfsBuilder::buildFreeSpace(const UModelIndex & index, UByteArray & freeSpace)
{ {
// Sanity check // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// No action required // No action required
if (model->action(index) == Actions::NoAction) { if (model->action(index) == Actions::NoAction) {
freeSpace = model->header(index).append(model->body(index)); 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); //msg(UString("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; 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;
} }

View File

@ -16,11 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <vector> #include <vector>
#include <QObject> #include "ubytearray.h"
#include <QByteArray> #include "ustring.h"
#include <QString>
#include <QModelIndex>
#include "basetypes.h" #include "basetypes.h"
#include "treemodel.h" #include "treemodel.h"
#include "descriptor.h" #include "descriptor.h"
@ -33,31 +30,31 @@ public:
FfsBuilder(const TreeModel * treeModel) : model(treeModel) {} FfsBuilder(const TreeModel * treeModel) : model(treeModel) {}
~FfsBuilder() {} ~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(); } void clearMessages() { messagesVector.clear(); }
STATUS build(const QModelIndex & root, QByteArray & image); USTATUS build(const UModelIndex & root, UByteArray & image);
private: private:
const TreeModel* model; 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()) { void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index)); messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
} }
STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule); USTATUS buildCapsule(const UModelIndex & index, UByteArray & capsule);
STATUS buildIntelImage(const QModelIndex & index, QByteArray & intelImage); USTATUS buildIntelImage(const UModelIndex & index, UByteArray & intelImage);
STATUS buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader = true); USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader = true);
STATUS buildPadding(const QModelIndex & index, QByteArray & padding); USTATUS buildPadding(const UModelIndex & index, UByteArray & padding);
STATUS buildVolume(const QModelIndex & index, QByteArray & volume); USTATUS buildVolume(const UModelIndex & index, UByteArray & volume);
STATUS buildNonUefiData(const QModelIndex & index, QByteArray & data); USTATUS buildNonUefiData(const UModelIndex & index, UByteArray & data);
STATUS buildFreeSpace(const QModelIndex & index, QByteArray & freeSpace); USTATUS buildFreeSpace(const UModelIndex & index, UByteArray & freeSpace);
STATUS buildPadFile(const QModelIndex & index, QByteArray & padFile); USTATUS buildPadFile(const UModelIndex & index, UByteArray & padFile);
STATUS buildFile(const QModelIndex & index, QByteArray & file); USTATUS buildFile(const UModelIndex & index, UByteArray & file);
STATUS buildSection(const QModelIndex & index, QByteArray & section); USTATUS buildSection(const UModelIndex & index, UByteArray & section);
// Utility functions // Utility functions
STATUS erase(const QModelIndex & index, QByteArray & erased); USTATUS erase(const UModelIndex & index, UByteArray & erased);
}; };
#endif // FFSBUILDER_H #endif // FFSBUILDER_H

View File

@ -13,24 +13,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsops.h" #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 // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get data from parsing data // Get data from parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(index); PARSING_DATA pdata = parsingDataFromUModelIndex(index);
// Construct a name for extracted data // Construct a name for extracted data
QString itemName = model->name(index); UString itemName = model->name(index);
QString itemText = model->text(index); UString itemText = model->text(index);
// Default name // Default name
name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_'); name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_');
switch (model->type(index)) { 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::NvarEntry:
case Types::VssEntry: case Types::VssEntry:
case Types::FsysEntry: 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::File: name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_').replace('-', '_'); break;
case Types::Section: { case Types::Section: {
// Get parent file name // Get parent file name
QModelIndex fileIndex = model->findParentOfType(index, Types::File); UModelIndex fileIndex = model->findParentOfType(index, Types::File);
QString fileText = model->text(fileIndex); UString fileText = model->text(fileIndex);
name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_').replace('-', '_'); name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_').replace('-', '_');
// Append section subtype name // Append section subtype name
name += QChar('_') + itemName.replace(' ', '_'); name += '_' + itemName.replace(' ', '_');
} break; } break;
} }
@ -67,9 +67,9 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
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++) {
QModelIndex 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.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 // Add current section header, body and tail
extracted.append(model->header(childIndex)); extracted.append(model->header(childIndex));
extracted.append(model->body(childIndex)); extracted.append(model->body(childIndex));
@ -77,49 +77,49 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
} }
} }
else 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 // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Get data from parsing data // Get data from parsing data
//PARSING_DATA pdata = parsingDataFromQModelIndex(index); //PARSING_DATA pdata = parsingDataFromQModelIndex(index);
if (mode == REPLACE_MODE_AS_IS) { if (mode == REPLACE_MODE_AS_IS) {
return ERR_NOT_IMPLEMENTED; return U_NOT_IMPLEMENTED;
} }
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
return ERR_NOT_IMPLEMENTED; return U_NOT_IMPLEMENTED;
} }
else 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 // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Set remove action // Set remove action
model->setAction(index, Actions::Remove); 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 // Sanity check
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// On insert action, set insert action for children // On insert action, set insert action for children
//if (action == Actions::Insert) //if (action == Actions::Insert)
@ -130,10 +130,10 @@ STATUS FfsOperations::rebuild(const QModelIndex & index)
model->setAction(index, Actions::Rebuild); model->setAction(index, Actions::Rebuild);
// Rebuild parent, if it has no action now // Rebuild parent, if it has no action now
QModelIndex parent = index.parent(); UModelIndex parent = index.parent();
if (parent.isValid() && model->type(parent) != Types::Root if (parent.isValid() && model->type(parent) != Types::Root
&& model->action(parent) == Actions::NoAction) && model->action(parent) == Actions::NoAction)
rebuild(parent); rebuild(parent);
return ERR_SUCCESS; return U_SUCCESS;
} }

View File

@ -16,11 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <vector> #include <vector>
#include <QObject> #include "ubytearray.h"
#include <QByteArray> #include "ustring.h"
#include <QString>
#include <QModelIndex>
#include "basetypes.h" #include "basetypes.h"
#include "treemodel.h" #include "treemodel.h"
#include "ffs.h" #include "ffs.h"
@ -33,21 +30,21 @@ public:
FfsOperations(TreeModel * treeModel) : model(treeModel) {} FfsOperations(TreeModel * treeModel) : model(treeModel) {}
~FfsOperations() {}; ~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(); } void clearMessages() { messagesVector.clear(); }
STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode); USTATUS extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode);
STATUS replace(const QModelIndex & index, const QString & data, const UINT8 mode); USTATUS replace(const UModelIndex & index, const UString & data, const UINT8 mode);
STATUS remove(const QModelIndex & index); USTATUS remove(const UModelIndex & index);
STATUS rebuild(const QModelIndex & index); USTATUS rebuild(const UModelIndex & index);
private: private:
TreeModel* model; 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()) { void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index)); messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
} }
}; };

View File

@ -1605,7 +1605,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 parentO
} }
// Construct parsing data // Construct parsing data
bool fixed(fileHeader->Attributes & FFS_ATTRIB_FIXED); bool fixed = (fileHeader->Attributes & FFS_ATTRIB_FIXED) != 0;
pdata.offset += parentOffset; pdata.offset += parentOffset;
@ -4543,7 +4543,7 @@ USTATUS FfsParser::parseFsysStoreBody(const UModelIndex & index)
pdata.offset = parentOffset + offset; pdata.offset = parentOffset + offset;
// Add tree item // 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 // Move to next variable
offset += variableSize; offset += variableSize;

View File

@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treeitem.h" #include "treeitem.h"
#include "treemodel.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 QVariant TreeModel::data(const UModelIndex &index, int role) const
{ {
if (!index.isValid()) if (!index.isValid())

View File

@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef TREEMODEL_H #ifndef TREEMODEL_H
#define TREEMODEL_H #define TREEMODEL_H
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL) #if defined(QT_CORE_LIB)
// Use Qt classes // Use Qt classes
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <QModelIndex> #include <QModelIndex>
@ -73,7 +73,7 @@ private:
}; };
#endif #endif
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL) #if defined(QT_CORE_LIB)
class TreeModel : public QAbstractItemModel class TreeModel : public QAbstractItemModel
{ {
Q_OBJECT Q_OBJECT
@ -165,7 +165,7 @@ public:
UModelIndex findParentOfType(const UModelIndex & index, UINT8 type) const; 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 // Nothing required here
#else #else
inline UModelIndex UModelIndex::parent() const { return m ? m->parent(*this) : UModelIndex(); } inline UModelIndex UModelIndex::parent() const { return m ? m->parent(*this) : UModelIndex(); }

View File

@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef UBYTEARRAY_H #ifndef UBYTEARRAY_H
#define 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 // Use Qt class, if Qt is available
#include <QByteArray> #include <QByteArray>
#define UByteArray QByteArray #define UByteArray QByteArray
@ -61,13 +61,13 @@ public:
inline void swap(UByteArray &other) { std::swap(d, other.d); } inline void swap(UByteArray &other) { std::swap(d, other.d); }
UByteArray toHex() { UByteArray toHex() {
std::basic_string<char> hex(size() * 2, '\x00'); 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 low = d[i] & 0x0F;
uint8_t high = (d[i] & 0xF0) >> 4; uint8_t high = (d[i] & 0xF0) >> 4;
low += (low < 10 ? 'a' : '0'); low += (low < 10 ? '0' : 'a');
high += (high < 10 ? 'a' : '0'); high += (high < 10 ? '0' : 'a');
hex[i] = low; hex[2*i] = low;
hex[i + 1] = high; hex[2*i + 1] = high;
} }
std::reverse(hex.begin(), hex.end()); std::reverse(hex.begin(), hex.end());
return UByteArray(hex); return UByteArray(hex);

View File

@ -13,9 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ustring.h" #include "ustring.h"
#include <stdarg.h> #include <stdarg.h>
//TODO: modify properly #if defined(QT_CORE_LIB)
#if defined(QT_CORE_LIB) && defined (U_USE_QSTRING)
UString usprintf(const char* fmt, ...) UString usprintf(const char* fmt, ...)
{ {
UString msg; UString msg;

View File

@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef USTRING_H #ifndef USTRING_H
#define 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 // Use Qt class, if Qt is available
#include <QString> #include <QString>
#define UString QString #define UString QString

View File

@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define UTILITY_H #define UTILITY_H
#include "ustring.h" #include "ustring.h"
#include "treemodel.h"
#include "basetypes.h" #include "basetypes.h"
#include "parsingdata.h" #include "parsingdata.h"