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:
Billy Laws 2025-01-09 22:22:24 +00:00 committed by Arkadiusz Hiler
parent e91fadea51
commit 6c13702ab3
9 changed files with 72 additions and 0 deletions

View File

@ -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',

View File

@ -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, &params ) || (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;

View File

@ -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 );

View File

@ -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 */

View File

@ -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 * );

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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,