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