mirror of
https://github.com/EnderIce2/rpc-bridge.git
synced 2025-05-25 22:14:38 +00:00
149 lines
3.4 KiB
C
149 lines
3.4 KiB
C
#include <windows.h>
|
|
#include <tlhelp32.h>
|
|
#include <winbase.h>
|
|
#include <winuser.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
|
|
void print(char const *fmt, ...);
|
|
LPTSTR GetErrorMessage();
|
|
|
|
BOOL IsChildProcess(DWORD parentID, DWORD childID)
|
|
{
|
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
PROCESSENTRY32 pe32;
|
|
|
|
if (hSnapshot == INVALID_HANDLE_VALUE)
|
|
return FALSE;
|
|
|
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
|
|
if (Process32First(hSnapshot, &pe32))
|
|
{
|
|
do
|
|
{
|
|
if (pe32.th32ParentProcessID == parentID && pe32.th32ProcessID == childID)
|
|
{
|
|
CloseHandle(hSnapshot);
|
|
return TRUE;
|
|
}
|
|
} while (Process32Next(hSnapshot, &pe32));
|
|
}
|
|
|
|
CloseHandle(hSnapshot);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL FileExists(LPCTSTR szPath)
|
|
{
|
|
DWORD dwAttrib = GetFileAttributes(szPath);
|
|
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
|
|
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
|
}
|
|
|
|
void LaunchGame(int argc, char **argv)
|
|
{
|
|
char *gamePath = "";
|
|
int startArg = 1;
|
|
if (argc > 1)
|
|
{
|
|
print("Checking if %s is a valid file\n", argv[1]);
|
|
if (FileExists(argv[1]))
|
|
{
|
|
print("Checking if %s is a valid executable\n", argv[1]);
|
|
DWORD dwBinaryType;
|
|
if (!GetBinaryType(argv[1], &dwBinaryType))
|
|
{
|
|
MessageBox(NULL, GetErrorMessage(),
|
|
"GetBinaryType",
|
|
MB_OK | MB_ICONSTOP);
|
|
ExitProcess(1);
|
|
}
|
|
print("Executable type: %d\n", dwBinaryType);
|
|
|
|
gamePath = argv[1];
|
|
startArg = 2;
|
|
}
|
|
else
|
|
{
|
|
MessageBox(NULL, "Invalid game path specified",
|
|
NULL, MB_OK | MB_ICONSTOP);
|
|
print("%s is not a valid file\n", argv[1]);
|
|
ExitProcess(1);
|
|
}
|
|
}
|
|
else if (argc == 1)
|
|
{
|
|
print("No game path specified. Idling...\n");
|
|
while (TRUE)
|
|
Sleep(1000);
|
|
}
|
|
else
|
|
{
|
|
MessageBox(NULL, "No game path specified",
|
|
NULL, MB_OK | MB_ICONSTOP);
|
|
ExitProcess(1);
|
|
}
|
|
|
|
STARTUPINFO game_si;
|
|
PROCESS_INFORMATION game_pi;
|
|
|
|
ZeroMemory(&game_si, sizeof(STARTUPINFO));
|
|
game_si.cb = sizeof(STARTUPINFO);
|
|
game_si.hStdOutput = INVALID_HANDLE_VALUE;
|
|
game_si.hStdError = INVALID_HANDLE_VALUE;
|
|
game_si.dwFlags |= STARTF_USESTDHANDLES;
|
|
|
|
char *gameArgs = LocalAlloc(LPTR, 512);
|
|
for (int i = startArg; i < argc; i++)
|
|
{
|
|
assert(strlen(gameArgs) + strlen(argv[i]) < 512);
|
|
gameArgs = strcat(gameArgs, argv[i]);
|
|
gameArgs = strcat(gameArgs, " ");
|
|
}
|
|
print("Launching \"%s\" with arguments \"%s\"\n", gamePath, gameArgs);
|
|
if (!CreateProcess(gamePath, gameArgs, NULL, NULL, FALSE,
|
|
0, NULL, NULL, &game_si, &game_pi))
|
|
{
|
|
MessageBox(NULL, GetErrorMessage(),
|
|
"CreateProcess", MB_OK | MB_ICONSTOP);
|
|
ExitProcess(1);
|
|
}
|
|
LocalFree(gameArgs);
|
|
DWORD parentID = game_pi.dwProcessId;
|
|
print("Waiting for PID %d to exit...\n", game_pi.dwProcessId);
|
|
WaitForSingleObject(game_pi.hProcess, INFINITE);
|
|
print("PID %d exited\n", game_pi.dwProcessId);
|
|
|
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
PROCESSENTRY32 pe32;
|
|
|
|
if (hSnapshot != INVALID_HANDLE_VALUE)
|
|
{
|
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
if (Process32First(hSnapshot, &pe32))
|
|
{
|
|
do
|
|
{
|
|
if (IsChildProcess(parentID, pe32.th32ProcessID))
|
|
{
|
|
WaitForSingleObject(OpenProcess(SYNCHRONIZE, FALSE,
|
|
pe32.th32ProcessID),
|
|
INFINITE);
|
|
print("Waiting for PID %d\n", pe32.th32ProcessID);
|
|
}
|
|
} while (Process32Next(hSnapshot, &pe32));
|
|
}
|
|
CloseHandle(hSnapshot);
|
|
}
|
|
else
|
|
{
|
|
MessageBox(NULL, GetErrorMessage(),
|
|
"CreateToolhelp32Snapshot", MB_OK | MB_ICONSTOP);
|
|
ExitProcess(0);
|
|
}
|
|
|
|
CloseHandle(game_pi.hProcess);
|
|
print("Game exited\n");
|
|
}
|