CmpWalkOneLevel

__int64 __fastcall CmpWalkOneLevel(
        __int64 a1,
        __int64 a2,
        __int64 *a3,
        __int64 a4,
        __int64 a5,
        __int64 a6,
        int a7,
        ULONG_PTR a8,
        __int64 a9,
        char a10,
        __int64 a11){
  __int64 v11; 
  ULONG_PTR v14; 
  INT16 v15; 
  __int16 v16; 
  __int64 v17; 
  ULONG_PTR v18; 
  UINT64 v19; 
  signed __int32 v20; 
  signed __int32 v21; 
  __int16 v22; 
  __int16 i; 
  __int64 v24; 
  __int64 v25; 
  __int64 v26; 
  _KPROCESS *v27; 
  __int16 v28; 
  _CM_KEY_CONTROL_BLOCK *v29; 
  __int64 KeyCell; 
  __int64 v31; 
  _HHIVE *KeyHive; 
  __int64 v33; 
  INT64 v34; 
  int v35; 
  __int64 v36; 
  unsigned int v37; 
  __int64 v38; 
  __int16 v39; 
  __int16 v40; 
  __int64 v41; 
  bool v42; 
  __int16 v43; 
  __int64 v44; 
  __int64 v45; 
  __int64 v46; 
  UINT64 v47; 
  _CM_KEY_INDEX *v49; 
  int v50; 
  __int16 v51; 
  UINT16 *v52; 
  __int64 v53; 
  UINT16 v54; 
  unsigned __int16 v55; 
  int v56; 
  volatile INT64 *v57; 
  int v58; 
  __int16 v59; 
  __int16 v60; 
  int v61; 
  __int64 v62; 
  LIST_ENTRY *v63; 
  int v64; 
  INT64 KcbAtLayerHeight; 
  _CMHIVE *v66; 
  void *KcbInHashEntryByName; 
  INT64 v68; 
  INT64 v69; 
  INT64 v70; 
  UINT64 v71; 
  UINT64 v72; 
  _HHIVE *v73; 
  UINT *BugCheckParameter4; 
  __int16 v75; 
  int SubKeyInLeafWithStatus; 
  __int16 v77; 
  __int16 v78; 
  UINT Index; 
  ULONG_PTR v80; 
  int v81[2]; 
  __int64 v82; 
  _CM_KEY_CONTROL_BLOCK *ParentKcb; 
  int v84; 
  int v85; 
  INT64 v86; 
  int v87; 
  __int64 v88; 
  _CM_KEY_CONTROL_BLOCK *ResultKcb; 
  LIST_ENTRY *ListIterator; 
  __m128i v91; 
  v11 = a1;
  v82 = 0i64;
  v14 = 0i64;
  v15 = *(_WORD *)(a1 + 66) - 1;
  ResultKcb = 0i64;
  LODWORD(v82) = -1;
  v75 = -1;
  v80 = 0i64;
  if( v15 >= 0 )
  {
    do
    {
      KcbAtLayerHeight = CmpGetKcbAtLayerHeight(a2, v15);
      CmpLockHashEntryShared(*(_QWORD *)(KcbAtLayerHeight + 32), (unsigned int)a8);
      v66 = *(_CMHIVE **)(KcbAtLayerHeight + 32);
      KcbInHashEntryByName = (void *)CmpFindKcbInHashEntryByName(
                                       (INT64)v66,
                                       (unsigned int)a8,
                                       KcbAtLayerHeight,
                                       (const UNICODE_STRING *)a6);
      v80 = (ULONG_PTR)KcbInHashEntryByName;
      if( KcbInHashEntryByName )
      {
        v14 = (ULONG_PTR)KcbInHashEntryByName;
        CmpReferenceKeyControlBlockLockNotHeld(KcbInHashEntryByName);
        CmpUnlockHashEntry(*(_CMHIVE **)(KcbAtLayerHeight + 32), (_CM_PATH_HASH)a8);
        CmpPopulateKcbStack(a4, v14);
        v16 = *(_WORD *)(v14 + 66) + 1;
        goto LABEL_3;
      }
      CmpUnlockHashEntry(v66, (_CM_PATH_HASH)a8);
      --v15;
    }
    while( v15 >= 0 );
    v14 = v80;
  }
  v16 = 0;
  *(_WORD *)(a4 + 2) = -1;
LABEL_3:
  v78 = v16;
  if( v16 <= *(__int16 *)(v11 + 66) )
  {
    do
    {
      if( v16 >= 2 )
        v17 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v16 - 16);
      else
        v17 = *(_QWORD *)(a2 + 8i64 * v16 + 8);
      v18 = *(_QWORD *)(v17 + 32);
      v19 = *(_QWORD *)(v18 + 1640)
          + 24
          * (((101027 * ((unsigned int)a8 ^ ((unsigned int)a8 >> 9))) ^ ((unsigned __int64)(101027
                                                                                          * ((unsigned int)a8 ^ ((unsigned int)a8 >> 9))) >> 9)) & (unsigned int)(*(_DWORD *)(v18 + 1648) - 1));
      ExAcquirePushLockExclusiveEx(v19, 0i64);
      *(_QWORD *)(v19 + 8) = KeGetCurrentThread();
      _m_prefetchw((const void *)(v18 + 4272));
      v20 = *(_DWORD *)(v18 + 4272);
      if( !v20 )
LABEL_136:
        KeBugCheckEx(0x51u, 0x17ui64, v18, 0xCui64, (unsigned int)a8);
      while( 1 )
      {
        v21 = v20;
        v20 = _InterlockedCompareExchange((volatile signed __int32 *)(v18 + 4272), v20 + 1, v20);
        if( v21 == v20 )
          break;
        if( !v20 )
          goto LABEL_136;
      }
      v75 = v16++;
    }
    while( v16 <= *(__int16 *)(v11 + 66) );
    v14 = v80;
  }
  v22 = *(_WORD *)(a2 + 2);
  for( i = 0; i <= v22; ++i )
  {
    if( i >= 2 )
      v24 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * i - 16);
    else
      v24 = *(_QWORD *)(a2 + 8i64 * i + 8);
    ExAcquirePushLockSharedEx(v24 + 48, 0i64);
    _InterlockedIncrement((volatile signed __int32 *)(v24 + 56));
    v22 = *(_WORD *)(a2 + 2);
  }
  ListIterator = 0i64;
  if( v22 < 0 )
    goto LABEL_121;
  while( 1 )
  {
    if( v22 >= 2 )
      v25 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v22 - 16);
    else
      v25 = *(_QWORD *)(a2 + 8i64 * v22 + 8);
    if( *(_WORD *)(v25 + 66) && *(_BYTE *)(v25 + 65) == 1 )
      goto LABEL_121;
    if( *(_DWORD *)(v25 + 40) != -1 )
      break;
    if( --v22 < 0 )
      goto LABEL_121;
  }
  if( a9 )
  {
    LODWORD(v62) = CmListGetNextElement((LIST_ENTRY *)(*(_QWORD *)(a2 + 8) + 208i64), &ListIterator, 32i64);
    if( v62 )
    {
      do
      {
        v64 = *(_DWORD *)(v62 + 68);
        if( v64 == 2 || v64 == 11 )
          break;
        LODWORD(v62) = CmListGetNextElement(v63 + 13, &ListIterator, 32i64);
      }
      while( v62 );
      if( CmEqualTrans(*(_QWORD *)(v62 + 56), a9) )
      {
LABEL_121:
        v68 = 328192i64;
LABEL_122:
        v35 = -1073741772;
        SubKeyInLeafWithStatus = -1073741772;
        v69 = 3221225524i64;
        goto LABEL_123;
      }
    }
  }
  v26 = *(_QWORD *)(v11 + 240);
  if( v26 && !CmEqualTrans(a9, v26) )
  {
    v68 = 328448i64;
    goto LABEL_122;
  }
  if( (*(_DWORD *)(v11 + 184) & 0x20000) != 0 )
  {
    v68 = 328704i64;
    goto LABEL_122;
  }
  if( (*(_DWORD *)(a11 + 160) & 1) == 0 )
  {
    v27 = (_EPROCESS *)*(&CmpRegistryProcess + 1);
    if( !*(&CmpRegistryProcess + 1) )
      v27 = (_EPROCESS *)*((_QWORD *)KeGetCurrentThread() + 23);
    KiStackAttachProcess((_KPROCESS *)v27, 0i64, (_KAPC_STATE *)(a11 + 168));
    *(_DWORD *)(a11 + 160) |= 1u;
  }
  if( v14 )
    v28 = *(_WORD *)(v14 + 66) + 1;
  else
    v28 = 0;
  v77 = v28;
  if( v28 > *(__int16 *)(v11 + 66) )
  {
LABEL_98:
    v80 = 0i64;
    SubKeyInLeafWithStatus = 0;
    v60 = v75 - 1;
    if( !a10 )
      v60 = v75;
    v39 = v60;
    *(_BYTE *)a5 = a10 != 0;
    *a3 = v14;
    v35 = 0;
    goto LABEL_46;
  }
  while( 2 )
  {
    if( v28 >= 2 )
      v29 = *(_CM_KEY_CONTROL_BLOCK **)(*(_QWORD *)(a2 + 24) + 8i64 * v28 - 16);
    else
      v29 = *(_CM_KEY_CONTROL_BLOCK **)(a2 + 8i64 * v28 + 8);
    KeyCell = v29->KeyHash.KeyCell;
    ParentKcb = v29;
    if( (_DWORD)KeyCell == -1 )
    {
      v37 = -1;
      goto LABEL_41;
    }
    v31 = (__int64)v29->KeyHash.KeyHive->GetCellRoutine(v29->KeyHash.KeyHive, KeyCell, (_HV_GET_CELL_CONTEXT *)&v82);
    KeyHive = v29->KeyHash.KeyHive;
    v33 = v31;
    v88 = v31;
    if( (KeyHive->HiveFlags & 0x8001) == 0 && (*(_BYTE *)(v31 + 12) & (unsigned __int8)CmpAccessBitForPhase) == 0 )
    {
      KeyHive->ReleaseCellRoutine(KeyHive, (_HV_GET_CELL_CONTEXT *)&v82);
      ExAcquirePushLockSharedEx((UINT64)&v29->KeyHash.KeyHive->FlusherLock, 0i64);
      v70 = (INT64)v29->KeyHash.KeyHive->GetCellRoutine(
                     v29->KeyHash.KeyHive,
                     v29->KeyHash.KeyCell,
                     (_HV_GET_CELL_CONTEXT *)&v82);
      v71 = v29->KeyHash.KeyCell;
      v72 = (UINT64)v29->KeyHash.KeyHive;
      v33 = v70;
      v88 = v70;
      CmpUpdateKeyNodeAccessBits(v72, v70, v71);
      v73 = v29->KeyHash.KeyHive;
      if( _InterlockedCompareExchange64((volatile signed __int64 *)&v73->FlusherLock, 0i64, 17i64) != 17 )
        ExfReleasePushLockShared((INT64 *)&v73->FlusherLock);
      KeAbPostRelease(&v73->FlusherLock);
    }
    v34 = (INT64)v29->KeyHash.KeyHive;
    v81[1] = 0;
    v86 = v34;
    v85 = -1;
    v35 = -1073741772;
    v36 = 0i64;
    v84 = 0;
    SubKeyInLeafWithStatus = -1073741772;
    v81[0] = -1;
    Index = 0;
    v87 = 0;
    if( !*(_DWORD *)(v34 + 208) )
      goto LABEL_38;
    while( !*(_DWORD *)(v33 + 4 * v36 + 20) )
    {
LABEL_36:
      v36 = (unsigned int)(v84 + 1);
      v84 = v36;
      if( (unsigned int)v36 >= *(_DWORD *)(v34 + 208) )
        goto LABEL_37;
    }
    v49 = (_CM_KEY_INDEX *)(*(__int64(__fastcall **)(INT64, _QWORD, int *))(v34 + 8))(
                             v34,
                             *(unsigned int *)(v33 + 4 * v36 + 28),
                             v81);
    if( !v49 )
      goto LABEL_145;
    if( v49->Signature == 26994 )
    {
      BugCheckParameter4 = &Index;
      if( CmpFindSubKeyInRoot((PVOID)v34, v49) < 0 )
      {
        v35 = -1073741670;
        goto LABEL_85;
      }
      (*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v81);
      if( Index == -1 )
        goto LABEL_80;
      v49 = (_CM_KEY_INDEX *)(*(__int64(__fastcall **)(INT64, _QWORD, int *))(v34 + 8))(v34, Index, v81);
      if( !v49 )
      {
LABEL_145:
        v35 = -1073741670;
        SubKeyInLeafWithStatus = -1073741670;
        goto LABEL_37;
      }
    }
    if( v49->Signature != 26732 )
    {
      SubKeyInLeafWithStatus = CmpFindSubKeyInLeafWithStatus(
                                 (_HHIVE *)v34,
                                 v49,
                                 (const _UNICODE_STRING *)a6,
                                 0i64,
                                 &Index);
      v35 = SubKeyInLeafWithStatus;
      if( (int)(SubKeyInLeafWithStatus + 0x80000000) >= 0 && SubKeyInLeafWithStatus != -1073741772 )
        goto LABEL_86;
      v56 = Index;
LABEL_83:
      if( v56 != -1 )
      {
        v85 = v56;
        v35 = 0;
        goto LABEL_85;
      }
      goto LABEL_79;
    }
    v50 = 0;
    v51 = _mm_cvtsi128_si32(*(__m128i *)a6);
    v91 = *(__m128i *)a6;
    if( v51 )
    {
      v52 = (UINT16 *)v91.m128i_i64[1];
      v53 = (unsigned __int16)(((unsigned __int16)(v51 - 1) >> 1) + 1);
      do
      {
        v54 = *v52;
        if( *v52 >= 0x61u )
        {
          if( v54 > 0x7Au )
            v54 = NLS_UPCASE(v54);
          else
            v54 -= 32;
        }
        ++v52;
        v50 = v54 + 37 * v50;
        --v53;
      }
      while( v53 );
      v91.m128i_i64[1] = (__int64)v52;
    }
    v55 = 0;
    Index = -1;
    if( !v49->Count )
    {
LABEL_78:
      v34 = v86;
      v35 = -1073741772;
      SubKeyInLeafWithStatus = -1073741772;
LABEL_79:
      (*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v81);
LABEL_80:
      v33 = v88;
      goto LABEL_36;
    }
    while( 1 )
    {
      if( v50 != *(_DWORD *)&v49[v55 + 1].Signature )
        goto LABEL_77;
      v61 = CmpDoCompareKeyName(v86, (const UNICODE_STRING *)a6, 0i64, v49[v55].List[0]);
      if( v61 == 2 )
        break;
      if( !v61 )
      {
        v56 = v49[v55].List[0];
        v34 = v86;
        v35 = 0;
        SubKeyInLeafWithStatus = 0;
        Index = v56;
        goto LABEL_83;
      }
LABEL_77:
      if( ++v55 >= v49->Count )
        goto LABEL_78;
    }
    v34 = v86;
    v35 = -1073741670;
LABEL_85:
    SubKeyInLeafWithStatus = v35;
LABEL_86:
    (*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v81);
LABEL_37:
    v11 = a1;
LABEL_38:
    ParentKcb->KeyHash.KeyHive->ReleaseCellRoutine(ParentKcb->KeyHash.KeyHive, (_HV_GET_CELL_CONTEXT *)&v82);
    if( v35 == -1073741772 )
    {
      v37 = -1;
      goto LABEL_40;
    }
    if( v35 < 0 )
    {
      CmpRecordParseFailure(a11, 328960i64, (unsigned int)v35);
      goto LABEL_45;
    }
    v37 = v85;
    if( v85 != -1 )
    {
      v29 = ParentKcb;
      goto LABEL_90;
    }
LABEL_40:
    v29 = ParentKcb;
LABEL_41:
    if( *(_WORD *)(v11 + 66) || a10 )
    {
LABEL_90:
      v57 = (volatile INT64 *)v80;
      LODWORD(BugCheckParameter4) = 0;
      v58 = CmpCreateKeyControlBlock(
              (_CMHIVE *)v29->KeyHash.KeyHive,
              v37,
              v29,
              (_CM_KEY_CONTROL_BLOCK *)v80,
              (UINT64)BugCheckParameter4,
              (_UNICODE_STRING *)a6,
              (_CM_COMPONENT_HASH)a7,
              (_CM_PATH_HASH)a8,
              &ResultKcb);
      SubKeyInLeafWithStatus = v58;
      v35 = v58;
      if( v58 >= 0 )
      {
        if( v57 )
          CmpDereferenceKeyControlBlockUnsafe(v57);
        v14 = (ULONG_PTR)ResultKcb;
        ResultKcb = 0i64;
        v80 = v14;
        ++*(_WORD *)(a4 + 2);
        if( v77 >= 2 )
          *(_QWORD *)(*(_QWORD *)(a4 + 24) + 8i64 * v77 - 16) = v14;
        else
          *(_QWORD *)(a4 + 8i64 * v77 + 8) = v14;
        v59 = *(_WORD *)(v11 + 66);
        if( v77 != v59 )
        {
          CmpUnlockHashEntry((_CMHIVE *)ParentKcb->KeyHash.KeyHive, (_CM_PATH_HASH)a8);
          ++v78;
          v59 = *(_WORD *)(v11 + 66);
        }
        v28 = v77 + 1;
        v77 = v28;
        if( v28 > v59 )
          goto LABEL_98;
        continue;
      }
      v69 = (unsigned int)v58;
      v68 = 329472i64;
LABEL_123:
      CmpRecordParseFailure(a11, v68, v69);
      goto LABEL_45;
    }
    break;
  }
  v35 = -1073741772;
  SubKeyInLeafWithStatus = -1073741772;
  v38 = *(unsigned __int8 *)(a11 + 258);
  if( (unsigned __int8)v38 < 4u )
  {
    *(_DWORD *)(a11 + 8 * v38 + 260) = -1073741772;
    *(_DWORD *)(a11 + 8i64 * (unsigned __int8)(*(_BYTE *)(a11 + 258))++ + 264) = 329216;
  }
LABEL_45:
  v39 = v75;
LABEL_46:
  v40 = 0;
  if( *(__int16 *)(a2 + 2) >= 0 )
  {
    do
    {
      if( v40 >= 2 )
        v41 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v40 - 16);
      else
        v41 = *(_QWORD *)(a2 + 8i64 * v40 + 8);
      v42 = (*(_DWORD *)(v41 + 8) & 0x80000) != 0;
      if( *(struct _KTHREAD **)(v41 + 56) == KeGetCurrentThread() )
        *(_QWORD *)(v41 + 56) = 0i64;
      else
        _InterlockedDecrement((volatile signed __int32 *)(v41 + 56));
      ExReleasePushLockEx(v41 + 48, 0i64);
      if( v42 && (*(_DWORD *)(v41 + 8) & 0x80000) != 0 )
        CmpFreeKeyControlBlock((_CM_KEY_CONTROL_BLOCK *)v41);
      ++v40;
    }
    while( v40 <= *(__int16 *)(a2 + 2) );
    v35 = SubKeyInLeafWithStatus;
  }
  v43 = v78;
  if( v78 <= v39 )
  {
    v44 = 8i64 * v78 - 16;
    do
    {
      if( v43 >= 2 )
        v45 = *(_QWORD *)(v44 + *(_QWORD *)(a2 + 24));
      else
        v45 = *(_QWORD *)(v44 + a2 + 24);
      v46 = *(_QWORD *)(v45 + 32);
      v47 = *(_QWORD *)(v46 + 1640)
          + 24
          * (((101027 * ((unsigned int)a8 ^ ((unsigned int)a8 >> 9))) ^ ((unsigned __int64)(101027
                                                                                          * ((unsigned int)a8 ^ ((unsigned int)a8 >> 9))) >> 9)) & (unsigned int)(*(_DWORD *)(v46 + 1648) - 1));
      *(_QWORD *)(v47 + 8) = 0i64;
      ExReleasePushLockEx(v47, 0i64);
      if( _InterlockedExchangeAdd((volatile signed __int32 *)(v46 + 4272), 0xFFFFFFFF) == 1 )
        CmpDeleteHive((PVOID)v46);
      ++v43;
      v44 += 8i64;
    }
    while( v43 <= v39 );
    v35 = SubKeyInLeafWithStatus;
  }
  if( v80 )
    CmpDereferenceKeyControlBlock(v80);
  return(unsigned int)v35;
}

Referenced by:

CmpDoBuildVirtualStack
CmpDoParseKey