Sync with trunk (r48545)
[reactos.git] / dll / win32 / 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 #define NDEBUG
14 #include <debug.h>
15
16 #define NANOS_TO_100NS(nanos) (((LONGLONG)(nanos)) / 100)
17 #define MICROS_TO_100NS(micros) (((LONGLONG)(micros)) * NANOS_TO_100NS(1000))
18 #define MILLIS_TO_100NS(milli) (((LONGLONG)(milli)) * MICROS_TO_100NS(1000))
19
20 /*
21 * @implemented
22 */
23 HANDLE
24 WINAPI
25 CreateIoCompletionPort(
26 HANDLE FileHandle,
27 HANDLE ExistingCompletionPort,
28 ULONG_PTR CompletionKey,
29 DWORD NumberOfConcurrentThreads
30 )
31 {
32 HANDLE CompletionPort = NULL;
33 NTSTATUS errCode;
34 FILE_COMPLETION_INFORMATION CompletionInformation;
35 IO_STATUS_BLOCK IoStatusBlock;
36
37 if ( FileHandle == INVALID_HANDLE_VALUE && ExistingCompletionPort != NULL )
38 {
39 SetLastError(ERROR_INVALID_PARAMETER);
40 return FALSE;
41 }
42
43 if ( ExistingCompletionPort != NULL )
44 {
45 CompletionPort = ExistingCompletionPort;
46 }
47 else
48 {
49
50 errCode = NtCreateIoCompletion(&CompletionPort,
51 IO_COMPLETION_ALL_ACCESS,
52 NULL,//ObjectAttributes
53 NumberOfConcurrentThreads);
54
55 if (!NT_SUCCESS(errCode) )
56 {
57 SetLastErrorByStatus (errCode);
58 return FALSE;
59 }
60
61 }
62
63 if ( FileHandle != INVALID_HANDLE_VALUE )
64 {
65 CompletionInformation.Port = CompletionPort;
66 CompletionInformation.Key = (PVOID)CompletionKey;
67
68 errCode = NtSetInformationFile(FileHandle,
69 &IoStatusBlock,
70 &CompletionInformation,
71 sizeof(FILE_COMPLETION_INFORMATION),
72 FileCompletionInformation);
73
74 if ( !NT_SUCCESS(errCode) )
75 {
76 if ( ExistingCompletionPort == NULL )
77 {
78 NtClose(CompletionPort);
79 }
80
81 SetLastErrorByStatus (errCode);
82 return FALSE;
83 }
84 }
85
86 return CompletionPort;
87 }
88
89
90 /*
91 * @implemented
92 */
93 BOOL
94 WINAPI
95 GetQueuedCompletionStatus(
96 HANDLE CompletionHandle,
97 LPDWORD lpNumberOfBytesTransferred,
98 PULONG_PTR lpCompletionKey,
99 LPOVERLAPPED *lpOverlapped,
100 DWORD dwMilliseconds
101 )
102 {
103 NTSTATUS errCode;
104 IO_STATUS_BLOCK IoStatus;
105 ULONG_PTR CompletionKey;
106 LARGE_INTEGER Interval;
107
108 if (!lpNumberOfBytesTransferred || !lpCompletionKey || !lpOverlapped)
109 {
110 SetLastError(ERROR_INVALID_PARAMETER);
111 return FALSE;
112 }
113
114 if (dwMilliseconds != INFINITE)
115 {
116 Interval.QuadPart = (-(MILLIS_TO_100NS(dwMilliseconds)));
117 }
118
119 errCode = NtRemoveIoCompletion(CompletionHandle,
120 (PVOID*)&CompletionKey,
121 (PVOID*)lpOverlapped,
122 &IoStatus,
123 dwMilliseconds == INFINITE ? NULL : &Interval);
124
125 if (!NT_SUCCESS(errCode) || errCode == STATUS_TIMEOUT) {
126 *lpOverlapped = NULL;
127 SetLastErrorByStatus(errCode);
128 return FALSE;
129 }
130
131 *lpCompletionKey = CompletionKey;
132 *lpNumberOfBytesTransferred = IoStatus.Information;
133
134 if (!NT_SUCCESS(IoStatus.Status)){
135 //failed io operation
136 SetLastErrorByStatus(IoStatus.Status);
137 return FALSE;
138 }
139
140 return TRUE;
141 }
142
143
144 /*
145 * @implemented
146 */
147 BOOL
148 WINAPI
149 PostQueuedCompletionStatus(
150 HANDLE CompletionHandle,
151 DWORD dwNumberOfBytesTransferred,
152 ULONG_PTR dwCompletionKey,
153 LPOVERLAPPED lpOverlapped
154 )
155 {
156 NTSTATUS errCode;
157
158 errCode = NtSetIoCompletion(CompletionHandle,
159 (PVOID)dwCompletionKey, // KeyContext
160 (PVOID)lpOverlapped, // ApcContext
161 STATUS_SUCCESS, // IoStatusBlock->Status
162 dwNumberOfBytesTransferred); // IoStatusBlock->Information
163
164 if ( !NT_SUCCESS(errCode) )
165 {
166 SetLastErrorByStatus (errCode);
167 return FALSE;
168 }
169 return TRUE;
170 }
171
172
173 /*
174 * @implemented
175 */
176 BOOL WINAPI
177 CancelIo(HANDLE hFile)
178 {
179 IO_STATUS_BLOCK IoStatusBlock;
180 NTSTATUS Status;
181
182 Status = NtCancelIoFile(hFile,
183 &IoStatusBlock);
184 if (!NT_SUCCESS(Status))
185 {
186 SetLastErrorByStatus(Status);
187 return(FALSE);
188 }
189
190 return(TRUE);
191 }
192
193
194 /*
195 * @unimplemented
196 */
197 BOOL
198 WINAPI
199 CancelIoEx(IN HANDLE hFile,
200 IN LPOVERLAPPED lpOverlapped)
201 {
202 UNIMPLEMENTED;
203 return FALSE;
204 }
205
206
207 /*
208 * @unimplemented
209 */
210 BOOL
211 WINAPI
212 CancelSynchronousIo(IN HANDLE hThread)
213 {
214 UNIMPLEMENTED;
215 return FALSE;
216 }
217
218 /* EOF */