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

iocompl.c
Go to the documentation of this file.
00001 /* $Id: iocompl.c 55793 2012-02-21 21:31:01Z ion $
00002  *
00003  * COPYRIGHT:       See COPYING in the top level directory
00004  * PROJECT:         ReactOS system libraries
00005  * FILE:            lib/kernel32/file/iocompl.c
00006  * PURPOSE:         Io Completion functions
00007  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
00008  * UPDATE HISTORY:
00009  *                  Created 01/11/98
00010  */
00011 
00012 #include <k32.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /*
00017  * @implemented
00018  */
00019 HANDLE
00020 WINAPI
00021 CreateIoCompletionPort(IN HANDLE FileHandle,
00022                        IN HANDLE ExistingCompletionPort,
00023                        IN ULONG_PTR CompletionKey,
00024                        IN DWORD NumberOfConcurrentThreads)
00025 {
00026     NTSTATUS Status;
00027     HANDLE NewPort;
00028     FILE_COMPLETION_INFORMATION CompletionInformation;
00029     IO_STATUS_BLOCK IoStatusBlock;
00030 
00031     /* Check if this is a new port */
00032     NewPort = ExistingCompletionPort;
00033     if (!ExistingCompletionPort)
00034     {
00035         /* Create it */
00036         Status = NtCreateIoCompletion(&NewPort,
00037                                       IO_COMPLETION_ALL_ACCESS,
00038                                       NULL,
00039                                       NumberOfConcurrentThreads);
00040         if (!NT_SUCCESS(Status))
00041         {
00042             /* Convert error and fail */
00043             BaseSetLastNTError(Status);
00044             return FALSE;
00045         }
00046     }
00047 
00048     /* Check if no actual file is being associated with the completion port */
00049     if (FileHandle == INVALID_HANDLE_VALUE)
00050     {
00051         /* Was there a port already associated? */
00052         if (ExistingCompletionPort)
00053         {
00054             /* You are not allowed using an old port and dropping the handle */
00055             NewPort = NULL;
00056             BaseSetLastNTError(STATUS_INVALID_PARAMETER);
00057         }
00058     }
00059     else
00060     {
00061         /* We have a file handle, so associated it with this completion port */
00062         CompletionInformation.Port = NewPort;
00063         CompletionInformation.Key = (PVOID)CompletionKey;
00064         Status = NtSetInformationFile(FileHandle,
00065                                       &IoStatusBlock,
00066                                       &CompletionInformation,
00067                                       sizeof(FILE_COMPLETION_INFORMATION),
00068                                       FileCompletionInformation);
00069         if (!NT_SUCCESS(Status))
00070         {
00071             /* Convert the error code and close the newly created port, if any */
00072             BaseSetLastNTError(Status);
00073             if (!ExistingCompletionPort) NtClose(NewPort);
00074             return FALSE;
00075         }
00076     }
00077 
00078     /* Return the newly created port, if any */
00079     return NewPort;
00080 }
00081 
00082 /*
00083  * @implemented
00084  */
00085 BOOL
00086 WINAPI
00087 GetQueuedCompletionStatus(IN HANDLE CompletionHandle,
00088                           IN LPDWORD lpNumberOfBytesTransferred,
00089                           OUT PULONG_PTR lpCompletionKey,
00090                           OUT LPOVERLAPPED *lpOverlapped,
00091                           IN DWORD dwMilliseconds)
00092 {
00093     NTSTATUS Status;
00094     IO_STATUS_BLOCK IoStatus;
00095     ULONG_PTR CompletionKey;
00096     LARGE_INTEGER Time;
00097     PLARGE_INTEGER TimePtr;
00098 
00099     /* Convert the timeout and then call the native API */
00100     TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);
00101     Status = NtRemoveIoCompletion(CompletionHandle,
00102                                   (PVOID*)&CompletionKey,
00103                                   (PVOID*)lpOverlapped,
00104                                   &IoStatus,
00105                                   TimePtr);
00106     if (!(NT_SUCCESS(Status)) || (Status == STATUS_TIMEOUT))
00107     {
00108         /* Clear out the overlapped output */
00109         *lpOverlapped = NULL;
00110 
00111         /* Check what kind of error we got */
00112         if (Status == STATUS_TIMEOUT)
00113         {
00114             /* Timeout error is set directly since there's no conversion */
00115             SetLastError(WAIT_TIMEOUT);
00116         }
00117         else
00118         {
00119             /* Any other error gets converted */
00120             BaseSetLastNTError(Status);
00121         }
00122 
00123         /* This is a failure case */
00124         return FALSE;
00125     }
00126 
00127     /* Write back the output parameters */
00128     *lpCompletionKey = CompletionKey;
00129     *lpNumberOfBytesTransferred = IoStatus.Information;
00130 
00131     /* Check for error */
00132     if (!NT_SUCCESS(IoStatus.Status))
00133     {
00134         /* Convert and fail */
00135         BaseSetLastNTError(IoStatus.Status);
00136         return FALSE;
00137     }
00138 
00139     /* Return success */
00140     return TRUE;
00141 }
00142 
00143 /*
00144  * @implemented
00145  */
00146 BOOL
00147 WINAPI
00148 PostQueuedCompletionStatus(IN HANDLE CompletionHandle,
00149                            IN DWORD dwNumberOfBytesTransferred,
00150                            IN ULONG_PTR dwCompletionKey,
00151                            IN LPOVERLAPPED lpOverlapped)
00152 {
00153     NTSTATUS Status;
00154 
00155     /* Call the native API */
00156     Status = NtSetIoCompletion(CompletionHandle,
00157                                (PVOID)dwCompletionKey,
00158                                (PVOID)lpOverlapped,
00159                                STATUS_SUCCESS,
00160                                dwNumberOfBytesTransferred);
00161     if (!NT_SUCCESS(Status))
00162     {
00163         /* Convert the error and fail */
00164         BaseSetLastNTError(Status);
00165         return FALSE;
00166     }
00167 
00168     /* Success path */
00169     return TRUE;
00170 }
00171 
00172 /*
00173  * @implemented
00174  */
00175 BOOL
00176 WINAPI
00177 GetOverlappedResult(IN HANDLE hFile,
00178                     IN LPOVERLAPPED lpOverlapped,
00179                     OUT LPDWORD lpNumberOfBytesTransferred,
00180                     IN BOOL bWait)
00181 {
00182     DWORD WaitStatus;
00183     HANDLE hObject;
00184 
00185     /* Check for pending operation */
00186     if (lpOverlapped->Internal == STATUS_PENDING)
00187     {
00188         /* Check if the caller is okay with waiting */
00189         if (!bWait)
00190         {
00191             /* Set timeout */
00192             WaitStatus = WAIT_TIMEOUT;
00193         }
00194         else
00195         {
00196             /* Wait for the result */
00197             hObject = lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile;
00198             WaitStatus = WaitForSingleObject(hObject, INFINITE);
00199         }
00200 
00201         /* Check for timeout */
00202         if (WaitStatus == WAIT_TIMEOUT)
00203         {
00204             /* We have to override the last error with INCOMPLETE instead */
00205             SetLastError(ERROR_IO_INCOMPLETE);
00206             return FALSE;
00207         }
00208 
00209         /* Fail if we had an error -- the last error is already set */
00210         if (WaitStatus) return FALSE;
00211     }
00212 
00213     /* Return bytes transferred */
00214     *lpNumberOfBytesTransferred = lpOverlapped->InternalHigh;
00215 
00216     /* Check for failure during I/O */
00217     if (!NT_SUCCESS(lpOverlapped->Internal))
00218     {
00219         /* Set the error and fail */
00220         BaseSetLastNTError(lpOverlapped->Internal);
00221         return FALSE;
00222     }
00223 
00224     /* All done */
00225     return TRUE;
00226 }
00227 
00228 /*
00229  * @implemented
00230  */
00231 BOOL
00232 WINAPI
00233 BindIoCompletionCallback(IN HANDLE FileHandle,
00234                          IN LPOVERLAPPED_COMPLETION_ROUTINE Function,
00235                          IN ULONG Flags)
00236 {
00237     NTSTATUS Status;
00238 
00239     /* Call RTL */
00240     Status = RtlSetIoCompletionCallback(FileHandle,
00241                                         (PIO_APC_ROUTINE)Function,
00242                                         Flags);
00243     if (!NT_SUCCESS(Status))
00244     {
00245         /* Set error and fail */
00246         BaseSetLastNTError(Status);
00247         return FALSE;
00248     }
00249 
00250     /* Return success */
00251     return TRUE;
00252 }
00253 
00254 /* EOF */

Generated on Sun May 27 2012 04:24:26 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.