Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrw.c
Go to the documentation of this file.
00001 /* $Id: rw.c 54326 2011-11-07 00:18:13Z ion $ 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS system libraries 00005 * FILE: lib/kernel32/file/rw.c 00006 * PURPOSE: Read/write functions 00007 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) 00008 * UPDATE HISTORY: 00009 * Created 01/11/98 00010 */ 00011 00012 /* INCLUDES ****************************************************************/ 00013 00014 #include <k32.h> 00015 #define NDEBUG 00016 #include <debug.h> 00017 DEBUG_CHANNEL(kernel32file); 00018 00019 /* FUNCTIONS ****************************************************************/ 00020 00021 /* 00022 * @implemented 00023 */ 00024 BOOL WINAPI 00025 WriteFile(IN HANDLE hFile, 00026 IN LPCVOID lpBuffer, 00027 IN DWORD nNumberOfBytesToWrite OPTIONAL, 00028 OUT LPDWORD lpNumberOfBytesWritten OPTIONAL, 00029 IN LPOVERLAPPED lpOverlapped OPTIONAL) 00030 { 00031 NTSTATUS Status; 00032 00033 TRACE("WriteFile(hFile %x)\n", hFile); 00034 00035 if (lpNumberOfBytesWritten != NULL) 00036 { 00037 *lpNumberOfBytesWritten = 0; 00038 } 00039 00040 hFile = TranslateStdHandle(hFile); 00041 00042 if (IsConsoleHandle(hFile)) 00043 { 00044 return WriteConsoleA(hFile, 00045 lpBuffer, 00046 nNumberOfBytesToWrite, 00047 lpNumberOfBytesWritten, 00048 lpOverlapped); 00049 } 00050 00051 if (lpOverlapped != NULL) 00052 { 00053 LARGE_INTEGER Offset; 00054 PVOID ApcContext; 00055 00056 Offset.u.LowPart = lpOverlapped->Offset; 00057 Offset.u.HighPart = lpOverlapped->OffsetHigh; 00058 lpOverlapped->Internal = STATUS_PENDING; 00059 ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped); 00060 00061 Status = NtWriteFile(hFile, 00062 lpOverlapped->hEvent, 00063 NULL, 00064 ApcContext, 00065 (PIO_STATUS_BLOCK)lpOverlapped, 00066 (PVOID)lpBuffer, 00067 nNumberOfBytesToWrite, 00068 &Offset, 00069 NULL); 00070 00071 /* return FALSE in case of failure and pending operations! */ 00072 if (!NT_SUCCESS(Status) || Status == STATUS_PENDING) 00073 { 00074 BaseSetLastNTError(Status); 00075 return FALSE; 00076 } 00077 00078 if (lpNumberOfBytesWritten != NULL) 00079 { 00080 *lpNumberOfBytesWritten = lpOverlapped->InternalHigh; 00081 } 00082 } 00083 else 00084 { 00085 IO_STATUS_BLOCK Iosb; 00086 00087 Status = NtWriteFile(hFile, 00088 NULL, 00089 NULL, 00090 NULL, 00091 &Iosb, 00092 (PVOID)lpBuffer, 00093 nNumberOfBytesToWrite, 00094 NULL, 00095 NULL); 00096 00097 /* wait in case operation is pending */ 00098 if (Status == STATUS_PENDING) 00099 { 00100 Status = NtWaitForSingleObject(hFile, 00101 FALSE, 00102 NULL); 00103 if (NT_SUCCESS(Status)) 00104 { 00105 Status = Iosb.Status; 00106 } 00107 } 00108 00109 if (NT_SUCCESS(Status)) 00110 { 00111 /* lpNumberOfBytesWritten must not be NULL here, in fact Win doesn't 00112 check that case either and crashes (only after the operation 00113 completed) */ 00114 *lpNumberOfBytesWritten = Iosb.Information; 00115 } 00116 else 00117 { 00118 BaseSetLastNTError(Status); 00119 return FALSE; 00120 } 00121 } 00122 00123 TRACE("WriteFile() succeeded\n"); 00124 return TRUE; 00125 } 00126 00127 00128 /* 00129 * @implemented 00130 */ 00131 BOOL WINAPI 00132 ReadFile(IN HANDLE hFile, 00133 IN LPVOID lpBuffer, 00134 IN DWORD nNumberOfBytesToRead, 00135 OUT LPDWORD lpNumberOfBytesRead OPTIONAL, 00136 IN LPOVERLAPPED lpOverlapped OPTIONAL) 00137 { 00138 NTSTATUS Status; 00139 00140 TRACE("ReadFile(hFile %x)\n", hFile); 00141 00142 if (lpNumberOfBytesRead != NULL) 00143 { 00144 *lpNumberOfBytesRead = 0; 00145 } 00146 00147 if (!nNumberOfBytesToRead) 00148 { 00149 return TRUE; 00150 } 00151 00152 hFile = TranslateStdHandle(hFile); 00153 00154 if (IsConsoleHandle(hFile)) 00155 { 00156 if (ReadConsoleA(hFile, 00157 lpBuffer, 00158 nNumberOfBytesToRead, 00159 lpNumberOfBytesRead, 00160 NULL)) 00161 { 00162 DWORD dwMode; 00163 GetConsoleMode(hFile, &dwMode); 00164 if ((dwMode & ENABLE_PROCESSED_INPUT) && *(char *)lpBuffer == 0x1a) 00165 { 00166 /* EOF character entered; simulate end-of-file */ 00167 *lpNumberOfBytesRead = 0; 00168 } 00169 return TRUE; 00170 } 00171 return FALSE; 00172 } 00173 00174 if (lpOverlapped != NULL) 00175 { 00176 LARGE_INTEGER Offset; 00177 PVOID ApcContext; 00178 00179 Offset.u.LowPart = lpOverlapped->Offset; 00180 Offset.u.HighPart = lpOverlapped->OffsetHigh; 00181 lpOverlapped->Internal = STATUS_PENDING; 00182 ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped); 00183 00184 Status = NtReadFile(hFile, 00185 lpOverlapped->hEvent, 00186 NULL, 00187 ApcContext, 00188 (PIO_STATUS_BLOCK)lpOverlapped, 00189 lpBuffer, 00190 nNumberOfBytesToRead, 00191 &Offset, 00192 NULL); 00193 00194 /* return FALSE in case of failure and pending operations! */ 00195 if (!NT_SUCCESS(Status) || Status == STATUS_PENDING) 00196 { 00197 if (Status == STATUS_END_OF_FILE && 00198 lpNumberOfBytesRead != NULL) 00199 { 00200 *lpNumberOfBytesRead = 0; 00201 } 00202 00203 BaseSetLastNTError(Status); 00204 return FALSE; 00205 } 00206 00207 if (lpNumberOfBytesRead != NULL) 00208 { 00209 *lpNumberOfBytesRead = lpOverlapped->InternalHigh; 00210 } 00211 } 00212 else 00213 { 00214 IO_STATUS_BLOCK Iosb; 00215 00216 Status = NtReadFile(hFile, 00217 NULL, 00218 NULL, 00219 NULL, 00220 &Iosb, 00221 lpBuffer, 00222 nNumberOfBytesToRead, 00223 NULL, 00224 NULL); 00225 00226 /* wait in case operation is pending */ 00227 if (Status == STATUS_PENDING) 00228 { 00229 Status = NtWaitForSingleObject(hFile, 00230 FALSE, 00231 NULL); 00232 if (NT_SUCCESS(Status)) 00233 { 00234 Status = Iosb.Status; 00235 } 00236 } 00237 00238 if (Status == STATUS_END_OF_FILE) 00239 { 00240 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't 00241 check that case either and crashes (only after the operation 00242 completed) */ 00243 *lpNumberOfBytesRead = 0; 00244 return TRUE; 00245 } 00246 00247 if (NT_SUCCESS(Status)) 00248 { 00249 /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't 00250 check that case either and crashes (only after the operation 00251 completed) */ 00252 *lpNumberOfBytesRead = Iosb.Information; 00253 } 00254 else 00255 { 00256 BaseSetLastNTError(Status); 00257 return FALSE; 00258 } 00259 } 00260 00261 TRACE("ReadFile() succeeded\n"); 00262 return TRUE; 00263 } 00264 00265 VOID WINAPI 00266 ApcRoutine(PVOID ApcContext, 00267 struct _IO_STATUS_BLOCK* IoStatusBlock, 00268 ULONG Reserved) 00269 { 00270 DWORD dwErrorCode; 00271 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine = 00272 (LPOVERLAPPED_COMPLETION_ROUTINE)ApcContext; 00273 00274 dwErrorCode = RtlNtStatusToDosError(IoStatusBlock->Status); 00275 lpCompletionRoutine(dwErrorCode, 00276 IoStatusBlock->Information, 00277 (LPOVERLAPPED)IoStatusBlock); 00278 } 00279 00280 00281 /* 00282 * @implemented 00283 */ 00284 BOOL WINAPI 00285 WriteFileEx(IN HANDLE hFile, 00286 IN LPCVOID lpBuffer, 00287 IN DWORD nNumberOfBytesToWrite OPTIONAL, 00288 IN LPOVERLAPPED lpOverlapped, 00289 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) 00290 { 00291 LARGE_INTEGER Offset; 00292 NTSTATUS Status; 00293 00294 Offset.u.LowPart = lpOverlapped->Offset; 00295 Offset.u.HighPart = lpOverlapped->OffsetHigh; 00296 lpOverlapped->Internal = STATUS_PENDING; 00297 00298 Status = NtWriteFile(hFile, 00299 NULL, 00300 ApcRoutine, 00301 lpCompletionRoutine, 00302 (PIO_STATUS_BLOCK)lpOverlapped, 00303 (PVOID)lpBuffer, 00304 nNumberOfBytesToWrite, 00305 &Offset, 00306 NULL); 00307 00308 if (!NT_SUCCESS(Status)) 00309 { 00310 BaseSetLastNTError(Status); 00311 return FALSE; 00312 } 00313 00314 return TRUE; 00315 } 00316 00317 00318 /* 00319 * @implemented 00320 */ 00321 BOOL WINAPI 00322 ReadFileEx(IN HANDLE hFile, 00323 IN LPVOID lpBuffer, 00324 IN DWORD nNumberOfBytesToRead OPTIONAL, 00325 IN LPOVERLAPPED lpOverlapped, 00326 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) 00327 { 00328 LARGE_INTEGER Offset; 00329 NTSTATUS Status; 00330 00331 Offset.u.LowPart = lpOverlapped->Offset; 00332 Offset.u.HighPart = lpOverlapped->OffsetHigh; 00333 lpOverlapped->Internal = STATUS_PENDING; 00334 00335 Status = NtReadFile(hFile, 00336 NULL, 00337 ApcRoutine, 00338 lpCompletionRoutine, 00339 (PIO_STATUS_BLOCK)lpOverlapped, 00340 lpBuffer, 00341 nNumberOfBytesToRead, 00342 &Offset, 00343 NULL); 00344 00345 if (!NT_SUCCESS(Status)) 00346 { 00347 BaseSetLastNTError(Status); 00348 return FALSE; 00349 } 00350 00351 return TRUE; 00352 } 00353 00354 00355 /* 00356 * @implemented 00357 */ 00358 BOOL 00359 WINAPI 00360 ReadFileScatter(HANDLE hFile, 00361 FILE_SEGMENT_ELEMENT aSegmentArray[], 00362 DWORD nNumberOfBytesToRead, 00363 LPDWORD lpReserved, 00364 LPOVERLAPPED lpOverlapped) 00365 { 00366 PIO_STATUS_BLOCK pIOStatus; 00367 LARGE_INTEGER Offset; 00368 NTSTATUS Status; 00369 00370 DPRINT("(%p %p %u %p)\n", hFile, aSegmentArray, nNumberOfBytesToRead, lpOverlapped); 00371 00372 Offset.LowPart = lpOverlapped->Offset; 00373 Offset.HighPart = lpOverlapped->OffsetHigh; 00374 pIOStatus = (PIO_STATUS_BLOCK) lpOverlapped; 00375 pIOStatus->Status = STATUS_PENDING; 00376 pIOStatus->Information = 0; 00377 00378 Status = NtReadFileScatter(hFile, 00379 NULL, 00380 NULL, 00381 NULL, 00382 pIOStatus, 00383 aSegmentArray, 00384 nNumberOfBytesToRead, 00385 &Offset, 00386 NULL); 00387 00388 if (!NT_SUCCESS(Status)) 00389 { 00390 SetLastError(RtlNtStatusToDosError(Status)); 00391 return FALSE; 00392 } 00393 00394 return TRUE; 00395 } 00396 00397 /* 00398 * @implemented 00399 */ 00400 BOOL 00401 WINAPI 00402 WriteFileGather(HANDLE hFile, 00403 FILE_SEGMENT_ELEMENT aSegmentArray[], 00404 DWORD nNumberOfBytesToWrite, 00405 LPDWORD lpReserved, 00406 LPOVERLAPPED lpOverlapped) 00407 { 00408 PIO_STATUS_BLOCK IOStatus; 00409 LARGE_INTEGER Offset; 00410 NTSTATUS Status; 00411 00412 DPRINT("%p %p %u %p\n", hFile, aSegmentArray, nNumberOfBytesToWrite, lpOverlapped); 00413 00414 Offset.LowPart = lpOverlapped->Offset; 00415 Offset.HighPart = lpOverlapped->OffsetHigh; 00416 IOStatus = (PIO_STATUS_BLOCK) lpOverlapped; 00417 IOStatus->Status = STATUS_PENDING; 00418 IOStatus->Information = 0; 00419 00420 Status = NtWriteFileGather(hFile, 00421 NULL, 00422 NULL, 00423 NULL, 00424 IOStatus, 00425 aSegmentArray, 00426 nNumberOfBytesToWrite, 00427 &Offset, 00428 NULL); 00429 00430 if (!NT_SUCCESS(Status)) 00431 { 00432 SetLastError(RtlNtStatusToDosError(Status)); 00433 return FALSE; 00434 } 00435 00436 return TRUE; 00437 } 00438 00439 /* EOF */ Generated on Sun May 27 2012 04:24:27 for ReactOS by
1.7.6.1
|