branch update for HEAD-2003050101
[reactos.git] / lib / kernel32 / file / iocompl.c
index c452eb2..dea9a51 100644 (file)
 
 #include <kernel32/error.h>
 
-
-typedef struct _FILE_COMPLETION_INFORMATION {
-    HANDLE CompletionPort;
-    ULONG CompletionKey;
-} FILE_COMPLETION_INFORMATION;
-typedef FILE_COMPLETION_INFORMATION *PFILE_COMPLETION_INFORMATION;
-
-
-VOID
-STDCALL
-FileIOCompletionRoutine(
-       DWORD dwErrorCode,
-       DWORD dwNumberOfBytesTransfered,
-       LPOVERLAPPED lpOverlapped
-       );
-
-
 HANDLE
 STDCALL
 CreateIoCompletionPort(
@@ -40,99 +23,146 @@ CreateIoCompletionPort(
     DWORD NumberOfConcurrentThreads
     )
 {
-       HANDLE CompletionPort = NULL;
-       NTSTATUS errCode;
-       FILE_COMPLETION_INFORMATION CompletionInformation;
-       IO_STATUS_BLOCK IoStatusBlock;
-
-        if ( ExistingCompletionPort == NULL && FileHandle == INVALID_HANDLE_VALUE ) {
-                SetLastErrorByStatus (STATUS_INVALID_PARAMETER);
-                return FALSE;
-        }
-
-        if ( ExistingCompletionPort != NULL ) {
-                CompletionPort = ExistingCompletionPort;
-       }
-       else {
-                errCode = NtCreateIoCompletion(&CompletionPort,GENERIC_ALL,&IoStatusBlock,NumberOfConcurrentThreads);
-                if (!NT_SUCCESS(errCode) ) {
-                        SetLastErrorByStatus (errCode);
-                        return FALSE;
-                }
-
-        }
-        if ( FileHandle != INVALID_HANDLE_VALUE ) {
-
-               CompletionInformation.CompletionPort = CompletionPort;
-                CompletionInformation.CompletionKey  = CompletionKey;
-
-                errCode = NtSetInformationFile(FileHandle, &IoStatusBlock,&CompletionInformation,sizeof(FILE_COMPLETION_INFORMATION),FileCompletionInformation);
-                if ( !NT_SUCCESS(errCode) ) {
-                       if ( ExistingCompletionPort == NULL )
-                               NtClose(CompletionPort);
-                        SetLastErrorByStatus (errCode);
-                        return FALSE;
-                }
-        }
-
-        return CompletionPort;
+   HANDLE CompletionPort = NULL;
+   NTSTATUS errCode;
+   FILE_COMPLETION_INFORMATION CompletionInformation;
+   IO_STATUS_BLOCK IoStatusBlock;
+
+   if ( ExistingCompletionPort == NULL && FileHandle == INVALID_HANDLE_VALUE ) 
+   {
+      SetLastErrorByStatus (STATUS_INVALID_PARAMETER);
+      return FALSE;
+   }
+
+   if ( ExistingCompletionPort != NULL ) 
+   {
+      CompletionPort = ExistingCompletionPort;
+   }
+   else 
+   {
+
+      errCode = NtCreateIoCompletion(&CompletionPort,
+                                     IO_COMPLETION_ALL_ACCESS,
+                                     NULL,//ObjectAttributes
+                                     NumberOfConcurrentThreads);
+
+      if (!NT_SUCCESS(errCode) ) 
+      {
+         SetLastErrorByStatus (errCode);
+         return FALSE;
+      }
+
+   }
+   
+   if ( FileHandle != INVALID_HANDLE_VALUE ) 
+   {
+      CompletionInformation.IoCompletionHandle = CompletionPort;
+      CompletionInformation.CompletionKey  = CompletionKey;
+
+      errCode = NtSetInformationFile(FileHandle, 
+                                     &IoStatusBlock,
+                                     &CompletionInformation,
+                                     sizeof(FILE_COMPLETION_INFORMATION),
+                                     FileCompletionInformation);
+
+      if ( !NT_SUCCESS(errCode) ) 
+      {
+         if ( ExistingCompletionPort == NULL )
+         {
+            NtClose(CompletionPort);
+         }
+   
+         SetLastErrorByStatus (errCode);
+         return FALSE;
+      }
+   }
+
+   return CompletionPort;
 }
 
 
 WINBOOL
 STDCALL
 GetQueuedCompletionStatus(
-                         HANDLE CompletionPort,
-                         LPDWORD lpNumberOfBytesTransferred,
-                         LPDWORD lpCompletionKey,
-                         LPOVERLAPPED *lpOverlapped,
-                         DWORD dwMilliseconds
-                         )
+   HANDLE CompletionHandle,
+   LPDWORD lpNumberOfBytesTransferred,
+   LPDWORD lpCompletionKey,
+   LPOVERLAPPED *lpOverlapped,
+   DWORD dwMilliseconds
+   )
 {
-       NTSTATUS errCode;
-       ULONG CompletionStatus;
-       LARGE_INTEGER TimeToWait;
+   NTSTATUS errCode;
+   IO_STATUS_BLOCK IoStatus;
+   LARGE_INTEGER Interval;
+
+   if (!lpNumberOfBytesTransferred||!lpCompletionKey||!lpOverlapped)
+   {
+      return ERROR_INVALID_PARAMETER;
+   }
+
+   if (dwMilliseconds != INFINITE)
+   {
+      /*
+       * System time units are 100 nanoseconds (a nanosecond is a billionth of
+       * a second).
+       */
+      Interval.QuadPart = dwMilliseconds;
+      Interval.QuadPart = -(Interval.QuadPart * 10000);
+   }  
+   else
+   {
+      /* Approximately 292000 years hence */
+      Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
+   }
+
+   errCode = NtRemoveIoCompletion(CompletionHandle,
+                                  lpCompletionKey,
+                                  lpNumberOfBytesTransferred,
+                                  &IoStatus,
+                                  &Interval);
+
+   if (!NT_SUCCESS(errCode) ) {
+      *lpOverlapped = NULL;
+      SetLastErrorByStatus(errCode);
+      return FALSE;
+   }
+
+   *lpOverlapped = (LPOVERLAPPED)IoStatus.Information;
+
+   if (!NT_SUCCESS(IoStatus.Status)){
+      //failed io operation
+      SetLastErrorByStatus (IoStatus.Status);
+      return FALSE;
+   }
+
+   return TRUE;
 
-       errCode = NtRemoveIoCompletion(CompletionPort,(PULONG)lpCompletionKey,(PIO_STATUS_BLOCK)lpOverlapped,&CompletionStatus,&TimeToWait);
-       if (!NT_SUCCESS(errCode) ) {
-               SetLastErrorByStatus (errCode);
-               return FALSE;
-       }
-
-       return TRUE;
 }
 
 
 WINBOOL
 STDCALL
 PostQueuedCompletionStatus(
-  HANDLE CompletionPort,
-  DWORD dwNumberOfBytesTransferred,
-  DWORD dwCompletionKey,
-  LPOVERLAPPED lpOverlapped
-)
-{
-       NTSTATUS errCode;
-       errCode = NtSetIoCompletion(CompletionPort,  dwCompletionKey, (PIO_STATUS_BLOCK)lpOverlapped , 0, (PULONG)&dwNumberOfBytesTransferred );
-
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastErrorByStatus (errCode);
-               return FALSE;
-       }
-       return TRUE;
-}
-
-
-// this should be a place holder ??????????????????
-VOID
-STDCALL
-FileIOCompletionRoutine(
-       DWORD dwErrorCode,
-       DWORD dwNumberOfBytesTransfered,
-       LPOVERLAPPED lpOverlapped
-       )
+   HANDLE CompletionHandle,
+   DWORD dwNumberOfBytesTransferred,
+   DWORD dwCompletionKey,
+   LPOVERLAPPED lpOverlapped
+   )
 {
-       return;
+   NTSTATUS errCode;
+
+   errCode = NtSetIoCompletion(CompletionHandle,  
+                               dwCompletionKey, 
+                               dwNumberOfBytesTransferred,//CompletionValue 
+                               0,                         //IoStatusBlock->Status
+                               (ULONG)lpOverlapped );     //IoStatusBlock->Information
+
+   if ( !NT_SUCCESS(errCode) ) 
+   {
+      SetLastErrorByStatus (errCode);
+      return FALSE;
+   }
+   return TRUE;
 }