From 1c391e3a4ba182148bc23721445def55dd02ed9d Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Sat, 22 Dec 2018 13:05:01 -0500 Subject: [PATCH] small refactor. rename and extract exception handling --- GUI/CMakeLists.txt | 1 + GUI/exception.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++ GUI/host/host.cpp | 2 +- GUI/host/util.cpp | 4 ++-- GUI/host/util.h | 4 ++-- GUI/main.cpp | 49 +------------------------------------------- GUI/mainwindow.cpp | 7 +++---- 7 files changed, 61 insertions(+), 57 deletions(-) create mode 100644 GUI/exception.cpp diff --git a/GUI/CMakeLists.txt b/GUI/CMakeLists.txt index fb5d05b..2d6ed53 100644 --- a/GUI/CMakeLists.txt +++ b/GUI/CMakeLists.txt @@ -9,6 +9,7 @@ set(gui_SRCS main.cpp mainwindow.cpp misc.cpp + exception.cpp extenwindow.cpp tests.cpp host/host.cpp diff --git a/GUI/exception.cpp b/GUI/exception.cpp new file mode 100644 index 0000000..48d07a4 --- /dev/null +++ b/GUI/exception.cpp @@ -0,0 +1,51 @@ +#include "host/util.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"; } + } + + thread_local std::wstring lastError = L"Unknown error"; + + __declspec(noreturn) void Terminate() + { + MessageBoxW(NULL, lastError.c_str(), L"Textractor ERROR", MB_ICONERROR); + std::abort(); + } + + LONG WINAPI ExceptionLogger(EXCEPTION_POINTERS* exception) + { + thread_local static auto _ = std::invoke(std::set_terminate, Terminate); + + MEMORY_BASIC_INFORMATION info = {}; + VirtualQuery(exception->ExceptionRecord->ExceptionAddress, &info, sizeof(info)); + + std::wstringstream errorMsg; + errorMsg << std::uppercase << std::hex << + L"Error code: " << exception->ExceptionRecord->ExceptionCode << std::endl << + L"Error address: " << exception->ExceptionRecord->ExceptionAddress << std::endl << + L"Error in module: " << Util::GetModuleFilename((HMODULE)info.AllocationBase).value_or(L"Could not find") << std::endl << + L"Additional info: " << info.AllocationBase << 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; + } + + auto _ = std::invoke([] + { + AddVectoredExceptionHandler(FALSE, ExceptionLogger); + return SetUnhandledExceptionFilter([](auto) -> LONG { Terminate(); }); + }); +} \ No newline at end of file diff --git a/GUI/host/host.cpp b/GUI/host/host.cpp index 856ccad..40098fb 100644 --- a/GUI/host/host.cpp +++ b/GUI/host/host.cpp @@ -155,7 +155,7 @@ namespace Host } static HMODULE vnrhook = LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES); - static std::wstring location = Util::GetModuleFileName(vnrhook).value(); + static std::wstring location = Util::GetModuleFilename(vnrhook).value(); if (AutoHandle<> process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId)) { diff --git a/GUI/host/util.cpp b/GUI/host/util.cpp index a16a9af..cb7aec6 100644 --- a/GUI/host/util.cpp +++ b/GUI/host/util.cpp @@ -4,7 +4,7 @@ namespace Util { - std::optional GetModuleFileName(DWORD processId, HMODULE module) + std::optional GetModuleFilename(DWORD processId, HMODULE module) { if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId)) { @@ -15,7 +15,7 @@ namespace Util return {}; } - std::optional GetModuleFileName(HMODULE module) + std::optional GetModuleFilename(HMODULE module) { std::vector buffer(MAX_PATH); if (::GetModuleFileNameW(module, buffer.data(), MAX_PATH)) return buffer.data(); diff --git a/GUI/host/util.h b/GUI/host/util.h index 70a4e60..1fd9a68 100644 --- a/GUI/host/util.h +++ b/GUI/host/util.h @@ -4,8 +4,8 @@ namespace Util { - std::optional GetModuleFileName(DWORD processId, HMODULE module = NULL); - std::optional GetModuleFileName(HMODULE module = NULL); + std::optional GetModuleFilename(DWORD processId, HMODULE module = NULL); + std::optional GetModuleFilename(HMODULE module = NULL); std::optional GetClipboardText(); std::optional StringToWideString(std::string text, UINT encoding = CP_UTF8); // return true if repetition found (see https://github.com/Artikash/Textractor/issues/40) diff --git a/GUI/main.cpp b/GUI/main.cpp index 7148b7e..cd9b31a 100644 --- a/GUI/main.cpp +++ b/GUI/main.cpp @@ -1,59 +1,12 @@ #include "mainwindow.h" #include "misc.h" #include "host/util.h" -#include #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"; } - } - - thread_local std::wstring lastError = L"Unknown error"; - - __declspec(noreturn) void Terminate() - { - MessageBoxW(NULL, lastError.c_str(), L"Textractor ERROR", MB_ICONERROR); - std::abort(); - } - - LONG WINAPI ExceptionLogger(EXCEPTION_POINTERS* exception) - { - thread_local static auto terminateSetter = std::invoke(std::set_terminate, Terminate); - - MEMORY_BASIC_INFORMATION info = {}; - VirtualQuery(exception->ExceptionRecord->ExceptionAddress, &info, sizeof(info)); - - std::wstringstream errorMsg; - errorMsg << std::uppercase << std::hex << - L"Error code: " << exception->ExceptionRecord->ExceptionCode << std::endl << - L"Error address: " << exception->ExceptionRecord->ExceptionAddress << std::endl << - L"Error in module: " << Util::GetModuleFileName((HMODULE)info.AllocationBase).value_or(L"Could not find") << std::endl << - L"Additional info: " << info.AllocationBase << 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; - } -} - int main(int argc, char *argv[]) { - AddVectoredExceptionHandler(FALSE, ExceptionLogger); - SetUnhandledExceptionFilter([](auto) -> LONG { Terminate(); }); - - QDir::setCurrent(QFileInfo(S(Util::GetModuleFileName().value())).absolutePath()); + QDir::setCurrent(QFileInfo(S(Util::GetModuleFilename().value())).absolutePath()); QApplication a(argc, argv); MainWindow w; diff --git a/GUI/mainwindow.cpp b/GUI/mainwindow.cpp index 7de0950..3ddbfb2 100644 --- a/GUI/mainwindow.cpp +++ b/GUI/mainwindow.cpp @@ -75,7 +75,6 @@ MainWindow::~MainWindow() QSettings settings(CONFIG_FILE, QSettings::IniFormat); settings.setValue(WINDOW, geometry()); settings.sync(); - delete ui; ExitProcess(0); } @@ -89,7 +88,7 @@ void MainWindow::ProcessConnected(DWORD processId) if (processId == 0) return; QMetaObject::invokeMethod(this, [this, processId] { - QString process = S(Util::GetModuleFileName(processId).value()); + QString process = S(Util::GetModuleFilename(processId).value()); ui->processCombo->addItem(QString::number(processId, 16).toUpper() + ": " + QFileInfo(process).fileName()); QStringList allProcesses = QString(QAutoFile(HOOK_SAVE_FILE, QIODevice::ReadOnly)->readAll()).split("\r", QString::SkipEmptyParts); @@ -189,7 +188,7 @@ void MainWindow::AttachProcess() DWORD allProcessIds[5000] = {}, spaceUsed = 0; EnumProcesses(allProcessIds, sizeof(allProcessIds), &spaceUsed); for (int i = 0; i < spaceUsed / sizeof(DWORD); ++i) - if (auto processName = Util::GetModuleFileName(allProcessIds[i])) allProcesses.insert(QFileInfo(S(processName.value())).fileName(), allProcessIds[i]); + if (auto processName = Util::GetModuleFilename(allProcessIds[i])) allProcesses.insert(QFileInfo(S(processName.value())).fileName(), allProcessIds[i]); QStringList processList(allProcesses.uniqueKeys()); processList.sort(Qt::CaseInsensitive); @@ -216,7 +215,7 @@ void MainWindow::AddHook() void MainWindow::SaveHooks() { - if (auto processName = Util::GetModuleFileName(GetSelectedProcessId())) + if (auto processName = Util::GetModuleFilename(GetSelectedProcessId())) { QHash hookCodes; for (int i = 0; i < ui->ttCombo->count(); ++i)