/* FUNCTIONS *****************************************************************/
+_Function_class_(KDEFERRED_ROUTINE)
VOID
NTAPI
CmpDelayCloseDpcRoutine(IN PKDPC Dpc,
ExQueueWorkItem(&CmpDelayCloseWorkItem, DelayedWorkQueue);
}
+_Function_class_(WORKER_THREAD_ROUTINE)
VOID
NTAPI
CmpDelayCloseWorker(IN PVOID Context)
INIT_FUNCTION
CmpInitializeDelayedCloseTable(VOID)
{
-
+
/* Setup the delayed close lock */
KeInitializeGuardedMutex(&CmpDelayedCloseTableLock);
-
+
/* Setup the work item */
ExInitializeWorkItem(&CmpDelayCloseWorkItem, CmpDelayCloseWorker, NULL);
-
+
/* Setup the list head */
InitializeListHead(&CmpDelayedLRUListHead);
-
+
/* Setup the DPC and its timer */
KeInitializeDpc(&CmpDelayCloseDpc, CmpDelayCloseDpcRoutine, NULL);
KeInitializeTimer(&CmpDelayCloseTimer);
}
+_Function_class_(KDEFERRED_ROUTINE)
VOID
NTAPI
CmpDelayDerefKCBDpcRoutine(IN PKDPC Dpc,
ExQueueWorkItem(&CmpDelayDerefKCBWorkItem, DelayedWorkQueue);
}
+_Function_class_(WORKER_THREAD_ROUTINE)
VOID
NTAPI
CmpDelayDerefKCBWorker(IN PVOID Context)
{
/* Grab an entry */
Entry = (PVOID)RemoveHeadList(&CmpDelayDerefKCBListHead);
-
+
/* We can release the lock now */
KeReleaseGuardedMutex(&CmpDelayDerefKCBLock);
-
+
/* Now grab the actual entry */
Entry = CONTAINING_RECORD(Entry, CM_DELAY_DEREF_KCB_ITEM, ListEntry);
Entry->ListEntry.Flink = Entry->ListEntry.Blink = NULL;
-
+
/* Dereference and free */
CmpDereferenceKeyControlBlock(Entry->Kcb);
CmpFreeDelayItem(Entry);
-
+
/* Lock the list again */
KeAcquireGuardedMutex(&CmpDelayDerefKCBLock);
}
-
+
/* We're done */
CmpDelayDerefKCBWorkItemActive = FALSE;
KeReleaseGuardedMutex(&CmpDelayDerefKCBLock);
{
LARGE_INTEGER Timeout;
PAGED_CODE();
-
+
/* Set the worker active */
CmpDelayCloseWorkItemActive = TRUE;
PCM_DELAYED_CLOSE_ENTRY Entry;
ULONG NewRefCount, OldRefCount;
PAGED_CODE();
-
+
/* Sanity checks */
ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
(CmpTestRegistryLockExclusive() == TRUE));
if (Kcb->DelayedCloseIndex == CmpDelayedCloseSize) ASSERT(FALSE);
-
+
/* Get the entry and lock the table */
Entry = Kcb->DelayCloseEntry;
ASSERT(Entry);
KeAcquireGuardedMutex(&CmpDelayedCloseTableLock);
-
+
/* Remove the entry */
RemoveEntryList(&Entry->DelayedLRUList);
-
+
/* Release the lock */
KeReleaseGuardedMutex(&CmpDelayedCloseTableLock);
-
+
/* Free the entry */
CmpFreeDelayItem(Entry);
-
+
/* Reduce the number of elements */
InterlockedDecrement((PLONG)&CmpDelayedCloseElements);
-
+
/* Sanity check */
if (!Kcb->InDelayClose) ASSERT(FALSE);
-
+
/* Get the previous reference count */
OldRefCount = *(PLONG)&Kcb->InDelayClose;
ASSERT(OldRefCount == 1);
-
+
/* Write the new one */
NewRefCount = 0;
if (InterlockedCompareExchange((PLONG)&Kcb->InDelayClose,
/* Sanity check */
ASSERT(FALSE);
}
-
+
/* Remove the link to the entry */
Kcb->DelayCloseEntry = NULL;
-
+
/* Set new delay size and remove the delete flag */
Kcb->DelayedCloseIndex = CmpDelayedCloseSize;
}