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)
12 /* INCLUDES ****************************************************************/
15 #include <wine/debug.h>
17 WINE_DEFAULT_DEBUG_CHANNEL(kernel32file
);
19 /* FUNCTIONS ****************************************************************/
25 WriteFile(IN HANDLE hFile
,
27 IN DWORD nNumberOfBytesToWrite OPTIONAL
,
28 OUT LPDWORD lpNumberOfBytesWritten OPTIONAL
,
29 IN LPOVERLAPPED lpOverlapped OPTIONAL
)
33 TRACE("WriteFile(hFile %x)\n", hFile
);
35 if (lpNumberOfBytesWritten
!= NULL
)
37 *lpNumberOfBytesWritten
= 0;
40 hFile
= TranslateStdHandle(hFile
);
42 if (IsConsoleHandle(hFile
))
44 return WriteConsoleA(hFile
,
46 nNumberOfBytesToWrite
,
47 lpNumberOfBytesWritten
,
51 if (lpOverlapped
!= NULL
)
56 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
57 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
58 lpOverlapped
->Internal
= STATUS_PENDING
;
59 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
61 Status
= NtWriteFile(hFile
,
65 (PIO_STATUS_BLOCK
)lpOverlapped
,
67 nNumberOfBytesToWrite
,
71 /* return FALSE in case of failure and pending operations! */
72 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
74 SetLastErrorByStatus(Status
);
78 if (lpNumberOfBytesWritten
!= NULL
)
80 *lpNumberOfBytesWritten
= lpOverlapped
->InternalHigh
;
87 Status
= NtWriteFile(hFile
,
93 nNumberOfBytesToWrite
,
97 /* wait in case operation is pending */
98 if (Status
== STATUS_PENDING
)
100 Status
= NtWaitForSingleObject(hFile
,
103 if (NT_SUCCESS(Status
))
105 Status
= Iosb
.Status
;
109 if (NT_SUCCESS(Status
))
111 /* lpNumberOfBytesWritten must not be NULL here, in fact Win doesn't
112 check that case either and crashes (only after the operation
114 *lpNumberOfBytesWritten
= Iosb
.Information
;
118 SetLastErrorByStatus(Status
);
123 TRACE("WriteFile() succeeded\n");
132 ReadFile(IN HANDLE hFile
,
134 IN DWORD nNumberOfBytesToRead
,
135 OUT LPDWORD lpNumberOfBytesRead OPTIONAL
,
136 IN LPOVERLAPPED lpOverlapped OPTIONAL
)
140 TRACE("ReadFile(hFile %x)\n", hFile
);
142 if (lpNumberOfBytesRead
!= NULL
)
144 *lpNumberOfBytesRead
= 0;
147 if (!nNumberOfBytesToRead
)
152 hFile
= TranslateStdHandle(hFile
);
154 if (IsConsoleHandle(hFile
))
156 if (ReadConsoleA(hFile
,
158 nNumberOfBytesToRead
,
163 GetConsoleMode(hFile
, &dwMode
);
164 if ((dwMode
& ENABLE_PROCESSED_INPUT
) && *(char *)lpBuffer
== 0x1a)
166 /* EOF character entered; simulate end-of-file */
167 *lpNumberOfBytesRead
= 0;
174 if (lpOverlapped
!= NULL
)
176 LARGE_INTEGER Offset
;
179 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
180 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
181 lpOverlapped
->Internal
= STATUS_PENDING
;
182 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
184 Status
= NtReadFile(hFile
,
185 lpOverlapped
->hEvent
,
188 (PIO_STATUS_BLOCK
)lpOverlapped
,
190 nNumberOfBytesToRead
,
194 /* return FALSE in case of failure and pending operations! */
195 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
197 if (Status
== STATUS_END_OF_FILE
&&
198 lpNumberOfBytesRead
!= NULL
)
200 *lpNumberOfBytesRead
= 0;
203 SetLastErrorByStatus(Status
);
207 if (lpNumberOfBytesRead
!= NULL
)
209 *lpNumberOfBytesRead
= lpOverlapped
->InternalHigh
;
214 IO_STATUS_BLOCK Iosb
;
216 Status
= NtReadFile(hFile
,
222 nNumberOfBytesToRead
,
226 /* wait in case operation is pending */
227 if (Status
== STATUS_PENDING
)
229 Status
= NtWaitForSingleObject(hFile
,
232 if (NT_SUCCESS(Status
))
234 Status
= Iosb
.Status
;
238 if (Status
== STATUS_END_OF_FILE
)
240 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
241 check that case either and crashes (only after the operation
243 *lpNumberOfBytesRead
= 0;
247 if (NT_SUCCESS(Status
))
249 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
250 check that case either and crashes (only after the operation
252 *lpNumberOfBytesRead
= Iosb
.Information
;
256 SetLastErrorByStatus(Status
);
261 TRACE("ReadFile() succeeded\n");
266 ApcRoutine(PVOID ApcContext
,
267 struct _IO_STATUS_BLOCK
* IoStatusBlock
,
271 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
=
272 (LPOVERLAPPED_COMPLETION_ROUTINE
)ApcContext
;
274 dwErrorCode
= RtlNtStatusToDosError(IoStatusBlock
->Status
);
275 lpCompletionRoutine(dwErrorCode
,
276 IoStatusBlock
->Information
,
277 (LPOVERLAPPED
)IoStatusBlock
);
285 WriteFileEx(IN HANDLE hFile
,
287 IN DWORD nNumberOfBytesToWrite OPTIONAL
,
288 IN LPOVERLAPPED lpOverlapped
,
289 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
291 LARGE_INTEGER Offset
;
294 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
295 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
296 lpOverlapped
->Internal
= STATUS_PENDING
;
298 Status
= NtWriteFile(hFile
,
302 (PIO_STATUS_BLOCK
)lpOverlapped
,
304 nNumberOfBytesToWrite
,
308 if (!NT_SUCCESS(Status
))
310 SetLastErrorByStatus(Status
);
322 ReadFileEx(IN HANDLE hFile
,
324 IN DWORD nNumberOfBytesToRead OPTIONAL
,
325 IN LPOVERLAPPED lpOverlapped
,
326 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
328 LARGE_INTEGER Offset
;
331 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
332 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
333 lpOverlapped
->Internal
= STATUS_PENDING
;
335 Status
= NtReadFile(hFile
,
339 (PIO_STATUS_BLOCK
)lpOverlapped
,
341 nNumberOfBytesToRead
,
345 if (!NT_SUCCESS(Status
))
347 SetLastErrorByStatus(Status
);