diff --git a/src/directplay.c b/src/directplay.c index 706dec3..b599f03 100644 --- a/src/directplay.c +++ b/src/directplay.c @@ -31,6 +31,7 @@ struct sp_data { SOCKET sock; struct sockaddr_ipx addr; + SOCKET ns_sock; /* For RECEIVING discovery messages only, -1 when not hosting */ struct sockaddr_ipx ns_addr; /* sa_family is 0 when undefined */ DPID ns_id; @@ -310,14 +311,31 @@ static HRESULT WINAPI IPX_Open(LPDPSP_OPENDATA data) { struct sp_data *sp_data = get_sp_data(data->lpISP); if(data->bCreate) { - struct sockaddr_ipx addr; + if(sp_data->ns_sock == -1) { + if((sp_data->ns_sock = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == -1) { + release_sp_data(data->lpISP); + + log_printf("Cannot create ns_sock: %s", w32_error(WSAGetLastError())); + return DPERR_CANNOTCREATESERVER; + } + + BOOL reuse = TRUE; + setsockopt(sp_data->ns_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(BOOL)); + + struct sockaddr_ipx addr; + + memcpy(&addr, &(sp_data->addr), sizeof(addr)); + addr.sa_socket = htons(DISCOVERY_SOCKET); - memcpy(&addr, &(sp_data->addr), sizeof(addr)); - addr.sa_socket = htons(DISCOVERY_SOCKET); - - if(ipx_ex_bind(sp_data->sock, &addr) == -1) { - release_sp_data(data->lpISP); - return DPERR_CANNOTCREATESERVER; + if(bind(sp_data->ns_sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + closesocket(sp_data->ns_sock); + sp_data->ns_sock = -1; + + release_sp_data(data->lpISP); + + log_printf("Cannot bind ns_sock: %s", w32_error(WSAGetLastError())); + return DPERR_CANNOTCREATESERVER; + } } }else if(data->lpSPMessageHeader) { memcpy(&(sp_data->ns_addr), data->lpSPMessageHeader, sizeof(struct sockaddr_ipx)); @@ -333,8 +351,10 @@ static HRESULT WINAPI IPX_CloseEx(LPDPSP_CLOSEDATA data) { struct sp_data *sp_data = get_sp_data(data->lpISP); - /* Disable the special bind if in use */ - ipx_ex_bind(sp_data->sock, NULL); + if(sp_data->ns_sock != -1) { + closesocket(sp_data->ns_sock); + sp_data->ns_sock = -1; + } release_sp_data(data->lpISP); return DP_OK; @@ -424,6 +444,7 @@ HRESULT WINAPI SPInit(LPSPINITDATA data) { return DPERR_UNAVAILABLE; } + sp_data->ns_sock = -1; sp_data->ns_addr.sa_family = 0; sp_data->worker_thread = NULL; diff --git a/src/ipxwrapper.def b/src/ipxwrapper.def index 10e6b38..d373277 100644 --- a/src/ipxwrapper.def +++ b/src/ipxwrapper.def @@ -14,4 +14,3 @@ EXPORTS EnumProtocolsW WSARecvEx ioctlsocket - ipx_ex_bind diff --git a/src/ipxwrapper.h b/src/ipxwrapper.h index 8aac5a6..7ccf3bd 100644 --- a/src/ipxwrapper.h +++ b/src/ipxwrapper.h @@ -38,7 +38,6 @@ #define IPX_BROADCAST (int)(1<<2) #define IPX_SEND (int)(1<<3) #define IPX_RECV (int)(1<<4) -#define IPX_EX_BOUND (int)(1<<5) #define IPX_REUSE (int)(1<<6) #define RETURN(...) \ @@ -120,8 +119,6 @@ void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipad void log_open(); void log_close(); -int ipx_ex_bind(SOCKET fd, const struct sockaddr_ipx *ipxaddr); - INT APIENTRY r_EnumProtocolsA(LPINT,LPVOID,LPDWORD); INT APIENTRY r_EnumProtocolsW(LPINT,LPVOID,LPDWORD); int PASCAL FAR r_WSARecvEx(SOCKET,char*,int,int*); diff --git a/src/winsock.c b/src/winsock.c index 63a22c2..6151388 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -231,13 +231,6 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen) { } } -/* Bind extra address of a socket, does not check if address is already in use - * Attempts to bind socket 0 will really bind socket 0 -*/ -int ipx_ex_bind(SOCKET fd, const struct sockaddr_ipx *ipxaddr) { - return 0; -} - int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen) { ipx_socket *ptr = get_socket(fd);