Proton/lsteamclient/steamclient_manual_common.cpp
Paul Gofman e8df09e258 lsteamclient: Also overload lin SteamNetworkingMessage_t.m_pfnRelease.
CW-Bug-Id: #22649

So msg wrapper is freed when the message is released from steamclient
side.
2023-09-12 14:44:08 +03:00

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" { */