mirror of
https://github.com/ValveSoftware/Proton.git
synced 2024-12-29 16:15:52 +03:00
lsteamclient: Move unix library loading to the unix side.
CW-Bug-Id: #22729
This commit is contained in:
parent
4823be943d
commit
e0b2b50fb1
@ -5,9 +5,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#define __USE_GNU
|
|
||||||
#include <dlfcn.h>
|
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
@ -45,33 +42,6 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sync_environment(void)
|
|
||||||
{
|
|
||||||
static const char *steamapi_envs[] =
|
|
||||||
{
|
|
||||||
"SteamAppId",
|
|
||||||
"IgnoreChildProcesses",
|
|
||||||
};
|
|
||||||
|
|
||||||
char value[32767];
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ARRAY_SIZE(steamapi_envs); i++)
|
|
||||||
{
|
|
||||||
if (!GetEnvironmentVariableA(steamapi_envs[i], value, ARRAY_SIZE(value)))
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
|
||||||
{
|
|
||||||
TRACE("unsetenv(\"%s\")\n", steamapi_envs[i]);
|
|
||||||
unsetenv(steamapi_envs[i]);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("setenv(\"%s\", \"%s\", 1)\n", steamapi_envs[i], value);
|
|
||||||
setenv(steamapi_envs[i], value, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns:
|
/* Returns:
|
||||||
* - if successful, the number of bytes written to dst, including the NULL terminator;
|
* - if successful, the number of bytes written to dst, including the NULL terminator;
|
||||||
* - 0 if failed;
|
* - 0 if failed;
|
||||||
@ -676,101 +646,30 @@ done:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *steamclient_lib;
|
|
||||||
static void *(*steamclient_CreateInterface)(const char *name, int *return_code);
|
|
||||||
bool (*steamclient_BGetCallback)( int32_t a, u_CallbackMsg_t *b, int32_t *c );
|
|
||||||
bool (*steamclient_GetAPICallResult)( int32_t, uint64_t, void *, int, int, bool * );
|
|
||||||
bool (*steamclient_FreeLastCallback)( int32_t );
|
|
||||||
static void (*steamclient_ReleaseThreadLocalMemory)(int);
|
|
||||||
static bool (*steamclient_IsKnownInterface)( const char *pchVersion );
|
|
||||||
static void (*steamclient_NotifyMissingInterface)( int32_t hSteamPipe, const char *pchVersion );
|
|
||||||
|
|
||||||
static int load_steamclient(void)
|
static int load_steamclient(void)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX], resolved_path[PATH_MAX];
|
char steam_app_id[4096], ignore_child_processes[4096];
|
||||||
|
struct steamclient_init_params params = {0};
|
||||||
|
|
||||||
if(steamclient_lib)
|
if (!GetEnvironmentVariableA("SteamAppId", steam_app_id, ARRAY_SIZE(steam_app_id)))
|
||||||
return 1;
|
params.steam_app_id_unset = GetLastError() == ERROR_ENVVAR_NOT_FOUND;
|
||||||
|
else
|
||||||
|
params.steam_app_id = steam_app_id;
|
||||||
|
|
||||||
sync_environment();
|
if (!GetEnvironmentVariableA("IgnoreChildProcesses", ignore_child_processes, ARRAY_SIZE(ignore_child_processes)))
|
||||||
|
params.ignore_child_processes_unset = GetLastError() == ERROR_ENVVAR_NOT_FOUND;
|
||||||
#ifdef __APPLE__
|
else
|
||||||
if(getenv("STEAM_COMPAT_CLIENT_INSTALL_PATH")){
|
params.ignore_child_processes = ignore_child_processes;
|
||||||
snprintf(path, PATH_MAX, "%s/steamclient.dylib", getenv("STEAM_COMPAT_CLIENT_INSTALL_PATH"));
|
|
||||||
}else{
|
|
||||||
WARN("Old Steam client, falling back to DYLD environment to locate native steamclient library\n");
|
|
||||||
strcpy(path, "steamclient.dylib");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#ifdef _WIN64
|
|
||||||
snprintf(path, PATH_MAX, "%s/.steam/sdk64/steamclient.so", getenv("HOME"));
|
|
||||||
#else
|
|
||||||
snprintf(path, PATH_MAX, "%s/.steam/sdk32/steamclient.so", getenv("HOME"));
|
|
||||||
#endif
|
|
||||||
if (realpath(path, resolved_path)){
|
|
||||||
lstrcpynA(path, resolved_path, PATH_MAX);
|
|
||||||
path[PATH_MAX - 1] = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
steamclient_lib = dlopen(path, RTLD_NOW);
|
|
||||||
if(!steamclient_lib){
|
|
||||||
ERR("unable to load native steamclient library\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
steamclient_CreateInterface = dlsym(steamclient_lib, "CreateInterface");
|
|
||||||
if(!steamclient_CreateInterface){
|
|
||||||
ERR("unable to load CreateInterface method\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
steamclient_BGetCallback = dlsym(steamclient_lib, "Steam_BGetCallback");
|
|
||||||
if(!steamclient_BGetCallback){
|
|
||||||
ERR("unable to load BGetCallback method\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
steamclient_GetAPICallResult = dlsym(steamclient_lib, "Steam_GetAPICallResult");
|
|
||||||
if(!steamclient_GetAPICallResult){
|
|
||||||
ERR("unable to load GetAPICallResult method\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
steamclient_FreeLastCallback = dlsym(steamclient_lib, "Steam_FreeLastCallback");
|
|
||||||
if(!steamclient_FreeLastCallback){
|
|
||||||
ERR("unable to load FreeLastCallback method\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
steamclient_ReleaseThreadLocalMemory = dlsym(steamclient_lib, "Steam_ReleaseThreadLocalMemory");
|
|
||||||
if(!steamclient_ReleaseThreadLocalMemory){
|
|
||||||
ERR("unable to load ReleaseThreadLocalMemory method\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
steamclient_IsKnownInterface = dlsym(steamclient_lib, "Steam_IsKnownInterface");
|
|
||||||
if(!steamclient_IsKnownInterface){
|
|
||||||
ERR("unable to load IsKnownInterface method\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
steamclient_NotifyMissingInterface = dlsym(steamclient_lib, "Steam_NotifyMissingInterface");
|
|
||||||
if(!steamclient_NotifyMissingInterface){
|
|
||||||
ERR("unable to load NotifyMissingInterface method\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!unix_steamclient_init( ¶ms )) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *CDECL CreateInterface(const char *name, int *return_code)
|
void *CDECL CreateInterface(const char *name, int *return_code)
|
||||||
{
|
{
|
||||||
TRACE("name: %s, return_code: %p\n", name, return_code);
|
TRACE("name: %s, return_code: %p\n", name, return_code);
|
||||||
|
if (!load_steamclient()) return NULL;
|
||||||
if(!load_steamclient())
|
return create_win_interface( name, unix_CreateInterface( name, return_code ) );
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return create_win_interface(name, steamclient_CreateInterface(name, return_code));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void execute_pending_callbacks(void)
|
static void execute_pending_callbacks(void)
|
||||||
@ -821,8 +720,7 @@ bool CDECL Steam_BGetCallback( int32_t pipe, w_CallbackMsg_t *win_msg, int32_t *
|
|||||||
|
|
||||||
TRACE("%u, %p, %p\n", pipe, win_msg, ignored);
|
TRACE("%u, %p, %p\n", pipe, win_msg, ignored);
|
||||||
|
|
||||||
if(!load_steamclient())
|
if (!load_steamclient()) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
execute_pending_callbacks();
|
execute_pending_callbacks();
|
||||||
|
|
||||||
@ -867,7 +765,6 @@ bool CDECL Steam_GetAPICallResult( int32_t pipe, uint64_t call, void *w_callback
|
|||||||
TRACE( "%u, x, %p, %u, %u, %p\n", pipe, w_callback, w_callback_len, id, failed );
|
TRACE( "%u, x, %p, %u, %u, %p\n", pipe, w_callback, w_callback_len, id, failed );
|
||||||
|
|
||||||
if (!load_steamclient()) return FALSE;
|
if (!load_steamclient()) return FALSE;
|
||||||
|
|
||||||
return unix_Steam_GetAPICallResult( pipe, call, w_callback, w_callback_len, id, failed );
|
return unix_Steam_GetAPICallResult( pipe, call, w_callback, w_callback_len, id, failed );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,10 +772,8 @@ void CDECL Steam_ReleaseThreadLocalMemory(int bThreadExit)
|
|||||||
{
|
{
|
||||||
TRACE("%d\n", bThreadExit);
|
TRACE("%d\n", bThreadExit);
|
||||||
|
|
||||||
if(!load_steamclient())
|
if (!load_steamclient()) return;
|
||||||
return;
|
unix_Steam_ReleaseThreadLocalMemory( bThreadExit );
|
||||||
|
|
||||||
steamclient_ReleaseThreadLocalMemory(bThreadExit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDECL Breakpad_SteamMiniDumpInit( uint32_t a, const char *b, const char *c )
|
void CDECL Breakpad_SteamMiniDumpInit( uint32_t a, const char *b, const char *c )
|
||||||
@ -912,12 +807,12 @@ bool CDECL Steam_IsKnownInterface( const char *pchVersion )
|
|||||||
{
|
{
|
||||||
TRACE("%s\n", pchVersion);
|
TRACE("%s\n", pchVersion);
|
||||||
load_steamclient();
|
load_steamclient();
|
||||||
return steamclient_IsKnownInterface( pchVersion );
|
return unix_Steam_IsKnownInterface( pchVersion );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDECL Steam_NotifyMissingInterface( int32_t hSteamPipe, const char *pchVersion )
|
void CDECL Steam_NotifyMissingInterface( int32_t hSteamPipe, const char *pchVersion )
|
||||||
{
|
{
|
||||||
TRACE("%u %s\n", hSteamPipe, pchVersion);
|
TRACE("%u %s\n", hSteamPipe, pchVersion);
|
||||||
load_steamclient();
|
load_steamclient();
|
||||||
steamclient_NotifyMissingInterface( hSteamPipe, pchVersion );
|
unix_Steam_NotifyMissingInterface( hSteamPipe, pchVersion );
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(steamclient);
|
WINE_DEFAULT_DEBUG_CHANNEL(steamclient);
|
||||||
|
|
||||||
@ -79,9 +80,17 @@ bool unix_steamclient_next_callback( struct callback *callback, uint32_t *size )
|
|||||||
return !!ptr;
|
return !!ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *(*p_CreateInterface)( const char *name, int *return_code );
|
||||||
|
static bool (*p_Steam_BGetCallback)( int32_t a, u_CallbackMsg_t *b, int32_t *c );
|
||||||
|
static bool (*p_Steam_GetAPICallResult)( int32_t, uint64_t, void *, int, int, bool * );
|
||||||
|
static bool (*p_Steam_FreeLastCallback)( int32_t );
|
||||||
|
static void (*p_Steam_ReleaseThreadLocalMemory)( int );
|
||||||
|
static bool (*p_Steam_IsKnownInterface)( const char * );
|
||||||
|
static void (*p_Steam_NotifyMissingInterface)( int32_t, const char * );
|
||||||
|
|
||||||
bool unix_Steam_BGetCallback( uint32_t pipe, w_CallbackMsg_t *w_msg, int32_t *ignored, u_CallbackMsg_t *u_msg )
|
bool unix_Steam_BGetCallback( uint32_t pipe, w_CallbackMsg_t *w_msg, int32_t *ignored, u_CallbackMsg_t *u_msg )
|
||||||
{
|
{
|
||||||
if (!steamclient_BGetCallback( pipe, u_msg, ignored )) return false;
|
if (!p_Steam_BGetCallback( pipe, u_msg, ignored )) return false;
|
||||||
callback_message_utow( u_msg, w_msg );
|
callback_message_utow( u_msg, w_msg );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -94,7 +103,7 @@ void unix_callback_message_receive( u_CallbackMsg_t *u_msg, w_CallbackMsg_t *w_m
|
|||||||
|
|
||||||
bool unix_Steam_FreeLastCallback( uint32_t pipe )
|
bool unix_Steam_FreeLastCallback( uint32_t pipe )
|
||||||
{
|
{
|
||||||
return steamclient_FreeLastCallback( pipe );
|
return p_Steam_FreeLastCallback( pipe );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unix_Steam_GetAPICallResult( int32_t pipe, uint64_t call, void *w_callback, int w_callback_len,
|
bool unix_Steam_GetAPICallResult( int32_t pipe, uint64_t call, void *w_callback, int w_callback_len,
|
||||||
@ -106,7 +115,7 @@ bool unix_Steam_GetAPICallResult( int32_t pipe, uint64_t call, void *w_callback,
|
|||||||
|
|
||||||
if (!(u_callback = alloc_callback_wtou( id, w_callback, &u_callback_len ))) return false;
|
if (!(u_callback = alloc_callback_wtou( id, w_callback, &u_callback_len ))) return false;
|
||||||
|
|
||||||
ret = steamclient_GetAPICallResult( pipe, call, u_callback, u_callback_len, id, failed );
|
ret = p_Steam_GetAPICallResult( pipe, call, u_callback, u_callback_len, id, failed );
|
||||||
|
|
||||||
if (ret && u_callback != w_callback)
|
if (ret && u_callback != w_callback)
|
||||||
{
|
{
|
||||||
@ -116,3 +125,81 @@ bool unix_Steam_GetAPICallResult( int32_t pipe, uint64_t call, void *w_callback,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool unix_steamclient_init( struct steamclient_init_params *params )
|
||||||
|
{
|
||||||
|
char path[PATH_MAX], resolved_path[PATH_MAX];
|
||||||
|
static void *steamclient;
|
||||||
|
|
||||||
|
if (params->steam_app_id_unset) unsetenv( "SteamAppId" );
|
||||||
|
else if (params->steam_app_id) setenv( "SteamAppId", params->steam_app_id, TRUE );
|
||||||
|
if (params->ignore_child_processes_unset) unsetenv( "IgnoreChildProcesses" );
|
||||||
|
else if (params->ignore_child_processes) setenv( "IgnoreChildProcesses", params->ignore_child_processes, TRUE );
|
||||||
|
|
||||||
|
if (steamclient) return true;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (getenv( "STEAM_COMPAT_CLIENT_INSTALL_PATH" ))
|
||||||
|
snprintf( path, PATH_MAX, "%s/steamclient.dylib", getenv( "STEAM_COMPAT_CLIENT_INSTALL_PATH" ) );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN( "Old Steam client, falling back to DYLD environment to locate native steamclient "
|
||||||
|
"library\n" );
|
||||||
|
strcpy( path, "steamclient.dylib" );
|
||||||
|
}
|
||||||
|
#else /* __APPLE__ */
|
||||||
|
#ifdef __x86_64__
|
||||||
|
snprintf( path, PATH_MAX, "%s/.steam/sdk64/steamclient.so", getenv( "HOME" ) );
|
||||||
|
#else
|
||||||
|
snprintf( path, PATH_MAX, "%s/.steam/sdk32/steamclient.so", getenv( "HOME" ) );
|
||||||
|
#endif
|
||||||
|
if (realpath( path, resolved_path ))
|
||||||
|
{
|
||||||
|
strcpy( path, resolved_path );
|
||||||
|
path[PATH_MAX - 1] = 0;
|
||||||
|
}
|
||||||
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
|
if (!(steamclient = dlopen( path, RTLD_NOW )))
|
||||||
|
{
|
||||||
|
ERR( "unable to load native steamclient library\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOAD_FUNC( x ) \
|
||||||
|
if (!(p_##x = (decltype(p_##x))dlsym( steamclient, #x ))) \
|
||||||
|
{ \
|
||||||
|
ERR( "unable to load " #x "\n" ); \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
|
LOAD_FUNC( CreateInterface );
|
||||||
|
LOAD_FUNC( Steam_BGetCallback );
|
||||||
|
LOAD_FUNC( Steam_GetAPICallResult );
|
||||||
|
LOAD_FUNC( Steam_FreeLastCallback );
|
||||||
|
LOAD_FUNC( Steam_ReleaseThreadLocalMemory );
|
||||||
|
LOAD_FUNC( Steam_IsKnownInterface );
|
||||||
|
LOAD_FUNC( Steam_NotifyMissingInterface );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *unix_CreateInterface( const char *name, int *return_code )
|
||||||
|
{
|
||||||
|
return p_CreateInterface( name, return_code );
|
||||||
|
}
|
||||||
|
|
||||||
|
void unix_Steam_ReleaseThreadLocalMemory( int thread_exit )
|
||||||
|
{
|
||||||
|
p_Steam_ReleaseThreadLocalMemory( thread_exit );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unix_Steam_IsKnownInterface( const char *version )
|
||||||
|
{
|
||||||
|
return p_Steam_IsKnownInterface( version );
|
||||||
|
}
|
||||||
|
|
||||||
|
void unix_Steam_NotifyMissingInterface( int32_t pipe, const char *version )
|
||||||
|
{
|
||||||
|
p_Steam_NotifyMissingInterface( pipe, version );
|
||||||
|
}
|
||||||
|
@ -27,6 +27,14 @@ extern void steamclient_free_path_array( const char **path_array );
|
|||||||
#define PATH_MAX 4096
|
#define PATH_MAX 4096
|
||||||
extern char g_tmppath[PATH_MAX];
|
extern char g_tmppath[PATH_MAX];
|
||||||
|
|
||||||
|
struct steamclient_init_params
|
||||||
|
{
|
||||||
|
const char *steam_app_id;
|
||||||
|
bool steam_app_id_unset;
|
||||||
|
const char *ignore_child_processes;
|
||||||
|
bool ignore_child_processes_unset;
|
||||||
|
};
|
||||||
|
|
||||||
enum callback_type
|
enum callback_type
|
||||||
{
|
{
|
||||||
SOCKETS_DEBUG_OUTPUT = 1,
|
SOCKETS_DEBUG_OUTPUT = 1,
|
||||||
@ -56,18 +64,17 @@ struct callback
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern bool unix_steamclient_init( struct steamclient_init_params *params );
|
||||||
extern bool unix_steamclient_next_callback( struct callback *callback, uint32_t *length );
|
extern bool unix_steamclient_next_callback( struct callback *callback, uint32_t *length );
|
||||||
|
extern void *unix_CreateInterface( const char *name, int *return_code );
|
||||||
extern bool (*steamclient_GetAPICallResult)( int32_t, uint64_t, void *, int, int, bool * );
|
|
||||||
extern bool unix_Steam_GetAPICallResult( int32_t pipe, uint64_t call, void *w_callback,
|
extern bool unix_Steam_GetAPICallResult( int32_t pipe, uint64_t call, void *w_callback,
|
||||||
int w_callback_len, int id, bool *failed );
|
int w_callback_len, int id, bool *failed );
|
||||||
|
|
||||||
extern bool (*steamclient_BGetCallback)( int32_t a, u_CallbackMsg_t *b, int32_t *c );
|
|
||||||
extern bool unix_Steam_BGetCallback( uint32_t pipe, w_CallbackMsg_t *w_msg, int32_t *ignored, u_CallbackMsg_t *u_msg );
|
extern bool unix_Steam_BGetCallback( uint32_t pipe, w_CallbackMsg_t *w_msg, int32_t *ignored, u_CallbackMsg_t *u_msg );
|
||||||
extern void unix_callback_message_receive( u_CallbackMsg_t *u_msg, w_CallbackMsg_t *w_msg );
|
extern void unix_callback_message_receive( u_CallbackMsg_t *u_msg, w_CallbackMsg_t *w_msg );
|
||||||
|
|
||||||
extern bool (*steamclient_FreeLastCallback)( int32_t );
|
|
||||||
extern bool unix_Steam_FreeLastCallback( uint32_t pipe );
|
extern bool unix_Steam_FreeLastCallback( uint32_t pipe );
|
||||||
|
extern void unix_Steam_ReleaseThreadLocalMemory( int thread_exit );
|
||||||
|
extern bool unix_Steam_IsKnownInterface( const char *version );
|
||||||
|
extern void unix_Steam_NotifyMissingInterface( int32_t pipe, const char *version );
|
||||||
|
|
||||||
struct networking_message_pool;
|
struct networking_message_pool;
|
||||||
struct networking_message
|
struct networking_message
|
||||||
|
Loading…
Reference in New Issue
Block a user