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