2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/file/rw.c
5 * PURPOSE: Read/write functions
6 * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
11 /* INCLUDES ****************************************************************/
16 DEBUG_CHANNEL(kernel32file
);
18 /* FUNCTIONS ****************************************************************/
24 WriteFile(IN HANDLE hFile
,
26 IN DWORD nNumberOfBytesToWrite OPTIONAL
,
27 OUT LPDWORD lpNumberOfBytesWritten OPTIONAL
,
28 IN LPOVERLAPPED lpOverlapped OPTIONAL
)
32 TRACE("WriteFile(hFile %p)\n", hFile
);
34 if (lpNumberOfBytesWritten
!= NULL
) *lpNumberOfBytesWritten
= 0;
36 hFile
= TranslateStdHandle(hFile
);
38 if (IsConsoleHandle(hFile
))
40 return WriteConsoleA(hFile
,
42 nNumberOfBytesToWrite
,
43 lpNumberOfBytesWritten
,
47 if (lpOverlapped
!= NULL
)
52 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
53 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
54 lpOverlapped
->Internal
= STATUS_PENDING
;
55 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
57 Status
= NtWriteFile(hFile
,
61 (PIO_STATUS_BLOCK
)lpOverlapped
,
63 nNumberOfBytesToWrite
,
67 /* return FALSE in case of failure and pending operations! */
68 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
70 BaseSetLastNTError(Status
);
74 if (lpNumberOfBytesWritten
!= NULL
)
75 *lpNumberOfBytesWritten
= lpOverlapped
->InternalHigh
;
81 Status
= NtWriteFile(hFile
,
87 nNumberOfBytesToWrite
,
91 /* Wait in case operation is pending */
92 if (Status
== STATUS_PENDING
)
94 Status
= NtWaitForSingleObject(hFile
, FALSE
, NULL
);
95 if (NT_SUCCESS(Status
)) Status
= Iosb
.Status
;
98 if (NT_SUCCESS(Status
))
101 * lpNumberOfBytesWritten must not be NULL here, in fact Win doesn't
102 * check that case either and crashes (only after the operation
105 *lpNumberOfBytesWritten
= Iosb
.Information
;
109 BaseSetLastNTError(Status
);
114 TRACE("WriteFile() succeeded\n");
123 ReadFile(IN HANDLE hFile
,
125 IN DWORD nNumberOfBytesToRead
,
126 OUT LPDWORD lpNumberOfBytesRead OPTIONAL
,
127 IN LPOVERLAPPED lpOverlapped OPTIONAL
)
131 TRACE("ReadFile(hFile %p)\n", hFile
);
133 if (lpNumberOfBytesRead
!= NULL
) *lpNumberOfBytesRead
= 0;
135 hFile
= TranslateStdHandle(hFile
);
137 if (IsConsoleHandle(hFile
))
139 if (ReadConsoleA(hFile
,
141 nNumberOfBytesToRead
,
146 GetConsoleMode(hFile
, &dwMode
);
147 if ((dwMode
& ENABLE_PROCESSED_INPUT
) && *(PCHAR
)lpBuffer
== 0x1a)
149 /* EOF character entered; simulate end-of-file */
150 *lpNumberOfBytesRead
= 0;
157 if (lpOverlapped
!= NULL
)
159 LARGE_INTEGER Offset
;
162 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
163 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
164 lpOverlapped
->Internal
= STATUS_PENDING
;
165 ApcContext
= (((ULONG_PTR
)lpOverlapped
->hEvent
& 0x1) ? NULL
: lpOverlapped
);
167 Status
= NtReadFile(hFile
,
168 lpOverlapped
->hEvent
,
171 (PIO_STATUS_BLOCK
)lpOverlapped
,
173 nNumberOfBytesToRead
,
177 /* return FALSE in case of failure and pending operations! */
178 if (!NT_SUCCESS(Status
) || Status
== STATUS_PENDING
)
180 if (Status
== STATUS_END_OF_FILE
&& lpNumberOfBytesRead
!= NULL
)
181 *lpNumberOfBytesRead
= 0;
183 BaseSetLastNTError(Status
);
187 if (lpNumberOfBytesRead
!= NULL
)
188 *lpNumberOfBytesRead
= lpOverlapped
->InternalHigh
;
192 IO_STATUS_BLOCK Iosb
;
194 Status
= NtReadFile(hFile
,
200 nNumberOfBytesToRead
,
204 /* Wait in case operation is pending */
205 if (Status
== STATUS_PENDING
)
207 Status
= NtWaitForSingleObject(hFile
, FALSE
, NULL
);
208 if (NT_SUCCESS(Status
)) Status
= Iosb
.Status
;
211 if (Status
== STATUS_END_OF_FILE
)
214 * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
215 * check that case either and crashes (only after the operation
218 *lpNumberOfBytesRead
= 0;
222 if (NT_SUCCESS(Status
))
225 * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
226 * check that case either and crashes (only after the operation
229 *lpNumberOfBytesRead
= Iosb
.Information
;
233 BaseSetLastNTError(Status
);
238 TRACE("ReadFile() succeeded\n");
243 ApcRoutine(PVOID ApcContext
,
244 PIO_STATUS_BLOCK IoStatusBlock
,
248 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
=
249 (LPOVERLAPPED_COMPLETION_ROUTINE
)ApcContext
;
251 dwErrorCode
= RtlNtStatusToDosError(IoStatusBlock
->Status
);
252 lpCompletionRoutine(dwErrorCode
,
253 IoStatusBlock
->Information
,
254 (LPOVERLAPPED
)IoStatusBlock
);
262 WriteFileEx(IN HANDLE hFile
,
264 IN DWORD nNumberOfBytesToWrite OPTIONAL
,
265 IN LPOVERLAPPED lpOverlapped
,
266 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
268 LARGE_INTEGER Offset
;
271 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
272 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
273 lpOverlapped
->Internal
= STATUS_PENDING
;
275 Status
= NtWriteFile(hFile
,
279 (PIO_STATUS_BLOCK
)lpOverlapped
,
281 nNumberOfBytesToWrite
,
285 if (!NT_SUCCESS(Status
))
287 BaseSetLastNTError(Status
);
299 ReadFileEx(IN HANDLE hFile
,
301 IN DWORD nNumberOfBytesToRead OPTIONAL
,
302 IN LPOVERLAPPED lpOverlapped
,
303 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
305 LARGE_INTEGER Offset
;
308 Offset
.u
.LowPart
= lpOverlapped
->Offset
;
309 Offset
.u
.HighPart
= lpOverlapped
->OffsetHigh
;
310 lpOverlapped
->Internal
= STATUS_PENDING
;
312 Status
= NtReadFile(hFile
,
316 (PIO_STATUS_BLOCK
)lpOverlapped
,
318 nNumberOfBytesToRead
,
322 if (!NT_SUCCESS(Status
))
324 BaseSetLastNTError(Status
);
337 ReadFileScatter(HANDLE hFile
,
338 FILE_SEGMENT_ELEMENT aSegmentArray
[],
339 DWORD nNumberOfBytesToRead
,
341 LPOVERLAPPED lpOverlapped
)
343 PIO_STATUS_BLOCK pIOStatus
;
344 LARGE_INTEGER Offset
;
347 DPRINT("(%p %p %u %p)\n", hFile
, aSegmentArray
, nNumberOfBytesToRead
, lpOverlapped
);
349 Offset
.LowPart
= lpOverlapped
->Offset
;
350 Offset
.HighPart
= lpOverlapped
->OffsetHigh
;
351 pIOStatus
= (PIO_STATUS_BLOCK
) lpOverlapped
;
352 pIOStatus
->Status
= STATUS_PENDING
;
353 pIOStatus
->Information
= 0;
355 Status
= NtReadFileScatter(hFile
,
361 nNumberOfBytesToRead
,
365 if (!NT_SUCCESS(Status
))
367 SetLastError(RtlNtStatusToDosError(Status
));
379 WriteFileGather(HANDLE hFile
,
380 FILE_SEGMENT_ELEMENT aSegmentArray
[],
381 DWORD nNumberOfBytesToWrite
,
383 LPOVERLAPPED lpOverlapped
)
385 PIO_STATUS_BLOCK IOStatus
;
386 LARGE_INTEGER Offset
;
389 DPRINT("%p %p %u %p\n", hFile
, aSegmentArray
, nNumberOfBytesToWrite
, lpOverlapped
);
391 Offset
.LowPart
= lpOverlapped
->Offset
;
392 Offset
.HighPart
= lpOverlapped
->OffsetHigh
;
393 IOStatus
= (PIO_STATUS_BLOCK
) lpOverlapped
;
394 IOStatus
->Status
= STATUS_PENDING
;
395 IOStatus
->Information
= 0;
397 Status
= NtWriteFileGather(hFile
,
403 nNumberOfBytesToWrite
,
407 if (!NT_SUCCESS(Status
))
409 SetLastError(RtlNtStatusToDosError(Status
));