Signed-off-by: Zebediah Figura z.figura12@gmail.com --- This fixes the test failure reported here: https://www.winehq.org/pipermail/wine-devel/2018-September/132962.html
Unlike previous uses of this facility, the goal here is to prevent filesystem virtualization. For whatever reason, on the w8 test machine, the contents of the virtualized WindowsUpdate.log differ from the contents of the real file. NtQueryDirectoryFile() retrieves the size of the latter, but NtOpenFile() opens the former.
dlls/ntdll/tests/Makefile.in | 3 +++ dlls/ntdll/tests/ntdll.manifest | 18 ++++++++++++++++++ dlls/ntdll/tests/ntdll.rc | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 dlls/ntdll/tests/ntdll.manifest create mode 100644 dlls/ntdll/tests/ntdll.rc
diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in index 5c70f3f..c088b7b 100644 --- a/dlls/ntdll/tests/Makefile.in +++ b/dlls/ntdll/tests/Makefile.in @@ -23,3 +23,6 @@ C_SRCS = \ string.c \ threadpool.c \ time.c + +RC_SRCS = \ + ntdll.rc diff --git a/dlls/ntdll/tests/ntdll.manifest b/dlls/ntdll/tests/ntdll.manifest new file mode 100644 index 0000000..1747ea8 --- /dev/null +++ b/dlls/ntdll/tests/ntdll.manifest @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity + type="win32" + name="Wine.ntdll.Test" + version="1.0.0.0" + processorArchitecture="*" + /> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> + <security> + <requestedPrivileges> + <requestedExecutionLevel + level="asInvoker" + /> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/dlls/ntdll/tests/ntdll.rc b/dlls/ntdll/tests/ntdll.rc new file mode 100644 index 0000000..74d5073 --- /dev/null +++ b/dlls/ntdll/tests/ntdll.rc @@ -0,0 +1,22 @@ +/* + * Copyright 2018 Zebediah Figura + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "winuser.h" + +/* @makedep: ntdll.manifest */ +1 RT_MANIFEST ntdll.manifest
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/tests/file.c | 106 ++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 58 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index b4223b3..b7ccf49 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -108,10 +108,6 @@ static HANDLE create_temp_file( ULONG flags ) #define CKEY_FIRST 0x1030341 #define CKEY_SECOND 0x132E46
-static ULONG_PTR completionKey; -static IO_STATUS_BLOCK ioSb; -static ULONG_PTR completionValue; - static ULONG get_pending_msgs(HANDLE h) { NTSTATUS res; @@ -124,21 +120,6 @@ static ULONG get_pending_msgs(HANDLE h) return a; }
-static BOOL get_msg(HANDLE h) -{ - LARGE_INTEGER timeout = {{-10000000*3}}; - DWORD res = pNtRemoveIoCompletion( h, &completionKey, &completionValue, &ioSb, &timeout); - ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %x\n", res ); - if (res != STATUS_SUCCESS) - { - completionKey = completionValue = 0; - memset(&ioSb, 0, sizeof(ioSb)); - return FALSE; - } - return TRUE; -} - - static void WINAPI apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved ) { int *count = arg; @@ -881,6 +862,9 @@ static void nt_mailslot_test(void)
static void test_iocp_setcompletion(HANDLE h) { + LARGE_INTEGER timeout = {{0}}; + IO_STATUS_BLOCK iosb; + ULONG_PTR key, value; NTSTATUS res; ULONG count; SIZE_T size = 3; @@ -893,13 +877,12 @@ static void test_iocp_setcompletion(HANDLE h) count = get_pending_msgs(h); ok( count == 1, "Unexpected msg count: %d\n", count );
- if (get_msg(h)) - { - ok( completionKey == CKEY_FIRST, "Invalid completion key: %lx\n", completionKey ); - ok( ioSb.Information == size, "Invalid ioSb.Information: %lu\n", ioSb.Information ); - ok( U(ioSb).Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid ioSb.Status: %x\n", U(ioSb).Status); - ok( completionValue == CVALUE_FIRST, "Invalid completion value: %lx\n", completionValue ); - } + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_FIRST, "Invalid completion key: %#lx\n", key ); + ok( iosb.Information == size, "Invalid iosb.Information: %lu\n", iosb.Information ); + ok( U(iosb).Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid iosb.Status: %#x\n", U(iosb).Status ); + ok( value == CVALUE_FIRST, "Invalid completion value: %#lx\n", value );
count = get_pending_msgs(h); ok( !count, "Unexpected msg count: %d\n", count ); @@ -911,7 +894,9 @@ static void test_iocp_fileio(HANDLE h)
IO_STATUS_BLOCK iosb; FILE_COMPLETION_INFORMATION fci = {h, CKEY_SECOND}; + LARGE_INTEGER timeout = {{0}}; HANDLE hPipeSrv, hPipeClt; + ULONG_PTR key, value; NTSTATUS res;
hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); @@ -960,14 +945,15 @@ static void test_iocp_fileio(HANDLE h) ok( !count, "Unexpected msg count: %ld\n", count ); WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL );
- if (get_msg(h)) - { - ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); - ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information ); - ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status); - ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); - ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); - } + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); + ok( iosb.Information == 3, "Invalid iosb.Information: %ld\n", iosb.Information ); + ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); + ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); + ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), + "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n", + recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); count = get_pending_msgs(h); ok( !count, "Unexpected msg count: %ld\n", count );
@@ -979,27 +965,29 @@ static void test_iocp_fileio(HANDLE h) ReadFile( hPipeSrv, recv_buf, 2, &read, &o); count = get_pending_msgs(h); ok( count == 1, "Unexpected msg count: %ld\n", count ); - if (get_msg(h)) - { - ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); - ok( ioSb.Information == 2, "Invalid ioSb.Information: %ld\n", ioSb.Information ); - ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status); - ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); - ok( !memcmp( send_buf, recv_buf, 2 ), "Receive buffer (%x %x) did not match send buffer (%x %x)\n", recv_buf[0], recv_buf[1], send_buf[0], send_buf[1] ); - } + + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); + ok( iosb.Information == 2, "Invalid iosb.Information: %ld\n", iosb.Information ); + ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); + ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); + ok( !memcmp( send_buf, recv_buf, 2 ), + "Receive buffer (%02x %02x) did not match send buffer (%02x %02x)\n", + recv_buf[0], recv_buf[1], send_buf[0], send_buf[1] );
ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o); CloseHandle( hPipeSrv ); count = get_pending_msgs(h); ok( count == 1, "Unexpected msg count: %ld\n", count ); - if (get_msg(h)) - { - ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); - ok( ioSb.Information == 0, "Invalid ioSb.Information: %ld\n", ioSb.Information ); - /* wine sends wrong status here */ - ok( U(ioSb).Status == STATUS_PIPE_BROKEN, "Invalid ioSb.Status: %x\n", U(ioSb).Status); - ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); - } + + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_SECOND, "Invalid completion key: %lx\n", key ); + ok( iosb.Information == 0, "Invalid iosb.Information: %ld\n", iosb.Information ); + /* wine sends wrong status here */ + ok( U(iosb).Status == STATUS_PIPE_BROKEN, "Invalid iosb.Status: %x\n", U(iosb).Status ); + ok( value == (ULONG_PTR)&o, "Invalid completion value: %lx\n", value ); }
CloseHandle( hPipeClt ); @@ -1034,14 +1022,16 @@ static void test_iocp_fileio(HANDLE h)
WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL );
- if (get_msg(h)) - { - ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); - ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information ); - ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status); - ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); - ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); - } + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); + ok( iosb.Information == 3, "Invalid iosb.Information: %ld\n", iosb.Information ); + ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); + ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); + ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), + "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n", + recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); + count = get_pending_msgs(h); ok( !count, "Unexpected msg count: %ld\n", count );
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=42702
Your paranoid android.
=== w8 (32 bit Windows report) ===
ntdll: file.c:441: Test failed: mismatched file size for L"WindowsUpdate.log"
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/tests/file.c | 309 +++++++++++++++++++++++------------------------- 1 file changed, 146 insertions(+), 163 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index b7ccf49..0773ad3 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -893,203 +893,186 @@ static void test_iocp_fileio(HANDLE h) static const char pipe_name[] = "\\.\pipe\iocompletiontestnamedpipe";
IO_STATUS_BLOCK iosb; + BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN]; FILE_COMPLETION_INFORMATION fci = {h, CKEY_SECOND}; LARGE_INTEGER timeout = {{0}}; - HANDLE hPipeSrv, hPipeClt; + HANDLE server, client; ULONG_PTR key, value; + OVERLAPPED o = {0}; + int apc_count = 0; NTSTATUS res; + DWORD read; + long count;
- hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); - ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" ); - if (hPipeSrv != INVALID_HANDLE_VALUE ) - { - hPipeClt = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); - ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" ); - if (hPipeClt != INVALID_HANDLE_VALUE) - { - U(iosb).Status = 0xdeadbeef; - res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation ); - ok( res == STATUS_INVALID_PARAMETER, "Unexpected NtSetInformationFile on non-overlapped handle: %x\n", res ); - ok( U(iosb).Status == STATUS_INVALID_PARAMETER /* 98 */ || U(iosb).Status == 0xdeadbeef /* NT4+ */, - "Unexpected iosb.Status on non-overlapped handle: %x\n", U(iosb).Status ); - CloseHandle(hPipeClt); - } - CloseHandle( hPipeSrv ); - } + server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + 4, 1024, 1024, 1000, NULL ); + ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError() ); + 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: %u\n", GetLastError() );
- hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); - ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" ); - if (hPipeSrv == INVALID_HANDLE_VALUE ) - return; + U(iosb).Status = 0xdeadbeef; + res = pNtSetInformationFile( server, &iosb, &fci, sizeof(fci), FileCompletionInformation ); + ok( res == STATUS_INVALID_PARAMETER, "NtSetInformationFile failed: %#x\n", res ); +todo_wine + ok( U(iosb).Status == 0xdeadbeef, "wrong status %#x\n", U(iosb).Status ); + CloseHandle( client ); + CloseHandle( server );
- hPipeClt = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); - ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" ); - if (hPipeClt != INVALID_HANDLE_VALUE) - { - OVERLAPPED o = {0,}; - BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN]; - DWORD read; - long count; + server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + 4, 1024, 1024, 1000, NULL ); + ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError() ); + 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: %u\n", GetLastError() );
- U(iosb).Status = 0xdeadbeef; - res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation ); - ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res ); - ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status ); + U(iosb).Status = 0xdeadbeef; + res = pNtSetInformationFile( server, &iosb, &fci, sizeof(fci), FileCompletionInformation ); + ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %#x\n", res ); + ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %#x\n", U(iosb).Status );
- memset( send_buf, 0, TEST_BUF_LEN ); - memset( recv_buf, 0xde, TEST_BUF_LEN ); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); - ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); - WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL ); + memset( send_buf, 0, TEST_BUF_LEN ); + memset( recv_buf, 0xde, TEST_BUF_LEN ); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count ); + ReadFile( server, recv_buf, TEST_BUF_LEN, &read, &o); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count ); + WriteFile( client, send_buf, TEST_BUF_LEN, &read, NULL );
- res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); - ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); - ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); - ok( iosb.Information == 3, "Invalid iosb.Information: %ld\n", iosb.Information ); - ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); - ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); - ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), - "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n", - recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); + ok( iosb.Information == 3, "Invalid iosb.Information: %ld\n", iosb.Information ); + ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); + ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); + ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), + "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n", + recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count );
- memset( send_buf, 0, TEST_BUF_LEN ); - memset( recv_buf, 0xde, TEST_BUF_LEN ); - WriteFile( hPipeClt, send_buf, 2, &read, NULL ); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); - ReadFile( hPipeSrv, recv_buf, 2, &read, &o); - count = get_pending_msgs(h); - ok( count == 1, "Unexpected msg count: %ld\n", count ); + memset( send_buf, 0, TEST_BUF_LEN ); + memset( recv_buf, 0xde, TEST_BUF_LEN ); + WriteFile( client, send_buf, 2, &read, NULL ); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count ); + ReadFile( server, recv_buf, 2, &read, &o); + count = get_pending_msgs(h); + ok( count == 1, "Unexpected msg count: %ld\n", count );
- res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); - ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); - ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); - ok( iosb.Information == 2, "Invalid iosb.Information: %ld\n", iosb.Information ); - ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); - ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); - ok( !memcmp( send_buf, recv_buf, 2 ), - "Receive buffer (%02x %02x) did not match send buffer (%02x %02x)\n", - recv_buf[0], recv_buf[1], send_buf[0], send_buf[1] ); + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); + ok( iosb.Information == 2, "Invalid iosb.Information: %ld\n", iosb.Information ); + ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); + ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); + ok( !memcmp( send_buf, recv_buf, 2 ), + "Receive buffer (%02x %02x) did not match send buffer (%02x %02x)\n", + recv_buf[0], recv_buf[1], send_buf[0], send_buf[1] );
- ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o); - CloseHandle( hPipeSrv ); - count = get_pending_msgs(h); - ok( count == 1, "Unexpected msg count: %ld\n", count ); + ReadFile( server, recv_buf, TEST_BUF_LEN, &read, &o); + CloseHandle( server ); + count = get_pending_msgs(h); + ok( count == 1, "Unexpected msg count: %ld\n", count );
- res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); - ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); - ok( key == CKEY_SECOND, "Invalid completion key: %lx\n", key ); - ok( iosb.Information == 0, "Invalid iosb.Information: %ld\n", iosb.Information ); - /* wine sends wrong status here */ - ok( U(iosb).Status == STATUS_PIPE_BROKEN, "Invalid iosb.Status: %x\n", U(iosb).Status ); - ok( value == (ULONG_PTR)&o, "Invalid completion value: %lx\n", value ); - } + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_SECOND, "Invalid completion key: %lx\n", key ); + ok( iosb.Information == 0, "Invalid iosb.Information: %ld\n", iosb.Information ); + ok( U(iosb).Status == STATUS_PIPE_BROKEN, "Invalid iosb.Status: %x\n", U(iosb).Status ); + ok( value == (ULONG_PTR)&o, "Invalid completion value: %lx\n", value );
- CloseHandle( hPipeClt ); + CloseHandle( client );
/* test associating a completion port with a handle after an async is queued */ - hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); - ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" ); - if (hPipeSrv == INVALID_HANDLE_VALUE ) - return; - hPipeClt = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); - ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" ); - if (hPipeClt != INVALID_HANDLE_VALUE) - { - OVERLAPPED o = {0,}; - BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN]; - int apc_count = 0; - DWORD read; - long count; + server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + 4, 1024, 1024, 1000, NULL ); + ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError() ); + 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: %u\n", GetLastError() );
- memset( send_buf, 0, TEST_BUF_LEN ); - memset( recv_buf, 0xde, TEST_BUF_LEN ); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); - ReadFile( hPipeSrv, recv_buf, TEST_BUF_LEN, &read, &o); + memset( send_buf, 0, TEST_BUF_LEN ); + memset( recv_buf, 0xde, TEST_BUF_LEN ); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count ); + ReadFile( server, recv_buf, TEST_BUF_LEN, &read, &o);
- U(iosb).Status = 0xdeadbeef; - res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation ); - ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res ); - ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status ); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); + U(iosb).Status = 0xdeadbeef; + res = pNtSetInformationFile( server, &iosb, &fci, sizeof(fci), FileCompletionInformation ); + ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res ); + ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status ); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count );
- WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL ); + WriteFile( client, send_buf, TEST_BUF_LEN, &read, NULL );
- res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); - ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); - ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); - ok( iosb.Information == 3, "Invalid iosb.Information: %ld\n", iosb.Information ); - ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); - ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); - ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), - "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n", - recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] ); + res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#x\n", res ); + ok( key == CKEY_SECOND, "Invalid completion key: %#lx\n", key ); + ok( iosb.Information == 3, "Invalid iosb.Information: %ld\n", iosb.Information ); + ok( U(iosb).Status == STATUS_SUCCESS, "Invalid iosb.Status: %#x\n", U(iosb).Status ); + ok( value == (ULONG_PTR)&o, "Invalid completion value: %#lx\n", value ); + ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ), + "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n", + recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] );
- count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count );
- /* using APCs on handle with associated completion port is not allowed */ - res = pNtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); - ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res); - } + /* using APCs on handle with associated completion port is not allowed */ + res = pNtReadFile( server, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); + ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res);
- CloseHandle( hPipeSrv ); - CloseHandle( hPipeClt ); + CloseHandle( server ); + CloseHandle( client );
/* test associating a completion port with a handle after an async using APC is queued */ - hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL ); - ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" ); - if (hPipeSrv == INVALID_HANDLE_VALUE ) - return; - hPipeClt = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); - ok( hPipeClt != INVALID_HANDLE_VALUE, "Cannot connect to pipe\n" ); - if (hPipeClt != INVALID_HANDLE_VALUE) - { - BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN]; - int apc_count = 0; - DWORD read; - long count; + server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + 4, 1024, 1024, 1000, NULL ); + ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError() ); + 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: %u\n", GetLastError() );
- memset( send_buf, 0, TEST_BUF_LEN ); - memset( recv_buf, 0xde, TEST_BUF_LEN ); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); + apc_count = 0; + memset( send_buf, 0, TEST_BUF_LEN ); + memset( recv_buf, 0xde, TEST_BUF_LEN ); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count );
- res = pNtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); - ok(res == STATUS_PENDING, "NtReadFile returned %x\n", res); + res = pNtReadFile( server, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); + ok(res == STATUS_PENDING, "NtReadFile returned %x\n", res);
- U(iosb).Status = 0xdeadbeef; - res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation ); - ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res ); - ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status ); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); + U(iosb).Status = 0xdeadbeef; + res = pNtSetInformationFile( server, &iosb, &fci, sizeof(fci), FileCompletionInformation ); + ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res ); + ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status ); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count );
- WriteFile( hPipeClt, send_buf, TEST_BUF_LEN, &read, NULL ); + WriteFile( client, send_buf, TEST_BUF_LEN, &read, NULL );
- ok(!apc_count, "apc_count = %u\n", apc_count); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); + ok(!apc_count, "apc_count = %u\n", apc_count); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count );
- SleepEx(1, TRUE); /* alertable sleep */ - ok(apc_count == 1, "apc was not called\n"); - count = get_pending_msgs(h); - ok( !count, "Unexpected msg count: %ld\n", count ); + SleepEx(1, TRUE); /* alertable sleep */ + ok(apc_count == 1, "apc was not called\n"); + count = get_pending_msgs(h); + ok( !count, "Unexpected msg count: %ld\n", count );
- /* using APCs on handle with associated completion port is not allowed */ - res = pNtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); - ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res); - } + /* using APCs on handle with associated completion port is not allowed */ + res = pNtReadFile( server, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL ); + ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res);
- CloseHandle( hPipeSrv ); - CloseHandle( hPipeClt ); + CloseHandle( server ); + CloseHandle( client ); }
static void test_file_full_size_information(void)
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=42703
Your paranoid android.
=== w8 (32 bit Windows report) ===
ntdll: file.c:441: Test failed: mismatched file size for L"WindowsUpdate.log"
Call I/O completion tests directly.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/tests/file.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 0773ad3..88b2b9b 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -860,7 +860,7 @@ static void nt_mailslot_test(void) ok( rc == STATUS_SUCCESS, "NtClose failed\n"); }
-static void test_iocp_setcompletion(HANDLE h) +static void test_set_io_completion(void) { LARGE_INTEGER timeout = {{0}}; IO_STATUS_BLOCK iosb; @@ -868,9 +868,14 @@ static void test_iocp_setcompletion(HANDLE h) NTSTATUS res; ULONG count; SIZE_T size = 3; + HANDLE h;
if (sizeof(size) > 4) size |= (ULONGLONG)0x12345678 << 32;
+ res = pNtCreateIoCompletion( &h, IO_COMPLETION_ALL_ACCESS, NULL, 0 ); + ok( res == STATUS_SUCCESS, "NtCreateIoCompletion failed: %#x\n", res ); + ok( h && h != INVALID_HANDLE_VALUE, "got invalid handle %p\n", h ); + res = pNtSetIoCompletion( h, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size ); ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %x\n", res );
@@ -886,15 +891,17 @@ static void test_iocp_setcompletion(HANDLE h)
count = get_pending_msgs(h); ok( !count, "Unexpected msg count: %d\n", count ); + + pNtClose( h ); }
-static void test_iocp_fileio(HANDLE h) +static void test_file_io_completion(void) { static const char pipe_name[] = "\\.\pipe\iocompletiontestnamedpipe";
IO_STATUS_BLOCK iosb; BYTE send_buf[TEST_BUF_LEN], recv_buf[TEST_BUF_LEN]; - FILE_COMPLETION_INFORMATION fci = {h, CKEY_SECOND}; + FILE_COMPLETION_INFORMATION fci; LARGE_INTEGER timeout = {{0}}; HANDLE server, client; ULONG_PTR key, value; @@ -903,6 +910,13 @@ static void test_iocp_fileio(HANDLE h) NTSTATUS res; DWORD read; long count; + HANDLE h; + + res = pNtCreateIoCompletion( &h, IO_COMPLETION_ALL_ACCESS, NULL, 0 ); + ok( res == STATUS_SUCCESS, "NtCreateIoCompletion failed: %#x\n", res ); + ok( h && h != INVALID_HANDLE_VALUE, "got invalid handle %p\n", h ); + fci.CompletionPort = h; + fci.CompletionKey = CKEY_SECOND;
server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, @@ -1073,6 +1087,7 @@ todo_wine
CloseHandle( server ); CloseHandle( client ); + pNtClose( h ); }
static void test_file_full_size_information(void) @@ -2921,24 +2936,6 @@ todo_wine RemoveDirectoryA( buffer ); }
-static void test_iocompletion(void) -{ - HANDLE h = INVALID_HANDLE_VALUE; - NTSTATUS res; - - res = pNtCreateIoCompletion( &h, IO_COMPLETION_ALL_ACCESS, NULL, 0); - - ok( res == 0, "NtCreateIoCompletion anonymous failed: %x\n", res ); - ok( h && h != INVALID_HANDLE_VALUE, "Invalid handle returned\n" ); - - if ( h && h != INVALID_HANDLE_VALUE) - { - test_iocp_setcompletion(h); - test_iocp_fileio(h); - pNtClose(h); - } -} - static void test_file_name_information(void) { WCHAR *file_name, *volume_prefix, *expected; @@ -4466,7 +4463,8 @@ START_TEST(file) read_file_test(); append_file_test(); nt_mailslot_test(); - test_iocompletion(); + test_set_io_completion(); + test_file_io_completion(); test_file_basic_information(); test_file_all_information(); test_file_both_information();
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=42704
Your paranoid android.
=== w8 (32 bit Windows report) ===
ntdll: file.c:441: Test failed: mismatched file size for L"WindowsUpdate.log"
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/tests/file.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ include/winternl.h | 7 ++++ 2 files changed, 93 insertions(+)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 88b2b9b..e546bef 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -74,6 +74,7 @@ static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_AT static NTSTATUS (WINAPI *pNtOpenIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); static NTSTATUS (WINAPI *pNtQueryIoCompletion)(HANDLE, IO_COMPLETION_INFORMATION_CLASS, PVOID, ULONG, PULONG); static NTSTATUS (WINAPI *pNtRemoveIoCompletion)(HANDLE, PULONG_PTR, PULONG_PTR, PIO_STATUS_BLOCK, PLARGE_INTEGER); +static NTSTATUS (WINAPI *pNtRemoveIoCompletionEx)(HANDLE,FILE_IO_COMPLETION_INFORMATION*,ULONG,ULONG*,LARGE_INTEGER*,BOOLEAN); static NTSTATUS (WINAPI *pNtSetIoCompletion)(HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T); static NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); static NTSTATUS (WINAPI *pNtQueryAttributesFile)(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*); @@ -860,9 +861,17 @@ static void nt_mailslot_test(void) ok( rc == STATUS_SUCCESS, "NtClose failed\n"); }
+static void WINAPI user_apc_proc(ULONG_PTR arg) +{ + unsigned int *apc_count = (unsigned int *)arg; + ++*apc_count; +} + static void test_set_io_completion(void) { + FILE_IO_COMPLETION_INFORMATION info[2] = {{0}}; LARGE_INTEGER timeout = {{0}}; + unsigned int apc_count; IO_STATUS_BLOCK iosb; ULONG_PTR key, value; NTSTATUS res; @@ -876,6 +885,9 @@ static void test_set_io_completion(void) ok( res == STATUS_SUCCESS, "NtCreateIoCompletion failed: %#x\n", res ); ok( h && h != INVALID_HANDLE_VALUE, "got invalid handle %p\n", h );
+ res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout ); + ok( res == STATUS_TIMEOUT, "NtRemoveIoCompletion failed: %#x\n", res ); + res = pNtSetIoCompletion( h, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size ); ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %x\n", res );
@@ -892,6 +904,79 @@ static void test_set_io_completion(void) count = get_pending_msgs(h); ok( !count, "Unexpected msg count: %d\n", count );
+ if (!pNtRemoveIoCompletionEx) + { + skip("NtRemoveIoCompletionEx() not present\n"); + pNtClose( h ); + return; + } + + count = 0xdeadbeef; + res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, FALSE ); + ok( res == STATUS_TIMEOUT, "NtRemoveIoCompletionEx failed: %#x\n", res ); + ok( count == 1, "wrong count %u\n", count ); + + res = pNtSetIoCompletion( h, 123, 456, 789, size ); + ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#x\n", res ); + + count = 0xdeadbeef; + res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, FALSE ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#x\n", res ); + ok( count == 1, "wrong count %u\n", count ); + ok( info[0].CompletionKey == 123, "wrong key %#lx\n", info[0].CompletionKey ); + ok( info[0].CompletionValue == 456, "wrong value %#lx\n", info[0].CompletionValue ); + ok( info[0].IoStatusBlock.Information == size, "wrong information %#lx\n", + info[0].IoStatusBlock.Information ); + ok( U(info[0].IoStatusBlock).Status == 789, "wrong status %#x\n", U(info[0].IoStatusBlock).Status); + + res = pNtSetIoCompletion( h, 123, 456, 789, size ); + ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#x\n", res ); + + res = pNtSetIoCompletion( h, 12, 34, 56, size ); + ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#x\n", res ); + + count = 0xdeadbeef; + res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, FALSE ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#x\n", res ); + ok( count == 2, "wrong count %u\n", count ); + ok( info[0].CompletionKey == 123, "wrong key %#lx\n", info[0].CompletionKey ); + ok( info[0].CompletionValue == 456, "wrong value %#lx\n", info[0].CompletionValue ); + ok( info[0].IoStatusBlock.Information == size, "wrong information %#lx\n", + info[0].IoStatusBlock.Information ); + ok( U(info[0].IoStatusBlock).Status == 789, "wrong status %#x\n", U(info[0].IoStatusBlock).Status); + ok( info[1].CompletionKey == 12, "wrong key %#lx\n", info[1].CompletionKey ); + ok( info[1].CompletionValue == 34, "wrong value %#lx\n", info[1].CompletionValue ); + ok( info[1].IoStatusBlock.Information == size, "wrong information %#lx\n", + info[1].IoStatusBlock.Information ); + ok( U(info[1].IoStatusBlock).Status == 56, "wrong status %#x\n", U(info[1].IoStatusBlock).Status); + + apc_count = 0; + QueueUserAPC( user_apc_proc, GetCurrentThread(), (ULONG_PTR)&apc_count ); + + count = 0xdeadbeef; + res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, FALSE ); + ok( res == STATUS_TIMEOUT, "NtRemoveIoCompletionEx failed: %#x\n", res ); + ok( count == 1, "wrong count %u\n", count ); + ok( !apc_count, "wrong apc count %d\n", apc_count ); + + res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, TRUE ); + ok( res == STATUS_USER_APC, "NtRemoveIoCompletionEx failed: %#x\n", res ); + ok( count == 1, "wrong count %u\n", count ); + ok( apc_count == 1, "wrong apc count %u\n", apc_count ); + + apc_count = 0; + QueueUserAPC( user_apc_proc, GetCurrentThread(), (ULONG_PTR)&apc_count ); + + res = pNtSetIoCompletion( h, 123, 456, 789, size ); + ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#x\n", res ); + + res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, TRUE ); + ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#x\n", res ); + ok( count == 1, "wrong count %u\n", count ); + ok( !apc_count, "wrong apc count %u\n", apc_count ); + + SleepEx( 1, TRUE ); + pNtClose( h ); }
@@ -4446,6 +4531,7 @@ START_TEST(file) pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion"); pNtQueryIoCompletion = (void *)GetProcAddress(hntdll, "NtQueryIoCompletion"); pNtRemoveIoCompletion = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletion"); + pNtRemoveIoCompletionEx = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletionEx"); pNtSetIoCompletion = (void *)GetProcAddress(hntdll, "NtSetIoCompletion"); pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile"); pNtQueryAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryAttributesFile"); diff --git a/include/winternl.h b/include/winternl.h index c718d4c..74f49a1 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2128,6 +2128,12 @@ typedef struct _FILE_COMPLETION_INFORMATION { #define IO_COMPLETION_MODIFY_STATE 0x0002 #define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
+typedef struct _FILE_IO_COMPLETION_INFORMATION { + ULONG_PTR CompletionKey; + ULONG_PTR CompletionValue; + IO_STATUS_BLOCK IoStatusBlock; +} FILE_IO_COMPLETION_INFORMATION, *PFILE_IO_COMPLETION_INFORMATION; + typedef enum _HARDERROR_RESPONSE_OPTION { OptionAbortRetryIgnore, OptionOk, @@ -2469,6 +2475,7 @@ NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE,const void*,BOOLEAN,const L NTSYSAPI NTSTATUS WINAPI NtReleaseMutant(HANDLE,PLONG); NTSYSAPI NTSTATUS WINAPI NtReleaseSemaphore(HANDLE,ULONG,PULONG); NTSYSAPI NTSTATUS WINAPI NtRemoveIoCompletion(HANDLE,PULONG_PTR,PULONG_PTR,PIO_STATUS_BLOCK,PLARGE_INTEGER); +NTSYSAPI NTSTATUS WINAPI NtRemoveIoCompletionEx(HANDLE,FILE_IO_COMPLETION_INFORMATION*,ULONG,ULONG*,LARGE_INTEGER*,BOOLEAN); NTSYSAPI NTSTATUS WINAPI NtRenameKey(HANDLE,UNICODE_STRING*); NTSYSAPI NTSTATUS WINAPI NtReplaceKey(POBJECT_ATTRIBUTES,HANDLE,POBJECT_ATTRIBUTES); NTSYSAPI NTSTATUS WINAPI NtReplyPort(HANDLE,PLPC_MESSAGE);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/sync.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 5e7c463..37e4e8e 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -308,6 +308,7 @@ @ stub NtReleaseProcessMutant @ stdcall NtReleaseSemaphore(long long ptr) @ stdcall NtRemoveIoCompletion(ptr ptr ptr ptr ptr) +@ stdcall NtRemoveIoCompletionEx(ptr ptr long ptr ptr long) # @ stub NtRemoveProcessDebug @ stdcall NtRenameKey(long ptr) @ stdcall NtReplaceKey(ptr long ptr) diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index bb462f2..4ae8e36 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -1334,6 +1334,54 @@ NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE CompletionPort, PULONG_PTR Completi }
/****************************************************************** + * NtRemoveIoCompletionEx (NTDLL.@) + * ZwRemoveIoCompletionEx (NTDLL.@) + */ +NTSTATUS WINAPI NtRemoveIoCompletionEx( HANDLE port, FILE_IO_COMPLETION_INFORMATION *info, ULONG count, + ULONG *written, LARGE_INTEGER *timeout, BOOLEAN alertable ) +{ + NTSTATUS ret; + ULONG i = 0; + + TRACE("%p %p %u %p %p %u\n", port, info, count, written, timeout, alertable); + + for (;;) + { + for (;;) + { + SERVER_START_REQ( remove_completion ) + { + req->handle = wine_server_obj_handle( port ); + if (!(ret = wine_server_call( req ))) + { + info[i].CompletionKey = reply->ckey; + info[i].CompletionValue = reply->cvalue; + info[i].IoStatusBlock.Information = reply->information; + info[i].IoStatusBlock.u.Status = reply->status; + } + } + SERVER_END_REQ; + + if (ret != STATUS_SUCCESS) break; + + if (i++ >= count) break; + } + + if (i && ret == STATUS_PENDING) + { + ret = STATUS_SUCCESS; + break; + } + + ret = NtWaitForSingleObject( port, alertable, timeout ); + if (ret != WAIT_OBJECT_0) break; + } + + *written = i ? i : 1; + return ret; +} + +/****************************************************************** * NtOpenIoCompletion (NTDLL.@) * ZwOpenIoCompletion (NTDLL.@) *
September 29, 2018 11:30 PM, "Zebediah Figura" z.figura12@gmail.com wrote:
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 5e7c463..37e4e8e 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -308,6 +308,7 @@ @ stub NtReleaseProcessMutant @ stdcall NtReleaseSemaphore(long long ptr) @ stdcall NtRemoveIoCompletion(ptr ptr ptr ptr ptr) +@ stdcall NtRemoveIoCompletionEx(ptr ptr long ptr ptr long) # @ stub NtRemoveProcessDebug @ stdcall NtRenameKey(long ptr) @ stdcall NtReplaceKey(ptr long ptr)
You forgot to export ZwRemoveIoCompletionEx().
Chip
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/kernel32/tests/file.c | 111 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 33cae4b..eb27d55 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -60,6 +60,7 @@ static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR*); static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOLEAN); static BOOL (WINAPI *pSetFileInformationByHandle)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, void*, DWORD); +static BOOL (WINAPI *pGetQueuedCompletionStatusEx)(HANDLE, OVERLAPPED_ENTRY*, ULONG, ULONG*, DWORD, BOOL);
static const char filename[] = "testfile.xxx"; static const char sillytext[] = @@ -105,6 +106,7 @@ static void InitFunctionPointers(void) pGetFinalPathNameByHandleA = (void *) GetProcAddress(hkernel32, "GetFinalPathNameByHandleA"); pGetFinalPathNameByHandleW = (void *) GetProcAddress(hkernel32, "GetFinalPathNameByHandleW"); pSetFileInformationByHandle = (void *) GetProcAddress(hkernel32, "SetFileInformationByHandle"); + pGetQueuedCompletionStatusEx = (void *) GetProcAddress(hkernel32, "GetQueuedCompletionStatusEx"); }
static void test__hread( void ) @@ -4988,6 +4990,114 @@ static void test_GetFileAttributesExW(void) ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected error ERROR_FILE_NOT_FOUND, got %u\n", GetLastError()); }
+static void test_post_completion(void) +{ + OVERLAPPED ovl, ovl2, *povl; + OVERLAPPED_ENTRY entries[2]; + ULONG_PTR key; + HANDLE port; + ULONG count; + DWORD size; + BOOL ret; + + port = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 999, 0 ); + ok(port != NULL, "CreateIoCompletionPort failed: %u\n", GetLastError()); + + ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 ); + ok(!ret, "GetQueuedCompletionStatus succeeded\n"); + ok(GetLastError() == WAIT_TIMEOUT, "wrong error %u\n", GetLastError()); + + ret = PostQueuedCompletionStatus( port, 123, 456, &ovl ); + ok(ret, "PostQueuedCompletionStatus failed: %u\n", GetLastError()); + + ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 ); + ok(ret, "GetQueuedCompletionStatus failed: %u\n", GetLastError()); + ok(size == 123, "wrong size %u\n", size); + ok(key == 456, "wrong key %lu\n", key); + ok(povl == &ovl, "wrong ovl %p\n", povl); + + ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 ); + ok(!ret, "GetQueuedCompletionStatus succeeded\n"); + ok(GetLastError() == WAIT_TIMEOUT, "wrong error %u\n", GetLastError()); + + if (!pGetQueuedCompletionStatusEx) + { + skip("GetQueuedCompletionStatusEx not available\n"); + CloseHandle( port ); + return; + } + + count = 0xdeadbeef; + ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE ); + ok(!ret, "GetQueuedCompletionStatusEx succeeded\n"); + ok(GetLastError() == WAIT_TIMEOUT, "wrong error %u\n", GetLastError()); + ok(count == 1, "wrong count %u\n", count); + + ret = PostQueuedCompletionStatus( port, 123, 456, &ovl ); + ok(ret, "PostQueuedCompletionStatus failed: %u\n", GetLastError()); + + count = 0xdeadbeef; + memset( entries, 0xcc, sizeof(entries) ); + ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE ); + ok(ret, "GetQueuedCompletionStatusEx failed\n"); + ok(count == 1, "wrong count %u\n", count); + ok(entries[0].lpCompletionKey == 456, "wrong key %lu\n", entries[0].lpCompletionKey); + ok(entries[0].lpOverlapped == &ovl, "wrong ovl %p\n", entries[0].lpOverlapped); + ok(!(ULONG)entries[0].Internal, "wrong internal %#x\n", (ULONG)entries[0].Internal); + ok(entries[0].dwNumberOfBytesTransferred == 123, "wrong size %u\n", entries[0].dwNumberOfBytesTransferred); + + ret = PostQueuedCompletionStatus( port, 123, 456, &ovl ); + ok(ret, "PostQueuedCompletionStatus failed: %u\n", GetLastError()); + + ret = PostQueuedCompletionStatus( port, 654, 321, &ovl2 ); + ok(ret, "PostQueuedCompletionStatus failed: %u\n", GetLastError()); + + count = 0xdeadbeef; + memset( entries, 0xcc, sizeof(entries) ); + ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE ); + ok(ret, "GetQueuedCompletionStatusEx failed\n"); + ok(count == 2, "wrong count %u\n", count); + ok(entries[0].lpCompletionKey == 456, "wrong key %lu\n", entries[0].lpCompletionKey); + ok(entries[0].lpOverlapped == &ovl, "wrong ovl %p\n", entries[0].lpOverlapped); + ok(!(ULONG)entries[0].Internal, "wrong internal %#x\n", (ULONG)entries[0].Internal); + ok(entries[0].dwNumberOfBytesTransferred == 123, "wrong size %u\n", entries[0].dwNumberOfBytesTransferred); + ok(entries[1].lpCompletionKey == 321, "wrong key %lu\n", entries[1].lpCompletionKey); + ok(entries[1].lpOverlapped == &ovl2, "wrong ovl %p\n", entries[1].lpOverlapped); + ok(!(ULONG)entries[1].Internal, "wrong internal %#x\n", (ULONG)entries[1].Internal); + ok(entries[1].dwNumberOfBytesTransferred == 654, "wrong size %u\n", entries[1].dwNumberOfBytesTransferred); + + user_apc_ran = FALSE; + QueueUserAPC( user_apc, GetCurrentThread(), 0 ); + + ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE ); + ok(!ret, "GetQueuedCompletionStatusEx succeeded\n"); + ok(GetLastError() == WAIT_TIMEOUT, "wrong error %u\n", GetLastError()); + ok(count == 1, "wrong count %u\n", count); + ok(!user_apc_ran, "user APC should not have run\n"); + + ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, TRUE ); + ok(!ret || broken(ret) /* Vista */, "GetQueuedCompletionStatusEx succeeded\n"); + if (!ret) + ok(GetLastError() == WAIT_IO_COMPLETION, "wrong error %u\n", GetLastError()); + ok(count == 1, "wrong count %u\n", count); + ok(user_apc_ran, "user APC should have run\n"); + + user_apc_ran = FALSE; + QueueUserAPC( user_apc, GetCurrentThread(), 0 ); + + ret = PostQueuedCompletionStatus( port, 123, 456, &ovl ); + ok(ret, "PostQueuedCompletionStatus failed: %u\n", GetLastError()); + + ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, TRUE ); + ok(ret, "GetQueuedCompletionStatusEx failed\n"); + ok(count == 1, "wrong count %u\n", count); + ok(!user_apc_ran, "user APC should not have run\n"); + + SleepEx(0, TRUE); + + CloseHandle( port ); +} + START_TEST(file) { InitFunctionPointers(); @@ -5046,4 +5156,5 @@ START_TEST(file) test_GetFinalPathNameByHandleW(); test_SetFileInformationByHandle(); test_GetFileAttributesExW(); + test_post_completion(); }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43878 Signed-off-by: Zebediah Figura z.figura12@gmail.com --- .../api-ms-win-core-io-l1-1-0.spec | 2 +- .../api-ms-win-core-io-l1-1-1.spec | 2 +- dlls/kernel32/kernel32.spec | 2 +- dlls/kernel32/sync.c | 19 +++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 2 +- include/winbase.h | 1 + 6 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/dlls/api-ms-win-core-io-l1-1-0/api-ms-win-core-io-l1-1-0.spec b/dlls/api-ms-win-core-io-l1-1-0/api-ms-win-core-io-l1-1-0.spec index f73e427..ea0fd94 100644 --- a/dlls/api-ms-win-core-io-l1-1-0/api-ms-win-core-io-l1-1-0.spec +++ b/dlls/api-ms-win-core-io-l1-1-0/api-ms-win-core-io-l1-1-0.spec @@ -3,5 +3,5 @@ @ stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) kernel32.DeviceIoControl @ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult @ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long) kernel32.GetQueuedCompletionStatus -@ stub GetQueuedCompletionStatusEx +@ stdcall GetQueuedCompletionStatusEx(ptr ptr long ptr long long) kernel32.GetQueuedCompletionStatusEx @ stdcall PostQueuedCompletionStatus(long long ptr ptr) kernel32.PostQueuedCompletionStatus diff --git a/dlls/api-ms-win-core-io-l1-1-1/api-ms-win-core-io-l1-1-1.spec b/dlls/api-ms-win-core-io-l1-1-1/api-ms-win-core-io-l1-1-1.spec index 73aae1a..907c0b4 100644 --- a/dlls/api-ms-win-core-io-l1-1-1/api-ms-win-core-io-l1-1-1.spec +++ b/dlls/api-ms-win-core-io-l1-1-1/api-ms-win-core-io-l1-1-1.spec @@ -6,5 +6,5 @@ @ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult @ stub GetOverlappedResultEx @ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long) kernel32.GetQueuedCompletionStatus -@ stub GetQueuedCompletionStatusEx +@ stdcall GetQueuedCompletionStatusEx(ptr ptr long ptr long long) kernel32.GetQueuedCompletionStatusEx @ stdcall PostQueuedCompletionStatus(long long ptr ptr) kernel32.PostQueuedCompletionStatus diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 9db7d98..e17ee97 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -804,7 +804,7 @@ @ stdcall GetProfileStringA(str str str ptr long) @ stdcall GetProfileStringW(wstr wstr wstr ptr long) @ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long) -# @ stub GetQueuedCompletionStatusEx +@ stdcall GetQueuedCompletionStatusEx(ptr ptr long ptr long long) @ stub -i386 GetSLCallbackTarget @ stub -i386 GetSLCallbackTemplate @ stdcall GetShortPathNameA(str ptr long) diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c index 1345aca..67f75af 100644 --- a/dlls/kernel32/sync.c +++ b/dlls/kernel32/sync.c @@ -2389,6 +2389,25 @@ BOOL WINAPI GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOf return FALSE; }
+/****************************************************************************** + * GetQueuedCompletionStatus (KERNEL32.@) + */ +BOOL WINAPI GetQueuedCompletionStatusEx( HANDLE port, OVERLAPPED_ENTRY *entries, ULONG count, + ULONG *written, DWORD timeout, BOOL alertable ) +{ + LARGE_INTEGER time; + NTSTATUS ret; + + TRACE("%p %p %u %p %u %u\n", port, entries, count, written, timeout, alertable); + + ret = NtRemoveIoCompletionEx( port, (FILE_IO_COMPLETION_INFORMATION *)entries, count, + written, get_nt_timeout( &time, timeout ), alertable ); + if (ret == STATUS_SUCCESS) return TRUE; + else if (ret == STATUS_TIMEOUT) SetLastError( WAIT_TIMEOUT ); + else if (ret == STATUS_USER_APC) SetLastError( WAIT_IO_COMPLETION ); + else SetLastError( RtlNtStatusToDosError(ret) ); + return FALSE; +}
/****************************************************************************** * PostQueuedCompletionStatus (KERNEL32.@) diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 2980576..7fa8c1d 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -645,7 +645,7 @@ # @ stub GetPublisherCacheFolder # @ stub GetPublisherRootFolder @ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long) kernel32.GetQueuedCompletionStatus -@ stub GetQueuedCompletionStatusEx +@ stdcall GetQueuedCompletionStatusEx(ptr ptr long ptr long long) kernel32.GetQueuedCompletionStatusEx # @ stub GetRegistryExtensionFlags # @ stub GetRoamingLastObservedChangeTime @ stdcall GetSecurityDescriptorControl(ptr ptr ptr) advapi32.GetSecurityDescriptorControl diff --git a/include/winbase.h b/include/winbase.h index de52e5a..ea450e1 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2205,6 +2205,7 @@ WINBASEAPI INT WINAPI GetProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT) WINBASEAPI INT WINAPI GetProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT); #define GetProfileString WINELIB_NAME_AW(GetProfileString) WINBASEAPI BOOL WINAPI GetQueuedCompletionStatus(HANDLE,LPDWORD,PULONG_PTR,LPOVERLAPPED*,DWORD); +WINBASEAPI BOOL WINAPI GetQueuedCompletionStatusEx(HANDLE,OVERLAPPED_ENTRY*,ULONG,ULONG*,DWORD,BOOL); WINADVAPI BOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR_CONTROL,LPDWORD); WINADVAPI BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,LPBOOL,PACL *,LPBOOL); WINADVAPI BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID *,LPBOOL);
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=42701
Your paranoid android.
=== w8 (32 bit Windows report) ===
ntdll: file.c:460: Test failed: mismatched file size for L"WindowsUpdate.log"
Is it essential to test in system or windows directory? Can we create two temporary ones and use that to avoid the issue?
On 30/09/18 00:52, Nikolay Sivov wrote:
Is it essential to test in system or windows directory? Can we create two temporary ones and use that to avoid the issue?
That's a good suggestion; I'll send an updated patch.