From effb005376162f3e3bf809a7d1617289bb0484aa Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Wed, 10 Oct 2018 07:03:15 -0400 Subject: [PATCH] add extension class and refactor extensions using it --- GUI/extensions.cpp | 56 ++++++++++++++++++++++++++-------------------- GUI/extensions.h | 24 +++++++++++++------- GUI/mainwindow.cpp | 3 +-- GUI/misc.h | 1 - GUI/qtcommon.h | 3 ++- include/common.h | 1 + 6 files changed, 52 insertions(+), 36 deletions(-) diff --git a/GUI/extensions.cpp b/GUI/extensions.cpp index 883f454..cc836d5 100644 --- a/GUI/extensions.cpp +++ b/GUI/extensions.cpp @@ -2,28 +2,34 @@ #include #include -std::shared_mutex extenMutex; -std::map extensions; - -std::map LoadExtensions() +std::optional LoadExtension(QString file) { - std::map newExtensions; - std::map extensionNames; + // 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()); + if (!module) return {}; + + auto callback = (wchar_t*(*)(const wchar_t*, const InfoForExtension*))GetProcAddress(module, "OnNewSentence"); + if (!callback) return {}; + + return Extension{ parsedFile.captured(1).toInt(), parsedFile.captured(2), callback }; +} + +std::shared_mutex extenMutex; +std::set extensions; + +std::set LoadExtensions() +{ + std::set newExtensions; QStringList files = QDir().entryList(); for (auto file : files) - if (file.split("_").size() > 1 && file.split("_")[0].toInt() && file.endsWith(".dll")) - if (GetProcAddress(GetModuleHandleW(file.toStdWString().c_str()), "OnNewSentence") || - GetProcAddress(LoadLibraryW(file.toStdWString().c_str()), "OnNewSentence")) - { - int extensionNumber = file.split("_")[0].toInt(); - newExtensions[extensionNumber] = (ExtensionFunction)GetProcAddress(GetModuleHandleW(file.toStdWString().c_str()), "OnNewSentence"); - file.chop(sizeof("dll")); - file.remove(0, file.indexOf("_") + 1); - extensionNames[extensionNumber] = file; - } + if (auto extension = LoadExtension(file)) newExtensions.insert(extension.value()); + std::unique_lock extenLock(extenMutex); - extensions = newExtensions; - return extensionNames; + return extensions = newExtensions; } bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map miscInfo) @@ -31,19 +37,21 @@ bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_mapnextProperty = new InfoForExtension{ i.first.c_str(), i.second, nullptr }; + + InfoForExtension miscInfoLinkedList{ "", 0, nullptr }; + InfoForExtension* miscInfoTraverser = &miscInfoLinkedList; + for (auto& i : miscInfo) miscInfoTraverser = miscInfoTraverser->next = new InfoForExtension{ i.first.c_str(), i.second, nullptr }; + std::shared_lock extenLock(extenMutex); - for (auto i : extensions) + for (auto extension : extensions) { - wchar_t* nextBuffer = i.second(sentenceBuffer, miscInfoLinkedList); + wchar_t* nextBuffer = extension.callback(sentenceBuffer, &miscInfoLinkedList); if (nextBuffer == nullptr) { success = false; break; } if (nextBuffer != sentenceBuffer) HeapFree(GetProcessHeap(), 0, sentenceBuffer); sentenceBuffer = nextBuffer; } sentence = std::wstring(sentenceBuffer); + HeapFree(GetProcessHeap(), 0, sentenceBuffer); - delete miscInfoLinkedList; return success; } diff --git a/GUI/extensions.h b/GUI/extensions.h index c7fbc81..de2d642 100644 --- a/GUI/extensions.h +++ b/GUI/extensions.h @@ -2,17 +2,25 @@ #define EXTENSIONS_H #include "qtcommon.h" -#include +#include -std::map LoadExtensions(); -bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map miscInfo); struct InfoForExtension { - ~InfoForExtension() { if (nextProperty) delete nextProperty; }; - const char* propertyName = ""; - int64_t propertyValue = 0; - InfoForExtension* nextProperty = nullptr; + const char* name; + int64_t value; + InfoForExtension* next; + ~InfoForExtension() { if (next) delete next; }; }; -typedef wchar_t*(*ExtensionFunction)(const wchar_t*, const InfoForExtension*); + +struct Extension +{ + int number; + QString name; + wchar_t*(*callback)(const wchar_t*, const InfoForExtension*); + bool operator<(const Extension& other) const { return number < other.number; } +}; + +std::set LoadExtensions(); +bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map miscInfo); #endif // EXTENSIONS_H diff --git a/GUI/mainwindow.cpp b/GUI/mainwindow.cpp index 7a1311e..e3275c7 100644 --- a/GUI/mainwindow.cpp +++ b/GUI/mainwindow.cpp @@ -141,8 +141,7 @@ DWORD MainWindow::GetSelectedProcessId() void MainWindow::ReloadExtensions() { extenCombo->clear(); - std::map extensions = LoadExtensions(); - for (auto i : extensions) extenCombo->addItem(QString::number(i.first) + ": " + i.second); + for (auto extension : LoadExtensions()) extenCombo->addItem(QString::number(extension.number) + ": " + extension.name); } std::unordered_map MainWindow::GetInfoForExtensions(TextThread* thread) diff --git a/GUI/misc.h b/GUI/misc.h index 572f851..685e278 100644 --- a/GUI/misc.h +++ b/GUI/misc.h @@ -4,7 +4,6 @@ #include "qtcommon.h" #include "types.h" #include -#include QString GetFullModuleName(DWORD processId, HMODULE module = NULL); QString GetModuleName(DWORD processId, HMODULE module = NULL); diff --git a/GUI/qtcommon.h b/GUI/qtcommon.h index 52be976..c162e16 100644 --- a/GUI/qtcommon.h +++ b/GUI/qtcommon.h @@ -3,4 +3,5 @@ #include "common.h" #include #include -#include \ No newline at end of file +#include +#include diff --git a/include/common.h b/include/common.h index 4db1fa3..2872a93 100644 --- a/include/common.h +++ b/include/common.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include