FsRtlpAcknowledgeOplockBreakByCacheFlags
INT64 __fastcall FsRtlpAcknowledgeOplockBreakByCacheFlags(
_NONOPAQUE_OPLOCK *Oplock,
_IO_STACK_LOCATION *AckIrpSp,
_IRP *AckIrp,
UINT64 NewOplockLevel,
_RH_OP_CONTEXT **NewRHOpContext,
UINT64 LowerOplockLevel){
unsigned int v6;
unsigned int v8;
_DELAY_ACK_FO *PoolWithTag;
char v10;
char v11;
unsigned int OplockState;
bool v13;
int v14;
int v15;
unsigned int v16;
_LIST_ENTRY *v17;
_FILE_OBJECT **v18;
int v19;
int v20;
_DELAY_ACK_FO *v21;
int v22;
_IO_STACK_LOCATION *v23;
_FILE_OBJECT *FileObject;
_FILE_OBJECT *v25;
_LIST_ENTRY *p_DelayAckFileObjectQueue;
_LIST_ENTRY *Flink;
_FILE_OBJECT *Blink;
UINT8 v29;
__int64 v30;
_LIST_ENTRY *v31;
_LIST_ENTRY *v32;
_ETHREAD *v33;
_FILE_OBJECT *v34;
unsigned int v35;
__int64 v36;
_LIST_ENTRY *v37;
_DELAY_ACK_FO **DelayAckFo;
UINT8 *ReleaseIrpsWaitingForExclusive;
UINT64 v41;
char v42;
bool RefFileObject;
char v44;
UINT8 v45;
UINT8 DereferenceExclusiveFileObject;
char v47;
int v48;
_DELAY_ACK_FO *v49;
char v50;
char v51;
_LIST_ENTRY *v52;
__int64 v53;
__int64 v54;
_ETHREAD *CurrentThread;
_ETHREAD *v56;
_NONOPAQUE_OPLOCK *Oplocka;
_IO_STACK_LOCATION *AckIrpSpa;
AckIrpSpa = AckIrpSp;
Oplocka = Oplock;
v6 = NewOplockLevel;
v8 = 0;
PoolWithTag = 0i64;
v49 = 0i64;
v42 = 0;
v10 = 0;
v47 = 0;
v50 = 0;
v44 = 0;
v11 = 0;
v51 = 0;
DereferenceExclusiveFileObject = 0;
v45 = 0;
if( !Oplock )
{
*((_DWORD *)AckIrp + 12) = -1073741597;
IofCompleteRequest(AckIrp, 1);
return 3221225699i64;
}
ExAcquireFastMutexUnsafe(Oplock->FastMutex);
OplockState = Oplocka->OplockState;
if( (OplockState & 0xF00000) == 0 && (((OplockState & 0x1F0FFDF) - 12288) & 0xFFFF7FFF) != 0
|| (((OplockState & 0x1F0FFDF) - 12288) & 0xFFFF7FFF) == 0 && Oplocka->RHBreakQueue.Flink == &Oplocka->RHBreakQueue )
{
LABEL_32:
v8 = -1073741597;
*((_DWORD *)AckIrp + 12) = -1073741597;
IofCompleteRequest(AckIrp, 1);
goto LABEL_98;
}
v53 = *((_QWORD *)AckIrp + 3);
v13 = (*(_DWORD *)(v53 + 8) & 4) == 0;
v14 = *(_DWORD *)(v53 + 8) & 4;
v48 = v14;
RefFileObject = !v13;
v15 = 0;
if( v14 )
{
PoolWithTag = (_DELAY_ACK_FO *)ExAllocatePoolWithTag((_POOL_TYPE)17, 0x18ui64, 0x6F725346ui64);
v49 = PoolWithTag;
PoolWithTag->Links = 0i64;
PoolWithTag->OriginalFileObject = 0i64;
v14 = v48;
v15 = 0;
}
v16 = Oplocka->OplockState & 0x1F0FFDF;
if( v16 <= 0x307040 )
{
if( v16 != 3174464 )
{
if( v16 == 12288 || v16 == 45056 || v16 == 1060864 )
goto LABEL_8;
if( v16 != 1069120 && v16 != 1077312 )
goto LABEL_32;
}
LABEL_39:
v23 = AckIrpSpa;
if( !v14 )
goto LABEL_44;
FileObject = Oplocka->FileObject;
v25 = (_FILE_OBJECT *)*((_QWORD *)AckIrpSpa + 6);
if( FileObject == v25 || !FsRtlpOplockKeysEqual(v25, FileObject, 0i64) )
goto LABEL_32;
v14 = v48;
if( !v48 )
{
LABEL_44:
if( Oplocka->FileObject != (_FILE_OBJECT *)*((_QWORD *)v23 + 6) )
goto LABEL_32;
if( !v14 )
goto LABEL_81;
}
if( v6 )
{
LABEL_81:
v35 = Oplocka->OplockState & 0x1F0FFDF;
if( (v35 == 1069120 || v35 == 1077312 || v35 == 3174464 || v35 == 5271616 || v35 == 8409152 || v35 == 8417344)
&& (v6 & 0x7000) > (Oplocka->OplockState & 0x200000 | ((Oplocka->OplockState & 0x100000 | (Oplocka->OplockState >> 1) & 0x200000) >> 1)) >> 7
&& Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
{
v11 = 1;
}
if( v11 )
{
v36 = *((_QWORD *)AckIrp + 3);
*(_OWORD *)v36 = 0i64;
*(_QWORD *)(v36 + 16) = 0i64;
*(_DWORD *)(v36 + 4) = (Oplocka->OplockState >> 12) & 7;
*(_DWORD *)(v36 + 8) = (Oplocka->OplockState & 0x200000 | ((Oplocka->OplockState & 0x100000 | (Oplocka->OplockState >> 1) & 0x200000) >> 1)) >> 19;
*(_DWORD *)(v36 + 12) |= 1u;
*((_QWORD *)AckIrp + 7) = 24i64;
v8 = -2147483602;
*((_DWORD *)AckIrp + 12) = -2147483602;
IofCompleteRequest(AckIrp, 1);
goto LABEL_98;
}
FsRtlpModifyThreadPriorities(Oplocka, 0i64, 0);
FsRtlpClearOwner((INT64)Oplocka, 0i64);
Oplocka->WaiterPriority = 0;
LODWORD(v41) = LowerOplockLevel;
v8 = FsRtlpGrantAnyOplockFromExclusive(
Oplocka,
AckIrp,
v23,
v6,
NewRHOpContext,
RefFileObject,
&v49,
&v45,
&DereferenceExclusiveFileObject,
v41);
PoolWithTag = v49;
goto LABEL_93;
}
FsRtlpModifyThreadPriorities(Oplocka, 0i64, 0);
FsRtlpClearOwner((INT64)Oplocka, 0i64);
Oplocka->WaiterPriority = 0;
Oplocka->OplockState = Oplocka->OplockState & 0x20 | 1;
PoolWithTag->OriginalFileObject = Oplocka->FileObject;
p_DelayAckFileObjectQueue = &Oplocka->DelayAckFileObjectQueue;
Flink = Oplocka->DelayAckFileObjectQueue.Flink;
if( Flink->Blink == &Oplocka->DelayAckFileObjectQueue )
{
PoolWithTag->Links.Flink = Flink;
PoolWithTag->Links.Blink = p_DelayAckFileObjectQueue;
Flink->Blink = &PoolWithTag->Links;
p_DelayAckFileObjectQueue->Flink = &PoolWithTag->Links;
PoolWithTag = 0i64;
v49 = 0i64;
Oplocka->FileObject = 0i64;
Oplocka->OplockState |= 0x1000000u;
*((_DWORD *)AckIrp + 12) = 0;
IofCompleteRequest(AckIrp, 1);
goto LABEL_93;
}
LABEL_80:
__fastfail(3u);
}
if( v16 != 8400896 )
{
if( v16 != 5271616 && v16 != 8409152 && v16 != 8417344 )
goto LABEL_32;
goto LABEL_39;
}
LABEL_8:
v17 = Oplocka->RHBreakQueue.Flink;
while( 1 )
{
v52 = v17;
if( v17 == &Oplocka->RHBreakQueue )
goto LABEL_24;
v18 = (_FILE_OBJECT **)((char *)AckIrpSpa + 48);
if( v14 )
break;
if( (_FILE_OBJECT *)v17[1].Blink == *v18 )
goto LABEL_12;
LABEL_55:
v17 = v17->Flink;
v10 = v47;
}
Blink = (_FILE_OBJECT *)v17[1].Blink;
if( Blink == *v18 )
goto LABEL_55;
v29 = FsRtlpOplockKeysEqual(*v18, Blink, 0i64);
v15 = 0;
v14 = v48;
if( !v29 )
goto LABEL_55;
LABEL_12:
v42 = 1;
v19 = (__int64)v17[3].Flink & 0xF00000;
v20 = LowerOplockLevel;
if( v19 != 0x800000 )
{
if( v19 != 0x100000
|| (v6 & 0x7000) <= 0x3000
|| Oplocka->WaitingIrps.Flink == &Oplocka->WaitingIrps
&& FsRtlpOplockUpperLowerCompatible(v6, (unsigned int)LowerOplockLevel) )
{
goto LABEL_14;
}
v30 = *((_QWORD *)AckIrp + 3);
*(_OWORD *)v30 = 0i64;
*(_QWORD *)(v30 + 16) = 0i64;
*(_DWORD *)(v30 + 4) = 3;
if( Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
v20 = 1;
LABEL_63:
*(_DWORD *)(v30 + 8) = v20;
*(_DWORD *)(v30 + 12) |= 1u;
*((_QWORD *)AckIrp + 7) = 24i64;
v8 = -2147483602;
*((_DWORD *)AckIrp + 12) = -2147483602;
IofCompleteRequest(AckIrp, 1);
goto LABEL_23;
}
if( v6
&& (Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps
|| !FsRtlpOplockUpperLowerCompatible(v6, (unsigned int)LowerOplockLevel)) )
{
v30 = *((_QWORD *)AckIrp + 3);
*(_OWORD *)v30 = 0i64;
*(_QWORD *)(v30 + 16) = 0i64;
*(_DWORD *)(v30 + 4) = 3;
if( Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
v20 = v15;
goto LABEL_63;
}
LABEL_14:
FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)v17);
if( !v22 )
{
v44 = 1;
if( !v6 )
{
ObfDereferenceObjectWithTag(v17[1].Blink, 0x746C6644ui64);
goto LABEL_17;
}
goto LABEL_71;
}
PoolWithTag->OriginalFileObject = (_FILE_OBJECT *)v17[1].Blink;
v31 = &Oplocka->DelayAckFileObjectQueue;
v32 = Oplocka->DelayAckFileObjectQueue.Flink;
if( v32->Blink != &Oplocka->DelayAckFileObjectQueue )
goto LABEL_80;
PoolWithTag->Links.Flink = v32;
PoolWithTag->Links.Blink = v31;
v32->Blink = &PoolWithTag->Links;
v31->Flink = &PoolWithTag->Links;
PoolWithTag = v21;
v49 = v21;
LABEL_17:
if( v6 )
{
LABEL_71:
if( (v6 & 0x4040) == 0 && (v6 & 0x3010) != 0 )
{
LODWORD(ReleaseIrpsWaitingForExclusive) = v20;
LOBYTE(DelayAckFo) = 1;
v8 = FsRtlpRequestShareableOplock(
&Oplocka,
AckIrpSpa,
AckIrp,
v6,
NewRHOpContext,
RefFileObject,
(INT64)DelayAckFo,
(UINT64)ReleaseIrpsWaitingForExclusive);
}
else
{
Oplocka->IrpExclusiveOplock = AckIrp;
v54 = *((_QWORD *)AckIrp + 23);
*(_BYTE *)(v54 + 3) |= 1u;
*((_QWORD *)AckIrp + 7) = Oplocka;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Oplocka->ExclusiveOplockOwner = (_EPROCESS *)*((_QWORD *)CurrentThread + 23);
v33 = (_ETHREAD *)KeGetCurrentThread();
v56 = v33;
Oplocka->ExclusiveOplockOwnerThread = v33;
ObfReferenceObjectWithTag(v33, 0x746C6644u);
Oplocka->WaiterPriority = 0;
if( v48 )
{
ObfReferenceObjectWithTag(*v18, 0x746C6644u);
v34 = *v18;
}
else
{
v34 = (_FILE_OBJECT *)v17[1].Blink;
}
Oplocka->FileObject = v34;
Oplocka->OplockState = v6 | Oplocka->OplockState & 0x20 | 0x40;
*((_BYTE *)AckIrp + 69) = KeAcquireQueuedSpinLock(7ui64);
if( *((_BYTE *)AckIrp + 68) )
{
FsRtlpCancelExclusiveIrp(AckIrp, 1u, !RefFileObject);
}
else
{
_InterlockedExchange64((volatile __int64 *)AckIrp + 13, (__int64)FsRtlpExclusiveIrpCancelRoutine);
KeReleaseQueuedSpinLock(7ui64, *((_BYTE *)AckIrp + 69));
}
v42 = 1;
v17 = v52;
PoolWithTag = v49;
v8 = 259;
}
}
else
{
FsRtlpComputeShareableOplockState(Oplocka);
v8 = 0;
*((_DWORD *)AckIrp + 12) = 0;
IofCompleteRequest(AckIrp, 1);
}
FsRtlpModifyThreadPriorities(Oplocka, (_RH_OP_CONTEXT *)v17, 0);
FsRtlpClearOwner((INT64)Oplocka, (INT64)v17);
if( Oplocka->RHBreakQueue.Flink == &Oplocka->RHBreakQueue )
Oplocka->WaiterPriority = 0;
ExFreePoolWithTag(v17, 0);
if( v48 )
Oplocka->OplockState |= 0x1000000u;
LABEL_23:
v10 = 1;
LABEL_24:
if( !v42 )
goto LABEL_32;
if( v44 )
FsRtlpReleaseIrpsWaitingForRH((INT64)Oplocka);
if( !v10 )
{
LABEL_93:
if( v45 )
{
while( 1 )
{
v37 = Oplocka->WaitingIrps.Flink;
if( v37 == &Oplocka->WaitingIrps )
break;
FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)v37);
}
}
if( DereferenceExclusiveFileObject )
{
ObfDereferenceObjectWithTag(Oplocka->FileObject, 0x746C6644ui64);
Oplocka->FileObject = 0i64;
}
}
LABEL_98:
if( PoolWithTag )
ExFreePoolWithTag(PoolWithTag, 0);
ExReleaseFastMutexUnsafe(Oplocka->FastMutex);
return v8;
}Referenced by:
FsRtlpOplockFsctrlInternal