1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00

DirectPlay: Move initialisation/destruction of main socket.

Initialise the socket when SP_Open or SP_EnumSessions is called and close it
when SP_CloseEx is called, per the DX5 implementation.
This commit is contained in:
Daniel Collins 2015-08-19 23:01:40 +01:00
parent 8ded8da35a
commit dbfdae63d2

View File

@ -145,35 +145,77 @@ static DWORD WINAPI worker_main(LPVOID sp) {
return 0;
}
static BOOL init_worker(IDirectPlaySP *sp) {
struct sp_data *sp_data = get_sp_data(sp);
if(sp_data->worker_thread) {
release_sp_data(sp_data);
static BOOL init_worker(IDirectPlaySP *sp, struct sp_data *sp_data)
{
if(sp_data->worker_thread)
{
return TRUE;
}
sp_data->worker_thread = CreateThread(NULL, 0, &worker_main, sp, 0, NULL);
if(!sp_data->worker_thread) {
if(!sp_data->worker_thread)
{
log_printf(LOG_ERROR, "Failed to create worker thread");
release_sp_data(sp_data);
return FALSE;
}
release_sp_data(sp_data);
return TRUE;
}
static BOOL init_main_socket(struct sp_data *sp_data)
{
if(sp_data->sock == -1)
{
int sock = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
if(sock == -1)
{
log_printf(LOG_ERROR,
"Error creating IPX socket: %s", w32_error(WSAGetLastError()));
return FALSE;
}
struct sockaddr_ipx addr;
memset(&addr, 0, sizeof(addr));
addr.sa_family = AF_IPX;
if(bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
log_printf(LOG_ERROR,
"Error binding IPX socket: %s", w32_error(WSAGetLastError()));
closesocket(sock);
return FALSE;
}
BOOL bcast = TRUE;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)(&bcast), sizeof(bcast));
if(WSAEventSelect(sock, sp_data->event, FD_READ) == -1)
{
log_printf(LOG_ERROR,
"WSAEventSelect: %s", w32_error(WSAGetLastError()));
closesocket(sock);
return FALSE;
}
sp_data->sock = sock;
}
return TRUE;
}
static HRESULT WINAPI IPX_EnumSessions(LPDPSP_ENUMSESSIONSDATA data) {
CALL("SP_EnumSessions");
if(!init_worker(data->lpISP)) {
struct sp_data *sp_data = get_sp_data(data->lpISP);
if(!init_worker(data->lpISP, sp_data) || !init_main_socket(sp_data))
{
release_sp_data(sp_data);
return DPERR_GENERIC;
}
struct sp_data *sp_data = get_sp_data(data->lpISP);
/* Get the address of our main socket. */
struct sockaddr_ipx my_addr;
@ -464,12 +506,14 @@ static HRESULT WINAPI IPX_GetCaps(LPDPSP_GETCAPSDATA data) {
static HRESULT WINAPI IPX_Open(LPDPSP_OPENDATA data) {
CALL("SP_Open");
if(!init_worker(data->lpISP)) {
struct sp_data *sp_data = get_sp_data(data->lpISP);
if(!init_worker(data->lpISP, sp_data) || !init_main_socket(sp_data))
{
release_sp_data(sp_data);
return DPERR_GENERIC;
}
struct sp_data *sp_data = get_sp_data(data->lpISP);
if(data->bCreate) {
if(sp_data->ns_sock == -1) {
if((sp_data->ns_sock = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == -1) {
@ -535,11 +579,18 @@ static HRESULT WINAPI IPX_CloseEx(LPDPSP_CLOSEDATA data) {
struct sp_data *sp_data = get_sp_data(data->lpISP);
if(sp_data->ns_sock != -1) {
if(sp_data->ns_sock != -1)
{
closesocket(sp_data->ns_sock);
sp_data->ns_sock = -1;
}
if(sp_data->sock == -1)
{
closesocket(sp_data->sock);
sp_data->sock = -1;
}
release_sp_data(sp_data);
return DP_OK;
}
@ -564,11 +615,18 @@ static HRESULT WINAPI IPX_ShutdownEx(LPDPSP_SHUTDOWNDATA data) {
sp_data->worker_thread = NULL;
}
if(sp_data->ns_sock != -1) {
if(sp_data->ns_sock != -1)
{
closesocket(sp_data->ns_sock);
sp_data->ns_sock = -1;
}
if(sp_data->sock == -1)
{
closesocket(sp_data->sock);
sp_data->sock = -1;
}
closesocket(sp_data->sock);
WSACloseEvent(sp_data->event);
DeleteCriticalSection(&(sp_data->lock));
@ -596,33 +654,12 @@ HRESULT WINAPI SPInit(LPSPINITDATA data) {
goto FAIL3;
}
if((sp_data.sock = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == -1) {
log_printf(LOG_ERROR, "Error creating IPX socket: %s", w32_error(WSAGetLastError()));
goto FAIL4;
}
struct sockaddr_ipx addr;
memset(&addr, 0, sizeof(addr));
addr.sa_family = AF_IPX;
if(bind(sp_data.sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
log_printf(LOG_ERROR, "Error binding IPX socket: %s", w32_error(WSAGetLastError()));
goto FAIL5;
}
sp_data.sock = -1;
sp_data.ns_sock = -1;
sp_data.ns_addr.sa_family = 0;
sp_data.running = TRUE;
sp_data.worker_thread = NULL;
BOOL bcast = TRUE;
setsockopt(sp_data.sock, SOL_SOCKET, SO_BROADCAST, (char*)&bcast, sizeof(BOOL));
if(WSAEventSelect(sp_data.sock, sp_data.event, FD_READ) == -1) {
log_printf(LOG_ERROR, "WSAEventSelect failed: %s", w32_error(WSAGetLastError()));
goto FAIL5;
}
HRESULT r = IDirectPlaySP_SetSPData(data->lpISP, &sp_data, sizeof(sp_data), DPSET_LOCAL);
if(r != DP_OK) {
log_printf(LOG_ERROR, "SetSPData: %d", (int)r);
@ -644,9 +681,6 @@ HRESULT WINAPI SPInit(LPSPINITDATA data) {
return DP_OK;
FAIL5:
closesocket(sp_data.sock);
FAIL4:
WSACloseEvent(sp_data.event);
FAIL3: