finished applying @implemented and @unimplemented comments and remove the comments...
[reactos.git] / reactos / ntoskrnl / io / rw.c
1 /* $Id: rw.c,v 1.45 2003/07/11 01:23:14 royce Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * 30/05/98: Created
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16 #include <internal/ob.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21 /* FUNCTIONS ***************************************************************/
22
23
24 /**********************************************************************
25 * NAME EXPORTED
26 * NtReadFile
27 *
28 * DESCRIPTION
29 *
30 * ARGUMENTS
31 *
32 * RETURN VALUE
33 *
34 * REVISIONS
35 *
36 * @implemented
37 */
38 NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
39 HANDLE EventHandle,
40 PIO_APC_ROUTINE ApcRoutine,
41 PVOID ApcContext,
42 PIO_STATUS_BLOCK UserIoStatusBlock,
43 PVOID Buffer,
44 ULONG Length,
45 PLARGE_INTEGER ByteOffset,
46 PULONG Key)
47 {
48 NTSTATUS Status;
49 PFILE_OBJECT FileObject;
50 PIRP Irp;
51 PIO_STACK_LOCATION StackPtr;
52 PKEVENT Event = NULL;
53 IO_STATUS_BLOCK Iosb;
54 PIO_STATUS_BLOCK IoStatusBlock;
55
56 DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
57 "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
58 IoStatusBlock);
59
60 Status = ObReferenceObjectByHandle(FileHandle,
61 FILE_READ_DATA,
62 IoFileObjectType,
63 UserMode,
64 (PVOID*)&FileObject,
65 NULL);
66 if (!NT_SUCCESS(Status))
67 {
68 return(Status);
69 }
70
71 if (ByteOffset == NULL)
72 {
73 ByteOffset = &FileObject->CurrentByteOffset;
74 }
75
76 if (EventHandle != NULL)
77 {
78 Status = ObReferenceObjectByHandle(EventHandle,
79 SYNCHRONIZE,
80 ExEventObjectType,
81 UserMode,
82 (PVOID*)&Event,
83 NULL);
84 if (!NT_SUCCESS(Status))
85 {
86 ObDereferenceObject(FileObject);
87 return(Status);
88 }
89
90 }
91 else
92 {
93 Event = &FileObject->Event;
94 KeResetEvent(Event);
95 }
96
97 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
98 {
99 IoStatusBlock = &Iosb;
100 }
101 else
102 {
103 IoStatusBlock = UserIoStatusBlock;
104 }
105
106 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
107 FileObject->DeviceObject,
108 Buffer,
109 Length,
110 ByteOffset,
111 Event,
112 IoStatusBlock);
113
114 //trigger FileObject/Event dereferencing
115 Irp->Tail.Overlay.OriginalFileObject = FileObject;
116
117 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
118 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
119
120 StackPtr = IoGetNextIrpStackLocation(Irp);
121 StackPtr->FileObject = FileObject;
122 if (Key != NULL)
123 {
124 StackPtr->Parameters.Read.Key = *Key;
125 }
126 else
127 {
128 StackPtr->Parameters.Read.Key = 0;
129 }
130
131
132 Status = IoCallDriver(FileObject->DeviceObject, Irp);
133 if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
134 {
135 BOOLEAN Alertable;
136
137 if (FileObject->Flags & FO_ALERTABLE_IO)
138 {
139 Alertable = TRUE;
140 }
141 else
142 {
143 Alertable = FALSE;
144 }
145
146 Status = KeWaitForSingleObject(Event,
147 Executive,
148 UserMode,
149 Alertable,
150 NULL);
151 if (Status != STATUS_WAIT_0)
152 {
153 /* Wait failed. */
154 return(Status);
155 }
156
157 Status = Iosb.Status;
158 return(Status);
159 }
160
161 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
162 {
163 *UserIoStatusBlock = Iosb;
164 }
165 return(Status);
166 }
167
168
169 /**********************************************************************
170 * NAME EXPORTED
171 * NtWriteFile
172 *
173 * DESCRIPTION
174 *
175 * ARGUMENTS
176 *
177 * RETURN VALUE
178 *
179 * REVISIONS
180 *
181 * @implemented
182 */
183 NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
184 HANDLE EventHandle,
185 PIO_APC_ROUTINE ApcRoutine,
186 PVOID ApcContext,
187 PIO_STATUS_BLOCK UserIoStatusBlock,
188 PVOID Buffer,
189 ULONG Length,
190 PLARGE_INTEGER ByteOffset,
191 PULONG Key)
192 {
193 NTSTATUS Status;
194 PFILE_OBJECT FileObject;
195 PIRP Irp;
196 PIO_STACK_LOCATION StackPtr;
197 PKEVENT Event = NULL;
198 IO_STATUS_BLOCK Iosb;
199 PIO_STATUS_BLOCK IoStatusBlock;
200
201 DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
202 "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
203 IoStatusBlock);
204
205 Status = ObReferenceObjectByHandle(FileHandle,
206 FILE_READ_DATA,
207 IoFileObjectType,
208 UserMode,
209 (PVOID*)&FileObject,
210 NULL);
211 if (!NT_SUCCESS(Status))
212 {
213 return(Status);
214 }
215
216 if (ByteOffset == NULL)
217 {
218 ByteOffset = &FileObject->CurrentByteOffset;
219 }
220
221 if (EventHandle != NULL)
222 {
223 Status = ObReferenceObjectByHandle(EventHandle,
224 SYNCHRONIZE,
225 ExEventObjectType,
226 UserMode,
227 (PVOID*)&Event,
228 NULL);
229 if (!NT_SUCCESS(Status))
230 {
231 ObDereferenceObject(FileObject);
232 return(Status);
233 }
234
235 }
236 else
237 {
238 Event = &FileObject->Event;
239 KeResetEvent(Event);
240 }
241
242 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
243 {
244 IoStatusBlock = &Iosb;
245 }
246 else
247 {
248 IoStatusBlock = UserIoStatusBlock;
249 }
250
251 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
252 FileObject->DeviceObject,
253 Buffer,
254 Length,
255 ByteOffset,
256 Event,
257 IoStatusBlock);
258
259 //trigger FileObject/Event dereferencing
260 Irp->Tail.Overlay.OriginalFileObject = FileObject;
261
262 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
263 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
264
265 StackPtr = IoGetNextIrpStackLocation(Irp);
266 StackPtr->FileObject = FileObject;
267 if (Key != NULL)
268 {
269 StackPtr->Parameters.Write.Key = *Key;
270 }
271 else
272 {
273 StackPtr->Parameters.Write.Key = 0;
274 }
275
276 Status = IoCallDriver(FileObject->DeviceObject, Irp);
277 if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
278 {
279 BOOLEAN Alertable;
280
281 if (FileObject->Flags & FO_ALERTABLE_IO)
282 {
283 Alertable = TRUE;
284 }
285 else
286 {
287 Alertable = FALSE;
288 }
289
290 Status = KeWaitForSingleObject(Event,
291 Executive,
292 UserMode,
293 Alertable,
294 NULL);
295 if (Status != STATUS_WAIT_0)
296 {
297 /* Wait failed. */
298 return(Status);
299 }
300
301 Status = Iosb.Status;
302 return(Status);
303 }
304
305 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
306 {
307 *UserIoStatusBlock = Iosb;
308 }
309 return(Status);
310 }
311
312
313 /**********************************************************************
314 * NAME EXPORTED
315 * NtReadFileScatter
316 *
317 * DESCRIPTION
318 *
319 * ARGUMENTS
320 *
321 * RETURN VALUE
322 *
323 * REVISIONS
324 */
325 NTSTATUS
326 STDCALL
327 NtReadFileScatter (
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
337 )
338 {
339 UNIMPLEMENTED;
340 }
341
342
343 /**********************************************************************
344 * NAME EXPORTED
345 * NtWriteFileGather
346 *
347 * DESCRIPTION
348 *
349 * ARGUMENTS
350 *
351 * RETURN VALUE
352 *
353 * REVISIONS
354 */
355 NTSTATUS
356 STDCALL
357 NtWriteFileGather (
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
367 )
368 {
369 UNIMPLEMENTED;
370 }
371
372
373 /* EOF */