Commit a891713f authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

ws2_32: Use IOCTL_AFD_WINE_CONNECT in connect().

parent d3b6c772
...@@ -1145,13 +1145,6 @@ static void _get_sock_errors(SOCKET s, int *events) ...@@ -1145,13 +1145,6 @@ static void _get_sock_errors(SOCKET s, int *events)
SERVER_END_REQ; SERVER_END_REQ;
} }
static int get_sock_error(SOCKET s, unsigned int bit)
{
int events[FD_MAX_EVENTS];
_get_sock_errors(s, events);
return events[bit];
}
static int _get_fd_type(int fd) static int _get_fd_type(int fd)
{ {
int sock_type = -1; int sock_type = -1;
...@@ -2976,82 +2969,65 @@ int WINAPI WS_closesocket(SOCKET s) ...@@ -2976,82 +2969,65 @@ int WINAPI WS_closesocket(SOCKET s)
return res; return res;
} }
static int do_connect(int fd, const struct WS_sockaddr* name, int namelen)
/***********************************************************************
* connect (ws2_32.4)
*/
int WINAPI WS_connect( SOCKET s, const struct WS_sockaddr *addr, int len )
{ {
union generic_unix_sockaddr uaddr; union generic_unix_sockaddr uaddr;
unsigned int uaddrlen = ws_sockaddr_ws2u(name, namelen, &uaddr); unsigned int uaddrlen = ws_sockaddr_ws2u( addr, len, &uaddr );
struct afd_connect_params *params;
IO_STATUS_BLOCK io;
HANDLE sync_event;
NTSTATUS status;
TRACE( "socket %#lx, addr %s, len %d\n", s, debugstr_sockaddr(addr), len );
if (!uaddrlen) if (!uaddrlen)
return WSAEFAULT; {
SetLastError( WSAEFAULT );
return -1;
}
if (name->sa_family == WS_AF_INET) if (addr->sa_family == WS_AF_INET)
{ {
struct sockaddr_in *in4 = (struct sockaddr_in*) &uaddr; struct sockaddr_in *in4 = (struct sockaddr_in *)&uaddr;
if (memcmp(&in4->sin_addr, magic_loopback_addr, 4) == 0) if (!memcmp(&in4->sin_addr, magic_loopback_addr, sizeof(magic_loopback_addr)))
{ {
/* Trying to connect to magic replace-loopback address, TRACE("Replacing magic address 127.12.34.56 with INADDR_LOOPBACK.\n");
* assuming we really want to connect to localhost */
TRACE("Trying to connect to magic IP address, using "
"INADDR_LOOPBACK instead.\n");
in4->sin_addr.s_addr = htonl(INADDR_LOOPBACK); in4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
} }
} }
if (connect(fd, &uaddr.addr, uaddrlen) == 0) if (!(sync_event = get_sync_event())) return -1;
return 0;
return wsaErrno();
}
/***********************************************************************
* connect (WS2_32.4)
*/
int WINAPI WS_connect(SOCKET s, const struct WS_sockaddr* name, int namelen)
{
int fd = get_sock_fd( s, FILE_READ_DATA, NULL );
TRACE("socket %04lx, ptr %p %s, length %d\n", s, name, debugstr_sockaddr(name), namelen);
if (fd != -1) if (!(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + uaddrlen )))
{ {
BOOL is_blocking; SetLastError( ERROR_NOT_ENOUGH_MEMORY );
int ret = do_connect(fd, name, namelen); return -1;
if (ret == 0) }
goto connect_success; params->addr_len = uaddrlen;
params->synchronous = TRUE;
memcpy(params + 1, &uaddr, uaddrlen);
if (ret == WSAEWOULDBLOCK) status = NtDeviceIoControlFile( (HANDLE)s, sync_event, NULL, NULL, &io, IOCTL_AFD_WINE_CONNECT,
{ params, sizeof(*params) + uaddrlen, NULL, 0);
/* tell wineserver that a connection is in progress */ HeapFree( GetProcessHeap(), 0, params );
_enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE, if (status == STATUS_PENDING)
FD_CONNECT,
FD_WINE_CONNECTED|FD_WINE_LISTENING);
ret = sock_is_blocking( s, &is_blocking );
if (!ret)
{
if (is_blocking)
{ {
do_block(fd, POLLIN | POLLOUT, -1); if (WaitForSingleObject( sync_event, INFINITE ) == WAIT_FAILED) return -1;
_sync_sock_state(s); /* let wineserver notice connection */ status = io.u.Status;
/* retrieve any error codes from it */
if (!(ret = get_sock_error(s, FD_CONNECT_BIT))) goto connect_success;
}
else ret = WSAEWOULDBLOCK;
}
} }
release_sock_fd( s, fd ); if (status)
SetLastError(ret); {
SetLastError( NtStatusToWSAError( status ) );
return -1;
} }
return SOCKET_ERROR;
connect_success:
release_sock_fd( s, fd );
_enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
FD_WINE_CONNECTED|FD_READ|FD_WRITE,
FD_CONNECT|FD_WINE_LISTENING);
TRACE("\tconnected %04lx\n", s);
return 0; return 0;
} }
/*********************************************************************** /***********************************************************************
* WSAConnect (WS2_32.30) * WSAConnect (WS2_32.30)
*/ */
......
...@@ -4159,7 +4159,7 @@ static void test_connect_events(struct event_test_ctx *ctx) ...@@ -4159,7 +4159,7 @@ static void test_connect_events(struct event_test_ctx *ctx)
if (ctx->is_message) if (ctx->is_message)
check_events(ctx, FD_WRITE, 0, 200); check_events(ctx, FD_WRITE, 0, 200);
else else
check_events_todo(ctx, FD_CONNECT, FD_WRITE, 200); check_events(ctx, FD_CONNECT, FD_WRITE, 200);
closesocket(client); closesocket(client);
closesocket(server); closesocket(server);
...@@ -6117,25 +6117,8 @@ todo_wine ...@@ -6117,25 +6117,8 @@ todo_wine
/* try to connect a socket that's being accepted into */ /* try to connect a socket that's being accepted into */
iret = connect(acceptor, (struct sockaddr*)&bindAddress, sizeof(bindAddress)); iret = connect(acceptor, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
todo_wine ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL, ok(iret == SOCKET_ERROR && WSAGetLastError() == WSAEINVAL,
"connecting to acceptex acceptor succeeded? return %d + errno %d\n", iret, WSAGetLastError()); "connecting to acceptex acceptor succeeded? return %d + errno %d\n", iret, WSAGetLastError());
if (!iret || (iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)) {
/* We need to cancel this call, otherwise things fail */
closesocket(acceptor);
acceptor = socket(AF_INET, SOCK_STREAM, 0);
ok(acceptor != INVALID_SOCKET, "failed to create socket, error %u\n", GetLastError());
bret = CancelIo((HANDLE) listener);
ok(bret, "Failed to cancel failed test. Bailing...\n");
if (!bret) return;
overlapped.Internal = 0xdeadbeef;
bret = pAcceptEx(listener, acceptor, buffer, 0,
sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
&bytesReturned, &overlapped);
ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
ok(overlapped.Internal == STATUS_PENDING, "got %08x\n", (ULONG)overlapped.Internal);
}
bret = pConnectEx(acceptor, (struct sockaddr *)&bindAddress, sizeof(bindAddress), bret = pConnectEx(acceptor, (struct sockaddr *)&bindAddress, sizeof(bindAddress),
NULL, 0, &bytesReturned, &overlapped2); NULL, 0, &bytesReturned, &overlapped2);
......
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