+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+IoSetIoCompletion(IN PVOID IoCompletion,
+ IN PVOID KeyContext,
+ IN PVOID ApcContext,
+ IN NTSTATUS IoStatus,
+ IN ULONG_PTR IoStatusInformation,
+ IN BOOLEAN Quota)
+{
+ PKQUEUE Queue = (PKQUEUE)IoCompletion;
+ PNPAGED_LOOKASIDE_LIST List;
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ PIO_COMPLETION_PACKET Packet;
+
+ /* Get the P List */
+ List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].P;
+
+ /* Try to allocate the Packet */
+ List->L.TotalAllocates++;
+ Packet = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
+
+ /* Check if that failed, use the L list if it did */
+ if (!Packet)
+ {
+ /* Let the balancer know */
+ List->L.AllocateMisses++;
+
+ /* Get L List */
+ List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].L;
+
+ /* Try to allocate the Packet */
+ List->L.TotalAllocates++;
+ Packet = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
+ }
+
+ /* Still failed, use pool */
+ if (!Packet)
+ {
+ /* Let the balancer know */
+ List->L.AllocateMisses++;
+
+ /* Allocate from Nonpaged Pool */
+ Packet = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Packet), IOC_TAG);
+ }
+
+ /* Make sure we have one by now... */
+ if (Packet)
+ {
+ /* Set up the Packet */
+ Packet->PacketType = IrpMiniCompletionPacket;
+ Packet->Key = KeyContext;
+ Packet->Context = ApcContext;
+ Packet->IoStatus.Status = IoStatus;
+ Packet->IoStatus.Information = IoStatusInformation;
+
+ /* Insert the Queue */
+ KeInsertQueue(Queue, &Packet->ListEntry);
+ }
+ else
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Return Success */
+ return STATUS_SUCCESS;
+}