#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 Ах, я понимаю, спасибо!