MiUnlockMdlWritePages
VOID __stdcall MiUnlockMdlWritePages(UINT64 *Page, UINT64 *LastPage, _IO_STATUS_BLOCK *IoStatus){
UINT64 *v4;
_MMPFN *PfnDb;
_MMPFN *v6;
unsigned __int8 CurrentIrql;
__int64 v8;
__int64 v9;
_MI_PARTITION *v10;
struct _KPRCB *CurrentPrcb;
__int64 CachedCommit;
__int64 v13;
unsigned __int64 v14;
struct _KPRCB *v15;
__int64 CachedResidentAvailable;
bool v17;
signed __int32 v18;
unsigned __int64 v19;
unsigned __int64 HighCommitThreshold;
unsigned __int64 LowCommitThreshold;
__int64 v22;
_KLOCK_QUEUE_HANDLE LockHandle;
UINT64 SpinCount;
if( Page < LastPage )
{
v4 = Page;
PfnDb = MmGetPfnDb();
do
{
v6 = &PfnDb[*v4];
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v6->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v6->u2._bf_0 < 0 );
}
v8 = 1i64;
v9 = ((unsigned __int64)v6->u4._bf_0 >> 39) & 0x3FF;
memset(&LockHandle, 0, sizeof(LockHandle));
v10 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v9);
if( !v10->Commit.OverCommit
|| (KeAcquireInStackQueuedSpinLock(&v10->Commit.EventLock, &LockHandle),
LODWORD(v22) = MiRestockOverCommit((INT64)v10, 1ui64),
v8 = v22,
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle),
__writecr8(LockHandle.OldIrql),
v8) )
{
if( v10 == &Irp
&& (CurrentPrcb = KeGetCurrentPrcb(),
_m_prefetchw((const void *)&CurrentPrcb->CachedCommit),
CachedCommit = CurrentPrcb->CachedCommit,
(unsigned __int64)(v8 + CachedCommit) <= 0x100) )
{
while( 1 )
{
v13 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedCommit,
CachedCommit + v8,
CachedCommit);
if( v13 == CachedCommit )
break;
CachedCommit = v13;
if( (unsigned __int64)(v13 + v8) > 0x100 )
goto LABEL_14;
}
}
else
{
LABEL_14:
v19 = _InterlockedExchangeAdd64((volatile signed __int64 *)&v10->Vp.TotalCommittedPages, -v8);
HighCommitThreshold = v10->Commit.HighCommitThreshold;
if( v19 >= HighCommitThreshold && v19 - v8 < HighCommitThreshold
|| (LowCommitThreshold = v10->Commit.LowCommitThreshold, v19 >= LowCommitThreshold)
&& v19 - v8 < LowCommitThreshold )
{
MiSyncCommitSignals(v10, 0i64);
}
}
}
v14 = 1i64;
if( v10 != &Irp )
goto LABEL_22;
v15 = KeGetCurrentPrcb();
CachedResidentAvailable = (int)v15->CachedResidentAvailable;
if( (_DWORD)CachedResidentAvailable == -1 )
goto LABEL_22;
if( (unsigned __int64)(CachedResidentAvailable + 1) <= 0x100 )
{
do
{
v18 = _InterlockedCompareExchange(
(volatile signed __int32 *)&v15->CachedResidentAvailable,
CachedResidentAvailable + 1,
CachedResidentAvailable);
v17 = (_DWORD)CachedResidentAvailable == v18;
LODWORD(CachedResidentAvailable) = v18;
if( v17 )
goto LABEL_12;
}
while( v18 != -1 && (unsigned __int64)(v18 + 1i64) <= 0x100 );
}
if( (int)CachedResidentAvailable > 192
&& (_DWORD)CachedResidentAvailable != -1
&& (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
(volatile signed __int32 *)&v15->CachedResidentAvailable,
192,
CachedResidentAvailable) )
{
v14 = (int)CachedResidentAvailable - 192 + 1i64;
}
if( v14 )
LABEL_22:
_InterlockedExchangeAdd64((volatile signed __int64 *)&v10->Vp.ResidentAvailablePages, v14);
LABEL_12:
MiWriteCompletePfn(v6);
_InterlockedAnd64(&v6->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(CurrentIrql);
++v4;
PfnDb = MmGetPfnDb();
}
while( v4 < LastPage );
}
}Referenced by:
MiFlushComplete
MiUnlockFlushMdl