398 lines
10 KiB
C++
398 lines
10 KiB
C++
#include "precomp.h"
|
|
#include "ObjAccess.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CProp
|
|
|
|
BOOL CObjAccess::InitDataForArray(CProp *pProp, DWORD dwItems, DWORD dwItemSize)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD dwSizeNeeded = dwItems * dwItemSize;
|
|
|
|
// Make room for the data if we need to.
|
|
//if (pProp->m_dwSize != dwSizeNeeded)
|
|
{
|
|
_variant_t vValue;
|
|
SAFEARRAYBOUND sabound;
|
|
VARTYPE typeBase = (VARTYPE)(pProp->m_type & ~VT_ARRAY);
|
|
|
|
sabound.lLbound = 0;
|
|
sabound.cElements = dwItems;
|
|
|
|
pProp->m_dwSize = 0;
|
|
|
|
// Fix up some of these for WinMgmt.
|
|
if (typeBase == CIM_UINT64 || typeBase == CIM_SINT64)
|
|
// Commented out because this function should never be called with
|
|
// these two types.
|
|
//typeBase == CIM_DATETIME || typeBase == CIM_REFERENCE)
|
|
typeBase = VT_BSTR;
|
|
else if (typeBase == VT_UI4)
|
|
typeBase = VT_I4;
|
|
else if (typeBase == VT_UI2)
|
|
typeBase = VT_I2;
|
|
else if (typeBase == VT_I1)
|
|
typeBase = VT_UI1;
|
|
else if (typeBase == CIM_CHAR16)
|
|
typeBase = VT_I2;
|
|
|
|
if ((V_ARRAY(&vValue) = SafeArrayCreate(typeBase, 1, &sabound)) != NULL)
|
|
{
|
|
V_VT(&vValue) = typeBase | VT_ARRAY;
|
|
|
|
// This is to make sure we have valid strings when calling Put().
|
|
if (typeBase == VT_BSTR)
|
|
{
|
|
LPCWSTR *pStrings = (LPCWSTR*) vValue.parray->pvData;
|
|
|
|
for (DWORD i = 0; i < dwItems; i++)
|
|
pStrings[i] = L"0";
|
|
}
|
|
|
|
HRESULT hr =
|
|
m_pObj->Put(
|
|
pProp->m_strName,
|
|
0,
|
|
&vValue,
|
|
0);
|
|
|
|
bRet = SUCCEEDED(hr);
|
|
|
|
_ASSERT(bRet);
|
|
|
|
// Clear this out since we didn't use SysAlloc'ed BSTRs.
|
|
if (typeBase == VT_BSTR)
|
|
ZeroMemory(vValue.parray->pvData, sizeof(BSTR) * dwItems);
|
|
|
|
if (bRet)
|
|
pProp->m_dwSize = dwSizeNeeded;
|
|
else
|
|
pProp->m_dwSize = 0;
|
|
}
|
|
}
|
|
|
|
//if (pProp->m_dwSize == dwSizeNeeded)
|
|
{
|
|
HRESULT hr;
|
|
DWORD nCount;
|
|
|
|
hr =
|
|
m_pWmiObj->GetArrayPropAddrByHandle(
|
|
pProp->m_lHandle,
|
|
0,
|
|
&nCount,
|
|
&pProp->m_pData);
|
|
|
|
_ASSERT(nCount == dwItems);
|
|
|
|
//pProp->m_pData = m_pWmiObj->GetArrayByHandle(pProp->m_lHandle);
|
|
|
|
if (SUCCEEDED(hr))
|
|
bRet = TRUE;
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
pProp->m_pData = NULL;
|
|
pProp->m_dwSize = 0;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CObjAccess
|
|
|
|
//static BOOL bFirst = TRUE;
|
|
//FPGET_PROPERTY_HANDLE_EX CObjAccess::m_pGetPropertyHandleEx;
|
|
//FPGET_ARRAY_BY_HANDLE CObjAccess::m_pGetArrayByHandle;
|
|
|
|
CObjAccess::CObjAccess() :
|
|
m_pObj(NULL),
|
|
m_pObjAccess(NULL),
|
|
m_pWmiObj(NULL),
|
|
m_pProps(0)
|
|
{
|
|
/*
|
|
if (bFirst)
|
|
{
|
|
bFirst = FALSE;
|
|
|
|
// I tried doing directly (from GetProcAddress into memember vars) but
|
|
// I couldn't come up with a conversion the compiler would let me do.
|
|
// So, do it the hard way.
|
|
HINSTANCE hWbemComn = GetModuleHandle(_T("wbemcomn.dll"));
|
|
FARPROC fpGetPropertyHandleEx =
|
|
GetProcAddress(
|
|
hWbemComn,
|
|
"?GetPropertyHandleEx@CWbemObject@@UAGJPBGJPAJ1@Z"),
|
|
//"?GetPropertyHandleEx@CWbemObject@@QAEJPBGPAJ1@Z"),
|
|
fpGetArrayByHandle =
|
|
GetProcAddress(
|
|
hWbemComn,
|
|
"?GetArrayByHandle@CWbemObject@@QAEPAVCUntypedArray@@J@Z");
|
|
|
|
memcpy(
|
|
&m_pGetPropertyHandleEx,
|
|
&fpGetPropertyHandleEx,
|
|
sizeof(fpGetPropertyHandleEx));
|
|
|
|
memcpy(
|
|
&m_pGetArrayByHandle,
|
|
&fpGetArrayByHandle,
|
|
sizeof(fpGetArrayByHandle));
|
|
}
|
|
*/
|
|
}
|
|
|
|
CObjAccess::CObjAccess(const CObjAccess& other) :
|
|
m_pProps(other.m_pProps),
|
|
m_pObj(NULL),
|
|
m_pObjAccess(NULL),
|
|
m_pWmiObj(NULL)
|
|
{
|
|
other.m_pObj->Clone(&m_pObj);
|
|
|
|
m_pObj->QueryInterface(
|
|
IID_IWbemObjectAccess,
|
|
(LPVOID*) &m_pObjAccess);
|
|
m_pObj->QueryInterface(
|
|
IID__IWmiObject,
|
|
(LPVOID*) &m_pWmiObj);
|
|
}
|
|
|
|
CObjAccess::~CObjAccess()
|
|
{
|
|
if (m_pObjAccess)
|
|
m_pObjAccess->Release();
|
|
|
|
if (m_pObj)
|
|
m_pObj->Release();
|
|
|
|
if (m_pWmiObj)
|
|
m_pWmiObj->Release();
|
|
}
|
|
|
|
|
|
const CObjAccess& CObjAccess::operator=(const CObjAccess& other)
|
|
{
|
|
m_pProps = other.m_pProps;
|
|
|
|
other.m_pObj->Clone(&m_pObj);
|
|
|
|
m_pObj->QueryInterface(
|
|
IID_IWbemObjectAccess,
|
|
(LPVOID*) &m_pObjAccess);
|
|
|
|
m_pObj->QueryInterface(
|
|
IID__IWmiObject,
|
|
(LPVOID*) &m_pWmiObj);
|
|
|
|
return *this;
|
|
}
|
|
|
|
BOOL CObjAccess::Init(
|
|
IWbemServices *pSvc,
|
|
LPCWSTR szClass,
|
|
LPCWSTR *pszPropNames,
|
|
DWORD nProps,
|
|
INIT_FAILED_PROP_TYPE typeFail)
|
|
{
|
|
IWbemClassObject *pClass = NULL;
|
|
BOOL bRet = FALSE;
|
|
|
|
if (SUCCEEDED(pSvc->GetObject(
|
|
_bstr_t(szClass),
|
|
0,
|
|
NULL,
|
|
&pClass,
|
|
NULL)) &&
|
|
SUCCEEDED(pClass->SpawnInstance(0, &m_pObj)))
|
|
{
|
|
// Get out if we don't need the whole IWbemObjectAccess stuff.
|
|
if (nProps == 0)
|
|
return TRUE;
|
|
|
|
m_pObj->QueryInterface(IID_IWbemObjectAccess, (LPVOID*) &m_pObjAccess);
|
|
m_pObj->QueryInterface(IID__IWmiObject, (LPVOID*) &m_pWmiObj);
|
|
|
|
if (m_pProps.Init(nProps))
|
|
{
|
|
m_pProps.SetCount(nProps);
|
|
|
|
bRet = TRUE;
|
|
|
|
for (DWORD i = 0; i < nProps; i++)
|
|
{
|
|
CProp &prop = m_pProps[i];
|
|
|
|
if(m_pWmiObj)
|
|
{
|
|
if (SUCCEEDED(m_pWmiObj->GetPropertyHandleEx(
|
|
pszPropNames[i],
|
|
0,
|
|
&prop.m_type,
|
|
&prop.m_lHandle)))
|
|
{
|
|
prop.m_strName = pszPropNames[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (SUCCEEDED(m_pObjAccess->GetPropertyHandle(
|
|
pszPropNames[i],
|
|
&prop.m_type,
|
|
&prop.m_lHandle)))
|
|
{
|
|
prop.m_strName = pszPropNames[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pClass)
|
|
pClass->Release();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CObjAccess::WriteData(DWORD dwIndex, LPVOID pData, DWORD dwSize)
|
|
{
|
|
CProp &prop = m_pProps[dwIndex];
|
|
BOOL bRet = FALSE;
|
|
|
|
// This function only works for non arrays.
|
|
_ASSERT((prop.m_type & CIM_FLAG_ARRAY) == 0);
|
|
|
|
bRet =
|
|
SUCCEEDED(m_pObjAccess->WritePropertyValue(
|
|
prop.m_lHandle,
|
|
dwSize,
|
|
(LPBYTE) pData));
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL CObjAccess::WriteArrayData(DWORD dwIndex, LPVOID pData, DWORD dwItemSize)
|
|
{
|
|
if(m_pWmiObj == NULL)
|
|
return TRUE; // pretend we did it
|
|
|
|
CProp &prop = m_pProps[dwIndex];
|
|
|
|
// This function only works for arrays.
|
|
_ASSERT(prop.m_type & CIM_FLAG_ARRAY);
|
|
|
|
// The SetArrayPropRangeByHandle is currently broken. Remove once Sanj
|
|
// gets it fixed.
|
|
//return TRUE;
|
|
|
|
DWORD dwItems = *(DWORD*) pData,
|
|
dwSize = dwItems * dwItemSize;
|
|
|
|
//if (prop.m_dwMaxSize != dwSize)
|
|
// InitDataForArray(&prop, dwItems, dwItemSize);
|
|
|
|
//return TRUE;
|
|
|
|
#if 1
|
|
//return TRUE;
|
|
|
|
HRESULT hr;
|
|
|
|
hr =
|
|
m_pWmiObj->SetArrayPropRangeByHandle(
|
|
prop.m_lHandle,
|
|
WMIARRAY_FLAG_ALLELEMENTS, // flags
|
|
0, // start index
|
|
dwItems, // # items
|
|
dwSize, // buffer size
|
|
((LPBYTE) pData) + sizeof(DWORD)); // data buffer
|
|
|
|
return SUCCEEDED(hr);
|
|
#else
|
|
BOOL bRet;
|
|
|
|
bRet = InitDataForArray(&prop, dwItems, dwItemSize);
|
|
|
|
if (bRet)
|
|
memcpy(prop.m_pData, ((LPBYTE) pData) + sizeof(DWORD), dwSize);
|
|
|
|
return bRet;
|
|
#endif
|
|
}
|
|
|
|
BOOL CObjAccess::WriteNonPackedArrayData(
|
|
DWORD dwIndex,
|
|
LPVOID pData,
|
|
DWORD dwItems,
|
|
DWORD dwTotalSize)
|
|
{
|
|
if(m_pWmiObj == NULL)
|
|
return TRUE; // pretend we did it
|
|
|
|
CProp &prop = m_pProps[dwIndex];
|
|
HRESULT hr;
|
|
|
|
// This function only works for arrays.
|
|
_ASSERT(prop.m_type & CIM_FLAG_ARRAY);
|
|
|
|
hr =
|
|
m_pWmiObj->SetArrayPropRangeByHandle(
|
|
prop.m_lHandle,
|
|
WMIARRAY_FLAG_ALLELEMENTS, // flags
|
|
0, // start index
|
|
dwItems, // # items
|
|
dwTotalSize, // buffer size
|
|
pData); // data buffer
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
BOOL CObjAccess::WriteString(DWORD dwIndex, LPCWSTR szValue)
|
|
{
|
|
return
|
|
SUCCEEDED(m_pObjAccess->WritePropertyValue(
|
|
m_pProps[dwIndex].m_lHandle,
|
|
(wcslen(szValue) + 1) * sizeof(WCHAR),
|
|
(LPBYTE) szValue));
|
|
}
|
|
|
|
BOOL CObjAccess::WriteString(DWORD dwIndex, LPCSTR szValue)
|
|
{
|
|
return WriteString(dwIndex, (LPCWSTR) _bstr_t(szValue));
|
|
}
|
|
|
|
BOOL CObjAccess::WriteDWORD(DWORD dwIndex, DWORD dwValue)
|
|
{
|
|
return
|
|
SUCCEEDED(m_pObjAccess->WriteDWORD(
|
|
m_pProps[dwIndex].m_lHandle,
|
|
dwValue));
|
|
}
|
|
|
|
BOOL CObjAccess::WriteDWORD64(DWORD dwIndex, DWORD64 dwValue)
|
|
{
|
|
return
|
|
SUCCEEDED(m_pObjAccess->WriteQWORD(
|
|
m_pProps[dwIndex].m_lHandle,
|
|
dwValue));
|
|
}
|
|
|
|
BOOL CObjAccess::WriteNULL(DWORD dwIndex)
|
|
{
|
|
return
|
|
SUCCEEDED(m_pObj->Put(
|
|
m_pProps[dwIndex].m_strName,
|
|
0,
|
|
NULL,
|
|
0));
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CProp
|
|
|