Skip to content

Commit

Permalink
battleye: Add support for -exe command line argument.
Browse files Browse the repository at this point in the history
Games can use this argument to override executable entries from BELauncher.ini.
  • Loading branch information
mundak committed Apr 27, 2022
1 parent df982e6 commit a7c00df
Showing 1 changed file with 46 additions and 9 deletions.
55 changes: 46 additions & 9 deletions programs/belauncher/main.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <wchar.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

Expand All @@ -7,16 +8,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(belauncher);

int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cmdshow)
{
char *configs, *config, *arch_32_exe = NULL, *arch_64_exe = NULL, *game_exe, *be_arg = NULL;
char *configs, *config, *arch_32_exe = NULL, *arch_64_exe = NULL, *game_exe, *be_arg = NULL, *arg_exe = NULL;
LARGE_INTEGER launcher_cfg_size;
unsigned char battleye_status;
int game_exe_len, arg_len;
int game_exe_len, arg_len, exe_arg_len;
PROCESS_INFORMATION pi;
HANDLE launcher_cfg;
LPWSTR launch_cmd;
LPWSTR launch_cmd, game_cmd, cmd_exe_arg = NULL, cmd_exe_arg_end;
STARTUPINFOW si = {0};
DWORD size;
BOOL wow64;
BOOL wow64, exe_arg_uses_quotation;

battleye_status = 0x3; /* Starting */
_write(1, &battleye_status, 1);
Expand Down Expand Up @@ -56,7 +57,37 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cm
}
while ((config = strchr(config, '\n')) && *(config++));

if (arch_64_exe && (sizeof(void *) == 8 || (IsWow64Process(GetCurrentProcess(), &wow64) && wow64)))
game_cmd = cmdline;

/* Check if -exe argument was passed, which will override .ini entry */
cmd_exe_arg = wcsstr(cmdline, L"-exe ");
if (cmd_exe_arg)
{
if (wcslen(cmd_exe_arg) < 6)
goto no_exe_arg;
exe_arg_uses_quotation = cmd_exe_arg[5] == '\"';
cmd_exe_arg_end = wcschr(&cmd_exe_arg[6], exe_arg_uses_quotation ? L'\"' : L' ');
if (!cmd_exe_arg_end)
goto no_exe_arg;

/* Extract the game executable */
exe_arg_len = cmd_exe_arg_end - cmd_exe_arg - 6;
arg_exe = HeapAlloc(GetProcessHeap(), 0, exe_arg_len + 1);
WideCharToMultiByte(CP_ACP, 0, cmd_exe_arg + 6, exe_arg_len, arg_exe, exe_arg_len, NULL, NULL);
arg_exe[exe_arg_len] = L'\0';

/* Rebuild the command line to skip -exe argument */
game_cmd = HeapAlloc(GetProcessHeap(), 0, (wcslen(cmdline) - exe_arg_len + 1) * sizeof(WCHAR));
lstrcpynW(game_cmd, cmdline, cmd_exe_arg - cmdline);
game_cmd[cmd_exe_arg - cmdline] = L' ';
wcscpy(&game_cmd[cmd_exe_arg - cmdline + 1], cmd_exe_arg_end);
}
no_exe_arg:

/* Replace the game executable */
if (arg_exe)
game_exe = arg_exe;
else if (arch_64_exe && (sizeof(void *) == 8 || (IsWow64Process(GetCurrentProcess(), &wow64) && wow64)))
game_exe = arch_64_exe;
else if (arch_32_exe)
game_exe = arch_32_exe;
Expand Down Expand Up @@ -87,14 +118,14 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cm
battleye_status = 0x9; /* Launching Game */
_write(1, &battleye_status, 1);

launch_cmd = HeapAlloc(GetProcessHeap(), 0, (game_exe_len + 1 + wcslen(cmdline) + 1 + arg_len + 1) * sizeof(WCHAR));
launch_cmd = HeapAlloc(GetProcessHeap(), 0, (game_exe_len + 1 + wcslen(game_cmd) + 1 + arg_len + 1) * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, game_exe, -1, launch_cmd, game_exe_len + 1);
launch_cmd[game_exe_len] = ' ';

wcscpy(launch_cmd + game_exe_len + 1, cmdline);
launch_cmd[game_exe_len + 1 + wcslen(cmdline)] = ' ';
wcscpy(launch_cmd + game_exe_len + 1, game_cmd);
launch_cmd[game_exe_len + 1 + wcslen(game_cmd)] = ' ';

MultiByteToWideChar(CP_ACP, 0, be_arg, -1, launch_cmd + game_exe_len + 1 + wcslen(cmdline) + 1, arg_len + 1);
MultiByteToWideChar(CP_ACP, 0, be_arg, -1, launch_cmd + game_exe_len + 1 + wcslen(game_cmd) + 1, arg_len + 1);

if (!CreateProcessW(NULL, launch_cmd, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
Expand All @@ -106,6 +137,12 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cm
}
HeapFree( GetProcessHeap(), 0, launch_cmd );

if (arg_exe)
{
HeapFree( GetProcessHeap(), 0, arg_exe );
HeapFree( GetProcessHeap(), 0, game_cmd );
}

WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
return 0;
Expand Down

0 comments on commit a7c00df

Please sign in to comment.