c456b56bc4a0ec04e32841d6764cb9a16c6dc534
[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 #ifndef LIBCAPTIVE
165
166 /**********************************************************************
167  * NAME                                                 EXPORTED
168  *      NtWriteFile
169  *
170  * DESCRIPTION
171  *
172  * ARGUMENTS
173  *
174  * RETURN VALUE
175  *
176  * REVISIONS
177  *
178  */
179 NTSTATUS STDCALL NtWriteFile(HANDLE                     FileHandle,
180                              HANDLE                     EventHandle,
181                              PIO_APC_ROUTINE            ApcRoutine,
182                              PVOID                      ApcContext,
183                              PIO_STATUS_BLOCK           UserIoStatusBlock,
184                              PVOID                      Buffer,
185                              ULONG                      Length,
186                              PLARGE_INTEGER             ByteOffset,
187                              PULONG                     Key)
188 {
189   NTSTATUS Status;
190   PFILE_OBJECT FileObject;
191   PIRP Irp;
192   PIO_STACK_LOCATION StackPtr;
193   PKEVENT Event = NULL;
194   IO_STATUS_BLOCK Iosb;
195   PIO_STATUS_BLOCK IoStatusBlock;
196   
197   DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
198          "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
199          IoStatusBlock);
200   
201   Status = ObReferenceObjectByHandle(FileHandle,
202                                      FILE_READ_DATA,
203                                      IoFileObjectType,
204                                      UserMode,
205                                      (PVOID*)&FileObject,
206                                      NULL);
207   if (!NT_SUCCESS(Status))
208     {
209       return(Status);
210     }
211   
212   if (ByteOffset == NULL)
213     {
214       ByteOffset = &FileObject->CurrentByteOffset;
215     }
216   
217   if (EventHandle != NULL)
218     {
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     }
231   else 
232     {
233       Event = &FileObject->Event;
234       KeResetEvent(Event);
235     }
236   
237   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
238     {
239       IoStatusBlock = &Iosb;
240     }
241   else
242     {
243       IoStatusBlock = UserIoStatusBlock;
244     }
245   
246   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
247                                      FileObject->DeviceObject,
248                                      Buffer,
249                                      Length,
250                                      ByteOffset,
251                                      Event,
252                                      IoStatusBlock);
253   
254   Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
255   Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
256   
257   StackPtr = IoGetNextIrpStackLocation(Irp);
258   StackPtr->FileObject = FileObject;
259   if (Key != NULL)
260     {
261       StackPtr->Parameters.Write.Key = *Key;
262     }
263   else
264     {
265       StackPtr->Parameters.Write.Key = 0;
266     }
267   
268   Status = IoCallDriver(FileObject->DeviceObject, Irp);
269   if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
270      {
271        BOOLEAN Alertable;
272        
273        if (FileObject->Flags & FO_ALERTABLE_IO)
274          {
275            Alertable = TRUE;
276          }
277        else
278          {
279            Alertable = FALSE;
280          } 
281        
282        Status = KeWaitForSingleObject(Event,
283                                       Executive,
284                                       UserMode,
285                                       Alertable,
286                                       NULL);
287        if (Status != STATUS_WAIT_0)
288          {
289            /* Wait failed. */
290            return(Status);
291          }
292         Status = Iosb.Status;
293         return(Status);
294      }
295   if (FileObject->Flags & FO_SYNCHRONOUS_IO)
296     {
297       *UserIoStatusBlock = Iosb;
298     }
299   return(Status);
300 }
301
302
303 /**********************************************************************
304  * NAME                                                 EXPORTED
305  *      NtReadFileScatter
306  *      
307  * DESCRIPTION
308  *
309  * ARGUMENTS
310  *
311  * RETURN VALUE
312  *
313  * REVISIONS
314  *
315  */
316 NTSTATUS
317 STDCALL
318 NtReadFileScatter (
319         IN      HANDLE                  FileHandle, 
320         IN      HANDLE                  Event                   OPTIONAL, 
321         IN      PIO_APC_ROUTINE         UserApcRoutine          OPTIONAL, 
322         IN      PVOID                   UserApcContext          OPTIONAL, 
323         OUT     PIO_STATUS_BLOCK        UserIoStatusBlock, 
324         IN      FILE_SEGMENT_ELEMENT    BufferDescription [], 
325         IN      ULONG                   BufferLength, 
326         IN      PLARGE_INTEGER          ByteOffset, 
327         IN      PULONG                  Key                     OPTIONAL
328         )
329 {
330         UNIMPLEMENTED;
331 }
332
333
334 /**********************************************************************
335  * NAME                                                 EXPORTED
336  *      NtWriteFileGather
337  *      
338  * DESCRIPTION
339  *
340  * ARGUMENTS
341  *
342  * RETURN VALUE
343  *
344  * REVISIONS
345  *
346  */
347 NTSTATUS
348 STDCALL
349 NtWriteFileGather (
350         IN      HANDLE                  FileHandle, 
351         IN      HANDLE                  Event OPTIONAL, 
352         IN      PIO_APC_ROUTINE         ApcRoutine              OPTIONAL, 
353         IN      PVOID                   ApcContext              OPTIONAL, 
354         OUT     PIO_STATUS_BLOCK        IoStatusBlock,
355         IN      FILE_SEGMENT_ELEMENT    BufferDescription [],
356         IN      ULONG                   BufferLength, 
357         IN      PLARGE_INTEGER          ByteOffset, 
358         IN      PULONG                  Key                     OPTIONAL
359         )
360 {
361         UNIMPLEMENTED;
362 }
363
364 #endif /* LIBCAPTIVE */
365
366 /* EOF */