ReactOS  0.4.15-dev-4853-g3a72a52
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  */
29 BOOL
30 WINAPI
32  IN UCHAR Flags)
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  */
63 HANDLE
64 WINAPI
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 */
80  Status = NtCreateIoCompletion(&NewPort,
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;
109  &IoStatusBlock,
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  */
129 BOOL
130 WINAPI
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 */
153  *lpOverlapped = NULL;
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  */
190 BOOL
191 WINAPI
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  */
219 BOOL
220 WINAPI
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 */
264  BaseSetLastNTError(lpOverlapped->Internal);
265  return FALSE;
266  }
267 
268  /* All done */
269  return TRUE;
270 }
271 
272 /*
273  * @implemented
274  */
275 BOOL
276 WINAPI
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 */
BOOL WINAPI BindIoCompletionCallback(IN HANDLE FileHandle, IN LPOVERLAPPED_COMPLETION_ROUTINE Function, IN ULONG Flags)
Definition: iocompl.c:277
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define IN
Definition: typedefs.h:39
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:877
#define IO_COMPLETION_ALL_ACCESS
Definition: file.c:72
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:221
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOL WINAPI GetQueuedCompletionStatus(IN HANDLE CompletionHandle, IN LPDWORD lpNumberOfBytesTransferred, OUT PULONG_PTR lpCompletionKey, OUT LPOVERLAPPED *lpOverlapped, IN DWORD dwMilliseconds)
Definition: iocompl.c:131
LONG NTSTATUS
Definition: precomp.h:26
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
Definition: iocompl.c:22
#define ERROR_IO_INCOMPLETE
Definition: winerror.h:576
PLARGE_INTEGER WINAPI BaseFormatTimeOut(OUT PLARGE_INTEGER Timeout, IN DWORD dwMilliseconds)
Definition: utils.c:288
BOOL WINAPI SetFileCompletionNotificationModes(IN HANDLE FileHandle, IN UCHAR Flags)
Definition: iocompl.c:31
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define WINAPI
Definition: msvc.h:6
#define FILE_SKIP_SET_EVENT_ON_HANDLE
Definition: iocompl.c:23
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
Definition: iocomp.c:569
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3401
#define WAIT_TIMEOUT
Definition: dderror.h:14
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOL WINAPI PostQueuedCompletionStatus(IN HANDLE CompletionHandle, IN DWORD dwNumberOfBytesTransferred, IN ULONG_PTR dwCompletionKey, IN LPOVERLAPPED lpOverlapped)
Definition: iocompl.c:192
NTSYSAPI NTSTATUS NTAPI RtlSetIoCompletionCallback(_In_ HANDLE FileHandle, _In_ PIO_APC_ROUTINE Callback, _In_ ULONG Flags)
_In_ HANDLE hFile
Definition: mswsock.h:90
void(CALLBACK * LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD, DWORD, LPOVERLAPPED)
Definition: winbase.h:1436
HANDLE WINAPI CreateIoCompletionPort(IN HANDLE FileHandle, IN HANDLE ExistingCompletionPort, IN ULONG_PTR CompletionKey, IN DWORD NumberOfConcurrentThreads)
Definition: iocompl.c:65
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1230
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
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
#define OUT
Definition: typedefs.h:40
uint32_t * LPDWORD
Definition: typedefs.h:59
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG NumberOfConcurrentThreads)
Definition: iocomp.c:253
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define STATUS_SUCCESS
Definition: shellext.h:65
#define INFINITE
Definition: serial.h:102
static PLARGE_INTEGER Time
Definition: time.c:105
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