ExAcquireSharedWaitForExclusive

VOID __stdcall ExAcquireSharedWaitForExclusive(_HHIVE *Hive, UINT64 NewLength, UINT64 OldLength){
  bool v3; 
  char v4; 
  int(__fastcall *CurrentThread)(_HHIVE *, unsigned int, unsigned int, void *, unsigned int); 
  int v7; 
  __int16 v8; 
  CHAR *v9; 
  CHAR *v10; 
  int v11; 
  int v12; 
  __int64 v13; 
  unsigned int v14; 
  OWNER_ENTRY *EmptyEntry; 
  OWNER_ENTRY *v16; 
  unsigned int v17; 
  unsigned int v18; 
  UINT64 v19; 
  UINT64 v20; 
  unsigned int v21; 
  unsigned int v22; 
  unsigned int v23; 
  CHAR *v24; 
  int v25; 
  int v26; 
  ULONG_PTR BugCheckParameter4; 
  UINT64 a6; 
  struct _KLOCK_QUEUE_HANDLE LockHandle; 
  INT64 Object[2]; 
  __int128 v31; 
  __int128 v32; 
  v3 = (BYTE2(Hive->Allocate) & 1) == 0;
  v4 = NewLength;
  memset(&LockHandle, 0, sizeof(LockHandle));
  *(_OWORD *)Object = 0i64;
  v31 = 0i64;
  v32 = 0i64;
  if( !v3 )
    KeBugCheckEx(0x1C6u, 0xEui64, (ULONG_PTR)Hive, 0i64, 0i64);
  CurrentThread = (int(__fastcall *)(_HHIVE *, unsigned int, unsigned int, void *, unsigned int))KeGetCurrentThread();
  v7 = HIDWORD(PerfGlobalGroupMask) & 0x20000;
  __incgsdword(0x86BCu);
  KeAcquireInStackQueuedSpinLock((UINT64 *)&Hive->DirtyVector.Buffer, &LockHandle);
  while( 1 )
  {
    while( 1 )
    {
      if( !LODWORD(Hive->BaseBlock) )
      {
        ExpTryAcquireResourceShared((INT64)Hive);
        v26 = (__int64)Hive->HiveLoadFailure & 7;
        Hive->FileRead = CurrentThread;
        LODWORD(Hive->HiveLoadFailure) = v26 | 8;
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(LockHandle.OldIrql);
        __incgsdword(0x86C4u);
        __incgsdword(0x8664u);
        if( v7 )
          PerfLogExecutiveResourceAcquire(0x10041ui64, Hive, 1ui64, HIDWORD(Hive->BaseBlock));
        return;
      }
      v8 = WORD1(Hive->Allocate) & 0x80;
      if( v8 && Hive->FileRead == CurrentThread )
      {
        v17 = LODWORD(Hive->HiveLoadFailure) + 8;
        LODWORD(Hive->HiveLoadFailure) = v17;
        v18 = v17 >> 3;
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(LockHandle.OldIrql);
        __incgsdword(0x86C0u);
        __incgsdword(0x8664u);
        if( !v7 )
          return;
        v19 = v18;
        v20 = 65585i64;
        goto LABEL_18;
      }
      if( v8 || HIDWORD(Hive->FlusherLock.Reserved) )
        break;
      LODWORD(a6) = ExpGetThreadResourceHint((INT64)CurrentThread);
      LODWORD(BugCheckParameter4) = 1;
      v9 = ExpFindCurrentThread((ERESOURCE *)Hive, (INT64)CurrentThread, &LockHandle, 1i64, BugCheckParameter4, a6);
      v10 = v9;
      if( v9 )
      {
        v11 = *((_DWORD *)v9 + 2);
        v12 = v11 & 7;
        if( *(_QWORD *)v10 )
        {
          v14 = v12 | (v11 + 8) & 0xFFFFFFF8;
          *((_DWORD *)v10 + 2) = v14;
        }
        else
        {
          *(_QWORD *)v10 = CurrentThread;
          *((_DWORD *)v10 + 2) = v12 | 8;
          ExpTryAcquireResourceShared((INT64)Hive);
          v14 = *(_DWORD *)(v13 + 8);
        }
        v21 = v14 >> 3;
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(LockHandle.OldIrql);
        v22 = 34504;
        v23 = 65617;
        if( v21 == 1 )
          v23 = 65601;
        if( v21 == 1 )
          v22 = 34500;
        __incgsdword(v22);
        __incgsdword(0x86C8u);
        if( v7 )
        {
          v19 = 1i64;
          v20 = v23;
LABEL_18:
          PerfLogExecutiveResourceAcquire(v20, Hive, v19, HIDWORD(Hive->BaseBlock));
          return;
        }
        return;
      }
    }
    if( !v4 )
    {
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
      __writecr8(LockHandle.OldIrql);
      __incgsdword(0x86D0u);
      return;
    }
    if( !v8 )
      break;
    EmptyEntry = ExpFindEmptyEntry((ERESOURCE *)Hive, &LockHandle);
    v16 = EmptyEntry;
    if( EmptyEntry )
    {
      EmptyEntry->OwnerThread = (unsigned __int64)CurrentThread;
      EmptyEntry->TableSize = EmptyEntry->TableSize & 7 | 8;
      goto LABEL_28;
    }
  }
  v16 = 0i64;
LABEL_28:
  ExpPrepareToWaitForResourceShared((INT64)Hive, (INT64)CurrentThread, (INT64)Object);
  KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
  __writecr8(LockHandle.OldIrql);
  __incgsdword(0x86CCu);
  if( v7 )
    PerfLogExecutiveResourceWait(0x10044ui64, Hive, 0i64);
  ExpApplyPrewaitBoost();
  ExpWaitForResource((ERESOURCE *)Hive, Object);
  if( !v16 )
  {
    KeAcquireInStackQueuedSpinLock((UINT64 *)&Hive->DirtyVector.Buffer, &LockHandle);
    do
    {
      LODWORD(a6) = 0;
      LODWORD(BugCheckParameter4) = 1;
      v24 = ExpFindCurrentThread((ERESOURCE *)Hive, (INT64)CurrentThread, &LockHandle, 1i64, BugCheckParameter4, a6);
    }
    while( !v24 );
    v25 = *((_DWORD *)v24 + 2) & 7;
    *(_QWORD *)v24 = CurrentThread;
    *((_DWORD *)v24 + 2) = v25 | 8;
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
    __writecr8(LockHandle.OldIrql);
  }
  ExpBoostIoAfterAcquire((ERESOURCE *)Hive, (UINT64)CurrentThread);
  __incgsdword(0x86C4u);
  __incgsdword(0x8664u);
  if( v7 )
  {
    v19 = 1i64;
    v20 = 65601i64;
    goto LABEL_18;
  }
}

Referenced by:

ExEnterCriticalRegionAndAcquireSharedWaitForExclusive
FsRtlAcquireFileForModWriteEx