Mike Kaplinskiy : ntdll: Implement NtCancelIoFileEx and fix NtCancelIoFile.

Alexandre Julliard julliard at winehq.org
Tue Aug 18 10:01:23 CDT 2009


Module: wine
Branch: master
Commit: af25949a51f8ef8bd6edfd1b078d7760c13c6702
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=af25949a51f8ef8bd6edfd1b078d7760c13c6702

Author: Mike Kaplinskiy <mike.kaplinskiy at gmail.com>
Date:   Sun Aug  9 00:11:30 2009 -0400

ntdll: Implement NtCancelIoFileEx and fix NtCancelIoFile.

---

 dlls/ntdll/file.c         |   44 +++++++++++++++++++++++++++++++++++++++++---
 dlls/ntdll/ntdll.spec     |    2 ++
 dlls/ntdll/tests/change.c |    5 ++---
 dlls/ntdll/tests/file.c   |    2 +-
 include/winternl.h        |    1 +
 5 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 3fa6f19..561baf0 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -2604,6 +2604,38 @@ NTSTATUS WINAPI NtDeleteFile( POBJECT_ATTRIBUTES ObjectAttributes )
 }
 
 /******************************************************************
+ *		NtCancelIoFileEx    (NTDLL.@)
+ *
+ *
+ */
+NTSTATUS WINAPI NtCancelIoFileEx( HANDLE hFile, PIO_STATUS_BLOCK iosb, PIO_STATUS_BLOCK io_status )
+{
+    LARGE_INTEGER timeout;
+
+    TRACE("%p %p %p\n", hFile, iosb, io_status );
+
+    SERVER_START_REQ( cancel_async )
+    {
+        req->handle      = wine_server_obj_handle( hFile );
+        req->iosb        = wine_server_client_ptr( iosb );
+        req->only_thread = FALSE;
+        io_status->u.Status = wine_server_call( req );
+    }
+    SERVER_END_REQ;
+    if (io_status->u.Status)
+        return io_status->u.Status;
+
+    /* Let some APC be run, so that we can run the remaining APCs on hFile
+     * either the cancelation of the pending one, but also the execution
+     * of the queued APC, but not yet run. This is needed to ensure proper
+     * clean-up of allocated data.
+     */
+    timeout.u.LowPart = timeout.u.HighPart = 0;
+    NtDelayExecution( TRUE, &timeout );
+    return io_status->u.Status;
+}
+
+/******************************************************************
  *		NtCancelIoFile    (NTDLL.@)
  *
  *
@@ -2616,17 +2648,23 @@ NTSTATUS WINAPI NtCancelIoFile( HANDLE hFile, PIO_STATUS_BLOCK io_status )
 
     SERVER_START_REQ( cancel_async )
     {
-        req->handle = wine_server_obj_handle( hFile );
-        wine_server_call( req );
+        req->handle      = wine_server_obj_handle( hFile );
+        req->iosb        = 0;
+        req->only_thread = TRUE;
+        io_status->u.Status = wine_server_call( req );
     }
     SERVER_END_REQ;
+    if (io_status->u.Status)
+        return io_status->u.Status;
+
     /* Let some APC be run, so that we can run the remaining APCs on hFile
      * either the cancelation of the pending one, but also the execution
      * of the queued APC, but not yet run. This is needed to ensure proper
      * clean-up of allocated data.
      */
     timeout.u.LowPart = timeout.u.HighPart = 0;
-    return io_status->u.Status = NtDelayExecution( TRUE, &timeout );
+    NtDelayExecution( TRUE, &timeout );
+    return io_status->u.Status;
 }
 
 /******************************************************************************
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 03686b2..6ec1dc0 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -109,6 +109,7 @@
 @ stub NtCallbackReturn
 # @ stub NtCancelDeviceWakeupRequest
 @ stdcall NtCancelIoFile(long ptr)
+@ stdcall NtCancelIoFileEx(long ptr ptr)
 @ stdcall NtCancelTimer(long ptr)
 @ stdcall NtClearEvent(long)
 @ stdcall NtClose(long)
@@ -959,6 +960,7 @@
 @ stub ZwCallbackReturn
 # @ stub ZwCancelDeviceWakeupRequest
 @ stdcall ZwCancelIoFile(long ptr) NtCancelIoFile
+@ stdcall ZwCancelIoFileEx(long ptr ptr) NtCancelIoFileEx
 @ stdcall ZwCancelTimer(long ptr) NtCancelTimer
 @ stdcall ZwClearEvent(long) NtClearEvent
 @ stdcall ZwClose(long) NtClose
diff --git a/dlls/ntdll/tests/change.c b/dlls/ntdll/tests/change.c
index f395962..ed7f22c 100644
--- a/dlls/ntdll/tests/change.c
+++ b/dlls/ntdll/tests/change.c
@@ -295,15 +295,14 @@ static void test_ntncdf_async(void)
     ok(U(iosb).Status == 0x01234567, "status set too soon\n");
     ok(iosb.Information == 0x12345678, "info set too soon\n");
 
-    todo_wine {
     r = pNtCancelIoFile(hdir, &iosb);
     ok( r == STATUS_SUCCESS, "cancel failed\n");
 
     CloseHandle(hdir);
 
     ok(U(iosb).Status == STATUS_SUCCESS, "status wrong\n");
-    ok(U(iosb2).Status == STATUS_CANCELLED, "status wrong\n");
-    }
+    todo_wine ok(U(iosb2).Status == STATUS_CANCELLED, "status wrong\n");
+
     ok(iosb.Information == 0, "info wrong\n");
     ok(iosb2.Information == 0, "info wrong\n");
 
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index a0e713a..ba3c688 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -376,7 +376,7 @@ static void read_file_test(void)
         ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status );
         ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information );
         ok( is_signaled( event ), "event is signaled\n" );
-        ok( !apc_count, "apc was called\n" );
+        todo_wine ok( !apc_count, "apc was called\n" );
         SleepEx( 1, TRUE ); /* alertable sleep */
         ok( apc_count == 1, "apc was not called\n" );
         CloseHandle( read );
diff --git a/include/winternl.h b/include/winternl.h
index 6d0b480..1d300bf 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2013,6 +2013,7 @@ NTSYSAPI NTSTATUS  WINAPI NtAreMappedFilesTheSame(PVOID,PVOID);
 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 NtCancelTimer(HANDLE, BOOLEAN*);
 NTSYSAPI NTSTATUS  WINAPI NtClearEvent(HANDLE);
 NTSYSAPI NTSTATUS  WINAPI NtClose(HANDLE);




More information about the wine-cvs mailing list