CmpWalkOneLevel

INT64 __fastcall CmpWalkOneLevel(
        INT64 a1,
        INT64 a2,
        INT64 *a3,
        INT64 a4,
        _BOOL *a5,
        const _UNICODE_STRING *SearchName,
        INT64 ComponentHash,
        UINT64 PathHash,
        INT64 a9,
        CHAR a10,
        INT64 a11){
  INT64 v11; 
  _WORD *v14; 
  INT16 v15; 
  __int16 v16; 
  __int64 v17; 
  __int64 v18; 
  _EX_PUSH_LOCK *v19; 
  signed __int32 v20; 
  signed __int32 v21; 
  __int16 v22; 
  __int16 i; 
  __int64 v24; 
  __int64 v25; 
  __int64 v26; 
  _EPROCESS *Process; 
  __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; 
  UINT64 v41; 
  bool v42; 
  __int16 v43; 
  __int64 v44; 
  __int64 v45; 
  __int64 v46; 
  unsigned __int64 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; 
  _CM_KEY_CONTROL_BLOCK *KcbInHashEntryByName; 
  INT64 v68; 
  INT64 v69; 
  _CM_KEY_NODE *v70; 
  UINT64 v71; 
  _HHIVE *v72; 
  _EX_PUSH_LOCK *v73; 
  __int16 v74; 
  int SubKeyInLeafWithStatus; 
  __int16 v76; 
  __int16 v77; 
  UINT Index; 
  PVOID v79; 
  int v80[2]; 
  __int64 v81; 
  _CM_KEY_CONTROL_BLOCK *ParentKcb; 
  int v83; 
  int v84; 
  INT64 v85; 
  int v86; 
  __int64 v87; 
  _CM_KEY_CONTROL_BLOCK *ResultKcb; 
  LIST_ENTRY *ListIterator; 
  __m128i v90; 

  v11 = a1;
  v81 = 0i64;
  v14 = 0i64;
  v15 = *(_WORD *)(a1 + 66) - 1;
  ResultKcb = 0i64;
  LODWORD(v81) = -1;
  v74 = -1;
  v79 = 0i64;
  if( v15 >= 0 )
  {
    do
    {
      KcbAtLayerHeight = CmpGetKcbAtLayerHeight(a2, v15);
      CmpLockHashEntryShared(*(_QWORD *)(KcbAtLayerHeight + 32), (unsigned int)PathHash);
      v66 = *(_CMHIVE **)(KcbAtLayerHeight + 32);
      KcbInHashEntryByName = CmpFindKcbInHashEntryByName(
                               v66,
                               (_CM_PATH_HASH)PathHash,
                               (_CM_KEY_CONTROL_BLOCK *)KcbAtLayerHeight,
                               SearchName);
      v79 = KcbInHashEntryByName;
      if( KcbInHashEntryByName )
      {
        v14 = KcbInHashEntryByName;
        CmpReferenceKeyControlBlockLockNotHeld(KcbInHashEntryByName);
        CmpUnlockHashEntry(*(_QWORD *)(KcbAtLayerHeight + 32), (unsigned int)PathHash);
        CmpPopulateKcbStack(a4, (__int64)v14);
        v16 = v14[33] + 1;
        goto LABEL_3;
      }
      CmpUnlockHashEntry((INT64)v66, (unsigned int)PathHash);
      --v15;
    }
    while( v15 >= 0 );
    v14 = v79;
  }
  v16 = 0;
  *(_WORD *)(a4 + 2) = -1;
LABEL_3:
  v77 = 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 = (_EX_PUSH_LOCK *)(*(_QWORD *)(v18 + 1640)
                            + 24
                            * (((101027 * ((unsigned int)PathHash ^ ((unsigned int)PathHash >> 9))) ^ ((unsigned __int64)(101027 * ((unsigned int)PathHash ^ ((unsigned int)PathHash >> 9))) >> 9)) & (unsigned int)(*(_DWORD *)(v18 + 1648) - 1)));
      ExAcquirePushLockExclusiveEx(v19, 0i64);
      v19[1]._bf_0 = (__int64)KeGetCurrentThread();
      _m_prefetchw((const void *)(v18 + 4272));
      v20 = *(_DWORD *)(v18 + 4272);
      if( !v20 )
LABEL_136:
        KeBugCheckEx(0x51u, (PVOID)0x17, (PVOID)v18, (PVOID)0xC, (PVOID)(unsigned int)PathHash);
      while( 1 )
      {
        v21 = v20;
        v20 = _InterlockedCompareExchange((volatile signed __int32 *)(v18 + 4272), v20 + 1, v20);
        if( v21 == v20 )
          break;
        if( !v20 )
          goto LABEL_136;
      }
      v74 = v16++;
    }
    while( v16 <= *(__int16 *)(v11 + 66) );
    v14 = v79;
  }
  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((_EX_PUSH_LOCK *)(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 )
  {
    Process = (_EPROCESS *)*(&CmpDummyThreadEvent + 5);
    if( !*(&CmpDummyThreadEvent + 5) )
      Process = KeGetCurrentThread()->ApcState.Process;
    KiStackAttachProcess(Process, 0i64, (_KAPC_STATE *)(a11 + 168));
    *(_DWORD *)(a11 + 160) |= 1u;
  }
  if( v14 )
    v28 = v14[33] + 1;
  else
    v28 = 0;
  v76 = v28;
  if( v28 > *(__int16 *)(v11 + 66) )
  {
LABEL_98:
    v79 = 0i64;
    SubKeyInLeafWithStatus = 0;
    v60 = v74 - 1;
    if( !a10 )
      v60 = v74;
    v39 = v60;
    *a5 = a10 != 0;
    *a3 = (INT64)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 *)&v81);
    KeyHive = v29->KeyHash.KeyHive;
    v33 = v31;
    v87 = v31;
    if( (KeyHive->HiveFlags & 0x8001) == 0 && (*(_BYTE *)(v31 + 12) & (unsigned __int8)CmpAccessBitForPhase) == 0 )
    {
      KeyHive->ReleaseCellRoutine(KeyHive, (_HV_GET_CELL_CONTEXT *)&v81);
      ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)&v29->KeyHash.KeyHive->FlusherLock, 0i64);
      v70 = (_CM_KEY_NODE *)v29->KeyHash.KeyHive->GetCellRoutine(
                              v29->KeyHash.KeyHive,
                              v29->KeyHash.KeyCell,
                              (_HV_GET_CELL_CONTEXT *)&v81);
      v71 = v29->KeyHash.KeyCell;
      v72 = v29->KeyHash.KeyHive;
      v33 = (__int64)v70;
      v87 = (__int64)v70;
      CmpUpdateKeyNodeAccessBits(v72, v70, v71);
      v73 = (_EX_PUSH_LOCK *)v29->KeyHash.KeyHive;
      if( _InterlockedCompareExchange64(&v73[9]._bf_0, 0i64, 17i64) != 17 )
        ExfReleasePushLockShared(v73 + 9);
      KeAbPostRelease(&v73[9]);
    }
    v34 = (INT64)v29->KeyHash.KeyHive;
    v80[1] = 0;
    v85 = v34;
    v84 = -1;
    v35 = -1073741772;
    v36 = 0i64;
    v83 = 0;
    SubKeyInLeafWithStatus = -1073741772;
    v80[0] = -1;
    Index = 0;
    v86 = 0;
    if( !*(_DWORD *)(v34 + 208) )
      goto LABEL_38;
    while( !*(_DWORD *)(v33 + 4 * v36 + 20) )
    {
LABEL_36:
      v36 = (unsigned int)(v83 + 1);
      v83 = 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),
                             v80);
    if( !v49 )
      goto LABEL_145;
    if( v49->Signature == 26994 )
    {
      if( (int)CmpFindSubKeyInRoot((_HHIVE *)v34, v49, SearchName, 0i64) < 0 )
      {
        v35 = -1073741670;
        goto LABEL_85;
      }
      (*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v80);
      if( Index == -1 )
        goto LABEL_80;
      v49 = (_CM_KEY_INDEX *)(*(__int64(__fastcall **)(INT64, _QWORD, int *))(v34 + 8))(v34, Index, v80);
      if( !v49 )
      {
LABEL_145:
        v35 = -1073741670;
        SubKeyInLeafWithStatus = -1073741670;
        goto LABEL_37;
      }
    }
    if( v49->Signature != 26732 )
    {
      SubKeyInLeafWithStatus = CmpFindSubKeyInLeafWithStatus((_HHIVE *)v34, v49, SearchName, 0i64, &Index);
      v35 = SubKeyInLeafWithStatus;
      if( (int)(SubKeyInLeafWithStatus + 0x80000000) >= 0 && SubKeyInLeafWithStatus != -1073741772 )
        goto LABEL_86;
      v56 = Index;
LABEL_83:
      if( v56 != -1 )
      {
        v84 = v56;
        v35 = 0;
        goto LABEL_85;
      }
      goto LABEL_79;
    }
    v50 = 0;
    v51 = _mm_cvtsi128_si32(*(__m128i *)SearchName);
    v90 = *(__m128i *)SearchName;
    if( v51 )
    {
      v52 = (UINT16 *)v90.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 );
      v90.m128i_i64[1] = (__int64)v52;
    }
    v55 = 0;
    Index = -1;
    if( !v49->Count )
    {
LABEL_78:
      v34 = v85;
      v35 = -1073741772;
      SubKeyInLeafWithStatus = -1073741772;
LABEL_79:
      (*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v80);
LABEL_80:
      v33 = v87;
      goto LABEL_36;
    }
    while( 1 )
    {
      if( v50 != *(_DWORD *)&v49[v55 + 1].Signature )
        goto LABEL_77;
      v61 = CmpDoCompareKeyName(v85, SearchName, 0i64, v49[v55].List[0]);
      if( v61 == 2 )
        break;
      if( !v61 )
      {
        v56 = v49[v55].List[0];
        v34 = v85;
        v35 = 0;
        SubKeyInLeafWithStatus = 0;
        Index = v56;
        goto LABEL_83;
      }
LABEL_77:
      if( ++v55 >= v49->Count )
        goto LABEL_78;
    }
    v34 = v85;
    v35 = -1073741670;
LABEL_85:
    SubKeyInLeafWithStatus = v35;
LABEL_86:
    (*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v80);
LABEL_37:
    v11 = a1;
LABEL_38:
    ParentKcb->KeyHash.KeyHive->ReleaseCellRoutine(ParentKcb->KeyHash.KeyHive, (_HV_GET_CELL_CONTEXT *)&v81);
    if( v35 == -1073741772 )
    {
      v37 = -1;
      goto LABEL_40;
    }
    if( v35 < 0 )
    {
      CmpRecordParseFailure(a11, 328960i64, (unsigned int)v35);
      goto LABEL_45;
    }
    v37 = v84;
    if( v84 != -1 )
    {
      v29 = ParentKcb;
      goto LABEL_90;
    }
LABEL_40:
    v29 = ParentKcb;
LABEL_41:
    if( *(_WORD *)(v11 + 66) || a10 )
    {
LABEL_90:
      v57 = (volatile INT64 *)v79;
      v58 = CmpCreateKeyControlBlock(
              (_CMHIVE *)v29->KeyHash.KeyHive,
              v37,
              v29,
              (_CM_KEY_CONTROL_BLOCK *)v79,
              0,
              (_UNICODE_STRING *)SearchName,
              (_CM_COMPONENT_HASH)ComponentHash,
              (_CM_PATH_HASH)PathHash,
              &ResultKcb);
      SubKeyInLeafWithStatus = v58;
      v35 = v58;
      if( v58 >= 0 )
      {
        if( v57 )
          CmpDereferenceKeyControlBlockUnsafe(v57);
        v14 = ResultKcb;
        ResultKcb = 0i64;
        v79 = v14;
        ++*(_WORD *)(a4 + 2);
        if( v76 >= 2 )
          *(_QWORD *)(*(_QWORD *)(a4 + 24) + 8i64 * v76 - 16) = v14;
        else
          *(_QWORD *)(a4 + 8i64 * v76 + 8) = v14;
        v59 = *(_WORD *)(v11 + 66);
        if( v76 != v59 )
        {
          CmpUnlockHashEntry((INT64)ParentKcb->KeyHash.KeyHive, (unsigned int)PathHash);
          ++v77;
          v59 = *(_WORD *)(v11 + 66);
        }
        v28 = v76 + 1;
        v76 = 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 = v74;
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, 0);
      if( v42 && (*(_DWORD *)(v41 + 8) & 0x80000) != 0 )
        CmpFreeKeyControlBlock(v41);
      ++v40;
    }
    while( v40 <= *(__int16 *)(a2 + 2) );
    v35 = SubKeyInLeafWithStatus;
  }
  v43 = v77;
  if( v77 <= v39 )
  {
    v44 = 8i64 * v77 - 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)PathHash ^ ((unsigned int)PathHash >> 9))) ^ ((unsigned __int64)(101027 * ((unsigned int)PathHash ^ ((unsigned int)PathHash >> 9))) >> 9)) & (unsigned int)(*(_DWORD *)(v46 + 1648) - 1));
      *(_QWORD *)(v47 + 8) = 0i64;
      ExReleasePushLockEx(v47, 0);
      if( _InterlockedExchangeAdd((volatile signed __int32 *)(v46 + 4272), 0xFFFFFFFF) == 1 )
        CmpDeleteHive((PVOID)v46);
      ++v43;
      v44 += 8i64;
    }
    while( v43 <= v39 );
    v35 = SubKeyInLeafWithStatus;
  }
  if( v79 )
    CmpDereferenceKeyControlBlock((UINT64)v79);
  return(unsigned int)v35;
}

Referenced by:

CmpDoBuildVirtualStack
CmpDoParseKey