ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

rw.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.