1998-10-05 04:00:59 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
1998-12-04 18:28:13 +00:00
|
|
|
* FILE: ntoskrnl/ke/iocomp.c
|
|
|
|
* PURPOSE:
|
1998-10-05 04:00:59 +00:00
|
|
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 22/05/98
|
1998-12-04 18:28:13 +00:00
|
|
|
Changed NtQueryIoCompletion
|
1998-10-05 04:00:59 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
#include <limits.h>
|
2003-06-07 Casper S. Hornstrup <chorns@users.sourceforge.net>
Changes for compiling with w32api
* include/ddk/obfuncs.h (ObCreateObject): Remove.
* include/ntos/zwtypes.h (ObRosCreateObject):
* ntoskrnl/ntoskrnl.def, ntoskrnl/ntoskrnl.edf: Export ObCreateObject@36
and ObRosCreateObject@20.
* ntoskrnl/cm/ntfunc.c, ntoskrnl/cm/registry.c, ntoskrnl/cm/regobj.c,
ntoskrnl/io/create.c, ntoskrnl/io/device.c, ntoskrnl/io/iocomp.c,
ntoskrnl/lpc/connect.c, ntoskrnl/lpc/create.c, ntoskrnl/mm/section.c,
ntoskrnl/nt/evtpair.c, ntoskrnl/nt/mutant.c, ntoskrnl/nt/ntevent.c,
ntoskrnl/nt/ntsem.c, ntoskrnl/nt/nttimer.c, ntoskrnl/nt/profile.c,
ntoskrnl/ob/dirobj.c, ntoskrnl/ob/namespc.c, ntoskrnl/ob/symlink.c,
ntoskrnl/ps/create.c, ntoskrnl/ps/process.c, ntoskrnl/se/token.c,
subsys/win32k/ntuser/winsta.c: Use ObRosCreateObject, not ObCreateObject.
* ntoskrnl/ob/object.c (ObRosCreateObject): Rename from ObCreateObject.
(ObCreateObject): Add stub.
svn path=/trunk/; revision=4866
2003-06-07 12:17:20 +00:00
|
|
|
#define NTOS_MODE_KERNEL
|
|
|
|
#include <ntos.h>
|
|
|
|
//#include <ntos/synch.h>
|
2003-08-14 18:30:28 +00:00
|
|
|
#include <internal/io.h>
|
1998-10-05 04:00:59 +00:00
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
#define NDEBUG
|
1998-10-05 04:00:59 +00:00
|
|
|
#include <internal/debug.h>
|
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
#define IOC_TAG TAG('I', 'O', 'C', 'T')
|
|
|
|
|
|
|
|
POBJECT_TYPE ExIoCompletionType;
|
|
|
|
|
|
|
|
NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
|
|
|
|
|
|
|
|
static GENERIC_MAPPING ExIoCompletionMapping =
|
|
|
|
{
|
|
|
|
STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE,
|
|
|
|
STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE,
|
|
|
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | IO_COMPLETION_QUERY_STATE,
|
|
|
|
IO_COMPLETION_ALL_ACCESS
|
|
|
|
};
|
|
|
|
|
1998-10-05 04:00:59 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
NtpCreateIoCompletion(
|
|
|
|
PVOID ObjectBody,
|
|
|
|
PVOID Parent,
|
|
|
|
PWSTR RemainingPath,
|
|
|
|
POBJECT_ATTRIBUTES ObjectAttributes
|
|
|
|
)
|
|
|
|
{
|
|
|
|
DPRINT("NtpCreateIoCompletion(ObjectBody %x, Parent %x, RemainingPath %S)\n",
|
|
|
|
ObjectBody, Parent, RemainingPath);
|
|
|
|
|
|
|
|
if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
|
|
|
|
{
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID STDCALL
|
|
|
|
NtpDeleteIoCompletion(PVOID ObjectBody)
|
|
|
|
{
|
|
|
|
PKQUEUE Queue = ObjectBody;
|
|
|
|
|
|
|
|
DPRINT("NtpDeleteIoCompletion()\n");
|
|
|
|
|
|
|
|
KeRundownQueue(Queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NtInitializeIoCompletionImplementation(VOID)
|
|
|
|
{
|
|
|
|
ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
|
|
|
|
|
|
|
RtlCreateUnicodeString(&ExIoCompletionType->TypeName, L"IoCompletion");
|
|
|
|
|
|
|
|
ExIoCompletionType->Tag = IOC_TAG;
|
|
|
|
ExIoCompletionType->MaxObjects = ULONG_MAX;
|
|
|
|
ExIoCompletionType->MaxHandles = ULONG_MAX;
|
|
|
|
ExIoCompletionType->TotalObjects = 0;
|
|
|
|
ExIoCompletionType->TotalHandles = 0;
|
|
|
|
ExIoCompletionType->PagedPoolCharge = 0;
|
|
|
|
ExIoCompletionType->NonpagedPoolCharge = sizeof(KQUEUE);
|
|
|
|
ExIoCompletionType->Mapping = &ExIoCompletionMapping;
|
|
|
|
ExIoCompletionType->Dump = NULL;
|
|
|
|
ExIoCompletionType->Open = NULL;
|
|
|
|
ExIoCompletionType->Close = NULL;
|
|
|
|
ExIoCompletionType->Delete = NtpDeleteIoCompletion;
|
|
|
|
ExIoCompletionType->Parse = NULL;
|
|
|
|
ExIoCompletionType->Security = NULL;
|
|
|
|
ExIoCompletionType->QueryName = NULL;
|
|
|
|
ExIoCompletionType->OkayToClose = NULL;
|
|
|
|
ExIoCompletionType->Create = NtpCreateIoCompletion;
|
|
|
|
ExIoCompletionType->DuplicationNotify = NULL;
|
|
|
|
|
|
|
|
ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
sizeof(IO_COMPLETION_PACKET),
|
|
|
|
IOC_TAG,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-06-18 22:11:21 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2003-03-19 23:17:52 +00:00
|
|
|
NtCreateIoCompletion(
|
|
|
|
OUT PHANDLE IoCompletionHandle,
|
|
|
|
IN ACCESS_MASK DesiredAccess,
|
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|
|
|
IN ULONG NumberOfConcurrentThreads
|
|
|
|
)
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2003-03-19 23:17:52 +00:00
|
|
|
PKQUEUE Queue;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2003-06-07 Casper S. Hornstrup <chorns@users.sourceforge.net>
Changes for compiling with w32api
* include/ddk/obfuncs.h (ObCreateObject): Remove.
* include/ntos/zwtypes.h (ObRosCreateObject):
* ntoskrnl/ntoskrnl.def, ntoskrnl/ntoskrnl.edf: Export ObCreateObject@36
and ObRosCreateObject@20.
* ntoskrnl/cm/ntfunc.c, ntoskrnl/cm/registry.c, ntoskrnl/cm/regobj.c,
ntoskrnl/io/create.c, ntoskrnl/io/device.c, ntoskrnl/io/iocomp.c,
ntoskrnl/lpc/connect.c, ntoskrnl/lpc/create.c, ntoskrnl/mm/section.c,
ntoskrnl/nt/evtpair.c, ntoskrnl/nt/mutant.c, ntoskrnl/nt/ntevent.c,
ntoskrnl/nt/ntsem.c, ntoskrnl/nt/nttimer.c, ntoskrnl/nt/profile.c,
ntoskrnl/ob/dirobj.c, ntoskrnl/ob/namespc.c, ntoskrnl/ob/symlink.c,
ntoskrnl/ps/create.c, ntoskrnl/ps/process.c, ntoskrnl/se/token.c,
subsys/win32k/ntuser/winsta.c: Use ObRosCreateObject, not ObCreateObject.
* ntoskrnl/ob/object.c (ObRosCreateObject): Rename from ObCreateObject.
(ObCreateObject): Add stub.
svn path=/trunk/; revision=4866
2003-06-07 12:17:20 +00:00
|
|
|
Status = ObRosCreateObject(IoCompletionHandle,
|
2003-03-19 23:17:52 +00:00
|
|
|
DesiredAccess,
|
|
|
|
ObjectAttributes,
|
|
|
|
ExIoCompletionType,
|
|
|
|
(PVOID*)&Queue);
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
(void) KeInitializeQueue(Queue, NumberOfConcurrentThreads);
|
|
|
|
ObDereferenceObject(Queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
/*
|
|
|
|
|
|
|
|
CompletionPort = NULL OR ExistingCompletionPort
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
/*
|
|
|
|
DesiredAccess:
|
|
|
|
ZERO
|
|
|
|
IO_COMPLETION_QUERY_STATE Query access
|
|
|
|
IO_COMPLETION_MODIFY_STATE Modify access
|
|
|
|
IO_COMPLETION_ALL_ACCESS All of the preceding + STANDARD_RIGHTS_ALL
|
|
|
|
|
|
|
|
ObjectAttributes
|
|
|
|
OBJ_OPENLINK and OBJ_PERMANENT are not valid attributes
|
1998-10-05 04:00:59 +00:00
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
Return Value
|
|
|
|
STATUS_SUCCESS or an error status, such as STATUS_ACCESS_DENIED or
|
|
|
|
STATUS_OBJECT_NAME_NOT_FOUND.
|
|
|
|
*/
|
1999-06-18 22:11:21 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2003-03-19 23:17:52 +00:00
|
|
|
NtOpenIoCompletion(
|
|
|
|
OUT PHANDLE IoCompletionHandle,
|
|
|
|
IN ACCESS_MASK DesiredAccess,
|
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes
|
|
|
|
)
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2003-03-19 23:17:52 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = ObOpenObjectByName(ObjectAttributes,
|
|
|
|
ExIoCompletionType,
|
|
|
|
NULL,
|
|
|
|
UserMode,
|
|
|
|
DesiredAccess,
|
|
|
|
NULL,
|
|
|
|
IoCompletionHandle); //<- ???
|
|
|
|
|
|
|
|
return Status;
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-06-18 22:11:21 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2003-03-19 23:17:52 +00:00
|
|
|
NtQueryIoCompletion(
|
|
|
|
IN HANDLE IoCompletionHandle,
|
|
|
|
IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
|
|
|
|
OUT PVOID IoCompletionInformation,
|
|
|
|
IN ULONG IoCompletionInformationLength,
|
|
|
|
OUT PULONG ResultLength OPTIONAL
|
|
|
|
)
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2003-03-19 23:17:52 +00:00
|
|
|
PKQUEUE Queue;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
if (IoCompletionInformationClass != IoCompletionBasicInformation)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_INFO_CLASS;
|
|
|
|
}
|
|
|
|
if (IoCompletionInformationLength < sizeof(IO_COMPLETION_BASIC_INFORMATION))
|
|
|
|
{
|
|
|
|
return STATUS_INFO_LENGTH_MISMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByHandle( IoCompletionHandle,
|
|
|
|
IO_COMPLETION_QUERY_STATE,
|
|
|
|
ExIoCompletionType,
|
|
|
|
UserMode,
|
|
|
|
(PVOID*)&Queue,
|
|
|
|
NULL);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2003-08-14 18:30:28 +00:00
|
|
|
((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->Depth =
|
2003-03-19 23:17:52 +00:00
|
|
|
Queue->Header.SignalState;
|
|
|
|
|
|
|
|
ObDereferenceObject(Queue);
|
|
|
|
|
|
|
|
if (ResultLength) *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
/*
|
|
|
|
* Dequeues an I/O completion message from an I/O completion object
|
|
|
|
*/
|
1999-06-18 22:11:21 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2003-03-19 23:17:52 +00:00
|
|
|
NtRemoveIoCompletion(
|
|
|
|
IN HANDLE IoCompletionHandle,
|
|
|
|
OUT PULONG CompletionKey,
|
|
|
|
OUT PULONG CompletionValue,
|
|
|
|
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
|
|
|
IN PLARGE_INTEGER Timeout OPTIONAL
|
|
|
|
)
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2003-03-19 23:17:52 +00:00
|
|
|
PKQUEUE Queue;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByHandle( IoCompletionHandle,
|
|
|
|
IO_COMPLETION_MODIFY_STATE,
|
|
|
|
ExIoCompletionType,
|
|
|
|
UserMode,
|
|
|
|
(PVOID*)&Queue,
|
|
|
|
NULL);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
PIO_COMPLETION_PACKET Packet;
|
|
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Try 2 remove packet from queue. Wait (optionaly) if
|
|
|
|
no packet in queue or max num of threads allready running.
|
|
|
|
*/
|
|
|
|
ListEntry = KeRemoveQueue(Queue, UserMode, Timeout );
|
|
|
|
|
|
|
|
ObDereferenceObject(Queue);
|
|
|
|
|
|
|
|
Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
|
|
|
|
|
|
|
|
if (CompletionKey) *CompletionKey = Packet->Key;
|
|
|
|
if (CompletionValue) *CompletionValue = Packet->Overlapped;
|
|
|
|
if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus;
|
|
|
|
|
|
|
|
ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-03-19 23:17:52 +00:00
|
|
|
/*
|
|
|
|
ASSOSIERT MED FOB's IoCompletionContext
|
|
|
|
|
|
|
|
typedef struct _IO_COMPLETION_CONTEXT {
|
|
|
|
PVOID Port;
|
|
|
|
ULONG Key;
|
|
|
|
} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Queues an I/O completion message to an I/O completion object
|
|
|
|
*/
|
1999-06-18 22:11:21 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2003-03-19 23:17:52 +00:00
|
|
|
NtSetIoCompletion(
|
|
|
|
IN HANDLE IoCompletionPortHandle,
|
|
|
|
IN ULONG CompletionKey,
|
|
|
|
IN ULONG CompletionValue,
|
|
|
|
IN NTSTATUS CompletionStatus,
|
|
|
|
IN ULONG CompletionInformation
|
|
|
|
)
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2003-03-19 23:17:52 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PKQUEUE Queue;
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByHandle( IoCompletionPortHandle,
|
|
|
|
IO_COMPLETION_MODIFY_STATE,
|
|
|
|
ExIoCompletionType,
|
|
|
|
UserMode,
|
|
|
|
(PVOID*)&Queue,
|
|
|
|
NULL);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
PIO_COMPLETION_PACKET Packet;
|
|
|
|
|
|
|
|
Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
|
|
|
|
|
|
|
|
Packet->Key = CompletionKey;
|
|
|
|
Packet->Overlapped = CompletionValue;
|
|
|
|
Packet->IoStatus.Status = CompletionStatus;
|
|
|
|
Packet->IoStatus.Information = CompletionInformation;
|
|
|
|
|
|
|
|
KeInsertQueue(Queue, &Packet->ListEntry);
|
|
|
|
ObDereferenceObject(Queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|