diff --git a/src/micetools/dll/dllmain.c b/src/micetools/dll/dllmain.c index 89505c2..ee0bc06 100644 --- a/src/micetools/dll/dllmain.c +++ b/src/micetools/dll/dllmain.c @@ -1,5 +1,6 @@ #include +#include "../lib/util/pid.h" #include "common.h" #include "devices/_devices.h" #include "drivers/mx.h" @@ -112,7 +113,7 @@ void init_injection(HMODULE hModule) { load_mice_config(); // We're in a new context now, so need to reconfigure - setup_logging(GetParentProcessId()); + setup_logging(); log_info(plfBoot, "Handover complete. Now executing within %ls", exeName); init_com_devices(); diff --git a/src/micetools/dll/drivers/mxjvs.c b/src/micetools/dll/drivers/mxjvs.c index 520c5ad..6293d21 100644 --- a/src/micetools/dll/drivers/mxjvs.c +++ b/src/micetools/dll/drivers/mxjvs.c @@ -453,7 +453,7 @@ DWORD __stdcall mxjvs_comdev_thread(com_device_t* com) { nbytes--; } - short packetSize = bufferPtr - inBuffer; + short packetSize = (bufferPtr - inBuffer) & 0xFFFF; mxjvs_handle(inBuffer, packetSize, outBuffer, _countof(outBuffer), &bytesReturned); com->modemStatus = !JVS_SENSE ? MS_DSR_ON : 0; comdev_write(com, outBuffer, bytesReturned & 0xFFFF); diff --git a/src/micetools/dll/hooks/processes.c b/src/micetools/dll/hooks/processes.c index d0e7aa7..187ceb8 100644 --- a/src/micetools/dll/hooks/processes.c +++ b/src/micetools/dll/hooks/processes.c @@ -21,21 +21,8 @@ BOOL WINAPI FakeCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, log_info(plfProcesses, "CreateProcessA %s %s", lpApplicationName, lpCommandLine); - // return TrueCreateProcessA("mxAuthDisc.bat", "", lpProcessAttributes, lpThreadAttributes, - // bInheritHandles, dwCreationFlags, lpEnvironment, - // lpCurrentDirectory, lpStartupInfo, lpProcessInformation); - - // HANDLE fake_evt = CreateEvent(NULL, TRUE, FALSE, NULL); - // SetEvent(fake_evt); - - HANDLE hProcess = start_and_inject(INVALID_HANDLE_VALUE, lpApplicationName, lpCommandLine, - MICELIB, FALSE, 0, "", 0); - - if (lpProcessInformation) { - lpProcessInformation->hProcess = hProcess; - } - - return TRUE; + return start_and_inject(INVALID_HANDLE_VALUE, lpApplicationName, lpCommandLine, + MICELIB, FALSE, 0, NULL, 0, lpProcessInformation); } BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, @@ -53,62 +40,8 @@ BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSTR commandLine = malloc(nMultiChars); WideCharToMultiByte(CP_ACP, 0, lpCommandLine, -1, commandLine, nMultiChars, NULL, NULL); - // WideCharToMultiByte(CP_ACP, 0, lpApplicationName, -1, applicationName, sizeof - // applicationName, - // NULL, NULL); - - // HANDLE child; - // CHAR commandLine[MAX_PATH + 1]; - // WCHAR commandLineW[MAX_PATH + 1]; - // WCHAR micePathW[MAX_PATH + 1]; - // GetModuleFileNameW(NULL, micePathW, MAX_PATH); - - // HANDLE fake_evt = CreateEvent(NULL, TRUE, FALSE, NULL); - // SetEvent(fake_evt); - - // return TrueCreateProcessA(applicationName, commandLine, lpProcessAttributes, lpThreadAttributes, - // bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, - // lpStartupInfo, lpProcessInformation); - - HANDLE hProcess = start_and_inject(INVALID_HANDLE_VALUE, applicationName, commandLine, MICELIB, - TRUE, 0, NULL, 0); - if (lpProcessInformation) { - lpProcessInformation->hProcess = hProcess; - lpProcessInformation->hThread = GetDummyHandle(); - } - - log_game(plfProcesses, "hP: %08x", hProcess); - - return TRUE; - - // if (lpCommandLine != NULL) { - // log_error(plfProcesses, "!!"); - // return FALSE; - // // WideCharToMultiByte(CP_ACP, 0, lpCommandLine, -1, commandLine, sizeof commandLine, - // NULL, - // // NULL); - // // child = start_and_inject(INVALID_HANDLE_VALUE, applicationName, commandLine, MICELIB, - // // false, 0, NULL, - // // CREATE_NEW_CONSOLE); - // } else { - // dwCreationFlags |= CREATE_NEW_CONSOLE; - // wsprintfW(commandLineW, L"mice -b %ls", lpApplicationName); - // printf("%ls %ls\n", micePathW, commandLineW); - // BOOL ret = - // TrueCreateProcessW(L"mice.cmd", commandLineW, lpProcessAttributes, - // lpThreadAttributes, - // bInheritHandles, dwCreationFlags, lpEnvironment, - // lpCurrentDirectory, lpStartupInfo, lpProcessInformation); - // printf("%d\n", ret); - // return ret; - // // CHAR commandLine[] - // // child = - // // start_and_inject(INVALID_HANDLE_VALUE, applicationName, NULL, MICELIB, false, 0, - // // NULL, CREATE_NEW_CONSOLE); - // } - - // return !FAILED(child); - // // #endif + return start_and_inject(INVALID_HANDLE_VALUE, applicationName, commandLine, MICELIB, + FALSE, 0, NULL, 0, lpProcessInformation); } BOOL WINAPI FakeGetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) { diff --git a/src/micetools/dll/util/_util.h b/src/micetools/dll/util/_util.h index b637545..cba260b 100644 --- a/src/micetools/dll/util/_util.h +++ b/src/micetools/dll/util/_util.h @@ -13,7 +13,6 @@ BOOL RemoveDataForHandle(HANDLE hObject, DWORD type); HANDLE GetDummyHandle(); void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes); void PrintStack(void); -DWORD GetParentProcessId(void); BOOL PathEqual(LPCSTR path1, LPCSTR path2); BOOL PathPrefix(LPCSTR path, LPCSTR prefix); diff --git a/src/micetools/dll/util/misc.c b/src/micetools/dll/util/misc.c index f5ab26a..d7acebe 100644 --- a/src/micetools/dll/util/misc.c +++ b/src/micetools/dll/util/misc.c @@ -1,7 +1,6 @@ #define _WIN32_WINNT 0x0600 #include #include -#include #include "../hooks/files.h" @@ -186,23 +185,3 @@ void* open_mapped_file(LPCWSTR path, DWORD size, HANDLE* file, HANDLE* file_mapp } return mapping; } - -DWORD GetParentProcessIdFor(DWORD pid) { - HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - PROCESSENTRY32 pe = { 0 }; - pe.dwSize = sizeof(PROCESSENTRY32); - - if (Process32First(h, &pe)) { - do { - if (pe.th32ProcessID == pid) { - CloseHandle(h); - return pe.th32ParentProcessID; - } - } while (Process32Next(h, &pe)); - } - CloseHandle(h); - return (DWORD)-1; -} -DWORD GetParentProcessId(void) { - return GetParentProcessIdFor(GetCurrentProcessId()); -} diff --git a/src/micetools/launcher/main.c b/src/micetools/launcher/main.c index f7008c8..4509154 100644 --- a/src/micetools/launcher/main.c +++ b/src/micetools/launcher/main.c @@ -2,6 +2,7 @@ #include #include "../lib/mice/mice.h" +#include "../lib/util/pid.h" #include "locate.h" #include "spawn.h" @@ -112,7 +113,7 @@ static DWORD WINAPI MiceMailslotWatcher(HANDLE* pSlot) { if (hLogFile != INVALID_HANDLE_VALUE) { // The only VT100 sequences being used are colours, so this lazy approach works BOOL inVt100 = FALSE; - for (int i = 0; i < nBytes; i++) { + for (unsigned int i = 0; i < nBytes; i++) { if (readBuffer[i] == '\033') { inVt100 = TRUE; continue; @@ -162,17 +163,16 @@ static int terminate(int err) { return err; } -HANDLE hGameProc = INVALID_HANDLE_VALUE; HANDLE hJob = INVALID_HANDLE_VALUE; BOOL WINAPI MiceHandlerRoutine(DWORD CtrlType) { if (hJob != INVALID_HANDLE_VALUE) CloseHandle(hJob); - // if (hGameProc != INVALID_HANDLE_VALUE) TerminateProcess(hGameProc, 0); + ExitProcess(terminate(0)); } int main(int argc, char* argv[]) { load_mice_config(); if (!setup_mailslot()) return 1; - setup_logging(GetCurrentProcessId()); + setup_logging(); log_info(plfBoot, "Micetools version: %s", MICE_VERSION); @@ -217,17 +217,18 @@ int main(int argc, char* argv[]) { SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &info, sizeof info); char* extra_injections = MiceConfig.launcher.inject; - hGameProc = start_and_inject(hJob, exe_name, commandline, micepath, debug_wait, boot_delay, - extra_injections, 0); - if (!hGameProc) return terminate(-1); + PROCESS_INFORMATION pi; + if (!start_and_inject(hJob, exe_name, commandline, micepath, debug_wait, boot_delay, + extra_injections, 0, &pi)) + return terminate(-1); SetConsoleCtrlHandler(MiceHandlerRoutine, TRUE); - if (FAILED(WaitForSingleObject(hGameProc, INFINITE))) { + if (FAILED(WaitForSingleObject(pi.hProcess, INFINITE))) { log_error(plfBoot, "Fatal: WaitForSingleObject failed: %03x", GetLastError()); } else { log_info(plfBoot, "Shutting down"); - CloseHandle(hGameProc); + CloseHandle(pi.hProcess); } return terminate(0); } diff --git a/src/micetools/launcher/meson.build b/src/micetools/launcher/meson.build index 7477e8b..9d96ac6 100644 --- a/src/micetools/launcher/meson.build +++ b/src/micetools/launcher/meson.build @@ -11,6 +11,7 @@ executable( link_with: [ mice_lib, mxklib, + util_lib, # Madoka service emulation mxk, diff --git a/src/micetools/lib/mice/exe.c b/src/micetools/lib/mice/exe.c index 2ee7f52..d104d56 100644 --- a/src/micetools/lib/mice/exe.c +++ b/src/micetools/lib/mice/exe.c @@ -73,8 +73,9 @@ bool inject_dll(HANDLE process, LPCSTR inject) { return remote_call(process, addr_LoadLibraryA, inject, &result); } -HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait, - DWORD delay, LPCSTR extra_injections, DWORD flags) { +BOOL start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait, + DWORD delay, LPCSTR extra_injections, DWORD flags, + LPPROCESS_INFORMATION lpProcessInformation) { STARTUPINFOA startupInfo; PROCESS_INFORMATION processInformation = { 0 }; @@ -143,7 +144,11 @@ HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, goto abort; } - return processInformation.hProcess; + if (lpProcessInformation) { + memcpy(lpProcessInformation, &processInformation, sizeof processInformation); + } + + return TRUE; abort: if (processInformation.hProcess && processInformation.hProcess != INVALID_HANDLE_VALUE) { @@ -158,5 +163,5 @@ abort: log_error(plfProcesses, "Fatal: CloseHandle(hThread) failed: %d", GetLastError()); } - return INVALID_HANDLE_VALUE; + return FALSE; } diff --git a/src/micetools/lib/mice/exe.h b/src/micetools/lib/mice/exe.h index 7b8ef19..7e9b407 100644 --- a/src/micetools/lib/mice/exe.h +++ b/src/micetools/lib/mice/exe.h @@ -2,7 +2,7 @@ #include #include -HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait, - DWORD delay, LPCSTR extra_injections, DWORD flags); +BOOL start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait, + DWORD delay, LPCSTR extra_injections, DWORD flags, LPPROCESS_INFORMATION lpProcessInformation); #define MICELIB "mice.dll" diff --git a/src/micetools/lib/mice/log.c b/src/micetools/lib/mice/log.c index 9a7f47d..53e7a34 100644 --- a/src/micetools/lib/mice/log.c +++ b/src/micetools/lib/mice/log.c @@ -7,6 +7,7 @@ #include #pragma comment(lib, "DbgHelp.lib") +#include "../util/pid.h" #include "config.h" #define _LF(category, name, display) \ @@ -87,7 +88,6 @@ int _do_log(BYTE log_level, PLOG_FACILITY facility, const char* format, va_list char prefix = LOG_PREFIXES[log_level]; - int col_len = strlen(log_colours[log_level]); EnterCriticalSection(&logger_lock); @@ -168,9 +168,9 @@ int _log_game(PLOG_FACILITY facility, const char* format, ...) { return ret; } -void setup_logging(DWORD slotPid) { +void setup_logging() { char slotName[MAX_PATH + 1]; - sprintf_s(slotName, MAX_PATH, "\\\\.\\mailslot\\micelog%d", slotPid); + sprintf_s(slotName, MAX_PATH, "\\\\.\\mailslot\\micelog%d", GetOutermostMiceId()); hSlot = CreateFile(slotName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); diff --git a/src/micetools/lib/mice/log.h b/src/micetools/lib/mice/log.h index 59a90b5..375d79b 100644 --- a/src/micetools/lib/mice/log.h +++ b/src/micetools/lib/mice/log.h @@ -38,7 +38,7 @@ int vlog_game(PLOG_FACILITY facility, const char* format, va_list args); void log_stack(PLOG_FACILITY facility); -void setup_logging(DWORD slotPid); +void setup_logging(); // Disable some logging entirely at build time for speed #define COMPILE_LOG_LEVEL 6 diff --git a/src/micetools/lib/util/meson.build b/src/micetools/lib/util/meson.build index f8bc41c..830cd91 100644 --- a/src/micetools/lib/util/meson.build +++ b/src/micetools/lib/util/meson.build @@ -2,5 +2,6 @@ util_lib = static_library( 'miceutil', sources: [ 'hex.c', + 'pid.c', ], ) diff --git a/src/micetools/lib/util/pid.c b/src/micetools/lib/util/pid.c new file mode 100644 index 0000000..415a344 --- /dev/null +++ b/src/micetools/lib/util/pid.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +#pragma comment(lib, "psapi.lib") + +DWORD GetParentProcessIdFor(DWORD pid) { + HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + PROCESSENTRY32 pe = { 0 }; + pe.dwSize = sizeof(PROCESSENTRY32); + + if (Process32First(h, &pe)) { + do { + if (pe.th32ProcessID == pid) { + CloseHandle(h); + return pe.th32ParentProcessID; + } + } while (Process32Next(h, &pe)); + } + CloseHandle(h); + return (DWORD)-1; +} +DWORD GetParentProcessId(void) { return GetParentProcessIdFor(GetCurrentProcessId()); } +DWORD GetOutermostMiceId(void) { + DWORD pid = GetCurrentProcessId(); + do { + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); + if (hProcess) { + CHAR baseName[MAX_PATH + 1]; + if (GetModuleFileNameEx(hProcess, NULL, baseName, sizeof baseName)) { + // TODO: Better + if (strcmp(PathFindFileNameA(baseName), "mice.exe") == 0) return pid; + } + CloseHandle(hProcess); + } + + pid = GetParentProcessIdFor(pid); + } while (pid != (DWORD)-1); + return (DWORD)-1; +} diff --git a/src/micetools/lib/util/pid.h b/src/micetools/lib/util/pid.h new file mode 100644 index 0000000..876cb43 --- /dev/null +++ b/src/micetools/lib/util/pid.h @@ -0,0 +1,5 @@ +#include + +DWORD GetParentProcessIdFor(DWORD pid); +DWORD GetParentProcessId(void); +DWORD GetOutermostMiceId(void);