diff --git a/NTOSKRNL/CC/ccpinsupport.cpp b/NTOSKRNL/CC/ccpinsupport.cpp index 62efc8c..f567bcc 100644 --- a/NTOSKRNL/CC/ccpinsupport.cpp +++ b/NTOSKRNL/CC/ccpinsupport.cpp @@ -77,10 +77,110 @@ VOID NTAPI CcUnpinFileDataEx( _In_ PCC_BCB Bcb, - _In_ BOOLEAN WriteStatus, - _In_ ULONG Type) + _In_ BOOLEAN& WriteStatus, + _In_ ULONG& UnPinType) { - // Unimplementd + PSHARED_CACHE_MAP SharedCacheMap = nullptr; + KIRQL OldIrql = {0}; + ULONG NumberOfPages = {0}; + BOOLEAN ReadOnly = false; + + + /* If it is not BCB Ptr,it must be VACB Pointer, free it*/ + if (Bcb->NodeTypeCode != BCB_NODE_TYPE_CODE) + { + PVACB Vacb = reinterpret_cast(Bcb); + + CcFreeVirtualAddress(Vacb); + + return; + } + + SharedCacheMap = Bcb->SharedCacheMap; + /* Is it only Unpinning if so is their no write performed by Cache Controller */ + if (!(SharedCacheMap->Flags & SHARED_CACHE_MAP_MODIFIED_NO_WRITE) || UnPinType == UnPin) + ReadOnly = TRUE; + + OldIrql = KeAcquireSpinLockRaiseToDpc(&SharedCacheMap->BcbSpinLock); + /* Just reduce pin count if BCB is not set to be cleaned else perform cleaning of BCB*/ + if (UnPinType < CLEAN_BCB_PIN) + { + ASSERT(Bcb->PinCount > 0); + Bcb->PinCount--; + } + else + { + if (UnPinType != CLEAN_BCB_PIN) + KeBugCheckEx(UNEXPECTED_VALUE, UnPinType, (ULONG_PTR)Bcb, 0, 0); + + if (Bcb->IsBCBDirty) + { + NumberOfPages = (Bcb->Length / PAGE_SIZE); + + Bcb->IsBCBDirty = FALSE; + Bcb->NewestDirtiedPage = 0; + Bcb->NewestLsn.QuadPart = 0; + + CcDeductIsBCBDirtyPages(SharedCacheMap, NumberOfPages); + /*Adjust page count */ + if (CcPagesYetToWrite <= NumberOfPages) + CcPagesYetToWrite = 0; + else + CcPagesYetToWrite -= NumberOfPages; + + if (!SharedCacheMap->IsBCBDirtyPages && SharedCacheMap->OpenCount) + CcInsertIntoCleanSharedCacheMapList(SharedCacheMap); + } + } + + if (Bcb->PinCount) + { /* If not read only BCB, release resources,their no point being pinned at that case */ + if (!ReadOnly) + ExReleaseResourceLite(&Bcb->BcbResource); + + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + } + /*if BCB is dirty, free the virtual adress*/ + else if (Bcb->IsBCBDirty) + { + if (Bcb->BaseAddress) + { + CcFreeVirtualAddress(Bcb->Vacb); + + Bcb->BaseAddress = NULL; + Bcb->Vacb = NULL; + } + + if (!ReadOnly) + ExReleaseResourceLite(&Bcb->BcbResource); + + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + } + else + { + KeAcquireSpinLockAtDpcLevel(&SharedCacheMap->VacbSpinLock); + + RemoveEntryList(&Bcb->Link); + + if (SharedCacheMap->SectionSize.QuadPart > CACHE_OVERALL_SIZE && + (SharedCacheMap->Flags & SHARED_CACHE_MAP_MODIFIED_NO_WRITE)) + { + CcAdjustVacbLevelLockCount(SharedCacheMap, &Bcb->FileOffset.QuadPart, -1); + } + + KeReleaseSpinLockFromDpcLevel(&SharedCacheMap->VacbSpinLock); + + if (Bcb->BaseAddress) + CcFreeVirtualAddress(Bcb->Vacb); + + if (!ReadOnly) + ExReleaseResourceLite(&Bcb->BcbResource); + + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + + CcDeallocateBcb(Bcb); + } + } BOOLEAN @@ -183,7 +283,7 @@ CcUnpinData( PCC_BCB Bcb = reinterpret_cast(BcbPtr); BOOLEAN WRITE_FLAG = NULL; -if (reinterpret_cast(Bcb) & 1) +if (reinterpret_cast((Bcb & 1)) { WRITE_FLAG = TRUE; Bcb = reinterpret_cast(reinterpret_cast(Bcb) & ~(1)); @@ -206,7 +306,7 @@ if (reinterpret_cast(Bcb) & 1) CcUnpinData(BCB_CURRENT); } -ExFreePoolWithTag(Bcb); +ExFreePoolWithTag(Bcb,NULL); } VOID @@ -217,7 +317,7 @@ CcUnpinDataForThread(IN PVOID BcbPtr, PCC_BCB Bcb = BcbPtr; BOOLEAN WRITE_FLAG = NULL; -if (reinterpret_cast(Bcb) & 1) +if (reinterpret_cast((Bcb & 1)) { WRITE_FLAG = TRUE; Bcb = reinterpret_cast(reinterpret_cast(Bcb) & ~(1)); @@ -241,7 +341,7 @@ if (Bcb->NodeTypeCode != 762) CcUnpinData(BCB_CURRENT); } -ExFreePoolWithTag(Bcb); +ExFreePoolWithTag(Bcb,NULL); }