From b80f7951438b1db2519b7a1c2f59e36a2b242f9b Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Thu, 22 Nov 2018 15:53:32 -0500 Subject: [PATCH] extract utility functions. specify deleted constructors. other misc fixes --- GUI/CMakeLists.txt | 1 + GUI/host/host.cc | 35 +++++++++-------------------------- GUI/host/host.h | 22 ---------------------- GUI/host/textthread.cc | 31 ++++++++++++------------------- GUI/host/textthread.h | 13 +++++-------- GUI/host/util.cpp | 37 +++++++++++++++++++++++++++++++++++++ GUI/host/util.h | 9 +++++++++ GUI/main.cpp | 2 +- include/types.h | 6 +++++- 9 files changed, 79 insertions(+), 77 deletions(-) create mode 100644 GUI/host/util.cpp create mode 100644 GUI/host/util.h diff --git a/GUI/CMakeLists.txt b/GUI/CMakeLists.txt index 26a8076..3c041d7 100644 --- a/GUI/CMakeLists.txt +++ b/GUI/CMakeLists.txt @@ -14,6 +14,7 @@ set(gui_SRCS tests.cpp host/host.cc host/textthread.cc + host/util.cpp ${RESOURCE_FILES} ) add_executable(${PROJECT_NAME} WIN32 ${gui_SRCS}) diff --git a/GUI/host/host.cc b/GUI/host/host.cc index 9e8668f..18bcc8c 100644 --- a/GUI/host/host.cc +++ b/GUI/host/host.cc @@ -1,10 +1,8 @@ -// host.cc -// 8/24/2013 jichi -// Branch IHF/main.cpp, rev 111 - #include "host.h" #include "const.h" +#include "text.h" #include "defs.h" +#include "util.h" #include "../vnrhook/texthook.h" namespace @@ -19,6 +17,9 @@ namespace sectionMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId)) {} + ProcessRecord(ProcessRecord&) = delete; + ProcessRecord& operator=(ProcessRecord) = delete; + ~ProcessRecord() { UnmapViewOfFile(sectionMap); @@ -103,7 +104,7 @@ namespace HANDLE hostPipe = CreateNamedPipeW(HOST_PIPE, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, 0, MAXDWORD, &pipeSA); ConnectNamedPipe(hookPipe, nullptr); - BYTE buffer[PIPE_BUFFER_SIZE + 1] = {}; + BYTE buffer[PIPE_BUFFER_SIZE] = {}; DWORD bytesRead, processId; ReadFile(hookPipe, &processId, sizeof(processId), &bytesRead, nullptr); RegisterProcess(processId, hostPipe); @@ -122,7 +123,7 @@ namespace case HOST_NOTIFICATION_TEXT: { auto info = *(ConsoleOutputNotif*)buffer; - Host::AddConsoleOutput(StringToWideString(info.message)); + Host::AddConsoleOutput(Util::StringToWideString(info.message)); } break; default: @@ -141,28 +142,12 @@ namespace }).detach(); } - std::optional GetClipboardText() - { - if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) return {}; - if (!OpenClipboard(NULL)) return {}; - - if (HANDLE clipboardHandle = GetClipboardData(CF_UNICODETEXT)) - { - std::wstring ret = (wchar_t*)GlobalLock(clipboardHandle); - GlobalUnlock(clipboardHandle); - CloseClipboard(); - return ret; - } - CloseClipboard(); - return {}; - } - void StartCapturingClipboard() { std::thread([] { for (std::wstring last; true; Sleep(50)) - if (auto text = GetClipboardText()) + if (auto text = Util::GetClipboardText()) if (last != text.value()) Host::GetThread(CLIPBOARD)->AddSentence(last = text.value()); }).detach(); @@ -269,7 +254,7 @@ namespace Host std::wstring GetHookName(DWORD processId, uint64_t addr) { LOCK(hostMutex); - return StringToWideString(processRecordsByIds.at(processId)->GetHook(addr).hookName); + return Util::StringToWideString(processRecordsByIds.at(processId)->GetHook(addr).hookName); } std::shared_ptr GetThread(ThreadParam tp) @@ -283,5 +268,3 @@ namespace Host GetThread(CONSOLE)->AddSentence(text); } } - -// EOF diff --git a/GUI/host/host.h b/GUI/host/host.h index f817b3e..f14604e 100644 --- a/GUI/host/host.h +++ b/GUI/host/host.h @@ -1,12 +1,7 @@ #pragma once -// host.h -// 8/23/2013 jichi -// Branch: ITH/IHF.h, rev 105 - #include "common.h" #include "textthread.h" -#include "text.h" typedef std::function ProcessEventCallback; typedef std::function)> ThreadEventCallback; @@ -30,20 +25,3 @@ namespace Host std::shared_ptr GetThread(ThreadParam tp); void AddConsoleOutput(std::wstring text); } - -inline std::wstring StringToWideString(const std::string& text, UINT encoding = CP_UTF8) -{ - std::wstring ret(text.size() + 1, 0); - if (int len = MultiByteToWideChar(encoding, 0, text.c_str(), -1, ret.data(), ret.size())) - { - ret.resize(len - 1); - return ret; - } - else - { - Host::AddConsoleOutput(INVALID_CODEPAGE); - return L""; - } -} - -// EOF diff --git a/GUI/host/textthread.cc b/GUI/host/textthread.cc index 36b9670..f7f9d75 100644 --- a/GUI/host/textthread.cc +++ b/GUI/host/textthread.cc @@ -1,10 +1,7 @@ -// textthread.cc -// 8/24/2013 jichi -// Branch IHF/TextThread.cpp, rev 133 - #include "textthread.h" -#include "host.h" #include "const.h" +#include "host.h" +#include "util.h" TextThread::TextThread(ThreadParam tp, HookParam hp, std::wstring name) : handle(threadCounter++), name(name), tp(tp), hp(hp) {} @@ -17,16 +14,15 @@ TextThread::~TextThread() std::wstring TextThread::GetStorage() { - LOCK(threadMutex); + LOCK(storageMutex); return storage; } void TextThread::AddSentence(std::wstring sentence) { - // Dispatch to extensions occurs here. Don't hold mutex! Extensions might take a while! if (Output(this, sentence)) { - LOCK(threadMutex); + LOCK(storageMutex); storage += sentence; } } @@ -34,10 +30,10 @@ void TextThread::AddSentence(std::wstring sentence) void TextThread::Push(const BYTE* data, int len) { if (len < 0) return; - LOCK(threadMutex); + LOCK(bufferMutex); buffer += hp.type & USING_UNICODE ? std::wstring((wchar_t*)data, len / 2) - : StringToWideString(std::string((char*)data, len), hp.codepage != 0 ? hp.codepage : defaultCodepage); + : Util::StringToWideString(std::string((char*)data, len), hp.codepage ? hp.codepage : defaultCodepage); if (std::all_of(buffer.begin(), buffer.end(), [&](wchar_t c) { return repeatingChars.count(c) > 0; })) buffer.clear(); lastPushTime = GetTickCount(); } @@ -53,19 +49,16 @@ bool TextThread::FilterRepetition(std::wstring& sentence) void TextThread::Flush() { - std::unique_lock locker(threadMutex); - if (buffer.empty()) return; - if (buffer.size() > maxBufferSize || GetTickCount() - lastPushTime > flushDelay) + std::wstring sentence; { - std::wstring sentence = buffer; + LOCK(bufferMutex); + if (buffer.empty()) return; + if (buffer.size() < maxBufferSize && GetTickCount() - lastPushTime < flushDelay) return; + sentence = buffer; buffer.clear(); if (FilterRepetition(sentence)) repeatingChars = std::unordered_set(sentence.begin(), sentence.end()); else repeatingChars.clear(); - - locker.unlock(); - AddSentence(sentence); } + AddSentence(sentence); } - -// EOF diff --git a/GUI/host/textthread.h b/GUI/host/textthread.h index 1d3ea1f..f6af2f4 100644 --- a/GUI/host/textthread.h +++ b/GUI/host/textthread.h @@ -1,9 +1,5 @@ #pragma once -// textthread.h -// 8/23/2013 jichi -// Branch: ITH/TextThread.h, rev 120 - #include "common.h" #include "types.h" @@ -20,6 +16,8 @@ public: inline static int threadCounter = 0; TextThread(ThreadParam tp, HookParam hp, std::wstring name); + TextThread(TextThread&) = delete; + TextThread& operator=(TextThread) = delete; ~TextThread(); std::wstring GetStorage(); @@ -37,13 +35,12 @@ private: void Flush(); std::wstring buffer; - std::wstring storage; std::unordered_set repeatingChars; - std::recursive_mutex threadMutex; + std::mutex bufferMutex; + std::wstring storage; + std::recursive_mutex storageMutex; HANDLE deletionEvent = CreateEventW(nullptr, FALSE, FALSE, NULL); std::thread flushThread = std::thread([&] { while (WaitForSingleObject(deletionEvent, 10) == WAIT_TIMEOUT) Flush(); }); DWORD lastPushTime = GetTickCount(); }; - -// EOF diff --git a/GUI/host/util.cpp b/GUI/host/util.cpp new file mode 100644 index 0000000..23ecda6 --- /dev/null +++ b/GUI/host/util.cpp @@ -0,0 +1,37 @@ +#include "util.h" +#include "text.h" +#include "host.h" + +namespace Util +{ + std::optional GetClipboardText() + { + if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) return {}; + if (!OpenClipboard(NULL)) return {}; + + if (HANDLE clipboardHandle = GetClipboardData(CF_UNICODETEXT)) + { + std::wstring ret = (wchar_t*)GlobalLock(clipboardHandle); + GlobalUnlock(clipboardHandle); + CloseClipboard(); + return ret; + } + CloseClipboard(); + return {}; + } + + std::wstring StringToWideString(std::string text, UINT encoding) + { + std::wstring ret(text.size() + 1, 0); + if (int len = MultiByteToWideChar(encoding, 0, text.c_str(), -1, ret.data(), ret.size())) + { + ret.resize(len - 1); + return ret; + } + else + { + Host::AddConsoleOutput(INVALID_CODEPAGE); + return L""; + } + } +} \ No newline at end of file diff --git a/GUI/host/util.h b/GUI/host/util.h new file mode 100644 index 0000000..43bb841 --- /dev/null +++ b/GUI/host/util.h @@ -0,0 +1,9 @@ +#pragma once + +#include "common.h" + +namespace Util +{ + std::optional GetClipboardText(); + std::wstring StringToWideString(std::string text, UINT encoding = CP_UTF8); +} diff --git a/GUI/main.cpp b/GUI/main.cpp index 0fb8813..6965cae 100644 --- a/GUI/main.cpp +++ b/GUI/main.cpp @@ -26,7 +26,7 @@ namespace L"Error in module: " << moduleName << std::endl; if (exception->ExceptionRecord->ExceptionCode == 0xE06D7363) - errorMsg << "Additional info: " << GetCppExceptionInfo(exception) << std::endl; + errorMsg << L"Additional info: " << GetCppExceptionInfo(exception) << std::endl; for (int i = 0; i < exception->ExceptionRecord->NumberParameters; ++i) errorMsg << L"Additional info: " << exception->ExceptionRecord->ExceptionInformation[i] << std::endl; diff --git a/include/types.h b/include/types.h index c9a7c7b..5e7a9e7 100644 --- a/include/types.h +++ b/include/types.h @@ -42,12 +42,16 @@ static bool operator==(const ThreadParam& one, const ThreadParam& two) { return class WinMutex { - HANDLE mutex; public: WinMutex(std::wstring name) : mutex(CreateMutexW(nullptr, false, name.c_str())) {} + WinMutex(WinMutex&) = delete; + WinMutex& operator=(WinMutex) = delete; ~WinMutex() { ReleaseMutex(mutex); CloseHandle(mutex); } void lock() { WaitForSingleObject(mutex, 0); } void unlock() { ReleaseMutex(mutex); } + +private: + HANDLE mutex; }; struct InsertHookCmd // From host