FsRtlpRequestExclusiveOplock
VOID __stdcall FsRtlpRequestExclusiveOplock(
_NONOPAQUE_OPLOCK **Oplock,
_IO_STACK_LOCATION *IrpSp,
_IRP *Irp,
UINT64 OpenCount,
UINT64 FsctrlFlags,
UINT64 NextOplockState,
UINT64 LowerOplockLevel){
unsigned int v7;
_IO_STACK_LOCATION *v9;
_NONOPAQUE_OPLOCK *v11;
INT64 v12;
int v13;
char v14;
_RH_OP_CONTEXT *v15;
_LIST_ENTRY *Flink;
_LIST_ENTRY *Blink;
int v18;
_CCHAR v19;
_WAITING_IRP *i;
_WAITING_IRP *v21;
_RH_OP_CONTEXT *v22;
_LIST_ENTRY *v23;
_LIST_ENTRY *v24;
char v25;
unsigned int OplockState;
char v27;
int v28;
_ETHREAD *CurrentThread;
INT64 v30;
INT64 v31;
int v32;
INT64 v33;
INT64 v34;
char v35;
__int64 v36;
__int64 MasterIrp;
_LIST_ENTRY *p_IrpOplocksRH;
_LIST_ENTRY *m;
char v40;
__int64 n;
__int64 *v42;
_BOOL4 v43;
VOID *v44;
_LIST_ENTRY *p_IrpOplocksR;
_LIST_ENTRY *j;
char v47;
_LIST_ENTRY *k;
_LIST_ENTRY **p_Flink;
_RH_OP_CONTEXT **v50;
INT64 v51;
UINT64 AccessMode;
INT64 a3;
__int64 v54;
_NONOPAQUE_OPLOCK *v55;
_IRP *IrpExclusiveOplock;
__int64 v57;
_LIST_ENTRY *v58;
_IO_STACK_LOCATION *CurrentStackLocation;
unsigned int v61;
v61 = OpenCount;
v7 = OpenCount;
v9 = IrpSp;
a3 = 0i64;
v11 = *Oplock;
if( !*Oplock )
{
v11 = FsRtlpAllocateOplock();
*Oplock = v11;
}
v55 = v11;
ExAcquireFastMutexUnsafe(v11->FastMutex);
if( (v11->OplockState & 0x10000) != 0 && v9->MajorFunction == 13 )
{
FsRtlpCallerIsAtomicRequestor((INT64)v11, v9->FileObject, (INT64)&a3, v12, v50);
if( v14 )
{
if( (v13 & 0x20000) != 0 )
{
v15 = (_RH_OP_CONTEXT *)a3;
FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)a3);
Flink = v15->AtomicLinks.Flink;
Blink = v15->AtomicLinks.Blink;
if( Flink->Blink != &v15->AtomicLinks || Blink->Flink != &v15->AtomicLinks )
__fastfail(3u);
Blink->Flink = Flink;
Flink->Blink = Blink;
if( v11->AtomicQueue.Flink == &v11->AtomicQueue )
v11->OplockState &= 0xFFFCFFFF;
if( v15->OplockOwnerThread )
FsRtlpClearOwner(v11, v15);
ExFreePoolWithTag(v15, 0);
a3 = 0i64;
FsRtlpComputeShareableOplockState(v11);
LABEL_14:
v18 = -1073741598;
LABEL_15:
v19 = 1;
goto LABEL_104;
}
for( i = (_WAITING_IRP *)v11->WaitingIrps.Flink;
i != (_WAITING_IRP *)&v11->WaitingIrps;
i = (_WAITING_IRP *)i->Links.Flink )
{
v21 = i;
if( !i->OplockBreakNotify )
{
i = (_WAITING_IRP *)i->Links.Blink;
FsRtlpRemoveAndCompleteWaitingIrp(v21);
}
}
v22 = (_RH_OP_CONTEXT *)a3;
FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)a3);
v23 = v22->AtomicLinks.Flink;
v24 = v22->AtomicLinks.Blink;
if( v23->Blink != &v22->AtomicLinks || v24->Flink != &v22->AtomicLinks )
__fastfail(3u);
v24->Flink = v23;
v23->Blink = v24;
if( v11->AtomicQueue.Flink == &v11->AtomicQueue )
v11->OplockState &= 0xFFFCFFFF;
if( v22->OplockOwnerThread )
FsRtlpClearOwner(v11, v22);
ExFreePoolWithTag(v22, 0);
a3 = 0i64;
FsRtlpComputeShareableOplockState(v11);
v9 = IrpSp;
}
}
if( !FsRtlpOplockUpperLowerCompatible((unsigned int)NextOplockState, (unsigned int)LowerOplockLevel) )
{
Irp->IoStatus.Status = -1073741598;
LOBYTE(v19) = v25;
IofCompleteRequest(Irp, v19);
goto LABEL_105;
}
if( (_DWORD)NextOplockState == 200 )
{
v11->IrpExclusiveOplock = Irp;
v11->FileObject = v9->FileObject;
v11->OplockState = v11->OplockState & 0x20 | 0xC8;
goto LABEL_105;
}
OplockState = v11->OplockState;
if( (OplockState & 0x91) == 0 )
{
if( (OplockState & 0x7000) != 0 && (OplockState & 0x1F00F00) == 0 && v11->RHBreakQueue.Flink == &v11->RHBreakQueue )
{
if( (NextOplockState & 0x10000) != 0 )
goto LABEL_105;
if( (NextOplockState & 0x7000) != 0 && (!v9->FileObject->DeletePending || (NextOplockState & 0x2000) == 0) )
{
v32 = OplockState & 0x1F0FFDF;
if( v32 == 4096 )
{
if( (((_DWORD)NextOplockState - 20544) & 0xFFFFDFFF) == 0 )
{
p_IrpOplocksR = &v11->IrpOplocksR;
for( j = v11->IrpOplocksR.Flink; j != p_IrpOplocksR; j = j->Flink )
{
v58 = j[1].Flink;
FsRtlpOplockKeysEqual(IrpSp->FileObject, (_FILE_OBJECT *)v58[3].Flink, 0i64);
if( !v47 )
{
v18 = -1073741598;
LOBYTE(v19) = 1;
goto LABEL_104;
}
}
v25 = 1;
if( v61 <= 1 || (FsctrlFlags & 1) != 0 )
{
for( k = p_IrpOplocksR->Flink; ; k = *p_Flink )
{
v54 = (__int64)k;
if( k == p_IrpOplocksR )
break;
p_Flink = &k->Blink->Flink;
FsRtlpRemoveAndCompleteReadOnlyIrp(*p_Flink, 533i64, NextOplockState & 0x7000);
}
goto LABEL_54;
}
}
}
else if( v32 == 12288 )
{
if( (_DWORD)NextOplockState == 28736 )
{
p_IrpOplocksRH = &v11->IrpOplocksRH;
for( m = v11->IrpOplocksRH.Flink; m != p_IrpOplocksRH; m = m->Flink )
{
FsRtlpOplockKeysEqual(IrpSp->FileObject, (_FILE_OBJECT *)m[1].Blink, 0i64);
if( !v40 )
goto LABEL_14;
if( m[3].Blink )
{
v18 = -1073741597;
goto LABEL_15;
}
}
v25 = 1;
if( v61 <= 1 || (FsctrlFlags & 1) != 0 )
{
for( n = (__int64)p_IrpOplocksRH->Flink; ; n = *v42 )
{
v54 = n;
if( (_LIST_ENTRY *)n == p_IrpOplocksRH )
break;
v42 = *(__int64 **)(n + 8);
v43 = Feature_Servicing_39887415__private_IsEnabled() != 0;
v44 = (VOID *)*v42;
if( v43 )
{
LODWORD(v51) = 0;
LODWORD(v50) = 0;
FsRtlpRemoveAndCompleteRHIrp(v44, v11, 533i64, 0x7000ui64, (INT64)v50, v51, 0);
}
else
{
LODWORD(AccessMode) = 0;
LODWORD(v51) = 0;
LODWORD(v50) = 28672;
FsRtlpRemoveAndBreakRHIrp(v44, v11, 1u, 533i64, (UINT64)v50, v51, AccessMode, 0);
}
}
goto LABEL_54;
}
}
}
else if( (v32 == 20544 || v32 == 28736 && (_DWORD)NextOplockState == 28736)
&& (((_DWORD)NextOplockState - 20544) & 0xFFFFDFFF) == 0 )
{
FsRtlpOplockKeysEqual(v9->FileObject, v11->FileObject, 0i64);
if( !v35 )
goto LABEL_14;
IrpExclusiveOplock = v11->IrpExclusiveOplock;
v36 = (__int64)IrpExclusiveOplock;
*(_BYTE *)(v36 + 69) = KeAcquireQueuedSpinLock(7i64, v33, v34);
_InterlockedExchange64((volatile __int64 *)(v36 + 104), 0i64);
KeReleaseQueuedSpinLock(LockQueueIoCancelLock, *(_BYTE *)(v36 + 69));
LODWORD(MasterIrp) = (_DWORD)IrpExclusiveOplock;
if( IrpExclusiveOplock->Cancel )
{
*(_QWORD *)(v36 + 56) = 0i64;
*(_DWORD *)(v36 + 48) = -1073741536;
}
else
{
MasterIrp = (__int64)IrpExclusiveOplock->AssociatedIrp.MasterIrp;
v57 = MasterIrp;
*(_OWORD *)MasterIrp = 0i64;
*(_QWORD *)(MasterIrp + 16) = 0i64;
*(_DWORD *)MasterIrp = 1572865;
*(_DWORD *)(MasterIrp + 4) = (v11->OplockState >> 12) & 7;
*(_DWORD *)(MasterIrp + 8) = ((unsigned int)NextOplockState >> 12) & 7;
*(_QWORD *)(v36 + 56) = 24i64;
*(_DWORD *)(v36 + 48) = 533;
}
LOBYTE(MasterIrp) = 1;
IofCompleteRequest((PIRP)v36, MasterIrp);
v11->IrpExclusiveOplock = 0i64;
ObfDereferenceObjectWithTag(v11->FileObject, 0x746C6644ui64);
v11->FileObject = 0i64;
goto LABEL_54;
}
}
LABEL_39:
v18 = -1073741598;
goto LABEL_103;
}
if( (NextOplockState & 0x10000) != 0 )
goto LABEL_105;
LABEL_102:
v18 = -1073741598;
if( !Irp )
goto LABEL_105;
LABEL_103:
LOBYTE(v19) = v25;
LABEL_104:
Irp->IoStatus.Status = v18;
IofCompleteRequest(Irp, v19);
goto LABEL_105;
}
if( (OplockState & 0x10) != 0 )
{
if( (NextOplockState & 0x7000) != 0 )
goto LABEL_37;
v7 = v61;
}
if( (OplockState & 0x80u) != 0 )
{
FsRtlpOplockKeysEqual(v9->FileObject, v11->FileObject, 0i64);
if( !v27 )
{
if( (NextOplockState & 0x10000) != 0 )
goto LABEL_105;
goto LABEL_14;
}
}
v28 = v11->OplockState & 0x1F0FFDF;
if( v28 == 16 || v28 == 4096 || v28 == 4112 )
FsRtlpRemoveAndCompleteReadOnlyIrp(v11->IrpOplocksR.Flink, 0i64, 0i64);
v25 = 1;
if( v7 > 1 && (v11->OplockState & 1) != 0 && (FsctrlFlags & 1) == 0 )
goto LABEL_102;
if( v9->FileObject->DeletePending && (NextOplockState & 0x2000) != 0 )
{
LABEL_37:
if( (NextOplockState & 0x10000) != 0 )
goto LABEL_105;
goto LABEL_39;
}
LABEL_54:
v11->IrpExclusiveOplock = Irp;
v11->FileObject = IrpSp->FileObject;
FsRtlpClearOwner(v11, 0i64);
v11->ExclusiveOplockOwner = KeGetCurrentThread()->ApcState.Process;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v11->ExclusiveOplockOwnerThread = CurrentThread;
ObfReferenceObjectWithTag(CurrentThread, 0x746C6644ui64);
v11->WaiterPriority = 0;
v11->OplockState = NextOplockState | v11->OplockState & 0x20;
ObfReferenceObjectWithTag(IrpSp->FileObject, 0x746C6644ui64);
CurrentStackLocation = Irp->Tail.CurrentStackLocation;
CurrentStackLocation->Control |= 1u;
Irp->IoStatus.Information = (unsigned __int64)v11;
Irp->CancelIrql = KeAcquireQueuedSpinLock(7i64, v30, v31);
if( Irp->Cancel )
{
FsRtlpCancelExclusiveIrp(Irp, 1u, 1u);
}
else
{
_InterlockedExchange64((volatile __int64 *)&Irp->CancelRoutine, (__int64)FsRtlpExclusiveIrpCancelRoutine);
KeReleaseQueuedSpinLock(LockQueueIoCancelLock, Irp->CancelIrql);
}
LABEL_105:
ExReleaseFastMutexUnsafe(v11->FastMutex);
}Referenced by:
FsRtlpOplockFsctrlInternal