CmpTransSearchAddTrans

INT64 __fastcall CmpTransSearchAddTrans(
        INT64 a1,
        VOID *a2,
        _LIST_ENTRY *a3,
        _EX_RUNDOWN_REF *a4,
        INT64 a5,
        _LIST_ENTRY **a6){
  _CM_TRANS *Trans; 
  int v7; 
  int v12; 
  int v13; 
  int v14; 
  _ETHREAD *CurrentThread; 
  _CM_TRANS *v16; 
  _LIST_ENTRY *p_TransactionListEntry; 
  _LIST_ENTRY *Blink; 
  _ETHREAD *v20; 
  UINT8 v21; 
  _ETHREAD *v22; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *v24; 
  int v25[8]; 
  int 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();
      --CurrentThread->Tcb.KernelApcDisable;
      ExAcquireFastMutexUnsafe((PFAST_MUTEX)((char *)&CmpDummyThreadEvent + 64));
      LODWORD(v16) = CmpSearchForTrans((__int64)a3, a1, a2);
      if( !v16 )
      {
        if( !v13 )
          goto LABEL_20;
        break;
      }
      if( a1 && (v16->TransState & 7) != 0 )
      {
LABEL_20:
        v12 = -1072103422;
        goto LABEL_21;
      }
      if( (v16->TransState & 8) == 0 )
        break;
      if( !v13 )
        goto LABEL_20;
      CompareAddress = dword_140C5030C;
      ExReleaseFastMutexUnsafe((PFAST_MUTEX)((char *)&CmpDummyThreadEvent + 64));
      KeLeaveCriticalRegionThread(KeGetCurrentThread());
      ExBlockOnAddressPushLock(
        (_EX_PUSH_LOCK *)&CmpDummyThreadEvent + 15,
        &dword_140C5030C,
        &CompareAddress,
        4ui64,
        0i64);
    }
    if( Trans )
      break;
    if( v16 )
    {
      CmpBindHiveToTrans((_CMHIVE *)a4, v16);
      goto LABEL_11;
    }
    ExReleaseFastMutexUnsafe((PFAST_MUTEX)((char *)&CmpDummyThreadEvent + 64));
    KeLeaveCriticalRegionThread(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();
    --v20->Tcb.KernelApcDisable;
    v21 = ExAcquireRundownProtection((_EX_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;
  ++dword_140C5030C;
  ExReleaseFastMutexUnsafe((PFAST_MUTEX)((char *)&CmpDummyThreadEvent + 64));
  KeLeaveCriticalRegionThread(KeGetCurrentThread());
  v14 = 0;
  v12 = CmpTransInitializeTransaction(Trans);
  if( v12 < 0 )
  {
    v22 = (_ETHREAD *)KeGetCurrentThread();
    --v22->Tcb.KernelApcDisable;
    ExAcquireFastMutexUnsafe((PFAST_MUTEX)((char *)&CmpDummyThreadEvent + 64));
    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;
        --dword_140C5030C;
        ExReleaseFastMutexUnsafe((PFAST_MUTEX)((char *)&CmpDummyThreadEvent + 64));
        KeLeaveCriticalRegionThread(KeGetCurrentThread());
        _InterlockedOr(v25, 0);
        if( *(&CmpDummyThreadEvent + 15) )
          ExfUnblockPushLock((INT64 *)&CmpDummyThreadEvent + 15, 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(KeGetCurrentThread());
  }
  if( v14 )
  {
    ExReleaseFastMutexUnsafe((PFAST_MUTEX)((char *)&CmpDummyThreadEvent + 64));
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
  }
LABEL_16:
  if( a1 )
    CmpTransDereferenceTransaction(a1);
  return(unsigned int)v12;
}

Referenced by:

CmpTransSearchAddTransFromKeyBody
CmpTransSearchAddTransFromRm