Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2335 lines
64 KiB

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
MOFPROP.CPP
Abstract:
History:
--*/
#include "precomp.h"
#include <wbemidl.h>
//#include "corepol.h"
#include "wstring.h"
#include "mofout.h"
#include "mofprop.h"
#include "typehelp.h"
#include "trace.h"
#include "strings.h"
#include "cwbemtime.h"
#include <genutils.h>
#include <wbemutil.h>
#include <cominit.h>
#include <arrtempl.h>
#include "moflex.h"
#include "mofparse.h"
#include <memory>
HRESULT MofdSetInterfaceSecurity(IUnknown * pInterface, LPWSTR pAuthority,
LPWSTR pUser, LPWSTR pPassword);
BOOL BinaryToInt(wchar_t * pConvert, __int64& i64Res);
void assign(WCHAR * &pTo, LPCWSTR pFrom)
{
if(pTo)
{
delete pTo;
pTo = NULL;
}
if(pFrom)
{
DWORD dwLen = wcslen(pFrom)+1;
pTo = new WCHAR[dwLen];
if(pTo)
StringCchCopyW(pTo, dwLen, pFrom);
}
}
BOOL ConvertAndTry(WCHAR * pFormat, WCHAR *pData, WCHAR *pCheck, unsigned __int64 & ui8)
{
static WCHAR wTemp[100];
if(swscanf(pData, pFormat, &ui8) != 1)
return FALSE;
StringCchPrintfW(wTemp, 100, pFormat, ui8);
return !wbem_wcsicmp(wTemp, pCheck);
}
CMoValue::CAlias::CAlias(COPY LPCWSTR wszAlias, int nArrayIndex)
{
m_nArrayIndex = nArrayIndex;
m_wszAlias = Macro_CloneStr(wszAlias);
}
CMoValue::CAlias::~CAlias()
{
delete [] m_wszAlias;
}
CMoValue::CMoValue(PDBG pDbg)
{
m_pDbg = pDbg;
m_vType = 0;
VariantInit(&m_varValue);
}
CMoValue::~CMoValue()
{
if(m_varValue.vt == VT_EMBEDDED_OBJECT)
{
#ifdef _WIN64
CMObject * pObj = (CMObject *)m_varValue.llVal;
#else
CMObject * pObj = (CMObject *)m_varValue.lVal;
#endif
if(pObj)
delete pObj;
m_varValue.vt = VT_NULL;
}
else if(m_varValue.vt == (VT_EMBEDDED_OBJECT | VT_ARRAY))
{
SCODE sc ;
SAFEARRAY * psaSrc = m_varValue.parray;
if(psaSrc == NULL)
return;
long lLBound, lUBound;
sc = SafeArrayGetLBound(psaSrc, 1, &lLBound);
sc |= SafeArrayGetUBound(psaSrc, 1, &lUBound);
if(sc != S_OK)
return;
for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
{
// Load the initial data element into a VARIANT
// ============================================
CMObject * pObj;
sc = SafeArrayGetElement(psaSrc, &lIndex, &pObj);
if(sc == S_OK && pObj)
delete pObj;
}
SafeArrayDestroy(psaSrc);
m_varValue.vt = VT_NULL;
}
if((m_varValue.vt & ~ VT_ARRAY) != VT_EMBEDDED_OBJECT)
VariantClear(&m_varValue);
for(int i = 0; i < m_aAliases.GetSize(); i++)
{
delete (CAlias*)m_aAliases[i];
}
}
BOOL CMoValue::GetAlias(IN int nAliasIndex,
OUT INTERNAL LPWSTR& wszAlias,
OUT int& nArrayIndex)
{
if(nAliasIndex >= m_aAliases.GetSize()) return FALSE;
CAlias* pAlias = (CAlias*)m_aAliases[nAliasIndex];
wszAlias = pAlias->m_wszAlias;
nArrayIndex = pAlias->m_nArrayIndex;
return TRUE;
}
HRESULT CMoValue::AddAlias(COPY LPCWSTR wszAlias, int nArrayIndex)
{
std::auto_ptr<CAlias> pAlias(new CAlias(wszAlias, nArrayIndex));
if(pAlias.get() == NULL)
return WBEM_E_OUT_OF_MEMORY;
if(pAlias->m_wszAlias == NULL && wszAlias != NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
m_aAliases.Add(pAlias.get());
pAlias.release();
return S_OK;
}
//*****************************************************************************
CMoProperty::CMoProperty(CMoQualifierArray * paQualifiers, PDBG pDbg) : m_Value(pDbg)
{
m_pDbg = pDbg;
m_wszName = NULL;
m_wszTypeTitle = NULL;
m_paQualifiers = paQualifiers;
}
HRESULT CMoProperty::SetPropName(COPY LPCWSTR wszName)
{
delete [] m_wszName;
m_wszName = Macro_CloneStr(wszName);
if(m_wszName == NULL && wszName != NULL )
return WBEM_E_OUT_OF_MEMORY;
else
return S_OK;
}
HRESULT CMoProperty::SetTypeTitle(COPY LPCWSTR wszName)
{
delete [] m_wszTypeTitle;
m_wszTypeTitle = Macro_CloneStr(wszName);
if(m_wszTypeTitle == NULL && wszName != NULL)
return WBEM_E_OUT_OF_MEMORY;
else
return S_OK;
}
void CMoProperty::SetQualifiers(ACQUIRE CMoQualifierArray* pQualifiers)
{
delete m_paQualifiers;
m_paQualifiers = pQualifiers;
}
IWbemClassObject * CMoProperty::GetInstPtr(const WCHAR * pClassName, IWbemServices* pNamespace, CMObject * pMo,
IWbemContext * pCtx)
{
IWbemClassObject *pInst = NULL;
SCODE sc;
BSTR bstr = SysAllocString(pClassName);
if(bstr == NULL)
return NULL;
CSysFreeMe fm(bstr);
if(!wbem_wcsicmp(L"__PARAMETERS", pClassName))
{
sc = pNamespace->GetObject(bstr, 0, pCtx, &pInst, NULL);
}
else if(pMo->IsInstance())
{
IWbemClassObject *pClass = NULL;
sc = pNamespace->GetObject(bstr, 0, pCtx, &pClass, NULL);
if(sc != S_OK)
return NULL;
sc = pClass->SpawnInstance(0, &pInst);
pClass->Release();
}
else
{
// got a class, not an instance!
CMoClass * pClass = (CMoClass * )pMo;
if(pClass->GetParentName() && wcslen(pClass->GetParentName()) > 0)
{
IWbemClassObject * pParent = NULL;
BSTR bstrParent = SysAllocString(pClass->GetParentName());
if(bstrParent == NULL)
return NULL;
CSysFreeMe fm2(bstrParent);
sc = pNamespace->GetObject(bstrParent, 0, pCtx, &pParent, NULL);
if(FAILED(sc))
return NULL;
CReleaseMe rm(pParent);
sc = pParent->SpawnDerivedClass(0, &pInst);
if(FAILED(sc))
return NULL;
}
else
sc = pNamespace->GetObject(NULL, 0, pCtx, &pInst, NULL);
if(sc != S_OK)
return NULL;
VARIANT var;
var.vt = VT_BSTR;
var.bstrVal = bstr;
pInst->Put(L"__CLASS", 0, &var, 0);
}
if(sc != S_OK)
return NULL;
BOOL bOK = pMo->ApplyToWbemObject(pInst,pNamespace,pCtx);
if(bOK)
return pInst;
else
{
pInst->Release();
return NULL;
}
}
BOOL CValueProperty::AddEmbeddedObject(OLE_MODIFY IWbemClassObject* pObject, IWbemServices* pNamespace, IWbemContext * pCtx)
{
VARIANT & var = m_Value.AccessVariant();
VARIANT vSet;
IWbemClassObject * pInst = NULL;
if(var.vt & VT_ARRAY)
{
vSet.vt = VT_EMBEDDED_OBJECT | VT_ARRAY;
SAFEARRAYBOUND aBounds[1];
long lLBound, lUBound;
SafeArrayGetLBound(var.parray, 1, &lLBound);
SafeArrayGetUBound(var.parray, 1, &lUBound);
aBounds[0].cElements = lUBound - lLBound + 1;
aBounds[0].lLbound = lLBound;
vSet.parray = SafeArrayCreate(VT_EMBEDDED_OBJECT & ~VT_ARRAY, 1, aBounds);
if(vSet.parray == NULL)
return FALSE;
// Stuff the individual data pieces
// ================================
for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
{
// Load the initial data element into a VARIANT
// ============================================
CMObject * pTemp;
SCODE hres = SafeArrayGetElement(var.parray, &lIndex, &pTemp);
if(FAILED(hres) || pTemp == FALSE)
{
SafeArrayDestroy(vSet.parray);
return FALSE;
}
// Cast it to the new type
// =======================
pInst = GetInstPtr(pTemp->GetClassName(), pNamespace, pTemp, pCtx);
if(pInst == NULL)
{
Trace(true, m_pDbg, ALIAS_PROP_ERROR, m_wszName);
SafeArrayDestroy(vSet.parray);
return FALSE;
}
// Put it into the new array
// =========================
hres = SafeArrayPutElement(vSet.parray, &lIndex, pInst);
pInst->Release();
if(FAILED(hres))
{
SafeArrayDestroy(vSet.parray);
return FALSE;
}
}
}
else
{
CMObject * pTemp = (CMObject *)var.punkVal;
pInst = GetInstPtr(pTemp->GetClassName(), pNamespace, pTemp, pCtx);
if(pInst == NULL)
{
Trace(true, m_pDbg, ALIAS_PROP_ERROR, m_wszName);
return FALSE;
}
vSet.punkVal = pInst;
vSet.vt = VT_EMBEDDED_OBJECT;
}
HRESULT hres = pObject->Put(m_wszName, 0, &vSet, 0);
// Release all the WbemObjects we have created
// ==========================================
if(var.vt & VT_ARRAY)
SafeArrayDestroy(vSet.parray);
else if(pInst)
pInst->Release();
return hres == S_OK;
}
BOOL CValueProperty::AddToObject(OLE_MODIFY IWbemClassObject* pObject, IWbemServices* pNamespace,
BOOL bClass, IWbemContext * pCtx)
{
if(m_wszName == NULL) return FALSE;
m_pDbg->SetString(m_wszName);
// Get the property value
// ======================
VARIANT & var = m_Value.AccessVariant();
// Determine if this is an embedded object.
VARTYPE vtSimple = var.vt & ~VT_ARRAY;
if(vtSimple == VT_NULL)
vtSimple = m_Value.GetType() & ~VT_ARRAY;
// If the type is embedded object, make sure the class name is OK.
if(vtSimple == VT_EMBEDDED_OBJECT)
{
// Determine the class name of the embedded object.
CMoValue * pValue = m_paQualifiers->Find(L"CIMTYPE");
if(pValue)
{
if(var.vt == VT_BSTR && wcslen(var.bstrVal) > wcslen(L"Object:"))
{
// Test if this class if valid by doing a GetObject call
WCHAR * pClassName = var.bstrVal + wcslen(L"Object:");
IWbemClassObject *pClass = NULL;
BSTR bstr = SysAllocString(pClassName);
if(bstr == NULL)
return FALSE;
SCODE sc = pNamespace->GetObject(bstr, 0, pCtx,&pClass, NULL);
SysFreeString(bstr);
if(sc != S_OK)
{
m_pDbg->hresError = WBEM_E_INVALID_PROPERTY_TYPE;
Trace(true, m_pDbg, BAD_PROP_TYPE, GetName());
return FALSE;
}
pClass->Release();
}
}
}
// If there is an actual embedded object, store it.
if((var.vt & ~VT_ARRAY) == VT_EMBEDDED_OBJECT)
{
if(!AddEmbeddedObject(pObject, pNamespace, pCtx))
return FALSE;
return GetQualifiers()->AddToPropOrMeth(pObject, m_wszName, bClass, TRUE);
}
VARTYPE vNewType = m_Value.GetType();
// arguments cannot be VT_EMPTY
if(m_bIsArg && var.vt == VT_EMPTY)
var.vt = VT_NULL;
// Set the property value. Not that reference types are a special case used by binary mofs
// and so the flag should be eliminated.
// ======================
vNewType &= ~VT_BYREF;
HRESULT hres = pObject->Put(m_wszName, 0, &var, (bClass || m_bIsArg) ? vNewType : 0);
if(FAILED(hres))
{
m_pDbg->hresError = hres;
return FALSE;
}
// Configure the qualifier set
// ===========================
if(!GetQualifiers()->AddToPropOrMeth(pObject, m_wszName, bClass, TRUE))
{
return FALSE;
}
// Get the syntax value
// ====================
// VariantClear(&vNew);
// VariantClear(&v);
return TRUE;
}
BOOL CValueProperty::RegisterAliases(MODIFY CMObject* pObject)
{
// Copy all alias registrations into the object
// ============================================
int iNumAlias = m_Value.GetNumAliases();
for(int i = 0; i < iNumAlias; i++)
{
LPWSTR wszAlias;
int nArrayIndex;
m_Value.GetAlias(i, wszAlias, nArrayIndex);
CPropertyLocation * pNew = new CPropertyLocation(m_wszName, nArrayIndex);
if(pNew == NULL)
return FALSE;
if(pNew->IsOK() == false)
{
delete pNew;
return FALSE;
}
HRESULT hr = pObject->AddAliasedValue(pNew, wszAlias);
if(FAILED(hr))
return FALSE;
}
// Ask the qualifier set to do the same
// ====================================
if(m_paQualifiers)
GetQualifiers()->RegisterAliases(pObject, m_wszName);
return TRUE;
}
CMoProperty::~CMoProperty()
{
if(m_paQualifiers)
delete m_paQualifiers;
if(m_wszName)
delete [] m_wszName;
if(m_wszTypeTitle)
delete [] m_wszTypeTitle;
}
//*****************************************************************************
CMoQualifier::CMoQualifier(PDBG pDbg) : m_Value(pDbg)
{
m_pDbg = pDbg;
m_wszName = NULL;
m_lFlavor = 0;
m_bOverrideSet = false;
m_bNotOverrideSet = false;
m_bIsRestricted = false;
m_bNotToInstance = false;
m_bToInstance = false;
m_bNotToSubclass = false;
m_bToSubclass = false;
m_bAmended = false;
m_dwScope = 0;
m_bCimDefaultQual = false;
m_bUsingDefaultValue = false;
}
CMoQualifier::~CMoQualifier()
{
if(m_wszName)
delete [] m_wszName;
}
HRESULT CMoQualifier::SetFlag(int iToken, LPCWSTR pwsText)
{
if(iToken == TOK_TOINSTANCE)
{
if(m_bIsRestricted || m_bNotToInstance)
return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
m_lFlavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
m_bToInstance = true;
}
else if(iToken == TOK_TOSUBCLASS)
{
if(m_bIsRestricted || m_bNotToSubclass)
return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
m_lFlavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
m_bToSubclass = true;
}
else if(iToken == TOK_NOTTOINSTANCE)
{
if(m_bToInstance)
return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
m_lFlavor &= ~WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
m_bNotToInstance = true;
}
else if(iToken == TOK_NOTTOSUBCLASS)
{
if(m_bToSubclass)
return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
m_lFlavor &= ~WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
m_bNotToSubclass = true;
}
else if(iToken == TOK_ENABLEOVERRIDE)
{
if(m_bNotOverrideSet)
return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
m_lFlavor &= ~WBEM_FLAVOR_NOT_OVERRIDABLE;
m_bOverrideSet = true;
}
else if(iToken == TOK_DISABLEOVERRIDE)
{
if(m_bOverrideSet)
return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
m_bNotOverrideSet = true;
m_lFlavor |= WBEM_FLAVOR_NOT_OVERRIDABLE;
}
else if(iToken == TOK_RESTRICTED)
{
if(m_bToInstance || m_bToSubclass)
return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
m_bIsRestricted = true;
m_lFlavor &= ~WBEM_FLAVOR_MASK_PROPAGATION;
}
else if(iToken == TOK_AMENDED)
{
m_bAmended = true;
}
else if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(L"translatable", pwsText))
{
return S_OK; // WBEMMOF_E_UNSUPPORTED_CIMV22_FLAVOR_TYPE;
}
else
return WBEMMOF_E_EXPECTED_FLAVOR_TYPE;
return S_OK;
}
BOOL CMoQualifier::SetScope(int iToken, LPCWSTR pwsText)
{
if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"ANY"))
{
m_dwScope |= 0XFFFFFFFF;
return TRUE;
}
if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"ASSOCIATION"))
{
m_dwScope |= SCOPE_ASSOCIATION;
return TRUE;
}
if(iToken == TOK_CLASS)
{
m_dwScope |= SCOPE_CLASS;
return TRUE;
}
if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"indication"))
{
ERRORTRACE((LOG_MOFCOMP,"Warning, unsupported INDICATION keyword used in scope\n"));
return TRUE; // IGNORE THESE
}
if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"schema"))
{
ERRORTRACE((LOG_MOFCOMP,"Warning, unsupported SCHEMA keyword used in scope\n"));
return TRUE; // IGNORE THESE
}
if(iToken == TOK_INSTANCE)
{
m_dwScope |= SCOPE_INSTANCE;
return TRUE;
}
if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"METHOD"))
{
m_dwScope |= SCOPE_METHOD;
return TRUE;
}
if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"PARAMETER"))
{
m_dwScope |= SCOPE_PARAMETER;
return TRUE;
}
if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"PROPERTY"))
{
m_dwScope |= SCOPE_PROPERTY;
return TRUE;
}
if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"REFERENCE"))
{
m_dwScope |= SCOPE_REFERENCE;
return TRUE;
}
return FALSE;
}
HRESULT CMoQualifier::SetQualName(COPY LPCWSTR wszName)
{
delete [] m_wszName;
m_wszName = Macro_CloneStr(wszName);
if(m_wszName == NULL && wszName != NULL)
return WBEM_E_OUT_OF_MEMORY;
else
return S_OK;
}
BOOL CMoQualifier::AddToSet(OLE_MODIFY IWbemQualifierSet* pQualifierSet,
BOOL bClass)
{
BSTR strName = SysAllocString(m_wszName);
if(strName == NULL)
{
return FALSE;
}
m_pDbg->SetString(strName);
HRESULT hres = pQualifierSet->Put(
strName,
&m_Value.AccessVariant(),GetFlavor());
if(FAILED(hres))
{
m_pDbg->hresError = hres;
return FALSE;
}
SysFreeString(strName);
return SUCCEEDED(hres);
}
INTERNAL CMoValue* CMoQualifierArray::Find(READ_ONLY LPCWSTR wszName)
{
for(int i = 0; i < GetSize(); i++)
{
CMoQualifier* pQual = GetAt(i);
if(!wbem_wcsicmp(pQual->GetName(), wszName))
{
return &pQual->AccessValue();
}
}
return NULL;
}
BOOL CMoQualifierArray::Add(ACQUIRE CMoQualifier* pQualifier)
{
// before adding a qualifier, check for a duplicate name.
if(pQualifier == NULL || pQualifier->GetName() == NULL)
return FALSE;
CMoValue * pValue = Find(pQualifier->GetName());
if(pValue != NULL)
return FALSE;
m_aQualifiers.Add(pQualifier);
return TRUE;
}
//*****************************************************************************
CMoQualifierArray::~CMoQualifierArray()
{
for(int i = 0; i < GetSize(); i++)
{
delete GetAt(i);
}
}
BOOL CMoQualifierArray::AddToSet(OLE_MODIFY IWbemQualifierSet* pQualifierSet,
BOOL bClass)
{
// Add all the qualifiers to it
// ============================
for(int i = 0; i < GetSize(); i++)
{
if(!GetAt(i)->AddToSet(pQualifierSet, bClass)) return FALSE;
}
return TRUE;
}
BOOL CMoQualifierArray::RegisterAliases(MODIFY CMObject* pObject,
READ_ONLY LPCWSTR wszPropName)
{
for(int i = 0; i < GetSize(); i++)
{
CMoValue& QualifierValue = GetAt(i)->AccessValue();
LPCWSTR wszName = GetAt(i)->GetName();
for(int j = 0; j < QualifierValue.GetNumAliases(); j++)
{
LPWSTR wszAlias;
int nArrayIndex;
QualifierValue.GetAlias(j, wszAlias, nArrayIndex);
VARIANT & Var = QualifierValue.AccessVariant();
if((Var.vt & VT_ARRAY) == 0)
nArrayIndex = -1;
CQualifierLocation * pNew = new CQualifierLocation(wszName, m_pDbg, wszPropName, nArrayIndex);
if(pNew == NULL)
return FALSE;
if(pNew->IsOK() == false)
{
delete pNew;
return FALSE;
}
HRESULT hr = pObject->AddAliasedValue(pNew , wszAlias);
if(FAILED(hr))
return FALSE;
}
}
return TRUE;
}
BOOL CMoQualifierArray::AddToObject(OLE_MODIFY IWbemClassObject* pObject,
BOOL bClass)
{
// Get the qualifier set from the object
// =====================================
IWbemQualifierSet* pQualifierSet;
if(FAILED(pObject->GetQualifierSet(&pQualifierSet)))
{
return FALSE;
}
// Add all qualifiers to it
// ========================
BOOL bRes = AddToSet(pQualifierSet, bClass);
pQualifierSet->Release();
return bRes;
}
BOOL CMoQualifierArray::AddToPropOrMeth(OLE_MODIFY IWbemClassObject* pObject,
READ_ONLY LPCWSTR wszName,
BOOL bClass, BOOL bProp)
{
// Get the qualifier set
// =====================
BSTR strName = SysAllocString(wszName);
if(strName == NULL)
{
return FALSE;
}
IWbemQualifierSet* pQualifierSet;
SCODE sc;
if(bProp)
sc = pObject->GetPropertyQualifierSet(strName, &pQualifierSet);
else
sc = pObject->GetMethodQualifierSet(strName, &pQualifierSet);
SysFreeString(strName);
if(FAILED(sc))
return FALSE;
// Add qualifiers to it
// ====================
BOOL bRes = AddToSet(pQualifierSet, bClass);
pQualifierSet->Release();
return bRes;
}
//*****************************************************************************
CMoType::~CMoType()
{
delete m_wszTitle;
}
HRESULT CMoType::SetTitle(COPY LPCWSTR wszTitle)
{
delete [] m_wszTitle;
m_wszTitle = Macro_CloneStr(wszTitle);
if(m_wszTitle == NULL && wszTitle != NULL)
return WBEM_E_OUT_OF_MEMORY;
else
return S_OK;
}
VARTYPE CMoType::GetCIMType()
{
if(IsRef() && IsArray()) return CIM_REFERENCE | VT_ARRAY;
if(IsRef()) return CIM_REFERENCE;
if(IsEmbedding() && IsArray()) return VT_EMBEDDED_OBJECT | VT_ARRAY;
if(IsEmbedding()) return VT_EMBEDDED_OBJECT;
VARTYPE vt_array = (IsArray())?VT_ARRAY:0;
// Check if it is even initialized
// ===============================
if(m_wszTitle == NULL)
{
return VT_BSTR; // HACK! string converts nicely into just about anything
}
// VT_UI1
if(!wbem_wcsicmp(m_wszTitle, L"sint8"))
return CIM_SINT8 | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"uint8"))
return CIM_UINT8 | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"sint16"))
return CIM_SINT16 | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"uint16"))
return CIM_UINT16 | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"sint32"))
return CIM_SINT32 | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"uint32"))
return CIM_UINT32 | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"sint64"))
return CIM_SINT64 | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"uint64"))
return CIM_UINT64 | vt_array;
// VT_R4
if (!wbem_wcsicmp(m_wszTitle, L"real32"))
return CIM_REAL32 | vt_array;
if (!wbem_wcsicmp(m_wszTitle, L"real64"))
return CIM_REAL64 | vt_array;
// Do other types
if(!wbem_wcsicmp(m_wszTitle, L"BOOLEAN"))
return CIM_BOOLEAN | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"string"))
return CIM_STRING | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"datetime"))
return CIM_DATETIME | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"REF"))
return CIM_REFERENCE | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"CHAR16"))
return CIM_CHAR16 | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"OBJECT"))
return CIM_OBJECT | vt_array;
if(!wbem_wcsicmp(m_wszTitle, L"void") ||
!wbem_wcsicmp(m_wszTitle, L"null"))
return VT_NULL;
if(!wbem_wcsnicmp(m_wszTitle, L"REF:", 4))
return CIM_REFERENCE | vt_array;
if(!wbem_wcsnicmp(m_wszTitle, L"OBJECT:", 7))
return CIM_OBJECT | vt_array;
return VT_ERROR;
}
bool CMoType::IsUnsupportedType()
{
if(m_wszTitle == NULL)
{
return false;
}
if(!wbem_wcsicmp(m_wszTitle, L"dt_sint8"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_uint8"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_sint16"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_uint16"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_sint32"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_uint32"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_sint64"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_uint64"))
return true;
if (!wbem_wcsicmp(m_wszTitle, L"dt_real32"))
return true;
if (!wbem_wcsicmp(m_wszTitle, L"dt_real64"))
return true;
if (!wbem_wcsicmp(m_wszTitle, L"dt_char16"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_BOOL"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_str"))
return true;
if(!wbem_wcsicmp(m_wszTitle, L"dt_datetime"))
return true;
return false;
}
BOOL CMoType::StoreIntoQualifiers(CMoQualifierArray * pQualifiers)
{
if(pQualifiers == NULL)
return FALSE;
if(IsRef() ||IsEmbedding())
{
WCHAR * pFormat = (IsRef()) ? L"ref" : L"object";
if(wbem_wcsicmp(m_wszTitle, L"object") == 0)
{
pQualifiers->Add(CreateSyntax(pFormat));
}
else
{
DWORD dwLen = wcslen(m_wszTitle) + 20;
LPWSTR wszSyntax = new WCHAR[dwLen];
if(wszSyntax == NULL)
return FALSE;
StringCchPrintfW(wszSyntax, dwLen, L"%s:%s",pFormat, m_wszTitle);
pQualifiers->Add(CreateSyntax(wszSyntax));
delete [] wszSyntax;
}
return TRUE;
}
pQualifiers->Add(CreateSyntax(m_wszTitle));
return TRUE;
}
DELETE_ME CMoQualifier* CMoType::CreateSyntax(READ_ONLY LPCWSTR wszSyntax)
{
CMoQualifier* pQualifier = new CMoQualifier(m_pDbg);
if(pQualifier == NULL)
return NULL;
if(FAILED(pQualifier->SetQualName(L"CIMTYPE")))
{
delete pQualifier;
return NULL;
}
pQualifier->SetFlavor(WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE |
WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS);
BSTR bstrVal = SysAllocString(wszSyntax);
if(bstrVal == NULL)
{
delete pQualifier;
return NULL;
}
V_VT(&pQualifier->AccessValue().AccessVariant()) = VT_BSTR;
V_BSTR(&pQualifier->AccessValue().AccessVariant()) = bstrVal;
return pQualifier;
}
//*****************************************************************************
HRESULT CValueLocation::SetArrayElement(
MODIFY VARIANT& vArray,
int nIndex,
READ_ONLY VARIANT& vValue)
{
if(V_VT(&vArray) != (VT_ARRAY | VT_BSTR)) return WBEM_E_FAILED;
// if(V_VT(&vArray) != (VT_ARRAY | VT_VARIANT)) return WBEM_E_FAILED;
SAFEARRAY* pSafeArray = V_ARRAY(&vArray);
long lLowerBound;
if(FAILED(SafeArrayGetLBound(pSafeArray, 1, &lLowerBound)))
return WBEM_E_FAILED;
long lActualIndex = lLowerBound + nIndex;
// Set the value in the array
// ==========================
if(FAILED(SafeArrayPutElement(pSafeArray,
(long*)&lActualIndex,
(void*)vValue.bstrVal)))
{
return WBEM_E_FAILED;
}
return WBEM_NO_ERROR;
}
//*****************************************************************************
CPropertyLocation::CPropertyLocation(COPY LPCWSTR wszName, int nArrayIndex)
{
m_bOK = true;
m_wszName = Macro_CloneStr(wszName);
if(m_wszName == NULL && wszName != NULL)
m_bOK = false;
m_nArrayIndex = nArrayIndex;
}
CPropertyLocation::~CPropertyLocation()
{
if(m_wszName)
delete m_wszName;
}
HRESULT CPropertyLocation::Set(READ_ONLY VARIANT& varValue,
OLE_MODIFY IWbemClassObject* pObject)
{
if(m_nArrayIndex == -1)
{
// Not an array index. Simply set the property
// ===========================================
return pObject->Put(m_wszName, 0, &varValue, 0);
}
else
{
// Array index. Get the value
// ==========================
VARIANT vArray;
VariantInit(&vArray);
HRESULT hres = pObject->Get(m_wszName, 0, &vArray, NULL, NULL);
if(FAILED(hres)) return hres;
// Set the value
// =============
if(FAILED(SetArrayElement(vArray, m_nArrayIndex, varValue)))
return WBEM_E_FAILED;
// Store the whole array back into the property
// ============================================
hres = pObject->Put(m_wszName, 0, &vArray, 0);
VariantClear(&vArray);
return hres;
}
}
//*****************************************************************************
CQualifierLocation::CQualifierLocation(COPY LPCWSTR wszName,PDBG pDbg,
COPY LPCWSTR wszPropName,
int nArrayIndex)
{
m_bOK = true;
m_pDbg = pDbg;
if(wszName)
m_wszName = Macro_CloneStr(wszName);
else
m_wszName = NULL;
if(m_wszName == NULL && wszName != NULL)
m_bOK = false;
if(wszPropName != NULL)
m_wszPropName = Macro_CloneStr(wszPropName);
else
m_wszPropName = NULL;
if(m_wszPropName == NULL && wszPropName != NULL)
m_bOK = false;
m_nArrayIndex = nArrayIndex;
}
CQualifierLocation::~CQualifierLocation()
{
if(m_wszName)
delete m_wszName;
if(m_wszPropName)
delete m_wszPropName;
}
HRESULT CQualifierLocation::Set(READ_ONLY VARIANT& varValue,
OLE_MODIFY IWbemClassObject* pObject)
{
HRESULT hres;
long lOrigFlavor= 0;
if(pObject == NULL)
return WBEM_E_INVALID_PARAMETER;
// Get the qualifier set for either the property or the object
// ===========================================================
IWbemQualifierSet* pQualifierSet;
if(m_wszPropName == NULL)
{
hres = pObject->GetQualifierSet(&pQualifierSet);
}
else
{
hres = pObject->GetPropertyQualifierSet(m_wszPropName, &pQualifierSet);
}
if(FAILED(hres))
return hres;
// Get the qualifier value (need it for the type in either case)
// =============================================================
VARIANT vQualifierVal;
VariantInit(&vQualifierVal);
hres = pQualifierSet->Get(m_wszName, 0, &vQualifierVal, &lOrigFlavor);
if(FAILED(hres)) return hres;
// Check if array is involved
// ==========================
if(m_nArrayIndex == -1)
{
// Just set the qualifier value
// ============================
hres = pQualifierSet->Put(m_wszName, &varValue, lOrigFlavor);
}
else
{
// Set the appropriate array element
// =================================
if(FAILED(SetArrayElement(vQualifierVal, m_nArrayIndex, varValue)))
return WBEM_E_FAILED;
// Store the value back
// ====================
hres = pQualifierSet->Put(m_wszName, &vQualifierVal, lOrigFlavor);
if(FAILED(hres))
{
m_pDbg->hresError = FALSE;
return hres;
}
}
pQualifierSet->Release();
VariantClear(&vQualifierVal);
return hres;
}
//*****************************************************************************
CMObject::CAliasedValue::CAliasedValue(
ACQUIRE CValueLocation* _pLocation,
COPY LPCWSTR _wszAlias)
{
pLocation = _pLocation;
wszAlias = Macro_CloneStr(_wszAlias);
}
CMObject::CAliasedValue::~CAliasedValue()
{
delete pLocation;
delete [] wszAlias;
}
CMObject::CMObject()
{
m_wszAlias = NULL;
m_wszNamespace = NULL;
m_paQualifiers = NULL;
m_wszFullPath = NULL;
m_nFirstLine = 0;
m_nLastLine = 0;
m_lDefClassFlags = 0;
m_lDefInstanceFlags = 0;
m_bDone = FALSE;
m_pWbemObj = NULL;
m_bParameter = false;
m_bAmended = false;
m_wFileName = NULL;
m_bDeflated = false;
m_bOK = true;
}
HRESULT CMObject::Deflate(bool bDestruct)
{
if(!bDestruct && (m_wszAlias || GetNumAliasedValues() > 0))
{
return S_OK;
}
m_bDeflated = true;
if(m_paQualifiers)
{
for(int i = 0; i < m_paQualifiers->GetSize(); i++)
{
CMoQualifier * pQual = (CMoQualifier *) m_paQualifiers->GetAt(i);
delete pQual;
}
m_paQualifiers->RemoveAll();
}
for(int i = 0; i < m_aProperties.GetSize(); i++)
{
CMoProperty * pProp = (CMoProperty *) m_aProperties[i];
// If this is an parameter object (in argument or out arguement), dont delete any embedded
// objects since they will be delete as the CMethodParameter is cleaned out
if(m_bParameter)
{
VARIANT * pVar = pProp->GetpVar();
if(pVar->vt & VT_UNKNOWN)
pVar->vt = VT_I4;
}
delete pProp;
}
m_aProperties.RemoveAll();
return S_OK;
}
HRESULT CMObject::Reflate(CMofParser & Parser)
{
if(!m_bDeflated)
return S_OK;
if(IsInstance())
Parser.SetState(REFLATE_INST);
else
Parser.SetState(REFLATE_CLASS);
Parser.SetParserPosition(&m_QualState);
if (!Parser.qualifier_decl(*m_paQualifiers, true, CLASSINST_SCOPE))
return WBEM_E_FAILED;
Parser.SetParserPosition(&m_DataState);
if(IsInstance())
{
Parser.NextToken();
Parser.prop_init_list(this);
}
else
{
Parser.NextToken();
Parser.property_decl_list(this);
}
m_bDeflated = false;
return S_OK;
}
CMObject::~CMObject()
{
if(m_wszAlias)
delete [] m_wszAlias;
if(m_wszNamespace)
delete [] m_wszNamespace;
if(m_wszFullPath)
delete [] m_wszFullPath;
if(m_pWbemObj)
m_pWbemObj->Release();
Deflate(true);
if(m_paQualifiers)
delete m_paQualifiers;
int i;
for(i = 0; i < m_aAliased.GetSize(); i++)
{
delete (CAliasedValue*)m_aAliased[i];
}
delete [] m_wFileName;
}
void CMObject::FreeWbemObjectIfPossible()
{
if(m_wszAlias == NULL && m_pWbemObj)
{
m_pWbemObj->Release();
m_pWbemObj = NULL;
}
}
HRESULT CMObject::SetAlias(COPY LPCWSTR wszAlias)
{
delete [] m_wszAlias;
m_wszAlias = Macro_CloneStr(wszAlias);
if(m_wszAlias == NULL && wszAlias != NULL)
return WBEM_E_OUT_OF_MEMORY;
else
return S_OK;
}
HRESULT CMObject::SetNamespace(COPY LPCWSTR wszNamespace)
{
delete [] m_wszNamespace;
m_wszNamespace = Macro_CloneStr(wszNamespace);
if(m_wszNamespace == NULL && wszNamespace != NULL)
return WBEM_E_OUT_OF_MEMORY;
else
return S_OK;
}
HRESULT CMObject::SetLineRange(int nFirstLine, int nLastLine, WCHAR * pFileName)
{
m_nFirstLine = nFirstLine;
m_nLastLine = nLastLine;
m_wFileName = Macro_CloneStr(pFileName);
if(m_wFileName == NULL && pFileName != NULL)
return WBEM_E_OUT_OF_MEMORY;
else
return S_OK;
}
void CMObject::SetQualifiers(ACQUIRE CMoQualifierArray* pQualifiers)
{
delete m_paQualifiers;
m_paQualifiers = pQualifiers;
pQualifiers->RegisterAliases(this, NULL);
}
BOOL CMObject::AddProperty(ACQUIRE CMoProperty* pProperty)
{
// Check if the property has already been specified
// ================================================
for(int i = 0; i < m_aProperties.GetSize(); i++)
{
CMoProperty* pCurrentProp = (CMoProperty*)m_aProperties[i];
if(!wbem_wcsicmp(pCurrentProp->GetName(), pProperty->GetName()))
{
return FALSE;
}
}
m_aProperties.Add(pProperty);
pProperty->RegisterAliases(this);
return TRUE;
}
BOOL CMObject::GetAliasedValue(IN int nIndex,
OUT INTERNAL LPWSTR& wszAlias)
{
if(nIndex >= m_aAliased.GetSize())
{
return FALSE;
}
CAliasedValue* pValue = (CAliasedValue*)m_aAliased[nIndex];
wszAlias = pValue->wszAlias;
return TRUE;
}
BOOL CMObject::ResolveAliasedValue(IN int nIndex,
READ_ONLY LPCWSTR wszPath,
OLE_MODIFY IWbemClassObject* pObject)
{
CAliasedValue* pValue = (CAliasedValue*)m_aAliased[nIndex];
// Construct the variant with the value
// ====================================
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = SysAllocString(wszPath);
if(v.bstrVal == NULL)
{
return FALSE;
}
// Tell the value locator to set it
// ================================
BOOL bRes = SUCCEEDED(pValue->pLocation->Set(v, pObject));
VariantClear(&v);
return bRes;
}
HRESULT CMObject::AddAliasedValue(ACQUIRE CValueLocation* pLocation,
COPY LPCWSTR wszAlias)
{
if(pLocation)
{
std::auto_ptr<CAliasedValue> pValue(new CAliasedValue(pLocation, wszAlias));
if(pValue.get() == NULL)
{
delete pLocation;
return WBEM_E_OUT_OF_MEMORY;
}
if(pValue->wszAlias == NULL && wszAlias != NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
m_aAliased.Add(pValue.get());
pValue.release();
}
return S_OK;
}
CMoProperty* CMObject::GetPropertyByName(WCHAR * pwcName)
{
for(int iCnt = 0; iCnt < m_aProperties.GetSize(); iCnt++)
{
CMoProperty* pProp = (CMoProperty*)m_aProperties[iCnt];
if(pProp && pProp->GetName())
if(!wbem_wcsicmp(pwcName, pProp->GetName()))
return pProp;
}
return NULL;
}
BOOL CMObject::ApplyToWbemObject(OLE_MODIFY IWbemClassObject* pObject, IWbemServices* pNamespace,
BOOL bClass, IWbemContext * pCtx)
{
if(GetQualifiers() && !GetQualifiers()->AddToObject(pObject, bClass)) return FALSE;
for(int i = 0; i < GetNumProperties(); i++)
{
if(!GetProperty(i)->AddToObject(pObject, pNamespace, bClass, pCtx)) return FALSE;
}
// Construct the path for future reference
// =======================================
VARIANT v;
VariantInit(&v);
SCODE sc = pObject->Get(L"__RELPATH", 0, &v, NULL, NULL);
if(sc != S_OK || V_VT(&v) != VT_BSTR)
{
// This is probably an embedded object. If not, we will fail shortly
// anyway. For now, just set the path to NULL and continue. // a-levn
delete [] m_wszFullPath;
m_wszFullPath = NULL;
return TRUE;
}
SetFullPath(v.bstrVal);
VariantClear(&v);
return TRUE;
}
void CMObject::SetFullPath(BSTR bstr)
{
if(bstr == NULL)
return;
if(m_wszFullPath)
delete [] m_wszFullPath;
int iLen = 20 + wcslen(bstr);
if(m_wszNamespace)
iLen += wcslen(m_wszNamespace);
m_wszFullPath = new WCHAR[iLen];
if(m_wszFullPath == NULL)
return;
// note that if m_wszNamespace is fully qualified, there is no need to
// prepend the slashes
if(m_wszNamespace && m_wszNamespace[0] == L'\\' && m_wszNamespace[1] == L'\\')
StringCchPrintfW (m_wszFullPath, iLen, L"%s:%s", m_wszNamespace, bstr);
else
StringCchPrintfW (m_wszFullPath, iLen, L"\\\\.\\%s:%s", m_wszNamespace, bstr);
}
int CMObject::GetNumAliasedValues()
{
int iRet = m_aAliased.GetSize();
// Also check the number of aliases in any embedded objects.
int iCnt;
for(iCnt = 0; iCnt < GetNumProperties(); iCnt++)
{
CMoProperty* pProp = GetProperty(iCnt);
if(pProp == NULL)
break;
if(!pProp->IsValueProperty())
{
// Method properties actually contain one or two embedded instances for holding the
// arguments. Use those for the method case.
CMethodProperty * pMeth = (CMethodProperty *)pProp;
CMoInstance * pArgListObj = pMeth->GetInObj();
if(pArgListObj)
iRet += pArgListObj->GetNumAliasedValues();
pArgListObj = pMeth->GetOutObj();
if(pArgListObj)
iRet += pArgListObj->GetNumAliasedValues();
continue;
}
CMoValue& value = pProp->AccessValue();
VARIANT & var = value.AccessVariant();
if(var.vt == VT_EMBEDDED_OBJECT)
{
CMObject * pTemp = (CMObject *)var.punkVal;
if(pTemp)
iRet += pTemp->GetNumAliasedValues();
}
else if(var.vt == (VT_EMBEDDED_OBJECT | VT_ARRAY))
{
long lLBound, lUBound;
SafeArrayGetLBound(var.parray, 1, &lLBound);
SafeArrayGetUBound(var.parray, 1, &lUBound);
// Check the individual embedded objects.
// ======================================
for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
{
CMObject * pTemp;
SCODE hres = SafeArrayGetElement(var.parray, &lIndex, &pTemp);
if(FAILED(hres) || pTemp == FALSE)
return iRet;
iRet += pTemp->GetNumAliasedValues();
}
}
}
return iRet;
}
HRESULT CMObject::ResolveAliasesInWbemObject(
OLE_MODIFY IWbemClassObject* pObject,
READ_ONLY CMofAliasCollection* pCollection)
{
int i;
SCODE sc;
// Resolve them all using the collection
// =====================================
for(i = 0; i < m_aAliased.GetSize(); i++)
{
LPWSTR wszAlias;
GetAliasedValue(i, wszAlias);
LPCWSTR wszPathToAliasee = pCollection->FindAliasee(wszAlias);
if(wszPathToAliasee == NULL) return WBEM_E_FAILED;
if(!ResolveAliasedValue(i, wszPathToAliasee, pObject))
{
return WBEM_E_FAILED;
}
}
// Also resolve any embedded objects
int iCnt;
for(iCnt = 0; iCnt < GetNumProperties(); iCnt++)
{
CMoProperty* pProp = GetProperty(iCnt);
if(pProp == NULL)
break;
CMoValue& value = pProp->AccessValue();
VARIANT & var = value.AccessVariant();
if(!pProp->IsValueProperty())
{
// Methods contain possibly and input and an output object for storing the arguments.
// These objects could contain aliases.
BOOL bChanged = FALSE;
CMethodProperty * pMeth = (CMethodProperty *)pProp;
CMoInstance * pArgListObj = pMeth->GetInObj();
BSTR bstr = SysAllocString(pProp->GetName());
if(!bstr)
return WBEM_E_FAILED;
IWbemClassObject *pIn = NULL;
IWbemClassObject *pOut = NULL;
sc = pObject->GetMethod(bstr, 0, &pIn, &pOut);
if(pArgListObj && pArgListObj->GetNumAliasedValues() && pIn)
{
sc = pArgListObj->ResolveAliasesInWbemObject((IWbemClassObject *)pIn,pCollection);
if(sc == S_OK)
bChanged = TRUE;
}
pArgListObj = pMeth->GetOutObj();
if(pArgListObj && pArgListObj->GetNumAliasedValues() && pOut)
{
sc = pArgListObj->ResolveAliasesInWbemObject((IWbemClassObject *)pOut,pCollection);
if(sc == S_OK)
bChanged = TRUE;
}
if(bChanged)
sc = pObject->PutMethod(bstr, 0, pIn, pOut);
if(bstr)
SysFreeString(bstr);
if(pIn)
pIn->Release();
if(pOut)
pOut->Release();
continue;
}
else if(var.vt == VT_EMBEDDED_OBJECT)
{
CMObject * pTemp = (CMObject *)var.punkVal;
if(pTemp)
{
VARIANT varDB;
VariantInit(&varDB);
BSTR bstr = SysAllocString(pProp->GetName());
if(bstr)
{
sc = pObject->Get(bstr, 0, &varDB, NULL, NULL);
if(sc == S_OK)
{
IWbemClassObject * pClass = (IWbemClassObject *)varDB.punkVal;
sc = pTemp->ResolveAliasesInWbemObject((IWbemClassObject *)varDB.punkVal,pCollection);
if(S_OK == sc)
pObject->Put(bstr, 0, &varDB, 0);
else
return WBEM_E_FAILED;
pClass->Release();
}
SysFreeString(bstr);
}
else
return WBEM_E_OUT_OF_MEMORY;
}
}
else if(var.vt == (VT_EMBEDDED_OBJECT | VT_ARRAY))
{
BSTR bstr = SysAllocString(pProp->GetName());
if(bstr)
{
VARIANT varDB;
VariantInit(&varDB);
sc = pObject->Get(bstr, 0, &varDB, NULL, NULL);
if(sc == S_OK)
{
long lLBound, lUBound;
SafeArrayGetLBound(var.parray, 1, &lLBound);
SafeArrayGetUBound(var.parray, 1, &lUBound);
// Check the individual embedded objects.
// ======================================
for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
{
CMObject * pTemp;
sc = SafeArrayGetElement(var.parray, &lIndex, &pTemp);
IWbemClassObject * pWBEMInst = NULL;
sc |= SafeArrayGetElement(varDB.parray, &lIndex, &pWBEMInst);
if(sc == S_OK && pTemp && pWBEMInst)
{
if(pTemp->m_aAliased.GetSize() > 0)
{
sc = pTemp->ResolveAliasesInWbemObject(pWBEMInst,pCollection);
if(sc != S_OK)
return WBEM_E_FAILED;
}
}
if(pWBEMInst)
pWBEMInst->Release();
}
sc = pObject->Put(bstr, 0, &varDB, 0);
SafeArrayDestroyData(varDB.parray);
SafeArrayDestroyDescriptor(varDB.parray);
}
SysFreeString(bstr);
}
else
return WBEM_E_OUT_OF_MEMORY;
}
}
return WBEM_NO_ERROR;
}
//*****************************************************************************
CMoClass::CMoClass(COPY LPCWSTR wszParentName, COPY LPCWSTR wszClassName, PDBG pDbg,
BOOL bUpdateOnly)
{
m_pDbg = pDbg;
m_wszParentName = Macro_CloneStr(wszParentName);
if(m_wszParentName == NULL && wszParentName != NULL)
m_bOK = false;
m_wszClassName = Macro_CloneStr(wszClassName);
if(m_wszClassName == NULL && wszClassName != NULL)
m_bOK = false;
m_bUpdateOnly = bUpdateOnly;
}
CMoClass::~CMoClass()
{
delete [] m_wszParentName;
delete [] m_wszClassName;
}
HRESULT CMoClass::CreateWbemObject(READ_ONLY IWbemServices* pNamespace,
RELEASE_ME IWbemClassObject** ppObject, IWbemContext * pCtx)
{
// Take care of update only case. In this case, the object is
// not created, on retrieved for the later put!
if(m_bUpdateOnly)
{
return pNamespace->GetObject(m_wszClassName, 0, pCtx, ppObject, NULL);
}
// Get the parent class from WINMGMT
// ==============================
BSTR strParentName = NULL;
if(m_wszParentName)
{
strParentName = SysAllocString(m_wszParentName);
if(strParentName == NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
m_pDbg->SetString(strParentName);
}
IWbemClassObject* pParentClass = NULL;
HRESULT hres = pNamespace->GetObject(strParentName, 0, pCtx, &pParentClass, NULL);
if(strParentName)
SysFreeString(strParentName);
if(FAILED(hres)) return hres;
if(m_wszParentName && wcslen(m_wszParentName))
{
// Create a child
// ==============
hres = pParentClass->SpawnDerivedClass(0, ppObject);
pParentClass->Release();
if(FAILED(hres)) return hres;
}
else
{
// Copy the dummy over
// ===================
*ppObject = pParentClass;
}
VARIANT v;
VariantInit(&v);
// Set the class name
// ==================
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = SysAllocString(m_wszClassName);
if(v.bstrVal == NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
(*ppObject)->Put(L"__CLASS", 0, &v, 0);
VariantClear(&v);
return hres;
}
HRESULT CMoClass::StoreWbemObject(READ_ONLY IWbemClassObject* pObject,
long lClassFlags, long lInstanceFlags,
OLE_MODIFY IWbemServices* pNamespace, IWbemContext * pCtx,
WCHAR * pUserName, WCHAR * pPassword, WCHAR * pAuthority)
{
return pNamespace->PutClass(pObject, lClassFlags, pCtx, NULL);
}
//*****************************************************************************
CMoInstance::CMoInstance(COPY LPCWSTR wszClassName, PDBG pDbg, bool bParameter)
{
m_pDbg = pDbg;
m_wszClassName = Macro_CloneStr(wszClassName);
if(m_wszClassName == NULL && wszClassName != NULL)
m_bOK = false;
m_bParameter = bParameter;
}
CMoInstance::~CMoInstance()
{
delete [] m_wszClassName;
}
// *****************************************************************************
// Used to determine if this object is the input arguement list of a method.
// That can be determined by checking if any of the properties have a "IN" qualifier
// *****************************************************************************
BOOL CMoInstance::IsInput()
{
for(int iCnt = 0; iCnt < GetNumProperties(); iCnt++)
{
CMoProperty* pProp = GetProperty(iCnt);
CMoQualifierArray* pQual = pProp->GetQualifiers();
if(pQual->Find(L"IN"))
return TRUE;
}
return FALSE;
}
HRESULT CMoInstance::CreateWbemObject(READ_ONLY IWbemServices* pNamespace,
RELEASE_ME IWbemClassObject** ppObject, IWbemContext * pCtx)
{
// Get the class from WINMGMT
// =======================
IWbemClassObject* pClass = NULL;
BSTR strClassName = SysAllocString(m_wszClassName);
if(strClassName == NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
m_pDbg->SetString(strClassName);
HRESULT hres = pNamespace->GetObject(strClassName, 0, pCtx, &pClass, NULL);
SysFreeString(strClassName);
if(FAILED(hres)) return hres;
// Spawn a new instance
// ====================
hres = pClass->SpawnInstance(0, ppObject);
pClass->Release();
return hres;
}
HRESULT CMoInstance::StoreWbemObject(READ_ONLY IWbemClassObject* pObject,
long lClassFlags, long lInstanceFlags,
OLE_MODIFY IWbemServices* pNamespace, IWbemContext * pCtx,
WCHAR * pUserName, WCHAR * pPassword, WCHAR * pAuthority)
{
IWbemCallResult *pCallResult = NULL;
SCODE scRet = pNamespace->PutInstance(pObject, lInstanceFlags, pCtx,
(m_wszAlias) ? &pCallResult : NULL);
if(scRet == S_OK && pCallResult)
{
BSTR bstr = NULL;
DWORD dwAuthLevel, dwImpLevel;
SCODE sc = GetAuthImp( pNamespace, &dwAuthLevel, &dwImpLevel);
if(sc == S_OK)
if(dwAuthLevel != RPC_C_AUTHN_LEVEL_NONE)
sc = MofdSetInterfaceSecurity(
pCallResult,
pAuthority,
(pUserName && wcslen(pUserName) > 0) ? pUserName : NULL ,
pPassword);
else
sc = WbemSetProxyBlanket(pCallResult, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE,NULL, 0);
scRet = pCallResult->GetResultString(9999, &bstr);
if(sc == S_OK && scRet == S_OK && bstr)
{
SetFullPath(bstr);
SysFreeString(bstr);
}
pCallResult->Release();
}
return scRet;
}
CMethodProperty::CMethodProperty(CMoQualifierArray * paQualifiers, PDBG pDbg, BOOL bBinary)
:CMoProperty(paQualifiers, pDbg)
{
m_pDbg = pDbg;
m_pInObj = NULL;
m_pOutObj = NULL;
m_IDType = UNSPECIFIED; // Gets set on first argument
m_NextAutoID = 0;
m_bBinaryMof = bBinary;
}
CValueProperty::CValueProperty(CMoQualifierArray * paQualifiers, PDBG pDbg)
:CMoProperty(paQualifiers, pDbg)
{
m_pDbg = pDbg;
m_bIsArg = FALSE;
}
CMethodProperty::~CMethodProperty()
{
VARIANT & var = m_Value.AccessVariant();
var.vt = VT_EMPTY;
if(m_pInObj != NULL)
delete m_pInObj;
if(m_pOutObj != NULL)
delete m_pOutObj;
for(int i = 0; i < m_Args.GetSize(); i++)
{
CValueProperty * pProp = (CValueProperty *)m_Args[i];
CMoProperty * pProp2 = (CMoProperty *)m_Args[i];
delete (CValueProperty *)m_Args[i];
}
m_Args.RemoveAll();
}
BOOL CMethodProperty::AddToObject(OLE_MODIFY IWbemClassObject* pObject, IWbemServices* pNamespace, BOOL bClass, IWbemContext * pCtx)
{
IWbemClassObject * pIn = NULL;
IWbemClassObject * pOut = NULL;
if(m_pInObj)
{
pIn = GetInstPtr(L"__PARAMETERS", pNamespace, m_pInObj, pCtx);
if(pIn == NULL)
return FALSE;
}
if(m_pOutObj)
{
pOut = GetInstPtr(L"__PARAMETERS", pNamespace, m_pOutObj, pCtx);
if(pOut == NULL)
return FALSE;
}
SCODE sc = pObject->PutMethod(GetName(), 0, pIn, pOut);
if(pIn)
pIn->Release();
if(pOut)
pOut->Release();
if(FAILED(sc))
{
m_pDbg->hresError = sc;
return FALSE;
}
if(!GetQualifiers()->AddToPropOrMeth(pObject, m_wszName, bClass, FALSE))
{
return FALSE;
}
return sc == S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////////
//
// Creates a new qualifier set which is a copy of the source.
//
/////////////////////////////////////////////////////////////////////////////////////////////
CMoQualifierArray * CreateArgQualifierList(BOOL bInput, CMoQualifierArray *pSrcQualifiers, PDBG pDbg)
{
if(pSrcQualifiers == NULL)
return NULL;
std::auto_ptr<CMoQualifierArray> pRet (new CMoQualifierArray (pDbg));
if (pRet.get() == NULL)
return NULL;
for(int iCnt = 0; iCnt < pSrcQualifiers->GetSize(); iCnt++)
{
CMoQualifier* pSrc = pSrcQualifiers->GetAt(iCnt);
if(pSrc == NULL)
continue;
// If this is for input, dont copy out qualifiers, and vice versa!
if(bInput && !wbem_wcsicmp(pSrc->GetName(), L"OUT"))
continue;
if(!bInput && !wbem_wcsicmp(pSrc->GetName(), L"IN"))
continue;
// Create the new qualifier, copy the values from the existing one
std::auto_ptr<CMoQualifier> pQual (new CMoQualifier(pDbg));
if(pQual.get() == NULL)
return NULL;
// if(pSrc->IsRestricted())
// pQual->SetRestricted();
pQual->SetFlavor(pSrc->GetFlavor());
// if(pSrc->IsOverrideSet())
// pQual->OverrideSet();
if(FAILED(pQual->SetQualName(pSrc->GetName())))
return NULL;
pQual->SetType(pSrc->GetType());
VARIANT * pSrcVar = pSrc->GetpVar();
HRESULT hr = WbemVariantChangeType(pQual->GetpVar(), pSrcVar, pSrcVar->vt);
if (SUCCEEDED (hr))
{
// Add the new qualifier to the new set
pRet->Add (pQual.release());
}
else
{
return NULL;
}
}
return pRet.release();
}
bool CMethodProperty::IsIDSpecified(CMoQualifierArray * paQualifiers)
{
int iSize = paQualifiers->GetSize();
for(int iCnt = 0; iCnt < iSize; iCnt++)
{
CMoQualifier* pTest = paQualifiers->GetAt(iCnt);
if(pTest == NULL || wbem_wcsicmp(pTest->GetName(), L"ID"))
continue;
VARIANT * pVar = pTest->GetpVar();
if(pVar->vt != VT_I4)
m_IDType = INVALID;
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////
//
// This takes a method argument and adds it to either the input or output arguement object
//
/////////////////////////////////////////////////////////////////////////////////////////////
BOOL CMethodProperty::AddIt(WString & sName, CMoType & Type, BOOL bInput,
CMoQualifierArray * paQualifiers, VARIANT * pVar,
CMoValue & Value, BOOL bRetValue, BOOL bSecondPass)
{
HRESULT hr;
// Except for the return value, all parameters must have an ID. We support both the automatic
// generation of IDs, as well as allowing the explicit settings of IDs. However, doing both
// in a method is not allowed
if(!bRetValue && !bSecondPass)
{
// Better have a qual set!
if(paQualifiers == NULL)
return FALSE;
if(IsIDSpecified(paQualifiers)) // find it was explicitly set
{
// Explicity set. Just pass it along to fastprox as is. Note that if we
if(m_IDType == AUTOMATIC || m_IDType == INVALID)
return FALSE;
m_IDType = MANUAL;
}
else
{
// The IDs must be set automatically
if(m_IDType == MANUAL || m_IDType == INVALID)
return FALSE;
m_IDType = AUTOMATIC;
// Add a new qualifier to this
CMoQualifier * pNew = new CMoQualifier(m_pDbg);
if(pNew == NULL)
return FALSE;
if(FAILED(pNew->SetQualName(L"ID")))
{
delete pNew;
return FALSE;
}
pNew->SetFlavor(WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE |
WBEM_FLAVOR_NOT_OVERRIDABLE);
VARIANT * pVar2 = pNew->GetpVar();
pVar2->vt = VT_I4;
pVar2->lVal = m_NextAutoID++;
paQualifiers->Add(pNew);
}
}
// Get a pointer to either the input or output object. In either case, the object
// will need to be created if this is the first property being added to it.
CMoInstance * pObj = NULL;
if(bInput)
{
if(m_pInObj == NULL)
{
m_pInObj = new CMoInstance(L"__PARAMETERS", m_pDbg, true);
if(m_pInObj == NULL)
return FALSE;
if(m_pInObj->IsOK() == false)
{
delete m_pInObj;
return FALSE;
}
}
pObj = m_pInObj;
}
else
{
if(m_pOutObj == NULL)
{
m_pOutObj = new CMoInstance(L"__PARAMETERS", m_pDbg ,true);
if(m_pOutObj == NULL)
return FALSE;
if(m_pOutObj->IsOK() == false)
{
delete m_pOutObj;
return FALSE;
}
}
pObj = m_pOutObj;
}
if(pObj == NULL)
return FALSE;
// If the property doesnt have a qualifier set, as would be the case for the retvalue,
// create one
CMoQualifierArray * pQualifiers = NULL;
if(paQualifiers == NULL)
pQualifiers = new CMoQualifierArray(m_pDbg);
else
pQualifiers = CreateArgQualifierList(bInput, paQualifiers, m_pDbg);
if(pQualifiers == NULL)
return FALSE;
// Create a new value property
CValueProperty * pNewProp = new CValueProperty(pQualifiers, m_pDbg);
if(pNewProp == NULL){
delete pQualifiers;
return FALSE;
}
VARTYPE vt = Type.GetCIMType();
if(FAILED(pNewProp->SetPropName(sName)))
{
delete pNewProp;
return FALSE;
}
pNewProp->SetAsArg();
Type.StoreIntoQualifiers(pQualifiers);
VARIANT * pDest;
pDest = pNewProp->GetpVar();
if(pVar && pVar->vt != VT_EMPTY && pVar->vt != VT_NULL)
{
VARTYPE vtSimple = pVar->vt & ~VT_ARRAY;
if(vtSimple != VT_EMBEDDED_OBJECT || pVar->vt == (VT_EMBEDDED_OBJECT | VT_ARRAY))
{
hr = VariantCopy(pDest, pVar);
if(FAILED(hr))
return FALSE;
}
else
{
pDest->vt = VT_EMBEDDED_OBJECT;
pDest->punkVal = pVar->punkVal;
}
}
pNewProp->SetType(vt);
// If the original value contains some aliases, make sure they get added
CMoValue & Dest = pNewProp->AccessValue();
for(int i = 0; i < Value.GetNumAliases(); i++)
{
LPWSTR wszAlias;
int nArrayIndex;
if(Value.GetAlias(i, wszAlias, nArrayIndex))
{
hr = Dest.AddAlias(wszAlias, nArrayIndex);
if(FAILED(hr))
return FALSE;
}
}
pObj->AddProperty(pNewProp);
return TRUE;
}
BOOL CMethodProperty::AddToArgObjects(CMoQualifierArray * paQualifiers, WString & sName,
CMoType & Type, BOOL bRetValue, int & ErrCtx, VARIANT * pVar,
CMoValue & Value)
{
// if return value and it is null or void, just bail out
if(Type.IsDefined() == FALSE && bRetValue)
return TRUE;
// Determine which arg list this goes into
BOOL bGoesIntoInputs = FALSE;
BOOL bGoesIntoOutputs = FALSE;
if( bRetValue)
bGoesIntoOutputs = TRUE;
else
{
// Loop through the arg list.
if(paQualifiers == NULL)
return FALSE;
if(paQualifiers->Find(L"IN"))
bGoesIntoInputs = TRUE;
if(paQualifiers->Find(L"OUT"))
bGoesIntoOutputs = TRUE;
}
// make sure it isnt already on the list
if(bGoesIntoInputs && m_pInObj && m_pInObj->GetPropertyByName(sName))
return FALSE;
if(bGoesIntoOutputs && m_pOutObj && m_pOutObj->GetPropertyByName(sName))
return FALSE;
if(bGoesIntoInputs == FALSE && bGoesIntoOutputs == FALSE)
{
ErrCtx = WBEMMOF_E_MUST_BE_IN_OR_OUT;
return FALSE;
}
// Create the object(s) if necessary
if(bGoesIntoInputs)
if(!AddIt(sName, Type, TRUE, paQualifiers, pVar, Value, bRetValue, FALSE))
return FALSE;
if(bGoesIntoOutputs)
return AddIt(sName, Type, FALSE, paQualifiers, pVar, Value, bRetValue, bGoesIntoInputs);
else
return TRUE;
}
CMoActionPragma::CMoActionPragma(COPY LPCWSTR wszClassName, PDBG pDbg, bool bFail, BOOL bClass)
{
m_pDbg = pDbg;
m_wszClassName = Macro_CloneStr(wszClassName);
if(m_wszClassName == NULL && wszClassName != NULL)
m_bOK = false;
m_bFail = bFail;
m_bClass = bClass;
}
CMoActionPragma::~CMoActionPragma()
{
delete [] m_wszClassName;
}
HRESULT CMoActionPragma::StoreWbemObject(READ_ONLY IWbemClassObject* pObject,
long lClassFlags, long lInstanceFlags,
OLE_MODIFY IWbemServices* pNamespace, IWbemContext * pCtx,
WCHAR * pUserName, WCHAR * pPassword, WCHAR * pAuthority)
{
if(m_wszClassName == NULL || wcslen(m_wszClassName) < 1)
return WBEM_E_FAILED;
BSTR bstr = SysAllocString(m_wszClassName);
if(bstr)
{
SCODE sc;
if(m_bClass)
sc = pNamespace->DeleteClass(bstr, 0, NULL, NULL);
else
sc = pNamespace->DeleteInstance(bstr, 0, NULL, NULL);
SysFreeString(bstr);
if(!m_bFail)
return S_OK;
else
{
if(FAILED(sc))
wcsncpy(m_pDbg->m_wcError, m_wszClassName, 99);
return sc;
}
}
else
return WBEM_E_OUT_OF_MEMORY;
}