mirror of
https://github.com/ValveSoftware/Proton.git
synced 2024-12-29 16:15:52 +03:00
e8df09e258
CW-Bug-Id: #22649 So msg wrapper is freed when the message is released from steamclient side.
220 lines
6.7 KiB
C++
220 lines
6.7 KiB
C++
extern "C" {
|
|
#include <stdarg.h>
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "wine/list.h"
|
|
#include "wine/debug.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(steamclient);
|
|
}
|
|
|
|
#include "steam_defs.h"
|
|
#pragma push_macro("__cdecl")
|
|
#undef __cdecl
|
|
#include "steamworks_sdk_153a/steam_api.h"
|
|
#include "steamworks_sdk_153a/steamnetworkingtypes.h"
|
|
|
|
#pragma pop_macro("__cdecl")
|
|
#include "steamclient_private.h"
|
|
|
|
extern "C" {
|
|
#define SDKVER_153a
|
|
#include "struct_converters.h"
|
|
#include "cb_converters.h"
|
|
#include "win_constructors.h"
|
|
|
|
#define SDK_VERSION 1531
|
|
#include "steamclient_manual_common.h"
|
|
|
|
#include <pthread.h>
|
|
|
|
struct msg_wrapper {
|
|
struct winSteamNetworkingMessage_t_153a win_msg;
|
|
struct SteamNetworkingMessage_t *lin_msg;
|
|
|
|
struct list mapping_entry;
|
|
void (*orig_FreeData)(SteamNetworkingMessage_t *);
|
|
void (*orig_Release)(SteamNetworkingMessage_t *);
|
|
};
|
|
|
|
/***** manual struct converter for SteamNetworkingMessage_t *****/
|
|
|
|
static struct list msg_lin_to_win_mapping = LIST_INIT(msg_lin_to_win_mapping);
|
|
static pthread_mutex_t msg_lin_to_win_mapping_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
static struct msg_wrapper *msg_wrapper_from_lin(struct SteamNetworkingMessage_t *lin_msg)
|
|
{
|
|
struct msg_wrapper *msg = NULL, *m;
|
|
|
|
pthread_mutex_lock(&msg_lin_to_win_mapping_mutex);
|
|
LIST_FOR_EACH_ENTRY(m, &msg_lin_to_win_mapping, struct msg_wrapper, mapping_entry)
|
|
{
|
|
if (m->lin_msg == lin_msg)
|
|
{
|
|
msg = m;
|
|
break;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&msg_lin_to_win_mapping_mutex);
|
|
if (!msg)
|
|
fprintf(stderr, "err:lsteamclient:msg_wrapper_from_lin Mapping for %p not found.\n", lin_msg);
|
|
return msg;
|
|
}
|
|
|
|
static void __attribute__((ms_abi)) win_FreeData(struct winSteamNetworkingMessage_t_153a *win_msg)
|
|
{
|
|
struct msg_wrapper *msg = CONTAINING_RECORD(win_msg, struct msg_wrapper, win_msg);
|
|
TRACE("%p\n", msg);
|
|
if(msg->orig_FreeData)
|
|
{
|
|
msg->lin_msg->m_pData = msg->win_msg.m_pData;
|
|
msg->orig_FreeData(msg->lin_msg);
|
|
}
|
|
}
|
|
|
|
static void __attribute__((ms_abi)) win_Release(struct winSteamNetworkingMessage_t_153a *win_msg)
|
|
{
|
|
struct msg_wrapper *msg = CONTAINING_RECORD(win_msg, struct msg_wrapper, win_msg);
|
|
|
|
TRACE("%p\n", msg);
|
|
if (msg->orig_Release)
|
|
msg->orig_Release(msg->lin_msg);
|
|
pthread_mutex_lock(&msg_lin_to_win_mapping_mutex);
|
|
list_remove(&msg->mapping_entry);
|
|
pthread_mutex_unlock(&msg_lin_to_win_mapping_mutex);
|
|
SecureZeroMemory(msg, sizeof(*msg));
|
|
HeapFree(GetProcessHeap(), 0, msg);
|
|
}
|
|
|
|
static void lin_FreeData(struct SteamNetworkingMessage_t *lin_msg)
|
|
{
|
|
struct msg_wrapper *msg = msg_wrapper_from_lin(lin_msg);
|
|
struct callback_data cb_data;
|
|
|
|
if (!msg)
|
|
return;
|
|
|
|
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);
|
|
}
|
|
|
|
static void lin_Release(struct SteamNetworkingMessage_t *lin_msg)
|
|
{
|
|
struct msg_wrapper *msg = msg_wrapper_from_lin(lin_msg);
|
|
struct callback_data cb_data;
|
|
|
|
if (!msg)
|
|
return;
|
|
|
|
if (!msg->win_msg.m_pfnRelease)
|
|
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_pfnRelease)(&msg->win_msg);
|
|
return;
|
|
}
|
|
|
|
cb_data.type = STEAM_API_CALLBACK_ONE_PARAM;
|
|
cb_data.func = (void *)msg->win_msg.m_pfnRelease;
|
|
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)
|
|
{
|
|
struct SteamNetworkingMessage_t *lin_msg = (struct SteamNetworkingMessage_t *)msg_;
|
|
struct msg_wrapper *msg;
|
|
|
|
msg = (struct msg_wrapper *)HeapAlloc(GetProcessHeap(), 0, sizeof(*msg));
|
|
|
|
TRACE("lin_msg %p, msg %p, m_cbSize %d.\n", lin_msg, msg, lin_msg->m_cbSize);
|
|
|
|
msg->lin_msg = lin_msg;
|
|
|
|
msg->win_msg.m_pData = msg->lin_msg->m_pData;
|
|
msg->win_msg.m_cbSize = msg->lin_msg->m_cbSize;
|
|
msg->win_msg.m_conn = msg->lin_msg->m_conn;
|
|
msg->win_msg.m_identityPeer = msg->lin_msg->m_identityPeer;
|
|
msg->win_msg.m_nConnUserData = msg->lin_msg->m_nConnUserData;
|
|
msg->win_msg.m_usecTimeReceived= msg->lin_msg->m_usecTimeReceived;
|
|
msg->win_msg.m_nMessageNumber = msg->lin_msg->m_nMessageNumber;
|
|
msg->win_msg.m_pfnFreeData = (void*)win_FreeData;
|
|
msg->win_msg.m_pfnRelease = (void*)win_Release;
|
|
msg->win_msg.m_nChannel = msg->lin_msg->m_nChannel;
|
|
if (version >= 1470)
|
|
{
|
|
msg->win_msg.m_nFlags = msg->lin_msg->m_nFlags;
|
|
msg->win_msg.m_nUserData = msg->lin_msg->m_nUserData;
|
|
}
|
|
if (version >= 1530)
|
|
msg->win_msg.m_idxLane = msg->lin_msg->m_idxLane;
|
|
|
|
msg->orig_FreeData = msg->lin_msg->m_pfnFreeData;
|
|
msg->lin_msg->m_pfnFreeData = lin_FreeData;
|
|
msg->orig_Release = msg->lin_msg->m_pfnRelease;
|
|
msg->lin_msg->m_pfnRelease = lin_Release;
|
|
|
|
pthread_mutex_lock(&msg_lin_to_win_mapping_mutex);
|
|
list_add_head(&msg_lin_to_win_mapping, &msg->mapping_entry);
|
|
pthread_mutex_unlock(&msg_lin_to_win_mapping_mutex);
|
|
|
|
return &msg->win_msg;
|
|
}
|
|
|
|
void lin_to_win_struct_SteamNetworkingMessage_t_(int n_messages, void **l, void **w, int max_messages, int version)
|
|
{
|
|
int i;
|
|
|
|
if(n_messages > 0)
|
|
TRACE("%u %p %p\n", n_messages, l, w);
|
|
|
|
for(i = 0; i < n_messages; ++i)
|
|
w[i] = network_message_lin_to_win_(l[i], version);
|
|
|
|
for(; i < max_messages; ++i)
|
|
w[i] = NULL;
|
|
}
|
|
|
|
void *network_message_win_to_lin_(void *win_msg, unsigned int version)
|
|
{
|
|
struct msg_wrapper *msg = CONTAINING_RECORD(win_msg, struct msg_wrapper, win_msg);
|
|
SteamNetworkingMessage_t *lin_msg = msg->lin_msg;
|
|
|
|
TRACE("msg %p, lin_msg %p.\n", msg, lin_msg);
|
|
|
|
lin_msg->m_pData = msg->win_msg.m_pData;
|
|
lin_msg->m_cbSize = msg->win_msg.m_cbSize;
|
|
lin_msg->m_conn = msg->win_msg.m_conn;
|
|
lin_msg->m_identityPeer = msg->win_msg.m_identityPeer;
|
|
lin_msg->m_nConnUserData = msg->win_msg.m_nConnUserData;
|
|
lin_msg->m_usecTimeReceived= msg->win_msg.m_usecTimeReceived;
|
|
lin_msg->m_nMessageNumber = msg->win_msg.m_nMessageNumber;
|
|
lin_msg->m_nChannel = msg->win_msg.m_nChannel;
|
|
if (version >= 1470)
|
|
{
|
|
lin_msg->m_nFlags = msg->win_msg.m_nFlags;
|
|
lin_msg->m_nUserData = msg->win_msg.m_nUserData;
|
|
}
|
|
if (version >= 1530)
|
|
lin_msg->m_idxLane = msg->win_msg.m_idxLane;
|
|
|
|
return lin_msg;
|
|
}
|
|
|
|
} /* extern "C" { */
|