8ffe9eeb5f9ffca245489cadbea42f1713db6e05
[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  */
37 NTSTATUS STDCALL NtReadFile(HANDLE                      FileHandle,
38                             HANDLE                      EventHandle,
39                             PIO_APC_ROUTINE             ApcRoutine,
40                             PVOID                       ApcContext,
41                             PIO_STATUS_BLOCK            UserIoStatusBlock,
42                             PVOID                       Buffer,
43                             ULONG                       Length,
44                             PLARGE_INTEGER              ByteOffset,
45                             PULONG                      Key)
46 {
47   NTSTATUS Status;
48   PFILE_OBJECT FileObject;
49   PIRP Irp;
50   PIO_STACK_LOCATION StackPtr;
51   PKEVENT Event = NULL;
52   IO_STATUS_BLOCK Iosb;
53   PIO_STATUS_BLOCK IoStatusBlock;
54   
55   DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
56          "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
57          IoStatusBlock);
58   
59   Status = ObReferenceObjectByHandle(FileHandle,
60                                      FILE_READ_DATA,
61                                      IoFileObjectType,
62                                      UserMode,
63                                      (PVOID*)&FileObject,
64                                      NULL);
65   if (!NT_SUCCESS(Status))
66     {
67       return(Status);
68     }
69   
70   if (ByteOffset == NULL)
71     {
72       ByteOffset = &FileObject->CurrentByteOffset;
73     }
74   
75   if (EventHandle != NULL)
76     {
77       Status = ObReferenceObjectByHandle(EventHandle,
78                                          SYNCHRONIZE,
79                                          ExEventObjectType,
80                                          UserMode,
81                                          (PVOID*)&Event,
82                                          NULL);
83       if (!NT_SUCCESS(Status))
84         {
85           ObDereferenceObject(FileObject);
86           return(Status);
87         }
88     }
89   else 
90     {
91       Event = &FileObject->Event;
92       KeResetEvent(Event);
93     }
94   
95   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
96     {
97       IoStatusBlock = &Iosb;
98     }
99   else
100     {
101       IoStatusBlock = UserIoStatusBlock;
102     }
103   
104   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
105                                      FileObject->DeviceObject,
106                                      Buffer,
107                                      Length,
108                                      ByteOffset,
109                                      Event,
110                                      IoStatusBlock);
111   
112   Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
113   Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
114   
115   StackPtr = IoGetNextIrpStackLocation(Irp);
116   StackPtr->FileObject = FileObject;
117   if (Key != NULL)
118     {
119       StackPtr->Parameters.Read.Key = *Key;
120     }
121   else
122     {
123       StackPtr->Parameters.Read.Key = 0;
124     }
125   
126   Status = IoCallDriver(FileObject->DeviceObject, Irp);
127   if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
128      {
129        BOOLEAN Alertable;
130        
131        if (FileObject->Flags & FO_ALERTABLE_IO)
132          {
133            Alertable = TRUE;
134          }
135        else
136          {
137            Alertable = FALSE;
138          } 
139        
140        Status = KeWaitForSingleObject(Event,
141                                       Executive,
142                                       UserMode,
143                                       Alertable,
144                                       NULL);
145        if (Status != STATUS_WAIT_0)
146          {
147            /* Wait failed. */
148            return(Status);
149          }
150         Status = Iosb.Status;
151         return(Status);
152      }
153   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
154     {
155       *UserIoStatusBlock = Iosb;
156     }
157   return(Status);
158 }
159
160
161 /**********************************************************************
162  * NAME                                                 EXPORTED
163  *      NtWriteFile
164  *
165  * DESCRIPTION
166  *
167  * ARGUMENTS
168  *
169  * RETURN VALUE
170  *
171  * REVISIONS
172  *
173  */
174 NTSTATUS STDCALL NtWriteFile(HANDLE                     FileHandle,
175                              HANDLE                     EventHandle,
176                              PIO_APC_ROUTINE            ApcRoutine,
177                              PVOID                      ApcContext,
178                              PIO_STATUS_BLOCK           UserIoStatusBlock,
179                              PVOID                      Buffer,
180                              ULONG                      Length,
181                              PLARGE_INTEGER             ByteOffset,
182                              PULONG                     Key)
183 {
184   NTSTATUS Status;
185   PFILE_OBJECT FileObject;
186   PIRP Irp;
187   PIO_STACK_LOCATION StackPtr;
188   PKEVENT Event = NULL;
189   IO_STATUS_BLOCK Iosb;
190   PIO_STATUS_BLOCK IoStatusBlock;
191   
192   DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
193          "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
194          IoStatusBlock);
195   
196   Status = ObReferenceObjectByHandle(FileHandle,
197                                      FILE_READ_DATA,
198                                      IoFileObjectType,
199                                      UserMode,
200                                      (PVOID*)&FileObject,
201                                      NULL);
202   if (!NT_SUCCESS(Status))
203     {
204       return(Status);
205     }
206   
207   if (ByteOffset == NULL)
208     {
209       ByteOffset = &FileObject->CurrentByteOffset;
210     }
211   
212   if (EventHandle != NULL)
213     {
214       Status = ObReferenceObjectByHandle(EventHandle,
215                                          SYNCHRONIZE,
216                                          ExEventObjectType,
217                                          UserMode,
218                                          (PVOID*)&Event,
219                                          NULL);
220       if (!NT_SUCCESS(Status))
221         {
222           ObDereferenceObject(FileObject);
223           return(Status);
224         }
225     }
226   else 
227     {
228       Event = &FileObject->Event;
229       KeResetEvent(Event);
230     }
231   
232   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
233     {
234       IoStatusBlock = &Iosb;
235     }
236   else
237     {
238       IoStatusBlock = UserIoStatusBlock;
239     }
240   
241   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
242                                      FileObject->DeviceObject,
243                                      Buffer,
244                                      Length,
245                                      ByteOffset,
246                                      Event,
247                                      IoStatusBlock);
248   
249   Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
250   Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
251   
252   StackPtr = IoGetNextIrpStackLocation(Irp);
253   StackPtr->FileObject = FileObject;
254   if (Key != NULL)
255     {
256       StackPtr->Parameters.Write.Key = *Key;
257     }
258   else
259     {
260       StackPtr->Parameters.Write.Key = 0;
261     }
262   
263   Status = IoCallDriver(FileObject->DeviceObject, Irp);
264   if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
265      {
266        BOOLEAN Alertable;
267        
268        if (FileObject->Flags & FO_ALERTABLE_IO)
269          {
270            Alertable = TRUE;
271          }
272        else
273          {
274            Alertable = FALSE;
275          } 
276        
277        Status = KeWaitForSingleObject(Event,
278                                       Executive,
279                                       UserMode,
280                                       Alertable,
281                                       NULL);
282        if (Status != STATUS_WAIT_0)
283          {
284            /* Wait failed. */
285            return(Status);
286          }
287         Status = Iosb.Status;
288         return(Status);
289      }
290   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
291     {
292       *UserIoStatusBlock = Iosb;
293     }
294   return(Status);
295 }
296
297
298 /**********************************************************************
299  * NAME                                                 EXPORTED
300  *      NtReadFileScatter
301  *      
302  * DESCRIPTION
303  *
304  * ARGUMENTS
305  *
306  * RETURN VALUE
307  *
308  * REVISIONS
309  *
310  */
311 NTSTATUS
312 STDCALL
313 NtReadFileScatter (
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
323         )
324 {
325         UNIMPLEMENTED;
326 }
327
328
329 /**********************************************************************
330  * NAME                                                 EXPORTED
331  *      NtWriteFileGather
332  *      
333  * DESCRIPTION
334  *
335  * ARGUMENTS
336  *
337  * RETURN VALUE
338  *
339  * REVISIONS
340  *
341  */
342 NTSTATUS
343 STDCALL
344 NtWriteFileGather (
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
354         )
355 {
356         UNIMPLEMENTED;
357 }
358
359
360 /* EOF */