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 return ReadConsoleA(hFile
,
153 nNumberOfBytesToRead
,
158 if (lpOverlapped
!= NULL
)
160 LARGE_INTEGER Offset
;
163 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
164 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
165 lpOverlapped
->Internal
= STATUS_PENDING
;
166 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
168 Status
= NtReadFile(hFile
,
169 lpOverlapped
->hEvent
,
172 (PIO_STATUS_BLOCK
)lpOverlapped
,
174 nNumberOfBytesToRead
,
178 /* return FALSE in case of failure and pending operations! */
179 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
181 if (Status
== STATUS_END_OF_FILE
&&
182 lpNumberOfBytesRead
!= NULL
)
184 *lpNumberOfBytesRead
= 0;
187 SetLastErrorByStatus(Status
);
191 if (lpNumberOfBytesRead
!= NULL
)
193 *lpNumberOfBytesRead
= lpOverlapped
->InternalHigh
;
198 IO_STATUS_BLOCK Iosb
;
200 Status
= NtReadFile(hFile
,
206 nNumberOfBytesToRead
,
210 /* wait in case operation is pending */
211 if (Status
== STATUS_PENDING
)
213 Status
= NtWaitForSingleObject(hFile
,
216 if (NT_SUCCESS(Status
))
218 Status
= Iosb
.Status
;
222 if (Status
== STATUS_END_OF_FILE
)
224 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
225 check that case either and crashes (only after the operation
227 *lpNumberOfBytesRead
= 0;
231 if (NT_SUCCESS(Status
))
233 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
234 check that case either and crashes (only after the operation
236 *lpNumberOfBytesRead
= Iosb
.Information
;
240 SetLastErrorByStatus(Status
);
245 TRACE("ReadFile() succeeded\n");
250 ApcRoutine(PVOID ApcContext
,
251 struct _IO_STATUS_BLOCK
* IoStatusBlock
,
255 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
=
256 (LPOVERLAPPED_COMPLETION_ROUTINE
)ApcContext
;
258 dwErrorCode
= RtlNtStatusToDosError(IoStatusBlock
->Status
);
259 lpCompletionRoutine(dwErrorCode
,
260 IoStatusBlock
->Information
,
261 (LPOVERLAPPED
)IoStatusBlock
);
269 WriteFileEx(IN HANDLE hFile
,
271 IN DWORD nNumberOfBytesToWrite OPTIONAL
,
272 IN LPOVERLAPPED lpOverlapped
,
273 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
275 LARGE_INTEGER Offset
;
278 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
279 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
280 lpOverlapped
->Internal
= STATUS_PENDING
;
282 Status
= NtWriteFile(hFile
,
286 (PIO_STATUS_BLOCK
)lpOverlapped
,
288 nNumberOfBytesToWrite
,
292 if (!NT_SUCCESS(Status
))
294 SetLastErrorByStatus(Status
);
306 ReadFileEx(IN HANDLE hFile
,
308 IN DWORD nNumberOfBytesToRead OPTIONAL
,
309 IN LPOVERLAPPED lpOverlapped
,
310 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
312 LARGE_INTEGER Offset
;
315 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
316 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
317 lpOverlapped
->Internal
= STATUS_PENDING
;
319 Status
= NtReadFile(hFile
,
323 (PIO_STATUS_BLOCK
)lpOverlapped
,
325 nNumberOfBytesToRead
,
329 if (!NT_SUCCESS(Status
))
331 SetLastErrorByStatus(Status
);