Fix the SOCKADDR_IPX declaration.
Centralize all sockaddr_xxx conversions in ws_sockaddr_ws2u and ws_sockaddr_u2ws. Remove ugly casts in TRACEs.
This commit is contained in:
parent
b85a6e8c0a
commit
76f6ffaf1b
@ -91,6 +91,7 @@
|
|||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "winsock2.h"
|
#include "winsock2.h"
|
||||||
|
#include "wsipx.h"
|
||||||
#include "wine/winsock16.h"
|
#include "wine/winsock16.h"
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
@ -153,6 +154,7 @@ static FARPROC blocking_hook;
|
|||||||
int WS_dup_he(struct hostent* p_he, int flag);
|
int WS_dup_he(struct hostent* p_he, int flag);
|
||||||
int WS_dup_pe(struct protoent* p_pe, int flag);
|
int WS_dup_pe(struct protoent* p_pe, int flag);
|
||||||
int WS_dup_se(struct servent* p_se, int flag);
|
int WS_dup_se(struct servent* p_se, int flag);
|
||||||
|
int WINAPI WSOCK32_getpeername(SOCKET s, ws_sockaddr *name, int *namelen);
|
||||||
|
|
||||||
typedef void WIN_hostent;
|
typedef void WIN_hostent;
|
||||||
typedef void WIN_protoent;
|
typedef void WIN_protoent;
|
||||||
@ -736,10 +738,13 @@ static struct ws_protoent* check_buffer_pe(int size)
|
|||||||
|
|
||||||
/* ----------------------------------- i/o APIs */
|
/* ----------------------------------- i/o APIs */
|
||||||
|
|
||||||
/***********************************************************************
|
#ifdef HAVE_IPX
|
||||||
* accept (WS2_32.1)
|
#define SUPPORTED_PF(pf) ((pf)==AF_INET || (pf)== AF_IPX)
|
||||||
*/
|
#else
|
||||||
static void WSOCK32_async_accept(SOCKET s, SOCKET as)
|
#define SUPPORTED_PF(pf) ((pf)==AF_INET)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void ws2_async_accept(SOCKET s, SOCKET as)
|
||||||
{
|
{
|
||||||
int q;
|
int q;
|
||||||
/* queue socket for WSAAsyncSelect */
|
/* queue socket for WSAAsyncSelect */
|
||||||
@ -756,12 +761,130 @@ static void WSOCK32_async_accept(SOCKET s, SOCKET as)
|
|||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr,
|
/* Returns the converted address if successful, NULL if it was too small to
|
||||||
INT *addrlen32)
|
* start with. Note that the returned pointer may be the original pointer
|
||||||
|
* if no conversion is necessary.
|
||||||
|
*/
|
||||||
|
const struct sockaddr* ws_sockaddr_ws2u(const ws_sockaddr* wsaddr, int wsaddrlen, int *uaddrlen)
|
||||||
{
|
{
|
||||||
|
switch (wsaddr->sa_family)
|
||||||
|
{
|
||||||
#ifdef HAVE_IPX
|
#ifdef HAVE_IPX
|
||||||
struct ws_sockaddr_ipx* addr2 = (struct ws_sockaddr_ipx *)addr;
|
case WS_AF_IPX:
|
||||||
|
{
|
||||||
|
struct ws_sockaddr_ipx* wsipx=(struct ws_sockaddr_ipx*)wsaddr;
|
||||||
|
struct sockaddr_ipx* uipx;
|
||||||
|
|
||||||
|
if (wsaddrlen<sizeof(struct ws_sockaddr_ipx))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*uaddrlen=sizeof(struct sockaddr_ipx);
|
||||||
|
uipx=malloc(*uaddrlen);
|
||||||
|
uipx->sipx_family=AF_IPX;
|
||||||
|
uipx->sipx_port=wsipx->sa_socket;
|
||||||
|
/* copy sa_netnum and sa_nodenum to sipx_network and sipx_node
|
||||||
|
* in one go
|
||||||
|
*/
|
||||||
|
memcpy(&uipx->sipx_network,wsipx->sa_netnum,sizeof(uipx->sipx_network)+sizeof(uipx->sipx_node));
|
||||||
|
uipx->sipx_type=IPX_FRAME_NONE;
|
||||||
|
uipx->sipx_zero=0;
|
||||||
|
return (const struct sockaddr*)uipx;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (wsaddrlen<sizeof(ws_sockaddr))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* No conversion needed, just return the original address */
|
||||||
|
*uaddrlen=wsaddrlen;
|
||||||
|
return (const struct sockaddr*)wsaddr;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocates a Unix sockaddr structure to receive the data */
|
||||||
|
inline struct sockaddr* ws_sockaddr_alloc(const ws_sockaddr* wsaddr, int* wsaddrlen, int* uaddrlen)
|
||||||
|
{
|
||||||
|
if (*wsaddrlen==0)
|
||||||
|
*uaddrlen=0;
|
||||||
|
else
|
||||||
|
*uaddrlen=max(sizeof(struct sockaddr),*wsaddrlen);
|
||||||
|
if (wsaddr==NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return malloc(*uaddrlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 0 if successful, -1 if the buffer is too small */
|
||||||
|
int ws_sockaddr_u2ws(const struct sockaddr* uaddr, int uaddrlen, ws_sockaddr* wsaddr, int* wsaddrlen)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
switch(uaddr->sa_family)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_IPX
|
||||||
|
case AF_IPX:
|
||||||
|
{
|
||||||
|
struct sockaddr_ipx* uipx=(struct sockaddr_ipx*)uaddr;
|
||||||
|
struct ws_sockaddr_ipx* wsipx=(struct ws_sockaddr_ipx*)wsaddr;
|
||||||
|
|
||||||
|
res=-1;
|
||||||
|
switch (*wsaddrlen) /* how much can we copy? */
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
res=0; /* enough */
|
||||||
|
wsipx->sa_socket=uipx->sipx_port;
|
||||||
|
/* fall through */
|
||||||
|
case 13:
|
||||||
|
case 12:
|
||||||
|
memcpy(wsipx->sa_nodenum,uipx->sipx_node,sizeof(wsipx->sa_nodenum));
|
||||||
|
/* fall through */
|
||||||
|
case 11:
|
||||||
|
case 10:
|
||||||
|
case 9:
|
||||||
|
case 8:
|
||||||
|
case 7:
|
||||||
|
case 6:
|
||||||
|
memcpy(wsipx->sa_netnum,&uipx->sipx_network,sizeof(wsipx->sa_netnum));
|
||||||
|
/* fall through */
|
||||||
|
case 5:
|
||||||
|
case 4:
|
||||||
|
case 3:
|
||||||
|
case 2:
|
||||||
|
wsipx->sa_family=AF_IPX;
|
||||||
|
/* fall through */
|
||||||
|
case 1:
|
||||||
|
case 0:
|
||||||
|
/* way too small */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* No conversion needed */
|
||||||
|
memcpy(wsaddr,uaddr,*wsaddrlen);
|
||||||
|
res=(*wsaddrlen<uaddrlen?-1:0);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* to be called to free the memory allocated by ws_sockaddr_ws2u or
|
||||||
|
* ws_sockaddr_alloc
|
||||||
|
*/
|
||||||
|
inline void ws_sockaddr_free(const struct sockaddr* uaddr, const ws_sockaddr* wsaddr)
|
||||||
|
{
|
||||||
|
if (uaddr!=NULL && uaddr!=(const struct sockaddr*)wsaddr)
|
||||||
|
free((void*)uaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* accept (WS2_32.1)
|
||||||
|
*/
|
||||||
|
SOCKET WINAPI WSOCK32_accept(SOCKET s, ws_sockaddr *addr,
|
||||||
|
int *addrlen32)
|
||||||
|
{
|
||||||
int fd = _get_sock_fd(s);
|
int fd = _get_sock_fd(s);
|
||||||
|
|
||||||
TRACE("socket %04x\n", (UINT16)s );
|
TRACE("socket %04x\n", (UINT16)s );
|
||||||
@ -790,37 +913,23 @@ SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr,
|
|||||||
if (as)
|
if (as)
|
||||||
{
|
{
|
||||||
unsigned omask = _get_sock_mask( s );
|
unsigned omask = _get_sock_mask( s );
|
||||||
int fd = _get_sock_fd( as );
|
WSOCK32_getpeername(fd, addr, addrlen32);
|
||||||
if( getpeername(fd, addr, addrlen32) != -1 )
|
|
||||||
{
|
|
||||||
#ifdef HAVE_IPX
|
|
||||||
if (addr && ((struct sockaddr_ipx *)addr)->sipx_family == AF_IPX) {
|
|
||||||
addr = (struct sockaddr *)
|
|
||||||
malloc(addrlen32 ? *addrlen32 : sizeof(*addr2));
|
|
||||||
memcpy(addr, addr2,
|
|
||||||
addrlen32 ? *addrlen32 : sizeof(*addr2));
|
|
||||||
addr2->sipx_family = WS_AF_IPX;
|
|
||||||
addr2->sipx_network = ((struct sockaddr_ipx *)addr)->sipx_network;
|
|
||||||
addr2->sipx_port = ((struct sockaddr_ipx *)addr)->sipx_port;
|
|
||||||
memcpy(addr2->sipx_node,
|
|
||||||
((struct sockaddr_ipx *)addr)->sipx_node, IPX_NODE_LEN);
|
|
||||||
free(addr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else SetLastError(wsaErrno());
|
|
||||||
close(fd);
|
|
||||||
if (omask & FD_WINE_SERVEVENT)
|
if (omask & FD_WINE_SERVEVENT)
|
||||||
WSOCK32_async_accept(s, as);
|
ws2_async_accept(s, as);
|
||||||
return as;
|
return as;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(WSAENOTSOCK);
|
||||||
|
}
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* accept (WINSOCK.1)
|
* accept (WINSOCK.1)
|
||||||
*/
|
*/
|
||||||
SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, struct sockaddr* addr,
|
SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, ws_sockaddr* addr,
|
||||||
INT16* addrlen16 )
|
INT16* addrlen16 )
|
||||||
{
|
{
|
||||||
INT addrlen32 = addrlen16 ? *addrlen16 : 0;
|
INT addrlen32 = addrlen16 ? *addrlen16 : 0;
|
||||||
@ -832,80 +941,73 @@ SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, struct sockaddr* addr,
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* bind (WS2_32.2)
|
* bind (WS2_32.2)
|
||||||
*/
|
*/
|
||||||
INT WINAPI WSOCK32_bind(SOCKET s, struct sockaddr *name, INT namelen)
|
int WINAPI WSOCK32_bind(SOCKET s, const ws_sockaddr* name, int namelen)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPX
|
|
||||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
|
||||||
#endif
|
|
||||||
int fd = _get_sock_fd(s);
|
int fd = _get_sock_fd(s);
|
||||||
|
int res;
|
||||||
|
|
||||||
TRACE("socket %04x, ptr %8x, length %d\n", s, (int) name, namelen);
|
TRACE("socket %04x, ptr %p, length %d\n", s, name, namelen);
|
||||||
#if DEBUG_SOCKADDR
|
#if DEBUG_SOCKADDR
|
||||||
dump_sockaddr(name);
|
dump_sockaddr(name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
res=SOCKET_ERROR;
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
/* FIXME: what family does this really map to on the Unix side? */
|
if (!name || !SUPPORTED_PF(name->sa_family))
|
||||||
if (name && ((struct ws_sockaddr_ipx *)name)->sipx_family == WS_AF_PUP)
|
|
||||||
((struct ws_sockaddr_ipx *)name)->sipx_family = AF_UNSPEC;
|
|
||||||
#ifdef HAVE_IPX
|
|
||||||
else if (name &&
|
|
||||||
((struct ws_sockaddr_ipx *)name)->sipx_family == WS_AF_IPX)
|
|
||||||
{
|
|
||||||
name = (struct sockaddr *) malloc(sizeof(struct sockaddr_ipx));
|
|
||||||
memset(name, '\0', sizeof(struct sockaddr_ipx));
|
|
||||||
((struct sockaddr_ipx *)name)->sipx_family = AF_IPX;
|
|
||||||
((struct sockaddr_ipx *)name)->sipx_port = name2->sipx_port;
|
|
||||||
((struct sockaddr_ipx *)name)->sipx_network = name2->sipx_network;
|
|
||||||
memcpy(((struct sockaddr_ipx *)name)->sipx_node,
|
|
||||||
name2->sipx_node, IPX_NODE_LEN);
|
|
||||||
namelen = sizeof(struct sockaddr_ipx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ( namelen >= sizeof(*name) )
|
|
||||||
{
|
|
||||||
if ( name && (((struct ws_sockaddr_in *)name)->sin_family == AF_INET
|
|
||||||
#ifdef HAVE_IPX
|
|
||||||
|| ((struct sockaddr_ipx *)name)->sipx_family == AF_IPX
|
|
||||||
#endif
|
|
||||||
))
|
|
||||||
{
|
{
|
||||||
if ( bind(fd, name, namelen) < 0 )
|
SetLastError(WSAEAFNOSUPPORT);
|
||||||
{
|
}
|
||||||
int loc_errno = errno;
|
else
|
||||||
WARN("\tfailure - errno = %i\n", errno);
|
{
|
||||||
errno = loc_errno;
|
const struct sockaddr* uaddr;
|
||||||
switch(errno)
|
int uaddrlen;
|
||||||
{
|
|
||||||
case EBADF: SetLastError(WSAENOTSOCK); break;
|
uaddr=ws_sockaddr_ws2u(name,namelen,&uaddrlen);
|
||||||
case EADDRNOTAVAIL: SetLastError(WSAEINVAL); break;
|
if (uaddr == NULL)
|
||||||
default: SetLastError(wsaErrno());break;
|
{
|
||||||
}
|
SetLastError(WSAEFAULT);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
#ifdef HAVE_IPX
|
{
|
||||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
if (bind(fd, uaddr, uaddrlen) < 0)
|
||||||
free(name);
|
{
|
||||||
#endif
|
int loc_errno = errno;
|
||||||
close(fd);
|
WARN("\tfailure - errno = %i\n", errno);
|
||||||
return 0; /* success */
|
errno = loc_errno;
|
||||||
}
|
switch (errno)
|
||||||
} else SetLastError(WSAEAFNOSUPPORT);
|
{
|
||||||
} else SetLastError(WSAEFAULT);
|
case EBADF:
|
||||||
#ifdef HAVE_IPX
|
SetLastError(WSAENOTSOCK);
|
||||||
if (name && ((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
break;
|
||||||
free(name);
|
case EADDRNOTAVAIL:
|
||||||
#endif
|
SetLastError(WSAEINVAL);
|
||||||
close(fd);
|
break;
|
||||||
|
default:
|
||||||
|
SetLastError(wsaErrno());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res=0; /* success */
|
||||||
|
}
|
||||||
|
ws_sockaddr_free(uaddr,name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
return SOCKET_ERROR;
|
else
|
||||||
|
{
|
||||||
|
SetLastError(WSAENOTSOCK);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* bind (WINSOCK.2)
|
* bind (WINSOCK.2)
|
||||||
*/
|
*/
|
||||||
INT16 WINAPI WINSOCK_bind16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
|
INT16 WINAPI WINSOCK_bind16(SOCKET16 s, ws_sockaddr *name, INT16 namelen)
|
||||||
{
|
{
|
||||||
return (INT16)WSOCK32_bind( s, name, namelen );
|
return (INT16)WSOCK32_bind( s, name, namelen );
|
||||||
}
|
}
|
||||||
@ -931,89 +1033,85 @@ INT16 WINAPI WINSOCK_closesocket16(SOCKET16 s)
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* connect (WS2_32.4)
|
* connect (WS2_32.4)
|
||||||
*/
|
*/
|
||||||
INT WINAPI WSOCK32_connect(SOCKET s, struct sockaddr *name, INT namelen)
|
int WINAPI WSOCK32_connect(SOCKET s, const ws_sockaddr* name, int namelen)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPX
|
int fd = _get_sock_fd(s);
|
||||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
|
||||||
#endif
|
|
||||||
int fd = _get_sock_fd(s);
|
|
||||||
|
|
||||||
TRACE("socket %04x, ptr %8x, length %d\n", s, (int) name, namelen);
|
TRACE("socket %04x, ptr %p, length %d\n", s, name, namelen);
|
||||||
#if DEBUG_SOCKADDR
|
#if DEBUG_SOCKADDR
|
||||||
dump_sockaddr(name);
|
dump_sockaddr(name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
|
||||||
if (name && ((struct ws_sockaddr_ipx *)name)->sipx_family == WS_AF_PUP)
|
|
||||||
((struct ws_sockaddr_ipx *)name)->sipx_family = AF_UNSPEC;
|
|
||||||
#ifdef HAVE_IPX
|
|
||||||
else if (name && ((struct ws_sockaddr_ipx *)name)->sipx_family == WS_AF_IPX)
|
|
||||||
{
|
{
|
||||||
name = (struct sockaddr *) malloc(sizeof(struct sockaddr_ipx));
|
const struct sockaddr* uaddr;
|
||||||
memset(name, '\0', sizeof(struct sockaddr_ipx));
|
int uaddrlen;
|
||||||
((struct sockaddr_ipx *)name)->sipx_family = AF_IPX;
|
|
||||||
((struct sockaddr_ipx *)name)->sipx_port = name2->sipx_port;
|
uaddr=ws_sockaddr_ws2u(name,namelen,&uaddrlen);
|
||||||
((struct sockaddr_ipx *)name)->sipx_network = name2->sipx_network;
|
if (uaddr == NULL)
|
||||||
memcpy(((struct sockaddr_ipx *)name)->sipx_node,
|
{
|
||||||
name2->sipx_node, IPX_NODE_LEN);
|
SetLastError(WSAEFAULT);
|
||||||
namelen = sizeof(struct sockaddr_ipx);
|
}
|
||||||
}
|
else
|
||||||
#endif
|
{
|
||||||
if (connect(fd, name, namelen) == 0) {
|
int rc;
|
||||||
close(fd);
|
|
||||||
goto connect_success;
|
rc=connect(fd, uaddr, uaddrlen);
|
||||||
}
|
ws_sockaddr_free(uaddr,name);
|
||||||
if (errno == EINPROGRESS)
|
if (rc == 0)
|
||||||
{
|
goto connect_success;
|
||||||
/* tell wineserver that a connection is in progress */
|
}
|
||||||
_enable_event(s, FD_CONNECT|FD_READ|FD_WRITE,
|
|
||||||
FD_CONNECT|FD_READ|FD_WRITE,
|
if (errno == EINPROGRESS)
|
||||||
FD_WINE_CONNECTED|FD_WINE_LISTENING);
|
{
|
||||||
if (_is_blocking(s))
|
/* tell wineserver that a connection is in progress */
|
||||||
{
|
_enable_event(s, FD_CONNECT|FD_READ|FD_WRITE,
|
||||||
int result;
|
FD_CONNECT|FD_READ|FD_WRITE,
|
||||||
/* block here */
|
FD_WINE_CONNECTED|FD_WINE_LISTENING);
|
||||||
do_block(fd, 7);
|
if (_is_blocking(s))
|
||||||
_sync_sock_state(s); /* let wineserver notice connection */
|
{
|
||||||
/* retrieve any error codes from it */
|
int result;
|
||||||
result = _get_sock_error(s, FD_CONNECT_BIT);
|
/* block here */
|
||||||
if (result)
|
do_block(fd, 7);
|
||||||
SetLastError(result);
|
_sync_sock_state(s); /* let wineserver notice connection */
|
||||||
else {
|
/* retrieve any error codes from it */
|
||||||
close(fd);
|
result = _get_sock_error(s, FD_CONNECT_BIT);
|
||||||
goto connect_success;
|
if (result)
|
||||||
}
|
SetLastError(result);
|
||||||
}
|
else
|
||||||
else SetLastError(WSAEWOULDBLOCK);
|
{
|
||||||
close(fd);
|
goto connect_success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(WSAEWOULDBLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(wsaErrno());
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetLastError(wsaErrno());
|
SetLastError(WSAENOTSOCK);
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
}
|
return SOCKET_ERROR;
|
||||||
#ifdef HAVE_IPX
|
|
||||||
if (name && ((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
|
||||||
free(name);
|
|
||||||
#endif
|
|
||||||
return SOCKET_ERROR;
|
|
||||||
connect_success:
|
connect_success:
|
||||||
#ifdef HAVE_IPX
|
close(fd);
|
||||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
|
||||||
free(name);
|
|
||||||
#endif
|
|
||||||
_enable_event(s, FD_CONNECT|FD_READ|FD_WRITE,
|
_enable_event(s, FD_CONNECT|FD_READ|FD_WRITE,
|
||||||
FD_WINE_CONNECTED|FD_READ|FD_WRITE,
|
FD_WINE_CONNECTED|FD_READ|FD_WRITE,
|
||||||
FD_CONNECT|FD_WINE_LISTENING);
|
FD_CONNECT|FD_WINE_LISTENING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* connect (WINSOCK.4)
|
* connect (WINSOCK.4)
|
||||||
*/
|
*/
|
||||||
INT16 WINAPI WINSOCK_connect16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
|
INT16 WINAPI WINSOCK_connect16(SOCKET16 s, ws_sockaddr *name, INT16 namelen)
|
||||||
{
|
{
|
||||||
return (INT16)WSOCK32_connect( s, name, namelen );
|
return (INT16)WSOCK32_connect( s, name, namelen );
|
||||||
}
|
}
|
||||||
@ -1021,44 +1119,47 @@ INT16 WINAPI WINSOCK_connect16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* getpeername (WS2_32.5)
|
* getpeername (WS2_32.5)
|
||||||
*/
|
*/
|
||||||
INT WINAPI WSOCK32_getpeername(SOCKET s, struct sockaddr *name,
|
int WINAPI WSOCK32_getpeername(SOCKET s, ws_sockaddr *name, int *namelen)
|
||||||
INT *namelen)
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPX
|
|
||||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
|
||||||
#endif
|
|
||||||
int fd = _get_sock_fd(s);
|
int fd = _get_sock_fd(s);
|
||||||
|
int res;
|
||||||
|
|
||||||
TRACE("socket: %04x, ptr %8x, ptr %8x\n", s, (int) name, *namelen);
|
TRACE("socket: %04x, ptr %p, len %8x\n", s, name, *namelen);
|
||||||
|
|
||||||
|
res=SOCKET_ERROR;
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
if (getpeername(fd, name, namelen) == 0) {
|
struct sockaddr* uaddr;
|
||||||
#ifdef HAVE_IPX
|
int uaddrlen;
|
||||||
if (((struct ws_sockaddr_ipx *)name)->sipx_family == AF_IPX) {
|
|
||||||
name = (struct sockaddr *)
|
uaddr=ws_sockaddr_alloc(name,namelen,&uaddrlen);
|
||||||
malloc(namelen ? *namelen : sizeof(*name2));
|
if (getpeername(fd, uaddr, &uaddrlen) != 0)
|
||||||
memcpy(name, name2, namelen ? *namelen : sizeof(*name2));
|
{
|
||||||
name2->sipx_family = WS_AF_IPX;
|
SetLastError(wsaErrno());
|
||||||
name2->sipx_network = ((struct sockaddr_ipx *)name)->sipx_network;
|
}
|
||||||
name2->sipx_port = ((struct sockaddr_ipx *)name)->sipx_port;
|
else if (ws_sockaddr_u2ws(uaddr,uaddrlen,name,namelen) != 0)
|
||||||
memcpy(name2->sipx_node,
|
{
|
||||||
((struct sockaddr_ipx *)name)->sipx_node, IPX_NODE_LEN);
|
/* The buffer was too small */
|
||||||
free(name);
|
SetLastError(WSAEFAULT);
|
||||||
}
|
}
|
||||||
#endif
|
else
|
||||||
close(fd);
|
{
|
||||||
return 0;
|
res=0;
|
||||||
}
|
}
|
||||||
SetLastError(wsaErrno());
|
ws_sockaddr_free(uaddr,name);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
return SOCKET_ERROR;
|
else
|
||||||
|
{
|
||||||
|
SetLastError(WSAENOTSOCK);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* getpeername (WINSOCK.5)
|
* getpeername (WINSOCK.5)
|
||||||
*/
|
*/
|
||||||
INT16 WINAPI WINSOCK_getpeername16(SOCKET16 s, struct sockaddr *name,
|
INT16 WINAPI WINSOCK_getpeername16(SOCKET16 s, ws_sockaddr *name,
|
||||||
INT16 *namelen16)
|
INT16 *namelen16)
|
||||||
{
|
{
|
||||||
INT namelen32 = *namelen16;
|
INT namelen32 = *namelen16;
|
||||||
@ -1075,44 +1176,46 @@ INT16 WINAPI WINSOCK_getpeername16(SOCKET16 s, struct sockaddr *name,
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* getsockname (WS2_32.6)
|
* getsockname (WS2_32.6)
|
||||||
*/
|
*/
|
||||||
INT WINAPI WSOCK32_getsockname(SOCKET s, struct sockaddr *name,
|
int WINAPI WSOCK32_getsockname(SOCKET s, ws_sockaddr *name, int *namelen)
|
||||||
INT *namelen)
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPX
|
|
||||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
|
||||||
#endif
|
|
||||||
int fd = _get_sock_fd(s);
|
int fd = _get_sock_fd(s);
|
||||||
|
int res;
|
||||||
|
|
||||||
TRACE("socket: %04x, ptr %8x, ptr %8x\n", s, (int) name, (int) *namelen);
|
TRACE("socket: %04x, ptr %p, len %8x\n", s, name, *namelen);
|
||||||
|
|
||||||
|
res=SOCKET_ERROR;
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
if (getsockname(fd, name, namelen) == 0) {
|
struct sockaddr* uaddr;
|
||||||
#ifdef HAVE_IPX
|
int uaddrlen;
|
||||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX) {
|
|
||||||
name = (struct sockaddr *)
|
uaddr=ws_sockaddr_alloc(name,namelen,&uaddrlen);
|
||||||
malloc(namelen ? *namelen : sizeof(*name2));
|
if (getsockname(fd, uaddr, &uaddrlen) != 0)
|
||||||
memcpy(name, name2, namelen ? *namelen : sizeof(*name2));
|
{
|
||||||
name2->sipx_family = WS_AF_IPX;
|
SetLastError(wsaErrno());
|
||||||
name2->sipx_network = ((struct sockaddr_ipx *)name)->sipx_network;
|
}
|
||||||
name2->sipx_port = ((struct sockaddr_ipx *)name)->sipx_port;
|
else if (ws_sockaddr_u2ws(uaddr,uaddrlen,name,namelen) != 0)
|
||||||
memcpy(name2->sipx_node,
|
{
|
||||||
((struct sockaddr_ipx *)name)->sipx_node, IPX_NODE_LEN);
|
/* The buffer was too small */
|
||||||
free(name);
|
SetLastError(WSAEFAULT);
|
||||||
}
|
}
|
||||||
#endif
|
else
|
||||||
close(fd);
|
{
|
||||||
return 0;
|
res=0;
|
||||||
}
|
}
|
||||||
SetLastError(wsaErrno());
|
close(fd);
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
return SOCKET_ERROR;
|
else
|
||||||
|
{
|
||||||
|
SetLastError(WSAENOTSOCK);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* getsockname (WINSOCK.6)
|
* getsockname (WINSOCK.6)
|
||||||
*/
|
*/
|
||||||
INT16 WINAPI WINSOCK_getsockname16(SOCKET16 s, struct sockaddr *name,
|
INT16 WINAPI WINSOCK_getsockname16(SOCKET16 s, ws_sockaddr *name,
|
||||||
INT16 *namelen16)
|
INT16 *namelen16)
|
||||||
{
|
{
|
||||||
INT retVal;
|
INT retVal;
|
||||||
@ -1684,77 +1787,70 @@ INT16 WINAPI WINSOCK_recv16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* recvfrom (WS2_32.17)
|
* recvfrom (WS2_32.17)
|
||||||
*/
|
*/
|
||||||
INT WINAPI WSOCK32_recvfrom(SOCKET s, char *buf, INT len, INT flags,
|
int WINAPI WSOCK32_recvfrom(SOCKET s, char *buf, INT len, int flags,
|
||||||
struct sockaddr *from, INT *fromlen32)
|
ws_sockaddr *from, int *fromlen)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPX
|
|
||||||
struct ws_sockaddr_ipx* from2 = (struct ws_sockaddr_ipx *)from;
|
|
||||||
#endif
|
|
||||||
int fd = _get_sock_fd(s);
|
int fd = _get_sock_fd(s);
|
||||||
|
int res;
|
||||||
|
|
||||||
TRACE("socket %04x, ptr %08x, len %d, flags %d\n", s, (unsigned)buf, len, flags);
|
TRACE("socket %04x, ptr %08x, len %d, flags %d\n", s, (unsigned)buf, len, flags);
|
||||||
#if DEBUG_SOCKADDR
|
#if DEBUG_SOCKADDR
|
||||||
if( from ) dump_sockaddr(from);
|
if (from)
|
||||||
else DPRINTF("from = NULL\n");
|
dump_sockaddr(from);
|
||||||
|
else
|
||||||
|
DPRINTF("from = NULL\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
res=SOCKET_ERROR;
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
int length;
|
struct sockaddr* uaddr;
|
||||||
|
int uaddrlen;
|
||||||
|
int length;
|
||||||
|
|
||||||
if (_is_blocking(s))
|
if (_is_blocking(s))
|
||||||
{
|
{
|
||||||
/* block here */
|
/* block here */
|
||||||
/* FIXME: OOB and exceptfds */
|
/* FIXME: OOB and exceptfds */
|
||||||
do_block(fd, 1);
|
do_block(fd, 1);
|
||||||
}
|
}
|
||||||
if ((length = recvfrom(fd, buf, len, flags, from, fromlen32)) >= 0)
|
|
||||||
{
|
|
||||||
TRACE(" -> %i bytes\n", length);
|
|
||||||
|
|
||||||
#ifdef HAVE_IPX
|
uaddr=ws_sockaddr_alloc(from,fromlen,&uaddrlen);
|
||||||
if (from && ((struct sockaddr_ipx *)from)->sipx_family == AF_IPX) {
|
length=recvfrom(fd, buf, len, flags, uaddr, &uaddrlen);
|
||||||
from = (struct sockaddr *)
|
if (length < 0)
|
||||||
malloc(fromlen32 ? *fromlen32 : sizeof(*from2));
|
{
|
||||||
memcpy(from, from2, fromlen32 ? *fromlen32 : sizeof(*from2));
|
SetLastError(wsaErrno());
|
||||||
from2->sipx_family = WS_AF_IPX;
|
WARN(" -> ERROR\n");
|
||||||
from2->sipx_network = ((struct sockaddr_ipx *)from)->sipx_network;
|
}
|
||||||
from2->sipx_port = ((struct sockaddr_ipx *)from)->sipx_port;
|
else if (ws_sockaddr_u2ws(uaddr,uaddrlen,from,fromlen) != 0)
|
||||||
memcpy(from2->sipx_node,
|
{
|
||||||
((struct sockaddr_ipx *)from)->sipx_node, IPX_NODE_LEN);
|
/* The from buffer was too small, but we read the data
|
||||||
free(from);
|
* anyway. Is that really bad?
|
||||||
}
|
*/
|
||||||
#endif
|
SetLastError(WSAEFAULT);
|
||||||
close(fd);
|
WARN(" -> WSAEFAULT\n");
|
||||||
_enable_event(s, FD_READ, 0, 0);
|
}
|
||||||
return length;
|
else
|
||||||
}
|
{
|
||||||
SetLastError(wsaErrno());
|
TRACE(" -> %i bytes\n", length);
|
||||||
close(fd);
|
_enable_event(s, FD_READ, 0, 0);
|
||||||
|
res=length;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
else SetLastError(WSAENOTSOCK);
|
else
|
||||||
WARN(" -> ERROR\n");
|
{
|
||||||
#ifdef HAVE_IPX
|
SetLastError(WSAENOTSOCK);
|
||||||
if (from && ((struct sockaddr_ipx *)from)->sipx_family == AF_IPX) {
|
WARN(" -> WSAENOTSOCK\n");
|
||||||
from = (struct sockaddr *)
|
|
||||||
malloc(fromlen32 ? *fromlen32 : sizeof(*from2));
|
|
||||||
memcpy(from, from2, fromlen32 ? *fromlen32 : sizeof(*from2));
|
|
||||||
from2->sipx_family = WS_AF_IPX;
|
|
||||||
from2->sipx_network = ((struct sockaddr_ipx *)from)->sipx_network;
|
|
||||||
from2->sipx_port = ((struct sockaddr_ipx *)from)->sipx_port;
|
|
||||||
memcpy(from2->sipx_node,
|
|
||||||
((struct sockaddr_ipx *)from)->sipx_node, IPX_NODE_LEN);
|
|
||||||
free(from);
|
|
||||||
}
|
}
|
||||||
#endif
|
return res;
|
||||||
return SOCKET_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* recvfrom (WINSOCK.17)
|
* recvfrom (WINSOCK.17)
|
||||||
*/
|
*/
|
||||||
INT16 WINAPI WINSOCK_recvfrom16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
|
INT16 WINAPI WINSOCK_recvfrom16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
|
||||||
struct sockaddr *from, INT16 *fromlen16)
|
ws_sockaddr *from, INT16 *fromlen16)
|
||||||
{
|
{
|
||||||
INT fromlen32;
|
INT fromlen32;
|
||||||
INT *p = &fromlen32;
|
INT *p = &fromlen32;
|
||||||
@ -1947,72 +2043,56 @@ INT16 WINAPI WINSOCK_send16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* sendto (WS2_32.20)
|
* sendto (WS2_32.20)
|
||||||
*/
|
*/
|
||||||
INT WINAPI WSOCK32_sendto(SOCKET s, char *buf, INT len, INT flags,
|
int WINAPI WSOCK32_sendto(SOCKET s, const char *buf, int len, int flags,
|
||||||
struct sockaddr *to, INT tolen)
|
const ws_sockaddr *to, int tolen)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IPX
|
|
||||||
struct ws_sockaddr_ipx* to2 = (struct ws_sockaddr_ipx *)to;
|
|
||||||
#endif
|
|
||||||
int fd = _get_sock_fd(s);
|
int fd = _get_sock_fd(s);
|
||||||
|
int res;
|
||||||
|
|
||||||
TRACE("socket %04x, ptr %p, length %d, flags %d\n", s, buf, len, flags);
|
TRACE("socket %04x, ptr %p, length %d, flags %d\n", s, buf, len, flags);
|
||||||
|
|
||||||
|
res=SOCKET_ERROR;
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
INT length;
|
const struct sockaddr* uaddr;
|
||||||
|
int uaddrlen;
|
||||||
|
|
||||||
if (to && ((struct ws_sockaddr_ipx *)to)->sipx_family == WS_AF_PUP)
|
uaddr=ws_sockaddr_ws2u(to,tolen,&uaddrlen);
|
||||||
((struct ws_sockaddr_ipx *)to)->sipx_family = AF_UNSPEC;
|
if (uaddr == NULL)
|
||||||
#ifdef HAVE_IPX
|
{
|
||||||
else if (to &&
|
SetLastError(WSAEFAULT);
|
||||||
((struct ws_sockaddr_ipx *)to)->sipx_family == WS_AF_IPX)
|
}
|
||||||
{
|
else
|
||||||
to = (struct sockaddr *) malloc(sizeof(struct sockaddr_ipx));
|
{
|
||||||
memset(to, '\0', sizeof(struct sockaddr_ipx));
|
if (_is_blocking(s))
|
||||||
((struct sockaddr_ipx *)to)->sipx_family = AF_IPX;
|
{
|
||||||
((struct sockaddr_ipx *)to)->sipx_port = to2->sipx_port;
|
/* block here */
|
||||||
((struct sockaddr_ipx *)to)->sipx_network = to2->sipx_network;
|
/* FIXME: exceptfds */
|
||||||
memcpy(((struct sockaddr_ipx *)to)->sipx_node,
|
do_block(fd, 2);
|
||||||
to2->sipx_node, IPX_NODE_LEN);
|
}
|
||||||
tolen = sizeof(struct sockaddr_ipx);
|
res=sendto(fd, buf, len, flags, uaddr, uaddrlen);
|
||||||
}
|
if (res < 0 )
|
||||||
#endif
|
{
|
||||||
if (_is_blocking(s))
|
SetLastError(wsaErrno());
|
||||||
{
|
if( GetLastError() == WSAEWOULDBLOCK )
|
||||||
/* block here */
|
_enable_event(s, FD_WRITE, 0, 0);
|
||||||
/* FIXME: exceptfds */
|
}
|
||||||
do_block(fd, 2);
|
ws_sockaddr_free(uaddr,to);
|
||||||
}
|
}
|
||||||
if ((length = sendto(fd, buf, len, flags, to, tolen)) < 0 )
|
close(fd);
|
||||||
{
|
|
||||||
SetLastError(wsaErrno());
|
|
||||||
if( GetLastError() == WSAEWOULDBLOCK )
|
|
||||||
_enable_event(s, FD_WRITE, 0, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#ifdef HAVE_IPX
|
|
||||||
if (to && ((struct sockaddr_ipx *)to)->sipx_family == AF_IPX) {
|
|
||||||
free(to);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
close(fd);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
else SetLastError(WSAENOTSOCK);
|
else
|
||||||
#ifdef HAVE_IPX
|
{
|
||||||
if (to && ((struct sockaddr_ipx *)to)->sipx_family == AF_IPX) {
|
SetLastError(WSAENOTSOCK);
|
||||||
free(to);
|
|
||||||
}
|
}
|
||||||
#endif
|
return res;
|
||||||
return SOCKET_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* sendto (WINSOCK.20)
|
* sendto (WINSOCK.20)
|
||||||
*/
|
*/
|
||||||
INT16 WINAPI WINSOCK_sendto16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
|
INT16 WINAPI WINSOCK_sendto16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
|
||||||
struct sockaddr *to, INT16 tolen)
|
ws_sockaddr *to, INT16 tolen)
|
||||||
{
|
{
|
||||||
return (INT16)WSOCK32_sendto( s, buf, len, flags, to, tolen );
|
return (INT16)WSOCK32_sendto( s, buf, len, flags, to, tolen );
|
||||||
}
|
}
|
||||||
|
@ -441,17 +441,6 @@ INT WINAPI WSARecvEx(SOCKET s, char *buf, INT len, INT *flags);
|
|||||||
|
|
||||||
#define WS_AF_MAX 27
|
#define WS_AF_MAX 27
|
||||||
|
|
||||||
#include "pshpack1.h"
|
|
||||||
|
|
||||||
struct ws_sockaddr_ipx
|
|
||||||
{
|
|
||||||
SHORT sipx_family;
|
|
||||||
UINT sipx_network;
|
|
||||||
CHAR sipx_node[6];
|
|
||||||
WORD sipx_port;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "poppack.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
/* WCIPX.H
|
/* WCIPX.H
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _WINE_WCIPX_
|
#ifndef _WINE_WSIPX_
|
||||||
#define _WINE_WCIPX_
|
#define _WINE_WSIPX_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* defined(__cplusplus) */
|
#endif /* defined(__cplusplus) */
|
||||||
|
|
||||||
|
typedef struct ws_sockaddr_ipx
|
||||||
|
{
|
||||||
|
short sa_family;
|
||||||
|
char sa_netnum[4];
|
||||||
|
char sa_nodenum[6];
|
||||||
|
unsigned short sa_socket;
|
||||||
|
} SOCKADDR_IPX, *PSOCKADDR_IPX, *LPSOCKADDR_IPX;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* constants
|
* constants
|
||||||
*/
|
*/
|
||||||
@ -20,4 +28,4 @@ extern "C" {
|
|||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif /* defined(__cplusplus) */
|
#endif /* defined(__cplusplus) */
|
||||||
|
|
||||||
#endif /* _WINE_WCIPX_ */
|
#endif /* _WINE_WSIPX_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user