|
|
/*++
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; }
|