ReactOS  0.4.10-dev-486-g11b7619
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  * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7  * UPDATE HISTORY:
8  * Created 01/11/98
9  */
10 
11 #include <k32.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /*
16  * SetFileCompletionNotificationModes is not entirely Vista-exclusive,
17  * it was actually added to Windows 2003 in SP2. Headers restrict it from
18  * pre-Vista though so define the flags we need for it.
19  */
20 #if (_WIN32_WINNT < 0x0600)
21 #define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1
22 #define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2
23 #endif
24 
25 /*
26  * @unimplemented
27  */
28 BOOL
29 WINAPI
31  IN UCHAR Flags)
32 {
34  {
36  return FALSE;
37  }
38 
40  return FALSE;
41 }
42 
43 /*
44  * @implemented
45  */
46 HANDLE
47 WINAPI
49  IN HANDLE ExistingCompletionPort,
50  IN ULONG_PTR CompletionKey,
51  IN DWORD NumberOfConcurrentThreads)
52 {
54  HANDLE NewPort;
55  FILE_COMPLETION_INFORMATION CompletionInformation;
57 
58  /* Check if this is a new port */
59  NewPort = ExistingCompletionPort;
60  if (!ExistingCompletionPort)
61  {
62  /* Create it */
63  Status = NtCreateIoCompletion(&NewPort,
65  NULL,
66  NumberOfConcurrentThreads);
67  if (!NT_SUCCESS(Status))
68  {
69  /* Convert error and fail */
70  BaseSetLastNTError(Status);
71  return FALSE;
72  }
73  }
74 
75  /* Check if no actual file is being associated with the completion port */
76  if (FileHandle == INVALID_HANDLE_VALUE)
77  {
78  /* Was there a port already associated? */
79  if (ExistingCompletionPort)
80  {
81  /* You are not allowed using an old port and dropping the handle */
82  NewPort = NULL;
84  }
85  }
86  else
87  {
88  /* We have a file handle, so associated it with this completion port */
89  CompletionInformation.Port = NewPort;
90  CompletionInformation.Key = (PVOID)CompletionKey;
91  Status = NtSetInformationFile(FileHandle,
92  &IoStatusBlock,
93  &CompletionInformation,
96  if (!NT_SUCCESS(Status))
97  {
98  /* Convert the error code and close the newly created port, if any */
99  BaseSetLastNTError(Status);
100  if (!ExistingCompletionPort) NtClose(NewPort);
101  return FALSE;
102  }
103  }
104 
105  /* Return the newly created port, if any */
106  return NewPort;
107 }
108 
109 /*
110  * @implemented
111  */
112 BOOL
113 WINAPI
115  IN LPDWORD lpNumberOfBytesTransferred,
116  OUT PULONG_PTR lpCompletionKey,
118  IN DWORD dwMilliseconds)
119 {
122  ULONG_PTR CompletionKey;
124  PLARGE_INTEGER TimePtr;
125 
126  /* Convert the timeout and then call the native API */
127  TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);
128  Status = NtRemoveIoCompletion(CompletionHandle,
129  (PVOID*)&CompletionKey,
130  (PVOID*)lpOverlapped,
131  &IoStatus,
132  TimePtr);
133  if (!(NT_SUCCESS(Status)) || (Status == STATUS_TIMEOUT))
134  {
135  /* Clear out the overlapped output */
136  *lpOverlapped = NULL;
137 
138  /* Check what kind of error we got */
139  if (Status == STATUS_TIMEOUT)
140  {
141  /* Timeout error is set directly since there's no conversion */
143  }
144  else
145  {
146  /* Any other error gets converted */
147  BaseSetLastNTError(Status);
148  }
149 
150  /* This is a failure case */
151  return FALSE;
152  }
153 
154  /* Write back the output parameters */
155  *lpCompletionKey = CompletionKey;
156  *lpNumberOfBytesTransferred = IoStatus.Information;
157 
158  /* Check for error */
159  if (!NT_SUCCESS(IoStatus.Status))
160  {
161  /* Convert and fail */
162  BaseSetLastNTError(IoStatus.Status);
163  return FALSE;
164  }
165 
166  /* Return success */
167  return TRUE;
168 }
169 
170 /*
171  * @implemented
172  */
173 BOOL
174 WINAPI
176  IN DWORD dwNumberOfBytesTransferred,
177  IN ULONG_PTR dwCompletionKey,
179 {
181 
182  /* Call the native API */
183  Status = NtSetIoCompletion(CompletionHandle,
184  (PVOID)dwCompletionKey,
185  (PVOID)lpOverlapped,
187  dwNumberOfBytesTransferred);
188  if (!NT_SUCCESS(Status))
189  {
190  /* Convert the error and fail */
191  BaseSetLastNTError(Status);
192  return FALSE;
193  }
194 
195  /* Success path */
196  return TRUE;
197 }
198 
199 /*
200  * @implemented
201  */
202 BOOL
203 WINAPI
206  OUT LPDWORD lpNumberOfBytesTransferred,
207  IN BOOL bWait)
208 {
209  DWORD WaitStatus;
210  HANDLE hObject;
211 
212  /* Check for pending operation */
213  if (lpOverlapped->Internal == STATUS_PENDING)
214  {
215  /* Check if the caller is okay with waiting */
216  if (!bWait)
217  {
218  /* Set timeout */
219  WaitStatus = WAIT_TIMEOUT;
220  }
221  else
222  {
223  /* Wait for the result */
224  hObject = lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile;
225  WaitStatus = WaitForSingleObject(hObject, INFINITE);
226  }
227 
228  /* Check for timeout */
229  if (WaitStatus == WAIT_TIMEOUT)
230  {
231  /* We have to override the last error with INCOMPLETE instead */
233  return FALSE;
234  }
235 
236  /* Fail if we had an error -- the last error is already set */
237  if (WaitStatus) return FALSE;
238  }
239 
240  /* Return bytes transferred */
241  *lpNumberOfBytesTransferred = lpOverlapped->InternalHigh;
242 
243  /* Check for failure during I/O */
244  if (!NT_SUCCESS(lpOverlapped->Internal))
245  {
246  /* Set the error and fail */
247  BaseSetLastNTError(lpOverlapped->Internal);
248  return FALSE;
249  }
250 
251  /* All done */
252  return TRUE;
253 }
254 
255 /*
256  * @implemented
257  */
258 BOOL
259 WINAPI
262  IN ULONG Flags)
263 {
265 
266  /* Call RTL */
267  Status = RtlSetIoCompletionCallback(FileHandle,
268  (PIO_APC_ROUTINE)Function,
269  Flags);
270  if (!NT_SUCCESS(Status))
271  {
272  /* Set error and fail */
273  BaseSetLastNTError(Status);
274  return FALSE;
275  }
276 
277  /* Return success */
278  return TRUE;
279 }
280 
281 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:60
BOOL WINAPI BindIoCompletionCallback(IN HANDLE FileHandle, IN LPOVERLAPPED_COMPLETION_ROUTINE Function, IN ULONG Flags)
Definition: iocompl.c:260
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
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 PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
return STATUS_SUCCESS
Definition: btrfs.c:2690
IN OUT PIRP IN ULONG IN WMIENABLEDISABLECONTROL Function
Definition: wmilib.h:37
BOOL WINAPI GetQueuedCompletionStatus(IN HANDLE CompletionHandle, IN LPDWORD lpNumberOfBytesTransferred, OUT PULONG_PTR lpCompletionKey, OUT LPOVERLAPPED *lpOverlapped, IN DWORD dwMilliseconds)
Definition: iocompl.c:114
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
Definition: iocompl.c:21
#define ERROR_IO_INCOMPLETE
Definition: winerror.h:576
DWORD DWORD
Definition: winlogon.h:83
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:30
HANDLE hObject
Definition: wglext.h:924
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
unsigned int BOOL
Definition: ntddk_ex.h:94
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define STATUS_PENDING
Definition: ntstatus.h:82
#define FILE_SKIP_SET_EVENT_ON_HANDLE
Definition: iocompl.c:22
#define SetLastError(x)
Definition: compat.h:409
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
Definition: iocomp.c:568
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#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:175
NTSYSAPI NTSTATUS NTAPI RtlSetIoCompletionCallback(_In_ HANDLE FileHandle, _In_ PIO_APC_ROUTINE Callback, _In_ ULONG Flags)
void(CALLBACK * LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD, DWORD, LPOVERLAPPED)
Definition: winbase.h:1404
_In_ HANDLE hFile
Definition: mswsock.h:90
#define WINAPI
Definition: msvc.h:20
Status
Definition: gdiplustypes.h:24
HANDLE WINAPI CreateIoCompletionPort(IN HANDLE FileHandle, IN HANDLE ExistingCompletionPort, IN ULONG_PTR CompletionKey, IN DWORD NumberOfConcurrentThreads)
Definition: iocompl.c:48
static HANDLE FileHandle
Definition: cabinet.c:48
DWORD *typedef HANDLE
Definition: winlogon.h:60
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
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:444
#define OUT
Definition: typedefs.h:39
uint32_t * LPDWORD
Definition: typedefs.h:57
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
#define UNIMPLEMENTED
Definition: debug.h:114
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#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:2854