I/O Completion Ports (2 of 2) - reworked
Robert Shearman
R.J.Shearman at warwick.ac.uk
Mon Apr 21 10:31:37 CDT 2003
The Win32 API code for I/O completion ports.
ChangeLog:
- Add Win32 API for I/O completion ports
License:
- LGPL
Rob
-------------- next part --------------
Index: dlls/kernel/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/kernel/Makefile.in,v
retrieving revision 1.61
diff -u -r1.61 Makefile.in
--- dlls/kernel/Makefile.in 31 Mar 2003 23:58:27 -0000 1.61
+++ dlls/kernel/Makefile.in 21 Apr 2003 14:44:12 -0000
@@ -29,6 +29,7 @@
debugger.c \
editline.c \
format_msg.c \
+ iocompletion.c \
kernel_main.c \
lcformat.c \
locale.c \
Index: dlls/kernel/kernel32.spec
===================================================================
RCS file: /home/wine/wine/dlls/kernel/kernel32.spec,v
retrieving revision 1.99
diff -u -r1.99 kernel32.spec
--- dlls/kernel/kernel32.spec 8 Apr 2003 19:40:37 -0000 1.99
+++ dlls/kernel/kernel32.spec 21 Apr 2003 14:44:15 -0000
@@ -644,7 +644,7 @@
@ stdcall PeekConsoleInputA(ptr ptr long ptr)
@ stdcall PeekConsoleInputW(ptr ptr long ptr)
@ stdcall PeekNamedPipe(long ptr long ptr ptr ptr)
-@ stub PostQueuedCompletionStatus
+@ stdcall PostQueuedCompletionStatus(ptr long long ptr)
@ stdcall PrepareTape(ptr long long)
@ stub PrivMoveFileIdentityW
@ stdcall Process32First (ptr ptr)
Index: win32/newfns.c
===================================================================
RCS file: /home/wine/wine/win32/newfns.c,v
retrieving revision 1.46
diff -u -r1.46 newfns.c
--- win32/newfns.c 14 Mar 2003 23:01:24 -0000 1.46
+++ win32/newfns.c 21 Apr 2003 14:47:34 -0000
@@ -290,29 +290,6 @@
/******************************************************************************
- * CreateIoCompletionPort (KERNEL32.@)
- */
-HANDLE WINAPI CreateIoCompletionPort(HANDLE hFileHandle,
-HANDLE hExistingCompletionPort, DWORD dwCompletionKey,
-DWORD dwNumberOfConcurrentThreads)
-{
- FIXME("(%p, %p, %08lx, %08lx): stub.\n", hFileHandle, hExistingCompletionPort, dwCompletionKey, dwNumberOfConcurrentThreads);
- return NULL;
-}
-
-/******************************************************************************
- * GetQueuedCompletionStatus (KERNEL32.@)
- */
-BOOL WINAPI GetQueuedCompletionStatus(
- HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred,
- LPDWORD lpCompletionKey, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds
-) {
- FIXME("(%p,%p,%p,%p,%ld), stub!\n",CompletionPort,lpNumberOfBytesTransferred,lpCompletionKey,lpOverlapped,dwMilliseconds);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/******************************************************************************
* GetDevicePowerState (KERNEL32.@)
*/
BOOL WINAPI GetDevicePowerState(HANDLE hDevice, BOOL* pfOn)
--- /dev/null Mon Jun 24 01:53:01 2002
+++ dlls/kernel/iocompletion.c Mon Mar 24 23:41:46 2003
@@ -0,0 +1,112 @@
+/*
+ * I/O Completion Ports
+ *
+ * Copyright (C) 2003 Robert Shearman
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "winbase.h"
+#include "winnt.h"
+#include "winternl.h"
+
+HANDLE WINAPI CreateIoCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads)
+{
+ HANDLE CompletionPort;
+ NTSTATUS Status;
+ if (((FileHandle == INVALID_HANDLE_VALUE) && (ExistingCompletionPort != NULL)) ||
+ (ExistingCompletionPort == INVALID_HANDLE_VALUE))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return INVALID_HANDLE_VALUE;
+ }
+ if (ExistingCompletionPort == NULL)
+ {
+ Status = NtCreateIoCompletion(&CompletionPort, GENERIC_ALL, 0, NumberOfConcurrentThreads);
+ if (Status != STATUS_SUCCESS)
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return INVALID_HANDLE_VALUE;
+ }
+ }
+ else
+ CompletionPort = ExistingCompletionPort;
+
+ if (FileHandle != INVALID_HANDLE_VALUE)
+ {
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_COMPLETION_INFORMATION CompletionInfo;
+ CompletionInfo.CompletionKey = CompletionKey;
+ CompletionInfo.CompletionPort = CompletionPort;
+
+ Status = NtSetInformationFile(FileHandle, &IoStatusBlock, (PVOID)&CompletionInfo, sizeof(FILE_COMPLETION_INFORMATION), FileCompletionInformation);
+ if (Status != STATUS_SUCCESS)
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return INVALID_HANDLE_VALUE;
+ }
+ }
+ return CompletionPort;
+}
+
+BOOL WINAPI GetQueuedCompletionStatus(HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred,
+ PULONG_PTR lpCompletionKey, LPOVERLAPPED * lplpOverlapped, DWORD dwMilliseconds)
+{
+ IO_STATUS_BLOCK CompletionBlock;
+ NTSTATUS Status;
+
+ if (dwMilliseconds == INFINITE)
+ {
+ Status = NtRemoveIoCompletion(CompletionPort, lpCompletionKey, lplpOverlapped, &CompletionBlock, NULL);
+ }
+ else
+ {
+ LARGE_INTEGER WaitTime;
+ /* multiplying two LONGLONGs with at least one LONGLONG having its
+ * higher long part not zero makes the multiplying a bit harder,
+ * therefore we do an easy multiply and negate afterwards rather than
+ * making it a hard multiply by doing "* -10000"
+ */
+ WaitTime.QuadPart = (LONGLONG)dwMilliseconds * (LONGLONG)10000;
+ WaitTime.QuadPart = -WaitTime.QuadPart;
+ Status = NtRemoveIoCompletion(CompletionPort, lpCompletionKey, lplpOverlapped, &CompletionBlock, &WaitTime);
+ }
+ if (Status == STATUS_SUCCESS)
+ {
+ *lpNumberOfBytesTransferred = CompletionBlock.Information;
+ return TRUE;
+ }
+ else
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+}
+
+BOOL WINAPI PostQueuedCompletionStatus(HANDLE CompletionPort, DWORD dwNumberOfBytesTransferred,
+ ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped)
+{
+ NTSTATUS Status;
+ Status = NtSetIoCompletion(CompletionPort, dwCompletionKey, lpOverlapped, 0, dwNumberOfBytesTransferred);
+ if (Status == STATUS_SUCCESS)
+ {
+ return TRUE;
+ }
+ else
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+}
More information about the wine-patches
mailing list