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
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;
|
|
}
|