1 /* $Id: rw.c,v 1.54 2004/08/15 16:39:03 chorns 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 ****************************************************************/
16 #include <internal/debug.h>
18 /* FUNCTIONS ***************************************************************/
21 /**********************************************************************
36 NtReadFile (IN HANDLE FileHandle
,
37 IN HANDLE Event OPTIONAL
,
38 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
39 IN PVOID ApcContext OPTIONAL
,
40 OUT PIO_STATUS_BLOCK IoStatusBlock
,
43 IN PLARGE_INTEGER ByteOffset OPTIONAL
, /* NOT optional for asynch. operations! */
44 IN PULONG Key OPTIONAL
)
47 PFILE_OBJECT FileObject
;
49 PIO_STACK_LOCATION StackPtr
;
50 KPROCESSOR_MODE PreviousMode
;
51 PKEVENT EventObject
= NULL
;
53 DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
54 "IoStatusBlock %x)\n", FileHandle
, Buffer
, Length
, ByteOffset
,
57 if (IoStatusBlock
== NULL
)
58 return STATUS_ACCESS_VIOLATION
;
60 PreviousMode
= ExGetPreviousMode();
62 Status
= ObReferenceObjectByHandle(FileHandle
,
68 if (!NT_SUCCESS(Status
))
73 if (ByteOffset
== NULL
)
75 /* a valid ByteOffset is required if asynch. op. */
76 if (!(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
78 DPRINT1("NtReadFile: missing ByteOffset for asynch. op\n");
79 ObDereferenceObject(FileObject
);
80 return STATUS_INVALID_PARAMETER
;
83 ByteOffset
= &FileObject
->CurrentByteOffset
;
88 Status
= ObReferenceObjectByHandle(Event
,
94 if (!NT_SUCCESS(Status
))
96 ObDereferenceObject(FileObject
);
99 KeClearEvent(EventObject
);
102 KeClearEvent(&FileObject
->Event
);
104 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
105 FileObject
->DeviceObject
,
112 /* Trigger FileObject/Event dereferencing */
113 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
115 Irp
->RequestorMode
= PreviousMode
;
117 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
118 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
120 StackPtr
= IoGetNextIrpStackLocation(Irp
);
121 StackPtr
->FileObject
= FileObject
;
122 StackPtr
->Parameters
.Read
.Key
= Key
? *Key
: 0;
124 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
125 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
127 Status
= KeWaitForSingleObject (&FileObject
->Event
,
130 FileObject
->Flags
& FO_ALERTABLE_IO
,
133 if (Status
!= STATUS_WAIT_0
)
139 Status
= IoStatusBlock
->Status
;
146 /**********************************************************************
161 NtWriteFile (IN HANDLE FileHandle
,
162 IN HANDLE Event OPTIONAL
,
163 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
164 IN PVOID ApcContext OPTIONAL
,
165 OUT PIO_STATUS_BLOCK IoStatusBlock
,
168 IN PLARGE_INTEGER ByteOffset OPTIONAL
, /* NOT optional for asynch. operations! */
169 IN PULONG Key OPTIONAL
)
172 PFILE_OBJECT FileObject
;
174 PIO_STACK_LOCATION StackPtr
;
175 KPROCESSOR_MODE PreviousMode
;
176 PKEVENT EventObject
= NULL
;
178 DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
179 "IoStatusBlock %x)\n", FileHandle
, Buffer
, Length
, ByteOffset
,
182 if (IoStatusBlock
== NULL
)
183 return STATUS_ACCESS_VIOLATION
;
185 PreviousMode
= ExGetPreviousMode();
187 Status
= ObReferenceObjectByHandle(FileHandle
,
193 if (!NT_SUCCESS(Status
))
198 if (ByteOffset
== NULL
)
200 /* a valid ByteOffset is required if asynch. op. */
201 if (!(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
203 DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
204 ObDereferenceObject(FileObject
);
205 return STATUS_INVALID_PARAMETER
;
208 ByteOffset
= &FileObject
->CurrentByteOffset
;
213 Status
= ObReferenceObjectByHandle(Event
,
217 (PVOID
*)&EventObject
,
220 if (!NT_SUCCESS(Status
))
222 ObDereferenceObject(FileObject
);
226 KeClearEvent(EventObject
);
229 KeClearEvent(&FileObject
->Event
);
231 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
232 FileObject
->DeviceObject
,
239 /* Trigger FileObject/Event dereferencing */
240 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
242 Irp
->RequestorMode
= PreviousMode
;
244 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
245 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
247 StackPtr
= IoGetNextIrpStackLocation(Irp
);
248 StackPtr
->FileObject
= FileObject
;
249 StackPtr
->Parameters
.Write
.Key
= Key
? *Key
: 0;
251 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
252 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
254 Status
= KeWaitForSingleObject (&FileObject
->Event
,
257 FileObject
->Flags
& FO_ALERTABLE_IO
,
259 if (Status
!= STATUS_WAIT_0
)
265 Status
= IoStatusBlock
->Status
;
272 /**********************************************************************
287 IN HANDLE FileHandle
,
288 IN HANDLE Event OPTIONAL
,
289 IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL
,
290 IN PVOID UserApcContext OPTIONAL
,
291 OUT PIO_STATUS_BLOCK UserIoStatusBlock
,
292 IN FILE_SEGMENT_ELEMENT BufferDescription
[],
293 IN ULONG BufferLength
,
294 IN PLARGE_INTEGER ByteOffset
,
295 IN PULONG Key OPTIONAL
299 return(STATUS_NOT_IMPLEMENTED
);
303 /**********************************************************************
318 IN HANDLE FileHandle
,
319 IN HANDLE Event OPTIONAL
,
320 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
321 IN PVOID ApcContext OPTIONAL
,
322 OUT PIO_STATUS_BLOCK IoStatusBlock
,
323 IN FILE_SEGMENT_ELEMENT BufferDescription
[],
324 IN ULONG BufferLength
,
325 IN PLARGE_INTEGER ByteOffset
,
326 IN PULONG Key OPTIONAL
330 return(STATUS_NOT_IMPLEMENTED
);