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