FsRtlpOplockCleanup
VOID __stdcall FsRtlpOplockCleanup(_NONOPAQUE_OPLOCK *Oplock, _IO_STACK_LOCATION *IrpSp){
char v3;
char v4;
_IO_STACK_LOCATION *v5;
char v6;
INT64 OplockFullFoExt;
_NONOPAQUE_OPLOCK *i;
_LIST_ENTRY *Flink;
_QWORD *v10;
__int64 v11;
_QWORD *v12;
_NONOPAQUE_OPLOCK *v13;
int v14;
_EPROCESS *ExclusiveOplockOwner;
INT64 v16;
_RH_OP_CONTEXT *v17;
char v18;
_QWORD *v19;
__int64 v20;
_QWORD *v21;
unsigned int OplockState;
_IRP *IrpExclusiveOplock;
__int64 v24;
__int64 v25;
_LIST_ENTRY *v26;
INT64 v27;
INT64 v28;
UINT64 v29;
char v30;
v3 = 0;
v4 = 0;
v30 = 0;
if( Oplock->OplockState == 1 )
goto LABEL_61;
OplockFullFoExt = IoGetOplockFullFoExt(*((_QWORD *)IrpSp + 6));
if( (Oplock->OplockState & 0x1000000) != 0 )
{
for( i = (_NONOPAQUE_OPLOCK *)Oplock->DelayAckFileObjectQueue.Flink;
i != (_NONOPAQUE_OPLOCK *)&Oplock->DelayAckFileObjectQueue;
i = (_NONOPAQUE_OPLOCK *)i->IrpExclusiveOplock )
{
if( (_EPROCESS *)*((_QWORD *)v5 + 6) == i->ExclusiveOplockOwner )
{
while( 1 )
{
Flink = Oplock->WaitingIrps.Flink;
if( Flink == &Oplock->WaitingIrps )
break;
FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)Flink);
}
v10 = *(_QWORD **)i->FileObject;
v11 = *v10;
v12 = (_QWORD *)v10[1];
if( *(_QWORD **)(*v10 + 8i64) != v10 || (_QWORD *)*v12 != v10 )
__fastfail(3u);
*v12 = v11;
*(_QWORD *)(v11 + 8) = v12;
ObfDereferenceObjectWithTag(i->ExclusiveOplockOwner, 0x746C6644ui64);
ExFreePoolWithTag(i, 0);
v5 = IrpSp;
v6 = 1;
break;
}
}
Oplock->OplockState &= ~0x1000000u;
if( Oplock->DelayAckFileObjectQueue.Flink != &Oplock->DelayAckFileObjectQueue )
v4 = v6;
v30 = v4;
}
v13 = (_NONOPAQUE_OPLOCK *)Oplock->IrpOplocksR.Flink;
v14 = 534;
if( v13 != (_NONOPAQUE_OPLOCK *)&Oplock->IrpOplocksR )
{
while( v13 != (_NONOPAQUE_OPLOCK *)&Oplock->IrpOplocksR )
{
ExclusiveOplockOwner = v13->ExclusiveOplockOwner;
if( *((_QWORD *)v5 + 6) == *((_QWORD *)ExclusiveOplockOwner + 6) )
{
v13 = (_NONOPAQUE_OPLOCK *)v13->FileObject;
if( *((_DWORD *)ExclusiveOplockOwner + 6) == 590400 )
v3 = v6;
v16 = 534i64;
if( *((_DWORD *)ExclusiveOplockOwner + 6) != 590400 )
v16 = 0i64;
FsRtlpRemoveAndCompleteReadOnlyIrp((LIST_ENTRY *)v13->IrpExclusiveOplock, v16, 0i64);
if( v3 )
break;
v5 = IrpSp;
v6 = 1;
}
v13 = (_NONOPAQUE_OPLOCK *)v13->IrpExclusiveOplock;
}
FsRtlpComputeShareableOplockState(Oplock);
}
if( OplockFullFoExt )
{
v17 = *(_RH_OP_CONTEXT **)(OplockFullFoExt + 40);
if( v17 )
{
v18 = 0;
if( (v17->Flags & 0xF00000) != 0 )
{
FsRtlpOplockDequeueRH(v17);
FsRtlpModifyThreadPriorities(Oplock, v17, 0);
FsRtlpClearOwner((INT64)Oplock, (INT64)v17);
if( Oplock->RHBreakQueue.Flink == &Oplock->RHBreakQueue )
Oplock->WaiterPriority = 0;
ObfDereferenceObjectWithTag(v17->OplockRequestFileObject, 0x746C6644ui64);
}
else
{
if( (Oplock->OplockState & 0x10000) == 0 || !v17->AtomicLinks.Flink )
{
if( (unsigned int)Feature_Servicing_39887415__private_IsEnabled() )
{
LODWORD(v28) = 0;
LODWORD(v27) = 0;
FsRtlpRemoveAndCompleteRHIrp((INT64)v17, (INT64)Oplock, 534i64, 0i64, v27, v28, 0);
}
else
{
LODWORD(v29) = 0;
LODWORD(v28) = 0;
LODWORD(v27) = 0;
FsRtlpRemoveAndBreakRHIrp(&v17->Links, Oplock, 1u, 534i64, v27, v28, v29, 0);
}
LABEL_46:
FsRtlpComputeShareableOplockState(Oplock);
if( v18 )
FsRtlpReleaseIrpsWaitingForRH((INT64)Oplock);
goto LABEL_48;
}
FsRtlpOplockDequeueRH(v17);
v20 = *v19;
v21 = (_QWORD *)v19[1];
if( *(_QWORD **)(*v19 + 8i64) != v19 || (_QWORD *)*v21 != v19 )
__fastfail(3u);
*v21 = v20;
*(_QWORD *)(v20 + 8) = v21;
if( Oplock->AtomicQueue.Flink == &Oplock->AtomicQueue )
Oplock->OplockState &= 0xFFFCFFFF;
if( v17->OplockOwnerThread )
FsRtlpClearOwner((INT64)Oplock, (INT64)v17);
}
ExFreePoolWithTag(v17, 0);
v18 = 1;
goto LABEL_46;
}
}
LABEL_48:
if( (_FILE_OBJECT *)*((_QWORD *)IrpSp + 6) == Oplock->FileObject )
{
OplockState = Oplock->OplockState;
if( (OplockState & 0x1F00F80) == 0 )
{
IrpExclusiveOplock = Oplock->IrpExclusiveOplock;
v24 = *((_QWORD *)Oplock->IrpExclusiveOplock + 23);
*((_BYTE *)IrpExclusiveOplock + 69) = KeAcquireQueuedSpinLock(7ui64);
_InterlockedExchange64((volatile __int64 *)IrpExclusiveOplock + 13, 0i64);
KeReleaseQueuedSpinLock(7ui64, *((_BYTE *)IrpExclusiveOplock + 69));
if( *(_DWORD *)(v24 + 24) == 590400 )
{
v25 = *((_QWORD *)IrpExclusiveOplock + 3);
*(_OWORD *)v25 = 0i64;
*(_QWORD *)(v25 + 16) = 0i64;
*(_DWORD *)v25 = 1572865;
*(_DWORD *)(v25 + 4) = (Oplock->OplockState >> 12) & 7;
*((_QWORD *)IrpExclusiveOplock + 7) = 24i64;
}
else
{
*((_QWORD *)IrpExclusiveOplock + 7) = 8i64;
v14 = 0;
}
*((_DWORD *)Oplock->IrpExclusiveOplock + 12) = v14;
IofCompleteRequest(Oplock->IrpExclusiveOplock, 1);
OplockState = Oplock->OplockState;
v4 = v30;
}
if( (OplockState & 0x80u) == 0 )
ObfDereferenceObjectWithTag(Oplock->FileObject, 0x746C6644ui64);
Oplock->FileObject = 0i64;
Oplock->IrpExclusiveOplock = 0i64;
if( Oplock->ExclusiveOplockOwnerThread )
{
FsRtlpModifyThreadPriorities(Oplock, 0i64, 0);
FsRtlpClearOwner((INT64)Oplock, 0i64);
Oplock->WaiterPriority = 0;
}
Oplock->OplockState = Oplock->OplockState & 0x20 | 1;
while( 1 )
{
v26 = Oplock->WaitingIrps.Flink;
if( v26 == &Oplock->WaitingIrps )
break;
FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)v26);
}
}
LABEL_61:
if( v4 )
Oplock->OplockState |= 0x1000000u;
}Referenced by:
FsRtlCheckOplockEx2