mirror of
https://github.com/ValveSoftware/Proton.git
synced 2025-06-13 05:37:48 +02:00
Add steam.exe winelib application that setups environment and launches the game.
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
This commit is contained in:

committed by
Andrew Eikum

parent
21760bf40a
commit
70822d8046
172
steam_helper/steam.cpp
Normal file
172
steam_helper/steam.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Valve Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This is a stub steam.exe implementation for use inside Proton. It provides
|
||||
* a small subset of the actual Steam functionality for games that expect
|
||||
* Windows version of Steam running. */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#pragma push_macro("_WIN32")
|
||||
#pragma push_macro("__cdecl")
|
||||
#undef _WIN32
|
||||
#undef __cdecl
|
||||
#include "steam_api.h"
|
||||
#pragma pop_macro("_WIN32")
|
||||
#pragma pop_macro("__cdecl")
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(steam);
|
||||
|
||||
EXTERN_C HANDLE CDECL __wine_make_process_system(void);
|
||||
|
||||
static void set_active_process_pid(void)
|
||||
{
|
||||
DWORD pid = GetCurrentProcessId();
|
||||
RegSetKeyValueA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", "pid", REG_DWORD, &pid, sizeof(pid));
|
||||
}
|
||||
|
||||
static DWORD WINAPI create_steam_window(void *arg)
|
||||
{
|
||||
static WNDCLASSEXW wndclass = { sizeof(WNDCLASSEXW) };
|
||||
static const WCHAR class_nameW[] = {'v','g','u','i','P','o','p','u','p','W','i','n','d','o','w',0};
|
||||
static const WCHAR steamW[] = {'S','t','e','a','m',0};
|
||||
MSG msg;
|
||||
|
||||
wndclass.lpfnWndProc = DefWindowProcW;
|
||||
wndclass.lpszClassName = class_nameW;
|
||||
|
||||
RegisterClassExW(&wndclass);
|
||||
CreateWindowW(class_nameW, steamW, WS_POPUP, 40, 40,
|
||||
400, 300, NULL, NULL, NULL, NULL);
|
||||
|
||||
while (GetMessageW(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_steam_registry(void)
|
||||
{
|
||||
const char *ui_lang;
|
||||
uint32 appid;
|
||||
char buf[256];
|
||||
HKEY key;
|
||||
LSTATUS status;
|
||||
|
||||
if (!SteamAPI_Init())
|
||||
{
|
||||
WINE_ERR("SteamAPI_Init failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ui_lang = SteamUtils()->GetSteamUILanguage();
|
||||
WINE_TRACE("UI language: %s\n", wine_dbgstr_a(ui_lang));
|
||||
RegSetKeyValueA(HKEY_CURRENT_USER, "Software\\Valve\\Steam", "language",
|
||||
REG_SZ, ui_lang, strlen(ui_lang) + 1);
|
||||
|
||||
appid = SteamUtils()->GetAppID();
|
||||
WINE_TRACE("appid: %u\n", appid);
|
||||
sprintf(buf, "Software\\Valve\\Steam\\Apps\\%u", appid);
|
||||
status = RegCreateKeyA(HKEY_CURRENT_USER, buf, &key);
|
||||
if (!status)
|
||||
{
|
||||
DWORD value;
|
||||
value = 1;
|
||||
RegSetKeyValueA(key, NULL, "Installed", REG_DWORD, &value, sizeof(value));
|
||||
RegSetKeyValueA(key, NULL, "Running", REG_DWORD, &value, sizeof(value));
|
||||
value = 0;
|
||||
RegSetKeyValueA(key, NULL, "Updating", REG_DWORD, &value, sizeof(value));
|
||||
RegCloseKey(key);
|
||||
}
|
||||
else WINE_ERR("Could not create key: %u\n", status);
|
||||
|
||||
SteamAPI_Shutdown();
|
||||
}
|
||||
|
||||
static int run_process(void)
|
||||
{
|
||||
WCHAR *cmdline = GetCommandLineW();
|
||||
STARTUPINFOW si = { sizeof(si) };
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
/* skip argv[0] */
|
||||
if (*cmdline == '"')
|
||||
{
|
||||
cmdline = strchrW(cmdline + 1, '"');
|
||||
if (cmdline) cmdline++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdline = strchrW(cmdline, ' ');
|
||||
}
|
||||
if (!cmdline)
|
||||
{
|
||||
WINE_ERR("Invalid command\n");
|
||||
return 1;
|
||||
}
|
||||
while (*cmdline == ' ') cmdline++;
|
||||
|
||||
WINE_TRACE("Running command %s\n", wine_dbgstr_w(cmdline));
|
||||
|
||||
if (!CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
||||
{
|
||||
WINE_ERR("Failed to create process %s: %u\n", wine_dbgstr_w(cmdline), GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
WINE_TRACE("\n");
|
||||
|
||||
CreateThread(NULL, 0, create_steam_window, NULL, 0, NULL);
|
||||
|
||||
set_active_process_pid();
|
||||
setup_steam_registry();
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
int ret = run_process();
|
||||
if (ret) return ret;
|
||||
}
|
||||
|
||||
WaitForSingleObject(__wine_make_process_system(), INFINITE);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user