update for HEAD-2003050101
[reactos.git] / lib / kernel32 / file / iocompl.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/file/iocompl.c
6  * PURPOSE:         Io Completion functions
7  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
8  * UPDATE HISTORY:
9  *                  Created 01/11/98
10  */
11
12 #include <k32.h>
13
14
15 #include <kernel32/error.h>
16
17 HANDLE
18 STDCALL
19 CreateIoCompletionPort(
20     HANDLE FileHandle,
21     HANDLE ExistingCompletionPort,
22     DWORD CompletionKey,
23     DWORD NumberOfConcurrentThreads
24     )
25 {
26    HANDLE CompletionPort = NULL;
27    NTSTATUS errCode;
28    FILE_COMPLETION_INFORMATION CompletionInformation;
29    IO_STATUS_BLOCK IoStatusBlock;
30
31    if ( ExistingCompletionPort == NULL && FileHandle == INVALID_HANDLE_VALUE ) 
32    {
33       SetLastErrorByStatus (STATUS_INVALID_PARAMETER);
34       return FALSE;
35    }
36
37    if ( ExistingCompletionPort != NULL ) 
38    {
39       CompletionPort = ExistingCompletionPort;
40    }
41    else 
42    {
43
44       errCode = NtCreateIoCompletion(&CompletionPort,
45                                      IO_COMPLETION_ALL_ACCESS,
46                                      NULL,//ObjectAttributes
47                                      NumberOfConcurrentThreads);
48
49       if (!NT_SUCCESS(errCode) ) 
50       {
51          SetLastErrorByStatus (errCode);
52          return FALSE;
53       }
54
55    }
56    
57    if ( FileHandle != INVALID_HANDLE_VALUE ) 
58    {
59       CompletionInformation.IoCompletionHandle = CompletionPort;
60       CompletionInformation.CompletionKey  = CompletionKey;
61
62       errCode = NtSetInformationFile(FileHandle, 
63                                      &IoStatusBlock,
64                                      &CompletionInformation,
65                                      sizeof(FILE_COMPLETION_INFORMATION),
66                                      FileCompletionInformation);
67
68       if ( !NT_SUCCESS(errCode) ) 
69       {
70          if ( ExistingCompletionPort == NULL )
71          {
72             NtClose(CompletionPort);
73          }
74    
75          SetLastErrorByStatus (errCode);
76          return FALSE;
77       }
78    }
79
80    return CompletionPort;
81 }
82
83
84 WINBOOL
85 STDCALL
86 GetQueuedCompletionStatus(
87    HANDLE CompletionHandle,
88    LPDWORD lpNumberOfBytesTransferred,
89    LPDWORD lpCompletionKey,
90    LPOVERLAPPED *lpOverlapped,
91    DWORD dwMilliseconds
92    )
93 {
94    NTSTATUS errCode;
95    IO_STATUS_BLOCK IoStatus;
96    LARGE_INTEGER Interval;
97
98    if (!lpNumberOfBytesTransferred||!lpCompletionKey||!lpOverlapped)
99    {
100       return ERROR_INVALID_PARAMETER;
101    }
102
103    if (dwMilliseconds != INFINITE)
104    {
105       /*
106        * System time units are 100 nanoseconds (a nanosecond is a billionth of
107        * a second).
108        */
109       Interval.QuadPart = dwMilliseconds;
110       Interval.QuadPart = -(Interval.QuadPart * 10000);
111    }  
112    else
113    {
114       /* Approximately 292000 years hence */
115       Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
116    }
117
118    errCode = NtRemoveIoCompletion(CompletionHandle,
119                                   lpCompletionKey,
120                                   lpNumberOfBytesTransferred,
121                                   &IoStatus,
122                                   &Interval);
123
124    if (!NT_SUCCESS(errCode) ) {
125       *lpOverlapped = NULL;
126       SetLastErrorByStatus(errCode);
127       return FALSE;
128    }
129
130    *lpOverlapped = (LPOVERLAPPED)IoStatus.Information;
131
132    if (!NT_SUCCESS(IoStatus.Status)){
133       //failed io operation
134       SetLastErrorByStatus (IoStatus.Status);
135       return FALSE;
136    }
137
138    return TRUE;
139
140 }
141
142
143 WINBOOL
144 STDCALL
145 PostQueuedCompletionStatus(
146    HANDLE CompletionHandle,
147    DWORD dwNumberOfBytesTransferred,
148    DWORD dwCompletionKey,
149    LPOVERLAPPED lpOverlapped
150    )
151 {
152    NTSTATUS errCode;
153
154    errCode = NtSetIoCompletion(CompletionHandle,  
155                                dwCompletionKey, 
156                                dwNumberOfBytesTransferred,//CompletionValue 
157                                0,                         //IoStatusBlock->Status
158                                (ULONG)lpOverlapped );     //IoStatusBlock->Information
159
160    if ( !NT_SUCCESS(errCode) ) 
161    {
162       SetLastErrorByStatus (errCode);
163       return FALSE;
164    }
165    return TRUE;
166 }
167
168
169 BOOL STDCALL
170 CancelIo(HANDLE hFile)
171 {
172   IO_STATUS_BLOCK IoStatusBlock;
173   NTSTATUS Status;
174
175   Status = NtCancelIoFile(hFile,
176                           &IoStatusBlock);
177   if (!NT_SUCCESS(Status))
178     {
179       SetLastErrorByStatus(Status);
180       return(FALSE);
181     }
182
183   return(TRUE);
184 }
185
186 /* EOF */