1 /* $Id: rw.c,v 1.45 2003/07/11 01:23:14 royce Exp $
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