[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