ntdll: Fill the I/O status block with the results of the send_socket call in sock_send().
The server might change the status. In particular, if we got a short but nonzero write on a nonblocking socket, try_send() would return STATUS_DEVICE_NOT_READY and hence leave the I/O status block unfilled. The server subsequently massages this into STATUS_SUCECSS, causing a garbage size to be eventually returned from ws2_32 send(). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51439 Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9bc5bc7c66
commit
4c639d6926
|
@ -922,12 +922,6 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
|
|||
if (status == STATUS_DEVICE_NOT_READY && force_async)
|
||||
status = STATUS_PENDING;
|
||||
|
||||
if (!NT_ERROR(status))
|
||||
{
|
||||
io->Status = status;
|
||||
io->Information = async->sent_len;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( send_socket )
|
||||
{
|
||||
req->status = status;
|
||||
|
@ -936,6 +930,11 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
|
|||
status = wine_server_call( req );
|
||||
wait_handle = wine_server_ptr_handle( reply->wait );
|
||||
options = reply->options;
|
||||
if ((!NT_ERROR(status) || wait_handle) && status != STATUS_PENDING)
|
||||
{
|
||||
io->Status = status;
|
||||
io->Information = async->sent_len;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
|
@ -1111,6 +1110,10 @@ static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc,
|
|||
status = wine_server_call( req );
|
||||
wait_handle = wine_server_ptr_handle( reply->wait );
|
||||
options = reply->options;
|
||||
/* In theory we'd fill the iosb here, as above in sock_send(), but it's
|
||||
* actually currently impossible to get STATUS_SUCCESS. The server will
|
||||
* either return STATUS_PENDING or an error code, and in neither case
|
||||
* should the iosb be filled. */
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
|
|
|
@ -5080,8 +5080,14 @@ static void test_write_events(struct event_test_ctx *ctx)
|
|||
|
||||
if (!broken(1))
|
||||
{
|
||||
while (send(server, buffer, buffer_size, 0) == buffer_size);
|
||||
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||
while ((ret = send(server, buffer, buffer_size, 0)) == buffer_size);
|
||||
/* Windows will never send less than buffer_size bytes here, but Linux
|
||||
* may do a short write. */
|
||||
todo_wine_if (ret > 0)
|
||||
{
|
||||
ok(ret == -1, "got %d\n", ret);
|
||||
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||
}
|
||||
|
||||
while (recv(client, buffer, buffer_size, 0) > 0);
|
||||
ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
|
||||
|
|
Loading…
Reference in New Issue