From: Elizabeth Figura zfigura@codeweavers.com
The current ioctls don't reliably return synchronously for overlapped handles on Windows, which makes some of the conclusions drawn by the tests less clear.
Use NtReadFile instead, which will always return synchronously if there is data in the pipe. --- dlls/ntdll/tests/wow64.c | 64 ++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 25 deletions(-)
diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 67770cb9b59..2ef21480cac 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -2131,8 +2131,10 @@ static void test_iosb(void) HANDLE client, server; NTSTATUS status; ULONG64 func; - DWORD id; IO_STATUS_BLOCK iosb32; + char buffer[6]; + DWORD size; + BOOL ret; struct { union @@ -2142,12 +2144,12 @@ static void test_iosb(void) }; ULONG64 Information; } iosb64; - ULONG64 args[] = { 0, 0, 0, 0, (ULONG_PTR)&iosb64, FSCTL_PIPE_LISTEN, 0, 0, 0, 0 }; + ULONG64 args[] = { 0, 0, 0, 0, (ULONG_PTR)&iosb64, (ULONG_PTR)buffer, sizeof(buffer), 0, 0 };
if (!is_wow64) return; if (!code_mem) return; if (!ntdll_module) return; - func = get_proc_address64( ntdll_module, "NtFsControlFile" ); + func = get_proc_address64( ntdll_module, "NtReadFile" );
/* async calls set iosb32 but not iosb64 */
@@ -2156,46 +2158,53 @@ static void test_iosb(void) 4, 1024, 1024, 1000, NULL ); ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
+ client = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_FLAG_NO_BUFFERING, NULL ); + ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() ); + + memset( buffer, 0xcc, sizeof(buffer) ); memset( &iosb32, 0x55, sizeof(iosb32) ); iosb64.Pointer = PtrToUlong( &iosb32 ); iosb64.Information = 0xdeadbeef;
args[0] = (LONG_PTR)server; status = call_func64( func, ARRAY_SIZE(args), args ); - ok( status == STATUS_PENDING, "NtFsControlFile returned %lx\n", status ); + ok( status == STATUS_PENDING, "NtReadFile returned %lx\n", status ); ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status ); - ok( iosb64.Pointer == PtrToUlong(&iosb32), "status changed to %lx\n", iosb64.Status ); + 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 );
- client = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, - FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); - ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() ); + ret = WriteFile( client, "data", sizeof("data"), &size, NULL ); + ok( ret == TRUE, "got error %lu\n", GetLastError() );
ok( iosb32.Status == 0, "Wrong iostatus %lx\n", iosb32.Status ); - ok( iosb64.Pointer == PtrToUlong(&iosb32), "status changed to %lx\n", iosb64.Status ); + ok( iosb32.Information == sizeof("data"), "Wrong information %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 ); + ok( !memcmp( buffer, "data", iosb32.Information ), + "got wrong data %s\n", debugstr_an(buffer, iosb32.Information) );
+ memset( buffer, 0xcc, sizeof(buffer) ); memset( &iosb32, 0x55, sizeof(iosb32) ); iosb64.Pointer = PtrToUlong( &iosb32 ); iosb64.Information = 0xdeadbeef; - id = 0xdeadbeef;
- args[5] = FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE; - args[6] = (ULONG_PTR)"ClientProcessId"; - args[7] = sizeof("ClientProcessId"); - args[8] = (ULONG_PTR)&id; - args[9] = sizeof(id); + ret = WriteFile( client, "data", sizeof("data"), &size, NULL ); + ok( ret == TRUE, "got error %lu\n", GetLastError() );
status = call_func64( func, ARRAY_SIZE(args), args ); - ok( status == STATUS_PENDING || status == STATUS_SUCCESS, "NtFsControlFile returned %lx\n", status ); + 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(id), "info changed to %Ix\n", iosb32.Information ); - ok( iosb64.Pointer == PtrToUlong(&iosb32), "status changed to %lx\n", iosb64.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( id == GetCurrentProcessId(), "wrong id %lx / %lx\n", id, GetCurrentProcessId() ); + CloseHandle( client ); CloseHandle( server );
@@ -2210,19 +2219,24 @@ static void test_iosb(void) FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
+ ret = WriteFile( client, "data", sizeof("data"), &size, NULL ); + ok( ret == TRUE, "got error %lu\n", GetLastError() ); + + memset( buffer, 0xcc, sizeof(buffer) ); memset( &iosb32, 0x55, sizeof(iosb32) ); iosb64.Pointer = PtrToUlong( &iosb32 ); iosb64.Information = 0xdeadbeef; - id = 0xdeadbeef;
args[0] = (LONG_PTR)server; status = call_func64( func, ARRAY_SIZE(args), args ); - ok( status == STATUS_SUCCESS, "NtFsControlFile returned %lx\n", status ); + 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 %Ix\n", iosb32.Information ); - ok( iosb64.Pointer == STATUS_SUCCESS, "status changed to %lx\n", iosb64.Status ); - ok( iosb64.Information == sizeof(id), "info changed to %Ix\n", (ULONG_PTR)iosb64.Information ); - ok( id == GetCurrentProcessId(), "wrong id %lx / %lx\n", id, GetCurrentProcessId() ); + ok( iosb32.Information == 0x55555555, "info changed to %lx\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 ), + "got wrong data %s\n", debugstr_an(buffer, iosb64.Information) ); + CloseHandle( client ); CloseHandle( server ); }
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/ntdll/tests/wow64.c | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 2ef21480cac..7c1cad2d533 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -2125,10 +2125,25 @@ static void test_init_block(void) }
+static DWORD WINAPI iosb_delayed_write_thread(void *arg) +{ + HANDLE client = arg; + DWORD size; + BOOL ret; + + Sleep(100); + + ret = WriteFile( client, "data", sizeof("data"), &size, NULL ); + ok( ret == TRUE, "got error %lu\n", GetLastError() ); + + return 0; +} + + static void test_iosb(void) { static const char pipe_name[] = "\\.\pipe\wow64iosbnamedpipe"; - HANDLE client, server; + HANDLE client, server, thread; NTSTATUS status; ULONG64 func; IO_STATUS_BLOCK iosb32; @@ -2237,6 +2252,30 @@ static void test_iosb(void) ok( !memcmp( buffer, "data", iosb64.Information ), "got wrong data %s\n", debugstr_an(buffer, iosb64.Information) );
+ thread = CreateThread( NULL, 0, iosb_delayed_write_thread, client, 0, NULL ); + + memset( buffer, 0xcc, sizeof(buffer) ); + memset( &iosb32, 0x55, sizeof(iosb32) ); + iosb64.Pointer = PtrToUlong( &iosb32 ); + iosb64.Information = 0xdeadbeef; + + args[0] = (LONG_PTR)server; + status = call_func64( func, ARRAY_SIZE(args), args ); + ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status ); + 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( 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 ), + "got wrong data %s\n", debugstr_an(buffer, iosb64.Information) ); + } + + ret = WaitForSingleObject( thread, 1000 ); + ok(!ret, "got %d\n", ret ); + CloseHandle( thread ); + CloseHandle( client ); CloseHandle( server ); }
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/ntdll/tests/wow64.c | 44 ++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 7c1cad2d533..f5fbf6fd432 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -2145,7 +2145,7 @@ static void test_iosb(void) static const char pipe_name[] = "\\.\pipe\wow64iosbnamedpipe"; HANDLE client, server, thread; NTSTATUS status; - ULONG64 func; + ULONG64 read_func, flush_func; IO_STATUS_BLOCK iosb32; char buffer[6]; DWORD size; @@ -2160,15 +2160,17 @@ static void test_iosb(void) ULONG64 Information; } iosb64; ULONG64 args[] = { 0, 0, 0, 0, (ULONG_PTR)&iosb64, (ULONG_PTR)buffer, sizeof(buffer), 0, 0 }; + ULONG64 flush_args[] = { 0, (ULONG_PTR)&iosb64 };
if (!is_wow64) return; if (!code_mem) return; if (!ntdll_module) return; - func = get_proc_address64( ntdll_module, "NtReadFile" ); + read_func = get_proc_address64( ntdll_module, "NtReadFile" ); + flush_func = get_proc_address64( ntdll_module, "NtFlushBuffersFile" );
/* async calls set iosb32 but not iosb64 */
- server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() ); @@ -2183,7 +2185,7 @@ static void test_iosb(void) iosb64.Information = 0xdeadbeef;
args[0] = (LONG_PTR)server; - status = call_func64( func, ARRAY_SIZE(args), args ); + status = call_func64( read_func, ARRAY_SIZE(args), args ); ok( status == STATUS_PENDING, "NtReadFile returned %lx\n", status ); ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status ); ok( iosb64.Pointer == PtrToUlong(&iosb32), "pointer changed to %I64x\n", iosb64.Pointer ); @@ -2207,7 +2209,7 @@ static void test_iosb(void) ret = WriteFile( client, "data", sizeof("data"), &size, NULL ); ok( ret == TRUE, "got error %lu\n", GetLastError() );
- status = call_func64( func, ARRAY_SIZE(args), args ); + status = call_func64( read_func, ARRAY_SIZE(args), args ); ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status ); todo_wine { @@ -2220,12 +2222,26 @@ static void test_iosb(void) "got wrong data %s\n", debugstr_an(buffer, iosb32.Information) ); }
+ /* syscalls which are always synchronous set iosb64 but not iosb32 */ + + memset( &iosb32, 0x55, sizeof(iosb32) ); + iosb64.Pointer = PtrToUlong( &iosb32 ); + iosb64.Information = 0xdeadbeef; + + flush_args[0] = (LONG_PTR)server; + 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( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer ); + ok( iosb64.Information == 0, "info changed to %lx\n", (ULONG_PTR)iosb64.Information ); + CloseHandle( client ); CloseHandle( server );
/* synchronous calls set iosb64 but not iosb32 */
- server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, + server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() ); @@ -2243,7 +2259,7 @@ static void test_iosb(void) iosb64.Information = 0xdeadbeef;
args[0] = (LONG_PTR)server; - status = call_func64( func, ARRAY_SIZE(args), args ); + 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 ); @@ -2260,7 +2276,7 @@ static void test_iosb(void) iosb64.Information = 0xdeadbeef;
args[0] = (LONG_PTR)server; - status = call_func64( func, ARRAY_SIZE(args), args ); + status = call_func64( read_func, ARRAY_SIZE(args), args ); ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status ); todo_wine { @@ -2276,6 +2292,18 @@ static void test_iosb(void) ok(!ret, "got %d\n", ret ); CloseHandle( thread );
+ memset( &iosb32, 0x55, sizeof(iosb32) ); + iosb64.Pointer = PtrToUlong( &iosb32 ); + iosb64.Information = 0xdeadbeef; + + flush_args[0] = (LONG_PTR)server; + 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( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer ); + ok( iosb64.Information == 0, "info changed to %lx\n", (ULONG_PTR)iosb64.Information ); + CloseHandle( client ); CloseHandle( server ); }