ExpReleaseResourceSharedForThreadLite
NTSTATUS __stdcall ExpReleaseResourceSharedForThreadLite(PVOID BugCheckParameter1, PVOID BugCheckParameter2){
_KSPIN_LOCK_QUEUE *v2;
_KSPIN_LOCK_QUEUE *v3;
__int64 v4;
unsigned int v6;
PVOID v7;
unsigned int *v8;
unsigned int v9;
unsigned __int64 v10;
unsigned int v11;
__int64 v12;
int v13;
int v14;
bool v15;
unsigned int v16;
_KSPIN_LOCK_QUEUE *v17;
_ADJUST_REASON v18;
NTSTATUS result;
char v20;
unsigned int *v21;
unsigned __int64 v22;
__int64 v23;
unsigned int *v24;
unsigned __int64 v25;
char *v26;
char *v27;
__int64 *v28;
__int64 v29;
__int64 **v30;
struct _KPRCB *CurrentPrcb;
_QWORD *v32;
_QWORD *v33;
_KWAIT_BLOCK *v34;
_LIST_ENTRY *Flink;
_KWAIT_BLOCK *v36;
_KWAIT_BLOCK **Blink;
int v38;
_KSPIN_LOCK_QUEUE *Next;
unsigned __int8 WaitType;
char v41;
__int64 **v42;
__int64 v43;
_QWORD *v44;
_ETHREAD *v45;
char v46;
int v47;
_ETHREAD **QuantumTarget;
_ETHREAD *Object;
_QWORD *v50;
_KWAIT_BLOCK *Entry;
__int64 v52;
_QWORD *v53;
_KPRCB *Prcb;
_ETHREAD *CurrentThread;
_KWAIT_BLOCK *v56;
UINT8 OldIrql;
UINT64 SpinCount;
UINT64 ContentionCount;
_QWORD *v60;
v3 = v2;
v4 = 0i64;
v60 = 0i64;
if( ((unsigned __int8)BugCheckParameter2 & 3) != 0 )
v6 = 0;
else
v6 = *((unsigned __int8 *)BugCheckParameter2 + 649);
v7 = (PVOID)*((_QWORD *)BugCheckParameter1 + 6);
v8 = (unsigned int *)((char *)BugCheckParameter1 + 48);
if( v7 != BugCheckParameter2 )
{
v21 = (unsigned int *)((char *)BugCheckParameter1 + 48);
v22 = v7 != 0i64;
if( v7 )
v21 = 0i64;
if( !v6
|| (v23 = *((_QWORD *)BugCheckParameter1 + 2)) == 0
|| v6 >= *(_DWORD *)(v23 + 8)
|| (v8 = (unsigned int *)(v23 + 16i64 * v6), *(PVOID *)v8 != BugCheckParameter2) )
{
v24 = (unsigned int *)*((_QWORD *)BugCheckParameter1 + 2);
v25 = *((unsigned int *)BugCheckParameter1 + 16) + (unsigned __int64)*((unsigned int *)BugCheckParameter1 + 18);
if( !v24 || (v8 = v24 + 4, v22 >= v25) )
LABEL_87:
KeBugCheckEx(0xE3u, BugCheckParameter1, BugCheckParameter2, v24, (PVOID)2);
while( 1 )
{
v26 = (char *)v21;
v27 = (char *)v21;
if( *(PVOID *)v8 == BugCheckParameter2 )
break;
if( *(_QWORD *)v8 )
{
if( ++v22 == v25 )
goto LABEL_87;
}
else
{
v21 = v8;
if( v27 )
v21 = (unsigned int *)v26;
}
v8 += 4;
if( v8 == &v24[4 * v24[2]] )
goto LABEL_87;
}
v4 = (__int64)v60;
KeGetCurrentThread()->SchedulerApc.SpareByte0 = ((char *)v8 - (char *)v24) >> 4;
}
}
v9 = v8[2] & 7 | (8 * (v8[2] >> 3) - 8);
v8[2] = v9;
if( v9 >= 8 )
{
_m_prefetchw(v3);
Next = v3->Next;
if( !v3->Next )
{
if( v3 == (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)v3->Lock,
0i64,
(signed __int64)v3) )
{
LABEL_60:
result = KiIrqlFlags;
__writecr8(LOBYTE(v3[1].Next));
goto LABEL_28;
}
Next = KxWaitForLockChainValid(v3);
}
v3->Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_60;
}
v10 = *(_QWORD *)v8;
if( (v9 & 2) != 0 )
{
v10 &= 0xFFFFFFFFFFFFFFFCui64;
}
else if( (v10 & 3) != 0 )
{
goto LABEL_14;
}
if( v10 )
{
if( (v9 & 1) != 0 )
{
PsBoostThreadIoEx((_ETHREAD *)v10, 1u, 0, 0i64);
v8[2] &= ~1u;
v11 = v8[2];
}
else
{
LOBYTE(v11) = v9;
}
if( (v11 & 4) != 0 )
{
_InterlockedDecrement((volatile signed __int32 *)(v10 + 1364));
v8[2] &= ~4u;
v11 = v8[2];
v4 = (__int64)v60;
}
if( (v11 & 2) != 0 )
{
ObDereferenceObjectDeferDelete(v10);
v8[2] &= ~2u;
}
}
LABEL_14:
*(_QWORD *)v8 = 0i64;
v12 = 0i64;
LODWORD(ContentionCount) = *((_DWORD *)BugCheckParameter1 + 17);
v52 = 0i64;
if( *((_DWORD *)BugCheckParameter1 + 16) > 1u )
{
LABEL_17:
v14 = 0;
goto LABEL_18;
}
v13 = *((_DWORD *)BugCheckParameter1 + 19);
if( v13 )
{
v28 = (__int64 *)*((_QWORD *)BugCheckParameter1 + 5);
if( !v28 )
{
LABEL_52:
v52 = v12;
*((_DWORD *)BugCheckParameter1 + 19) = v13 - 1;
v14 = 1;
*((_WORD *)BugCheckParameter1 + 13) |= 0x80u;
goto LABEL_18;
}
if( (__int64 *)*v28 == v28 )
{
*((_QWORD *)BugCheckParameter1 + 5) = 0i64;
}
else
{
*((_QWORD *)BugCheckParameter1 + 5) = *v28;
v29 = *v28;
v30 = (__int64 **)v28[1];
if( *(__int64 **)(*v28 + 8) != v28 || *v30 != v28 )
goto LABEL_57;
*v30 = (__int64 *)v29;
*(_QWORD *)(v29 + 8) = v30;
}
v12 = v28[2];
if( !v4 )
{
v28[1] = (__int64)v28;
*v28 = (__int64)v28;
LABEL_51:
v13 = *((_DWORD *)BugCheckParameter1 + 19);
v60 = v28;
goto LABEL_52;
}
v42 = *(__int64 ***)(v4 + 8);
if( *v42 == (__int64 *)v4 )
{
*v28 = v4;
v28[1] = (__int64)v42;
*v42 = v28;
*(_QWORD *)(v4 + 8) = v28;
goto LABEL_51;
}
LABEL_57:
__fastfail(3u);
}
if( !*((_DWORD *)BugCheckParameter1 + 18) )
goto LABEL_17;
v43 = *((_QWORD *)BugCheckParameter1 + 4);
*((_QWORD *)BugCheckParameter1 + 4) = 0i64;
v14 = *((_DWORD *)BugCheckParameter1 + 18);
*((_DWORD *)BugCheckParameter1 + 18) = 0;
v60 = (_QWORD *)v43;
LABEL_18:
v15 = v14 - 1 + *((_DWORD *)BugCheckParameter1 + 16) == 0;
*((_DWORD *)BugCheckParameter1 + 16) += v14 - 1;
if( v15 )
*((_WORD *)BugCheckParameter1 + 12) = 0;
if( !*((_DWORD *)BugCheckParameter1 + 19) && !*((_DWORD *)BugCheckParameter1 + 18) )
*((_WORD *)BugCheckParameter1 + 13) &= 0xF9u;
v16 = *((unsigned __int8 *)BugCheckParameter1 + 27);
if( v12 )
{
v38 = *((_DWORD *)BugCheckParameter1 + 14) & 7;
*((_QWORD *)BugCheckParameter1 + 6) = v12;
*((_DWORD *)BugCheckParameter1 + 14) = v38 | 8;
}
_m_prefetchw(v3);
v17 = v3->Next;
if( v3->Next )
goto LABEL_43;
if( v3 != (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)v3->Lock,
0i64,
(signed __int64)v3) )
{
v17 = KxWaitForLockChainValid(v3);
LABEL_43:
v3->Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&v17->Lock, 1ui64);
}
__writecr8(LOBYTE(v3[1].Next));
v18 = AdjustUnwait;
result = v52 != 0;
v20 = 2 * result + 1;
if( !v60 )
goto LABEL_28;
OldIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
v32 = v60;
do
{
v33 = v32;
LODWORD(SpinCount) = 0;
v32 = (_QWORD *)*v32;
v50 = v32;
if( _interlockedbittestandset((volatile signed __int32 *)v33 + 6, 7u) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( (*((_DWORD *)v33 + 6) & 0x80u) != 0 );
}
while( _interlockedbittestandset((volatile signed __int32 *)v33 + 6, 7u) );
v32 = v50;
}
*((_DWORD *)v33 + 7) = 1;
v34 = (_KWAIT_BLOCK *)v33[4];
if( v34 != (_KWAIT_BLOCK *)(v33 + 4) )
{
while( 1 )
{
Flink = v34->WaitListEntry.Flink;
v36 = v34;
Entry = v34;
Blink = (_KWAIT_BLOCK **)v34->WaitListEntry.Blink;
v56 = (_KWAIT_BLOCK *)Flink;
if( (_KWAIT_BLOCK *)Flink->Blink != v36 || *Blink != v36 )
goto LABEL_57;
*Blink = (_KWAIT_BLOCK *)Flink;
Flink->Blink = (_LIST_ENTRY *)Blink;
WaitType = v36->WaitType;
if( WaitType == 1 )
{
if( KiTryUnwaitThread(CurrentPrcb, v36, v36->WaitKey, 0i64) )
{
v15 = (*((_DWORD *)v33 + 7))-- == 1;
if( v15 )
{
LABEL_67:
v32 = v50;
break;
}
}
}
else
{
if( WaitType == 2 )
{
v36->BlockState = 5;
Object = v36->Thread;
v53 = &Object->Tcb.gap0[8];
v36->WaitListEntry.Flink = 0i64;
KeGetCurrentIrql();
__writecr8(2ui64);
Prcb = KeGetCurrentPrcb();
CurrentThread = Prcb->CurrentThread;
KiAcquireKobjectLockSafe(Object);
v44 = v53;
v45 = Object;
if( (_QWORD *)*v44 == v44
|| LODWORD(Object->Tcb.InitialStack) >= HIDWORD(Object->Tcb.InitialStack)
|| (_ETHREAD *)CurrentThread->Tcb.Queue == Object && CurrentThread->Tcb.WaitReason == 15 )
{
LABEL_98:
v47 = *(_DWORD *)&v45->Tcb.gap0[4];
*(_DWORD *)&v45->Tcb.gap0[4] = v47 + 1;
QuantumTarget = (_ETHREAD **)v45->Tcb.QuantumTarget;
if( *QuantumTarget != (_ETHREAD *)&v45->Tcb.SListFaultAddress )
goto LABEL_57;
Entry->WaitListEntry.Flink = (_LIST_ENTRY *)&v45->Tcb.SListFaultAddress;
Entry->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
*QuantumTarget = (_ETHREAD *)Entry;
v45->Tcb.QuantumTarget = (unsigned __int64)Entry;
if( !v47 && (_QWORD *)*v44 != v44 )
{
KiWakeOtherQueueWaiters(Prcb, (_KQUEUE *)v45);
v45 = Object;
}
}
else
{
KiWakeQueueWaiter(Prcb, (_KQUEUE *)Object, (INT64)Entry);
v45 = Object;
if( !v46 )
{
v44 = &Object->Tcb.gap0[8];
goto LABEL_98;
}
}
_InterlockedAnd((volatile signed __int32 *)v45, 0xFFFFFF7F);
v15 = (*((_DWORD *)v33 + 7))-- == 1;
if( v15 )
goto LABEL_67;
goto LABEL_105;
}
KiTryUnwaitThread(CurrentPrcb, v36, 256i64, 0i64);
}
LABEL_105:
v34 = v56;
if( v56 == (_KWAIT_BLOCK *)(v33 + 4) )
goto LABEL_67;
}
}
_InterlockedAnd((volatile signed __int32 *)v33 + 6, 0xFFFFFF7F);
}
while( v32 != v60 );
KiRemoveBoostThread(CurrentPrcb, CurrentPrcb->CurrentThread);
if( v16 )
{
v18 = AdjustBoost;
if( v41 > (char)v16 )
v16 = v41;
}
if( (v20 & 2) != 0 && v18 == AdjustUnwait )
v16 = 1;
KiExitDispatcher(CurrentPrcb, 0i64, v18, v16, OldIrql);
LABEL_28:
__incgsdword(0x8670u);
return result;
}Referenced by:
ExReleaseResourceAndLeaveCriticalRegion
ExReleaseResourceForThreadLite
ExReleaseResourceLite