Andrey Turkin : kernel32: Implement IO completion functions on top of the NT IoCompletion API.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Jun 8 07:19:13 CDT 2007


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

Author: Andrey Turkin <andrey.turkin at gmail.com>
Date:   Sat Jun  2 02:32:07 2007 +0400

kernel32: Implement IO completion functions on top of the NT IoCompletion API.

---

 dlls/kernel32/sync.c |   75 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c
index be536a4..07bd9b0 100644
--- a/dlls/kernel32/sync.c
+++ b/dlls/kernel32/sync.c
@@ -1811,12 +1811,45 @@ BOOL WINAPI SetMailslotInfo( HANDLE hMailslot, DWORD dwReadTimeout)
 HANDLE WINAPI CreateIoCompletionPort(HANDLE hFileHandle, HANDLE hExistingCompletionPort,
                                      ULONG_PTR CompletionKey, DWORD dwNumberOfConcurrentThreads)
 {
-    FIXME("(%p, %p, %08lx, %08x): stub.\n",
+    NTSTATUS status;
+    HANDLE ret = 0;
+
+    TRACE("(%p, %p, %08lx, %08x)\n",
           hFileHandle, hExistingCompletionPort, CompletionKey, dwNumberOfConcurrentThreads);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return NULL;
-}
 
+    if (hExistingCompletionPort && hFileHandle == INVALID_HANDLE_VALUE)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER);
+        return NULL;
+    }
+
+    if (hExistingCompletionPort)
+        ret = hExistingCompletionPort;
+    else
+    {
+        status = NtCreateIoCompletion( &ret, IO_COMPLETION_ALL_ACCESS, NULL, dwNumberOfConcurrentThreads );
+        if (status != STATUS_SUCCESS) goto fail;
+    }
+
+    if (hFileHandle != INVALID_HANDLE_VALUE)
+    {
+        FILE_COMPLETION_INFORMATION info;
+        IO_STATUS_BLOCK iosb;
+
+        info.CompletionPort = ret;
+        info.CompletionKey = CompletionKey;
+        status = NtSetInformationFile( hFileHandle, &iosb, &info, sizeof(info), FileCompletionInformation );
+        if (status != STATUS_SUCCESS) goto fail;
+    }
+
+    return ret;
+
+fail:
+    if (ret && !hExistingCompletionPort)
+        CloseHandle( ret );
+    SetLastError( RtlNtStatusToDosError(status) );
+    return 0;
+}
 
 /******************************************************************************
  *		GetQueuedCompletionStatus (KERNEL32.@)
@@ -1825,17 +1858,43 @@ BOOL WINAPI GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOf
                                        PULONG_PTR pCompletionKey, LPOVERLAPPED *lpOverlapped,
                                        DWORD dwMilliseconds )
 {
-    FIXME("(%p,%p,%p,%p,%d), stub!\n",
+    NTSTATUS status;
+    IO_STATUS_BLOCK iosb;
+    LARGE_INTEGER wait_time;
+
+    TRACE("(%p,%p,%p,%p,%d)\n",
           CompletionPort,lpNumberOfBytesTransferred,pCompletionKey,lpOverlapped,dwMilliseconds);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+
+    *lpOverlapped = NULL;
+
+    status = NtRemoveIoCompletion( CompletionPort, pCompletionKey, (PULONG_PTR)lpOverlapped,
+                                   &iosb, get_nt_timeout( &wait_time, dwMilliseconds ) );
+    if (status == STATUS_SUCCESS)
+    {
+        *lpNumberOfBytesTransferred = iosb.Information;
+        return TRUE;
+    }
+
+    SetLastError( RtlNtStatusToDosError(status) );
     return FALSE;
 }
 
+
+/******************************************************************************
+ *		PostQueuedCompletionStatus (KERNEL32.@)
+ */
 BOOL WINAPI PostQueuedCompletionStatus( HANDLE CompletionPort, DWORD dwNumberOfBytes,
                                         ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped)
 {
-    FIXME("%p %d %08lx %p\n", CompletionPort, dwNumberOfBytes, dwCompletionKey, lpOverlapped );
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    NTSTATUS status;
+
+    TRACE("%p %d %08lx %p\n", CompletionPort, dwNumberOfBytes, dwCompletionKey, lpOverlapped );
+
+    status = NtSetIoCompletion( CompletionPort, dwCompletionKey, (ULONG_PTR)lpOverlapped,
+                                STATUS_SUCCESS, dwNumberOfBytes );
+
+    if (status == STATUS_SUCCESS) return TRUE;
+    SetLastError( RtlNtStatusToDosError(status) );
     return FALSE;
 }
 




More information about the wine-cvs mailing list