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 <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <pthread.h>
|
#include <pthread.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"
|
||||||
|
@ -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_ready_event;
|
||||||
static pthread_cond_t callback_queue_complete_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)
|
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
||||||
{
|
{
|
||||||
TRACE("(%p, %u, %p)\n", instance, reason, 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:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls(instance);
|
DisableThreadLibraryCalls(instance);
|
||||||
steam_overlay_event = CreateEventA(NULL, TRUE, FALSE, "__wine_steamclient_GameOverlayActivated");
|
steam_overlay_event = CreateEventA(NULL, TRUE, FALSE, "__wine_steamclient_GameOverlayActivated");
|
||||||
|
init_ntdll_so_funcs();
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (callback_thread_handle)
|
if (callback_thread_handle)
|
||||||
|
@ -76,6 +110,13 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL is_native_thread(void)
|
||||||
|
{
|
||||||
|
if (!p_NtCurrentTeb)
|
||||||
|
return TRUE;
|
||||||
|
return !p_NtCurrentTeb();
|
||||||
|
}
|
||||||
|
|
||||||
void sync_environment(void)
|
void sync_environment(void)
|
||||||
{
|
{
|
||||||
static const char *steamapi_envs[] =
|
static const char *steamapi_envs[] =
|
||||||
|
@ -743,7 +784,12 @@ static DWORD WINAPI callback_thread(void *dummy)
|
||||||
cb_data.steam_api_warning_hook.msg);
|
cb_data.steam_api_warning_hook.msg);
|
||||||
callback_complete(cookie);
|
callback_complete(cookie);
|
||||||
break;
|
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:
|
default:
|
||||||
ERR("Unexpected callback type %u.\n", cb_data.type);
|
ERR("Unexpected callback type %u.\n", cb_data.type);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -88,13 +88,25 @@ static void __attribute__((ms_abi)) win_Release(struct winSteamNetworkingMessage
|
||||||
static void lin_FreeData(struct SteamNetworkingMessage_t *lin_msg)
|
static void lin_FreeData(struct SteamNetworkingMessage_t *lin_msg)
|
||||||
{
|
{
|
||||||
struct msg_wrapper *msg = msg_wrapper_from_lin(lin_msg);
|
struct msg_wrapper *msg = msg_wrapper_from_lin(lin_msg);
|
||||||
|
struct callback_data cb_data;
|
||||||
|
|
||||||
TRACE("%p\n", msg);
|
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
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);
|
((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)
|
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));
|
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;
|
msg->lin_msg = lin_msg;
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ enum callback_type
|
||||||
{
|
{
|
||||||
SOCKET_DEBUG_OUTPUT = 1,
|
SOCKET_DEBUG_OUTPUT = 1,
|
||||||
STEAM_API_WARNING_HOOK,
|
STEAM_API_WARNING_HOOK,
|
||||||
|
STEAM_API_CALLBACK_ONE_PARAM,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct callback_data
|
struct callback_data
|
||||||
|
@ -96,10 +97,16 @@ struct callback_data
|
||||||
const char *msg;
|
const char *msg;
|
||||||
}
|
}
|
||||||
steam_api_warning_hook;
|
steam_api_warning_hook;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
void *param;
|
||||||
|
}
|
||||||
|
steam_api_callback_one_param;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
void execute_callback(struct callback_data *cb_data);
|
void execute_callback(struct callback_data *cb_data);
|
||||||
|
BOOL is_native_thread(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue