Added some modifications for asyncronous i/o requests (for vfatfs).
[reactos.git] / reactos / ntoskrnl / io / rw.c
1 /* $Id: rw.c,v 1.34 2001/11/02 22:22:33 hbirr Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/rw.c
6 * PURPOSE: Implements read/write APIs
7 * PROGRAMMER: David Welch (welch@cwcom.net)
8 * UPDATE HISTORY:
9 * 30/05/98: Created
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16 #include <internal/ob.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21 /* DATA ********************************************************************/
22
23
24
25 /* FUNCTIONS ***************************************************************/
26
27
28 /**********************************************************************
29 * NAME EXPORTED
30 * NtReadFile
31 *
32 * DESCRIPTION
33 *
34 * ARGUMENTS
35 *
36 * RETURN VALUE
37 *
38 * REVISIONS
39 *
40 */
41 NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
42 HANDLE EventHandle,
43 PIO_APC_ROUTINE ApcRoutine,
44 PVOID ApcContext,
45 PIO_STATUS_BLOCK IoStatusBlock,
46 PVOID Buffer,
47 ULONG Length,
48 PLARGE_INTEGER ByteOffset,
49 PULONG Key)
50 {
51 NTSTATUS Status;
52 PFILE_OBJECT FileObject;
53 PIRP Irp;
54 PIO_STACK_LOCATION StackPtr;
55 PKEVENT ptrEvent = NULL;
56 KEVENT Event;
57 IO_STATUS_BLOCK IoSB;
58
59 DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
60 "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
61 IoStatusBlock);
62
63 Status = ObReferenceObjectByHandle(FileHandle,
64 FILE_READ_DATA,
65 IoFileObjectType,
66 UserMode,
67 (PVOID*)&FileObject,
68 NULL);
69 if (!NT_SUCCESS(Status))
70 {
71 DPRINT("NtReadFile() = %x\n",Status);
72 return Status;
73 }
74
75 if (ByteOffset == NULL)
76 {
77 ByteOffset = &FileObject->CurrentByteOffset;
78 }
79
80 if (EventHandle != NULL)
81 {
82 Status = ObReferenceObjectByHandle(EventHandle,
83 SYNCHRONIZE,
84 ExEventObjectType,
85 UserMode,
86 (PVOID*)&ptrEvent,
87 NULL);
88 if (!NT_SUCCESS(Status))
89 {
90 ObDereferenceObject(FileObject);
91 return Status;
92 }
93 }
94 else if (FileObject->Flags & FO_SYNCHRONOUS_IO)
95 {
96 ptrEvent = NULL;
97 }
98 else
99 {
100 KeInitializeEvent(&Event,
101 NotificationEvent,
102 FALSE);
103 ptrEvent = &Event;
104 }
105
106 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
107 FileObject->DeviceObject,
108 Buffer,
109 Length,
110 ByteOffset,
111 ptrEvent,
112 EventHandle ? IoStatusBlock : &IoSB);
113
114 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
115 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
116
117 StackPtr = IoGetNextIrpStackLocation(Irp);
118 StackPtr->FileObject = FileObject;
119 if (Key != NULL)
120 {
121 StackPtr->Parameters.Read.Key = *Key;
122 }
123 else
124 {
125 StackPtr->Parameters.Read.Key = 0;
126 }
127
128 Status = IoCallDriver(FileObject->DeviceObject,
129 Irp);
130 if (EventHandle == NULL && Status == STATUS_PENDING &&
131 !(FileObject->Flags & FO_SYNCHRONOUS_IO))
132 {
133 BOOLEAN Alertable;
134
135 if (FileObject->Flags & FO_ALERTABLE_IO)
136 {
137 Alertable = TRUE;
138 }
139 else
140 {
141 Alertable = FALSE;
142 }
143
144 KeWaitForSingleObject(&Event,
145 Executive,
146 KernelMode,
147 Alertable,
148 NULL);
149 Status = IoSB.Status;
150 }
151 if (IoStatusBlock && EventHandle == NULL)
152 {
153 *IoStatusBlock = IoSB;
154 }
155 return (Status);
156 }
157
158
159 /**********************************************************************
160 * NAME EXPORTED
161 * NtWriteFile
162 *
163 * DESCRIPTION
164 *
165 * ARGUMENTS
166 *
167 * RETURN VALUE
168 *
169 * REVISIONS
170 *
171 */
172 NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
173 HANDLE EventHandle,
174 PIO_APC_ROUTINE ApcRoutine,
175 PVOID ApcContext,
176 PIO_STATUS_BLOCK IoStatusBlock,
177 PVOID Buffer,
178 ULONG Length,
179 PLARGE_INTEGER ByteOffset,
180 PULONG Key)
181 {
182 NTSTATUS Status;
183 PFILE_OBJECT FileObject;
184 PIRP Irp;
185 PIO_STACK_LOCATION StackPtr;
186 KEVENT Event;
187 PKEVENT ptrEvent;
188 IO_STATUS_BLOCK IoSB;
189
190 DPRINT("NtWriteFile(FileHandle %x, Buffer %x, Length %d)\n",
191 FileHandle, Buffer, Length);
192
193 Status = ObReferenceObjectByHandle(FileHandle,
194 FILE_WRITE_DATA,
195 IoFileObjectType,
196 UserMode,
197 (PVOID*)&FileObject,
198 NULL);
199 if (!NT_SUCCESS(Status))
200 {
201 return(Status);
202 }
203
204 if (ByteOffset == NULL)
205 {
206 ByteOffset = &FileObject->CurrentByteOffset;
207 }
208
209 if (EventHandle != NULL)
210 {
211 Status = ObReferenceObjectByHandle(EventHandle,
212 SYNCHRONIZE,
213 ExEventObjectType,
214 UserMode,
215 (PVOID*)&ptrEvent,
216 NULL);
217 if (!NT_SUCCESS(Status))
218 {
219 ObDereferenceObject(FileObject);
220 return(Status);
221 }
222 }
223 else if (FileObject->Flags & FO_SYNCHRONOUS_IO)
224 {
225 ptrEvent = NULL;
226 }
227 else
228 {
229 KeInitializeEvent(&Event,
230 NotificationEvent,
231 FALSE);
232 ptrEvent = &Event;
233 }
234
235 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
236 FileObject->DeviceObject,
237 Buffer,
238 Length,
239 ByteOffset,
240 ptrEvent,
241 EventHandle ? IoStatusBlock : &IoSB);
242
243 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
244 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
245
246 DPRINT("FileObject->DeviceObject %x\n",FileObject->DeviceObject);
247
248 StackPtr = IoGetNextIrpStackLocation(Irp);
249 StackPtr->FileObject = FileObject;
250 if (Key != NULL)
251 {
252 StackPtr->Parameters.Write.Key = *Key;
253 }
254 else
255 {
256 StackPtr->Parameters.Write.Key = 0;
257 }
258 Status = IoCallDriver(FileObject->DeviceObject, Irp);
259 if (EventHandle == NULL && Status == STATUS_PENDING &&
260 !(FileObject->Flags & FO_SYNCHRONOUS_IO))
261 {
262 KeWaitForSingleObject(&Event,
263 Executive,
264 KernelMode,
265 FALSE,
266 NULL);
267 Status = IoSB.Status;
268 }
269 if (IoStatusBlock && EventHandle == NULL)
270 {
271 *IoStatusBlock = IoSB;
272 }
273 return(Status);
274 }
275
276
277 /**********************************************************************
278 * NAME EXPORTED
279 * NtReadFileScatter
280 *
281 * DESCRIPTION
282 *
283 * ARGUMENTS
284 *
285 * RETURN VALUE
286 *
287 * REVISIONS
288 *
289 */
290 NTSTATUS
291 STDCALL
292 NtReadFileScatter (
293 IN HANDLE FileHandle,
294 IN HANDLE Event OPTIONAL,
295 IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
296 IN PVOID UserApcContext OPTIONAL,
297 OUT PIO_STATUS_BLOCK UserIoStatusBlock,
298 IN FILE_SEGMENT_ELEMENT BufferDescription [],
299 IN ULONG BufferLength,
300 IN PLARGE_INTEGER ByteOffset,
301 IN PULONG Key OPTIONAL
302 )
303 {
304 UNIMPLEMENTED;
305 }
306
307
308 /**********************************************************************
309 * NAME EXPORTED
310 * NtWriteFileGather
311 *
312 * DESCRIPTION
313 *
314 * ARGUMENTS
315 *
316 * RETURN VALUE
317 *
318 * REVISIONS
319 *
320 */
321 NTSTATUS
322 STDCALL
323 NtWriteFileGather (
324 IN HANDLE FileHandle,
325 IN HANDLE Event OPTIONAL,
326 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
327 IN PVOID ApcContext OPTIONAL,
328 OUT PIO_STATUS_BLOCK IoStatusBlock,
329 IN FILE_SEGMENT_ELEMENT BufferDescription [],
330 IN ULONG BufferLength,
331 IN PLARGE_INTEGER ByteOffset,
332 IN PULONG Key OPTIONAL
333 )
334 {
335 UNIMPLEMENTED;
336 }
337
338
339 /* EOF */