diff --git a/trunk/dlgpreferences.cpp b/trunk/dlgpreferences.cpp index 085c310..f68df85 100644 --- a/trunk/dlgpreferences.cpp +++ b/trunk/dlgpreferences.cpp @@ -1,200 +1,215 @@ #include "dlgpreferences.h" #include "ui_dlgpreferences.h" #include #include #include #include #include #include #include /******************************************************************************* * Public ******************************************************************************/ DlgPreferences::DlgPreferences(Settings *p_sets, QWidget *p_parent) : QDialog(p_parent), ui(new Ui::DlgPreferences) { ui->setupUi(this); this->p_settings=p_sets; // Load current values this->LoadPreferences(); } DlgPreferences::~DlgPreferences() { delete ui; } /******************************************************************************* * Private slots ******************************************************************************/ void DlgPreferences::on_BtnCancel_clicked() { this->reject(); } void DlgPreferences::on_ListReportLocations_clicked(const QModelIndex &index) { if(!index.isValid()) { // No valid row selected, disable some buttons this->ui->BtnEditReportLoc->setEnabled(false); this->ui->BtnRemoveReportLoc->setEnabled(false); this->ui->BtnMoveReportLocUp->setEnabled(false); this->ui->BtnMoveReportLocDown->setEnabled(false); + this->ui->BtnAddReportLoc->setFocus(); return; } if(this->ui->ListReportLocations->count()==1) { // Only one item left, disable up/down buttons this->ui->BtnEditReportLoc->setEnabled(true); this->ui->BtnRemoveReportLoc->setEnabled(true); this->ui->BtnMoveReportLocUp->setEnabled(false); this->ui->BtnMoveReportLocDown->setEnabled(false); return; } if(index.row()==0) { // First row selected, disable up button + if(this->ui->BtnMoveReportLocUp->hasFocus()) + this->ui->BtnMoveReportLocDown->setFocus(); this->ui->BtnEditReportLoc->setEnabled(true); this->ui->BtnRemoveReportLoc->setEnabled(true); this->ui->BtnMoveReportLocUp->setEnabled(false); this->ui->BtnMoveReportLocDown->setEnabled(true); return; } if(index.row()==(this->ui->ListReportLocations->count()-1)) { // Last row selected, disable down button + if(this->ui->BtnMoveReportLocDown->hasFocus()) + this->ui->BtnMoveReportLocUp->setFocus(); this->ui->BtnEditReportLoc->setEnabled(true); this->ui->BtnRemoveReportLoc->setEnabled(true); this->ui->BtnMoveReportLocUp->setEnabled(true); this->ui->BtnMoveReportLocDown->setEnabled(false); return; } // Any other valid row selected, enable up/down buttons this->ui->BtnEditReportLoc->setEnabled(true); this->ui->BtnRemoveReportLoc->setEnabled(true); this->ui->BtnMoveReportLocUp->setEnabled(true); this->ui->BtnMoveReportLocDown->setEnabled(true); } void DlgPreferences::on_BtnAddReportLoc_clicked() { QString new_loc=QFileDialog::getExistingDirectory(this, tr("Select new report " "directory")); if(!new_loc.isEmpty()) { this->ui->ListReportLocations->addItem(new_loc); } } void DlgPreferences::on_BtnEditReportLoc_clicked() { QModelIndex cur_item=this->ui->ListReportLocations->currentIndex(); if(!cur_item.isValid()) return; // Get selected item QListWidgetItem *p_item=this->ui->ListReportLocations->item(cur_item.row()); // Let user select new directory QString new_loc=QFileDialog::getExistingDirectory(this, tr("Edit report directory"), p_item->text()); if(!new_loc.isEmpty()) { p_item->setText(new_loc); } } void DlgPreferences::on_BtnRemoveReportLoc_clicked() { QModelIndex cur_item=this->ui->ListReportLocations->currentIndex(); if(!cur_item.isValid()) return; QListWidgetItem *p_item= this->ui->ListReportLocations->takeItem(cur_item.row()); delete p_item; // Update buttons this->on_ListReportLocations_clicked( this->ui->ListReportLocations->currentIndex()); } void DlgPreferences::on_BtnMoveReportLocUp_clicked() { QModelIndex cur_item=this->ui->ListReportLocations->currentIndex(); if(!cur_item.isValid() || cur_item.row()==0) return; // Move selected item up QListWidgetItem *p_item= this->ui->ListReportLocations->takeItem(cur_item.row()); this->ui->ListReportLocations->insertItem(cur_item.row()-1,p_item); // Reselect moved item and update buttons this->ui->ListReportLocations->setCurrentItem(p_item); this->on_ListReportLocations_clicked( this->ui->ListReportLocations->currentIndex()); } void DlgPreferences::on_BtnMoveReportLocDown_clicked() { QModelIndex cur_item=this->ui->ListReportLocations->currentIndex(); if(!cur_item.isValid() || cur_item.row()==(this->ui->ListReportLocations->count()-1)) { return; } // Move selected item up QListWidgetItem *p_item= this->ui->ListReportLocations->takeItem(cur_item.row()); this->ui->ListReportLocations->insertItem(cur_item.row()+1,p_item); // Reselect moved item and update buttons this->ui->ListReportLocations->setCurrentItem(p_item); this->on_ListReportLocations_clicked( this->ui->ListReportLocations->currentIndex()); } void DlgPreferences::on_BtnReset_clicked() { if(QMessageBox::warning(this, tr("Reset default settings"), tr("Are you sure to reset all settings to their defaults?"), QMessageBox::No, QMessageBox::Yes)==QMessageBox::Yes) { this->p_settings->Reset(); + this->LoadPreferences(); } } void DlgPreferences::on_BtnOk_clicked() { this->SavePreferences(); this->accept(); } /******************************************************************************* * Private ******************************************************************************/ void DlgPreferences::LoadPreferences() { + // Load general preferences + this->ui->SpinBoxRecentFiles-> + setValue(this->p_settings->GetRecentFilesDepth()); + this->ui->ChkBoxSavePositions-> + setChecked(this->p_settings->GetWindowGeometryStatus()); // Populate report location list this->ui->ListReportLocations->clear(); QStringList report_dirs=this->p_settings->GetReportTemplateDirs(); QListIterator it_report_dirs(report_dirs); if(!report_dirs.isEmpty()) { while(it_report_dirs.hasNext()) { this->ui->ListReportLocations->addItem(it_report_dirs.next()); } this->ui->ListReportLocations->setCurrentRow(0); this->ui->BtnEditReportLoc->setEnabled(true); this->ui->BtnRemoveReportLoc->setEnabled(true); this->ui->BtnMoveReportLocDown->setEnabled(true); } } void DlgPreferences::SavePreferences() { + // Save general preferences + this->p_settings->SetRecentFilesDepth(this->ui->SpinBoxRecentFiles->value()); + this->p_settings->SetWindowGeometryStatus( + this->ui->ChkBoxSavePositions->isChecked()); // Save report location list QStringList report_dirs; for(int i=0;iui->ListReportLocations->count();i++) { report_dirs.append(this->ui->ListReportLocations->item(i)->text()); } this->p_settings->SetReportTemplateDirs(report_dirs); } diff --git a/trunk/dlgpreferences.ui b/trunk/dlgpreferences.ui index ddd0d1a..bf14b80 100644 --- a/trunk/dlgpreferences.ui +++ b/trunk/dlgpreferences.ui @@ -1,224 +1,233 @@ DlgPreferences 0 0 615 404 Preferences :/icons/resources/fred.png:/icons/resources/fred.png 0 General Number of recent files to remember: Save position and size of main window and dialogs: 0 0 true false false Qt::Vertical 20 40 Reports <html><head/><body><p><span style=" font-weight:600;">Warning:</span></p><p>The following list gives you the possibility to add/remove report locations and to change their precedence. Reports are searched and added from top to bottom, thus reports found in later directories replace reports found earlier if they have same name, category and hive! In addition, you may also remove the two default system and user locations which might result in no reports being found at all if you don't have added your own locations.</p></body></html> true Add false Edit false Remove false Move up false Move down Qt::Vertical 20 40 &Cancel Reset to defaults Qt::Horizontal 40 20 &Ok BtnOk BtnCancel + BtnReset tabWidget + SpinBoxRecentFiles + ChkBoxSavePositions + ListReportLocations + BtnAddReportLoc + BtnEditReportLoc + BtnRemoveReportLoc + BtnMoveReportLocUp + BtnMoveReportLocDown diff --git a/trunk/dlgreportchooser.cpp b/trunk/dlgreportchooser.cpp index 535c935..d9852ec 100644 --- a/trunk/dlgreportchooser.cpp +++ b/trunk/dlgreportchooser.cpp @@ -1,163 +1,159 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #include "dlgreportchooser.h" #include "ui_dlgreportchooser.h" #include #include #include #include DlgReportChooser::DlgReportChooser(Reports *p_reps, QString hive_type_string, Settings *p_sets, QWidget *p_parent) : QDialog(p_parent), ui(new Ui::DlgReportChooser) { QStringList tree_cats; QString cur_tree_cat; QTreeWidgetItem *p_tree_cat_widget; QTreeWidgetItem *p_tree_cat_rep_widget; QList tree_cat_reports; ReportTemplate* p_report; // Init private vars this->ui->setupUi(this); this->p_reports=p_reps; this->p_settings=p_sets; this->hive_type=hive_type_string; this->tree_category_items.clear(); this->selected_reports.clear(); // Restore dialog geometry if possible QByteArray geometry=this->p_settings->GetWindowGeometry("DlgReportChooser"); if(!geometry.isEmpty()) this->restoreGeometry(geometry); // Populate tree with reports tree_cats=this->p_reports->GetAvailableReportCategories(); QListIterator tree_cat_it(tree_cats); while(tree_cat_it.hasNext()) { cur_tree_cat=tree_cat_it.next(); p_tree_cat_widget=new QTreeWidgetItem(this->ui->TrReports); p_tree_cat_widget->setText(0,cur_tree_cat); p_tree_cat_widget->setFlags(Qt::ItemIsEnabled| Qt::ItemIsUserCheckable| Qt::ItemIsTristate); p_tree_cat_widget->setCheckState(0,Qt::Unchecked); tree_cat_reports=this->p_reports->GetAvailableReports(cur_tree_cat); QListIterator tree_cat_rep_it(tree_cat_reports); while(tree_cat_rep_it.hasNext()) { p_report=tree_cat_rep_it.next(); p_tree_cat_rep_widget=new QTreeWidgetItem(p_tree_cat_widget); // Save pointer to ReportTemplate alongside p_tree_cat_rep_widget->setData(0, Qt::UserRole, QVariant().fromValue(p_report)); p_tree_cat_rep_widget->setText(0,p_report->Name()); p_tree_cat_rep_widget->setFlags(Qt::ItemIsEnabled| Qt::ItemIsSelectable| Qt::ItemIsUserCheckable); if(this->hive_type!="UNKNOWN" && this->hive_type==p_report->Hive()) { p_tree_cat_rep_widget->setCheckState(0,Qt::Checked); } else { p_tree_cat_rep_widget->setCheckState(0,Qt::Unchecked); } } this->tree_category_items.append(p_tree_cat_widget); } // Finally, expand all categories this->ui->TrReports->expandAll(); } DlgReportChooser::~DlgReportChooser() { + // Save dialog geometry + this->p_settings->SetWindowGeometry("DlgReportChooser",this->saveGeometry()); delete this->ui; } QList DlgReportChooser::GetSelectedReports() { return this->selected_reports; } -void DlgReportChooser::changeEvent(QEvent *e) { - QDialog::changeEvent(e); - switch (e->type()) { +void DlgReportChooser::changeEvent(QEvent *p_event) { + QDialog::changeEvent(p_event); + switch (p_event->type()) { case QEvent::LanguageChange: this->ui->retranslateUi(this); break; default: break; } } -void DlgReportChooser::closeEvent(QCloseEvent *p_event) { - Q_UNUSED(p_event) - - this->p_settings->SaveWindowGeometry("DlgReportChooser",this->saveGeometry()); -} - void DlgReportChooser::on_BtnCancel_clicked() { this->reject(); } void DlgReportChooser::on_TrReports_currentItemChanged( QTreeWidgetItem *p_current, QTreeWidgetItem *p_previous) { Q_UNUSED(p_previous) // If item has no parent, clear labels and return if(p_current->parent()==NULL) { this->ui->LblHive->clear(); this->ui->LblAuthor->clear(); this->ui->LblDesc->clear(); return; } // Update labels this->ui->LblHive->setText( p_current->data(0,Qt::UserRole).value()->Hive()); this->ui->LblAuthor->setText( p_current->data(0,Qt::UserRole).value()->Author()); this->ui->LblDesc->setText( p_current->data(0,Qt::UserRole).value()->Description()); } void DlgReportChooser::on_BtnGenerate_clicked() { QTreeWidgetItem *p_cat; int i; // Add selected reports to selected_reports QListIterator cat_it(this->tree_category_items); while(cat_it.hasNext()) { p_cat=cat_it.next(); for(i=0;ichildCount();i++) { if(p_cat->child(i)->checkState(0)==Qt::Checked) { // Get saved pointer to ReportTemplate and append it to selected_reps this->selected_reports.append(p_cat-> child(i)->data(0,Qt::UserRole).value()); } } } this->accept(); } diff --git a/trunk/dlgreportchooser.h b/trunk/dlgreportchooser.h index 2967169..fb178f4 100644 --- a/trunk/dlgreportchooser.h +++ b/trunk/dlgreportchooser.h @@ -1,66 +1,65 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #ifndef DLGREPORTCHOOSER_H #define DLGREPORTCHOOSER_H #include "reports.h" #include "settings.h" #include #include #include namespace Ui { class DlgReportChooser; } class DlgReportChooser : public QDialog { Q_OBJECT public: explicit DlgReportChooser(Reports *p_reps, QString hive_type_string, Settings *p_sets, QWidget *p_parent=0); ~DlgReportChooser(); QList GetSelectedReports(); protected: - void changeEvent(QEvent *e); - void closeEvent(QCloseEvent *p_event); + void changeEvent(QEvent *p_event); private slots: void on_BtnCancel_clicked(); void on_TrReports_currentItemChanged(QTreeWidgetItem *p_current, QTreeWidgetItem *p_previous); void on_BtnGenerate_clicked(); private: Ui::DlgReportChooser *ui; Reports *p_reports; Settings *p_settings; QString hive_type; QList tree_category_items; QList selected_reports; }; #endif // DLGREPORTCHOOSER_H diff --git a/trunk/dlgreportviewer.cpp b/trunk/dlgreportviewer.cpp index 695632a..c7cbe5f 100644 --- a/trunk/dlgreportviewer.cpp +++ b/trunk/dlgreportviewer.cpp @@ -1,117 +1,116 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #include "dlgreportviewer.h" #include "ui_dlgreportviewer.h" #include #include #include #include #include DlgReportViewer::DlgReportViewer(QString &report_data, Settings *p_sets, 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; this->orig_report_data=report_data; this->p_settings=p_sets; // Try to restore dialog geometry QByteArray geometry=this->p_settings->GetWindowGeometry("DlgReportViewer"); if(!geometry.isEmpty()) this->restoreGeometry(geometry); // Set report content this->ui->WebView->setHtml(report_data); // Set dialog title based on report content title QString report_title=this->ui->WebView->title(); this->setWindowTitle("Report Viewer"); } DlgReportViewer::~DlgReportViewer() { + // Save dialog geometry + this->p_settings->SetWindowGeometry("DlgReportViewer",this->saveGeometry()); 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()) { +void DlgReportViewer::changeEvent(QEvent *p_event) { + QMainWindow::changeEvent(p_event); + switch(p_event->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } -void DlgReportViewer::closeEvent(QCloseEvent *event) { - // Save dialog geometry - this->p_settings->SaveWindowGeometry("DlgReportViewer",this->saveGeometry()); - +void DlgReportViewer::closeEvent(QCloseEvent *p_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(); + p_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(); } void DlgReportViewer::on_action_Save_triggered() { QString filename=QFileDialog::getSaveFileName(this, tr("Save report as"), "", "ODF file (*.odf)"); if(filename!="") { QTextDocument *p_doc=new QTextDocument(this); p_doc->setHtml(this->orig_report_data); QTextDocumentWriter *p_doc_writer=new QTextDocumentWriter(filename); p_doc_writer->setFormat(QByteArray("ODF")); p_doc_writer->write(p_doc); delete p_doc_writer; delete p_doc; } } diff --git a/trunk/dlgreportviewer.h b/trunk/dlgreportviewer.h index 04f8f53..8336028 100644 --- a/trunk/dlgreportviewer.h +++ b/trunk/dlgreportviewer.h @@ -1,62 +1,62 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #ifndef DLGREPORTVIEWER_H #define DLGREPORTVIEWER_H #include "settings.h" #include #include #include namespace Ui { class DlgReportViewer; } class DlgReportViewer : public QMainWindow { Q_OBJECT public: explicit DlgReportViewer(QString &report_data, Settings *p_sets, QWidget *p_parent=0); ~DlgReportViewer(); void exec(); protected: - void changeEvent(QEvent *e); - void closeEvent(QCloseEvent *event); + void changeEvent(QEvent *p_event); + void closeEvent(QCloseEvent *p_event); private slots: void on_action_Print_triggered(); void on_action_Close_triggered(); void on_action_Save_triggered(); private: Ui::DlgReportViewer *ui; QEventLoop *p_local_event_loop; QString orig_report_data; Settings *p_settings; }; #endif // DLGREPORTVIEWER_H diff --git a/trunk/mainwindow.cpp b/trunk/mainwindow.cpp index 4d7c888..05a6bcf 100644 --- a/trunk/mainwindow.cpp +++ b/trunk/mainwindow.cpp @@ -1,681 +1,673 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #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 #include #include #include #include #include #include #include #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 "compileinfo.h" /******************************************************************************* * Public ******************************************************************************/ 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 settings this->p_settings=new Settings(this); // 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(); // 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(); // 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(); - // Set last open location to home dir - this->last_open_location=QDir::homePath(); - // Load report templates - this->p_reports=new Reports(); - this->ReloadReportTemplates(); + 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")); } } 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 ******************************************************************************/ void MainWindow::closeEvent(QCloseEvent *p_event) { Q_UNUSED(p_event) // Save window position and size on exit - this->p_settings->SaveWindowGeometry("MainWindow",this->saveGeometry()); + this->p_settings->SetWindowGeometry("MainWindow",this->saveGeometry()); QMainWindow::closeEvent(p_event); } /******************************************************************************* * Private slots ******************************************************************************/ 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, + this->p_settings->GetLastOpenLocation(), 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_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->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::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 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: "<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); // Set focus back to nodetree to be able to navigate with keyboard this->p_node_tree->setFocus(); } 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::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::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 \ from path path.chop(key.length()+1); } // Expand treeview to correct node QList indexes= this->p_reg_node_tree_model->GetIndexListOf(path); for(i=0;ip_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::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::SlotRecentlyOpenedFileClicked(bool checked) { Q_UNUSED(checked) QAction *p_sender=(QAction*)QObject::sender(); this->OpenHive(p_sender->text()); } /******************************************************************************* * Private ******************************************************************************/ 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::OpenHive(QString hive_file) { // Update last open location - this->last_open_location=hive_file.left(hive_file. - lastIndexOf(QDir::separator())); + 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)) { 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_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); // Update window title this->UpdateWindowTitle(hive_file); // Add file to recent list and update recently opened menu this->p_settings->AddRecentFile(hive_file); this->UpdateRecentlyOpenedMenu(); } -void MainWindow::ReloadReportTemplates() { - QListIterator it(this->p_settings->GetReportTemplateDirs()); - while(it.hasNext()) { - this->p_reports->LoadReportTemplates(it.next()); - } -} - void MainWindow::on_ActionReloadReportTemplates_triggered() { - this->ReloadReportTemplates(); + this->p_reports->LoadReportTemplates(); } void MainWindow::ClearRecentlyOpenedMenu() { QAction *p_action; // Remove existing menu entries QList menu_entries=this->p_recently_opened_menu->actions(); QListIterator it_me(menu_entries); while(it_me.hasNext()) { p_action=it_me.next(); this->p_recently_opened_menu->removeAction(p_action); delete p_action; } } 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 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); } } void MainWindow::on_ActionPreferences_triggered() { DlgPreferences dlg_preferences(this->p_settings,this); dlg_preferences.exec(); + // Update objects and GUI elements which might be affected by new settings + this->UpdateRecentlyOpenedMenu(); + this->p_reports->LoadReportTemplates(); } diff --git a/trunk/mainwindow.h b/trunk/mainwindow.h index 6d3d070..7adfbf8 100644 --- a/trunk/mainwindow.h +++ b/trunk/mainwindow.h @@ -1,121 +1,119 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include #include #include #include #include #include #include "argparser.h" #include "registryhive.h" #include "registrynodetree.h" #include "registrynodetreemodel.h" #include "registrynodetreemodelproxy.h" #include "registrykeytable.h" #include "registrykeytablemodel.h" #include "hexeditwidget.h" #include "reports.h" #include "threadsearch.h" #include "searchresultwidget.h" #include "tabwidget.h" #include "settings.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(ArgParser *p_arg_parser); ~MainWindow(); protected: void closeEvent(QCloseEvent *p_event); 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 on_ActionGenerateReport_triggered(); void on_ActionReloadReportTemplates_triggered(); void SlotNodeTreeClicked(QModelIndex index); void SlotKeyTableClicked(QModelIndex index); void SlotKeyTableDoubleClicked(QModelIndex index); void SlotSearchFinished(); void SlotSearchResultWidgetDoubleClicked(QModelIndex index); void SlotTabCloseButtonClicked(int index); void SlotRecentlyOpenedFileClicked(bool checked); void on_ActionPreferences_triggered(); private: Ui::MainWindow *ui; ArgParser *p_args; - QString last_open_location; RegistryHive *p_hive; bool is_hive_open; QByteArray selected_key_value; QList search_result_widgets; Settings *p_settings; // Models RegistryNodeTreeModel *p_reg_node_tree_model; RegistryNodeTreeModelProxy *p_reg_node_tree_model_proxy; RegistryKeyTableModel *p_reg_key_table_model; // 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; Reports *p_reports; QMenu *p_recently_opened_menu; // Threads ThreadSearch *p_search_thread; // Functions void CheckUserConfigDir(); void UpdateWindowTitle(QString filename=""); void OpenHive(QString hive_file); - void ReloadReportTemplates(); void ClearRecentlyOpenedMenu(); void UpdateRecentlyOpenedMenu(); }; #endif // MAINWINDOW_H diff --git a/trunk/reports.cpp b/trunk/reports.cpp index 15a5b43..62fb8b8 100644 --- a/trunk/reports.cpp +++ b/trunk/reports.cpp @@ -1,183 +1,203 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #include "reports.h" +#include #include #include #include #include /******************************************************************************* * Public ******************************************************************************/ -Reports::Reports() { +Reports::Reports(Settings *p_sets) { + this->p_settings=p_sets; this->p_engine=new ReportEngine(NULL); this->report_templates.clear(); + + if(this->p_settings!=NULL) this->LoadReportTemplates(); } Reports::~Reports() { qDeleteAll(this->report_templates); delete this->p_engine; } -void Reports::LoadReportTemplates(QString dir) { +void Reports::LoadReportTemplates() { + // Delete any previously loaded reports + qDeleteAll(this->report_templates); + this->report_templates.clear(); + + // Return if we have no settings loaded + if(this->p_settings==NULL) return; + + // Load all available reports + QStringList report_dirs=this->p_settings->GetReportTemplateDirs(); + QListIterator report_dir_it(report_dirs); + while(report_dir_it.hasNext()) { + this->LoadReportTemplatesFromDir(report_dir_it.next()); + } +} + +QStringList Reports::GetAvailableReportCategories() { + QStringList ret; + QString cat; + int i; + + ret.clear(); + for(i=0;ireport_templates.count();i++) { + cat=this->report_templates.value(i)->Category(); + if(!ret.contains(cat)) ret.append(cat); + } + ret.sort(); + + return ret; +} + + +QList Reports::GetAvailableReports(QString category) { + QList ret; + QString cat; + int i=0; + + ret.clear(); + for(i=0;ireport_templates.count();i++) { + cat=this->report_templates.value(i)->Category(); + if(cat==category) ret.append(this->report_templates.value(i)); + } + + return ret; +} + +bool Reports::GenerateReport(RegistryHive *p_hive, + QString report_file, + QString &report_result, + bool console_mode) +{ + return this->p_engine->GenerateReport(p_hive, + report_file, + report_result, + console_mode); +} + +bool Reports::GenerateReport(RegistryHive *p_hive, + QList report_list, + QString &report_result, + bool console_mode) +{ + bool ret; + QString res; + + QListIterator rep_it(report_list); + while(rep_it.hasNext()) { + res=""; + ret=this->GenerateReport(p_hive, + rep_it.next()->File(), + res, + console_mode); + if(ret) report_result.append(res); + // TODO: Inform user something didn't work + } + + return true; +} + +/******************************************************************************* + * Private + ******************************************************************************/ + +void Reports::LoadReportTemplatesFromDir(QString dir) { QString report_template=""; QString report_category,report_name,report_author,report_desc,report_hive; bool found; int i; ReportTemplate *p_report; // Get all template files in report_templates directory QDir report_dir(dir); QStringList found_report_templates=report_dir. entryList(QStringList()<<"*.qs"); QListIterator it(found_report_templates); while(it.hasNext()) { // Build path to template file report_template=report_dir.path(); report_template.append(QDir::separator()); report_template.append(it.next()); // Get report info QMap report_info=this->p_engine-> GetReportTemplateInfo(report_template); if(report_info.contains("error")) { // TODO: Inform user qDebug()<<"Error in report '"< FRED_REPORTENGINE_API_VERSION) { // TODO: Inform user qDebug()<<"Report '"<report_templates.count();i++) { if(this->report_templates.at(i)->Category()==report_category && this->report_templates.at(i)->Name()==report_name) { found=true; break; } } // Add to or update report template list if(!found) { // Add report to list p_report=new ReportTemplate(report_template, report_category, report_name, report_author, report_desc, report_hive); this->report_templates.append(p_report); } else { // Update report entry p_report=this->report_templates.at(i); p_report->SetFile(report_template); p_report->SetAuthor(report_author); p_report->SetDescription(report_desc); } } } - -QStringList Reports::GetAvailableReportCategories() { - QStringList ret; - QString cat; - int i; - - ret.clear(); - for(i=0;ireport_templates.count();i++) { - cat=this->report_templates.value(i)->Category(); - if(!ret.contains(cat)) ret.append(cat); - } - ret.sort(); - - return ret; -} - - -QList Reports::GetAvailableReports(QString category) { - QList ret; - QString cat; - int i=0; - - ret.clear(); - for(i=0;ireport_templates.count();i++) { - cat=this->report_templates.value(i)->Category(); - if(cat==category) ret.append(this->report_templates.value(i)); - } - - return ret; -} - -bool Reports::GenerateReport(RegistryHive *p_hive, - QString report_file, - QString &report_result, - bool console_mode) -{ - return this->p_engine->GenerateReport(p_hive, - report_file, - report_result, - console_mode); -} - -bool Reports::GenerateReport(RegistryHive *p_hive, - QList report_list, - QString &report_result, - bool console_mode) -{ - bool ret; - QString res; - - QListIterator rep_it(report_list); - while(rep_it.hasNext()) { - res=""; - ret=this->GenerateReport(p_hive, - rep_it.next()->File(), - res, - console_mode); - if(ret) report_result.append(res); - // TODO: Inform user something didn't work - } - - return true; -} - -/******************************************************************************* - * Private - ******************************************************************************/ diff --git a/trunk/reports.h b/trunk/reports.h index 13fcba3..b3d5fe2 100644 --- a/trunk/reports.h +++ b/trunk/reports.h @@ -1,53 +1,57 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #ifndef REPORTS_H #define REPORTS_H #include "reporttemplate.h" #include "reportengine.h" +#include "settings.h" #include #include #include class Reports { public: - Reports(); + Reports(Settings *p_sets=NULL); ~Reports(); - void LoadReportTemplates(QString dir); + void LoadReportTemplates(); QStringList GetAvailableReportCategories(); QList GetAvailableReports(QString category); bool GenerateReport(RegistryHive *p_hive, QString report_file, QString &report_result, bool console_mode=false); bool GenerateReport(RegistryHive *p_hive, QList report_list, QString &report_result, bool console_mode=false); private: + Settings *p_settings; QList report_templates; ReportEngine *p_engine; + + void LoadReportTemplatesFromDir(QString dir); }; #endif // REPORTS_H diff --git a/trunk/settings.cpp b/trunk/settings.cpp index 78e4cf6..2e2f3ac 100644 --- a/trunk/settings.cpp +++ b/trunk/settings.cpp @@ -1,141 +1,194 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #include "settings.h" #include #ifndef FRED_REPORT_TEMPLATE_DIR #ifndef __MINGW32__ #define SYSTEM_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates" #else #define SYSTEM_REPORT_TEMPLATE_DIR ".\\report_templates\\" #endif #endif #define APP_ORGANIZATION "pinguin.lu" #define APP_NAME "fred" +// Default settings +#define DEFAULT_REPORT_TEMPLATE_DIRS QStringList()<user_report_template_dir +#define DEFAULT_WINDOW_GEOMETRY_STATUS true +#define DEFAULT_RECENT_FILES_DEPTH 5 +#define DEFAULT_LAST_OPEN_LOCATION QDir::homePath() + /******************************************************************************* * Public ******************************************************************************/ Settings::Settings(QObject *p_parent) : QObject(p_parent) { // Init vars this->p_settings=NULL; this->initialized=false; this->user_settings_dir=QDir::homePath() .append(QDir::separator()).append(".fred"); - - - - this->user_report_template_dir=QString(this->user_settings_dir) .append(QDir::separator()) .append("report_templates"); // Make sure config dirs exist if(!QDir(this->user_settings_dir).exists()) { // User config dir does not exists, try to create it if(!QDir().mkpath(this->user_settings_dir)) { // TODO: Maybe warn user return; } } if(!QDir(this->user_report_template_dir).exists()) { // Create config dir sub folder for report templates if(!QDir().mkpath(this->user_report_template_dir)) { // TODO: Maybe warn user return; } } // Create / open settings #ifndef __MINGW32__ // On any Unix-like OS, settings should be saved in the .fred folder this->p_settings=new QSettings(QString(this->user_settings_dir) .append(QDir::separator()) .append("fred.conf"), QSettings::NativeFormat, this); #else // On Windows, it can be stored inside registry this->p_settings=new QSettings(QSettings::NativeFormat, QSettings::UserScope, APP_ORGANIZATION, APP_NAME, this); #endif if(this->p_settings->status()!=QSettings::NoError || !this->p_settings->isWritable()) { return; } this->initialized=true; } void Settings::Reset() { - + if(!this->initialized) return; + // Clear all current settings + this->p_settings->clear(); } void Settings::SetReportTemplateDirs(QStringList &dirs) { + if(!this->initialized) return; this->p_settings->setValue("ReportTemplateDirs",dirs); } QStringList Settings::GetReportTemplateDirs() { - if(!this->initialized) return QStringList(); + if(!this->initialized) return DEFAULT_REPORT_TEMPLATE_DIRS; return this->p_settings->value("ReportTemplateDirs", - QStringList()<user_report_template_dir - ).toStringList(); + DEFAULT_REPORT_TEMPLATE_DIRS).toStringList(); } -void Settings::SaveWindowGeometry(QString window_name, QByteArray geometry) { +void Settings::SetWindowGeometryStatus(bool save) { if(!this->initialized) return; - this->p_settings->setValue(QString("WindowGeometry_%1").arg(window_name), + this->p_settings->setValue("WindowGeometries/EnableSaving",save); +} + +bool Settings::GetWindowGeometryStatus() { + if(!this->initialized) return DEFAULT_WINDOW_GEOMETRY_STATUS; + return this->p_settings->value("WindowGeometries/EnableSaving", + DEFAULT_WINDOW_GEOMETRY_STATUS).toBool(); +} + +void Settings::SetWindowGeometry(QString window_name, QByteArray geometry) { + if(!this->initialized || !this->GetWindowGeometryStatus()) return; + this->p_settings->setValue(QString("WindowGeometries/%1").arg(window_name), geometry); } QByteArray Settings::GetWindowGeometry(QString window_name) { - if(!this->initialized) return QByteArray(); - return this->p_settings->value(QString("WindowGeometry_%1") + if(!this->initialized || !this->GetWindowGeometryStatus()) { + return QByteArray(); + } + return this->p_settings->value(QString("WindowGeometries/%1") .arg(window_name)).toByteArray(); } +void Settings::SetRecentFilesDepth(int depth) { + if(!this->initialized) return; + this->p_settings->setValue("RecentFilesDepth",depth); + // Make sure there are currently not more recent files as allowed + QStringList recent_files=this->GetRecentFiles(); + while(recent_files.count()>depth) recent_files.removeLast(); + this->SetRecentFiles(recent_files); +} + +int Settings::GetRecentFilesDepth() { + if(!this->initialized) return DEFAULT_RECENT_FILES_DEPTH; + return this->p_settings->value("RecentFilesDepth", + DEFAULT_RECENT_FILES_DEPTH).toInt(); +} + +void Settings::SetRecentFiles(QStringList &recent_files) { + if(!this->initialized) return; + this->p_settings->setValue("RecentFiles",recent_files); +} + void Settings::AddRecentFile(QString file) { // Get recent files QStringList recent_files=this->GetRecentFiles(); if(recent_files.contains(file)) { // File already exists in recent list. Simply move it to top recent_files.move(recent_files.indexOf(file),0); } else { - // We only save 5 files at max - if(recent_files.count()==5) recent_files.removeLast(); + // We only save RecentFilesDepth() files at max + while(recent_files.count()>=this->GetRecentFilesDepth()) + recent_files.removeLast(); recent_files.prepend(file); } - this->p_settings->setValue("RecentFiles",recent_files); + this->SetRecentFiles(recent_files); } QStringList Settings::GetRecentFiles() { - return this->p_settings->value("RecentFiles").toStringList(); + if(!this->initialized) return QStringList(); + return this->p_settings->value("RecentFiles",QStringList()).toStringList(); +} + +void Settings::SetLastOpenLocation(QString dir) { + if(!this->initialized) return; + this->p_settings->setValue("LastOpenLocation",dir); +} + +QString Settings::GetLastOpenLocation() { + if(!this->initialized) return DEFAULT_LAST_OPEN_LOCATION; + QString last_loc; + last_loc=this->p_settings->value("RecentFiles", + DEFAULT_LAST_OPEN_LOCATION).toString(); + if(QDir(last_loc).exists()) return last_loc; + else return DEFAULT_LAST_OPEN_LOCATION; } diff --git a/trunk/settings.h b/trunk/settings.h index 4d65a7a..936d70f 100644 --- a/trunk/settings.h +++ b/trunk/settings.h @@ -1,57 +1,62 @@ /******************************************************************************* * fred Copyright (c) 2011-2013 by Gillen Daniel * * * * 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 . * *******************************************************************************/ #ifndef SETTINGS_H #define SETTINGS_H #include #include #include #include #include class Settings : public QObject { Q_OBJECT public: explicit Settings(QObject *p_parent=0); void Reset(); void SetReportTemplateDirs(QStringList &dirs); QStringList GetReportTemplateDirs(); - void SetSaveWindowGeometryStatus(bool save); - bool GetSaveWindowGeometryStatus(); - void SaveWindowGeometry(QString window_name, QByteArray geometry); + void SetWindowGeometryStatus(bool save); + bool GetWindowGeometryStatus(); + void SetWindowGeometry(QString window_name, QByteArray geometry); QByteArray GetWindowGeometry(QString window_name); - void SetRecentFileDepth(int depth); - int GetRecentFileDepth(); + + void SetRecentFilesDepth(int depth); + int GetRecentFilesDepth(); + void SetRecentFiles(QStringList &recent_files); void AddRecentFile(QString file); QStringList GetRecentFiles(); + void SetLastOpenLocation(QString dir); + QString GetLastOpenLocation(); + private: QSettings *p_settings; bool initialized; QString user_settings_dir; QString user_report_template_dir; }; #endif // SETTINGS_H