CmpDoAccessCheckOnSubtree

INT64 __fastcall CmpDoAccessCheckOnSubtree(INT64 a1, UINT64 a2, INT64 a3, INT64 a4, INT64 a5){
  unsigned int v5; 
  CHAR v6; 
  unsigned int v7; 
  int SubKeyByNumber; 
  unsigned int *TransientPoolWithTag; 
  VOID *v11; 
  __int64 v12; 
  UINT *v13; 
  UINT64 v14; 
  _CM_KEY_NODE *v15; 
  _CM_KEY_NODE *v16; 
  UINT64 v17; 
  UINT v18; 
  __int64 v19; 
  UINT ChildCell; 
  _DWORD v22[2]; 
  CHAR v23; 

  v23 = a3;
  v22[0] = -1;
  v5 = a4;
  v6 = a3;
  ChildCell = 0;
  v7 = a2;
  v22[1] = 0;
  if( (a5 & 0xFFFFFFFC) != 0 )
  {
    return(unsigned int)-1073741811;
  }
  else
  {
    TransientPoolWithTag = (unsigned int *)CmpAllocateTransientPoolWithTag(1ui64, 0x2800ui64);
    v11 = TransientPoolWithTag;
    if( TransientPoolWithTag )
    {
      TransientPoolWithTag[3] = 0;
      *TransientPoolWithTag = v7;
      v12 = 0i64;
      *((_BYTE *)TransientPoolWithTag + 16) = !(a5 & 1);
      v13 = TransientPoolWithTag;
      while( 1 )
      {
        if( !*((_BYTE *)v13 + 16) )
        {
          v14 = *v13;
          *((_BYTE *)v13 + 16) = 1;
          SubKeyByNumber = CmpCheckKeyAccess((_HHIVE *)a1, v14, v6, v5);
          if( SubKeyByNumber < 0 )
            break;
        }
        v15 = (_CM_KEY_NODE *)(*(__int64(__fastcall **)(INT64, _QWORD, _DWORD *))(a1 + 8))(a1, *v13, v22);
        v16 = v15;
        if( !v15 )
        {
          SubKeyByNumber = -1073741670;
          break;
        }
        v17 = v13[3];
        if( (unsigned int)v17 >= v15->SubKeyCounts[0] + v15->SubKeyCounts[1] )
        {
          v13 -= 5;
          v19 = -1i64;
        }
        else
        {
          SubKeyByNumber = CmpFindSubKeyByNumber((_HHIVE *)a1, v15, v17, &ChildCell);
          if( SubKeyByNumber < 0 )
            goto LABEL_19;
          v18 = ChildCell;
          if( ChildCell == -1 || (++v13[3], v13 += 5, v12 == 511) )
          {
            SubKeyByNumber = -1073741670;
            goto LABEL_19;
          }
          v13[3] = 0;
          *v13 = v18;
          v19 = 1i64;
          *((_BYTE *)v13 + 16) = 0;
        }
        v12 += v19;
        (*(void(__fastcall **)(INT64, _DWORD *))(a1 + 16))(a1, v22);
        if( v12 < 0 )
        {
          SubKeyByNumber = 0;
          v16 = 0i64;
LABEL_19:
          if( v16 )
            (*(void(__fastcall **)(INT64, _DWORD *))(a1 + 16))(a1, v22);
          break;
        }
        v6 = v23;
      }
      CmpFreeTransientPoolWithTag(v11, 0x74634D43ui64);
    }
    else
    {
      return(unsigned int)-1073741670;
    }
  }
  return(unsigned int)SubKeyByNumber;
}

Referenced by:

CmDumpKey
CmRestoreKey
CmSaveMergedKeys