CmpFindSubKeyByNumberEx

INT64 __fastcall CmpFindSubKeyByNumberEx(
        _HHIVE *Hive,
        INT64 NodeCellIndex,
        UINT64 Number,
        UINT *ChildCell,
        _CM_KEY_CONTROL_BLOCK *ParentKcb,
        _CM_KEY_CONTROL_BLOCK *LockedKcb,
        _CM_TRANS *CmTrans,
        _CM_KEY_CONTROL_BLOCK **ChildKcb){
  _CELL_DATA *(__fastcall *GetCellRoutine)(_HHIVE *, unsigned int, _HV_GET_CELL_CONTEXT *); 
  UINT *v9; 
  unsigned int SubKeyByNumber; 
  _CM_KEY_NODE *v13; 
  INT64 result; 
  unsigned int v15; 
  unsigned int v16; 
  unsigned int v17; 
  unsigned int v18; 
  int v19; 
  bool v20; 
  _CELL_DATA *(__fastcall *v21)(_HHIVE *, unsigned int, _HV_GET_CELL_CONTEXT *); 
  INT16 *v22; 
  UINT v23; 
  _HV_GET_CELL_CONTEXT *v24; 
  unsigned int v25; 
  int SubkeyInHashByChildCell; 
  __int64 v27; 
  int v28; 
  INT16 *v29; 
  unsigned int i; 
  PVOID BugCheckParameter2; 
  unsigned int v32; 
  unsigned int v33; 
  int v34[2]; 
  __int64 v35; 
  LIST_ENTRY *ListIterator; 
  int v37[2]; 
  int v38[2]; 
  int v39; 
  unsigned int Numbera; 
  UINT **v41; 

  Numbera = Number;
  v34[0] = -1;
  v34[1] = 0;
  GetCellRoutine = Hive->GetCellRoutine;
  v9 = 0i64;
  BugCheckParameter2 = 0i64;
  SubKeyByNumber = 0;
  v13 = (_CM_KEY_NODE *)GetCellRoutine(Hive, NodeCellIndex, (_HV_GET_CELL_CONTEXT *)v34);
  if( !v13 )
    return 3221225626i64;
  *ChildCell = -1;
  if( v41 )
    *v41 = 0i64;
  if( !ParentKcb || ParentKcb->KCBUoWListHead[0].Flink == ParentKcb->KCBUoWListHead )
  {
    SubKeyByNumber = CmpFindSubKeyByNumber(Hive, v13, Numbera, ChildCell);
  }
  else
  {
    v15 = v13->SubKeyCounts[0];
    v39 = 0;
    v37[0] = -1;
    v37[1] = 0;
    v38[0] = -1;
    v38[1] = 0;
    LODWORD(ListIterator) = v15;
    if( v15 )
      v33 = v13->SubKeyLists[0];
    else
      v33 = -1;
    v16 = v13->SubKeyCounts[1];
    if( v16 )
      LODWORD(v35) = v13->SubKeyLists[1];
    else
      LODWORD(v35) = -1;
    v32 = v15 + v16;
    Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v34);
    v17 = v32;
    v18 = 0;
    v13 = 0i64;
    for( i = 0; v18 < v32; i = v18 )
    {
      v19 = (int)ListIterator;
      v20 = v18 < (unsigned int)ListIterator;
      v21 = Hive->GetCellRoutine;
      BugCheckParameter2 = 0i64;
      if( v20 )
      {
        v22 = (INT16 *)v21(Hive, v33, (_HV_GET_CELL_CONTEXT *)v37);
        if( !v22 )
          return 3221225626i64;
        v23 = CmpDoFindSubKeyByNumber((INT64)Hive, v22, i);
        v24 = (_HV_GET_CELL_CONTEXT *)v37;
      }
      else
      {
        v29 = (INT16 *)v21(Hive, v35, (_HV_GET_CELL_CONTEXT *)v38);
        if( !v29 )
          return 3221225626i64;
        v23 = CmpDoFindSubKeyByNumber((INT64)Hive, v29, i - v19);
        v24 = (_HV_GET_CELL_CONTEXT *)v38;
      }
      *ChildCell = v23;
      Hive->ReleaseCellRoutine(Hive, v24);
      if( *ChildCell == -1 )
        return 3221225626i64;
      result = CmpFindSubkeyInHashByChildCell(
                 (unsigned __int64)ParentKcb,
                 (unsigned __int64)LockedKcb,
                 (__int64)Hive,
                 *ChildCell,
                 (unsigned __int64 *)&BugCheckParameter2);
      SubKeyByNumber = result;
      if( (int)result < 0 )
        return result;
      v9 = (UINT *)BugCheckParameter2;
      if( !BugCheckParameter2
        || CmRmIsKCBVisible((__int64)BugCheckParameter2, (__int64)CmTrans)
        && !CmpIsKeyDeleted((INT64)v9, (INT64)CmTrans) )
      {
        ++v39;
      }
      if( v39 == Numbera + 1 )
      {
        v18 = i;
        v17 = v32;
        break;
      }
      if( v9 )
        CmpDelayDerefKeyControlBlock(v9, (INT64)ChildKcb);
      v17 = v32;
      v18 = i + 1;
    }
    if( v18 == v17 )
    {
      ListIterator = 0i64;
      *ChildCell = -1;
      while( 1 )
      {
        LODWORD(v27) = CmListGetNextElement(ParentKcb->KCBUoWListHead, &ListIterator, 32i64);
        v35 = v27;
        if( !v27 )
          break;
        if( CmEqualTrans(*(_QWORD *)(v27 + 56), (__int64)CmTrans) )
        {
          v28 = *(_DWORD *)(v35 + 68);
          if( v28 == 1 )
          {
            v9 = *(UINT **)(v35 + 88);
          }
          else
          {
            if( v28 != 10 )
              goto LABEL_46;
            v9 = *(UINT **)(v35 + 96);
          }
          BugCheckParameter2 = v9;
          if( CmRmIsKCBVisible((__int64)v9, (__int64)CmTrans) && !CmpIsKeyDeleted((INT64)v9, (INT64)CmTrans) )
          {
            if( v39 == Numbera )
            {
              *ChildCell = v9[10];
              CmpReferenceKeyControlBlock(v9);
              break;
            }
            ++v39;
          }
        }
LABEL_46:
        v9 = 0i64;
        BugCheckParameter2 = 0i64;
      }
    }
  }
  if( !v41 || (v25 = *ChildCell, *ChildCell == -1) )
  {
    if( v9 )
      CmpDelayDerefKeyControlBlock(v9, (INT64)ChildKcb);
  }
  else
  {
    if( !v9 )
    {
      if( v13 )
      {
        Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v34);
        v25 = *ChildCell;
        v13 = 0i64;
      }
      SubkeyInHashByChildCell = CmpFindSubkeyInHashByChildCell(
                                  (unsigned __int64)ParentKcb,
                                  (unsigned __int64)LockedKcb,
                                  (__int64)Hive,
                                  v25,
                                  (unsigned __int64 *)&BugCheckParameter2);
      v9 = (UINT *)BugCheckParameter2;
      SubKeyByNumber = SubkeyInHashByChildCell;
      if( SubkeyInHashByChildCell < 0 )
        *ChildCell = -1;
    }
    *v41 = v9;
  }
  if( v13 )
    Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v34);
  return SubKeyByNumber;
}

Referenced by:

CmEnumerateKey
CmpFindSubKeyByNumberFromMergedView