EmpProviderRegister

__int64 __fastcall EmpProviderRegister(PVOID Object, __int64 a2, unsigned int a3, __int64 a4, int a5, __int64 a6){
  __int64 v7; 
  unsigned int v10; 
  void *v11; 
  unsigned int v12; 
  _QWORD *PoolWithTag; 
  _QWORD *v14; 
  VOID *v15; 
  _QWORD *v16; 
  __int64 v17; 
  int v18; 
  __int64 v19; 
  __int64 v20; 
  const GUID *v21; 
  SINGLE_LIST_ENTRY *v22; 
  __int64 v23; 
  SINGLE_LIST_ENTRY *v24; 
  _SINGLE_LIST_ENTRY *v25; 
  VOID *v26; 
  unsigned int v27; 
  __int64 v28; 
  _SINGLE_LIST_ENTRY **v29; 
  _SINGLE_LIST_ENTRY *v30; 
  const GUID *v31; 
  SINGLE_LIST_ENTRY *v32; 
  _SINGLE_LIST_ENTRY **v33; 
  SINGLE_LIST_ENTRY *v34; 
  _SINGLE_LIST_ENTRY *v35; 
  _SINGLE_LIST_ENTRY *v36; 
  __int64 i; 
  __int64 v38; 
  _QWORD *j; 
  __int64 k; 
  __int64 v41; 
  _QWORD *m; 
  VOID *v44; 
  _SINGLE_LIST_ENTRY *v45; 
  SINGLE_LIST_ENTRY *v46; 
  _SINGLE_LIST_ENTRY *Next; 
  _SINGLE_LIST_ENTRY *v48; 
  void *v49; 
  unsigned int v50; 
  _QWORD *v51; 
  __int64 v52; 
  _QWORD *v53; 
  char *v54; 
  char *v55; 
  __int64 v56; 
  __int64 v57; 
  __int64 v58; 
  v7 = a3;
  v10 = 0;
  v11 = 0i64;
  v12 = 0;
  ExAcquirePushLockExclusiveEx((UINT64)&EmpDatabaseLock, 0i64);
  if( a6 && (!(_DWORD)v7 || a2) && (!a5 || a4) )
  {
    PoolWithTag = ExAllocatePoolWithTag(PagedPool, 0x48ui64, 0x72704D45ui64);
    v11 = PoolWithTag;
    if( !PoolWithTag )
    {
      v12 = -1073741670;
      goto LABEL_40;
    }
    PoolWithTag[3] = 0i64;
    *((_DWORD *)PoolWithTag + 8) = 0;
    PoolWithTag[5] = 0i64;
    *((_DWORD *)PoolWithTag + 12) = 0;
    PoolWithTag[1] = 0i64;
    *((_DWORD *)PoolWithTag + 4) = 0;
    v14 = PoolWithTag + 7;
    v14[1] = v14;
    *v14 = v14;
    if( (_DWORD)v7 )
    {
      v15 = ExAllocatePoolWithTag(PagedPool, (unsigned int)(8 * v7), 0x72704D45ui64);
      *((_QWORD *)v11 + 1) = v15;
      if( v15 )
      {
        memset((INT64)v15, 0i64);
        v16 = (_QWORD *)(a2 + 8);
        *((_DWORD *)v11 + 4) = v7;
        v17 = v7;
        do
        {
          if( *v16 )
            ++*((_DWORD *)v11 + 8);
          v16 += 3;
          --v17;
        }
        while( v17 );
        v18 = *((_DWORD *)v11 + 8);
        if( !v18 )
        {
LABEL_14:
          v19 = 0i64;
          while( 1 )
          {
            v20 = 3 * v19;
            v21 = *(const GUID **)(a2 + 24 * v19);
            if( !v21 )
              goto LABEL_52;
            v22 = EmpSearchEntryDatabase(v21);
            v24 = v22;
            if( !v22 )
            {
LABEL_49:
              v12 = -1073741275;
              goto LABEL_53;
            }
            *(_QWORD *)(*((_QWORD *)v11 + 1) + 8 * v23) = v22;
            v25 = *(_SINGLE_LIST_ENTRY **)(a2 + 8 * v20 + 8);
            if( v25 )
            {
              v45 = (_SINGLE_LIST_ENTRY *)(*((_QWORD *)v11 + 3) + 32i64 * v10);
              v45->Next = v25;
              v45[1].Next = *(_SINGLE_LIST_ENTRY **)(a2 + 8 * v20 + 16);
              v46 = v24 + 7;
              Next = v24[8].Next;
              v48 = v45 + 2;
              if( Next->Next != v46 )
                goto LABEL_72;
              v48->Next = v46;
              ++v10;
              v48[1].Next = Next;
              Next->Next = v48;
              v46[1].Next = v48;
            }
            v19 = (unsigned int)(v23 + 1);
            if( (unsigned int)v19 >= (unsigned int)v7 )
              goto LABEL_19;
          }
        }
        v44 = ExAllocatePoolWithTag(PagedPool, (unsigned int)(32 * v18), 0x72704D45ui64);
        *((_QWORD *)v11 + 3) = v44;
        if( v44 )
        {
          memset((INT64)v44, 0i64);
          goto LABEL_14;
        }
      }
LABEL_44:
      v12 = -1073741670;
      goto LABEL_53;
    }
LABEL_19:
    if( !a5 )
    {
LABEL_27:
      for( i = 0i64; (unsigned int)i < *((_DWORD *)v11 + 4); i = (unsigned int)(i + 1) )
      {
        v38 = *(_QWORD *)(*((_QWORD *)v11 + 1) + 8 * i);
        _InterlockedIncrement((volatile signed __int32 *)(v38 + 16));
        for( j = *(_QWORD **)(v38 + 72); j; j = (_QWORD *)*j )
          EmpQueueRuleUpdateState(*(j - 1), 0i64);
      }
      for( k = 0i64; (unsigned int)k < *((_DWORD *)v11 + 12); k = (unsigned int)(k + 1) )
      {
        v41 = *(_QWORD *)(*((_QWORD *)v11 + 5) + 8 * k);
        _InterlockedIncrement((volatile signed __int32 *)(v41 + 24));
        for( m = *(_QWORD **)(v41 + 48); m; m = (_QWORD *)*m )
          EmpQueueRuleUpdateState(*(m - 1), 0i64);
      }
      if( Object )
        ObfReferenceObject(Object);
      *(_QWORD *)v11 = Object;
      *(_QWORD *)a6 = v11;
      goto LABEL_40;
    }
    v26 = ExAllocatePoolWithTag(PagedPool, (unsigned int)(8 * a5), 0x72704D45ui64);
    *((_QWORD *)v11 + 5) = v26;
    if( !v26 )
      goto LABEL_44;
    memset((INT64)v26, 0i64);
    v27 = 0;
    v28 = 0i64;
    *((_DWORD *)v11 + 12) = a5;
    v29 = (_SINGLE_LIST_ENTRY **)(a4 + 8);
    while( 1 )
    {
      v30 = *v29;
      if( !*v29 )
        break;
      v31 = (const GUID *)*(v29 - 1);
      if( !v31 )
        break;
      v32 = EmpSearchCallbackDatabase(v31);
      v34 = v32;
      if( !v32 )
        goto LABEL_49;
      v35 = v32[2].Next;
      if( v35 && v35 != v30 )
      {
        v12 = -1073741771;
        goto LABEL_53;
      }
      ++v27;
      *(_QWORD *)(v28 + *((_QWORD *)v11 + 5)) = v34;
      v28 += 8i64;
      v34[2].Next = *v33;
      v36 = v33[1];
      v29 = v33 + 3;
      v34[4].Next = v36;
      if( v27 >= a5 )
        goto LABEL_27;
    }
  }
LABEL_52:
  v12 = -1073741811;
LABEL_53:
  if( v11 )
  {
    v49 = (void *)*((_QWORD *)v11 + 1);
    if( v49 )
      ExFreePoolWithTag(v49, 0x72704D45u);
    if( *((_QWORD *)v11 + 3) )
    {
      v50 = 0;
      if( v10 )
      {
        while( 1 )
        {
          v51 = (_QWORD *)(32i64 * v50 + 16 + *((_QWORD *)v11 + 3));
          v52 = *v51;
          if( *(_QWORD **)(*v51 + 8i64) != v51 )
            break;
          v53 = (_QWORD *)v51[1];
          if( (_QWORD *)*v53 != v51 )
            break;
          ++v50;
          *v53 = v52;
          *(_QWORD *)(v52 + 8) = v53;
          if( v50 >= v10 )
            goto LABEL_61;
        }
LABEL_72:
        __fastfail(3u);
      }
LABEL_61:
      ExFreePoolWithTag(*((PVOID *)v11 + 3), 0x72704D45u);
    }
    v54 = (char *)*((_QWORD *)v11 + 5);
    if( v54 )
    {
      if( a5 )
      {
        v55 = (char *)*((_QWORD *)v11 + 5);
        v56 = 0i64;
        v57 = (unsigned int)a5;
        do
        {
          v58 = *(_QWORD *)&v54[v56];
          if( v58 && !*(_DWORD *)(v58 + 24) )
          {
            *(_QWORD *)(v58 + 16) = 0i64;
            v54 = (char *)*((_QWORD *)v11 + 5);
            v55 = v54;
          }
          v56 += 8i64;
          --v57;
        }
        while( v57 );
        v54 = v55;
      }
      ExFreePoolWithTag(v54, 0x72704D45u);
    }
    ExFreePoolWithTag(v11, 0x72704D45u);
  }
LABEL_40:
  if( (_InterlockedExchangeAdd64((volatile signed __int64 *)&EmpDatabaseLock, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)&EmpDatabaseLock);
  KeAbPostRelease(&EmpDatabaseLock);
  return v12;
}

Referenced by:

EmInitSystem
EmProviderRegister
HalRegisterErrataCallbacks
PoInitSystem