FsRtlpOplockCleanup
VOID __stdcall FsRtlpOplockCleanup(_NONOPAQUE_OPLOCK *Oplock, _IO_STACK_LOCATION *IrpSp){
char v3;
char v4;
_IO_STACK_LOCATION *v5;
INT64 v6;
_OPLOCK_FOEXT *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;
_IO_STACK_LOCATION *CurrentStackLocation;
_CCHAR v25;
union {_IRP *MasterIrp;int IrpCount;void *SystemBuffer;} v26;
_LIST_ENTRY *v27;
INT64 v28;
INT64 v29;
UINT64 AccessMode;
char v31;
v3 = 0;
v4 = 0;
v31 = 0;
if( Oplock->OplockState == 1 )
goto LABEL_61;
OplockFullFoExt = IoGetOplockFullFoExt(IrpSp->FileObject);
if( (Oplock->OplockState & 0x1000000) != 0 )
{
for( i = (_NONOPAQUE_OPLOCK *)Oplock->DelayAckFileObjectQueue.Flink;
i != (_NONOPAQUE_OPLOCK *)&Oplock->DelayAckFileObjectQueue;
i = (_NONOPAQUE_OPLOCK *)i->IrpExclusiveOplock )
{
if( v5->FileObject == (_FILE_OBJECT *)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 = 1i64;
break;
}
}
Oplock->OplockState &= ~0x1000000u;
if( Oplock->DelayAckFileObjectQueue.Flink != &Oplock->DelayAckFileObjectQueue )
v4 = v6;
v31 = 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( v5->FileObject == (_FILE_OBJECT *)ExclusiveOplockOwner->Pcb.ThreadListHead.Flink )
{
v13 = (_NONOPAQUE_OPLOCK *)v13->FileObject;
if( LODWORD(ExclusiveOplockOwner->Pcb.ProfileListHead.Flink) == 590400 )
v3 = v6;
v16 = 534i64;
if( LODWORD(ExclusiveOplockOwner->Pcb.ProfileListHead.Flink) != 590400 )
v16 = 0i64;
FsRtlpRemoveAndCompleteReadOnlyIrp((_LIST_ENTRY *)v13->IrpExclusiveOplock, v16, 0i64);
if( v3 )
break;
v5 = IrpSp;
LOBYTE(v6) = 1;
}
v13 = (_NONOPAQUE_OPLOCK *)v13->IrpExclusiveOplock;
}
FsRtlpComputeShareableOplockState(Oplock);
}
if( OplockFullFoExt )
{
v17 = (_RH_OP_CONTEXT *)*((_QWORD *)OplockFullFoExt + 5);
if( v17 )
{
v18 = 0;
if( (v17->Flags & 0xF00000) != 0 )
{
FsRtlpOplockDequeueRH(v17);
FsRtlpModifyThreadPriorities(Oplock, v17, 0);
FsRtlpClearOwner(Oplock, v17);
if( Oplock->RHBreakQueue.Flink == &Oplock->RHBreakQueue )
Oplock->WaiterPriority = 0;
ObfDereferenceObjectWithTag(v17->OplockRequestFileObject, 0x746C6644ui64);
}
else
{
if( (Oplock->OplockState & 0x10000) == 0 || !v17->AtomicLinks.Flink )
{
if( Feature_Servicing_39887415__private_IsEnabled() )
{
LODWORD(v29) = 0;
LODWORD(v28) = 0;
FsRtlpRemoveAndCompleteRHIrp(v17, Oplock, 534i64, 0i64, v28, v29, 0);
}
else
{
LODWORD(AccessMode) = 0;
LODWORD(v29) = 0;
LODWORD(v28) = 0;
FsRtlpRemoveAndBreakRHIrp(v17, Oplock, 1u, 534i64, v28, v29, AccessMode, 0);
}
LABEL_46:
FsRtlpComputeShareableOplockState(Oplock);
if( v18 )
FsRtlpReleaseIrpsWaitingForRH(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(Oplock, v17);
}
ExFreePoolWithTag(v17, 0);
v18 = 1;
goto LABEL_46;
}
}
LABEL_48:
if( IrpSp->FileObject == Oplock->FileObject )
{
OplockState = Oplock->OplockState;
if( (OplockState & 0x1F00F80) == 0 )
{
IrpExclusiveOplock = Oplock->IrpExclusiveOplock;
CurrentStackLocation = Oplock->IrpExclusiveOplock->Tail.CurrentStackLocation;
IrpExclusiveOplock->CancelIrql = KeAcquireQueuedSpinLock(7i64, (INT64)v5, v6);
_InterlockedExchange64((volatile __int64 *)&IrpExclusiveOplock->CancelRoutine, 0i64);
KeReleaseQueuedSpinLock(LockQueueIoCancelLock, IrpExclusiveOplock->CancelIrql);
if( *(_DWORD *)&CurrentStackLocation->Parameters.FileAttributes == 590400 )
{
v26.MasterIrp = (_IRP *)IrpExclusiveOplock->AssociatedIrp;
*(_OWORD *)&v26.MasterIrp->Type = 0i64;
*(_QWORD *)&v26.MasterIrp->Flags = 0i64;
*(_DWORD *)&v26.MasterIrp->Type = 1572865;
v25 = 24;
*(_DWORD *)&v26.MasterIrp->AllocationProcessorNumber = (Oplock->OplockState >> 12) & 7;
IrpExclusiveOplock->IoStatus.Information = 24i64;
}
else
{
IrpExclusiveOplock->IoStatus.Information = 8i64;
v14 = 0;
}
Oplock->IrpExclusiveOplock->IoStatus.Status = v14;
LOBYTE(v25) = 1;
IofCompleteRequest(Oplock->IrpExclusiveOplock, v25);
OplockState = Oplock->OplockState;
v4 = v31;
}
if( (OplockState & 0x80u) == 0 )
ObfDereferenceObjectWithTag(Oplock->FileObject, 0x746C6644ui64);
Oplock->FileObject = 0i64;
Oplock->IrpExclusiveOplock = 0i64;
if( Oplock->ExclusiveOplockOwnerThread )
{
FsRtlpModifyThreadPriorities(Oplock, 0i64, 0);
FsRtlpClearOwner(Oplock, 0i64);
Oplock->WaiterPriority = 0;
}
Oplock->OplockState = Oplock->OplockState & 0x20 | 1;
while( 1 )
{
v27 = Oplock->WaitingIrps.Flink;
if( v27 == &Oplock->WaitingIrps )
break;
FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)v27);
}
}
LABEL_61:
if( v4 )
Oplock->OplockState |= 0x1000000u;
}Referenced by:
FsRtlCheckOplockEx2