FsRtlCheckOplockEx2
INT64 __fastcall FsRtlCheckOplockEx2(
PVOID *Oplock,
IRP *Irp,
UINT64 Flags,
INT64 a4,
INT64 a5,
INT64 a6,
INT64 a7,
INT64 a8,
INT64 a9,
INT64 a10){
unsigned int v10;
unsigned int v13;
_NONOPAQUE_OPLOCK *v14;
FAST_MUTEX *v15;
NTSTATUS v16;
int v17;
__int64 v19;
struct _ECP_LIST *v20;
int v21;
__int64 FileObject;
char Count;
ULONG_PTR v24;
ULONG_PTR v25;
unsigned __int8 v26;
__int64 v27;
__int64 v28;
int SessionId;
FAST_MUTEX *v30;
unsigned int v31;
char v32;
int v33;
int Count_low;
__int64 v35;
char Contention_high;
unsigned int Contention;
bool v38;
int v39;
char v40;
unsigned int Lock;
FAST_MUTEX *FastMutex;
unsigned __int32 v43;
__int64 v44;
int v45;
INT64 v46;
char v47;
_QWORD *v48;
__int64 v49;
_QWORD *v50;
_RH_OP_CONTEXT **BugCheckParameter4;
bool v52;
char v53;
bool v54;
char v55[4];
int v56;
int v57;
unsigned int v58;
FAST_MUTEX *Mutex;
int OplockState;
unsigned int v61;
PVOID EcpContext;
__int64 v63;
int v64;
int v65;
int v66;
int v67;
void(__fastcall *v68)(__int128 *);
__int64 v69;
void(__fastcall *v70)(__int64, __int64);
__int64 v71;
PVOID P;
struct _ECP_LIST *ExtraCreateParameter;
__int64 v74;
__int64 v75;
PVOID v76;
_ETHREAD *CurrentThread;
__int64 v78;
GUID EcpType;
v66 = a4;
v10 = Flags;
v67 = Flags;
v63 = a5;
v71 = a6;
v70 = (void(__fastcall *)(__int64, __int64))a7;
v69 = a9;
v68 = (void(__fastcall *)(__int128 *))a10;
v13 = 0;
v58 = 0;
v14 = (_NONOPAQUE_OPLOCK *)*Oplock;
v76 = *Oplock;
if( (_DWORD)a4 )
return 3221225485i64;
v15 = (FAST_MUTEX *)*((_QWORD *)Irp + 23);
Mutex = v15;
if( (Flags & 4) != 0 )
{
P = 0i64;
if( !v14 )
return 0i64;
ExAcquireFastMutexUnsafe(v14->FastMutex);
if( LOBYTE(v15->Count) )
{
v13 = -1073741811;
}
else if( (v14->OplockState & 0x10000) != 0 )
{
FsRtlpCallerIsAtomicRequestor((INT64)v14, *(_FILE_OBJECT **)&v15->OldIrql, (INT64)&P, v46, BugCheckParameter4);
if( v47 )
{
v48 = P;
FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)P);
v49 = v48[7];
v50 = (_QWORD *)v48[8];
if( *(_QWORD **)(v49 + 8) != v48 + 7 || (_QWORD *)*v50 != v48 + 7 )
__fastfail(3u);
*v50 = v49;
*(_QWORD *)(v49 + 8) = v50;
if( v14->AtomicQueue.Flink == &v14->AtomicQueue )
v14->OplockState &= 0xFFFCFFFF;
if( v48[5] )
FsRtlpClearOwner((INT64)v14, (INT64)v48);
ExFreePoolWithTag(v48, 0);
FsRtlpComputeShareableOplockState(v14);
FsRtlpReleaseIrpsWaitingForRH((INT64)v14);
}
}
ExReleaseFastMutexUnsafe(v14->FastMutex);
return v13;
}
if( (Flags & 0x10000000) == 0 )
{
v16 = 0;
if( LOBYTE(v15->Count) )
goto LABEL_5;
v19 = *(_QWORD *)(*(_QWORD *)&v15->OldIrql + 208i64);
if( v19 )
{
if( v19 != IopRevocationExtension )
{
v44 = *(_QWORD *)(v19 + 56);
if( v44 )
{
if( (*(_BYTE *)(v44 + 2) & 3) != 0 )
goto LABEL_5;
}
}
}
EcpContext = 0i64;
ExtraCreateParameter = 0i64;
EcpType = 0i64;
IoGetIrpExtraCreateParameter(Irp, &ExtraCreateParameter);
v20 = ExtraCreateParameter;
if( ExtraCreateParameter )
{
EcpType = GUID_ECP_DUAL_OPLOCK_KEY;
if( FsRtlFindExtraCreateParameter(ExtraCreateParameter, &EcpType, &EcpContext, 0i64) )
{
EcpType = GUID_ECP_OPLOCK_KEY;
if( FsRtlRemoveExtraCreateParameter(v20, &EcpType, &EcpContext, 0i64) )
goto LABEL_15;
v45 = 1;
}
else
{
v45 = 2;
}
v57 = v45;
v15 = Mutex;
v16 = IoSetOplockKeyContext(*(_FILE_OBJECT **)&Mutex->OldIrql, EcpContext, v45);
if( (_WORD)v57 == 1 )
FsRtlFreeExtraCreateParameter(EcpContext);
else
FsRtlAcknowledgeEcp(EcpContext);
if( v16 == -1073741823 )
v16 = 0;
goto LABEL_5;
}
LABEL_15:
v15 = Mutex;
LABEL_5:
v58 = v16;
}
FsRtlpOplockStoreKeyForDeleteOperation(Oplock, Irp, v10);
if( v14 != *Oplock )
{
v14 = (_NONOPAQUE_OPLOCK *)*Oplock;
v76 = *Oplock;
}
if( (v10 & 2) == 0 && v14 && (*((_DWORD *)Irp + 4) & 2) == 0 && !v58 )
{
v52 = (v10 & 0x20000000) != 0;
v53 = 1;
while( 1 )
{
v55[0] = 0;
v21 = v10 & 0x10;
v57 = v21;
if( (v10 & 0x10) == 0 && !v52 )
{
OplockState = v14->OplockState;
FileObject = (__int64)v14->FileObject;
v78 = FileObject;
Count = v15->Count;
v17 = OplockState;
if( LOBYTE(v15->Count) == 3 && (OplockState & 0xFFFF4FFE) == 0 )
v53 = 0;
if( Count == 4 && (OplockState & 0xFFFFDFFE) == 0 )
v53 = 0;
if( (v10 & 8) == 0 && Count != 18 && FileObject && FileObject == *(_QWORD *)&v15->OldIrql )
{
v53 = 0;
goto LABEL_132;
}
}
if( !v53 )
goto LABEL_132;
if( !v52 )
break;
LABEL_46:
v52 = 1;
v31 = v14->OplockState;
if( v31 != 1 )
{
LOBYTE(v17) = 0;
v57 = v17;
v54 = 0;
v32 = 0;
v33 = 0;
v56 = 0;
if( v21 )
goto LABEL_64;
Count_low = LOBYTE(v15->Count);
if( Count_low == 3 )
{
if( (v31 & 8) != 0 )
{
LABEL_82:
v33 = 0x4000;
v56 = 0x4000;
}
else
{
LOBYTE(v17) = 1;
v54 = 1;
v33 = 0x4000;
v56 = 0x4000;
}
goto LABEL_51;
}
if( Count_low == 4 )
{
LABEL_63:
v32 = 1;
LABEL_64:
v33 = 20480;
v56 = 20480;
}
else
{
switch( LOBYTE(v15->Count) )
{
case 0:
if( ((v31 & 0x7000) == 0 || (*((_DWORD *)v15->Owner + 4) & 0xFFEDFE7F) == 0)
&& ((v31 & 0x1E) == 0 || (*((_DWORD *)v15->Owner + 4) & 0xFFEFFE7F) == 0)
&& (v15->Contention & 0x100000) == 0
|| (v31 & 8) != 0
&& (*((_DWORD *)v15->Owner + 4) & 0xFFEDFE56) == 0
&& (v15->Event.Header.Size & 1) != 0 )
{
break;
}
Contention_high = HIBYTE(v15->Contention);
if( ((Contention_high & 0xFA) != 0 || Contention_high == 1) && (v15->Contention & 0x100000) == 0 )
goto LABEL_81;
goto LABEL_63;
case 2:
if( (*(_DWORD *)(*(_QWORD *)&v15->OldIrql + 80i64) & 0x4000) != 0 )
break;
goto LABEL_72;
case 6:
Contention = v15->Contention;
if( Contention == 20 )
{
v38 = BYTE1(v15->Event.Header.WaitListHead.Flink) == 0;
goto LABEL_92;
}
if( Contention == 19 )
goto LABEL_63;
switch( Contention )
{
case 0xAu:
case 0xBu:
case 0x28u:
case 0x41u:
v33 = 0x2000;
v56 = 0x2000;
if( (v31 & 0xC) == 0 )
goto LABEL_51;
v32 = 1;
break;
case 0xDu:
if( **((_BYTE **)Irp + 3) )
goto LABEL_97;
goto LABEL_51;
case 0x27u:
goto LABEL_63;
case 0x40u:
if( (**((_DWORD **)Irp + 3) & 1) != 0 )
{
v33 = 0x2000;
v56 = 0x2000;
}
goto LABEL_51;
default:
goto LABEL_51;
}
goto LABEL_52;
case 9:
LABEL_81:
LOBYTE(v17) = 1;
v54 = 1;
goto LABEL_82;
case 0xD:
Lock = v15->Event.Header.Lock;
if( Lock > 0x98268 )
{
if( Lock == 623428 || Lock == 623592 )
goto LABEL_63;
v38 = Lock == 639668;
LABEL_92:
if( v38 )
goto LABEL_63;
}
else
{
switch( Lock )
{
case 0x98268u:
goto LABEL_63;
case 0x900FCu:
if( (FsRtlGetMarkHandleInfo(Irp) & 0x4000) == 0 )
{
LABEL_75:
v17 = v57;
goto LABEL_51;
}
v33 = 0x2000;
v56 = 0x2000;
v17 = v57;
if( (v31 & 0xC) != 0 )
{
v32 = 1;
goto LABEL_52;
}
break;
case 0x94264u:
v17 = (v31 & 8) == 0;
v54 = (v31 & 8) == 0;
v33 = 0x4000;
v56 = 0x4000;
goto LABEL_51;
case 0x980C8u:
case 0x98208u:
goto LABEL_63;
}
}
break;
case 0x11:
if( (v31 & 8) != 0 )
break;
goto LABEL_63;
case 0x12:
LABEL_72:
FsRtlpOplockCleanup(v14, (_IO_STACK_LOCATION *)v15);
if( LOBYTE(v15->Count) == 18 && (v10 & 0x20) != 0 )
{
v33 = 0x2000;
v56 = 0x2000;
}
goto LABEL_75;
case 0x15:
LABEL_97:
v33 = 0x2000;
v56 = 0x2000;
break;
default:
break;
}
LABEL_51:
v32 = 0;
}
LABEL_52:
if( (_BYTE)v17 )
{
if( (v14->OplockState & 0x1F0FFDF) == 16
|| FsRtlpOplockKeysEqual(*(_FILE_OBJECT **)&v15->OldIrql, v14->FileObject, 0i64) )
{
goto LABEL_55;
}
v35 = v63;
v58 = FsRtlpOplockBreakToII(
(__int64)v14,
(__int64)v15,
(__int64)Irp,
v10,
(int)BugCheckParameter4,
v63,
v71,
v70,
a8,
v69,
v68,
&v52,
v55);
}
else if( v32
&& ((v14->OplockState & 0x1F0FFDF) == 16
|| !FsRtlpOplockKeysEqual(*(_FILE_OBJECT **)&v15->OldIrql, v14->FileObject, 0i64)) )
{
v35 = v63;
v58 = FsRtlpOplockBreakToNone(
(__int64)v14,
(__int64)v15,
(__int64)Irp,
v10,
(int)BugCheckParameter4,
v63,
v71,
v70,
a8,
v69,
v68,
&v52,
v55);
}
else
{
LABEL_55:
v35 = v63;
}
if( !v58 && (v14->OplockState & v33) != 0 )
{
LODWORD(BugCheckParameter4) = v66;
v58 = FsRtlpOplockBreakByCacheFlags(
(__int64)v14,
(__int64)v15,
(__int64)Irp,
v10,
(__int64)BugCheckParameter4,
v33,
v35,
v71,
v70,
a8,
v69,
v68,
&v52,
v55);
}
}
LABEL_132:
if( v52 && (v10 & 0x20000000) == 0 )
{
FastMutex = v14->FastMutex;
FastMutex->Owner = 0i64;
v43 = _InterlockedCompareExchange(&FastMutex->Count, 1, 0);
if( v43 )
ExpReleaseFastMutexContended(FastMutex, v43);
KeAbPostRelease(FastMutex);
}
if( !v55[0] )
return v58;
}
v24 = (ULONG_PTR)v14->FastMutex;
Mutex = (FAST_MUTEX *)v24;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v75 = 0i64;
v61 = 0;
v25 = (ULONG_PTR)CurrentThread;
--*((_WORD *)CurrentThread + 243);
if( ++*(_BYTE *)(v25 + 794) != 1 )
KeBugCheckEx(0x192u, v25, v24, KeGetCurrentIrql(), 0i64);
v75 = 0i64;
v74 = 0i64;
v65 = 0;
v26 = *(_BYTE *)(v25 + 792);
if( v26
|| ((v39 = 0, *(_BYTE *)(v25 + 870)) ? (v40 = *(_BYTE *)(v25 + 870),
*(_BYTE *)(v25 + 870) = 0,
*(_BYTE *)(v25 + 792) |= v40,
v26 = *(_BYTE *)(v25 + 792),
v39 = 1) : (v26 = 0),
(v64 = v39) != 0) )
{
_BitScanForward((unsigned int *)&v27, v26);
v65 = v27;
*(_BYTE *)(v25 + 792) = v26 & ~(1 << v27);
v28 = *(_QWORD *)(v25 + 800) + 96 * v27;
v74 = v28;
v24 = (ULONG_PTR)Mutex;
}
else
{
v28 = 0i64;
v74 = 0i64;
}
v75 = v28;
if( !v28 )
{
_interlockedbittestandset((volatile signed __int32 *)(v25 + 120), 0x10u);
LABEL_38:
--*(_BYTE *)(v25 + 794);
KiAbThreadRemoveBoosts(v25, v24, &v61);
v38 = (*(_WORD *)(v25 + 486))++ == 0xFFFF;
if( v38 && *(_QWORD *)(v25 + 152) != v25 + 152 )
KiCheckForKernelApcDelivery();
v30 = Mutex;
if( !_interlockedbittestandreset(&Mutex->Count, 0) )
ExpAcquireFastMutexContended(v30, (PVOID)v28);
if( v28 )
*(_BYTE *)(v28 + 26) |= 1u;
v30->Owner = CurrentThread;
v21 = v57;
goto LABEL_46;
}
if( v24 >= 0xFFFF800000000000ui64 )
{
if( *((_BYTE *)&antNameB + ((v24 >> 39) & 0x1FF) - 256) == 1 )
{
SessionId = MmGetSessionIdEx(*(_QWORD *)(v25 + 184));
v24 = (ULONG_PTR)Mutex;
goto LABEL_37;
}
v24 = (ULONG_PTR)Mutex;
}
SessionId = -1;
LABEL_37:
*(_DWORD *)(v28 + 40) = SessionId;
*(_QWORD *)(v28 + 32) = v24 & 0x7FFFFFFFFFFFFFFCi64;
goto LABEL_38;
}
return v58;
}Referenced by:
FsRtlCheckOplock
FsRtlCheckOplockEx