CmpSubtreeEnumeratorAdvance

INT64 __fastcall CmpSubtreeEnumeratorAdvance(INT64 a1){
  unsigned int v2; 
  __int16 v3; 
  __int64 v4; 
  INT64 v6; 
  INT64 KcbInHashEntryByName; 
  INT16 v8; 
  INT64 KcbAtLayerHeight; 
  __int64 v10; 
  INT64 EntryAtLayerHeight; 
  __int16 v12; 
  bool v13; 
  WCHAR *v14; 
  unsigned int ComponentNameLength; 
  int v16; 
  int v17; 
  __int64 v18; 
  UNICODE_STRING Component; 
  v2 = 0;
  v3 = *(_WORD *)a1;
  Component = 0i64;
  if( v3 < 0 )
  {
    return(unsigned int)-2147483622;
  }
  else
  {
    while( 1 )
    {
      v4 = *(_QWORD *)(a1 + 96) + 408i64 * v3;
      if( !*(_BYTE *)v4 )
      {
        CmpKeyEnumStackBeginEnumerationForKeyNodeStack((INT16 *)(v4 + 56), *(_QWORD *)(v4 + 16));
        *(_BYTE *)v4 = 1;
      }
      if( (unsigned int)CmpKeyEnumStackAdvance((INT16 *)(v4 + 56)) != -2147483622 )
        break;
      CmpKeyEnumStackReset(v4 + 56);
      *(_QWORD *)(v4 + 16) = 0i64;
      *(_QWORD *)(v4 + 8) = 0i64;
      *(_BYTE *)v4 = 0;
      v3 = *(_WORD *)a1 - 1;
      *(_WORD *)a1 = v3;
      if( v3 < 0 )
        return(unsigned int)-2147483622;
    }
    v6 = *(_QWORD *)(v4 + 8);
    if( v6 )
    {
      KcbAtLayerHeight = CmpGetKcbAtLayerHeight(v6, *(_WORD *)(a1 + 2));
      v10 = 0i64;
      if( v8 >= 0 )
      {
        while( 1 )
        {
          EntryAtLayerHeight = CmpKeyNodeStackGetEntryAtLayerHeight(v4 + 64, v8);
          if( *(_QWORD *)(EntryAtLayerHeight + 16) )
            break;
          v8 = v12 - 1;
          if( v8 < 0 )
            goto LABEL_15;
        }
        v10 = *(_QWORD *)(EntryAtLayerHeight + 16);
      }
LABEL_15:
      v13 = (*(_BYTE *)(v10 + 2) & 0x20) == 0;
      v14 = (WCHAR *)(v10 + 76);
      ComponentNameLength = *(unsigned __int16 *)(v10 + 72);
      Component.Buffer = (wchar_t *)(v10 + 76);
      Component.Length = ComponentNameLength;
      Component.MaximumLength = ComponentNameLength;
      if( v13 )
      {
        v17 = CmpHashUnicodeComponent(&Component);
        KcbInHashEntryByName = CmpFindKcbInHashEntryByName(
                                 *(_QWORD *)(KcbAtLayerHeight + 32),
                                 (unsigned int)(v17 + 37 * *(_DWORD *)(KcbAtLayerHeight + 16)),
                                 KcbAtLayerHeight,
                                 &Component);
      }
      else
      {
        v16 = CmpHashCompressedComponent((UINT8 *)(v10 + 76), ComponentNameLength);
        CmpFindKcbInHashEntryByCompressedName(
          *(_CMHIVE **)(KcbAtLayerHeight + 32),
          (_CM_PATH_HASH)(v16 + 37 * *(_DWORD *)(KcbAtLayerHeight + 16)),
          (_CM_KEY_CONTROL_BLOCK *)KcbAtLayerHeight,
          v14,
          ComponentNameLength);
      }
    }
    else
    {
      KcbInHashEntryByName = 0i64;
    }
    *(_QWORD *)(v4 + 424) = v4 + 64;
    if( KcbInHashEntryByName )
    {
      CmpPopulateKcbStack(v4 + 24, KcbInHashEntryByName);
      *(_QWORD *)(v4 + 416) = v18;
    }
    ++*(_WORD *)a1;
  }
  return v2;
}

Referenced by:

CmRenameKey
CmpDoAccessCheckOnLayeredSubtree
CmpPromoteSubtree