Author: ion
Date: Tue Feb 21 21:31:01 2012
New Revision: 55793
URL:
http://svn.reactos.org/svn/reactos?rev=55793&view=rev
Log:
[KERNEL32]: Format, comment, annotate, cleanup the I/O completion APIs.
Modified:
trunk/reactos/dll/win32/kernel32/client/file/iocompl.c
Modified: trunk/reactos/dll/win32/kernel32/client/file/iocompl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/file/iocompl.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/file/iocompl.c [iso-8859-1] Tue Feb 21
21:31:01 2012
@@ -13,164 +13,160 @@
#define NDEBUG
#include <debug.h>
-#define NANOS_TO_100NS(nanos) (((LONGLONG)(nanos)) / 100)
-#define MICROS_TO_100NS(micros) (((LONGLONG)(micros)) * NANOS_TO_100NS(1000))
-#define MILLIS_TO_100NS(milli) (((LONGLONG)(milli)) * MICROS_TO_100NS(1000))
-
/*
* @implemented
*/
HANDLE
WINAPI
-CreateIoCompletionPort(
- HANDLE FileHandle,
- HANDLE ExistingCompletionPort,
- ULONG_PTR CompletionKey,
- DWORD NumberOfConcurrentThreads
- )
-{
- HANDLE CompletionPort = NULL;
- NTSTATUS errCode;
- FILE_COMPLETION_INFORMATION CompletionInformation;
- IO_STATUS_BLOCK IoStatusBlock;
-
- if ( FileHandle == INVALID_HANDLE_VALUE && ExistingCompletionPort != NULL )
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- if ( ExistingCompletionPort != NULL )
- {
- CompletionPort = ExistingCompletionPort;
- }
- else
- {
-
- errCode = NtCreateIoCompletion(&CompletionPort,
- IO_COMPLETION_ALL_ACCESS,
- NULL,//ObjectAttributes
- NumberOfConcurrentThreads);
-
- if (!NT_SUCCESS(errCode) )
- {
- BaseSetLastNTError (errCode);
- return FALSE;
- }
-
- }
-
- if ( FileHandle != INVALID_HANDLE_VALUE )
- {
- CompletionInformation.Port = CompletionPort;
- CompletionInformation.Key = (PVOID)CompletionKey;
-
- errCode = NtSetInformationFile(FileHandle,
- &IoStatusBlock,
- &CompletionInformation,
- sizeof(FILE_COMPLETION_INFORMATION),
- FileCompletionInformation);
-
- if ( !NT_SUCCESS(errCode) )
- {
- if ( ExistingCompletionPort == NULL )
- {
- NtClose(CompletionPort);
- }
-
- BaseSetLastNTError (errCode);
- return FALSE;
- }
- }
-
- return CompletionPort;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-GetQueuedCompletionStatus(
- HANDLE CompletionHandle,
- LPDWORD lpNumberOfBytesTransferred,
- PULONG_PTR lpCompletionKey,
- LPOVERLAPPED *lpOverlapped,
- DWORD dwMilliseconds
- )
-{
- NTSTATUS errCode;
- IO_STATUS_BLOCK IoStatus;
- ULONG_PTR CompletionKey;
- LARGE_INTEGER Time;
- PLARGE_INTEGER TimePtr;
-
- if (!lpNumberOfBytesTransferred || !lpCompletionKey || !lpOverlapped)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- /* Convert the timeout */
- TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);
-
- errCode = NtRemoveIoCompletion(CompletionHandle,
+CreateIoCompletionPort(IN HANDLE FileHandle,
+ IN HANDLE ExistingCompletionPort,
+ IN ULONG_PTR CompletionKey,
+ IN DWORD NumberOfConcurrentThreads)
+{
+ NTSTATUS Status;
+ HANDLE NewPort;
+ FILE_COMPLETION_INFORMATION CompletionInformation;
+ IO_STATUS_BLOCK IoStatusBlock;
+
+ /* Check if this is a new port */
+ NewPort = ExistingCompletionPort;
+ if (!ExistingCompletionPort)
+ {
+ /* Create it */
+ Status = NtCreateIoCompletion(&NewPort,
+ IO_COMPLETION_ALL_ACCESS,
+ NULL,
+ NumberOfConcurrentThreads);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Convert error and fail */
+ BaseSetLastNTError(Status);
+ return FALSE;
+ }
+ }
+
+ /* Check if no actual file is being associated with the completion port */
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ {
+ /* Was there a port already associated? */
+ if (ExistingCompletionPort)
+ {
+ /* You are not allowed using an old port and dropping the handle */
+ NewPort = NULL;
+ BaseSetLastNTError(STATUS_INVALID_PARAMETER);
+ }
+ }
+ else
+ {
+ /* We have a file handle, so associated it with this completion port */
+ CompletionInformation.Port = NewPort;
+ CompletionInformation.Key = (PVOID)CompletionKey;
+ Status = NtSetInformationFile(FileHandle,
+ &IoStatusBlock,
+ &CompletionInformation,
+ sizeof(FILE_COMPLETION_INFORMATION),
+ FileCompletionInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Convert the error code and close the newly created port, if any */
+ BaseSetLastNTError(Status);
+ if (!ExistingCompletionPort) NtClose(NewPort);
+ return FALSE;
+ }
+ }
+
+ /* Return the newly created port, if any */
+ return NewPort;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+GetQueuedCompletionStatus(IN HANDLE CompletionHandle,
+ IN LPDWORD lpNumberOfBytesTransferred,
+ OUT PULONG_PTR lpCompletionKey,
+ OUT LPOVERLAPPED *lpOverlapped,
+ IN DWORD dwMilliseconds)
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatus;
+ ULONG_PTR CompletionKey;
+ LARGE_INTEGER Time;
+ PLARGE_INTEGER TimePtr;
+
+ /* Convert the timeout and then call the native API */
+ TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);
+ Status = NtRemoveIoCompletion(CompletionHandle,
(PVOID*)&CompletionKey,
(PVOID*)lpOverlapped,
&IoStatus,
TimePtr);
-
- if (!NT_SUCCESS(errCode) || errCode == STATUS_TIMEOUT) {
- *lpOverlapped = NULL;
-
- if(errCode == STATUS_TIMEOUT)
- SetLastError(WAIT_TIMEOUT);
- else
- BaseSetLastNTError(errCode);
-
- return FALSE;
- }
-
- *lpCompletionKey = CompletionKey;
- *lpNumberOfBytesTransferred = IoStatus.Information;
-
- if (!NT_SUCCESS(IoStatus.Status)){
- //failed io operation
- BaseSetLastNTError(IoStatus.Status);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-PostQueuedCompletionStatus(
- HANDLE CompletionHandle,
- DWORD dwNumberOfBytesTransferred,
- ULONG_PTR dwCompletionKey,
- LPOVERLAPPED lpOverlapped
- )
-{
- NTSTATUS errCode;
-
- errCode = NtSetIoCompletion(CompletionHandle,
- (PVOID)dwCompletionKey, // KeyContext
- (PVOID)lpOverlapped, // ApcContext
- STATUS_SUCCESS, // IoStatusBlock->Status
- dwNumberOfBytesTransferred); //
IoStatusBlock->Information
-
- if ( !NT_SUCCESS(errCode) )
- {
- BaseSetLastNTError (errCode);
- return FALSE;
- }
- return TRUE;
+ if (!(NT_SUCCESS(Status)) || (Status == STATUS_TIMEOUT))
+ {
+ /* Clear out the overlapped output */
+ *lpOverlapped = NULL;
+
+ /* Check what kind of error we got */
+ if (Status == STATUS_TIMEOUT)
+ {
+ /* Timeout error is set directly since there's no conversion */
+ SetLastError(WAIT_TIMEOUT);
+ }
+ else
+ {
+ /* Any other error gets converted */
+ BaseSetLastNTError(Status);
+ }
+
+ /* This is a failure case */
+ return FALSE;
+ }
+
+ /* Write back the output parameters */
+ *lpCompletionKey = CompletionKey;
+ *lpNumberOfBytesTransferred = IoStatus.Information;
+
+ /* Check for error */
+ if (!NT_SUCCESS(IoStatus.Status))
+ {
+ /* Convert and fail */
+ BaseSetLastNTError(IoStatus.Status);
+ return FALSE;
+ }
+
+ /* Return success */
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+PostQueuedCompletionStatus(IN HANDLE CompletionHandle,
+ IN DWORD dwNumberOfBytesTransferred,
+ IN ULONG_PTR dwCompletionKey,
+ IN LPOVERLAPPED lpOverlapped)
+{
+ NTSTATUS Status;
+
+ /* Call the native API */
+ Status = NtSetIoCompletion(CompletionHandle,
+ (PVOID)dwCompletionKey,
+ (PVOID)lpOverlapped,
+ STATUS_SUCCESS,
+ dwNumberOfBytesTransferred);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Convert the error and fail */
+ BaseSetLastNTError(Status);
+ return FALSE;
+ }
+
+ /* Success path */
+ return TRUE;
}
/*
@@ -211,7 +207,7 @@
}
/* Fail if we had an error -- the last error is already set */
- if (WaitStatus != 0) return FALSE;
+ if (WaitStatus) return FALSE;
}
/* Return bytes transferred */
@@ -234,24 +230,24 @@
*/
BOOL
WINAPI
-BindIoCompletionCallback(HANDLE FileHandle,
- LPOVERLAPPED_COMPLETION_ROUTINE Function,
- ULONG Flags)
-{
- NTSTATUS Status = 0;
-
- DPRINT("(%p, %p, %d)\n", FileHandle, Function, Flags);
-
+BindIoCompletionCallback(IN HANDLE FileHandle,
+ IN LPOVERLAPPED_COMPLETION_ROUTINE Function,
+ IN ULONG Flags)
+{
+ NTSTATUS Status;
+
+ /* Call RTL */
Status = RtlSetIoCompletionCallback(FileHandle,
(PIO_APC_ROUTINE)Function,
Flags);
-
if (!NT_SUCCESS(Status))
{
- SetLastError(RtlNtStatusToDosError(Status));
- return FALSE;
- }
-
+ /* Set error and fail */
+ BaseSetLastNTError(Status);
+ return FALSE;
+ }
+
+ /* Return success */
return TRUE;
}