lsteamclient: Handle calls to SteamNetworkingMessage_t.m_pfnFreeData from native threads.
CW-Bug-Id: #22649
This commit is contained in:
parent
a798b8308f
commit
8a109013b4
3 changed files with 70 additions and 5 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue