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.exe.

Change-Id: I53bed6c1591d77d5a382d50dfc692bfc90321846
  • Loading branch information
mundak committed Apr 29, 2022
1 parent df982e6 commit e16d580
Showing 1 changed file with 66 additions and 9 deletions.
75 changes: 66 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,23 +8,28 @@ 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;
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;
DWORD size, exe_arg_len;
BOOL wow64;

battleye_status = 0x3; /* Starting */
_write(1, &battleye_status, 1);

WINE_TRACE("Started BELauncher with parameters: %s\n", debugstr_w(cmdline));

launcher_cfg = CreateFileW(L"Battleye\\BELauncher.ini", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (launcher_cfg == INVALID_HANDLE_VALUE)
{
WINE_WARN("Failed to open Battleye\\BELauncher.ini file\n");
goto start_failed;
}

if(!GetFileSizeEx(launcher_cfg, &launcher_cfg_size) || launcher_cfg_size.u.HighPart)
{
Expand Down Expand Up @@ -56,7 +62,51 @@ 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 && wcslen(cmd_exe_arg) >= 6)
{
cmd_exe_arg += 5;
if (cmd_exe_arg[1] == L'\"')
{
cmd_exe_arg_end = wcschr(&cmd_exe_arg[2], L'\"');
if (cmd_exe_arg_end)
{
// Include closing '\"'
cmd_exe_arg_end++;
}
}
else
{
cmd_exe_arg_end = wcschr(cmd_exe_arg, ' ');
}

if (!cmd_exe_arg_end)
{
// This means -exe was the last argument
cmd_exe_arg_end = cmd_exe_arg + wcslen(cmd_exe_arg);
}

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

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

/* 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 All @@ -83,18 +133,19 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cm
arg_len = MultiByteToWideChar(CP_ACP, 0, be_arg, -1, NULL, 0) - 1;
}

WINE_TRACE("Launching game executable %s for BattlEye.\n", game_exe);
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);

WINE_TRACE("Launching game executable for BattlEye: %s\n", debugstr_w(launch_cmd));

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

if (game_cmd != cmdline)
HeapFree( GetProcessHeap(), 0, game_cmd );
if (arg_exe)
HeapFree( GetProcessHeap(), 0, arg_exe );

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

start_failed:
WINE_WARN("Failed to launch the game using BELauncher\n");
battleye_status = 0x4; /* Start Failed */
_write(1, &battleye_status, 1);
return 0;
Expand Down

0 comments on commit e16d580

Please sign in to comment.