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 *****************************************************************/
16 #include <internal/debug.h>
18 #define IOC_TAG TAG('I', 'O', 'C', 'T')
20 POBJECT_TYPE ExIoCompletionType
;
22 NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside
;
24 static GENERIC_MAPPING ExIoCompletionMapping
=
26 STANDARD_RIGHTS_READ
| IO_COMPLETION_QUERY_STATE
,
27 STANDARD_RIGHTS_WRITE
| IO_COMPLETION_MODIFY_STATE
,
28 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| IO_COMPLETION_QUERY_STATE
,
29 IO_COMPLETION_ALL_ACCESS
32 /* FUNCTIONS *****************************************************************/
36 NtpCreateIoCompletion(
40 POBJECT_ATTRIBUTES ObjectAttributes
43 DPRINT("NtpCreateIoCompletion(ObjectBody %x, Parent %x, RemainingPath %S)\n",
44 ObjectBody
, Parent
, RemainingPath
);
46 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
48 return STATUS_UNSUCCESSFUL
;
51 return STATUS_SUCCESS
;
55 NtpDeleteIoCompletion(PVOID ObjectBody
)
57 PKQUEUE Queue
= ObjectBody
;
59 DPRINT("NtpDeleteIoCompletion()\n");
61 KeRundownQueue(Queue
);
70 IoSetCompletionRoutineEx(
71 IN PDEVICE_OBJECT DeviceObject
,
73 IN PIO_COMPLETION_ROUTINE CompletionRoutine
,
75 IN BOOLEAN InvokeOnSuccess
,
76 IN BOOLEAN InvokeOnError
,
77 IN BOOLEAN InvokeOnCancel
81 return STATUS_NOT_IMPLEMENTED
;
90 IN PVOID IoCompletion
,
94 IN ULONG_PTR IoStatusInformation
,
98 PKQUEUE Queue
= (PKQUEUE
) IoCompletion
;
99 PIO_COMPLETION_PACKET Packet
;
101 Packet
= ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside
);
104 return STATUS_NO_MEMORY
;
107 Packet
->Key
= KeyContext
;
108 Packet
->Context
= ApcContext
;
109 Packet
->IoStatus
.Status
= IoStatus
;
110 Packet
->IoStatus
.Information
= IoStatusInformation
;
112 KeInsertQueue(Queue
, &Packet
->ListEntry
);
114 return STATUS_SUCCESS
;
119 IopInitIoCompletionImplementation(VOID
)
121 ExIoCompletionType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
123 RtlCreateUnicodeString(&ExIoCompletionType
->TypeName
, L
"IoCompletion");
125 ExIoCompletionType
->Tag
= IOC_TAG
;
126 ExIoCompletionType
->MaxObjects
= ULONG_MAX
;
127 ExIoCompletionType
->MaxHandles
= ULONG_MAX
;
128 ExIoCompletionType
->TotalObjects
= 0;
129 ExIoCompletionType
->TotalHandles
= 0;
130 ExIoCompletionType
->PagedPoolCharge
= 0;
131 ExIoCompletionType
->NonpagedPoolCharge
= sizeof(KQUEUE
);
132 ExIoCompletionType
->Mapping
= &ExIoCompletionMapping
;
133 ExIoCompletionType
->Dump
= NULL
;
134 ExIoCompletionType
->Open
= NULL
;
135 ExIoCompletionType
->Close
= NULL
;
136 ExIoCompletionType
->Delete
= NtpDeleteIoCompletion
;
137 ExIoCompletionType
->Parse
= NULL
;
138 ExIoCompletionType
->Security
= NULL
;
139 ExIoCompletionType
->QueryName
= NULL
;
140 ExIoCompletionType
->OkayToClose
= NULL
;
141 ExIoCompletionType
->Create
= NtpCreateIoCompletion
;
142 ExIoCompletionType
->DuplicationNotify
= NULL
;
144 ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside
,
148 sizeof(IO_COMPLETION_PACKET
),
156 NtCreateIoCompletion(
157 OUT PHANDLE IoCompletionHandle
,
158 IN ACCESS_MASK DesiredAccess
,
159 IN POBJECT_ATTRIBUTES ObjectAttributes
,
160 IN ULONG NumberOfConcurrentThreads
166 Status
= ObCreateObject(ExGetPreviousMode(),
175 if (!NT_SUCCESS(Status
))
180 Status
= ObInsertObject ((PVOID
)Queue
,
186 if (!NT_SUCCESS(Status
))
188 ObDereferenceObject(Queue
);
192 KeInitializeQueue(Queue
, NumberOfConcurrentThreads
);
193 ObDereferenceObject(Queue
);
195 return STATUS_SUCCESS
;
198 CompletionPort = NULL OR ExistingCompletionPort
208 IO_COMPLETION_QUERY_STATE Query access
209 IO_COMPLETION_MODIFY_STATE Modify access
210 IO_COMPLETION_ALL_ACCESS All of the preceding + STANDARD_RIGHTS_ALL
213 OBJ_OPENLINK and OBJ_PERMANENT are not valid attributes
216 STATUS_SUCCESS or an error status, such as STATUS_ACCESS_DENIED or
217 STATUS_OBJECT_NAME_NOT_FOUND.
222 OUT PHANDLE IoCompletionHandle
,
223 IN ACCESS_MASK DesiredAccess
,
224 IN POBJECT_ATTRIBUTES ObjectAttributes
229 Status
= ObOpenObjectByName(ObjectAttributes
,
235 IoCompletionHandle
); //<- ???
244 IN HANDLE IoCompletionHandle
,
245 IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass
,
246 OUT PVOID IoCompletionInformation
,
247 IN ULONG IoCompletionInformationLength
,
248 OUT PULONG ResultLength OPTIONAL
254 if (IoCompletionInformationClass
!= IoCompletionBasicInformation
)
256 return STATUS_INVALID_INFO_CLASS
;
258 if (IoCompletionInformationLength
< sizeof(IO_COMPLETION_BASIC_INFORMATION
))
260 return STATUS_INFO_LENGTH_MISMATCH
;
263 Status
= ObReferenceObjectByHandle( IoCompletionHandle
,
264 IO_COMPLETION_QUERY_STATE
,
269 if (NT_SUCCESS(Status
))
271 ((PIO_COMPLETION_BASIC_INFORMATION
)IoCompletionInformation
)->Depth
=
272 Queue
->Header
.SignalState
;
274 ObDereferenceObject(Queue
);
276 if (ResultLength
) *ResultLength
= sizeof(IO_COMPLETION_BASIC_INFORMATION
);
284 * Dequeues an I/O completion message from an I/O completion object
288 NtRemoveIoCompletion(
289 IN HANDLE IoCompletionHandle
,
290 OUT PVOID
*CompletionKey
,
291 OUT PVOID
*CompletionContext
,
292 OUT PIO_STATUS_BLOCK IoStatusBlock
,
293 IN PLARGE_INTEGER Timeout OPTIONAL
298 PIO_COMPLETION_PACKET Packet
;
299 PLIST_ENTRY ListEntry
;
301 Status
= ObReferenceObjectByHandle( IoCompletionHandle
,
302 IO_COMPLETION_MODIFY_STATE
,
307 if (!NT_SUCCESS(Status
))
313 Try 2 remove packet from queue. Wait (optionaly) if
314 no packet in queue or max num of threads allready running.
319 ListEntry
= KeRemoveQueue(Queue
, UserMode
, Timeout
);
321 /* Nebbets book says nothing about NtRemoveIoCompletion returning STATUS_USER_APC,
322 and the umode equivalent GetQueuedCompletionStatus says nothing about this either,
323 so my guess it we should restart the operation. Need further investigation. -Gunnar
326 } while((NTSTATUS
)ListEntry
== STATUS_USER_APC
);
328 ObDereferenceObject(Queue
);
330 if ((NTSTATUS
)ListEntry
== STATUS_TIMEOUT
)
332 return STATUS_TIMEOUT
;
337 Packet
= CONTAINING_RECORD(ListEntry
, IO_COMPLETION_PACKET
, ListEntry
);
339 if (CompletionKey
) *CompletionKey
= Packet
->Key
;
340 if (CompletionContext
) *CompletionContext
= Packet
->Context
;
341 if (IoStatusBlock
) *IoStatusBlock
= Packet
->IoStatus
;
343 ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside
, Packet
);
345 return STATUS_SUCCESS
;
350 ASSOSIERT MED FOB's IoCompletionContext
352 typedef struct _IO_COMPLETION_CONTEXT {
355 } IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
361 * Queues an I/O completion message to an I/O completion object
366 IN HANDLE IoCompletionPortHandle
,
367 IN PVOID CompletionKey
,
368 IN PVOID CompletionContext
,
369 IN NTSTATUS CompletionStatus
,
370 IN ULONG CompletionInformation
376 Status
= ObReferenceObjectByHandle( IoCompletionPortHandle
,
377 IO_COMPLETION_MODIFY_STATE
,
382 if (NT_SUCCESS(Status
))
384 Status
= IoSetIoCompletion(Queue
, CompletionKey
, CompletionContext
,
385 CompletionStatus
, CompletionInformation
, TRUE
);
386 ObDereferenceObject(Queue
);