CmpFindSubKeyByNumberEx

NTSTATUS __stdcall CmpFindSubKeyByNumberEx(
        _HHIVE *Hive,
        UINT64 NodeCellIndex,
        UINT64 Number,
        UINT64 *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 *); 
  _CM_KEY_CONTROL_BLOCK *v9; 
  NTSTATUS SubKeyByNumber; 
  _CM_KEY_NODE *v13; 
  NTSTATUS 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; 
  int v23; 
  _HV_GET_CELL_CONTEXT *v24; 
  UINT64 v25; 
  UINT64 v26; 
  int SubkeyInHashByChildCell; 
  __int64 v28; 
  int v29; 
  INT16 *v30; 
  unsigned int i; 
  ULONG_PTR BugCheckParameter2; 
  unsigned int v33; 
  unsigned int v34; 
  int v35[2]; 
  __int64 v36; 
  LIST_ENTRY *ListIterator; 
  int v38[2]; 
  int v39[2]; 
  int v40; 
  unsigned int Numbera; 
  _CM_KEY_CONTROL_BLOCK **v42; 
  Numbera = Number;
  v35[0] = -1;
  v35[1] = 0;
  GetCellRoutine = Hive->GetCellRoutine;
  v9 = 0i64;
  BugCheckParameter2 = 0i64;
  SubKeyByNumber = 0;
  v13 = (_CM_KEY_NODE *)GetCellRoutine(Hive, NodeCellIndex, (_HV_GET_CELL_CONTEXT *)v35);
  if( !v13 )
    return -1073741670;
  *(_DWORD *)ChildCell = -1;
  if( v42 )
    *v42 = 0i64;
  if( !ParentKcb || ParentKcb->KCBUoWListHead.Flink == &ParentKcb->KCBUoWListHead )
  {
    SubKeyByNumber = CmpFindSubKeyByNumber(Hive, v13, Numbera, (UINT *)ChildCell);
  }
  else
  {
    v15 = v13->SubKeyCounts[0];
    v40 = 0;
    v38[0] = -1;
    v38[1] = 0;
    v39[0] = -1;
    v39[1] = 0;
    LODWORD(ListIterator) = v15;
    if( v15 )
      v34 = v13->SubKeyLists[0];
    else
      v34 = -1;
    v16 = v13->SubKeyCounts[1];
    if( v16 )
      LODWORD(v36) = v13->SubKeyLists[1];
    else
      LODWORD(v36) = -1;
    v33 = v15 + v16;
    Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v35);
    v17 = v33;
    v18 = 0;
    v13 = 0i64;
    for( i = 0; v18 < v33; i = v18 )
    {
      v19 = (int)ListIterator;
      v20 = v18 < (unsigned int)ListIterator;
      v21 = Hive->GetCellRoutine;
      BugCheckParameter2 = 0i64;
      if( v20 )
      {
        v22 = (INT16 *)v21(Hive, v34, (_HV_GET_CELL_CONTEXT *)v38);
        if( !v22 )
          return -1073741670;
        v23 = CmpDoFindSubKeyByNumber((INT64)Hive, v22, i);
        v24 = (_HV_GET_CELL_CONTEXT *)v38;
      }
      else
      {
        v30 = (INT16 *)v21(Hive, v36, (_HV_GET_CELL_CONTEXT *)v39);
        if( !v30 )
          return -1073741670;
        v23 = CmpDoFindSubKeyByNumber((INT64)Hive, v30, i - v19);
        v24 = (_HV_GET_CELL_CONTEXT *)v39;
      }
      *(_DWORD *)ChildCell = v23;
      Hive->ReleaseCellRoutine(Hive, v24);
      v25 = *(unsigned int *)ChildCell;
      if( (_DWORD)v25 == -1 )
        return -1073741670;
      result = CmpFindSubkeyInHashByChildCell(
                 (UINT64)ParentKcb,
                 (UINT64)LockedKcb,
                 (INT64)Hive,
                 v25,
                 &BugCheckParameter2);
      SubKeyByNumber = result;
      if( result < 0 )
        return result;
      v9 = (_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2;
      if( !BugCheckParameter2
        || CmRmIsKCBVisible(BugCheckParameter2, (INT64)CmTrans) && !CmpIsKeyDeleted((INT64)v9, (INT64)CmTrans) )
      {
        ++v40;
      }
      if( v40 == Numbera + 1 )
      {
        v18 = i;
        v17 = v33;
        break;
      }
      if( v9 )
        CmpDelayDerefKeyControlBlock(v9);
      v17 = v33;
      v18 = i + 1;
    }
    if( v18 == v17 )
    {
      ListIterator = 0i64;
      *(_DWORD *)ChildCell = -1;
      while( 1 )
      {
        LODWORD(v28) = CmListGetNextElement(&ParentKcb->KCBUoWListHead, &ListIterator, 32i64);
        v36 = v28;
        if( !v28 )
          break;
        if( CmEqualTrans(*(_QWORD *)(v28 + 56), (__int64)CmTrans) )
        {
          v29 = *(_DWORD *)(v36 + 68);
          if( v29 == 1 )
          {
            v9 = *(_CM_KEY_CONTROL_BLOCK **)(v36 + 88);
          }
          else
          {
            if( v29 != 10 )
              goto LABEL_46;
            v9 = *(_CM_KEY_CONTROL_BLOCK **)(v36 + 96);
          }
          BugCheckParameter2 = (ULONG_PTR)v9;
          if( CmRmIsKCBVisible((INT64)v9, (INT64)CmTrans) && !CmpIsKeyDeleted((INT64)v9, (INT64)CmTrans) )
          {
            if( v40 == Numbera )
            {
              *(_DWORD *)ChildCell = v9->KeyHash.KeyCell;
              CmpReferenceKeyControlBlock((UINT64)v9);
              break;
            }
            ++v40;
          }
        }
LABEL_46:
        v9 = 0i64;
        BugCheckParameter2 = 0i64;
      }
    }
  }
  if( !v42 || (v26 = *(unsigned int *)ChildCell, (_DWORD)v26 == -1) )
  {
    if( v9 )
      CmpDelayDerefKeyControlBlock(v9);
  }
  else
  {
    if( !v9 )
    {
      if( v13 )
      {
        Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v35);
        v26 = *(unsigned int *)ChildCell;
        v13 = 0i64;
      }
      SubkeyInHashByChildCell = CmpFindSubkeyInHashByChildCell(
                                  (UINT64)ParentKcb,
                                  (UINT64)LockedKcb,
                                  (INT64)Hive,
                                  v26,
                                  &BugCheckParameter2);
      v9 = (_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2;
      SubKeyByNumber = SubkeyInHashByChildCell;
      if( SubkeyInHashByChildCell < 0 )
        *(_DWORD *)ChildCell = -1;
    }
    *v42 = v9;
  }
  if( v13 )
    Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v35);
  return SubKeyByNumber;
}

Referenced by:

CmEnumerateKey
CmpFindSubKeyByNumberFromMergedView