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