Стек вокруг переменной был поврежден при запросе массивов в WMI

#c #winapi #wmi

Вопрос:

Я пытаюсь запросить массив Uint16 в WMI, более конкретно, я пытаюсь получить удобное имя для мониторов, которое хранится в Uint16[] в WMI. Мой код выглядит следующим образом:

 template<> UInt16Vec _convertValue<UInt16Vec>(VARIANTamp; vtProp)
    {
        UInt16Vec uint16Array;

        if (V_VT(amp;vtProp) amp; (VT_ARRAY | VT_UINT))
        {
            long lBound = 0;
            long uBound = 0;
            HRESULT hresult = SafeArrayGetLBound(vtProp.parray, 1, amp;lBound);
            if (SUCCEEDED(hresult))
            {
                hresult = SafeArrayGetUBound(vtProp.parray, 1, amp;uBound);
            }

            if (SUCCEEDED(hresult))
            {
                long cnt_elements = uBound - lBound   1;
                for (long i = 0; i < cnt_elements;   i)
                {
                    UINT16 val;
                    hresult = SafeArrayGetElement(vtProp.parray, amp;i, amp;val);
                    uint16Array.push_back(SUCCEEDED(hresult) ? val : -1);
                }
            }
        }

        return uint16Array;
    }

 std::vector<UInt16Vec> WMIService::queryUInt16Array(bstr_t query, LPCWSTR value)
    {
        std::vector<UInt16Vec> vec;
        if (SUCCEEDED(mStatus) amp;amp; pSvc)
        {
            _queryWMI<UInt16Vec>(pSvc, vec, query, value);
        }
        return vec;
    }

template<typename T>
    void WMIService::_queryWMI(IWbemServices *pSvc, std::vector<T> amp;vec, bstr_t query, LPCWSTR value, int index)
    {
        // Use the IWbemServices pointer to make requests of WMI ----
        IEnumWbemClassObject* pEnumerator = nullptr;
        HRESULT hres = pSvc->ExecQuery(
            bstr_t("WQL"),
            query,
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
            NULL,
            amp;pEnumerator);

        if (SUCCEEDED(hres) amp;amp; pEnumerator != nullptr)
        {
            // Get the data from the query
            IWbemClassObject *pclsObj = NULL;
            ULONG uReturn = 0;
            int localIndex = 0;

            while (pEnumerator)
            {
                pEnumerator->Next(WBEM_INFINITE, 1, amp;pclsObj, amp;uReturn);

                if (0 == uReturn || (index>-1 amp;amp; localIndex == index   1))
                {
                    break;
                }

                VARIANT vtProp;
                if (SUCCEEDED(pclsObj->Get(value, 0, amp;vtProp, 0, 0)))
                {
                    vec.push_back(_convertValue<T>(vtProp));
                    VariantClear(amp;vtProp);
                }

                pclsObj->Release();

                  localIndex;
            }
        }

        if (pEnumerator != nullptr)
        {
            pEnumerator->Release();
        }
    }
}
 

Однако в конце _convertValue, когда я возвращаю Uint16Array, я получаю «Ошибка проверки во время выполнения #2-Стек вокруг переменной ‘val’ был поврежден», и я не уверен, почему.

Комментарии:

1. Вы забыли позвонить SafeArrayGetDim , чтобы определить, сколько существует измерений. Если это 2-мерный (или более) массив, вы передаете только одно измерение SafeArrayGetElement , а остальные будут недоступны. Вы также считываете 4-байтовое целое число ( VT_UINT ) в двухбайтовую переменную ( UINT16 ), которая является переполнением двухбайтового буфера.

2. @RaymondChen Ах, я понимаю, спасибо!