From 3a3bdfd48e4a35358f1f37b2a570c4a426c76600 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Sun, 28 Oct 2018 02:27:24 -0400 Subject: [PATCH] refactor extensions some and let user rearrange them --- GUI/extensions.cpp | 63 +++++++++++++++++++-------------------- GUI/extensions.h | 23 ++++++++------ GUI/mainwindow.cpp | 56 ++++++++++++++++++++++++---------- GUI/mainwindow.h | 3 +- GUI/mainwindow.ui | 7 +++++ deploy.ps1 | 33 ++++++++++++++++++-- extensions/CMakeLists.txt | 10 +++---- 7 files changed, 130 insertions(+), 65 deletions(-) diff --git a/GUI/extensions.cpp b/GUI/extensions.cpp index 1db6791..467046e 100644 --- a/GUI/extensions.cpp +++ b/GUI/extensions.cpp @@ -1,34 +1,46 @@ #include "extensions.h" -#include -#include -std::optional LoadExtension(QString file) +static std::optional LoadExtension(QString extenName) { - // Extension file format: {NUMBER}_{NAME}.dll and exports "OnNewSentence" - QRegularExpressionMatch parsedFile = QRegularExpression("^(\\d+)_(.+).dll$").match(file); - if (!parsedFile.hasMatch()) return {}; - HMODULE module = GetModuleHandleW(file.toStdWString().c_str()); - if (!module) module = LoadLibraryW(file.toStdWString().c_str()); + // Extension is dll and exports "OnNewSentence" + HMODULE module = GetModuleHandleW(extenName.toStdWString().c_str()); + if (!module) module = LoadLibraryW(extenName.toStdWString().c_str()); if (!module) return {}; FARPROC callback = GetProcAddress(module, "OnNewSentence"); if (!callback) return {}; - return Extension{ parsedFile.captured(1).toInt(), parsedFile.captured(2), (wchar_t*(*)(const wchar_t*, const InfoForExtension*))callback }; + return Extension{ extenName, (wchar_t*(*)(const wchar_t*, const InfoForExtension*))callback }; } -std::shared_mutex extenMutex; -std::set extensions; - -std::set LoadExtensions() +void Extension::Load(QString extenName) { - std::set newExtensions; - QStringList files = QDir().entryList(); - for (auto file : files) - if (auto extension = LoadExtension(file)) newExtensions.insert(extension.value()); std::unique_lock extenLock(extenMutex); - return extensions = newExtensions; + if (auto extension = LoadExtension(extenName)) extensions.push_back(extension.value()); } -bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map miscInfo) +void Extension::SendToBack(QString extenName) +{ + std::unique_lock extenLock(extenMutex); + Extension* extenIter = std::find_if(extensions.begin(), extensions.end(), [&](Extension extension) { return extension.name == extenName; }); + Extension extension = *extenIter; + extensions.erase(extenIter); + extensions.push_back(extension); +} + +void Extension::Unload(QString extenName) +{ + std::unique_lock extenLock(extenMutex); + extensions.erase(std::find_if(extensions.begin(), extensions.end(), [&](Extension extension) { return extension.name == extenName; })); + FreeLibrary(GetModuleHandleW(extenName.toStdWString().c_str())); +} + +QVector Extension::GetNames() +{ + QVector ret; + for (auto extension : extensions) ret.push_back(extension.name); + return ret; +} + +bool Extension::DispatchSentence(std::wstring& sentence, std::unordered_map miscInfo) { bool success = true; wchar_t* sentenceBuffer = (wchar_t*)HeapAlloc(GetProcessHeap(), 0, (sentence.size() + 1) * sizeof(wchar_t)); @@ -51,16 +63,3 @@ bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map extenLock(extenMutex); - if (extensions.find({ extenNumber }) == extensions.end()) return; - QString extenFileName = QString::number(extenNumber) + "_" + extensions.find({ extenNumber })->name + ".dll"; - FreeLibrary(GetModuleHandleW(extenFileName.toStdWString().c_str())); - QString removedFileName = extenFileName; - removedFileName.remove(0, removedFileName.indexOf("_")); - QFile::remove(removedFileName); - if (!QFile::rename(extenFileName, removedFileName)) QFile::remove(extenFileName); - extensions.erase(extensions.find({ extenNumber })); -} diff --git a/GUI/extensions.h b/GUI/extensions.h index 9741ccf..fd414f9 100644 --- a/GUI/extensions.h +++ b/GUI/extensions.h @@ -2,7 +2,7 @@ #define EXTENSIONS_H #include "qtcommon.h" -#include +#include struct InfoForExtension { @@ -12,16 +12,21 @@ struct InfoForExtension ~InfoForExtension() { if (next) delete next; }; }; -struct Extension +class Extension { - int number; +public: + static bool DispatchSentence(std::wstring& sentence, std::unordered_map miscInfo); + static void Load(QString extenName); + static void SendToBack(QString extenName); + static void Unload(QString extenName); + static QVector GetNames(); + QString name; - wchar_t*(*callback)(const wchar_t*, const InfoForExtension*); - bool operator<(const Extension& other) const { return number < other.number; } + wchar_t* (*callback)(const wchar_t*, const InfoForExtension*); + +private: + inline static std::shared_mutex extenMutex; + inline static QVector extensions; }; -std::set LoadExtensions(); -bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map miscInfo); -void UnloadExtension(int extenNumber); - #endif // EXTENSIONS_H diff --git a/GUI/mainwindow.cpp b/GUI/mainwindow.cpp index 6463234..7d689ba 100644 --- a/GUI/mainwindow.cpp +++ b/GUI/mainwindow.cpp @@ -11,24 +11,36 @@ MainWindow::MainWindow(QWidget *parent) : ui(new Ui::MainWindow) { ui->setupUi(this); - if (settings.contains("Window")) this->setGeometry(settings.value("Window").toRect()); - // TODO: add GUI for changing these - if (settings.contains("Flush_Delay")) TextThread::flushDelay = settings.value("Flush_Delay").toInt(); - if (settings.contains("Max_Buffer_Size")) TextThread::maxBufferSize = settings.value("Max_Buffer_Size").toInt(); processCombo = findChild("processCombo"); ttCombo = findChild("ttCombo"); extenCombo = findChild("extenCombo"); textOutput = findChild("textOutput"); + QFile extenSaveFile("Extensions.txt"); + if (extenSaveFile.exists()) + { + extenSaveFile.open(QIODevice::ReadOnly); + for (auto extenName : QString(extenSaveFile.readAll()).split(">")) Extension::Load(extenName); + } + else + { + for (auto file : QDir().entryList()) + if (file.endsWith(".dll") && file != "vnrhook.dll") Extension::Load(file.left(file.lastIndexOf(".dll"))); + } + ReloadExtensions(); + + if (settings.contains("Window")) this->setGeometry(settings.value("Window").toRect()); + // TODO: add GUI for changing these + if (settings.contains("Flush_Delay")) TextThread::flushDelay = settings.value("Flush_Delay").toInt(); + if (settings.contains("Max_Buffer_Size")) TextThread::maxBufferSize = settings.value("Max_Buffer_Size").toInt(); + connect(this, &MainWindow::SigAddProcess, this, &MainWindow::AddProcess); connect(this, &MainWindow::SigRemoveProcess, this, &MainWindow::RemoveProcess); connect(this, &MainWindow::SigAddThread, this, &MainWindow::AddThread); connect(this, &MainWindow::SigRemoveThread, this, &MainWindow::RemoveThread); connect(this, &MainWindow::SigThreadOutput, this, &MainWindow::ThreadOutput); - ReloadExtensions(); - Host::Start( [&](DWORD processId) { emit SigAddProcess(processId); }, [&](DWORD processId) { emit SigRemoveProcess(processId); }, @@ -53,7 +65,7 @@ void MainWindow::AddProcess(unsigned processId) { processCombo->addItem(QString::number(processId, 16).toUpper() + ": " + GetModuleName(processId)); QFile file("SavedHooks.txt"); - if (!file.open(QIODevice::ReadOnly)) return; + file.open(QIODevice::ReadOnly); QString processName = GetFullModuleName(processId); QStringList allProcesses = QString(file.readAll()).split("\r", QString::SkipEmptyParts); for (auto hooks = allProcesses.rbegin(); hooks != allProcesses.rend(); ++hooks) @@ -105,7 +117,7 @@ void MainWindow::ThreadOutput(TextThread* thread, QString output) bool MainWindow::ProcessThreadOutput(TextThread* thread, std::wstring& output) { - if (DispatchSentenceToExtensions(output, GetInfoForExtensions(thread))) + if (Extension::DispatchSentence(output, GetInfoForExtensions(thread))) { output += L"\r\n"; emit SigThreadOutput(thread, QString::fromStdWString(output)); @@ -140,7 +152,13 @@ DWORD MainWindow::GetSelectedProcessId() void MainWindow::ReloadExtensions() { extenCombo->clear(); - for (auto extension : LoadExtensions()) extenCombo->addItem(QString::number(extension.number) + ": " + extension.name); + QFile extenSaveFile("Extensions.txt"); + extenSaveFile.open(QIODevice::WriteOnly | QIODevice::Truncate); + for (auto extenName : Extension::GetNames()) + { + extenSaveFile.write((extenName + ">").toUtf8()); + extenCombo->addItem(extenName); + } } std::unordered_map MainWindow::GetInfoForExtensions(TextThread* thread) @@ -226,7 +244,7 @@ void MainWindow::on_saveButton_clicked() if (!(hook.type & HOOK_ENGINE)) hookList += " , " + GenerateCode(hook, GetSelectedProcessId()); QFile file("SavedHooks.txt"); - if (!file.open(QIODevice::Append | QIODevice::Text)) return; + file.open(QIODevice::Append); file.write((hookList + "\r\n").toUtf8()); } @@ -238,17 +256,25 @@ void MainWindow::on_ttCombo_activated(int index) void MainWindow::on_addExtenButton_clicked() { - QString extenFileName = QFileDialog::getOpenFileName(this, "Select Extension dll", "C:\\", "Extensions (*.dll)"); + QString extenFileName = QFileDialog::getOpenFileName(this, "Select Extension", "C:\\", "Extensions (*.dll)"); if (!extenFileName.size()) return; - QString extenName = extenFileName.split("/")[extenFileName.split("/").count() - 1]; - QString copyTo = QString::number(extenCombo->itemText(extenCombo->count() - 1).split(":")[0].toInt() + 1) + "_" + extenName; - QFile::copy(extenFileName, copyTo); + QString extenName = extenFileName.mid(extenFileName.lastIndexOf("/") + 1); + QFile::copy(extenFileName, extenName); + Extension::Load(extenName.left(extenName.lastIndexOf(".dll"))); ReloadExtensions(); } +void MainWindow::on_moveExtenButton_clicked() +{ + if (extenCombo->currentText() == "") return; + Extension::SendToBack(extenCombo->currentText()); + ReloadExtensions(); + Host::AddConsoleOutput(L"extension sent to back"); +} + void MainWindow::on_rmvExtenButton_clicked() { if (extenCombo->currentText() == "") return; - UnloadExtension(extenCombo->currentText().split(":")[0].toInt()); + Extension::Unload(extenCombo->currentText()); ReloadExtensions(); } diff --git a/GUI/mainwindow.h b/GUI/mainwindow.h index 5ca76cb..a57d672 100644 --- a/GUI/mainwindow.h +++ b/GUI/mainwindow.h @@ -2,11 +2,11 @@ #define MAINWINDOW_H #include "qtcommon.h" +#include "host/host.h" #include #include #include #include -#include "host/host.h" namespace Ui { @@ -41,6 +41,7 @@ private slots: void on_hookButton_clicked(); void on_saveButton_clicked(); void on_addExtenButton_clicked(); + void on_moveExtenButton_clicked(); void on_rmvExtenButton_clicked(); private: diff --git a/GUI/mainwindow.ui b/GUI/mainwindow.ui index c519296..b3d9271 100644 --- a/GUI/mainwindow.ui +++ b/GUI/mainwindow.ui @@ -216,6 +216,13 @@ QPushButton, QComboBox + + + + Move extension + + + diff --git a/deploy.ps1 b/deploy.ps1 index 952f2f0..63d3bbf 100644 --- a/deploy.ps1 +++ b/deploy.ps1 @@ -1,4 +1,31 @@ -cd Builds/RelWithDebInfo/x86; -Compress-Archive -Force -Path "Textractor.exe","styles","platforms","Qt5Core.dll","Qt5Gui.dll","Qt5Widgets.dll","vnrhook.dll","256_Remove Repetition.dll","512_Copy to Clipboard.dll","1024_Bing Translate.dll","2048_Extra Newlines.dll" -DestinationPath Textractor; +cd Builds/RelWithDebInfo/x86; +Compress-Archive -Force -DestinationPath Textractor -Path @( + "Textractor.exe", + "styles", + "platforms", + "Qt5Core.dll", + "Qt5Gui.dll", + "Qt5Widgets.dll", + "vnrhook.dll", + "Remove Repetition.dll", + "Copy to Clipboard.dll", + "Bing Translate.dll", + "Extra Newlines.dll", + "Extensions.txt" +) + cd ../x64; -Compress-Archive -Force -Path "Textractor.exe","styles","platforms","Qt5Core.dll","Qt5Gui.dll","Qt5Widgets.dll","vnrhook.dll","256_Remove Repetition.dll","512_Copy to Clipboard.dll","1024_Bing Translate.dll","2048_Extra Newlines.dll" -DestinationPath Textractor; +Compress-Archive -Force -DestinationPath Textractor -Path @( + "Textractor.exe", + "styles", + "platforms", + "Qt5Core.dll", + "Qt5Gui.dll", + "Qt5Widgets.dll", + "vnrhook.dll", + "Remove Repetition.dll", + "Copy to Clipboard.dll", + "Bing Translate.dll", + "Extra Newlines.dll", + "Extensions.txt" +) \ No newline at end of file diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index 694f97c..08e4295 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -4,9 +4,9 @@ find_qt5(Core Widgets) cmake_policy(SET CMP0037 OLD) -add_library(256_Remove\ Repetition SHARED removerepeat.cpp extensionimpl.cpp) -add_library(512_Copy\ to\ Clipboard SHARED copyclipboard.cpp extensionimpl.cpp) -add_library(1024_Bing\ Translate SHARED bingtranslate.cpp extensionimpl.cpp) -add_library(2048_Extra\ Newlines SHARED extranewlines.cpp extensionimpl.cpp) +add_library(Remove\ Repetition SHARED removerepeat.cpp extensionimpl.cpp) +add_library(Copy\ to\ Clipboard SHARED copyclipboard.cpp extensionimpl.cpp) +add_library(Bing\ Translate SHARED bingtranslate.cpp extensionimpl.cpp) +add_library(Extra\ Newlines SHARED extranewlines.cpp extensionimpl.cpp) -target_link_libraries(1024_Bing\ Translate winhttp.lib Qt5::Widgets) +target_link_libraries(Bing\ Translate winhttp.lib Qt5::Widgets)