mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-21 23:48:22 +08:00
Big structure update
- files split into common and app-specific ones - messages from parser and finder separated - ffsEngine split into multiple classes to reduce complexity - still no image rebuild
This commit is contained in:
parent
1f0a80d035
commit
2e788a8a1a
44
README.rst
44
README.rst
@ -1,44 +0,0 @@
|
|||||||
UEFITool
|
|
||||||
========
|
|
||||||
.. image:: https://raw.githubusercontent.com/LongSoft/UEFITool/master/uefitool.ico
|
|
||||||
.. image:: https://scan.coverity.com/projects/1812/badge.svg?flat=1
|
|
||||||
:target: https://scan.coverity.com/projects/1812/
|
|
||||||
|
|
||||||
|
|
|
||||||
| UEFITool is a cross-platform C++/Qt program for parsing, extracting and modifying UEFI firmware images.
|
|
||||||
| It supports parsing of full BIOS images starting with the flash descriptor or any binary files containing UEFI volumes.
|
|
||||||
| Original development was started `here <http://forums.mydigitallife.info/threads/48979-UEFITool-UEFI-firmware-image-viewer-and-editor>`_ at MDL forums as a cross-platform analog to `PhoenixTool <http://forums.mydigitallife.info/threads/13194-Tool-to-Insert-Replace-SLIC-in-Phoenix-Insyde-Dell-EFI-BIOSes>`_'s structure mode with some additional features, but the program's engine was proven to be usefull for another projects like `UEFIPatch <http://www.insanelymac.com/forum/topic/285444-uefipatch-uefi-patching-utility/>`_, `UBU <http://www.win-raid.com/t154f16-Tool-quot-UEFI-BIOS-Updater-quot-UBU.html>`_ and `OZMTool <http://www.insanelymac.com/forum/topic/299711-ozmtool-an-ozmosis-toolbox/>`_.
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
| You can either use `pre-built binaries for Windows and OSX <https://github.com/LongSoft/UEFITool/releases/latest>`_ or build a binary yourself.
|
|
||||||
| To build a binary you need a C++ compiler and an instance of Qt4/Qt5 library for it.
|
|
||||||
| Install both of them, get the sources, generate makefiles using qmake (*qmake UEFITool.pro*) and use your make command on that generated files (i.e. *nmake release*, *make release* and so on).
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
| The program can be started directly without any arguments or supplied with a single argument - a path to the UEFI image file to open after start.
|
|
||||||
|
|
|
||||||
| The program window is divided into three panels: **Structure**, **Information** and **Messages**.
|
|
||||||
| Structure of the image is represented as a tree of elements with different names, types and subtypes. If you select an element, **Information** panel will show the available information about the selected element based on it's type and contents.
|
|
||||||
| **Messages** panel show all messages from the engine, including structure warnings and search results. Most of messages can be double-clicked to select the element that causes the message.
|
|
||||||
|
|
|
||||||
| You can open a menu on each tree element to see what operations are possible for the selected element. This can include various types of **Extract**, **Insert** and **Replace** operations, as well as **Remove** and **Rebuild**.
|
|
||||||
| **Extract** has two variants: **Extract as is** and **Extract body**. The difference is that **Extract as is** extracts the element with it's header (GUID, size, attributes and other structure-related information are located there), and **Extract body** extracts the element data only.
|
|
||||||
| **Replace** has the same two variants as **Extract** with the same meaning.
|
|
||||||
| **Insert** has the three different variants: **Insert before**, **Insert after** and **Insert into**, which is only available for UEFI volumes and encapsulation sections.
|
|
||||||
| **Remove** marks an element for removal on image reconstuction.
|
|
||||||
| **Rebuild** marks an element for rebuilding on image reconstruction. Normally, all elements that aren't marked for rebuild won't be changed at all and if you need to correct some structure error (i.e. invalid data checksum) you must mark an element for rebuild manually. If you change an element all it's parents up to the tree root will be marked for rebuild automatically. If UEFI volume is marked for rebuild all uncompressed PEI files in it will also be marked for rebuild because they must be rebased in the reconstructed image to maintain the executable-in-place constraint.
|
|
||||||
|
|
|
||||||
| There is also a search function available from the *File* menu, you can search all tree elements for a specified hexadecimal pattern (spaces are not counted, dot symbol (.) is used as placeholder for a single hex digit), a specified GUID (rules are the same as for hex except for spaces) and a specified text (either Unicode or ASCII, case sensitive or not). Search results will be added into **Messages** panel, if anything is found.
|
|
||||||
|
|
|
||||||
| After you've finished the modifications, you need to initiate image reconstruction using *Save image file* command from the *File* menu. If anything goes wrong on the reconstruction, an error will pop up, otherwise the program will prompt if you need to open the reconstructed file. Don't rush it, because reconstruction process can also generate some usefull messages, which will be lost if you open the reconstructed file immediatelly.
|
|
||||||
|
|
||||||
Known issues
|
|
||||||
------------
|
|
||||||
* Some images has non-standard calculation of base address of TE images, so the program can rebase them incorrectly after modifications. Will be solved ASAP.
|
|
||||||
* Some images may not work after modification because of no FIT table support implemented yet. It's on my high priority features list, so I hope it will be corrected soon.
|
|
||||||
* The program is meant to work with BIOS images, not some vendor-specific BIOS update files, that is why some of that update file either can\t be opened at all or return errors on reconstruction. If someone wants to write an unpacker for such crappy files - I will be glad to use it.
|
|
||||||
* AMI-specific features like NCBs, ROM_AREA structure and other things like that can't be implemented by me because of the NDA I have.
|
|
91
UEFIExtract/ffsdumper.cpp
Normal file
91
UEFIExtract/ffsdumper.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/* 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 "ffsdumper.h"
|
||||||
|
|
||||||
|
FfsDumper::FfsDumper(TreeModel* treeModel, QObject *parent)
|
||||||
|
: model(treeModel), QObject(parent), dumped(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FfsDumper::~FfsDumper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsDumper::dump(const QModelIndex & root, const QString & path)
|
||||||
|
{
|
||||||
|
dumped = false;
|
||||||
|
UINT8 result = recursiveDump(root, path);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
else if (!dumped)
|
||||||
|
return ERR_ITEM_NOT_FOUND;
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsDumper::recursiveDump(const QModelIndex & index, const QString & path)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
QDir dir;
|
||||||
|
|
||||||
|
if (dir.cd(path))
|
||||||
|
return ERR_DIR_ALREADY_EXIST;
|
||||||
|
|
||||||
|
if (!dir.mkpath(path))
|
||||||
|
return ERR_DIR_CREATE;
|
||||||
|
|
||||||
|
QFile file;
|
||||||
|
if (!model->header(index).isEmpty()) {
|
||||||
|
file.setFileName(tr("%1/header.bin").arg(path));
|
||||||
|
if (!file.open(QFile::WriteOnly))
|
||||||
|
return ERR_FILE_OPEN;
|
||||||
|
|
||||||
|
file.write(model->header(index));
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!model->body(index).isEmpty()) {
|
||||||
|
file.setFileName(tr("%1/body.bin").arg(path));
|
||||||
|
if (!file.open(QFile::WriteOnly))
|
||||||
|
return ERR_FILE_OPEN;
|
||||||
|
|
||||||
|
file.write(model->body(index));
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString info = tr("Type: %1\nSubtype: %2\n%3%4")
|
||||||
|
.arg(itemTypeToQString(model->type(index)))
|
||||||
|
.arg(itemSubtypeToQString(model->type(index), model->subtype(index)))
|
||||||
|
.arg(model->text(index).isEmpty() ? "" : tr("Text: %1\n").arg(model->text(index)))
|
||||||
|
.arg(model->info(index));
|
||||||
|
file.setFileName(tr("%1/info.txt").arg(path));
|
||||||
|
if (!file.open(QFile::Text | QFile::WriteOnly))
|
||||||
|
return ERR_FILE_OPEN;
|
||||||
|
|
||||||
|
file.write(info.toLatin1());
|
||||||
|
file.close();
|
||||||
|
dumped = true;
|
||||||
|
|
||||||
|
UINT8 result;
|
||||||
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
|
QModelIndex childIndex = index.child(i, 0);
|
||||||
|
QString childPath = QString("%1/%2 %3").arg(path).arg(i).arg(model->text(childIndex).isEmpty() ? model->name(childIndex) : model->text(childIndex));
|
||||||
|
result = recursiveDump(childIndex, childPath);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
43
UEFIExtract/ffsdumper.h
Normal file
43
UEFIExtract/ffsdumper.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* ffsdumper.h
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FFSDUMPER_H__
|
||||||
|
#define __FFSDUMPER_H__
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#include "..\common\basetypes.h"
|
||||||
|
#include "..\common\treemodel.h"
|
||||||
|
|
||||||
|
class FfsDumper : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FfsDumper(TreeModel * treeModel, QObject *parent = 0);
|
||||||
|
~FfsDumper();
|
||||||
|
|
||||||
|
STATUS dump(const QModelIndex & root, const QString & path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
STATUS recursiveDump(const QModelIndex & root, const QString & path);
|
||||||
|
TreeModel* model;
|
||||||
|
bool dumped;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
37
UEFIExtract/uefiextract.pro
Normal file
37
UEFIExtract/uefiextract.pro
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
QT += core
|
||||||
|
QT -= gui
|
||||||
|
|
||||||
|
TARGET = UEFIExtract
|
||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
SOURCES += uefiextract_main.cpp \
|
||||||
|
ffsdumper.cpp \
|
||||||
|
../common/types.cpp \
|
||||||
|
../common/descriptor.cpp \
|
||||||
|
../common/ffs.cpp \
|
||||||
|
../common/ffsparser.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 \
|
||||||
|
|
||||||
|
HEADERS += ffsdumper.h \
|
||||||
|
../common/basetypes.h \
|
||||||
|
../common/descriptor.h \
|
||||||
|
../common/gbe.h \
|
||||||
|
../common/me.h \
|
||||||
|
../common/ffs.h \
|
||||||
|
../common/ffsparser.h \
|
||||||
|
../common/peimage.h \
|
||||||
|
../common/types.h \
|
||||||
|
../common/treeitem.h \
|
||||||
|
../common/treemodel.h \
|
||||||
|
../common/utility.h \
|
||||||
|
../common/LZMA/LzmaDecompress.h \
|
||||||
|
../common/Tiano/EfiTianoDecompress.h
|
||||||
|
|
65
UEFIExtract/uefiextract_main.cpp
Normal file
65
UEFIExtract/uefiextract_main.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* uefiextract_main.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 <QCoreApplication>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QPair>
|
||||||
|
#include <QString>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "..\common\ffsparser.h"
|
||||||
|
#include "ffsdumper.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QCoreApplication a(argc, argv);
|
||||||
|
a.setOrganizationName("CodeRush");
|
||||||
|
a.setOrganizationDomain("coderush.me");
|
||||||
|
a.setApplicationName("UEFIExtract");
|
||||||
|
|
||||||
|
if (a.arguments().length() > 1) {
|
||||||
|
QString path = a.arguments().at(1);
|
||||||
|
QFileInfo fileInfo(path);
|
||||||
|
if (!fileInfo.exists())
|
||||||
|
return ERR_FILE_OPEN;
|
||||||
|
|
||||||
|
QFile inputFile;
|
||||||
|
inputFile.setFileName(path);
|
||||||
|
if (!inputFile.open(QFile::ReadOnly))
|
||||||
|
return ERR_FILE_OPEN;
|
||||||
|
|
||||||
|
QByteArray buffer = inputFile.readAll();
|
||||||
|
inputFile.close();
|
||||||
|
|
||||||
|
TreeModel model;
|
||||||
|
FfsParser ffsParser(&model);
|
||||||
|
STATUS result = ffsParser.parseImageFile(buffer, model.index(0, 0));
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
QVector<QPair<QString, QModelIndex> > messages = ffsParser.getMessages();
|
||||||
|
QPair<QString, QModelIndex> msg;
|
||||||
|
foreach(msg, messages) {
|
||||||
|
std::cout << msg.first.toLatin1().constData() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
FfsDumper ffsDumper(&model);
|
||||||
|
return ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "UEFIExtract 0.10.0" << std::endl << std::endl
|
||||||
|
<< "Usage: uefiextract imagefile" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
@ -20,8 +20,8 @@ Header file for compression routine.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _EFITIANOCOMPRESS_H_
|
#ifndef __EFITIANOCOMPRESS_H__
|
||||||
#define _EFITIANOCOMPRESS_H_
|
#define __EFITIANOCOMPRESS_H__
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
@ -21,8 +21,8 @@ Providing both EFI and Tiano decompress algorithms.
|
|||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
#ifndef _EFITIANODECOMPRESS_H_
|
#ifndef __EFITIANODECOMPRESS_H__
|
||||||
#define _EFITIANODECOMPRESS_H_
|
#define __EFITIANODECOMPRESS_H__
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -60,7 +60,7 @@ typedef UINT8 STATUS;
|
|||||||
#define ERR_VOLUMES_NOT_FOUND 14
|
#define ERR_VOLUMES_NOT_FOUND 14
|
||||||
#define ERR_INVALID_VOLUME 15
|
#define ERR_INVALID_VOLUME 15
|
||||||
#define ERR_VOLUME_REVISION_NOT_SUPPORTED 16
|
#define ERR_VOLUME_REVISION_NOT_SUPPORTED 16
|
||||||
#define ERR_VOLUME_GROW_FAILED 17
|
#define ERR_COMPLEX_BLOCK_MAP 17
|
||||||
#define ERR_UNKNOWN_FFS 18
|
#define ERR_UNKNOWN_FFS 18
|
||||||
#define ERR_INVALID_FILE 19
|
#define ERR_INVALID_FILE 19
|
||||||
#define ERR_INVALID_SECTION 20
|
#define ERR_INVALID_SECTION 20
|
||||||
@ -70,22 +70,13 @@ typedef UINT8 STATUS;
|
|||||||
#define ERR_STANDARD_DECOMPRESSION_FAILED 24
|
#define ERR_STANDARD_DECOMPRESSION_FAILED 24
|
||||||
#define ERR_CUSTOMIZED_DECOMPRESSION_FAILED 25
|
#define ERR_CUSTOMIZED_DECOMPRESSION_FAILED 25
|
||||||
#define ERR_UNKNOWN_COMPRESSION_TYPE 26
|
#define ERR_UNKNOWN_COMPRESSION_TYPE 26
|
||||||
#define ERR_UNKNOWN_EXTRACT_MODE 27
|
#define ERR_DEPEX_PARSE_FAILED 27
|
||||||
#define ERR_UNKNOWN_INSERT_MODE 28
|
#define ERR_UNKNOWN_EXTRACT_MODE 28
|
||||||
#define ERR_UNKNOWN_IMAGE_TYPE 29
|
#define ERR_UNKNOWN_IMAGE_TYPE 29
|
||||||
#define ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 30
|
#define ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 30
|
||||||
#define ERR_UNKNOWN_RELOCATION_TYPE 31
|
#define ERR_UNKNOWN_RELOCATION_TYPE 31
|
||||||
#define ERR_GENERIC_CALL_NOT_SUPPORTED 32
|
#define ERR_DIR_ALREADY_EXIST 32
|
||||||
#define ERR_VOLUME_BASE_NOT_FOUND 33
|
#define ERR_DIR_CREATE 33
|
||||||
#define ERR_PEI_CORE_ENTRY_POINT_NOT_FOUND 34
|
|
||||||
#define ERR_COMPLEX_BLOCK_MAP 35
|
|
||||||
#define ERR_DIR_ALREADY_EXIST 36
|
|
||||||
#define ERR_DIR_CREATE 37
|
|
||||||
#define ERR_UNKNOWN_PATCH_TYPE 38
|
|
||||||
#define ERR_PATCH_OFFSET_OUT_OF_BOUNDS 39
|
|
||||||
#define ERR_INVALID_SYMBOL 40
|
|
||||||
#define ERR_NOTHING_TO_PATCH 41
|
|
||||||
#define ERR_DEPEX_PARSE_FAILED 42
|
|
||||||
#define ERR_NOT_IMPLEMENTED 0xFF
|
#define ERR_NOT_IMPLEMENTED 0xFF
|
||||||
|
|
||||||
// UDK porting definitions
|
// UDK porting definitions
|
13
common/ffsbuilder.cpp
Normal file
13
common/ffsbuilder.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* fssbuilder.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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
17
common/ffsbuilder.h
Normal file
17
common/ffsbuilder.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* fssbuilder.h
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FFSBUILDER_H__
|
||||||
|
#define __FFSBUILDER_H__
|
||||||
|
|
||||||
|
#endif
|
@ -20,78 +20,28 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "gbe.h"
|
#include "gbe.h"
|
||||||
#include "me.h"
|
#include "me.h"
|
||||||
|
|
||||||
|
FfsParser::FfsParser(TreeModel* treeModel, QObject *parent)
|
||||||
#ifdef _CONSOLE
|
: model(treeModel), QObject(parent)
|
||||||
#include <iostream>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FfsParser::FfsParser(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
{
|
||||||
model = new TreeModel();
|
|
||||||
//oldPeiCoreEntryPoint = 0;
|
|
||||||
//newPeiCoreEntryPoint = 0;
|
|
||||||
//dumped = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FfsParser::~FfsParser(void)
|
FfsParser::~FfsParser()
|
||||||
{
|
{
|
||||||
delete model;
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeModel* FfsParser::treeModel() const
|
|
||||||
{
|
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FfsParser::msg(const QString & message, const QModelIndex & index)
|
void FfsParser::msg(const QString & message, const QModelIndex & index)
|
||||||
{
|
{
|
||||||
#ifndef _DISABLE_ENGINE_MESSAGES
|
messagesVector.push_back(QPair<QString, QModelIndex>(message, index));
|
||||||
#ifndef _CONSOLE
|
|
||||||
messageItems.enqueue(MessageListItem(message, NULL, 0, index));
|
|
||||||
#else
|
|
||||||
(void) index;
|
|
||||||
std::cout << message.toLatin1().constData() << std::endl;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
(void)message;
|
|
||||||
(void)index;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _CONSOLE
|
QVector<QPair<QString, QModelIndex> > FfsParser::getMessages() const
|
||||||
QQueue<MessageListItem> FfsParser::messages() const
|
|
||||||
{
|
{
|
||||||
return messageItems;
|
return messagesVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FfsParser::clearMessages()
|
void FfsParser::clearMessages()
|
||||||
{
|
{
|
||||||
messageItems.clear();
|
messagesVector.clear();
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Utility functions
|
|
||||||
PARSING_DATA FfsParser::getParsingData(const QModelIndex & index)
|
|
||||||
{
|
|
||||||
if (index.isValid()) {
|
|
||||||
return *(PARSING_DATA*)model->parsingData(index).data();
|
|
||||||
}
|
|
||||||
|
|
||||||
PARSING_DATA data;
|
|
||||||
data.fixed = FALSE; // Item is not fixed by default
|
|
||||||
data.isOnFlash = TRUE; // Data is on flash by default
|
|
||||||
data.offset = 0;
|
|
||||||
data.address = 0;
|
|
||||||
data.ffsVersion = 0; // Unknown by default
|
|
||||||
|
|
||||||
// Type-specific parts remain unitialized
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray FfsParser::convertParsingData(const PARSING_DATA & pdata)
|
|
||||||
{
|
|
||||||
return QByteArray((const char*)&pdata, sizeof(PARSING_DATA));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FfsParser::hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2)
|
BOOLEAN FfsParser::hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2)
|
||||||
@ -107,178 +57,8 @@ BOOLEAN FfsParser::hasIntersection(const UINT32 begin1, const UINT32 end1, const
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search routines
|
|
||||||
STATUS FfsParser::findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode)
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
|
|
||||||
if (hexPattern.isEmpty())
|
|
||||||
return ERR_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
// Check for "all substrings" pattern
|
|
||||||
if (hexPattern.count('.') == hexPattern.length())
|
|
||||||
return ERR_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;
|
|
||||||
if (hasChildren) {
|
|
||||||
if (mode != SEARCH_MODE_BODY)
|
|
||||||
data = model->header(index);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (mode == SEARCH_MODE_HEADER)
|
|
||||||
data.append(model->header(index));
|
|
||||||
else if (mode == SEARCH_MODE_BODY)
|
|
||||||
data.append(model->body(index));
|
|
||||||
else
|
|
||||||
data.append(model->header(index)).append(model->body(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString hexBody = QString(data.toHex());
|
|
||||||
QRegExp regexp = QRegExp(QString(hexPattern), Qt::CaseInsensitive);
|
|
||||||
INT32 offset = regexp.indexIn(hexBody);
|
|
||||||
while (offset >= 0) {
|
|
||||||
if (offset % 2 == 0) {
|
|
||||||
msg(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 ? tr("body") : tr("header"))
|
|
||||||
.hexarg(offset / 2),
|
|
||||||
index);
|
|
||||||
}
|
|
||||||
offset = regexp.indexIn(hexBody, offset + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATUS FfsParser::findGuidPattern(const QModelIndex & index, const QByteArray & guidPattern, const UINT8 mode)
|
|
||||||
{
|
|
||||||
if (guidPattern.isEmpty())
|
|
||||||
return ERR_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (!index.isValid())
|
|
||||||
return ERR_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;
|
|
||||||
if (hasChildren) {
|
|
||||||
if (mode != SEARCH_MODE_BODY)
|
|
||||||
data = model->header(index);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (mode == SEARCH_MODE_HEADER)
|
|
||||||
data.append(model->header(index));
|
|
||||||
else if (mode == SEARCH_MODE_BODY)
|
|
||||||
data.append(model->body(index));
|
|
||||||
else
|
|
||||||
data.append(model->header(index)).append(model->body(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString hexBody = QString(data.toHex());
|
|
||||||
QList<QByteArray> list = guidPattern.split('-');
|
|
||||||
if (list.count() != 5)
|
|
||||||
return ERR_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
QByteArray hexPattern;
|
|
||||||
// Reverse first GUID block
|
|
||||||
hexPattern.append(list.at(0).mid(6, 2));
|
|
||||||
hexPattern.append(list.at(0).mid(4, 2));
|
|
||||||
hexPattern.append(list.at(0).mid(2, 2));
|
|
||||||
hexPattern.append(list.at(0).mid(0, 2));
|
|
||||||
// Reverse second GUID block
|
|
||||||
hexPattern.append(list.at(1).mid(2, 2));
|
|
||||||
hexPattern.append(list.at(1).mid(0, 2));
|
|
||||||
// Reverse third GUID block
|
|
||||||
hexPattern.append(list.at(2).mid(2, 2));
|
|
||||||
hexPattern.append(list.at(2).mid(0, 2));
|
|
||||||
// Append fourth and fifth GUID blocks as is
|
|
||||||
hexPattern.append(list.at(3)).append(list.at(4));
|
|
||||||
|
|
||||||
// Check for "all substrings" pattern
|
|
||||||
if (hexPattern.count('.') == hexPattern.length())
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
|
|
||||||
QRegExp regexp = QRegExp(QString(hexPattern), Qt::CaseInsensitive);
|
|
||||||
INT32 offset = regexp.indexIn(hexBody);
|
|
||||||
while (offset >= 0) {
|
|
||||||
if (offset % 2 == 0) {
|
|
||||||
msg(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 ? tr("body") : tr("header"))
|
|
||||||
.hexarg(offset / 2),
|
|
||||||
index);
|
|
||||||
}
|
|
||||||
offset = regexp.indexIn(hexBody, offset + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATUS FfsParser::findTextPattern(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive)
|
|
||||||
{
|
|
||||||
if (pattern.isEmpty())
|
|
||||||
return ERR_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (!index.isValid())
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
|
|
||||||
bool hasChildren = (model->rowCount(index) > 0);
|
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
|
||||||
findTextPattern(index.child(i, index.column()), pattern, unicode, caseSensitive);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasChildren)
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
|
|
||||||
QString data;
|
|
||||||
if (unicode)
|
|
||||||
data = QString::fromUtf16((const ushort*)model->body(index).data(), model->body(index).length() / 2);
|
|
||||||
else
|
|
||||||
data = QString::fromLatin1((const char*)model->body(index).data(), model->body(index).length());
|
|
||||||
|
|
||||||
int offset = -1;
|
|
||||||
while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) {
|
|
||||||
msg(tr("%1 text \"%2\" found in %3 at offset %4h")
|
|
||||||
.arg(unicode ? "Unicode" : "ASCII")
|
|
||||||
.arg(pattern)
|
|
||||||
.arg(model->name(index))
|
|
||||||
.hexarg(unicode ? offset * 2 : offset),
|
|
||||||
index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATUS FfsParser::parseAprioriRawSection(const QByteArray & body, QString & parsed)
|
|
||||||
{
|
|
||||||
parsed.clear();
|
|
||||||
|
|
||||||
UINT32 count = body.size() / sizeof(EFI_GUID);
|
|
||||||
if (count > 0) {
|
|
||||||
for (UINT32 i = 0; i < count; i++) {
|
|
||||||
const EFI_GUID* guid = (const EFI_GUID*)body.constData() + i;
|
|
||||||
parsed += tr("\n%1").arg(guidToQString(*guid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Firmware image parsing functions
|
// Firmware image parsing functions
|
||||||
STATUS FfsParser::parseImageFile(const QByteArray & buffer)
|
STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex & root)
|
||||||
{
|
{
|
||||||
// Check buffer size to be more then or equal to size of EFI_CAPSULE_HEADER
|
// Check buffer size to be more then or equal to size of EFI_CAPSULE_HEADER
|
||||||
if ((UINT32)buffer.size() <= sizeof(EFI_CAPSULE_HEADER)) {
|
if ((UINT32)buffer.size() <= sizeof(EFI_CAPSULE_HEADER)) {
|
||||||
@ -304,15 +84,14 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer)
|
|||||||
.hexarg2(capsuleHeader->Flags, 8);
|
.hexarg2(capsuleHeader->Flags, 8);
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
PARSING_DATA pdata = getParsingData();
|
PARSING_DATA pdata = getParsingData(QModelIndex());
|
||||||
pdata.fixed = TRUE;
|
pdata.fixed = TRUE;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, convertParsingData(pdata));
|
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, convertParsingData(pdata), root);
|
||||||
}
|
}
|
||||||
// Check buffer for being extended Aptio signed capsule header
|
// Check buffer for being extended Aptio signed capsule header
|
||||||
else if (buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID) || buffer.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) {
|
else if (buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID) || buffer.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) {
|
||||||
|
|
||||||
bool signedCapsule = buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID);
|
bool signedCapsule = buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID);
|
||||||
// Get info
|
// Get info
|
||||||
const APTIO_CAPSULE_HEADER* capsuleHeader = (const APTIO_CAPSULE_HEADER*)buffer.constData();
|
const APTIO_CAPSULE_HEADER* capsuleHeader = (const APTIO_CAPSULE_HEADER*)buffer.constData();
|
||||||
@ -328,17 +107,21 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer)
|
|||||||
.hexarg2(capsuleHeader->CapsuleHeader.Flags, 8);
|
.hexarg2(capsuleHeader->CapsuleHeader.Flags, 8);
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
PARSING_DATA pdata = getParsingData();
|
PARSING_DATA pdata = getParsingData(QModelIndex());
|
||||||
pdata.fixed = TRUE;
|
pdata.fixed = TRUE;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, QString(), info, header, body, convertParsingData(pdata));
|
index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, QString(), info, header, body, convertParsingData(pdata), root);
|
||||||
|
|
||||||
// Show message about possible Aptio signature break
|
// Show message about possible Aptio signature break
|
||||||
if (signedCapsule) {
|
if (signedCapsule) {
|
||||||
msg(tr("parseImageFile: Aptio capsule signature may become invalid after image modifications"), index);
|
msg(tr("parseImageFile: Aptio capsule signature may become invalid after image modifications"), index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Other cases
|
||||||
|
else {
|
||||||
|
index = root;
|
||||||
|
}
|
||||||
|
|
||||||
// Skip capsule header to have flash chip image
|
// Skip capsule header to have flash chip image
|
||||||
QByteArray flashImage = buffer.mid(capsuleHeaderSize);
|
QByteArray flashImage = buffer.mid(capsuleHeaderSize);
|
||||||
@ -368,6 +151,8 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer)
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
QModelIndex biosIndex = model->addItem(Types::Image, Subtypes::UefiImage, name, QString(), info, QByteArray(), flashImage, convertParsingData(pdata), index);
|
QModelIndex biosIndex = model->addItem(Types::Image, Subtypes::UefiImage, name, QString(), info, QByteArray(), flashImage, convertParsingData(pdata), index);
|
||||||
|
|
||||||
|
// Parse the image
|
||||||
return parseRawArea(flashImage, biosIndex);
|
return parseRawArea(flashImage, biosIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,7 +445,7 @@ STATUS FfsParser::parseMeRegion(const QByteArray & me, const UINT32 parentOffset
|
|||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = getParsingData(parent);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("ME/TXE region");
|
QString name = tr("ME region");
|
||||||
QString info = tr("Full size: %1h (%2)").
|
QString info = tr("Full size: %1h (%2)").
|
||||||
hexarg(me.size()).arg(me.size());
|
hexarg(me.size()).arg(me.size());
|
||||||
|
|
||||||
@ -706,10 +491,10 @@ STATUS FfsParser::parseMeRegion(const QByteArray & me, const UINT32 parentOffset
|
|||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (emptyRegion) {
|
if (emptyRegion) {
|
||||||
msg(tr("parseMeRegion: ME/TXE region is empty"), index);
|
msg(tr("parseMeRegion: ME region is empty"), index);
|
||||||
}
|
}
|
||||||
else if (!versionFound) {
|
else if (!versionFound) {
|
||||||
msg(tr("parseMeRegion: ME/TXE region version is unknown, it can be damaged"), index);
|
msg(tr("parseMeRegion: ME version is unknown, it can be damaged"), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -779,7 +564,7 @@ UINT8 FfsParser::getPaddingType(const QByteArray & padding)
|
|||||||
return Subtypes::DataPadding;
|
return Subtypes::DataPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATUS FfsParser::parseRawArea(const QByteArray & bios, const QModelIndex & index)
|
STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & index)
|
||||||
{
|
{
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
@ -794,7 +579,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & bios, const QModelIndex & inde
|
|||||||
STATUS result;
|
STATUS result;
|
||||||
UINT32 prevVolumeOffset;
|
UINT32 prevVolumeOffset;
|
||||||
|
|
||||||
result = findNextVolume(bios, 0, prevVolumeOffset);
|
result = findNextVolume(data, 0, prevVolumeOffset);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -803,7 +588,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & bios, const QModelIndex & inde
|
|||||||
QString info;
|
QString info;
|
||||||
if (prevVolumeOffset > 0) {
|
if (prevVolumeOffset > 0) {
|
||||||
// Get info
|
// Get info
|
||||||
QByteArray padding = bios.left(prevVolumeOffset);
|
QByteArray padding = data.left(prevVolumeOffset);
|
||||||
name = tr("Padding");
|
name = tr("Padding");
|
||||||
info = tr("Full size: %1h (%2)")
|
info = tr("Full size: %1h (%2)")
|
||||||
.hexarg(padding.size()).arg(padding.size());
|
.hexarg(padding.size()).arg(padding.size());
|
||||||
@ -826,7 +611,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & bios, const QModelIndex & inde
|
|||||||
if (volumeOffset > prevVolumeOffset + prevVolumeSize) {
|
if (volumeOffset > prevVolumeOffset + prevVolumeSize) {
|
||||||
UINT32 paddingOffset = prevVolumeOffset + prevVolumeSize;
|
UINT32 paddingOffset = prevVolumeOffset + prevVolumeSize;
|
||||||
UINT32 paddingSize = volumeOffset - paddingOffset;
|
UINT32 paddingSize = volumeOffset - paddingOffset;
|
||||||
QByteArray padding = bios.mid(paddingOffset, paddingSize);
|
QByteArray padding = data.mid(paddingOffset, paddingSize);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
name = tr("Padding");
|
name = tr("Padding");
|
||||||
@ -845,15 +630,15 @@ STATUS FfsParser::parseRawArea(const QByteArray & bios, const QModelIndex & inde
|
|||||||
// Get volume size
|
// Get volume size
|
||||||
UINT32 volumeSize = 0;
|
UINT32 volumeSize = 0;
|
||||||
UINT32 bmVolumeSize = 0;
|
UINT32 bmVolumeSize = 0;
|
||||||
result = getVolumeSize(bios, volumeOffset, volumeSize, bmVolumeSize);
|
result = getVolumeSize(data, volumeOffset, volumeSize, bmVolumeSize);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
// Check that volume is fully present in input
|
// Check that volume is fully present in input
|
||||||
QByteArray volume = bios.mid(volumeOffset, volumeSize);
|
QByteArray volume = data.mid(volumeOffset, volumeSize);
|
||||||
if (volumeSize > (UINT32)volume.size()) {
|
if (volumeSize > (UINT32)volume.size()) {
|
||||||
// Mark the rest as padding and finish the parsing
|
// Mark the rest as padding and finish the parsing
|
||||||
QByteArray padding = bios.right(volume.size());
|
QByteArray padding = data.right(volume.size());
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
name = tr("Padding");
|
name = tr("Padding");
|
||||||
@ -892,13 +677,13 @@ STATUS FfsParser::parseRawArea(const QByteArray & bios, const QModelIndex & inde
|
|||||||
// Go to next volume
|
// Go to next volume
|
||||||
prevVolumeOffset = volumeOffset;
|
prevVolumeOffset = volumeOffset;
|
||||||
prevVolumeSize = volumeSize;
|
prevVolumeSize = volumeSize;
|
||||||
result = findNextVolume(bios, volumeOffset + prevVolumeSize, volumeOffset);
|
result = findNextVolume(data, volumeOffset + prevVolumeSize, volumeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Padding at the end of BIOS space
|
// Padding at the end of BIOS space
|
||||||
volumeOffset = prevVolumeOffset + prevVolumeSize;
|
volumeOffset = prevVolumeOffset + prevVolumeSize;
|
||||||
if ((UINT32)bios.size() > volumeOffset) {
|
if ((UINT32)data.size() > volumeOffset) {
|
||||||
QByteArray padding = bios.mid(volumeOffset);
|
QByteArray padding = data.mid(volumeOffset);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
name = tr("Padding");
|
name = tr("Padding");
|
||||||
@ -1268,7 +1053,7 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
QModelIndex fileIndex;
|
QModelIndex fileIndex;
|
||||||
STATUS result = parseFileHeader(file, volumeHeaderSize + fileOffset, index, fileIndex);
|
STATUS result = parseFileHeader(file, volumeHeaderSize + fileOffset, index, fileIndex);
|
||||||
if (result)
|
if (result)
|
||||||
msg(tr("parseVolumeBody: file header parsing failed with error %1").arg(errorCodeToQString(result)), index);
|
msg(tr("parseVolumeBody: file header parsing failed with error \"%1\"").arg(errorCodeToQString(result)), index);
|
||||||
|
|
||||||
// Move to next file
|
// Move to next file
|
||||||
fileOffset += fileSize;
|
fileOffset += fileSize;
|
||||||
@ -1608,7 +1393,7 @@ STATUS FfsParser::parseSections(QByteArray sections, const QModelIndex & index)
|
|||||||
QModelIndex sectionIndex;
|
QModelIndex sectionIndex;
|
||||||
STATUS result = parseSectionHeader(sections.mid(sectionOffset, sectionSize), headerSize + sectionOffset, index, sectionIndex);
|
STATUS result = parseSectionHeader(sections.mid(sectionOffset, sectionSize), headerSize + sectionOffset, index, sectionIndex);
|
||||||
if (result)
|
if (result)
|
||||||
msg(tr("parseSections: section header parsing failed with error %1").arg(errorCodeToQString(result)), index);
|
msg(tr("parseSections: section header parsing failed with error \"%1\"").arg(errorCodeToQString(result)), index);
|
||||||
|
|
||||||
// Move to next section
|
// Move to next section
|
||||||
sectionOffset += sectionSize;
|
sectionOffset += sectionSize;
|
||||||
@ -2271,6 +2056,21 @@ STATUS FfsParser::parseUiSectionBody(const QModelIndex & index)
|
|||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATUS FfsParser::parseAprioriRawSection(const QByteArray & body, QString & parsed)
|
||||||
|
{
|
||||||
|
parsed.clear();
|
||||||
|
|
||||||
|
UINT32 count = body.size() / sizeof(EFI_GUID);
|
||||||
|
if (count > 0) {
|
||||||
|
for (UINT32 i = 0; i < count; i++) {
|
||||||
|
const EFI_GUID* guid = (const EFI_GUID*)body.constData() + i;
|
||||||
|
parsed += tr("\n%1").arg(guidToQString(*guid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
STATUS FfsParser::parseRawSectionBody(const QModelIndex & index)
|
STATUS FfsParser::parseRawSectionBody(const QModelIndex & index)
|
||||||
{
|
{
|
||||||
// Sanity check
|
// Sanity check
|
||||||
@ -2485,65 +2285,3 @@ STATUS FfsEngine::parseFirmwareVolumeImageSectionHeader(const QByteArray & secti
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
STATUS FfsParser::extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode)
|
|
||||||
{
|
|
||||||
// Sanity check
|
|
||||||
if (!index.isValid())
|
|
||||||
return ERR_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
// Get data from parsing data
|
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
|
||||||
|
|
||||||
// Construct a name for extracted data
|
|
||||||
QString itemName = model->name(index);
|
|
||||||
QString itemText = model->text(index);
|
|
||||||
switch (model->type(index)) {
|
|
||||||
case Types::Volume: {
|
|
||||||
if (pdata.volume.hasExtendedHeader)
|
|
||||||
name = guidToQString(pdata.volume.extendedHeaderGuid);
|
|
||||||
else
|
|
||||||
name = itemName;
|
|
||||||
} break;
|
|
||||||
case Types::File: {
|
|
||||||
name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_');
|
|
||||||
} break;
|
|
||||||
case Types::Section: {
|
|
||||||
// Get parent file name
|
|
||||||
QModelIndex fileIndex = model->findParentOfType(index, Types::File);
|
|
||||||
QString fileText = model->text(fileIndex);
|
|
||||||
name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_');
|
|
||||||
// Append section subtype name
|
|
||||||
name += QChar('_') + itemName.replace(' ', '_');
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Types::Capsule:
|
|
||||||
case Types::Image:
|
|
||||||
case Types::Region:
|
|
||||||
case Types::Padding:
|
|
||||||
default:
|
|
||||||
name = itemName.replace(' ', '_').replace('/', '_');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get extracted data
|
|
||||||
if (mode == EXTRACT_MODE_AS_IS) {
|
|
||||||
// Extract as is, with header body and tail
|
|
||||||
extracted.clear();
|
|
||||||
extracted.append(model->header(index));
|
|
||||||
extracted.append(model->body(index));
|
|
||||||
// Handle file tail
|
|
||||||
if (model->type(index) == Types::File) {
|
|
||||||
if (pdata.file.hasTail)
|
|
||||||
extracted.append(pdata.file.tail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == EXTRACT_MODE_BODY) {
|
|
||||||
name += tr("_body");
|
|
||||||
// Extract without header and tail
|
|
||||||
extracted.clear();
|
|
||||||
extracted.append(model->body(index));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return ERR_UNKNOWN_EXTRACT_MODE;
|
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
@ -19,112 +19,33 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QQueue>
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include "basetypes.h"
|
#include "basetypes.h"
|
||||||
#include "treemodel.h"
|
#include "treemodel.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "peimage.h"
|
#include "peimage.h"
|
||||||
|
#include "parsingdata.h"
|
||||||
#ifndef _CONSOLE
|
|
||||||
#include "messagelistitem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class TreeModel;
|
class TreeModel;
|
||||||
|
|
||||||
//The whole parsing data is an information needed for each level of image reconstruction
|
|
||||||
//routines without the need of backward traversal
|
|
||||||
|
|
||||||
//typedef struct _CAPSULE_PARSING_DATA {
|
|
||||||
//} CAPSULE_PARSING_DATA;
|
|
||||||
|
|
||||||
//typedef struct _IMAGE_PARSING_DATA {
|
|
||||||
//} IMAGE_PARSING_DATA;
|
|
||||||
|
|
||||||
//typedef struct _PADDING_PARSING_DATA {
|
|
||||||
//} PADDING_PARSING_DATA;
|
|
||||||
|
|
||||||
typedef struct _VOLUME_PARSING_DATA {
|
|
||||||
EFI_GUID extendedHeaderGuid;
|
|
||||||
UINT32 alignment;
|
|
||||||
UINT8 revision;
|
|
||||||
BOOLEAN hasExtendedHeader;
|
|
||||||
BOOLEAN hasZeroVectorCRC32;
|
|
||||||
BOOLEAN isWeakAligned;
|
|
||||||
} VOLUME_PARSING_DATA;
|
|
||||||
|
|
||||||
//typedef struct _FREE_SPACE_PARSING_DATA {
|
|
||||||
//} FREE_SPACE_PARSING_DATA;
|
|
||||||
|
|
||||||
typedef struct _FILE_PARSING_DATA {
|
|
||||||
UINT16 tail;
|
|
||||||
BOOLEAN hasTail;
|
|
||||||
} FILE_PARSING_DATA;
|
|
||||||
|
|
||||||
typedef struct _COMPRESSED_SECTION_PARSING_DATA {
|
|
||||||
UINT32 uncompressedSize;
|
|
||||||
UINT8 compressionType;
|
|
||||||
UINT8 algorithm;
|
|
||||||
} COMPRESSED_SECTION_PARSING_DATA;
|
|
||||||
|
|
||||||
typedef struct _GUIDED_SECTION_PARSING_DATA {
|
|
||||||
EFI_GUID guid;
|
|
||||||
UINT32 attributes;
|
|
||||||
} GUIDED_SECTION_PARSING_DATA;
|
|
||||||
|
|
||||||
typedef struct _FREEFORM_GUIDED_SECTION_PARSING_DATA {
|
|
||||||
EFI_GUID guid;
|
|
||||||
} FREEFORM_GUIDED_SECTION_PARSING_DATA;
|
|
||||||
|
|
||||||
typedef struct _SECTION_PARSING_DATA {
|
|
||||||
union {
|
|
||||||
COMPRESSED_SECTION_PARSING_DATA compressed;
|
|
||||||
GUIDED_SECTION_PARSING_DATA guidDefined;
|
|
||||||
FREEFORM_GUIDED_SECTION_PARSING_DATA freeformSubtypeGuid;
|
|
||||||
};
|
|
||||||
} SECTION_PARSING_DATA;
|
|
||||||
|
|
||||||
typedef struct _PARSING_DATA {
|
|
||||||
BOOLEAN fixed;
|
|
||||||
BOOLEAN isOnFlash;
|
|
||||||
UINT8 emptyByte;
|
|
||||||
UINT8 ffsVersion;
|
|
||||||
UINT32 offset;
|
|
||||||
UINT64 address;
|
|
||||||
union {
|
|
||||||
//CAPSULE_PARSING_DATA capsule;
|
|
||||||
//IMAGE_PARSING_DATA image;
|
|
||||||
//PADDING_PARSING_DATA padding;
|
|
||||||
VOLUME_PARSING_DATA volume;
|
|
||||||
//FREE_SPACE_PARSING_DATA freeSpace;
|
|
||||||
FILE_PARSING_DATA file;
|
|
||||||
SECTION_PARSING_DATA section;
|
|
||||||
};
|
|
||||||
} PARSING_DATA;
|
|
||||||
|
|
||||||
class FfsParser : public QObject
|
class FfsParser : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Default constructor and destructor
|
// Default constructor and destructor
|
||||||
FfsParser(QObject *parent = 0);
|
FfsParser(TreeModel* treeModel, QObject *parent = 0);
|
||||||
~FfsParser(void);
|
~FfsParser();
|
||||||
|
|
||||||
// Returns model for Qt view classes
|
// Returns messages
|
||||||
TreeModel* treeModel() const;
|
QVector<QPair<QString, QModelIndex> > getMessages() const;
|
||||||
|
// Clears messages
|
||||||
#ifndef _CONSOLE
|
|
||||||
// Returns message items queue
|
|
||||||
QQueue<MessageListItem> messages() const;
|
|
||||||
// Clears message items queue
|
|
||||||
void clearMessages();
|
void clearMessages();
|
||||||
#endif
|
|
||||||
|
|
||||||
// Firmware image parsing
|
// Firmware image parsing
|
||||||
STATUS parseImageFile(const QByteArray & imageFile);
|
STATUS parseImageFile(const QByteArray & imageFile, const QModelIndex & index);
|
||||||
STATUS parseRawArea(const QByteArray & bios, const QModelIndex & index);
|
STATUS parseRawArea(const QByteArray & data, const QModelIndex & index);
|
||||||
STATUS parseVolumeHeader(const QByteArray & volume, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
STATUS parseVolumeHeader(const QByteArray & volume, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
STATUS parseVolumeBody(const QModelIndex & index);
|
STATUS parseVolumeBody(const QModelIndex & index);
|
||||||
STATUS parseFileHeader(const QByteArray & file, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
STATUS parseFileHeader(const QByteArray & file, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
@ -132,17 +53,15 @@ public:
|
|||||||
STATUS parseSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
STATUS parseSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
STATUS parseSectionBody(const QModelIndex & index);
|
STATUS parseSectionBody(const QModelIndex & index);
|
||||||
|
|
||||||
// Search routines TODO: move to another class
|
/*// Search routines TODO: move to another class
|
||||||
STATUS findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode);
|
// Extract routine TODO: move to another class
|
||||||
STATUS findGuidPattern(const QModelIndex & index, const QByteArray & guidPattern, const UINT8 mode);
|
STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode);*/
|
||||||
STATUS findTextPattern(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive);
|
|
||||||
|
|
||||||
STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeModel *model;
|
TreeModel *model;
|
||||||
|
QVector<QPair<QString, QModelIndex> > messagesVector;
|
||||||
|
|
||||||
STATUS parseIntelImage(const QByteArray & intelImage, const QModelIndex & parent, QModelIndex & index);
|
STATUS parseIntelImage(const QByteArray & intelImage, const QModelIndex & parent, QModelIndex & root = QModelIndex());
|
||||||
STATUS parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
STATUS parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
STATUS parseMeRegion(const QByteArray & me, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
STATUS parseMeRegion(const QByteArray & me, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
STATUS parseBiosRegion(const QByteArray & bios, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
STATUS parseBiosRegion(const QByteArray & bios, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
|
||||||
@ -165,7 +84,7 @@ private:
|
|||||||
STATUS parseUiSectionBody(const QModelIndex & index);
|
STATUS parseUiSectionBody(const QModelIndex & index);
|
||||||
STATUS parseRawSectionBody(const QModelIndex & index);
|
STATUS parseRawSectionBody(const QModelIndex & index);
|
||||||
|
|
||||||
UINT8 getPaddingType(const QByteArray & padding);
|
UINT8 getPaddingType(const QByteArray & padding);
|
||||||
STATUS parseAprioriRawSection(const QByteArray & body, QString & parsed);
|
STATUS parseAprioriRawSection(const QByteArray & body, QString & parsed);
|
||||||
STATUS findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
|
STATUS findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
|
||||||
STATUS getVolumeSize(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
|
STATUS getVolumeSize(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
|
||||||
@ -174,12 +93,7 @@ private:
|
|||||||
|
|
||||||
// Internal operations
|
// Internal operations
|
||||||
BOOLEAN hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2);
|
BOOLEAN hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2);
|
||||||
PARSING_DATA getParsingData(const QModelIndex & index = QModelIndex());
|
|
||||||
QByteArray convertParsingData(const PARSING_DATA & pdata);
|
|
||||||
|
|
||||||
#ifndef _CONSOLE
|
|
||||||
QQueue<MessageListItem> messageItems;
|
|
||||||
#endif
|
|
||||||
// Message helper
|
// Message helper
|
||||||
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
||||||
|
|
90
common/parsingdata.h
Normal file
90
common/parsingdata.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* ffsparser.h
|
||||||
|
|
||||||
|
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,
|
||||||
|
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
|
||||||
|
Parsing data is an information needed for each level of image reconstruction
|
||||||
|
routines without the need of backward traversal
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PARSINGDATA_H__
|
||||||
|
#define __PARSINGDATA_H__
|
||||||
|
|
||||||
|
#include "basetypes.h"
|
||||||
|
|
||||||
|
//typedef struct _CAPSULE_PARSING_DATA {
|
||||||
|
//} CAPSULE_PARSING_DATA;
|
||||||
|
|
||||||
|
//typedef struct _IMAGE_PARSING_DATA {
|
||||||
|
//} IMAGE_PARSING_DATA;
|
||||||
|
|
||||||
|
//typedef struct _PADDING_PARSING_DATA {
|
||||||
|
//} PADDING_PARSING_DATA;
|
||||||
|
|
||||||
|
typedef struct _VOLUME_PARSING_DATA {
|
||||||
|
EFI_GUID extendedHeaderGuid;
|
||||||
|
UINT32 alignment;
|
||||||
|
UINT8 revision;
|
||||||
|
BOOLEAN hasExtendedHeader;
|
||||||
|
BOOLEAN hasZeroVectorCRC32;
|
||||||
|
BOOLEAN isWeakAligned;
|
||||||
|
} VOLUME_PARSING_DATA;
|
||||||
|
|
||||||
|
//typedef struct _FREE_SPACE_PARSING_DATA {
|
||||||
|
//} FREE_SPACE_PARSING_DATA;
|
||||||
|
|
||||||
|
typedef struct _FILE_PARSING_DATA {
|
||||||
|
UINT16 tail;
|
||||||
|
BOOLEAN hasTail;
|
||||||
|
} FILE_PARSING_DATA;
|
||||||
|
|
||||||
|
typedef struct _COMPRESSED_SECTION_PARSING_DATA {
|
||||||
|
UINT32 uncompressedSize;
|
||||||
|
UINT8 compressionType;
|
||||||
|
UINT8 algorithm;
|
||||||
|
} COMPRESSED_SECTION_PARSING_DATA;
|
||||||
|
|
||||||
|
typedef struct _GUIDED_SECTION_PARSING_DATA {
|
||||||
|
EFI_GUID guid;
|
||||||
|
UINT32 attributes;
|
||||||
|
} GUIDED_SECTION_PARSING_DATA;
|
||||||
|
|
||||||
|
typedef struct _FREEFORM_GUIDED_SECTION_PARSING_DATA {
|
||||||
|
EFI_GUID guid;
|
||||||
|
} FREEFORM_GUIDED_SECTION_PARSING_DATA;
|
||||||
|
|
||||||
|
typedef struct _SECTION_PARSING_DATA {
|
||||||
|
union {
|
||||||
|
COMPRESSED_SECTION_PARSING_DATA compressed;
|
||||||
|
GUIDED_SECTION_PARSING_DATA guidDefined;
|
||||||
|
FREEFORM_GUIDED_SECTION_PARSING_DATA freeformSubtypeGuid;
|
||||||
|
};
|
||||||
|
} SECTION_PARSING_DATA;
|
||||||
|
|
||||||
|
typedef struct _PARSING_DATA {
|
||||||
|
BOOLEAN fixed;
|
||||||
|
BOOLEAN isOnFlash;
|
||||||
|
UINT8 emptyByte;
|
||||||
|
UINT8 ffsVersion;
|
||||||
|
UINT32 offset;
|
||||||
|
UINT64 address;
|
||||||
|
union {
|
||||||
|
//CAPSULE_PARSING_DATA capsule;
|
||||||
|
//IMAGE_PARSING_DATA image;
|
||||||
|
//PADDING_PARSING_DATA padding;
|
||||||
|
VOLUME_PARSING_DATA volume;
|
||||||
|
//FREE_SPACE_PARSING_DATA freeSpace;
|
||||||
|
FILE_PARSING_DATA file;
|
||||||
|
SECTION_PARSING_DATA section;
|
||||||
|
};
|
||||||
|
} PARSING_DATA;
|
||||||
|
|
||||||
|
#endif
|
@ -24,7 +24,7 @@ QString regionTypeToQString(const UINT8 type)
|
|||||||
case Subtypes::GbeRegion:
|
case Subtypes::GbeRegion:
|
||||||
return QObject::tr("GbE");
|
return QObject::tr("GbE");
|
||||||
case Subtypes::MeRegion:
|
case Subtypes::MeRegion:
|
||||||
return QObject::tr("ME/TXE");
|
return QObject::tr("ME");
|
||||||
case Subtypes::BiosRegion:
|
case Subtypes::BiosRegion:
|
||||||
return QObject::tr("BIOS");
|
return QObject::tr("BIOS");
|
||||||
case Subtypes::PdrRegion:
|
case Subtypes::PdrRegion:
|
@ -11,6 +11,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include "treemodel.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "ffs.h"
|
#include "ffs.h"
|
||||||
#include "Tiano/EfiTianoCompress.h"
|
#include "Tiano/EfiTianoCompress.h"
|
||||||
@ -18,6 +19,31 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "LZMA/LzmaCompress.h"
|
#include "LZMA/LzmaCompress.h"
|
||||||
#include "LZMA/LzmaDecompress.h"
|
#include "LZMA/LzmaDecompress.h"
|
||||||
|
|
||||||
|
// Returns either new parsing data instance or obtains it from index
|
||||||
|
PARSING_DATA getParsingData(const QModelIndex & index)
|
||||||
|
{
|
||||||
|
if (index.isValid()) {
|
||||||
|
TreeModel* model = (TreeModel*)index.model();
|
||||||
|
return *(PARSING_DATA*)model->parsingData(index).data();
|
||||||
|
}
|
||||||
|
|
||||||
|
PARSING_DATA data;
|
||||||
|
data.fixed = FALSE; // Item is not fixed by default
|
||||||
|
data.isOnFlash = TRUE; // Data is on flash by default
|
||||||
|
data.offset = 0;
|
||||||
|
data.address = 0;
|
||||||
|
data.ffsVersion = 0; // Unknown by default
|
||||||
|
|
||||||
|
// Type-specific parts remain unitialized
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts parsing data to byte array
|
||||||
|
QByteArray convertParsingData(const PARSING_DATA & pdata)
|
||||||
|
{
|
||||||
|
return QByteArray((const char*)&pdata, sizeof(PARSING_DATA));
|
||||||
|
}
|
||||||
|
|
||||||
// Returns text representation of error code
|
// Returns text representation of error code
|
||||||
QString errorCodeToQString(UINT8 errorCode)
|
QString errorCodeToQString(UINT8 errorCode)
|
||||||
{
|
{
|
||||||
@ -40,7 +66,7 @@ QString errorCodeToQString(UINT8 errorCode)
|
|||||||
case ERR_VOLUMES_NOT_FOUND: return QObject::tr("UEFI volumes not found");
|
case ERR_VOLUMES_NOT_FOUND: return QObject::tr("UEFI volumes not found");
|
||||||
case ERR_INVALID_VOLUME: return QObject::tr("Invalid UEFI volume");
|
case ERR_INVALID_VOLUME: return QObject::tr("Invalid UEFI volume");
|
||||||
case ERR_VOLUME_REVISION_NOT_SUPPORTED: return QObject::tr("Volume revision not supported");
|
case ERR_VOLUME_REVISION_NOT_SUPPORTED: return QObject::tr("Volume revision not supported");
|
||||||
case ERR_VOLUME_GROW_FAILED: return QObject::tr("Volume grow failed");
|
//case ERR_VOLUME_GROW_FAILED: return QObject::tr("Volume grow failed");
|
||||||
case ERR_UNKNOWN_FFS: return QObject::tr("Unknown file system");
|
case ERR_UNKNOWN_FFS: return QObject::tr("Unknown file system");
|
||||||
case ERR_INVALID_FILE: return QObject::tr("Invalid file");
|
case ERR_INVALID_FILE: return QObject::tr("Invalid file");
|
||||||
case ERR_INVALID_SECTION: return QObject::tr("Invalid section");
|
case ERR_INVALID_SECTION: return QObject::tr("Invalid section");
|
||||||
@ -51,20 +77,20 @@ QString errorCodeToQString(UINT8 errorCode)
|
|||||||
case ERR_CUSTOMIZED_DECOMPRESSION_FAILED: return QObject::tr("Customized compression failed");
|
case ERR_CUSTOMIZED_DECOMPRESSION_FAILED: return QObject::tr("Customized compression failed");
|
||||||
case ERR_UNKNOWN_COMPRESSION_TYPE: return QObject::tr("Unknown compression type");
|
case ERR_UNKNOWN_COMPRESSION_TYPE: return QObject::tr("Unknown compression type");
|
||||||
case ERR_UNKNOWN_EXTRACT_MODE: return QObject::tr("Unknown extract mode");
|
case ERR_UNKNOWN_EXTRACT_MODE: return QObject::tr("Unknown extract mode");
|
||||||
case ERR_UNKNOWN_INSERT_MODE: return QObject::tr("Unknown insert mode");
|
//case ERR_UNKNOWN_INSERT_MODE: return QObject::tr("Unknown insert mode");
|
||||||
case ERR_UNKNOWN_IMAGE_TYPE: return QObject::tr("Unknown executable image type");
|
case ERR_UNKNOWN_IMAGE_TYPE: return QObject::tr("Unknown executable image type");
|
||||||
case ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE: return QObject::tr("Unknown PE optional header type");
|
case ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE: return QObject::tr("Unknown PE optional header type");
|
||||||
case ERR_UNKNOWN_RELOCATION_TYPE: return QObject::tr("Unknown relocation type");
|
case ERR_UNKNOWN_RELOCATION_TYPE: return QObject::tr("Unknown relocation type");
|
||||||
case ERR_GENERIC_CALL_NOT_SUPPORTED: return QObject::tr("Generic call not supported");
|
//case ERR_GENERIC_CALL_NOT_SUPPORTED: return QObject::tr("Generic call not supported");
|
||||||
case ERR_VOLUME_BASE_NOT_FOUND: return QObject::tr("Volume base address not found");
|
//case ERR_VOLUME_BASE_NOT_FOUND: return QObject::tr("Volume base address not found");
|
||||||
case ERR_PEI_CORE_ENTRY_POINT_NOT_FOUND: return QObject::tr("PEI core entry point not found");
|
//case ERR_PEI_CORE_ENTRY_POINT_NOT_FOUND: return QObject::tr("PEI core entry point not found");
|
||||||
case ERR_COMPLEX_BLOCK_MAP: return QObject::tr("Block map structure too complex for correct analysis");
|
case ERR_COMPLEX_BLOCK_MAP: return QObject::tr("Block map structure too complex for correct analysis");
|
||||||
case ERR_DIR_ALREADY_EXIST: return QObject::tr("Directory already exists");
|
case ERR_DIR_ALREADY_EXIST: return QObject::tr("Directory already exists");
|
||||||
case ERR_DIR_CREATE: return QObject::tr("Directory can't be created");
|
case ERR_DIR_CREATE: return QObject::tr("Directory can't be created");
|
||||||
case ERR_UNKNOWN_PATCH_TYPE: return QObject::tr("Unknown patch type");
|
//case ERR_UNKNOWN_PATCH_TYPE: return QObject::tr("Unknown patch type");
|
||||||
case ERR_PATCH_OFFSET_OUT_OF_BOUNDS: return QObject::tr("Patch offset out of bounds");
|
//case ERR_PATCH_OFFSET_OUT_OF_BOUNDS: return QObject::tr("Patch offset out of bounds");
|
||||||
case ERR_INVALID_SYMBOL: return QObject::tr("Invalid symbol");
|
//case ERR_INVALID_SYMBOL: return QObject::tr("Invalid symbol");
|
||||||
case ERR_NOTHING_TO_PATCH: return QObject::tr("Nothing to patch");
|
//case ERR_NOTHING_TO_PATCH: return QObject::tr("Nothing to patch");
|
||||||
case ERR_DEPEX_PARSE_FAILED: return QObject::tr("Dependency expression parsing failed");
|
case ERR_DEPEX_PARSE_FAILED: return QObject::tr("Dependency expression parsing failed");
|
||||||
default: return QObject::tr("Unknown error %1").arg(errorCode);
|
default: return QObject::tr("Unknown error %1").arg(errorCode);
|
||||||
}
|
}
|
||||||
@ -198,7 +224,6 @@ STATUS decompress(const QByteArray & compressedData, UINT8 & algorithm, QByteArr
|
|||||||
|
|
||||||
// Decompress section data
|
// Decompress section data
|
||||||
if (ERR_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
|
if (ERR_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
|
||||||
//TODO: implement it again, if needed
|
|
||||||
// Intel modified LZMA workaround
|
// Intel modified LZMA workaround
|
||||||
// Decompress section data once again
|
// Decompress section data once again
|
||||||
data += sizeof(UINT32);
|
data += sizeof(UINT32);
|
@ -10,8 +10,20 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTILITY_H__
|
||||||
|
#define __UTILITY_H__
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QModelIndex>
|
||||||
#include "basetypes.h"
|
#include "basetypes.h"
|
||||||
|
#include "parsingdata.h"
|
||||||
|
|
||||||
|
// Returns either new parsing data instance or obtains it from index
|
||||||
|
PARSING_DATA getParsingData(const QModelIndex & index);
|
||||||
|
|
||||||
|
// Converts parsing data to byte array
|
||||||
|
QByteArray convertParsingData(const PARSING_DATA & pdata);
|
||||||
|
|
||||||
// Converts error code to QString
|
// Converts error code to QString
|
||||||
extern QString errorCodeToQString(UINT8 errorCode);
|
extern QString errorCodeToQString(UINT8 errorCode);
|
||||||
@ -24,3 +36,5 @@ extern STATUS decompress(const QByteArray & compressed, UINT8 & algorithm, QByte
|
|||||||
|
|
||||||
// CRC32
|
// CRC32
|
||||||
extern UINT32 crc32(UINT32 initial, const UINT8* buffer, UINT32 length);
|
extern UINT32 crc32(UINT32 initial, const UINT8* buffer, UINT32 length);
|
||||||
|
|
||||||
|
#endif
|
@ -1,61 +0,0 @@
|
|||||||
/* guidlineedit.cpp
|
|
||||||
|
|
||||||
Copyright (c) 2014, 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 "guidlineedit.h"
|
|
||||||
|
|
||||||
GuidLineEdit::GuidLineEdit(QWidget * parent)
|
|
||||||
:QLineEdit(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GuidLineEdit::GuidLineEdit(const QString & contents, QWidget * parent)
|
|
||||||
:QLineEdit(contents, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GuidLineEdit::~GuidLineEdit()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GuidLineEdit::keyPressEvent(QKeyEvent * event)
|
|
||||||
{
|
|
||||||
if (event == QKeySequence::Delete || event->key() == Qt::Key_Backspace)
|
|
||||||
{
|
|
||||||
int pos = cursorPosition();
|
|
||||||
if (event->key() == Qt::Key_Backspace && pos > 0) {
|
|
||||||
cursorBackward(false);
|
|
||||||
pos = cursorPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString txt = text();
|
|
||||||
QString selected = selectedText();
|
|
||||||
|
|
||||||
if (!selected.isEmpty()) {
|
|
||||||
pos = QLineEdit::selectionStart();
|
|
||||||
for (int i = pos; i < pos + selected.count(); i++)
|
|
||||||
if (txt[i] != QChar('-'))
|
|
||||||
txt[i] = QChar('.');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
txt[pos] = QChar('.');
|
|
||||||
|
|
||||||
setCursorPosition(0);
|
|
||||||
insert(txt);
|
|
||||||
setCursorPosition(pos);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call original event handler
|
|
||||||
QLineEdit::keyPressEvent(event);
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/* guidlineedit.h
|
|
||||||
|
|
||||||
Copyright (c) 2014, 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 __GUIDLINEEDIT_H__
|
|
||||||
#define __GUIDLINEEDIT_H__
|
|
||||||
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QKeySequence>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
#include "basetypes.h"
|
|
||||||
|
|
||||||
class GuidLineEdit : public QLineEdit
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GuidLineEdit(QWidget * parent = 0);
|
|
||||||
GuidLineEdit(const QString & contents, QWidget * parent = 0);
|
|
||||||
~GuidLineEdit();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent * event);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,46 +0,0 @@
|
|||||||
/* messagelistitem.cpp
|
|
||||||
|
|
||||||
Copyright (c) 2013, 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 "messagelistitem.h"
|
|
||||||
|
|
||||||
MessageListItem::MessageListItem(QListWidget * parent, int type, const QModelIndex & index)
|
|
||||||
: QListWidgetItem(parent, type)
|
|
||||||
{
|
|
||||||
itemIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageListItem::MessageListItem(const QString & text, QListWidget * parent, int type, const QModelIndex & index)
|
|
||||||
: QListWidgetItem(text, parent, type)
|
|
||||||
{
|
|
||||||
itemIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageListItem::MessageListItem(const QIcon & icon, const QString & text, QListWidget * parent, int type, const QModelIndex & index)
|
|
||||||
: QListWidgetItem(icon, text, parent, type)
|
|
||||||
{
|
|
||||||
itemIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageListItem::~MessageListItem()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex MessageListItem::index() const
|
|
||||||
{
|
|
||||||
return itemIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageListItem::setIndex(QModelIndex & index)
|
|
||||||
{
|
|
||||||
itemIndex = index;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/* messagelistitem.h
|
|
||||||
|
|
||||||
Copyright (c) 2014, 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 __MESSAGELISTITEM_H__
|
|
||||||
#define __MESSAGELISTITEM_H__
|
|
||||||
|
|
||||||
#include <QModelIndex>
|
|
||||||
#include <QListWidgetItem>
|
|
||||||
|
|
||||||
#include "basetypes.h"
|
|
||||||
|
|
||||||
class MessageListItem : public QListWidgetItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MessageListItem(QListWidget * parent = 0, int type = Type, const QModelIndex & index = QModelIndex());
|
|
||||||
MessageListItem(const QString & text, QListWidget * parent = 0, int type = Type, const QModelIndex & index = QModelIndex());
|
|
||||||
MessageListItem(const QIcon & icon, const QString & text, QListWidget * parent = 0, int type = Type, const QModelIndex & index = QModelIndex());
|
|
||||||
~MessageListItem();
|
|
||||||
|
|
||||||
QModelIndex index() const;
|
|
||||||
void setIndex(QModelIndex & index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QModelIndex itemIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,49 +0,0 @@
|
|||||||
/* searchdialog.cpp
|
|
||||||
|
|
||||||
Copyright (c) 2014, 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 "searchdialog.h"
|
|
||||||
|
|
||||||
SearchDialog::SearchDialog(QWidget *parent) :
|
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::SearchDialog),
|
|
||||||
hexValidator(QRegExp("([0-9a-fA-F\\. ])*")),
|
|
||||||
guidValidator(QRegExp("[0-9a-fA-F\\.]{8}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{4}-[0-9a-fA-F\\.]{12}"))
|
|
||||||
{
|
|
||||||
// Create UI
|
|
||||||
ui->setupUi(this);
|
|
||||||
ui->hexEdit->setValidator(&hexValidator);
|
|
||||||
ui->guidEdit->setValidator(&guidValidator);
|
|
||||||
|
|
||||||
// Connect
|
|
||||||
connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(setEditFocus(int)));
|
|
||||||
|
|
||||||
// Set initial focus
|
|
||||||
setEditFocus(ui->tabWidget->currentIndex());
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchDialog::~SearchDialog()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SearchDialog::setEditFocus(int index)
|
|
||||||
{
|
|
||||||
if (index == 0) // Hex pattern
|
|
||||||
ui->hexEdit->setFocus();
|
|
||||||
else if (index == 1) { // GUID
|
|
||||||
ui->guidEdit->setFocus();
|
|
||||||
ui->guidEdit->setCursorPosition(0);
|
|
||||||
}
|
|
||||||
else if (index == 2) // Text
|
|
||||||
ui->textEdit->setFocus();
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/* searchdialog.h
|
|
||||||
|
|
||||||
Copyright (c) 2014, 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 SEARCHDIALOG_H
|
|
||||||
#define SEARCHDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QRegExpValidator>
|
|
||||||
#include "ui_searchdialog.h"
|
|
||||||
|
|
||||||
class SearchDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
SearchDialog(QWidget *parent = 0);
|
|
||||||
~SearchDialog();
|
|
||||||
Ui::SearchDialog* ui;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void setEditFocus(int index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QRegExpValidator hexValidator;
|
|
||||||
QRegExpValidator guidValidator;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
249
searchdialog.ui
249
searchdialog.ui
@ -1,249 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>SearchDialog</class>
|
|
||||||
<widget class="QDialog" name="SearchDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>237</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Search</string>
|
|
||||||
</property>
|
|
||||||
<property name="modal">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="hexTab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Hex pattern</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="hexLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Hex pattern:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="hexEdit">
|
|
||||||
<property name="inputMask">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<widget class="QGroupBox" name="hexGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Search scope</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="hexScopeFullRadioButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Header and body</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="hexScopeHeaderRadioButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Header only</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="hexScopeBodyRadioButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Body only</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="guidTab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>GUID</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="guidLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>GUID:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="GuidLineEdit" name="guidEdit">
|
|
||||||
<property name="inputMask">
|
|
||||||
<string>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>........-....-....-....-............</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<widget class="QGroupBox" name="guidGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Search scope</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="guidScopeFullRadioButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Header and body</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="guidScopeHeaderRadioButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Header only</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="guidScopeBodyRadioButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Body only</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="textTab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Text</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="textLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Text:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="textEdit"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<widget class="QGroupBox" name="textGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Text search options</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="textUnicodeCheckBox">
|
|
||||||
<property name="text">
|
|
||||||
<string>Unicode</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="textCaseSensitiveCheckBox">
|
|
||||||
<property name="text">
|
|
||||||
<string>Case sensitive</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>GuidLineEdit</class>
|
|
||||||
<extends>QLineEdit</extends>
|
|
||||||
<header>guidlineedit.h</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<tabstops>
|
|
||||||
<tabstop>tabWidget</tabstop>
|
|
||||||
<tabstop>hexEdit</tabstop>
|
|
||||||
<tabstop>hexScopeFullRadioButton</tabstop>
|
|
||||||
<tabstop>hexScopeHeaderRadioButton</tabstop>
|
|
||||||
<tabstop>hexScopeBodyRadioButton</tabstop>
|
|
||||||
<tabstop>buttonBox</tabstop>
|
|
||||||
<tabstop>textEdit</tabstop>
|
|
||||||
<tabstop>textUnicodeCheckBox</tabstop>
|
|
||||||
<tabstop>textCaseSensitiveCheckBox</tabstop>
|
|
||||||
</tabstops>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>SearchDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>182</x>
|
|
||||||
<y>185</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>194</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>SearchDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>182</x>
|
|
||||||
<y>185</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>194</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
744
uefitool.cpp
744
uefitool.cpp
@ -1,744 +0,0 @@
|
|||||||
/* uefitool.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 "uefitool.h"
|
|
||||||
#include "ui_uefitool.h"
|
|
||||||
|
|
||||||
UEFITool::UEFITool(QWidget *parent) :
|
|
||||||
QMainWindow(parent),
|
|
||||||
ui(new Ui::UEFITool),
|
|
||||||
version(tr("0.30.0_alpha_parser_only"))
|
|
||||||
{
|
|
||||||
clipboard = QApplication::clipboard();
|
|
||||||
|
|
||||||
// Create UI
|
|
||||||
ui->setupUi(this);
|
|
||||||
searchDialog = new SearchDialog(this);
|
|
||||||
ffsParser = NULL;
|
|
||||||
|
|
||||||
// Set window title
|
|
||||||
this->setWindowTitle(tr("UEFITool %1").arg(version));
|
|
||||||
|
|
||||||
// Connect signals to slots
|
|
||||||
connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile()));
|
|
||||||
connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile()));
|
|
||||||
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
|
|
||||||
connect(ui->actionExtract, SIGNAL(triggered()), this, SLOT(extractAsIs()));
|
|
||||||
connect(ui->actionExtractBody, SIGNAL(triggered()), this, SLOT(extractBody()));
|
|
||||||
connect(ui->actionInsertInto, SIGNAL(triggered()), this, SLOT(insertInto()));
|
|
||||||
connect(ui->actionInsertBefore, SIGNAL(triggered()), this, SLOT(insertBefore()));
|
|
||||||
connect(ui->actionInsertAfter, SIGNAL(triggered()), this, SLOT(insertAfter()));
|
|
||||||
connect(ui->actionReplace, SIGNAL(triggered()), this, SLOT(replaceAsIs()));
|
|
||||||
connect(ui->actionReplaceBody, SIGNAL(triggered()), this, SLOT(replaceBody()));
|
|
||||||
connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(remove()));
|
|
||||||
connect(ui->actionRebuild, SIGNAL(triggered()), this, SLOT(rebuild()));
|
|
||||||
connect(ui->actionMessagesCopy, SIGNAL(triggered()), this, SLOT(copyMessage()));
|
|
||||||
connect(ui->actionMessagesCopyAll, SIGNAL(triggered()), this, SLOT(copyAllMessages()));
|
|
||||||
connect(ui->actionMessagesClear, SIGNAL(triggered()), this, SLOT(clearMessages()));
|
|
||||||
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
|
|
||||||
connect(ui->actionAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt()));
|
|
||||||
connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(exit()));
|
|
||||||
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings()));
|
|
||||||
|
|
||||||
// Enable Drag-and-Drop actions
|
|
||||||
this->setAcceptDrops(true);
|
|
||||||
|
|
||||||
// Set current directory
|
|
||||||
currentDir = ".";
|
|
||||||
|
|
||||||
// Set monospace font for some controls
|
|
||||||
QFont font("Courier New", 10);
|
|
||||||
#if defined Q_OS_OSX
|
|
||||||
font = QFont("Menlo", 10);
|
|
||||||
#elif defined Q_OS_WIN
|
|
||||||
font = QFont("Consolas", 9);
|
|
||||||
#endif
|
|
||||||
ui->infoEdit->setFont(font);
|
|
||||||
ui->messageListWidget->setFont(font);
|
|
||||||
ui->structureTreeView->setFont(font);
|
|
||||||
searchDialog->ui->guidEdit->setFont(font);
|
|
||||||
searchDialog->ui->hexEdit->setFont(font);
|
|
||||||
|
|
||||||
// Initialize non-persistent data
|
|
||||||
init();
|
|
||||||
|
|
||||||
// Read stored settings
|
|
||||||
readSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
UEFITool::~UEFITool()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
delete ffsParser;
|
|
||||||
delete searchDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::init()
|
|
||||||
{
|
|
||||||
// Clear components
|
|
||||||
ui->messageListWidget->clear();
|
|
||||||
ui->infoEdit->clear();
|
|
||||||
|
|
||||||
// Set window title
|
|
||||||
this->setWindowTitle(tr("UEFITool %1").arg(version));
|
|
||||||
|
|
||||||
// Disable menus
|
|
||||||
ui->menuCapsuleActions->setDisabled(true);
|
|
||||||
ui->menuImageActions->setDisabled(true);
|
|
||||||
ui->menuRegionActions->setDisabled(true);
|
|
||||||
ui->menuPaddingActions->setDisabled(true);
|
|
||||||
ui->menuVolumeActions->setDisabled(true);
|
|
||||||
ui->menuFileActions->setDisabled(true);
|
|
||||||
ui->menuSectionActions->setDisabled(true);
|
|
||||||
ui->actionMessagesCopy->setDisabled(true);
|
|
||||||
ui->actionMessagesCopyAll->setDisabled(true);
|
|
||||||
|
|
||||||
// Make new ffsEngine
|
|
||||||
if (ffsParser)
|
|
||||||
delete ffsParser;
|
|
||||||
ffsParser = new FfsParser(this);
|
|
||||||
ui->structureTreeView->setModel(ffsParser->treeModel());
|
|
||||||
|
|
||||||
// Connect
|
|
||||||
connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
|
|
||||||
this, SLOT(populateUi(const QModelIndex &)));
|
|
||||||
connect(ui->messageListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
|
||||||
connect(ui->messageListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::populateUi(const QModelIndex ¤t)
|
|
||||||
{
|
|
||||||
if (!current.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
TreeModel* model = ffsParser->treeModel();
|
|
||||||
UINT8 type = model->type(current);
|
|
||||||
//UINT8 subtype = model->subtype(current);
|
|
||||||
|
|
||||||
// Set info text
|
|
||||||
ui->infoEdit->setPlainText(model->info(current));
|
|
||||||
|
|
||||||
// Enable menus
|
|
||||||
ui->menuCapsuleActions->setEnabled(type == Types::Capsule);
|
|
||||||
ui->menuImageActions->setEnabled(type == Types::Image);
|
|
||||||
ui->menuRegionActions->setEnabled(type == Types::Region);
|
|
||||||
ui->menuPaddingActions->setEnabled(type == Types::Padding);
|
|
||||||
ui->menuVolumeActions->setEnabled(type == Types::Volume);
|
|
||||||
ui->menuFileActions->setEnabled(type == Types::File);
|
|
||||||
ui->menuSectionActions->setEnabled(type == Types::Section);
|
|
||||||
|
|
||||||
// Enable actions
|
|
||||||
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current));
|
|
||||||
//ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
|
||||||
ui->actionExtractBody->setDisabled(model->hasEmptyBody(current));
|
|
||||||
//ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
|
||||||
//ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) ||
|
|
||||||
// (type == Types::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD) ||
|
|
||||||
// (type == Types::Section && (subtype == EFI_SECTION_COMPRESSION || subtype == EFI_SECTION_GUID_DEFINED || subtype == EFI_SECTION_DISPOSABLE)));
|
|
||||||
//ui->actionInsertBefore->setEnabled(type == Types::File || type == Types::Section);
|
|
||||||
//ui->actionInsertAfter->setEnabled(type == Types::File || type == Types::Section);
|
|
||||||
//ui->actionReplace->setEnabled((type == Types::Region && subtype != Subtypes::DescriptorRegion) || type == Types::Volume || type == Types::File || type == Types::Section);
|
|
||||||
//ui->actionReplaceBody->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
|
||||||
ui->actionMessagesCopy->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::search()
|
|
||||||
{
|
|
||||||
if (searchDialog->exec() != QDialog::Accepted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QModelIndex rootIndex = ffsParser->treeModel()->index(0, 0);
|
|
||||||
|
|
||||||
int index = searchDialog->ui->tabWidget->currentIndex();
|
|
||||||
if (index == 0) { // Hex pattern
|
|
||||||
searchDialog->ui->hexEdit->setFocus();
|
|
||||||
QByteArray pattern = searchDialog->ui->hexEdit->text().toLatin1().replace(" ", "");
|
|
||||||
if (pattern.isEmpty())
|
|
||||||
return;
|
|
||||||
UINT8 mode;
|
|
||||||
if (searchDialog->ui->hexScopeHeaderRadioButton->isChecked())
|
|
||||||
mode = SEARCH_MODE_HEADER;
|
|
||||||
else if (searchDialog->ui->hexScopeBodyRadioButton->isChecked())
|
|
||||||
mode = SEARCH_MODE_BODY;
|
|
||||||
else
|
|
||||||
mode = SEARCH_MODE_ALL;
|
|
||||||
ffsParser->findHexPattern(rootIndex, pattern, mode);
|
|
||||||
showMessages();
|
|
||||||
}
|
|
||||||
else if (index == 1) { // GUID
|
|
||||||
searchDialog->ui->guidEdit->setFocus();
|
|
||||||
searchDialog->ui->guidEdit->setCursorPosition(0);
|
|
||||||
QByteArray pattern = searchDialog->ui->guidEdit->text().toLatin1();
|
|
||||||
if (pattern.isEmpty())
|
|
||||||
return;
|
|
||||||
UINT8 mode;
|
|
||||||
if (searchDialog->ui->guidScopeHeaderRadioButton->isChecked())
|
|
||||||
mode = SEARCH_MODE_HEADER;
|
|
||||||
else if (searchDialog->ui->guidScopeBodyRadioButton->isChecked())
|
|
||||||
mode = SEARCH_MODE_BODY;
|
|
||||||
else
|
|
||||||
mode = SEARCH_MODE_ALL;
|
|
||||||
ffsParser->findGuidPattern(rootIndex, pattern, mode);
|
|
||||||
showMessages();
|
|
||||||
}
|
|
||||||
else if (index == 2) { // Text string
|
|
||||||
searchDialog->ui->textEdit->setFocus();
|
|
||||||
QString pattern = searchDialog->ui->textEdit->text();
|
|
||||||
if (pattern.isEmpty())
|
|
||||||
return;
|
|
||||||
ffsParser->findTextPattern(rootIndex, pattern, searchDialog->ui->textUnicodeCheckBox->isChecked(),
|
|
||||||
(Qt::CaseSensitivity) searchDialog->ui->textCaseSensitiveCheckBox->isChecked());
|
|
||||||
showMessages();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::rebuild()
|
|
||||||
{
|
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*UINT8 result = ffsEngine->rebuild(index);
|
|
||||||
|
|
||||||
if (result == ERR_SUCCESS)
|
|
||||||
ui->actionSaveImageFile->setEnabled(true);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::remove()
|
|
||||||
{
|
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*UINT8 result = ffsEngine->remove(index);
|
|
||||||
|
|
||||||
if (result == ERR_SUCCESS)
|
|
||||||
ui->actionSaveImageFile->setEnabled(true);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::insert(const UINT8 mode)
|
|
||||||
{
|
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
TreeModel* model = ffsParser->treeModel();
|
|
||||||
UINT8 type;
|
|
||||||
|
|
||||||
if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER)
|
|
||||||
type = model->type(index.parent());
|
|
||||||
else
|
|
||||||
type = model->type(index);
|
|
||||||
|
|
||||||
QString path;
|
|
||||||
switch (type) {
|
|
||||||
case Types::Volume:
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"), currentDir, "FFS files (*.ffs *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::File:
|
|
||||||
case Types::Section:
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select section file to insert"), currentDir, "Section files (*.sct *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.trimmed().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QFileInfo fileInfo = QFileInfo(path);
|
|
||||||
if (!fileInfo.exists()) {
|
|
||||||
ui->statusBar->showMessage(tr("Please select existing file"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile inputFile;
|
|
||||||
inputFile.setFileName(path);
|
|
||||||
|
|
||||||
if (!inputFile.open(QFile::ReadOnly)) {
|
|
||||||
QMessageBox::critical(this, tr("Insertion failed"), tr("Can't open output file for reading"), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray buffer = inputFile.readAll();
|
|
||||||
inputFile.close();
|
|
||||||
|
|
||||||
/*UINT8 result = ffsEngine->insert(index, buffer, mode);
|
|
||||||
if (result) {
|
|
||||||
QMessageBox::critical(this, tr("Insertion failed"), errorMessage(result), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ui->actionSaveImageFile->setEnabled(true);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::insertInto()
|
|
||||||
{
|
|
||||||
insert(CREATE_MODE_PREPEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::insertBefore()
|
|
||||||
{
|
|
||||||
insert(CREATE_MODE_BEFORE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::insertAfter()
|
|
||||||
{
|
|
||||||
insert(CREATE_MODE_AFTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::replaceAsIs()
|
|
||||||
{
|
|
||||||
replace(REPLACE_MODE_AS_IS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::replaceBody()
|
|
||||||
{
|
|
||||||
replace(REPLACE_MODE_BODY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::replace(const UINT8 mode)
|
|
||||||
{
|
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
TreeModel* model = ffsParser->treeModel();
|
|
||||||
QString path;
|
|
||||||
if (model->type(index) == Types::Region) {
|
|
||||||
if (mode == REPLACE_MODE_AS_IS) {
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select region file to replace selected object"), currentDir, "Region files (*.rgn *.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (model->type(index) == Types::Volume) {
|
|
||||||
if (mode == REPLACE_MODE_AS_IS) {
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace selected object"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
else if (mode == REPLACE_MODE_BODY) {
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select volume body file to replace body"), currentDir, "Volume body files (*.vbd *.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (model->type(index) == Types::File) {
|
|
||||||
if (mode == REPLACE_MODE_AS_IS) {
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to replace selected object"), currentDir, "FFS files (*.ffs *.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
else if (mode == REPLACE_MODE_BODY) {
|
|
||||||
if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW)
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
|
|
||||||
else if (model->subtype(index) == EFI_FV_FILETYPE_PAD) // Pad file body can't be replaced
|
|
||||||
//!TODO: handle non-empty pad files
|
|
||||||
return;
|
|
||||||
else
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace body"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (model->type(index) == Types::Section) {
|
|
||||||
if (mode == REPLACE_MODE_AS_IS) {
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"), currentDir, "Section files (*.sct *.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
else if (mode == REPLACE_MODE_BODY) {
|
|
||||||
if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE)
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body file to replace body"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
|
|
||||||
else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE)
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace body"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
|
|
||||||
else if (model->subtype(index) == EFI_SECTION_RAW)
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
|
|
||||||
else
|
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select file to replace body"), currentDir, "Binary files (*.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (path.trimmed().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QFileInfo fileInfo = QFileInfo(path);
|
|
||||||
if (!fileInfo.exists()) {
|
|
||||||
ui->statusBar->showMessage(tr("Please select existing file"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile inputFile;
|
|
||||||
inputFile.setFileName(path);
|
|
||||||
|
|
||||||
if (!inputFile.open(QFile::ReadOnly)) {
|
|
||||||
QMessageBox::critical(this, tr("Replacing failed"), tr("Can't open input file for reading"), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray buffer = inputFile.readAll();
|
|
||||||
inputFile.close();
|
|
||||||
|
|
||||||
/*UINT8 result = ffsEngine->replace(index, buffer, mode);
|
|
||||||
if (result) {
|
|
||||||
QMessageBox::critical(this, tr("Replacing failed"), errorMessage(result), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ui->actionSaveImageFile->setEnabled(true);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::extractAsIs()
|
|
||||||
{
|
|
||||||
extract(EXTRACT_MODE_AS_IS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::extractBody()
|
|
||||||
{
|
|
||||||
extract(EXTRACT_MODE_BODY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::extract(const UINT8 mode)
|
|
||||||
{
|
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
TreeModel* model = ffsParser->treeModel();
|
|
||||||
|
|
||||||
QByteArray extracted;
|
|
||||||
QString name;
|
|
||||||
UINT8 result = ffsParser->extract(index, name, extracted, mode);
|
|
||||||
if (result) {
|
|
||||||
QMessageBox::critical(this, tr("Extraction failed"), errorCodeToQString(result), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
name = currentDir + QDir::separator() + name;
|
|
||||||
|
|
||||||
UINT8 type = model->type(index);
|
|
||||||
QString path;
|
|
||||||
if (mode == EXTRACT_MODE_AS_IS) {
|
|
||||||
switch (type) {
|
|
||||||
case Types::Capsule:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"), name + ".cap", "Capsule files (*.cap *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::Image:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save image to file"), name + ".rom", "Image files (*.rom *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::Region:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save region to file"), name + ".rgn", "Region files (*.rgn *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::Padding:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save padding to file"), name + ".pad", "Padding files (*.pad *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::Volume:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save volume to file"), name + ".vol", "Volume files (*.vol *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::File:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"), name + ".ffs", "FFS files (*.ffs *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::Section:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save section file to file"), name + ".sct", "Section files (*.sct *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == EXTRACT_MODE_BODY) {
|
|
||||||
switch (type) {
|
|
||||||
case Types::Capsule:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), name + ".rom", "Image files (*.rom *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::Volume:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), name + ".vbd", "Volume body files (*.vbd *.bin);;All files (*)");
|
|
||||||
break;
|
|
||||||
case Types::File: {
|
|
||||||
if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW)
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)");
|
|
||||||
else
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), name + ".fbd", "FFS file body files (*.fbd *.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Types::Section: {
|
|
||||||
if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE)
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"), name + ".fbd", "FFS file body files (*.fbd *.bin);;All files (*)");
|
|
||||||
else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE)
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), name + ".vol", "Volume files (*.vol *.bin);;All files (*)");
|
|
||||||
else if (model->subtype(index) == EFI_SECTION_RAW)
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)");
|
|
||||||
else
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), name + ".bin", "Binary files (*.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)");
|
|
||||||
|
|
||||||
if (path.trimmed().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QFile outputFile;
|
|
||||||
outputFile.setFileName(path);
|
|
||||||
if (!outputFile.open(QFile::WriteOnly)) {
|
|
||||||
QMessageBox::critical(this, tr("Extraction failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
outputFile.resize(0);
|
|
||||||
outputFile.write(extracted);
|
|
||||||
outputFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::about()
|
|
||||||
{
|
|
||||||
QMessageBox::about(this, tr("About UEFITool"), tr(
|
|
||||||
"Copyright (c) 2015, Nikolaj Schlej aka <b>CodeRush</b>.<br>"
|
|
||||||
"Program icon made by <a href=https://www.behance.net/alzhidkov>Alexander Zhidkov</a>.<br><br>"
|
|
||||||
"The program is dedicated to <b>RevoGirl</b>. Rest in peace, young genius.<br><br>"
|
|
||||||
"The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License.<br>"
|
|
||||||
"The full text of the license may be found at <a href=http://opensource.org/licenses/bsd-license.php>OpenSource.org</a>.<br><br>"
|
|
||||||
"<b>THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, "
|
|
||||||
"WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, "
|
|
||||||
"EITHER EXPRESS OR IMPLIED.</b>"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::aboutQt()
|
|
||||||
{
|
|
||||||
QMessageBox::aboutQt(this, tr("About Qt"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::exit()
|
|
||||||
{
|
|
||||||
QCoreApplication::exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::saveImageFile()
|
|
||||||
{
|
|
||||||
/*QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.efi *.dec);;All files (*)");
|
|
||||||
|
|
||||||
if (path.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QByteArray reconstructed;
|
|
||||||
UINT8 result = ffsEngine->reconstructImageFile(reconstructed);
|
|
||||||
showMessages();
|
|
||||||
if (result) {
|
|
||||||
QMessageBox::critical(this, tr("Image reconstruction failed"), errorMessage(result), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile outputFile;
|
|
||||||
outputFile.setFileName(path);
|
|
||||||
|
|
||||||
if (!outputFile.open(QFile::WriteOnly)) {
|
|
||||||
QMessageBox::critical(this, tr("Image reconstruction failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
outputFile.resize(0);
|
|
||||||
outputFile.write(reconstructed);
|
|
||||||
outputFile.close();
|
|
||||||
if (QMessageBox::information(this, tr("Image reconstruction successful"), tr("Open reconstructed file?"), QMessageBox::Yes, QMessageBox::No)
|
|
||||||
== QMessageBox::Yes)
|
|
||||||
openImageFile(path);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::openImageFile()
|
|
||||||
{
|
|
||||||
QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.efi *.dec);;All files (*)");
|
|
||||||
openImageFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::openImageFile(QString path)
|
|
||||||
{
|
|
||||||
if (path.trimmed().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QFileInfo fileInfo = QFileInfo(path);
|
|
||||||
|
|
||||||
if (!fileInfo.exists()) {
|
|
||||||
ui->statusBar->showMessage(tr("Please select existing file"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile inputFile;
|
|
||||||
inputFile.setFileName(path);
|
|
||||||
|
|
||||||
if (!inputFile.open(QFile::ReadOnly)) {
|
|
||||||
QMessageBox::critical(this, tr("Image parsing failed"), tr("Can't open input file for reading"), QMessageBox::Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray buffer = inputFile.readAll();
|
|
||||||
inputFile.close();
|
|
||||||
|
|
||||||
init();
|
|
||||||
this->setWindowTitle(tr("UEFITool %1 - %2").arg(version).arg(fileInfo.fileName()));
|
|
||||||
|
|
||||||
UINT8 result = ffsParser->parseImageFile(buffer);
|
|
||||||
showMessages();
|
|
||||||
if (result)
|
|
||||||
QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToQString(result), QMessageBox::Ok);
|
|
||||||
else
|
|
||||||
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
|
|
||||||
|
|
||||||
// Enable search
|
|
||||||
ui->actionSearch->setEnabled(true);
|
|
||||||
|
|
||||||
// Set current directory
|
|
||||||
currentDir = fileInfo.absolutePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::copyMessage()
|
|
||||||
{
|
|
||||||
clipboard->clear();
|
|
||||||
clipboard->setText(ui->messageListWidget->currentItem()->text());
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::copyAllMessages()
|
|
||||||
{
|
|
||||||
QString text;
|
|
||||||
clipboard->clear();
|
|
||||||
for(INT32 i = 0; i < ui->messageListWidget->count(); i++)
|
|
||||||
text.append(ui->messageListWidget->item(i)->text()).append("\n");
|
|
||||||
|
|
||||||
clipboard->clear();
|
|
||||||
clipboard->setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::enableMessagesCopyActions(QListWidgetItem* item)
|
|
||||||
{
|
|
||||||
ui->actionMessagesCopy->setEnabled(item != NULL);
|
|
||||||
ui->actionMessagesCopyAll->setEnabled(item != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::clearMessages()
|
|
||||||
{
|
|
||||||
ffsParser->clearMessages();
|
|
||||||
messageItems.clear();
|
|
||||||
ui->messageListWidget->clear();
|
|
||||||
ui->actionMessagesCopy->setEnabled(false);
|
|
||||||
ui->actionMessagesCopyAll->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::dragEnterEvent(QDragEnterEvent* event)
|
|
||||||
{
|
|
||||||
if (event->mimeData()->hasFormat("text/uri-list"))
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::dropEvent(QDropEvent* event)
|
|
||||||
{
|
|
||||||
QString path = event->mimeData()->urls().at(0).toLocalFile();
|
|
||||||
openImageFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::showMessages()
|
|
||||||
{
|
|
||||||
ui->messageListWidget->clear();
|
|
||||||
if (!ffsParser)
|
|
||||||
return;
|
|
||||||
|
|
||||||
messageItems = ffsParser->messages();
|
|
||||||
for (int i = 0; i < messageItems.count(); i++) {
|
|
||||||
ui->messageListWidget->addItem(new MessageListItem(messageItems.at(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->messageListWidget->scrollToBottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::scrollTreeView(QListWidgetItem* item)
|
|
||||||
{
|
|
||||||
MessageListItem* messageItem = static_cast<MessageListItem*>(item);
|
|
||||||
QModelIndex index = messageItem->index();
|
|
||||||
if (index.isValid()) {
|
|
||||||
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
|
||||||
ui->structureTreeView->selectionModel()->clearSelection();
|
|
||||||
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
|
||||||
{
|
|
||||||
if (ui->messageListWidget->underMouse()) {
|
|
||||||
ui->menuMessages->exec(event->globalPos());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ui->structureTreeView->underMouse())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QPoint pt = event->pos();
|
|
||||||
QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt));
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
TreeModel* model = ffsParser->treeModel();
|
|
||||||
switch (model->type(index))
|
|
||||||
{
|
|
||||||
case Types::Capsule:
|
|
||||||
ui->menuCapsuleActions->exec(event->globalPos());
|
|
||||||
break;
|
|
||||||
case Types::Image:
|
|
||||||
ui->menuImageActions->exec(event->globalPos());
|
|
||||||
break;
|
|
||||||
case Types::Region:
|
|
||||||
ui->menuRegionActions->exec(event->globalPos());
|
|
||||||
break;
|
|
||||||
case Types::Padding:
|
|
||||||
ui->menuPaddingActions->exec(event->globalPos());
|
|
||||||
break;
|
|
||||||
case Types::Volume:
|
|
||||||
ui->menuVolumeActions->exec(event->globalPos());
|
|
||||||
break;
|
|
||||||
case Types::File:
|
|
||||||
ui->menuFileActions->exec(event->globalPos());
|
|
||||||
break;
|
|
||||||
case Types::Section:
|
|
||||||
ui->menuSectionActions->exec(event->globalPos());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::readSettings()
|
|
||||||
{
|
|
||||||
QSettings settings(this);
|
|
||||||
resize(settings.value("mainWindow/size", QSize(800, 600)).toSize());
|
|
||||||
move(settings.value("mainWindow/position", QPoint(0, 0)).toPoint());
|
|
||||||
QList<int> horList, vertList;
|
|
||||||
horList.append(settings.value("mainWindow/treeWidth", 600).toInt());
|
|
||||||
horList.append(settings.value("mainWindow/infoWidth", 180).toInt());
|
|
||||||
vertList.append(settings.value("mainWindow/treeHeight", 400).toInt());
|
|
||||||
vertList.append(settings.value("mainWindow/messageHeight", 180).toInt());
|
|
||||||
ui->infoSplitter->setSizes(horList);
|
|
||||||
ui->messagesSplitter->setSizes(vertList);
|
|
||||||
ui->structureTreeView->setColumnWidth(0, settings.value("tree/columnWidth0", ui->structureTreeView->columnWidth(0)).toInt());
|
|
||||||
ui->structureTreeView->setColumnWidth(1, settings.value("tree/columnWidth1", ui->structureTreeView->columnWidth(1)).toInt());
|
|
||||||
ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt());
|
|
||||||
ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::writeSettings()
|
|
||||||
{
|
|
||||||
QSettings settings(this);
|
|
||||||
settings.setValue("mainWindow/size", size());
|
|
||||||
settings.setValue("mainWindow/position", pos());
|
|
||||||
settings.setValue("mainWindow/treeWidth", ui->structureGroupBox->width());
|
|
||||||
settings.setValue("mainWindow/infoWidth", ui->infoGroupBox->width());
|
|
||||||
settings.setValue("mainWindow/treeHeight", ui->structureGroupBox->height());
|
|
||||||
settings.setValue("mainWindow/messageHeight", ui->messageGroupBox->height());
|
|
||||||
settings.setValue("tree/columnWidth0", ui->structureTreeView->columnWidth(0));
|
|
||||||
settings.setValue("tree/columnWidth1", ui->structureTreeView->columnWidth(1));
|
|
||||||
settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2));
|
|
||||||
settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3));
|
|
||||||
}
|
|
110
uefitool.h
110
uefitool.h
@ -1,110 +0,0 @@
|
|||||||
/* uefitool.h
|
|
||||||
|
|
||||||
Copyright (c) 2014, 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 __UEFITOOL_H__
|
|
||||||
#define __UEFITOOL_H__
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QClipboard>
|
|
||||||
#include <QDragEnterEvent>
|
|
||||||
#include <QDropEvent>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QListWidget>
|
|
||||||
#include <QMenu>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QMimeData>
|
|
||||||
#include <QPlainTextEdit>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QSplitter>
|
|
||||||
#include <QString>
|
|
||||||
#include <QTreeView>
|
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
#include "basetypes.h"
|
|
||||||
#include "utility.h"
|
|
||||||
#include "ffs.h"
|
|
||||||
#include "ffsparser.h"
|
|
||||||
#include "searchdialog.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class UEFITool;
|
|
||||||
}
|
|
||||||
|
|
||||||
class UEFITool : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit UEFITool(QWidget *parent = 0);
|
|
||||||
~UEFITool();
|
|
||||||
|
|
||||||
void openImageFile(QString path);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void init();
|
|
||||||
void populateUi(const QModelIndex ¤t);
|
|
||||||
void scrollTreeView(QListWidgetItem* item);
|
|
||||||
|
|
||||||
void openImageFile();
|
|
||||||
void saveImageFile();
|
|
||||||
void search();
|
|
||||||
|
|
||||||
void extract(const UINT8 mode);
|
|
||||||
void extractAsIs();
|
|
||||||
void extractBody();
|
|
||||||
|
|
||||||
void insert(const UINT8 mode);
|
|
||||||
void insertInto();
|
|
||||||
void insertBefore();
|
|
||||||
void insertAfter();
|
|
||||||
|
|
||||||
void replace(const UINT8 mode);
|
|
||||||
void replaceAsIs();
|
|
||||||
void replaceBody();
|
|
||||||
|
|
||||||
void rebuild();
|
|
||||||
|
|
||||||
void remove();
|
|
||||||
|
|
||||||
void copyMessage();
|
|
||||||
void copyAllMessages();
|
|
||||||
void enableMessagesCopyActions(QListWidgetItem* item);
|
|
||||||
void clearMessages();
|
|
||||||
|
|
||||||
void about();
|
|
||||||
void aboutQt();
|
|
||||||
|
|
||||||
void exit();
|
|
||||||
void writeSettings();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::UEFITool* ui;
|
|
||||||
FfsParser* ffsParser;
|
|
||||||
SearchDialog* searchDialog;
|
|
||||||
QClipboard* clipboard;
|
|
||||||
QString currentDir;
|
|
||||||
QQueue<MessageListItem> messageItems;
|
|
||||||
const QString version;
|
|
||||||
|
|
||||||
void showMessages();
|
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent* event);
|
|
||||||
void dropEvent(QDropEvent* event);
|
|
||||||
void contextMenuEvent(QContextMenuEvent* event);
|
|
||||||
void readSettings();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
BIN
uefitool.icns
BIN
uefitool.icns
Binary file not shown.
BIN
uefitool.ico
BIN
uefitool.ico
Binary file not shown.
Before Width: | Height: | Size: 31 KiB |
55
uefitool.pro
55
uefitool.pro
@ -1,55 +0,0 @@
|
|||||||
QT += core gui
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
|
||||||
|
|
||||||
TARGET = UEFITool
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
SOURCES += uefitool_main.cpp \
|
|
||||||
uefitool.cpp \
|
|
||||||
searchdialog.cpp \
|
|
||||||
types.cpp \
|
|
||||||
descriptor.cpp \
|
|
||||||
ffs.cpp \
|
|
||||||
peimage.cpp \
|
|
||||||
utility.cpp \
|
|
||||||
ffsparser.cpp \
|
|
||||||
treeitem.cpp \
|
|
||||||
treemodel.cpp \
|
|
||||||
messagelistitem.cpp \
|
|
||||||
guidlineedit.cpp \
|
|
||||||
LZMA/LzmaCompress.c \
|
|
||||||
LZMA/LzmaDecompress.c \
|
|
||||||
LZMA/SDK/C/LzFind.c \
|
|
||||||
LZMA/SDK/C/LzmaDec.c \
|
|
||||||
LZMA/SDK/C/LzmaEnc.c \
|
|
||||||
Tiano/EfiTianoDecompress.c \
|
|
||||||
Tiano/EfiTianoCompress.c \
|
|
||||||
Tiano/EfiTianoCompressLegacy.c
|
|
||||||
|
|
||||||
HEADERS += uefitool.h \
|
|
||||||
searchdialog.h \
|
|
||||||
basetypes.h \
|
|
||||||
descriptor.h \
|
|
||||||
gbe.h \
|
|
||||||
me.h \
|
|
||||||
ffs.h \
|
|
||||||
peimage.h \
|
|
||||||
types.h \
|
|
||||||
utility.h \
|
|
||||||
ffsparser.h \
|
|
||||||
treeitem.h \
|
|
||||||
treemodel.h \
|
|
||||||
messagelistitem.h \
|
|
||||||
guidlineedit.h \
|
|
||||||
LZMA/LzmaCompress.h \
|
|
||||||
LZMA/LzmaDecompress.h \
|
|
||||||
Tiano/EfiTianoDecompress.h \
|
|
||||||
Tiano/EfiTianoCompress.h
|
|
||||||
|
|
||||||
FORMS += uefitool.ui \
|
|
||||||
searchdialog.ui
|
|
||||||
|
|
||||||
RC_FILE = uefitool.rc
|
|
||||||
|
|
||||||
ICON = uefitool.icns
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
IDI_ICON1 ICON DISCARDABLE "uefitool.ico"
|
|
529
uefitool.ui
529
uefitool.ui
@ -1,529 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>UEFITool</class>
|
|
||||||
<widget class="QMainWindow" name="UEFITool">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>800</width>
|
|
||||||
<height>600</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="acceptDrops">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>UEFITool</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="centralWidget">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QSplitter" name="messagesSplitter">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="QSplitter" name="infoSplitter">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="QGroupBox" name="structureGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Structure</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QTreeView" name="structureTreeView">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="indentation">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="headerHidden">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="headerCascadingSectionResizes">
|
|
||||||
<bool>true</bool>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="headerDefaultSectionSize">
|
|
||||||
<number>200</number>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="headerStretchLastSection">
|
|
||||||
<bool>true</bool>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QGroupBox" name="infoGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Information</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QPlainTextEdit" name="infoEdit">
|
|
||||||
<property name="acceptDrops">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="undoRedoEnabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="centerOnScroll">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<widget class="QGroupBox" name="messageGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Messages</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="messageListWidget">
|
|
||||||
<property name="mouseTracking">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QStatusBar" name="statusBar"/>
|
|
||||||
<widget class="QMenuBar" name="menuBar">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>800</width>
|
|
||||||
<height>21</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<widget class="QMenu" name="menuFile">
|
|
||||||
<property name="title">
|
|
||||||
<string>&File</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionOpenImageFile"/>
|
|
||||||
<addaction name="actionSaveImageFile"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionSearch"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionQuit"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuHelp">
|
|
||||||
<property name="title">
|
|
||||||
<string>H&elp</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionAbout"/>
|
|
||||||
<addaction name="actionAboutQt"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuAction">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Action</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QMenu" name="menuCapsuleActions">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Capsule</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionExtract"/>
|
|
||||||
<addaction name="actionExtractBody"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuImageActions">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Image</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionExtract"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuRegionActions">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Region</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionExtract"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionReplace"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuPaddingActions">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Padding</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionExtract"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuVolumeActions">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Volume</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionExtract"/>
|
|
||||||
<addaction name="actionExtractBody"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionRebuild"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionInsertInto"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionReplace"/>
|
|
||||||
<addaction name="actionReplaceBody"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuFileActions">
|
|
||||||
<property name="title">
|
|
||||||
<string>&File</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionExtract"/>
|
|
||||||
<addaction name="actionExtractBody"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionRebuild"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionInsertInto"/>
|
|
||||||
<addaction name="actionInsertBefore"/>
|
|
||||||
<addaction name="actionInsertAfter"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionReplace"/>
|
|
||||||
<addaction name="actionReplaceBody"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionRemove"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuSectionActions">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Section</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionExtract"/>
|
|
||||||
<addaction name="actionExtractBody"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionRebuild"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionInsertInto"/>
|
|
||||||
<addaction name="actionInsertBefore"/>
|
|
||||||
<addaction name="actionInsertAfter"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionReplace"/>
|
|
||||||
<addaction name="actionReplaceBody"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionRemove"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuMessages">
|
|
||||||
<property name="title">
|
|
||||||
<string>&Messages</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionMessagesCopy"/>
|
|
||||||
<addaction name="actionMessagesCopyAll"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionMessagesClear"/>
|
|
||||||
</widget>
|
|
||||||
<addaction name="menuCapsuleActions"/>
|
|
||||||
<addaction name="menuImageActions"/>
|
|
||||||
<addaction name="menuRegionActions"/>
|
|
||||||
<addaction name="menuPaddingActions"/>
|
|
||||||
<addaction name="menuVolumeActions"/>
|
|
||||||
<addaction name="menuFileActions"/>
|
|
||||||
<addaction name="menuSectionActions"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="menuMessages"/>
|
|
||||||
</widget>
|
|
||||||
<addaction name="menuFile"/>
|
|
||||||
<addaction name="menuAction"/>
|
|
||||||
<addaction name="menuHelp"/>
|
|
||||||
</widget>
|
|
||||||
<action name="actionInsertAfter">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Insert &after...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Insert an object from file after selected object</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Shift+I</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionInsertBefore">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Insert b&efore...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Insert object from file before selected object</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Alt+I</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionReplace">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Rep&lace as is...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Replace selected object as is with an object from file</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+R</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionExtract">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>E&xtract as is...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Extract selected object as is to file</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+E</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionExtractBody">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Extract &body...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Extract body of selected object to file</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Shift+E</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionRemove">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Re&move</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Remove selected object</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Del</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionOpenImageFile">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Open image file...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Open image file</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+O</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionInsertInto">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Insert &into...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Insert object from file into selected object</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+I</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionSaveImageFile">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Save image file...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Save modified image file</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+S</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionRebuild">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>&Rebuild</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Rebuild selected object</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Space</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionAbout">
|
|
||||||
<property name="text">
|
|
||||||
<string>&About UEFITool</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>F1</string>
|
|
||||||
</property>
|
|
||||||
<property name="menuRole">
|
|
||||||
<enum>QAction::AboutRole</enum>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionAboutQt">
|
|
||||||
<property name="text">
|
|
||||||
<string>About &Qt</string>
|
|
||||||
</property>
|
|
||||||
<property name="menuRole">
|
|
||||||
<enum>QAction::AboutQtRole</enum>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionQuit">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Quit</string>
|
|
||||||
</property>
|
|
||||||
<property name="menuRole">
|
|
||||||
<enum>QAction::QuitRole</enum>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionSearch">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Sear&ch...</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+F</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionMessagesClear">
|
|
||||||
<property name="text">
|
|
||||||
<string>Cl&ear</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Clear messages</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Backspace</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionReplaceBody">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Replace b&ody...</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Replace body of selected object with a data from file</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Shift+R</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionMessagesCopy">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Copy</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Shift+C</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionMessagesCopyAll">
|
|
||||||
<property name="text">
|
|
||||||
<string>C&opy all</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+Alt+C</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
</widget>
|
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
@ -1,31 +0,0 @@
|
|||||||
/* uefitool_main.cpp
|
|
||||||
|
|
||||||
Copyright (c) 2014, 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 <QApplication>
|
|
||||||
#include <QString>
|
|
||||||
#include "uefitool.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QApplication a(argc, argv);
|
|
||||||
a.setOrganizationName("CodeRush");
|
|
||||||
a.setOrganizationDomain("coderush.me");
|
|
||||||
a.setApplicationName("UEFITool");
|
|
||||||
|
|
||||||
UEFITool w;
|
|
||||||
if (a.arguments().length() > 1)
|
|
||||||
w.openImageFile(a.arguments().at(1));
|
|
||||||
w.show();
|
|
||||||
|
|
||||||
return a.exec();
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user