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((ULONG_PTR
)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 hFile
= TranslateStdHandle(hFile
);
149 if (IsConsoleHandle(hFile
))
151 if (ReadConsoleA(hFile
,
153 nNumberOfBytesToRead
,
158 GetConsoleMode(hFile
, &dwMode
);
159 if ((dwMode
& ENABLE_PROCESSED_INPUT
) && *(char *)lpBuffer
== 0x1a)
161 /* EOF character entered; simulate end-of-file */
162 *lpNumberOfBytesRead
= 0;
169 if (lpOverlapped
!= NULL
)
171 LARGE_INTEGER Offset
;
174 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
175 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
176 lpOverlapped
->Internal
= STATUS_PENDING
;
177 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
179 Status
= NtReadFile(hFile
,
180 lpOverlapped
->hEvent
,
183 (PIO_STATUS_BLOCK
)lpOverlapped
,
185 nNumberOfBytesToRead
,
189 /* return FALSE in case of failure and pending operations! */
190 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
192 if (Status
== STATUS_END_OF_FILE
&&
193 lpNumberOfBytesRead
!= NULL
)
195 *lpNumberOfBytesRead
= 0;
198 SetLastErrorByStatus(Status
);
202 if (lpNumberOfBytesRead
!= NULL
)
204 *lpNumberOfBytesRead
= lpOverlapped
->InternalHigh
;
209 IO_STATUS_BLOCK Iosb
;
211 Status
= NtReadFile(hFile
,
217 nNumberOfBytesToRead
,
221 /* wait in case operation is pending */
222 if (Status
== STATUS_PENDING
)
224 Status
= NtWaitForSingleObject(hFile
,
227 if (NT_SUCCESS(Status
))
229 Status
= Iosb
.Status
;
233 if (Status
== STATUS_END_OF_FILE
)
235 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
236 check that case either and crashes (only after the operation
238 *lpNumberOfBytesRead
= 0;
242 if (NT_SUCCESS(Status
))
244 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
245 check that case either and crashes (only after the operation
247 *lpNumberOfBytesRead
= Iosb
.Information
;
251 SetLastErrorByStatus(Status
);
256 TRACE("ReadFile() succeeded\n");
261 ApcRoutine(PVOID ApcContext
,
262 struct _IO_STATUS_BLOCK
* IoStatusBlock
,
266 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
=
267 (LPOVERLAPPED_COMPLETION_ROUTINE
)ApcContext
;
269 dwErrorCode
= RtlNtStatusToDosError(IoStatusBlock
->Status
);
270 lpCompletionRoutine(dwErrorCode
,
271 IoStatusBlock
->Information
,
272 (LPOVERLAPPED
)IoStatusBlock
);
280 WriteFileEx(IN HANDLE hFile
,
282 IN DWORD nNumberOfBytesToWrite OPTIONAL
,
283 IN LPOVERLAPPED lpOverlapped
,
284 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
286 LARGE_INTEGER Offset
;
289 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
290 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
291 lpOverlapped
->Internal
= STATUS_PENDING
;
293 Status
= NtWriteFile(hFile
,
297 (PIO_STATUS_BLOCK
)lpOverlapped
,
299 nNumberOfBytesToWrite
,
303 if (!NT_SUCCESS(Status
))
305 SetLastErrorByStatus(Status
);
317 ReadFileEx(IN HANDLE hFile
,
319 IN DWORD nNumberOfBytesToRead OPTIONAL
,
320 IN LPOVERLAPPED lpOverlapped
,
321 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
323 LARGE_INTEGER Offset
;
326 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
327 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
328 lpOverlapped
->Internal
= STATUS_PENDING
;
330 Status
= NtReadFile(hFile
,
334 (PIO_STATUS_BLOCK
)lpOverlapped
,
336 nNumberOfBytesToRead
,
340 if (!NT_SUCCESS(Status
))
342 SetLastErrorByStatus(Status
);