Page MenuHomePhabricator

No OneTemporary

Size
275 KB
Referenced Files
None
Subscribers
None
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/trunk/argparser.cpp b/trunk/argparser.cpp
index 2824047..fc162e7 100644
--- a/trunk/argparser.cpp
+++ b/trunk/argparser.cpp
@@ -1,133 +1,133 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "argparser.h"
ArgParser::ArgParser(QStringList args) {
this->argv=QStringList(args);
this->argc=this->argv.count();
this->error_msg="";
this->parsed_args.clear();
}
QString ArgParser::GetErrorMsg() {
QString msg=this->error_msg;
this->error_msg="";
return msg;
}
bool ArgParser::ParseArgs() {
int i=0;
int sep_pos=0;
QString cur_arg="";
QString cur_arg_param="";
while(i+1<this->argc) {
// Get current argument
cur_arg=this->argv.at(++i);
if(cur_arg.size()>1) {
// Check for short mode command line args
if(cur_arg[0]=='-' && cur_arg[1]!='-') {
if(cur_arg=="-?" || cur_arg=="-h") {
this->parsed_args.insert(cur_arg.mid(1),QString());
continue;
} else if(cur_arg=="-v") {
this->parsed_args.insert(cur_arg.mid(1),QString());
continue;
} else {
// Unknown argument
this->SetError(QString("Unknown command line argument '%1'!")
.arg(cur_arg));
return false;
}
}
// Check for long mode command line args
if(cur_arg[0]=='-' && cur_arg[1]=='-') {
// Extract argument parameter if there is one
sep_pos=cur_arg.indexOf('=');
if(sep_pos!=-1) {
cur_arg_param=cur_arg.mid(sep_pos+1);
// Remove parameter from arg
cur_arg=cur_arg.left(sep_pos);
} else {
cur_arg_param="";
}
if(cur_arg=="--") {
// Stop processing arguments. Anything that follows this argument is
// considered to be a hive to open
i++;
break;
} else if(cur_arg=="--dump-report") {
this->parsed_args.insert(cur_arg.mid(2),cur_arg_param);
continue;
} else if(cur_arg=="--fullscreen") {
this->parsed_args.insert(cur_arg.mid(2),cur_arg_param);
continue;
} else if(cur_arg=="--help") {
this->parsed_args.insert(cur_arg.mid(2),QString());
continue;
} else if(cur_arg=="--maximized") {
this->parsed_args.insert(cur_arg.mid(2),cur_arg_param);
continue;
} else if(cur_arg=="--version") {
this->parsed_args.insert(cur_arg.mid(2),QString());
continue;
} else {
// Unknown argument
this->SetError(QString("Unknown command line argument '%1'!")
.arg(cur_arg));
return false;
}
}
}
// Found argument not beginning with '-' or '--'
if(i+1==this->argc) {
// If this is the last argument, it should be a hive file
this->parsed_args.insert(QString("hive-file"),cur_arg);
break;
} else {
// If it isn't the last argument, there is an error
this->SetError(QString("Unknown command line argument '%1'!")
.arg(cur_arg));
return false;
}
}
return true;
}
bool ArgParser::IsSet(QString arg) {
return this->parsed_args.contains(arg);
}
QString ArgParser::GetArgVal(QString arg) {
// If arg is not in parsed_args, the following will return a
// "default-constructed value" which should be a QString() according to the
// docs.
return this->parsed_args[arg];
}
void ArgParser::SetError(QString msg) {
this->error_msg=msg;
}
diff --git a/trunk/argparser.h b/trunk/argparser.h
index 04a2eb5..0ca9259 100644
--- a/trunk/argparser.h
+++ b/trunk/argparser.h
@@ -1,45 +1,45 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef ARGPARSER_H
#define ARGPARSER_H
#include <QString>
#include <QStringList>
#include <QHash>
class ArgParser {
public:
ArgParser(QStringList args);
QString GetErrorMsg();
bool ParseArgs();
bool IsSet(QString arg);
QString GetArgVal(QString arg);
private:
QStringList argv;
int argc;
QString error_msg;
QHash<QString,QString> parsed_args;
void SetError(QString msg=QString());
};
#endif // ARGPARSER_H
diff --git a/trunk/datainterpretertable.cpp b/trunk/datainterpretertable.cpp
index 3af93b9..f4efd41 100644
--- a/trunk/datainterpretertable.cpp
+++ b/trunk/datainterpretertable.cpp
@@ -1,111 +1,111 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "datainterpretertable.h"
#include <QHeaderView>
#include <QFontMetrics>
#include <QMenu>
#include <QApplication>
#include <QClipboard>
DataInterpreterTable::DataInterpreterTable(QWidget *p_parent)
: QTableWidget(p_parent)
{
this->setColumnCount(2);
this->setTextElideMode(Qt::ElideNone);
this->horizontalHeader()->setHidden(true);
this->verticalHeader()->setHidden(true);
this->setSelectionBehavior(QAbstractItemView::SelectRows);
this->setSelectionMode(QAbstractItemView::SingleSelection);
// Create context menu actions
this->p_action_copy_value=new QAction(tr("Copy value"),this);
this->connect(this->p_action_copy_value,
SIGNAL(triggered()),
this,
SLOT(SlotCopyValue()));
}
DataInterpreterTable::~DataInterpreterTable() {
// Free table widget items
this->ClearValues();
// Delete context menu actions
delete this->p_action_copy_value;
}
void DataInterpreterTable::AddValue(QString name, QString value) {
QTableWidgetItem *p_name_item=new QTableWidgetItem(name);
p_name_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QTableWidgetItem *p_value_item=new QTableWidgetItem(value);
p_value_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
this->setRowCount(this->rowCount()+1);
this->setItem(this->rowCount()-1,0,p_name_item);
this->setItem(this->rowCount()-1,1,p_value_item);
this->resizeColumnsToContents();
this->resizeRowsToContents();
}
void DataInterpreterTable::ClearValues() {
// Free all items
while(this->rowCount()>0) {
delete this->item(0,0);
delete this->item(0,1);
this->setRowCount(this->rowCount()-1);
}
}
int DataInterpreterTable::sizeHintForColumn(int column) const {
int size_hint=0;
int i=0;
int item_width=0;
QFontMetrics fm(this->fontMetrics());
// Find string that needs the most amount of space
for(i=0;i<this->rowCount();i++) {
item_width=fm.width(this->item(i,column)->text())+10;
if(item_width>size_hint) size_hint=item_width;
}
return size_hint;
}
void DataInterpreterTable::contextMenuEvent(QContextMenuEvent *p_event) {
// Only show context menu when a node is selected
if(this->selectedIndexes().count()!=2) return;
// Only show context menu when user clicked on selected row
if(!(this->indexAt(p_event->pos())==this->selectedIndexes().at(0) ||
this->indexAt(p_event->pos())==this->selectedIndexes().at(1)))
{
return;
}
// Create context menu and add actions
QMenu context_menu(this);
context_menu.addAction(this->p_action_copy_value);
context_menu.exec(p_event->globalPos());
}
void DataInterpreterTable::SlotCopyValue() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(1).data().toString(),
QClipboard::Clipboard);
}
diff --git a/trunk/datainterpretertable.h b/trunk/datainterpretertable.h
index 891fccd..6fe37a0 100644
--- a/trunk/datainterpretertable.h
+++ b/trunk/datainterpretertable.h
@@ -1,68 +1,68 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DATAINTERPRETERTABLE_H
#define DATAINTERPRETERTABLE_H
#include <QWidget>
#include <QTableWidget>
#include <QContextMenuEvent>
#include <QAction>
class DataInterpreterTable : public QTableWidget {
Q_OBJECT
public:
DataInterpreterTable(QWidget *p_parent=0);
~DataInterpreterTable();
/*
* AddValue
*
* Add a value pair (name,value) to data interprter.
*/
void AddValue(QString name, QString value);
/*
* ClearValues
*
* Remove all value pairs from table
*/
void ClearValues();
protected:
/*
* sizeHintForColumn
*
* Needed reimplementation in order to allow resizeColumnsToContent
* to resize hidden columns too.
*/
int sizeHintForColumn(int column) const;
void contextMenuEvent(QContextMenuEvent *p_event);
private:
QAction *p_action_copy_value;
private slots:
void SlotCopyValue();
};
#endif // DATAINTERPRETERTABLE_H
diff --git a/trunk/datainterpreterwidget.cpp b/trunk/datainterpreterwidget.cpp
index 3f80882..dc6dfa0 100644
--- a/trunk/datainterpreterwidget.cpp
+++ b/trunk/datainterpreterwidget.cpp
@@ -1,201 +1,201 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "datainterpreterwidget.h"
#include "registryhive.h"
DataInterpreterWidget::DataInterpreterWidget(QWidget *p_parent) :
QWidget(p_parent)
{
// Init private vars
this->data=QByteArray();
this->endianness=DataInterpreterWidget::Endianness_LittleEndian;
// Set widget layout. Setting it's parent to "this" will also call
// this->SetLayout.
this->p_widget_layout=new QVBoxLayout(this);
// Create sub-widgets
this->p_data_interpreter_table=new DataInterpreterTable();
this->p_endianness_selector_layout=new QHBoxLayout();
this->p_endianness_selector_le=new QRadioButton(tr("Little endian"));
this->p_endianness_selector_be=new QRadioButton(tr("Big endian"));
// Add endianness selector buttons to their layout
this->p_endianness_selector_layout->addWidget(this->p_endianness_selector_le);
this->p_endianness_selector_layout->addWidget(this->p_endianness_selector_be);
// Add sub-widgets to our layout
this->p_widget_layout->addWidget(this->p_data_interpreter_table);
this->p_widget_layout->addLayout(this->p_endianness_selector_layout);
// Configure widget and sub-widgets
this->setContentsMargins(0,0,0,0);
this->p_widget_layout->setContentsMargins(0,0,0,0);
this->p_endianness_selector_layout->setContentsMargins(0,0,0,0);
this->p_endianness_selector_le->setContentsMargins(0,0,0,0);
this->p_endianness_selector_be->setContentsMargins(0,0,0,0);
// Set initial endianness selector state
this->p_endianness_selector_le->setChecked(
(this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_endianness_selector_be->setChecked(
(this->endianness==DataInterpreterWidget::Endianness_BigEndian));
// Connect signals
this->connect(this->p_endianness_selector_le,
SIGNAL(clicked(bool)),
this,
SLOT(SlotEndiannessSelectorLeClicked(bool)));
this->connect(this->p_endianness_selector_be,
SIGNAL(clicked(bool)),
this,
SLOT(SlotEndiannessSelectorBeClicked(bool)));
}
DataInterpreterWidget::~DataInterpreterWidget() {
delete this->p_endianness_selector_le;
delete this->p_endianness_selector_be;
delete this->p_endianness_selector_layout;
delete this->p_data_interpreter_table;
delete this->p_widget_layout;
}
void DataInterpreterWidget::SetData(QByteArray new_data) {
// Save new data and interpret it
this->data=new_data;
this->InterpretData();
}
void DataInterpreterWidget::InterpretData() {
// Get data length
int data_length=this->data.size();
// Remove old values from data interpreter table
this->p_data_interpreter_table->ClearValues();
if(data_length>=1) {
this->p_data_interpreter_table->AddValue("int8:",
RegistryHive::KeyValueToString(
this->data,
"int8"));
this->p_data_interpreter_table->AddValue("uint8:",
RegistryHive::KeyValueToString(
this->data,
"uint8"));
}
if(data_length>=2) {
this->p_data_interpreter_table->AddValue(
"int16:",
RegistryHive::KeyValueToString(
this->data,
"int16",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_data_interpreter_table->AddValue(
"uint16:",
RegistryHive::KeyValueToString(
this->data,
"uint16",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
}
if(data_length>=4) {
this->p_data_interpreter_table->AddValue(
"int32:",
RegistryHive::KeyValueToString(
this->data,
"int32",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_data_interpreter_table->AddValue(
"uint32:",
RegistryHive::KeyValueToString(
this->data,
"uint32",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_data_interpreter_table->AddValue(
"unixtime:",
RegistryHive::KeyValueToString(
this->data,
"unixtime",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
}
if(data_length>=8) {
this->p_data_interpreter_table->AddValue(
"int64:",
RegistryHive::KeyValueToString(
this->data,
"int64",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_data_interpreter_table->AddValue(
"uint64:",
RegistryHive::KeyValueToString(
this->data,
"uint64",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
/*
TODO: Check how one could implement this
this->p_data_interpreter_table->AddValue(
"unixtime64:",
RegistryHive::KeyValueToString(
this->data,
"unixtime64",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
*/
this->p_data_interpreter_table->AddValue(
"filetime64:",
RegistryHive::KeyValueToString(
this->data,
"filetime",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
}
}
void DataInterpreterWidget::SlotEndiannessSelectorLeClicked(bool checked) {
if(checked) {
// Save selected endianness and update interpreted values
this->endianness=DataInterpreterWidget::Endianness_LittleEndian;
this->InterpretData();
}
}
void DataInterpreterWidget::SlotEndiannessSelectorBeClicked(bool checked) {
if(checked) {
// Save selected endianness and update interpreted values
this->endianness=DataInterpreterWidget::Endianness_BigEndian;
this->InterpretData();
}
}
diff --git a/trunk/datainterpreterwidget.h b/trunk/datainterpreterwidget.h
index 08e4e52..2c61367 100644
--- a/trunk/datainterpreterwidget.h
+++ b/trunk/datainterpreterwidget.h
@@ -1,72 +1,72 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DATAINTERPRETERWIDGET_H
#define DATAINTERPRETERWIDGET_H
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QRadioButton>
#include <QString>
#include <QByteArray>
#include "datainterpretertable.h"
class DataInterpreterWidget : public QWidget {
Q_OBJECT
public:
enum Endianness {
Endianness_LittleEndian=0,
Endianness_BigEndian
};
explicit DataInterpreterWidget(QWidget *p_parent=0);
~DataInterpreterWidget();
/*
* SetData
*
* Set data to be interpreted (will also interpret it).
*/
void SetData(QByteArray new_data);
private:
// Widget layout
QVBoxLayout *p_widget_layout;
// Sub-widgets
DataInterpreterTable *p_data_interpreter_table;
QHBoxLayout *p_endianness_selector_layout;
QRadioButton *p_endianness_selector_le;
QRadioButton *p_endianness_selector_be;
// Vars
QByteArray data;
int endianness;
void InterpretData();
private slots:
void SlotEndiannessSelectorLeClicked(bool checked);
void SlotEndiannessSelectorBeClicked(bool checked);
};
#endif // DATAINTERPRETERWIDGET_H
diff --git a/trunk/datareporter.cpp b/trunk/datareporter.cpp
index 73013bc..b547870 100644
--- a/trunk/datareporter.cpp
+++ b/trunk/datareporter.cpp
@@ -1,200 +1,200 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "datareporter.h"
#include <QDir>
#include <QTextStream>
#include <QtScript/QScriptEngine>
#include <QMessageBox>
DataReporter::DataReporter() {
this->report_templates.clear();
//this->p_report_engine=new DataReporterEngine();
}
DataReporter::~DataReporter() {
//delete this->p_report_engine;
qDeleteAll(this->report_templates);
}
void DataReporter::LoadReportTemplates(QString dir) {
QString report_template="";
int i=0;
int ii=0;
bool found=false;
QString report_category="";
QString report_name="";
ReportTemplate *p_report;
// Get all template files in report_templates directory
QDir report_dir(dir);
QStringList found_report_templates=report_dir.
entryList(QStringList()<<"*.qs");
for(i=0;i<found_report_templates.count();i++) {
// Build complete path to template file
report_template=report_dir.path();
report_template.append(QDir::separator());
report_template.append(found_report_templates.value(i));
// Extract report category and name from file name (<category>_<name>.qs)
report_category=found_report_templates.value(i).left(
found_report_templates.value(i).indexOf("_"));
report_name=found_report_templates.value(i).mid(
found_report_templates.value(i).indexOf("_")+1);
report_name=report_name.left(report_name.lastIndexOf("."));
// Check if a report with the same category/name was already added
found=false;
for(ii=0;ii<this->report_templates.count();ii++) {
if(this->report_templates.at(ii)->Category()==report_category &&
this->report_templates.at(ii)->Name()==report_name)
{
found=true;
break;
}
}
if(!found) {
// Add report to list
p_report=new ReportTemplate(report_category,
report_name,
report_template);
this->report_templates.append(p_report);
} else {
// Update report entry
p_report=this->report_templates.at(ii);
p_report->SetFile(report_template);
}
}
}
QStringList DataReporter::GetAvailableReportCategories() {
QStringList ret;
QString cat;
int i=0;
ret.clear();
for(i=0;i<this->report_templates.count();i++) {
cat=this->report_templates.value(i)->Category();
if(!ret.contains(cat)) ret.append(cat);
}
ret.sort();
return ret;
}
QStringList DataReporter::GetAvailableReports(QString category) {
QStringList ret;
QString cat;
int i=0;
ret.clear();
for(i=0;i<this->report_templates.count();i++) {
cat=this->report_templates.value(i)->Category();
if(cat==category) ret.append(this->report_templates.value(i)->Name());
}
ret.sort();
return ret;
}
QString DataReporter::GenerateReport(RegistryHive *p_hive,
QString report_category,
QString report_name)
{
int i=0;
ReportTemplate *p_report;
// Search report template
for(i=0;i<this->report_templates.count();i++) {
p_report=this->report_templates.value(i);
if(p_report->Category()!=report_category || p_report->Name()!=report_name) {
continue;
}
// Report template was found, now generate report and return result
return this->GenerateReport(p_hive,p_report->File());
}
// Report template couldn't be found
QMessageBox::critical(0,
"Report engine error",
QString("Unable to find report with name '%1' in category '%2'!")
.arg(report_name)
.arg(report_category));
return QString();
}
QString DataReporter::GenerateReport(RegistryHive *p_hive,
QString report_template,
bool console_mode)
{
QString report_code;
// Init data reporter engine
DataReporterEngine engine(p_hive);
QScriptValue hive_value=engine.newQObject(p_hive);
engine.globalObject().setProperty("RegistryHive",hive_value);
// Open report template
QFile template_file(report_template);
if(!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
if(!console_mode) {
QMessageBox::critical(0,
"Report engine error",
QString("Couldn't open report template file '%1'!")
.arg(report_template));
} else {
printf("ERROR: Couldn't open report template file '%s'!\n",
report_template.toAscii().constData());
}
return QString();
}
// Read template file
QTextStream in(&template_file);
while(!in.atEnd()) report_code.append(in.readLine()).append("\n");
// Close report template file
template_file.close();
// Execute report template script
QScriptValue report_result=engine.evaluate(report_code,report_template);
if (report_result.isError() || engine.hasUncaughtException()) {
if(!console_mode) {
QMessageBox::critical(0,
"Report engine error",
QString::fromLatin1("File: %0\n Line: %1\nError: %2")
.arg(report_template)
.arg(report_result.property("lineNumber")
.toInt32())
.arg(report_result.toString()));
} else {
printf("ERROR: %s:%u: %s\n",
report_template.toAscii().constData(),
report_result.property("lineNumber").toInt32(),
report_result.toString().toAscii().constData());
}
return QString();
}
return engine.report_content;
}
diff --git a/trunk/datareporter.h b/trunk/datareporter.h
index ae04051..efdc2e0 100644
--- a/trunk/datareporter.h
+++ b/trunk/datareporter.h
@@ -1,51 +1,51 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DATAREPORTER_H
#define DATAREPORTER_H
#include <QList>
#include "reporttemplate.h"
#include "datareporterengine.h"
#include "registryhive.h"
class DataReporter {
public:
DataReporter();
~DataReporter();
void LoadReportTemplates(QString dir);
QStringList GetAvailableReportCategories();
QStringList GetAvailableReports(QString category);
QString GenerateReport(RegistryHive *p_hive,
QString report_category,
QString report_name);
QString GenerateReport(RegistryHive *p_hive,
QString report_template,
bool console_mode=false);
private:
QList<ReportTemplate*> report_templates;
//DataReporterEngine *p_report_engine;
};
#endif // DATAREPORTER_H
diff --git a/trunk/datareporterengine.cpp b/trunk/datareporterengine.cpp
index 6046fdb..7d5a76b 100644
--- a/trunk/datareporterengine.cpp
+++ b/trunk/datareporterengine.cpp
@@ -1,369 +1,369 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "datareporterengine.h"
#include <QString>
#include <QMap>
#include <QMapIterator>
#include <QStringList>
#include <QDateTime>
#include <stdio.h>
DataReporterEngine::DataReporterEngine(RegistryHive *p_hive) : QScriptEngine() {
// Init vars
this->p_registry_hive=p_hive;
this->report_content="";
// Add our types to engine
qScriptRegisterMetaType<s_RegistryKeyValue>(this,
this->RegistryKeyValueToScript,
this->RegistryKeyValueFromScript);
this->p_type_byte_array=new ByteArray(this);
this->globalObject().setProperty("ByteArray",
this->p_type_byte_array->constructor());
// Add our functions
// print
QScriptValue func_print=this->newFunction(this->Print);
this->globalObject().setProperty("print",func_print);
// println
QScriptValue func_println=this->newFunction(this->PrintLn);
this->globalObject().setProperty("println",func_println);
// GetRegistryNodes
QScriptValue func_get_nodes=this->newFunction(this->GetRegistryNodes,1);
func_get_nodes.setData(this->newQObject(this->p_registry_hive));
this->globalObject().setProperty("GetRegistryNodes",func_get_nodes);
// GetRegistryKeys
QScriptValue func_get_keys=this->newFunction(this->GetRegistryKeys,1);
func_get_keys.setData(this->newQObject(this->p_registry_hive));
this->globalObject().setProperty("GetRegistryKeys",func_get_keys);
// GetRegistryKeyValue
QScriptValue func_get_key_value=this->newFunction(this->GetRegistryKeyValue,
2);
func_get_key_value.setData(this->newQObject(this->p_registry_hive));
this->globalObject().setProperty("GetRegistryKeyValue",func_get_key_value);
// GetRegistryKeyModTime
QScriptValue func_get_key_modt=this->newFunction(this->GetRegistryKeyModTime,
2);
func_get_key_modt.setData(this->newQObject(this->p_registry_hive));
this->globalObject().setProperty("GetRegistryKeyModTime",func_get_key_modt);
// RegistryKeyValueToString
QScriptValue func_value_to_string=
this->newFunction(this->RegistryKeyValueToString,2);
this->globalObject().setProperty("RegistryKeyValueToString",
func_value_to_string);
// RegistryKeyValueToVariant
QScriptValue func_value_to_variant=
this->newFunction(this->RegistryKeyValueToVariant);
this->globalObject().setProperty("RegistryKeyValueToVariant",
func_value_to_variant);
// RegistryKeyTypeToString
QScriptValue func_type_to_string=
this->newFunction(this->RegistryKeyTypeToString,1);
this->globalObject().setProperty("RegistryKeyTypeToString",
func_type_to_string);
}
DataReporterEngine::~DataReporterEngine() {
delete this->p_type_byte_array;
}
QScriptValue DataReporterEngine::Print(QScriptContext *context,
QScriptEngine *engine)
{
int i;
QString content;
// Append all arguments to content
for(i=0;i<context->argumentCount();++i) {
//if(i>0) content.append(" ");
content.append(context->argument(i).toString());
}
//QScriptValue calleeData=context->callee().data();
//DataReporterEngine *engine=
// qobject_cast<DataReporterEngine*>(calleeData.toQObject());
qobject_cast<DataReporterEngine*>(engine)->report_content.append(content);
return engine->undefinedValue();
}
QScriptValue DataReporterEngine::PrintLn(QScriptContext *context,
QScriptEngine *engine)
{
int i;
QString content;
// Append all arguments to content
for(i=0;i<context->argumentCount();++i) {
//if(i>0) content.append(" ");
content.append(context->argument(i).toString());
}
qobject_cast<DataReporterEngine*>(engine)->
report_content.append(content).append("\n");
return engine->undefinedValue();
}
/*
* GetRegistryNodes
*/
QScriptValue DataReporterEngine::GetRegistryNodes(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QMap<QString,int> nodes;
QScriptValue ret_nodes;
int ii=0;
// This function needs one argument, parent node path
if(context->argumentCount()!=1) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
// Get nodes
nodes=p_hive->GetNodes(context->argument(0).toString());
if(p_hive->Error()) {
// Clear error state
p_hive->GetErrorMsg();
return engine->undefinedValue();
}
// Build script array
ret_nodes=engine->newArray(nodes.count());
QMapIterator<QString,int> i(nodes);
while(i.hasNext()) {
i.next();
ret_nodes.setProperty(ii++,QScriptValue(i.key()));
}
return ret_nodes;
}
/*
* GetRegistryKeys
*/
QScriptValue DataReporterEngine::GetRegistryKeys(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QMap<QString,int> keys;
QScriptValue ret_keys;
int ii=0;
// This function needs one argument, parent node path
if(context->argumentCount()!=1) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
// Get keys
keys=p_hive->GetKeys(context->argument(0).toString());
if(p_hive->Error()) {
// Clear error state
p_hive->GetErrorMsg();
return engine->undefinedValue();
}
//qDebug(QString("P: %1 A: %2").arg(context->argument(0).toString()).arg(keys.count()).toAscii().constData());
// Build script array
ret_keys=engine->newArray(keys.count());
QMapIterator<QString,int> i(keys);
while(i.hasNext()) {
i.next();
ret_keys.setProperty(ii++,QScriptValue(i.key()));
}
return ret_keys;
}
/*
* RegistryKeyValueToScript
*/
QScriptValue DataReporterEngine::RegistryKeyValueToScript(QScriptEngine *engine,
const
s_RegistryKeyValue
&s)
{
QScriptValue obj=engine->newObject();
obj.setProperty("type",s.type);
obj.setProperty("length",s.length);
ByteArray *p_byte_array=new ByteArray(engine);
obj.setProperty("value",p_byte_array->newInstance(s.value));
return obj;
}
/*
* RegistryKeyValueFromScriptValue
*/
void DataReporterEngine::RegistryKeyValueFromScript(const QScriptValue &obj,
s_RegistryKeyValue &s)
{
s.type=obj.property("type").toInt32();
s.length=obj.property("length").toInt32();
// TODO: Don't know if this works, but it probably does ;)
s.value=qvariant_cast<QByteArray>(obj.property("value").data().toVariant());
}
QScriptValue DataReporterEngine::GetRegistryKeyValue(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QByteArray key_value;
int key_type=0;
size_t key_length=0;
s_RegistryKeyValue script_key_value;
// This function needs two arguments, key path and key name
if(context->argumentCount()!=2) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
// Get key value
key_value=p_hive->GetKeyValue(context->argument(0).toString(),
context->argument(1).toString(),
&key_type,
&key_length);
if(p_hive->Error()) {
// Get error message to clear error state
p_hive->GetErrorMsg();
// printf("\nError: %s\n",p_hive->GetErrorMsg().toAscii().constData());
return engine->undefinedValue();
}
// Save key value to s_RegistryKeyValue struct
script_key_value.type=key_type;
script_key_value.length=key_length;
script_key_value.value=key_value;
return DataReporterEngine::RegistryKeyValueToScript(engine,script_key_value);
}
QScriptValue DataReporterEngine::RegistryKeyValueToString(
QScriptContext *context,
QScriptEngine *engine)
{
QByteArray key_value;
QString ret="";
// This function needs two arguments, key value and value type
if(context->argumentCount()!=2) return engine->undefinedValue();
// Cast ByteArray argument to QByteArray and convert
key_value=qvariant_cast<QByteArray>(context->argument(0).data().toVariant());
ret=RegistryHive::KeyValueToString(key_value,
context->argument(1).toInt32());
return engine->newVariant(ret);
}
QScriptValue DataReporterEngine::RegistryKeyValueToVariant(
QScriptContext *context,
QScriptEngine *engine)
{
int offset=0;
int length=-1;
bool little_endian=true;
QByteArray key_value;
QString format="";
QString ret="";
// This function needs at least two arguments, key value and variant type,
// and may have three optional arguments, offset, length and little_endian
if(context->argumentCount()<2 || context->argumentCount()>5) {
return engine->undefinedValue();
}
if(context->argumentCount()==3) {
offset=context->argument(2).toInt32();
}
if(context->argumentCount()==4) {
offset=context->argument(2).toInt32();
length=context->argument(3).toInt32();
}
if(context->argumentCount()==5) {
offset=context->argument(2).toInt32();
length=context->argument(3).toInt32();
little_endian=(context->argument(4).toInt32()==1);
}
// Cast ByteArray argument to QByteArray
key_value=qvariant_cast<QByteArray>(context->argument(0).data().toVariant());
format=context->argument(1).toString();
ret=RegistryHive::KeyValueToString(key_value,format,offset,length,little_endian);
return engine->newVariant(ret);
}
QScriptValue DataReporterEngine::RegistryKeyTypeToString(
QScriptContext *context,
QScriptEngine *engine)
{
QString ret="";
// This function needs one argument, key type
if(context->argumentCount()!=1) return engine->undefinedValue();
ret=RegistryHive::KeyTypeToString(context->argument(0).toInt32());
return engine->newVariant(ret);
}
QScriptValue DataReporterEngine::GetRegistryKeyModTime(
QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
int64_t mod_time=0;
// This function needs two argument, key path and key name
if(context->argumentCount()!=2) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
mod_time=p_hive->GetKeyModTime(context->argument(0).toString(),
context->argument(1).toString());
if(p_hive->Error()) {
// Get error message to clear error state
p_hive->GetErrorMsg();
return engine->undefinedValue();
}
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(RegistryHive::FiletimeToUnixtime(mod_time));
return engine->newVariant(date_time.toString("yyyy/MM/dd hh:mm:ss"));
}
diff --git a/trunk/datareporterengine.h b/trunk/datareporterengine.h
index 3891185..c9b5e5a 100644
--- a/trunk/datareporterengine.h
+++ b/trunk/datareporterengine.h
@@ -1,76 +1,76 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DATAREPORTERENGINE_H
#define DATAREPORTERENGINE_H
#include <QObject>
#include <QString>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptValue>
#include <QtScript/QScriptContext>
#include "registryhive.h"
#include "qtscript_types/bytearray.h"
class DataReporterEngine : public QScriptEngine {
Q_OBJECT
public:
struct s_RegistryKeyValue {
int type;
int length;
QByteArray value;
};
RegistryHive *p_registry_hive;
QString report_content;
DataReporterEngine(RegistryHive *p_hive);
~DataReporterEngine();
private:
ByteArray *p_type_byte_array;
static QScriptValue Print(QScriptContext *context, QScriptEngine *engine);
static QScriptValue PrintLn(QScriptContext *context, QScriptEngine *engine);
static QScriptValue GetRegistryNodes(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue GetRegistryKeys(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToScript(QScriptEngine *engine,
const s_RegistryKeyValue &s);
static void RegistryKeyValueFromScript(const QScriptValue &obj,
s_RegistryKeyValue &s);
static QScriptValue GetRegistryKeyValue(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToString(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToVariant(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyTypeToString(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue GetRegistryKeyModTime(QScriptContext *context,
QScriptEngine *engine);
};
Q_DECLARE_METATYPE(DataReporterEngine::s_RegistryKeyValue)
#endif // DATAREPORTERENGINE_H
diff --git a/trunk/dlgabout.cpp b/trunk/dlgabout.cpp
index bfce197..3d7e712 100644
--- a/trunk/dlgabout.cpp
+++ b/trunk/dlgabout.cpp
@@ -1,72 +1,72 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "dlgabout.h"
#include "ui_dlgabout.h"
#include "compileinfo.h"
DlgAbout::DlgAbout(QWidget *parent) :
QDialog(parent),
m_ui(new Ui::DlgAbout)
{
m_ui->setupUi(this);
this->setWindowTitle(tr("About %1").arg(APP_NAME));
// Update dialog with current infos
this->m_ui->LblAbout->setText(
this->m_ui->LblAbout->text().replace("%APP_NAME%",APP_NAME));
this->m_ui->LblAbout->setText(
this->m_ui->LblAbout->text().replace("%APP_COPYRIGHT%",APP_COPYRIGHT));
this->m_ui->TextEditInfo->setPlainText(
this->m_ui->TextEditInfo->toPlainText().replace("%APP_NAME%",APP_NAME));
this->m_ui->TextEditInfo->setPlainText(
this->m_ui->TextEditInfo->toPlainText().replace("%APP_VERSION%",
APP_VERSION));
this->m_ui->TextEditInfo->setPlainText(
this->m_ui->TextEditInfo->toPlainText().replace("%APP_DESCRIPTION%",
APP_DESCRIPTION));
this->m_ui->TextEditCopyright->setPlainText(
this->m_ui->TextEditCopyright->toPlainText().replace("%APP_COPYRIGHT%",
APP_COPYRIGHT));
this->m_ui->TextEditCopyright->setPlainText(
this->m_ui->TextEditCopyright->toPlainText()
.replace("%APP_DEVELOPPER_EMAIL%",
APP_DEVELOPPER_EMAIL));
}
DlgAbout::~DlgAbout() {
delete m_ui;
}
void DlgAbout::changeEvent(QEvent *e) {
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
m_ui->retranslateUi(this);
break;
default:
break;
}
}
void DlgAbout::on_btnClose_clicked() {
this->accept();
}
diff --git a/trunk/dlgabout.h b/trunk/dlgabout.h
index ff13445..8d8c881 100644
--- a/trunk/dlgabout.h
+++ b/trunk/dlgabout.h
@@ -1,47 +1,47 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DLGABOUT_H
#define DLGABOUT_H
#include <QDialog>
namespace Ui {
class DlgAbout;
}
class DlgAbout : public QDialog {
Q_OBJECT
public:
DlgAbout(QWidget *parent = 0);
~DlgAbout();
protected:
void changeEvent(QEvent *e);
private:
Ui::DlgAbout *m_ui;
private slots:
void on_btnClose_clicked();
};
#endif // DLGABOUT_H
diff --git a/trunk/dlgkeydetails.cpp b/trunk/dlgkeydetails.cpp
index 8927728..310e131 100644
--- a/trunk/dlgkeydetails.cpp
+++ b/trunk/dlgkeydetails.cpp
@@ -1,86 +1,86 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "dlgkeydetails.h"
#include "ui_dlgkeydetails.h"
DlgKeyDetails::DlgKeyDetails(QWidget *p_parent)
: QDialog(p_parent), ui(new Ui::DlgKeyDetails)
{
ui->setupUi(this);
// Init private vars
this->parent_nodes=QStringList();
this->key_name=QString();
this->key_type=QString();
this->key_value=QByteArray();
this->p_hex_edit=NULL;
}
DlgKeyDetails::~DlgKeyDetails() {
if(this->p_hex_edit!=NULL) delete this->p_hex_edit;
delete ui;
}
void DlgKeyDetails::SetValues(QStringList &r_parent_nodes,
QString &r_key_name,
QString &r_key_type,
QByteArray &r_key_value)
{
// Save params to local vars
this->parent_nodes=r_parent_nodes;
this->key_name=r_key_name;
this->key_type=r_key_type;
this->key_value=r_key_value;
// Set dialog title to complete registry path
this->setWindowTitle(parent_nodes.join("/").append("/").append(r_key_name));
// Create read only hex edit widget
this->p_hex_edit=new QHexEdit();
this->p_hex_edit->setReadOnly(true);
// Make sure hex viewer font is monospaced.
QFont mono_font("Monospace");
mono_font.setStyleHint(QFont::TypeWriter);
this->p_hex_edit->setFont(mono_font);
// Add the hexedit widget to the dialog
// As we know the dialog uses a box layout...
((QBoxLayout*)this->layout())->insertWidget(0,this->p_hex_edit);
// Add data to hex edit
this->p_hex_edit->setData(this->key_value);
}
void DlgKeyDetails::changeEvent(QEvent *e) {
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void DlgKeyDetails::on_BtnClose_clicked() {
this->accept();
}
diff --git a/trunk/dlgkeydetails.h b/trunk/dlgkeydetails.h
index 678bb90..9217f3b 100644
--- a/trunk/dlgkeydetails.h
+++ b/trunk/dlgkeydetails.h
@@ -1,60 +1,60 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DLGKEYDETAILS_H
#define DLGKEYDETAILS_H
#include <QDialog>
#include <QByteArray>
#include "qhexedit/qhexedit.h"
namespace Ui {
class DlgKeyDetails;
}
class DlgKeyDetails : public QDialog {
Q_OBJECT
public:
explicit DlgKeyDetails(QWidget *p_parent=0);
~DlgKeyDetails();
void SetValues(QStringList &r_parent_nodes,
QString &r_key_name,
QString &r_key_type,
QByteArray &r_key_value);
protected:
void changeEvent(QEvent *e);
private slots:
void on_BtnClose_clicked();
private:
Ui::DlgKeyDetails *ui;
QStringList parent_nodes;
QString key_name;
QString key_type;
QByteArray key_value;
QHexEdit *p_hex_edit;
};
#endif // DLGKEYDETAILS_H
diff --git a/trunk/dlgreportviewer.cpp b/trunk/dlgreportviewer.cpp
index 44606bd..a962057 100644
--- a/trunk/dlgreportviewer.cpp
+++ b/trunk/dlgreportviewer.cpp
@@ -1,88 +1,88 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "dlgreportviewer.h"
#include "ui_dlgreportviewer.h"
#include <QPrinter>
#include <QPrintDialog>
DlgReportViewer::DlgReportViewer(QString &report_data, QWidget *p_parent)
: QMainWindow(p_parent,Qt::Dialog | Qt::Popup), ui(new Ui::DlgReportViewer)
{
// Init local vars
ui->setupUi(this);
this->p_local_event_loop=NULL;
// Set report content
this->ui->WebView->setHtml(report_data);
// Set dialog title based on report content title
QString report_title=this->ui->WebView->title();
if(report_title.isEmpty()) this->setWindowTitle("Report Viewer");
else this->setWindowTitle(report_title.prepend("Report Viewer : "));
}
DlgReportViewer::~DlgReportViewer() {
delete ui;
if(this->p_local_event_loop!=NULL) this->p_local_event_loop->exit();
}
void DlgReportViewer::changeEvent(QEvent *e) {
QMainWindow::changeEvent(e);
switch(e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void DlgReportViewer::closeEvent(QCloseEvent *event) {
// Make sure we exit the local event loop on exit
if(this->p_local_event_loop!=NULL) {
this->p_local_event_loop->exit();
this->p_local_event_loop=NULL;
}
event->accept();
}
void DlgReportViewer::exec() {
// Create local event loop
this->p_local_event_loop=new QEventLoop(this);
// Show window and enter loop
this->show();
this->p_local_event_loop->exec();
}
void DlgReportViewer::on_action_Print_triggered() {
// Print report
QPrinter printer;
QPrintDialog *p_dlg_print=new QPrintDialog(&printer);
if(p_dlg_print->exec()==QDialog::Accepted) {
this->ui->WebView->print(&printer);
}
delete p_dlg_print;
}
void DlgReportViewer::on_action_Close_triggered() {
this->close();
}
diff --git a/trunk/dlgreportviewer.h b/trunk/dlgreportviewer.h
index bae96f7..88c182f 100644
--- a/trunk/dlgreportviewer.h
+++ b/trunk/dlgreportviewer.h
@@ -1,56 +1,56 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DLGREPORTVIEWER_H
#define DLGREPORTVIEWER_H
#include <QMainWindow>
#include <QEventLoop>
#include <QCloseEvent>
namespace Ui {
class DlgReportViewer;
}
class DlgReportViewer : public QMainWindow {
Q_OBJECT
public:
explicit DlgReportViewer(QString &report_data,
QWidget *p_parent=0);
~DlgReportViewer();
void exec();
protected:
void changeEvent(QEvent *e);
void closeEvent(QCloseEvent *event);
private slots:
void on_action_Print_triggered();
void on_action_Close_triggered();
private:
Ui::DlgReportViewer *ui;
QEventLoop *p_local_event_loop;
};
#endif // DLGREPORTVIEWER_H
diff --git a/trunk/dlgsearch.cpp b/trunk/dlgsearch.cpp
index 8e5cdc6..e22dec0 100644
--- a/trunk/dlgsearch.cpp
+++ b/trunk/dlgsearch.cpp
@@ -1,135 +1,135 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "dlgsearch.h"
#include "ui_dlgsearch.h"
#include <QMessageBox>
DlgSearch::DlgSearch(QWidget *parent) : QDialog(parent), ui(new Ui::DlgSearch)
{
ui->setupUi(this);
}
DlgSearch::~DlgSearch() {
delete ui;
}
QList<QByteArray> DlgSearch::Keywords() {
return this->keywords;
}
bool DlgSearch::SearchNodeNames() {
return this->search_nodes;
}
bool DlgSearch::SearchKeyNames() {
return this->search_keys;
}
bool DlgSearch::SearchKeyValues() {
return this->search_values;
}
void DlgSearch::changeEvent(QEvent *e) {
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void DlgSearch::keyPressEvent(QKeyEvent *p_event) {
if(p_event->key()==Qt::Key_Return || p_event->key()==Qt::Key_Enter) {
this->on_BtnSearch_clicked();
} else {
QDialog::keyPressEvent(p_event);
}
}
void DlgSearch::on_BtnCancel_clicked() {
this->reject();
}
void DlgSearch::on_BtnSearch_clicked() {
if(this->ui->EdtValue->text()=="" ||
(!this->ui->CbAscii->isChecked() &&
!this->ui->CbUtf16->isChecked() &&
!this->ui->CbHex->isChecked()))
{
// No value type specified
QMessageBox::critical(this,
tr("Error"),
tr("Please specify a search value and type!"));
return;
}
if(!this->ui->CbNodeNames->isChecked() &&
!this->ui->CbKeyNames->isChecked() &&
!this->ui->CbKeyValues->isChecked())
{
// No target specified
QMessageBox::critical(this,
tr("Error"),
tr("Please specify a search target!"));
return;
}
// Save settings
QString keyword=this->ui->EdtValue->text();
this->keywords.clear();
if(this->ui->CbAscii->isChecked()) this->keywords.append(QByteArray(keyword.toAscii()));
if(this->ui->CbUtf16->isChecked()) {
// TODO: .size()*2 will definetly fail sometimes!!!!
this->keywords.append(QByteArray((char*)(keyword.utf16()),keyword.size()*2));
}
if(this->ui->CbHex->isChecked()) {
// TODO: Convert to hex
}
this->search_nodes=this->ui->CbNodeNames->isChecked();
this->search_keys=this->ui->CbKeyNames->isChecked();
this->search_values=this->ui->CbKeyValues->isChecked();
this->accept();
}
void DlgSearch::on_CbAscii_toggled(bool checked) {
// It is not possible to search for text and hex
if(checked && this->ui->CbHex->isChecked())
this->ui->CbHex->setChecked(false);
}
void DlgSearch::on_CbUtf16_toggled(bool checked) {
// It is not possible to search for text and hex
if(checked && this->ui->CbHex->isChecked())
this->ui->CbHex->setChecked(false);
}
void DlgSearch::on_CbHex_toggled(bool checked) {
// It is not possible to search for text and hex
if(checked) {
this->ui->CbAscii->setChecked(false);
this->ui->CbUtf16->setChecked(false);
}
}
diff --git a/trunk/dlgsearch.h b/trunk/dlgsearch.h
index bb18b6f..8ebb8f6 100644
--- a/trunk/dlgsearch.h
+++ b/trunk/dlgsearch.h
@@ -1,64 +1,64 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DLGSEARCH_H
#define DLGSEARCH_H
#include <QDialog>
#include <QList>
#include <QByteArray>
#include <QKeyEvent>
namespace Ui {
class DlgSearch;
}
class DlgSearch : public QDialog {
Q_OBJECT
public:
explicit DlgSearch(QWidget *parent = 0);
~DlgSearch();
QList<QByteArray> Keywords();
bool SearchNodeNames();
bool SearchKeyNames();
bool SearchKeyValues();
protected:
void changeEvent(QEvent *e);
void keyPressEvent(QKeyEvent *p_event);
private slots:
void on_BtnCancel_clicked();
void on_BtnSearch_clicked();
void on_CbAscii_toggled(bool checked);
void on_CbUtf16_toggled(bool checked);
void on_CbHex_toggled(bool checked);
private:
Ui::DlgSearch *ui;
QList<QByteArray> keywords;
bool search_nodes;
bool search_keys;
bool search_values;
};
#endif // DLGSEARCH_H
diff --git a/trunk/fred.pro b/trunk/fred.pro
index d6f5dcc..0a40c7a 100644
--- a/trunk/fred.pro
+++ b/trunk/fred.pro
@@ -1,113 +1,113 @@
#*******************************************************************************
-# fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+# fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
# *
# Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
# with special feautures useful during forensic analysis. *
# *
# This program is free software: you can redistribute it and/or modify it *
# under the terms of the GNU General Public License as published by the Free *
# Software Foundation, either version 3 of the License, or (at your option) *
# any later version. *
# *
# This program is distributed in the hope that it will be useful, but WITHOUT *
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
# more details. *
# *
# You should have received a copy of the GNU General Public License along with *
# this program. If not, see <http://www.gnu.org/licenses/>. *
#******************************************************************************/
# Generate compileinfo.h
system(bash compileinfo.sh > compileinfo.h)
#compileinfo.target = compileinfo.h
#compileinfo.commands = $$PWD/compileinfo.sh > compileinfo.h
#QMAKE_EXTRA_TARGETS += compileinfo
#PRE_TARGETDEPS += compileinfo.h
# Build fred
QMAKE_CXXFLAGS += -Wall
QT += core \
gui \
script \
webkit
CONFIG += console
TARGET = fred
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
registrynode.cpp \
registrynodetreemodel.cpp \
registrykey.cpp \
registrykeytablemodel.cpp \
dlgabout.cpp \
dlgkeydetails.cpp \
qhexedit/qhexedit_p.cpp \
qhexedit/qhexedit.cpp \
reporttemplate.cpp \
datareporter.cpp \
datareporterengine.cpp \
registryhive.cpp \
qtscript_types/bytearray.cpp \
qtscript_types/bytearrayprototype.cpp \
qtscript_types/bytearrayiterator.cpp \
dlgreportviewer.cpp \
registrykeytable.cpp \
registrynodetree.cpp \
dlgsearch.cpp \
threadsearch.cpp \
searchresultwidget.cpp \
tabwidget.cpp \
argparser.cpp \
datainterpretertable.cpp \
datainterpreterwidget.cpp \
hexeditwidget.cpp
HEADERS += mainwindow.h \
registrynode.h \
registrynodetreemodel.h \
registrykey.h \
registrykeytablemodel.h \
dlgabout.h \
dlgkeydetails.h \
qhexedit/qhexedit_p.h \
qhexedit/qhexedit.h \
reporttemplate.h \
datareporter.h \
datareporterengine.h \
registryhive.h \
qtscript_types/bytearray.h \
qtscript_types/bytearrayprototype.h \
qtscript_types/bytearrayiterator.h \
dlgreportviewer.h \
registrykeytable.h \
registrynodetree.h \
dlgsearch.h \
threadsearch.h \
searchresultwidget.h \
tabwidget.h \
argparser.h \
datainterpretertable.h \
datainterpreterwidget.h \
hexeditwidget.h
FORMS += mainwindow.ui \
dlgabout.ui \
dlgkeydetails.ui \
dlgreportviewer.ui \
dlgsearch.ui
#LIBS += -lhivex
LIBS += $$PWD/hivex/lib/.libs/libhivex.a \
#DEFINES += __STDC_FORMAT_MACROS
RESOURCES += fred.qrc
RC_FILE = fred.rc
ICON = resources/fred.icns
diff --git a/trunk/hexeditwidget.cpp b/trunk/hexeditwidget.cpp
index 70ba521..bcedcaf 100644
--- a/trunk/hexeditwidget.cpp
+++ b/trunk/hexeditwidget.cpp
@@ -1,125 +1,125 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <QFont>
#include <QSizePolicy>
#include "hexeditwidget.h"
HexEditWidget::HexEditWidget(QWidget *p_parent) : QWidget(p_parent) {
// Init private vars
this->data=QByteArray();
this->read_only=true;
// Set widget layout. Setting it's parent to "this" will also call
// this->SetLayout.
this->p_widget_layout=new QVBoxLayout(this);
// Create sub-widgets
this->p_widget_splitter=new QSplitter(this);
this->p_hex_edit_layout_widget=new QWidget(this->p_widget_splitter);
this->p_hex_edit_layout=new QVBoxLayout(this->p_hex_edit_layout_widget);
this->p_hex_edit=new QHexEdit(this->p_hex_edit_layout_widget);
this->p_hex_edit_status_bar=new QLabel();
this->p_data_interpreter_widget=
new DataInterpreterWidget(this);
// Add hex edit and hex edit status bar to their layout
this->p_hex_edit_layout->addWidget(this->p_hex_edit);
this->p_hex_edit_layout->addWidget(this->p_hex_edit_status_bar);
// Add sub-widgets to splitter and splitter to our layout
this->p_widget_splitter->addWidget(this->p_hex_edit_layout_widget);
this->p_widget_splitter->addWidget(this->p_data_interpreter_widget);
this->p_widget_layout->addWidget(this->p_widget_splitter);
// Configure widget and sub-widgets
this->setContentsMargins(0,0,0,0);
this->p_widget_layout->setContentsMargins(0,0,0,0);
this->p_widget_splitter->setOrientation(Qt::Horizontal);
this->p_hex_edit_layout_widget->setContentsMargins(0,0,0,0);
this->p_hex_edit_layout->setContentsMargins(0,0,0,0);
this->p_hex_edit->setContentsMargins(0,0,0,0);
// 5 pixel bottom margin makes hex edit and data interpreter lignup correctly
this->p_hex_edit_status_bar->setContentsMargins(0,0,0,5);
this->p_hex_edit->setReadOnly(this->read_only);
this->setEnabled(false);
// Make sure hex edit font is monospaced.
QFont mono_font("Monospace");
mono_font.setStyleHint(QFont::TypeWriter);
this->p_hex_edit->setFont(mono_font);
// Set size policies of sub-widgets
QSizePolicy hex_edit_layout_widget_policy=
this->p_hex_edit_layout_widget->sizePolicy();
hex_edit_layout_widget_policy.setVerticalStretch(2);
hex_edit_layout_widget_policy.setHorizontalStretch(200);
this->p_hex_edit_layout_widget->setSizePolicy(hex_edit_layout_widget_policy);
QSizePolicy data_interpreter_widget_policy=
this->p_data_interpreter_widget->sizePolicy();
data_interpreter_widget_policy.setVerticalStretch(2);
data_interpreter_widget_policy.setHorizontalStretch(0);
this->p_data_interpreter_widget->
setSizePolicy(data_interpreter_widget_policy);
// Connect signals
this->connect(this->p_hex_edit,
SIGNAL(currentAddressChanged(int)),
this,
SLOT(SlotHexEditOffsetChanged(int)));
}
HexEditWidget::~HexEditWidget() {
delete this->p_data_interpreter_widget;
delete this->p_hex_edit_status_bar;
delete this->p_hex_edit;
delete this->p_hex_edit_layout;
delete this->p_hex_edit_layout_widget;
delete this->p_widget_splitter;
delete this->p_widget_layout;
}
void HexEditWidget::SetData(QByteArray const &new_data) {
this->data=new_data;
this->p_hex_edit->setData(this->data);
if(data.size()!=0) {
// Data set, update status bar and init data interpreter
this->SlotHexEditOffsetChanged(0);
} else {
// No data set, clear status bar and data interpreter
this->p_hex_edit_status_bar->setText("");
this->p_data_interpreter_widget->SetData(QByteArray());
}
}
void HexEditWidget::SlotHexEditOffsetChanged(int offset) {
// Update hex edit status bar
this->p_hex_edit_status_bar->setText(tr("Byte offset: 0x%1 (%2)")
.arg((quint16)offset,
4,
16,
QChar('0'))
.arg(offset));
// Update data interpreter
this->p_data_interpreter_widget->SetData(this->data.mid(offset,8));
}
diff --git a/trunk/hexeditwidget.h b/trunk/hexeditwidget.h
index b9d1cf9..db8d58d 100644
--- a/trunk/hexeditwidget.h
+++ b/trunk/hexeditwidget.h
@@ -1,64 +1,64 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef HEXEDITWIDGET_H
#define HEXEDITWIDGET_H
#include <QWidget>
#include <QSplitter>
#include <QVBoxLayout>
#include <QLabel>
#include <QByteArray>
#include "qhexedit/qhexedit.h"
#include "datainterpreterwidget.h"
class HexEditWidget : public QWidget {
Q_OBJECT
public:
explicit HexEditWidget(QWidget *p_parent=0);
~HexEditWidget();
void SetData(QByteArray const &data);
signals:
public slots:
private:
// Widget layout
QVBoxLayout *p_widget_layout;
QSplitter *p_widget_splitter;
// Sub-widgets
QWidget *p_hex_edit_layout_widget;
QVBoxLayout *p_hex_edit_layout;
QHexEdit *p_hex_edit;
QLabel *p_hex_edit_status_bar;
DataInterpreterWidget *p_data_interpreter_widget;
// Vars
QByteArray data;
bool read_only;
private slots:
void SlotHexEditOffsetChanged(int offset);
};
#endif // HEXEDITWIDGET_H
diff --git a/trunk/main.cpp b/trunk/main.cpp
index f8923cf..956e982 100644
--- a/trunk/main.cpp
+++ b/trunk/main.cpp
@@ -1,154 +1,154 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <QtGui/QApplication>
#include <QStringList>
#include <stdio.h>
#include "mainwindow.h"
#include "argparser.h"
#include "compileinfo.h"
#include "datareporter.h"
#include "registryhive.h"
// Forward declarations
void PrintUsage();
void DumpReport(QString report_template, QString hive_file);
// Main entry point
int main(int argc, char *argv[]) {
// Disable output buffering
setbuf(stdout,NULL);
// Init QApplication
QApplication a(argc, argv);
#define PRINT_HEADER { \
printf("%s v%s %s\n\n",APP_NAME,APP_VERSION,APP_COPYRIGHT); \
}
#define PRINT_HEADER_AND_USAGE { \
PRINT_HEADER; \
PrintUsage(); \
}
#define PRINT_VERSION printf("%s\n",APP_VERSION);
#define PRINT_UNKNOWN_ARG_ERROR(s) { \
PRINT_HEADER; \
printf("ERROR: Unknown command line argument '%s'!\n\n",s); \
PrintUsage(); \
}
// Parse command line args
ArgParser args(a.arguments());
if(!args.ParseArgs()) {
PRINT_HEADER;
printf("ERROR: %s\n\n",args.GetErrorMsg().toAscii().constData());
PrintUsage();
exit(1);
}
// Check command line args for correctness
if(args.IsSet("dump-report")) {
if(args.GetArgVal("dump-report")=="") {
PRINT_HEADER;
printf("ERROR: --dump-report specified without a report file!\n\n");
PrintUsage();
exit(1);
}
if(!args.IsSet("hive-file")) {
PRINT_HEADER;
printf("ERROR: --dump-report specified without a hive file!\n\n");
PrintUsage();
exit(1);
}
}
if(args.IsSet("fullscreen") && args.IsSet("maximized")) {
PRINT_HEADER;
printf("ERROR: --fullscreen and --maximized cannot be specified both!\n\n");
PrintUsage();
exit(1);
}
// React on some command line args early
if(args.IsSet("?") || args.IsSet("h") || args.IsSet("help")) {
PRINT_HEADER_AND_USAGE;
exit(0);
}
if(args.IsSet("v") || args.IsSet("version")) {
PRINT_VERSION;
exit(0);
}
if(args.IsSet("dump-report")) {
// Dump report to stdout
DumpReport(args.GetArgVal("dump-report"),args.GetArgVal("hive-file"));
exit(0);
}
#undef PRINT_UNKNOWN_ARG_ERROR
#undef PRINT_VERSION
#undef PRINT_HEADER_AND_USAGE
#undef PRINT_HEADER
// Create and show main window
MainWindow w(&args);
w.show();
return a.exec();
}
void PrintUsage() {
printf("Usage:\n");
printf(" %s [opts] [hive]\n\n",
qApp->arguments().at(0).toAscii().constData());
printf("Options:\n");
printf(" opts:\n");
printf(" --dump-report=FILE : Dump the specified report to stdout.\n");
printf(" --fullscreen : Display main window in fullscreen mode.\n");
printf(" -h, -?, --help : Display this help message.\n");
printf(" --maximized : Display main window in maximized mode.\n");
printf(" -v, --version : Display version info.\n");
printf(" hive:\n");
printf(" Open / Use the specified hive file.\n");
printf("\n");
}
void DumpReport(QString report_template, QString hive_file) {
RegistryHive *p_hive=new RegistryHive();
DataReporter *p_data_reporter=new DataReporter();
// Open hive
if(!p_hive->Open(hive_file,true)) {
printf("ERROR: Unable to open hive file '%s'!\n",
hive_file.toAscii().constData());
exit(1);
}
// Generate report
QString result=p_data_reporter->GenerateReport(p_hive,report_template,true);
// Close hive and free DataReporter and RegistryHive
p_hive->Close();
delete p_data_reporter;
delete p_hive;
// Print result to stdout
printf("%s",result.toAscii().constData());
}
diff --git a/trunk/mainwindow.cpp b/trunk/mainwindow.cpp
index 42fa460..2fd9c9c 100644
--- a/trunk/mainwindow.cpp
+++ b/trunk/mainwindow.cpp
@@ -1,564 +1,564 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef FRED_REPORT_TEMPLATE_DIR
#ifndef __MINGW32__
#define FRED_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates/"
#else
#define FRED_REPORT_TEMPLATE_DIR ".\\report_templates\\"
#endif
#endif
#include <QFileDialog>
#include <QMessageBox>
#include <QStringList>
#include <QDesktopWidget>
#include <QDir>
#include <QSplitter>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dlgabout.h"
#include "dlgkeydetails.h"
#include "dlgreportviewer.h"
#include "dlgsearch.h"
#include "compileinfo.h"
MainWindow::MainWindow(ArgParser *p_arg_parser) :
QMainWindow(0), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Initialize private vars
this->p_args=p_arg_parser;
this->p_hive=new RegistryHive(this);
this->is_hive_open=false;
this->p_reg_node_tree_model=NULL;
this->p_reg_key_table_model=NULL;
this->p_search_thread=NULL;
this->search_result_widgets.clear();
// Check for ~/.fred config dir
this->CheckUserConfigDir();
// Set main window size
int cur_screen=QApplication::desktop()->screenNumber(this);
int window_width=
QApplication::desktop()->availableGeometry(cur_screen).width()*0.5;
int window_height=
QApplication::desktop()->availableGeometry(cur_screen).height()*0.5;
int window_x=
(QApplication::desktop()->availableGeometry(cur_screen).width()/2)-
(window_width/2);
int window_y=
(QApplication::desktop()->availableGeometry(cur_screen).height()/2)-
(window_height/2);
this->setGeometry(window_x,
window_y,
window_width,
window_height);
// Create widgets
this->p_horizontal_splitter=new QSplitter();
this->p_horizontal_splitter->setOrientation(Qt::Horizontal);
this->p_node_tree=new RegistryNodeTree(this->p_horizontal_splitter);
this->p_node_tree->setHeaderHidden(true);
this->p_vertical_splitter=new QSplitter(this->p_horizontal_splitter);
this->p_vertical_splitter->setOrientation(Qt::Vertical);
this->p_key_table=new RegistryKeyTable(this->p_vertical_splitter);
this->p_tab_widget=new TabWidget(this->p_vertical_splitter);
this->p_hex_edit_widget=new HexEditWidget();
// Add hexedit page to tab_widget
this->p_tab_widget->addTab(this->p_hex_edit_widget,tr("Hex viewer"));
// Add widgets to their splitters
this->p_vertical_splitter->addWidget(this->p_key_table);
this->p_vertical_splitter->addWidget(this->p_tab_widget);
this->p_horizontal_splitter->addWidget(this->p_node_tree);
this->p_horizontal_splitter->addWidget(this->p_vertical_splitter);
// Set stretch factors
QSizePolicy node_tree_policy=this->p_node_tree->sizePolicy();
node_tree_policy.setHorizontalStretch(1);
node_tree_policy.setVerticalStretch(100);
this->p_node_tree->setSizePolicy(node_tree_policy);
QSizePolicy vertical_splitter_policy=this->p_vertical_splitter->sizePolicy();
vertical_splitter_policy.setHorizontalStretch(4);
vertical_splitter_policy.setVerticalStretch(100);
this->p_vertical_splitter->setSizePolicy(vertical_splitter_policy);
QSizePolicy key_table_policy=this->p_key_table->sizePolicy();
key_table_policy.setVerticalStretch(5);
key_table_policy.setHorizontalStretch(100);
this->p_key_table->setSizePolicy(key_table_policy);
QSizePolicy tab_widget_policy=this->p_tab_widget->sizePolicy();
tab_widget_policy.setVerticalStretch(2);
tab_widget_policy.setHorizontalStretch(200);
this->p_tab_widget->setSizePolicy(tab_widget_policy);
// Connect signals
this->connect(this->p_node_tree,
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_node_tree,
SIGNAL(activated(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_node_tree,
SIGNAL(CurrentItemChanged(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotKeyTableClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotKeyTableDoubleClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(CurrentItemChanged(QModelIndex)),
this,
SLOT(SlotKeyTableClicked(QModelIndex)));
this->connect(this->p_tab_widget,
SIGNAL(tabCloseRequested(int)),
this,
SLOT(SlotTabCloseButtonClicked(int)));
// Add central widget
this->setCentralWidget(this->p_horizontal_splitter);
this->centralWidget()->setContentsMargins(4,4,4,0);
// Set window title
this->UpdateWindowTitle();
// Set last open location to home dir
this->last_open_location=QDir::homePath();
// Load report templates and update menu
this->p_data_reporter=new DataReporter();
// Load reports from system wide include dir
this->p_data_reporter->LoadReportTemplates(FRED_REPORT_TEMPLATE_DIR);
// Load user's report templates
this->p_data_reporter->LoadReportTemplates(QDir::homePath()
.append(QDir::separator())
.append(".fred")
.append(QDir::separator())
.append("report_templates"));
this->UpdateDataReporterMenu();
// Finally, react on some command line arguments
if(this->p_args->IsSet("maximized")) {
this->setWindowState(Qt::WindowMaximized);
}
if(this->p_args->IsSet("fullscreen")) {
this->setWindowState(Qt::WindowFullScreen);
}
if(this->p_args->IsSet("hive-file")) {
this->OpenHive(this->p_args->GetArgVal("hive-file"));
}
}
MainWindow::~MainWindow() {
if(this->is_hive_open) {
this->p_hive->Close();
}
delete ui;
}
void MainWindow::on_action_Quit_triggered() {
qApp->exit();
}
void MainWindow::on_action_Open_hive_triggered() {
QString hive_file="";
hive_file=QFileDialog::getOpenFileName(this,
tr("Open registry hive"),
this->last_open_location,
tr("All files (*)"));
if(hive_file=="") return;
this->OpenHive(hive_file);
}
void MainWindow::on_action_Close_hive_triggered() {
if(this->is_hive_open) {
// Remove search results
while(this->p_tab_widget->count()>1) {
this->p_tab_widget->removeTab(this->p_tab_widget->count()-1);
delete this->search_result_widgets.at(this->p_tab_widget->count()-1);
this->search_result_widgets.removeLast();
}
// Delete models
if(this->p_reg_node_tree_model!=NULL) {
this->p_node_tree->setModel(NULL);
delete this->p_reg_node_tree_model;
this->p_reg_node_tree_model=NULL;
}
if(this->p_reg_key_table_model!=NULL) {
this->p_key_table->setModel(NULL);
delete this->p_reg_key_table_model;
this->p_reg_key_table_model=NULL;
}
// Remove any data from hex edit and data interpreter
this->p_hex_edit_widget->SetData(QByteArray());
this->p_hex_edit_widget->setEnabled(false);
// Close hive
this->p_hive->Close();
this->is_hive_open=false;
this->ui->action_Close_hive->setEnabled(false);
this->ui->ActionSearch->setEnabled(false);
this->ui->MenuReports->setEnabled(false);
this->UpdateWindowTitle();
}
}
void MainWindow::on_actionAbout_Qt_triggered() {
QMessageBox::aboutQt(this,tr("About Qt"));
}
void MainWindow::on_actionAbout_fred_triggered() {
DlgAbout dlg_about(this);
dlg_about.exec();
}
void MainWindow::on_ActionSearch_triggered() {
DlgSearch dlg_search(this);
if(dlg_search.exec()==QDialog::Accepted) {
// Create search thread and connect needed signals/slots
this->p_search_thread=new ThreadSearch(this);
// Add new search widget to tabwidget and to internal widget list
SearchResultWidget *p_search_widget=
new SearchResultWidget(this->p_tab_widget);
p_search_widget->setEnabled(false);
this->search_result_widgets.append(p_search_widget);
this->connect(p_search_widget,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotSearchResultWidgetDoubleClicked(QModelIndex)));
this->p_tab_widget->addTab(p_search_widget,tr("Search results"),true);
this->p_tab_widget->setCurrentIndex(this->p_tab_widget->count()-1);
// Connect search thread to result widget
this->connect(this->p_search_thread,
SIGNAL(SignalFoundMatch(ThreadSearch::eMatchType,
QString,QString,QString)),
p_search_widget,
SLOT(SlotFoundMatch(ThreadSearch::eMatchType,
QString,QString,QString)));
this->connect(this->p_search_thread,
SIGNAL(finished()),
this,
SLOT(SlotSearchFinished()));
this->connect(this->p_search_thread,
SIGNAL(finished()),
p_search_widget,
SLOT(SlotSearchFinished()));
// Start searching
this->ui->ActionSearch->setEnabled(false);
p_search_thread->Search(this->p_hive->Filename(),
dlg_search.Keywords(),
dlg_search.SearchNodeNames(),
dlg_search.SearchKeyNames(),
dlg_search.SearchKeyValues());
}
}
void MainWindow::SlotNodeTreeClicked(QModelIndex index) {
QString node_path;
if(!index.isValid()) return;
// Built node path
node_path=this->p_reg_node_tree_model->GetNodePath(index);
// Create table model and attach it to the table view
if(this->p_reg_key_table_model!=NULL) {
// If a previous model was set, delete it and clear hexedit etc...
this->p_key_table->setModel(NULL);
delete this->p_reg_key_table_model;
this->p_hex_edit_widget->SetData(QByteArray());
}
this->p_reg_key_table_model=new RegistryKeyTableModel(this->p_hive,node_path);
this->p_key_table->setModel(this->p_reg_key_table_model);
// Set focus back to nodetree to be able to navigate with keyboard
this->p_node_tree->setFocus();
}
void MainWindow::SlotKeyTableDoubleClicked(QModelIndex index) {
Q_UNUSED(index);
/*
QModelIndex key_index;
QModelIndex node_index;
QStringList nodes;
QString key_name;
QString key_type;
QByteArray key_value;
if(!index.isValid()) return;
// Get key name, type and value
key_index=this->p_reg_key_table_model->index(index.row(),0);
key_name=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();
key_index=this->p_reg_key_table_model->index(index.row(),1);
key_type=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();ThreadSearch
key_index=this->p_reg_key_table_model->index(index.row(),2);
key_value=this->p_reg_key_table_model->data(key_index,
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
// Get current node
node_index=this->p_node_tree->currentIndex();
//Built node path
nodes.clear();
nodes.append(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
while(this->p_reg_node_tree_model->parent(node_index)!=QModelIndex()) {
// Prepend all parent nodes
node_index=this->p_reg_node_tree_model->parent(node_index);
nodes.prepend(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
}
DlgKeyDetails dlg_key_details(this);
dlg_key_details.SetValues(nodes,key_name,key_type,key_value);
dlg_key_details.exec();
*/
}
void MainWindow::SlotKeyTableClicked(QModelIndex index) {
if(!index.isValid()) return;
this->selected_key_value=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),2),
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
this->p_hex_edit_widget->SetData(this->selected_key_value);
// Set focus back to nodetree to be able to navigate with keyboard
this->p_key_table->setFocus();
}
void MainWindow::SlotReportClicked() {
// Get report category and name from sender and it's parent
QString category=((QMenu*)((QAction*)QObject::sender())->parent())->title();
QString report=((QAction*)QObject::sender())->text();
// Generate report
QString report_content=this->p_data_reporter->GenerateReport(this->p_hive,
category,
report);
// Show result in report viewer
if(report_content!=QString()) {
DlgReportViewer *p_dlg_report_view=new DlgReportViewer(report_content,this);
p_dlg_report_view->exec();
delete p_dlg_report_view;
} else {
// TODO: Something went wrong!
}
}
void MainWindow::SlotSearchFinished() {
delete this->p_search_thread;
this->p_search_thread=NULL;
this->ui->ActionSearch->setEnabled(true);
// Enable result widget
this->search_result_widgets.last()->setEnabled(true);
}
void MainWindow::SlotSearchResultWidgetDoubleClicked(QModelIndex index) {
SearchResultWidget *p_sender;
QString path;
QString match_type;
QString value;
QString key="";
int i;
if(!index.isValid()) return;
// Get pointer to sender
p_sender=(SearchResultWidget*)QObject::sender();
// Get path and matchtype
path=p_sender->item(index.row(),0)->text();
match_type=p_sender->item(index.row(),1)->text();
value=p_sender->item(index.row(),2)->text();
if(match_type==tr("Node name")) {
// Node name is not part of path. Add it
if(path=="\\") path.append(value);
else path.append("\\").append(value);
} else if(match_type==tr("Key name")) {
// Key name is stored in value
key=value;
} else if(match_type==tr("Key value")) {
// Key name is part of path. Save and remove it
QStringList nodes=path.split("\\",QString::SkipEmptyParts);
key=nodes.at(nodes.count()-1);
// Remove \<key name> from path
path.chop(key.length()+1);
}
// Expand treeview to correct node
QList<QModelIndex> indexes=
this->p_reg_node_tree_model->GetIndexListOf(path);
for(i=0;i<indexes.count();i++) {
this->p_node_tree->expand(indexes.at(i));
}
if(indexes.count()>0) {
// Scroll to last expanded node, select it and update widgets
this->p_node_tree->scrollTo(indexes.at(indexes.count()-1),
QAbstractItemView::PositionAtCenter);
this->p_node_tree->selectionModel()->clear();
this->p_node_tree->selectionModel()->
select(indexes.at(indexes.count()-1),
QItemSelectionModel::Select);
// TODO: This does not work!!
this->SlotNodeTreeClicked(indexes.at(indexes.count()-1));
}
// Select correct key if search matched on keay name / value
if(key!="") {
int row=this->p_reg_key_table_model->GetKeyRow(key);
this->p_key_table->clearSelection();
this->p_key_table->scrollTo(this->p_reg_key_table_model->index(row,0),
QAbstractItemView::PositionAtCenter);
this->p_key_table->selectRow(row);
this->SlotKeyTableClicked(this->p_reg_key_table_model->index(row,0));
}
}
void MainWindow::SlotTabCloseButtonClicked(int index) {
// Delete tab widget and remove tab
this->p_tab_widget->removeTab(index);
delete this->search_result_widgets.at(index-1);
this->search_result_widgets.removeAt(index-1);
}
void MainWindow::CheckUserConfigDir() {
QString user_config_dir=QDir::homePath()
.append(QDir::separator())
.append(".fred");
if(!QDir(user_config_dir).exists()) {
// User config dir does not exists, try to create it
if(!QDir().mkpath(user_config_dir)) {
// TODO: Maybe warn user
return;
}
user_config_dir.append(QDir::separator()).append("report_templates");
if(!QDir().mkpath(user_config_dir)) {
// TODO: Maybe warn user
return;
}
}
}
void MainWindow::UpdateWindowTitle(QString filename) {
if(filename=="") {
this->setWindowTitle(QString("%1 v%2").arg(APP_TITLE,APP_VERSION));
} else {
this->setWindowTitle(QString("%1 v%2 - %3").arg(APP_TITLE,
APP_VERSION,
filename.toLocal8Bit()
.constData()));
}
}
void MainWindow::UpdateDataReporterMenu() {
int i=0,ii=0;
QMenu *p_category_entry;
QAction *p_report_entry;
QStringList categories=this->p_data_reporter->GetAvailableReportCategories();
QStringList reports;
for(i=0;i<categories.count();i++) {
// First create category submenu
p_category_entry=this->ui->MenuReports->addMenu(categories.value(i));
// Now add category reports
reports=this->p_data_reporter->GetAvailableReports(categories.value(i));
for(ii=0;ii<reports.count();ii++) {
p_report_entry=new QAction(reports.value(ii),p_category_entry);
p_category_entry->addAction(p_report_entry);
this->connect(p_report_entry,
SIGNAL(triggered()),
this,
SLOT(SlotReportClicked()));
}
}
}
void MainWindow::OpenHive(QString hive_file) {
// Update last open location
this->last_open_location=hive_file.left(hive_file.
lastIndexOf(QDir::separator()));
// If another hive is currently open, close it
if(this->is_hive_open) this->on_action_Close_hive_triggered();
// Try to open hive
if(!this->p_hive->Open(hive_file)) {
QMessageBox::critical(this,
tr("Error opening hive file"),
tr("Unable to open file '%1'").arg(hive_file));
return;
}
// Create tree model
this->p_reg_node_tree_model=
new RegistryNodeTreeModel(this->p_hive);
this->p_node_tree->setModel(this->p_reg_node_tree_model);
this->is_hive_open=true;
this->ui->action_Close_hive->setEnabled(true);
this->ui->ActionSearch->setEnabled(true);
this->ui->MenuReports->setEnabled(true);
// Enable data interpreter
this->p_hex_edit_widget->setEnabled(true);
this->UpdateWindowTitle(hive_file);
}
diff --git a/trunk/mainwindow.h b/trunk/mainwindow.h
index b27cf14..926d869 100644
--- a/trunk/mainwindow.h
+++ b/trunk/mainwindow.h
@@ -1,123 +1,123 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QLabel>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QSplitter>
#include <QString>
#include <QByteArray>
#include <hivex.h>
#include "argparser.h"
#include "registryhive.h"
#include "registrynodetree.h"
#include "registrynodetreemodel.h"
#include "registrykeytable.h"
#include "registrykeytablemodel.h"
#include "hexeditwidget.h"
#include "datareporter.h"
#include "threadsearch.h"
#include "searchresultwidget.h"
#include "tabwidget.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(ArgParser *p_arg_parser);
~MainWindow();
private slots:
void on_action_Quit_triggered();
void on_action_Open_hive_triggered();
void on_action_Close_hive_triggered();
void on_actionAbout_Qt_triggered();
void on_actionAbout_fred_triggered();
void on_ActionSearch_triggered();
void SlotNodeTreeClicked(QModelIndex index);
void SlotKeyTableClicked(QModelIndex index);
void SlotKeyTableDoubleClicked(QModelIndex index);
void SlotReportClicked();
void SlotSearchFinished();
void SlotSearchResultWidgetDoubleClicked(QModelIndex index);
void SlotTabCloseButtonClicked(int index);
private:
Ui::MainWindow *ui;
ArgParser *p_args;
QString last_open_location;
RegistryHive *p_hive;
bool is_hive_open;
RegistryNodeTreeModel *p_reg_node_tree_model;
RegistryKeyTableModel *p_reg_key_table_model;
QByteArray selected_key_value;
QList<SearchResultWidget*> search_result_widgets;
// Widgets etc...
RegistryNodeTree *p_node_tree;
RegistryKeyTable *p_key_table;
TabWidget *p_tab_widget;
HexEditWidget *p_hex_edit_widget;
QSplitter *p_horizontal_splitter;
QSplitter *p_vertical_splitter;
DataReporter *p_data_reporter;
ThreadSearch *p_search_thread;
/*
* CheckUserConfigDir
*
* Checks for and possibly creates the ~/.fred directory
*/
void CheckUserConfigDir();
/*
* UpdateWindowTitle
*
* Updates the window title
*/
void UpdateWindowTitle(QString filename="");
/*
* UpdateDataReporterMenu
*
*/
void UpdateDataReporterMenu();
/*
* OpenHive
*
* Open a registry hive
*/
void OpenHive(QString hive_file);
};
#endif // MAINWINDOW_H
diff --git a/trunk/qhexedit/qhexedit.cpp b/trunk/qhexedit/qhexedit.cpp
index c157950..9dfd01a 100644
--- a/trunk/qhexedit/qhexedit.cpp
+++ b/trunk/qhexedit/qhexedit.cpp
@@ -1,137 +1,137 @@
/*******************************************************************************
-* qhexedit Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* qhexedit Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Simple hex editor widget for Qt. *
* *
* Derived from code by Simon Winfried under a compatible license: *
* Copyright (c) 2010 by Simon Winfried *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <QtGui>
#include "qhexedit.h"
QHexEdit::QHexEdit(QWidget *parent) : QScrollArea(parent)
{
qHexEdit_p = new QHexEditPrivate(this);
setWidget(qHexEdit_p);
setWidgetResizable(true);
connect(qHexEdit_p, SIGNAL(currentAddressChanged(int)), this, SIGNAL(currentAddressChanged(int)));
connect(qHexEdit_p, SIGNAL(currentSizeChanged(int)), this, SIGNAL(currentSizeChanged(int)));
connect(qHexEdit_p, SIGNAL(dataChanged()), this, SIGNAL(dataChanged()));
connect(qHexEdit_p, SIGNAL(overwriteModeChanged(bool)), this, SIGNAL(overwriteModeChanged(bool)));
}
void QHexEdit::insert(int i, const QByteArray & ba)
{
qHexEdit_p->insert(i, ba);
}
void QHexEdit::insert(int i, char ch)
{
qHexEdit_p->insert(i, ch);
}
void QHexEdit::remove(int pos, int len)
{
qHexEdit_p->remove(pos, len);
}
void QHexEdit::setAddressArea(bool addressArea)
{
qHexEdit_p->setAddressArea(addressArea);
}
void QHexEdit::setAddressWidth(int addressWidth)
{
qHexEdit_p->setAddressWidth(addressWidth);
}
void QHexEdit::setAsciiArea(bool asciiArea)
{
qHexEdit_p->setAsciiArea(asciiArea);
}
void QHexEdit::setHighlighting(bool mode)
{
qHexEdit_p->setHighlighting(mode);
}
void QHexEdit::setAddressOffset(int offset)
{
qHexEdit_p->setAddressOffset(offset);
}
int QHexEdit::addressOffset()
{
return addressOffset();
}
void QHexEdit::setData(const QByteArray &data)
{
qHexEdit_p->setData(data);
}
QByteArray QHexEdit::data()
{
return qHexEdit_p->data();
}
void QHexEdit::setAddressAreaColor(const QColor &color)
{
qHexEdit_p->setAddressAreaColor(color);
}
QColor QHexEdit::addressAreaColor()
{
return qHexEdit_p->addressAreaColor();
}
void QHexEdit::setHighlightingColor(const QColor &color)
{
qHexEdit_p->setHighlightingColor(color);
}
QColor QHexEdit::highlightingColor()
{
return qHexEdit_p->highlightingColor();
}
void QHexEdit::setOverwriteMode(bool overwriteMode)
{
qHexEdit_p->setOverwriteMode(overwriteMode);
}
bool QHexEdit::overwriteMode()
{
return qHexEdit_p->overwriteMode();
}
void QHexEdit::setReadOnly(bool read_only) {
qHexEdit_p->setReadOnly(read_only);
}
bool QHexEdit::readOnly() {
return qHexEdit_p->readOnly();
}
void QHexEdit::setFont(const QFont &font)
{
qHexEdit_p->setFont(font);
}
diff --git a/trunk/qhexedit/qhexedit.h b/trunk/qhexedit/qhexedit.h
index 9eb4574..e427efb 100644
--- a/trunk/qhexedit/qhexedit.h
+++ b/trunk/qhexedit/qhexedit.h
@@ -1,177 +1,177 @@
/*******************************************************************************
-* qhexedit Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* qhexedit Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Simple hex editor widget for Qt. *
* *
* Derived from code by Simon Winfried under a compatible license: *
* Copyright (c) 2010 by Simon Winfried *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef QHEXEDIT_H
#define QHEXEDIT_H
#include <QtGui>
#include "qhexedit_p.h"
/** \mainpage
QHexEdit is a binary editor widget for Qt.
\version Version 0.4.6
\image html hexedit.png
*/
/*! QHexEdit is a hex editor widget written in C++ for the Qt (Qt4) framework.
It is a simple editor for binary data, just like QPlainTextEdit is for text data.
There are sip configuration files included, so it is easy to create bindings
for PyQt and you can use this widget also in python.
QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use the
mouse or the keyboard to navigate inside the widget. If you hit the keys (0..9, a..f)
you will change the data. Changed data is highlighted and can be accessed via data().
Normaly QHexEdit works in the overwrite Mode. You can set overwriteMode(false) and
insert data. In this case the size of data() increases. It is also possible to delete
bytes under the cursor, here the size of data decreases.
There are some limitations: The size of data has in general to be below 10 megabytes,
otherwise the scroll sliders ard not shown and you can't scroll any more. Copy and
paste functionality is perhaps a subject of a later release.
*/
class QHexEdit : public QScrollArea
{
Q_OBJECT
/*! Property data holds the content of QHexEdit. Call setData() to set the
content of QHexEdit, data() returns the actual content.
*/
Q_PROPERTY(QByteArray data READ data WRITE setData)
/*! Property addressOffset is added to the Numbers of the Address Area.
A offset in the address area (left side) is sometimes usefull, whe you show
only a segment of a complete memory picture. With setAddressOffset() you set
this property - with addressOffset() you get the actual value.
*/
Q_PROPERTY(int addressOffset READ addressOffset WRITE setAddressOffset)
/*! Property address area color sets (setAddressAreaColor()) the backgorund
color of address areas. You can also read the color (addressaAreaColor()).
*/
Q_PROPERTY(QColor addressAreaColor READ addressAreaColor WRITE setAddressAreaColor)
/*! Property highlighting color sets (setHighlightingColor()) the backgorund
color of highlighted text areas. You can also read the color
(highlightingColor()).
*/
Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor)
/*! Porperty overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the mode
in which the editor works. In overwritem mode the user will overwrite existing data.
*/
Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
/*! Porperty read only sets (setReadOnly()) or gets (readOnly()) the
current editable mode.
*/
Q_PROPERTY(bool readOnly READ readOnly WRITE setReadOnly)
public:
/*! Creates an instance of QHexEdit.
\param parent Parent widget of QHexEdit.
*/
QHexEdit(QWidget *parent = 0);
/*! Inserts a byte array.
\param i Index position, where to insert
\param ba byte array, which is to insert
*/
void insert(int i, const QByteArray & ba);
/*! Inserts a char.
\param i Index position, where to insert
\param ch Char, which is to insert
*/
void insert(int i, char ch);
/*! Removes len bytes from the content.
\param pos Index position, where to remove
\param len Amount of bytes to remove
*/
void remove(int pos, int len=1);
/*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/
void setFont(const QFont &);
/*! \cond docNever */
void setAddressOffset(int offset);
int addressOffset();
void setData(QByteArray const &data);
QByteArray data();
void setAddressAreaColor(QColor const &color);
QColor addressAreaColor();
void setHighlightingColor(QColor const &color);
QColor highlightingColor();
void setOverwriteMode(bool);
bool overwriteMode();
void setReadOnly(bool);
bool readOnly();
/*! \endcond docNever */
public slots:
/*! Set the minimum width of the address area.
\param addressWidth Width in characters.
*/
void setAddressWidth(int addressWidth);
/*! Switch the address area on or off.
\param addressArea true (show it), false (hide it).
*/
void setAddressArea(bool addressArea);
/*! Switch the ascii area on or off.
\param asciiArea true (show it), false (hide it).
*/
void setAsciiArea(bool asciiArea);
/*! Switch the highlighting feature on or of.
\param mode true (show it), false (hide it).
*/
void setHighlighting(bool mode);
signals:
/*! Contains the address, where the cursor is located. */
void currentAddressChanged(int address);
/*! Contains the size of the data to edit. */
void currentSizeChanged(int size);
/*! The signal is emited every time, the data is changed. */
void dataChanged();
/*! The signal is emited every time, the overwrite mode is changed. */
void overwriteModeChanged(bool state);
private:
/*! \cond docNever */
QHexEditPrivate *qHexEdit_p;
QHBoxLayout *layout;
QScrollArea *scrollArea;
/*! \endcond docNever */
};
#endif
diff --git a/trunk/qhexedit/qhexedit_p.cpp b/trunk/qhexedit/qhexedit_p.cpp
index 7d2a6ed..272ee8a 100644
--- a/trunk/qhexedit/qhexedit_p.cpp
+++ b/trunk/qhexedit/qhexedit_p.cpp
@@ -1,628 +1,628 @@
/*******************************************************************************
-* qhexedit Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* qhexedit Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Simple hex editor widget for Qt. *
* *
* Derived from code by Simon Winfried under a compatible license: *
* Copyright (c) 2010 by Simon Winfried *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <QtGui>
#include <QClipboard>
#include "qhexedit_p.h"
const int HEXCHARS_IN_LINE = 47;
const int GAP_ADR_HEX = 10;
const int GAP_HEX_ASCII = 16;
const int BYTES_PER_LINE = 16;
QHexEditPrivate::QHexEditPrivate(QScrollArea *parent) : QWidget(parent) {
_scrollArea = parent;
setAddressWidth(4);
setAddressOffset(0);
setAddressArea(true);
setAsciiArea(true);
setHighlighting(true);
setOverwriteMode(true);
setAddressAreaColor(QColor(Qt::lightGray).lighter(110));
setHighlightingColor(QColor(Qt::yellow).lighter(160));
this->setReadOnly(true);
this->sel_origin=QPoint(0,0);
this->sel_start=QPoint(0,0);
this->sel_end=QPoint(0,0);
setFont(QFont("Mono", 10));
connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor()));
_cursorTimer.setInterval(500);
setFocusPolicy(Qt::StrongFocus);
_size = -1;
// Create context menu
this->p_menu_copy=new QMenu(tr("Copy"),this);
this->p_action_copy_selected_bytes=
new QAction(tr("Selected bytes"),this->p_menu_copy);
this->p_action_copy_selected_text_ascii=
new QAction(tr("Selected bytes converted to ASCII"),this->p_menu_copy);
/*
this->p_action_copy_selected_text_utf8=
new QAction(tr("Selected text as UTF8"),this->p_menu_copy);
*/
this->p_menu_copy->addAction(this->p_action_copy_selected_bytes);
this->p_menu_copy->addAction(this->p_action_copy_selected_text_ascii);
/*
this->p_menu_copy->addAction(this->p_action_copy_selected_text_utf8);
*/
this->connect(this->p_action_copy_selected_bytes,
SIGNAL(triggered()),
this,
SLOT(SlotCopySelectedBytes()));
this->connect(this->p_action_copy_selected_text_ascii,
SIGNAL(triggered()),
this,
SLOT(SlotCopySelectedTextAsAscii()));
/*
this->connect(this->p_action_copy_selected_text_utf8,
SIGNAL(triggered()),
this,
SLOT(SlotCopySelectedTextAsUtf8()));
*/
}
QHexEditPrivate::~QHexEditPrivate() {
// Delete context menu
delete this->p_action_copy_selected_bytes;
delete this->p_action_copy_selected_text_ascii;
/*
delete this->p_action_copy_selected_text_utf8;
*/
delete this->p_menu_copy;
}
void QHexEditPrivate::setAddressOffset(int offset)
{
_addressOffset = offset;
adjust();
}
int QHexEditPrivate::addressOffset()
{
return _addressOffset;
}
void QHexEditPrivate::setData(const QByteArray &data)
{
// Delete any previous selections
this->sel_origin.setX(0);
this->sel_origin.setY(0);
this->sel_start=this->sel_origin;
this->sel_end=this->sel_origin;
if(!data.isNull() && !data.isEmpty()) this->_cursorTimer.start();
else this->_cursorTimer.stop();
this->_data = data;
this->_originalData = data;
this->adjust();
this->setCursorPos(0);
this->setFocus();
}
QByteArray QHexEditPrivate::data()
{
return _data;
}
void QHexEditPrivate::setAddressAreaColor(const QColor &color)
{
_addressAreaColor = color;
update();
}
QColor QHexEditPrivate::addressAreaColor()
{
return _addressAreaColor;
}
void QHexEditPrivate::setHighlightingColor(const QColor &color)
{
_highlightingColor = color;
update();
}
QColor QHexEditPrivate::highlightingColor()
{
return _highlightingColor;
}
void QHexEditPrivate::setOverwriteMode(bool overwriteMode)
{
if (overwriteMode != _overwriteMode)
{
emit overwriteModeChanged(overwriteMode);
_overwriteMode = overwriteMode;
adjust();
}
}
bool QHexEditPrivate::overwriteMode()
{
return _overwriteMode;
}
void QHexEditPrivate::setReadOnly(bool read_only) {
this->_readOnly=read_only;
}
bool QHexEditPrivate::readOnly() {
return this->_readOnly;
}
void QHexEditPrivate::insert(int i, const QByteArray & ba)
{
_data.insert(i, ba);
_originalData.insert(i, ba);
}
void QHexEditPrivate::insert(int i, char ch)
{
_data.insert(i, ch);
_originalData.insert(i, ch);
}
void QHexEditPrivate::remove(int index, int len)
{
_data.remove(index, len);
_originalData.remove(index, len);
}
void QHexEditPrivate::setAddressArea(bool addressArea)
{
_addressArea = addressArea;
adjust();
setCursorPos(_cursorPosition);
}
void QHexEditPrivate::setAddressWidth(int addressWidth)
{
if ((addressWidth >= 0) and (addressWidth<=6))
{
_addressNumbers = addressWidth;
adjust();
setCursorPos(_cursorPosition);
}
}
void QHexEditPrivate::setAsciiArea(bool asciiArea)
{
_asciiArea = asciiArea;
adjust();
}
void QHexEditPrivate::setFont(const QFont &font)
{
QWidget::setFont(font);
adjust();
}
void QHexEditPrivate::setHighlighting(bool mode)
{
_highlighting = mode;
update();
}
void QHexEditPrivate::keyPressEvent(QKeyEvent *event)
{
bool down = false;
int charX = (_cursorX - _xPosHex) / _charWidth;
int posX = (charX / 3) * 2 + (charX % 3);
int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2;
int key = int(event->text()[0].toAscii());
if (!this->_readOnly &&
((key>='0' && key<='9') || (key>='a' && key <= 'f')))
{
// insert char
if (_overwriteMode == false)
if ((charX % 3) == 0)
{
insert(posBa, char(0));
adjust();
}
if (_data.size() > 0)
{
QByteArray hexValue = _data.mid(posBa, 1).toHex();
if ((charX % 3) == 0)
hexValue[0] = key;
else
hexValue[1] = key;
_data.replace(posBa, 1, QByteArray().fromHex(hexValue));
emit dataChanged();
setCursorPos(_cursorPosition + 1);
down = true;
}
}
// delete char
if (!this->_readOnly && event->matches(QKeySequence::Delete)) {
remove(posBa);
}
if (!this->_readOnly && event->key() == Qt::Key_Backspace) {
remove(posBa - 1);
setCursorPos(_cursorPosition - 2);
}
// handle other function keys
if(!this->_readOnly && event->key() == Qt::Key_Insert) {
setOverwriteMode(!_overwriteMode);
setCursorPos(_cursorPosition);
}
if (event->matches(QKeySequence::MoveToNextChar))
{
setCursorPos(_cursorPosition + 1);
down = true;
}
if (event->matches(QKeySequence::MoveToPreviousChar))
setCursorPos(_cursorPosition - 1);
if (event->matches(QKeySequence::MoveToStartOfLine))
setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)));
if (event->matches(QKeySequence::MoveToEndOfLine))
setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE -1));
if (event->matches(QKeySequence::MoveToPreviousLine))
setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE));
if (event->matches(QKeySequence::MoveToPreviousPage))
setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE));
if (event->matches(QKeySequence::MoveToStartOfDocument))
setCursorPos(0);
if (event->matches(QKeySequence::MoveToNextLine))
{
setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE));
down = true;
}
if (event->matches(QKeySequence::MoveToEndOfDocument))
{
setCursorPos(_data.size() * 2);
down = true;
}
if (event->matches(QKeySequence::MoveToNextPage))
{
setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE));
down = true;
}
// when we move downwards, we have to go a little further
if (down)
_scrollArea->ensureVisible(_cursorX, _cursorY, 3, 3 + _charHeight);
else
_scrollArea->ensureVisible(_cursorX, _cursorY, 3, 3);
update();
}
void QHexEditPrivate::mousePressEvent(QMouseEvent *p_event) {
if(p_event->button()==Qt::LeftButton) {
// Init selection origin, start and end point
this->sel_origin=p_event->pos();
this->sel_end=this->sel_start=this->sel_origin;
// Set cursor to current pos
int curs_pos=this->Point2Char(this->sel_start);
if(curs_pos!=-1) setCursorPos(curs_pos);
} else {
QWidget::mousePressEvent(p_event);
}
}
void QHexEditPrivate::mouseMoveEvent(QMouseEvent *p_event) {
if(p_event->buttons()==Qt::LeftButton) {
// Update current selection and repaint hexedit
if(this->Point2Char(p_event->pos())>this->Point2Char(this->sel_origin)) {
this->sel_start=this->sel_origin;
this->sel_end=p_event->pos();
} else {
this->sel_end=this->sel_origin;
this->sel_start=p_event->pos();
}
this->update();
} else {
QWidget::mouseMoveEvent(p_event);
}
}
void QHexEditPrivate::paintEvent(QPaintEvent *event) {
QPainter painter(this);
// Draw some patterns if needed
painter.fillRect(event->rect(), this->palette().color(QPalette::Base));
if(_addressArea) {
painter.fillRect(QRect(_xPosAdr,
event->rect().top(),
_xPosHex-GAP_ADR_HEX+2,
height()),
_addressAreaColor);
}
if(_asciiArea) {
int linePos=_xPosAscii-(GAP_HEX_ASCII / 2);
painter.setPen(Qt::gray);
painter.drawLine(linePos,event->rect().top(),linePos,height());
}
painter.setPen(this->palette().color(QPalette::WindowText));
// Calc positions
int firstLineIdx=
((event->rect().top()/_charHeight)-_charHeight)*BYTES_PER_LINE;
if(firstLineIdx<0) firstLineIdx=0;
int lastLineIdx=
((event->rect().bottom()/_charHeight)+_charHeight)*BYTES_PER_LINE;
if(lastLineIdx>_data.size()) lastLineIdx=_data.size();
int yPosStart=((firstLineIdx)/BYTES_PER_LINE)*_charHeight+_charHeight;
// Paint address area
if(_addressArea) {
for(int lineIdx=firstLineIdx, yPos=yPosStart;
lineIdx<lastLineIdx;
lineIdx+=BYTES_PER_LINE, yPos+=_charHeight)
{
QString address=QString("%1").arg(lineIdx+_addressOffset,
_realAddressNumbers,
16,
QChar('0'));
painter.drawText(_xPosAdr, yPos, address);
}
}
// Prepare values for a selection
int selection_start=0,selection_end=0;
bool selection=false;
if(!(this->sel_start.isNull() && this->sel_end.isNull()) &&
this->sel_start!=this->sel_end)
{
selection_start=this->Point2Char(this->sel_start)/2;
selection_end=this->Point2Char(this->sel_end)/2;
selection=true;
}
// Paint hex area
QByteArray hexBa(_data.mid(firstLineIdx,lastLineIdx-firstLineIdx+1).toHex());
QBrush highLighted=QBrush(_highlightingColor);
painter.setBackground(highLighted);
painter.setBackgroundMode(Qt::TransparentMode);
for(int lineIdx=firstLineIdx, yPos=yPosStart;
lineIdx<lastLineIdx;
lineIdx+=BYTES_PER_LINE, yPos+=_charHeight)
{
QByteArray hex;
int xPos=_xPosHex;
for(int colIdx=0;
((lineIdx+colIdx)<_data.size() && (colIdx<BYTES_PER_LINE));
colIdx++)
{
// Highlight diff bytes
if(_highlighting) {
int posBa=lineIdx+colIdx;
if(posBa>=_originalData.size()) {
painter.setBackgroundMode(Qt::TransparentMode);
} else {
if(_data[posBa]==_originalData[posBa]) {
painter.setBackgroundMode(Qt::TransparentMode);
} else {
painter.setBackgroundMode(Qt::OpaqueMode);
}
}
}
// Highlight selection
if(selection) {
int cur_char=lineIdx+colIdx;
if(cur_char>=selection_start && cur_char<=selection_end) {
painter.setBackgroundMode(Qt::OpaqueMode);
} else {
painter.setBackgroundMode(Qt::TransparentMode);
}
}
// Render hex value
if(colIdx==0) {
hex=hexBa.mid((lineIdx-firstLineIdx)*2,2);
painter.drawText(xPos,yPos,hex);
xPos+=2*_charWidth;
} else {
hex=hexBa.mid((lineIdx+colIdx-firstLineIdx)*2,2).prepend(" ");
painter.drawText(xPos,yPos,hex);
xPos+=3*_charWidth;
}
}
}
// Paint ascii area
if(_asciiArea) {
for(int lineIdx=firstLineIdx, yPos=yPosStart;
lineIdx<lastLineIdx;
lineIdx+=BYTES_PER_LINE, yPos+=_charHeight)
{
QByteArray ascii=_data.mid(lineIdx,BYTES_PER_LINE);
for(int idx=0, xpos=_xPosAscii;
idx<ascii.size();
idx++, xpos+=_charWidth)
{
// Highlight selection
if(selection) {
int cur_char=lineIdx+idx;
if(cur_char>=selection_start && cur_char<=selection_end) {
painter.setBackgroundMode(Qt::OpaqueMode);
} else {
painter.setBackgroundMode(Qt::TransparentMode);
}
}
// Render char
if(((char)ascii[idx]<0x20) || ((char)ascii[idx]>0x7e)) {
painter.drawText(xpos, yPos, QString("."));
} else {
painter.drawText(xpos, yPos, QString(ascii.at(idx)));
}
}
}
}
// Reset painter background if it is still set from highlighting
painter.setBackgroundMode(Qt::TransparentMode);
// Paint cursor
if(_blink && !this->_data.isNull() && !this->_data.isEmpty()) {
if(_overwriteMode) {
painter.fillRect(_cursorX,
_cursorY+_charHeight-2,
_charWidth,
2,
this->palette().color(QPalette::WindowText));
} else {
painter.fillRect(_cursorX,
_cursorY,
2,
_charHeight,
this->palette().color(QPalette::WindowText));
}
}
if(_size!=_data.size()) {
_size=_data.size();
emit currentSizeChanged(_size);
}
}
void QHexEditPrivate::setCursorPos(int position)
{
// delete cursor
_blink=false;
update();
// cursor in range?
if(_overwriteMode) {
if(position>(_data.size()*2-1)) position=_data.size()*2-1;
} else {
if(position>(_data.size()*2)) position=_data.size()*2;
}
if(position < 0) position=0;
// calc position
_cursorPosition=position;
_cursorY=(position/(2*BYTES_PER_LINE))*_charHeight+4;
int x=(position%(2*BYTES_PER_LINE));
_cursorX=(((x/2)*3)+(x%2))*_charWidth+_xPosHex;
// immiadately draw cursor
_blink=true;
update();
emit currentAddressChanged(_cursorPosition/2);
}
void QHexEditPrivate::contextMenuEvent(QContextMenuEvent *p_event) {
// Only show context menu when something is selected
if(!(this->sel_start.isNull() && this->sel_end.isNull()) &&
this->sel_start!=this->sel_end)
{
// Create context menu and add actions
QMenu context_menu(this);
context_menu.addMenu(this->p_menu_copy);
context_menu.exec(p_event->globalPos());
}
}
void QHexEditPrivate::updateCursor()
{
if (_blink)
_blink = false;
else
_blink = true;
update(_cursorX, _cursorY, _charWidth, _charHeight);
}
void QHexEditPrivate::SlotCopySelectedBytes() {
int selection_start=this->Point2Char(this->sel_start)/2;
int selection_count=this->Point2Char(this->sel_end)/2;
selection_count-=(selection_start-1);
QByteArray hex(this->_data.mid(selection_start,selection_count).toHex());
QApplication::clipboard()->setText(hex,QClipboard::Clipboard);
}
void QHexEditPrivate::SlotCopySelectedTextAsAscii() {
int selection_start=this->Point2Char(this->sel_start)/2;
int selection_count=this->Point2Char(this->sel_end)/2;
selection_count-=(selection_start-1);
QByteArray values(this->_data.mid(selection_start,selection_count));
QString ascii="";
int i=0;
for(i=0;i<values.size();i++) {
if(!(((char)values[i]<0x20) || ((char)values[i]>0x7e))) {
ascii.append(values.at(i));
}
}
QApplication::clipboard()->setText(ascii,QClipboard::Clipboard);
}
/*
void QHexEditPrivate::SlotCopySelectedTextAsUtf8() {
// TODO: Implement
}
*/
void QHexEditPrivate::adjust()
{
_charWidth = fontMetrics().width(QLatin1Char('9'));
_charHeight = fontMetrics().height();
// is addressNumbers wide enought?
QString test = QString("%1")
.arg(_data.size() + _addressOffset, _addressNumbers, 16, QChar('0'));
_realAddressNumbers = test.size();
_xPosAdr = 0;
if (_addressArea)
_xPosHex = _realAddressNumbers *_charWidth + GAP_ADR_HEX;
else
_xPosHex = 0;
_xPosAscii = _xPosHex + HEXCHARS_IN_LINE * _charWidth + GAP_HEX_ASCII;
// tell QAbstractScollbar, how big we are
setMinimumHeight(((_data.size()/16 + 1) * _charHeight) + 3);
setMinimumWidth(_xPosAscii + (BYTES_PER_LINE * _charWidth));
update();
}
int QHexEditPrivate::Point2Char(QPoint pos) {
// find char under cursor
if((pos.x()>=_xPosHex) && (pos.x()<(_xPosHex+HEXCHARS_IN_LINE*_charWidth))) {
int x=(pos.x()-_xPosHex)/_charWidth;
if((x%3)==0) x=(x/3)*2;
else x=((x/3)*2)+1;
int y=(pos.y()/_charHeight)*2*BYTES_PER_LINE;
return x+y;
}
return -1;
}
diff --git a/trunk/qhexedit/qhexedit_p.h b/trunk/qhexedit/qhexedit_p.h
index bf880d0..37a5c5c 100644
--- a/trunk/qhexedit/qhexedit_p.h
+++ b/trunk/qhexedit/qhexedit_p.h
@@ -1,125 +1,125 @@
/*******************************************************************************
-* qhexedit Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* qhexedit Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Simple hex editor widget for Qt. *
* *
* Derived from code by Simon Winfried under a compatible license: *
* Copyright (c) 2010 by Simon Winfried *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef QHEXEDIT_P_H
#define QHEXEDIT_P_H
/** \cond docNever */
#include <QtGui>
#include <QPoint>
class QHexEditPrivate : public QWidget {
Q_OBJECT
public:
QHexEditPrivate(QScrollArea *parent);
~QHexEditPrivate();
void setAddressOffset(int offset);
int addressOffset();
void setData(QByteArray const &data);
QByteArray data();
void setAddressAreaColor(QColor const &color);
QColor addressAreaColor();
void setHighlightingColor(QColor const &color);
QColor highlightingColor();
void setOverwriteMode(bool overwriteMode);
bool overwriteMode();
void setReadOnly(bool read_only);
bool readOnly();
void insert(int i, const QByteArray & ba);
void insert(int i, char ch);
void remove(int index, int len=1);
void setAddressArea(bool addressArea);
void setAddressWidth(int addressWidth);
void setAsciiArea(bool asciiArea);
void setHighlighting(bool mode);
virtual void setFont(const QFont &font);
signals:
void currentAddressChanged(int address);
void currentSizeChanged(int size);
void dataChanged();
void overwriteModeChanged(bool state);
protected:
void keyPressEvent(QKeyEvent * event);
void mousePressEvent(QMouseEvent *p_event);
void mouseMoveEvent(QMouseEvent *p_event);
void paintEvent(QPaintEvent *event);
void setCursorPos(int position);
void contextMenuEvent(QContextMenuEvent *p_event);
private slots:
void updateCursor();
void SlotCopySelectedBytes();
void SlotCopySelectedTextAsAscii();
/*
void SlotCopySelectedTextAsUtf8();
*/
private:
void adjust();
int Point2Char(QPoint pos);
QColor _addressAreaColor;
QByteArray _data;
QByteArray _originalData;
QColor _highlightingColor;
QScrollArea *_scrollArea;
QTimer _cursorTimer;
QPoint sel_origin;
QPoint sel_start;
QPoint sel_end;
QMenu *p_menu_copy;
QAction *p_action_copy_selected_bytes;
QAction *p_action_copy_selected_text_ascii;
/*
QAction *p_action_copy_selected_text_utf8;
*/
bool _blink;
bool _addressArea;
bool _asciiArea;
bool _highlighting;
bool _overwriteMode;
bool _readOnly;
int _addressNumbers, _realAddressNumbers;
int _addressOffset;
int _charWidth, _charHeight;
int _cursorX, _cursorY, _cursorPosition;
int _xPosAdr, _xPosHex, _xPosAscii;
int _size;
};
/** \endcond docNever */
#endif
diff --git a/trunk/qtscript_types/bytearray.cpp b/trunk/qtscript_types/bytearray.cpp
index b3a14f7..0eed658 100644
--- a/trunk/qtscript_types/bytearray.cpp
+++ b/trunk/qtscript_types/bytearray.cpp
@@ -1,181 +1,181 @@
/*******************************************************************************
-* Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
* compatible license: *
* *
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
* All rights reserved. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <QtScript/QScriptEngine>
#include "bytearray.h"
#include "bytearrayiterator.h"
#include "bytearrayprototype.h"
#include <stdlib.h>
Q_DECLARE_METATYPE(QByteArray*)
Q_DECLARE_METATYPE(ByteArray*)
ByteArray::ByteArray(QScriptEngine *engine)
: QObject(engine), QScriptClass(engine)
{
qScriptRegisterMetaType<QByteArray>(engine,
this->toScriptValue,
this->fromScriptValue);
this->length=engine->toStringHandle(QLatin1String("length"));
this->proto=engine->newQObject(new ByteArrayPrototype(this),
QScriptEngine::QtOwnership,
QScriptEngine::SkipMethodsInEnumeration |
QScriptEngine::ExcludeSuperClassMethods |
QScriptEngine::ExcludeSuperClassProperties);
QScriptValue global=engine->globalObject();
proto.setPrototype(global.property("Object").property("prototype"));
this->ctor=engine->newFunction(this->construct,this->proto);
this->ctor.setData(qScriptValueFromValue(engine,this));
}
ByteArray::~ByteArray() {}
QScriptClass::QueryFlags ByteArray::queryProperty(const QScriptValue &object,
const QScriptString &name,
QueryFlags flags,
uint *id)
{
QByteArray *ba=qscriptvalue_cast<QByteArray*>(object.data());
if(!ba) return 0;
if(name!=this->length) {
bool is_array_index;
qint32 pos=name.toArrayIndex(&is_array_index);
if(!is_array_index) return 0;
*id=pos;
if((flags & HandlesReadAccess) && (pos>=ba->size()))
flags &= ~HandlesReadAccess;
}
return flags;
}
QScriptValue ByteArray::property(const QScriptValue &object,
const QScriptString &name,
uint id)
{
QByteArray *ba=qscriptvalue_cast<QByteArray*>(object.data());
if(!ba) return QScriptValue();
if(name==length) return ba->length();
else {
qint32 pos=id;
if((pos < 0) || (pos >= ba->size())) return QScriptValue();
return uint(ba->at(pos)) & 255;
}
return QScriptValue();
}
void ByteArray::setProperty(QScriptValue &object,
const QScriptString &name,
uint id,
const QScriptValue &value)
{
QByteArray *ba=qscriptvalue_cast<QByteArray*>(object.data());
if(!ba) return;
if(name==length) this->resize(*ba,value.toInt32());
else {
qint32 pos=id;
if(pos<0) return;
if(ba->size()<=pos) this->resize(*ba,pos + 1);
(*ba)[pos]=char(value.toInt32());
}
}
QScriptValue::PropertyFlags ByteArray::propertyFlags(const QScriptValue &object,
const QScriptString &name,
uint id)
{
Q_UNUSED(object);
Q_UNUSED(id);
if(name==length) {
return QScriptValue::Undeletable | QScriptValue::SkipInEnumeration;
}
return QScriptValue::Undeletable;
}
QScriptClassPropertyIterator *ByteArray::newIterator(const QScriptValue &object)
{
return new ByteArrayIterator(object);
}
QString ByteArray::name() const {
return QLatin1String("ByteArray");
}
QScriptValue ByteArray::prototype() const {
return proto;
}
QScriptValue ByteArray::constructor() {
return ctor;
}
QScriptValue ByteArray::newInstance(int size) {
#if QT_VERSION >= 0x040700
this->engine()->reportAdditionalMemoryCost(size);
#endif
return newInstance(QByteArray(size,0));
}
QScriptValue ByteArray::newInstance(const QByteArray &ba) {
QScriptValue data=engine()->newVariant(qVariantFromValue(ba));
return engine()->newObject(this,data);
}
QScriptValue ByteArray::construct(QScriptContext *ctx, QScriptEngine *) {
ByteArray *cls=qscriptvalue_cast<ByteArray*>(ctx->callee().data());
if(!cls) return QScriptValue();
QScriptValue arg=ctx->argument(0);
if(arg.instanceOf(ctx->callee()))
return cls->newInstance(qscriptvalue_cast<QByteArray>(arg));
int size=arg.toInt32();
return cls->newInstance(size);
}
QScriptValue ByteArray::toScriptValue(QScriptEngine *eng, const QByteArray &ba)
{
QScriptValue ctor=eng->globalObject().property("ByteArray");
ByteArray *cls=qscriptvalue_cast<ByteArray*>(ctor.data());
if(!cls) return eng->newVariant(qVariantFromValue(ba));
return cls->newInstance(ba);
}
void ByteArray::fromScriptValue(const QScriptValue &obj, QByteArray &ba) {
ba=qvariant_cast<QByteArray>(obj.data().toVariant());
}
void ByteArray::resize(QByteArray &ba, int newSize) {
int oldSize=ba.size();
ba.resize(newSize);
#if QT_VERSION >= 0x040700
if(newSize>oldSize)
this->engine()->reportAdditionalMemoryCost(newSize-oldSize);
#endif
}
diff --git a/trunk/qtscript_types/bytearray.h b/trunk/qtscript_types/bytearray.h
index b367a9f..7de44f6 100644
--- a/trunk/qtscript_types/bytearray.h
+++ b/trunk/qtscript_types/bytearray.h
@@ -1,76 +1,76 @@
/*******************************************************************************
-* Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
* compatible license: *
* *
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
* All rights reserved. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
// Description: http://cs.karelia.ru/~aborod/doc/qt/script-customclass.html
#ifndef BYTEARRAY_H
#define BYTEARRAY_H
#include <QObject>
#include <QtScript/QScriptClass>
#include <QtScript/QScriptString>
class ByteArray : public QObject, public QScriptClass {
public:
ByteArray(QScriptEngine *engine);
~ByteArray();
QScriptValue constructor();
QScriptValue newInstance(int size = 0);
QScriptValue newInstance(const QByteArray &ba);
QueryFlags queryProperty(const QScriptValue &object,
const QScriptString &name,
QueryFlags flags,
uint *id);
QScriptValue property(const QScriptValue &object,
const QScriptString &name,
uint id);
void setProperty(QScriptValue &object,
const QScriptString &name,
uint id,
const QScriptValue &value);
QScriptValue::PropertyFlags propertyFlags(const QScriptValue &object,
const QScriptString &name,
uint id);
QScriptClassPropertyIterator *newIterator(const QScriptValue &object);
QString name() const;
QScriptValue prototype() const;
private:
static QScriptValue construct(QScriptContext *ctx, QScriptEngine *eng);
static QScriptValue toScriptValue(QScriptEngine *eng, const QByteArray &ba);
static void fromScriptValue(const QScriptValue &obj, QByteArray &ba);
void resize(QByteArray &ba, int newSize);
QScriptString length;
QScriptValue proto;
QScriptValue ctor;
};
#endif // BYTEARRAY_H
diff --git a/trunk/qtscript_types/bytearrayiterator.cpp b/trunk/qtscript_types/bytearrayiterator.cpp
index 3975a49..c499d2b 100644
--- a/trunk/qtscript_types/bytearrayiterator.cpp
+++ b/trunk/qtscript_types/bytearrayiterator.cpp
@@ -1,74 +1,74 @@
/*******************************************************************************
-* Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
* compatible license: *
* *
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
* All rights reserved. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "bytearrayiterator.h"
#include <QtScript/QScriptEngine>
Q_DECLARE_METATYPE(QByteArray*)
ByteArrayIterator::ByteArrayIterator(const QScriptValue &object)
: QScriptClassPropertyIterator(object)
{
toFront();
}
ByteArrayIterator::~ByteArrayIterator() {}
bool ByteArrayIterator::hasNext() const {
QByteArray *ba=qscriptvalue_cast<QByteArray*>(object().data());
return m_index<ba->size();
}
void ByteArrayIterator::next() {
m_last=m_index;
++m_index;
}
bool ByteArrayIterator::hasPrevious() const {
return(m_index>0);
}
void ByteArrayIterator::previous() {
--m_index;
m_last=m_index;
}
void ByteArrayIterator::toFront() {
m_index=0;
m_last=-1;
}
void ByteArrayIterator::toBack() {
QByteArray *ba=qscriptvalue_cast<QByteArray*>(object().data());
m_index=ba->size();
m_last=-1;
}
QScriptString ByteArrayIterator::name() const {
return this->object().engine()->toStringHandle(QString::number(this->m_last));
}
uint ByteArrayIterator::id() const {
return m_last;
}
diff --git a/trunk/qtscript_types/bytearrayiterator.h b/trunk/qtscript_types/bytearrayiterator.h
index 34637cd..088489b 100644
--- a/trunk/qtscript_types/bytearrayiterator.h
+++ b/trunk/qtscript_types/bytearrayiterator.h
@@ -1,51 +1,51 @@
/*******************************************************************************
-* Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
* compatible license: *
* *
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
* All rights reserved. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef BYTEARRAYITERATOR_H
#define BYTEARRAYITERATOR_H
#include <QtScript/QScriptClassPropertyIterator>
class ByteArrayIterator : public QScriptClassPropertyIterator {
public:
ByteArrayIterator(const QScriptValue &object);
~ByteArrayIterator();
bool hasNext() const;
void next();
bool hasPrevious() const;
void previous();
void toFront();
void toBack();
QScriptString name() const;
uint id() const;
private:
int m_index;
int m_last;
};
#endif // BYTEARRAYITERATOR_H
diff --git a/trunk/qtscript_types/bytearrayprototype.cpp b/trunk/qtscript_types/bytearrayprototype.cpp
index 32b2118..4308f87 100644
--- a/trunk/qtscript_types/bytearrayprototype.cpp
+++ b/trunk/qtscript_types/bytearrayprototype.cpp
@@ -1,98 +1,98 @@
/*******************************************************************************
-* Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
* compatible license: *
* *
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
* All rights reserved. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "bytearrayprototype.h"
#include <QtScript/QScriptEngine>
Q_DECLARE_METATYPE(QByteArray*)
ByteArrayPrototype::ByteArrayPrototype(QObject *p_parent) : QObject(p_parent) {}
ByteArrayPrototype::~ByteArrayPrototype() {}
QByteArray *ByteArrayPrototype::thisByteArray() const {
return qscriptvalue_cast<QByteArray*>(thisObject().data());
}
void ByteArrayPrototype::chop(int n) {
thisByteArray()->chop(n);
}
bool ByteArrayPrototype::equals(const QByteArray &other) {
return *thisByteArray()==other;
}
QByteArray ByteArrayPrototype::left(int len) const {
return thisByteArray()->left(len);
}
QByteArray ByteArrayPrototype::mid(int pos, int len) const {
return thisByteArray()->mid(pos,len);
}
QScriptValue ByteArrayPrototype::remove(int pos, int len) {
thisByteArray()->remove(pos,len);
return thisObject();
}
QScriptValue ByteArrayPrototype::appendByte(char byte) const {
thisByteArray()->append(byte);
return thisObject();
}
QByteArray ByteArrayPrototype::right(int len) const {
return thisByteArray()->right(len);
}
QByteArray ByteArrayPrototype::simplified() const {
return thisByteArray()->simplified();
}
QByteArray ByteArrayPrototype::toBase64() const {
return thisByteArray()->toBase64();
}
QByteArray ByteArrayPrototype::toLower() const {
return thisByteArray()->toLower();
}
QByteArray ByteArrayPrototype::toUpper() const {
return thisByteArray()->toUpper();
}
QByteArray ByteArrayPrototype::trimmed() const {
return thisByteArray()->trimmed();
}
void ByteArrayPrototype::truncate(int pos) {
thisByteArray()->truncate(pos);
}
QString ByteArrayPrototype::toLatin1String() const {
return QString::fromLatin1(*thisByteArray());
}
QScriptValue ByteArrayPrototype::valueOf() const {
return thisObject().data();
}
diff --git a/trunk/qtscript_types/bytearrayprototype.h b/trunk/qtscript_types/bytearrayprototype.h
index 2153181..a7c6e84 100644
--- a/trunk/qtscript_types/bytearrayprototype.h
+++ b/trunk/qtscript_types/bytearrayprototype.h
@@ -1,61 +1,61 @@
/*******************************************************************************
-* Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
* compatible license: *
* *
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
* All rights reserved. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef BYTEARRAYPROTOTYPE_H
#define BYTEARRAYPROTOTYPE_H
#include <QByteArray>
#include <QObject>
#include <QtScript/QScriptable>
#include <QtScript/QScriptValue>
class ByteArrayPrototype : public QObject, public QScriptable {
Q_OBJECT
public:
ByteArrayPrototype(QObject *p_parent=0);
~ByteArrayPrototype();
public slots:
void chop(int n);
bool equals(const QByteArray &other);
QByteArray left(int len) const;
QByteArray mid(int pos, int len = -1) const;
QScriptValue remove(int pos, int len);
QScriptValue appendByte(char byte) const;
QByteArray right(int len) const;
QByteArray simplified() const;
QByteArray toBase64() const;
QByteArray toLower() const;
QByteArray toUpper() const;
QByteArray trimmed() const;
void truncate(int pos);
QString toLatin1String() const;
QScriptValue valueOf() const;
private:
QByteArray *thisByteArray() const;
};
#endif // BYTEARRAYPROTOTYPE_H
diff --git a/trunk/registryhive.cpp b/trunk/registryhive.cpp
index c92e269..e45334f 100644
--- a/trunk/registryhive.cpp
+++ b/trunk/registryhive.cpp
@@ -1,638 +1,638 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registryhive.h"
#include <QStringList>
#include <QDateTime>
#include <stdlib.h>
#include <stdio.h>
// TODO: __WORDSIZE is not defined under mingw and I currently have no idea how
// to identify a 64bit windows
#ifndef __WORDSIZE
#define __WORDSIZE 32
#endif
#if __WORDSIZE == 64
#define EPOCH_DIFF 0x19DB1DED53E8000
#else
#define EPOCH_DIFF 0x19DB1DED53E8000LL
#endif
/*
* RegistryHive
*/
RegistryHive::RegistryHive(QObject *p_parent) : QObject(p_parent) {
this->erro_msg="";
this->is_error=false;
this->hive_file="";
this->p_hive=NULL;
this->is_hive_open=false;
}
/*
* ~RegistryHive
*/
RegistryHive::~RegistryHive() {
if(this->is_hive_open) this->Close();
}
/*
* Error
*/
bool RegistryHive::Error() {
return this->is_error;
}
/*
* GetErrorMsg
*/
QString RegistryHive::GetErrorMsg() {
QString msg=this->erro_msg;
this->erro_msg="";
this->is_error=false;
return msg;
}
/*
* Open
*/
bool RegistryHive::Open(QString file, bool read_only) {
if(this->is_hive_open) return false;
// Open hive file
this->p_hive=hivex_open(file.toAscii().constData(),
read_only ? 0 : HIVEX_OPEN_WRITE);
if(this->p_hive==NULL) return false;
// Set local vars
this->hive_file=file;
this->is_hive_open=true;
return true;
}
/*
* Close
*/
bool RegistryHive::Close(bool commit_changes) {
if(this->is_hive_open) {
if(commit_changes) {
// Commit changes before closing hive.
// TODO: Maybe it would be more secure to commit changes to a new file and
// then move it over the original one.
hivex_commit(this->p_hive,NULL,0);
}
// As hivex_close will _ALWAYS_ free the handle, we don't need the following
// values anymore
this->hive_file="";
this->is_hive_open=false;
// Close hive
if(hivex_close(this->p_hive)!=0) return false;
}
return true;
}
QString RegistryHive::Filename() {
if(this->is_hive_open) return this->hive_file;
return QString();
}
/*
* GetNodes
*/
QMap<QString,int> RegistryHive::GetNodes(QString path) {
hive_node_h parent_node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QMap<QString,int>();
// Get and return nodes
return this->GetNodesHelper(parent_node);
}
/*
* GetNodes
*/
QMap<QString,int> RegistryHive::GetNodes(int parent_node) {
if(parent_node==0) {
this->SetError(tr("Invalid parent node handle specified!"));
return QMap<QString,int>();
}
// Get and return nodes
return this->GetNodesHelper(parent_node);
}
/*
* GetKeys
*/
QMap<QString,int> RegistryHive::GetKeys(QString path) {
hive_node_h parent_node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QMap<QString,int>();
// Get and return keys
return this->GetKeysHelper(parent_node);
}
/*
* GetKeys
*/
QMap<QString,int> RegistryHive::GetKeys(int parent_node) {
if(parent_node==0) {
this->SetError(tr("Invalid parent node handle specified!"));
return QMap<QString,int>();
}
// Get and return keys
return this->GetKeysHelper(parent_node);
}
/*
* GetKeyValue
*/
QByteArray RegistryHive::GetKeyValue(QString path,
QString key,
int *p_value_type,
size_t *p_value_len)
{
hive_node_h parent_node;
hive_value_h hive_key;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QByteArray();
// Get key handle
hive_key=hivex_node_get_value(this->p_hive,
parent_node,key.toAscii().constData());
if(hive_key==0) {
this->SetError(tr("Unable to get key handle!"));
*p_value_len=-1;
return QByteArray();
}
// Get and return key value
return this->GetKeyValueHelper(hive_key,p_value_type,p_value_len);
}
/*
* GetKeyValue
*/
QByteArray RegistryHive::GetKeyValue(int hive_key,
int *p_value_type,
size_t *p_value_len)
{
if(hive_key==0) {
this->SetError(tr("Invalid key handle specified!"));
*p_value_type=-1;
return QByteArray();
}
// Get and return key value
return this->GetKeyValueHelper(hive_key,p_value_type,p_value_len);
}
/*
* GetKeyModTime
*/
int64_t RegistryHive::GetKeyModTime(QString path,QString key) {
hive_node_h parent_node;
hive_value_h hive_key;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) {
this->SetError(tr("Unable to get node handle!"));
return 0;
}
// Get key handle
hive_key=hivex_node_get_value(this->p_hive,
parent_node,
key.toAscii().constData());
if(hive_key==0) {
this->SetError(tr("Unable to get key handle!"));
return 0;
}
// Get and return key's last modification timestamp
return this->GetKeyModTime(hive_key);
}
/*
* GetKeyModTime
*/
int64_t RegistryHive::GetKeyModTime(int hive_key) {
if(hive_key==0) {
this->SetError(tr("Invalid key handle specified!"));
return 0;
}
// Get and return key's last modification timestamp
return hivex_node_timestamp(this->p_hive,hive_key);
}
/*
* KeyValueToString
*/
QString RegistryHive::KeyValueToString(QByteArray value, int value_type) {
QString ret="";
int i=0;
#define ToHexStr() { \
for(i=0;i<value.size();i++) { \
ret.append(QString().sprintf("%02X ",(uint8_t)(value.constData()[i]))); \
} \
ret.chop(1); \
}
switch(value_type) {
case hive_t_REG_NONE:
// Just a key without a value, but to be certain...
ToHexStr();
break;
case hive_t_REG_SZ:
// A Windows string (encoding is unknown, but often UTF16-LE)
// TODO: What happens if encoding is not UTF16-LE ??? Thx Billy!!!
ret=value.size() ? QString().fromUtf16((ushort*)(value.constData())) : "";
break;
case hive_t_REG_EXPAND_SZ:
// A Windows string that contains %env% (environment variable expansion)
ret=value.size() ? QString().fromUtf16((ushort*)(value.constData())) : "";
break;
case hive_t_REG_BINARY:
// A blob of binary
ToHexStr();
break;
case hive_t_REG_DWORD:
// DWORD (32 bit integer), little endian
ret=QString().sprintf("0x%08X",*(uint32_t*)value.constData());
break;
case hive_t_REG_DWORD_BIG_ENDIAN:
// DWORD (32 bit integer), big endian
ret=QString().sprintf("0x%08X",*(uint32_t*)value.constData());
break;
case hive_t_REG_LINK:
// Symbolic link to another part of the registry tree
ToHexStr();
break;
case hive_t_REG_MULTI_SZ:
// Multiple Windows strings.
// See http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx
ToHexStr();
break;
case hive_t_REG_RESOURCE_LIST:
// Resource list
ToHexStr();
break;
case hive_t_REG_FULL_RESOURCE_DESCRIPTOR:
// Resource descriptor
ToHexStr();
break;
case hive_t_REG_RESOURCE_REQUIREMENTS_LIST:
// Resouce requirements list
ToHexStr();
break;
case hive_t_REG_QWORD:
// QWORD (64 bit integer). Usually little endian.
ret=
QString("0x%1").arg((quint64)(*(uint64_t*)value.constData()),16,16,QChar('0'));
break;
default:
ToHexStr();
}
#undef ToHexStr
return ret;
}
/*
* KeyValueToString
*/
QString RegistryHive::KeyValueToString(QByteArray key_value,
QString format,
int offset,
int length,
bool little_endian)
{
int remaining_data_len;
const char *p_data;
QString ret="";
// Calculate how many bytes are remainig after specified offset
remaining_data_len=key_value.size()-offset;
if(!remaining_data_len>0) {
// Nothing to show
return QString();
}
// Get pointer to data at specified offset
p_data=key_value.constData();
p_data+=offset;
// TODO: This will fail on platforms with different endianness!
#define bswap_16(value) ((((value) & 0xff) << 8) | ((value) >> 8))
#define bswap_32(value) \
(((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
(uint32_t)bswap_16((uint16_t)((value) >> 16)))
#define bswap_64(value) \
(((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) << 32) | \
(uint64_t)bswap_32((uint32_t)((value) >> 32))) \
// ConvertFull name
if(format=="int8" && remaining_data_len>=1) {
ret=QString().sprintf("%d",*(int8_t*)p_data);
} else if(format=="uint8" && remaining_data_len>=1) {
ret=QString().sprintf("%u",*(uint8_t*)p_data);
} else if(format=="int16" && remaining_data_len>=2) {
int16_t val=*(int16_t*)p_data;
if(little_endian) ret=QString().sprintf("%d",val);
else ret=QString().sprintf("%d",bswap_16(val));
} else if(format=="uint16" && remaining_data_len>=2) {
uint16_t val=*(uint16_t*)p_data;
if(little_endian) ret=QString().sprintf("%u",val);
else ret=QString().sprintf("%u",bswap_16(val));
} else if(format=="int32" && remaining_data_len>=4) {
int32_t val=*(int32_t*)p_data;
if(little_endian) ret=QString().sprintf("%d",val);
else ret=QString().sprintf("%d",bswap_32(val));
} else if(format=="uint32" && remaining_data_len>=4) {
uint32_t val=*(uint32_t*)p_data;
if(little_endian) ret=QString().sprintf("%u",val);
else ret=QString().sprintf("%u",bswap_32(val));
} else if(format=="unixtime" && remaining_data_len>=4) {
uint32_t val=*(uint32_t*)p_data;
if(!little_endian) val=bswap_32(val);
if(val==0) {
ret="n/a";
} else {
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(val);
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
} else if(format=="int64" && remaining_data_len>=8) {
int64_t val=*(int64_t*)p_data;
if(little_endian) ret=QString("%1").arg(val);
else ret=QString("%1").arg((int64_t)bswap_64(val));
} else if(format=="uint64" && remaining_data_len>=8) {
uint64_t val=*(uint64_t*)p_data;
if(little_endian) ret=QString("%1").arg(val);
else ret=QString("%1").arg(bswap_64(val));
/*
// TODO: Check how one could implement this
} else if(format=="unixtime64" && remaining_data_len>=8) {
if(*(uint64_t*)p_data==0) {
ret="n/a";
} else {
uint64_t secs=*(uint64_t*)p_data;
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
// Set 32bit part of date/time
date_time.setTime_t(secs&0xFFFFFFFF);
// Now add high 32bit part of date/time
date_time.addSecs(secs>>32);
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
*/
} else if(format=="filetime" && remaining_data_len>=8) {
uint64_t val=*(uint64_t*)p_data;
if(!little_endian) val=bswap_64(val);
if(val==0) {
ret="n/a";
} else {
// TODO: Warn if >32bit
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(RegistryHive::FiletimeToUnixtime(val));
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
} else if(format=="ascii") {
// TODO: This fails bad if the string is not null terminated!! It might be
// wise checking for a null char here
ret=QString().fromAscii((char*)p_data,length);
} else if(format=="utf16" && remaining_data_len>=2) {
ret=QString().fromUtf16((ushort*)p_data,length);
} else {
// Unknown variant type or another error
return QString();
}
return ret;
}
/*
* KeyTypeToString
*/
QString RegistryHive::KeyTypeToString(int value_type) {
QString ret="";
switch(value_type) {
case hive_t_REG_NONE:
ret="REG_NONE";
break;
case hive_t_REG_SZ:
ret="REG_SZ";
break;
case hive_t_REG_EXPAND_SZ:
ret="REG_EXPAND_SZ";
break;
case hive_t_REG_BINARY:
ret="REG_BINARY";
break;
case hive_t_REG_DWORD:
ret="REG_DWORD";
break;
case hive_t_REG_DWORD_BIG_ENDIAN:
ret="REG_DWORD_BIG_ENDIAN";
break;
case hive_t_REG_LINK:
ret="REG_LINK";
break;
case hive_t_REG_MULTI_SZ:
ret="REG_MULTI_SZ";
break;
case hive_t_REG_RESOURCE_LIST:
ret="REG_RESOURCE_LIST";
break;
case hive_t_REG_FULL_RESOURCE_DESCRIPTOR:
ret="REG_FULL_RESOURCE_DESC";
break;
case hive_t_REG_RESOURCE_REQUIREMENTS_LIST:
ret="REG_RESOURCE_REQ_LIST";
break;
case hive_t_REG_QWORD:
ret="REG_QWORD";
break;
default:
ret=QString().sprintf("0x%08X",(uint32_t)value_type);
}
return ret;
}
/*
* FiletimeToUnixtime
*/
uint64_t RegistryHive::FiletimeToUnixtime(int64_t filetime) {
return (unsigned)((filetime-EPOCH_DIFF)/10000000);
}
/*
* SetError
*/
void RegistryHive::SetError(QString msg) {
this->erro_msg=msg;
this->is_error=true;
}
/*
* GetNodeHandle
*/
bool RegistryHive::GetNodeHandle(QString &path, hive_node_h *p_node) {
QStringList nodes;
int i=0;
// Get root node handle
*p_node=hivex_root(this->p_hive);
if(*p_node==0) {
this->SetError(tr("Unable to get root node!"));
return false;
}
if(path!="\\") {
// If we aren't listing the root node, we have to get a handle to the
// last node in the path. Split path into nodes
nodes=path.split('\\',QString::SkipEmptyParts);
// Iterate to the correct parent node
for(i=0;i<nodes.count();i++) {
// printf("Spotting node '%s'\n",nodes.value(i).toAscii().constData());
*p_node=hivex_node_get_child(this->p_hive,
*p_node,
nodes.value(i).toAscii().constData());
if(*p_node==0) {
this->SetError(tr("Unable to find node '%1'!").arg(nodes.value(i)));
return false;
}
}
}
return true;
}
/*
* GetNodesHelper
*/
QMap<QString,int> RegistryHive::GetNodesHelper(hive_node_h parent_node) {
QMap<QString,int> keys;
char *p_name;
int i=0;
// Get child nodes
hive_node_h *child_nodes=hivex_node_children(this->p_hive,parent_node);
if(child_nodes==NULL) {
this->SetError(
tr("Unable to enumerate child nodes!"));
return QMap<QString,int>();
}
// Build result
keys.clear();
i=0;
while(child_nodes[i]) {
p_name=hivex_node_name(this->p_hive,child_nodes[i]);
if(p_name==NULL) {
this->SetError(tr("Unable to get node name!"));
free(child_nodes);
return QMap<QString,int>();
}
keys.insert(QString(p_name),(int)child_nodes[i]);
free(p_name);
i++;
}
free(child_nodes);
return keys;
}
/*
* GetKeysHelper
*/
QMap<QString,int> RegistryHive::GetKeysHelper(hive_node_h parent_node) {
QMap<QString,int> keys;
char *p_name;
int i=0;
// Get child keys
hive_value_h *p_keys=hivex_node_values(this->p_hive,parent_node);
if(p_keys==NULL) {
this->SetError(
tr("Unable to enumerate child keys!"));
return QMap<QString,int>();
}
// Build result list
keys.clear();
i=0;
while(p_keys[i]) {
p_name=hivex_value_key(this->p_hive,p_keys[i]);
if(p_name==NULL) {
this->SetError(tr("Unable to get key name!"));
return QMap<QString,int>();
}
keys.insert(QString(p_name),p_keys[i]);
free(p_name);
i++;
}
free(p_keys);
return keys;
}
QByteArray RegistryHive::GetKeyValueHelper(hive_value_h hive_key,
int *p_value_type,
size_t *p_value_len)
{
QByteArray key_value;
char *p_key_value;
p_key_value=hivex_value_value(this->p_hive,
hive_key,
(hive_type*)p_value_type,
p_value_len);
if(p_key_value==NULL) {
this->SetError(tr("Unable to get key value!"));
*p_value_type=-1;
return QByteArray();
}
// Feed QByteArray and free p_key_value
key_value=QByteArray(p_key_value,*p_value_len);
free(p_key_value);
return key_value;
}
diff --git a/trunk/registryhive.h b/trunk/registryhive.h
index 2c47709..5a8d88a 100644
--- a/trunk/registryhive.h
+++ b/trunk/registryhive.h
@@ -1,83 +1,83 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYHIVE_H
#define REGISTRYHIVE_H
#include <QObject>
#include <QMap>
#include <hivex.h>
class RegistryHive : public QObject {
Q_OBJECT
public:
explicit RegistryHive(QObject *p_parent=0);
~RegistryHive();
bool Error();
QString GetErrorMsg();
bool Open(QString file, bool read_only=true);
bool Close(bool commit_changes=false);
QString Filename();
QMap<QString,int> GetNodes(QString path="\\");
QMap<QString,int> GetNodes(int parent_node=0);
QMap<QString,int> GetKeys(QString path="\\");
QMap<QString,int> GetKeys(int parent_node=0);
QByteArray GetKeyValue(QString path,
QString key,
int *p_value_type,
size_t *p_value_len);
QByteArray GetKeyValue(int hive_key,
int *p_value_type,
size_t *p_value_len);
int64_t GetKeyModTime(QString path,QString key);
int64_t GetKeyModTime(int hive_key);
static QString KeyValueToString(QByteArray value, int value_type);
static QString KeyValueToString(QByteArray value,
QString format,
int offset=0,
int length=0,
bool little_endian=true);
static QString KeyTypeToString(int value_type);
static uint64_t FiletimeToUnixtime(int64_t filetime);
private:
QString erro_msg;
bool is_error;
QString hive_file;
hive_h *p_hive;
bool is_hive_open;
void SetError(QString msg);
bool GetNodeHandle(QString &path, hive_node_h *p_node);
QMap<QString,int> GetNodesHelper(hive_node_h parent_node);
QMap<QString,int> GetKeysHelper(hive_node_h parent_node);
QByteArray GetKeyValueHelper(hive_value_h hive_key,
int *p_value_type,
size_t *p_value_len);
};
#endif // REGISTRYHIVE_H
diff --git a/trunk/registrykey.cpp b/trunk/registrykey.cpp
index 8630e36..709d3e7 100644
--- a/trunk/registrykey.cpp
+++ b/trunk/registrykey.cpp
@@ -1,54 +1,54 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrykey.h"
RegistryKey::RegistryKey(const QList<QVariant> &data) {
this->key_data=data;
}
RegistryKey::~RegistryKey() {
qDeleteAll(this->keys);
}
void RegistryKey::Append(RegistryKey *p_key) {
this->keys.append(p_key);
}
RegistryKey* RegistryKey::Key(uint64_t row) {
return this->keys.value(row);
}
uint64_t RegistryKey::RowCount() {
return this->keys.count();
}
QVariant RegistryKey::Data(uint64_t column) const {
if(column>=0 && column<4) {
return this->key_data.value(column);
} else {
return QVariant();
}
}
uint64_t RegistryKey::Row() const {
return this->keys.indexOf(const_cast<RegistryKey*>(this));
}
diff --git a/trunk/registrykey.h b/trunk/registrykey.h
index 1ae14aa..6a9cbf4 100644
--- a/trunk/registrykey.h
+++ b/trunk/registrykey.h
@@ -1,44 +1,44 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYKEY_H
#define REGISTRYKEY_H
#include <QList>
#include <QVariant>
#include <inttypes.h>
class RegistryKey {
public:
RegistryKey(const QList<QVariant> &data);
~RegistryKey();
void Append(RegistryKey *p_key);
RegistryKey *Key(uint64_t row);
uint64_t RowCount();
QVariant Data(uint64_t column) const;
uint64_t Row() const;
private:
QList<RegistryKey*> keys;
QList<QVariant> key_data;
};
#endif // REGISTRYKEY_H
diff --git a/trunk/registrykeytable.cpp b/trunk/registrykeytable.cpp
index a488c3b..d028496 100644
--- a/trunk/registrykeytable.cpp
+++ b/trunk/registrykeytable.cpp
@@ -1,146 +1,146 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrykeytable.h"
#include <QHeaderView>
#include <QApplication>
#include <QClipboard>
RegistryKeyTable::RegistryKeyTable(QWidget *p_parent) : QTableView(p_parent) {
// Configure widget
this->setSelectionMode(QAbstractItemView::SingleSelection);
this->setSelectionBehavior(QAbstractItemView::SelectRows);
this->setAutoScroll(false);
this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
this->verticalHeader()->setHidden(true);
this->setTextElideMode(Qt::ElideNone);
// Create context menu
this->p_menu_copy=new QMenu(tr("Copy"),this);
this->p_action_copy_key_name=new QAction(tr("Key name"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_key_name);
this->connect(this->p_action_copy_key_name,
SIGNAL(triggered()),
this,
SLOT(SlotCopyKeyName()));
this->p_action_copy_key_value=new QAction(tr("Key value"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_key_value);
this->connect(this->p_action_copy_key_value,
SIGNAL(triggered()),
this,
SLOT(SlotCopyKeyValue()));
}
RegistryKeyTable::~RegistryKeyTable() {
// Delete context menu
delete this->p_action_copy_key_name;
delete this->p_action_copy_key_value;
delete this->p_menu_copy;
}
void RegistryKeyTable::setModel(QAbstractItemModel *p_model) {
QTableView::setModel(p_model);
// Resize table rows / columns to fit data
this->resizeColumnsToContents();
this->resizeRowsToContents();
this->horizontalHeader()->stretchLastSection();
if(p_model!=NULL && p_model->rowCount()>0) {
// Select first table item
this->selectRow(0);
}
}
/*
void RegistryKeyTable::selectRow(QString key_name) {
int i;
this->clearSelection();
for(i=0;i<this->model()->rowCount();i++) {
if(this->model())
}
}
*/
int RegistryKeyTable::sizeHintForColumn(int column) const {
int size_hint=-1;
int i=0;
int item_width=0;
QFontMetrics fm(this->fontMetrics());
QModelIndex idx;
if(this->model()==NULL) return -1;
// Find string that needs the most amount of space
idx=this->model()->index(i,column);
while(idx.isValid()) {
item_width=fm.width(this->model()->data(idx).toString())+10;
if(item_width>size_hint) size_hint=item_width;
idx=this->model()->index(++i,column);
}
return size_hint;
}
void RegistryKeyTable::contextMenuEvent(QContextMenuEvent *p_event) {
// Only show context menu when a row is selected
if(this->selectedIndexes().count()!=4) return;
// Only show context menu when user clicked on selected row
if(!(this->indexAt(p_event->pos())==this->selectedIndexes().at(0) ||
this->indexAt(p_event->pos())==this->selectedIndexes().at(1) ||
this->indexAt(p_event->pos())==this->selectedIndexes().at(2) ||
this->indexAt(p_event->pos())==this->selectedIndexes().at(3)))
{
return;
}
// Emit a click signal
emit(this->clicked(this->indexAt(p_event->pos())));
// Create context menu and add actions
QMenu context_menu(this);
context_menu.addMenu(this->p_menu_copy);
context_menu.exec(p_event->globalPos());
}
void RegistryKeyTable::currentChanged(const QModelIndex &current,
const QModelIndex &previous)
{
// Call parent class's currentChanged first
QTableView::currentChanged(current,previous);
// Now emit our signal
QModelIndex current_item=QModelIndex(current);
emit(RegistryKeyTable::CurrentItemChanged(current_item));
}
void RegistryKeyTable::SlotCopyKeyName() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(0).data().toString(),
QClipboard::Clipboard);
}
void RegistryKeyTable::SlotCopyKeyValue() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(2).data().toString(),
QClipboard::Clipboard);
}
diff --git a/trunk/registrykeytable.h b/trunk/registrykeytable.h
index 29216f3..52f983a 100644
--- a/trunk/registrykeytable.h
+++ b/trunk/registrykeytable.h
@@ -1,58 +1,58 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYKEYTABLE_H
#define REGISTRYKEYTABLE_H
#include <QTableView>
#include <QContextMenuEvent>
#include <QMenu>
#include <QAction>
class RegistryKeyTable : public QTableView {
Q_OBJECT
public:
RegistryKeyTable(QWidget *p_parent=0);
~RegistryKeyTable();
void setModel(QAbstractItemModel *p_model);
//void selectRow(QString key_name);
Q_SIGNALS:
void CurrentItemChanged(QModelIndex current);
protected:
int sizeHintForColumn(int column) const;
void contextMenuEvent(QContextMenuEvent *p_event);
private:
QMenu *p_menu_copy;
QAction *p_action_copy_key_name;
QAction *p_action_copy_key_value;
void currentChanged(const QModelIndex &current,
const QModelIndex &previous);
private slots:
void SlotCopyKeyName();
void SlotCopyKeyValue();
};
#endif // REGISTRYKEYTABLE_H
diff --git a/trunk/registrykeytablemodel.cpp b/trunk/registrykeytablemodel.cpp
index 7e06971..3219772 100644
--- a/trunk/registrykeytablemodel.cpp
+++ b/trunk/registrykeytablemodel.cpp
@@ -1,201 +1,201 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrykeytablemodel.h"
#include <stdlib.h>
RegistryKeyTableModel::RegistryKeyTableModel(RegistryHive *p_hive,
QString node_path,
QObject *p_parent)
: QAbstractTableModel(p_parent)
{
// Create the "root" key. It's values will be used for as header values.
this->p_keys=new RegistryKey(QList<QVariant>()<<
tr("Key")<<
tr("Type")<<
tr("Value")<<
tr("Last modified"));
// Build key list
this->SetupModelData(p_hive,node_path);
}
RegistryKeyTableModel::~RegistryKeyTableModel() {
delete this->p_keys;
}
QVariant RegistryKeyTableModel::data(const QModelIndex &index, int role) const {
bool ok;
if(!index.isValid()) return QVariant();
RegistryKey *p_key=static_cast<RegistryKey*>(index.internalPointer());
switch(role) {
case Qt::DisplayRole: {
switch(index.column()) {
case RegistryKeyTableModel::ColumnContent_KeyName: {
return p_key->Data(index.column());
break;
}
case RegistryKeyTableModel::ColumnContent_KeyType: {
int value_type=p_key->Data(index.column()).toInt(&ok);
if(!ok) return QVariant();
return RegistryHive::KeyTypeToString(value_type);
break;
}
case RegistryKeyTableModel::ColumnContent_KeyValue: {
// Get index to value type
QModelIndex type_index=this->index(index.row(),
RegistryKeyTableModel::
ColumnContent_KeyType);
// Get value type
int value_type=this->data(type_index,
RegistryKeyTableModel::
AdditionalRoles_GetRawData).toInt(&ok);
if(!ok) return QVariant();
// Return value converted to human readeable string
QByteArray value_array=p_key->Data(index.column()).toByteArray();
return RegistryHive::KeyValueToString(value_array,value_type);
break;
}
case RegistryKeyTableModel::ColumnContent_KeyModTime: {
QDateTime date_time;
bool ok=false;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(RegistryHive::FiletimeToUnixtime(
p_key->Data(index.column()).toLongLong(&ok)));
if(ok) return date_time.toString("yyyy/MM/dd hh:mm:ss");
else return tr("Unknown");
break;
}
default:
return QVariant();
}
break;
}
case RegistryKeyTableModel::AdditionalRoles_GetRawData: {
return p_key->Data(index.column());
break;
}
default:
return QVariant();
}
return QVariant();
}
Qt::ItemFlags RegistryKeyTableModel::flags(const QModelIndex &index) const {
if(!index.isValid()) return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant RegistryKeyTableModel::headerData(int section,
Qt::Orientation orientation,
int role) const
{
// Only horizontal header is supported
if(orientation!=Qt::Horizontal) return QVariant();
switch(role) {
case Qt::TextAlignmentRole:
// Handle text alignment
if(section==2) return Qt::AlignLeft;
else return Qt::AlignCenter;
break;
case Qt::DisplayRole:
// Header text
return this->p_keys->Data(section);
break;
default:
return QVariant();
}
}
QModelIndex RegistryKeyTableModel::index(int row,
int column,
const QModelIndex &parent) const
{
if(!this->hasIndex(row,column,parent)) return QModelIndex();
RegistryKey *p_key=this->p_keys->Key(row);
return this->createIndex(row,column,p_key);
}
int RegistryKeyTableModel::rowCount(const QModelIndex &parent) const {
// According to Qt doc, when parent in TableModel is valid, we should return 0
if(parent.isValid()) return 0;
// Get and return row count from the keys list
return this->p_keys->RowCount();
}
int RegistryKeyTableModel::columnCount(const QModelIndex &parent) const {
// According to Qt doc, when parent in TableModel is valid, we should return 0
if(parent.isValid()) return 0;
// There are always 4 columns
return 4;
}
int RegistryKeyTableModel::GetKeyRow(QString key_name) const {
int i;
for(i=0;i<this->p_keys->RowCount();i++) {
if(this->p_keys->Key(i)->Data(0)==key_name) {
return i;
}
}
// When key isn't found, return the first row
return 0;
}
void RegistryKeyTableModel::SetupModelData(RegistryHive *p_hive,
QString &node_path)
{
QMap<QString,int> node_keys;
RegistryKey *p_key;
QByteArray key_value;
int key_value_type;
int64_t key_mod_time;
size_t key_value_len;
// Get all keys for current node
node_keys=p_hive->GetKeys(node_path);
if(node_keys.isEmpty()) return;
// Add all keys to list
QMapIterator<QString,int> i(node_keys);
while(i.hasNext()) {
i.next();
key_value=p_hive->GetKeyValue(i.value(),
&key_value_type,
&key_value_len);
if(p_hive->GetErrorMsg()!="") continue;
key_mod_time=p_hive->GetKeyModTime(i.value());
// TODO: Maybe we have to call GetErrorMsg in case an error occured
p_key=new RegistryKey(QList<QVariant>()<<
QString(i.key().length() ? i.key() : "(default)")<<
QVariant(key_value_type)<<
key_value<<
QVariant((qlonglong)key_mod_time));
this->p_keys->Append(p_key);
}
}
diff --git a/trunk/registrykeytablemodel.h b/trunk/registrykeytablemodel.h
index 881402d..508f7d3 100644
--- a/trunk/registrykeytablemodel.h
+++ b/trunk/registrykeytablemodel.h
@@ -1,69 +1,69 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYKEYTABLEMODEL_H
#define REGISTRYKEYTABLEMODEL_H
#include <QAbstractTableModel>
#include <QDateTime>
#include "registrykey.h"
#include "registryhive.h"
class RegistryKeyTableModel : public QAbstractTableModel {
Q_OBJECT
public:
enum AdditionalRoles {
AdditionalRoles_GetRawData=Qt::UserRole
};
RegistryKeyTableModel(RegistryHive *p_hive,
QString node_path,
QObject *p_parent=0);
~RegistryKeyTableModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section,
Qt::Orientation orientation,
int role=Qt::DisplayRole) const;
QModelIndex index(int row,
int column,
const QModelIndex &parent=QModelIndex()) const;
int rowCount(const QModelIndex &parent=QModelIndex()) const;
int columnCount(const QModelIndex &parent=QModelIndex()) const;
int GetKeyRow(QString key_name) const;
private:
enum ColumnContent {
ColumnContent_KeyName=0,
ColumnContent_KeyType,
ColumnContent_KeyValue,
ColumnContent_KeyModTime
};
RegistryKey *p_keys;
void SetupModelData(RegistryHive *p_hive, QString &node_path);
};
#endif // REGISTRYKEYTABLEMODEL_H
diff --git a/trunk/registrynode.cpp b/trunk/registrynode.cpp
index 4b4ec5a..9a3845b 100644
--- a/trunk/registrynode.cpp
+++ b/trunk/registrynode.cpp
@@ -1,61 +1,61 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrynode.h"
RegistryNode::RegistryNode(const QString name,
RegistryNode *p_parent)
{
this->p_parent_node=p_parent;
this->node_name=name;
}
RegistryNode::~RegistryNode() {
qDeleteAll(this->child_nodes);
}
void RegistryNode::AppendChild(RegistryNode *p_child) {
this->child_nodes.append(p_child);
}
RegistryNode* RegistryNode::child(uint64_t row) {
return this->child_nodes.value(row);
}
uint64_t RegistryNode::childCount() const {
return this->child_nodes.count();
}
QString RegistryNode::data() const {
return this->node_name;
}
uint64_t RegistryNode::row() const {
if(this->p_parent_node) {
return this->p_parent_node->
child_nodes.indexOf(const_cast<RegistryNode*>(this));
} else {
return 0;
}
}
RegistryNode *RegistryNode::parent() {
return this->p_parent_node;
}
diff --git a/trunk/registrynode.h b/trunk/registrynode.h
index 9df1e55..c1fd624 100644
--- a/trunk/registrynode.h
+++ b/trunk/registrynode.h
@@ -1,47 +1,47 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYNODE_H
#define REGISTRYNODE_H
#include <QList>
#include <QString>
#include <inttypes.h>
class RegistryNode {
public:
RegistryNode(const QString name, RegistryNode *p_parent=0);
~RegistryNode();
void AppendChild(RegistryNode *p_child);
RegistryNode *child(uint64_t row);
uint64_t childCount() const;
QString data() const;
uint64_t row() const;
RegistryNode *parent();
private:
QList<RegistryNode*> child_nodes;
QString node_name;
RegistryNode *p_parent_node;
};
#endif // REGISTRYNODE_H
diff --git a/trunk/registrynodetree.cpp b/trunk/registrynodetree.cpp
index 6e09e91..f3d64fe 100644
--- a/trunk/registrynodetree.cpp
+++ b/trunk/registrynodetree.cpp
@@ -1,130 +1,130 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrynodetree.h"
#include "registrynodetreemodel.h"
#include <QHeaderView>
#include <QApplication>
#include <QClipboard>
RegistryNodeTree::RegistryNodeTree(QWidget *p_parent) : QTreeView(p_parent) {
// Configure widget
this->setTextElideMode(Qt::ElideNone);
// Create context menu
this->p_menu_copy=new QMenu(tr("Copy"),this);
this->p_action_copy_node_name=new QAction(tr("Node name"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_node_name);
this->connect(this->p_action_copy_node_name,
SIGNAL(triggered()),
this,
SLOT(SlotCopyNodeName()));
this->p_action_copy_node_path=new QAction(tr("Node path"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_node_path);
this->connect(this->p_action_copy_node_path,
SIGNAL(triggered()),
this,
SLOT(SlotCopyNodePath()));
}
RegistryNodeTree::~RegistryNodeTree() {
// Delete context menu
delete this->p_action_copy_node_name;
delete this->p_action_copy_node_path;
delete this->p_menu_copy;
}
void RegistryNodeTree::setModel(QAbstractItemModel *p_model) {
QTreeView::setModel(p_model);
this->header()->setResizeMode(0,QHeaderView::ResizeToContents);
this->header()->setStretchLastSection(false);
if(p_model!=NULL && p_model->index(0,0).isValid()) {
// Select first tree item
this->setCurrentIndex(p_model->index(0,0));
}
}
//int RegistryNodeTree::sizeHintForColumn(int column) const {}
void RegistryNodeTree::contextMenuEvent(QContextMenuEvent *p_event) {
// Only show context menu when a node is selected
if(this->selectedIndexes().count()!=1) return;
// Only show context menu when user clicked on selected row
if(this->indexAt(p_event->pos())!=this->selectedIndexes().at(0)) return;
// Emit a click signal
emit(this->clicked(this->indexAt(p_event->pos())));
// Create context menu and add actions
QMenu context_menu(this);
context_menu.addMenu(this->p_menu_copy);
context_menu.exec(p_event->globalPos());
}
void RegistryNodeTree::keyPressEvent(QKeyEvent *p_event) {
// Only react if a node is selected and user pressed Key_Left
if(this->selectedIndexes().count()==1 &&
p_event->key()==Qt::Key_Left)
{
QModelIndex cur_index=this->selectedIndexes().at(0);
if(this->model()->hasChildren(cur_index) && this->isExpanded(cur_index)) {
// Current node is expanded. Only collapse this one
this->collapse(cur_index);
return;
}
if(!cur_index.parent().isValid()) {
// Do no try to collapse anything above root node
return;
}
this->collapse(cur_index.parent());
this->setCurrentIndex(cur_index.parent());
return;
}
// If we didn't handle the key event, let our parent handle it
QTreeView::keyPressEvent(p_event);
}
void RegistryNodeTree::currentChanged(const QModelIndex &current,
const QModelIndex &previous)
{
// Call parent class's currentChanged first
QTreeView::currentChanged(current,previous);
// Now emit our signal
QModelIndex current_item=QModelIndex(current);
emit(RegistryNodeTree::CurrentItemChanged(current_item));
}
void RegistryNodeTree::SlotCopyNodeName() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(0).data().toString(),
QClipboard::Clipboard);
}
void RegistryNodeTree::SlotCopyNodePath() {
QString path=((RegistryNodeTreeModel*)(this->model()))->
GetNodePath(this->selectedIndexes().at(0));
QApplication::clipboard()->setText(path,QClipboard::Clipboard);
}
diff --git a/trunk/registrynodetree.h b/trunk/registrynodetree.h
index d3b5c45..216f016 100644
--- a/trunk/registrynodetree.h
+++ b/trunk/registrynodetree.h
@@ -1,59 +1,59 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYNODETREE_H
#define REGISTRYNODETREE_H
#include <QTreeView>
#include <QAbstractItemModel>
#include <QContextMenuEvent>
#include <QMenu>
#include <QAction>
class RegistryNodeTree : public QTreeView {
Q_OBJECT
public:
RegistryNodeTree(QWidget *p_parent=0);
~RegistryNodeTree();
void setModel(QAbstractItemModel *p_model);
Q_SIGNALS:
void CurrentItemChanged(QModelIndex current);
protected:
// int sizeHintForColumn(int column) const;
void contextMenuEvent(QContextMenuEvent *p_event);
void keyPressEvent(QKeyEvent *p_event);
private:
QMenu *p_menu_copy;
QAction *p_action_copy_node_name;
QAction *p_action_copy_node_path;
void currentChanged(const QModelIndex &current,
const QModelIndex &previous);
private slots:
void SlotCopyNodeName();
void SlotCopyNodePath();
};
#endif // REGISTRYNODETREE_H
diff --git a/trunk/registrynodetreemodel.cpp b/trunk/registrynodetreemodel.cpp
index 1b7195a..64fb863 100644
--- a/trunk/registrynodetreemodel.cpp
+++ b/trunk/registrynodetreemodel.cpp
@@ -1,184 +1,184 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrynodetreemodel.h"
#include <QStringList>
#include <stdlib.h>
RegistryNodeTreeModel::RegistryNodeTreeModel(RegistryHive *p_hive,
QObject *p_parent)
: QAbstractItemModel(p_parent)
{
// Create root node
this->p_root_node=new RegistryNode("ROOT");
// Build node list
this->SetupModelData(p_hive,this->p_root_node);
}
RegistryNodeTreeModel::~RegistryNodeTreeModel() {
delete this->p_root_node;
}
QVariant RegistryNodeTreeModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid()) return QVariant();
if(role!=Qt::DisplayRole) return QVariant();
RegistryNode *p_node=static_cast<RegistryNode*>(index.internalPointer());
return p_node->data();
}
Qt::ItemFlags RegistryNodeTreeModel::flags(const QModelIndex &index) const {
if(!index.isValid()) return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant RegistryNodeTreeModel::headerData(int section,
Qt::Orientation orientation,
int role) const
{
Q_UNUSED(section);
if(orientation==Qt::Horizontal && role==Qt::DisplayRole) {
return QVariant("Registry key folders");
} else {
return QVariant();
}
}
QModelIndex RegistryNodeTreeModel::index(int row,
int column,
const QModelIndex &parent) const
{
if(!this->hasIndex(row,column,parent)) return QModelIndex();
RegistryNode *p_parent_node;
if(!parent.isValid()) {
p_parent_node=this->p_root_node;
} else {
p_parent_node=static_cast<RegistryNode*>(parent.internalPointer());
}
RegistryNode *p_child_node=p_parent_node->child(row);
if(p_child_node) {
return this->createIndex(row,column,p_child_node);
} else {
return QModelIndex();
}
}
QModelIndex RegistryNodeTreeModel::parent(const QModelIndex &index) const {
if(!index.isValid()) return QModelIndex();
RegistryNode *p_child_node=
static_cast<RegistryNode*>(index.internalPointer());
RegistryNode *p_parent_node=p_child_node->parent();
if(p_parent_node==this->p_root_node) {
return QModelIndex();
} else {
return this->createIndex(p_parent_node->row(),0,p_parent_node);
}
}
int RegistryNodeTreeModel::rowCount(const QModelIndex &parent) const {
if(parent.column()>0) return 0;
RegistryNode *p_parent_node;
if(!parent.isValid()) {
p_parent_node=this->p_root_node;
} else {
p_parent_node=static_cast<RegistryNode*>(parent.internalPointer());
}
return p_parent_node->childCount();
}
int RegistryNodeTreeModel::columnCount(const QModelIndex &parent) const {
Q_UNUSED(parent);
return 1;
}
QList<QModelIndex> RegistryNodeTreeModel::GetIndexListOf(QString path) const {
RegistryNode *p_parent_node=this->p_root_node;
QList<QModelIndex> ret;
QStringList nodes=path.split("\\",QString::SkipEmptyParts);
int i,ii;
bool found=false;
// Create a list of all index's that form the supplied path
ret.clear();
for(i=0;i<nodes.count();i++) {
found=false;
for(ii=0;ii<p_parent_node->childCount();ii++) {
if(p_parent_node->child(ii)->data()==nodes.at(i)) {
ret.append(this->createIndex(ii,0,p_parent_node->child(ii)));
p_parent_node=p_parent_node->child(ii);
found=true;
break;
}
}
// Break when last child node was found
if(found && i==nodes.count()-1) break;
// Return an empty list when a child node wasn't found
else if(!found) return QList<QModelIndex>();
}
return ret;
}
QString RegistryNodeTreeModel::GetNodePath(QModelIndex child_index) const
{
QString path;
// Get current node name
path=this->data(child_index,Qt::DisplayRole).toString().prepend("\\");
// Build node path by prepending all parent nodes names
while(this->parent(child_index)!=QModelIndex()) {
child_index=this->parent(child_index);
path.prepend(this->data(child_index,
Qt::DisplayRole).toString().prepend("\\"));
}
return path;
}
void RegistryNodeTreeModel::SetupModelData(RegistryHive *p_hive,
RegistryNode *p_parent,
int hive_node)
{
QMap<QString,int> hive_children;
RegistryNode *p_node;
// Get all sub nodes of current hive node
if(hive_node) hive_children=p_hive->GetNodes(hive_node);
else hive_children=p_hive->GetNodes("\\");
if(hive_children.isEmpty()) return;
// Recursivly iterate over all sub nodes
QMapIterator<QString, int> i(hive_children);
while(i.hasNext()) {
i.next();
p_node=new RegistryNode(i.key(),p_parent);
p_parent->AppendChild(p_node);
this->SetupModelData(p_hive,p_node,i.value());
}
}
diff --git a/trunk/registrynodetreemodel.h b/trunk/registrynodetreemodel.h
index 2718188..6e0d67f 100644
--- a/trunk/registrynodetreemodel.h
+++ b/trunk/registrynodetreemodel.h
@@ -1,61 +1,61 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYNODETREEMODEL_H
#define REGISTRYNODETREEMODEL_H
#include <QAbstractItemModel>
#include <QList>
#include <QString>
#include "registrynode.h"
#include "registryhive.h"
class RegistryNodeTreeModel : public QAbstractItemModel {
Q_OBJECT
public:
RegistryNodeTreeModel(RegistryHive *p_hive, QObject *p_parent=0);
~RegistryNodeTreeModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section,
Qt::Orientation orientation,
int role=Qt::DisplayRole) const;
QModelIndex index(int row,
int column,
const QModelIndex &parent=QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent=QModelIndex()) const;
int columnCount(const QModelIndex &parent=QModelIndex()) const;
QList<QModelIndex> GetIndexListOf(QString path) const;
QString GetNodePath(QModelIndex child_index) const;
private:
RegistryNode *p_root_node;
void SetupModelData(RegistryHive *p_hive,
RegistryNode *p_parent,
int hive_node=0);
};
#endif // REGISTRYNODETREEMODEL_H
diff --git a/trunk/reporttemplate.cpp b/trunk/reporttemplate.cpp
index a518e23..03b4438 100644
--- a/trunk/reporttemplate.cpp
+++ b/trunk/reporttemplate.cpp
@@ -1,54 +1,54 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "reporttemplate.h"
ReportTemplate::ReportTemplate(QString report_category,
QString report_name,
QString report_template_file)
{
this->category=report_category;
this->name=report_name;
this->template_file=report_template_file;
}
void ReportTemplate::SetCategory(QString new_category) {
this->category=new_category;
}
void ReportTemplate::SetName(QString new_name) {
this->name=new_name;
}
void ReportTemplate::SetFile(QString new_file) {
this->template_file=new_file;
}
QString ReportTemplate::ReportTemplate::Category() {
return this->category;
}
QString ReportTemplate::ReportTemplate::Name() {
return this->name;
}
QString ReportTemplate::ReportTemplate::File() {
return this->template_file;
}
diff --git a/trunk/reporttemplate.h b/trunk/reporttemplate.h
index 5102be7..23ae59a 100644
--- a/trunk/reporttemplate.h
+++ b/trunk/reporttemplate.h
@@ -1,46 +1,46 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REPORTTEMPLATE_H
#define REPORTTEMPLATE_H
#include <QString>
class ReportTemplate {
public:
ReportTemplate(QString report_category,
QString report_name,
QString report_template_file);
void SetCategory(QString new_category);
void SetName(QString new_name);
void SetFile(QString new_file);
QString Category();
QString Name();
QString File();
private:
QString category;
QString name;
QString template_file;
};
#endif // REPORTTEMPLATE_H
diff --git a/trunk/searchresultwidget.cpp b/trunk/searchresultwidget.cpp
index 343acb6..c4b76ae 100644
--- a/trunk/searchresultwidget.cpp
+++ b/trunk/searchresultwidget.cpp
@@ -1,106 +1,106 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "searchresultwidget.h"
#include <QHeaderView>
#include <QAbstractItemView>
#include <QStringList>
#include <QTableWidgetItem>
#include <QFontMetrics>
SearchResultWidget::SearchResultWidget(QWidget *p_parent)
: QTableWidget(p_parent)
{
this->setColumnCount(3);
this->setRowCount(0);
this->setTextElideMode(Qt::ElideNone);
this->verticalHeader()->setHidden(true);
this->setSelectionBehavior(QAbstractItemView::SelectRows);
this->setSelectionMode(QAbstractItemView::SingleSelection);
this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
this->setHorizontalHeaderLabels(QStringList()<<tr("Path")
<<tr("Match type")
<<tr("Match text"));
}
void SearchResultWidget::SlotFoundMatch(ThreadSearch::eMatchType match_type,
QString path,
QString key,
QString value)
{
QTableWidgetItem *p_item;
QString full_path;
QString type;
QString match;
switch(match_type) {
case ThreadSearch::eMatchType_NodeName:
type=tr("Node name");
full_path=path;
match=key;
break;
case ThreadSearch::eMatchType_KeyName:
type=tr("Key name");
full_path=path;
match=key;
break;
case ThreadSearch::eMatchType_KeyValue:
type=tr("Key value");
full_path=path+"\\"+key;
match=value;
break;
}
int rows=this->rowCount();
this->setRowCount(rows+1);
// TODO: Use setCellWidget to add QTextEdit and then use insertText and
// insertHtml to format match
p_item=new QTableWidgetItem(full_path=="" ? "\\" : full_path);
p_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
this->setItem(rows,0,p_item);
p_item=new QTableWidgetItem(type);
p_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
this->setItem(rows,1,p_item);
p_item=new QTableWidgetItem(match);
p_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
this->setItem(rows,2,p_item);
}
int SearchResultWidget::sizeHintForColumn(int column) const {
int size_hint=0;
int i=0;
int item_width=0;
QFontMetrics fm(this->fontMetrics());
// Find string that needs the most amount of space
for(i=0;i<this->rowCount();i++) {
item_width=fm.width(this->item(i,column)->text())+10;
if(item_width>size_hint) size_hint=item_width;
}
return size_hint;
}
void SearchResultWidget::SlotSearchFinished() {
this->resizeColumnsToContents();
this->resizeRowsToContents();
}
diff --git a/trunk/searchresultwidget.h b/trunk/searchresultwidget.h
index 60e6d35..d7040ca 100644
--- a/trunk/searchresultwidget.h
+++ b/trunk/searchresultwidget.h
@@ -1,45 +1,45 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef SEARCHRESULTWIDGET_H
#define SEARCHRESULTWIDGET_H
#include <QTableWidget>
#include "threadsearch.h"
class SearchResultWidget : public QTableWidget {
Q_OBJECT
public:
SearchResultWidget(QWidget *p_parent=0);
public slots:
void SlotFoundMatch(ThreadSearch::eMatchType match_type,
QString path,
QString key,
QString value);
void SlotSearchFinished();
protected:
int sizeHintForColumn(int column) const;
};
#endif // SEARCHRESULTWIDGET_H
diff --git a/trunk/tabwidget.cpp b/trunk/tabwidget.cpp
index 9c29f15..f3cec34 100644
--- a/trunk/tabwidget.cpp
+++ b/trunk/tabwidget.cpp
@@ -1,65 +1,65 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "tabwidget.h"
#include <QTabBar>
#include <QPushButton>
#include <QIcon>
#include <QSize>
#include <QPoint>
TabWidget::TabWidget(QWidget *p_parent) : QTabWidget(p_parent) {}
int TabWidget::addTab(QWidget *p_widget,
const QString &title,
bool close_button)
{
// Add tab
int tab_index=QTabWidget::addTab(p_widget,title);
// If desired, add a close button to the tab
if(close_button) {
// Create close button
QPushButton *p_close_button=
new QPushButton(QIcon(":/icons/close_button"),QString());
p_close_button->setFlat(true);
p_close_button->setIconSize(QSize(14,14));
p_close_button->setGeometry(p_close_button->x(),p_close_button->y(),14,14);
// Connect clicked signal
this->connect(p_close_button,
SIGNAL(clicked()),
this,
SLOT(SlotCloseButtonClicked()));
this->tabBar()->setTabButton(tab_index,QTabBar::RightSide,p_close_button);
}
return tab_index;
}
void TabWidget::SlotCloseButtonClicked() {
// Find index of tab to close. The trolls do it by iterating over all tabs
// and comparing their widget with QObject::sender().
QPushButton *p_close_button=(QPushButton*)(QObject::sender());
int index=this->tabBar()->tabAt(QPoint(p_close_button->x(),
p_close_button->y()));
// Emit tabCloseRequested
emit(this->tabCloseRequested(index));
}
diff --git a/trunk/tabwidget.h b/trunk/tabwidget.h
index 2fc2ea7..5dbf65a 100644
--- a/trunk/tabwidget.h
+++ b/trunk/tabwidget.h
@@ -1,41 +1,41 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef TABWIDGET_H
#define TABWIDGET_H
#include <QTabWidget>
#include <QString>
class TabWidget : public QTabWidget {
Q_OBJECT
public:
TabWidget(QWidget *p_parent);
int addTab(QWidget *p_widget,
const QString &title,
bool close_button=false);
private slots:
void SlotCloseButtonClicked();
};
#endif // TABWIDGET_H
diff --git a/trunk/threadsearch.cpp b/trunk/threadsearch.cpp
index 6d332ad..5df3a97 100644
--- a/trunk/threadsearch.cpp
+++ b/trunk/threadsearch.cpp
@@ -1,195 +1,195 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "threadsearch.h"
#include "registryhive.h"
#include <QStringList>
#include <QMetaType>
ThreadSearch::ThreadSearch(QObject *p_parent) : QThread(p_parent) {
this->hive_file="";
this->h_hive=NULL;
this->keywords=QList<QByteArray>();
this->search_nodes=false;
this->search_keys=false;
this->search_values=false;
this->root_node=0;
// Register meta types to be used in signals
qRegisterMetaType<ThreadSearch::eMatchType>("ThreadSearch::eMatchType");
}
bool ThreadSearch::Search(QString registry_hive,
QList<QByteArray> search_keywords,
bool search_node_names,
bool search_key_names,
bool search_key_values,
QString search_path)
{
this->hive_file=registry_hive;
this->keywords=search_keywords;
this->search_nodes=search_node_names;
this->search_keys=search_key_names;
this->search_values=search_key_values;
this->root_path=search_path=="\\" ? "" : search_path;
// Try to open hive
this->h_hive=hivex_open(this->hive_file.toAscii().constData(),0);
if(this->h_hive==NULL) return false;
// Get root node
this->root_node=hivex_root(this->h_hive);
if(this->root_node==0) {
hivex_close(this->h_hive);
return false;
}
// If a root path was specified, iterate to it
if(this->root_path!="") {
QStringList path_nodes=search_path.split("\\",QString::SkipEmptyParts);
int i;
for(i=0;i<path_nodes.count();i++) {
this->root_node=hivex_node_get_child(this->h_hive,
this->root_node,
path_nodes.at(i).toAscii().constData());
if(this->root_node==0) {
hivex_close(this->h_hive);
return false;
}
}
}
this->start();
return true;
}
void ThreadSearch::run() {
this->Match();
hivex_close(this->h_hive);
}
void ThreadSearch::Match(QString path, hive_node_h node) {
char *p_node_name;
int i,ii;
hive_node_h *p_node_childs;
QByteArray *p_byte_array;
if(node!=0) {
p_node_name=hivex_node_name(this->h_hive,node);
if(p_node_name==NULL) return;
if(this->search_nodes) {
// Compare node name to keywords
p_byte_array=new QByteArray(p_node_name);
for(i=0;i<this->keywords.count();i++) {
if(p_byte_array->indexOf(this->keywords.at(i))!=-1) {
emit(SignalFoundMatch(ThreadSearch::eMatchType_NodeName,
path,
QString(p_node_name),
QString()));
break;
}
}
delete p_byte_array;
}
if(this->search_keys || this->search_values) {
// Get key,value pairs for current node
hive_value_h *p_keys=hivex_node_values(this->h_hive,node);
if(p_keys==NULL) {
delete p_node_name;
return;
}
if(this->search_keys) {
// Compare key names to keywords
char *p_keyname;
for(i=0;p_keys[i];i++) {
p_keyname=hivex_value_key(this->h_hive,p_keys[i]);
if(p_keyname==NULL) continue;
p_byte_array=new QByteArray(p_keyname);
for(ii=0;ii<this->keywords.count();ii++) {
if(p_byte_array->indexOf(this->keywords.at(ii))!=-1) {
emit(SignalFoundMatch(ThreadSearch::eMatchType_KeyName,
path+"\\"+p_node_name,
strlen(p_keyname)==0 ? QString("(default)") : QString(p_keyname),
QString()));
break;
}
}
delete p_byte_array;
delete p_keyname;
}
}
if(this->search_values) {
// Compare key values to keywords
char *p_value;
hive_type val_type;
size_t val_len;
for(i=0;p_keys[i];i++) {
p_value=hivex_value_value(this->h_hive,p_keys[i],&val_type,&val_len);
if(p_value==NULL) continue;
p_byte_array=new QByteArray(p_value,val_len);
for(ii=0;ii<this->keywords.count();ii++) {
if(p_byte_array->indexOf(this->keywords.at(ii))!=-1) {
char *p_keyname=hivex_value_key(this->h_hive,p_keys[i]);
if(p_keyname==NULL) continue;
emit(SignalFoundMatch(ThreadSearch::eMatchType_KeyValue,
path+"\\"+p_node_name,
strlen(p_keyname)==0 ? QString("(default)") : QString(p_keyname),
RegistryHive::KeyValueToString(*p_byte_array,val_type)));
delete p_keyname;
break;
}
}
delete p_byte_array;
delete p_value;
}
}
delete p_keys;
}
// Search in subnodes
p_node_childs=hivex_node_children(this->h_hive,node);
if(p_node_childs!=NULL) {
i=0;
while(p_node_childs[i]) {
this->Match(path+"\\"+p_node_name,p_node_childs[i]);
i++;
}
delete p_node_childs;
}
delete p_node_name;
} else {
p_node_childs=hivex_node_children(this->h_hive,this->root_node);
if(p_node_childs!=NULL) {
i=0;
while(p_node_childs[i]) {
this->Match(this->root_path,p_node_childs[i]);
i++;
}
delete p_node_childs;
}
}
}
diff --git a/trunk/threadsearch.h b/trunk/threadsearch.h
index 7050e46..4afb4d6 100644
--- a/trunk/threadsearch.h
+++ b/trunk/threadsearch.h
@@ -1,73 +1,73 @@
/*******************************************************************************
-* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef THREADSEARCH_H
#define THREADSEARCH_H
#include <QThread>
#include <QObject>
#include <QString>
#include <QList>
#include <QByteArray>
#include <hivex.h>
class ThreadSearch : public QThread {
Q_OBJECT
public:
enum eMatchType {
eMatchType_NodeName=0,
eMatchType_KeyName,
eMatchType_KeyValue
};
ThreadSearch(QObject *p_parent=0);
bool Search(QString registry_hive,
QList<QByteArray> search_keywords,
bool search_node_names,
bool search_key_names,
bool search_key_values,
QString search_path="\\");
signals:
void SignalFoundMatch(ThreadSearch::eMatchType match_type,
QString path,
QString key,
QString value);
protected:
void run();
private:
QString hive_file;
hive_h *h_hive;
QList<QByteArray> keywords;
bool search_nodes;
bool search_keys;
bool search_values;
QString root_path;
hive_node_h root_node;
void Match(QString path="", hive_node_h node=0);
};
#endif // THREADSEARCH_H

File Metadata

Mime Type
text/x-diff
Expires
Tue, Dec 24, 3:09 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1176985
Default Alt Text
(275 KB)

Event Timeline