ReactOS  0.4.14-dev-583-g2a1ba2c
rw.c
Go to the documentation of this file.
1 /*
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)
7  * UPDATE HISTORY:
8  * Created 01/11/98
9  */
10 
11 /* INCLUDES ****************************************************************/
12 
13 #include <k32.h>
14 #define NDEBUG
15 #include <debug.h>
17 
18 /* FUNCTIONS ****************************************************************/
19 
20 /*
21  * @implemented
22  */
27  OUT LPDWORD lpNumberOfBytesWritten,
29 {
31 
32  TRACE("WriteFile(hFile %p)\n", hFile);
33 
34  if (lpNumberOfBytesWritten != NULL) *lpNumberOfBytesWritten = 0;
35 
37 
39  {
40  return WriteConsoleA(hFile,
41  lpBuffer,
43  lpNumberOfBytesWritten,
44  lpOverlapped);
45  }
46 
47  if (lpOverlapped != NULL)
48  {
51 
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);
56 
58  lpOverlapped->hEvent,
59  NULL,
60  ApcContext,
62  (PVOID)lpBuffer,
64  &Offset,
65  NULL);
66 
67  /* return FALSE in case of failure and pending operations! */
69  {
71  return FALSE;
72  }
73 
74  if (lpNumberOfBytesWritten != NULL)
75  *lpNumberOfBytesWritten = lpOverlapped->InternalHigh;
76  }
77  else
78  {
80 
82  NULL,
83  NULL,
84  NULL,
85  &Iosb,
86  (PVOID)lpBuffer,
88  NULL,
89  NULL);
90 
91  /* Wait in case operation is pending */
92  if (Status == STATUS_PENDING)
93  {
95  if (NT_SUCCESS(Status)) Status = Iosb.Status;
96  }
97 
98  if (NT_SUCCESS(Status))
99  {
100  /*
101  * lpNumberOfBytesWritten must not be NULL here, in fact Win doesn't
102  * check that case either and crashes (only after the operation
103  * completed).
104  */
105  *lpNumberOfBytesWritten = Iosb.Information;
106  }
107  else
108  {
110  return FALSE;
111  }
112  }
113 
114  TRACE("WriteFile() succeeded\n");
115  return TRUE;
116 }
117 
118 
119 /*
120  * @implemented
121  */
122 BOOL WINAPI
125  IN DWORD nNumberOfBytesToRead,
126  OUT LPDWORD lpNumberOfBytesRead OPTIONAL,
128 {
130 
131  TRACE("ReadFile(hFile %p)\n", hFile);
132 
133  if (lpNumberOfBytesRead != NULL) *lpNumberOfBytesRead = 0;
134 
136 
137  if (IsConsoleHandle(hFile))
138  {
139  if (ReadConsoleA(hFile,
140  lpBuffer,
141  nNumberOfBytesToRead,
142  lpNumberOfBytesRead,
143  NULL))
144  {
145  DWORD dwMode;
146  GetConsoleMode(hFile, &dwMode);
147  if ((dwMode & ENABLE_PROCESSED_INPUT) && *(PCHAR)lpBuffer == 0x1a)
148  {
149  /* EOF character entered; simulate end-of-file */
150  *lpNumberOfBytesRead = 0;
151  }
152  return TRUE;
153  }
154  return FALSE;
155  }
156 
157  if (lpOverlapped != NULL)
158  {
161 
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);
166 
168  lpOverlapped->hEvent,
169  NULL,
170  ApcContext,
172  lpBuffer,
173  nNumberOfBytesToRead,
174  &Offset,
175  NULL);
176 
177  /* return FALSE in case of failure and pending operations! */
179  {
180  if (Status == STATUS_END_OF_FILE && lpNumberOfBytesRead != NULL)
181  *lpNumberOfBytesRead = 0;
182 
184  return FALSE;
185  }
186 
187  if (lpNumberOfBytesRead != NULL)
188  *lpNumberOfBytesRead = lpOverlapped->InternalHigh;
189  }
190  else
191  {
193 
195  NULL,
196  NULL,
197  NULL,
198  &Iosb,
199  lpBuffer,
200  nNumberOfBytesToRead,
201  NULL,
202  NULL);
203 
204  /* Wait in case operation is pending */
205  if (Status == STATUS_PENDING)
206  {
208  if (NT_SUCCESS(Status)) Status = Iosb.Status;
209  }
210 
211  if (Status == STATUS_END_OF_FILE)
212  {
213  /*
214  * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
215  * check that case either and crashes (only after the operation
216  * completed).
217  */
218  *lpNumberOfBytesRead = 0;
219  return TRUE;
220  }
221 
222  if (NT_SUCCESS(Status))
223  {
224  /*
225  * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't
226  * check that case either and crashes (only after the operation
227  * completed).
228  */
229  *lpNumberOfBytesRead = Iosb.Information;
230  }
231  else
232  {
234  return FALSE;
235  }
236  }
237 
238  TRACE("ReadFile() succeeded\n");
239  return TRUE;
240 }
241 
242 VOID WINAPI
245  ULONG Reserved)
246 {
247  DWORD dwErrorCode;
248  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine =
250 
252  lpCompletionRoutine(dwErrorCode,
255 }
256 
257 
258 /*
259  * @implemented
260  */
261 BOOL WINAPI
266  IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
267 {
270 
271  Offset.u.LowPart = lpOverlapped->Offset;
272  Offset.u.HighPart = lpOverlapped->OffsetHigh;
273  lpOverlapped->Internal = STATUS_PENDING;
274 
276  NULL,
277  ApcRoutine,
278  lpCompletionRoutine,
280  (PVOID)lpBuffer,
282  &Offset,
283  NULL);
284 
285  if (!NT_SUCCESS(Status))
286  {
288  return FALSE;
289  }
290 
291  return TRUE;
292 }
293 
294 
295 /*
296  * @implemented
297  */
298 BOOL WINAPI
301  IN DWORD nNumberOfBytesToRead OPTIONAL,
303  IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
304 {
307 
308  Offset.u.LowPart = lpOverlapped->Offset;
309  Offset.u.HighPart = lpOverlapped->OffsetHigh;
310  lpOverlapped->Internal = STATUS_PENDING;
311 
313  NULL,
314  ApcRoutine,
315  lpCompletionRoutine,
317  lpBuffer,
318  nNumberOfBytesToRead,
319  &Offset,
320  NULL);
321 
322  if (!NT_SUCCESS(Status))
323  {
325  return FALSE;
326  }
327 
328  return TRUE;
329 }
330 
331 
332 /*
333  * @implemented
334  */
335 BOOL
336 WINAPI
338  FILE_SEGMENT_ELEMENT aSegmentArray[],
339  DWORD nNumberOfBytesToRead,
340  LPDWORD lpReserved,
342 {
343  PIO_STATUS_BLOCK pIOStatus;
346 
347  DPRINT("(%p %p %u %p)\n", hFile, aSegmentArray, nNumberOfBytesToRead, lpOverlapped);
348 
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;
354 
356  NULL,
357  NULL,
358  NULL,
359  pIOStatus,
360  aSegmentArray,
361  nNumberOfBytesToRead,
362  &Offset,
363  NULL);
364 
365  if (!NT_SUCCESS(Status))
366  {
368  return FALSE;
369  }
370 
371  return TRUE;
372 }
373 
374 /*
375  * @implemented
376  */
377 BOOL
378 WINAPI
380  FILE_SEGMENT_ELEMENT aSegmentArray[],
382  LPDWORD lpReserved,
384 {
385  PIO_STATUS_BLOCK IOStatus;
388 
389  DPRINT("%p %p %u %p\n", hFile, aSegmentArray, nNumberOfBytesToWrite, lpOverlapped);
390 
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;
396 
398  NULL,
399  NULL,
400  NULL,
401  IOStatus,
402  aSegmentArray,
404  &Offset,
405  NULL);
406 
407  if (!NT_SUCCESS(Status))
408  {
410  return FALSE;
411  }
412 
413  return TRUE;
414 }
415 
416 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define IN
Definition: typedefs.h:38
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:719
#define TRUE
Definition: types.h:120
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
BOOL WINAPI GetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode)
Definition: console.c:1571
LONG NTSTATUS
Definition: precomp.h:26
HANDLE TranslateStdHandle(IN HANDLE hHandle)
Definition: handle.c:19
#define STATUS_END_OF_FILE
Definition: shellext.h:67
DEBUG_CHANNEL(kernel32file)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
BOOL WINAPI ReadFileEx(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: rw.c:299
NTSTATUS NTAPI NtReadFileScatter(IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK UserIoStatusBlock, IN FILE_SEGMENT_ELEMENT BufferDescription [], IN ULONG BufferLength, IN PLARGE_INTEGER ByteOffset, IN PULONG Key OPTIONAL)
Definition: iofunc.c:3009
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleA(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1470
unsigned int BOOL
Definition: ntddk_ex.h:94
#define kernel32file
Definition: kernel32.h:6
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
VOID WINAPI ApcRoutine(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
Definition: rw.c:243
#define TRACE(s)
Definition: solgame.cpp:4
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleA(IN HANDLE hConsoleInput, OUT LPVOID lpBuffer, IN DWORD nNumberOfCharsToRead, OUT LPDWORD lpNumberOfCharsRead, IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
Definition: readwrite.c:1197
#define SetLastError(x)
Definition: compat.h:417
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
#define IsConsoleHandle(h)
Definition: console.h:14
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
_In_ HANDLE hFile
Definition: mswsock.h:90
void(CALLBACK * LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD, DWORD, LPOVERLAPPED)
Definition: winbase.h:1411
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:75
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
NTSTATUS NTAPI NtWriteFileGather(IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK UserIoStatusBlock, IN FILE_SEGMENT_ELEMENT BufferDescription [], IN ULONG BufferLength, IN PLARGE_INTEGER ByteOffset, IN PULONG Key OPTIONAL)
Definition: iofunc.c:4065
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
CONST void * LPCVOID
Definition: windef.h:191
#define OUT
Definition: typedefs.h:39
uint32_t * LPDWORD
Definition: typedefs.h:57
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
BOOL WINAPI ReadFileScatter(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[], DWORD nNumberOfBytesToRead, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
Definition: rw.c:337
_In_ HANDLE _In_ DWORD nNumberOfBytesToWrite
Definition: mswsock.h:90
BOOL WINAPI WriteFileEx(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: rw.c:262
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
BOOL WINAPI WriteFileGather(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[], DWORD nNumberOfBytesToWrite, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
Definition: rw.c:379
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)