3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/iocomp.c
6 * PURPOSE: No purpose listed.
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 #define IOC_TAG TAG('I', 'O', 'C', 'T')
19 POBJECT_TYPE ExIoCompletionType
;
21 NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside
;
23 static GENERIC_MAPPING ExIoCompletionMapping
=
25 STANDARD_RIGHTS_READ
| IO_COMPLETION_QUERY_STATE
,
26 STANDARD_RIGHTS_WRITE
| IO_COMPLETION_MODIFY_STATE
,
27 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| IO_COMPLETION_QUERY_STATE
,
28 IO_COMPLETION_ALL_ACCESS
31 /* FUNCTIONS *****************************************************************/
35 IopCreateIoCompletion(
39 POBJECT_ATTRIBUTES ObjectAttributes
42 DPRINT("IopCreateIoCompletion(ObjectBody %x, Parent %x, RemainingPath %S)\n",
43 ObjectBody
, Parent
, RemainingPath
);
45 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
47 return STATUS_UNSUCCESSFUL
;
50 return STATUS_SUCCESS
;
54 IopDeleteIoCompletion(PVOID ObjectBody
)
56 PKQUEUE Queue
= ObjectBody
;
58 DPRINT("IopDeleteIoCompletion()\n");
60 KeRundownQueue(Queue
);
69 IoSetCompletionRoutineEx(
70 IN PDEVICE_OBJECT DeviceObject
,
72 IN PIO_COMPLETION_ROUTINE CompletionRoutine
,
74 IN BOOLEAN InvokeOnSuccess
,
75 IN BOOLEAN InvokeOnError
,
76 IN BOOLEAN InvokeOnCancel
80 return STATUS_NOT_IMPLEMENTED
;
89 IN PVOID IoCompletion
,
93 IN ULONG_PTR IoStatusInformation
,
97 PKQUEUE Queue
= (PKQUEUE
) IoCompletion
;
98 PIO_COMPLETION_PACKET Packet
;
100 Packet
= ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside
);
103 return STATUS_NO_MEMORY
;
106 Packet
->Key
= KeyContext
;
107 Packet
->Context
= ApcContext
;
108 Packet
->IoStatus
.Status
= IoStatus
;
109 Packet
->IoStatus
.Information
= IoStatusInformation
;
111 KeInsertQueue(Queue
, &Packet
->ListEntry
);
113 return STATUS_SUCCESS
;
118 IopInitIoCompletionImplementation(VOID
)
120 ExIoCompletionType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
122 RtlpCreateUnicodeString(&ExIoCompletionType
->TypeName
, L
"IoCompletion", NonPagedPool
);
124 ExIoCompletionType
->Tag
= IOC_TAG
;
125 ExIoCompletionType
->PeakObjects
= 0;
126 ExIoCompletionType
->PeakHandles
= 0;
127 ExIoCompletionType
->TotalObjects
= 0;
128 ExIoCompletionType
->TotalHandles
= 0;
129 ExIoCompletionType
->PagedPoolCharge
= 0;
130 ExIoCompletionType
->NonpagedPoolCharge
= sizeof(KQUEUE
);
131 ExIoCompletionType
->Mapping
= &ExIoCompletionMapping
;
132 ExIoCompletionType
->Dump
= NULL
;
133 ExIoCompletionType
->Open
= NULL
;
134 ExIoCompletionType
->Close
= NULL
;
135 ExIoCompletionType
->Delete
= IopDeleteIoCompletion
;
136 ExIoCompletionType
->Parse
= NULL
;
137 ExIoCompletionType
->Security
= NULL
;
138 ExIoCompletionType
->QueryName
= NULL
;
139 ExIoCompletionType
->OkayToClose
= NULL
;
140 ExIoCompletionType
->Create
= IopCreateIoCompletion
;
141 ExIoCompletionType
->DuplicationNotify
= NULL
;
143 ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside
,
147 sizeof(IO_COMPLETION_PACKET
),
155 NtCreateIoCompletion(
156 OUT PHANDLE IoCompletionHandle
,
157 IN ACCESS_MASK DesiredAccess
,
158 IN POBJECT_ATTRIBUTES ObjectAttributes
,
159 IN ULONG NumberOfConcurrentThreads
165 Status
= ObCreateObject(ExGetPreviousMode(),
174 if (!NT_SUCCESS(Status
))
179 Status
= ObInsertObject ((PVOID
)Queue
,
185 if (!NT_SUCCESS(Status
))
187 ObDereferenceObject(Queue
);
191 KeInitializeQueue(Queue
, NumberOfConcurrentThreads
);
192 ObDereferenceObject(Queue
);
194 return STATUS_SUCCESS
;
197 CompletionPort = NULL OR ExistingCompletionPort
207 IO_COMPLETION_QUERY_STATE Query access
208 IO_COMPLETION_MODIFY_STATE Modify access
209 IO_COMPLETION_ALL_ACCESS All of the preceding + STANDARD_RIGHTS_ALL
212 OBJ_OPENLINK and OBJ_PERMANENT are not valid attributes
215 STATUS_SUCCESS or an error status, such as STATUS_ACCESS_DENIED or
216 STATUS_OBJECT_NAME_NOT_FOUND.
221 OUT PHANDLE IoCompletionHandle
,
222 IN ACCESS_MASK DesiredAccess
,
223 IN POBJECT_ATTRIBUTES ObjectAttributes
228 Status
= ObOpenObjectByName(ObjectAttributes
,
234 IoCompletionHandle
); //<- ???
243 IN HANDLE IoCompletionHandle
,
244 IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass
,
245 OUT PVOID IoCompletionInformation
,
246 IN ULONG IoCompletionInformationLength
,
247 OUT PULONG ResultLength OPTIONAL
253 if (IoCompletionInformationClass
!= IoCompletionBasicInformation
)
255 return STATUS_INVALID_INFO_CLASS
;
257 if (IoCompletionInformationLength
< sizeof(IO_COMPLETION_BASIC_INFORMATION
))
259 return STATUS_INFO_LENGTH_MISMATCH
;
262 Status
= ObReferenceObjectByHandle( IoCompletionHandle
,
263 IO_COMPLETION_QUERY_STATE
,
268 if (NT_SUCCESS(Status
))
270 ((PIO_COMPLETION_BASIC_INFORMATION
)IoCompletionInformation
)->Depth
=
271 Queue
->Header
.SignalState
;
273 ObDereferenceObject(Queue
);
275 if (ResultLength
) *ResultLength
= sizeof(IO_COMPLETION_BASIC_INFORMATION
);
283 * Dequeues an I/O completion message from an I/O completion object
287 NtRemoveIoCompletion(
288 IN HANDLE IoCompletionHandle
,
289 OUT PVOID
*CompletionKey
,
290 OUT PVOID
*CompletionContext
,
291 OUT PIO_STATUS_BLOCK IoStatusBlock
,
292 IN PLARGE_INTEGER Timeout OPTIONAL
297 PIO_COMPLETION_PACKET Packet
;
298 PLIST_ENTRY ListEntry
;
300 Status
= ObReferenceObjectByHandle( IoCompletionHandle
,
301 IO_COMPLETION_MODIFY_STATE
,
306 if (!NT_SUCCESS(Status
))
312 Try 2 remove packet from queue. Wait (optionaly) if
313 no packet in queue or max num of threads allready running.
318 ListEntry
= KeRemoveQueue(Queue
, UserMode
, Timeout
);
320 /* Nebbets book says nothing about NtRemoveIoCompletion returning STATUS_USER_APC,
321 and the umode equivalent GetQueuedCompletionStatus says nothing about this either,
322 so my guess it we should restart the operation. Need further investigation. -Gunnar
325 } while((NTSTATUS
)ListEntry
== STATUS_USER_APC
);
327 ObDereferenceObject(Queue
);
329 if ((NTSTATUS
)ListEntry
== STATUS_TIMEOUT
)
331 return STATUS_TIMEOUT
;
336 Packet
= CONTAINING_RECORD(ListEntry
, IO_COMPLETION_PACKET
, ListEntry
);
338 if (CompletionKey
) *CompletionKey
= Packet
->Key
;
339 if (CompletionContext
) *CompletionContext
= Packet
->Context
;
340 if (IoStatusBlock
) *IoStatusBlock
= Packet
->IoStatus
;
342 ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside
, Packet
);
344 return STATUS_SUCCESS
;
349 ASSOSIERT MED FOB's IoCompletionContext
351 typedef struct _IO_COMPLETION_CONTEXT {
354 } IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
360 * Queues an I/O completion message to an I/O completion object
365 IN HANDLE IoCompletionPortHandle
,
366 IN PVOID CompletionKey
,
367 IN PVOID CompletionContext
,
368 IN NTSTATUS CompletionStatus
,
369 IN ULONG CompletionInformation
375 Status
= ObReferenceObjectByHandle( IoCompletionPortHandle
,
376 IO_COMPLETION_MODIFY_STATE
,
381 if (NT_SUCCESS(Status
))
383 Status
= IoSetIoCompletion(Queue
, CompletionKey
, CompletionContext
,
384 CompletionStatus
, CompletionInformation
, TRUE
);
385 ObDereferenceObject(Queue
);