28a13b9711e530166fe1c6efad084ded8be47731
[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 #ifndef LIBCAPTIVE
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 #else /* !LIBCAPTIVE */
90       KeBugCheck(0);
91 #endif /* LIBCAPTIVE */
92     }
93   else 
94     {
95       Event = &FileObject->Event;
96       KeResetEvent(Event);
97     }
98   
99   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
100     {
101       IoStatusBlock = &Iosb;
102     }
103   else
104     {
105       IoStatusBlock = UserIoStatusBlock;
106     }
107   
108   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
109                                      FileObject->DeviceObject,
110                                      Buffer,
111                                      Length,
112                                      ByteOffset,
113                                      Event,
114                                      IoStatusBlock);
115   
116   Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
117   Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
118   
119   StackPtr = IoGetNextIrpStackLocation(Irp);
120   StackPtr->FileObject = FileObject;
121   if (Key != NULL)
122     {
123       StackPtr->Parameters.Read.Key = *Key;
124     }
125   else
126     {
127       StackPtr->Parameters.Read.Key = 0;
128     }
129   
130   Status = IoCallDriver(FileObject->DeviceObject, Irp);
131   if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
132      {
133        BOOLEAN Alertable;
134        
135        if (FileObject->Flags & FO_ALERTABLE_IO)
136          {
137            Alertable = TRUE;
138          }
139        else
140          {
141            Alertable = FALSE;
142          } 
143        
144        Status = KeWaitForSingleObject(Event,
145                                       Executive,
146                                       UserMode,
147                                       Alertable,
148                                       NULL);
149        if (Status != STATUS_WAIT_0)
150          {
151            /* Wait failed. */
152            return(Status);
153          }
154         Status = Iosb.Status;
155         return(Status);
156      }
157   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
158     {
159       *UserIoStatusBlock = Iosb;
160     }
161   return(Status);
162 }
163
164
165 /**********************************************************************
166  * NAME                                                 EXPORTED
167  *      NtWriteFile
168  *
169  * DESCRIPTION
170  *
171  * ARGUMENTS
172  *
173  * RETURN VALUE
174  *
175  * REVISIONS
176  *
177  */
178 NTSTATUS STDCALL NtWriteFile(HANDLE                     FileHandle,
179                              HANDLE                     EventHandle,
180                              PIO_APC_ROUTINE            ApcRoutine,
181                              PVOID                      ApcContext,
182                              PIO_STATUS_BLOCK           UserIoStatusBlock,
183                              PVOID                      Buffer,
184                              ULONG                      Length,
185                              PLARGE_INTEGER             ByteOffset,
186                              PULONG                     Key)
187 {
188   NTSTATUS Status;
189   PFILE_OBJECT FileObject;
190   PIRP Irp;
191   PIO_STACK_LOCATION StackPtr;
192   PKEVENT Event = NULL;
193   IO_STATUS_BLOCK Iosb;
194   PIO_STATUS_BLOCK IoStatusBlock;
195   
196   DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
197          "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
198          IoStatusBlock);
199   
200   Status = ObReferenceObjectByHandle(FileHandle,
201                                      FILE_READ_DATA,
202                                      IoFileObjectType,
203                                      UserMode,
204                                      (PVOID*)&FileObject,
205                                      NULL);
206   if (!NT_SUCCESS(Status))
207     {
208       return(Status);
209     }
210   
211   if (ByteOffset == NULL)
212     {
213       ByteOffset = &FileObject->CurrentByteOffset;
214     }
215   
216   if (EventHandle != NULL)
217     {
218 #ifndef LIBCAPTIVE
219       Status = ObReferenceObjectByHandle(EventHandle,
220                                          SYNCHRONIZE,
221                                          ExEventObjectType,
222                                          UserMode,
223                                          (PVOID*)&Event,
224                                          NULL);
225       if (!NT_SUCCESS(Status))
226         {
227           ObDereferenceObject(FileObject);
228           return(Status);
229         }
230 #else /* !LIBCAPTIVE */
231       KeBugCheck(0);
232 #endif /* LIBCAPTIVE */
233     }
234   else 
235     {
236       Event = &FileObject->Event;
237       KeResetEvent(Event);
238     }
239   
240   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
241     {
242       IoStatusBlock = &Iosb;
243     }
244   else
245     {
246       IoStatusBlock = UserIoStatusBlock;
247     }
248   
249   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
250                                      FileObject->DeviceObject,
251                                      Buffer,
252                                      Length,
253                                      ByteOffset,
254                                      Event,
255                                      IoStatusBlock);
256   
257   Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
258   Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
259   
260   StackPtr = IoGetNextIrpStackLocation(Irp);
261   StackPtr->FileObject = FileObject;
262   if (Key != NULL)
263     {
264       StackPtr->Parameters.Write.Key = *Key;
265     }
266   else
267     {
268       StackPtr->Parameters.Write.Key = 0;
269     }
270   
271   Status = IoCallDriver(FileObject->DeviceObject, Irp);
272   if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
273      {
274        BOOLEAN Alertable;
275        
276        if (FileObject->Flags & FO_ALERTABLE_IO)
277          {
278            Alertable = TRUE;
279          }
280        else
281          {
282            Alertable = FALSE;
283          } 
284        
285        Status = KeWaitForSingleObject(Event,
286                                       Executive,
287                                       UserMode,
288                                       Alertable,
289                                       NULL);
290        if (Status != STATUS_WAIT_0)
291          {
292            /* Wait failed. */
293            return(Status);
294          }
295         Status = Iosb.Status;
296         return(Status);
297      }
298   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
299     {
300       *UserIoStatusBlock = Iosb;
301     }
302   return(Status);
303 }
304
305 #ifndef LIBCAPTIVE
306
307 /**********************************************************************
308  * NAME                                                 EXPORTED
309  *      NtReadFileScatter
310  *      
311  * DESCRIPTION
312  *
313  * ARGUMENTS
314  *
315  * RETURN VALUE
316  *
317  * REVISIONS
318  *
319  */
320 NTSTATUS
321 STDCALL
322 NtReadFileScatter (
323         IN      HANDLE                  FileHandle, 
324         IN      HANDLE                  Event                   OPTIONAL, 
325         IN      PIO_APC_ROUTINE         UserApcRoutine          OPTIONAL, 
326         IN      PVOID                   UserApcContext          OPTIONAL, 
327         OUT     PIO_STATUS_BLOCK        UserIoStatusBlock, 
328         IN      FILE_SEGMENT_ELEMENT    BufferDescription [], 
329         IN      ULONG                   BufferLength, 
330         IN      PLARGE_INTEGER          ByteOffset, 
331         IN      PULONG                  Key                     OPTIONAL
332         )
333 {
334         UNIMPLEMENTED;
335 }
336
337
338 /**********************************************************************
339  * NAME                                                 EXPORTED
340  *      NtWriteFileGather
341  *      
342  * DESCRIPTION
343  *
344  * ARGUMENTS
345  *
346  * RETURN VALUE
347  *
348  * REVISIONS
349  *
350  */
351 NTSTATUS
352 STDCALL
353 NtWriteFileGather (
354         IN      HANDLE                  FileHandle, 
355         IN      HANDLE                  Event OPTIONAL, 
356         IN      PIO_APC_ROUTINE         ApcRoutine              OPTIONAL, 
357         IN      PVOID                   ApcContext              OPTIONAL, 
358         OUT     PIO_STATUS_BLOCK        IoStatusBlock,
359         IN      FILE_SEGMENT_ELEMENT    BufferDescription [],
360         IN      ULONG                   BufferLength, 
361         IN      PLARGE_INTEGER          ByteOffset, 
362         IN      PULONG                  Key                     OPTIONAL
363         )
364 {
365         UNIMPLEMENTED;
366 }
367
368 #endif /* LIBCAPTIVE */
369
370 /* EOF */