[PATCH 2/4] ntdll: Add NtCancelSynchronousIoFile stub.

Daniel Lehman dlehman25 at gmail.com
Tue Apr 19 00:49:36 CDT 2022


Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>
---
 dlls/ntdll/ntdll.spec    |  2 +
 dlls/ntdll/tests/pipe.c  | 93 ++++++++++++++++++++++++++++++++++++++++
 dlls/ntdll/unix/file.c   |  9 ++++
 dlls/ntdll/unix/loader.c |  1 +
 include/winternl.h       |  1 +
 5 files changed, 106 insertions(+)

diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 311f99be054..74152ef10bc 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -153,6 +153,7 @@
 # @ stub NtCancelDeviceWakeupRequest
 @ stdcall -syscall NtCancelIoFile(long ptr)
 @ stdcall -syscall NtCancelIoFileEx(long ptr ptr)
+@ stdcall -syscall NtCancelSynchronousIoFile(long ptr ptr)
 @ stdcall -syscall NtCancelTimer(long ptr)
 @ stdcall -syscall NtClearEvent(long)
 @ stdcall -syscall NtClose(long)
@@ -1181,6 +1182,7 @@
 # @ stub ZwCancelDeviceWakeupRequest
 @ stdcall -private -syscall ZwCancelIoFile(long ptr) NtCancelIoFile
 @ stdcall -private -syscall ZwCancelIoFileEx(long ptr ptr) NtCancelIoFileEx
+@ stdcall -private -syscall ZwCancelSynchronousIoFile(long ptr ptr) NtCancelSynchronousIoFile
 @ stdcall -private -syscall ZwCancelTimer(long ptr) NtCancelTimer
 @ stdcall -private -syscall ZwClearEvent(long) NtClearEvent
 @ stdcall -private -syscall ZwClose(long) NtClose
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index dc9737e73d8..1298e7a37ae 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -79,6 +79,7 @@ static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE handle, PIO_STATU
 static NTSTATUS (WINAPI *pNtSetInformationFile) (HANDLE handle, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class);
 static NTSTATUS (WINAPI *pNtCancelIoFile) (HANDLE hFile, PIO_STATUS_BLOCK io_status);
 static NTSTATUS (WINAPI *pNtCancelIoFileEx) (HANDLE hFile, IO_STATUS_BLOCK *iosb, IO_STATUS_BLOCK *io_status);
+static NTSTATUS (WINAPI *pNtCancelSynchronousIoFile) (HANDLE hFile, IO_STATUS_BLOCK *iosb, IO_STATUS_BLOCK *io_status);
 static NTSTATUS (WINAPI *pNtRemoveIoCompletion)(HANDLE, PULONG_PTR, PULONG_PTR, PIO_STATUS_BLOCK, PLARGE_INTEGER);
 static void (WINAPI *pRtlInitUnicodeString) (PUNICODE_STRING target, PCWSTR source);
 
@@ -103,6 +104,7 @@ static BOOL init_func_ptrs(void)
     loadfunc(NtQueryVolumeInformationFile)
     loadfunc(NtSetInformationFile)
     loadfunc(NtCancelIoFile)
+    loadfunc(NtCancelSynchronousIoFile)
     loadfunc(RtlInitUnicodeString)
     loadfunc(NtRemoveIoCompletion)
 
@@ -562,6 +564,94 @@ static void test_cancelio(void)
     CloseHandle(hEvent);
 }
 
+static DWORD WINAPI synchronousio_thread(void *arg)
+{
+    IO_STATUS_BLOCK iosb;
+    NTSTATUS res;
+    HANDLE pipe;
+
+    pipe = arg;
+    U(iosb).Status = 0xdeadbabe;
+    iosb.Information = 0xdeadbeef;
+    res = listen_pipe(pipe, NULL, &iosb, FALSE);
+    todo_wine {
+    ok(res == STATUS_CANCELLED, "NtFsControlFile returned %lx\n", res);
+    ok(U(iosb).Status == 0xdeadbabe, "wrong status %lx\n", U(iosb).Status);
+    ok(iosb.Information == 0xdeadbeef, "wrong info %Iu\n", iosb.Information);
+    }
+    return 0;
+}
+
+static void test_cancelsynchronousio(void)
+{
+    DWORD ret;
+    HANDLE pipe;
+    HANDLE event;
+    HANDLE thread;
+    HANDLE client;
+    NTSTATUS res;
+    IO_STATUS_BLOCK iosb;
+
+    /* bogus values */
+    res = pNtCancelSynchronousIoFile((HANDLE)0xdeadbeef, NULL, &iosb);
+    todo_wine
+    ok(res == STATUS_INVALID_HANDLE, "NtCancelSynchronousIoFile returned %lx\n", res);
+    res = pNtCancelSynchronousIoFile(GetCurrentThread(), NULL, NULL);
+    todo_wine
+    ok(res == STATUS_ACCESS_VIOLATION, "NtCancelSynchronousIoFile returned %lx\n", res);
+    res = pNtCancelSynchronousIoFile(GetCurrentThread(), NULL, (IO_STATUS_BLOCK*)0xdeadbeef);
+    todo_wine
+    ok(res == STATUS_ACCESS_VIOLATION, "NtCancelSynchronousIoFile returned %lx\n", res);
+    memset(&iosb, 0x55, sizeof(iosb));
+    res = pNtCancelSynchronousIoFile(GetCurrentThread(), (HANDLE)0xdeadbeef, &iosb);
+    todo_wine
+    ok(res == STATUS_ACCESS_VIOLATION || broken(res == STATUS_NOT_FOUND),
+        "NtCancelSynchronousIoFile returned %lx\n", res);
+
+    /* synchronous i/o */
+    res = create_pipe(&pipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT);
+    ok(!res, "NtCreateNamedPipeFile returned %lx\n", res);
+    thread = CreateThread(NULL, 0, synchronousio_thread, pipe, 0, 0);
+    /* wait for thread to start listening */
+    Sleep(100);
+    memset(&iosb, 0x55, sizeof(iosb));
+    res = pNtCancelSynchronousIoFile(thread, NULL, &iosb);
+    todo_wine {
+    ok(res == STATUS_SUCCESS, "Failed to cancel I/O\n");
+    ok(U(iosb).Status == STATUS_SUCCESS, "iosb.Status got changed to %lx\n", U(iosb).Status);
+    ok(U(iosb).Information == 0, "iosb.Information got changed to %Iu\n", U(iosb).Information);
+    }
+    CloseHandle(pipe);
+    WaitForSingleObject(thread, INFINITE);
+    CloseHandle(thread);
+
+    /* asynchronous i/o */
+    res = create_pipe(&pipe, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
+    ok(!res, "NtCreateNamedPipeFile returned %lx\n", res);
+    event = CreateEventW(NULL, TRUE, FALSE, NULL);
+    ok(event != INVALID_HANDLE_VALUE, "Can't create event, GetLastError: %lx\n", GetLastError());
+    memset(&iosb, 0x55, sizeof(iosb));
+    res = listen_pipe(pipe, event, &iosb, FALSE);
+    ok(res == STATUS_PENDING, "NtFsControlFile returned %lx\n", res);
+    memset(&iosb, 0x55, sizeof(iosb));
+    res = pNtCancelSynchronousIoFile(GetCurrentThread(), NULL, &iosb);
+    todo_wine {
+    ok(res == STATUS_NOT_FOUND, "NtCancelSynchronousIoFile returned %lx\n", res);
+    ok(U(iosb).Status == STATUS_NOT_FOUND, "iosb.Status got changed to %lx\n", U(iosb).Status);
+    ok(U(iosb).Information == 0, "iosb.Information got changed to %Iu\n", U(iosb).Information);
+    }
+    ret = WaitForSingleObject(event, 0);
+    ok(ret == WAIT_TIMEOUT, "wait returned %lx\n", ret);
+    client = CreateFileW(testpipe, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
+                         FILE_FLAG_OVERLAPPED, 0);
+    ok(client != INVALID_HANDLE_VALUE, "can't open pipe: %lu\n", GetLastError());
+    ret = WaitForSingleObject(event, 0);
+    ok(ret == WAIT_OBJECT_0, "wait returned %lx\n", ret);
+    CloseHandle(pipe);
+    CloseHandle(event);
+    CloseHandle(client);
+}
+
 static void _check_pipe_handle_state(int line, HANDLE handle, ULONG read, ULONG completion)
 {
     IO_STATUS_BLOCK iosb;
@@ -2606,6 +2696,9 @@ START_TEST(pipe)
     trace("starting cancelio tests\n");
     test_cancelio();
 
+    trace("starting cancelsynchronousio tests\n");
+    test_cancelsynchronousio();
+
     trace("starting byte read in byte mode client -> server\n");
     read_pipe_test(PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE);
     trace("starting byte read in message mode client -> server\n");
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index cc8bf0c6e82..6990f9b4719 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -5970,6 +5970,15 @@ NTSTATUS WINAPI NtCancelIoFileEx( HANDLE handle, IO_STATUS_BLOCK *io, IO_STATUS_
 }
 
 
+/**************************************************************************
+ *           NtCancelSynchronousIoFile (NTDLL.@)
+ */
+NTSTATUS WINAPI NtCancelSynchronousIoFile( HANDLE handle, IO_STATUS_BLOCK *io, IO_STATUS_BLOCK *io_status )
+{
+    FIXME( "(%p,%p,%p) stub\n", handle, io, io_status );
+    return STATUS_NOT_IMPLEMENTED;
+}
+
 /******************************************************************
  *           NtLockFile   (NTDLL.@)
  */
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index d1c42ddc0f3..a3ddce6414a 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -139,6 +139,7 @@ static void * const syscalls[] =
     NtCallbackReturn,
     NtCancelIoFile,
     NtCancelIoFileEx,
+    NtCancelSynchronousIoFile,
     NtCancelTimer,
     NtClearEvent,
     NtClose,
diff --git a/include/winternl.h b/include/winternl.h
index b4942d86b4c..7e41ad6ab60 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -3927,6 +3927,7 @@ NTSYSAPI NTSTATUS  WINAPI NtAssignProcessToJobObject(HANDLE,HANDLE);
 NTSYSAPI NTSTATUS  WINAPI NtCallbackReturn(PVOID,ULONG,NTSTATUS);
 NTSYSAPI NTSTATUS  WINAPI NtCancelIoFile(HANDLE,PIO_STATUS_BLOCK);
 NTSYSAPI NTSTATUS  WINAPI NtCancelIoFileEx(HANDLE,PIO_STATUS_BLOCK,PIO_STATUS_BLOCK);
+NTSYSAPI NTSTATUS  WINAPI NtCancelSynchronousIoFile(HANDLE,PIO_STATUS_BLOCK,PIO_STATUS_BLOCK);
 NTSYSAPI NTSTATUS  WINAPI NtCancelTimer(HANDLE, BOOLEAN*);
 NTSYSAPI NTSTATUS  WINAPI NtClearEvent(HANDLE);
 NTSYSAPI NTSTATUS  WINAPI NtClose(HANDLE);
-- 
2.25.1




More information about the wine-devel mailing list