Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F4324501
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
48 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/trunk/dlgkeydetails.cpp b/trunk/dlgkeydetails.cpp
deleted file mode 100644
index 310e131..0000000
--- a/trunk/dlgkeydetails.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*******************************************************************************
-* 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
deleted file mode 100644
index 8f9cb09..0000000
--- a/trunk/dlgkeydetails.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
-* 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
-
-// TODO: Is this dialog still needed in any ways????
-
-#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/dlgkeydetails.ui b/trunk/dlgkeydetails.ui
deleted file mode 100644
index 53429ed..0000000
--- a/trunk/dlgkeydetails.ui
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>DlgKeyDetails</class>
- <widget class="QDialog" name="DlgKeyDetails">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>678</width>
- <height>346</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Dialog</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QPushButton" name="BtnClose">
- <property name="text">
- <string>&Close</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/trunk/fred.pro b/trunk/fred.pro
index a062e08..9cef798 100644
--- a/trunk/fred.pro
+++ b/trunk/fred.pro
@@ -1,129 +1,126 @@
#*******************************************************************************
# 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 \
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 \
settings.cpp \
searchresulttabledelegate.cpp \
registrynodetreemodelproxy.cpp \
reports.cpp \
reportengine.cpp \
dlgreportchooser.cpp \
dlgpreferences.cpp \
dlgaddkey.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 \
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 \
settings.h \
searchresulttabledelegate.h \
registrynodetreemodelproxy.h \
reports.h \
reportengine.h \
dlgreportchooser.h \
dlgpreferences.h \
dlgaddkey.h \
macros.h
FORMS += mainwindow.ui \
dlgabout.ui \
- dlgkeydetails.ui \
dlgreportviewer.ui \
dlgsearch.ui \
dlgreportchooser.ui \
dlgpreferences.ui \
dlgaddkey.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/mainwindow.cpp b/trunk/mainwindow.cpp
index c325ef7..76782af 100644
--- a/trunk/mainwindow.cpp
+++ b/trunk/mainwindow.cpp
@@ -1,1061 +1,1033 @@
/*******************************************************************************
* 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 <QListIterator>
#include <QInputDialog>
#include <QDebug>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dlgabout.h"
-#include "dlgkeydetails.h"
#include "dlgreportchooser.h"
#include "dlgreportviewer.h"
#include "dlgsearch.h"
#include "dlgpreferences.h"
#include "dlgaddkey.h"
#include "compileinfo.h"
/*******************************************************************************
* Public
******************************************************************************/
/*
* Constructor
*/
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_node_tree_model_proxy=NULL;
this->p_reg_key_table_model=NULL;
this->p_search_thread=NULL;
this->search_result_widgets.clear();
// Init and load settings
this->p_settings=new Settings(this);
this->is_hive_writable=!this->p_settings->GetOpenHivesReadOnly();
// Set main window size
QByteArray geometry=this->p_settings->GetWindowGeometry("MainWindow");
if(!geometry.isEmpty()) {
// Restore saved geometry
this->restoreGeometry(geometry);
} else {
// No saved geometry, calculate and set default
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_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();
this->p_hex_edit_widget->setEnabled(false);
// 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)));
this->connect(this->p_node_tree,
SIGNAL(SignalAddNode(QModelIndex)),
this,
SLOT(SlotAddNode(QModelIndex)));
this->connect(this->p_node_tree,
SIGNAL(SignalDeleteNode(QModelIndex)),
this,
SLOT(SlotDeleteNode(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(SignalAddKey()),
this,
SLOT(SlotAddKey()));
this->connect(this->p_key_table,
SIGNAL(SignalEditKey(QModelIndex)),
this,
SLOT(SlotEditKey(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(SignalDeleteKey(QModelIndex)),
this,
SLOT(SlotDeleteKey(QModelIndex)));
// Add central widget
this->setCentralWidget(this->p_horizontal_splitter);
this->centralWidget()->setContentsMargins(4,4,4,0);
// Set window title
this->UpdateWindowTitle();
// Create and update recently opened menu
this->p_recently_opened_menu=new QMenu(this);
this->ui->ActionRecentlyOpened->setMenu(this->p_recently_opened_menu);
this->UpdateRecentlyOpenedMenu();
// Update EnableWriteSupport menu according to defaults
this->UpdateEnableWriteSupportMenu();
// Load report templates
this->p_reports=new Reports(this->p_settings);
// 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"));
}
}
/*
* Destructor
*/
MainWindow::~MainWindow() {
if(this->is_hive_open) {
this->p_hive->Close();
}
// Delete created objects
delete this->p_reports;
this->ClearRecentlyOpenedMenu();
delete this->p_recently_opened_menu;
delete this->p_hex_edit_widget;
delete this->p_tab_widget;
delete this->p_key_table;
delete this->p_vertical_splitter;
delete this->p_node_tree;
delete this->p_horizontal_splitter;
delete this->p_settings;
delete this->p_hive;
delete ui;
}
/*******************************************************************************
* Protected
******************************************************************************/
/*
* closeEvent
*/
void MainWindow::closeEvent(QCloseEvent *p_event) {
Q_UNUSED(p_event)
// Make sure the user can save any changes
// TODO: If saving fails, let the user cancel closing
this->SaveHiveChanges();
// Save window position and size on exit
this->p_settings->SetWindowGeometry("MainWindow",this->saveGeometry());
QMainWindow::closeEvent(p_event);
}
/*******************************************************************************
* Private slots
******************************************************************************/
/*
* on_action_Open_hive_triggered
*/
void MainWindow::on_action_Open_hive_triggered() {
QString hive_file="";
hive_file=QFileDialog::getOpenFileName(this,
tr("Open registry hive"),
this->p_settings->GetLastOpenLocation(),
tr("All files (*)"));
if(hive_file=="") return;
this->OpenHive(hive_file);
}
/*
* on_action_Close_hive_triggered
*/
void MainWindow::on_action_Close_hive_triggered() {
// Make sure the user can save any changes
// TODO: If saving fails, let the user cancel closing
this->SaveHiveChanges();
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_proxy;
delete this->p_reg_node_tree_model;
this->p_reg_node_tree_model_proxy=NULL;
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->is_hive_writable=!this->p_settings->GetOpenHivesReadOnly();
this->UpdateWindowTitle();
this->UpdateMenuStates();
this->UpdateEnableWriteSupportMenu();
}
}
/*
* on_action_Quit_triggered
*/
void MainWindow::on_action_Quit_triggered() {
qApp->exit();
}
/*
* on_ActionSearch_triggered
*/
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());
}
}
/*
* on_ActionEnableWriteSupport_triggered
*/
void MainWindow::on_ActionEnableWriteSupport_triggered() {
// There might be unsaved changes, give the user the chance to save them
if(!this->SaveHiveChanges()) return;
// Reopen hive
// Reopen has read_only as parameter. Thus we need to pass
// !this->is_hive_writable which is the case when passing
// this->is_hive_writable as long as we do it before actually changing our
// internal state.
if(!this->p_hive->Reopen(this->is_hive_writable)) {
// TODO: get error message from RegistryHive
QMessageBox::critical(this,
tr("Error"),
tr("Unable to switch write-support!"));
return;
}
// Switch internal state
this->is_hive_writable=!this->is_hive_writable;
this->UpdateEnableWriteSupportMenu();
this->p_node_tree->SetWritable(this->is_hive_writable);
this->p_key_table->SetWritable(this->is_hive_writable);
this->UpdateWindowTitle(this->p_hive->Filename());
}
/*
* on_ActionPreferences_triggered
*/
void MainWindow::on_ActionPreferences_triggered() {
DlgPreferences dlg_preferences(this->p_settings,this);
dlg_preferences.exec();
// Update vars, objects and GUI elements which might be affected by the new
// settings
this->UpdateRecentlyOpenedMenu();
this->is_hive_writable=!this->p_settings->GetOpenHivesReadOnly();
this->UpdateEnableWriteSupportMenu();
this->p_reports->LoadReportTemplates();
}
/*
* on_ActionGenerateReport_triggered
*/
void MainWindow::on_ActionGenerateReport_triggered() {
DlgReportChooser dlg_repchooser(this->p_reports,
this->p_hive->HiveTypeToString(
this->p_hive->HiveType()),
this->p_settings,
this);
if(dlg_repchooser.exec()==QDialog::Accepted) {
QList<ReportTemplate*> selected_reports;
// Get selected report
selected_reports=dlg_repchooser.GetSelectedReports();
if(selected_reports.isEmpty()) return;
// Generate report(s)
QString report_result="";
if(this->p_reports->GenerateReport(this->p_hive,
selected_reports,
report_result,
false))
{
// Report generation was successfull, show reports
DlgReportViewer *p_dlg_report_view=new DlgReportViewer(report_result,
this->p_settings,
this);
p_dlg_report_view->exec();
delete p_dlg_report_view;
} else {
// TODO: Inform user
qDebug()<<"ERROR: "<<report_result;
}
}
}
/*
* on_ActionReloadReportTemplates_triggered
*/
void MainWindow::on_ActionReloadReportTemplates_triggered() {
this->p_reports->LoadReportTemplates();
}
/*
* on_actionAbout_Qt_triggered
*/
void MainWindow::on_actionAbout_Qt_triggered() {
QMessageBox::aboutQt(this,tr("About Qt"));
}
/*
* on_actionAbout_fred_triggered
*/
void MainWindow::on_actionAbout_fred_triggered() {
DlgAbout dlg_about(this);
dlg_about.exec();
}
/*
* SlotNodeTreeClicked
*/
void MainWindow::SlotNodeTreeClicked(QModelIndex index) {
QString node_path;
if(!index.isValid()) return;
// Map proxy index to tree model index
index=this->p_reg_node_tree_model_proxy->mapToSource(index);
// 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,
this->is_hive_writable);
// Set focus back to nodetree to be able to navigate with keyboard
this->p_node_tree->setFocus();
}
/*
* SlotKeyTableClicked
*/
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();
}
/*
* SlotKeyTableDoubleClicked
*/
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;
+ if(!this->is_hive_open) 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();
- */
+ if(this->is_hive_writable) this->SlotEditKey(index);
}
/*
* SlotSearchFinished
*/
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);
}
/*
* SlotSearchResultWidgetDoubleClicked
*/
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++) {
indexes.replace(i,this->p_reg_node_tree_model_proxy->
mapFromSource(indexes.at(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::ClearAndSelect |
QItemSelectionModel::Rows |
QItemSelectionModel::Current);
// 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));
}
}
/*
* SlotTabCloseButtonClicked
*/
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);
}
/*
* SlotRecentlyOpenedFileClicked
*/
void MainWindow::SlotRecentlyOpenedFileClicked(bool checked) {
Q_UNUSED(checked)
QAction *p_sender=(QAction*)QObject::sender();
this->OpenHive(p_sender->text());
}
/*
* SlotAddNode
*/
void MainWindow::SlotAddNode(QModelIndex index) {
QString node_path;
int new_node_id;
if(!index.isValid()) return;
// Map proxy index to tree model index and get node path
index=this->p_reg_node_tree_model_proxy->mapToSource(index);
node_path=this->p_reg_node_tree_model->GetNodePath(index);
// Query user for a node name
bool ok=false;
QString node_name=QInputDialog::getText(this,
tr("Add node"),
tr("Please specify a name for the new node"),
QLineEdit::Normal,
QString(),
&ok);
if(ok) {
if((new_node_id=this->p_hive->AddNode(node_path,node_name))==0) {
// TODO: Get error message and display it
QMessageBox::critical(this,
tr("Error"),
tr("Unable to create node '%1\\%2'!")
.arg(node_path,node_name));
} else {
// Add node to model. We have to pass node_name as Ascii as utf8 names are
// not supported inside hives!
QModelIndex new_node_index=
this->p_reg_node_tree_model->AddNode(this->p_hive,
index,
new_node_id,
node_name.toAscii());
// Now that node has been added, expand parent and select new node
this->p_node_tree->expand(
this->p_reg_node_tree_model_proxy->mapFromSource(index));
new_node_index=
this->p_reg_node_tree_model_proxy->mapFromSource(new_node_index);
this->p_node_tree->scrollTo(new_node_index,
QAbstractItemView::PositionAtCenter);
this->p_node_tree->selectionModel()->clear();
this->p_node_tree->selectionModel()->
select(new_node_index,
QItemSelectionModel::ClearAndSelect |
QItemSelectionModel::Rows |
QItemSelectionModel::Current);
// And finally update key table
this->SlotNodeTreeClicked(new_node_index);
}
}
}
/*
* SlotDeleteNode
*/
void MainWindow::SlotDeleteNode(QModelIndex index) {
QString node_path;
if(!index.isValid()) return;
// Map proxy index to tree model index and get node path
index=this->p_reg_node_tree_model_proxy->mapToSource(index);
node_path=this->p_reg_node_tree_model->GetNodePath(index);
if(QMessageBox::warning(this,
tr("Delete node"),
tr("Are you sure you want to remove the node '%1' and all of its child nodes?").arg(node_path),
QMessageBox::Yes,
QMessageBox::No)==QMessageBox::Yes)
{
// Remove node from hive
if(!this->p_hive->DeleteNode(node_path)) {
// TODO: Get error message and display it
QMessageBox::critical(this,
tr("Error"),
tr("Unable to delete node '%1'!")
.arg(node_path));
return;
}
// Remove node from tree model and select nearest node
QModelIndex next_node_index=this->p_reg_node_tree_model->RemoveNode(index);
next_node_index=
this->p_reg_node_tree_model_proxy->mapFromSource(next_node_index);
this->p_node_tree->selectionModel()->clear();
this->p_node_tree->selectionModel()->
select(next_node_index,
QItemSelectionModel::ClearAndSelect |
QItemSelectionModel::Rows |
QItemSelectionModel::Current);
// And finally update key table
this->SlotNodeTreeClicked(next_node_index);
}
}
+/*
+ * SlotAddKey
+ */
void MainWindow::SlotAddKey() {
DlgAddKey dlg_add_key(this);
if(dlg_add_key.exec()==QDialog::Accepted) {
// Get selected parent node
QModelIndex parent_node=this->p_node_tree->currentIndex();
parent_node=this->p_reg_node_tree_model_proxy->mapToSource(parent_node);
QString parent_node_path=this->p_reg_node_tree_model->GetNodePath(parent_node);
// Add key
int new_key=this->p_hive->AddKey(parent_node_path,
dlg_add_key.KeyName(),
dlg_add_key.KeyType(),
dlg_add_key.KeyValue());
if(new_key==0) {
// TODO: Get error
QMessageBox::critical(this,
tr("Error"),
tr("Unable to add key!"));
return;
}
// Add new key to the key table model
QModelIndex new_key_index=
this->p_reg_key_table_model->AddKey(this->p_hive,new_key);
this->p_key_table->clearSelection();
this->p_key_table->scrollTo(new_key_index,
QAbstractItemView::PositionAtCenter);
this->p_key_table->selectRow(new_key_index.row());
this->SlotKeyTableClicked(new_key_index);
}
}
+/*
+ * SlotEditKey
+ */
void MainWindow::SlotEditKey(QModelIndex index) {
if(!index.isValid()) return;
// Get current values
QString key_name=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),
RegistryKeyTableModel::
ColumnContent_KeyName),
Qt::DisplayRole).toString();
QString key_value_type=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),
RegistryKeyTableModel::
ColumnContent_KeyType),
Qt::DisplayRole).toString();
QByteArray key_value=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),
RegistryKeyTableModel::
ColumnContent_KeyValue),
RegistryKeyTableModel::
AdditionalRoles_GetRawData).toByteArray();
// Exec update dialog
DlgAddKey dlg_update_key(this,key_name,key_value_type,key_value);
if(dlg_update_key.exec()==QDialog::Accepted) {
// Get selected parent node
QModelIndex parent_node=this->p_node_tree->currentIndex();
parent_node=this->p_reg_node_tree_model_proxy->mapToSource(parent_node);
QString parent_node_path=this->p_reg_node_tree_model->GetNodePath(parent_node);
// Update key
int new_key=this->p_hive->UpdateKey(parent_node_path,
dlg_update_key.KeyName(),
dlg_update_key.KeyType(),
dlg_update_key.KeyValue());
if(new_key==0) {
// TODO: Get error
QMessageBox::critical(this,
tr("Error"),
tr("Unable to update key!"));
return;
}
// Update key in key table model
QModelIndex new_key_index=
this->p_reg_key_table_model->UpdateKey(this->p_hive,new_key);
this->p_key_table->clearSelection();
this->p_key_table->scrollTo(new_key_index,
QAbstractItemView::PositionAtCenter);
this->p_key_table->selectRow(new_key_index.row());
+ // TODO: Update geometry in case data has been added and is now expanding
+ // behind the right border
+ // Update HexEditWidget
this->SlotKeyTableClicked(new_key_index);
}
}
+/*
+ * SlotDeleteKey
+ */
void MainWindow::SlotDeleteKey(QModelIndex index) {
// TODO
}
/*******************************************************************************
* Private
******************************************************************************/
/*
* OpenHive
*/
void MainWindow::OpenHive(QString hive_file) {
// Update last open location
this->p_settings->SetLastOpenLocation(
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,!this->is_hive_writable)) {
QMessageBox::critical(this,
tr("Error opening hive file"),
tr("Unable to open file '%1'").arg(hive_file));
return;
}
// Create tree model & proxy
this->p_reg_node_tree_model=new RegistryNodeTreeModel(this->p_hive);
this->p_reg_node_tree_model_proxy=new RegistryNodeTreeModelProxy(this);
//this->p_reg_node_tree_model_proxy->setDynamicSortFilter(true);
this->p_reg_node_tree_model_proxy->
setSourceModel(this->p_reg_node_tree_model);
this->p_node_tree->setModel(this->p_reg_node_tree_model_proxy,
this->is_hive_writable);
this->is_hive_open=true;
// Enable data interpreter
this->p_hex_edit_widget->setEnabled(true);
// Update window title
this->UpdateWindowTitle(hive_file);
// Update menu states
this->UpdateMenuStates();
// Add file to recent list and update recently opened menu
this->p_settings->AddRecentFile(hive_file);
this->UpdateRecentlyOpenedMenu();
}
/*
* UpdateWindowTitle
*/
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()));
if(!this->is_hive_writable) {
this->setWindowTitle(this->windowTitle().append(QString(" (%1)")
.arg(tr("read-only"))));
}
}
}
/*
* UpdateMenuStates
*/
void MainWindow::UpdateMenuStates() {
if(this->is_hive_open) {
this->ui->action_Close_hive->setEnabled(true);
this->ui->ActionEnableWriteSupport->setEnabled(true);
this->ui->ActionSearch->setEnabled(true);
this->ui->ActionEnableWriteSupport->setEnabled(true);
this->ui->ActionGenerateReport->setEnabled(true);
this->ui->ActionReloadReportTemplates->setEnabled(true);
} else {
this->ui->action_Close_hive->setEnabled(false);
this->ui->ActionEnableWriteSupport->setEnabled(false);
this->ui->ActionSearch->setEnabled(false);
this->ui->ActionEnableWriteSupport->setEnabled(false);
this->ui->ActionGenerateReport->setEnabled(false);
this->ui->ActionReloadReportTemplates->setEnabled(false);
}
}
/*
* ClearRecentlyOpenedMenu
*/
void MainWindow::ClearRecentlyOpenedMenu() {
QAction *p_action;
// Remove existing menu entries
QList<QAction*> menu_entries=this->p_recently_opened_menu->actions();
QListIterator<QAction*> it_me(menu_entries);
while(it_me.hasNext()) {
p_action=it_me.next();
this->p_recently_opened_menu->removeAction(p_action);
delete p_action;
}
}
/*
* UpdateRecentlyOpenedMenu
*/
void MainWindow::UpdateRecentlyOpenedMenu() {
QStringList recent_files=this->p_settings->GetRecentFiles();
QAction *p_action;
// Remove existing menu entries
this->ClearRecentlyOpenedMenu();
// If there are no recent files, disable submenu and return
if(recent_files.isEmpty()) {
this->ui->ActionRecentlyOpened->setEnabled(false);
return;
} else {
this->ui->ActionRecentlyOpened->setEnabled(true);
}
// Add recently opened files to menu
QListIterator<QString> it_rf(recent_files);
while(it_rf.hasNext()) {
// Create menu entry
p_action=new QAction(it_rf.next(),this->p_recently_opened_menu);
// Connect it to us
this->connect(p_action,
SIGNAL(triggered(bool)),
this,
SLOT(SlotRecentlyOpenedFileClicked(bool)));
// Add it to submenu
this->p_recently_opened_menu->addAction(p_action);
}
}
/*
* UpdateEnableWriteSupportMenu
*/
void MainWindow::UpdateEnableWriteSupportMenu() {
if(!this->is_hive_writable) {
this->ui->ActionEnableWriteSupport->setText(tr("Enable &write support"));
this->p_node_tree->SetWritable(false);
this->p_key_table->SetWritable(false);
} else {
this->ui->ActionEnableWriteSupport->setText(tr("Disable &write support"));
this->p_node_tree->SetWritable(true);
this->p_key_table->SetWritable(true);
}
}
/*
* SaveHiveChanges
*/
bool MainWindow::SaveHiveChanges() {
if(!this->is_hive_open) return true;
if(!this->is_hive_writable) return true;
if(!this->p_hive->HasChangesToCommit()) return true;
// There are unsaved changes, ask user if we should commit them
switch(QMessageBox::information(this,
tr("Hive contains unsaved data"),
tr("Do you want to save them now?"),
QMessageBox::Yes,
QMessageBox::No,
QMessageBox::Cancel))
{
case QMessageBox::Yes: {
if(!this->p_hive->CommitChanges()) {
// TODO: Get error message
QMessageBox::critical(this,
tr("Saving changes"),
tr("Unable to save changes!"));
return false;
}
break;
}
case QMessageBox::No: {
// TODO: Discard any changes if we are changing to read-only!
break;
}
default: {
return false;
}
}
return true;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Dec 23, 11:37 AM (11 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1176835
Default Alt Text
(48 KB)
Attached To
Mode
rFRED fred
Attached
Detach File
Event Timeline
Log In to Comment