CmQueryMultipleValueKey

__int64 __fastcall CmQueryMultipleValueKey(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        unsigned int a4,
        _LOOKASIDE_LIST_EX *a5,
        unsigned int *a6,
        unsigned int *a7){
  _CM_KEY_CONTROL_BLOCK *v11; 
  _CM_KEY_CONTROL_BLOCK *v12; 
  INT64 KeyHive; 
  volatile signed __int64 *v14; 
  _CM_KEY_NODE *v15; 
  __int64 v16; 
  CM_TRANS *v17; 
  __int64 v18; 
  int v19; 
  int v20; 
  unsigned int v21; 
  _CM_KEY_VALUE *v22; 
  __int64 v23; 
  unsigned __int16 i; 
  unsigned int ValueByName; 
  INT64 v26; 
  _CM_KEY_VALUE *v27; 
  size_t DataLength; 
  unsigned int v29; 
  unsigned int v30; 
  __int64 v31; 
  INT64 v32; 
  __int64 v33; 
  unsigned int v34; 
  __int64 v35; 
  unsigned int MultipleValueForLayeredKey; 
  int v38; 
  int v39; 
  NTSTATUS v40; 
  int v41; 
  char v42; 
  unsigned int v43; 
  unsigned int v44; 
  size_t v45; 
  int v46; 
  int v47; 
  CM_TRANS *CmTrans; 
  INT64 v49; 
  size_t Size; 
  unsigned int v51; 
  __int64 v52; 
  VOID *Src; 
  int v54[2]; 
  __int64 v55; 
  int v56[2]; 
  __int64 v57; 
  INT64 v58; 
  INT64 v59; 
  _DWORD v60[2]; 
  UINT64 v61; 
  _CM_KEY_VALUE *v62; 
  _CM_KEY_NODE *v63; 
  INT64 v64; 
  UINT64 v65; 
  INT64 v66; 
  __int64 v67; 
  unsigned int v68; 

  v68 = a4;
  v67 = a3;
  v59 = 0i64;
  v49 = 0i64;
  v54[0] = -1;
  v54[1] = 0;
  v45 = 0;
  v43 = 0;
  v42 = 0;
  v56[0] = -1;
  v56[1] = 0;
  v55 = 0i64;
  v60[0] = -1;
  v60[1] = 0;
  v11 = 0i64;
  v61 = 0i64;
  CmTrans = 0i64;
  LOBYTE(v47) = 0;
  LOBYTE(v46) = 0;
  Src = 0i64;
  LOBYTE(v66) = 0;
  v58 = 0xFFFFFFFFi64;
  CmpLockRegistry();
  v12 = *(_CM_KEY_CONTROL_BLOCK **)(a1 + 8);
  v65 = (UINT64)v12;
  if( v12->LayerHeight )
  {
    MultipleValueForLayeredKey = CmQueryMultipleValueForLayeredKey(a1, a3, a4, a5, a6, a7);
    CmpUnlockRegistry();
    return MultipleValueForLayeredKey;
  }
  if( *(_QWORD *)(a1 + 56) || *(_QWORD *)(a1 + 64) )
  {
    ExAcquirePushLockSharedEx(&v12->KcbPushlock, 0i64);
    _InterlockedAdd((volatile signed __int32 *)&v12->56, 1u);
    if( CmpIsKeyDeletedForKeyBody((CM_KEY_BODY *)a1, 0i64) )
    {
      v38 = (*(_DWORD *)(a1 + 48) & 1) != 0 ? 0x2A9 : 0;
      CmpUnlockKcb(v12);
LABEL_51:
      CmpUnlockRegistry();
      return(unsigned int)(v38 - 1073741444);
    }
    CmpUnlockKcb(v12);
    v40 = CmpTransSearchAddTransFromKeyBody((_CM_KEY_BODY *)a1, &CmTrans);
    if( v40 < 0 )
    {
      CmpUnlockRegistry();
      return(unsigned int)v40;
    }
  }
  if( a2 )
  {
    v11 = *(_CM_KEY_CONTROL_BLOCK **)(a2 + 8);
    v61 = (UINT64)v11;
  }
  CmpLockTwoKcbsShared(v11, v12);
  if( CmpIsKeyDeletedForKeyBody((CM_KEY_BODY *)a1, CmTrans) )
  {
    v39 = *(_DWORD *)(a1 + 48);
LABEL_50:
    v38 = (v39 & 1) != 0 ? 0x2A9 : 0;
    CmpUnlockTwoKcbs(v11, v12);
    goto LABEL_51;
  }
  if( a2 && CmpIsKeyDeletedForKeyBody((CM_KEY_BODY *)a2, CmTrans) )
  {
    v39 = *(_DWORD *)(a2 + 48);
    goto LABEL_50;
  }
  KeyHive = (INT64)v12->KeyHash.KeyHive;
  v52 = KeyHive;
  v64 = KeyHive;
  v14 = (volatile signed __int64 *)(KeyHive + 72);
  ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)(KeyHive + 72), 0i64);
  v15 = (_CM_KEY_NODE *)(*(__int64(__fastcall **)(INT64, _QWORD, int *))(KeyHive + 8))(
                          KeyHive,
                          v12->KeyHash.KeyCell,
                          v56);
  v63 = v15;
  if( !v15 )
  {
    if( _InterlockedCompareExchange64(v14, 0i64, 17i64) != 17 )
      ExfReleasePushLockShared((_EX_PUSH_LOCK *)(KeyHive + 72));
    KeAbPostRelease((VOID *)(KeyHive + 72));
    goto LABEL_60;
  }
  CmpUpdateKeyNodeAccessBits((_HHIVE *)KeyHive, v15, v12->KeyHash.KeyCell);
  if( _InterlockedCompareExchange64(v14, 0i64, 17i64) != 17 )
    ExfReleasePushLockShared((_EX_PUSH_LOCK *)(KeyHive + 72));
  KeAbPostRelease((VOID *)(KeyHive + 72));
  v17 = CmTrans;
  if( CmTrans )
  {
    v41 = (unsigned __int8)v47;
    if( v12->TransValueListOwner == CmTrans )
      v41 = 1;
    v47 = v41;
  }
  if( !v11 )
  {
    v18 = 0i64;
    LOBYTE(v19) = v46;
    goto LABEL_14;
  }
  v59 = (INT64)v11->KeyHash.KeyHive;
  v18 = (*(__int64(__fastcall **)(INT64, _QWORD, _DWORD *))(v59 + 8))(v59, v11->KeyHash.KeyCell, v60);
  v55 = v18;
  if( !v18 )
  {
    (*(void(__fastcall **)(INT64, int *))(KeyHive + 16))(KeyHive, v56);
LABEL_60:
    CmpUnlockTwoKcbs(v11, v12);
    CmpUnlockRegistry();
    return 3221225626i64;
  }
  LOBYTE(v19) = v46;
  if( v17 )
  {
    v19 = (unsigned __int8)v46;
    if( v11->TransValueListOwner == v17 )
      v19 = 1;
    v46 = v19;
  }
LABEL_14:
  v20 = 0;
  v21 = 0;
  while( 1 )
  {
    v51 = v21;
    v22 = 0i64;
    if( v21 >= v68 )
      break;
    v23 = v67 + 32i64 * v21;
    v57 = v23;
    for( i = *(_WORD *)v23; i && !*(_WORD *)(*(_QWORD *)(v23 + 8) + 2 * ((unsigned __int64)i >> 1) - 2); *(_WORD *)v23 = i )
      i -= 2;
    ValueByName = -1;
    v44 = -1;
    if( v11 )
    {
      v26 = v59;
      v49 = v59;
      if( (_BYTE)v19 )
      {
        CmpFindNameInList(v59, (unsigned int *)&v11->TransValueCache, v23, 0, 0i64, &v44);
        ValueByName = v44;
      }
      else
      {
        ValueByName = CmpFindValueByName(v59, v18, v23);
        v44 = ValueByName;
      }
      v23 = v57;
    }
    else
    {
      v26 = v49;
    }
    if( ValueByName == -1 )
    {
      v26 = KeyHive;
      v49 = KeyHive;
      if( (_BYTE)v47 )
      {
        CmpFindNameInList(KeyHive, (unsigned int *)&v12->TransValueCache, v23, 0, 0i64, &v44);
        ValueByName = v44;
      }
      else
      {
        ValueByName = CmpFindValueByName(KeyHive, (__int64)v63, v23);
      }
      if( ValueByName == -1 )
      {
        v20 = -1073741772;
        v22 = 0i64;
        break;
      }
    }
    v27 = (_CM_KEY_VALUE *)(*(__int64(__fastcall **)(INT64, _QWORD, int *, __int64))(v26 + 8))(
                             v26,
                             ValueByName,
                             v54,
                             v18);
    v22 = v27;
    v62 = v27;
    if( !v27 )
      goto LABEL_75;
    DataLength = v27->DataLength;
    if( DataLength >= 0x80000000 )
      DataLength += 0x80000000;
    Size = DataLength;
    v29 = (v43 + 3) & 0xFFFFFFFC;
    v43 = v29;
    LODWORD(CmTrans) = v29;
    v30 = (v45 + 3) & 0xFFFFFFFC;
    v45 = v30;
    v44 = v30;
    if( DataLength + v29 > *a6 || DataLength + v29 < v29 || v42 )
    {
      v42 = 1;
      v32 = v49;
    }
    else
    {
      v31 = ValueByName;
      v32 = v49;
      if( !CmpGetValueData((_HHIVE *)v49, v31, v27, &Size, &Src, (unsigned __int8 *)&v66, (_HV_GET_CELL_CONTEXT *)&v58) )
      {
LABEL_75:
        v20 = -1073741670;
        v35 = v52;
        goto LABEL_41;
      }
      DataLength = Size;
      memmove((char *)a5 + v43, Src, Size);
      v33 = v57;
      *(_DWORD *)(v57 + 24) = v22->Type;
      *(_DWORD *)(v33 + 16) = DataLength;
      *(_DWORD *)(v33 + 20) = v43;
      if( (_BYTE)v66 )
      {
        ExFreePoolWithTag(Src, 0);
        LOBYTE(v66) = 0;
      }
      else
      {
        (*(void(__fastcall **)(INT64, INT64 *))(v32 + 16))(v32, &v58);
      }
      Src = 0i64;
      v43 += DataLength;
      v30 = v45;
    }
    v45 = DataLength + v30;
    (*(void(__fastcall **)(INT64, int *))(v32 + 16))(v32, v54);
    v21 = v51 + 1;
    KeyHive = v52;
    v18 = v55;
    LOBYTE(v19) = v46;
  }
  v34 = v45;
  v35 = v52;
  if( v20 >= 0 )
  {
    if( v42 )
      v20 = -2147483643;
    *a6 = v43;
    if( a7 )
      *a7 = v34;
  }
LABEL_41:
  if( v22 )
    (*(void(__fastcall **)(INT64, int *, __int64, __int64))(v49 + 16))(v49, v54, v16, v18);
  if( v55 )
    (*(void(__fastcall **)(INT64, _DWORD *, __int64, __int64))(v59 + 16))(v59, v60, v16, v18);
  (*(void(__fastcall **)(__int64, int *, __int64, __int64))(v35 + 16))(v35, v56, v16, v18);
  CmpUnlockTwoKcbs(v11, v12);
  CmpUnlockRegistry();
  return(unsigned int)v20;
}

Referenced by:

NtQueryMultipleValueKey