1 /* $Id: rw.c,v 1.55 2004/09/28 10:51:05 ekohl 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
);
100 KeClearEvent(EventObject
);
103 KeClearEvent(&FileObject
->Event
);
105 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
106 FileObject
->DeviceObject
,
113 /* Trigger FileObject/Event dereferencing */
114 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
116 Irp
->RequestorMode
= PreviousMode
;
118 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
119 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
121 StackPtr
= IoGetNextIrpStackLocation(Irp
);
122 StackPtr
->FileObject
= FileObject
;
123 StackPtr
->Parameters
.Read
.Key
= Key
? *Key
: 0;
125 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
126 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
128 Status
= KeWaitForSingleObject(&FileObject
->Event
,
131 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
)
171 OBJECT_HANDLE_INFORMATION HandleInformation
;
173 PFILE_OBJECT FileObject
;
175 PIO_STACK_LOCATION StackPtr
;
176 KPROCESSOR_MODE PreviousMode
;
177 PKEVENT EventObject
= NULL
;
178 LARGE_INTEGER Offset
;
180 DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
181 "IoStatusBlock %x)\n", FileHandle
, Buffer
, Length
, ByteOffset
,
184 if (IoStatusBlock
== NULL
)
185 return STATUS_ACCESS_VIOLATION
;
187 PreviousMode
= ExGetPreviousMode();
189 Status
= ObReferenceObjectByHandle(FileHandle
,
195 if (!NT_SUCCESS(Status
))
200 /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
201 if (!(HandleInformation
.GrantedAccess
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)))
203 DPRINT1("Invalid access rights\n");
204 ObDereferenceObject(FileObject
);
205 return STATUS_ACCESS_DENIED
;
208 if (HandleInformation
.GrantedAccess
& FILE_WRITE_DATA
)
210 if (ByteOffset
== NULL
)
212 /* a valid ByteOffset is required if asynch. op. */
213 if (!(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
215 DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
216 ObDereferenceObject(FileObject
);
217 return STATUS_INVALID_PARAMETER
;
220 ByteOffset
= &FileObject
->CurrentByteOffset
;
223 else if (HandleInformation
.GrantedAccess
& FILE_APPEND_DATA
)
225 /* a valid ByteOffset is required if asynch. op. */
226 if (!(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
228 DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
229 ObDereferenceObject(FileObject
);
230 return STATUS_INVALID_PARAMETER
;
233 Offset
.u
.LowPart
= FILE_WRITE_TO_END_OF_FILE
;
234 Offset
.u
.HighPart
= 0xffffffff;
235 ByteOffset
= &Offset
;
240 Status
= ObReferenceObjectByHandle(Event
,
244 (PVOID
*)&EventObject
,
246 if (!NT_SUCCESS(Status
))
248 ObDereferenceObject(FileObject
);
252 KeClearEvent(EventObject
);
255 KeClearEvent(&FileObject
->Event
);
257 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
258 FileObject
->DeviceObject
,
265 /* Trigger FileObject/Event dereferencing */
266 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
268 Irp
->RequestorMode
= PreviousMode
;
270 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
271 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
273 StackPtr
= IoGetNextIrpStackLocation(Irp
);
274 StackPtr
->FileObject
= FileObject
;
275 StackPtr
->Parameters
.Write
.Key
= Key
? *Key
: 0;
277 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
278 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
280 Status
= KeWaitForSingleObject(&FileObject
->Event
,
283 FileObject
->Flags
& FO_ALERTABLE_IO
,
285 if (Status
!= STATUS_WAIT_0
)
291 Status
= IoStatusBlock
->Status
;
298 /**********************************************************************
313 IN HANDLE FileHandle
,
314 IN HANDLE Event OPTIONAL
,
315 IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL
,
316 IN PVOID UserApcContext OPTIONAL
,
317 OUT PIO_STATUS_BLOCK UserIoStatusBlock
,
318 IN FILE_SEGMENT_ELEMENT BufferDescription
[],
319 IN ULONG BufferLength
,
320 IN PLARGE_INTEGER ByteOffset
,
321 IN PULONG Key OPTIONAL
325 return(STATUS_NOT_IMPLEMENTED
);
329 /**********************************************************************
344 IN HANDLE FileHandle
,
345 IN HANDLE Event OPTIONAL
,
346 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
347 IN PVOID ApcContext OPTIONAL
,
348 OUT PIO_STATUS_BLOCK IoStatusBlock
,
349 IN FILE_SEGMENT_ELEMENT BufferDescription
[],
350 IN ULONG BufferLength
,
351 IN PLARGE_INTEGER ByteOffset
,
352 IN PULONG Key OPTIONAL
356 return(STATUS_NOT_IMPLEMENTED
);