Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeniocompl.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
1.7.6.1
|