ReactOS 0.4.15-dev-7953-g1f49173
iocompl.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/file/iocompl.c
5 * PURPOSE: Io Completion functions
6 * PROGRAMMERS: Ariadne (ariadne@xs4all.nl)
7 * Oleg Dubinskiy (oleg.dubinskij30@gmail.com)
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 */
11
12#include <k32.h>
13#define NDEBUG
14#include <debug.h>
15
16/*
17 * SetFileCompletionNotificationModes is not entirely Vista-exclusive,
18 * it was actually added to Windows 2003 in SP2. Headers restrict it from
19 * pre-Vista though so define the flags we need for it.
20 */
21#if (_WIN32_WINNT < 0x0600)
22#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1
23#define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2
24#endif
25
26/*
27 * @implemented
28 */
29BOOL
33{
37
39 {
41 return FALSE;
42 }
43
44 FileInformation.Flags = Flags;
45
49 sizeof(FileInformation),
51 if (!NT_SUCCESS(Status))
52 {
54 return FALSE;
55 }
56
57 return TRUE;
58}
59
60/*
61 * @implemented
62 */
66 IN HANDLE ExistingCompletionPort,
67 IN ULONG_PTR CompletionKey,
68 IN DWORD NumberOfConcurrentThreads)
69{
71 HANDLE NewPort;
72 FILE_COMPLETION_INFORMATION CompletionInformation;
74
75 /* Check if this is a new port */
76 NewPort = ExistingCompletionPort;
77 if (!ExistingCompletionPort)
78 {
79 /* Create it */
82 NULL,
83 NumberOfConcurrentThreads);
84 if (!NT_SUCCESS(Status))
85 {
86 /* Convert error and fail */
88 return FALSE;
89 }
90 }
91
92 /* Check if no actual file is being associated with the completion port */
94 {
95 /* Was there a port already associated? */
96 if (ExistingCompletionPort)
97 {
98 /* You are not allowed using an old port and dropping the handle */
99 NewPort = NULL;
101 }
102 }
103 else
104 {
105 /* We have a file handle, so associated it with this completion port */
106 CompletionInformation.Port = NewPort;
107 CompletionInformation.Key = (PVOID)CompletionKey;
110 &CompletionInformation,
113 if (!NT_SUCCESS(Status))
114 {
115 /* Convert the error code and close the newly created port, if any */
117 if (!ExistingCompletionPort) NtClose(NewPort);
118 return FALSE;
119 }
120 }
121
122 /* Return the newly created port, if any */
123 return NewPort;
124}
125
126/*
127 * @implemented
128 */
129BOOL
130WINAPI
132 IN LPDWORD lpNumberOfBytesTransferred,
133 OUT PULONG_PTR lpCompletionKey,
135 IN DWORD dwMilliseconds)
136{
139 ULONG_PTR CompletionKey;
141 PLARGE_INTEGER TimePtr;
142
143 /* Convert the timeout and then call the native API */
144 TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);
145 Status = NtRemoveIoCompletion(CompletionHandle,
146 (PVOID*)&CompletionKey,
148 &IoStatus,
149 TimePtr);
150 if (!(NT_SUCCESS(Status)) || (Status == STATUS_TIMEOUT))
151 {
152 /* Clear out the overlapped output */
154
155 /* Check what kind of error we got */
156 if (Status == STATUS_TIMEOUT)
157 {
158 /* Timeout error is set directly since there's no conversion */
160 }
161 else
162 {
163 /* Any other error gets converted */
165 }
166
167 /* This is a failure case */
168 return FALSE;
169 }
170
171 /* Write back the output parameters */
172 *lpCompletionKey = CompletionKey;
173 *lpNumberOfBytesTransferred = IoStatus.Information;
174
175 /* Check for error */
176 if (!NT_SUCCESS(IoStatus.Status))
177 {
178 /* Convert and fail */
180 return FALSE;
181 }
182
183 /* Return success */
184 return TRUE;
185}
186
187/*
188 * @implemented
189 */
190BOOL
191WINAPI
193 IN DWORD dwNumberOfBytesTransferred,
194 IN ULONG_PTR dwCompletionKey,
196{
198
199 /* Call the native API */
200 Status = NtSetIoCompletion(CompletionHandle,
201 (PVOID)dwCompletionKey,
204 dwNumberOfBytesTransferred);
205 if (!NT_SUCCESS(Status))
206 {
207 /* Convert the error and fail */
209 return FALSE;
210 }
211
212 /* Success path */
213 return TRUE;
214}
215
216/*
217 * @implemented
218 */
219BOOL
220WINAPI
223 OUT LPDWORD lpNumberOfBytesTransferred,
224 IN BOOL bWait)
225{
226 DWORD WaitStatus;
227 HANDLE hObject;
228
229 /* Check for pending operation */
230 if (lpOverlapped->Internal == STATUS_PENDING)
231 {
232 /* Check if the caller is okay with waiting */
233 if (!bWait)
234 {
235 /* Set timeout */
236 WaitStatus = WAIT_TIMEOUT;
237 }
238 else
239 {
240 /* Wait for the result */
241 hObject = lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile;
242 WaitStatus = WaitForSingleObject(hObject, INFINITE);
243 }
244
245 /* Check for timeout */
246 if (WaitStatus == WAIT_TIMEOUT)
247 {
248 /* We have to override the last error with INCOMPLETE instead */
250 return FALSE;
251 }
252
253 /* Fail if we had an error -- the last error is already set */
254 if (WaitStatus) return FALSE;
255 }
256
257 /* Return bytes transferred */
258 *lpNumberOfBytesTransferred = lpOverlapped->InternalHigh;
259
260 /* Check for failure during I/O */
261 if (!NT_SUCCESS(lpOverlapped->Internal))
262 {
263 /* Set the error and fail */
265 return FALSE;
266 }
267
268 /* All done */
269 return TRUE;
270}
271
272/*
273 * @implemented
274 */
275BOOL
276WINAPI
279 IN ULONG Flags)
280{
282
283 /* Call RTL */
286 Flags);
287 if (!NT_SUCCESS(Status))
288 {
289 /* Set error and fail */
291 return FALSE;
292 }
293
294 /* Return success */
295 return TRUE;
296}
297
298/* EOF */
LONG NTSTATUS
Definition: precomp.h:26
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
PLARGE_INTEGER WINAPI BaseFormatTimeOut(OUT PLARGE_INTEGER Timeout, IN DWORD dwMilliseconds)
Definition: utils.c:288
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FileIoCompletionNotificationInformation
Definition: from_kernel.h:102
@ FileCompletionInformation
Definition: from_kernel.h:91
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
Definition: iocomp.c:569
NTSTATUS NTAPI NtRemoveIoCompletion(IN HANDLE IoCompletionHandle, OUT PVOID *KeyContext, OUT PVOID *ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: iocomp.c:445
NTSTATUS NTAPI NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG NumberOfConcurrentThreads)
Definition: iocomp.c:253
BOOL WINAPI PostQueuedCompletionStatus(IN HANDLE CompletionHandle, IN DWORD dwNumberOfBytesTransferred, IN ULONG_PTR dwCompletionKey, IN LPOVERLAPPED lpOverlapped)
Definition: iocompl.c:192
HANDLE WINAPI CreateIoCompletionPort(IN HANDLE FileHandle, IN HANDLE ExistingCompletionPort, IN ULONG_PTR CompletionKey, IN DWORD NumberOfConcurrentThreads)
Definition: iocompl.c:65
#define FILE_SKIP_SET_EVENT_ON_HANDLE
Definition: iocompl.c:23
BOOL WINAPI SetFileCompletionNotificationModes(IN HANDLE FileHandle, IN UCHAR Flags)
Definition: iocompl.c:31
#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
Definition: iocompl.c:22
BOOL WINAPI BindIoCompletionCallback(IN HANDLE FileHandle, IN LPOVERLAPPED_COMPLETION_ROUTINE Function, IN ULONG Flags)
Definition: iocompl.c:277
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:221
BOOL WINAPI GetQueuedCompletionStatus(IN HANDLE CompletionHandle, IN LPDWORD lpNumberOfBytesTransferred, OUT PULONG_PTR lpCompletionKey, OUT LPOVERLAPPED *lpOverlapped, IN DWORD dwMilliseconds)
Definition: iocompl.c:131
#define IO_COMPLETION_ALL_ACCESS
Definition: file.c:72
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
static PLARGE_INTEGER Time
Definition: time.c:105
_In_ HANDLE hFile
Definition: mswsock.h:90
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:93
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
NTSYSAPI NTSTATUS NTAPI RtlSetIoCompletionCallback(_In_ HANDLE FileHandle, _In_ PIO_APC_ROUTINE Callback, _In_ ULONG Flags)
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:877
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_PENDING
Definition: ntstatus.h:82
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
#define STATUS_SUCCESS
Definition: shellext.h:65
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint32_t * PULONG_PTR
Definition: typedefs.h:65
void * PVOID
Definition: typedefs.h:50
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
void(CALLBACK * LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD, DWORD, LPOVERLAPPED)
Definition: winbase.h:1451
#define WINAPI
Definition: msvc.h:6
#define ERROR_IO_INCOMPLETE
Definition: winerror.h:576
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned char UCHAR
Definition: xmlstorage.h:181