diff --git a/tags/fred-0.1.0beta1/compileinfo.sh b/tags/fred-0.1.0beta1/compileinfo.sh new file mode 100755 index 0000000..d63ec14 --- /dev/null +++ b/tags/fred-0.1.0beta1/compileinfo.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +echo '// Automatically generated file. See project file and compileinfo.sh for further informations.' +#head -n 1 debian/changelog | awk '{ +# Version = $2 +# gsub ("\\(", "", Version) +# gsub ("\\)", "", Version) +# print "const char *pCompileInfoVersion = \"" Version "\";"}' + +echo '#define APP_NAME "fred"' +echo '#define APP_TITLE "Forensic Registry EDitor (fred)"' +echo '#define APP_COPYRIGHT "Copyright (c) 2011 by Gillen Daniel"' +echo '#define APP_DEVELOPPER_EMAIL "gillen.dan@pinguin.lu"' +echo '#define APP_DESCRIPTION "Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor with special feautures useful during forensic analysis."' +date '+#define APP_COMPILETIME "%Y/%m/%d %H:%M:%S"' + +GOT_VERSION=0 + +if [[ $GOT_VERSION -eq 0 && -f debian/changelog ]]; then + # Get version and release timestamp from debian/changelog file + CUR_LINE=0 + while read LINE; do + CUR_LINE=$(($CUR_LINE+1)) + if [ $CUR_LINE -eq 1 ]; then + # first line contains version + echo "$LINE" | awk '{ Version = $2 + gsub ("\\(", "", Version) + gsub ("\\)", "", Version) + print "#define APP_VERSION \"" Version "\"" }' + break + fi + done * +* * +* 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 "datainterpreter.h" + +#include +#include + +DataInterpreter::DataInterpreter(QWidget *p_parent) + : QTableWidget(p_parent) +{ + this->setColumnCount(2); + this->setTextElideMode(Qt::ElideNone); + this->horizontalHeader()->setHidden(true); + this->verticalHeader()->setHidden(true); +} + +DataInterpreter::~DataInterpreter() { + // Free table widget items + this->ClearValues(); +} + +void DataInterpreter::AddValue(QString name, QString value) { + QTableWidgetItem *p_name_item=new QTableWidgetItem(name); + QTableWidgetItem *p_value_item=new QTableWidgetItem(value); + this->setRowCount(this->rowCount()+1); + this->setItem(this->rowCount()-1,0,p_name_item); + this->setItem(this->rowCount()-1,1,p_value_item); + this->resizeColumnsToContents(); + this->resizeRowsToContents(); +} + +void DataInterpreter::ClearValues() { + // Free all items + while(this->rowCount()>0) { + delete this->item(0,0); + delete this->item(0,1); + this->setRowCount(this->rowCount()-1); + } +} + +int DataInterpreter::sizeHintForColumn(int column) const { + int size_hint=0; + int i=0; + int item_width=0; + QFontMetrics fm(this->fontMetrics()); + + // Find string that needs the most amount of space + for(i=0;irowCount();i++) { + item_width=fm.width(this->item(i,column)->text())+10; + if(item_width>size_hint) size_hint=item_width; + } + + return size_hint; +} diff --git a/tags/fred-0.1.0beta1/datainterpreter.h b/tags/fred-0.1.0beta1/datainterpreter.h new file mode 100644 index 0000000..2f237fe --- /dev/null +++ b/tags/fred-0.1.0beta1/datainterpreter.h @@ -0,0 +1,57 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 DATAINTERPRETER_H +#define DATAINTERPRETER_H + +#include +#include + +class DataInterpreter : public QTableWidget { + Q_OBJECT + + public: + DataInterpreter(QWidget *p_parent=0); + ~DataInterpreter(); + + /* + * AddValue + * + * Add a value pair (name,value) to data interprter. + */ + void AddValue(QString name, QString value); + /* + * ClearValues + * + * Remove all value pairs from table + */ + void ClearValues(); + + protected: + /* + * sizeHintForColumn + * + * Needed reimplementation in order to allow resizeColumnsToContent + * to resize hidden columns too. + */ + int sizeHintForColumn(int column) const; +}; + +#endif // DATAINTERPRETER_H diff --git a/tags/fred-0.1.0beta1/datareporter.cpp b/tags/fred-0.1.0beta1/datareporter.cpp new file mode 100644 index 0000000..10072dc --- /dev/null +++ b/tags/fred-0.1.0beta1/datareporter.cpp @@ -0,0 +1,152 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "datareporter.h" + +#include +#include +#include +#include + +DataReporter::DataReporter() { + this->report_templates.clear(); + //this->p_report_engine=new DataReporterEngine(); +} + +DataReporter::~DataReporter() { + //delete this->p_report_engine; + qDeleteAll(this->report_templates); +} + +void DataReporter::LoadReportTemplates(QString dir) { + QString report_template=""; + int i=0; + QString report_category=""; + QString report_name=""; + ReportTemplate *p_report; + + // Get all template files in report_templates directory + QDir report_dir(dir); + QStringList found_report_templates=report_dir. + entryList(QStringList()<<"*.qs"); + + for(i=0;i_.qs) + report_category=found_report_templates.value(i).left( + found_report_templates.value(i).indexOf("_")); + report_name=found_report_templates.value(i).mid( + found_report_templates.value(i).indexOf("_")+1); + report_name=report_name.left(report_name.lastIndexOf(".")); + + // Add report to list + p_report=new ReportTemplate(report_category, + report_name, + report_template); + this->report_templates.append(p_report); + } +} + +QStringList DataReporter::GetAvailableReportCategories() { + QStringList ret; + QString cat; + int i=0; + + 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; +} + +QStringList DataReporter::GetAvailableReports(QString category) { + QStringList 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)->Name()); + } + ret.sort(); + + return ret; +} + +QString DataReporter::GenerateReport(RegistryHive *p_hive, + QString report_category, + QString report_name) +{ + int i=0; + ReportTemplate *p_report; + DataReporterEngine engine(p_hive); + QString report_code; + //ReportData report_data; + + for(i=0;ireport_templates.count();i++) { + p_report=this->report_templates.value(i); + if(p_report->Category()!=report_category || p_report->Name()!=report_name) { + continue; + } + + QScriptValue hive_value=engine.newQObject(p_hive); + engine.globalObject().setProperty("RegistryHive",hive_value); + //QScriptValue return_value=engine.newQObject(&report_data); + //engine.globalObject().setProperty("ReportData",return_value); + + // Open report template + QFile template_file(p_report->File()); + if(!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug("Couldn't open file '%s'",p_report->File().toAscii().constData()); + return QString(); + } + // Read template file + QTextStream in(&template_file); + while(!in.atEnd()) { + report_code.append(in.readLine()).append("\n"); + } + // Close report template file + template_file.close(); + + QScriptValue report_result=engine.evaluate(report_code,p_report->File()); + + if (report_result.isError() || engine.hasUncaughtException()) { + QMessageBox::critical(0, + "Hello Script", + QString::fromLatin1("%0:%1: %2") + .arg(p_report->File()) + .arg(report_result.property("lineNumber").toInt32()) + .arg(report_result.toString())); + return QString(); + } + + return engine.report_content; + } + + return QString(); +} diff --git a/tags/fred-0.1.0beta1/datareporter.h b/tags/fred-0.1.0beta1/datareporter.h new file mode 100644 index 0000000..e9e887f --- /dev/null +++ b/tags/fred-0.1.0beta1/datareporter.h @@ -0,0 +1,48 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 DATAREPORTER_H +#define DATAREPORTER_H + +#include + +#include "reporttemplate.h" +#include "datareporterengine.h" +#include "registryhive.h" + +class DataReporter { + public: + DataReporter(); + ~DataReporter(); + + void LoadReportTemplates(QString dir); + QStringList GetAvailableReportCategories(); + QStringList GetAvailableReports(QString category); + + QString GenerateReport(RegistryHive *p_hive, + QString report_category, + QString report_name); + + private: + QList report_templates; + //DataReporterEngine *p_report_engine; +}; + +#endif // DATAREPORTER_H diff --git a/tags/fred-0.1.0beta1/datareporterengine.cpp b/tags/fred-0.1.0beta1/datareporterengine.cpp new file mode 100644 index 0000000..4b43e68 --- /dev/null +++ b/tags/fred-0.1.0beta1/datareporterengine.cpp @@ -0,0 +1,383 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "datareporterengine.h" + +#include +#include +#include +#include +#include + +DataReporterEngine::DataReporterEngine(RegistryHive *p_hive) : QScriptEngine() { + // Init vars + this->p_registry_hive=p_hive; + this->report_content=""; + + // Add our types to engine + qScriptRegisterMetaType(this, + this->RegistryKeyValueToScript, + this->RegistryKeyValueFromScript); + this->p_type_byte_array=new ByteArray(this); + this->globalObject().setProperty("ByteArray", + this->p_type_byte_array->constructor()); + + // Add our functions + // print + QScriptValue func_print=this->newFunction(this->Print); + this->globalObject().setProperty("print",func_print); + // println + QScriptValue func_println=this->newFunction(this->PrintLn); + this->globalObject().setProperty("println",func_println); + // GetRegistryNodes + QScriptValue func_get_nodes=this->newFunction(this->GetRegistryNodes,1); + func_get_nodes.setData(this->newQObject(this->p_registry_hive)); + this->globalObject().setProperty("GetRegistryNodes",func_get_nodes); + // GetRegistryKeys + QScriptValue func_get_keys=this->newFunction(this->GetRegistryKeys,1); + func_get_keys.setData(this->newQObject(this->p_registry_hive)); + this->globalObject().setProperty("GetRegistryKeys",func_get_keys); + // GetRegistryKeyValue + QScriptValue func_get_key_value=this->newFunction(this->GetRegistryKeyValue, + 2); + func_get_key_value.setData(this->newQObject(this->p_registry_hive)); + this->globalObject().setProperty("GetRegistryKeyValue",func_get_key_value); + // RegistryKeyValueToString + QScriptValue func_value_to_string= + this->newFunction(this->RegistryKeyValueToString,2); + this->globalObject().setProperty("RegistryKeyValueToString", + func_value_to_string); + // RegistryKeyValueToVariant + QScriptValue func_value_to_variant= + this->newFunction(this->RegistryKeyValueToVariant); + this->globalObject().setProperty("RegistryKeyValueToVariant", + func_value_to_variant); + // RegistryKeyTypeToString + QScriptValue func_type_to_string= + this->newFunction(this->RegistryKeyTypeToString,1); + this->globalObject().setProperty("RegistryKeyTypeToString", + func_type_to_string); + +/* + // Add RegistryHive object + QScriptValue obj_registry_hive=this->newQObject(this->p_registry_hive); + this->globalObject().setProperty("RegistryHive",obj_registry_hive); +*/ +} + +DataReporterEngine::~DataReporterEngine() { + delete this->p_type_byte_array; +} + +QScriptValue DataReporterEngine::Print(QScriptContext *context, + QScriptEngine *engine) +{ + int i; + QString content; + + // Append all arguments to content + for(i=0;iargumentCount();++i) { + //if(i>0) content.append(" "); + content.append(context->argument(i).toString()); + } + + //QScriptValue calleeData=context->callee().data(); + //DataReporterEngine *engine= + // qobject_cast(calleeData.toQObject()); + qobject_cast(engine)->report_content.append(content); + + return engine->undefinedValue(); +} + +QScriptValue DataReporterEngine::PrintLn(QScriptContext *context, + QScriptEngine *engine) +{ + int i; + QString content; + + // Append all arguments to content + for(i=0;iargumentCount();++i) { + //if(i>0) content.append(" "); + content.append(context->argument(i).toString()); + } + + qobject_cast(engine)-> + report_content.append(content).append("\n"); + + return engine->undefinedValue(); +} + +/* + * GetRegistryNodes + */ +QScriptValue DataReporterEngine::GetRegistryNodes(QScriptContext *context, + QScriptEngine *engine) +{ + QScriptValue calleeData; + RegistryHive *p_hive; + QMap nodes; + QScriptValue ret_nodes; + int ii=0; + + // This function needs one argument, parent node path + if(context->argumentCount()!=1) return engine->undefinedValue(); + + // Get calle data (Pointer to RegistryHive class) + calleeData=context->callee().data(); + p_hive=qobject_cast(calleeData.toQObject()); + + // Get nodes + nodes=p_hive->GetNodes(context->argument(0).toString()); + if(p_hive->Error()) { + // Clear error state + p_hive->GetErrorMsg(); + return engine->undefinedValue(); + } + + // Build script array + ret_nodes=engine->newArray(nodes.count()); + QMapIterator i(nodes); + while(i.hasNext()) { + i.next(); + ret_nodes.setProperty(ii++,QScriptValue(i.key())); + } + + return ret_nodes; +} + +/* + * GetRegistryKeys + */ +QScriptValue DataReporterEngine::GetRegistryKeys(QScriptContext *context, + QScriptEngine *engine) +{ + QScriptValue calleeData; + RegistryHive *p_hive; + QMap keys; + QScriptValue ret_keys; + int ii=0; + + // This function needs one argument, parent node path + if(context->argumentCount()!=1) return engine->undefinedValue(); + + // Get calle data (Pointer to RegistryHive class) + calleeData=context->callee().data(); + p_hive=qobject_cast(calleeData.toQObject()); + + // Get keys + keys=p_hive->GetKeys(context->argument(0).toString()); + if(p_hive->Error()) { + // Clear error state + p_hive->GetErrorMsg(); + return engine->undefinedValue(); + } + + // Build script array + ret_keys=engine->newArray(keys.count()); + QMapIterator i(keys); + while(i.hasNext()) { + i.next(); + ret_keys.setProperty(ii++,QScriptValue(i.key())); + } + + return ret_keys; +} + +/* + * RegistryKeyValueToScript + */ +QScriptValue DataReporterEngine::RegistryKeyValueToScript(QScriptEngine *engine, + const + s_RegistryKeyValue + &s) +{ + QScriptValue obj=engine->newObject(); + obj.setProperty("type",s.type); + obj.setProperty("length",s.length); + ByteArray *p_byte_array=new ByteArray(engine); + obj.setProperty("value",p_byte_array->newInstance(s.value)); + return obj; +} + +/* + * RegistryKeyValueFromScriptValue + */ +void DataReporterEngine::RegistryKeyValueFromScript(const QScriptValue &obj, + s_RegistryKeyValue &s) +{ + s.type=obj.property("type").toInt32(); + s.length=obj.property("length").toInt32(); + // TODO: Don't know if this works, but it probably does ;) + s.value=qvariant_cast(obj.property("value").data().toVariant()); +} + +QScriptValue DataReporterEngine::GetRegistryKeyValue(QScriptContext *context, + QScriptEngine *engine) +{ + QScriptValue calleeData; + RegistryHive *p_hive; + QByteArray key_value; + int key_type=0; + size_t key_length=0; + s_RegistryKeyValue script_key_value; + + // This function needs two arguments, key path and key name + if(context->argumentCount()!=2) return engine->undefinedValue(); + + // Get calle data (Pointer to RegistryHive class) + calleeData=context->callee().data(); + p_hive=qobject_cast(calleeData.toQObject()); + + // Get key value + key_value=p_hive->GetKeyValue(context->argument(0).toString(), + context->argument(1).toString(), + &key_type, + &key_length); + if(p_hive->Error()) { + // Get error message to clear error state + p_hive->GetErrorMsg(); + return engine->undefinedValue(); + } + + // Save key value to s_RegistryKeyValue struct + script_key_value.type=key_type; + script_key_value.length=key_length; + script_key_value.value=key_value; + + return DataReporterEngine::RegistryKeyValueToScript(engine,script_key_value); +} + +QScriptValue DataReporterEngine::RegistryKeyValueToString( + QScriptContext *context, + QScriptEngine *engine) +{ + QByteArray key_value; + QString ret=""; + + // This function needs two arguments, key value and value type + if(context->argumentCount()!=2) return engine->undefinedValue(); + + // Cast ByteArray argument to QByteArray and convert + key_value=qvariant_cast(context->argument(0).data().toVariant()); + ret=RegistryHive::KeyValueToString(key_value, + context->argument(1).toInt32()); + + return engine->newVariant(ret); +} + +QScriptValue DataReporterEngine::RegistryKeyValueToVariant( + QScriptContext *context, + QScriptEngine *engine) +{ + int offset=0; + int length=0; + QByteArray key_value; + QString variant_type; + int remaining_data_len; + const char *p_data; + QString ret=""; + + // This function needs at least two arguments, key value and variant type, + // and may have two optional arguments, offset and length + if(context->argumentCount()<2 || context->argumentCount()>4) { + return engine->undefinedValue(); + } + if(context->argumentCount()==3) { + offset=context->argument(2).toInt32(); + length=-1; + } + if(context->argumentCount()==4) { + offset=context->argument(2).toInt32(); + length=context->argument(3).toInt32(); + } + + + // Cast ByteArray argument to QByteArray + key_value=qvariant_cast(context->argument(0).data().toVariant()); + variant_type=context->argument(1).toString(); + + // Calculate how many bytes are remainig after specified offset + remaining_data_len=key_value.size()-offset; + if(!remaining_data_len>0) { + // Nothing to show + return engine->undefinedValue(); + } + + // Get pointer to data at specified offset + p_data=key_value.constData(); + p_data+=offset; + + // ConvertFull name + if(variant_type=="int8" && remaining_data_len>=1) { + ret=QString().sprintf("%d",*(int8_t*)p_data); + } else if(variant_type=="uint8" && remaining_data_len>=1) { + ret=QString().sprintf("%u",*(uint8_t*)p_data); + } else if(variant_type=="int16" && remaining_data_len>=2) { + ret=QString().sprintf("%d",*(int16_t*)p_data); + } else if(variant_type=="uint16" && remaining_data_len>=2) { + ret=QString().sprintf("%u",*(uint16_t*)p_data); + } else if(variant_type=="int32" && remaining_data_len>=4) { + ret=QString().sprintf("%d",*(int32_t*)p_data); + } else if(variant_type=="uint32" && remaining_data_len>=4) { + ret=QString().sprintf("%u",*(uint32_t*)p_data); + } else if(variant_type=="unixtime" && remaining_data_len>=4) { + if(*(uint32_t*)p_data==0) { + ret="n/a"; + } else { + QDateTime date_time; + date_time.setTime_t(*(uint32_t*)p_data); + ret=date_time.toString("yyyy/MM/dd hh:mm:ss"); + } + } else if(variant_type=="filetime" && remaining_data_len>=8) { + if(*(uint64_t*)p_data==0) { + ret="n/a"; + } else { + // TODO: Warn if >32bit + QDateTime date_time; + date_time.setTime_t((*(uint64_t*)p_data-116444736000000000)/10000000); + ret=date_time.toString("yyyy/MM/dd hh:mm:ss"); + } + } else if(variant_type=="ascii") { + // TODO: This fails bad if the string is not null terminated!! It might be + // wise checking for a null char here + ret=QString().fromAscii((char*)p_data,length); + } else if(variant_type=="utf16" && remaining_data_len>=2) { + ret=QString().fromUtf16((ushort*)p_data,length); + } else { + // Unknown variant type or another error + return engine->undefinedValue(); + } + + return engine->newVariant(ret); +} + +QScriptValue DataReporterEngine::RegistryKeyTypeToString( + QScriptContext *context, + QScriptEngine *engine) +{ + QString ret=""; + + // This function needs one arguments, key type + if(context->argumentCount()!=1) return engine->undefinedValue(); + + ret=RegistryHive::KeyTypeToString(context->argument(0).toInt32()); + + return engine->newVariant(ret); +} diff --git a/tags/fred-0.1.0beta1/datareporterengine.h b/tags/fred-0.1.0beta1/datareporterengine.h new file mode 100644 index 0000000..fae13d8 --- /dev/null +++ b/tags/fred-0.1.0beta1/datareporterengine.h @@ -0,0 +1,74 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 DATAREPORTERENGINE_H +#define DATAREPORTERENGINE_H + +#include +#include +#include +#include +#include + +#include "registryhive.h" +#include "qtscript_types/bytearray.h" + +class DataReporterEngine : public QScriptEngine { + Q_OBJECT + + public: + struct s_RegistryKeyValue { + int type; + int length; + QByteArray value; + }; + + RegistryHive *p_registry_hive; + QString report_content; + + DataReporterEngine(RegistryHive *p_hive); + ~DataReporterEngine(); + + private: + ByteArray *p_type_byte_array; + + static QScriptValue Print(QScriptContext *context, QScriptEngine *engine); + static QScriptValue PrintLn(QScriptContext *context, QScriptEngine *engine); + static QScriptValue GetRegistryNodes(QScriptContext *context, + QScriptEngine *engine); + static QScriptValue GetRegistryKeys(QScriptContext *context, + QScriptEngine *engine); + static QScriptValue RegistryKeyValueToScript(QScriptEngine *engine, + const s_RegistryKeyValue &s); + static void RegistryKeyValueFromScript(const QScriptValue &obj, + s_RegistryKeyValue &s); + static QScriptValue GetRegistryKeyValue(QScriptContext *context, + QScriptEngine *engine); + static QScriptValue RegistryKeyValueToString(QScriptContext *context, + QScriptEngine *engine); + static QScriptValue RegistryKeyValueToVariant(QScriptContext *context, + QScriptEngine *engine); + static QScriptValue RegistryKeyTypeToString(QScriptContext *context, + QScriptEngine *engine); +}; + +Q_DECLARE_METATYPE(DataReporterEngine::s_RegistryKeyValue) + +#endif // DATAREPORTERENGINE_H diff --git a/trunk/debian/changelog b/tags/fred-0.1.0beta1/debian/changelog similarity index 74% copy from trunk/debian/changelog copy to tags/fred-0.1.0beta1/debian/changelog index 9edc012..9240078 100644 --- a/trunk/debian/changelog +++ b/tags/fred-0.1.0beta1/debian/changelog @@ -1,18 +1,24 @@ +fred (0.1.0beta1) unstable; urgency=low + + * Fixed some minor bugs and added more report templates + + -- Daniel Gillen Mon, 22 Aug 2011 08:00:00 +0200 + fred (0.1.0alpha3) unstable; urgency=low * Added data report engine and 2 basic report templates -- Daniel Gillen Wed, 17 Aug 2011 11:30:00 +0200 fred (0.1.0alpha2) unstable; urgency=low * Integrated hexeditor into main windows. * Added data interpreters -- Daniel Gillen Tue, 09 Aug 2011 17:00:00 +0200 fred (0.1.0alpha1) unstable; urgency=low * First public release -- Daniel Gillen Sat, 06 Aug 2011 22:00:00 +0200 diff --git a/tags/fred-0.1.0beta1/debian/compat b/tags/fred-0.1.0beta1/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/tags/fred-0.1.0beta1/debian/compat @@ -0,0 +1 @@ +5 diff --git a/tags/fred-0.1.0beta1/debian/control b/tags/fred-0.1.0beta1/debian/control new file mode 100644 index 0000000..65b1f45 --- /dev/null +++ b/tags/fred-0.1.0beta1/debian/control @@ -0,0 +1,27 @@ +Source: fred +Section: x11 +Priority: optional +Maintainer: Gillen Daniel +Uploaders: Gillen Daniel +Build-Depends: debhelper (>= 5), libqt4-dev, libhivex-dev +Standards-Version: 3.8.2 +Homepage: https://www.pinguin.lu + +Package: fred +Architecture: any +Depends: ${shlibs:Depends} +Recommends: fred-reports +Description: Forensic Registry EDitor + Forensic Registry EDitor (fred) is a cross-platform M$ registry + hive editor with special feautures useful during forensic + analysis. + +Package: fred-reports +Architecture: any +Depends: ${shlibs:Depends} +Description: Forensic Registry EDitor + Forensic Registry EDitor (fred) is a cross-platform M$ registry + hive editor with special feautures useful during forensic + analysis. + + This package contains the report-templates for fred. diff --git a/tags/fred-0.1.0beta1/debian/copyright b/tags/fred-0.1.0beta1/debian/copyright new file mode 100644 index 0000000..d9710fd --- /dev/null +++ b/tags/fred-0.1.0beta1/debian/copyright @@ -0,0 +1,28 @@ +This package was debianised by Daniel Gillen + +Upstream Author: Daniel Gillen + +Copyright: Copyright (c) 2001 by Daniel Gillen + +License: + + This package 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 2 of the License, or + (at your option) any later version. + + This package 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 package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL-2'. + +The Debian packaging is © 2008 by Guy Voncken +and © 2009 by Michael Prokop +and is licensed under the GPL, see above. diff --git a/tags/fred-0.1.0beta1/debian/fred-reports.install b/tags/fred-0.1.0beta1/debian/fred-reports.install new file mode 100644 index 0000000..d406d30 --- /dev/null +++ b/tags/fred-0.1.0beta1/debian/fred-reports.install @@ -0,0 +1,7 @@ +report_templates/NTUSER_RecentDocs.qs usr/share/fred/report_templates/ +report_templates/NTUSER_TypedUrls.qs usr/share/fred/report_templates/ +report_templates/SAM_UserAccounts.qs usr/share/fred/report_templates/ +report_templates/SOFTWARE_WindowsVersion.qs usr/share/fred/report_templates/ +report_templates/SYSTEM_CurrentNetworkSettings.qs usr/share/fred/report_templates/ +report_templates/SYSTEM_SystemTimeInfo.qs usr/share/fred/report_templates/ +report_templates/SYSTEM_UsbStorageDevices.qs usr/share/fred/report_templates/ diff --git a/tags/fred-0.1.0beta1/debian/fred.dirs b/tags/fred-0.1.0beta1/debian/fred.dirs new file mode 100644 index 0000000..7344f38 --- /dev/null +++ b/tags/fred-0.1.0beta1/debian/fred.dirs @@ -0,0 +1,4 @@ +usr/bin +usr/share/applications +usr/share/pixmaps +usr/share/fred diff --git a/tags/fred-0.1.0beta1/debian/fred.install b/tags/fred-0.1.0beta1/debian/fred.install new file mode 100644 index 0000000..7b9c38e --- /dev/null +++ b/tags/fred-0.1.0beta1/debian/fred.install @@ -0,0 +1,2 @@ +resources/fred.desktop usr/share/applications/ +resources/fred.png usr/share/pixmaps/ diff --git a/tags/fred-0.1.0beta1/debian/fred.menu b/tags/fred-0.1.0beta1/debian/fred.menu new file mode 100644 index 0000000..0e5adb1 --- /dev/null +++ b/tags/fred-0.1.0beta1/debian/fred.menu @@ -0,0 +1,3 @@ +?package(fred):needs="X11" section="Applications/System/Security"\ + title="fred" command="/usr/bin/fred"\ + hints="System" diff --git a/tags/fred-0.1.0beta1/debian/rules b/tags/fred-0.1.0beta1/debian/rules new file mode 100755 index 0000000..690dd2d --- /dev/null +++ b/tags/fred-0.1.0beta1/debian/rules @@ -0,0 +1,98 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + qmake-qt4 DEFINES+="FRED_REPORT_TEMPLATE_DIR=\'\\\"/usr/share/fred/report_templates\\\"\'" + + touch configure-stamp + + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + # Optimised make for fast compilation on multi-core machines + $(MAKE) -j$(shell cat /proc/cpuinfo | grep ^processor | wc -l) + lrelease fred.pro + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + # dpkg-buildpackage starts with cleaning, so we have to be sure that there's a Makefile (and thus call qmake-qt4) + qmake-qt4 + + # Add here commands to clean up after the build process. + $(MAKE) clean + # remove leftover files: + rm -f fred + rm -f compileinfo.cpp + #rm -f fred_*.qm + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/fred. + # $(MAKE) DESTDIR=$(CURDIR)/debian/fred install + + cp fred debian/fred/usr/bin + #cp fred_*.qm debian/fred/usr/share/fred + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs +# dh_installdocs +# dh_installexamples + dh_install + dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo +# dh_installman + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure + diff --git a/tags/fred-0.1.0beta1/dlgabout.cpp b/tags/fred-0.1.0beta1/dlgabout.cpp new file mode 100644 index 0000000..8811001 --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgabout.cpp @@ -0,0 +1,72 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "dlgabout.h" +#include "ui_dlgabout.h" + +#include "compileinfo.h" + +DlgAbout::DlgAbout(QWidget *parent) : + QDialog(parent), + m_ui(new Ui::DlgAbout) +{ + m_ui->setupUi(this); + this->setWindowTitle(tr("About %1").arg(APP_NAME)); + + // Update dialog with current infos + this->m_ui->LblAbout->setText( + this->m_ui->LblAbout->text().replace("%APP_NAME%",APP_NAME)); + this->m_ui->LblAbout->setText( + this->m_ui->LblAbout->text().replace("%APP_COPYRIGHT%",APP_COPYRIGHT)); + this->m_ui->TextEditInfo->setPlainText( + this->m_ui->TextEditInfo->toPlainText().replace("%APP_NAME%",APP_NAME)); + this->m_ui->TextEditInfo->setPlainText( + this->m_ui->TextEditInfo->toPlainText().replace("%APP_VERSION%", + APP_VERSION)); + this->m_ui->TextEditInfo->setPlainText( + this->m_ui->TextEditInfo->toPlainText().replace("%APP_DESCRIPTION%", + APP_DESCRIPTION)); + this->m_ui->TextEditCopyright->setPlainText( + this->m_ui->TextEditCopyright->toPlainText().replace("%APP_COPYRIGHT%", + APP_COPYRIGHT)); + this->m_ui->TextEditCopyright->setPlainText( + this->m_ui->TextEditCopyright->toPlainText() + .replace("%APP_DEVELOPPER_EMAIL%", + APP_DEVELOPPER_EMAIL)); +} + +DlgAbout::~DlgAbout() { + delete m_ui; +} + +void DlgAbout::changeEvent(QEvent *e) { + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + m_ui->retranslateUi(this); + break; + default: + break; + } +} + +void DlgAbout::on_btnClose_clicked() { + this->accept(); +} diff --git a/tags/fred-0.1.0beta1/dlgabout.h b/tags/fred-0.1.0beta1/dlgabout.h new file mode 100644 index 0000000..82363e5 --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgabout.h @@ -0,0 +1,47 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 DLGABOUT_H +#define DLGABOUT_H + +#include + +namespace Ui { + class DlgAbout; +} + +class DlgAbout : public QDialog { + Q_OBJECT + + public: + DlgAbout(QWidget *parent = 0); + ~DlgAbout(); + + protected: + void changeEvent(QEvent *e); + + private: + Ui::DlgAbout *m_ui; + + private slots: + void on_btnClose_clicked(); +}; + +#endif // DLGABOUT_H diff --git a/tags/fred-0.1.0beta1/dlgabout.ui b/tags/fred-0.1.0beta1/dlgabout.ui new file mode 100644 index 0000000..1d70be4 --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgabout.ui @@ -0,0 +1,807 @@ + + + DlgAbout + + + + 0 + 0 + 540 + 363 + + + + Dialog + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + + + + 80 + 80 + + + + + + + :/icons/resources/fred.png + + + true + + + + + + + QFrame::NoFrame + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Droid Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:12pt; font-weight:600;">About %APP_NAME%</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">%APP_COPYRIGHT%</span></p></body></html> + + + 0 + + + 10 + + + + + + + + + + 0 + + + + Info + + + + + + + 500 + 0 + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">%APP_NAME% version %APP_VERSION%</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">%APP_DESCRIPTION%</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">%APP_NAME% is licensed under GPLv3.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Look at the documentation, the source code or the %APP_NAME% website (https://www.pinguin.lu) for more information.</span></p></body></html> + + + + + + + + Copyright + + + + + + + 500 + 0 + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">%APP_COPYRIGHT% &lt;%APP_DEVELOPPER_EMAIL%&gt;</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">This program uses </span><span style=" font-family:'Droid Sans';">Richard W.M. Jones's</span><span style=" font-family:'Sans Serif'; font-size:9pt;"> hivex library</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Copyright (C) 2009-2010 Red Hat Inc.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Derived from code by Petter Nordahl-Hagen under a compatible license:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Copyright (C) 1997-2007 Petter Nordahl-Hagen.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Derived from code by Markus Stephany under a compatible license:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Copyright (C) 2000-2004 Markus Stephany.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans';"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">This program uses a derived version of the QHexEdit widget by Simon Winfried under a compatible license:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Droid Sans';"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Droid Sans';">Copyright (c) 2010 by Simon Winfried</span></p></body></html> + + + + + + + + GPL + + + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Version 3, 29 June 2007</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Everyone is permitted to copy and distribute verbatim copies</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> of this license document, but changing it is not allowed.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Preamble</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The GNU General Public License is a free, copyleft license for</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">software and other kinds of works.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The licenses for most software and other practical works are designed</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">to take away your freedom to share and change the works. By contrast,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the GNU General Public License is intended to guarantee your freedom to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">share and change all versions of a program--to make sure it remains free</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">software for all its users. We, the Free Software Foundation, use the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">GNU General Public License for most of our software; it applies also to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">any other work released this way by its authors. You can apply it to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">your programs, too.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> When we speak of free software, we are referring to freedom, not</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">price. Our General Public Licenses are designed to make sure that you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">have the freedom to distribute copies of free software (and charge for</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">them if you wish), that you receive source code or can get it if you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">want it, that you can change the software or use pieces of it in new</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">free programs, and that you know you can do these things.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> To protect your rights, we need to prevent others from denying you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">these rights or asking you to surrender the rights. Therefore, you have</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">certain responsibilities if you distribute copies of the software, or if</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">you modify it: responsibilities to respect the freedom of others.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> For example, if you distribute copies of such a program, whether</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">gratis or for a fee, you must pass on to the recipients the same</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">freedoms that you received. You must make sure that they, too, receive</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">or can get the source code. And you must show them these terms so they</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">know their rights.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">(1) assert copyright on the software, and (2) offer you this License</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> For the developers' and authors' protection, the GPL clearly explains</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">that there is no warranty for this free software. For both users' and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">authors' sake, the GPL requires that modified versions be marked as</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">changed, so that their problems will not be attributed erroneously to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">authors of previous versions.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Some devices are designed to deny users access to install or run</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">modified versions of the software inside them, although the manufacturer</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">can do so. This is fundamentally incompatible with the aim of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">protecting users' freedom to change the software. The systematic</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">pattern of such abuse occurs in the area of products for individuals to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">use, which is precisely where it is most unacceptable. Therefore, we</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">have designed this version of the GPL to prohibit the practice for those</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">products. If such problems arise substantially in other domains, we</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">stand ready to extend this provision to those domains in future versions</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">of the GPL, as needed to protect the freedom of users.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Finally, every program is threatened constantly by software patents.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">States should not allow patents to restrict development and use of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">software on general-purpose computers, but in those that do, we wish to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">avoid the special danger that patents applied to a free program could</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">make it effectively proprietary. To prevent this, the GPL assures that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">patents cannot be used to render the program non-free.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The precise terms and conditions for copying, distribution and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">modification follow.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> TERMS AND CONDITIONS</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 0. Definitions.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> &quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> &quot;Copyright&quot; also means copyright-like laws that apply to other kinds of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">works, such as semiconductor masks.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> &quot;The Program&quot; refers to any copyrightable work licensed under this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">&quot;recipients&quot; may be individuals or organizations.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> To &quot;modify&quot; a work means to copy from or adapt all or part of the work</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">in a fashion requiring copyright permission, other than the making of an</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">exact copy. The resulting work is called a &quot;modified version&quot; of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> A &quot;covered work&quot; means either the unmodified Program or a work based</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">on the Program.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> To &quot;propagate&quot; a work means to do anything with it that, without</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">permission, would make you directly or secondarily liable for</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">infringement under applicable copyright law, except executing it on a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">computer or modifying a private copy. Propagation includes copying,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">distribution (with or without modification), making available to the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">public, and in some countries other activities as well.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> To &quot;convey&quot; a work means any kind of propagation that enables other</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">parties to make or receive copies. Mere interaction with a user through</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> An interactive user interface displays &quot;Appropriate Legal Notices&quot;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">to the extent that it includes a convenient and prominently visible</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">feature that (1) displays an appropriate copyright notice, and (2)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tells the user that there is no warranty for the work (except to the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">extent that warranties are provided), that licensees may convey the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">work under this License, and how to view a copy of this License. If</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the interface presents a list of user commands or options, such as a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">menu, a prominent item in the list meets this criterion.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 1. Source Code.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The &quot;source code&quot; for a work means the preferred form of the work</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">for making modifications to it. &quot;Object code&quot; means any non-source</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">form of a work.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> A &quot;Standard Interface&quot; means an interface that either is an official</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">standard defined by a recognized standards body, or, in the case of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">interfaces specified for a particular programming language, one that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">is widely used among developers working in that language.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The &quot;System Libraries&quot; of an executable work include anything, other</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">than the work as a whole, that (a) is included in the normal form of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">packaging a Major Component, but which is not part of that Major</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Component, and (b) serves only to enable use of the work with that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Major Component, or to implement a Standard Interface for which an</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">implementation is available to the public in source code form. A</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">&quot;Major Component&quot;, in this context, means a major essential component</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">(kernel, window system, and so on) of the specific operating system</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">(if any) on which the executable work runs, or a compiler used to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">produce the work, or an object code interpreter used to run it.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The &quot;Corresponding Source&quot; for a work in object code form means all</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the source code needed to generate, install, and (for an executable</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">work) run the object code and to modify the work, including scripts to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">control those activities. However, it does not include the work's</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">System Libraries, or general-purpose tools or generally available free</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">programs which are used unmodified in performing those activities but</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">which are not part of the work. For example, Corresponding Source</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">includes interface definition files associated with source files for</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the work, and the source code for shared libraries and dynamically</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">linked subprograms that the work is specifically designed to require,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">such as by intimate data communication or control flow between those</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">subprograms and other parts of the work.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The Corresponding Source need not include anything that users</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">can regenerate automatically from other parts of the Corresponding</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Source.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The Corresponding Source for a work in source code form is that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">same work.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 2. Basic Permissions.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> All rights granted under this License are granted for the term of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">copyright on the Program, and are irrevocable provided the stated</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">conditions are met. This License explicitly affirms your unlimited</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">permission to run the unmodified Program. The output from running a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">covered work is covered by this License only if the output, given its</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">content, constitutes a covered work. This License acknowledges your</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> You may make, run and propagate covered works that you do not</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">convey, without conditions so long as your license otherwise remains</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">in force. You may convey covered works to others for the sole purpose</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">of having them make modifications exclusively for you, or provide you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">with facilities for running those works, provided that you comply with</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the terms of this License in conveying all material for which you do</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">not control copyright. Those thus making or running the covered works</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">for you must do so exclusively on your behalf, under your direction</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">and control, on terms that prohibit them from making any copies of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">your copyrighted material outside their relationship with you.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Conveying under any other circumstances is permitted solely under</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the conditions stated below. Sublicensing is not allowed; section 10</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">makes it unnecessary.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> No covered work shall be deemed part of an effective technological</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">measure under any applicable law fulfilling obligations under article</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">11 of the WIPO copyright treaty adopted on 20 December 1996, or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">similar laws prohibiting or restricting circumvention of such</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">measures.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> When you convey a covered work, you waive any legal power to forbid</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">circumvention of technological measures to the extent such circumvention</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">is effected by exercising rights under this License with respect to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the covered work, and you disclaim any intention to limit operation or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">modification of the work as a means of enforcing, against the work's</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">users, your or third parties' legal rights to forbid circumvention of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">technological measures.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 4. Conveying Verbatim Copies.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> You may convey verbatim copies of the Program's source code as you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">receive it, in any medium, provided that you conspicuously and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">appropriately publish on each copy an appropriate copyright notice;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">keep intact all notices stating that this License and any</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">non-permissive terms added in accord with section 7 apply to the code;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">keep intact all notices of the absence of any warranty; and give all</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">recipients a copy of this License along with the Program.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> You may charge any price or no price for each copy that you convey,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">and you may offer support or warranty protection for a fee.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 5. Conveying Modified Source Versions.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> You may convey a work based on the Program, or the modifications to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">produce it from the Program, in the form of source code under the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> a) The work must carry prominent notices stating that you modified</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> it, and giving a relevant date.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> b) The work must carry prominent notices stating that it is</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> released under this License and any conditions added under section</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 7. This requirement modifies the requirement in section 4 to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> &quot;keep intact all notices&quot;.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> c) You must license the entire work, as a whole, under this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> License to anyone who comes into possession of a copy. This</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> License will therefore apply, along with any applicable section 7</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> additional terms, to the whole of the work, and all its parts,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> regardless of how they are packaged. This License gives no</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> permission to license the work in any other way, but it does not</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> invalidate such permission if you have separately received it.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> d) If the work has interactive user interfaces, each must display</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Appropriate Legal Notices; however, if the Program has interactive</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> interfaces that do not display Appropriate Legal Notices, your</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> work need not make them do so.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> A compilation of a covered work with other separate and independent</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">works, which are not by their nature extensions of the covered work,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">and which are not combined with it such as to form a larger program,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">in or on a volume of a storage or distribution medium, is called an</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">&quot;aggregate&quot; if the compilation and its resulting copyright are not</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">used to limit the access or legal rights of the compilation's users</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">beyond what the individual works permit. Inclusion of a covered work</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">in an aggregate does not cause this License to apply to the other</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">parts of the aggregate.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 6. Conveying Non-Source Forms.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> You may convey a covered work in object code form under the terms</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">of sections 4 and 5, provided that you also convey the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">machine-readable Corresponding Source under the terms of this License,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">in one of these ways:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> a) Convey the object code in, or embodied in, a physical product</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> (including a physical distribution medium), accompanied by the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Corresponding Source fixed on a durable physical medium</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> customarily used for software interchange.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> b) Convey the object code in, or embodied in, a physical product</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> (including a physical distribution medium), accompanied by a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> written offer, valid for at least three years and valid for as</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> long as you offer spare parts or customer support for that product</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> model, to give anyone who possesses the object code either (1) a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> copy of the Corresponding Source for all the software in the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> product that is covered by this License, on a durable physical</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> medium customarily used for software interchange, for a price no</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> more than your reasonable cost of physically performing this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> conveying of source, or (2) access to copy the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Corresponding Source from a network server at no charge.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> c) Convey individual copies of the object code with a copy of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> written offer to provide the Corresponding Source. This</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> alternative is allowed only occasionally and noncommercially, and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> only if you received the object code with such an offer, in accord</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> with subsection 6b.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> d) Convey the object code by offering access from a designated</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> place (gratis or for a charge), and offer equivalent access to the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Corresponding Source in the same way through the same place at no</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> further charge. You need not require recipients to copy the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Corresponding Source along with the object code. If the place to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> copy the object code is a network server, the Corresponding Source</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> may be on a different server (operated by you or a third party)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> that supports equivalent copying facilities, provided you maintain</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> clear directions next to the object code saying where to find the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Corresponding Source. Regardless of what server hosts the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Corresponding Source, you remain obligated to ensure that it is</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> available for as long as needed to satisfy these requirements.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> e) Convey the object code using peer-to-peer transmission, provided</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> you inform other peers where the object code and Corresponding</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Source of the work are being offered to the general public at no</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> charge under subsection 6d.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> A separable portion of the object code, whose source code is excluded</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">from the Corresponding Source as a System Library, need not be</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">included in conveying the object code work.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tangible personal property which is normally used for personal, family,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">or household purposes, or (2) anything designed or sold for incorporation</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">into a dwelling. In determining whether a product is a consumer product,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">doubtful cases shall be resolved in favor of coverage. For a particular</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">product received by a particular user, &quot;normally used&quot; refers to a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">typical or common use of that class of product, regardless of the status</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">of the particular user or of the way in which the particular user</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">actually uses, or expects or is expected to use, the product. A product</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">is a consumer product regardless of whether the product has substantial</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">commercial, industrial or non-consumer uses, unless such uses represent</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the only significant mode of use of the product.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> &quot;Installation Information&quot; for a User Product means any methods,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">procedures, authorization keys, or other information required to install</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">and execute modified versions of a covered work in that User Product from</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">a modified version of its Corresponding Source. The information must</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">suffice to ensure that the continued functioning of the modified object</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">code is in no case prevented or interfered with solely because</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">modification has been made.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> If you convey an object code work under this section in, or with, or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">specifically for use in, a User Product, and the conveying occurs as</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">part of a transaction in which the right of possession and use of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">User Product is transferred to the recipient in perpetuity or for a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">fixed term (regardless of how the transaction is characterized), the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Corresponding Source conveyed under this section must be accompanied</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">by the Installation Information. But this requirement does not apply</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">if neither you nor any third party retains the ability to install</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">modified object code on the User Product (for example, the work has</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">been installed in ROM).</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The requirement to provide Installation Information does not include a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">requirement to continue to provide support service, warranty, or updates</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">for a work that has been modified or installed by the recipient, or for</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the User Product in which it has been modified or installed. Access to a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">network may be denied when the modification itself materially and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">adversely affects the operation of the network or violates the rules and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">protocols for communication across the network.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Corresponding Source conveyed, and Installation Information provided,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">in accord with this section must be in a format that is publicly</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">documented (and with an implementation available to the public in</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">source code form), and must require no special password or key for</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">unpacking, reading or copying.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 7. Additional Terms.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> &quot;Additional permissions&quot; are terms that supplement the terms of this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">License by making exceptions from one or more of its conditions.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Additional permissions that are applicable to the entire Program shall</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">be treated as though they were included in this License, to the extent</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">that they are valid under applicable law. If additional permissions</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">apply only to part of the Program, that part may be used separately</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">under those permissions, but the entire Program remains governed by</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">this License without regard to the additional permissions.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> When you convey a copy of a covered work, you may at your option</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">remove any additional permissions from that copy, or from any part of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">it. (Additional permissions may be written to require their own</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">removal in certain cases when you modify the work.) You may place</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">additional permissions on material, added by you to a covered work,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">for which you have or can give appropriate copyright permission.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Notwithstanding any other provision of this License, for material you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">add to a covered work, you may (if authorized by the copyright holders of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">that material) supplement the terms of this License with terms:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> a) Disclaiming warranty or limiting liability differently from the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> terms of sections 15 and 16 of this License; or</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> b) Requiring preservation of specified reasonable legal notices or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> author attributions in that material or in the Appropriate Legal</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Notices displayed by works containing it; or</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> c) Prohibiting misrepresentation of the origin of that material, or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> requiring that modified versions of such material be marked in</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> reasonable ways as different from the original version; or</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> d) Limiting the use for publicity purposes of names of licensors or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> authors of the material; or</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> e) Declining to grant rights under trademark law for use of some</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> trade names, trademarks, or service marks; or</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> f) Requiring indemnification of licensors and authors of that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> material by anyone who conveys the material (or modified versions of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> it) with contractual assumptions of liability to the recipient, for</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> any liability that these contractual assumptions directly impose on</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> those licensors and authors.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> All other non-permissive additional terms are considered &quot;further</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">restrictions&quot; within the meaning of section 10. If the Program as you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">received it, or any part of it, contains a notice stating that it is</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">governed by this License along with a term that is a further</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">restriction, you may remove that term. If a license document contains</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">a further restriction but permits relicensing or conveying under this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">License, you may add to a covered work material governed by the terms</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">of that license document, provided that the further restriction does</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">not survive such relicensing or conveying.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> If you add terms to a covered work in accord with this section, you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">must place, in the relevant source files, a statement of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">additional terms that apply to those files, or a notice indicating</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">where to find the applicable terms.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Additional terms, permissive or non-permissive, may be stated in the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">form of a separately written license, or stated as exceptions;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the above requirements apply either way.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 8. Termination.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> You may not propagate or modify a covered work except as expressly</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">provided under this License. Any attempt otherwise to propagate or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">modify it is void, and will automatically terminate your rights under</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">this License (including any patent licenses granted under the third</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">paragraph of section 11).</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> However, if you cease all violation of this License, then your</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">license from a particular copyright holder is reinstated (a)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">provisionally, unless and until the copyright holder explicitly and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">finally terminates your license, and (b) permanently, if the copyright</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">holder fails to notify you of the violation by some reasonable means</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">prior to 60 days after the cessation.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Moreover, your license from a particular copyright holder is</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">reinstated permanently if the copyright holder notifies you of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">violation by some reasonable means, this is the first time you have</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">received notice of violation of this License (for any work) from that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">copyright holder, and you cure the violation prior to 30 days after</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">your receipt of the notice.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Termination of your rights under this section does not terminate the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">licenses of parties who have received copies or rights from you under</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">this License. If your rights have been terminated and not permanently</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">reinstated, you do not qualify to receive new licenses for the same</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">material under section 10.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 9. Acceptance Not Required for Having Copies.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> You are not required to accept this License in order to receive or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">run a copy of the Program. Ancillary propagation of a covered work</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">occurring solely as a consequence of using peer-to-peer transmission</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">to receive a copy likewise does not require acceptance. However,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">nothing other than this License grants you permission to propagate or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">modify any covered work. These actions infringe copyright if you do</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">not accept this License. Therefore, by modifying or propagating a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">covered work, you indicate your acceptance of this License to do so.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 10. Automatic Licensing of Downstream Recipients.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Each time you convey a covered work, the recipient automatically</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">receives a license from the original licensors, to run, modify and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">propagate that work, subject to this License. You are not responsible</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">for enforcing compliance by third parties with this License.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> An &quot;entity transaction&quot; is a transaction transferring control of an</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">organization, or substantially all assets of one, or subdividing an</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">organization, or merging organizations. If propagation of a covered</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">work results from an entity transaction, each party to that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">transaction who receives a copy of the work also receives whatever</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">licenses to the work the party's predecessor in interest had or could</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">give under the previous paragraph, plus a right to possession of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Corresponding Source of the work from the predecessor in interest, if</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the predecessor has it or can get it with reasonable efforts.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> You may not impose any further restrictions on the exercise of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">rights granted or affirmed under this License. For example, you may</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">not impose a license fee, royalty, or other charge for exercise of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">rights granted under this License, and you may not initiate litigation</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">(including a cross-claim or counterclaim in a lawsuit) alleging that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">any patent claim is infringed by making, using, selling, offering for</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">sale, or importing the Program or any portion of it.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 11. Patents.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> A &quot;contributor&quot; is a copyright holder who authorizes use under this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">License of the Program or a work on which the Program is based. The</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> A contributor's &quot;essential patent claims&quot; are all patent claims</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">owned or controlled by the contributor, whether already acquired or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">hereafter acquired, that would be infringed by some manner, permitted</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">by this License, of making, using, or selling its contributor version,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">but do not include claims that would be infringed only as a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">consequence of further modification of the contributor version. For</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">purposes of this definition, &quot;control&quot; includes the right to grant</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">patent sublicenses in a manner consistent with the requirements of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">this License.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Each contributor grants you a non-exclusive, worldwide, royalty-free</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">patent license under the contributor's essential patent claims, to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">make, use, sell, offer for sale, import and otherwise run, modify and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">propagate the contents of its contributor version.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> In the following three paragraphs, a &quot;patent license&quot; is any express</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">agreement or commitment, however denominated, not to enforce a patent</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">(such as an express permission to practice a patent or covenant not to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">sue for patent infringement). To &quot;grant&quot; such a patent license to a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">party means to make such an agreement or commitment not to enforce a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">patent against the party.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> If you convey a covered work, knowingly relying on a patent license,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">and the Corresponding Source of the work is not available for anyone</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">to copy, free of charge and under the terms of this License, through a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">publicly available network server or other readily accessible means,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">then you must either (1) cause the Corresponding Source to be so</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">available, or (2) arrange to deprive yourself of the benefit of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">patent license for this particular work, or (3) arrange, in a manner</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">consistent with the requirements of this License, to extend the patent</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">license to downstream recipients. &quot;Knowingly relying&quot; means you have</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">actual knowledge that, but for the patent license, your conveying the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">covered work in a country, or your recipient's use of the covered work</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">in a country, would infringe one or more identifiable patents in that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">country that you have reason to believe are valid.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> If, pursuant to or in connection with a single transaction or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">arrangement, you convey, or propagate by procuring conveyance of, a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">covered work, and grant a patent license to some of the parties</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">receiving the covered work authorizing them to use, propagate, modify</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">or convey a specific copy of the covered work, then the patent license</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">you grant is automatically extended to all recipients of the covered</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">work and works based on it.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> A patent license is &quot;discriminatory&quot; if it does not include within</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the scope of its coverage, prohibits the exercise of, or is</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">conditioned on the non-exercise of one or more of the rights that are</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">specifically granted under this License. You may not convey a covered</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">work if you are a party to an arrangement with a third party that is</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">in the business of distributing software, under which you make payment</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">to the third party based on the extent of your activity of conveying</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the work, and under which the third party grants, to any of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">parties who would receive the covered work from you, a discriminatory</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">patent license (a) in connection with copies of the covered work</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">conveyed by you (or copies made from those copies), or (b) primarily</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">for and in connection with specific products or compilations that</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">contain the covered work, unless you entered into that arrangement,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">or that patent license was granted, prior to 28 March 2007.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Nothing in this License shall be construed as excluding or limiting</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">any implied license or other defenses to infringement that may</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">otherwise be available to you under applicable patent law.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 12. No Surrender of Others' Freedom.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> If conditions are imposed on you (whether by court order, agreement or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">otherwise) that contradict the conditions of this License, they do not</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">excuse you from the conditions of this License. If you cannot convey a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">covered work so as to satisfy simultaneously your obligations under this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">License and any other pertinent obligations, then as a consequence you may</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">not convey it at all. For example, if you agree to terms that obligate you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">to collect a royalty for further conveying from those to whom you convey</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the Program, the only way you could satisfy both those terms and this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">License would be to refrain entirely from conveying the Program.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 13. Use with the GNU Affero General Public License.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Notwithstanding any other provision of this License, you have</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">permission to link or combine any covered work with a work licensed</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">under version 3 of the GNU Affero General Public License into a single</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">combined work, and to convey the resulting work. The terms of this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">License will continue to apply to the part which is the covered work,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">but the special requirements of the GNU Affero General Public License,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">section 13, concerning interaction through a network will apply to the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">combination as such.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 14. Revised Versions of this License.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> The Free Software Foundation may publish revised and/or new versions of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">the GNU General Public License from time to time. Such new versions will</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">be similar in spirit to the present version, but may differ in detail to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">address new problems or concerns.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Each version is given a distinguishing version number. If the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Program specifies that a certain numbered version of the GNU General</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Public License &quot;or any later version&quot; applies to it, you have the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">option of following the terms and conditions either of that numbered</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">version or of any later version published by the Free Software</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Foundation. If the Program does not specify a version number of the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">GNU General Public License, you may choose any version ever published</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">by the Free Software Foundation.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> If the Program specifies that a proxy can decide which future</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">versions of the GNU General Public License can be used, that proxy's</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">public statement of acceptance of a version permanently authorizes you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">to choose that version for the Program.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> Later license versions may give you additional or different</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">permissions. However, no additional obligations are imposed on any</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">author or copyright holder as a result of your choosing to follow a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">later version.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 15. Disclaimer of Warranty.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 16. Limitation of Liability.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">SUCH DAMAGES.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> 17. Interpretation of Sections 15 and 16.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;"> If the disclaimer of warranty and limitation of liability provided</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">above cannot be given local legal effect according to their terms,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">reviewing courts shall apply local law that most closely approximates</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">an absolute waiver of all civil liability in connection with the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Program, unless a warranty or assumption of liability accompanies a</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">copy of the Program in return for a fee.</span></p></body></html> + + + + + + + + + + + &Close + + + + :/icons/cross.png:/icons/cross.png + + + + + + + + + + diff --git a/tags/fred-0.1.0beta1/dlgkeydetails.cpp b/tags/fred-0.1.0beta1/dlgkeydetails.cpp new file mode 100644 index 0000000..95a0cb6 --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgkeydetails.cpp @@ -0,0 +1,86 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "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/tags/fred-0.1.0beta1/dlgkeydetails.h b/tags/fred-0.1.0beta1/dlgkeydetails.h new file mode 100644 index 0000000..43d1bf5 --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgkeydetails.h @@ -0,0 +1,60 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 DLGKEYDETAILS_H +#define DLGKEYDETAILS_H + +#include +#include + +#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/tags/fred-0.1.0beta1/dlgkeydetails.ui b/tags/fred-0.1.0beta1/dlgkeydetails.ui new file mode 100644 index 0000000..53429ed --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgkeydetails.ui @@ -0,0 +1,28 @@ + + + DlgKeyDetails + + + + 0 + 0 + 678 + 346 + + + + Dialog + + + + + + &Close + + + + + + + + diff --git a/tags/fred-0.1.0beta1/dlgreportviewer.cpp b/tags/fred-0.1.0beta1/dlgreportviewer.cpp new file mode 100644 index 0000000..9eaf6f4 --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgreportviewer.cpp @@ -0,0 +1,88 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 + +DlgReportViewer::DlgReportViewer(QString &report_data, QWidget *p_parent) + : QMainWindow(p_parent,Qt::Dialog), ui(new Ui::DlgReportViewer) +{ + // Init local vars + ui->setupUi(this); + this->p_local_event_loop=NULL; + + // Set report content + this->ui->WebView->setHtml(report_data); + + // Set dialog title based on report content title + QString report_title=this->ui->WebView->title(); + if(report_title.isEmpty()) this->setWindowTitle("Report Viewer"); + else this->setWindowTitle(report_title.prepend("Report Viewer : ")); +} + +DlgReportViewer::~DlgReportViewer() { + delete ui; + if(this->p_local_event_loop!=NULL) this->p_local_event_loop->exit(); +} + +void DlgReportViewer::changeEvent(QEvent *e) { + QMainWindow::changeEvent(e); + switch(e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void DlgReportViewer::closeEvent(QCloseEvent *event) { + // Make sure we exit the local event loop on exit + if(this->p_local_event_loop!=NULL) { + this->p_local_event_loop->exit(); + this->p_local_event_loop=NULL; + } + event->accept(); +} + +void DlgReportViewer::exec() { + // Create local event loop + this->p_local_event_loop=new QEventLoop(this); + // Show window and enter loop + this->show(); + this->p_local_event_loop->exec(); +} + +void DlgReportViewer::on_action_Print_triggered() { + // Print report + QPrinter printer; + QPrintDialog *p_dlg_print=new QPrintDialog(&printer); + if(p_dlg_print->exec()==QDialog::Accepted) { + this->ui->WebView->print(&printer); + } + delete p_dlg_print; +} + +void DlgReportViewer::on_action_Close_triggered() { + this->close(); +} diff --git a/tags/fred-0.1.0beta1/dlgreportviewer.h b/tags/fred-0.1.0beta1/dlgreportviewer.h new file mode 100644 index 0000000..bb295f1 --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgreportviewer.h @@ -0,0 +1,56 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 +#include +#include + +namespace Ui { + class DlgReportViewer; +} + +class DlgReportViewer : public QMainWindow { + Q_OBJECT + + public: + explicit DlgReportViewer(QString &report_data, + QWidget *p_parent=0); + ~DlgReportViewer(); + + void exec(); + + protected: + void changeEvent(QEvent *e); + void closeEvent(QCloseEvent *event); + + private slots: + void on_action_Print_triggered(); + void on_action_Close_triggered(); + +private: + Ui::DlgReportViewer *ui; + QEventLoop *p_local_event_loop; + +}; + +#endif // DLGREPORTVIEWER_H diff --git a/tags/fred-0.1.0beta1/dlgreportviewer.ui b/tags/fred-0.1.0beta1/dlgreportviewer.ui new file mode 100644 index 0000000..831704e --- /dev/null +++ b/tags/fred-0.1.0beta1/dlgreportviewer.ui @@ -0,0 +1,82 @@ + + + DlgReportViewer + + + Qt::WindowModal + + + + 0 + 0 + 605 + 497 + + + + + + + + :/icons/resources/fred.png:/icons/resources/fred.png + + + + + + + + about:blank + + + + + + + + + + 0 + 0 + 605 + 25 + + + + + &File + + + + + + + + + + &Save + + + + + &Print + + + + + &Close + + + + + + QWebView + QWidget +
QtWebKit/QWebView
+
+
+ + + + +
diff --git a/tags/fred-0.1.0beta1/fred.pro b/tags/fred-0.1.0beta1/fred.pro new file mode 100644 index 0000000..934bb59 --- /dev/null +++ b/tags/fred-0.1.0beta1/fred.pro @@ -0,0 +1,80 @@ +#******************************************************************************* +# fred Copyright (c) 2011 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 . * +#******************************************************************************/ + +system(bash compileinfo.sh > compileinfo.h) + +QT += core \ + gui \ + xml \ + script \ + webkit + +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 \ + datainterpreter.cpp \ + reporttemplate.cpp \ + datareporter.cpp \ + datareporterengine.cpp \ + registryhive.cpp \ + qtscript_types/bytearray.cpp \ + qtscript_types/bytearrayprototype.cpp \ + qtscript_types/bytearrayiterator.cpp \ + dlgreportviewer.cpp + +HEADERS += mainwindow.h \ + registrynode.h \ + registrynodetreemodel.h \ + registrykey.h \ + registrykeytablemodel.h \ + dlgabout.h \ + dlgkeydetails.h \ + qhexedit/qhexedit_p.h \ + qhexedit/qhexedit.h \ + datainterpreter.h \ + reporttemplate.h \ + datareporter.h \ + datareporterengine.h \ + registryhive.h \ + qtscript_types/bytearray.h \ + qtscript_types/bytearrayprototype.h \ + qtscript_types/bytearrayiterator.h \ + dlgreportviewer.h + +FORMS += mainwindow.ui \ + dlgabout.ui \ + dlgkeydetails.ui \ + dlgreportviewer.ui + +LIBS += -lhivex + +RESOURCES += fred.qrc diff --git a/tags/fred-0.1.0beta1/fred.qrc b/tags/fred-0.1.0beta1/fred.qrc new file mode 100644 index 0000000..27bb0b8 --- /dev/null +++ b/tags/fred-0.1.0beta1/fred.qrc @@ -0,0 +1,5 @@ + + + resources/fred.png + + diff --git a/tags/fred-0.1.0beta1/fred_license_template.txt b/tags/fred-0.1.0beta1/fred_license_template.txt new file mode 100644 index 0000000..0a4ef39 --- /dev/null +++ b/tags/fred-0.1.0beta1/fred_license_template.txt @@ -0,0 +1,19 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 . * +*******************************************************************************/ diff --git a/tags/fred-0.1.0beta1/main.cpp b/tags/fred-0.1.0beta1/main.cpp new file mode 100644 index 0000000..fce4bc7 --- /dev/null +++ b/tags/fred-0.1.0beta1/main.cpp @@ -0,0 +1,31 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/tags/fred-0.1.0beta1/mainwindow.cpp b/tags/fred-0.1.0beta1/mainwindow.cpp new file mode 100644 index 0000000..7454487 --- /dev/null +++ b/tags/fred-0.1.0beta1/mainwindow.cpp @@ -0,0 +1,532 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 + #define FRED_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates/" +#endif + +#include +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "dlgabout.h" +#include "dlgkeydetails.h" +#include "dlgreportviewer.h" + +#include "compileinfo.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + // Initialize private vars + this->p_hive=new RegistryHive(this); + this->is_hive_open=false; + this->p_reg_node_tree_model=NULL; + this->p_reg_key_table_model=NULL; + + // Check for ~/.fred config dir + this->CheckUserConfigDir(); + + // Set main window size + int cur_screen=QApplication::desktop()->screenNumber(this); + int window_width= + QApplication::desktop()->availableGeometry(cur_screen).width()*0.5; + int window_height= + QApplication::desktop()->availableGeometry(cur_screen).height()*0.5; + int window_x= + (QApplication::desktop()->availableGeometry(cur_screen).width()/2)- + (window_width/2); + int window_y= + (QApplication::desktop()->availableGeometry(cur_screen).height()/2)- + (window_height/2); + this->setGeometry(window_x, + window_y, + window_width, + window_height); + + // Create widgets + this->p_horizontal_splitter=new QSplitter(); + this->p_horizontal_splitter->setOrientation(Qt::Horizontal); + + this->p_node_tree=new QTreeView(this->p_horizontal_splitter); + this->p_node_tree->setHeaderHidden(true); + + this->p_vertical_splitter=new QSplitter(this->p_horizontal_splitter); + this->p_vertical_splitter->setOrientation(Qt::Vertical); + + this->p_key_table=new QTableView(this->p_vertical_splitter); + this->p_key_table->setSelectionBehavior(QAbstractItemView::SelectRows); + + this->p_horizontal_splitter2=new QSplitter(this->p_vertical_splitter); + this->p_horizontal_splitter2->setOrientation(Qt::Horizontal); + + this->p_hex_edit_widget=new QWidget(this->p_horizontal_splitter2); + this->p_hex_edit_layout=new QVBoxLayout(this->p_hex_edit_widget); + this->p_hex_edit_layout->setContentsMargins(0,0,0,0); + this->p_hex_edit=new QHexEdit(); + this->p_hex_edit->setReadOnly(true); + this->p_hex_edit_status_bar=new QLabel(); + + this->p_data_interpreter=new DataInterpreter(this->p_horizontal_splitter2); + + // Make sure hex viewer font is monospaced. + QFont mono_font("Monospace"); + mono_font.setStyleHint(QFont::TypeWriter); + this->p_hex_edit->setFont(mono_font); + + // Lay out widgets + this->p_hex_edit_layout->addWidget(this->p_hex_edit); + this->p_hex_edit_layout->addWidget(this->p_hex_edit_status_bar); + + this->p_horizontal_splitter2->addWidget(this->p_hex_edit_widget); + this->p_horizontal_splitter2->addWidget(this->p_data_interpreter); + + this->p_vertical_splitter->addWidget(this->p_key_table); + this->p_vertical_splitter->addWidget(this->p_horizontal_splitter2); + + 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 hex_edit_widget_policy=this->p_hex_edit_widget->sizePolicy(); + hex_edit_widget_policy.setVerticalStretch(2); + hex_edit_widget_policy.setHorizontalStretch(200); + this->p_hex_edit_widget->setSizePolicy(hex_edit_widget_policy); + + QSizePolicy data_interpreter_policy=this->p_data_interpreter->sizePolicy(); + data_interpreter_policy.setVerticalStretch(2); + data_interpreter_policy.setHorizontalStretch(0); + this->p_data_interpreter->setSizePolicy(data_interpreter_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_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_hex_edit, + SIGNAL(currentAddressChanged(int)), + this, + SLOT(SlotHexEditAddressChanged(int))); + + // Add central widget + this->setContentsMargins(4,4,4,0); + this->setCentralWidget(this->p_horizontal_splitter); + + // Set window title + this->UpdateWindowTitle(); + + // Set last open location to home dir + this->last_open_location=QDir::homePath(); + + // Load report templates and update menu + this->p_data_reporter=new DataReporter(); + // Load reports from system wide include dir + this->p_data_reporter->LoadReportTemplates(FRED_REPORT_TEMPLATE_DIR); + // Load user's report templates + this->p_data_reporter->LoadReportTemplates(QDir::homePath() + .append(QDir::separator()) + .append(".fred") + .append(QDir::separator()) + .append("report_templates")); + this->UpdateDataReporterMenu(); + + // Finally, parse command line arguments + this->ParseCommandLineArgs(); +} + +MainWindow::~MainWindow() { + if(this->is_hive_open) { + this->p_hive->Close(); + } + delete ui; +} + +void MainWindow::on_action_Quit_triggered() { + qApp->exit(); +} + +void MainWindow::on_action_Open_hive_triggered() { + QString hive_file=""; + + hive_file=QFileDialog::getOpenFileName(this, + tr("Open registry hive"), + this->last_open_location, + tr("All files (*)")); + if(hive_file=="") return; + + this->OpenHive(hive_file); +} + +void MainWindow::on_action_Close_hive_triggered() { + if(this->is_hive_open) { + // Delete models + if(this->p_reg_node_tree_model!=NULL) { + delete this->p_reg_node_tree_model; + this->p_reg_node_tree_model=NULL; + } + if(this->p_reg_key_table_model!=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->setData(QByteArray()); + this->p_hex_edit_status_bar->setText(""); + this->p_data_interpreter->ClearValues(); + + // Close hive + this->p_hive->Close(); + + this->is_hive_open=false; + this->ui->action_Close_hive->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::SlotNodeTreeClicked(QModelIndex index) { + QString node_path; + + if(!index.isValid()) return; + + //Built node path + node_path.clear(); + node_path=this->p_reg_node_tree_model->data(index,Qt::DisplayRole) + .toString().prepend("\\"); + while(this->p_reg_node_tree_model->parent(index)!=QModelIndex()) { + // Prepend all parent nodes + index=this->p_reg_node_tree_model->parent(index); + node_path.prepend(this->p_reg_node_tree_model->data(index,Qt::DisplayRole) + .toString().prepend("\\")); + } + + // Create table model and attach it to the table view + if(this->p_reg_key_table_model!=NULL) { + delete this->p_reg_key_table_model; + this->p_hex_edit->setData(QByteArray()); + this->p_hex_edit_status_bar->setText(""); + this->p_data_interpreter->ClearValues(); + } + this->p_reg_key_table_model=new RegistryKeyTableModel(this->p_hive,node_path); + this->p_key_table->setModel(this->p_reg_key_table_model); + + // Resize table rows / columns to fit data + this->p_key_table->resizeColumnsToContents(); + this->p_key_table->horizontalHeader()->stretchLastSection(); +} + +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(); + key_index=this->p_reg_key_table_model->index(index.row(),2); + key_value=this->p_reg_key_table_model->data(key_index, + RegistryKeyTableModel:: + AdditionalRoles_GetRawData) + .toByteArray(); + + // Get current node + node_index=this->p_node_tree->currentIndex(); + + //Built node path + nodes.clear(); + nodes.append(this->p_reg_node_tree_model-> + data(node_index,Qt::DisplayRole).toString()); + while(this->p_reg_node_tree_model->parent(node_index)!=QModelIndex()) { + // Prepend all parent nodes + node_index=this->p_reg_node_tree_model->parent(node_index); + nodes.prepend(this->p_reg_node_tree_model-> + data(node_index,Qt::DisplayRole).toString()); + } + + DlgKeyDetails dlg_key_details(this); + dlg_key_details.SetValues(nodes,key_name,key_type,key_value); + dlg_key_details.exec(); + */ +} + +void MainWindow::SlotKeyTableClicked(QModelIndex index) { + if(!index.isValid()) return; + + this->selected_key_value= + this->p_reg_key_table_model->data(this->p_reg_key_table_model-> + index(index.row(),2), + RegistryKeyTableModel:: + AdditionalRoles_GetRawData) + .toByteArray(); + this->p_hex_edit->setData(this->selected_key_value); +} + +void MainWindow::SlotHexEditAddressChanged(int hex_offset) { + // Update hex edit status bar + this->p_hex_edit_status_bar-> + setText(QString().sprintf("Byte offset: 0x%04X (%u)",hex_offset,hex_offset)); + // Update data interpreter + this->UpdateDataInterpreter(hex_offset); +} + +void MainWindow::SlotReportClicked() { + // Get report category and name from sender and it's parent + QString category=((QMenu*)((QAction*)QObject::sender())->parent())->title(); + QString report=((QAction*)QObject::sender())->text(); + + // Generate report + QString report_content=this->p_data_reporter->GenerateReport(this->p_hive, + category, + report); + + // Show result in report viewer + if(report_content!=QString()) { + DlgReportViewer *p_dlg_report_view=new DlgReportViewer(report_content,this); + p_dlg_report_view->exec(); + delete p_dlg_report_view; + } else { + // TODO: Something went wrong! + } +} + +void MainWindow::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().sprintf("%s v%s",APP_TITLE,APP_VERSION)); + } else { + this->setWindowTitle(QString().sprintf("%s v%s - %s", + APP_TITLE, + APP_VERSION, + filename.toLocal8Bit().constData())); + } +} + +void MainWindow::UpdateDataInterpreter(int hex_offset) { + QDateTime date_time; + const char *p_data; + int remaining_data_len; + + // Remove all old values from data interpreter + this->p_data_interpreter->ClearValues(); + + // Calculate how many bytes are remainig after current offset + remaining_data_len=this->selected_key_value.size()-hex_offset; + if(!remaining_data_len>0) { + // Nothing to show + return; + } + + // Get pointer to data at current offset + p_data=this->selected_key_value.constData(); + p_data+=hex_offset; + + //#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) + //#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) + //#define rotl64(x,n) (((x) << n) | ((x) >> (64 - n))) + //#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n))) + + if(remaining_data_len>=1) { + this->p_data_interpreter->AddValue("int8:", + QString().sprintf("%d", + *(int8_t*)p_data)); + this->p_data_interpreter->AddValue("uint8:", + QString().sprintf("%u", + *(uint8_t*)p_data)); + } + if(remaining_data_len>=2) { + this->p_data_interpreter->AddValue("int16:", + QString().sprintf("%d", + *(int16_t*)p_data)); + this->p_data_interpreter->AddValue("uint16:", + QString().sprintf("%u", + *(uint16_t*)p_data)); + } + if(remaining_data_len>=4) { + this->p_data_interpreter->AddValue("int32:", + QString().sprintf("%d", + *(int32_t*)p_data)); + this->p_data_interpreter->AddValue("uint32:", + QString().sprintf("%u", + *(uint32_t*)p_data)); + date_time.setTime_t(*(uint32_t*)p_data); + this->p_data_interpreter->AddValue("Unixtime:", + date_time. + toString("yyyy/MM/dd hh:mm:ss")); + } + if(remaining_data_len>=8) { +#if __WORDSIZE == 64 + this->p_data_interpreter->AddValue("int64:", + QString().sprintf("%ld", + *(int64_t*)p_data)); + this->p_data_interpreter->AddValue("uint64:", + QString().sprintf("%lu", + *(uint64_t*)p_data)); +#else + this->p_data_interpreter->AddValue("int64:", + QString().sprintf("%lld", + *(int64_t*)p_data)); + this->p_data_interpreter->AddValue("uint64:", + QString().sprintf("%llu", + *(uint64_t*)p_data)); +#endif + date_time.setTime_t((*(uint64_t*)p_data-116444736000000000)/10000000); + this->p_data_interpreter->AddValue("Win64time:", + date_time. + toString("yyyy/MM/dd hh:mm:ss")); + } + + //#undef rotl32 + //#undef rotl64 +} + +void MainWindow::UpdateDataReporterMenu() { + int i=0,ii=0; + QMenu *p_category_entry; + QAction *p_report_entry; + + QStringList categories=this->p_data_reporter->GetAvailableReportCategories(); + QStringList reports; + + for(i=0;iui->MenuReports->addMenu(categories.value(i)); + // Now add category reports + reports=this->p_data_reporter->GetAvailableReports(categories.value(i)); + for(ii=0;iiaddAction(p_report_entry); + this->connect(p_report_entry, + SIGNAL(triggered()), + this, + SLOT(SlotReportClicked())); + } + } +} + +void MainWindow::OpenHive(QString hive_file) { + // Update last open location + this->last_open_location=hive_file.left(hive_file. + lastIndexOf(QDir::separator())); + + // If another hive is currently open, close it + if(this->is_hive_open) this->on_action_Close_hive_triggered(); + + // Try to open hive + if(!this->p_hive->Open(hive_file)) { + QMessageBox::critical(this, + tr("Error opening hive file"), + tr("Unable to open file '%1'").arg(hive_file)); + return; + } + + // Create tree model + this->p_reg_node_tree_model= + new RegistryNodeTreeModel(this->p_hive); + this->p_node_tree->setModel(this->p_reg_node_tree_model); + + this->is_hive_open=true; + this->ui->action_Close_hive->setEnabled(true); + this->ui->MenuReports->setEnabled(true); + this->UpdateWindowTitle(hive_file); +} + +void MainWindow::ParseCommandLineArgs() { + QStringList args=qApp->arguments(); + + // Return if no args were specified + if(args.count()==1) return; + + if(args.count()==2) { + // Try to open specified hive file + this->OpenHive(args.at(1)); + } +} diff --git a/tags/fred-0.1.0beta1/mainwindow.h b/tags/fred-0.1.0beta1/mainwindow.h new file mode 100644 index 0000000..68d4b6e --- /dev/null +++ b/tags/fred-0.1.0beta1/mainwindow.h @@ -0,0 +1,119 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "registryhive.h" +#include "registrynodetreemodel.h" +#include "registrykeytablemodel.h" +#include "qhexedit/qhexedit.h" +#include "datainterpreter.h" +#include "datareporter.h" + +namespace Ui { + class MainWindow; +} + +class MainWindow : public QMainWindow { + Q_OBJECT + + public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + + private slots: + void on_action_Quit_triggered(); + void on_action_Open_hive_triggered(); + void on_action_Close_hive_triggered(); + void on_actionAbout_Qt_triggered(); + void on_actionAbout_fred_triggered(); + + void SlotNodeTreeClicked(QModelIndex index); + void SlotKeyTableClicked(QModelIndex index); + void SlotKeyTableDoubleClicked(QModelIndex index); + void SlotHexEditAddressChanged(int hex_offset); + void SlotReportClicked(); + +private: + Ui::MainWindow *ui; + QString last_open_location; + RegistryHive *p_hive; + bool is_hive_open; + RegistryNodeTreeModel *p_reg_node_tree_model; + RegistryKeyTableModel *p_reg_key_table_model; + QByteArray selected_key_value; + + // Widgets etc... + QTreeView *p_node_tree; + QTableView *p_key_table; + QWidget *p_hex_edit_widget; + QHexEdit *p_hex_edit; + QLabel *p_hex_edit_status_bar; + DataInterpreter *p_data_interpreter; + QVBoxLayout *p_hex_edit_layout; + QSplitter *p_horizontal_splitter; + QSplitter *p_horizontal_splitter2; + QSplitter *p_vertical_splitter; + + DataReporter *p_data_reporter; + + /* + * CheckUserConfigDir + * + * Checks for and possibly creates the ~/.fred directory + */ + void CheckUserConfigDir(); + /* + * UpdateWindowTitle + * + * Updates the window title + */ + void UpdateWindowTitle(QString filename=""); + /* + * UpdateDataInterpreter + * + * Update data interpreter + */ + void UpdateDataInterpreter(int hex_offset); + /* + * UpdateDataReporterMenu + * + */ + void UpdateDataReporterMenu(); + /* + * OpenHive + * + * Open a registry hive + */ + void OpenHive(QString hive_file); + /* + * ParseCommandLineArgs + * + * Parse command line arguments + */ + void ParseCommandLineArgs(); +}; + +#endif // MAINWINDOW_H diff --git a/tags/fred-0.1.0beta1/mainwindow.ui b/tags/fred-0.1.0beta1/mainwindow.ui new file mode 100644 index 0000000..052d89e --- /dev/null +++ b/tags/fred-0.1.0beta1/mainwindow.ui @@ -0,0 +1,105 @@ + + + MainWindow + + + + 0 + 0 + 508 + 317 + + + + + 0 + 0 + + + + + 0 + 0 + + + + MainWindow + + + + :/icons/resources/fred.png:/icons/resources/fred.png + + + + + + 0 + 0 + 508 + 25 + + + + + &File + + + + + + + + + &Help + + + + + + + false + + + &Reports + + + + + + + + + + &Open hive + + + + + false + + + &Close hive + + + + + &Quit + + + + + About Qt + + + + + About fred + + + + + + + + + diff --git a/tags/fred-0.1.0beta1/qhexedit/qhexedit.cpp b/tags/fred-0.1.0beta1/qhexedit/qhexedit.cpp new file mode 100644 index 0000000..7ad0216 --- /dev/null +++ b/tags/fred-0.1.0beta1/qhexedit/qhexedit.cpp @@ -0,0 +1,137 @@ +/******************************************************************************* +* qhexedit Copyright (c) 2011 by Gillen Daniel * +* * +* Simple hex editor widget for Qt. * +* * +* Derived from code by Simon Winfried under a compatible license: * +* Copyright (c) 2010 by Simon Winfried * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#include + +#include "qhexedit.h" + + +QHexEdit::QHexEdit(QWidget *parent) : QScrollArea(parent) +{ + qHexEdit_p = new QHexEditPrivate(this); + setWidget(qHexEdit_p); + setWidgetResizable(true); + + connect(qHexEdit_p, SIGNAL(currentAddressChanged(int)), this, SIGNAL(currentAddressChanged(int))); + connect(qHexEdit_p, SIGNAL(currentSizeChanged(int)), this, SIGNAL(currentSizeChanged(int))); + connect(qHexEdit_p, SIGNAL(dataChanged()), this, SIGNAL(dataChanged())); + connect(qHexEdit_p, SIGNAL(overwriteModeChanged(bool)), this, SIGNAL(overwriteModeChanged(bool))); +} + +void QHexEdit::insert(int i, const QByteArray & ba) +{ + qHexEdit_p->insert(i, ba); +} + +void QHexEdit::insert(int i, char ch) +{ + qHexEdit_p->insert(i, ch); +} + +void QHexEdit::remove(int pos, int len) +{ + qHexEdit_p->remove(pos, len); +} + +void QHexEdit::setAddressArea(bool addressArea) +{ + qHexEdit_p->setAddressArea(addressArea); +} + +void QHexEdit::setAddressWidth(int addressWidth) +{ + qHexEdit_p->setAddressWidth(addressWidth); +} + +void QHexEdit::setAsciiArea(bool asciiArea) +{ + qHexEdit_p->setAsciiArea(asciiArea); +} + +void QHexEdit::setHighlighting(bool mode) +{ + qHexEdit_p->setHighlighting(mode); +} + +void QHexEdit::setAddressOffset(int offset) +{ + qHexEdit_p->setAddressOffset(offset); +} + +int QHexEdit::addressOffset() +{ + return addressOffset(); +} + +void QHexEdit::setData(const QByteArray &data) +{ + qHexEdit_p->setData(data); +} + +QByteArray QHexEdit::data() +{ + return qHexEdit_p->data(); +} + +void QHexEdit::setAddressAreaColor(const QColor &color) +{ + qHexEdit_p->setAddressAreaColor(color); +} + +QColor QHexEdit::addressAreaColor() +{ + return qHexEdit_p->addressAreaColor(); +} + +void QHexEdit::setHighlightingColor(const QColor &color) +{ + qHexEdit_p->setHighlightingColor(color); +} + +QColor QHexEdit::highlightingColor() +{ + return qHexEdit_p->highlightingColor(); +} + +void QHexEdit::setOverwriteMode(bool overwriteMode) +{ + qHexEdit_p->setOverwriteMode(overwriteMode); +} + +bool QHexEdit::overwriteMode() +{ + return qHexEdit_p->overwriteMode(); +} + +void QHexEdit::setReadOnly(bool read_only) { + qHexEdit_p->setReadOnly(read_only); +} + +bool QHexEdit::readOnly() { + return qHexEdit_p->readOnly(); +} + +void QHexEdit::setFont(const QFont &font) +{ + qHexEdit_p->setFont(font); +} + diff --git a/tags/fred-0.1.0beta1/qhexedit/qhexedit.h b/tags/fred-0.1.0beta1/qhexedit/qhexedit.h new file mode 100644 index 0000000..eb6e6b1 --- /dev/null +++ b/tags/fred-0.1.0beta1/qhexedit/qhexedit.h @@ -0,0 +1,177 @@ +/******************************************************************************* +* qhexedit Copyright (c) 2011 by Gillen Daniel * +* * +* Simple hex editor widget for Qt. * +* * +* Derived from code by Simon Winfried under a compatible license: * +* Copyright (c) 2010 by Simon Winfried * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#ifndef QHEXEDIT_H +#define QHEXEDIT_H + +#include +#include "qhexedit_p.h" + +/** \mainpage +QHexEdit is a binary editor widget for Qt. + +\version Version 0.4.6 +\image html hexedit.png +*/ + + +/*! QHexEdit is a hex editor widget written in C++ for the Qt (Qt4) framework. +It is a simple editor for binary data, just like QPlainTextEdit is for text data. +There are sip configuration files included, so it is easy to create bindings +for PyQt and you can use this widget also in python. + +QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use the +mouse or the keyboard to navigate inside the widget. If you hit the keys (0..9, a..f) +you will change the data. Changed data is highlighted and can be accessed via data(). + +Normaly QHexEdit works in the overwrite Mode. You can set overwriteMode(false) and +insert data. In this case the size of data() increases. It is also possible to delete +bytes under the cursor, here the size of data decreases. + +There are some limitations: The size of data has in general to be below 10 megabytes, +otherwise the scroll sliders ard not shown and you can't scroll any more. Copy and +paste functionality is perhaps a subject of a later release. +*/ + class QHexEdit : public QScrollArea +{ + Q_OBJECT + /*! Property data holds the content of QHexEdit. Call setData() to set the + content of QHexEdit, data() returns the actual content. + */ + Q_PROPERTY(QByteArray data READ data WRITE setData) + + /*! Property addressOffset is added to the Numbers of the Address Area. + A offset in the address area (left side) is sometimes usefull, whe you show + only a segment of a complete memory picture. With setAddressOffset() you set + this property - with addressOffset() you get the actual value. + */ + Q_PROPERTY(int addressOffset READ addressOffset WRITE setAddressOffset) + + /*! Property address area color sets (setAddressAreaColor()) the backgorund + color of address areas. You can also read the color (addressaAreaColor()). + */ + Q_PROPERTY(QColor addressAreaColor READ addressAreaColor WRITE setAddressAreaColor) + + /*! Property highlighting color sets (setHighlightingColor()) the backgorund + color of highlighted text areas. You can also read the color + (highlightingColor()). + */ + Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor) + + /*! Porperty overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the mode + in which the editor works. In overwritem mode the user will overwrite existing data. + */ + Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode) + + /*! Porperty read only sets (setReadOnly()) or gets (readOnly()) the + current editable mode. + */ + Q_PROPERTY(bool readOnly READ readOnly WRITE setReadOnly) + +public: + /*! Creates an instance of QHexEdit. + \param parent Parent widget of QHexEdit. + */ + QHexEdit(QWidget *parent = 0); + + /*! Inserts a byte array. + \param i Index position, where to insert + \param ba byte array, which is to insert + */ + void insert(int i, const QByteArray & ba); + + /*! Inserts a char. + \param i Index position, where to insert + \param ch Char, which is to insert + */ + void insert(int i, char ch); + + /*! Removes len bytes from the content. + \param pos Index position, where to remove + \param len Amount of bytes to remove + */ + void remove(int pos, int len=1); + + /*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/ + void setFont(const QFont &); + + /*! \cond docNever */ + void setAddressOffset(int offset); + int addressOffset(); + void setData(QByteArray const &data); + QByteArray data(); + void setAddressAreaColor(QColor const &color); + QColor addressAreaColor(); + void setHighlightingColor(QColor const &color); + QColor highlightingColor(); + void setOverwriteMode(bool); + bool overwriteMode(); + void setReadOnly(bool); + bool readOnly(); + /*! \endcond docNever */ + +public slots: + + /*! Set the minimum width of the address area. + \param addressWidth Width in characters. + */ + void setAddressWidth(int addressWidth); + + /*! Switch the address area on or off. + \param addressArea true (show it), false (hide it). + */ + void setAddressArea(bool addressArea); + + /*! Switch the ascii area on or off. + \param asciiArea true (show it), false (hide it). + */ + void setAsciiArea(bool asciiArea); + + /*! Switch the highlighting feature on or of. + \param mode true (show it), false (hide it). + */ + void setHighlighting(bool mode); + +signals: + + /*! Contains the address, where the cursor is located. */ + void currentAddressChanged(int address); + + /*! Contains the size of the data to edit. */ + void currentSizeChanged(int size); + + /*! The signal is emited every time, the data is changed. */ + void dataChanged(); + + /*! The signal is emited every time, the overwrite mode is changed. */ + void overwriteModeChanged(bool state); + +private: + /*! \cond docNever */ + QHexEditPrivate *qHexEdit_p; + QHBoxLayout *layout; + QScrollArea *scrollArea; + /*! \endcond docNever */ +}; + +#endif + diff --git a/tags/fred-0.1.0beta1/qhexedit/qhexedit_p.cpp b/tags/fred-0.1.0beta1/qhexedit/qhexedit_p.cpp new file mode 100644 index 0000000..3988385 --- /dev/null +++ b/tags/fred-0.1.0beta1/qhexedit/qhexedit_p.cpp @@ -0,0 +1,455 @@ +/******************************************************************************* +* qhexedit Copyright (c) 2011 by Gillen Daniel * +* * +* Simple hex editor widget for Qt. * +* * +* Derived from code by Simon Winfried under a compatible license: * +* Copyright (c) 2010 by Simon Winfried * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#include + +#include "qhexedit_p.h" + +const int HEXCHARS_IN_LINE = 47; +const int GAP_ADR_HEX = 10; +const int GAP_HEX_ASCII = 16; +const int BYTES_PER_LINE = 16; + +QHexEditPrivate::QHexEditPrivate(QScrollArea *parent) : QWidget(parent) +{ + _scrollArea = parent; + setAddressWidth(4); + setAddressOffset(0); + setAddressArea(true); + setAsciiArea(true); + setHighlighting(true); + setOverwriteMode(true); + setAddressAreaColor(QColor(Qt::lightGray).lighter(110)); + setHighlightingColor(QColor(Qt::yellow).lighter(160)); + this->setReadOnly(true); + + setFont(QFont("Mono", 10)); + connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor())); + + _cursorTimer.setInterval(500); + + setFocusPolicy(Qt::StrongFocus); + _size = -1; +} + +void QHexEditPrivate::setAddressOffset(int offset) +{ + _addressOffset = offset; + adjust(); +} + +int QHexEditPrivate::addressOffset() +{ + return _addressOffset; +} + +void QHexEditPrivate::setData(const QByteArray &data) +{ + if(!data.isNull() && !data.isEmpty()) this->_cursorTimer.start(); + else this->_cursorTimer.stop(); + this->_data = data; + this->_originalData = data; + this->adjust(); + this->setCursorPos(0); + this->setFocus(); +} + +QByteArray QHexEditPrivate::data() +{ + return _data; +} + +void QHexEditPrivate::setAddressAreaColor(const QColor &color) +{ + _addressAreaColor = color; + update(); +} + +QColor QHexEditPrivate::addressAreaColor() +{ + return _addressAreaColor; +} + +void QHexEditPrivate::setHighlightingColor(const QColor &color) +{ + _highlightingColor = color; + update(); +} + +QColor QHexEditPrivate::highlightingColor() +{ + return _highlightingColor; +} + +void QHexEditPrivate::setOverwriteMode(bool overwriteMode) +{ + if (overwriteMode != _overwriteMode) + { + emit overwriteModeChanged(overwriteMode); + _overwriteMode = overwriteMode; + adjust(); + } +} + +bool QHexEditPrivate::overwriteMode() +{ + return _overwriteMode; +} + +void QHexEditPrivate::setReadOnly(bool read_only) { + this->_readOnly=read_only; +} + +bool QHexEditPrivate::readOnly() { + return this->_readOnly; +} + +void QHexEditPrivate::insert(int i, const QByteArray & ba) +{ + _data.insert(i, ba); + _originalData.insert(i, ba); +} + +void QHexEditPrivate::insert(int i, char ch) +{ + _data.insert(i, ch); + _originalData.insert(i, ch); +} + +void QHexEditPrivate::remove(int index, int len) +{ + _data.remove(index, len); + _originalData.remove(index, len); +} + +void QHexEditPrivate::setAddressArea(bool addressArea) +{ + _addressArea = addressArea; + adjust(); + setCursorPos(_cursorPosition); +} + +void QHexEditPrivate::setAddressWidth(int addressWidth) +{ + if ((addressWidth >= 0) and (addressWidth<=6)) + { + _addressNumbers = addressWidth; + adjust(); + setCursorPos(_cursorPosition); + } +} + +void QHexEditPrivate::setAsciiArea(bool asciiArea) +{ + _asciiArea = asciiArea; + adjust(); +} + +void QHexEditPrivate::setFont(const QFont &font) +{ + QWidget::setFont(font); + adjust(); +} + +void QHexEditPrivate::setHighlighting(bool mode) +{ + _highlighting = mode; + update(); +} + +void QHexEditPrivate::keyPressEvent(QKeyEvent *event) +{ + bool down = false; + int charX = (_cursorX - _xPosHex) / _charWidth; + int posX = (charX / 3) * 2 + (charX % 3); + int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2; + + int key = int(event->text()[0].toAscii()); + if (!this->_readOnly && + ((key>='0' && key<='9') || (key>='a' && key <= 'f'))) + { + // insert char + if (_overwriteMode == false) + if ((charX % 3) == 0) + { + insert(posBa, char(0)); + adjust(); + } + if (_data.size() > 0) + { + QByteArray hexValue = _data.mid(posBa, 1).toHex(); + if ((charX % 3) == 0) + hexValue[0] = key; + else + hexValue[1] = key; + _data.replace(posBa, 1, QByteArray().fromHex(hexValue)); + emit dataChanged(); + + setCursorPos(_cursorPosition + 1); + down = true; + } + } + + // delete char + if (!this->_readOnly && event->matches(QKeySequence::Delete)) { + remove(posBa); + } + if (!this->_readOnly && event->key() == Qt::Key_Backspace) { + remove(posBa - 1); + setCursorPos(_cursorPosition - 2); + } + + // handle other function keys + if(!this->_readOnly && event->key() == Qt::Key_Insert) { + setOverwriteMode(!_overwriteMode); + setCursorPos(_cursorPosition); + } + + if (event->matches(QKeySequence::MoveToNextChar)) + { + setCursorPos(_cursorPosition + 1); + down = true; + } + if (event->matches(QKeySequence::MoveToPreviousChar)) + setCursorPos(_cursorPosition - 1); + if (event->matches(QKeySequence::MoveToStartOfLine)) + setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); + if (event->matches(QKeySequence::MoveToEndOfLine)) + setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE -1)); + if (event->matches(QKeySequence::MoveToPreviousLine)) + setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE)); + if (event->matches(QKeySequence::MoveToPreviousPage)) + setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); + if (event->matches(QKeySequence::MoveToStartOfDocument)) + setCursorPos(0); + if (event->matches(QKeySequence::MoveToNextLine)) + { + setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE)); + down = true; + } + if (event->matches(QKeySequence::MoveToEndOfDocument)) + { + setCursorPos(_data.size() * 2); + down = true; + } + if (event->matches(QKeySequence::MoveToNextPage)) + { + setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); + down = true; + } + + // when we move downwards, we have to go a little further + if (down) + _scrollArea->ensureVisible(_cursorX, _cursorY, 3, 3 + _charHeight); + else + _scrollArea->ensureVisible(_cursorX, _cursorY, 3, 3); + update(); +} + +void QHexEditPrivate::mousePressEvent(QMouseEvent * event) +{ + setCursorPos(event->pos()); +} + +void QHexEditPrivate::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + // draw some patterns if needed + painter.fillRect(event->rect(), this->palette().color(QPalette::Base)); + if (_addressArea) + painter.fillRect(QRect(_xPosAdr, event->rect().top(), _xPosHex - GAP_ADR_HEX + 2, height()), _addressAreaColor); + if (_asciiArea) + { + int linePos = _xPosAscii - (GAP_HEX_ASCII / 2); + painter.setPen(Qt::gray); + painter.drawLine(linePos, event->rect().top(), linePos, height()); + } + + painter.setPen(this->palette().color(QPalette::WindowText)); + + // calc position + int firstLineIdx = ((event->rect().top()/ _charHeight) - _charHeight) * BYTES_PER_LINE; + if (firstLineIdx < 0) + firstLineIdx = 0; + int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE; + if (lastLineIdx > _data.size()) + lastLineIdx = _data.size(); + int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight; + + // paint address area + if (_addressArea) + { + for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) + { + QString address = QString("%1") + .arg(lineIdx + _addressOffset, _realAddressNumbers, 16, QChar('0')); + painter.drawText(_xPosAdr, yPos, address); + } + } + + // paint hex area + QByteArray hexBa(_data.mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); + QBrush highLighted = QBrush(_highlightingColor); + painter.setBackground(highLighted); + painter.setBackgroundMode(Qt::TransparentMode); + for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) + { + QByteArray hex; + int xPos = _xPosHex; + for (int colIdx = 0; ((lineIdx + colIdx) < _data.size() and (colIdx < BYTES_PER_LINE)); colIdx++) + { + // hilight diff bytes + if (_highlighting) + { + int posBa = lineIdx + colIdx; + if (posBa >= _originalData.size()) + painter.setBackgroundMode(Qt::TransparentMode); + else + if (_data[posBa] == _originalData[posBa]) + painter.setBackgroundMode(Qt::TransparentMode); + else + painter.setBackgroundMode(Qt::OpaqueMode); + } + + // render hex value + if (colIdx == 0) + { + hex = hexBa.mid((lineIdx - firstLineIdx) * 2, 2); + painter.drawText(xPos, yPos, hex); + xPos += 2 * _charWidth; + } else { + hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).prepend(" "); + painter.drawText(xPos, yPos, hex); + xPos += 3 * _charWidth; + } + } + } + painter.setBackgroundMode(Qt::TransparentMode); + + // paint ascii area + if (_asciiArea) + { + for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight) + { + QByteArray ascii = _data.mid(lineIdx, BYTES_PER_LINE); + for (int idx=0; idx < ascii.size(); idx++) + if (((char)ascii[idx] < 0x20) or ((char)ascii[idx] > 0x7e)) + ascii[idx] = '.'; + painter.drawText(_xPosAscii, yPos, ascii); + } + } + + // paint cursor + if (_blink && !this->_data.isNull() && !this->_data.isEmpty()) + { + if (_overwriteMode) + painter.fillRect(_cursorX, _cursorY + _charHeight - 2, _charWidth, 2, this->palette().color(QPalette::WindowText)); + else + painter.fillRect(_cursorX, _cursorY, 2, _charHeight, this->palette().color(QPalette::WindowText)); + } + + if (_size != _data.size()) + { + _size = _data.size(); + emit currentSizeChanged(_size); + } +} + +void QHexEditPrivate::setCursorPos(int position) +{ + // delete cursor + _blink = false; + update(); + + // cursor in range? + if (_overwriteMode) + { + if (position > (_data.size() * 2 - 1)) + position = _data.size() * 2 - 1; + } else { + if (position > (_data.size() * 2)) + position = _data.size() * 2; + } + + if (position < 0) + position = 0; + + // calc position + _cursorPosition = position; + _cursorY = (position / (2 * BYTES_PER_LINE)) * _charHeight + 4; + int x = (position % (2 * BYTES_PER_LINE)); + _cursorX = (((x / 2) * 3) + (x % 2)) * _charWidth + _xPosHex; + + // immiadately draw cursor + _blink = true; + update(); + emit currentAddressChanged(_cursorPosition/2); +} + +void QHexEditPrivate::setCursorPos(QPoint pos) +{ + // find char under cursor + if ((pos.x() >= _xPosHex) and (pos.x() < (_xPosHex + HEXCHARS_IN_LINE * _charWidth))) + { + int x = (pos.x() - _xPosHex) / _charWidth; + if ((x % 3) == 0) + x = (x / 3) * 2; + else + x = ((x / 3) * 2) + 1; + int y = (pos.y() / _charHeight) * 2 * BYTES_PER_LINE; + setCursorPos(x + y); + } +} + +void QHexEditPrivate::updateCursor() +{ + if (_blink) + _blink = false; + else + _blink = true; + update(_cursorX, _cursorY, _charWidth, _charHeight); +} + +void QHexEditPrivate::adjust() +{ + _charWidth = fontMetrics().width(QLatin1Char('9')); + _charHeight = fontMetrics().height(); + + // is addressNumbers wide enought? + QString test = QString("%1") + .arg(_data.size() + _addressOffset, _addressNumbers, 16, QChar('0')); + _realAddressNumbers = test.size(); + + _xPosAdr = 0; + if (_addressArea) + _xPosHex = _realAddressNumbers *_charWidth + GAP_ADR_HEX; + else + _xPosHex = 0; + _xPosAscii = _xPosHex + HEXCHARS_IN_LINE * _charWidth + GAP_HEX_ASCII; + + // tell QAbstractScollbar, how big we are + setMinimumHeight(((_data.size()/16 + 1) * _charHeight) + 3); + setMinimumWidth(_xPosAscii + (BYTES_PER_LINE * _charWidth)); + + update(); +} diff --git a/tags/fred-0.1.0beta1/qhexedit/qhexedit_p.h b/tags/fred-0.1.0beta1/qhexedit/qhexedit_p.h new file mode 100644 index 0000000..70ec39e --- /dev/null +++ b/tags/fred-0.1.0beta1/qhexedit/qhexedit_p.h @@ -0,0 +1,109 @@ +/******************************************************************************* +* qhexedit Copyright (c) 2011 by Gillen Daniel * +* * +* Simple hex editor widget for Qt. * +* * +* Derived from code by Simon Winfried under a compatible license: * +* Copyright (c) 2010 by Simon Winfried * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#ifndef QHEXEDIT_P_H +#define QHEXEDIT_P_H + +/** \cond docNever */ + + +#include + +class QHexEditPrivate : public QWidget +{ +Q_OBJECT + +public: + QHexEditPrivate(QScrollArea *parent); + + void setAddressOffset(int offset); + int addressOffset(); + + void setData(QByteArray const &data); + QByteArray data(); + + void setAddressAreaColor(QColor const &color); + QColor addressAreaColor(); + + void setHighlightingColor(QColor const &color); + QColor highlightingColor(); + + void setOverwriteMode(bool overwriteMode); + bool overwriteMode(); + void setReadOnly(bool read_only); + bool readOnly(); + + void insert(int i, const QByteArray & ba); + void insert(int i, char ch); + void remove(int index, int len=1); + + void setAddressArea(bool addressArea); + void setAddressWidth(int addressWidth); + void setAsciiArea(bool asciiArea); + void setHighlighting(bool mode); + virtual void setFont(const QFont &font); + +signals: + void currentAddressChanged(int address); + void currentSizeChanged(int size); + void dataChanged(); + void overwriteModeChanged(bool state); + +protected: + void keyPressEvent(QKeyEvent * event); + void mousePressEvent(QMouseEvent * event); + void paintEvent(QPaintEvent *event); + void setCursorPos(QPoint pos); + void setCursorPos(int position); + +private slots: + void updateCursor(); + +private: + void adjust(); + + QColor _addressAreaColor; + QByteArray _data; + QByteArray _originalData; + QColor _highlightingColor; + QScrollArea *_scrollArea; + QTimer _cursorTimer; + + bool _blink; + bool _addressArea; + bool _asciiArea; + bool _highlighting; + bool _overwriteMode; + bool _readOnly; + + int _addressNumbers, _realAddressNumbers; + int _addressOffset; + int _charWidth, _charHeight; + int _cursorX, _cursorY, _cursorPosition; + int _xPosAdr, _xPosHex, _xPosAscii; + int _size; +}; + +/** \endcond docNever */ + +#endif + diff --git a/tags/fred-0.1.0beta1/qtscript_types/bytearray.cpp b/tags/fred-0.1.0beta1/qtscript_types/bytearray.cpp new file mode 100644 index 0000000..37df935 --- /dev/null +++ b/tags/fred-0.1.0beta1/qtscript_types/bytearray.cpp @@ -0,0 +1,181 @@ +/******************************************************************************* +* Copyright (c) 2011 by Gillen Daniel * +* * +* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a * +* compatible license: * +* * +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * +* All rights reserved. * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#include + +#include "bytearray.h" +#include "bytearrayiterator.h" +#include "bytearrayprototype.h" + +#include + +Q_DECLARE_METATYPE(QByteArray*) +Q_DECLARE_METATYPE(ByteArray*) + +ByteArray::ByteArray(QScriptEngine *engine) + : QObject(engine), QScriptClass(engine) +{ + qScriptRegisterMetaType(engine, + this->toScriptValue, + this->fromScriptValue); + + this->length=engine->toStringHandle(QLatin1String("length")); + + this->proto=engine->newQObject(new ByteArrayPrototype(this), + QScriptEngine::QtOwnership, + QScriptEngine::SkipMethodsInEnumeration | + QScriptEngine::ExcludeSuperClassMethods | + QScriptEngine::ExcludeSuperClassProperties); + QScriptValue global=engine->globalObject(); + proto.setPrototype(global.property("Object").property("prototype")); + + this->ctor=engine->newFunction(this->construct,this->proto); + this->ctor.setData(qScriptValueFromValue(engine,this)); +} + +ByteArray::~ByteArray() {} + +QScriptClass::QueryFlags ByteArray::queryProperty(const QScriptValue &object, + const QScriptString &name, + QueryFlags flags, + uint *id) +{ + QByteArray *ba=qscriptvalue_cast(object.data()); + + if(!ba) return 0; + if(name!=this->length) { + bool is_array_index; + qint32 pos=name.toArrayIndex(&is_array_index); + if(!is_array_index) return 0; + *id=pos; + if((flags & HandlesReadAccess) && (pos>=ba->size())) + flags &= ~HandlesReadAccess; + } + + return flags; +} + +QScriptValue ByteArray::property(const QScriptValue &object, + const QScriptString &name, + uint id) +{ + QByteArray *ba=qscriptvalue_cast(object.data()); + if(!ba) return QScriptValue(); + if(name==length) return ba->length(); + else { + qint32 pos=id; + if((pos < 0) || (pos >= ba->size())) return QScriptValue(); + return uint(ba->at(pos)) & 255; + } + + return QScriptValue(); +} + +void ByteArray::setProperty(QScriptValue &object, + const QScriptString &name, + uint id, + const QScriptValue &value) +{ + QByteArray *ba=qscriptvalue_cast(object.data()); + if(!ba) return; + if(name==length) this->resize(*ba,value.toInt32()); + else { + qint32 pos=id; + if(pos<0) return; + if(ba->size()<=pos) this->resize(*ba,pos + 1); + (*ba)[pos]=char(value.toInt32()); + } +} + +QScriptValue::PropertyFlags ByteArray::propertyFlags(const QScriptValue &object, + const QScriptString &name, + uint id) +{ + Q_UNUSED(object); + Q_UNUSED(id); + + if(name==length) { + return QScriptValue::Undeletable | QScriptValue::SkipInEnumeration; + } + return QScriptValue::Undeletable; +} + +QScriptClassPropertyIterator *ByteArray::newIterator(const QScriptValue &object) +{ + return new ByteArrayIterator(object); +} + +QString ByteArray::name() const { + return QLatin1String("ByteArray"); +} + +QScriptValue ByteArray::prototype() const { + return proto; +} + +QScriptValue ByteArray::constructor() { + return ctor; +} + +QScriptValue ByteArray::newInstance(int size) { +#if QT_VERSION >= 0x040700 + this->engine()->reportAdditionalMemoryCost(size); +#endif + return newInstance(QByteArray(size,0)); +} + +QScriptValue ByteArray::newInstance(const QByteArray &ba) { + QScriptValue data=engine()->newVariant(qVariantFromValue(ba)); + return engine()->newObject(this,data); +} + +QScriptValue ByteArray::construct(QScriptContext *ctx, QScriptEngine *) { + ByteArray *cls=qscriptvalue_cast(ctx->callee().data()); + if(!cls) return QScriptValue(); + QScriptValue arg=ctx->argument(0); + if(arg.instanceOf(ctx->callee())) + return cls->newInstance(qscriptvalue_cast(arg)); + int size=arg.toInt32(); + return cls->newInstance(size); +} + +QScriptValue ByteArray::toScriptValue(QScriptEngine *eng, const QByteArray &ba) +{ + QScriptValue ctor=eng->globalObject().property("ByteArray"); + ByteArray *cls=qscriptvalue_cast(ctor.data()); + if(!cls) return eng->newVariant(qVariantFromValue(ba)); + return cls->newInstance(ba); +} + +void ByteArray::fromScriptValue(const QScriptValue &obj, QByteArray &ba) { + ba=qvariant_cast(obj.data().toVariant()); +} + +void ByteArray::resize(QByteArray &ba, int newSize) { + int oldSize=ba.size(); + ba.resize(newSize); +#if QT_VERSION >= 0x040700 + if(newSize>oldSize) + this->engine()->reportAdditionalMemoryCost(newSize-oldSize); +#endif + } diff --git a/tags/fred-0.1.0beta1/qtscript_types/bytearray.h b/tags/fred-0.1.0beta1/qtscript_types/bytearray.h new file mode 100644 index 0000000..154f577 --- /dev/null +++ b/tags/fred-0.1.0beta1/qtscript_types/bytearray.h @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (c) 2011 by Gillen Daniel * +* * +* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a * +* compatible license: * +* * +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * +* All rights reserved. * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +// Description: http://cs.karelia.ru/~aborod/doc/qt/script-customclass.html + +#ifndef BYTEARRAY_H +#define BYTEARRAY_H + +#include +#include +#include + +class ByteArray : public QObject, public QScriptClass { + public: + ByteArray(QScriptEngine *engine); + ~ByteArray(); + + QScriptValue constructor(); + + QScriptValue newInstance(int size = 0); + QScriptValue newInstance(const QByteArray &ba); + + QueryFlags queryProperty(const QScriptValue &object, + const QScriptString &name, + QueryFlags flags, + uint *id); + QScriptValue property(const QScriptValue &object, + const QScriptString &name, + uint id); + void setProperty(QScriptValue &object, + const QScriptString &name, + uint id, + const QScriptValue &value); + QScriptValue::PropertyFlags propertyFlags(const QScriptValue &object, + const QScriptString &name, + uint id); + QScriptClassPropertyIterator *newIterator(const QScriptValue &object); + + QString name() const; + + QScriptValue prototype() const; + + private: + static QScriptValue construct(QScriptContext *ctx, QScriptEngine *eng); + + static QScriptValue toScriptValue(QScriptEngine *eng, const QByteArray &ba); + static void fromScriptValue(const QScriptValue &obj, QByteArray &ba); + + void resize(QByteArray &ba, int newSize); + + QScriptString length; + QScriptValue proto; + QScriptValue ctor; +}; + +#endif // BYTEARRAY_H diff --git a/tags/fred-0.1.0beta1/qtscript_types/bytearrayiterator.cpp b/tags/fred-0.1.0beta1/qtscript_types/bytearrayiterator.cpp new file mode 100644 index 0000000..920f699 --- /dev/null +++ b/tags/fred-0.1.0beta1/qtscript_types/bytearrayiterator.cpp @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (c) 2011 by Gillen Daniel * +* * +* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a * +* compatible license: * +* * +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * +* All rights reserved. * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#include "bytearrayiterator.h" + +#include + +Q_DECLARE_METATYPE(QByteArray*) + +ByteArrayIterator::ByteArrayIterator(const QScriptValue &object) + : QScriptClassPropertyIterator(object) +{ + toFront(); +} + +ByteArrayIterator::~ByteArrayIterator() {} + +bool ByteArrayIterator::hasNext() const { + QByteArray *ba=qscriptvalue_cast(object().data()); + return m_indexsize(); +} + +void ByteArrayIterator::next() { + m_last=m_index; + ++m_index; +} + +bool ByteArrayIterator::hasPrevious() const { + return(m_index>0); +} + +void ByteArrayIterator::previous() { + --m_index; + m_last=m_index; +} + +void ByteArrayIterator::toFront() { + m_index=0; + m_last=-1; +} + +void ByteArrayIterator::toBack() { + QByteArray *ba=qscriptvalue_cast(object().data()); + m_index=ba->size(); + m_last=-1; +} + +QScriptString ByteArrayIterator::name() const { + return this->object().engine()->toStringHandle(QString::number(this->m_last)); +} + +uint ByteArrayIterator::id() const { + return m_last; +} diff --git a/tags/fred-0.1.0beta1/qtscript_types/bytearrayiterator.h b/tags/fred-0.1.0beta1/qtscript_types/bytearrayiterator.h new file mode 100644 index 0000000..3574ea8 --- /dev/null +++ b/tags/fred-0.1.0beta1/qtscript_types/bytearrayiterator.h @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (c) 2011 by Gillen Daniel * +* * +* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a * +* compatible license: * +* * +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * +* All rights reserved. * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#ifndef BYTEARRAYITERATOR_H +#define BYTEARRAYITERATOR_H + +#include + +class ByteArrayIterator : public QScriptClassPropertyIterator { + public: + ByteArrayIterator(const QScriptValue &object); + ~ByteArrayIterator(); + + bool hasNext() const; + void next(); + + bool hasPrevious() const; + void previous(); + + void toFront(); + void toBack(); + + QScriptString name() const; + uint id() const; + + private: + int m_index; + int m_last; +}; + +#endif // BYTEARRAYITERATOR_H diff --git a/tags/fred-0.1.0beta1/qtscript_types/bytearrayprototype.cpp b/tags/fred-0.1.0beta1/qtscript_types/bytearrayprototype.cpp new file mode 100644 index 0000000..dca2279 --- /dev/null +++ b/tags/fred-0.1.0beta1/qtscript_types/bytearrayprototype.cpp @@ -0,0 +1,93 @@ +/******************************************************************************* +* Copyright (c) 2011 by Gillen Daniel * +* * +* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a * +* compatible license: * +* * +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * +* All rights reserved. * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#include "bytearrayprototype.h" +#include + +Q_DECLARE_METATYPE(QByteArray*) + +ByteArrayPrototype::ByteArrayPrototype(QObject *p_parent) : QObject(p_parent) {} + +ByteArrayPrototype::~ByteArrayPrototype() {} + +QByteArray *ByteArrayPrototype::thisByteArray() const { + return qscriptvalue_cast(thisObject().data()); +} + +void ByteArrayPrototype::chop(int n) { + thisByteArray()->chop(n); +} + +bool ByteArrayPrototype::equals(const QByteArray &other) { + return *thisByteArray()==other; +} + +QByteArray ByteArrayPrototype::left(int len) const { + return thisByteArray()->left(len); +} + +QByteArray ByteArrayPrototype::mid(int pos, int len) const { + return thisByteArray()->mid(pos,len); +} + +QScriptValue ByteArrayPrototype::remove(int pos, int len) { + thisByteArray()->remove(pos,len); + return thisObject(); +} + +QByteArray ByteArrayPrototype::right(int len) const { + return thisByteArray()->right(len); +} + +QByteArray ByteArrayPrototype::simplified() const { + return thisByteArray()->simplified(); +} + +QByteArray ByteArrayPrototype::toBase64() const { + return thisByteArray()->toBase64(); +} + +QByteArray ByteArrayPrototype::toLower() const { + return thisByteArray()->toLower(); +} + +QByteArray ByteArrayPrototype::toUpper() const { + return thisByteArray()->toUpper(); +} + +QByteArray ByteArrayPrototype::trimmed() const { + return thisByteArray()->trimmed(); +} + +void ByteArrayPrototype::truncate(int pos) { + thisByteArray()->truncate(pos); +} + +QString ByteArrayPrototype::toLatin1String() const { + return QString::fromLatin1(*thisByteArray()); +} + +QScriptValue ByteArrayPrototype::valueOf() const { + return thisObject().data(); +} + diff --git a/tags/fred-0.1.0beta1/qtscript_types/bytearrayprototype.h b/tags/fred-0.1.0beta1/qtscript_types/bytearrayprototype.h new file mode 100644 index 0000000..adc2a5e --- /dev/null +++ b/tags/fred-0.1.0beta1/qtscript_types/bytearrayprototype.h @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (c) 2011 by Gillen Daniel * +* * +* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a * +* compatible license: * +* * +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * +* All rights reserved. * +* * +* This program is free software: you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation, either version 3 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along with * +* this program. If not, see . * +*******************************************************************************/ + +#ifndef BYTEARRAYPROTOTYPE_H +#define BYTEARRAYPROTOTYPE_H + +#include +#include +#include +#include + +class ByteArrayPrototype : public QObject, public QScriptable { + Q_OBJECT + + public: + ByteArrayPrototype(QObject *p_parent=0); + ~ByteArrayPrototype(); + + public slots: + void chop(int n); + bool equals(const QByteArray &other); + QByteArray left(int len) const; + QByteArray mid(int pos, int len = -1) const; + QScriptValue remove(int pos, int len); + QByteArray right(int len) const; + QByteArray simplified() const; + QByteArray toBase64() const; + QByteArray toLower() const; + QByteArray toUpper() const; + QByteArray trimmed() const; + void truncate(int pos); + QString toLatin1String() const; + QScriptValue valueOf() const; + + private: + QByteArray *thisByteArray() const; +}; + +#endif // BYTEARRAYPROTOTYPE_H + diff --git a/tags/fred-0.1.0beta1/registryhive.cpp b/tags/fred-0.1.0beta1/registryhive.cpp new file mode 100644 index 0000000..256d1fd --- /dev/null +++ b/tags/fred-0.1.0beta1/registryhive.cpp @@ -0,0 +1,462 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "registryhive.h" + +#include + +#include + +/* + * RegistryHive + */ +RegistryHive::RegistryHive(QObject *p_parent) : QObject(p_parent) { + this->erro_msg=""; + this->is_error=false; + this->hive_file=""; + this->p_hive=NULL; + this->is_hive_open=false; +} + +/* + * ~RegistryHive + */ +RegistryHive::~RegistryHive() { + if(this->is_hive_open) this->Close(); +} + +/* + * Error + */ +bool RegistryHive::Error() { + return this->is_error; +} + +/* + * GetErrorMsg + */ +QString RegistryHive::GetErrorMsg() { + QString msg=this->erro_msg; + this->erro_msg=""; + this->is_error=false; + return msg; +} + +/* + * Open + */ +bool RegistryHive::Open(QString file, bool read_only) { + if(this->is_hive_open) return false; + + // Open hive file + this->p_hive=hivex_open(file.toAscii().constData(), + read_only ? 0 : HIVEX_OPEN_WRITE); + if(this->p_hive==NULL) return false; + + // Set local vars + this->hive_file=file; + this->is_hive_open=true; + + return true; +} + +/* + * Close + */ +bool RegistryHive::Close(bool commit_changes) { + if(this->is_hive_open) { + if(commit_changes) { + // Commit changes before closing hive. + // TODO: Maybe it would be more secure to commit changes to a new file and + // then move it over the original one. + hivex_commit(this->p_hive,NULL,0); + } + + // As hivex_close will _ALWAYS_ free the handle, we don't need the following + // values anymore + this->hive_file=""; + this->is_hive_open=false; + + // Close hive + if(hivex_close(this->p_hive)!=0) return false; + } + return true; +} + +/* + * GetNodes + */ +QMap RegistryHive::GetNodes(QString path) { + hive_node_h parent_node; + + // Get handle to last node in path + if(!this->GetNodeHandle(path,&parent_node)) return QMap(); + + // Get and return nodes + return this->GetNodesHelper(parent_node); +} + +/* + * GetNodes + */ +QMap RegistryHive::GetNodes(int parent_node) { + if(parent_node==0) { + this->SetError(tr("Invalid parent node handle specified!")); + return QMap(); + } + + // Get and return nodes + return this->GetNodesHelper(parent_node); +} + +/* + * GetKeys + */ +QMap RegistryHive::GetKeys(QString path) { + hive_node_h parent_node; + + // Get handle to last node in path + if(!this->GetNodeHandle(path,&parent_node)) return QMap(); + + // Get and return keys + return this->GetKeysHelper(parent_node); +} + +/* + * GetKeys + */ +QMap RegistryHive::GetKeys(int parent_node) { + if(parent_node==0) { + this->SetError(tr("Invalid parent node handle specified!")); + return QMap(); + } + + // Get and return keys + return this->GetKeysHelper(parent_node); +} + +/* + * GetKeyValue + */ +QByteArray RegistryHive::GetKeyValue(QString path, + QString key, + int *p_value_type, + size_t *p_value_len) +{ + hive_node_h parent_node; + hive_value_h hive_key; + + // Get handle to last node in path + if(!this->GetNodeHandle(path,&parent_node)) return QByteArray(); + + // Get key handle + hive_key=hivex_node_get_value(this->p_hive, + parent_node,key.toAscii().constData()); + if(hive_key==0) { + this->SetError(tr("Unable to get key handle!")); + *p_value_len=-1; + return QByteArray(); + } + + // Get and return key value + return this->GetKeyValueHelper(hive_key,p_value_type,p_value_len); +} + +/* + * GetKeyValue + */ +QByteArray RegistryHive::GetKeyValue(int hive_key, + int *p_value_type, + size_t *p_value_len) +{ + if(hive_key==0) { + this->SetError(tr("Invalid key handle specified!")); + *p_value_type=-1; + return QByteArray(); + } + + // Get and return key value + return this->GetKeyValueHelper(hive_key,p_value_type,p_value_len); +} + +/* + * KeyValueToString + */ +QString RegistryHive::KeyValueToString(QByteArray value, int value_type) { + QString ret=""; + int i=0; + + #define ToHexStr() { \ + for(i=0;ierro_msg=msg; + this->is_error=true; +} + +/* + * GetNodeHandle + */ +bool RegistryHive::GetNodeHandle(QString &path, hive_node_h *p_node) { + QStringList nodes; + int i=0; + + // Get root node handle + *p_node=hivex_root(this->p_hive); + if(*p_node==0) { + this->SetError(tr("Unable to get root node!")); + return false; + } + + if(path!="\\") { + // If we aren't listing the root node, we have to get a handle to the + // last node in the path. Split path into nodes + nodes=path.split('\\',QString::SkipEmptyParts); + + // Iterate to the correct parent node + for(i=0;ip_hive, + *p_node, + nodes.value(i).toAscii().constData()); + if(*p_node==0) { + this->SetError(tr("Unable to find node '%1'!").arg(nodes.value(i))); + return false; + } + } + } + + return true; +} + +/* + * GetNodesHelper + */ +QMap RegistryHive::GetNodesHelper(hive_node_h parent_node) { + QMap keys; + char *p_name; + int i=0; + + // Get child nodes + hive_node_h *child_nodes=hivex_node_children(this->p_hive,parent_node); + if(child_nodes==NULL) { + this->SetError( + tr("Unable to enumerate child nodes!")); + return QMap(); + } + + // Build result + keys.clear(); + i=0; + while(child_nodes[i]) { + p_name=hivex_node_name(this->p_hive,child_nodes[i]); + if(p_name==NULL) { + this->SetError(tr("Unable to get node name!")); + free(child_nodes); + return QMap(); + } + keys.insert(QString(p_name),(int)child_nodes[i]); + free(p_name); + i++; + } + free(child_nodes); + + return keys; +} + +/* + * GetKeysHelper + */ +QMap RegistryHive::GetKeysHelper(hive_node_h parent_node) { + QMap keys; + char *p_name; + int i=0; + + // Get child keys + hive_value_h *p_keys=hivex_node_values(this->p_hive,parent_node); + if(p_keys==NULL) { + this->SetError( + tr("Unable to enumerate child keys!")); + return QMap(); + } + + // Build result list + keys.clear(); + i=0; + while(p_keys[i]) { + p_name=hivex_value_key(this->p_hive,p_keys[i]); + if(p_name==NULL) { + this->SetError(tr("Unable to get key name!")); + return QMap(); + } + keys.insert(QString(p_name),p_keys[i]); + free(p_name); + i++; + } + free(p_keys); + + return keys; +} + +QByteArray RegistryHive::GetKeyValueHelper(hive_value_h hive_key, + int *p_value_type, + size_t *p_value_len) +{ + QByteArray key_value; + char *p_key_value; + + p_key_value=hivex_value_value(this->p_hive, + hive_key, + (hive_type*)p_value_type, + p_value_len); + if(p_key_value==NULL) { + this->SetError(tr("Unable to get key value!")); + *p_value_type=-1; + return QByteArray(); + } + + // Feed QByteArray and free p_key_value + key_value=QByteArray(p_key_value,*p_value_len); + free(p_key_value); + + return key_value; +} diff --git a/tags/fred-0.1.0beta1/registryhive.h b/tags/fred-0.1.0beta1/registryhive.h new file mode 100644 index 0000000..9230c1a --- /dev/null +++ b/tags/fred-0.1.0beta1/registryhive.h @@ -0,0 +1,74 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 REGISTRYHIVE_H +#define REGISTRYHIVE_H + +#include +#include + +#include + +class RegistryHive : public QObject { + Q_OBJECT + + public: + explicit RegistryHive(QObject *p_parent=0); + ~RegistryHive(); + + bool Error(); + QString GetErrorMsg(); + + bool Open(QString file, bool read_only=true); + bool Close(bool commit_changes=false); + + QMap GetNodes(QString path="\\"); + QMap GetNodes(int parent_node=0); + QMap GetKeys(QString path="\\"); + QMap GetKeys(int parent_node=0); + QByteArray GetKeyValue(QString path, + QString key, + int *p_value_type, + size_t *p_value_len); + QByteArray GetKeyValue(int hive_key, + int *p_value_type, + size_t *p_value_len); + Q_INVOKABLE static QString KeyValueToString(QByteArray value, + int value_type); + Q_INVOKABLE static QString KeyTypeToString(int value_type); + + private: + QString erro_msg; + bool is_error; + QString hive_file; + hive_h *p_hive; + bool is_hive_open; + + void SetError(QString msg); + bool GetNodeHandle(QString &path, hive_node_h *p_node); + QMap GetNodesHelper(hive_node_h parent_node); + QMap GetKeysHelper(hive_node_h parent_node); + QByteArray GetKeyValueHelper(hive_value_h hive_key, + int *p_value_type, + size_t *p_value_len); + +}; + +#endif // REGISTRYHIVE_H diff --git a/tags/fred-0.1.0beta1/registrykey.cpp b/tags/fred-0.1.0beta1/registrykey.cpp new file mode 100644 index 0000000..611216b --- /dev/null +++ b/tags/fred-0.1.0beta1/registrykey.cpp @@ -0,0 +1,54 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "registrykey.h" + +RegistryKey::RegistryKey(const QList &data) { + this->key_data=data; +} + +RegistryKey::~RegistryKey() { + qDeleteAll(this->keys); +} + +void RegistryKey::Append(RegistryKey *p_key) { + this->keys.append(p_key); +} + +RegistryKey* RegistryKey::Key(uint64_t row) { + return this->keys.value(row); +} + +uint64_t RegistryKey::RowCount() { + return this->keys.count(); +} + +QVariant RegistryKey::Data(uint64_t column) const { + if(column>=0 && column<3) { + return this->key_data.value(column); + } else { + return QVariant(); + } +} + +uint64_t RegistryKey::Row() const { + return this->keys.indexOf(const_cast(this)); +} + diff --git a/tags/fred-0.1.0beta1/registrykey.h b/tags/fred-0.1.0beta1/registrykey.h new file mode 100644 index 0000000..dedeeb6 --- /dev/null +++ b/tags/fred-0.1.0beta1/registrykey.h @@ -0,0 +1,44 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 REGISTRYKEY_H +#define REGISTRYKEY_H + +#include +#include +#include + +class RegistryKey { + public: + RegistryKey(const QList &data); + ~RegistryKey(); + + void Append(RegistryKey *p_key); + RegistryKey *Key(uint64_t row); + uint64_t RowCount(); + QVariant Data(uint64_t column) const; + uint64_t Row() const; + + private: + QList keys; + QList key_data; +}; + +#endif // REGISTRYKEY_H diff --git a/tags/fred-0.1.0beta1/registrykeytablemodel.cpp b/tags/fred-0.1.0beta1/registrykeytablemodel.cpp new file mode 100644 index 0000000..6bbb483 --- /dev/null +++ b/tags/fred-0.1.0beta1/registrykeytablemodel.cpp @@ -0,0 +1,297 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "registrykeytablemodel.h" + +#include + +RegistryKeyTableModel::RegistryKeyTableModel(RegistryHive *p_hive, + QString node_path, + QObject *p_parent) + : QAbstractTableModel(p_parent) +{ + // Create the "root" key. It's values will be used for as header values. + this->p_keys=new RegistryKey(QList()<< + tr("Key")<SetupModelData(p_hive,node_path); +} + +RegistryKeyTableModel::~RegistryKeyTableModel() { + delete this->p_keys; +} + +QVariant RegistryKeyTableModel::data(const QModelIndex &index, int role) const { + bool ok; + + if(!index.isValid()) return QVariant(); + + RegistryKey *p_key=static_cast(index.internalPointer()); + + switch(role) { + case Qt::DisplayRole: { + switch(index.column()) { + case RegistryKeyTableModel::ColumnContent_KeyName: { + return p_key->Data(index.column()); + break; + } + case RegistryKeyTableModel::ColumnContent_KeyType: { + int value_type=p_key->Data(index.column()).toInt(&ok); + if(!ok) return QVariant(); + return this->TypeToString(value_type); + break; + } + case RegistryKeyTableModel::ColumnContent_KeyValue: { + // Get index to value type + QModelIndex type_index=this->index(index.row(), + RegistryKeyTableModel:: + ColumnContent_KeyType); + // Get value type + int value_type=this->data(type_index, + RegistryKeyTableModel:: + AdditionalRoles_GetRawData).toInt(&ok); + if(!ok) return QVariant(); + // Return value converted to human readeable string + QByteArray value_array=p_key->Data(index.column()).toByteArray(); + return this->ValueToString(value_array,value_type); + break; + } + default: + return QVariant(); + } + break; + } + case RegistryKeyTableModel::AdditionalRoles_GetRawData: { + return p_key->Data(index.column()); + break; + } + default: + return QVariant(); + } + return QVariant(); +} + +Qt::ItemFlags RegistryKeyTableModel::flags(const QModelIndex &index) const { + if(!index.isValid()) return 0; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant RegistryKeyTableModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + // Only horizontal header is supported + if(orientation!=Qt::Horizontal) return QVariant(); + + switch(role) { + case Qt::TextAlignmentRole: + // Handle text alignment + if(section==2) return Qt::AlignLeft; + else return Qt::AlignCenter; + break; + case Qt::DisplayRole: + // Header text + return this->p_keys->Data(section); + break; + default: + return QVariant(); + } +} + +QModelIndex RegistryKeyTableModel::index(int row, + int column, + const QModelIndex &parent) const +{ + if(!this->hasIndex(row,column,parent)) return QModelIndex(); + + RegistryKey *p_key=this->p_keys->Key(row); + + return this->createIndex(row,column,p_key); +} + +int RegistryKeyTableModel::rowCount(const QModelIndex &parent) const { + // According to Qt doc, when parent in TableModel is valid, we should return 0 + if(parent.isValid()) return 0; + // Get and return row count from the keys list + return this->p_keys->RowCount(); +} + +int RegistryKeyTableModel::columnCount(const QModelIndex &parent) const { + // According to Qt doc, when parent in TableModel is valid, we should return 0 + if(parent.isValid()) return 0; + // There are always 3 columns + return 3; +} + +void RegistryKeyTableModel::SetupModelData(RegistryHive *p_hive, + QString &node_path) +{ + QMap node_keys; + RegistryKey *p_key; + QByteArray key_value; + int key_value_type; + size_t key_value_len; + + // Get all keys for current node + node_keys=p_hive->GetKeys(node_path); + if(node_keys.isEmpty()) return; + + // Add all keys to list + QMapIterator i(node_keys); + while(i.hasNext()) { + i.next(); + key_value=p_hive->GetKeyValue(i.value(), + &key_value_type, + &key_value_len); + if(p_hive->GetErrorMsg()!="") continue; + p_key=new RegistryKey(QList()<< + QString(i.key().length() ? i.key() : "(default)")<< + QVariant(key_value_type)<< + key_value); + this->p_keys->Append(p_key); + } +} + +QString RegistryKeyTableModel::ValueToString(QByteArray &value, + int value_type) const +{ + QString ret=""; + int i=0; + + #define ToHexStr() { \ + for(i=0;i * +* * +* 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 REGISTRYKEYTABLEMODEL_H +#define REGISTRYKEYTABLEMODEL_H + +#include + +#include "registrykey.h" +#include "registryhive.h" + +class RegistryKeyTableModel : public QAbstractTableModel { + Q_OBJECT + + public: + enum AdditionalRoles { + AdditionalRoles_GetRawData=Qt::UserRole + }; + + RegistryKeyTableModel(RegistryHive *p_hive, + QString node_path, + QObject *p_parent=0); + ~RegistryKeyTableModel(); + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, + Qt::Orientation orientation, + int role=Qt::DisplayRole) const; + QModelIndex index(int row, + int column, + const QModelIndex &parent=QModelIndex()) const; + int rowCount(const QModelIndex &parent=QModelIndex()) const; + int columnCount(const QModelIndex &parent=QModelIndex()) const; + + private: + enum ColumnContent { + ColumnContent_KeyName=0, + ColumnContent_KeyType, + ColumnContent_KeyValue + }; + + RegistryKey *p_keys; + + void SetupModelData(RegistryHive *p_hive, QString &node_path); + QString ValueToString(QByteArray &value, int value_type) const; + QString TypeToString(int value_type) const; +}; + +#endif // REGISTRYKEYTABLEMODEL_H diff --git a/tags/fred-0.1.0beta1/registrynode.cpp b/tags/fred-0.1.0beta1/registrynode.cpp new file mode 100644 index 0000000..06f4ee6 --- /dev/null +++ b/tags/fred-0.1.0beta1/registrynode.cpp @@ -0,0 +1,61 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "registrynode.h" + +RegistryNode::RegistryNode(const QString name, + RegistryNode *p_parent) +{ + this->p_parent_node=p_parent; + this->node_name=name; +} + +RegistryNode::~RegistryNode() { + qDeleteAll(this->child_nodes); +} + +void RegistryNode::AppendChild(RegistryNode *p_child) { + this->child_nodes.append(p_child); +} + +RegistryNode* RegistryNode::child(uint64_t row) { + return this->child_nodes.value(row); +} + +uint64_t RegistryNode::childCount() const { + return this->child_nodes.count(); +} + +QString RegistryNode::data() const { + return this->node_name; +} + +uint64_t RegistryNode::row() const { + if(this->p_parent_node) { + return this->p_parent_node-> + child_nodes.indexOf(const_cast(this)); + } else { + return 0; + } +} + +RegistryNode *RegistryNode::parent() { + return this->p_parent_node; +} diff --git a/tags/fred-0.1.0beta1/registrynode.h b/tags/fred-0.1.0beta1/registrynode.h new file mode 100644 index 0000000..4303963 --- /dev/null +++ b/tags/fred-0.1.0beta1/registrynode.h @@ -0,0 +1,47 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 REGISTRYNODE_H +#define REGISTRYNODE_H + +#include +#include + +#include + +class RegistryNode { + public: + RegistryNode(const QString name, RegistryNode *p_parent=0); + ~RegistryNode(); + + void AppendChild(RegistryNode *p_child); + RegistryNode *child(uint64_t row); + uint64_t childCount() const; + QString data() const; + uint64_t row() const; + RegistryNode *parent(); + + private: + QList child_nodes; + QString node_name; + RegistryNode *p_parent_node; +}; + +#endif // REGISTRYNODE_H diff --git a/tags/fred-0.1.0beta1/registrynodetreemodel.cpp b/tags/fred-0.1.0beta1/registrynodetreemodel.cpp new file mode 100644 index 0000000..078d5ac --- /dev/null +++ b/tags/fred-0.1.0beta1/registrynodetreemodel.cpp @@ -0,0 +1,138 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "registrynodetreemodel.h" + +#include + +RegistryNodeTreeModel::RegistryNodeTreeModel(RegistryHive *p_hive, + QObject *p_parent) + : QAbstractItemModel(p_parent) +{ + // Create root node + this->p_root_node=new RegistryNode("ROOT"); + // Build node list + this->SetupModelData(p_hive,this->p_root_node); +} + +RegistryNodeTreeModel::~RegistryNodeTreeModel() { + delete this->p_root_node; +} + +QVariant RegistryNodeTreeModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) return QVariant(); + if(role!=Qt::DisplayRole) return QVariant(); + + RegistryNode *p_node=static_cast(index.internalPointer()); + + return p_node->data(); +} + +Qt::ItemFlags RegistryNodeTreeModel::flags(const QModelIndex &index) const { + if(!index.isValid()) return 0; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant RegistryNodeTreeModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + Q_UNUSED(section); + if(orientation==Qt::Horizontal && role==Qt::DisplayRole) { + return QVariant("Registry key folders"); + } else { + return QVariant(); + } +} + +QModelIndex RegistryNodeTreeModel::index(int row, + int column, + const QModelIndex &parent) const +{ + if(!this->hasIndex(row,column,parent)) return QModelIndex(); + + RegistryNode *p_parent_node; + if(!parent.isValid()) { + p_parent_node=this->p_root_node; + } else { + p_parent_node=static_cast(parent.internalPointer()); + } + + RegistryNode *p_child_node=p_parent_node->child(row); + if(p_child_node) { + return this->createIndex(row,column,p_child_node); + } else { + return QModelIndex(); + } +} + +QModelIndex RegistryNodeTreeModel::parent(const QModelIndex &index) const { + if(!index.isValid()) return QModelIndex(); + + RegistryNode *p_child_node= + static_cast(index.internalPointer()); + RegistryNode *p_parent_node=p_child_node->parent(); + + if(p_parent_node==this->p_root_node) { + return QModelIndex(); + } else { + return this->createIndex(p_parent_node->row(),0,p_parent_node); + } +} + +int RegistryNodeTreeModel::rowCount(const QModelIndex &parent) const { + if(parent.column()>0) return 0; + + RegistryNode *p_parent_node; + if(!parent.isValid()) { + p_parent_node=this->p_root_node; + } else { + p_parent_node=static_cast(parent.internalPointer()); + } + + return p_parent_node->childCount(); +} + +int RegistryNodeTreeModel::columnCount(const QModelIndex &parent) const { + Q_UNUSED(parent); + return 1; +} + +void RegistryNodeTreeModel::SetupModelData(RegistryHive *p_hive, + RegistryNode *p_parent, + int hive_node) +{ + QMap hive_children; + RegistryNode *p_node; + + // Get all sub nodes of current hive node + if(hive_node) hive_children=p_hive->GetNodes(hive_node); + else hive_children=p_hive->GetNodes("\\"); + if(hive_children.isEmpty()) return; + + // Recursivly iterate over all sub nodes + QMapIterator i(hive_children); + while(i.hasNext()) { + i.next(); + p_node=new RegistryNode(i.key(),p_parent); + p_parent->AppendChild(p_node); + this->SetupModelData(p_hive,p_node,i.value()); + } +} diff --git a/tags/fred-0.1.0beta1/registrynodetreemodel.h b/tags/fred-0.1.0beta1/registrynodetreemodel.h new file mode 100644 index 0000000..941407f --- /dev/null +++ b/tags/fred-0.1.0beta1/registrynodetreemodel.h @@ -0,0 +1,56 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 REGISTRYNODETREEMODEL_H +#define REGISTRYNODETREEMODEL_H + +#include + +#include "registrynode.h" +#include "registryhive.h" + +class RegistryNodeTreeModel : public QAbstractItemModel { + Q_OBJECT + + public: + RegistryNodeTreeModel(RegistryHive *p_hive, QObject *p_parent=0); + ~RegistryNodeTreeModel(); + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, + Qt::Orientation orientation, + int role=Qt::DisplayRole) const; + QModelIndex index(int row, + int column, + const QModelIndex &parent=QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent=QModelIndex()) const; + int columnCount(const QModelIndex &parent=QModelIndex()) const; + + private: + RegistryNode *p_root_node; + + void SetupModelData(RegistryHive *p_hive, + RegistryNode *p_parent, + int hive_node=0); +}; + +#endif // REGISTRYNODETREEMODEL_H diff --git a/tags/fred-0.1.0beta1/report_templates/NTUSER_RecentDocs.qs b/tags/fred-0.1.0beta1/report_templates/NTUSER_RecentDocs.qs new file mode 100644 index 0000000..a0f9127 --- /dev/null +++ b/tags/fred-0.1.0beta1/report_templates/NTUSER_RecentDocs.qs @@ -0,0 +1,23 @@ +println(""); +println(" Recent Documents"); +println(" "); +println("

Recent documents

"); +println("

"); +println(" "); + +// Get list of recent docs +var recent_docs=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs","MRUListEx"); + +// Iterate over all recent docs +var i=0; +var runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i); +while(Number(runlist)!=0xffffffff) { + var entry=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs",runlist.toString(10)); + println(" "); + i+=4; + runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i); +} + +println("
",RegistryKeyValueToVariant(entry.value,"utf16",0),"
"); +println("

"); +println(""); diff --git a/tags/fred-0.1.0beta1/report_templates/NTUSER_TypedUrls.qs b/tags/fred-0.1.0beta1/report_templates/NTUSER_TypedUrls.qs new file mode 100644 index 0000000..29ecb94 --- /dev/null +++ b/tags/fred-0.1.0beta1/report_templates/NTUSER_TypedUrls.qs @@ -0,0 +1,17 @@ +println(""); +println(" Typed Urls"); +println(" "); +println("

Typed urls

"); +println("

"); +println(" "); + +// Iterate over all typed urls +var typed_urls=GetRegistryKeys("\\Software\\Microsoft\\Internet Explorer\\TypedURLs"); +for(var i=0;i"); +} + +println("
",RegistryKeyValueToString(val.value,val.type),"
"); +println("

"); +println(""); diff --git a/tags/fred-0.1.0beta1/report_templates/SAM_UserAccounts.qs b/tags/fred-0.1.0beta1/report_templates/SAM_UserAccounts.qs new file mode 100644 index 0000000..7ab402c --- /dev/null +++ b/tags/fred-0.1.0beta1/report_templates/SAM_UserAccounts.qs @@ -0,0 +1,81 @@ +// See http://windowsir.blogspot.com/2006/08/getting-user-info-from-image.html + +function print_table_row(cell01,cell02) { + println(" ",cell01,"",cell02,""); +} + +function print_v_info(v_key_value,info_name,str_off) { + var offset=Number(RegistryKeyValueToVariant(v_key_value,"uint16",str_off))+0x0cc; + var len=Number(RegistryKeyValueToVariant(v_key_value,"uint16",str_off+4))/2; + if(len>0) print_table_row(info_name,RegistryKeyValueToVariant(v_key_value,"utf16",offset,len)); +} + +println(""); +println(" User Accounts"); +println(" "); +println("

User accounts

"); + +// Iterate over all user names +var user_names=GetRegistryNodes("\\SAM\\Domains\\Account\\Users\\Names"); +for(var i=0;i"); + + // Print user name + println(" ",user_names[i],"
"); + + println(" "); + + // Get user rid stored in "default" key + var user_rid=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\Names\\",user_names[i]),""); + user_rid=RegistryKeyTypeToString(user_rid.type); + println(" "); + + // RegistryKeyTypeToString returns the rid prepended with "0x". We have to remove that for further processing + user_rid=String(user_rid).substr(2); + + // Get user's V key and print various infos + var v_key=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"V"); + print_v_info(v_key.value,"Full name:",0x18); + print_v_info(v_key.value,"Comment:",0x24); + print_v_info(v_key.value,"Home directory:",0x48); + print_v_info(v_key.value,"Home directory drive:",0x54); + print_v_info(v_key.value,"Logon script path:",0x60); + print_v_info(v_key.value,"Profile path:",0x6c); + + // Get user's F key and print various infos + var f_key=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"F"); + print_table_row("Last login time:",RegistryKeyValueToVariant(f_key.value,"filetime",8)); + print_table_row("Last pw change:",RegistryKeyValueToVariant(f_key.value,"filetime",24)); + print_table_row("Last failed login:",RegistryKeyValueToVariant(f_key.value,"filetime",40)); + print_table_row("Account expires:",RegistryKeyValueToVariant(f_key.value,"filetime",32)); + print_table_row("Total logins:",RegistryKeyValueToVariant(f_key.value,"uint16",66)); + print_table_row("Failed logins:",RegistryKeyValueToVariant(f_key.value,"uint16",64)); + var acc_flags=Number(RegistryKeyValueToVariant(f_key.value,"uint16",56)); + print(" "); + + // Get password hint if available + var hint=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"UserPasswordHint"); + if(typeof hint !== 'undefined') { + print_table_row("Password hint:",RegistryKeyValueToVariant(hint.value,"utf16",0)); + } + + // TODO: User group membership + + println("
RID:",Number(user_rid).toString(10)," (",user_rid,")","
Account flags:"); + if(acc_flags&0x0001) print("Disabled "); + if(acc_flags&0x0002) print("HomeDirReq "); + if(acc_flags&0x0004) print("PwNotReq "); + if(acc_flags&0x0008) print("TempDupAcc "); + // I don't think this would be useful to show + //if(acc_flags&0x0010) print("NormUserAcc "); + if(acc_flags&0x0020) print("MnsAcc "); + if(acc_flags&0x0040) print("DomTrustAcc "); + if(acc_flags&0x0080) print("WksTrustAcc "); + if(acc_flags&0x0100) print("SrvTrustAcc "); + if(acc_flags&0x0200) print("NoPwExpiry "); + if(acc_flags&0x0400) print("AccAutoLock "); + println("
"); + println("

"); +} + +println(""); diff --git a/tags/fred-0.1.0beta1/report_templates/SOFTWARE_WindowsVersion.qs b/tags/fred-0.1.0beta1/report_templates/SOFTWARE_WindowsVersion.qs new file mode 100644 index 0000000..5c301c8 --- /dev/null +++ b/tags/fred-0.1.0beta1/report_templates/SOFTWARE_WindowsVersion.qs @@ -0,0 +1,82 @@ +function print_table_row(cell01,cell02) { + println(" ",cell01,"",cell02,""); +} + +function DecodeProductKey(arr) { + //ProductKey is base24 encoded + var keychars=new Array("B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9"); + var key=new Array(30); + var ret=""; + var ncur; + + if(arr.length<66) return ret; + + arr=arr.mid(52,15); + for(var ilbyte=24;ilbyte>=0;ilbyte--) { + ncur=0; + for(var ilkeybyte=14;ilkeybyte>=0;ilkeybyte--) { + ncur=ncur*256^arr[ilkeybyte]; + arr[ilkeybyte]=ncur/24; + ncur%=24; + } + ret=keychars[ncur]+ret; + if(ilbyte%5==0 && ilbyte!=0) ret="-"+ret; + } + return ret; +} + +println(""); +println(" Windows version info"); +println(" "); +println("

Windows version info

"); +println("

"); +println(" "); + +// Windows version sp and build info +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","ProductName"); +print(" "); +// Build string +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","BuildLab"); +print_table_row("Build string:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); +// Extended build string +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","BuildLabEx"); +print_table_row("Extended build string:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); + +// Install date +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","InstallDate"); +print_table_row("Install date:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"unixtime") : "n/a"); + +// Owner and Organization info +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","RegisteredOwner"); +print_table_row("Registered owner:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","RegisteredOrganization"); +print_table_row("Registered organization:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); + +// Windows ID / Key +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","ProductId"); +print_table_row("Product ID:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","DigitalProductId"); +if(typeof val !== 'undefined') { + var key=DecodeProductKey(val.value); + if(key!="BBBBB-BBBBB-BBBBB-BBBBB-BBBBB") print_table_row("Product Key:",key); + else print_table_row("Product Key:","n/a (Probably a volume license key was used)"); +} else print_table_row("Product Key:","n/a"); + +// Install directory / Source directory +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","PathName"); +print_table_row("Install path:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","SourcePath"); +print_table_row("Source path:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); + +println("
Windows version:",RegistryKeyValueToString(val.value,val.type)); +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","CSDVersion"); +if(typeof val !== 'undefined') { + print(" ",RegistryKeyValueToString(val.value,val.type)); +} +var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","CurrentBuildNumber"); +if(typeof val !== 'undefined') { + print(" build ",RegistryKeyValueToString(val.value,val.type)); +} +println("
"); +println("

"); +println(""); diff --git a/tags/fred-0.1.0beta1/report_templates/SYSTEM_CurrentNetworkSettings.qs b/tags/fred-0.1.0beta1/report_templates/SYSTEM_CurrentNetworkSettings.qs new file mode 100644 index 0000000..583fc63 --- /dev/null +++ b/tags/fred-0.1.0beta1/report_templates/SYSTEM_CurrentNetworkSettings.qs @@ -0,0 +1,91 @@ +function print_table_row(cell01,cell02) { + println(" ",cell01,"",cell02,""); +} + +// Global vars +var val; + +// Get current controlset +var cur_controlset=GetRegistryKeyValue("\\Select","Current"); +cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type); +// Current holds a DWORD value, thus we get a string like 0x00000000, but +// control sets are referenced only with the last 3 digits. +cur_controlset="ControlSet"+String(cur_controlset).substr(7,3); + +println(""); +println(" Current Network Settings (Tcp/Ip)"); +println(" "); +println("

Current network settings (Tcp/Ip)

"); +println("

"); +println(" "); + +print_table_row("Active control set:",cur_controlset); + +// Computer name +val=GetRegistryKeyValue(cur_controlset+"\\Control\\ComputerName\\ComputerName","ComputerName"); +print_table_row("Computer name:",RegistryKeyValueToString(val.value,val.type)); + +println("
"); +println("
"); + +// Iterate over all available network adapters +var adapters=GetRegistryNodes(cur_controlset+"\\Services\\Tcpip\\Parameters\\Adapters"); +for(var i=0;i"); + + // Get configuration mode + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"EnableDHCP"); + val=Number(RegistryKeyValueToString(val.value,val.type)); + if(val) { + // DHCP enabled + print_table_row("Configuration mode:","DHCP"); + // DHCP server + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpServer"); + print_table_row("Last used DHCP server:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : ""); + // IP address + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpIPAddress"); + print_table_row("IP address:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : ""); + // Subnet mask + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpSubnetMask"); + print_table_row("Subnet mask:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : ""); + // Nameserver(s) + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpNameServer"); + print_table_row("Nameserver(s):",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : ""); + // Default gw + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpDefaultGateway"); + print_table_row("Default gateway:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : ""); + // Lease obtained + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"LeaseObtainedTime"); + print_table_row("Lease obtained:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"unixtime",0) : ""); + // Lease valid until + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"LeaseTerminatesTime"); + print_table_row("Lease terminates:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"unixtime",0) : ""); + } else { + print_table_row("Configuration mode:","Manual"); + // IP address + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"IPAddress"); + print_table_row("IP address:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : ""); + // Subnet mask + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"SubnetMask"); + print_table_row("Subnet mask:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : ""); + // Nameserver + // TODO: Has to be validated + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"NameServer"); + print_table_row("Nameserver:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : ""); + // Default gw + val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DefaultGateway"); + print_table_row("Default gateway:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : ""); + } + + println(" "); + println("
"); +} + +println("

"); +println(""); diff --git a/tags/fred-0.1.0beta1/report_templates/SYSTEM_SystemTimeInfo.qs b/tags/fred-0.1.0beta1/report_templates/SYSTEM_SystemTimeInfo.qs new file mode 100644 index 0000000..17af169 --- /dev/null +++ b/tags/fred-0.1.0beta1/report_templates/SYSTEM_SystemTimeInfo.qs @@ -0,0 +1,90 @@ +function print_table_row(cell01,cell02) { + println(" ",cell01,"",cell02,""); +} + +function ToUTC(num) { + var retnum=new Number(num); + if(retnum&0x80000000) { + retnum=((0xFFFFFFFF-retnum)+1)/60; + return "UTC+"+Number(retnum).toString(10); + } else { + retnum=retnum/60; + if(retnum!=0) return "UTC-"+Number(retnum).toString(10); + else return "UTC+"+Number(retnum).toString(10); + } +} + +// Global vars +var val; + +// Get current controlset +var cur_controlset=GetRegistryKeyValue("\\Select","Current"); +cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type); +// Current holds a DWORD value, thus we get a string like 0x00000000, but +// control sets are referenced only with the last 3 digits. +cur_controlset="ControlSet"+String(cur_controlset).substr(7,3); + +println(""); +println(" System Time Info"); +println(" "); +println("

System time info (",cur_controlset,")

"); +println("

"); +println(" Time zone info"); +println(" "); + +// Active time bias +val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","ActiveTimeBias"); +print_table_row("Active time bias:",(typeof val !== 'undefined') ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a"); + +// Std. tz name and bias +val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","StandardName"); +print_table_row("Std. time zone name:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); +val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","StandardBias"); +print_table_row("Std. time bias:",(typeof val !== 'undefined') ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a"); + +// Daylight tz name and bias +val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","DaylightName"); +print_table_row("Daylight time zone name:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); +val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","DaylightBias"); +print_table_row("Daylight time bias:",(typeof val !== 'undefined') ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a"); + +println("
"); +println("
"); +println(" W32Time service info"); +println(" "); + +// Get W32Time service settings +val=GetRegistryKeyValue(cur_controlset+"\\Services\\W32Time","Start"); +if(typeof val !== 'undefined') { + print(" "); + // If service is enabled, get ntp server + if(Number(val)<4) { + val=GetRegistryKeyValue(cur_controlset+"\\Services\\W32Time\\Parameters","NtpServer"); + print_table_row("NTP server(s):",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a"); + } +} else print_table_row("Startup method:","n/a"); + +println("
Startup method:"); + val=RegistryKeyValueToString(val.value,val.type); + switch(Number(val)) { + case 0: + print("Boot"); + break; + case 1: + print("System"); + break; + case 2: + print("Automatic"); + break; + case 3: + print("Manual"); + break; + case 4: + print("Disabled"); + break; + default: + print("Unknown"); + } + println("
"); +println("

"); +println(""); diff --git a/tags/fred-0.1.0beta1/report_templates/SYSTEM_UsbStorageDevices.qs b/tags/fred-0.1.0beta1/report_templates/SYSTEM_UsbStorageDevices.qs new file mode 100644 index 0000000..32d7353 --- /dev/null +++ b/tags/fred-0.1.0beta1/report_templates/SYSTEM_UsbStorageDevices.qs @@ -0,0 +1,43 @@ +// TODO: There is more here. Check http://www.forensicswiki.org/wiki/USB_History_Viewing + +function print_table_row(cell01,cell02) { + println(" ",cell01,"",cell02,""); +} + +// Global vars +var val; + +// Get current controlset +var cur_controlset=GetRegistryKeyValue("\\Select","Current"); +cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type); +// Current holds a DWORD value, thus we get a string like 0x00000000, but +// control sets are referenced only with the last 3 digits. +cur_controlset="ControlSet"+String(cur_controlset).substr(7,3); + +println(""); +println(" USB Storage Devices"); +println(" "); +println("

USB storage devices

"); +println("

"); + +var storage_roots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR"); +for(var i=0;i",storage_roots[i],"
"); + var storage_subroots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]); + for(ii=0;ii"); + // Note: If the second character of the unique instance ID is a '&', then the ID was + // generated by the system, as the device did not have a serial number. + print_table_row("Unique ID:",storage_subroots[ii]); + + val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"Class"); + print_table_row("Class:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : ""); + val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"DeviceDesc"); + print_table_row("Device description:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : ""); + val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"FriendlyName"); + print_table_row("Friendly name:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : ""); + } +} + +println("

"); +println(""); diff --git a/tags/fred-0.1.0beta1/reporttemplate.cpp b/tags/fred-0.1.0beta1/reporttemplate.cpp new file mode 100644 index 0000000..8f6ee11 --- /dev/null +++ b/tags/fred-0.1.0beta1/reporttemplate.cpp @@ -0,0 +1,42 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 "reporttemplate.h" + +ReportTemplate::ReportTemplate(QString report_category, + QString report_name, + QString report_template_file) +{ + this->category=report_category; + this->name=report_name; + this->template_file=report_template_file; +} + +QString ReportTemplate::ReportTemplate::Category() { + return this->category; +} + +QString ReportTemplate::ReportTemplate::Name() { + return this->name; +} + +QString ReportTemplate::ReportTemplate::File() { + return this->template_file; +} diff --git a/tags/fred-0.1.0beta1/reporttemplate.h b/tags/fred-0.1.0beta1/reporttemplate.h new file mode 100644 index 0000000..5acebeb --- /dev/null +++ b/tags/fred-0.1.0beta1/reporttemplate.h @@ -0,0 +1,42 @@ +/******************************************************************************* +* fred Copyright (c) 2011 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 REPORTTEMPLATE_H +#define REPORTTEMPLATE_H + +#include + +class ReportTemplate { + public: + ReportTemplate(QString report_category, + QString report_name, + QString report_template_file); + + QString Category(); + QString Name(); + QString File(); + + private: + QString category; + QString name; + QString template_file; +}; + +#endif // REPORTTEMPLATE_H diff --git a/tags/fred-0.1.0beta1/resources/fred.desktop b/tags/fred-0.1.0beta1/resources/fred.desktop new file mode 100755 index 0000000..8e16128 --- /dev/null +++ b/tags/fred-0.1.0beta1/resources/fred.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Version=1.0 +Encoding=UTF-8 +Name=Fred +Type=Application +Comment=M$ registry hive editor +Terminal=false +Exec=fred +Icon=fred +Categories=System; +StartupNotify=true diff --git a/tags/fred-0.1.0beta1/resources/fred.png b/tags/fred-0.1.0beta1/resources/fred.png new file mode 100644 index 0000000..6e1124c Binary files /dev/null and b/tags/fred-0.1.0beta1/resources/fred.png differ diff --git a/tags/fred-0.1.0beta1/resources/regedit.gif b/tags/fred-0.1.0beta1/resources/regedit.gif new file mode 100644 index 0000000..e66d4d4 Binary files /dev/null and b/tags/fred-0.1.0beta1/resources/regedit.gif differ diff --git a/tags/fred-0.1.0beta1/resources/tux.png b/tags/fred-0.1.0beta1/resources/tux.png new file mode 100644 index 0000000..33294b0 Binary files /dev/null and b/tags/fred-0.1.0beta1/resources/tux.png differ diff --git a/tags/fred-0.1.0beta1/resources/tux.xcf b/tags/fred-0.1.0beta1/resources/tux.xcf new file mode 100644 index 0000000..676afc2 Binary files /dev/null and b/tags/fred-0.1.0beta1/resources/tux.xcf differ diff --git a/tags/fred-0.1.0beta1/sample_data/NTUSER.DAT b/tags/fred-0.1.0beta1/sample_data/NTUSER.DAT new file mode 100644 index 0000000..7b5435a Binary files /dev/null and b/tags/fred-0.1.0beta1/sample_data/NTUSER.DAT differ diff --git a/tags/fred-0.1.0beta1/sample_data/SAM b/tags/fred-0.1.0beta1/sample_data/SAM new file mode 100644 index 0000000..b99b1bc Binary files /dev/null and b/tags/fred-0.1.0beta1/sample_data/SAM differ diff --git a/tags/fred-0.1.0beta1/sample_data/software b/tags/fred-0.1.0beta1/sample_data/software new file mode 100644 index 0000000..392bfd5 Binary files /dev/null and b/tags/fred-0.1.0beta1/sample_data/software differ diff --git a/tags/fred-0.1.0beta1/sample_data/system b/tags/fred-0.1.0beta1/sample_data/system new file mode 100644 index 0000000..f098171 Binary files /dev/null and b/tags/fred-0.1.0beta1/sample_data/system differ diff --git a/trunk/debian/changelog b/trunk/debian/changelog index 9edc012..9240078 100644 --- a/trunk/debian/changelog +++ b/trunk/debian/changelog @@ -1,18 +1,24 @@ +fred (0.1.0beta1) unstable; urgency=low + + * Fixed some minor bugs and added more report templates + + -- Daniel Gillen Mon, 22 Aug 2011 08:00:00 +0200 + fred (0.1.0alpha3) unstable; urgency=low * Added data report engine and 2 basic report templates -- Daniel Gillen Wed, 17 Aug 2011 11:30:00 +0200 fred (0.1.0alpha2) unstable; urgency=low * Integrated hexeditor into main windows. * Added data interpreters -- Daniel Gillen Tue, 09 Aug 2011 17:00:00 +0200 fred (0.1.0alpha1) unstable; urgency=low * First public release -- Daniel Gillen Sat, 06 Aug 2011 22:00:00 +0200