3742a0d7888606854d957ac1e78dd18b3b591c11
[reactos.git] / lib / kernel32 / file / rw.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/file/rw.c
6  * PURPOSE:         Read/write functions
7  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
8  * UPDATE HISTORY:
9  *                  Created 01/11/98
10  */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <k32.h>
15
16 #define NDEBUG
17 #include <kernel32/kernel32.h>
18
19
20 /* FUNCTIONS ****************************************************************/
21
22 WINBOOL STDCALL WriteFile(HANDLE hFile,
23                           LPCVOID lpBuffer,     
24                           DWORD nNumberOfBytesToWrite,
25                           LPDWORD lpNumberOfBytesWritten,       
26                           LPOVERLAPPED lpOverLapped)
27 {
28    HANDLE hEvent = NULL;
29    LARGE_INTEGER Offset;
30    NTSTATUS errCode;
31    IO_STATUS_BLOCK IIosb;
32    PIO_STATUS_BLOCK IoStatusBlock;
33    PLARGE_INTEGER ptrOffset;
34
35    DPRINT("WriteFile(hFile %x)\n",hFile);
36    
37    if (IsConsoleHandle(hFile))
38      {
39         return(WriteConsoleA(hFile,
40                              lpBuffer,
41                              nNumberOfBytesToWrite,
42                              lpNumberOfBytesWritten,
43                              NULL));
44      }
45       
46    if (lpOverLapped != NULL) 
47      {
48         Offset.u.LowPart = lpOverLapped->Offset;
49         Offset.u.HighPart = lpOverLapped->OffsetHigh;
50         lpOverLapped->Internal = STATUS_PENDING;
51         hEvent = lpOverLapped->hEvent;
52         IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
53         ptrOffset = &Offset;
54      }
55    else 
56      {
57         ptrOffset = NULL;
58         IoStatusBlock = &IIosb;
59         Offset.QuadPart = 0;
60      }
61
62    errCode = NtWriteFile(hFile,
63                          hEvent,
64                          NULL,
65                          NULL,
66                          IoStatusBlock,
67                          (PVOID)lpBuffer, 
68                          nNumberOfBytesToWrite,
69                          ptrOffset,
70                          NULL);
71    if (!NT_SUCCESS(errCode))
72      {
73         SetLastErrorByStatus (errCode);
74         DPRINT("WriteFile() failed\n");
75         return FALSE;
76      }
77    if (lpNumberOfBytesWritten != NULL )
78      {
79         *lpNumberOfBytesWritten = IoStatusBlock->Information;
80      }
81    DPRINT("WriteFile() succeeded\n");
82    return(TRUE);
83 }
84
85
86
87 WINBOOL STDCALL ReadFile(HANDLE hFile,
88                          LPVOID lpBuffer,
89                          DWORD nNumberOfBytesToRead,
90                          LPDWORD lpNumberOfBytesRead,
91                          LPOVERLAPPED lpOverLapped)
92 {
93    HANDLE hEvent = NULL;
94    LARGE_INTEGER Offset;
95    NTSTATUS errCode;
96    IO_STATUS_BLOCK IIosb;
97    PIO_STATUS_BLOCK IoStatusBlock;
98    PLARGE_INTEGER ptrOffset;
99    
100    if (IsConsoleHandle(hFile))
101      {
102         return(ReadConsoleA(hFile,
103                             lpBuffer,
104                             nNumberOfBytesToRead,
105                             lpNumberOfBytesRead,
106                             NULL));
107      }
108    
109    if (lpOverLapped != NULL) 
110      {
111         Offset.u.LowPart = lpOverLapped->Offset;
112         Offset.u.HighPart = lpOverLapped->OffsetHigh;
113         lpOverLapped->Internal = STATUS_PENDING;
114         hEvent = lpOverLapped->hEvent;
115         IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
116         ptrOffset = &Offset;
117      }
118    else 
119      {
120         ptrOffset = NULL;
121         IoStatusBlock = &IIosb;
122      }
123    
124    errCode = NtReadFile(hFile,
125                         hEvent,
126                         NULL,
127                         NULL,
128                         IoStatusBlock,
129                         lpBuffer,
130                         nNumberOfBytesToRead,
131                         ptrOffset,
132                         NULL);
133    
134    if (errCode != STATUS_PENDING && lpNumberOfBytesRead != NULL)
135      {
136         *lpNumberOfBytesRead = IoStatusBlock->Information;
137      }
138    
139    if (!NT_SUCCESS(errCode) && errCode != STATUS_END_OF_FILE)  
140      {
141         SetLastErrorByStatus (errCode);
142         return(FALSE);
143      }
144    return(TRUE);
145 }
146
147 VOID STDCALL ApcRoutine(PVOID ApcContext, 
148                 struct _IO_STATUS_BLOCK* IoStatusBlock, 
149                 ULONG NumberOfBytesTransfered)
150 {
151    DWORD dwErrorCode;
152    LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine = 
153      (LPOVERLAPPED_COMPLETION_ROUTINE)ApcContext;
154    
155    dwErrorCode = RtlNtStatusToDosError(IoStatusBlock->Status);
156    lpCompletionRoutine(dwErrorCode, 
157                        NumberOfBytesTransfered, 
158                        (LPOVERLAPPED)IoStatusBlock);
159 }
160
161
162 WINBOOL STDCALL 
163 WriteFileEx (HANDLE                             hFile,
164              LPCVOID                            lpBuffer,
165              DWORD                              nNumberOfBytesToWrite,
166              LPOVERLAPPED                       lpOverLapped,
167              LPOVERLAPPED_COMPLETION_ROUTINE    lpCompletionRoutine)
168 {
169
170    LARGE_INTEGER Offset;
171    NTSTATUS errCode;
172    PIO_STATUS_BLOCK IoStatusBlock;
173    PLARGE_INTEGER ptrOffset;
174    
175    DPRINT("WriteFileEx(hFile %x)\n",hFile);
176    
177    if (lpOverLapped == NULL) 
178         return FALSE;
179
180    Offset.u.LowPart = lpOverLapped->Offset;
181    Offset.u.HighPart = lpOverLapped->OffsetHigh;
182    lpOverLapped->Internal = STATUS_PENDING;
183    IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
184    ptrOffset = &Offset;
185
186    errCode = NtWriteFile(hFile,
187                          NULL,
188                          ApcRoutine,
189                          lpCompletionRoutine,
190                          IoStatusBlock,
191                          (PVOID)lpBuffer, 
192                          nNumberOfBytesToWrite,
193                          ptrOffset,
194                          NULL);
195    if (!NT_SUCCESS(errCode))
196      {
197         SetLastErrorByStatus (errCode);
198         DPRINT("WriteFileEx() failed\n");
199         return FALSE;
200      }
201   
202    DPRINT("WriteFileEx() succeeded\n");
203    return(TRUE);
204 }
205
206 WINBOOL STDCALL ReadFileEx(HANDLE hFile,
207                            LPVOID lpBuffer,
208                            DWORD nNumberOfBytesToRead,
209                            LPOVERLAPPED lpOverLapped,
210                            LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
211 {
212    LARGE_INTEGER Offset;
213    NTSTATUS errCode;
214    PIO_STATUS_BLOCK IoStatusBlock;
215    PLARGE_INTEGER ptrOffset;
216    
217    if (lpOverLapped == NULL) 
218         return FALSE;
219
220    Offset.u.LowPart = lpOverLapped->Offset;
221    Offset.u.HighPart = lpOverLapped->OffsetHigh;
222    lpOverLapped->Internal = STATUS_PENDING;
223    IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
224    ptrOffset = &Offset;
225
226    errCode = NtReadFile(hFile,
227                         NULL,
228                         ApcRoutine,
229                         lpCompletionRoutine,
230                         IoStatusBlock,
231                         lpBuffer,
232                         nNumberOfBytesToRead,
233                         ptrOffset,
234                         NULL);
235
236    if (!NT_SUCCESS(errCode))  
237      {
238         SetLastErrorByStatus (errCode);
239         return(FALSE);
240      }
241    return(TRUE);
242 }
243
244 /* EOF */