From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/ntdll/tests/wow64.c | 8 ++------ dlls/ntdll/unix/file.c | 31 +++++++++++++++++++------------ 2 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index f5fbf6fd432..8c7d2507ebe 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( 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 */
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;