diff --git a/GUI/host/host.cpp b/GUI/host/host.cpp index b23e58e..5579b55 100644 --- a/GUI/host/host.cpp +++ b/GUI/host/host.cpp @@ -4,50 +4,9 @@ #include "defs.h" #include "util.h" #include "../vnrhook/texthook.h" -#include namespace { - char* GetCppExceptionInfo(EXCEPTION_POINTERS* exception) - { - // See https://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273 - // Not very reliable so use __try - __try { return ((char****)exception->ExceptionRecord->ExceptionInformation[2])[3][1][1] + 8; } - __except (EXCEPTION_EXECUTE_HANDLER) { return "Could not find"; } - } - - std::wstring lastError = L"Unknown error"; - - LONG WINAPI ExceptionLogger(EXCEPTION_POINTERS* exception) - { - MEMORY_BASIC_INFORMATION info = {}; - VirtualQuery(exception->ExceptionRecord->ExceptionAddress, &info, sizeof(info)); - wchar_t moduleName[MAX_PATH] = {}; - GetModuleFileNameW((HMODULE)info.AllocationBase, moduleName, MAX_PATH); - - std::wstringstream errorMsg; - errorMsg << std::uppercase << std::hex << - L"Error code: " << exception->ExceptionRecord->ExceptionCode << std::endl << - L"Error address: " << (uint64_t)exception->ExceptionRecord->ExceptionAddress << std::endl << - L"Error in module: " << moduleName << std::endl; - - if (exception->ExceptionRecord->ExceptionCode == 0xE06D7363) - 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; - - lastError = errorMsg.str(); - - return EXCEPTION_CONTINUE_SEARCH; - } - - void Terminate() - { - MessageBoxW(NULL, lastError.c_str(), L"Textractor ERROR", MB_ICONERROR); - std::abort(); - } - class ProcessRecord { public: @@ -137,7 +96,6 @@ namespace { std::thread([] { - Host::Setup(); SECURITY_DESCRIPTOR pipeSD = {}; InitializeSecurityDescriptor(&pipeSD, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&pipeSD, TRUE, NULL, FALSE); // Allow non-admin processes to connect to pipe created by admin host @@ -188,7 +146,6 @@ namespace { std::thread([] { - Host::Setup(); for (std::wstring last; true; Sleep(50)) if (auto text = Util::GetClipboardText()) if (last != text.value()) @@ -199,17 +156,6 @@ namespace namespace Host { - void Setup() - { - static std::once_flag flag; - std::call_once(flag, [] - { - AddVectoredExceptionHandler(FALSE, ExceptionLogger); - SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)Terminate); - }); - std::set_terminate(Terminate); - } - void Start(ProcessEventCallback onAttach, ProcessEventCallback onDetach, ThreadEventCallback onCreate, ThreadEventCallback onDestroy, TextThread::OutputCallback output) { OnAttach = onAttach; OnDetach = onDetach; OnCreate = onCreate; OnDestroy = onDestroy; TextThread::Output = output; diff --git a/GUI/host/host.h b/GUI/host/host.h index 3bafe4b..f14604e 100644 --- a/GUI/host/host.h +++ b/GUI/host/host.h @@ -8,7 +8,6 @@ typedef std::function)> ThreadEventCallback; namespace Host { - void Setup(); void Start(ProcessEventCallback onAttach, ProcessEventCallback onDetach, ThreadEventCallback onCreate, ThreadEventCallback onDestroy, TextThread::OutputCallback output); void Close(); diff --git a/GUI/host/textthread.cpp b/GUI/host/textthread.cpp index ec6e7cd..3ec8d97 100644 --- a/GUI/host/textthread.cpp +++ b/GUI/host/textthread.cpp @@ -4,14 +4,7 @@ #include "host.h" #include "util.h" -TextThread::TextThread(ThreadParam tp, HookParam hp, std::wstring name) : - handle(threadCounter++), - name(name), - tp(tp), - hp(hp), - deletionEvent(CreateEventW(nullptr, FALSE, FALSE, NULL)), - flushThread([&] { Host::Setup(); while (WaitForSingleObject(deletionEvent, 10) == WAIT_TIMEOUT) Flush(); }) -{} +TextThread::TextThread(ThreadParam tp, HookParam hp, std::wstring name) : handle(threadCounter++), name(name), tp(tp), hp(hp) {} TextThread::~TextThread() { diff --git a/GUI/host/textthread.h b/GUI/host/textthread.h index ecc8625..d793e89 100644 --- a/GUI/host/textthread.h +++ b/GUI/host/textthread.h @@ -37,7 +37,8 @@ private: std::mutex bufferMutex; std::wstring storage; std::mutex storageMutex; - HANDLE deletionEvent; - std::thread flushThread; - DWORD lastPushTime; + + HANDLE deletionEvent = CreateEventW(nullptr, FALSE, FALSE, NULL); + std::thread flushThread = std::thread([&] { while (WaitForSingleObject(deletionEvent, 10) == WAIT_TIMEOUT) Flush(); }); + DWORD lastPushTime = GetTickCount(); }; diff --git a/GUI/main.cpp b/GUI/main.cpp index c79e034..6965cae 100644 --- a/GUI/main.cpp +++ b/GUI/main.cpp @@ -1,14 +1,45 @@ #include "mainwindow.h" -#include "host/host.h" -#include "misc.h" #include #include +namespace +{ + char* GetCppExceptionInfo(EXCEPTION_POINTERS* exception) + { + // See https://blogs.msdn.microsoft.com/oldnewthing/20100730-00/?p=13273 + // Not very reliable so use __try + __try { return ((char****)exception->ExceptionRecord->ExceptionInformation[2])[3][1][1] + 8; } + __except (EXCEPTION_EXECUTE_HANDLER) { return "Could not find"; } + } + + LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS* exception) + { + MEMORY_BASIC_INFORMATION info = {}; + VirtualQuery(exception->ExceptionRecord->ExceptionAddress, &info, sizeof(info)); + wchar_t moduleName[MAX_PATH] = {}; + GetModuleFileNameW((HMODULE)info.AllocationBase, moduleName, MAX_PATH); + + std::wstringstream errorMsg; + errorMsg << std::uppercase << std::hex << + L"Error code: " << exception->ExceptionRecord->ExceptionCode << std::endl << + L"Error address: " << (uint64_t)exception->ExceptionRecord->ExceptionAddress << std::endl << + L"Error in module: " << moduleName << std::endl; + + if (exception->ExceptionRecord->ExceptionCode == 0xE06D7363) + 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; + + MessageBoxW(NULL, errorMsg.str().c_str(), L"Textractor ERROR", MB_ICONERROR); + + return EXCEPTION_CONTINUE_SEARCH; + } +} + int main(int argc, char *argv[]) { - Host::Setup(); - QString exe = GetFullModuleName(GetCurrentProcessId()); - SetCurrentDirectoryW(exe.left(exe.lastIndexOf("\\")).toStdWString().c_str()); + SetUnhandledExceptionFilter(ExceptionHandler); QApplication a(argc, argv); MainWindow w; w.show();