CmpMergeKeyValues

char __fastcall CmpMergeKeyValues(
        __int64 a1,
        __int64 a2,
        _DWORD *a3,
        void (__fastcall **a4)(_QWORD, _QWORD),
        unsigned int a5,
        __int64 a6){
  char v6; 
  __int64 v8; 
  unsigned int v10; 
  unsigned int v11; 
  unsigned int *v12; 
  VOID **PoolWithTag; 
  unsigned int v14; 
  _WCHAR *v15; 
  __int64 v16; 
  unsigned int *v17; 
  unsigned int v18; 
  _CM_KEY_VALUE *v19; 
  bool v20; 
  void(__fastcall *v21)(__int64, int *); 
  unsigned int v22; 
  UINT64 *v24; 
  INT64 v25; 
  char v26; 
  int v27[2]; 
  int v28[2]; 
  _UNICODE_STRING ValueName; 
  int v30; 
  UINT64 v31; 
  void(__fastcall **Hive)(_QWORD, _QWORD); 

  Hive = a4;
  v30 = a2;
  v6 = 0;
  v28[1] = 0;
  v27[1] = 0;
  v8 = a6;
  v28[0] = -1;
  v27[0] = -1;
  v10 = a3[15];
  v30 = 0;
  LODWORD(v31) = 0;
  ValueName = 0i64;
  if( *(_DWORD *)(a6 + 60) < v10 )
    *(_DWORD *)(a6 + 60) = v10;
  v11 = a3[16];
  if( *(_DWORD *)(v8 + 64) < v11 )
    *(_DWORD *)(v8 + 64) = v11;
  v12 = (unsigned int *)(v8 + 36);
  if( *(_DWORD *)(v8 + 36) )
  {
    v14 = a3[9];
    if( v14 )
    {
      PoolWithTag = ExAllocatePoolWithTag(1ui64, 0x7FFFui64, 538987843i64);
      v15 = (_WCHAR *)PoolWithTag;
      if( !PoolWithTag )
        return(char)PoolWithTag;
      v16 = (unsigned int)a3[10];
      LODWORD(a6) = a5 >> 31;
      v17 = (unsigned int *)(*(__int64(__fastcall **)(__int64, __int64, int *))(a1 + 8))(a1, v16, v28);
      if( v17 )
      {
        v18 = 0;
        while( 1 )
        {
          v19 = (_CM_KEY_VALUE *)(*(__int64(__fastcall **)(__int64, _QWORD, int *))(a1 + 8))(a1, *v17, v27);
          if( !v19 )
            break;
          CmpInitializeValueNameString(v19, &ValueName, v15);
          v20 = !CmpFindNameInList((__int64)Hive, v12, (__int64)&ValueName, 0, (unsigned int *)&v31, &v30);
          v21 = *(void(__fastcall **)(__int64, int *))(a1 + 16);
          if( v20 )
          {
            v21(a1, v27);
            break;
          }
          v21(a1, v27);
          if( v30 == -1 )
          {
            v22 = CmpCopyValue(a1, *v17, (UINT64)Hive, (unsigned int)a6);
            if( v22 == -1 )
              break;
            LODWORD(v25) = 1;
            if( (int)CmpAddValueToListEx((UINT64)Hive, v22, (unsigned int)v31, (unsigned int)a6, (UINT64 *)v12, v25) < 0 )
              break;
          }
          ++v18;
          ++v17;
          if( v18 >= v14 )
          {
            v6 = 1;
            break;
          }
        }
        (*(void(__fastcall **)(__int64, int *))(a1 + 16))(a1, v28);
      }
      ExFreePoolWithTag(v15, 0);
    }
    else
    {
      v6 = 1;
    }
    LOBYTE(PoolWithTag) = v6;
    return(char)PoolWithTag;
  }
  LODWORD(v24) = a5;
  LOBYTE(PoolWithTag) = CmpSyncKeyValues((_EX_PUSH_LOCK *)a1, a2, (__int64)a3, (__int64)a4, (UINT64)v24, v8, v26);
  return(char)PoolWithTag;
}

Referenced by:

CmSaveMergedKeys
CmpCopySyncTree2