update for HEAD-2003091401
[reactos.git] / ntoskrnl / io / rw.c
1 /* $Id$
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 */