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 "winuser.h"
|
||||
#include "winsock2.h"
|
||||
#include "wsipx.h"
|
||||
#include "wine/winsock16.h"
|
||||
#include "winnt.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_pe(struct protoent* p_pe, 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_protoent;
|
||||
|
@ -736,10 +738,13 @@ static struct ws_protoent* check_buffer_pe(int size)
|
|||
|
||||
/* ----------------------------------- i/o APIs */
|
||||
|
||||
/***********************************************************************
|
||||
* accept (WS2_32.1)
|
||||
*/
|
||||
static void WSOCK32_async_accept(SOCKET s, SOCKET as)
|
||||
#ifdef HAVE_IPX
|
||||
#define SUPPORTED_PF(pf) ((pf)==AF_INET || (pf)== AF_IPX)
|
||||
#else
|
||||
#define SUPPORTED_PF(pf) ((pf)==AF_INET)
|
||||
#endif
|
||||
|
||||
static void ws2_async_accept(SOCKET s, SOCKET as)
|
||||
{
|
||||
int q;
|
||||
/* 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,
|
||||
INT *addrlen32)
|
||||
/* Returns the converted address if successful, NULL if it was too small to
|
||||
* 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
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
TRACE("socket %04x\n", (UINT16)s );
|
||||
|
@ -790,37 +913,23 @@ SOCKET WINAPI WSOCK32_accept(SOCKET s, struct sockaddr *addr,
|
|||
if (as)
|
||||
{
|
||||
unsigned omask = _get_sock_mask( s );
|
||||
int fd = _get_sock_fd( as );
|
||||
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);
|
||||
WSOCK32_getpeername(fd, addr, addrlen32);
|
||||
if (omask & FD_WINE_SERVEVENT)
|
||||
WSOCK32_async_accept(s, as);
|
||||
ws2_async_accept(s, as);
|
||||
return as;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(WSAENOTSOCK);
|
||||
}
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* accept (WINSOCK.1)
|
||||
*/
|
||||
SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, struct sockaddr* addr,
|
||||
SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, ws_sockaddr* addr,
|
||||
INT16* addrlen16 )
|
||||
{
|
||||
INT addrlen32 = addrlen16 ? *addrlen16 : 0;
|
||||
|
@ -832,80 +941,73 @@ SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, struct sockaddr* addr,
|
|||
/***********************************************************************
|
||||
* 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 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
|
||||
dump_sockaddr(name);
|
||||
#endif
|
||||
|
||||
res=SOCKET_ERROR;
|
||||
if (fd != -1)
|
||||
{
|
||||
/* FIXME: what family does this really map to on the Unix side? */
|
||||
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 (!name || !SUPPORTED_PF(name->sa_family))
|
||||
{
|
||||
if ( bind(fd, name, namelen) < 0 )
|
||||
{
|
||||
int loc_errno = errno;
|
||||
WARN("\tfailure - errno = %i\n", errno);
|
||||
errno = loc_errno;
|
||||
switch(errno)
|
||||
{
|
||||
case EBADF: SetLastError(WSAENOTSOCK); break;
|
||||
case EADDRNOTAVAIL: SetLastError(WSAEINVAL); break;
|
||||
default: SetLastError(wsaErrno());break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_IPX
|
||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
||||
free(name);
|
||||
#endif
|
||||
close(fd);
|
||||
return 0; /* success */
|
||||
}
|
||||
} else SetLastError(WSAEAFNOSUPPORT);
|
||||
} else SetLastError(WSAEFAULT);
|
||||
#ifdef HAVE_IPX
|
||||
if (name && ((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
||||
free(name);
|
||||
#endif
|
||||
close(fd);
|
||||
SetLastError(WSAEAFNOSUPPORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
const struct sockaddr* uaddr;
|
||||
int uaddrlen;
|
||||
|
||||
uaddr=ws_sockaddr_ws2u(name,namelen,&uaddrlen);
|
||||
if (uaddr == NULL)
|
||||
{
|
||||
SetLastError(WSAEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bind(fd, uaddr, uaddrlen) < 0)
|
||||
{
|
||||
int loc_errno = errno;
|
||||
WARN("\tfailure - errno = %i\n", errno);
|
||||
errno = loc_errno;
|
||||
switch (errno)
|
||||
{
|
||||
case EBADF:
|
||||
SetLastError(WSAENOTSOCK);
|
||||
break;
|
||||
case EADDRNOTAVAIL:
|
||||
SetLastError(WSAEINVAL);
|
||||
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)
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
|
@ -931,89 +1033,85 @@ INT16 WINAPI WINSOCK_closesocket16(SOCKET16 s)
|
|||
/***********************************************************************
|
||||
* 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
|
||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
||||
#endif
|
||||
int fd = _get_sock_fd(s);
|
||||
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
|
||||
dump_sockaddr(name);
|
||||
dump_sockaddr(name);
|
||||
#endif
|
||||
|
||||
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)
|
||||
if (fd != -1)
|
||||
{
|
||||
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 (connect(fd, name, namelen) == 0) {
|
||||
close(fd);
|
||||
goto connect_success;
|
||||
}
|
||||
if (errno == EINPROGRESS)
|
||||
{
|
||||
/* tell wineserver that a connection is in progress */
|
||||
_enable_event(s, FD_CONNECT|FD_READ|FD_WRITE,
|
||||
FD_CONNECT|FD_READ|FD_WRITE,
|
||||
FD_WINE_CONNECTED|FD_WINE_LISTENING);
|
||||
if (_is_blocking(s))
|
||||
{
|
||||
int result;
|
||||
/* block here */
|
||||
do_block(fd, 7);
|
||||
_sync_sock_state(s); /* let wineserver notice connection */
|
||||
/* retrieve any error codes from it */
|
||||
result = _get_sock_error(s, FD_CONNECT_BIT);
|
||||
if (result)
|
||||
SetLastError(result);
|
||||
else {
|
||||
close(fd);
|
||||
goto connect_success;
|
||||
}
|
||||
}
|
||||
else SetLastError(WSAEWOULDBLOCK);
|
||||
close(fd);
|
||||
const struct sockaddr* uaddr;
|
||||
int uaddrlen;
|
||||
|
||||
uaddr=ws_sockaddr_ws2u(name,namelen,&uaddrlen);
|
||||
if (uaddr == NULL)
|
||||
{
|
||||
SetLastError(WSAEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc=connect(fd, uaddr, uaddrlen);
|
||||
ws_sockaddr_free(uaddr,name);
|
||||
if (rc == 0)
|
||||
goto connect_success;
|
||||
}
|
||||
|
||||
if (errno == EINPROGRESS)
|
||||
{
|
||||
/* tell wineserver that a connection is in progress */
|
||||
_enable_event(s, FD_CONNECT|FD_READ|FD_WRITE,
|
||||
FD_CONNECT|FD_READ|FD_WRITE,
|
||||
FD_WINE_CONNECTED|FD_WINE_LISTENING);
|
||||
if (_is_blocking(s))
|
||||
{
|
||||
int result;
|
||||
/* block here */
|
||||
do_block(fd, 7);
|
||||
_sync_sock_state(s); /* let wineserver notice connection */
|
||||
/* retrieve any error codes from it */
|
||||
result = _get_sock_error(s, FD_CONNECT_BIT);
|
||||
if (result)
|
||||
SetLastError(result);
|
||||
else
|
||||
{
|
||||
goto connect_success;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(WSAEWOULDBLOCK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(wsaErrno());
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(wsaErrno());
|
||||
close(fd);
|
||||
SetLastError(WSAENOTSOCK);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPX
|
||||
if (name && ((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
||||
free(name);
|
||||
#endif
|
||||
return SOCKET_ERROR;
|
||||
return SOCKET_ERROR;
|
||||
|
||||
connect_success:
|
||||
#ifdef HAVE_IPX
|
||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
||||
free(name);
|
||||
#endif
|
||||
close(fd);
|
||||
_enable_event(s, FD_CONNECT|FD_READ|FD_WRITE,
|
||||
FD_WINE_CONNECTED|FD_READ|FD_WRITE,
|
||||
FD_CONNECT|FD_WINE_LISTENING);
|
||||
return 0;
|
||||
FD_WINE_CONNECTED|FD_READ|FD_WRITE,
|
||||
FD_CONNECT|FD_WINE_LISTENING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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 );
|
||||
}
|
||||
|
@ -1021,44 +1119,47 @@ INT16 WINAPI WINSOCK_connect16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
|
|||
/***********************************************************************
|
||||
* getpeername (WS2_32.5)
|
||||
*/
|
||||
INT WINAPI WSOCK32_getpeername(SOCKET s, struct sockaddr *name,
|
||||
INT *namelen)
|
||||
int WINAPI WSOCK32_getpeername(SOCKET s, 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 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 (getpeername(fd, name, namelen) == 0) {
|
||||
#ifdef HAVE_IPX
|
||||
if (((struct ws_sockaddr_ipx *)name)->sipx_family == AF_IPX) {
|
||||
name = (struct sockaddr *)
|
||||
malloc(namelen ? *namelen : sizeof(*name2));
|
||||
memcpy(name, name2, namelen ? *namelen : sizeof(*name2));
|
||||
name2->sipx_family = WS_AF_IPX;
|
||||
name2->sipx_network = ((struct sockaddr_ipx *)name)->sipx_network;
|
||||
name2->sipx_port = ((struct sockaddr_ipx *)name)->sipx_port;
|
||||
memcpy(name2->sipx_node,
|
||||
((struct sockaddr_ipx *)name)->sipx_node, IPX_NODE_LEN);
|
||||
free(name);
|
||||
}
|
||||
#endif
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
SetLastError(wsaErrno());
|
||||
close(fd);
|
||||
struct sockaddr* uaddr;
|
||||
int uaddrlen;
|
||||
|
||||
uaddr=ws_sockaddr_alloc(name,namelen,&uaddrlen);
|
||||
if (getpeername(fd, uaddr, &uaddrlen) != 0)
|
||||
{
|
||||
SetLastError(wsaErrno());
|
||||
}
|
||||
else if (ws_sockaddr_u2ws(uaddr,uaddrlen,name,namelen) != 0)
|
||||
{
|
||||
/* The buffer was too small */
|
||||
SetLastError(WSAEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
res=0;
|
||||
}
|
||||
ws_sockaddr_free(uaddr,name);
|
||||
close(fd);
|
||||
}
|
||||
return SOCKET_ERROR;
|
||||
else
|
||||
{
|
||||
SetLastError(WSAENOTSOCK);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* getpeername (WINSOCK.5)
|
||||
*/
|
||||
INT16 WINAPI WINSOCK_getpeername16(SOCKET16 s, struct sockaddr *name,
|
||||
INT16 WINAPI WINSOCK_getpeername16(SOCKET16 s, ws_sockaddr *name,
|
||||
INT16 *namelen16)
|
||||
{
|
||||
INT namelen32 = *namelen16;
|
||||
|
@ -1075,44 +1176,46 @@ INT16 WINAPI WINSOCK_getpeername16(SOCKET16 s, struct sockaddr *name,
|
|||
/***********************************************************************
|
||||
* getsockname (WS2_32.6)
|
||||
*/
|
||||
INT WINAPI WSOCK32_getsockname(SOCKET s, struct sockaddr *name,
|
||||
INT *namelen)
|
||||
int WINAPI WSOCK32_getsockname(SOCKET s, 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 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 (getsockname(fd, name, namelen) == 0) {
|
||||
#ifdef HAVE_IPX
|
||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX) {
|
||||
name = (struct sockaddr *)
|
||||
malloc(namelen ? *namelen : sizeof(*name2));
|
||||
memcpy(name, name2, namelen ? *namelen : sizeof(*name2));
|
||||
name2->sipx_family = WS_AF_IPX;
|
||||
name2->sipx_network = ((struct sockaddr_ipx *)name)->sipx_network;
|
||||
name2->sipx_port = ((struct sockaddr_ipx *)name)->sipx_port;
|
||||
memcpy(name2->sipx_node,
|
||||
((struct sockaddr_ipx *)name)->sipx_node, IPX_NODE_LEN);
|
||||
free(name);
|
||||
}
|
||||
#endif
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
SetLastError(wsaErrno());
|
||||
close(fd);
|
||||
struct sockaddr* uaddr;
|
||||
int uaddrlen;
|
||||
|
||||
uaddr=ws_sockaddr_alloc(name,namelen,&uaddrlen);
|
||||
if (getsockname(fd, uaddr, &uaddrlen) != 0)
|
||||
{
|
||||
SetLastError(wsaErrno());
|
||||
}
|
||||
else if (ws_sockaddr_u2ws(uaddr,uaddrlen,name,namelen) != 0)
|
||||
{
|
||||
/* The buffer was too small */
|
||||
SetLastError(WSAEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
res=0;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
return SOCKET_ERROR;
|
||||
else
|
||||
{
|
||||
SetLastError(WSAENOTSOCK);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* getsockname (WINSOCK.6)
|
||||
*/
|
||||
INT16 WINAPI WINSOCK_getsockname16(SOCKET16 s, struct sockaddr *name,
|
||||
INT16 WINAPI WINSOCK_getsockname16(SOCKET16 s, ws_sockaddr *name,
|
||||
INT16 *namelen16)
|
||||
{
|
||||
INT retVal;
|
||||
|
@ -1684,77 +1787,70 @@ INT16 WINAPI WINSOCK_recv16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
|
|||
/***********************************************************************
|
||||
* recvfrom (WS2_32.17)
|
||||
*/
|
||||
INT WINAPI WSOCK32_recvfrom(SOCKET s, char *buf, INT len, INT flags,
|
||||
struct sockaddr *from, INT *fromlen32)
|
||||
int WINAPI WSOCK32_recvfrom(SOCKET s, char *buf, INT len, int flags,
|
||||
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 res;
|
||||
|
||||
TRACE("socket %04x, ptr %08x, len %d, flags %d\n", s, (unsigned)buf, len, flags);
|
||||
#if DEBUG_SOCKADDR
|
||||
if( from ) dump_sockaddr(from);
|
||||
else DPRINTF("from = NULL\n");
|
||||
if (from)
|
||||
dump_sockaddr(from);
|
||||
else
|
||||
DPRINTF("from = NULL\n");
|
||||
#endif
|
||||
|
||||
res=SOCKET_ERROR;
|
||||
if (fd != -1)
|
||||
{
|
||||
int length;
|
||||
struct sockaddr* uaddr;
|
||||
int uaddrlen;
|
||||
int length;
|
||||
|
||||
if (_is_blocking(s))
|
||||
{
|
||||
/* block here */
|
||||
/* FIXME: OOB and exceptfds */
|
||||
do_block(fd, 1);
|
||||
}
|
||||
if ((length = recvfrom(fd, buf, len, flags, from, fromlen32)) >= 0)
|
||||
{
|
||||
TRACE(" -> %i bytes\n", length);
|
||||
if (_is_blocking(s))
|
||||
{
|
||||
/* block here */
|
||||
/* FIXME: OOB and exceptfds */
|
||||
do_block(fd, 1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPX
|
||||
if (from && ((struct sockaddr_ipx *)from)->sipx_family == AF_IPX) {
|
||||
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
|
||||
close(fd);
|
||||
_enable_event(s, FD_READ, 0, 0);
|
||||
return length;
|
||||
}
|
||||
SetLastError(wsaErrno());
|
||||
close(fd);
|
||||
uaddr=ws_sockaddr_alloc(from,fromlen,&uaddrlen);
|
||||
length=recvfrom(fd, buf, len, flags, uaddr, &uaddrlen);
|
||||
if (length < 0)
|
||||
{
|
||||
SetLastError(wsaErrno());
|
||||
WARN(" -> ERROR\n");
|
||||
}
|
||||
else if (ws_sockaddr_u2ws(uaddr,uaddrlen,from,fromlen) != 0)
|
||||
{
|
||||
/* The from buffer was too small, but we read the data
|
||||
* anyway. Is that really bad?
|
||||
*/
|
||||
SetLastError(WSAEFAULT);
|
||||
WARN(" -> WSAEFAULT\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE(" -> %i bytes\n", length);
|
||||
_enable_event(s, FD_READ, 0, 0);
|
||||
res=length;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
else SetLastError(WSAENOTSOCK);
|
||||
WARN(" -> ERROR\n");
|
||||
#ifdef HAVE_IPX
|
||||
if (from && ((struct sockaddr_ipx *)from)->sipx_family == AF_IPX) {
|
||||
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);
|
||||
else
|
||||
{
|
||||
SetLastError(WSAENOTSOCK);
|
||||
WARN(" -> WSAENOTSOCK\n");
|
||||
}
|
||||
#endif
|
||||
return SOCKET_ERROR;
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* recvfrom (WINSOCK.17)
|
||||
*/
|
||||
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 *p = &fromlen32;
|
||||
|
@ -1947,72 +2043,56 @@ INT16 WINAPI WINSOCK_send16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
|
|||
/***********************************************************************
|
||||
* sendto (WS2_32.20)
|
||||
*/
|
||||
INT WINAPI WSOCK32_sendto(SOCKET s, char *buf, INT len, INT flags,
|
||||
struct sockaddr *to, INT tolen)
|
||||
int WINAPI WSOCK32_sendto(SOCKET s, const char *buf, int len, int flags,
|
||||
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 res;
|
||||
|
||||
TRACE("socket %04x, ptr %p, length %d, flags %d\n", s, buf, len, flags);
|
||||
|
||||
res=SOCKET_ERROR;
|
||||
if (fd != -1)
|
||||
{
|
||||
INT length;
|
||||
const struct sockaddr* uaddr;
|
||||
int uaddrlen;
|
||||
|
||||
if (to && ((struct ws_sockaddr_ipx *)to)->sipx_family == WS_AF_PUP)
|
||||
((struct ws_sockaddr_ipx *)to)->sipx_family = AF_UNSPEC;
|
||||
#ifdef HAVE_IPX
|
||||
else if (to &&
|
||||
((struct ws_sockaddr_ipx *)to)->sipx_family == WS_AF_IPX)
|
||||
{
|
||||
to = (struct sockaddr *) malloc(sizeof(struct sockaddr_ipx));
|
||||
memset(to, '\0', sizeof(struct sockaddr_ipx));
|
||||
((struct sockaddr_ipx *)to)->sipx_family = AF_IPX;
|
||||
((struct sockaddr_ipx *)to)->sipx_port = to2->sipx_port;
|
||||
((struct sockaddr_ipx *)to)->sipx_network = to2->sipx_network;
|
||||
memcpy(((struct sockaddr_ipx *)to)->sipx_node,
|
||||
to2->sipx_node, IPX_NODE_LEN);
|
||||
tolen = sizeof(struct sockaddr_ipx);
|
||||
}
|
||||
#endif
|
||||
if (_is_blocking(s))
|
||||
{
|
||||
/* block here */
|
||||
/* FIXME: exceptfds */
|
||||
do_block(fd, 2);
|
||||
}
|
||||
if ((length = sendto(fd, buf, len, flags, to, tolen)) < 0 )
|
||||
{
|
||||
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);
|
||||
uaddr=ws_sockaddr_ws2u(to,tolen,&uaddrlen);
|
||||
if (uaddr == NULL)
|
||||
{
|
||||
SetLastError(WSAEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_is_blocking(s))
|
||||
{
|
||||
/* block here */
|
||||
/* FIXME: exceptfds */
|
||||
do_block(fd, 2);
|
||||
}
|
||||
res=sendto(fd, buf, len, flags, uaddr, uaddrlen);
|
||||
if (res < 0 )
|
||||
{
|
||||
SetLastError(wsaErrno());
|
||||
if( GetLastError() == WSAEWOULDBLOCK )
|
||||
_enable_event(s, FD_WRITE, 0, 0);
|
||||
}
|
||||
ws_sockaddr_free(uaddr,to);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
else SetLastError(WSAENOTSOCK);
|
||||
#ifdef HAVE_IPX
|
||||
if (to && ((struct sockaddr_ipx *)to)->sipx_family == AF_IPX) {
|
||||
free(to);
|
||||
else
|
||||
{
|
||||
SetLastError(WSAENOTSOCK);
|
||||
}
|
||||
#endif
|
||||
return SOCKET_ERROR;
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* sendto (WINSOCK.20)
|
||||
*/
|
||||
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 );
|
||||
}
|
||||
|
|
|
@ -441,17 +441,6 @@ INT WINAPI WSARecvEx(SOCKET s, char *buf, INT len, INT *flags);
|
|||
|
||||
#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
|
||||
}
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
/* WCIPX.H
|
||||
*/
|
||||
|
||||
#ifndef _WINE_WCIPX_
|
||||
#define _WINE_WCIPX_
|
||||
#ifndef _WINE_WSIPX_
|
||||
#define _WINE_WSIPX_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#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
|
||||
*/
|
||||
|
@ -20,4 +28,4 @@ extern "C" {
|
|||
} /* extern "C" */
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif /* _WINE_WCIPX_ */
|
||||
#endif /* _WINE_WSIPX_ */
|
||||
|
|
Loading…
Reference in New Issue