ws2_32: Pass a Win32 socket address to IOCTL_AFD_WINE_CONNECT.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-06-16 23:33:10 -05:00 committed by Alexandre Julliard
parent f0b42b2ffa
commit 5295cc273e
3 changed files with 24 additions and 51 deletions

View File

@ -1959,8 +1959,6 @@ int WINAPI WS_closesocket(SOCKET s)
*/
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;
IO_STATUS_BLOCK io;
HANDLE sync_event;
@ -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 );
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 (!(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + uaddrlen )))
if (!(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + len )))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return -1;
}
params->addr_len = uaddrlen;
params->addr_len = len;
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,
params, sizeof(*params) + uaddrlen, NULL, 0);
params, sizeof(*params) + len, NULL, 0 );
HeapFree( GetProcessHeap(), 0, params );
if (status == STATUS_PENDING)
{
@ -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,
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;
void *cvalue = NULL;
NTSTATUS status;
@ -2060,35 +2040,19 @@ static BOOL WINAPI WS2_ConnectEx( SOCKET s, const struct WS_sockaddr *name, int
overlapped->Internal = STATUS_PENDING;
overlapped->InternalHigh = 0;
if (!uaddrlen)
{
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 )))
if (!(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + namelen + send_len )))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return SOCKET_ERROR;
}
params->addr_len = uaddrlen;
params->addr_len = namelen;
params->synchronous = FALSE;
memcpy( params + 1, &uaddr, uaddrlen );
memcpy( (char *)(params + 1) + uaddrlen, send_buffer, send_len );
memcpy( params + 1, name, namelen );
memcpy( (char *)(params + 1) + namelen, send_buffer, send_len );
status = NtDeviceIoControlFile( SOCKET2HANDLE(s), overlapped->hEvent, NULL, cvalue,
(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 );
if (ret_len) *ret_len = overlapped->InternalHigh;
SetLastError( NtStatusToWSAError( status ) );

View File

@ -173,7 +173,7 @@ struct afd_connect_params
{
int addr_len;
int synchronous;
/* VARARG(addr, struct sockaddr, addr_len); */
/* VARARG(addr, struct WS(sockaddr), addr_len); */
/* VARARG(data, bytes); */
};

View File

@ -109,6 +109,8 @@
#define IP_UNICAST_IF 50
#endif
static const char magic_loopback_addr[] = {127, 12, 34, 56};
union win_sockaddr
{
struct WS_sockaddr addr;
@ -2109,8 +2111,8 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
case IOCTL_AFD_WINE_CONNECT:
{
const struct afd_connect_params *params = get_req_data();
const struct WS_sockaddr *addr;
union unix_sockaddr unix_addr;
const struct sockaddr *addr;
struct connect_req *req;
socklen_t unix_len;
int send_len, ret;
@ -2122,7 +2124,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
return 0;
}
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)
{
@ -2144,7 +2146,16 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
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)
{
set_error( sock_get_ntstatus( errno ) );
@ -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)
{
static const char magic_loopback_addr[] = {127, 12, 34, 56};
if (!memcmp( &unix_addr.in.sin_addr, magic_loopback_addr, 4 )
|| bind_to_interface( sock, &unix_addr.in ))
bind_addr.in.sin_addr.s_addr = htonl( INADDR_ANY );