CcUnpinFileDataEx
VOID __stdcall CcUnpinFileDataEx(VOID *Bcb, UINT8 ReadOnly, UNMAP_ACTIONS UnmapAction){
void *v3;
__int64 v6;
_KEVENT *v7;
_SHARED_CACHE_MAP *v8;
__int64 v9;
UINT8 CurrentIrql;
signed __int32 v11;
_MI_PARTITION *v12;
_FAST_MUTEX *v13;
_ETHREAD *CurrentThread;
__int64 v15;
char v16;
__int64 v17;
NTSTATUS SessionId;
bool v19;
unsigned __int8 v20;
int v21;
_SHARED_CACHE_MAP *v22;
int v23;
__int64 v24;
__int16 v25;
char *v26;
__int16 v27;
_ETHREAD *v28;
unsigned __int8 v29;
_ETHREAD *v30;
__int16 v31;
unsigned int SpareByte0;
_ETHREAD *v33;
INT64 v34;
unsigned int v35;
bool v36;
__int64 v37;
int v38;
int v39;
_KSPIN_LOCK_QUEUE *volatile Next;
char v41;
_ADJUST_REASON v42;
unsigned __int64 OldIrql_low;
unsigned __int32 v44;
_KEVENT *v45;
__int64 v46;
unsigned int v47;
unsigned int v48;
INT64 v49;
VOID **v50;
VOID **v51;
unsigned __int8 v52;
_ETHREAD *v53;
__int64 v54;
_KEVENT *v55;
unsigned __int64 v56;
char *v57;
__int64 v58;
unsigned int *v59;
unsigned __int64 v60;
__int64 AbOrphanedEntrySummary;
signed __int32 v62;
__int64 v63;
int v64;
__int64 v65;
_KWAIT_BLOCK **v66;
_KWAIT_BLOCK *v67;
_KWAIT_BLOCK *v68;
__int64 Flink;
_KWAIT_BLOCK **Blink;
unsigned __int8 WaitType;
_QWORD *v72;
_DWORD *v73;
char v74;
int v75;
INT64 *v76;
INT64 v77;
char v78;
INT64 v79;
_KLOCK_QUEUE_HANDLE LockQueue;
VOID *Object;
__int64 v82;
__int64 v83;
_KPRCB *Prcb;
int v85;
UINT64 a3;
__int64 v87;
INT64 Entry;
_QWORD *v89;
_KPRCB *CurrentPrcb;
_ETHREAD *v91;
_KWAIT_BLOCK *v92;
_KWAIT_BLOCK *v93;
volatile signed __int32 *v94;
__int64 v95;
__int64 v96;
_KLOCK_QUEUE_HANDLE LockHandle;
_SHARED_CACHE_MAP *SharedCacheMap;
UINT64 SpinCount;
v3 = (void *)(int)UnmapAction;
memset(&LockHandle, 0, sizeof(LockHandle));
if( *(_WORD *)Bcb != 765 )
{
v6 = *((_QWORD *)Bcb + 1);
if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)Bcb + 4) )
{
v7 = *(_KEVENT **)(v6 + 184);
if( v7 )
KeSetEvent(v7, 0, 0);
_InterlockedDecrement((volatile signed __int32 *)(v6 + 544));
}
return;
}
v8 = (_SHARED_CACHE_MAP *)*((_QWORD *)Bcb + 22);
v83 = *((_QWORD *)v8 + 66);
SharedCacheMap = v8;
if( *((_QWORD *)v8 + 21) )
{
v9 = *(_QWORD *)((*((_QWORD *)v8 + 12) & 0xFFFFFFFFFFFFFFF0ui64) + 0x28);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset((volatile signed __int32 *)&SpinLock, 0x1Fu) )
LODWORD(SpinCount) = ExpWaitForSpinLockExclusiveAndAcquire(&SpinLock, CurrentIrql);
v11 = SpinLock;
while( (v11 & 0xBFFFFFFF) != 0x80000000 )
{
if( (v11 & 0x40000000) == 0 )
{
v62 = _InterlockedCompareExchange((volatile signed __int32 *)&SpinLock, v11 | 0x40000000, v11);
v19 = v11 == v62;
v11 = v62;
if( !v19 )
continue;
}
KeYieldProcessorEx(&SpinCount);
v11 = SpinLock;
}
if( *(_QWORD *)v9 )
v12 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8i64 * (*(_WORD *)(*(_QWORD *)v9 + 60i64) & 0x3FF));
else
v12 = &Irp;
LODWORD(SpinLock) = 0;
__writecr8(CurrentIrql);
if( (void *)v83 != v12->Core.PartitionObject->CcPartition )
KeBugCheckEx(0x34u, (PVOID)0x1313, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
v8 = SharedCacheMap;
}
if( (*((_DWORD *)v8 + 38) & 0x200) == 0 || (_DWORD)v3 == 1 )
ReadOnly = 1;
LODWORD(a3) = 0;
v13 = (_FAST_MUTEX *)((char *)v8 + 280);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--CurrentThread->Tcb.SpecialApcDisable;
if( ++CurrentThread->Tcb.AbAllocationRegionCount != 1 )
KeBugCheckEx(0x192u, CurrentThread, (char *)v8 + 280, (PVOID)KeGetCurrentIrql(), 0i64);
LOBYTE(v15) = CurrentThread->Tcb.AbEntrySummary;
v85 = 0;
if( !(_BYTE)v15 )
{
if( !CurrentThread->Tcb.AbOrphanedEntrySummary )
{
v17 = 0i64;
goto LABEL_119;
}
AbOrphanedEntrySummary = CurrentThread->Tcb.AbOrphanedEntrySummary;
CurrentThread->Tcb.AbOrphanedEntrySummary = 0;
LOBYTE(v15) = AbOrphanedEntrySummary | CurrentThread->Tcb.AbEntrySummary;
}
v16 = v15;
_BitScanForward((unsigned int *)&v15, (unsigned __int8)v15);
v85 = v15;
CurrentThread->Tcb.AbEntrySummary = v16 & ~(1 << v15);
v17 = (__int64)&CurrentThread->Tcb.LockEntries[v15];
if( !v17 )
{
LABEL_119:
_interlockedbittestandset((volatile signed __int32 *)&CurrentThread->Tcb.116 + 1, 0x10u);
goto LABEL_23;
}
if( (unsigned __int64)v13 >= 0xFFFF800000000000ui64
&& *((_BYTE *)&MiState[1537] + (((unsigned __int64)v13 >> 39) & 0x1FF)) == 1 )
{
SessionId = MmGetSessionIdEx(CurrentThread->Tcb.ApcState.Process);
}
else
{
SessionId = -1;
}
*(_DWORD *)(v17 + 40) = SessionId;
*(_QWORD *)(v17 + 32) = (unsigned __int64)v13 & 0x7FFFFFFFFFFFFFFCi64;
LABEL_23:
--CurrentThread->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&CurrentThread->Tcb, v13, &a3);
v19 = CurrentThread->Tcb.SpecialApcDisable++ == -1;
if( v19
&& ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152 )
{
KiCheckForKernelApcDelivery();
}
v20 = KeGetCurrentIrql();
__writecr8(1ui64);
if( !_interlockedbittestandreset(&v13->Count, 0) )
ExpAcquireFastMutexContended(v13, (VOID *)v17);
if( v17 )
*(_BYTE *)(v17 + 26) |= 1u;
v13->Owner = KeGetCurrentThread();
v13->OldIrql = v20;
if( !(_DWORD)v3 || (_DWORD)v3 == 1 )
{
v21 = *((_DWORD *)Bcb + 16);
if( !v21 )
KeBugCheckEx(0x34u, (PVOID)0x443, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
v22 = SharedCacheMap;
v23 = v21 - 1;
*((_DWORD *)Bcb + 16) = v23;
}
else
{
if( (_DWORD)v3 != 2 )
KeBugCheckEx(0x34u, (PVOID)0x2047A, v3, 0i64, 0i64);
if( *((_BYTE *)Bcb + 2) )
{
v46 = v83;
v47 = *((_DWORD *)Bcb + 1) >> 12;
*((_BYTE *)Bcb + 2) = 0;
*((_QWORD *)Bcb + 5) = 0i64;
*((_QWORD *)Bcb + 6) = 0i64;
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v46 + 128), &LockHandle);
v22 = SharedCacheMap;
CcDeductDirtyPages(SharedCacheMap, v47);
v48 = 0;
if( *(_DWORD *)(v46 + 496) > v47 )
v48 = *(_DWORD *)(v46 + 496) - v47;
*(_DWORD *)(v46 + 496) = v48;
if( !*((_DWORD *)SharedCacheMap + 28) && *((_DWORD *)SharedCacheMap + 1) )
CcInsertIntoCleanSharedCacheMapList(SharedCacheMap);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
else
{
v22 = SharedCacheMap;
}
v23 = *((_DWORD *)Bcb + 16);
}
if( v23 )
{
if( !ReadOnly )
ExReleaseResourceLite((PERESOURCE)((char *)Bcb + 72));
KeReleaseGuardedMutex(v13);
}
else
{
if( *((_BYTE *)Bcb + 2) )
{
if( *((_QWORD *)Bcb + 23) )
{
v24 = *(_QWORD *)(*((_QWORD *)Bcb + 7) + 8i64);
if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)(*((_QWORD *)Bcb + 7) + 16i64)) )
{
v45 = *(_KEVENT **)(v24 + 184);
if( v45 )
KeSetEvent(v45, 0, 0);
_InterlockedDecrement((volatile signed __int32 *)(v24 + 544));
}
*((_QWORD *)Bcb + 23) = 0i64;
*((_QWORD *)Bcb + 7) = 0i64;
}
if( ReadOnly )
goto LABEL_68;
v25 = *((_WORD *)Bcb + 49);
v26 = (char *)Bcb + 72;
if( (v25 & 0x41) == 1 )
KeBugCheckEx(0x1C6u, (PVOID)0xF, v26, 0i64, 0i64);
v27 = v25 & 1;
if( v27 )
{
v52 = KeGetCurrentIrql();
v53 = (_ETHREAD *)KeGetCurrentThread();
if( v52 > 2u )
KeBugCheckEx(0x1C6u, 0i64, (PVOID)v52, (PVOID)2, 0i64);
if( !v52 && (v53->Tcb._bf_0 & 0x400) == 0 && !v53->Tcb.WaitBlock[3].SpareLong )
KeBugCheckEx(0x1C6u, (PVOID)7, 0i64, 0i64, 0i64);
}
if( v27 )
{
ExpFastResourceLegacyRelease(v26);
goto LABEL_68;
}
v28 = (_ETHREAD *)KeGetCurrentThread();
LockQueue.LockQueue.Lock = (unsigned __int64 *volatile)(v26 + 96);
LockQueue.LockQueue.Next = 0i64;
v29 = KeGetCurrentIrql();
__writecr8(2ui64);
*(_QWORD *)&LockQueue.OldIrql = v29;
if( _InterlockedExchange64((volatile __int64 *)v26 + 12, (__int64)&LockQueue) )
KxWaitForLockOwnerShip((INT64)&LockQueue);
v30 = (_ETHREAD *)KeGetCurrentThread();
v31 = *((_WORD *)v26 + 13);
if( ((v31 & 1) != 0 || *(&WheapDeferredInternalLogsEventLock + 740))
&& ((unsigned __int8)v28 & 3) != 3
&& v28 != v30 )
{
KeBugCheckEx(0x16Eu, v26, v30, v28, 0i64);
}
if( (v31 & 0x80u) != 0 )
{
ExpReleaseResourceExclusiveForThreadLite(v26, v28);
goto LABEL_68;
}
v82 = 0i64;
if( ((unsigned __int8)v28 & 3) != 0 )
SpareByte0 = 0;
else
SpareByte0 = v28->Tcb.SchedulerApc.SpareByte0;
v33 = (_ETHREAD *)*((_QWORD *)v26 + 6);
v34 = (INT64)(v26 + 48);
if( v33 != v28 )
{
v56 = 0i64;
v57 = 0i64;
if( v33 )
v56 = 1i64;
else
v57 = v26 + 48;
if( !SpareByte0
|| (v58 = *((_QWORD *)v26 + 2)) == 0
|| SpareByte0 >= *(_DWORD *)(v58 + 8)
|| (v34 = v58 + 16i64 * SpareByte0, *(_ETHREAD **)v34 != v28) )
{
v59 = (unsigned int *)*((_QWORD *)v26 + 2);
v60 = *((unsigned int *)v26 + 16) + (unsigned __int64)*((unsigned int *)v26 + 18);
if( !v59 || (v34 = (INT64)(v59 + 4), v56 >= v60) )
LABEL_145:
KeBugCheckEx(0xE3u, v26, v28, v59, (PVOID)2);
while( *(_ETHREAD **)v34 != v28 )
{
if( *(_QWORD *)v34 )
{
if( ++v56 == v60 )
goto LABEL_145;
}
else if( !v57 )
{
v57 = (char *)v34;
}
v34 += 16i64;
if( (unsigned int *)v34 == &v59[4 * v59[2]] )
goto LABEL_145;
}
KeGetCurrentThread()->SchedulerApc.SpareByte0 = (v34 - (__int64)v59) >> 4;
}
}
v35 = *(_DWORD *)(v34 + 8) & 7 | (8 * (*(_DWORD *)(v34 + 8) >> 3) - 8);
*(_DWORD *)(v34 + 8) = v35;
if( v35 >= 8 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
__writecr8(LockQueue.OldIrql);
goto LABEL_67;
}
ExpFreeOwnerEntry(v34);
v36 = *((_DWORD *)v26 + 16) <= 1u;
v37 = 0i64;
v87 = 0i64;
if( !v36 )
goto LABEL_54;
if( *((_DWORD *)v26 + 19) )
{
KeCaptureWaitChainHeadEx((_QWORD **)v26 + 5, &v82, &v87);
--*((_DWORD *)v26 + 19);
*((_WORD *)v26 + 13) |= 0x80u;
v38 = 1;
v37 = v87;
}
else
{
if( !*((_DWORD *)v26 + 18) )
{
LABEL_54:
v38 = 0;
goto LABEL_55;
}
v63 = *((_QWORD *)v26 + 4);
*((_QWORD *)v26 + 4) = 0i64;
v82 = v63;
v38 = *((_DWORD *)v26 + 18);
*((_DWORD *)v26 + 18) = 0;
}
LABEL_55:
v39 = v38 - 1;
v19 = v39 + *((_DWORD *)v26 + 16) == 0;
*((_DWORD *)v26 + 16) += v39;
if( v19 )
*((_WORD *)v26 + 12) = 0;
if( !*((_DWORD *)v26 + 19) && !*((_DWORD *)v26 + 18) )
*((_WORD *)v26 + 13) &= 0xF9u;
HIDWORD(a3) = (unsigned __int8)v26[27];
if( v37 )
{
v64 = *((_DWORD *)v26 + 14) & 7;
*((_QWORD *)v26 + 6) = v37;
*((_DWORD *)v26 + 14) = v64 | 8;
}
_m_prefetchw(&LockQueue);
Next = LockQueue.LockQueue.Next;
if( !LockQueue.LockQueue.Next )
{
if( (_KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.LockQueue.Lock,
0i64,
(signed __int64)&LockQueue) == &LockQueue )
goto LABEL_64;
Next = KxWaitForLockChainValid(&LockQueue.LockQueue);
}
LockQueue.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
LABEL_64:
__writecr8(LockQueue.OldIrql);
v41 = 1;
if( v87 )
v41 = 3;
v42 = AdjustUnwait;
if( !v82 )
goto LABEL_67;
v96 = KeGetCurrentIrql();
__writecr8(2ui64);
v65 = v82;
Prcb = KeGetCurrentPrcb();
do
{
v83 = v65;
v95 = *(_QWORD *)v65;
v94 = (volatile signed __int32 *)(v65 + 24);
KiAcquireKobjectLockSafe((VOID *)(v65 + 24));
v66 = (_KWAIT_BLOCK **)(v83 + 32);
v93 = (_KWAIT_BLOCK *)(v83 + 32);
*(_DWORD *)(v83 + 28) = 1;
v67 = *v66;
if( *v66 != (_KWAIT_BLOCK *)v66 )
{
do
{
v68 = v67;
Entry = (INT64)v67;
Flink = (__int64)v67->WaitListEntry.Flink;
v92 = (_KWAIT_BLOCK *)Flink;
Blink = (_KWAIT_BLOCK **)v68->WaitListEntry.Blink;
if( *(_KWAIT_BLOCK **)(Flink + 8) != v68 || *Blink != v68 )
goto LABEL_182;
*Blink = (_KWAIT_BLOCK *)Flink;
*(_QWORD *)(Flink + 8) = Blink;
WaitType = v68->WaitType;
if( WaitType == 1 )
{
if( KiTryUnwaitThread(Prcb, v68, v68->WaitKey, 0i64) )
{
v19 = (*(_DWORD *)(v83 + 28))-- == 1;
if( v19 )
break;
}
}
else
{
if( WaitType == 2 )
{
v68->BlockState = 5;
Object = v68->Thread;
v89 = (char *)Object + 8;
v68->WaitListEntry.Flink = 0i64;
KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
v91 = CurrentPrcb->CurrentThread;
KiAcquireKobjectLockSafe(Object);
v72 = v89;
v73 = Object;
if( (_QWORD *)*v72 == v72
|| *((_DWORD *)Object + 10) >= *((_DWORD *)Object + 11)
|| v91->Tcb.Queue == Object && v91->Tcb.WaitReason == 15 )
{
LABEL_166:
v75 = v73[1];
v73[1] = v75 + 1;
v76 = (INT64 *)*((_QWORD *)v73 + 4);
if( (_DWORD *)*v76 != v73 + 6 )
goto LABEL_182;
v77 = Entry;
*(_QWORD *)Entry = v73 + 6;
*(_QWORD *)(v77 + 8) = v76;
*v76 = v77;
*((_QWORD *)v73 + 4) = v77;
if( !v75 && (_QWORD *)*v72 != v72 )
{
KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)v73);
v73 = Object;
}
}
else
{
KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)Object, Entry);
v73 = Object;
if( !v74 )
{
v72 = v89;
goto LABEL_166;
}
}
_InterlockedAnd(v73, 0xFFFFFF7F);
v19 = (*(_DWORD *)(v83 + 28))-- == 1;
if( v19 )
break;
goto LABEL_173;
}
KiTryUnwaitThread(Prcb, v68, 256i64, 0i64);
}
LABEL_173:
v67 = v92;
}
while( v92 != v93 );
}
_InterlockedAnd(v94, 0xFFFFFF7F);
v65 = v95;
}
while( v95 != v82 );
KiRemoveBoostThread(Prcb, Prcb->CurrentThread);
v79 = HIDWORD(a3);
if( HIDWORD(a3) )
{
v42 = AdjustBoost;
if( v78 > SBYTE4(a3) )
v79 = (unsigned int)v78;
}
if( (v41 & 2) != 0 && v42 == AdjustUnwait )
v79 = 1i64;
KiExitDispatcher(Prcb, 0i64, v42, v79, v96);
v82 = 0i64;
LABEL_67:
__incgsdword(0x8670u);
LABEL_68:
OldIrql_low = LOBYTE(v13->OldIrql);
v13->Owner = 0i64;
v44 = _InterlockedCompareExchange(&v13->Count, 1, 0);
if( v44 )
ExpReleaseFastMutexContended(v13, v44);
__writecr8(OldIrql_low);
KeAbPostRelease(v13);
return;
}
ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)v22 + 13, 0i64);
v50 = (VOID **)*((_QWORD *)Bcb + 2);
v51 = (VOID **)*((_QWORD *)Bcb + 3);
if( v50[1] != (char *)Bcb + 16 || *v51 != (char *)Bcb + 16 )
LABEL_182:
__fastfail(3u);
*v51 = v50;
v50[1] = v51;
if( *((__int64 *)v22 + 4) > 0x2000000 && (*((_DWORD *)v22 + 38) & 0x200) != 0 )
CcAdjustVacbLevelLockCount(v22, *((_QWORD *)Bcb + 1), 0xFFFFFFFFi64, v49);
ExReleasePushLockEx((_DWORD)v22 + 104, 0);
if( *((_QWORD *)Bcb + 23) )
{
v54 = *(_QWORD *)(*((_QWORD *)Bcb + 7) + 8i64);
if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)(*((_QWORD *)Bcb + 7) + 16i64)) )
{
v55 = *(_KEVENT **)(v54 + 184);
if( v55 )
KeSetEvent(v55, 0, 0);
_InterlockedDecrement((volatile signed __int32 *)(v54 + 544));
}
}
KeReleaseGuardedMutex(v13);
CcDeallocateBcb((_BCB *)Bcb);
}
}Referenced by:
CcAcquireByteRangeForWrite
CcGetDirtyPagesHelper
CcPinFileData
CcReleaseByteRangeFromWrite
CcUnpinData
CcUnpinDataForThread
CcUnpinRepinnedBcb
CcZeroDataInCache