server: Report AFD_POLL_CONNECT_ERR if a previous connection attempt failed.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51331
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51366
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-07-05 19:14:19 -05:00 committed by Alexandre Julliard
parent c86ba5d09d
commit 53e69130cc
3 changed files with 37 additions and 38 deletions

View file

@ -464,30 +464,24 @@ static void test_poll(void)
memset(out_params, 0xcc, sizeof(out_buffer));
ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
todo_wine
{
ok(!ret, "got %#x\n", ret);
ok(!io.Status, "got %#x\n", io.Status);
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
ok(out_params->count == 1, "got count %u\n", out_params->count);
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
}
ok(!ret, "got %#x\n", ret);
ok(!io.Status, "got %#x\n", io.Status);
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
ok(out_params->count == 1, "got count %u\n", out_params->count);
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
memset(out_params, 0xcc, sizeof(out_buffer));
ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
todo_wine
{
ok(!ret, "got %#x\n", ret);
ok(!io.Status, "got %#x\n", io.Status);
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
ok(out_params->count == 1, "got count %u\n", out_params->count);
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
}
ok(!ret, "got %#x\n", ret);
ok(!io.Status, "got %#x\n", io.Status);
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
ok(out_params->count == 1, "got count %u\n", out_params->count);
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
ok(ret == -1, "got %d\n", ret);
@ -514,16 +508,13 @@ static void test_poll(void)
memset(out_params, 0xcc, sizeof(out_buffer));
ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
todo_wine
{
ok(!ret, "got %#x\n", ret);
ok(!io.Status, "got %#x\n", io.Status);
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
ok(out_params->count == 1, "got count %u\n", out_params->count);
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
}
ok(!ret, "got %#x\n", ret);
ok(!io.Status, "got %#x\n", io.Status);
ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
ok(out_params->count == 1, "got count %u\n", out_params->count);
ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
closesocket(client);
}

View file

@ -3263,8 +3263,8 @@ static void test_select(void)
FD_SET(fdWrite, &exceptfds);
select_timeout.tv_sec = 10;
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
todo_wine ok(ret == 1, "expected 1, got %d\n", ret);
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
ok(ret == 1, "expected 1, got %d\n", ret);
ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
ok(select_timeout.tv_usec == 250000, "select timeout should not have changed\n");
len = sizeof(id);
@ -3285,8 +3285,8 @@ static void test_select(void)
FD_SET(fdWrite, &exceptfds);
select_timeout.tv_sec = 10;
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
todo_wine ok(ret == 1, "got %d\n", ret);
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
ok(ret == 1, "got %d\n", ret);
ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
/* Calling connect() doesn't reset the socket error, but a successful
* connection does. This is kind of tricky to test, because while
@ -3315,8 +3315,8 @@ static void test_select(void)
FD_SET(fdWrite, &exceptfds);
select_timeout.tv_sec = 10;
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
todo_wine ok(ret == 1, "got %d\n", ret);
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
ok(ret == 1, "got %d\n", ret);
ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
len = sizeof(address);
ret = getsockname(fdListen, (struct sockaddr *)&address, &len);
@ -3362,8 +3362,8 @@ static void test_select(void)
FD_SET(fdWrite, &exceptfds);
select_timeout.tv_sec = 0;
ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
todo_wine ok(ret == 1, "expected 1, got %d\n", ret);
todo_wine ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
ok(ret == 1, "expected 1, got %d\n", ret);
ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
len = sizeof(id);
id = 0xdeadbeef;

View file

@ -2820,6 +2820,14 @@ static int poll_socket( struct sock *poll_sock, struct async *async, timeout_t t
output[i].flags = flags;
output[i].status = sock_get_ntstatus( sock_error( sock->fd ) );
}
/* FIXME: do other error conditions deserve a similar treatment? */
if (sock->state != SOCK_CONNECTING && sock->errors[AFD_POLL_BIT_CONNECT_ERR] && (mask & AFD_POLL_CONNECT_ERR))
{
req->iosb->status = STATUS_SUCCESS;
output[i].flags |= AFD_POLL_CONNECT_ERR;
output[i].status = sock_get_ntstatus( sock->errors[AFD_POLL_BIT_CONNECT_ERR] );
}
}
if (req->iosb->status != STATUS_PENDING)