Index: cc/cacheman.c =================================================================== --- ntoskrnl/cc/cacheman.c (revision 71904) +++ ntoskrnl/cc/cacheman.c (working copy) @@ -14,6 +14,10 @@ #include PFSN_PREFETCHER_GLOBALS CcPfGlobals; +#if CC_MAP_DEBUGGING +extern KGUARDED_MUTEX CcMappedBcbsMutex; +extern LIST_ENTRY CcMappedBcbsList; +#endif /* FUNCTIONS *****************************************************************/ @@ -40,6 +44,10 @@ INIT_FUNCTION CcInitializeCacheManager(VOID) { +#if CC_MAP_DEBUGGING + KeInitializeGuardedMutex(&CcMappedBcbsMutex); + InitializeListHead(&CcMappedBcbsList); +#endif CcInitView(); return TRUE; } Index: cc/pin.c =================================================================== --- ntoskrnl/cc/pin.c (revision 71904) +++ ntoskrnl/cc/pin.c (working copy) @@ -18,6 +18,11 @@ extern NPAGED_LOOKASIDE_LIST iBcbLookasideList; +#if CC_MAP_DEBUGGING +KGUARDED_MUTEX CcMappedBcbsMutex; +LIST_ENTRY CcMappedBcbsList; +#endif + /* FUNCTIONS *****************************************************************/ /* @@ -122,6 +127,13 @@ iBcb->Pinned = FALSE; iBcb->RefCount = 1; ExInitializeResourceLite(&iBcb->Lock); +#if CC_MAP_DEBUGGING + KeAcquireGuardedMutex(&CcMappedBcbsMutex); + InsertTailList(&CcMappedBcbsList, &iBcb->MappedBcbsEntry); + RtlZeroMemory(iBcb->Backtrace, sizeof(iBcb->Backtrace)); + RtlCaptureStackBackTrace(0, 16, iBcb->Backtrace, NULL); + KeReleaseGuardedMutex(&CcMappedBcbsMutex); +#endif *pBcb = (PVOID)iBcb; CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> TRUE Bcb=%p\n", @@ -264,6 +276,38 @@ CcUnpinDataForThread(Bcb, (ERESOURCE_THREAD)PsGetCurrentThread()); } +#if CC_MAP_DEBUGGING +VOID +CcDumpMappedBcbs(VOID) +{ + PLIST_ENTRY Entry; + PINTERNAL_BCB iBcb; + ULONG i; + + DPRINT1("*** Dumping Mapped BCBs ***\n"); + KeAcquireGuardedMutex(&CcMappedBcbsMutex); + Entry = CcMappedBcbsList.Flink; + while (Entry != &CcMappedBcbsList) + { + iBcb = CONTAINING_RECORD(Entry, INTERNAL_BCB, MappedBcbsEntry); + Entry = Entry->Flink; + + DPRINT1("BCB %p mapped with backtrace:\n", iBcb); + for (i = 0; i < 16; i++) + { + if (iBcb->Backtrace[i] == NULL) + { + break; + } + DPRINT1("%p\n", iBcb->Backtrace[i]); + } + DPRINT1("---end---\n"); + } + KeReleaseGuardedMutex(&CcMappedBcbsMutex); + DPRINT1("*** End of Mapped BCB Dump ***\n"); +} +#endif + /* * @unimplemented */ @@ -296,6 +340,11 @@ TRUE, iBcb->Dirty, FALSE); +#if CC_MAP_DEBUGGING + KeAcquireGuardedMutex(&CcMappedBcbsMutex); + RemoveEntryList(&iBcb->MappedBcbsEntry); + KeReleaseGuardedMutex(&CcMappedBcbsMutex); +#endif if (--iBcb->RefCount == 0) { Index: include/internal/cc.h =================================================================== --- ntoskrnl/include/internal/cc.h (revision 71904) +++ ntoskrnl/include/internal/cc.h (working copy) @@ -191,6 +191,7 @@ /* Pointer to the next VACB in a chain. */ } ROS_VACB, *PROS_VACB; +#define CC_MAP_DEBUGGING 1 typedef struct _INTERNAL_BCB { /* Lock */ @@ -200,6 +201,10 @@ BOOLEAN Dirty; BOOLEAN Pinned; CSHORT RefCount; /* (At offset 0x34 on WinNT4) */ +#if CC_MAP_DEBUGGING + LIST_ENTRY MappedBcbsEntry; + PVOID Backtrace[16]; +#endif } INTERNAL_BCB, *PINTERNAL_BCB; VOID Index: io/iomgr/irp.c =================================================================== --- ntoskrnl/io/iomgr/irp.c (revision 71904) +++ ntoskrnl/io/iomgr/irp.c (working copy) @@ -1185,6 +1185,8 @@ IoQueueThreadIrp(Irp); } +VOID CcDumpPinnedBcbs(VOID); + /* * @implemented */ @@ -1218,8 +1220,40 @@ StackPtr->DeviceObject = DeviceObject; /* Call it */ +#if DBG + { + KIRQL OldIrql; + PKTHREAD Thread; + ULONG CombinedApcDisable; + NTSTATUS Status; + UCHAR MajorFunction; + + Thread = KeGetCurrentThread(); + OldIrql = KeGetCurrentIrql(); + CombinedApcDisable = Thread->CombinedApcDisable; + MajorFunction = StackPtr->MajorFunction; + + Status = DriverObject->MajorFunction[MajorFunction](DeviceObject, + Irp); + if (KeGetCurrentIrql() != OldIrql || + Thread->CombinedApcDisable != CombinedApcDisable) + { + DPRINT1("Dispatch function %p (major %u) changed IRQL (%u -> %u) or APC state (0x%lx -> 0x%lx)\n", + DriverObject->MajorFunction[MajorFunction], MajorFunction, OldIrql, KeGetCurrentIrql(), CombinedApcDisable, Thread->CombinedApcDisable); + DPRINT1("%wZ: Major: %x, minor: %x\n", &DriverObject->DriverName, StackPtr->MajorFunction, StackPtr->MinorFunction); + if (StackPtr->FileObject) DPRINT1("Involved FN: %wZ\n", &StackPtr->FileObject->FileName); +#if CC_MAP_DEBUGGING + CcDumpMappedBcbs(); +#endif + NT_ASSERT(KeGetCurrentIrql() == OldIrql); + NT_ASSERT(Thread->CombinedApcDisable == CombinedApcDisable); + } + return Status; + } +#else return DriverObject->MajorFunction[StackPtr->MajorFunction](DeviceObject, Irp); +#endif } FORCEINLINE