extract utility functions. specify deleted constructors. other misc fixes

This commit is contained in:
Akash Mozumdar 2018-11-22 15:53:32 -05:00
parent 902ded684d
commit b80f795143
9 changed files with 79 additions and 77 deletions

View File

@ -14,6 +14,7 @@ set(gui_SRCS
tests.cpp tests.cpp
host/host.cc host/host.cc
host/textthread.cc host/textthread.cc
host/util.cpp
${RESOURCE_FILES} ${RESOURCE_FILES}
) )
add_executable(${PROJECT_NAME} WIN32 ${gui_SRCS}) add_executable(${PROJECT_NAME} WIN32 ${gui_SRCS})

View File

@ -1,10 +1,8 @@
// host.cc
// 8/24/2013 jichi
// Branch IHF/main.cpp, rev 111
#include "host.h" #include "host.h"
#include "const.h" #include "const.h"
#include "text.h"
#include "defs.h" #include "defs.h"
#include "util.h"
#include "../vnrhook/texthook.h" #include "../vnrhook/texthook.h"
namespace namespace
@ -19,6 +17,9 @@ namespace
sectionMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId)) sectionMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId))
{} {}
ProcessRecord(ProcessRecord&) = delete;
ProcessRecord& operator=(ProcessRecord) = delete;
~ProcessRecord() ~ProcessRecord()
{ {
UnmapViewOfFile(sectionMap); 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); 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); ConnectNamedPipe(hookPipe, nullptr);
BYTE buffer[PIPE_BUFFER_SIZE + 1] = {}; BYTE buffer[PIPE_BUFFER_SIZE] = {};
DWORD bytesRead, processId; DWORD bytesRead, processId;
ReadFile(hookPipe, &processId, sizeof(processId), &bytesRead, nullptr); ReadFile(hookPipe, &processId, sizeof(processId), &bytesRead, nullptr);
RegisterProcess(processId, hostPipe); RegisterProcess(processId, hostPipe);
@ -122,7 +123,7 @@ namespace
case HOST_NOTIFICATION_TEXT: case HOST_NOTIFICATION_TEXT:
{ {
auto info = *(ConsoleOutputNotif*)buffer; auto info = *(ConsoleOutputNotif*)buffer;
Host::AddConsoleOutput(StringToWideString(info.message)); Host::AddConsoleOutput(Util::StringToWideString(info.message));
} }
break; break;
default: default:
@ -141,28 +142,12 @@ namespace
}).detach(); }).detach();
} }
std::optional<std::wstring> 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() void StartCapturingClipboard()
{ {
std::thread([] std::thread([]
{ {
for (std::wstring last; true; Sleep(50)) for (std::wstring last; true; Sleep(50))
if (auto text = GetClipboardText()) if (auto text = Util::GetClipboardText())
if (last != text.value()) if (last != text.value())
Host::GetThread(CLIPBOARD)->AddSentence(last = text.value()); Host::GetThread(CLIPBOARD)->AddSentence(last = text.value());
}).detach(); }).detach();
@ -269,7 +254,7 @@ namespace Host
std::wstring GetHookName(DWORD processId, uint64_t addr) std::wstring GetHookName(DWORD processId, uint64_t addr)
{ {
LOCK(hostMutex); LOCK(hostMutex);
return StringToWideString(processRecordsByIds.at(processId)->GetHook(addr).hookName); return Util::StringToWideString(processRecordsByIds.at(processId)->GetHook(addr).hookName);
} }
std::shared_ptr<TextThread> GetThread(ThreadParam tp) std::shared_ptr<TextThread> GetThread(ThreadParam tp)
@ -283,5 +268,3 @@ namespace Host
GetThread(CONSOLE)->AddSentence(text); GetThread(CONSOLE)->AddSentence(text);
} }
} }
// EOF

View File

@ -1,12 +1,7 @@
#pragma once #pragma once
// host.h
// 8/23/2013 jichi
// Branch: ITH/IHF.h, rev 105
#include "common.h" #include "common.h"
#include "textthread.h" #include "textthread.h"
#include "text.h"
typedef std::function<void(DWORD)> ProcessEventCallback; typedef std::function<void(DWORD)> ProcessEventCallback;
typedef std::function<void(std::shared_ptr<TextThread>)> ThreadEventCallback; typedef std::function<void(std::shared_ptr<TextThread>)> ThreadEventCallback;
@ -30,20 +25,3 @@ namespace Host
std::shared_ptr<TextThread> GetThread(ThreadParam tp); std::shared_ptr<TextThread> GetThread(ThreadParam tp);
void AddConsoleOutput(std::wstring text); 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

View File

@ -1,10 +1,7 @@
// textthread.cc
// 8/24/2013 jichi
// Branch IHF/TextThread.cpp, rev 133
#include "textthread.h" #include "textthread.h"
#include "host.h"
#include "const.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) {} 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() std::wstring TextThread::GetStorage()
{ {
LOCK(threadMutex); LOCK(storageMutex);
return storage; return storage;
} }
void TextThread::AddSentence(std::wstring sentence) void TextThread::AddSentence(std::wstring sentence)
{ {
// Dispatch to extensions occurs here. Don't hold mutex! Extensions might take a while!
if (Output(this, sentence)) if (Output(this, sentence))
{ {
LOCK(threadMutex); LOCK(storageMutex);
storage += sentence; storage += sentence;
} }
} }
@ -34,10 +30,10 @@ void TextThread::AddSentence(std::wstring sentence)
void TextThread::Push(const BYTE* data, int len) void TextThread::Push(const BYTE* data, int len)
{ {
if (len < 0) return; if (len < 0) return;
LOCK(threadMutex); LOCK(bufferMutex);
buffer += hp.type & USING_UNICODE buffer += hp.type & USING_UNICODE
? std::wstring((wchar_t*)data, len / 2) ? 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(); if (std::all_of(buffer.begin(), buffer.end(), [&](wchar_t c) { return repeatingChars.count(c) > 0; })) buffer.clear();
lastPushTime = GetTickCount(); lastPushTime = GetTickCount();
} }
@ -53,19 +49,16 @@ bool TextThread::FilterRepetition(std::wstring& sentence)
void TextThread::Flush() void TextThread::Flush()
{ {
std::unique_lock locker(threadMutex); std::wstring sentence;
if (buffer.empty()) return;
if (buffer.size() > maxBufferSize || GetTickCount() - lastPushTime > flushDelay)
{ {
std::wstring sentence = buffer; LOCK(bufferMutex);
if (buffer.empty()) return;
if (buffer.size() < maxBufferSize && GetTickCount() - lastPushTime < flushDelay) return;
sentence = buffer;
buffer.clear(); buffer.clear();
if (FilterRepetition(sentence)) repeatingChars = std::unordered_set(sentence.begin(), sentence.end()); if (FilterRepetition(sentence)) repeatingChars = std::unordered_set(sentence.begin(), sentence.end());
else repeatingChars.clear(); else repeatingChars.clear();
locker.unlock();
AddSentence(sentence);
} }
AddSentence(sentence);
} }
// EOF

View File

@ -1,9 +1,5 @@
#pragma once #pragma once
// textthread.h
// 8/23/2013 jichi
// Branch: ITH/TextThread.h, rev 120
#include "common.h" #include "common.h"
#include "types.h" #include "types.h"
@ -20,6 +16,8 @@ public:
inline static int threadCounter = 0; inline static int threadCounter = 0;
TextThread(ThreadParam tp, HookParam hp, std::wstring name); TextThread(ThreadParam tp, HookParam hp, std::wstring name);
TextThread(TextThread&) = delete;
TextThread& operator=(TextThread) = delete;
~TextThread(); ~TextThread();
std::wstring GetStorage(); std::wstring GetStorage();
@ -37,13 +35,12 @@ private:
void Flush(); void Flush();
std::wstring buffer; std::wstring buffer;
std::wstring storage;
std::unordered_set<wchar_t> repeatingChars; std::unordered_set<wchar_t> repeatingChars;
std::recursive_mutex threadMutex; std::mutex bufferMutex;
std::wstring storage;
std::recursive_mutex storageMutex;
HANDLE deletionEvent = CreateEventW(nullptr, FALSE, FALSE, NULL); HANDLE deletionEvent = CreateEventW(nullptr, FALSE, FALSE, NULL);
std::thread flushThread = std::thread([&] { while (WaitForSingleObject(deletionEvent, 10) == WAIT_TIMEOUT) Flush(); }); std::thread flushThread = std::thread([&] { while (WaitForSingleObject(deletionEvent, 10) == WAIT_TIMEOUT) Flush(); });
DWORD lastPushTime = GetTickCount(); DWORD lastPushTime = GetTickCount();
}; };
// EOF

37
GUI/host/util.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "util.h"
#include "text.h"
#include "host.h"
namespace Util
{
std::optional<std::wstring> 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"";
}
}
}

9
GUI/host/util.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include "common.h"
namespace Util
{
std::optional<std::wstring> GetClipboardText();
std::wstring StringToWideString(std::string text, UINT encoding = CP_UTF8);
}

View File

@ -26,7 +26,7 @@ namespace
L"Error in module: " << moduleName << std::endl; L"Error in module: " << moduleName << std::endl;
if (exception->ExceptionRecord->ExceptionCode == 0xE06D7363) 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) for (int i = 0; i < exception->ExceptionRecord->NumberParameters; ++i)
errorMsg << L"Additional info: " << exception->ExceptionRecord->ExceptionInformation[i] << std::endl; errorMsg << L"Additional info: " << exception->ExceptionRecord->ExceptionInformation[i] << std::endl;

View File

@ -42,12 +42,16 @@ static bool operator==(const ThreadParam& one, const ThreadParam& two) { return
class WinMutex class WinMutex
{ {
HANDLE mutex;
public: public:
WinMutex(std::wstring name) : mutex(CreateMutexW(nullptr, false, name.c_str())) {} WinMutex(std::wstring name) : mutex(CreateMutexW(nullptr, false, name.c_str())) {}
WinMutex(WinMutex&) = delete;
WinMutex& operator=(WinMutex) = delete;
~WinMutex() { ReleaseMutex(mutex); CloseHandle(mutex); } ~WinMutex() { ReleaseMutex(mutex); CloseHandle(mutex); }
void lock() { WaitForSingleObject(mutex, 0); } void lock() { WaitForSingleObject(mutex, 0); }
void unlock() { ReleaseMutex(mutex); } void unlock() { ReleaseMutex(mutex); }
private:
HANDLE mutex;
}; };
struct InsertHookCmd // From host struct InsertHookCmd // From host