CmpTransSearchAddTrans

INT64 __fastcall CmpTransSearchAddTrans(
        INT64 a1,
        VOID *a2,
        LIST_ENTRY *a3,
        EX_RUNDOWN_REF *a4,
        INT64 a5,
        LIST_ENTRY **a6){
  _CM_TRANS *Trans; 
  BOOL v7; 
  int v12; 
  int v13; 
  int v14; 
  _ETHREAD *CurrentThread; 
  __int64 v16; 
  LIST_ENTRY *p_TransactionListEntry; 
  _LIST_ENTRY *Blink; 
  _ETHREAD *v20; 
  bool v21; 
  _ETHREAD *v22; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *v24; 
  int v25[8]; 
  __int64 CompareAddress; 
  Trans = 0i64;
  v7 = 0;
  if( a1 )
  {
    v12 = CmpTransReferenceTransaction(a1);
    if( v12 < 0 )
      return(unsigned int)v12;
  }
  v13 = a5;
  v14 = 1;
  while( 1 )
  {
    while( 1 )
    {
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      --*((_WORD *)CurrentThread + 242);
      ExAcquireFastMutexUnsafe(&CmpTransactionListLock);
      v16 = CmpSearchForTrans((INT64)a3, a1, (GUID *)a2);
      if( !v16 )
      {
        if( !v13 )
          goto LABEL_20;
        break;
      }
      if( a1 && (*(_DWORD *)(v16 + 48) & 7) != 0 )
      {
LABEL_20:
        v12 = -1072103422;
        goto LABEL_21;
      }
      if( (*(_DWORD *)(v16 + 48) & 8) == 0 )
        break;
      if( !v13 )
        goto LABEL_20;
      LODWORD(CompareAddress) = CmpTransactionInitializingCount;
      ExReleaseFastMutexUnsafe(&CmpTransactionListLock);
      KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
      ExBlockOnAddressPushLock(
        &CmpTransactionInitializingEvent,
        &CmpTransactionInitializingCount,
        &CompareAddress,
        4ui64,
        0i64);
    }
    if( Trans )
      break;
    if( v16 )
    {
      CmpBindHiveToTrans((__int64)a4, v16);
      goto LABEL_11;
    }
    ExReleaseFastMutexUnsafe(&CmpTransactionListLock);
    KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
    Trans = CmpTransAllocateTrans((_CM_TRANS_PTR)a1, (_GUID *)a2, (_CM_RM *)a3, (_CMHIVE *)a4);
    if( !Trans )
    {
      v12 = -1073741670;
      goto LABEL_16;
    }
  }
  if( a3[5].Flink )
  {
    v20 = (_ETHREAD *)KeGetCurrentThread();
    --*((_WORD *)v20 + 242);
    v21 = ExAcquireRundownProtection((PEX_RUNDOWN_REF)&a3[5].Flink[102]);
    v7 = v21;
    if( !v21 )
    {
      v12 = -1073741431;
      goto LABEL_21;
    }
  }
  Blink = a3[1].Blink;
  if( Blink->Flink != &a3[1] )
    goto LABEL_37;
  Trans->TransactionListEntry.Blink = Blink;
  Trans->TransactionListEntry.Flink = a3 + 1;
  Blink->Flink = &Trans->TransactionListEntry;
  a3[1].Blink = &Trans->TransactionListEntry;
  ++CmpTransactionInitializingCount;
  ExReleaseFastMutexUnsafe(&CmpTransactionListLock);
  KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  v14 = 0;
  v12 = CmpTransInitializeTransaction((__int64)Trans);
  if( v12 < 0 )
  {
    v22 = (_ETHREAD *)KeGetCurrentThread();
    --*((_WORD *)v22 + 242);
    ExAcquireFastMutexUnsafe(&CmpTransactionListLock);
    Flink = Trans->TransactionListEntry.Flink;
    if( (_CM_TRANS *)Trans->TransactionListEntry.Flink->Blink == Trans )
    {
      v24 = Trans->TransactionListEntry.Blink;
      if( (_CM_TRANS *)v24->Flink == Trans )
      {
        v24->Flink = Flink;
        Flink->Blink = v24;
        --CmpTransactionInitializingCount;
        ExReleaseFastMutexUnsafe(&CmpTransactionListLock);
        KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
        _InterlockedOr(v25, 0);
        if( CmpTransactionInitializingEvent.0 )
          ExfUnblockPushLock(&CmpTransactionInitializingEvent, 0i64);
LABEL_21:
        if( Trans )
          ExFreePoolWithTag(Trans, 0x72544D43u);
        goto LABEL_12;
      }
    }
LABEL_37:
    __fastfail(3u);
  }
  p_TransactionListEntry = &Trans->TransactionListEntry;
LABEL_11:
  v12 = 0;
  *a6 = p_TransactionListEntry;
LABEL_12:
  if( v7 )
  {
    ExReleaseRundownProtection(a4 + 204);
    KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  }
  if( v14 )
  {
    ExReleaseFastMutexUnsafe(&CmpTransactionListLock);
    KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  }
LABEL_16:
  if( a1 )
    CmpTransDereferenceTransaction(a1);
  return(unsigned int)v12;
}

Referenced by:

CmpTransSearchAddTransFromKeyBody
CmpTransSearchAddTransFromRm