Module: wine Branch: master Commit: 6310819afb0ac294573551c2117f636ed8367ccc URL: http://source.winehq.org/git/wine.git/?a=commit;h=6310819afb0ac294573551c211...
Author: Andrey Turkin andrey.turkin@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; }