lsteamclient: Handle calls to SteamNetworkingMessage_t.m_pfnFreeData from native threads.

CW-Bug-Id: #22649
This commit is contained in:
Paul Gofman 2023-08-23 20:06:09 -06:00 committed by Arkadiusz Hiler
parent a798b8308f
commit 8a109013b4
3 changed files with 70 additions and 5 deletions

View file

@ -1,12 +1,14 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <limits.h>
#include <stdint.h>
#include <pthread.h>
#include <assert.h>
#define __USE_GNU
#include <dlfcn.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
@ -42,6 +44,37 @@ static pthread_cond_t callback_queue_callback_event;
static pthread_cond_t callback_queue_ready_event;
static pthread_cond_t callback_queue_complete_event;
static void * (WINAPI *p_NtCurrentTeb)(void);
static void init_ntdll_so_funcs(void)
{
Dl_info info;
UINT64 unix_funcs;
unsigned int status;
void *ntdll;
status = NtQueryVirtualMemory(GetCurrentProcess(), GetModuleHandleW(L"ntdll.dll"), (MEMORY_INFORMATION_CLASS)1000 /*MemoryWineUnixFuncs*/,
&unix_funcs, sizeof(unix_funcs), NULL);
if (status)
{
fprintf(stderr, "err:lsteamclient:init_ntdll_so_funcs NtQueryVirtualMemory status %#x.\n", status);
return;
}
if (!dladdr((void *)(ULONG_PTR)unix_funcs, &info))
{
fprintf(stderr, "err:lsteamclient:init_ntdll_so_funcs dladdr failed.\n");
return;
}
ntdll = dlopen(info.dli_fname, RTLD_NOW);
if (!ntdll)
{
fprintf(stderr, "err:lsteamclient:init_ntdll_so_funcs could not find ntdll.so.\n");
return;
}
p_NtCurrentTeb = dlsym(ntdll, "NtCurrentTeb");
dlclose(ntdll);
}
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
{
TRACE("(%p, %u, %p)\n", instance, reason, reserved);
@ -51,6 +84,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(instance);
steam_overlay_event = CreateEventA(NULL, TRUE, FALSE, "__wine_steamclient_GameOverlayActivated");
init_ntdll_so_funcs();
break;
case DLL_PROCESS_DETACH:
if (callback_thread_handle)
@ -76,6 +110,13 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
return TRUE;
}
BOOL is_native_thread(void)
{
if (!p_NtCurrentTeb)
return TRUE;
return !p_NtCurrentTeb();
}
void sync_environment(void)
{
static const char *steamapi_envs[] =
@ -743,7 +784,12 @@ static DWORD WINAPI callback_thread(void *dummy)
cb_data.steam_api_warning_hook.msg);
callback_complete(cookie);
break;
case STEAM_API_CALLBACK_ONE_PARAM:
TRACE("STEAM_API_CALLBACK_ONE_PARAM func %p, param %p.\n",
cb_data.func, cb_data.steam_api_callback_one_param.param);
((void (WINAPI *)(void *))cb_data.func)(cb_data.steam_api_callback_one_param.param);
callback_complete(cookie);
break;
default:
ERR("Unexpected callback type %u.\n", cb_data.type);
break;

View file

@ -88,13 +88,25 @@ static void __attribute__((ms_abi)) win_Release(struct winSteamNetworkingMessage
static void lin_FreeData(struct SteamNetworkingMessage_t *lin_msg)
{
struct msg_wrapper *msg = msg_wrapper_from_lin(lin_msg);
struct callback_data cb_data;
TRACE("%p\n", msg);
if (!msg)
return;
if(msg->win_msg.m_pfnFreeData)
if (!msg->win_msg.m_pfnFreeData)
return;
if (!is_native_thread())
{
TRACE("msg %p, callback %p.\n", msg, msg->win_msg.m_pfnFreeData);
((void (__attribute__((ms_abi))*)(struct winSteamNetworkingMessage_t_153a *))msg->win_msg.m_pfnFreeData)(&msg->win_msg);
return;
}
cb_data.type = STEAM_API_CALLBACK_ONE_PARAM;
cb_data.func = (void *)msg->win_msg.m_pfnFreeData;
cb_data.steam_api_callback_one_param.param = (void *)&msg->win_msg;
execute_callback(&cb_data);
}
void *network_message_lin_to_win_(void *msg_, unsigned int version)
@ -104,7 +116,7 @@ void *network_message_lin_to_win_(void *msg_, unsigned int version)
msg = (struct msg_wrapper *)HeapAlloc(GetProcessHeap(), 0, sizeof(*msg));
TRACE("lin_msg %p, msg %p.\n", lin_msg, msg);
TRACE("lin_msg %p, msg %p, m_cbSize %d.\n", lin_msg, msg, lin_msg->m_cbSize);
msg->lin_msg = lin_msg;

View file

@ -75,6 +75,7 @@ enum callback_type
{
SOCKET_DEBUG_OUTPUT = 1,
STEAM_API_WARNING_HOOK,
STEAM_API_CALLBACK_ONE_PARAM,
};
struct callback_data
@ -96,10 +97,16 @@ struct callback_data
const char *msg;
}
steam_api_warning_hook;
struct
{
void *param;
}
steam_api_callback_one_param;
};
};
void execute_callback(struct callback_data *cb_data);
BOOL is_native_thread(void);
#ifdef __cplusplus
}