diff --git a/LunaTranslator/LunaTranslator/gui/usefulwidget.py b/LunaTranslator/LunaTranslator/gui/usefulwidget.py index fda6a426..b19944f5 100644 --- a/LunaTranslator/LunaTranslator/gui/usefulwidget.py +++ b/LunaTranslator/LunaTranslator/gui/usefulwidget.py @@ -551,8 +551,8 @@ class WebivewWidget(QWidget): self.webview = _Webview(debug=debug, window=int(self.winId())) - # self.webview.bind("__on_load", self._on_load) - # self.webview.init("""window.__on_load(window.location.href)""") + self.webview.bind("__on_load", self._on_load) + self.webview.init("""window.__on_load(window.location.href)""") def _on_load(self, _, href): self.on_load.emit(json.loads(href)[0]) diff --git a/LunaTranslator/LunaTranslator/network/libcurl/requests.py b/LunaTranslator/LunaTranslator/network/libcurl/requests.py index b4cbfa7f..06f750f7 100644 --- a/LunaTranslator/LunaTranslator/network/libcurl/requests.py +++ b/LunaTranslator/LunaTranslator/network/libcurl/requests.py @@ -1,7 +1,6 @@ from libcurl import * -import winsharedutils -import threading -from ctypes import c_long, cast, pointer, POINTER +import threading, functools, queue +from ctypes import c_long, cast, pointer, POINTER, c_char from network.requests_common import * from traceback import print_exc @@ -25,9 +24,8 @@ class Response(ResponseBase): downloadeddata = b"" canend = False allbs = 0 - while not (self.cqueue.empty() and canend): - buff = self.cqueue.get() - + while not (self.queue.empty() and canend): + buff = self.queue.get() if buff is None: canend = True continue @@ -174,23 +172,33 @@ class Session(Sessionbase): resp = Response() if stream: - resp.cqueue = winsharedutils.lockedqueue() - curl_easy_setopt(curl, CURLoption.CURLOPT_WRITEDATA, resp.cqueue.ptr) + + def WriteMemoryCallback(queue, contents, size, nmemb, userp): + realsize = size * nmemb + queue.put(cast(contents, POINTER(c_char))[:realsize]) + return realsize + + _content = [] + _headers = [] + resp.queue = queue.Queue() + headerqueue = queue.Queue() + resp.keepref1 = WRITEFUNCTION( + functools.partial(WriteMemoryCallback, resp.queue) + ) + resp.keepref2 = WRITEFUNCTION( + functools.partial(WriteMemoryCallback, headerqueue) + ) curl_easy_setopt( curl, CURLoption.CURLOPT_WRITEFUNCTION, - winsharedutils.WriteMemoryToQueue, + cast(resp.keepref1, c_void_p).value, ) - headercqueue = winsharedutils.lockedqueue() - curl_easy_setopt(curl, CURLoption.CURLOPT_HEADERDATA, headercqueue.ptr) curl_easy_setopt( curl, CURLoption.CURLOPT_HEADERFUNCTION, - winsharedutils.WriteMemoryToQueue, + cast(resp.keepref2, c_void_p).value, ) - headerok = threading.Lock() - headerok.acquire() def ___perform(): try: @@ -198,31 +206,22 @@ class Session(Sessionbase): except: print_exc() self.raise_for_status() - headercqueue.pushnone() - headerok.acquire() + headerqueue.put(None) curl_easy_reset(curl) - resp.cqueue.pushnone() + resp.queue.put(None) threading.Thread(target=___perform, daemon=True).start() headerb = b"" - CLRFnum = 1 + int(bool((proxy))) while True: - _headerb = headercqueue.get() + _headerb = headerqueue.get() if _headerb is None: self.raise_for_status() headerb += _headerb if _headerb == b"\r\n": - # 使用代理时: - # b'HTTP/1.1 200 Connection established\r\n' - # b'\r\n' - CLRFnum -= 1 - if CLRFnum == 0: - break - else: - headerb = b"" + break resp.headers = self._update_header_cookie(headerb.decode("utf8")) - headerok.release() + if proxy: resp.status_code = int( headerb.decode("utf8").split("\r\n")[0].split(" ")[1] @@ -230,24 +229,35 @@ class Session(Sessionbase): else: resp.status_code = self._getStatusCode(curl) else: - _content = winsharedutils.MemoryStruct() - curl_easy_setopt(curl, CURLoption.CURLOPT_WRITEDATA, pointer(_content)) + + def WriteMemoryCallback(saver, contents, size, nmemb, userp): + realsize = size * nmemb + saver.append(cast(contents, POINTER(c_char))[:realsize]) + return realsize + + _content = [] + _headers = [] + resp.keepref1 = WRITEFUNCTION( + functools.partial(WriteMemoryCallback, _content) + ) + resp.keepref2 = WRITEFUNCTION( + functools.partial(WriteMemoryCallback, _headers) + ) + curl_easy_setopt( curl, CURLoption.CURLOPT_WRITEFUNCTION, - winsharedutils.WriteMemoryCallback, + cast(resp.keepref1, c_void_p).value, ) - _headers = winsharedutils.MemoryStruct() - curl_easy_setopt(curl, CURLoption.CURLOPT_HEADERDATA, pointer(_headers)) curl_easy_setopt( curl, CURLoption.CURLOPT_HEADERFUNCTION, - winsharedutils.WriteMemoryCallback, + cast(resp.keepref2, c_void_p).value, ) - # curl_easy_setopt(curl,CURLoption.CURLOPT_HEADERFUNCTION,cast(WRITEFUNCTION(WRITEFUNCTIONXX),c_void_p)) + self._perform(curl) - resp.content = _content.get() - resp.headers = self._update_header_cookie(_headers.get().decode("utf8")) + resp.content = b"".join(_content) + resp.headers = self._update_header_cookie(b"".join(_headers).decode("utf8")) resp.status_code = self._getStatusCode(curl) curl_easy_reset(curl) resp.last_error = self.last_error diff --git a/LunaTranslator/LunaTranslator/textsource/texthook.py b/LunaTranslator/LunaTranslator/textsource/texthook.py index db67a62d..7c6e3733 100644 --- a/LunaTranslator/LunaTranslator/textsource/texthook.py +++ b/LunaTranslator/LunaTranslator/textsource/texthook.py @@ -12,11 +12,13 @@ from myutils.hwnd import injectdll from myutils.wrapper import threader from ctypes import ( CDLL, + CFUNCTYPE, c_bool, POINTER, Structure, c_int, pointer, + c_char_p, c_wchar_p, c_uint64, sizeof, @@ -71,21 +73,13 @@ class SearchParam(Structure): ] -class Message(Structure): - _fields_ = [ - ("read", c_bool), - ("type", c_int), - ("pid", DWORD), - ("hn", c_char * HOOK_NAME_SIZE), - ("hc", c_wchar * HOOKCODE_LEN), - ("tp", ThreadParam), - ("stringptr", c_void_p), - ("addr", c_uint64), - ] - - -class simplehooks(Structure): - _fields_ = [("hookcode", c_wchar * 500), ("text", c_void_p)] +findhookcallback_t = CFUNCTYPE(None, c_wchar_p, c_wchar_p) +ProcessEvent = CFUNCTYPE(None, DWORD) +ThreadEvent = CFUNCTYPE(None, c_wchar_p, c_char_p, ThreadParam) +OutputCallback = CFUNCTYPE(None, c_wchar_p, c_char_p, ThreadParam, c_wchar_p) +ConsoleHandler = CFUNCTYPE(None, c_wchar_p) +HookInsertHandler = CFUNCTYPE(None, c_uint64, c_wchar_p) +EmbedCallback = CFUNCTYPE(None, c_wchar_p, ThreadParam) class texthook(basetext): @@ -96,7 +90,7 @@ class texthook(basetext): autostarthookcode = [] if needinserthookcode is None: needinserthookcode = [] - + self.keepref = [] self.newline = Queue() self.newline_delaywait = Queue() self.is64bit = Is64bit(pids[0]) @@ -147,7 +141,16 @@ class texthook(basetext): self.Luna_Settings = LunaHost.Luna_Settings self.Luna_Settings.argtypes = c_int, c_bool, c_int, c_int self.Luna_Start = LunaHost.Luna_Start - self.Luna_Start.argtypes = (POINTER(HANDLE),) + self.Luna_Start.argtypes = ( + c_void_p, + c_void_p, + c_void_p, + c_void_p, + c_void_p, + c_void_p, + c_void_p, + c_void_p, + ) self.Luna_Inject = LunaHost.Luna_Inject self.Luna_Inject.argtypes = DWORD, LPCWSTR self.Luna_CreatePipeAndCheck = LunaHost.Luna_CreatePipeAndCheck @@ -160,17 +163,12 @@ class texthook(basetext): self.Luna_RemoveHook.argtypes = DWORD, c_uint64 self.Luna_Detach = LunaHost.Luna_Detach self.Luna_Detach.argtypes = (DWORD,) - self.Luna_cfree = LunaHost.Luna_cfree - self.Luna_cfree.argtypes = (c_void_p,) self.Luna_FindHooks = LunaHost.Luna_FindHooks self.Luna_FindHooks.argtypes = ( DWORD, SearchParam, - POINTER(HANDLE), - POINTER(POINTER(c_int)), + c_void_p, ) - self.Luna_FindHooks_waiting = LunaHost.Luna_FindHooks_waiting - self.Luna_FindHooks_waiting.argtypes = (POINTER(c_int),) self.Luna_EmbedSettings = LunaHost.Luna_EmbedSettings self.Luna_EmbedSettings.argtypes = ( DWORD, @@ -190,10 +188,24 @@ class texthook(basetext): self.Luna_embedcallback = LunaHost.Luna_embedcallback self.Luna_embedcallback.argtypes = DWORD, LPCWSTR, LPCWSTR + def Luna_Startup(self): + procs = [ + ProcessEvent(self.onprocconnect), + ProcessEvent(self.connectedpids.remove), + ThreadEvent(self.onnewhook), + ThreadEvent(lambda _1, _2, tp: self.onremovehook(tp)), + OutputCallback(self.handle_output), + ConsoleHandler(gobject.baseobject.hookselectdialog.sysmessagesignal.emit), + HookInsertHandler(self.newhookinsert), + EmbedCallback(self.getembedtext), + ] + self.keepref += procs + ptrs = [cast(_, c_void_p).value for _ in procs] + self.Luna_Start(*ptrs) + def start(self): - self.hRead = HANDLE() - self.Luna_Start(pointer(self.hRead)) - self.solveeventthread() + + self.Luna_Startup() self.setsettings() injectpids = [] @@ -216,7 +228,6 @@ class texthook(basetext): # subprocess.Popen('"{}" dllinject {} "{}"'.format(injecter,pid,dll)) injectdll(injectpids, injecter, dll) - @threader def onprocconnect(self, pid): self.connectedpids.append(pid) time.sleep(savehook_new_data[self.pname]["inserthooktimeout"] / 1000) @@ -225,45 +236,6 @@ class texthook(basetext): self.showgamename() self.flashembedsettings(pid) - @threader - def solveeventthread(self): - while self.ending == False: - message = windows.ReadFile(self.hRead, sizeof(Message)) - if len(message) != sizeof(Message): - break - message = Message.from_buffer_copy(message) - _type = message.type - if _type in [0, 1]: - pid = message.pid - if _type == 0: - self.onprocconnect(pid) - elif _type == 1: - self.connectedpids.remove(pid) - elif _type in [2, 3]: - if _type == 2: - self.onnewhook(message.hc, message.hn, message.tp) - elif _type == 3: - self.onremovehook(message.tp) - elif _type == 4: - self.handle_output( - message.hc, - message.hn, - message.tp, - cast(message.stringptr, c_wchar_p).value, - ) - elif _type == 5: - gobject.baseobject.hookselectdialog.sysmessagesignal.emit( - cast(message.stringptr, c_wchar_p).value - ) - elif _type == 6: - self.newhookinsert( - message.addr, cast(message.stringptr, c_wchar_p).value - ) - elif _type == 7: - self.getembedtext(cast(message.stringptr, c_wchar_p).value, message.tp) - if message.stringptr: - self.Luna_cfree(message.stringptr) - def newhookinsert(self, addr, hcode): for _hc, _addr, _ctx1, _ctx2 in savehook_new_data[self.pname]["embedablehook"]: if hcode == _hc: @@ -415,32 +387,24 @@ class texthook(basetext): def findhook(self, usestruct): savefound = {} pids = self.connectedpids.copy() + cntref = [] - headers = {} - waiters = {} + def __callback(cntref, hcode, text): + if hcode not in savefound: + savefound[hcode] = [] + savefound[hcode].append(text) + cntref.append(0) + + _callback = findhookcallback_t(functools.partial(__callback, cntref)) + self.keepref.append(_callback) for pid in pids: - headers[pid] = HANDLE() - count = POINTER(c_int)() - waiters[pid] = count - self.Luna_FindHooks(pid, usestruct, pointer(headers[pid]), pointer(count)) + self.Luna_FindHooks(pid, usestruct, cast(_callback, c_void_p).value) - def ReadThread(hread): - while True: - message = windows.ReadFile(hread, sizeof(simplehooks)) - if len(message) != sizeof(simplehooks): - break - message = simplehooks.from_buffer_copy(message) - hc = message.hookcode - text = cast(message.text, c_wchar_p).value - if hc not in savefound: - savefound[hc] = [] - savefound[hc].append(text) - self.Luna_cfree(message.text) - windows.CloseHandle(hread) - - threading.Thread(target=ReadThread, args=(headers[pid],)).start() - for pid in pids: - self.Luna_FindHooks_waiting(waiters[pid]) + while True: + lastsize = len(cntref) + time.sleep(2) + if lastsize == len(cntref) and lastsize != 0: + break gobject.baseobject.hookselectdialog.getfoundhooksignal.emit(savefound) def inserthook(self, hookcode): diff --git a/LunaTranslator/LunaTranslator/winsharedutils.py b/LunaTranslator/LunaTranslator/winsharedutils.py index 6bb1cd69..13e3cee2 100644 --- a/LunaTranslator/LunaTranslator/winsharedutils.py +++ b/LunaTranslator/LunaTranslator/winsharedutils.py @@ -238,65 +238,10 @@ def extracticon2data(fname): return None -WriteMemoryCallback = utilsdll.WriteMemoryCallback c_free = utilsdll.c_free c_free.argtypes = (c_void_p,) -class MemoryStruct(Structure): - _fields_ = [("memory", c_void_p), ("size", c_size_t)] - - def __init__(self): - super().__init__() - self.memory = 0 - self.size = 0 - - def __del__(self): - if self.memory: - c_free(self.memory) - - def get(self): - return cast(self.memory, POINTER(c_char))[: self.size] - - -WriteMemoryToQueue = utilsdll.WriteMemoryToQueue -lockedqueuecreate = utilsdll.lockedqueuecreate -lockedqueuecreate.restype = c_void_p -lockedqueuefree = utilsdll.lockedqueuefree -lockedqueuefree.argtypes = (c_void_p,) -lockedqueueget = utilsdll.lockedqueueget -lockedqueueget.argtypes = c_void_p, POINTER(c_size_t) -lockedqueueget.restype = c_void_p -lockedqueuepush = utilsdll.lockedqueuepush -lockedqueuepush.argtypes = c_void_p, c_size_t, c_void_p -lockedqueueempty = utilsdll.lockedqueueempty -lockedqueueempty.argtypes = (c_void_p,) -lockedqueueempty.restype = c_bool - - -class lockedqueue: - def __init__(self) -> None: - self.ptr = lockedqueuecreate() - - def __del__(self): - lockedqueuefree(self.ptr) - - def get(self): - sz = c_size_t() - dataptr = lockedqueueget(self.ptr, pointer(sz)) - data = cast(dataptr, POINTER(c_char))[: sz.value] - c_free(dataptr) - if sz.value == 0: - return None - return data - - def pushnone(self): - lockedqueuepush(self.ptr, 0, b"\0") - - def empty(self): - return lockedqueueempty(self.ptr) - - _queryversion = utilsdll.queryversion _queryversion.restype = c_bool _queryversion.argtypes = ( diff --git a/LunaTranslator/files/defaultconfig/static_data.json b/LunaTranslator/files/defaultconfig/static_data.json index 288fd3e4..50d9bbcc 100644 --- a/LunaTranslator/files/defaultconfig/static_data.json +++ b/LunaTranslator/files/defaultconfig/static_data.json @@ -1,5 +1,5 @@ { - "version":"v2.46.2", + "version":"v2.47.0", "themes":{ "dark":[ {"file":"dark1.qss","name":"PyQtDarkTheme"}, diff --git a/LunaTranslator/requirements.txt b/LunaTranslator/requirements.txt index acfbf414..3a97bc79 100644 --- a/LunaTranslator/requirements.txt +++ b/LunaTranslator/requirements.txt @@ -1,6 +1,6 @@ PyQt5==5.15.10 PyQt5-Qt5==5.15.2 -webviewpy==1.0.4 +webviewpy==1.0.5 nuitka==2.0.5 imageio pefile \ No newline at end of file diff --git a/plugins/shareddllproxy/aspatch.cpp b/plugins/shareddllproxy/aspatch.cpp index 8c0122da..26f81b55 100644 --- a/plugins/shareddllproxy/aspatch.cpp +++ b/plugins/shareddllproxy/aspatch.cpp @@ -102,36 +102,33 @@ struct ThreadParam uint64_t ctx; // The context of the hook: by default the first value on stack, usually the return address uint64_t ctx2; // The subcontext of the hook: 0 by default, generated in a method specific to the hook }; -struct messagelist -{ - bool read; - int type; - DWORD pid; - char name[HOOK_NAME_SIZE]; - wchar_t hookcode[HOOKCODE_LEN]; - ThreadParam tp; - wchar_t *stringptr; - uint64_t addr; -}; - +typedef void (*ProcessEvent)(DWORD); +typedef void (*ThreadEvent)(wchar_t *, char *, ThreadParam); +typedef void (*OutputCallback)(wchar_t *, char *, ThreadParam, const wchar_t *); +typedef void (*ConsoleHandler)(const wchar_t *); +typedef void (*HookInsertHandler)(uint64_t, const wchar_t *); +typedef void (*EmbedCallback)(const wchar_t *, ThreadParam); +nlohmann::json config; +std::map translation; +std::unordered_set connectedpids; +void (*Luna_Start)(ProcessEvent Connect, ProcessEvent Disconnect, ThreadEvent Create, ThreadEvent Destroy, OutputCallback Output, ConsoleHandler console, HookInsertHandler hookinsert, EmbedCallback embed); +void (*Luna_Inject)(DWORD pid, LPCWSTR basepath); +void (*Luna_EmbedSettings)(DWORD pid, UINT32 waittime, UINT8 fontCharSet, bool fontCharSetEnabled, wchar_t *fontFamily, UINT32 spaceadjustpolicy, UINT32 keeprawtext, bool fastskipignore); +void (*Luna_useembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2, bool use); +bool (*Luna_checkisusingembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2); +void (*Luna_embedcallback)(DWORD pid, LPCWSTR text, LPCWSTR trans); +std::set notranslation; +HANDLE hsema; class lunapatch { public: HANDLE hMessage; HANDLE hwait; - nlohmann::json config; - std::map translation; - std::unordered_set connectedpids; - void (*Luna_Start)(HANDLE *hRead); - void (*Luna_Inject)(DWORD pid, LPCWSTR basepath); - void (*Luna_EmbedSettings)(DWORD pid, UINT32 waittime, UINT8 fontCharSet, bool fontCharSetEnabled, wchar_t *fontFamily, UINT32 spaceadjustpolicy, UINT32 keeprawtext, bool fastskipignore); - void (*Luna_useembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2, bool use); - bool (*Luna_checkisusingembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2); - void (*Luna_embedcallback)(DWORD pid, LPCWSTR text, LPCWSTR trans); - std::set notranslation; - HANDLE hsema; - lunapatch(std::wstring dll, nlohmann::json &&_translation, nlohmann::json &&_config) : translation(_translation), config(_config) + + lunapatch(std::wstring dll, nlohmann::json &&_translation, nlohmann::json &&_config) { + translation = _translation; + config = _config; auto LunaHost = LoadLibraryW(dll.c_str()); Luna_Start = (decltype(Luna_Start))GetProcAddress(LunaHost, "Luna_Start"); @@ -141,10 +138,54 @@ public: Luna_checkisusingembed = (decltype(Luna_checkisusingembed))GetProcAddress(LunaHost, "Luna_checkisusingembed"); Luna_embedcallback = (decltype(Luna_embedcallback))GetProcAddress(LunaHost, "Luna_embedcallback"); hsema = CreateSemaphore(NULL, 0, 100, NULL); - Luna_Start(&hMessage); - std::thread([&]() - { Parsehostmessage(); }) - .detach(); + Luna_Start( + [](DWORD pid) + { + auto font = StringToWideString(config["embedsettings"]["font"]); + auto insertspace_policy = config["embedsettings"]["insertspace_policy"]; + auto keeprawtext = config["embedsettings"]["keeprawtext"]; + Luna_EmbedSettings(pid, 1000, 2, false, font.data(), insertspace_policy, keeprawtext, false); + connectedpids.insert(pid); + }, + [](DWORD pid) + { + connectedpids.erase(pid); + ReleaseSemaphore(hsema, 1, NULL); + }, + [](auto, auto, auto) {}, + [](auto, auto, auto) {}, + [](auto, auto, auto, auto) {}, + [](auto) {}, + [](uint64_t addr, const wchar_t *output) + { + std::wstring newhookcode = output; + for (auto hook : config["embedhook"]) + { + auto hookcode = StringToWideString(hook[0]); + uint64_t _addr = hook[1]; + uint64_t _ctx1 = hook[2]; + uint64_t _ctx2 = hook[3]; + if (hookcode == newhookcode) + { + for (auto pid : connectedpids) + { + Luna_useembed(pid, addr, _ctx1, _ctx2, true); + } + } + } + }, + [](const wchar_t *output, ThreadParam tp) + { + std::wstring text = output; + for (auto pid : connectedpids) + { + if ((Luna_checkisusingembed(pid, tp.addr, tp.ctx, tp.ctx2))) + { + auto trans = findtranslation(text); + Luna_embedcallback(pid, output, trans.c_str()); + } + } + }); } void run() { @@ -194,7 +235,7 @@ public: } } } - std::wstring findtranslation(const std::wstring &text) + static std::wstring findtranslation(const std::wstring &text) { auto utf8text = WideStringToString(text); if (translation.find(utf8text) == translation.end()) @@ -205,71 +246,6 @@ public: } return StringToWideString(translation.at(utf8text)); } - void Parsehostmessage() - { - while (true) - { - messagelist message; - DWORD _; - ReadFile(hMessage, &message, sizeof(message), &_, NULL); - switch (message.type) - { - case 0: - { - auto font = StringToWideString(config["embedsettings"]["font"]); - auto insertspace_policy = config["embedsettings"]["insertspace_policy"]; - auto keeprawtext = config["embedsettings"]["keeprawtext"]; - Luna_EmbedSettings(message.pid, 1000, 2, false, font.data(), insertspace_policy, keeprawtext, false); - connectedpids.insert(message.pid); - } - break; - case 1: - { - connectedpids.erase(message.pid); - ReleaseSemaphore(hsema, 1, NULL); - } - break; - case 7: - { - std::wstring text = message.stringptr; - auto tp = message.tp; - for (auto pid : connectedpids) - { - if ((Luna_checkisusingembed(pid, tp.addr, tp.ctx, tp.ctx2))) - { - auto trans = findtranslation(text); - Luna_embedcallback(pid, text.c_str(), trans.c_str()); - } - } - } - break; - case 6: - { - std::wstring newhookcode = message.stringptr; - for (auto hook : config["embedhook"]) - { - auto hookcode = StringToWideString(hook[0]); - uint64_t _addr = hook[1]; - uint64_t _ctx1 = hook[2]; - uint64_t _ctx2 = hook[3]; - if (hookcode == newhookcode) - { - for (auto pid : connectedpids) - { - Luna_useembed(pid, message.addr, _ctx1, _ctx2, true); - } - } - } - } - break; - default: - break; - } - - if (message.stringptr) - free(message.stringptr); - } - } }; std::wstring GetExecutablePath() { diff --git a/plugins/winsharedutils/cinterface.cpp b/plugins/winsharedutils/cinterface.cpp index 1e629935..10f865fb 100644 --- a/plugins/winsharedutils/cinterface.cpp +++ b/plugins/winsharedutils/cinterface.cpp @@ -64,104 +64,7 @@ wchar_t **vecwstr2c(std::vector &vs) return argv; } -struct MemoryStruct -{ - char *memory; - size_t size; -}; -size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ - size_t realsize = size * nmemb; - struct MemoryStruct *mem = (struct MemoryStruct *)userp; - - char *ptr; - if (mem->memory) - ptr = (char *)realloc(mem->memory, mem->size + realsize + 1); - else - ptr = (char *)malloc(mem->size + realsize + 1); - if (!ptr) - { - /* out of memory! */ - printf("not enough memory (realloc returned NULL)\n"); - return 0; - } - - mem->memory = ptr; - memcpy(&(mem->memory[mem->size]), contents, realsize); - mem->size += realsize; - mem->memory[mem->size] = 0; - - return realsize; -} void c_free(void *ptr) { free(ptr); } - -class lockedqueue -{ - std::mutex lock; - std::queue data; - HANDLE hsema; - -public: - lockedqueue() - { - hsema = CreateSemaphore(NULL, 0, 65535, NULL); - } - ~lockedqueue() - { - CloseHandle(hsema); - } - void push(std::string &&_) - { - std::lock_guard _l(lock); - data.push(std::move(_)); - ReleaseSemaphore(hsema, 1, NULL); - } - std::string pop() - { - WaitForSingleObject(hsema, INFINITE); - std::lock_guard _l(lock); - auto _ = data.front(); - data.pop(); - return _; - } - bool empty() - { - std::lock_guard _l(lock); - return data.empty(); - } -}; -void *lockedqueuecreate() -{ - return new lockedqueue(); -} -void lockedqueuefree(void *q) -{ - delete reinterpret_cast(q); -} -void *lockedqueueget(void *q, size_t *l) -{ - auto data = reinterpret_cast(q)->pop(); - auto datastatic = new char[data.size()]; - memcpy(datastatic, data.data(), data.size()); - *l = data.size(); - return datastatic; -} -void lockedqueuepush(void *q, size_t l, void *ptr) -{ - reinterpret_cast(q)->push(std::string((char *)ptr, l)); -} -bool lockedqueueempty(void *q) -{ - return reinterpret_cast(q)->empty(); -} - -size_t WriteMemoryToQueue(void *contents, size_t size, size_t nmemb, void *userp) -{ - size_t realsize = size * nmemb; - auto queue = reinterpret_cast(userp); - queue->push(std::string((char *)contents, realsize)); - return realsize; -} diff --git a/plugins/winsharedutils/define.h b/plugins/winsharedutils/define.h index 954a1f34..21c90e6c 100644 --- a/plugins/winsharedutils/define.h +++ b/plugins/winsharedutils/define.h @@ -33,12 +33,5 @@ extern "C" __declspec(dllexport) void *extracticon2data(const wchar_t *name, size_t *l); - __declspec(dllexport) size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp); - __declspec(dllexport) size_t WriteMemoryToQueue(void *contents, size_t size, size_t nmemb, void *userp); - __declspec(dllexport) void *lockedqueuecreate(); - __declspec(dllexport) void lockedqueuefree(void *); - __declspec(dllexport) void *lockedqueueget(void *, size_t *); - __declspec(dllexport) void lockedqueuepush(void *, size_t, void *); - __declspec(dllexport) bool lockedqueueempty(void *); __declspec(dllexport) void c_free(void *); } \ No newline at end of file