Fix child process spawning
This commit is contained in:
parent
b015c0cce4
commit
800b6f28e1
@ -1,5 +1,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "../lib/util/pid.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "devices/_devices.h"
|
#include "devices/_devices.h"
|
||||||
#include "drivers/mx.h"
|
#include "drivers/mx.h"
|
||||||
@ -112,7 +113,7 @@ void init_injection(HMODULE hModule) {
|
|||||||
load_mice_config();
|
load_mice_config();
|
||||||
|
|
||||||
// We're in a new context now, so need to reconfigure
|
// 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);
|
log_info(plfBoot, "Handover complete. Now executing within %ls", exeName);
|
||||||
|
|
||||||
init_com_devices();
|
init_com_devices();
|
||||||
|
@ -453,7 +453,7 @@ DWORD __stdcall mxjvs_comdev_thread(com_device_t* com) {
|
|||||||
nbytes--;
|
nbytes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
short packetSize = bufferPtr - inBuffer;
|
short packetSize = (bufferPtr - inBuffer) & 0xFFFF;
|
||||||
mxjvs_handle(inBuffer, packetSize, outBuffer, _countof(outBuffer), &bytesReturned);
|
mxjvs_handle(inBuffer, packetSize, outBuffer, _countof(outBuffer), &bytesReturned);
|
||||||
com->modemStatus = !JVS_SENSE ? MS_DSR_ON : 0;
|
com->modemStatus = !JVS_SENSE ? MS_DSR_ON : 0;
|
||||||
comdev_write(com, outBuffer, bytesReturned & 0xFFFF);
|
comdev_write(com, outBuffer, bytesReturned & 0xFFFF);
|
||||||
|
@ -21,21 +21,8 @@ BOOL WINAPI FakeCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine,
|
|||||||
|
|
||||||
log_info(plfProcesses, "CreateProcessA %s %s", lpApplicationName, lpCommandLine);
|
log_info(plfProcesses, "CreateProcessA %s %s", lpApplicationName, lpCommandLine);
|
||||||
|
|
||||||
// return TrueCreateProcessA("mxAuthDisc.bat", "", lpProcessAttributes, lpThreadAttributes,
|
return start_and_inject(INVALID_HANDLE_VALUE, lpApplicationName, lpCommandLine,
|
||||||
// bInheritHandles, dwCreationFlags, lpEnvironment,
|
MICELIB, FALSE, 0, NULL, 0, lpProcessInformation);
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
|
BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
|
||||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
@ -53,62 +40,8 @@ BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
|
|||||||
LPSTR commandLine = malloc(nMultiChars);
|
LPSTR commandLine = malloc(nMultiChars);
|
||||||
WideCharToMultiByte(CP_ACP, 0, lpCommandLine, -1, commandLine, nMultiChars, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, lpCommandLine, -1, commandLine, nMultiChars, NULL, NULL);
|
||||||
|
|
||||||
// WideCharToMultiByte(CP_ACP, 0, lpApplicationName, -1, applicationName, sizeof
|
return start_and_inject(INVALID_HANDLE_VALUE, applicationName, commandLine, MICELIB,
|
||||||
// applicationName,
|
FALSE, 0, NULL, 0, lpProcessInformation);
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI FakeGetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) {
|
BOOL WINAPI FakeGetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) {
|
||||||
|
@ -13,7 +13,6 @@ BOOL RemoveDataForHandle(HANDLE hObject, DWORD type);
|
|||||||
HANDLE GetDummyHandle();
|
HANDLE GetDummyHandle();
|
||||||
void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes);
|
void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes);
|
||||||
void PrintStack(void);
|
void PrintStack(void);
|
||||||
DWORD GetParentProcessId(void);
|
|
||||||
|
|
||||||
BOOL PathEqual(LPCSTR path1, LPCSTR path2);
|
BOOL PathEqual(LPCSTR path1, LPCSTR path2);
|
||||||
BOOL PathPrefix(LPCSTR path, LPCSTR prefix);
|
BOOL PathPrefix(LPCSTR path, LPCSTR prefix);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#define _WIN32_WINNT 0x0600
|
#define _WIN32_WINNT 0x0600
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
#include <tlhelp32.h>
|
|
||||||
|
|
||||||
#include "../hooks/files.h"
|
#include "../hooks/files.h"
|
||||||
|
|
||||||
@ -186,23 +185,3 @@ void* open_mapped_file(LPCWSTR path, DWORD size, HANDLE* file, HANDLE* file_mapp
|
|||||||
}
|
}
|
||||||
return mapping;
|
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());
|
|
||||||
}
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "../lib/mice/mice.h"
|
#include "../lib/mice/mice.h"
|
||||||
|
#include "../lib/util/pid.h"
|
||||||
#include "locate.h"
|
#include "locate.h"
|
||||||
#include "spawn.h"
|
#include "spawn.h"
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ static DWORD WINAPI MiceMailslotWatcher(HANDLE* pSlot) {
|
|||||||
if (hLogFile != INVALID_HANDLE_VALUE) {
|
if (hLogFile != INVALID_HANDLE_VALUE) {
|
||||||
// The only VT100 sequences being used are colours, so this lazy approach works
|
// The only VT100 sequences being used are colours, so this lazy approach works
|
||||||
BOOL inVt100 = FALSE;
|
BOOL inVt100 = FALSE;
|
||||||
for (int i = 0; i < nBytes; i++) {
|
for (unsigned int i = 0; i < nBytes; i++) {
|
||||||
if (readBuffer[i] == '\033') {
|
if (readBuffer[i] == '\033') {
|
||||||
inVt100 = TRUE;
|
inVt100 = TRUE;
|
||||||
continue;
|
continue;
|
||||||
@ -162,17 +163,16 @@ static int terminate(int err) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE hGameProc = INVALID_HANDLE_VALUE;
|
|
||||||
HANDLE hJob = INVALID_HANDLE_VALUE;
|
HANDLE hJob = INVALID_HANDLE_VALUE;
|
||||||
BOOL WINAPI MiceHandlerRoutine(DWORD CtrlType) {
|
BOOL WINAPI MiceHandlerRoutine(DWORD CtrlType) {
|
||||||
if (hJob != INVALID_HANDLE_VALUE) CloseHandle(hJob);
|
if (hJob != INVALID_HANDLE_VALUE) CloseHandle(hJob);
|
||||||
// if (hGameProc != INVALID_HANDLE_VALUE) TerminateProcess(hGameProc, 0);
|
ExitProcess(terminate(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
load_mice_config();
|
load_mice_config();
|
||||||
if (!setup_mailslot()) return 1;
|
if (!setup_mailslot()) return 1;
|
||||||
setup_logging(GetCurrentProcessId());
|
setup_logging();
|
||||||
|
|
||||||
log_info(plfBoot, "Micetools version: %s", MICE_VERSION);
|
log_info(plfBoot, "Micetools version: %s", MICE_VERSION);
|
||||||
|
|
||||||
@ -217,17 +217,18 @@ int main(int argc, char* argv[]) {
|
|||||||
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &info, sizeof info);
|
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &info, sizeof info);
|
||||||
|
|
||||||
char* extra_injections = MiceConfig.launcher.inject;
|
char* extra_injections = MiceConfig.launcher.inject;
|
||||||
hGameProc = start_and_inject(hJob, exe_name, commandline, micepath, debug_wait, boot_delay,
|
PROCESS_INFORMATION pi;
|
||||||
extra_injections, 0);
|
if (!start_and_inject(hJob, exe_name, commandline, micepath, debug_wait, boot_delay,
|
||||||
if (!hGameProc) return terminate(-1);
|
extra_injections, 0, &pi))
|
||||||
|
return terminate(-1);
|
||||||
|
|
||||||
SetConsoleCtrlHandler(MiceHandlerRoutine, TRUE);
|
SetConsoleCtrlHandler(MiceHandlerRoutine, TRUE);
|
||||||
|
|
||||||
if (FAILED(WaitForSingleObject(hGameProc, INFINITE))) {
|
if (FAILED(WaitForSingleObject(pi.hProcess, INFINITE))) {
|
||||||
log_error(plfBoot, "Fatal: WaitForSingleObject failed: %03x", GetLastError());
|
log_error(plfBoot, "Fatal: WaitForSingleObject failed: %03x", GetLastError());
|
||||||
} else {
|
} else {
|
||||||
log_info(plfBoot, "Shutting down");
|
log_info(plfBoot, "Shutting down");
|
||||||
CloseHandle(hGameProc);
|
CloseHandle(pi.hProcess);
|
||||||
}
|
}
|
||||||
return terminate(0);
|
return terminate(0);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ executable(
|
|||||||
link_with: [
|
link_with: [
|
||||||
mice_lib,
|
mice_lib,
|
||||||
mxklib,
|
mxklib,
|
||||||
|
util_lib,
|
||||||
|
|
||||||
# Madoka service emulation
|
# Madoka service emulation
|
||||||
mxk,
|
mxk,
|
||||||
|
@ -73,8 +73,9 @@ bool inject_dll(HANDLE process, LPCSTR inject) {
|
|||||||
return remote_call(process, addr_LoadLibraryA, inject, &result);
|
return remote_call(process, addr_LoadLibraryA, inject, &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
|
BOOL start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
|
||||||
DWORD delay, LPCSTR extra_injections, DWORD flags) {
|
DWORD delay, LPCSTR extra_injections, DWORD flags,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation) {
|
||||||
STARTUPINFOA startupInfo;
|
STARTUPINFOA startupInfo;
|
||||||
PROCESS_INFORMATION processInformation = { 0 };
|
PROCESS_INFORMATION processInformation = { 0 };
|
||||||
|
|
||||||
@ -143,7 +144,11 @@ HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject,
|
|||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
return processInformation.hProcess;
|
if (lpProcessInformation) {
|
||||||
|
memcpy(lpProcessInformation, &processInformation, sizeof processInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
if (processInformation.hProcess && processInformation.hProcess != INVALID_HANDLE_VALUE) {
|
if (processInformation.hProcess && processInformation.hProcess != INVALID_HANDLE_VALUE) {
|
||||||
@ -158,5 +163,5 @@ abort:
|
|||||||
log_error(plfProcesses, "Fatal: CloseHandle(hThread) failed: %d", GetLastError());
|
log_error(plfProcesses, "Fatal: CloseHandle(hThread) failed: %d", GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
return INVALID_HANDLE_VALUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
|
BOOL start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
|
||||||
DWORD delay, LPCSTR extra_injections, DWORD flags);
|
DWORD delay, LPCSTR extra_injections, DWORD flags, LPPROCESS_INFORMATION lpProcessInformation);
|
||||||
|
|
||||||
#define MICELIB "mice.dll"
|
#define MICELIB "mice.dll"
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#pragma comment(lib, "DbgHelp.lib")
|
#pragma comment(lib, "DbgHelp.lib")
|
||||||
|
|
||||||
|
#include "../util/pid.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#define _LF(category, name, display) \
|
#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];
|
char prefix = LOG_PREFIXES[log_level];
|
||||||
|
|
||||||
|
|
||||||
int col_len = strlen(log_colours[log_level]);
|
int col_len = strlen(log_colours[log_level]);
|
||||||
|
|
||||||
EnterCriticalSection(&logger_lock);
|
EnterCriticalSection(&logger_lock);
|
||||||
@ -168,9 +168,9 @@ int _log_game(PLOG_FACILITY facility, const char* format, ...) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_logging(DWORD slotPid) {
|
void setup_logging() {
|
||||||
char slotName[MAX_PATH + 1];
|
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,
|
hSlot = CreateFile(slotName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
@ -38,7 +38,7 @@ int vlog_game(PLOG_FACILITY facility, const char* format, va_list args);
|
|||||||
|
|
||||||
void log_stack(PLOG_FACILITY facility);
|
void log_stack(PLOG_FACILITY facility);
|
||||||
|
|
||||||
void setup_logging(DWORD slotPid);
|
void setup_logging();
|
||||||
|
|
||||||
// Disable some logging entirely at build time for speed
|
// Disable some logging entirely at build time for speed
|
||||||
#define COMPILE_LOG_LEVEL 6
|
#define COMPILE_LOG_LEVEL 6
|
||||||
|
@ -2,5 +2,6 @@ util_lib = static_library(
|
|||||||
'miceutil',
|
'miceutil',
|
||||||
sources: [
|
sources: [
|
||||||
'hex.c',
|
'hex.c',
|
||||||
|
'pid.c',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
41
src/micetools/lib/util/pid.c
Normal file
41
src/micetools/lib/util/pid.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include <Windows.h>
|
||||||
|
#include <psapi.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
5
src/micetools/lib/util/pid.h
Normal file
5
src/micetools/lib/util/pid.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
DWORD GetParentProcessIdFor(DWORD pid);
|
||||||
|
DWORD GetParentProcessId(void);
|
||||||
|
DWORD GetOutermostMiceId(void);
|
Loading…
Reference in New Issue
Block a user