Module: wine Branch: master Commit: e51aa91b751eb04905383d6e580947d6ddf489c9 URL: https://gitlab.winehq.org/wine/wine/-/commit/e51aa91b751eb04905383d6e580947d...
Author: Elizabeth Figura zfigura@codeweavers.com Date: Thu Jun 13 23:22:25 2024 -0500
ntdll: Always fill the 32-bit iosb for overlapped handles, for server I/O.
---
dlls/ntdll/tests/wow64.c | 22 +++++++++------------- dlls/ntdll/unix/file.c | 31 +++++++++++++++++++------------ 2 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index f5fbf6fd432..f997a02a04f 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -2211,16 +2211,12 @@ static void test_iosb(void)
status = call_func64( read_func, ARRAY_SIZE(args), args ); ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status ); - todo_wine - { ok( iosb32.Status == STATUS_SUCCESS, "status changed to %lx\n", iosb32.Status ); - ok( iosb32.Information == sizeof("data"), "info changed to %lx\n", iosb32.Information ); + ok( iosb32.Information == sizeof("data"), "info changed to %Ix\n", iosb32.Information ); ok( iosb64.Pointer == PtrToUlong(&iosb32), "pointer changed to %I64x\n", iosb64.Pointer ); ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information ); - if (iosb32.Information == sizeof("data")) - ok( !memcmp( buffer, "data", iosb32.Information ), - "got wrong data %s\n", debugstr_an(buffer, iosb32.Information) ); - } + ok( !memcmp( buffer, "data", iosb32.Information ), + "got wrong data %s\n", debugstr_an(buffer, iosb32.Information) );
/* syscalls which are always synchronous set iosb64 but not iosb32 */
@@ -2232,9 +2228,9 @@ static void test_iosb(void) status = call_func64( flush_func, ARRAY_SIZE(flush_args), flush_args ); ok( status == STATUS_SUCCESS, "NtFlushBuffersFile returned %lx\n", status ); ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status ); - ok( iosb32.Information == 0x55555555, "info changed to %lx\n", iosb32.Information ); + ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information ); ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer ); - ok( iosb64.Information == 0, "info changed to %lx\n", (ULONG_PTR)iosb64.Information ); + ok( iosb64.Information == 0, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
CloseHandle( client ); CloseHandle( server ); @@ -2262,7 +2258,7 @@ static void test_iosb(void) status = call_func64( read_func, ARRAY_SIZE(args), args ); ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status ); ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status ); - ok( iosb32.Information == 0x55555555, "info changed to %lx\n", iosb32.Information ); + ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information ); ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer ); ok( iosb64.Information == sizeof("data"), "info changed to %Ix\n", (ULONG_PTR)iosb64.Information ); ok( !memcmp( buffer, "data", iosb64.Information ), @@ -2281,7 +2277,7 @@ static void test_iosb(void) todo_wine { ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status ); - ok( iosb32.Information == 0x55555555, "info changed to %lx\n", iosb32.Information ); + ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information ); ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer ); ok( iosb64.Information == sizeof("data"), "info changed to %Ix\n", (ULONG_PTR)iosb64.Information ); ok( !memcmp( buffer, "data", iosb64.Information ), @@ -2300,9 +2296,9 @@ static void test_iosb(void) status = call_func64( flush_func, ARRAY_SIZE(flush_args), flush_args ); ok( status == STATUS_SUCCESS, "NtFlushBuffersFile returned %lx\n", status ); ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status ); - ok( iosb32.Information == 0x55555555, "info changed to %lx\n", iosb32.Information ); + ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information ); ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer ); - ok( iosb64.Information == 0, "info changed to %lx\n", (ULONG_PTR)iosb64.Information ); + ok( iosb64.Information == 0, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
CloseHandle( client ); CloseHandle( server ); diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 8415478c046..4f0fe685d88 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -5186,6 +5186,22 @@ static BOOL async_write_proc( void *user, ULONG_PTR *info, unsigned int *status return TRUE; }
+static void set_sync_iosb( IO_STATUS_BLOCK *io, NTSTATUS status, ULONG_PTR info, unsigned int options ) +{ + if (in_wow64_call() && !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))) + { + IO_STATUS_BLOCK32 *io32 = io->Pointer; + + io32->Status = status; + io32->Information = info; + } + else + { + io->Status = status; + io->Information = info; + } +} + /* do a read call through the server */ static unsigned int server_read_file( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_context, IO_STATUS_BLOCK *io, void *buffer, ULONG size, @@ -5211,10 +5227,7 @@ static unsigned int server_read_file( HANDLE handle, HANDLE event, PIO_APC_ROUTI wait_handle = wine_server_ptr_handle( reply->wait ); options = reply->options; if (wait_handle && status != STATUS_PENDING) - { - io->Status = status; - io->Information = wine_server_reply_size( reply ); - } + set_sync_iosb( io, status, wine_server_reply_size( reply ), options ); } SERVER_END_REQ;
@@ -5249,10 +5262,7 @@ static unsigned int server_write_file( HANDLE handle, HANDLE event, PIO_APC_ROUT wait_handle = wine_server_ptr_handle( reply->wait ); options = reply->options; if (wait_handle && status != STATUS_PENDING) - { - io->Status = status; - io->Information = reply->size; - } + set_sync_iosb( io, status, reply->size, options ); } SERVER_END_REQ;
@@ -5290,10 +5300,7 @@ static NTSTATUS server_ioctl_file( HANDLE handle, HANDLE event, wait_handle = wine_server_ptr_handle( reply->wait ); options = reply->options; if (wait_handle && status != STATUS_PENDING) - { - io->Status = status; - io->Information = wine_server_reply_size( reply ); - } + set_sync_iosb( io, status, wine_server_reply_size( reply ), options ); } SERVER_END_REQ;