initial work on I/O completion
[reactos.git] / reactos / lib / kernel32 / file / iocompl.c
1 /* $Id: iocompl.c,v 1.9 2003/03/19 23:16:55 gdalsnes Exp $
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
15 #include <kernel32/error.h>
16
17 HANDLE
18 STDCALL
19 CreateIoCompletionPort(
20 HANDLE FileHandle,
21 HANDLE ExistingCompletionPort,
22 DWORD CompletionKey,
23 DWORD NumberOfConcurrentThreads
24 )
25 {
26 HANDLE CompletionPort = NULL;
27 NTSTATUS errCode;
28 FILE_COMPLETION_INFORMATION CompletionInformation;
29 IO_STATUS_BLOCK IoStatusBlock;
30
31 if ( ExistingCompletionPort == NULL && FileHandle == INVALID_HANDLE_VALUE )
32 {
33 SetLastErrorByStatus (STATUS_INVALID_PARAMETER);
34 return FALSE;
35 }
36
37 if ( ExistingCompletionPort != NULL )
38 {
39 CompletionPort = ExistingCompletionPort;
40 }
41 else
42 {
43
44 errCode = NtCreateIoCompletion(&CompletionPort,
45 IO_COMPLETION_ALL_ACCESS,
46 NULL,//ObjectAttributes
47 NumberOfConcurrentThreads);
48
49 if (!NT_SUCCESS(errCode) )
50 {
51 SetLastErrorByStatus (errCode);
52 return FALSE;
53 }
54
55 }
56
57 if ( FileHandle != INVALID_HANDLE_VALUE )
58 {
59 CompletionInformation.IoCompletionHandle = CompletionPort;
60 CompletionInformation.CompletionKey = CompletionKey;
61
62 errCode = NtSetInformationFile(FileHandle,
63 &IoStatusBlock,
64 &CompletionInformation,
65 sizeof(FILE_COMPLETION_INFORMATION),
66 FileCompletionInformation);
67
68 if ( !NT_SUCCESS(errCode) )
69 {
70 if ( ExistingCompletionPort == NULL )
71 {
72 NtClose(CompletionPort);
73 }
74
75 SetLastErrorByStatus (errCode);
76 return FALSE;
77 }
78 }
79
80 return CompletionPort;
81 }
82
83
84 WINBOOL
85 STDCALL
86 GetQueuedCompletionStatus(
87 HANDLE CompletionHandle,
88 LPDWORD lpNumberOfBytesTransferred,
89 LPDWORD lpCompletionKey,
90 LPOVERLAPPED *lpOverlapped,
91 DWORD dwMilliseconds
92 )
93 {
94 NTSTATUS errCode;
95 IO_STATUS_BLOCK IoStatus;
96 LARGE_INTEGER Interval;
97
98 if (!lpNumberOfBytesTransferred||!lpCompletionKey||!lpOverlapped)
99 {
100 return ERROR_INVALID_PARAMETER;
101 }
102
103 if (dwMilliseconds != INFINITE)
104 {
105 /*
106 * System time units are 100 nanoseconds (a nanosecond is a billionth of
107 * a second).
108 */
109 Interval.QuadPart = dwMilliseconds;
110 Interval.QuadPart = -(Interval.QuadPart * 10000);
111 }
112 else
113 {
114 /* Approximately 292000 years hence */
115 Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
116 }
117
118 errCode = NtRemoveIoCompletion(CompletionHandle,
119 lpCompletionKey,
120 lpNumberOfBytesTransferred,
121 &IoStatus,
122 &Interval);
123
124 if (!NT_SUCCESS(errCode) ) {
125 *lpOverlapped = NULL;
126 SetLastErrorByStatus(errCode);
127 return FALSE;
128 }
129
130 *lpOverlapped = (LPOVERLAPPED)IoStatus.Information;
131
132 if (!NT_SUCCESS(IoStatus.Status)){
133 //failed io operation
134 SetLastErrorByStatus (IoStatus.Status);
135 return FALSE;
136 }
137
138 return TRUE;
139
140 }
141
142
143 WINBOOL
144 STDCALL
145 PostQueuedCompletionStatus(
146 HANDLE CompletionHandle,
147 DWORD dwNumberOfBytesTransferred,
148 DWORD dwCompletionKey,
149 LPOVERLAPPED lpOverlapped
150 )
151 {
152 NTSTATUS errCode;
153
154 errCode = NtSetIoCompletion(CompletionHandle,
155 dwCompletionKey,
156 dwNumberOfBytesTransferred,//CompletionValue
157 0, //IoStatusBlock->Status
158 (ULONG)lpOverlapped ); //IoStatusBlock->Information
159
160 if ( !NT_SUCCESS(errCode) )
161 {
162 SetLastErrorByStatus (errCode);
163 return FALSE;
164 }
165 return TRUE;
166 }
167
168
169 BOOL STDCALL
170 CancelIo(HANDLE hFile)
171 {
172 IO_STATUS_BLOCK IoStatusBlock;
173 NTSTATUS Status;
174
175 Status = NtCancelIoFile(hFile,
176 &IoStatusBlock);
177 if (!NT_SUCCESS(Status))
178 {
179 SetLastErrorByStatus(Status);
180 return(FALSE);
181 }
182
183 return(TRUE);
184 }
185
186 /* EOF */