EmpProviderRegister

NTSTATUS __fastcall EmpProviderRegister(UINT64 a1, INT64 a2, UINT64 a3, INT64 a4, UINT64 a5, UINT64 *a6){
  __int64 v7; 
  unsigned int v10; 
  VOID **v11; 
  NTSTATUS v12; 
  VOID **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; 
  UINT64 v44; 
  VOID **v45; 
  _SINGLE_LIST_ENTRY *v46; 
  _SINGLE_LIST_ENTRY *v47; 
  _SINGLE_LIST_ENTRY *Next; 
  _SINGLE_LIST_ENTRY *v49; 
  void *v50; 
  unsigned int v51; 
  _QWORD *v52; 
  __int64 v53; 
  _QWORD *v54; 
  char *v55; 
  char *v56; 
  __int64 v57; 
  __int64 v58; 
  __int64 v59; 

  v7 = (unsigned int)a3;
  v10 = 0;
  v11 = 0i64;
  v12 = 0;
  ExAcquirePushLockExclusiveEx(&EmpDatabaseLock, 0i64);
  if( a6 && (!(_DWORD)v7 || a2) && (!(_DWORD)a5 || a4) )
  {
    PoolWithTag = ExAllocatePoolWithTag(1ui64, 0x48ui64, 1919962437i64);
    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(1ui64, (unsigned int)(8 * v7), 1919962437i64);
      v11[1] = v15;
      if( v15 )
      {
        memset(v15, 0i64, 8 * v7);
        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 *)v11[1] + v23) = v22;
            v25 = *(_SINGLE_LIST_ENTRY **)(a2 + 8 * v20 + 8);
            if( v25 )
            {
              v46 = (_SINGLE_LIST_ENTRY *)((char *)v11[3] + 32 * v10);
              v46->Next = v25;
              v46[1].Next = *(_SINGLE_LIST_ENTRY **)(a2 + 8 * v20 + 16);
              v47 = v24 + 7;
              Next = v24[8].Next;
              v49 = v46 + 2;
              if( Next->Next != v47 )
                goto LABEL_72;
              v49->Next = v47;
              ++v10;
              v49[1].Next = Next;
              Next->Next = v49;
              v47[1].Next = v49;
            }
            v19 = (unsigned int)(v23 + 1);
            if( (unsigned int)v19 >= (unsigned int)v7 )
              goto LABEL_19;
          }
        }
        v44 = (unsigned int)(32 * v18);
        v45 = ExAllocatePoolWithTag(1ui64, v44, 1919962437i64);
        v11[3] = v45;
        if( v45 )
        {
          memset(v45, 0i64, v44);
          goto LABEL_14;
        }
      }
LABEL_44:
      v12 = -1073741670;
      goto LABEL_53;
    }
LABEL_19:
    if( !(_DWORD)a5 )
    {
LABEL_27:
      for( i = 0i64; (unsigned int)i < *((_DWORD *)v11 + 4); i = (unsigned int)(i + 1) )
      {
        v38 = *((_QWORD *)v11[1] + i);
        _InterlockedIncrement((volatile signed __int32 *)(v38 + 16));
        for( j = *(_QWORD **)(v38 + 72); j; j = (_QWORD *)*j )
          EmpQueueRuleUpdateState((_EMP_RULE_DB_RECORD *)*(j - 1), 0i64);
      }
      for( k = 0i64; (unsigned int)k < *((_DWORD *)v11 + 12); k = (unsigned int)(k + 1) )
      {
        v41 = *((_QWORD *)v11[5] + k);
        _InterlockedIncrement((volatile signed __int32 *)(v41 + 24));
        for( m = *(_QWORD **)(v41 + 48); m; m = (_QWORD *)*m )
          EmpQueueRuleUpdateState((_EMP_RULE_DB_RECORD *)*(m - 1), 0i64);
      }
      if( a1 )
        ObfReferenceObject((PVOID)a1);
      *v11 = (VOID *)a1;
      *a6 = (UINT64)v11;
      goto LABEL_40;
    }
    v26 = ExAllocatePoolWithTag(1ui64, (unsigned int)(8 * a5), 1919962437i64);
    v11[5] = v26;
    if( !v26 )
      goto LABEL_44;
    memset(v26, 0i64, 8 * a5);
    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 *)((char *)v11[5] + v28) = v34;
      v28 += 8i64;
      v34[2].Next = *v33;
      v36 = v33[1];
      v29 = v33 + 3;
      v34[4].Next = v36;
      if( v27 >= (unsigned int)a5 )
        goto LABEL_27;
    }
  }
LABEL_52:
  v12 = -1073741811;
LABEL_53:
  if( v11 )
  {
    v50 = v11[1];
    if( v50 )
      ExFreePoolWithTag(v50, 0x72704D45u);
    if( v11[3] )
    {
      v51 = 0;
      if( v10 )
      {
        while( 1 )
        {
          v52 = (char *)v11[3] + 32 * v51 + 16;
          v53 = *v52;
          if( *(_QWORD **)(*v52 + 8i64) != v52 )
            break;
          v54 = (_QWORD *)v52[1];
          if( (_QWORD *)*v54 != v52 )
            break;
          ++v51;
          *v54 = v53;
          *(_QWORD *)(v53 + 8) = v54;
          if( v51 >= v10 )
            goto LABEL_61;
        }
LABEL_72:
        __fastfail(3u);
      }
LABEL_61:
      ExFreePoolWithTag(v11[3], 0x72704D45u);
    }
    v55 = (char *)v11[5];
    if( v55 )
    {
      if( (_DWORD)a5 )
      {
        v56 = (char *)v11[5];
        v57 = 0i64;
        v58 = (unsigned int)a5;
        do
        {
          v59 = *(_QWORD *)&v55[v57];
          if( v59 && !*(_DWORD *)(v59 + 24) )
          {
            *(_QWORD *)(v59 + 16) = 0i64;
            v55 = (char *)v11[5];
            v56 = v55;
          }
          v57 += 8i64;
          --v58;
        }
        while( v58 );
        v55 = v56;
      }
      ExFreePoolWithTag(v55, 0x72704D45u);
    }
    ExFreePoolWithTag(v11, 0x72704D45u);
  }
LABEL_40:
  if( (_InterlockedExchangeAdd64(&EmpDatabaseLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(&EmpDatabaseLock);
  KeAbPostRelease(&EmpDatabaseLock);
  return v12;
}

Referenced by:

EmInitSystem
EmProviderRegister
HalRegisterErrataCallbacks
PoInitSystem