return Result;
}
-VOID
+BOOLEAN
NTAPI
-CcpUnpinData(IN PNOCC_BCB RealBcb)
+CcpUnpinData(IN PNOCC_BCB RealBcb, BOOLEAN ReleaseBit)
{
if (RealBcb->RefCount <= 2)
{
{
DPRINT("Triggering exclusive waiter\n");
KeSetEvent(&RealBcb->ExclusiveWait, IO_NO_INCREMENT, FALSE);
- return;
+ return TRUE;
}
}
+ if (RealBcb->RefCount == 2 && !ReleaseBit)
+ return FALSE;
if (RealBcb->RefCount > 1)
{
DPRINT("Removing one reference #%x\n", RealBcb - CcCacheSections);
if (RealBcb->RefCount == 1)
{
DPRINT("Clearing allocation bit #%x\n", RealBcb - CcCacheSections);
+
RtlClearBit(CcCacheBitmap, RealBcb - CcCacheSections);
#ifdef PIN_WRITE_ONLY
&OldProtect);
#endif
}
+
+ return TRUE;
}
\f
VOID
{
PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
ULONG Selected = RealBcb - CcCacheSections;
+ BOOLEAN Released;
ASSERT(RealBcb >= CcCacheSections && RealBcb - CcCacheSections < CACHE_NUM_SECTIONS);
DPRINT("CcUnpinData Bcb #%x (RefCount %d)\n", Selected, RealBcb->RefCount);
CcpLock();
- CcpUnpinData(RealBcb);
+ Released = CcpUnpinData(RealBcb, FALSE);
CcpUnlock();
+
+ if (!Released) {
+ MiFlushMappedSection(RealBcb->BaseAddress, &RealBcb->FileOffset, &RealBcb->Map->FileSizes.FileSize, RealBcb->Dirty);
+ CcpLock();
+ CcpUnpinData(RealBcb, TRUE);
+ CcpUnlock();
+ }
}
VOID