Zebediah Figura : ws2_32: Use IOCTL_AFD_WINE_CONNECT in connect().
Alexandre Julliard
julliard at winehq.org
Tue May 18 15:42:37 CDT 2021
Module: wine
Branch: master
Commit: a891713f48fbcdae05f27f7e73b1cec78cf42644
URL: https://source.winehq.org/git/wine.git/?a=commit;h=a891713f48fbcdae05f27f7e73b1cec78cf42644
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Mon May 17 21:30:01 2021 -0500
ws2_32: Use IOCTL_AFD_WINE_CONNECT in connect().
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ws2_32/socket.c | 106 ++++++++++++++++++-----------------------------
dlls/ws2_32/tests/sock.c | 21 +---------
2 files changed, 43 insertions(+), 84 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 3a39493bc3b..889f0327baf 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1145,13 +1145,6 @@ static void _get_sock_errors(SOCKET s, int *events)
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)
{
int sock_type = -1;
@@ -2976,82 +2969,65 @@ int WINAPI WS_closesocket(SOCKET s)
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;
- 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)
- 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;
- if (memcmp(&in4->sin_addr, magic_loopback_addr, 4) == 0)
+ struct sockaddr_in *in4 = (struct sockaddr_in *)&uaddr;
+ if (!memcmp(&in4->sin_addr, magic_loopback_addr, sizeof(magic_loopback_addr)))
{
- /* Trying to connect to magic replace-loopback address,
- * assuming we really want to connect to localhost */
- TRACE("Trying to connect to magic IP address, using "
- "INADDR_LOOPBACK instead.\n");
+ TRACE("Replacing magic address 127.12.34.56 with INADDR_LOOPBACK.\n");
in4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
}
- if (connect(fd, &uaddr.addr, uaddrlen) == 0)
- 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 );
+ if (!(sync_event = get_sync_event())) return -1;
- 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;
- int ret = do_connect(fd, name, namelen);
- if (ret == 0)
- goto connect_success;
-
- if (ret == WSAEWOULDBLOCK)
- {
- /* tell wineserver that a connection is in progress */
- _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE,
- 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);
- _sync_sock_state(s); /* let wineserver notice connection */
- /* 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 );
- SetLastError(ret);
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return -1;
}
- return SOCKET_ERROR;
+ params->addr_len = uaddrlen;
+ params->synchronous = TRUE;
+ memcpy(params + 1, &uaddr, uaddrlen);
-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);
+ status = NtDeviceIoControlFile( (HANDLE)s, sync_event, NULL, NULL, &io, IOCTL_AFD_WINE_CONNECT,
+ params, sizeof(*params) + uaddrlen, NULL, 0);
+ HeapFree( GetProcessHeap(), 0, params );
+ if (status == STATUS_PENDING)
+ {
+ if (WaitForSingleObject( sync_event, INFINITE ) == WAIT_FAILED) return -1;
+ status = io.u.Status;
+ }
+ if (status)
+ {
+ SetLastError( NtStatusToWSAError( status ) );
+ return -1;
+ }
return 0;
}
+
/***********************************************************************
* WSAConnect (WS2_32.30)
*/
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 33cdd5d6d15..5028a4e749e 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -4159,7 +4159,7 @@ static void test_connect_events(struct event_test_ctx *ctx)
if (ctx->is_message)
check_events(ctx, FD_WRITE, 0, 200);
else
- check_events_todo(ctx, FD_CONNECT, FD_WRITE, 200);
+ check_events(ctx, FD_CONNECT, FD_WRITE, 200);
closesocket(client);
closesocket(server);
@@ -6117,25 +6117,8 @@ todo_wine
/* try to connect a socket that's being accepted into */
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());
- 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),
NULL, 0, &bytesReturned, &overlapped2);
More information about the wine-cvs
mailing list