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
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
11 /* INCLUDES ****************************************************************/
15 #include <internal/debug.h>
17 /* FUNCTIONS ***************************************************************/
20 /**********************************************************************
35 NtReadFile (IN HANDLE FileHandle
,
36 IN HANDLE Event OPTIONAL
,
37 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
38 IN PVOID ApcContext OPTIONAL
,
39 OUT PIO_STATUS_BLOCK IoStatusBlock
,
42 IN PLARGE_INTEGER ByteOffset OPTIONAL
, /* NOT optional for asynch. operations! */
43 IN PULONG Key OPTIONAL
)
46 PFILE_OBJECT FileObject
;
48 PIO_STACK_LOCATION StackPtr
;
49 KPROCESSOR_MODE PreviousMode
;
50 PKEVENT EventObject
= NULL
;
52 DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
53 "IoStatusBlock %x)\n", FileHandle
, Buffer
, Length
, ByteOffset
,
56 if (IoStatusBlock
== NULL
)
57 return STATUS_ACCESS_VIOLATION
;
59 PreviousMode
= ExGetPreviousMode();
61 Status
= ObReferenceObjectByHandle(FileHandle
,
67 if (!NT_SUCCESS(Status
))
72 if (ByteOffset
== NULL
||
73 (ByteOffset
->u
.LowPart
== FILE_USE_FILE_POINTER_POSITION
&&
74 ByteOffset
->u
.HighPart
== 0xffffffff))
76 /* a valid ByteOffset is required if asynch. op. */
77 if (!(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
79 DPRINT1("NtReadFile: missing ByteOffset for asynch. op\n");
80 ObDereferenceObject(FileObject
);
81 return STATUS_INVALID_PARAMETER
;
84 ByteOffset
= &FileObject
->CurrentByteOffset
;
89 Status
= ObReferenceObjectByHandle(Event
,
95 if (!NT_SUCCESS(Status
))
97 ObDereferenceObject(FileObject
);
101 KeClearEvent(EventObject
);
104 KeClearEvent(&FileObject
->Event
);
106 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
107 FileObject
->DeviceObject
,
114 /* Trigger FileObject/Event dereferencing */
115 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
117 Irp
->RequestorMode
= PreviousMode
;
119 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
120 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
122 StackPtr
= IoGetNextIrpStackLocation(Irp
);
123 StackPtr
->FileObject
= FileObject
;
124 StackPtr
->Parameters
.Read
.Key
= Key
? *Key
: 0;
126 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
127 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
129 Status
= KeWaitForSingleObject(&FileObject
->Event
,
132 FileObject
->Flags
& FO_ALERTABLE_IO
,
134 if (Status
!= STATUS_WAIT_0
)
140 Status
= IoStatusBlock
->Status
;
147 /**********************************************************************
162 NtWriteFile (IN HANDLE FileHandle
,
163 IN HANDLE Event OPTIONAL
,
164 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
165 IN PVOID ApcContext OPTIONAL
,
166 OUT PIO_STATUS_BLOCK IoStatusBlock
,
169 IN PLARGE_INTEGER ByteOffset OPTIONAL
, /* NOT optional for asynch. operations! */
170 IN PULONG Key OPTIONAL
)
172 OBJECT_HANDLE_INFORMATION HandleInformation
;
174 PFILE_OBJECT FileObject
;
176 PIO_STACK_LOCATION StackPtr
;
177 KPROCESSOR_MODE PreviousMode
;
178 PKEVENT EventObject
= NULL
;
179 LARGE_INTEGER Offset
;
181 DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
182 "IoStatusBlock %x)\n", FileHandle
, Buffer
, Length
, ByteOffset
,
185 if (IoStatusBlock
== NULL
)
186 return STATUS_ACCESS_VIOLATION
;
188 PreviousMode
= ExGetPreviousMode();
190 Status
= ObReferenceObjectByHandle(FileHandle
,
196 if (!NT_SUCCESS(Status
))
201 /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
202 if (!(HandleInformation
.GrantedAccess
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)))
204 DPRINT1("Invalid access rights\n");
205 ObDereferenceObject(FileObject
);
206 return STATUS_ACCESS_DENIED
;
209 if (HandleInformation
.GrantedAccess
& FILE_WRITE_DATA
)
211 if (ByteOffset
== NULL
)
213 /* a valid ByteOffset is required if asynch. op. */
214 if (!(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
216 DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
217 ObDereferenceObject(FileObject
);
218 return STATUS_INVALID_PARAMETER
;
221 ByteOffset
= &FileObject
->CurrentByteOffset
;
224 else if (HandleInformation
.GrantedAccess
& FILE_APPEND_DATA
)
226 /* a valid ByteOffset is required if asynch. op. */
227 if (!(FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
229 DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
230 ObDereferenceObject(FileObject
);
231 return STATUS_INVALID_PARAMETER
;
234 Offset
.u
.LowPart
= FILE_WRITE_TO_END_OF_FILE
;
235 Offset
.u
.HighPart
= 0xffffffff;
236 ByteOffset
= &Offset
;
241 Status
= ObReferenceObjectByHandle(Event
,
245 (PVOID
*)&EventObject
,
247 if (!NT_SUCCESS(Status
))
249 ObDereferenceObject(FileObject
);
253 KeClearEvent(EventObject
);
256 KeClearEvent(&FileObject
->Event
);
258 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
259 FileObject
->DeviceObject
,
266 /* Trigger FileObject/Event dereferencing */
267 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
269 Irp
->RequestorMode
= PreviousMode
;
271 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
272 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
274 StackPtr
= IoGetNextIrpStackLocation(Irp
);
275 StackPtr
->FileObject
= FileObject
;
276 StackPtr
->Parameters
.Write
.Key
= Key
? *Key
: 0;
278 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
279 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
281 Status
= KeWaitForSingleObject(&FileObject
->Event
,
284 FileObject
->Flags
& FO_ALERTABLE_IO
,
286 if (Status
!= STATUS_WAIT_0
)
292 Status
= IoStatusBlock
->Status
;
299 /**********************************************************************
314 IN HANDLE FileHandle
,
315 IN HANDLE Event OPTIONAL
,
316 IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL
,
317 IN PVOID UserApcContext OPTIONAL
,
318 OUT PIO_STATUS_BLOCK UserIoStatusBlock
,
319 IN FILE_SEGMENT_ELEMENT BufferDescription
[],
320 IN ULONG BufferLength
,
321 IN PLARGE_INTEGER ByteOffset
,
322 IN PULONG Key OPTIONAL
326 return(STATUS_NOT_IMPLEMENTED
);
330 /**********************************************************************
345 IN HANDLE FileHandle
,
346 IN HANDLE Event OPTIONAL
,
347 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
348 IN PVOID ApcContext OPTIONAL
,
349 OUT PIO_STATUS_BLOCK IoStatusBlock
,
350 IN FILE_SEGMENT_ELEMENT BufferDescription
[],
351 IN ULONG BufferLength
,
352 IN PLARGE_INTEGER ByteOffset
,
353 IN PULONG Key OPTIONAL
357 return(STATUS_NOT_IMPLEMENTED
);