mirror of
https://github.com/ValveSoftware/Proton.git
synced 2025-07-23 05:31:48 +03:00
lsteamclient: Introduce unix-side buffer cache with PE allocate pointers.
There are several steam API calls that currently pass unix pointers for e.g. strings directly to the PE-side, this allows for caching such return values and returning a PE-side pointer instead.
This commit is contained in:
parent
e91fadea51
commit
6c13702ab3
@ -211,6 +211,7 @@ UNIX_FUNCS = [
|
||||
'steamclient_init',
|
||||
'steamclient_init_registry',
|
||||
'steamclient_next_callback',
|
||||
'steamclient_get_unix_buffer',
|
||||
'steamclient_CreateInterface',
|
||||
'steamclient_Steam_GetAPICallResult',
|
||||
'steamclient_Steam_BGetCallback',
|
||||
|
@ -325,6 +325,24 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *get_unix_buffer( struct u_buffer buf )
|
||||
{
|
||||
struct steamclient_get_unix_buffer_params params = {.buf = buf};
|
||||
void *ret;
|
||||
|
||||
if ((UINT_PTR)buf.ptr == buf.ptr && (UINT_PTR)(buf.ptr + buf.len) == (buf.ptr + buf.len))
|
||||
return (void *)(UINT_PTR)buf.ptr;
|
||||
|
||||
if (!(params.ptr = ret = HeapAlloc( GetProcessHeap(), 0, buf.len ))) return NULL;
|
||||
if (STEAMCLIENT_CALL( steamclient_get_unix_buffer, ¶ms ) || (ret != params.ptr))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, ret );
|
||||
ret = params.ptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL get_env_win(const WCHAR *name, char *value, unsigned int size)
|
||||
{
|
||||
DWORD i, env_size;
|
||||
|
@ -46,6 +46,7 @@ extern void execute_pending_callbacks(void);
|
||||
struct w_iface *create_win_interface( const char *name, struct u_iface );
|
||||
void *alloc_mem_for_iface(size_t size, const char *iface_version);
|
||||
void *alloc_vtable(void *vtable, unsigned int method_count, const char *iface_version);
|
||||
void *get_unix_buffer( struct u_buffer buf );
|
||||
|
||||
void init_rtti( char *base );
|
||||
|
||||
|
@ -67,4 +67,14 @@ struct u_iface
|
||||
#endif /* __cplusplus */
|
||||
};
|
||||
|
||||
struct u_buffer
|
||||
{
|
||||
UINT64 ptr;
|
||||
UINT64 len;
|
||||
#ifdef __cplusplus
|
||||
struct u_buffer &operator=(const char* value) { this->ptr = (UINT_PTR)value; this->len = value ? strlen( value ) + 1 : 0; return *this; }
|
||||
operator char*() const { return (char*)(UINT_PTR)this->ptr; }
|
||||
#endif /* __cplusplus */
|
||||
};
|
||||
|
||||
#endif /* __STEAMCLIENT_STRUCTS_H */
|
||||
|
@ -74,6 +74,7 @@ void convert_callback_utow( int id, void *u_callback, int u_callback_len, void *
|
||||
extern NTSTATUS steamclient_init( void * );
|
||||
extern NTSTATUS steamclient_init_registry( void * );
|
||||
extern NTSTATUS steamclient_next_callback( void * );
|
||||
extern NTSTATUS steamclient_get_unix_buffer( void * );
|
||||
extern NTSTATUS steamclient_CreateInterface( void * );
|
||||
extern NTSTATUS steamclient_Steam_GetAPICallResult( void * );
|
||||
extern NTSTATUS steamclient_Steam_BGetCallback( void * );
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#if 0
|
||||
#pragma makedep unix
|
||||
@ -683,6 +684,38 @@ NTSTATUS steamclient_init( void *args )
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<> struct hash< struct u_buffer >
|
||||
{
|
||||
using argument_type = struct u_buffer;
|
||||
using result_type = std::size_t;
|
||||
result_type operator()( argument_type const& buf ) const { return buf.ptr; }
|
||||
};
|
||||
}
|
||||
|
||||
static pthread_mutex_t buffer_cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static std::unordered_map< struct u_buffer, void * > buffer_cache;
|
||||
|
||||
NTSTATUS steamclient_get_unix_buffer( void *args )
|
||||
{
|
||||
struct steamclient_get_unix_buffer_params *params = (struct steamclient_get_unix_buffer_params *)args;
|
||||
struct cache_entry *entry;
|
||||
struct rb_entry *ptr;
|
||||
|
||||
pthread_mutex_lock( &buffer_cache_lock );
|
||||
auto iter = buffer_cache.find( params->buf );
|
||||
if (iter != buffer_cache.end()) params->ptr = iter->second;
|
||||
else
|
||||
{
|
||||
memcpy( params->ptr, (char *)params->buf, params->buf.len );
|
||||
buffer_cache[params->buf] = params->ptr;
|
||||
}
|
||||
pthread_mutex_unlock( &buffer_cache_lock );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTSTATUS steamclient_CreateInterface( void *args )
|
||||
{
|
||||
struct steamclient_CreateInterface_params *params = (struct steamclient_CreateInterface_params *)args;
|
||||
|
@ -32,6 +32,12 @@ struct steamclient_init_params
|
||||
int8_t ignore_child_processes_unset;
|
||||
};
|
||||
|
||||
struct steamclient_get_unix_buffer_params
|
||||
{
|
||||
struct u_buffer buf;
|
||||
void *ptr; /* client-side ptr */
|
||||
};
|
||||
|
||||
enum callback_type
|
||||
{
|
||||
SOCKETS_DEBUG_OUTPUT = 1,
|
||||
|
@ -11,6 +11,7 @@ extern "C" const unixlib_entry_t __wine_unix_call_funcs[] =
|
||||
steamclient_init,
|
||||
steamclient_init_registry,
|
||||
steamclient_next_callback,
|
||||
steamclient_get_unix_buffer,
|
||||
steamclient_CreateInterface,
|
||||
steamclient_Steam_GetAPICallResult,
|
||||
steamclient_Steam_BGetCallback,
|
||||
|
@ -48759,6 +48759,7 @@ enum unix_funcs
|
||||
unix_steamclient_init,
|
||||
unix_steamclient_init_registry,
|
||||
unix_steamclient_next_callback,
|
||||
unix_steamclient_get_unix_buffer,
|
||||
unix_steamclient_CreateInterface,
|
||||
unix_steamclient_Steam_GetAPICallResult,
|
||||
unix_steamclient_Steam_BGetCallback,
|
||||
|
Loading…
x
Reference in New Issue
Block a user