ExAcquireFastResourceExclusive
INT8 __fastcall ExAcquireFastResourceExclusive(UINT64 a1, UINT64 a2, INT8 a3){
_BYTE *v6;
unsigned __int8 v7;
_ETHREAD *CurrentThread;
unsigned __int8 CurrentIrql;
_ETHREAD *v10;
_ETHREAD *v11;
void *v12;
unsigned __int8 v13;
_BYTE *v14;
CHAR v15;
_QWORD *v16;
_QWORD *v17;
INT64 v18;
_QWORD *v20;
_QWORD *v21;
INT64 v22;
INT64 *FastOwnerEntryForThread;
UINT64 *v24;
INT64 *v25;
_KLOCK_QUEUE_HANDLE LockQueue;
INT64 Object[2];
__int128 v28;
__int128 v29;
INT64 v30;
v6 = 0i64;
v7 = 2 - (a3 != 0);
*(_OWORD *)Object = 0i64;
v28 = 0i64;
v29 = 0i64;
memset(&LockQueue, 0, sizeof(LockQueue));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v30 = (INT64)CurrentThread;
if( (*(_BYTE *)(a1 + 26) & 1) == 0 )
KeBugCheckEx(0x1C6u, (PVOID)3, (PVOID)a1, 0i64, 0i64);
CurrentIrql = KeGetCurrentIrql();
v10 = (_ETHREAD *)KeGetCurrentThread();
if( CurrentIrql > v7 )
KeBugCheckEx(0x1C6u, 0i64, (PVOID)CurrentIrql, (PVOID)v7, 0i64);
if( CurrentIrql >= 2u && (KeGetPcr()->Prcb._bf_0 & 0x10001) != 0 )
KeBugCheckEx(0x1C6u, (PVOID)5, 0i64, 0i64, 0i64);
if( (v10->Tcb.ApcState.InProgressFlags & 2) != 0 )
KeBugCheckEx(0x1C6u, (PVOID)6, 0i64, 0i64, 0i64);
if( !CurrentIrql && (v10->Tcb._bf_0 & 0x400) == 0 && !v10->Tcb.WaitBlock[3].SpareLong )
KeBugCheckEx(0x1C6u, (PVOID)7, 0i64, 0i64, 0i64);
v11 = *(_ETHREAD **)(a2 + 32);
if( v11 != v10 )
KeBugCheckEx(0x1C6u, (PVOID)9, (PVOID)a2, v11, 0i64);
v12 = *(void **)(a2 + 24);
if( v12 )
KeBugCheckEx(0x1C6u, (PVOID)2, (PVOID)a2, v12, 0i64);
*(_BYTE *)(a2 + 17) |= 4u;
*(_QWORD *)(a2 + 24) = a1;
v13 = KeGetCurrentIrql();
__writecr8(2ui64);
if( *(char *)(a1 + 26) < 0 )
{
FastOwnerEntryForThread = ExpFindFastOwnerEntryForThread((INT64)CurrentThread, a1, 0, 0);
if( FastOwnerEntryForThread )
{
v24 = (UINT64 *)FastOwnerEntryForThread[6];
v25 = FastOwnerEntryForThread + 5;
if( (INT64 *)*v24 == v25 )
{
*(_QWORD *)a2 = v25;
v15 = 1;
*(_QWORD *)(a2 + 8) = v24;
*v24 = a2;
v25[1] = a2;
goto LABEL_16;
}
goto LABEL_41;
}
}
v14 = KeAbPreAcquire((VOID *)a1, 0i64, a3 == 0);
v6 = v14;
if( v14 )
*(_BYTE *)(a2 + 16) = (2 * ((__int64)&v14[-*(_QWORD *)&v14[-16 * (unsigned __int8)v14[24] + 800]] / 96)) | 1;
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = (unsigned __int64 *volatile)(a1 + 96);
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, (UINT64 *)(a1 + 96));
v15 = ExpTryAcquireResourceExclusive(a1);
if( v15 )
{
v16 = *(_QWORD **)(a1 + 56);
v17 = (_QWORD *)(a2 + 56);
if( *v16 == a1 + 48 )
{
*v17 = a1 + 48;
*(_QWORD *)(a2 + 64) = v16;
*v16 = v17;
*(_QWORD *)(a1 + 56) = v17;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
ExpAddFastOwnerEntryToThreadList(v30, v18, 0, a2);
LABEL_16:
__writecr8(v13);
goto LABEL_17;
}
LABEL_41:
__fastfail(3u);
}
if( !a3 )
{
*(_BYTE *)(a2 + 17) &= 0xFAu;
*(_QWORD *)(a2 + 24) = 0i64;
*(_BYTE *)(a2 + 16) = 0;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
goto LABEL_16;
}
if( v6 )
KeAbPreWait(v6);
v20 = *(_QWORD **)(a1 + 56);
v21 = (_QWORD *)(a2 + 56);
if( *v20 != a1 + 48 )
goto LABEL_41;
*(_QWORD *)(a2 + 64) = v20;
*v21 = a1 + 48;
*v20 = v21;
*(_QWORD *)(a1 + 56) = v21;
*(_BYTE *)(a2 + 19) = 1;
ExpPrepareToWaitForResourceExclusive(a1, v30, (INT64)Object);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
ExpAddFastOwnerEntryToThreadList(v30, v22, 0, a2);
__writecr8(v13);
ExpWaitForResource((_ERESOURCE *)a1, Object);
*(_BYTE *)(a2 + 19) = 0;
if( v6 )
KeAbPreAcquire((VOID *)a1, v6, 0i64);
v15 = 1;
LABEL_17:
if( v6 )
{
if( v15 )
v6[26] |= 1u;
else
KeAbPostReleaseEx((VOID *)a1, v6);
}
return v15;
}Referenced by:
ExpFastResourceLegacyAcquireExclusive