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)
12 /* INCLUDES ****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16 #include <internal/ob.h>
19 #include <internal/debug.h>
21 /* FUNCTIONS ***************************************************************/
24 /**********************************************************************
38 NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
40 PIO_APC_ROUTINE ApcRoutine,
42 PIO_STATUS_BLOCK UserIoStatusBlock,
45 PLARGE_INTEGER ByteOffset,
49 PFILE_OBJECT FileObject;
51 PIO_STACK_LOCATION StackPtr;
54 PIO_STATUS_BLOCK IoStatusBlock;
56 DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
57 "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
60 Status = ObReferenceObjectByHandle(FileHandle,
66 if (!NT_SUCCESS(Status))
71 if (ByteOffset == NULL)
73 ByteOffset = &FileObject->CurrentByteOffset;
76 if (EventHandle != NULL)
78 Status = ObReferenceObjectByHandle(EventHandle,
84 if (!NT_SUCCESS(Status))
86 ObDereferenceObject(FileObject);
93 Event = &FileObject->Event;
97 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
99 IoStatusBlock = &Iosb;
103 IoStatusBlock = UserIoStatusBlock;
106 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
107 FileObject->DeviceObject,
114 //trigger FileObject/Event dereferencing
115 Irp->Tail.Overlay.OriginalFileObject = FileObject;
117 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
118 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
120 StackPtr = IoGetNextIrpStackLocation(Irp);
121 StackPtr->FileObject = FileObject;
124 StackPtr->Parameters.Read.Key = *Key;
128 StackPtr->Parameters.Read.Key = 0;
132 Status = IoCallDriver(FileObject->DeviceObject, Irp);
133 if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
137 if (FileObject->Flags & FO_ALERTABLE_IO)
146 Status = KeWaitForSingleObject(Event,
151 if (Status != STATUS_WAIT_0)
157 Status = Iosb.Status;
161 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
163 *UserIoStatusBlock = Iosb;
169 /**********************************************************************
183 NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
185 PIO_APC_ROUTINE ApcRoutine,
187 PIO_STATUS_BLOCK UserIoStatusBlock,
190 PLARGE_INTEGER ByteOffset,
194 PFILE_OBJECT FileObject;
196 PIO_STACK_LOCATION StackPtr;
197 PKEVENT Event = NULL;
198 IO_STATUS_BLOCK Iosb;
199 PIO_STATUS_BLOCK IoStatusBlock;
201 DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
202 "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
205 Status = ObReferenceObjectByHandle(FileHandle,
211 if (!NT_SUCCESS(Status))
216 if (ByteOffset == NULL)
218 ByteOffset = &FileObject->CurrentByteOffset;
221 if (EventHandle != NULL)
223 Status = ObReferenceObjectByHandle(EventHandle,
229 if (!NT_SUCCESS(Status))
231 ObDereferenceObject(FileObject);
238 Event = &FileObject->Event;
242 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
244 IoStatusBlock = &Iosb;
248 IoStatusBlock = UserIoStatusBlock;
251 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
252 FileObject->DeviceObject,
259 //trigger FileObject/Event dereferencing
260 Irp->Tail.Overlay.OriginalFileObject = FileObject;
262 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
263 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
265 StackPtr = IoGetNextIrpStackLocation(Irp);
266 StackPtr->FileObject = FileObject;
269 StackPtr->Parameters.Write.Key = *Key;
273 StackPtr->Parameters.Write.Key = 0;
276 Status = IoCallDriver(FileObject->DeviceObject, Irp);
277 if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
281 if (FileObject->Flags & FO_ALERTABLE_IO)
290 Status = KeWaitForSingleObject(Event,
295 if (Status != STATUS_WAIT_0)
301 Status = Iosb.Status;
305 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
307 *UserIoStatusBlock = Iosb;
313 /**********************************************************************
328 IN HANDLE FileHandle,
329 IN HANDLE Event OPTIONAL,
330 IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
331 IN PVOID UserApcContext OPTIONAL,
332 OUT PIO_STATUS_BLOCK UserIoStatusBlock,
333 IN FILE_SEGMENT_ELEMENT BufferDescription [],
334 IN ULONG BufferLength,
335 IN PLARGE_INTEGER ByteOffset,
336 IN PULONG Key OPTIONAL
343 /**********************************************************************
358 IN HANDLE FileHandle,
359 IN HANDLE Event OPTIONAL,
360 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
361 IN PVOID ApcContext OPTIONAL,
362 OUT PIO_STATUS_BLOCK IoStatusBlock,
363 IN FILE_SEGMENT_ELEMENT BufferDescription [],
364 IN ULONG BufferLength,
365 IN PLARGE_INTEGER ByteOffset,
366 IN PULONG Key OPTIONAL