2005-01-06 13:58:04 +00:00
|
|
|
/* $Id$
|
2000-06-03 14:47:33 +00:00
|
|
|
*
|
1998-12-04 18:28:13 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS system libraries
|
|
|
|
* FILE: lib/kernel32/file/iocompl.c
|
|
|
|
* PURPOSE: Io Completion functions
|
|
|
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 01/11/98
|
|
|
|
*/
|
|
|
|
|
2003-01-15 21:24:36 +00:00
|
|
|
#include <k32.h>
|
2010-08-13 14:47:01 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
2002-09-08 10:23:54 +00:00
|
|
|
|
2009-01-25 16:13:16 +00:00
|
|
|
#define NANOS_TO_100NS(nanos) (((LONGLONG)(nanos)) / 100)
|
|
|
|
#define MICROS_TO_100NS(micros) (((LONGLONG)(micros)) * NANOS_TO_100NS(1000))
|
|
|
|
#define MILLIS_TO_100NS(milli) (((LONGLONG)(milli)) * MICROS_TO_100NS(1000))
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
1999-10-07 23:46:27 +00:00
|
|
|
HANDLE
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
1999-10-07 23:46:27 +00:00
|
|
|
CreateIoCompletionPort(
|
|
|
|
HANDLE FileHandle,
|
|
|
|
HANDLE ExistingCompletionPort,
|
2004-11-25 22:18:17 +00:00
|
|
|
ULONG_PTR CompletionKey,
|
1999-10-07 23:46:27 +00:00
|
|
|
DWORD NumberOfConcurrentThreads
|
1998-12-04 18:28:13 +00:00
|
|
|
)
|
|
|
|
{
|
2003-03-19 23:17:52 +00:00
|
|
|
HANDLE CompletionPort = NULL;
|
|
|
|
NTSTATUS errCode;
|
|
|
|
FILE_COMPLETION_INFORMATION CompletionInformation;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
|
2008-01-20 11:18:22 +00:00
|
|
|
if ( FileHandle == INVALID_HANDLE_VALUE && ExistingCompletionPort != NULL )
|
2003-03-19 23:17:52 +00:00
|
|
|
{
|
2004-12-06 14:37:11 +00:00
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
2003-03-19 23:17:52 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-05-09 01:46:57 +00:00
|
|
|
if ( ExistingCompletionPort != NULL )
|
2003-03-19 23:17:52 +00:00
|
|
|
{
|
|
|
|
CompletionPort = ExistingCompletionPort;
|
|
|
|
}
|
2005-05-09 01:46:57 +00:00
|
|
|
else
|
2003-03-19 23:17:52 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
errCode = NtCreateIoCompletion(&CompletionPort,
|
|
|
|
IO_COMPLETION_ALL_ACCESS,
|
|
|
|
NULL,//ObjectAttributes
|
|
|
|
NumberOfConcurrentThreads);
|
|
|
|
|
2005-05-09 01:46:57 +00:00
|
|
|
if (!NT_SUCCESS(errCode) )
|
2003-03-19 23:17:52 +00:00
|
|
|
{
|
|
|
|
SetLastErrorByStatus (errCode);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2005-05-09 01:46:57 +00:00
|
|
|
|
|
|
|
if ( FileHandle != INVALID_HANDLE_VALUE )
|
2003-03-19 23:17:52 +00:00
|
|
|
{
|
2004-06-13 20:04:56 +00:00
|
|
|
CompletionInformation.Port = CompletionPort;
|
2004-11-25 22:18:17 +00:00
|
|
|
CompletionInformation.Key = (PVOID)CompletionKey;
|
2003-03-19 23:17:52 +00:00
|
|
|
|
2005-05-09 01:46:57 +00:00
|
|
|
errCode = NtSetInformationFile(FileHandle,
|
2003-03-19 23:17:52 +00:00
|
|
|
&IoStatusBlock,
|
|
|
|
&CompletionInformation,
|
|
|
|
sizeof(FILE_COMPLETION_INFORMATION),
|
|
|
|
FileCompletionInformation);
|
|
|
|
|
2005-05-09 01:46:57 +00:00
|
|
|
if ( !NT_SUCCESS(errCode) )
|
2003-03-19 23:17:52 +00:00
|
|
|
{
|
|
|
|
if ( ExistingCompletionPort == NULL )
|
|
|
|
{
|
|
|
|
NtClose(CompletionPort);
|
|
|
|
}
|
2005-05-09 01:46:57 +00:00
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
SetLastErrorByStatus (errCode);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return CompletionPort;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 16:37:11 +00:00
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
1998-12-04 18:28:13 +00:00
|
|
|
GetQueuedCompletionStatus(
|
2003-03-19 23:17:52 +00:00
|
|
|
HANDLE CompletionHandle,
|
|
|
|
LPDWORD lpNumberOfBytesTransferred,
|
2004-11-25 22:18:17 +00:00
|
|
|
PULONG_PTR lpCompletionKey,
|
2003-03-19 23:17:52 +00:00
|
|
|
LPOVERLAPPED *lpOverlapped,
|
|
|
|
DWORD dwMilliseconds
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2003-03-19 23:17:52 +00:00
|
|
|
NTSTATUS errCode;
|
|
|
|
IO_STATUS_BLOCK IoStatus;
|
2008-12-17 05:50:20 +00:00
|
|
|
ULONG_PTR CompletionKey;
|
2003-03-19 23:17:52 +00:00
|
|
|
LARGE_INTEGER Interval;
|
|
|
|
|
2008-12-17 05:50:20 +00:00
|
|
|
if (!lpNumberOfBytesTransferred || !lpCompletionKey || !lpOverlapped)
|
2003-03-19 23:17:52 +00:00
|
|
|
{
|
2004-12-06 14:37:11 +00:00
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
2003-03-19 23:17:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dwMilliseconds != INFINITE)
|
|
|
|
{
|
2009-01-25 16:13:16 +00:00
|
|
|
Interval.QuadPart = (-(MILLIS_TO_100NS(dwMilliseconds)));
|
2005-05-09 01:46:57 +00:00
|
|
|
}
|
2003-03-19 23:17:52 +00:00
|
|
|
|
|
|
|
errCode = NtRemoveIoCompletion(CompletionHandle,
|
2008-12-17 05:50:20 +00:00
|
|
|
(PVOID*)&CompletionKey,
|
|
|
|
(PVOID*)lpOverlapped,
|
2003-03-19 23:17:52 +00:00
|
|
|
&IoStatus,
|
2004-12-06 14:37:11 +00:00
|
|
|
dwMilliseconds == INFINITE ? NULL : &Interval);
|
2003-03-19 23:17:52 +00:00
|
|
|
|
2008-12-17 05:50:20 +00:00
|
|
|
if (!NT_SUCCESS(errCode) || errCode == STATUS_TIMEOUT) {
|
2003-03-19 23:17:52 +00:00
|
|
|
*lpOverlapped = NULL;
|
|
|
|
SetLastErrorByStatus(errCode);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2008-12-17 05:50:20 +00:00
|
|
|
*lpCompletionKey = CompletionKey;
|
|
|
|
*lpNumberOfBytesTransferred = IoStatus.Information;
|
2003-03-19 23:17:52 +00:00
|
|
|
|
|
|
|
if (!NT_SUCCESS(IoStatus.Status)){
|
|
|
|
//failed io operation
|
2004-12-06 14:37:11 +00:00
|
|
|
SetLastErrorByStatus(IoStatus.Status);
|
2003-03-19 23:17:52 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 16:37:11 +00:00
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
1998-12-04 18:28:13 +00:00
|
|
|
PostQueuedCompletionStatus(
|
2003-03-19 23:17:52 +00:00
|
|
|
HANDLE CompletionHandle,
|
|
|
|
DWORD dwNumberOfBytesTransferred,
|
2006-05-27 09:18:10 +00:00
|
|
|
ULONG_PTR dwCompletionKey,
|
2003-03-19 23:17:52 +00:00
|
|
|
LPOVERLAPPED lpOverlapped
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2003-03-19 23:17:52 +00:00
|
|
|
NTSTATUS errCode;
|
|
|
|
|
2005-05-09 01:46:57 +00:00
|
|
|
errCode = NtSetIoCompletion(CompletionHandle,
|
2008-12-17 05:50:20 +00:00
|
|
|
(PVOID)dwCompletionKey, // KeyContext
|
|
|
|
(PVOID)lpOverlapped, // ApcContext
|
|
|
|
STATUS_SUCCESS, // IoStatusBlock->Status
|
|
|
|
dwNumberOfBytesTransferred); // IoStatusBlock->Information
|
2003-03-19 23:17:52 +00:00
|
|
|
|
2005-05-09 01:46:57 +00:00
|
|
|
if ( !NT_SUCCESS(errCode) )
|
2003-03-19 23:17:52 +00:00
|
|
|
{
|
|
|
|
SetLastErrorByStatus (errCode);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
2000-06-03 14:47:33 +00:00
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
BOOL WINAPI
|
2003-02-03 14:20:24 +00:00
|
|
|
CancelIo(HANDLE hFile)
|
|
|
|
{
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtCancelIoFile(hFile,
|
|
|
|
&IoStatusBlock);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
2006-01-14 22:47:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
CancelIoEx(IN HANDLE hFile,
|
|
|
|
IN LPOVERLAPPED lpOverlapped)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
CancelSynchronousIo(IN HANDLE hThread)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2000-06-03 14:47:33 +00:00
|
|
|
/* EOF */
|