I/O Completion Ports (2 of 2)
Robert Shearman
R.J.Shearman at warwick.ac.uk
Sun Mar 23 19:19:44 CST 2003
The Win32 API code for I/O completion ports. Separate from the server code just in case that doesn't get applied.
ChangeLog:
- Add Win32 API for I/O completion ports
License:
- LGPL
Rob
-------------- next part --------------
diff -r -u -x *.o wine/dlls/kernel/kernel32.spec newwine/dlls/kernel/kernel32.spec
--- wine/dlls/kernel/kernel32.spec Sun Mar 23 14:07:41 2003
+++ newwine/dlls/kernel/kernel32.spec Sat Mar 22 21:40:54 2003
@@ -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)
diff -r -u -x *.o wine/win32/newfns.c newwine/win32/newfns.c
--- wine/win32/newfns.c Sun Mar 23 14:06:05 2003
+++ newwine/win32/newfns.c Sat Mar 22 21:41:52 2003
@@ -286,28 +286,4 @@
{
FIXME("(%s,%p): stub\n",debugstr_w(lpFileName),lpFileSizeHigh);
return 0xffffffff;
}
-
-
-/******************************************************************************
- * 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.@)
*/
--- /dev/null Mon Jun 24 01:53:01 2002
+++ newwine/dlls/kernel/iocompletion.c Sat Mar 22 21:42:43 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;
+ }
+}
--- wine/include/winbase.h Fri Mar 14 20:07:11 2003
+++ newwine/include/winbase.h Sun Mar 23 22:06:42 2003
@@ -1208,6 +1208,7 @@
HANDLE WINAPI CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR);
HANDLE WINAPI CreateFileMappingW(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCWSTR);
#define CreateFileMapping WINELIB_NAME_AW(CreateFileMapping)
+HANDLE WINAPI CreateIoCompletionPort(HANDLE,HANDLE,ULONG_PTR,DWORD);
HANDLE WINAPI CreateMutexA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR);
HANDLE WINAPI CreateMutexW(LPSECURITY_ATTRIBUTES,BOOL,LPCWSTR);
#define CreateMutex WINELIB_NAME_AW(CreateMutex)
@@ -1342,6 +1343,7 @@
BOOL WINAPI GetProcessAffinityMask(HANDLE,PDWORD,PDWORD);
BOOL WINAPI GetProcessTimes(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME);
DWORD WINAPI GetProcessVersion(DWORD);
+BOOL WINAPI GetQueuedCompletionStatus(HANDLE,LPDWORD,PULONG_PTR,LPOVERLAPPED*,DWORD);
BOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR_CONTROL,LPDWORD);
BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,LPBOOL,PACL *,LPBOOL);
BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID *,LPBOOL);
@@ -1442,6 +1444,7 @@
HANDLE WINAPI OpenWaitableTimerW(DWORD,BOOL,LPCWSTR);
#define OpenWaitableTimer WINELIB_NAME_AW(OpenWaitableTimer)
BOOL WINAPI PeekNamedPipe(HANDLE,PVOID,DWORD,PDWORD,PDWORD,PDWORD);
+BOOL WINAPI PostQueuedCompletionStatus(HANDLE,DWORD,ULONG_PTR,LPOVERLAPPED);
DWORD WINAPI PrepareTape(HANDLE,DWORD,BOOL);
BOOL WINAPI PulseEvent(HANDLE);
BOOL WINAPI PurgeComm(HANDLE,DWORD);
More information about the wine-patches
mailing list