2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/iocomp.c
6 * PROGRAMMER: David Welch (welch@mcmail.com)
9 Changed NtQueryIoCompletion
12 /* INCLUDES *****************************************************************/
15 #include <ddk/ntddk.h>
16 #include <ntos/synch.h>
19 #include <internal/debug.h>
21 #define IOC_TAG TAG('I', 'O', 'C', 'T')
23 POBJECT_TYPE ExIoCompletionType;
25 NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
27 static GENERIC_MAPPING ExIoCompletionMapping =
29 STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE,
30 STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE,
31 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | IO_COMPLETION_QUERY_STATE,
32 IO_COMPLETION_ALL_ACCESS
35 /* FUNCTIONS *****************************************************************/
39 NtpCreateIoCompletion(
43 POBJECT_ATTRIBUTES ObjectAttributes
46 DPRINT("NtpCreateIoCompletion(ObjectBody %x, Parent %x, RemainingPath %S)\n",
47 ObjectBody, Parent, RemainingPath);
49 if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
51 return STATUS_UNSUCCESSFUL;
54 return STATUS_SUCCESS;
58 NtpDeleteIoCompletion(PVOID ObjectBody)
60 PKQUEUE Queue = ObjectBody;
62 DPRINT("NtpDeleteIoCompletion()\n");
64 KeRundownQueue(Queue);
69 NtInitializeIoCompletionImplementation(VOID)
71 ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
73 RtlCreateUnicodeString(&ExIoCompletionType->TypeName, L"IoCompletion");
75 ExIoCompletionType->Tag = IOC_TAG;
76 ExIoCompletionType->MaxObjects = ULONG_MAX;
77 ExIoCompletionType->MaxHandles = ULONG_MAX;
78 ExIoCompletionType->TotalObjects = 0;
79 ExIoCompletionType->TotalHandles = 0;
80 ExIoCompletionType->PagedPoolCharge = 0;
81 ExIoCompletionType->NonpagedPoolCharge = sizeof(KQUEUE);
82 ExIoCompletionType->Mapping = &ExIoCompletionMapping;
83 ExIoCompletionType->Dump = NULL;
84 ExIoCompletionType->Open = NULL;
85 ExIoCompletionType->Close = NULL;
86 ExIoCompletionType->Delete = NtpDeleteIoCompletion;
87 ExIoCompletionType->Parse = NULL;
88 ExIoCompletionType->Security = NULL;
89 ExIoCompletionType->QueryName = NULL;
90 ExIoCompletionType->OkayToClose = NULL;
91 ExIoCompletionType->Create = NtpCreateIoCompletion;
92 ExIoCompletionType->DuplicationNotify = NULL;
94 ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside,
98 sizeof(IO_COMPLETION_PACKET),
106 NtCreateIoCompletion(
107 OUT PHANDLE IoCompletionHandle,
108 IN ACCESS_MASK DesiredAccess,
109 IN POBJECT_ATTRIBUTES ObjectAttributes,
110 IN ULONG NumberOfConcurrentThreads
116 Status = ObCreateObject(IoCompletionHandle,
122 if (NT_SUCCESS(Status))
124 (void) KeInitializeQueue(Queue, NumberOfConcurrentThreads);
125 ObDereferenceObject(Queue);
131 CompletionPort = NULL OR ExistingCompletionPort
141 IO_COMPLETION_QUERY_STATE Query access
142 IO_COMPLETION_MODIFY_STATE Modify access
143 IO_COMPLETION_ALL_ACCESS All of the preceding + STANDARD_RIGHTS_ALL
146 OBJ_OPENLINK and OBJ_PERMANENT are not valid attributes
149 STATUS_SUCCESS or an error status, such as STATUS_ACCESS_DENIED or
150 STATUS_OBJECT_NAME_NOT_FOUND.
155 OUT PHANDLE IoCompletionHandle,
156 IN ACCESS_MASK DesiredAccess,
157 IN POBJECT_ATTRIBUTES ObjectAttributes
162 Status = ObOpenObjectByName(ObjectAttributes,
168 IoCompletionHandle); //<- ???
177 IN HANDLE IoCompletionHandle,
178 IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
179 OUT PVOID IoCompletionInformation,
180 IN ULONG IoCompletionInformationLength,
181 OUT PULONG ResultLength OPTIONAL
187 if (IoCompletionInformationClass != IoCompletionBasicInformation)
189 return STATUS_INVALID_INFO_CLASS;
191 if (IoCompletionInformationLength < sizeof(IO_COMPLETION_BASIC_INFORMATION))
193 return STATUS_INFO_LENGTH_MISMATCH;
196 Status = ObReferenceObjectByHandle( IoCompletionHandle,
197 IO_COMPLETION_QUERY_STATE,
202 if (NT_SUCCESS(Status))
204 ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->SignalState =
205 Queue->Header.SignalState;
207 ObDereferenceObject(Queue);
209 if (ResultLength) *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
217 * Dequeues an I/O completion message from an I/O completion object
221 NtRemoveIoCompletion(
222 IN HANDLE IoCompletionHandle,
223 OUT PULONG CompletionKey,
224 OUT PULONG CompletionValue,
225 OUT PIO_STATUS_BLOCK IoStatusBlock,
226 IN PLARGE_INTEGER Timeout OPTIONAL
232 Status = ObReferenceObjectByHandle( IoCompletionHandle,
233 IO_COMPLETION_MODIFY_STATE,
238 if (NT_SUCCESS(Status))
240 PIO_COMPLETION_PACKET Packet;
241 PLIST_ENTRY ListEntry;
244 Try 2 remove packet from queue. Wait (optionaly) if
245 no packet in queue or max num of threads allready running.
247 ListEntry = KeRemoveQueue(Queue, UserMode, Timeout );
249 ObDereferenceObject(Queue);
251 Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
253 if (CompletionKey) *CompletionKey = Packet->Key;
254 if (CompletionValue) *CompletionValue = Packet->Overlapped;
255 if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus;
257 ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
265 ASSOSIERT MED FOB's IoCompletionContext
267 typedef struct _IO_COMPLETION_CONTEXT {
270 } IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
276 * Queues an I/O completion message to an I/O completion object
281 IN HANDLE IoCompletionPortHandle,
282 IN ULONG CompletionKey,
283 IN ULONG CompletionValue,
284 IN NTSTATUS CompletionStatus,
285 IN ULONG CompletionInformation
291 Status = ObReferenceObjectByHandle( IoCompletionPortHandle,
292 IO_COMPLETION_MODIFY_STATE,
297 if (NT_SUCCESS(Status))
299 PIO_COMPLETION_PACKET Packet;
301 Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
303 Packet->Key = CompletionKey;
304 Packet->Overlapped = CompletionValue;
305 Packet->IoStatus.Status = CompletionStatus;
306 Packet->IoStatus.Information = CompletionInformation;
308 KeInsertQueue(Queue, &Packet->ListEntry);
309 ObDereferenceObject(Queue);