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