diff --git a/NTOSKRNL/CC/ccloghandler.cpp b/NTOSKRNL/CC/ccloghandler.cpp index 039844f..afbcc29 100644 --- a/NTOSKRNL/CC/ccloghandler.cpp +++ b/NTOSKRNL/CC/ccloghandler.cpp @@ -291,12 +291,12 @@ CcSetLogHandleForFileEx( _In_opt_ PFILE_OBJECT RelatedLogHandleFileObject ) { - PSHARED_CACHE_MAP SharedCacheMap; + PSHARED_CACHE_MAP SharedCacheMap = nullptr; KIRQL OldIrql; - LOG_HANDLE_CONTEXT LogHandleContext; - PLOG_HANDLE_CONTEXT VolumeLogHandleContext; - PLIST_ENTRY ListHead; - PLIST_ENTRY PrevEntry; + LOG_HANDLE_CONTEXT LogHandleContext ={0}; + PLOG_HANDLE_CONTEXT VolumeLogHandleContext = nullptr; + PLIST_ENTRY ListHead = nullptr; + PLIST_ENTRY PrevEntry = nullptr; /* Retrieve the Shared Cache Map*/ SharedCacheMap = (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; @@ -379,3 +379,88 @@ CcSetLogHandleForFileEx( KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql); } +VOID +VECTORCALL +CcSetLoggedDataThreshold ( + _In_ PVOID LogHandle, + _In_ ULONG NumberOfPages) +{ + KIRQL OldIrql; + PVOLUME_CACHE_MAP VolumeCacheMap = nullptr; + + + OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock); + + /* Check if the volume cache map list is valid */ + if (!IsListEmpty(&CcVolumeCacheMapList)) + { + /* Iterate through the list to find the matching log handle*/ + for (auto it = ListEntryIterator::begin(&CcVolumeCacheMapList); it != ListEntryIterator::end(&CcVolumeCacheMapList); ++it) + { + VolumeCacheMap = CONTAINING_RECORD(*it, VOLUME_CACHE_MAP, VolumeCacheMapLinks); + if (&VolumeCacheMap->VolumeCacheMapLinks == LogHandle) + { + /* We Found the matching log handle, update the Data threshold */ + VolumeCacheMap->LoggedDataThreshold = NumberOfPages; + break; + } + VolumeCacheMap = NULL; + if(*it = &CcVolumeCacheMapList) + { + break; + } + } + } + + + KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql); +} +VECTORCALL +BOOLEAN +CcIsThereDirtyLoggedPages ( + _In_ PDEVICE_OBJECT DeviceObject, + _Out_opt_ PULONG NumberOfDirtyPages +) +{ + BOOLEAN DirtyPagesExist = false; + KIRQL OldIrql; + PVOLUME_CACHE_MAP VolumeCacheMap = nullptr; + + + OldIrql = KeAcquireQueuedSpinLock(LockQueueCcVolumeCacheMapLock); + + /*Iterate through the volume cache map list to find the matching device object*/ + + for (auto it = ListEntryIterator::begin(&CcVolumeCacheMapList); it != ListEntryIterator::end(&CcVolumeCacheMapList); ++it) + { + VolumeCacheMap = CONTAINING_RECORD(*it, VOLUME_CACHE_MAP, VolumeCacheMapLinks); + if (VolumeCacheMap->DeviceObject == DeviceObject) + { + break; + } + VolumeCacheMap = NULL; + } + + // Ensure that the volume cache map was found + if (VolumeCacheMap != nullptr) + { + // Check if there are dirty pages or logged pages queued to disk + if (VolumeCacheMap->LogHandleContext.DirtyPages || VolumeCacheMap->LoggedPagesQueuedToDisk) + { + if (NumberOfDirtyPages) + { + *NumberOfDirtyPages = VolumeCacheMap->LogHandleContext.DirtyPages + VolumeCacheMap->LoggedPagesQueuedToDisk; + } + DirtyPagesExist = true; + } + } + + + KeReleaseQueuedSpinLock(LockQueueCcVolumeCacheMapLock, OldIrql); + + return DirtyPagesExist; +} + + + +