1175 lines
35 KiB
C++
1175 lines
35 KiB
C++
//***************************************************************************
|
|
|
|
//
|
|
|
|
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
//***************************************************************************
|
|
#include "precomp.h"
|
|
#include "wmicom.h"
|
|
#include "wmimap.h"
|
|
#include <stdlib.h>
|
|
#include <winerror.h>
|
|
#include <crc32.h>
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//**********************************************************************************************
|
|
// THE CWbemInfoClass
|
|
//**********************************************************************************************
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//**********************************************************************************************
|
|
//
|
|
// NAME GetPropertiesInID_Order
|
|
// PURPOSE Return a WCHAR string containing the class's
|
|
// property names, orderd by an ID number
|
|
// contained within the named property qualifier.
|
|
//
|
|
// WRAPPER Not a wrapper. This is a standalone filter/sort
|
|
// utility function.
|
|
//
|
|
//**********************************************************************************************
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
CWMI_IDOrder::CWMI_IDOrder(IWbemClassObject * pC, IWbemObjectAccess * pA)
|
|
{
|
|
m_pWMIDataIdList = NULL;
|
|
InitMemberVars();
|
|
m_pClass = pC;
|
|
m_pAccess = pA;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
CWMI_IDOrder::~CWMI_IDOrder()
|
|
{
|
|
// m_pClass & m_pAccess released elsewhere
|
|
InitMemberVars();
|
|
}
|
|
///////////////////////////////////////////////////////////////////////
|
|
void CWMI_IDOrder::InitMemberVars()
|
|
{
|
|
//m_pObj = NULL;
|
|
m_nTotal = 0;
|
|
m_nCurrent = 0;
|
|
m_nStartingPosition = sizeof(m_nStartingPosition);
|
|
if( m_pWMIDataIdList )
|
|
{
|
|
SAFE_DELETE_ARRAY(m_pWMIDataIdList);
|
|
m_pWMIDataIdList = NULL;
|
|
}
|
|
}
|
|
///////////////////////////////////////////////////////////////////////
|
|
WCHAR * CWMI_IDOrder::GetFirstID()
|
|
{
|
|
//***********************************************************
|
|
// Since we have to deal with IDs starting at both 0, 1, or
|
|
// whatever, we need to find out where the list starts
|
|
// find out which way this list starts.
|
|
// decrement the m_nCurrent count by 1 and call the GetNextId
|
|
// function which immediately bumps it up by one.
|
|
//***********************************************************
|
|
m_nCurrent = m_nStartingPosition -1;
|
|
return GetNextID();
|
|
}
|
|
///////////////////////////////////////////////////////////////////////
|
|
WCHAR * CWMI_IDOrder::GetNextID()
|
|
{
|
|
WCHAR * pChar = NULL;
|
|
|
|
//===================================================================
|
|
// Go in a loop to find the next ID
|
|
// Increment current first, remember, current has to stay valid at
|
|
// all times
|
|
//===================================================================
|
|
m_nCurrent++;
|
|
|
|
//===================================================================
|
|
// If there is no property name, then we know we are done
|
|
// with the properties
|
|
//===================================================================
|
|
while( m_pWMIDataIdList[m_nCurrent].pwcsPropertyName ){
|
|
|
|
if( m_pWMIDataIdList[m_nCurrent].fPutProperty == FALSE )
|
|
{
|
|
m_nCurrent++;
|
|
}
|
|
else
|
|
{
|
|
pChar = m_pWMIDataIdList[m_nCurrent].pwcsPropertyName;
|
|
break;
|
|
}
|
|
}//End while loop
|
|
|
|
return pChar;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMI_IDOrder::ProcessPropertyQualifiers(LPCWSTR strPropName, int nMax,BOOL fHiPerf)
|
|
{
|
|
IWbemQualifierSet * pIWbemQualifierSet = NULL;
|
|
CIMTYPE lType = 0;
|
|
|
|
HRESULT hr = m_pClass->GetPropertyQualifierSet(strPropName,&pIWbemQualifierSet);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
int nPosition = 0;
|
|
CVARIANT v;
|
|
|
|
hr = pIWbemQualifierSet->Get(L"WmiDataId", 0, &v, 0);
|
|
if( hr == S_OK )
|
|
{
|
|
nPosition = v.GetLONG();
|
|
}
|
|
else
|
|
{
|
|
hr = pIWbemQualifierSet->Get(L"ID", 0, &v, 0);
|
|
if( hr == S_OK )
|
|
{
|
|
nPosition = v.GetLONG();
|
|
// instance ids start with 0, methods with 1, so
|
|
// just force these to match our method processing.
|
|
}
|
|
}
|
|
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
if( nPosition > nMax )
|
|
{
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
//===================================================
|
|
// Get the exact number and
|
|
// copy property name into the correct array location
|
|
// and get all of the attributes of the property
|
|
// we will need in the future to process it.
|
|
//===================================================
|
|
hr =m_pClass->Get(strPropName, 0, &v, &lType, NULL);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
//=================================================================
|
|
// If we are accumulating hi perf info, then get the handle to
|
|
// access the property instead of via property name
|
|
//=================================================================
|
|
if( fHiPerf )
|
|
{
|
|
long lHandle = 0;
|
|
if( S_OK == m_pAccess->GetPropertyHandle(strPropName, 0, &lHandle))
|
|
{
|
|
m_pWMIDataIdList[nPosition].lHandle = (long)lHandle;
|
|
}
|
|
}
|
|
|
|
//=================================================================
|
|
// Now, set the rest of the property information
|
|
//=================================================================
|
|
m_pWMIDataIdList[nPosition].lType = (long)lType;
|
|
m_pWMIDataIdList[nPosition].SetPropertyName((WCHAR*)strPropName);
|
|
m_pWMIDataIdList[nPosition].fPutProperty = TRUE;
|
|
|
|
CVARIANT vQual;
|
|
CWMIDataTypeMap MapWMIData;
|
|
|
|
hr = pIWbemQualifierSet->Get(L"CIMType", 0, &vQual,0);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
CBSTR cbstrTmp(vQual.GetStr());
|
|
MapWMIData.GetSizeAndType(cbstrTmp, &m_pWMIDataIdList[nPosition],
|
|
m_pWMIDataIdList[nPosition].lType,
|
|
m_pWMIDataIdList[nPosition].nWMISize);
|
|
|
|
m_pWMIDataIdList[nPosition].dwArraySize = GetSizeOfArray(strPropName,m_pWMIDataIdList[nPosition].lType );
|
|
}
|
|
m_nStartingPosition = min( m_nStartingPosition, nPosition ); //whichever is the smallest
|
|
m_nTotal++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// As some properties are ok not to have WMIDataIds, we have
|
|
// to set this to OK, need to log this in the future
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// This is a system property, so it is ok
|
|
hr = S_OK;
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pIWbemQualifierSet);
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMI_IDOrder::GetPropertiesInIDOrder(BOOL fHiPerf)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
SAFEARRAY * psaNames = NULL;
|
|
|
|
//======================================================
|
|
// Get Array boundaries
|
|
//======================================================
|
|
// IWbemClassObject * p = m_pObj->ClassPtr();
|
|
hr = m_pClass->GetNames(NULL, 0, NULL, &psaNames);
|
|
if (SUCCEEDED(hr)){
|
|
long lLower = 0, lUpper = 0;
|
|
|
|
hr = SafeArrayGetLBound(psaNames,1,&lLower);
|
|
if (SUCCEEDED(hr)){
|
|
|
|
hr = SafeArrayGetUBound(psaNames,1,&lUpper);
|
|
if (SUCCEEDED(hr)){
|
|
|
|
//===========================================
|
|
// Get the total number of elements, so we
|
|
// create the right sized array of ID structs
|
|
//===========================================
|
|
|
|
int nSize = (lUpper-lLower)+2;
|
|
m_pWMIDataIdList = (IDOrder * ) new IDOrder[nSize];
|
|
if( m_pWMIDataIdList )
|
|
{
|
|
try
|
|
{
|
|
memset(m_pWMIDataIdList,NULL,(sizeof(IDOrder)* nSize));
|
|
|
|
for(long ndx = lLower; ndx <= lUpper; ndx++)
|
|
{
|
|
CBSTR cbstrPropName;
|
|
hr = SafeArrayGetElement(psaNames, &ndx, &cbstrPropName);
|
|
if (WBEM_S_NO_ERROR == hr)
|
|
{
|
|
hr = ProcessPropertyQualifiers( cbstrPropName, lUpper, fHiPerf);
|
|
if( hr != WBEM_S_NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
SAFE_DELETE_ARRAY(m_pWMIDataIdList);
|
|
hr = WBEM_E_UNEXPECTED;
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( psaNames )
|
|
{
|
|
SafeArrayDestroy(psaNames);
|
|
}
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////
|
|
DWORD CWMI_IDOrder::GetSizeOfArray(LPCWSTR strProp, long lType)
|
|
{
|
|
HRESULT hr = WBEM_E_OUT_OF_MEMORY;
|
|
CAutoWChar pwcsArraySize(_MAX_PATH+2);
|
|
DWORD dwCount = 0L;
|
|
if( pwcsArraySize.Valid() )
|
|
{
|
|
IWbemQualifierSet * pIWbemQualifierSet = NULL;
|
|
|
|
lType = lType &~ CIM_FLAG_ARRAY;
|
|
//======================================================
|
|
// Get the number of elements in the array from the
|
|
// "ArraySize" property qualifier
|
|
//======================================================
|
|
hr = m_pClass->GetPropertyQualifierSet(strProp,&pIWbemQualifierSet);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
CVARIANT v;
|
|
hr = pIWbemQualifierSet->Get(L"MAX", 0, &v, 0);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
dwCount = v.GetLONG();
|
|
}
|
|
else
|
|
{
|
|
hr = pIWbemQualifierSet->Get(L"WMISizeIs", 0, &v, 0);
|
|
if( hr == S_OK )
|
|
{
|
|
CVARIANT var;
|
|
CIMTYPE lTmpType=0;
|
|
CWMIDataTypeMap MapWMIData;
|
|
hr = m_pClass->Get(v, 0, &var, &lTmpType,NULL);
|
|
if( hr == S_OK )
|
|
{
|
|
dwCount = MapWMIData.ArraySize(lTmpType,var);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pIWbemQualifierSet);
|
|
}
|
|
return dwCount;
|
|
}
|
|
//******************************************************************
|
|
////////////////////////////////////////////////////////////////////
|
|
// CWMIProcessClass
|
|
////////////////////////////////////////////////////////////////////
|
|
//******************************************************************
|
|
// WbemClassInfo deals with all the pointers and info with one
|
|
// particular wbem class
|
|
//
|
|
//******************************************************************
|
|
////////////////////////////////////////////////////////////////////
|
|
CWMIProcessClass::~CWMIProcessClass()
|
|
{
|
|
ReleaseInstancePointers();
|
|
SAFE_RELEASE_PTR(m_pAccess);
|
|
SAFE_RELEASE_PTR(m_pClass );
|
|
SAFE_DELETE_ARRAY(m_pwcsClassName);
|
|
SAFE_DELETE_PTR(m_pCurrentProperty);
|
|
SAFE_DELETE_PTR(m_pWMI);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::Initialize()
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
SAFE_DELETE_PTR(m_pWMI);
|
|
|
|
m_pWMI = new CWMIManagement;
|
|
if( m_pWMI )
|
|
{
|
|
hr = S_OK;
|
|
m_fInit = TRUE;
|
|
}
|
|
return hr;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
CWMIProcessClass::CWMIProcessClass(BOOL b)
|
|
{
|
|
m_pWMI = NULL;
|
|
m_fInit = FALSE;
|
|
m_fGetNewInstance = TRUE;
|
|
m_pAccessInstance = NULL;
|
|
m_pClassInstance = NULL;
|
|
m_pClass = NULL;
|
|
m_pAccess = NULL;
|
|
m_pCurrentProperty = NULL;
|
|
m_pwcsClassName = NULL;
|
|
m_wHardCodedGuid = 0;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIProcessClass::GetANewAccessInstance()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = m_pAccess->SpawnInstance(0, &m_pClassInstance);
|
|
m_pClassInstance->AddRef();
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = m_pClassInstance->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccessInstance);
|
|
|
|
}
|
|
return ( hr == 0 ) ? TRUE : FALSE;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
BOOL CWMIProcessClass::GetANewInstance()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if( m_fGetNewInstance )
|
|
{
|
|
SAFE_RELEASE_PTR(m_pClassInstance);
|
|
hr = m_pClass->SpawnInstance(0, &m_pClassInstance);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
if( m_fHiPerf )
|
|
{
|
|
SAFE_RELEASE_PTR(m_pAccessInstance);
|
|
hr = m_pClassInstance->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccessInstance);
|
|
}
|
|
}
|
|
}
|
|
return ( hr == 0 ) ? TRUE : FALSE;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::SetKeyFromAccessPointer()
|
|
{
|
|
CVARIANT varName;
|
|
|
|
HRESULT hr = m_pAccess->Get(L"InstanceName", 0, &varName, NULL, NULL);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL);
|
|
}
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::GetKeyFromAccessPointer(CVARIANT * v)
|
|
{
|
|
return m_pAccessInstance->Get(L"InstanceName", 0, (VARIANT *)v, NULL, NULL);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::SetHiPerfProperties(LARGE_INTEGER TimeStamp)
|
|
{
|
|
LONG lHandle = 0;
|
|
|
|
//=========================================================================================================
|
|
// Timestamp_PerfTime = timestamp in PerfFreq units returned by (QueryPerformanceCounter)
|
|
//=========================================================================================================
|
|
HRESULT hr = m_pAccess->GetPropertyHandle(L"Frequency_PerfTime", 0, &lHandle);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
LARGE_INTEGER Counter;
|
|
if( QueryPerformanceCounter(&Counter))
|
|
{
|
|
hr = m_pAccessInstance->WriteQWORD(lHandle, Counter.QuadPart);
|
|
}
|
|
|
|
//=====================================================================================================
|
|
// Timestamp_Sys100NS = timestamp in 100 NS units/QueryPerformanceCounter()dumbed down to 100NS
|
|
//=====================================================================================================
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
hr = m_pAccess->GetPropertyHandle(L"Timestamp_Sys100NS", 0, &lHandle);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
LARGE_INTEGER Sys;
|
|
Sys.QuadPart = Counter.QuadPart / 100;
|
|
hr = m_pAccessInstance->WriteQWORD(lHandle, Sys.QuadPart);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=========================================================================================================
|
|
// Frequency_PerfTime = the value returned by QueryPerformanceFrequency
|
|
//=========================================================================================================
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
hr = m_pAccess->GetPropertyHandle(L"Timestamp_PerfTime", 0, &lHandle);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
LARGE_INTEGER freq;
|
|
if( QueryPerformanceFrequency (&freq))
|
|
{
|
|
hr = m_pAccessInstance->WriteQWORD(lHandle, freq.QuadPart);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//=========================================================================================================
|
|
// Timestamp_Object = (WnodeHeader)->TimeStamp
|
|
//=========================================================================================================
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
hr = m_pAccess->GetPropertyHandle(L"Timestamp_Object", 0, &lHandle);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = m_pAccessInstance->WriteQWORD(lHandle, TimeStamp.QuadPart);
|
|
}
|
|
}
|
|
|
|
//=========================================================================================================
|
|
// Frequency_Sys100NS = 10000000
|
|
// Frequency_Object = 10000000
|
|
//=========================================================================================================
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
LARGE_INTEGER Tmp;
|
|
Tmp.QuadPart = 10000000;
|
|
hr = m_pAccess->GetPropertyHandle(L"Frequency_Object", 0, &lHandle);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = m_pAccessInstance->WriteQWORD(lHandle, Tmp.QuadPart);
|
|
}
|
|
hr = m_pAccess->GetPropertyHandle(L"Frequency_Sys100NS", 0, &lHandle);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = m_pAccessInstance->WriteQWORD(lHandle, Tmp.QuadPart);
|
|
}
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CWMIProcessClass::SetActiveProperty()
|
|
{
|
|
CVARIANT vActive;
|
|
vActive.SetBool(TRUE);
|
|
|
|
if( !m_fHiPerf )
|
|
{
|
|
m_pClassInstance->Put(L"Active", 0, &vActive, NULL);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CWMIProcessClass::ReleaseInstancePointers()
|
|
{
|
|
SAFE_RELEASE_PTR( m_pClassInstance );
|
|
SAFE_RELEASE_PTR( m_pAccessInstance);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::SendInstanceBack()
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
//===============================================
|
|
// Send the object to the caller
|
|
//===============================================
|
|
if( HANDLER )
|
|
{
|
|
hr = HANDLER->Indicate(1,&m_pClassInstance);
|
|
if( m_fGetNewInstance )
|
|
{
|
|
ReleaseInstancePointers();
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::SetInstanceName(WCHAR * wName, BOOL fSetName)
|
|
{
|
|
CVARIANT varName(wName);
|
|
HRESULT hr = WBEM_E_INVALID_OBJECT;
|
|
|
|
if( fSetName )
|
|
{
|
|
if( m_pClassInstance )
|
|
{
|
|
if( !m_fHiPerf )
|
|
{
|
|
hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL);
|
|
}
|
|
else
|
|
{
|
|
hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = SetClassName(wName);
|
|
}
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::GetInstanceName(WCHAR *& p)
|
|
{
|
|
CVARIANT vValue;
|
|
|
|
HRESULT hr = m_pClass->Get(L"InstanceName", 0, &vValue, NULL, NULL);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
if( vValue.GetStr() )
|
|
{
|
|
int nlen = wcslen(vValue.GetStr());
|
|
p = new WCHAR [nlen + 4];
|
|
if( p )
|
|
{
|
|
wcscpy(p,vValue.GetStr());
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_UNEXPECTED;
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::GetPropertiesInIDOrder(BOOL fHiPerf)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
//============================================
|
|
// If the pointer is NOT = to NULL, then this
|
|
// means we haven't released the previous one
|
|
// return FALSE, to prevent memory leaks
|
|
//============================================
|
|
if( !m_pCurrentProperty )
|
|
{
|
|
m_pCurrentProperty = new CWMI_IDOrder(m_pClass,m_pAccess);
|
|
if( m_pCurrentProperty )
|
|
{
|
|
try
|
|
{
|
|
hr = m_pCurrentProperty->GetPropertiesInIDOrder(fHiPerf);
|
|
if( hr != S_OK )
|
|
{
|
|
SAFE_DELETE_PTR(m_pCurrentProperty);
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = WBEM_E_UNEXPECTED;
|
|
SAFE_DELETE_PTR(m_pCurrentProperty);
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// NAME GetQualifierString (takes a class name)
|
|
// PURPOSE Gets a qualifier value and returns it as a wide char string
|
|
// WRAPPER High level
|
|
//
|
|
// PARAMETERS (1) [in] Pointer to an existing IWbemClassObject
|
|
// (2) [in] Pointer to a Property Name string
|
|
// (3) [in] Pointer to a Qualifier Name
|
|
// (4) [in\out] Pointer to an external character buffer
|
|
//
|
|
// RETURNS Success: S_OK
|
|
// Failure: non zero value
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::GetQualifierString( WCHAR * ppwcsPropertyName,
|
|
WCHAR * pwcsQualifierName,
|
|
WCHAR * pwcsExternalOutputBuffer,
|
|
int nSize )
|
|
{
|
|
CVARIANT vQual;
|
|
HRESULT hr = GetQualifierValue( ppwcsPropertyName, pwcsQualifierName, (CVARIANT*)&vQual);
|
|
if (WBEM_S_NO_ERROR == hr)
|
|
{
|
|
if(vQual.GetType() != VT_BSTR)
|
|
{
|
|
VariantChangeType(&vQual, &vQual, 0, VT_BSTR);
|
|
}
|
|
int nTmp=wcslen(V_BSTR(&vQual));
|
|
if( nTmp > nSize )
|
|
{
|
|
hr = WBEM_E_BUFFER_TOO_SMALL;
|
|
}
|
|
else
|
|
{
|
|
wcscat(pwcsExternalOutputBuffer, V_BSTR(&vQual));
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::GetQualifierValue( WCHAR * ppwcsPropertyName, WCHAR * pwcsQualifierName, CVARIANT * vQual )
|
|
{
|
|
IWbemClassObject * pClass = NULL;
|
|
IWbemQualifierSet * pIWbemQualifierSet = NULL;
|
|
CBSTR cbstr(m_pwcsClassName);
|
|
|
|
|
|
HRESULT hr = SERVICES->GetObject(cbstr, 0,CONTEXT, &pClass, NULL);
|
|
if (WBEM_S_NO_ERROR != hr)
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(ppwcsPropertyName)
|
|
{
|
|
pClass->GetPropertyQualifierSet(ppwcsPropertyName, &pIWbemQualifierSet);
|
|
}
|
|
else
|
|
{
|
|
pClass->GetQualifierSet(&pIWbemQualifierSet);
|
|
}
|
|
|
|
if( pIWbemQualifierSet )
|
|
{
|
|
long lType = 0L;
|
|
hr = pIWbemQualifierSet->Get(pwcsQualifierName, 0,(VARIANT *) vQual,&lType);
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pIWbemQualifierSet);
|
|
SAFE_RELEASE_PTR(pClass);
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::GetPrivilegesQualifer(SAFEARRAY ** psaPrivReq)
|
|
{
|
|
IWbemClassObject * pClass = NULL;
|
|
IWbemQualifierSet * pIWbemQualifierSet = NULL;
|
|
CBSTR cbstr(m_pwcsClassName);
|
|
|
|
|
|
HRESULT hr = SERVICES->GetObject(cbstr, 0,CONTEXT, &pClass, NULL);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
pClass->GetQualifierSet(&pIWbemQualifierSet);
|
|
if( pIWbemQualifierSet ) {
|
|
|
|
CVARIANT vQual;
|
|
long lType = 0L;
|
|
|
|
hr = pIWbemQualifierSet->Get(L"Privileges", 0, &vQual,&lType);
|
|
if (SUCCEEDED(hr)){
|
|
|
|
VARIANT *p = (VARIANT *)vQual;
|
|
SAFEARRAY * psa = V_ARRAY(p);
|
|
|
|
if( !IsBadReadPtr( psaPrivReq, sizeof(SAFEARRAY)))
|
|
{
|
|
CSAFEARRAY Safe(psa);
|
|
*psaPrivReq = OMSSafeArrayCreate(VT_BSTR,Safe.GetNumElements());
|
|
hr = SafeArrayCopy(psa,psaPrivReq );
|
|
Safe.Unbind();
|
|
// Don't need to destroy, it will be destroyed
|
|
}
|
|
}
|
|
SAFE_RELEASE_PTR(pIWbemQualifierSet);
|
|
}
|
|
}
|
|
|
|
SAFE_RELEASE_PTR(pClass);
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::GetGuid(void)
|
|
{
|
|
WCHAR pwcsGuidString[128];
|
|
HRESULT hr = S_OK;
|
|
|
|
//=======================================
|
|
// Initialize ptrs we will need
|
|
//=======================================
|
|
if( m_wHardCodedGuid ){
|
|
wcscpy( pwcsGuidString,WMI_BINARY_MOF_GUID);
|
|
}
|
|
else{
|
|
memset(pwcsGuidString,NULL,128);
|
|
hr = GetQualifierString( NULL, L"guid", pwcsGuidString,128);
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
//===========================================================
|
|
// Set the GUID first, before we try to open the WMI
|
|
// data block, if succeeds, then open WMI
|
|
//===========================================================
|
|
if( !SetGuid(pwcsGuidString,m_Guid) )
|
|
{
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::SetClass(WCHAR * wcsClass)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
if( wcsClass )
|
|
{
|
|
hr = SetClassName(wcsClass);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
CBSTR cbstr(m_pwcsClassName);
|
|
|
|
hr = m_pWMI->Services()->GetObject(cbstr,0,CONTEXT,&m_pClass, NULL);
|
|
if( hr == S_OK )
|
|
{
|
|
hr = GetGuid();
|
|
// If there is no GUID for the class then set proper error message
|
|
if(hr == WBEM_E_NOT_FOUND)
|
|
{
|
|
hr = WBEM_E_NOT_SUPPORTED;
|
|
}
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
//===========================================================
|
|
// Get the IWbemObjectAccess interface for the object
|
|
// ==========================================================
|
|
if( m_fHiPerf )
|
|
{
|
|
hr = m_pClass->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccess);
|
|
}
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = GetPropertiesInIDOrder(m_fHiPerf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
//=============================================================
|
|
//=============================================================
|
|
HRESULT CWMIProcessClass::SetClassName(WCHAR * pIn )
|
|
{
|
|
SAFE_DELETE_ARRAY(m_pwcsClassName);
|
|
return AllocAndCopy(pIn,&m_pwcsClassName);
|
|
}
|
|
//=============================================================
|
|
HRESULT CWMIProcessClass::SetClass(IWbemClassObject * pPtr)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
if( pPtr )
|
|
{
|
|
m_pClass = pPtr;
|
|
CVARIANT vName;
|
|
hr = m_pClass->Get(L"__CLASS", 0, &vName, NULL, NULL);
|
|
if( hr == S_OK )
|
|
{
|
|
hr = SetClassName(vName.GetStr());
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = GetPropertiesInIDOrder(FALSE);
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
//=============================================================
|
|
HRESULT CWMIProcessClass::SetAccess(IWbemObjectAccess * pPtr)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
if( pPtr )
|
|
{
|
|
SAFE_RELEASE_PTR(m_pAccess);
|
|
SAFE_RELEASE_PTR(m_pClass);
|
|
|
|
m_pAccess = pPtr;
|
|
m_pAccess->AddRef();
|
|
|
|
CVARIANT vName;
|
|
hr = m_pAccess->Get(L"__CLASS", 0, &vName, NULL, NULL);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = SetClassName(vName.GetStr());
|
|
if( hr == S_OK )
|
|
{
|
|
CBSTR cbstr(m_pwcsClassName);
|
|
|
|
hr = SERVICES->GetObject(cbstr, 0,CONTEXT, &m_pClass, NULL);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = GetGuid();
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
hr = GetPropertiesInIDOrder(TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
//=============================================================
|
|
HRESULT CWMIProcessClass::SetClassPointerOnly(IWbemClassObject * pPtr)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
if( pPtr )
|
|
{
|
|
SAFE_RELEASE_PTR(m_pClass);
|
|
m_pClass = pPtr;
|
|
m_pClass->AddRef();
|
|
hr = S_OK;
|
|
}
|
|
return hr;
|
|
}
|
|
//=============================================================
|
|
void CWMIProcessClass::SaveEmbeddedClass(CVARIANT & v)
|
|
{
|
|
IDispatch * pAlterEgo = NULL;
|
|
m_pClassInstance->QueryInterface(IID_IUnknown, (void**)&pAlterEgo);
|
|
// VariantClear will call release()
|
|
v.SetUnknown(pAlterEgo);
|
|
}
|
|
//=============================================================
|
|
HRESULT CWMIProcessClass::ReadEmbeddedClassInstance( IUnknown * pUnknown, CVARIANT & v )
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
//=============================================
|
|
// Get the class
|
|
//=============================================
|
|
IUnknown * pUnk = NULL;
|
|
if( pUnknown )
|
|
{
|
|
pUnk = pUnknown;
|
|
}
|
|
else
|
|
{
|
|
pUnk = v.GetUnknown();
|
|
}
|
|
|
|
IWbemClassObject * pClass = NULL;
|
|
if( pUnk )
|
|
{
|
|
pUnk->QueryInterface(IID_IWbemClassObject,(void**) &pClass );
|
|
if( pClass )
|
|
{
|
|
//===============================================
|
|
// Get class definition, so we need to get the
|
|
// class name
|
|
CVARIANT vName;
|
|
CAutoWChar wcsClassName(_MAX_PATH+2);
|
|
if( wcsClassName.Valid() )
|
|
{
|
|
hr = pClass->Get(L"__CLASS", 0, &vName, NULL, NULL);
|
|
if( hr == S_OK )
|
|
{
|
|
wcscpy( wcsClassName,vName.GetStr());
|
|
hr = SetClass(wcsClassName);
|
|
if( S_OK == hr )
|
|
{
|
|
hr = SetClassPointerOnly(pClass);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
}
|
|
SAFE_RELEASE_PTR( pClass );
|
|
|
|
return hr;
|
|
}
|
|
//=======================================================================
|
|
int CWMIProcessClass::PropertyCategory()
|
|
{
|
|
if (!(m_pCurrentProperty->PropertyType() & CIM_FLAG_ARRAY) )
|
|
{
|
|
if( m_pCurrentProperty->PropertyType() == VT_UNKNOWN )
|
|
{
|
|
return CWMIProcessClass::EmbeddedClass;
|
|
}
|
|
else
|
|
{
|
|
return CWMIProcessClass::Data;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return CWMIProcessClass::Array;
|
|
}
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::InitializeEmbeddedClass(CWMIProcessClass * p)
|
|
{
|
|
SetWMIPointers(p);
|
|
return SetClass(p->EmbeddedClassName());
|
|
}
|
|
|
|
//=======================================================================
|
|
HRESULT CWMIProcessClass::GetLargestDataTypeInClass(int & nSize)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
WCHAR * pwcsProperty;
|
|
BOOL fClassContainsAnotherDataTypeBesidesAnEmbeddedClass = FALSE;
|
|
int nNewSize = 0L;
|
|
|
|
nSize = 0L;
|
|
//=========================================================
|
|
// Get size of largest data type within the class and
|
|
// align it on that, however, if the class contains an
|
|
// embedded class ONLY, then get the size of the largest
|
|
// datatype within that embedded class.
|
|
//=========================================================
|
|
pwcsProperty = FirstProperty();
|
|
|
|
while (NULL != pwcsProperty)
|
|
{
|
|
switch( PropertyCategory())
|
|
{
|
|
case CWMIProcessClass::EmbeddedClass:
|
|
{
|
|
if( !fClassContainsAnotherDataTypeBesidesAnEmbeddedClass ){
|
|
CWMIProcessClass EmbeddedClass(0);
|
|
|
|
hr = EmbeddedClass.Initialize();
|
|
if( S_OK == hr )
|
|
{
|
|
hr = EmbeddedClass.InitializeEmbeddedClass(this);
|
|
if( hr != S_OK ){
|
|
break;
|
|
}
|
|
|
|
// embedded object
|
|
hr = EmbeddedClass.GetLargestDataTypeInClass(nNewSize);
|
|
if( hr != S_OK ){
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CWMIProcessClass::Array:
|
|
case CWMIProcessClass::Data:
|
|
fClassContainsAnotherDataTypeBesidesAnEmbeddedClass = TRUE;
|
|
nNewSize = PropertySize();
|
|
break;
|
|
}
|
|
|
|
if( nNewSize == SIZEOFWBEMDATETIME ){
|
|
nNewSize = 1;
|
|
}
|
|
|
|
if( nNewSize > nSize ){
|
|
nSize = nNewSize;
|
|
}
|
|
|
|
pwcsProperty = NextProperty();
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
////////////////////////////////////////////////////////////////////
|
|
HRESULT CWMIProcessClass::GetSizeOfArray(long & lType, DWORD & dwCount, BOOL & fDynamic)
|
|
{
|
|
HRESULT hr = WBEM_E_OUT_OF_MEMORY;
|
|
CAutoWChar pwcsArraySize(_MAX_PATH+2);
|
|
|
|
if( pwcsArraySize.Valid() )
|
|
{
|
|
dwCount = 0;
|
|
lType = m_pCurrentProperty->PropertyType() &~ CIM_FLAG_ARRAY;
|
|
|
|
pwcsArraySize[0]=NULL;
|
|
//======================================================
|
|
// Get the number of elements in the array from the
|
|
// "ArraySize" property qualifier
|
|
//======================================================
|
|
hr = GetQualifierString(m_pCurrentProperty->PropertyName(), L"MAX",pwcsArraySize, MAX_PATH);
|
|
if( hr == S_OK )
|
|
{
|
|
CAnsiUnicode XLate;
|
|
char * pChar = NULL;
|
|
|
|
if( SUCCEEDED(XLate.UnicodeToAnsi(pwcsArraySize, pChar )))
|
|
{
|
|
if( pChar )
|
|
{
|
|
dwCount = atol(pChar);
|
|
SAFE_DELETE_ARRAY(pChar);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = GetQualifierString(m_pCurrentProperty->PropertyName(),L"WMISizeIs",pwcsArraySize,MAX_PATH);
|
|
if( hr == S_OK )
|
|
{
|
|
CVARIANT var;
|
|
CIMTYPE lTmpType;
|
|
hr = WBEM_E_FAILED;
|
|
|
|
fDynamic = TRUE;
|
|
|
|
if( m_pClassInstance )
|
|
{
|
|
hr = m_pClassInstance->Get(pwcsArraySize, 0, &var, &lTmpType,NULL);
|
|
}
|
|
else
|
|
{
|
|
if( m_pClass )
|
|
{
|
|
hr = m_pClass->Get(pwcsArraySize, 0, &var, &lTmpType,NULL);
|
|
}
|
|
}
|
|
if( hr == S_OK )
|
|
{
|
|
CWMIDataTypeMap MapIt;
|
|
dwCount = MapIt.ArraySize(lTmpType,var);
|
|
}
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
// If all else fails, get the size of the array from the class definition.
|
|
//==============================================================================
|
|
if( hr != S_OK )
|
|
{
|
|
dwCount = m_pCurrentProperty->ArraySize();
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
//======================================================================
|
|
HRESULT CWMIProcessClass::GetSizeOfClass(DWORD & dwSize)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
WCHAR * pwcsProperty;
|
|
|
|
dwSize = 0;
|
|
|
|
pwcsProperty = FirstProperty();
|
|
|
|
while (NULL != pwcsProperty)
|
|
{
|
|
switch( PropertyCategory())
|
|
{
|
|
case CWMIProcessClass::EmbeddedClass:
|
|
{
|
|
DWORD dwEmbeddedSize;
|
|
CWMIProcessClass EmbeddedClass(0);
|
|
|
|
hr = EmbeddedClass.Initialize();
|
|
if( S_OK == hr )
|
|
{
|
|
hr = EmbeddedClass.InitializeEmbeddedClass(this);
|
|
if( hr != S_OK ){
|
|
break;
|
|
}
|
|
// embedded object
|
|
hr = EmbeddedClass.GetSizeOfClass(dwEmbeddedSize);
|
|
if( hr != S_OK ){
|
|
break;
|
|
}
|
|
dwSize += dwEmbeddedSize;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CWMIProcessClass::Array:
|
|
{
|
|
int nSize = PropertySize();
|
|
dwSize += (nSize * ArraySize());
|
|
}
|
|
break;
|
|
|
|
case CWMIProcessClass::Data:
|
|
dwSize += PropertySize();
|
|
break;
|
|
}
|
|
pwcsProperty = NextProperty();
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ULONG CWMIProcessClass::GetMethodId(LPCWSTR strProp)
|
|
{
|
|
ULONG uMethodId = 0;
|
|
IWbemQualifierSet * pIWbemQualifierSet = NULL;
|
|
|
|
//======================================================
|
|
// Get the number of elements in the array from the
|
|
// "ArraySize" property qualifier
|
|
//======================================================
|
|
HRESULT hr = m_pClass->GetMethodQualifierSet(strProp,&pIWbemQualifierSet);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
CVARIANT v;
|
|
hr = pIWbemQualifierSet->Get(L"WMIMethodId", 0, &v, 0);
|
|
if( SUCCEEDED(hr))
|
|
{
|
|
uMethodId = v.GetLONG();
|
|
}
|
|
SAFE_RELEASE_PTR(pIWbemQualifierSet);
|
|
}
|
|
return uMethodId;
|
|
}
|
|
|