Commit 5295cc27 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

ws2_32: Pass a Win32 socket address to IOCTL_AFD_WINE_CONNECT.

parent f0b42b2f
...@@ -1959,8 +1959,6 @@ int WINAPI WS_closesocket(SOCKET s) ...@@ -1959,8 +1959,6 @@ int WINAPI WS_closesocket(SOCKET s)
*/ */
int WINAPI WS_connect( SOCKET s, const struct WS_sockaddr *addr, int len ) int WINAPI WS_connect( SOCKET s, const struct WS_sockaddr *addr, int len )
{ {
union generic_unix_sockaddr uaddr;
unsigned int uaddrlen = ws_sockaddr_ws2u( addr, len, &uaddr );
struct afd_connect_params *params; struct afd_connect_params *params;
IO_STATUS_BLOCK io; IO_STATUS_BLOCK io;
HANDLE sync_event; HANDLE sync_event;
...@@ -1968,35 +1966,19 @@ int WINAPI WS_connect( SOCKET s, const struct WS_sockaddr *addr, int len ) ...@@ -1968,35 +1966,19 @@ int WINAPI WS_connect( SOCKET s, const struct WS_sockaddr *addr, int len )
TRACE( "socket %#lx, addr %s, len %d\n", s, debugstr_sockaddr(addr), len ); TRACE( "socket %#lx, addr %s, len %d\n", s, debugstr_sockaddr(addr), len );
if (!uaddrlen)
{
SetLastError( WSAEFAULT );
return -1;
}
if (addr->sa_family == WS_AF_INET)
{
struct sockaddr_in *in4 = (struct sockaddr_in *)&uaddr;
if (!memcmp(&in4->sin_addr, magic_loopback_addr, sizeof(magic_loopback_addr)))
{
TRACE("Replacing magic address 127.12.34.56 with INADDR_LOOPBACK.\n");
in4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
}
if (!(sync_event = get_sync_event())) return -1; if (!(sync_event = get_sync_event())) return -1;
if (!(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + uaddrlen ))) if (!(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + len )))
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return -1; return -1;
} }
params->addr_len = uaddrlen; params->addr_len = len;
params->synchronous = TRUE; params->synchronous = TRUE;
memcpy(params + 1, &uaddr, uaddrlen); memcpy( params + 1, addr, len );
status = NtDeviceIoControlFile( (HANDLE)s, sync_event, NULL, NULL, &io, IOCTL_AFD_WINE_CONNECT, status = NtDeviceIoControlFile( (HANDLE)s, sync_event, NULL, NULL, &io, IOCTL_AFD_WINE_CONNECT,
params, sizeof(*params) + uaddrlen, NULL, 0); params, sizeof(*params) + len, NULL, 0 );
HeapFree( GetProcessHeap(), 0, params ); HeapFree( GetProcessHeap(), 0, params );
if (status == STATUS_PENDING) if (status == STATUS_PENDING)
{ {
...@@ -2029,8 +2011,6 @@ int WINAPI WSAConnect( SOCKET s, const struct WS_sockaddr* name, int namelen, ...@@ -2029,8 +2011,6 @@ int WINAPI WSAConnect( SOCKET s, const struct WS_sockaddr* name, int namelen,
static BOOL WINAPI WS2_ConnectEx( SOCKET s, const struct WS_sockaddr *name, int namelen, static BOOL WINAPI WS2_ConnectEx( SOCKET s, const struct WS_sockaddr *name, int namelen,
void *send_buffer, DWORD send_len, DWORD *ret_len, OVERLAPPED *overlapped ) void *send_buffer, DWORD send_len, DWORD *ret_len, OVERLAPPED *overlapped )
{ {
union generic_unix_sockaddr uaddr;
unsigned int uaddrlen = ws_sockaddr_ws2u(name, namelen, &uaddr);
struct afd_connect_params *params; struct afd_connect_params *params;
void *cvalue = NULL; void *cvalue = NULL;
NTSTATUS status; NTSTATUS status;
...@@ -2060,35 +2040,19 @@ static BOOL WINAPI WS2_ConnectEx( SOCKET s, const struct WS_sockaddr *name, int ...@@ -2060,35 +2040,19 @@ static BOOL WINAPI WS2_ConnectEx( SOCKET s, const struct WS_sockaddr *name, int
overlapped->Internal = STATUS_PENDING; overlapped->Internal = STATUS_PENDING;
overlapped->InternalHigh = 0; overlapped->InternalHigh = 0;
if (!uaddrlen) if (!(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + namelen + send_len )))
{
SetLastError( WSAEFAULT );
return SOCKET_ERROR;
}
if (name->sa_family == WS_AF_INET)
{
struct sockaddr_in *in4 = (struct sockaddr_in *)&uaddr;
if (!memcmp( &in4->sin_addr, magic_loopback_addr, sizeof(magic_loopback_addr) ))
{
TRACE("Replacing magic address 127.12.34.56 with INADDR_LOOPBACK.\n");
in4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
}
if (!(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + uaddrlen + send_len )))
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return SOCKET_ERROR; return SOCKET_ERROR;
} }
params->addr_len = uaddrlen; params->addr_len = namelen;
params->synchronous = FALSE; params->synchronous = FALSE;
memcpy( params + 1, &uaddr, uaddrlen ); memcpy( params + 1, name, namelen );
memcpy( (char *)(params + 1) + uaddrlen, send_buffer, send_len ); memcpy( (char *)(params + 1) + namelen, send_buffer, send_len );
status = NtDeviceIoControlFile( SOCKET2HANDLE(s), overlapped->hEvent, NULL, cvalue, status = NtDeviceIoControlFile( SOCKET2HANDLE(s), overlapped->hEvent, NULL, cvalue,
(IO_STATUS_BLOCK *)overlapped, IOCTL_AFD_WINE_CONNECT, (IO_STATUS_BLOCK *)overlapped, IOCTL_AFD_WINE_CONNECT,
params, sizeof(*params) + uaddrlen + send_len, NULL, 0 ); params, sizeof(*params) + namelen + send_len, NULL, 0 );
HeapFree( GetProcessHeap(), 0, params ); HeapFree( GetProcessHeap(), 0, params );
if (ret_len) *ret_len = overlapped->InternalHigh; if (ret_len) *ret_len = overlapped->InternalHigh;
SetLastError( NtStatusToWSAError( status ) ); SetLastError( NtStatusToWSAError( status ) );
......
...@@ -173,7 +173,7 @@ struct afd_connect_params ...@@ -173,7 +173,7 @@ struct afd_connect_params
{ {
int addr_len; int addr_len;
int synchronous; int synchronous;
/* VARARG(addr, struct sockaddr, addr_len); */ /* VARARG(addr, struct WS(sockaddr), addr_len); */
/* VARARG(data, bytes); */ /* VARARG(data, bytes); */
}; };
......
...@@ -109,6 +109,8 @@ ...@@ -109,6 +109,8 @@
#define IP_UNICAST_IF 50 #define IP_UNICAST_IF 50
#endif #endif
static const char magic_loopback_addr[] = {127, 12, 34, 56};
union win_sockaddr union win_sockaddr
{ {
struct WS_sockaddr addr; struct WS_sockaddr addr;
...@@ -2109,8 +2111,8 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) ...@@ -2109,8 +2111,8 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
case IOCTL_AFD_WINE_CONNECT: case IOCTL_AFD_WINE_CONNECT:
{ {
const struct afd_connect_params *params = get_req_data(); const struct afd_connect_params *params = get_req_data();
const struct WS_sockaddr *addr;
union unix_sockaddr unix_addr; union unix_sockaddr unix_addr;
const struct sockaddr *addr;
struct connect_req *req; struct connect_req *req;
socklen_t unix_len; socklen_t unix_len;
int send_len, ret; int send_len, ret;
...@@ -2122,7 +2124,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) ...@@ -2122,7 +2124,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
return 0; return 0;
} }
send_len = get_req_data_size() - sizeof(*params) - params->addr_len; send_len = get_req_data_size() - sizeof(*params) - params->addr_len;
addr = (const struct sockaddr *)(params + 1); addr = (const struct WS_sockaddr *)(params + 1);
if (sock->accept_recv_req) if (sock->accept_recv_req)
{ {
...@@ -2144,7 +2146,16 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) ...@@ -2144,7 +2146,16 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
return 0; return 0;
} }
ret = connect( unix_fd, addr, params->addr_len ); unix_len = sockaddr_to_unix( addr, params->addr_len, &unix_addr );
if (!unix_len)
{
set_error( STATUS_INVALID_ADDRESS );
return 0;
}
if (unix_addr.addr.sa_family == AF_INET && !memcmp( &unix_addr.in.sin_addr, magic_loopback_addr, 4 ))
unix_addr.in.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
ret = connect( unix_fd, &unix_addr.addr, unix_len );
if (ret < 0 && errno != EINPROGRESS) if (ret < 0 && errno != EINPROGRESS)
{ {
set_error( sock_get_ntstatus( errno ) ); set_error( sock_get_ntstatus( errno ) );
...@@ -2427,8 +2438,6 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) ...@@ -2427,8 +2438,6 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
if (unix_addr.addr.sa_family == WS_AF_INET) if (unix_addr.addr.sa_family == WS_AF_INET)
{ {
static const char magic_loopback_addr[] = {127, 12, 34, 56};
if (!memcmp( &unix_addr.in.sin_addr, magic_loopback_addr, 4 ) if (!memcmp( &unix_addr.in.sin_addr, magic_loopback_addr, 4 )
|| bind_to_interface( sock, &unix_addr.in )) || bind_to_interface( sock, &unix_addr.in ))
bind_addr.in.sin_addr.s_addr = htonl( INADDR_ANY ); bind_addr.in.sin_addr.s_addr = htonl( INADDR_ANY );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment