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

2335 lines
64 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. MOFPROP.CPP
  5. Abstract:
  6. History:
  7. --*/
  8. #include "precomp.h"
  9. #include <wbemidl.h>
  10. //#include "corepol.h"
  11. #include "wstring.h"
  12. #include "mofout.h"
  13. #include "mofprop.h"
  14. #include "typehelp.h"
  15. #include "trace.h"
  16. #include "strings.h"
  17. #include "cwbemtime.h"
  18. #include <genutils.h>
  19. #include <wbemutil.h>
  20. #include <cominit.h>
  21. #include <arrtempl.h>
  22. #include "moflex.h"
  23. #include "mofparse.h"
  24. #include <memory>
  25. HRESULT MofdSetInterfaceSecurity(IUnknown * pInterface, LPWSTR pAuthority,
  26. LPWSTR pUser, LPWSTR pPassword);
  27. BOOL BinaryToInt(wchar_t * pConvert, __int64& i64Res);
  28. void assign(WCHAR * &pTo, LPCWSTR pFrom)
  29. {
  30. if(pTo)
  31. {
  32. delete pTo;
  33. pTo = NULL;
  34. }
  35. if(pFrom)
  36. {
  37. DWORD dwLen = wcslen(pFrom)+1;
  38. pTo = new WCHAR[dwLen];
  39. if(pTo)
  40. StringCchCopyW(pTo, dwLen, pFrom);
  41. }
  42. }
  43. BOOL ConvertAndTry(WCHAR * pFormat, WCHAR *pData, WCHAR *pCheck, unsigned __int64 & ui8)
  44. {
  45. static WCHAR wTemp[100];
  46. if(swscanf(pData, pFormat, &ui8) != 1)
  47. return FALSE;
  48. StringCchPrintfW(wTemp, 100, pFormat, ui8);
  49. return !wbem_wcsicmp(wTemp, pCheck);
  50. }
  51. CMoValue::CAlias::CAlias(COPY LPCWSTR wszAlias, int nArrayIndex)
  52. {
  53. m_nArrayIndex = nArrayIndex;
  54. m_wszAlias = Macro_CloneStr(wszAlias);
  55. }
  56. CMoValue::CAlias::~CAlias()
  57. {
  58. delete [] m_wszAlias;
  59. }
  60. CMoValue::CMoValue(PDBG pDbg)
  61. {
  62. m_pDbg = pDbg;
  63. m_vType = 0;
  64. VariantInit(&m_varValue);
  65. }
  66. CMoValue::~CMoValue()
  67. {
  68. if(m_varValue.vt == VT_EMBEDDED_OBJECT)
  69. {
  70. #ifdef _WIN64
  71. CMObject * pObj = (CMObject *)m_varValue.llVal;
  72. #else
  73. CMObject * pObj = (CMObject *)m_varValue.lVal;
  74. #endif
  75. if(pObj)
  76. delete pObj;
  77. m_varValue.vt = VT_NULL;
  78. }
  79. else if(m_varValue.vt == (VT_EMBEDDED_OBJECT | VT_ARRAY))
  80. {
  81. SCODE sc ;
  82. SAFEARRAY * psaSrc = m_varValue.parray;
  83. if(psaSrc == NULL)
  84. return;
  85. long lLBound, lUBound;
  86. sc = SafeArrayGetLBound(psaSrc, 1, &lLBound);
  87. sc |= SafeArrayGetUBound(psaSrc, 1, &lUBound);
  88. if(sc != S_OK)
  89. return;
  90. for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
  91. {
  92. // Load the initial data element into a VARIANT
  93. // ============================================
  94. CMObject * pObj;
  95. sc = SafeArrayGetElement(psaSrc, &lIndex, &pObj);
  96. if(sc == S_OK && pObj)
  97. delete pObj;
  98. }
  99. SafeArrayDestroy(psaSrc);
  100. m_varValue.vt = VT_NULL;
  101. }
  102. if((m_varValue.vt & ~ VT_ARRAY) != VT_EMBEDDED_OBJECT)
  103. VariantClear(&m_varValue);
  104. for(int i = 0; i < m_aAliases.GetSize(); i++)
  105. {
  106. delete (CAlias*)m_aAliases[i];
  107. }
  108. }
  109. BOOL CMoValue::GetAlias(IN int nAliasIndex,
  110. OUT INTERNAL LPWSTR& wszAlias,
  111. OUT int& nArrayIndex)
  112. {
  113. if(nAliasIndex >= m_aAliases.GetSize()) return FALSE;
  114. CAlias* pAlias = (CAlias*)m_aAliases[nAliasIndex];
  115. wszAlias = pAlias->m_wszAlias;
  116. nArrayIndex = pAlias->m_nArrayIndex;
  117. return TRUE;
  118. }
  119. HRESULT CMoValue::AddAlias(COPY LPCWSTR wszAlias, int nArrayIndex)
  120. {
  121. std::auto_ptr<CAlias> pAlias(new CAlias(wszAlias, nArrayIndex));
  122. if(pAlias.get() == NULL)
  123. return WBEM_E_OUT_OF_MEMORY;
  124. if(pAlias->m_wszAlias == NULL && wszAlias != NULL)
  125. {
  126. return WBEM_E_OUT_OF_MEMORY;
  127. }
  128. m_aAliases.Add(pAlias.get());
  129. pAlias.release();
  130. return S_OK;
  131. }
  132. //*****************************************************************************
  133. CMoProperty::CMoProperty(CMoQualifierArray * paQualifiers, PDBG pDbg) : m_Value(pDbg)
  134. {
  135. m_pDbg = pDbg;
  136. m_wszName = NULL;
  137. m_wszTypeTitle = NULL;
  138. m_paQualifiers = paQualifiers;
  139. }
  140. HRESULT CMoProperty::SetPropName(COPY LPCWSTR wszName)
  141. {
  142. delete [] m_wszName;
  143. m_wszName = Macro_CloneStr(wszName);
  144. if(m_wszName == NULL && wszName != NULL )
  145. return WBEM_E_OUT_OF_MEMORY;
  146. else
  147. return S_OK;
  148. }
  149. HRESULT CMoProperty::SetTypeTitle(COPY LPCWSTR wszName)
  150. {
  151. delete [] m_wszTypeTitle;
  152. m_wszTypeTitle = Macro_CloneStr(wszName);
  153. if(m_wszTypeTitle == NULL && wszName != NULL)
  154. return WBEM_E_OUT_OF_MEMORY;
  155. else
  156. return S_OK;
  157. }
  158. void CMoProperty::SetQualifiers(ACQUIRE CMoQualifierArray* pQualifiers)
  159. {
  160. delete m_paQualifiers;
  161. m_paQualifiers = pQualifiers;
  162. }
  163. IWbemClassObject * CMoProperty::GetInstPtr(const WCHAR * pClassName, IWbemServices* pNamespace, CMObject * pMo,
  164. IWbemContext * pCtx)
  165. {
  166. IWbemClassObject *pInst = NULL;
  167. SCODE sc;
  168. BSTR bstr = SysAllocString(pClassName);
  169. if(bstr == NULL)
  170. return NULL;
  171. CSysFreeMe fm(bstr);
  172. if(!wbem_wcsicmp(L"__PARAMETERS", pClassName))
  173. {
  174. sc = pNamespace->GetObject(bstr, 0, pCtx, &pInst, NULL);
  175. }
  176. else if(pMo->IsInstance())
  177. {
  178. IWbemClassObject *pClass = NULL;
  179. sc = pNamespace->GetObject(bstr, 0, pCtx, &pClass, NULL);
  180. if(sc != S_OK)
  181. return NULL;
  182. sc = pClass->SpawnInstance(0, &pInst);
  183. pClass->Release();
  184. }
  185. else
  186. {
  187. // got a class, not an instance!
  188. CMoClass * pClass = (CMoClass * )pMo;
  189. if(pClass->GetParentName() && wcslen(pClass->GetParentName()) > 0)
  190. {
  191. IWbemClassObject * pParent = NULL;
  192. BSTR bstrParent = SysAllocString(pClass->GetParentName());
  193. if(bstrParent == NULL)
  194. return NULL;
  195. CSysFreeMe fm2(bstrParent);
  196. sc = pNamespace->GetObject(bstrParent, 0, pCtx, &pParent, NULL);
  197. if(FAILED(sc))
  198. return NULL;
  199. CReleaseMe rm(pParent);
  200. sc = pParent->SpawnDerivedClass(0, &pInst);
  201. if(FAILED(sc))
  202. return NULL;
  203. }
  204. else
  205. sc = pNamespace->GetObject(NULL, 0, pCtx, &pInst, NULL);
  206. if(sc != S_OK)
  207. return NULL;
  208. VARIANT var;
  209. var.vt = VT_BSTR;
  210. var.bstrVal = bstr;
  211. pInst->Put(L"__CLASS", 0, &var, 0);
  212. }
  213. if(sc != S_OK)
  214. return NULL;
  215. BOOL bOK = pMo->ApplyToWbemObject(pInst,pNamespace,pCtx);
  216. if(bOK)
  217. return pInst;
  218. else
  219. {
  220. pInst->Release();
  221. return NULL;
  222. }
  223. }
  224. BOOL CValueProperty::AddEmbeddedObject(OLE_MODIFY IWbemClassObject* pObject, IWbemServices* pNamespace, IWbemContext * pCtx)
  225. {
  226. VARIANT & var = m_Value.AccessVariant();
  227. VARIANT vSet;
  228. IWbemClassObject * pInst = NULL;
  229. if(var.vt & VT_ARRAY)
  230. {
  231. vSet.vt = VT_EMBEDDED_OBJECT | VT_ARRAY;
  232. SAFEARRAYBOUND aBounds[1];
  233. long lLBound, lUBound;
  234. SafeArrayGetLBound(var.parray, 1, &lLBound);
  235. SafeArrayGetUBound(var.parray, 1, &lUBound);
  236. aBounds[0].cElements = lUBound - lLBound + 1;
  237. aBounds[0].lLbound = lLBound;
  238. vSet.parray = SafeArrayCreate(VT_EMBEDDED_OBJECT & ~VT_ARRAY, 1, aBounds);
  239. if(vSet.parray == NULL)
  240. return FALSE;
  241. // Stuff the individual data pieces
  242. // ================================
  243. for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
  244. {
  245. // Load the initial data element into a VARIANT
  246. // ============================================
  247. CMObject * pTemp;
  248. SCODE hres = SafeArrayGetElement(var.parray, &lIndex, &pTemp);
  249. if(FAILED(hres) || pTemp == FALSE)
  250. {
  251. SafeArrayDestroy(vSet.parray);
  252. return FALSE;
  253. }
  254. // Cast it to the new type
  255. // =======================
  256. pInst = GetInstPtr(pTemp->GetClassName(), pNamespace, pTemp, pCtx);
  257. if(pInst == NULL)
  258. {
  259. Trace(true, m_pDbg, ALIAS_PROP_ERROR, m_wszName);
  260. SafeArrayDestroy(vSet.parray);
  261. return FALSE;
  262. }
  263. // Put it into the new array
  264. // =========================
  265. hres = SafeArrayPutElement(vSet.parray, &lIndex, pInst);
  266. pInst->Release();
  267. if(FAILED(hres))
  268. {
  269. SafeArrayDestroy(vSet.parray);
  270. return FALSE;
  271. }
  272. }
  273. }
  274. else
  275. {
  276. CMObject * pTemp = (CMObject *)var.punkVal;
  277. pInst = GetInstPtr(pTemp->GetClassName(), pNamespace, pTemp, pCtx);
  278. if(pInst == NULL)
  279. {
  280. Trace(true, m_pDbg, ALIAS_PROP_ERROR, m_wszName);
  281. return FALSE;
  282. }
  283. vSet.punkVal = pInst;
  284. vSet.vt = VT_EMBEDDED_OBJECT;
  285. }
  286. HRESULT hres = pObject->Put(m_wszName, 0, &vSet, 0);
  287. // Release all the WbemObjects we have created
  288. // ==========================================
  289. if(var.vt & VT_ARRAY)
  290. SafeArrayDestroy(vSet.parray);
  291. else if(pInst)
  292. pInst->Release();
  293. return hres == S_OK;
  294. }
  295. BOOL CValueProperty::AddToObject(OLE_MODIFY IWbemClassObject* pObject, IWbemServices* pNamespace,
  296. BOOL bClass, IWbemContext * pCtx)
  297. {
  298. if(m_wszName == NULL) return FALSE;
  299. m_pDbg->SetString(m_wszName);
  300. // Get the property value
  301. // ======================
  302. VARIANT & var = m_Value.AccessVariant();
  303. // Determine if this is an embedded object.
  304. VARTYPE vtSimple = var.vt & ~VT_ARRAY;
  305. if(vtSimple == VT_NULL)
  306. vtSimple = m_Value.GetType() & ~VT_ARRAY;
  307. // If the type is embedded object, make sure the class name is OK.
  308. if(vtSimple == VT_EMBEDDED_OBJECT)
  309. {
  310. // Determine the class name of the embedded object.
  311. CMoValue * pValue = m_paQualifiers->Find(L"CIMTYPE");
  312. if(pValue)
  313. {
  314. if(var.vt == VT_BSTR && wcslen(var.bstrVal) > wcslen(L"Object:"))
  315. {
  316. // Test if this class if valid by doing a GetObject call
  317. WCHAR * pClassName = var.bstrVal + wcslen(L"Object:");
  318. IWbemClassObject *pClass = NULL;
  319. BSTR bstr = SysAllocString(pClassName);
  320. if(bstr == NULL)
  321. return FALSE;
  322. SCODE sc = pNamespace->GetObject(bstr, 0, pCtx,&pClass, NULL);
  323. SysFreeString(bstr);
  324. if(sc != S_OK)
  325. {
  326. m_pDbg->hresError = WBEM_E_INVALID_PROPERTY_TYPE;
  327. Trace(true, m_pDbg, BAD_PROP_TYPE, GetName());
  328. return FALSE;
  329. }
  330. pClass->Release();
  331. }
  332. }
  333. }
  334. // If there is an actual embedded object, store it.
  335. if((var.vt & ~VT_ARRAY) == VT_EMBEDDED_OBJECT)
  336. {
  337. if(!AddEmbeddedObject(pObject, pNamespace, pCtx))
  338. return FALSE;
  339. return GetQualifiers()->AddToPropOrMeth(pObject, m_wszName, bClass, TRUE);
  340. }
  341. VARTYPE vNewType = m_Value.GetType();
  342. // arguments cannot be VT_EMPTY
  343. if(m_bIsArg && var.vt == VT_EMPTY)
  344. var.vt = VT_NULL;
  345. // Set the property value. Not that reference types are a special case used by binary mofs
  346. // and so the flag should be eliminated.
  347. // ======================
  348. vNewType &= ~VT_BYREF;
  349. HRESULT hres = pObject->Put(m_wszName, 0, &var, (bClass || m_bIsArg) ? vNewType : 0);
  350. if(FAILED(hres))
  351. {
  352. m_pDbg->hresError = hres;
  353. return FALSE;
  354. }
  355. // Configure the qualifier set
  356. // ===========================
  357. if(!GetQualifiers()->AddToPropOrMeth(pObject, m_wszName, bClass, TRUE))
  358. {
  359. return FALSE;
  360. }
  361. // Get the syntax value
  362. // ====================
  363. // VariantClear(&vNew);
  364. // VariantClear(&v);
  365. return TRUE;
  366. }
  367. BOOL CValueProperty::RegisterAliases(MODIFY CMObject* pObject)
  368. {
  369. // Copy all alias registrations into the object
  370. // ============================================
  371. int iNumAlias = m_Value.GetNumAliases();
  372. for(int i = 0; i < iNumAlias; i++)
  373. {
  374. LPWSTR wszAlias;
  375. int nArrayIndex;
  376. m_Value.GetAlias(i, wszAlias, nArrayIndex);
  377. CPropertyLocation * pNew = new CPropertyLocation(m_wszName, nArrayIndex);
  378. if(pNew == NULL)
  379. return FALSE;
  380. if(pNew->IsOK() == false)
  381. {
  382. delete pNew;
  383. return FALSE;
  384. }
  385. HRESULT hr = pObject->AddAliasedValue(pNew, wszAlias);
  386. if(FAILED(hr))
  387. return FALSE;
  388. }
  389. // Ask the qualifier set to do the same
  390. // ====================================
  391. if(m_paQualifiers)
  392. GetQualifiers()->RegisterAliases(pObject, m_wszName);
  393. return TRUE;
  394. }
  395. CMoProperty::~CMoProperty()
  396. {
  397. if(m_paQualifiers)
  398. delete m_paQualifiers;
  399. if(m_wszName)
  400. delete [] m_wszName;
  401. if(m_wszTypeTitle)
  402. delete [] m_wszTypeTitle;
  403. }
  404. //*****************************************************************************
  405. CMoQualifier::CMoQualifier(PDBG pDbg) : m_Value(pDbg)
  406. {
  407. m_pDbg = pDbg;
  408. m_wszName = NULL;
  409. m_lFlavor = 0;
  410. m_bOverrideSet = false;
  411. m_bNotOverrideSet = false;
  412. m_bIsRestricted = false;
  413. m_bNotToInstance = false;
  414. m_bToInstance = false;
  415. m_bNotToSubclass = false;
  416. m_bToSubclass = false;
  417. m_bAmended = false;
  418. m_dwScope = 0;
  419. m_bCimDefaultQual = false;
  420. m_bUsingDefaultValue = false;
  421. }
  422. CMoQualifier::~CMoQualifier()
  423. {
  424. if(m_wszName)
  425. delete [] m_wszName;
  426. }
  427. HRESULT CMoQualifier::SetFlag(int iToken, LPCWSTR pwsText)
  428. {
  429. if(iToken == TOK_TOINSTANCE)
  430. {
  431. if(m_bIsRestricted || m_bNotToInstance)
  432. return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
  433. m_lFlavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
  434. m_bToInstance = true;
  435. }
  436. else if(iToken == TOK_TOSUBCLASS)
  437. {
  438. if(m_bIsRestricted || m_bNotToSubclass)
  439. return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
  440. m_lFlavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
  441. m_bToSubclass = true;
  442. }
  443. else if(iToken == TOK_NOTTOINSTANCE)
  444. {
  445. if(m_bToInstance)
  446. return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
  447. m_lFlavor &= ~WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
  448. m_bNotToInstance = true;
  449. }
  450. else if(iToken == TOK_NOTTOSUBCLASS)
  451. {
  452. if(m_bToSubclass)
  453. return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
  454. m_lFlavor &= ~WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
  455. m_bNotToSubclass = true;
  456. }
  457. else if(iToken == TOK_ENABLEOVERRIDE)
  458. {
  459. if(m_bNotOverrideSet)
  460. return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
  461. m_lFlavor &= ~WBEM_FLAVOR_NOT_OVERRIDABLE;
  462. m_bOverrideSet = true;
  463. }
  464. else if(iToken == TOK_DISABLEOVERRIDE)
  465. {
  466. if(m_bOverrideSet)
  467. return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
  468. m_bNotOverrideSet = true;
  469. m_lFlavor |= WBEM_FLAVOR_NOT_OVERRIDABLE;
  470. }
  471. else if(iToken == TOK_RESTRICTED)
  472. {
  473. if(m_bToInstance || m_bToSubclass)
  474. return WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2;
  475. m_bIsRestricted = true;
  476. m_lFlavor &= ~WBEM_FLAVOR_MASK_PROPAGATION;
  477. }
  478. else if(iToken == TOK_AMENDED)
  479. {
  480. m_bAmended = true;
  481. }
  482. else if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(L"translatable", pwsText))
  483. {
  484. return S_OK; // WBEMMOF_E_UNSUPPORTED_CIMV22_FLAVOR_TYPE;
  485. }
  486. else
  487. return WBEMMOF_E_EXPECTED_FLAVOR_TYPE;
  488. return S_OK;
  489. }
  490. BOOL CMoQualifier::SetScope(int iToken, LPCWSTR pwsText)
  491. {
  492. if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"ANY"))
  493. {
  494. m_dwScope |= 0XFFFFFFFF;
  495. return TRUE;
  496. }
  497. if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"ASSOCIATION"))
  498. {
  499. m_dwScope |= SCOPE_ASSOCIATION;
  500. return TRUE;
  501. }
  502. if(iToken == TOK_CLASS)
  503. {
  504. m_dwScope |= SCOPE_CLASS;
  505. return TRUE;
  506. }
  507. if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"indication"))
  508. {
  509. ERRORTRACE((LOG_MOFCOMP,"Warning, unsupported INDICATION keyword used in scope\n"));
  510. return TRUE; // IGNORE THESE
  511. }
  512. if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"schema"))
  513. {
  514. ERRORTRACE((LOG_MOFCOMP,"Warning, unsupported SCHEMA keyword used in scope\n"));
  515. return TRUE; // IGNORE THESE
  516. }
  517. if(iToken == TOK_INSTANCE)
  518. {
  519. m_dwScope |= SCOPE_INSTANCE;
  520. return TRUE;
  521. }
  522. if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"METHOD"))
  523. {
  524. m_dwScope |= SCOPE_METHOD;
  525. return TRUE;
  526. }
  527. if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"PARAMETER"))
  528. {
  529. m_dwScope |= SCOPE_PARAMETER;
  530. return TRUE;
  531. }
  532. if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"PROPERTY"))
  533. {
  534. m_dwScope |= SCOPE_PROPERTY;
  535. return TRUE;
  536. }
  537. if(iToken == TOK_SIMPLE_IDENT && !wbem_wcsicmp(pwsText, L"REFERENCE"))
  538. {
  539. m_dwScope |= SCOPE_REFERENCE;
  540. return TRUE;
  541. }
  542. return FALSE;
  543. }
  544. HRESULT CMoQualifier::SetQualName(COPY LPCWSTR wszName)
  545. {
  546. delete [] m_wszName;
  547. m_wszName = Macro_CloneStr(wszName);
  548. if(m_wszName == NULL && wszName != NULL)
  549. return WBEM_E_OUT_OF_MEMORY;
  550. else
  551. return S_OK;
  552. }
  553. BOOL CMoQualifier::AddToSet(OLE_MODIFY IWbemQualifierSet* pQualifierSet,
  554. BOOL bClass)
  555. {
  556. BSTR strName = SysAllocString(m_wszName);
  557. if(strName == NULL)
  558. {
  559. return FALSE;
  560. }
  561. m_pDbg->SetString(strName);
  562. HRESULT hres = pQualifierSet->Put(
  563. strName,
  564. &m_Value.AccessVariant(),GetFlavor());
  565. if(FAILED(hres))
  566. {
  567. m_pDbg->hresError = hres;
  568. return FALSE;
  569. }
  570. SysFreeString(strName);
  571. return SUCCEEDED(hres);
  572. }
  573. INTERNAL CMoValue* CMoQualifierArray::Find(READ_ONLY LPCWSTR wszName)
  574. {
  575. for(int i = 0; i < GetSize(); i++)
  576. {
  577. CMoQualifier* pQual = GetAt(i);
  578. if(!wbem_wcsicmp(pQual->GetName(), wszName))
  579. {
  580. return &pQual->AccessValue();
  581. }
  582. }
  583. return NULL;
  584. }
  585. BOOL CMoQualifierArray::Add(ACQUIRE CMoQualifier* pQualifier)
  586. {
  587. // before adding a qualifier, check for a duplicate name.
  588. if(pQualifier == NULL || pQualifier->GetName() == NULL)
  589. return FALSE;
  590. CMoValue * pValue = Find(pQualifier->GetName());
  591. if(pValue != NULL)
  592. return FALSE;
  593. m_aQualifiers.Add(pQualifier);
  594. return TRUE;
  595. }
  596. //*****************************************************************************
  597. CMoQualifierArray::~CMoQualifierArray()
  598. {
  599. for(int i = 0; i < GetSize(); i++)
  600. {
  601. delete GetAt(i);
  602. }
  603. }
  604. BOOL CMoQualifierArray::AddToSet(OLE_MODIFY IWbemQualifierSet* pQualifierSet,
  605. BOOL bClass)
  606. {
  607. // Add all the qualifiers to it
  608. // ============================
  609. for(int i = 0; i < GetSize(); i++)
  610. {
  611. if(!GetAt(i)->AddToSet(pQualifierSet, bClass)) return FALSE;
  612. }
  613. return TRUE;
  614. }
  615. BOOL CMoQualifierArray::RegisterAliases(MODIFY CMObject* pObject,
  616. READ_ONLY LPCWSTR wszPropName)
  617. {
  618. for(int i = 0; i < GetSize(); i++)
  619. {
  620. CMoValue& QualifierValue = GetAt(i)->AccessValue();
  621. LPCWSTR wszName = GetAt(i)->GetName();
  622. for(int j = 0; j < QualifierValue.GetNumAliases(); j++)
  623. {
  624. LPWSTR wszAlias;
  625. int nArrayIndex;
  626. QualifierValue.GetAlias(j, wszAlias, nArrayIndex);
  627. VARIANT & Var = QualifierValue.AccessVariant();
  628. if((Var.vt & VT_ARRAY) == 0)
  629. nArrayIndex = -1;
  630. CQualifierLocation * pNew = new CQualifierLocation(wszName, m_pDbg, wszPropName, nArrayIndex);
  631. if(pNew == NULL)
  632. return FALSE;
  633. if(pNew->IsOK() == false)
  634. {
  635. delete pNew;
  636. return FALSE;
  637. }
  638. HRESULT hr = pObject->AddAliasedValue(pNew , wszAlias);
  639. if(FAILED(hr))
  640. return FALSE;
  641. }
  642. }
  643. return TRUE;
  644. }
  645. BOOL CMoQualifierArray::AddToObject(OLE_MODIFY IWbemClassObject* pObject,
  646. BOOL bClass)
  647. {
  648. // Get the qualifier set from the object
  649. // =====================================
  650. IWbemQualifierSet* pQualifierSet;
  651. if(FAILED(pObject->GetQualifierSet(&pQualifierSet)))
  652. {
  653. return FALSE;
  654. }
  655. // Add all qualifiers to it
  656. // ========================
  657. BOOL bRes = AddToSet(pQualifierSet, bClass);
  658. pQualifierSet->Release();
  659. return bRes;
  660. }
  661. BOOL CMoQualifierArray::AddToPropOrMeth(OLE_MODIFY IWbemClassObject* pObject,
  662. READ_ONLY LPCWSTR wszName,
  663. BOOL bClass, BOOL bProp)
  664. {
  665. // Get the qualifier set
  666. // =====================
  667. BSTR strName = SysAllocString(wszName);
  668. if(strName == NULL)
  669. {
  670. return FALSE;
  671. }
  672. IWbemQualifierSet* pQualifierSet;
  673. SCODE sc;
  674. if(bProp)
  675. sc = pObject->GetPropertyQualifierSet(strName, &pQualifierSet);
  676. else
  677. sc = pObject->GetMethodQualifierSet(strName, &pQualifierSet);
  678. SysFreeString(strName);
  679. if(FAILED(sc))
  680. return FALSE;
  681. // Add qualifiers to it
  682. // ====================
  683. BOOL bRes = AddToSet(pQualifierSet, bClass);
  684. pQualifierSet->Release();
  685. return bRes;
  686. }
  687. //*****************************************************************************
  688. CMoType::~CMoType()
  689. {
  690. delete m_wszTitle;
  691. }
  692. HRESULT CMoType::SetTitle(COPY LPCWSTR wszTitle)
  693. {
  694. delete [] m_wszTitle;
  695. m_wszTitle = Macro_CloneStr(wszTitle);
  696. if(m_wszTitle == NULL && wszTitle != NULL)
  697. return WBEM_E_OUT_OF_MEMORY;
  698. else
  699. return S_OK;
  700. }
  701. VARTYPE CMoType::GetCIMType()
  702. {
  703. if(IsRef() && IsArray()) return CIM_REFERENCE | VT_ARRAY;
  704. if(IsRef()) return CIM_REFERENCE;
  705. if(IsEmbedding() && IsArray()) return VT_EMBEDDED_OBJECT | VT_ARRAY;
  706. if(IsEmbedding()) return VT_EMBEDDED_OBJECT;
  707. VARTYPE vt_array = (IsArray())?VT_ARRAY:0;
  708. // Check if it is even initialized
  709. // ===============================
  710. if(m_wszTitle == NULL)
  711. {
  712. return VT_BSTR; // HACK! string converts nicely into just about anything
  713. }
  714. // VT_UI1
  715. if(!wbem_wcsicmp(m_wszTitle, L"sint8"))
  716. return CIM_SINT8 | vt_array;
  717. if(!wbem_wcsicmp(m_wszTitle, L"uint8"))
  718. return CIM_UINT8 | vt_array;
  719. if(!wbem_wcsicmp(m_wszTitle, L"sint16"))
  720. return CIM_SINT16 | vt_array;
  721. if(!wbem_wcsicmp(m_wszTitle, L"uint16"))
  722. return CIM_UINT16 | vt_array;
  723. if(!wbem_wcsicmp(m_wszTitle, L"sint32"))
  724. return CIM_SINT32 | vt_array;
  725. if(!wbem_wcsicmp(m_wszTitle, L"uint32"))
  726. return CIM_UINT32 | vt_array;
  727. if(!wbem_wcsicmp(m_wszTitle, L"sint64"))
  728. return CIM_SINT64 | vt_array;
  729. if(!wbem_wcsicmp(m_wszTitle, L"uint64"))
  730. return CIM_UINT64 | vt_array;
  731. // VT_R4
  732. if (!wbem_wcsicmp(m_wszTitle, L"real32"))
  733. return CIM_REAL32 | vt_array;
  734. if (!wbem_wcsicmp(m_wszTitle, L"real64"))
  735. return CIM_REAL64 | vt_array;
  736. // Do other types
  737. if(!wbem_wcsicmp(m_wszTitle, L"BOOLEAN"))
  738. return CIM_BOOLEAN | vt_array;
  739. if(!wbem_wcsicmp(m_wszTitle, L"string"))
  740. return CIM_STRING | vt_array;
  741. if(!wbem_wcsicmp(m_wszTitle, L"datetime"))
  742. return CIM_DATETIME | vt_array;
  743. if(!wbem_wcsicmp(m_wszTitle, L"REF"))
  744. return CIM_REFERENCE | vt_array;
  745. if(!wbem_wcsicmp(m_wszTitle, L"CHAR16"))
  746. return CIM_CHAR16 | vt_array;
  747. if(!wbem_wcsicmp(m_wszTitle, L"OBJECT"))
  748. return CIM_OBJECT | vt_array;
  749. if(!wbem_wcsicmp(m_wszTitle, L"void") ||
  750. !wbem_wcsicmp(m_wszTitle, L"null"))
  751. return VT_NULL;
  752. if(!wbem_wcsnicmp(m_wszTitle, L"REF:", 4))
  753. return CIM_REFERENCE | vt_array;
  754. if(!wbem_wcsnicmp(m_wszTitle, L"OBJECT:", 7))
  755. return CIM_OBJECT | vt_array;
  756. return VT_ERROR;
  757. }
  758. bool CMoType::IsUnsupportedType()
  759. {
  760. if(m_wszTitle == NULL)
  761. {
  762. return false;
  763. }
  764. if(!wbem_wcsicmp(m_wszTitle, L"dt_sint8"))
  765. return true;
  766. if(!wbem_wcsicmp(m_wszTitle, L"dt_uint8"))
  767. return true;
  768. if(!wbem_wcsicmp(m_wszTitle, L"dt_sint16"))
  769. return true;
  770. if(!wbem_wcsicmp(m_wszTitle, L"dt_uint16"))
  771. return true;
  772. if(!wbem_wcsicmp(m_wszTitle, L"dt_sint32"))
  773. return true;
  774. if(!wbem_wcsicmp(m_wszTitle, L"dt_uint32"))
  775. return true;
  776. if(!wbem_wcsicmp(m_wszTitle, L"dt_sint64"))
  777. return true;
  778. if(!wbem_wcsicmp(m_wszTitle, L"dt_uint64"))
  779. return true;
  780. if (!wbem_wcsicmp(m_wszTitle, L"dt_real32"))
  781. return true;
  782. if (!wbem_wcsicmp(m_wszTitle, L"dt_real64"))
  783. return true;
  784. if (!wbem_wcsicmp(m_wszTitle, L"dt_char16"))
  785. return true;
  786. if(!wbem_wcsicmp(m_wszTitle, L"dt_BOOL"))
  787. return true;
  788. if(!wbem_wcsicmp(m_wszTitle, L"dt_str"))
  789. return true;
  790. if(!wbem_wcsicmp(m_wszTitle, L"dt_datetime"))
  791. return true;
  792. return false;
  793. }
  794. BOOL CMoType::StoreIntoQualifiers(CMoQualifierArray * pQualifiers)
  795. {
  796. if(pQualifiers == NULL)
  797. return FALSE;
  798. if(IsRef() ||IsEmbedding())
  799. {
  800. WCHAR * pFormat = (IsRef()) ? L"ref" : L"object";
  801. if(wbem_wcsicmp(m_wszTitle, L"object") == 0)
  802. {
  803. pQualifiers->Add(CreateSyntax(pFormat));
  804. }
  805. else
  806. {
  807. DWORD dwLen = wcslen(m_wszTitle) + 20;
  808. LPWSTR wszSyntax = new WCHAR[dwLen];
  809. if(wszSyntax == NULL)
  810. return FALSE;
  811. StringCchPrintfW(wszSyntax, dwLen, L"%s:%s",pFormat, m_wszTitle);
  812. pQualifiers->Add(CreateSyntax(wszSyntax));
  813. delete [] wszSyntax;
  814. }
  815. return TRUE;
  816. }
  817. pQualifiers->Add(CreateSyntax(m_wszTitle));
  818. return TRUE;
  819. }
  820. DELETE_ME CMoQualifier* CMoType::CreateSyntax(READ_ONLY LPCWSTR wszSyntax)
  821. {
  822. CMoQualifier* pQualifier = new CMoQualifier(m_pDbg);
  823. if(pQualifier == NULL)
  824. return NULL;
  825. if(FAILED(pQualifier->SetQualName(L"CIMTYPE")))
  826. {
  827. delete pQualifier;
  828. return NULL;
  829. }
  830. pQualifier->SetFlavor(WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE |
  831. WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS);
  832. BSTR bstrVal = SysAllocString(wszSyntax);
  833. if(bstrVal == NULL)
  834. {
  835. delete pQualifier;
  836. return NULL;
  837. }
  838. V_VT(&pQualifier->AccessValue().AccessVariant()) = VT_BSTR;
  839. V_BSTR(&pQualifier->AccessValue().AccessVariant()) = bstrVal;
  840. return pQualifier;
  841. }
  842. //*****************************************************************************
  843. HRESULT CValueLocation::SetArrayElement(
  844. MODIFY VARIANT& vArray,
  845. int nIndex,
  846. READ_ONLY VARIANT& vValue)
  847. {
  848. if(V_VT(&vArray) != (VT_ARRAY | VT_BSTR)) return WBEM_E_FAILED;
  849. // if(V_VT(&vArray) != (VT_ARRAY | VT_VARIANT)) return WBEM_E_FAILED;
  850. SAFEARRAY* pSafeArray = V_ARRAY(&vArray);
  851. long lLowerBound;
  852. if(FAILED(SafeArrayGetLBound(pSafeArray, 1, &lLowerBound)))
  853. return WBEM_E_FAILED;
  854. long lActualIndex = lLowerBound + nIndex;
  855. // Set the value in the array
  856. // ==========================
  857. if(FAILED(SafeArrayPutElement(pSafeArray,
  858. (long*)&lActualIndex,
  859. (void*)vValue.bstrVal)))
  860. {
  861. return WBEM_E_FAILED;
  862. }
  863. return WBEM_NO_ERROR;
  864. }
  865. //*****************************************************************************
  866. CPropertyLocation::CPropertyLocation(COPY LPCWSTR wszName, int nArrayIndex)
  867. {
  868. m_bOK = true;
  869. m_wszName = Macro_CloneStr(wszName);
  870. if(m_wszName == NULL && wszName != NULL)
  871. m_bOK = false;
  872. m_nArrayIndex = nArrayIndex;
  873. }
  874. CPropertyLocation::~CPropertyLocation()
  875. {
  876. if(m_wszName)
  877. delete m_wszName;
  878. }
  879. HRESULT CPropertyLocation::Set(READ_ONLY VARIANT& varValue,
  880. OLE_MODIFY IWbemClassObject* pObject)
  881. {
  882. if(m_nArrayIndex == -1)
  883. {
  884. // Not an array index. Simply set the property
  885. // ===========================================
  886. return pObject->Put(m_wszName, 0, &varValue, 0);
  887. }
  888. else
  889. {
  890. // Array index. Get the value
  891. // ==========================
  892. VARIANT vArray;
  893. VariantInit(&vArray);
  894. HRESULT hres = pObject->Get(m_wszName, 0, &vArray, NULL, NULL);
  895. if(FAILED(hres)) return hres;
  896. // Set the value
  897. // =============
  898. if(FAILED(SetArrayElement(vArray, m_nArrayIndex, varValue)))
  899. return WBEM_E_FAILED;
  900. // Store the whole array back into the property
  901. // ============================================
  902. hres = pObject->Put(m_wszName, 0, &vArray, 0);
  903. VariantClear(&vArray);
  904. return hres;
  905. }
  906. }
  907. //*****************************************************************************
  908. CQualifierLocation::CQualifierLocation(COPY LPCWSTR wszName,PDBG pDbg,
  909. COPY LPCWSTR wszPropName,
  910. int nArrayIndex)
  911. {
  912. m_bOK = true;
  913. m_pDbg = pDbg;
  914. if(wszName)
  915. m_wszName = Macro_CloneStr(wszName);
  916. else
  917. m_wszName = NULL;
  918. if(m_wszName == NULL && wszName != NULL)
  919. m_bOK = false;
  920. if(wszPropName != NULL)
  921. m_wszPropName = Macro_CloneStr(wszPropName);
  922. else
  923. m_wszPropName = NULL;
  924. if(m_wszPropName == NULL && wszPropName != NULL)
  925. m_bOK = false;
  926. m_nArrayIndex = nArrayIndex;
  927. }
  928. CQualifierLocation::~CQualifierLocation()
  929. {
  930. if(m_wszName)
  931. delete m_wszName;
  932. if(m_wszPropName)
  933. delete m_wszPropName;
  934. }
  935. HRESULT CQualifierLocation::Set(READ_ONLY VARIANT& varValue,
  936. OLE_MODIFY IWbemClassObject* pObject)
  937. {
  938. HRESULT hres;
  939. long lOrigFlavor= 0;
  940. if(pObject == NULL)
  941. return WBEM_E_INVALID_PARAMETER;
  942. // Get the qualifier set for either the property or the object
  943. // ===========================================================
  944. IWbemQualifierSet* pQualifierSet;
  945. if(m_wszPropName == NULL)
  946. {
  947. hres = pObject->GetQualifierSet(&pQualifierSet);
  948. }
  949. else
  950. {
  951. hres = pObject->GetPropertyQualifierSet(m_wszPropName, &pQualifierSet);
  952. }
  953. if(FAILED(hres))
  954. return hres;
  955. // Get the qualifier value (need it for the type in either case)
  956. // =============================================================
  957. VARIANT vQualifierVal;
  958. VariantInit(&vQualifierVal);
  959. hres = pQualifierSet->Get(m_wszName, 0, &vQualifierVal, &lOrigFlavor);
  960. if(FAILED(hres)) return hres;
  961. // Check if array is involved
  962. // ==========================
  963. if(m_nArrayIndex == -1)
  964. {
  965. // Just set the qualifier value
  966. // ============================
  967. hres = pQualifierSet->Put(m_wszName, &varValue, lOrigFlavor);
  968. }
  969. else
  970. {
  971. // Set the appropriate array element
  972. // =================================
  973. if(FAILED(SetArrayElement(vQualifierVal, m_nArrayIndex, varValue)))
  974. return WBEM_E_FAILED;
  975. // Store the value back
  976. // ====================
  977. hres = pQualifierSet->Put(m_wszName, &vQualifierVal, lOrigFlavor);
  978. if(FAILED(hres))
  979. {
  980. m_pDbg->hresError = FALSE;
  981. return hres;
  982. }
  983. }
  984. pQualifierSet->Release();
  985. VariantClear(&vQualifierVal);
  986. return hres;
  987. }
  988. //*****************************************************************************
  989. CMObject::CAliasedValue::CAliasedValue(
  990. ACQUIRE CValueLocation* _pLocation,
  991. COPY LPCWSTR _wszAlias)
  992. {
  993. pLocation = _pLocation;
  994. wszAlias = Macro_CloneStr(_wszAlias);
  995. }
  996. CMObject::CAliasedValue::~CAliasedValue()
  997. {
  998. delete pLocation;
  999. delete [] wszAlias;
  1000. }
  1001. CMObject::CMObject()
  1002. {
  1003. m_wszAlias = NULL;
  1004. m_wszNamespace = NULL;
  1005. m_paQualifiers = NULL;
  1006. m_wszFullPath = NULL;
  1007. m_nFirstLine = 0;
  1008. m_nLastLine = 0;
  1009. m_lDefClassFlags = 0;
  1010. m_lDefInstanceFlags = 0;
  1011. m_bDone = FALSE;
  1012. m_pWbemObj = NULL;
  1013. m_bParameter = false;
  1014. m_bAmended = false;
  1015. m_wFileName = NULL;
  1016. m_bDeflated = false;
  1017. m_bOK = true;
  1018. }
  1019. HRESULT CMObject::Deflate(bool bDestruct)
  1020. {
  1021. if(!bDestruct && (m_wszAlias || GetNumAliasedValues() > 0))
  1022. {
  1023. return S_OK;
  1024. }
  1025. m_bDeflated = true;
  1026. if(m_paQualifiers)
  1027. {
  1028. for(int i = 0; i < m_paQualifiers->GetSize(); i++)
  1029. {
  1030. CMoQualifier * pQual = (CMoQualifier *) m_paQualifiers->GetAt(i);
  1031. delete pQual;
  1032. }
  1033. m_paQualifiers->RemoveAll();
  1034. }
  1035. for(int i = 0; i < m_aProperties.GetSize(); i++)
  1036. {
  1037. CMoProperty * pProp = (CMoProperty *) m_aProperties[i];
  1038. // If this is an parameter object (in argument or out arguement), dont delete any embedded
  1039. // objects since they will be delete as the CMethodParameter is cleaned out
  1040. if(m_bParameter)
  1041. {
  1042. VARIANT * pVar = pProp->GetpVar();
  1043. if(pVar->vt & VT_UNKNOWN)
  1044. pVar->vt = VT_I4;
  1045. }
  1046. delete pProp;
  1047. }
  1048. m_aProperties.RemoveAll();
  1049. return S_OK;
  1050. }
  1051. HRESULT CMObject::Reflate(CMofParser & Parser)
  1052. {
  1053. if(!m_bDeflated)
  1054. return S_OK;
  1055. if(IsInstance())
  1056. Parser.SetState(REFLATE_INST);
  1057. else
  1058. Parser.SetState(REFLATE_CLASS);
  1059. Parser.SetParserPosition(&m_QualState);
  1060. if (!Parser.qualifier_decl(*m_paQualifiers, true, CLASSINST_SCOPE))
  1061. return WBEM_E_FAILED;
  1062. Parser.SetParserPosition(&m_DataState);
  1063. if(IsInstance())
  1064. {
  1065. Parser.NextToken();
  1066. Parser.prop_init_list(this);
  1067. }
  1068. else
  1069. {
  1070. Parser.NextToken();
  1071. Parser.property_decl_list(this);
  1072. }
  1073. m_bDeflated = false;
  1074. return S_OK;
  1075. }
  1076. CMObject::~CMObject()
  1077. {
  1078. if(m_wszAlias)
  1079. delete [] m_wszAlias;
  1080. if(m_wszNamespace)
  1081. delete [] m_wszNamespace;
  1082. if(m_wszFullPath)
  1083. delete [] m_wszFullPath;
  1084. if(m_pWbemObj)
  1085. m_pWbemObj->Release();
  1086. Deflate(true);
  1087. if(m_paQualifiers)
  1088. delete m_paQualifiers;
  1089. int i;
  1090. for(i = 0; i < m_aAliased.GetSize(); i++)
  1091. {
  1092. delete (CAliasedValue*)m_aAliased[i];
  1093. }
  1094. delete [] m_wFileName;
  1095. }
  1096. void CMObject::FreeWbemObjectIfPossible()
  1097. {
  1098. if(m_wszAlias == NULL && m_pWbemObj)
  1099. {
  1100. m_pWbemObj->Release();
  1101. m_pWbemObj = NULL;
  1102. }
  1103. }
  1104. HRESULT CMObject::SetAlias(COPY LPCWSTR wszAlias)
  1105. {
  1106. delete [] m_wszAlias;
  1107. m_wszAlias = Macro_CloneStr(wszAlias);
  1108. if(m_wszAlias == NULL && wszAlias != NULL)
  1109. return WBEM_E_OUT_OF_MEMORY;
  1110. else
  1111. return S_OK;
  1112. }
  1113. HRESULT CMObject::SetNamespace(COPY LPCWSTR wszNamespace)
  1114. {
  1115. delete [] m_wszNamespace;
  1116. m_wszNamespace = Macro_CloneStr(wszNamespace);
  1117. if(m_wszNamespace == NULL && wszNamespace != NULL)
  1118. return WBEM_E_OUT_OF_MEMORY;
  1119. else
  1120. return S_OK;
  1121. }
  1122. HRESULT CMObject::SetLineRange(int nFirstLine, int nLastLine, WCHAR * pFileName)
  1123. {
  1124. m_nFirstLine = nFirstLine;
  1125. m_nLastLine = nLastLine;
  1126. m_wFileName = Macro_CloneStr(pFileName);
  1127. if(m_wFileName == NULL && pFileName != NULL)
  1128. return WBEM_E_OUT_OF_MEMORY;
  1129. else
  1130. return S_OK;
  1131. }
  1132. void CMObject::SetQualifiers(ACQUIRE CMoQualifierArray* pQualifiers)
  1133. {
  1134. delete m_paQualifiers;
  1135. m_paQualifiers = pQualifiers;
  1136. pQualifiers->RegisterAliases(this, NULL);
  1137. }
  1138. BOOL CMObject::AddProperty(ACQUIRE CMoProperty* pProperty)
  1139. {
  1140. // Check if the property has already been specified
  1141. // ================================================
  1142. for(int i = 0; i < m_aProperties.GetSize(); i++)
  1143. {
  1144. CMoProperty* pCurrentProp = (CMoProperty*)m_aProperties[i];
  1145. if(!wbem_wcsicmp(pCurrentProp->GetName(), pProperty->GetName()))
  1146. {
  1147. return FALSE;
  1148. }
  1149. }
  1150. m_aProperties.Add(pProperty);
  1151. pProperty->RegisterAliases(this);
  1152. return TRUE;
  1153. }
  1154. BOOL CMObject::GetAliasedValue(IN int nIndex,
  1155. OUT INTERNAL LPWSTR& wszAlias)
  1156. {
  1157. if(nIndex >= m_aAliased.GetSize())
  1158. {
  1159. return FALSE;
  1160. }
  1161. CAliasedValue* pValue = (CAliasedValue*)m_aAliased[nIndex];
  1162. wszAlias = pValue->wszAlias;
  1163. return TRUE;
  1164. }
  1165. BOOL CMObject::ResolveAliasedValue(IN int nIndex,
  1166. READ_ONLY LPCWSTR wszPath,
  1167. OLE_MODIFY IWbemClassObject* pObject)
  1168. {
  1169. CAliasedValue* pValue = (CAliasedValue*)m_aAliased[nIndex];
  1170. // Construct the variant with the value
  1171. // ====================================
  1172. VARIANT v;
  1173. VariantInit(&v);
  1174. V_VT(&v) = VT_BSTR;
  1175. V_BSTR(&v) = SysAllocString(wszPath);
  1176. if(v.bstrVal == NULL)
  1177. {
  1178. return FALSE;
  1179. }
  1180. // Tell the value locator to set it
  1181. // ================================
  1182. BOOL bRes = SUCCEEDED(pValue->pLocation->Set(v, pObject));
  1183. VariantClear(&v);
  1184. return bRes;
  1185. }
  1186. HRESULT CMObject::AddAliasedValue(ACQUIRE CValueLocation* pLocation,
  1187. COPY LPCWSTR wszAlias)
  1188. {
  1189. if(pLocation)
  1190. {
  1191. std::auto_ptr<CAliasedValue> pValue(new CAliasedValue(pLocation, wszAlias));
  1192. if(pValue.get() == NULL)
  1193. {
  1194. delete pLocation;
  1195. return WBEM_E_OUT_OF_MEMORY;
  1196. }
  1197. if(pValue->wszAlias == NULL && wszAlias != NULL)
  1198. {
  1199. return WBEM_E_OUT_OF_MEMORY;
  1200. }
  1201. m_aAliased.Add(pValue.get());
  1202. pValue.release();
  1203. }
  1204. return S_OK;
  1205. }
  1206. CMoProperty* CMObject::GetPropertyByName(WCHAR * pwcName)
  1207. {
  1208. for(int iCnt = 0; iCnt < m_aProperties.GetSize(); iCnt++)
  1209. {
  1210. CMoProperty* pProp = (CMoProperty*)m_aProperties[iCnt];
  1211. if(pProp && pProp->GetName())
  1212. if(!wbem_wcsicmp(pwcName, pProp->GetName()))
  1213. return pProp;
  1214. }
  1215. return NULL;
  1216. }
  1217. BOOL CMObject::ApplyToWbemObject(OLE_MODIFY IWbemClassObject* pObject, IWbemServices* pNamespace,
  1218. BOOL bClass, IWbemContext * pCtx)
  1219. {
  1220. if(GetQualifiers() && !GetQualifiers()->AddToObject(pObject, bClass)) return FALSE;
  1221. for(int i = 0; i < GetNumProperties(); i++)
  1222. {
  1223. if(!GetProperty(i)->AddToObject(pObject, pNamespace, bClass, pCtx)) return FALSE;
  1224. }
  1225. // Construct the path for future reference
  1226. // =======================================
  1227. VARIANT v;
  1228. VariantInit(&v);
  1229. SCODE sc = pObject->Get(L"__RELPATH", 0, &v, NULL, NULL);
  1230. if(sc != S_OK || V_VT(&v) != VT_BSTR)
  1231. {
  1232. // This is probably an embedded object. If not, we will fail shortly
  1233. // anyway. For now, just set the path to NULL and continue. // a-levn
  1234. delete [] m_wszFullPath;
  1235. m_wszFullPath = NULL;
  1236. return TRUE;
  1237. }
  1238. SetFullPath(v.bstrVal);
  1239. VariantClear(&v);
  1240. return TRUE;
  1241. }
  1242. void CMObject::SetFullPath(BSTR bstr)
  1243. {
  1244. if(bstr == NULL)
  1245. return;
  1246. if(m_wszFullPath)
  1247. delete [] m_wszFullPath;
  1248. int iLen = 20 + wcslen(bstr);
  1249. if(m_wszNamespace)
  1250. iLen += wcslen(m_wszNamespace);
  1251. m_wszFullPath = new WCHAR[iLen];
  1252. if(m_wszFullPath == NULL)
  1253. return;
  1254. // note that if m_wszNamespace is fully qualified, there is no need to
  1255. // prepend the slashes
  1256. if(m_wszNamespace && m_wszNamespace[0] == L'\\' && m_wszNamespace[1] == L'\\')
  1257. StringCchPrintfW (m_wszFullPath, iLen, L"%s:%s", m_wszNamespace, bstr);
  1258. else
  1259. StringCchPrintfW (m_wszFullPath, iLen, L"\\\\.\\%s:%s", m_wszNamespace, bstr);
  1260. }
  1261. int CMObject::GetNumAliasedValues()
  1262. {
  1263. int iRet = m_aAliased.GetSize();
  1264. // Also check the number of aliases in any embedded objects.
  1265. int iCnt;
  1266. for(iCnt = 0; iCnt < GetNumProperties(); iCnt++)
  1267. {
  1268. CMoProperty* pProp = GetProperty(iCnt);
  1269. if(pProp == NULL)
  1270. break;
  1271. if(!pProp->IsValueProperty())
  1272. {
  1273. // Method properties actually contain one or two embedded instances for holding the
  1274. // arguments. Use those for the method case.
  1275. CMethodProperty * pMeth = (CMethodProperty *)pProp;
  1276. CMoInstance * pArgListObj = pMeth->GetInObj();
  1277. if(pArgListObj)
  1278. iRet += pArgListObj->GetNumAliasedValues();
  1279. pArgListObj = pMeth->GetOutObj();
  1280. if(pArgListObj)
  1281. iRet += pArgListObj->GetNumAliasedValues();
  1282. continue;
  1283. }
  1284. CMoValue& value = pProp->AccessValue();
  1285. VARIANT & var = value.AccessVariant();
  1286. if(var.vt == VT_EMBEDDED_OBJECT)
  1287. {
  1288. CMObject * pTemp = (CMObject *)var.punkVal;
  1289. if(pTemp)
  1290. iRet += pTemp->GetNumAliasedValues();
  1291. }
  1292. else if(var.vt == (VT_EMBEDDED_OBJECT | VT_ARRAY))
  1293. {
  1294. long lLBound, lUBound;
  1295. SafeArrayGetLBound(var.parray, 1, &lLBound);
  1296. SafeArrayGetUBound(var.parray, 1, &lUBound);
  1297. // Check the individual embedded objects.
  1298. // ======================================
  1299. for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
  1300. {
  1301. CMObject * pTemp;
  1302. SCODE hres = SafeArrayGetElement(var.parray, &lIndex, &pTemp);
  1303. if(FAILED(hres) || pTemp == FALSE)
  1304. return iRet;
  1305. iRet += pTemp->GetNumAliasedValues();
  1306. }
  1307. }
  1308. }
  1309. return iRet;
  1310. }
  1311. HRESULT CMObject::ResolveAliasesInWbemObject(
  1312. OLE_MODIFY IWbemClassObject* pObject,
  1313. READ_ONLY CMofAliasCollection* pCollection)
  1314. {
  1315. int i;
  1316. SCODE sc;
  1317. // Resolve them all using the collection
  1318. // =====================================
  1319. for(i = 0; i < m_aAliased.GetSize(); i++)
  1320. {
  1321. LPWSTR wszAlias;
  1322. GetAliasedValue(i, wszAlias);
  1323. LPCWSTR wszPathToAliasee = pCollection->FindAliasee(wszAlias);
  1324. if(wszPathToAliasee == NULL) return WBEM_E_FAILED;
  1325. if(!ResolveAliasedValue(i, wszPathToAliasee, pObject))
  1326. {
  1327. return WBEM_E_FAILED;
  1328. }
  1329. }
  1330. // Also resolve any embedded objects
  1331. int iCnt;
  1332. for(iCnt = 0; iCnt < GetNumProperties(); iCnt++)
  1333. {
  1334. CMoProperty* pProp = GetProperty(iCnt);
  1335. if(pProp == NULL)
  1336. break;
  1337. CMoValue& value = pProp->AccessValue();
  1338. VARIANT & var = value.AccessVariant();
  1339. if(!pProp->IsValueProperty())
  1340. {
  1341. // Methods contain possibly and input and an output object for storing the arguments.
  1342. // These objects could contain aliases.
  1343. BOOL bChanged = FALSE;
  1344. CMethodProperty * pMeth = (CMethodProperty *)pProp;
  1345. CMoInstance * pArgListObj = pMeth->GetInObj();
  1346. BSTR bstr = SysAllocString(pProp->GetName());
  1347. if(!bstr)
  1348. return WBEM_E_FAILED;
  1349. IWbemClassObject *pIn = NULL;
  1350. IWbemClassObject *pOut = NULL;
  1351. sc = pObject->GetMethod(bstr, 0, &pIn, &pOut);
  1352. if(pArgListObj && pArgListObj->GetNumAliasedValues() && pIn)
  1353. {
  1354. sc = pArgListObj->ResolveAliasesInWbemObject((IWbemClassObject *)pIn,pCollection);
  1355. if(sc == S_OK)
  1356. bChanged = TRUE;
  1357. }
  1358. pArgListObj = pMeth->GetOutObj();
  1359. if(pArgListObj && pArgListObj->GetNumAliasedValues() && pOut)
  1360. {
  1361. sc = pArgListObj->ResolveAliasesInWbemObject((IWbemClassObject *)pOut,pCollection);
  1362. if(sc == S_OK)
  1363. bChanged = TRUE;
  1364. }
  1365. if(bChanged)
  1366. sc = pObject->PutMethod(bstr, 0, pIn, pOut);
  1367. if(bstr)
  1368. SysFreeString(bstr);
  1369. if(pIn)
  1370. pIn->Release();
  1371. if(pOut)
  1372. pOut->Release();
  1373. continue;
  1374. }
  1375. else if(var.vt == VT_EMBEDDED_OBJECT)
  1376. {
  1377. CMObject * pTemp = (CMObject *)var.punkVal;
  1378. if(pTemp)
  1379. {
  1380. VARIANT varDB;
  1381. VariantInit(&varDB);
  1382. BSTR bstr = SysAllocString(pProp->GetName());
  1383. if(bstr)
  1384. {
  1385. sc = pObject->Get(bstr, 0, &varDB, NULL, NULL);
  1386. if(sc == S_OK)
  1387. {
  1388. IWbemClassObject * pClass = (IWbemClassObject *)varDB.punkVal;
  1389. sc = pTemp->ResolveAliasesInWbemObject((IWbemClassObject *)varDB.punkVal,pCollection);
  1390. if(S_OK == sc)
  1391. pObject->Put(bstr, 0, &varDB, 0);
  1392. else
  1393. return WBEM_E_FAILED;
  1394. pClass->Release();
  1395. }
  1396. SysFreeString(bstr);
  1397. }
  1398. else
  1399. return WBEM_E_OUT_OF_MEMORY;
  1400. }
  1401. }
  1402. else if(var.vt == (VT_EMBEDDED_OBJECT | VT_ARRAY))
  1403. {
  1404. BSTR bstr = SysAllocString(pProp->GetName());
  1405. if(bstr)
  1406. {
  1407. VARIANT varDB;
  1408. VariantInit(&varDB);
  1409. sc = pObject->Get(bstr, 0, &varDB, NULL, NULL);
  1410. if(sc == S_OK)
  1411. {
  1412. long lLBound, lUBound;
  1413. SafeArrayGetLBound(var.parray, 1, &lLBound);
  1414. SafeArrayGetUBound(var.parray, 1, &lUBound);
  1415. // Check the individual embedded objects.
  1416. // ======================================
  1417. for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
  1418. {
  1419. CMObject * pTemp;
  1420. sc = SafeArrayGetElement(var.parray, &lIndex, &pTemp);
  1421. IWbemClassObject * pWBEMInst = NULL;
  1422. sc |= SafeArrayGetElement(varDB.parray, &lIndex, &pWBEMInst);
  1423. if(sc == S_OK && pTemp && pWBEMInst)
  1424. {
  1425. if(pTemp->m_aAliased.GetSize() > 0)
  1426. {
  1427. sc = pTemp->ResolveAliasesInWbemObject(pWBEMInst,pCollection);
  1428. if(sc != S_OK)
  1429. return WBEM_E_FAILED;
  1430. }
  1431. }
  1432. if(pWBEMInst)
  1433. pWBEMInst->Release();
  1434. }
  1435. sc = pObject->Put(bstr, 0, &varDB, 0);
  1436. SafeArrayDestroyData(varDB.parray);
  1437. SafeArrayDestroyDescriptor(varDB.parray);
  1438. }
  1439. SysFreeString(bstr);
  1440. }
  1441. else
  1442. return WBEM_E_OUT_OF_MEMORY;
  1443. }
  1444. }
  1445. return WBEM_NO_ERROR;
  1446. }
  1447. //*****************************************************************************
  1448. CMoClass::CMoClass(COPY LPCWSTR wszParentName, COPY LPCWSTR wszClassName, PDBG pDbg,
  1449. BOOL bUpdateOnly)
  1450. {
  1451. m_pDbg = pDbg;
  1452. m_wszParentName = Macro_CloneStr(wszParentName);
  1453. if(m_wszParentName == NULL && wszParentName != NULL)
  1454. m_bOK = false;
  1455. m_wszClassName = Macro_CloneStr(wszClassName);
  1456. if(m_wszClassName == NULL && wszClassName != NULL)
  1457. m_bOK = false;
  1458. m_bUpdateOnly = bUpdateOnly;
  1459. }
  1460. CMoClass::~CMoClass()
  1461. {
  1462. delete [] m_wszParentName;
  1463. delete [] m_wszClassName;
  1464. }
  1465. HRESULT CMoClass::CreateWbemObject(READ_ONLY IWbemServices* pNamespace,
  1466. RELEASE_ME IWbemClassObject** ppObject, IWbemContext * pCtx)
  1467. {
  1468. // Take care of update only case. In this case, the object is
  1469. // not created, on retrieved for the later put!
  1470. if(m_bUpdateOnly)
  1471. {
  1472. return pNamespace->GetObject(m_wszClassName, 0, pCtx, ppObject, NULL);
  1473. }
  1474. // Get the parent class from WINMGMT
  1475. // ==============================
  1476. BSTR strParentName = NULL;
  1477. if(m_wszParentName)
  1478. {
  1479. strParentName = SysAllocString(m_wszParentName);
  1480. if(strParentName == NULL)
  1481. {
  1482. return WBEM_E_OUT_OF_MEMORY;
  1483. }
  1484. m_pDbg->SetString(strParentName);
  1485. }
  1486. IWbemClassObject* pParentClass = NULL;
  1487. HRESULT hres = pNamespace->GetObject(strParentName, 0, pCtx, &pParentClass, NULL);
  1488. if(strParentName)
  1489. SysFreeString(strParentName);
  1490. if(FAILED(hres)) return hres;
  1491. if(m_wszParentName && wcslen(m_wszParentName))
  1492. {
  1493. // Create a child
  1494. // ==============
  1495. hres = pParentClass->SpawnDerivedClass(0, ppObject);
  1496. pParentClass->Release();
  1497. if(FAILED(hres)) return hres;
  1498. }
  1499. else
  1500. {
  1501. // Copy the dummy over
  1502. // ===================
  1503. *ppObject = pParentClass;
  1504. }
  1505. VARIANT v;
  1506. VariantInit(&v);
  1507. // Set the class name
  1508. // ==================
  1509. V_VT(&v) = VT_BSTR;
  1510. V_BSTR(&v) = SysAllocString(m_wszClassName);
  1511. if(v.bstrVal == NULL)
  1512. {
  1513. return WBEM_E_OUT_OF_MEMORY;
  1514. }
  1515. (*ppObject)->Put(L"__CLASS", 0, &v, 0);
  1516. VariantClear(&v);
  1517. return hres;
  1518. }
  1519. HRESULT CMoClass::StoreWbemObject(READ_ONLY IWbemClassObject* pObject,
  1520. long lClassFlags, long lInstanceFlags,
  1521. OLE_MODIFY IWbemServices* pNamespace, IWbemContext * pCtx,
  1522. WCHAR * pUserName, WCHAR * pPassword, WCHAR * pAuthority)
  1523. {
  1524. return pNamespace->PutClass(pObject, lClassFlags, pCtx, NULL);
  1525. }
  1526. //*****************************************************************************
  1527. CMoInstance::CMoInstance(COPY LPCWSTR wszClassName, PDBG pDbg, bool bParameter)
  1528. {
  1529. m_pDbg = pDbg;
  1530. m_wszClassName = Macro_CloneStr(wszClassName);
  1531. if(m_wszClassName == NULL && wszClassName != NULL)
  1532. m_bOK = false;
  1533. m_bParameter = bParameter;
  1534. }
  1535. CMoInstance::~CMoInstance()
  1536. {
  1537. delete [] m_wszClassName;
  1538. }
  1539. // *****************************************************************************
  1540. // Used to determine if this object is the input arguement list of a method.
  1541. // That can be determined by checking if any of the properties have a "IN" qualifier
  1542. // *****************************************************************************
  1543. BOOL CMoInstance::IsInput()
  1544. {
  1545. for(int iCnt = 0; iCnt < GetNumProperties(); iCnt++)
  1546. {
  1547. CMoProperty* pProp = GetProperty(iCnt);
  1548. CMoQualifierArray* pQual = pProp->GetQualifiers();
  1549. if(pQual->Find(L"IN"))
  1550. return TRUE;
  1551. }
  1552. return FALSE;
  1553. }
  1554. HRESULT CMoInstance::CreateWbemObject(READ_ONLY IWbemServices* pNamespace,
  1555. RELEASE_ME IWbemClassObject** ppObject, IWbemContext * pCtx)
  1556. {
  1557. // Get the class from WINMGMT
  1558. // =======================
  1559. IWbemClassObject* pClass = NULL;
  1560. BSTR strClassName = SysAllocString(m_wszClassName);
  1561. if(strClassName == NULL)
  1562. {
  1563. return WBEM_E_OUT_OF_MEMORY;
  1564. }
  1565. m_pDbg->SetString(strClassName);
  1566. HRESULT hres = pNamespace->GetObject(strClassName, 0, pCtx, &pClass, NULL);
  1567. SysFreeString(strClassName);
  1568. if(FAILED(hres)) return hres;
  1569. // Spawn a new instance
  1570. // ====================
  1571. hres = pClass->SpawnInstance(0, ppObject);
  1572. pClass->Release();
  1573. return hres;
  1574. }
  1575. HRESULT CMoInstance::StoreWbemObject(READ_ONLY IWbemClassObject* pObject,
  1576. long lClassFlags, long lInstanceFlags,
  1577. OLE_MODIFY IWbemServices* pNamespace, IWbemContext * pCtx,
  1578. WCHAR * pUserName, WCHAR * pPassword, WCHAR * pAuthority)
  1579. {
  1580. IWbemCallResult *pCallResult = NULL;
  1581. SCODE scRet = pNamespace->PutInstance(pObject, lInstanceFlags, pCtx,
  1582. (m_wszAlias) ? &pCallResult : NULL);
  1583. if(scRet == S_OK && pCallResult)
  1584. {
  1585. BSTR bstr = NULL;
  1586. DWORD dwAuthLevel, dwImpLevel;
  1587. SCODE sc = GetAuthImp( pNamespace, &dwAuthLevel, &dwImpLevel);
  1588. if(sc == S_OK)
  1589. if(dwAuthLevel != RPC_C_AUTHN_LEVEL_NONE)
  1590. sc = MofdSetInterfaceSecurity(
  1591. pCallResult,
  1592. pAuthority,
  1593. (pUserName && wcslen(pUserName) > 0) ? pUserName : NULL ,
  1594. pPassword);
  1595. else
  1596. sc = WbemSetProxyBlanket(pCallResult, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
  1597. NULL, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE,NULL, 0);
  1598. scRet = pCallResult->GetResultString(9999, &bstr);
  1599. if(sc == S_OK && scRet == S_OK && bstr)
  1600. {
  1601. SetFullPath(bstr);
  1602. SysFreeString(bstr);
  1603. }
  1604. pCallResult->Release();
  1605. }
  1606. return scRet;
  1607. }
  1608. CMethodProperty::CMethodProperty(CMoQualifierArray * paQualifiers, PDBG pDbg, BOOL bBinary)
  1609. :CMoProperty(paQualifiers, pDbg)
  1610. {
  1611. m_pDbg = pDbg;
  1612. m_pInObj = NULL;
  1613. m_pOutObj = NULL;
  1614. m_IDType = UNSPECIFIED; // Gets set on first argument
  1615. m_NextAutoID = 0;
  1616. m_bBinaryMof = bBinary;
  1617. }
  1618. CValueProperty::CValueProperty(CMoQualifierArray * paQualifiers, PDBG pDbg)
  1619. :CMoProperty(paQualifiers, pDbg)
  1620. {
  1621. m_pDbg = pDbg;
  1622. m_bIsArg = FALSE;
  1623. }
  1624. CMethodProperty::~CMethodProperty()
  1625. {
  1626. VARIANT & var = m_Value.AccessVariant();
  1627. var.vt = VT_EMPTY;
  1628. if(m_pInObj != NULL)
  1629. delete m_pInObj;
  1630. if(m_pOutObj != NULL)
  1631. delete m_pOutObj;
  1632. for(int i = 0; i < m_Args.GetSize(); i++)
  1633. {
  1634. CValueProperty * pProp = (CValueProperty *)m_Args[i];
  1635. CMoProperty * pProp2 = (CMoProperty *)m_Args[i];
  1636. delete (CValueProperty *)m_Args[i];
  1637. }
  1638. m_Args.RemoveAll();
  1639. }
  1640. BOOL CMethodProperty::AddToObject(OLE_MODIFY IWbemClassObject* pObject, IWbemServices* pNamespace, BOOL bClass, IWbemContext * pCtx)
  1641. {
  1642. IWbemClassObject * pIn = NULL;
  1643. IWbemClassObject * pOut = NULL;
  1644. if(m_pInObj)
  1645. {
  1646. pIn = GetInstPtr(L"__PARAMETERS", pNamespace, m_pInObj, pCtx);
  1647. if(pIn == NULL)
  1648. return FALSE;
  1649. }
  1650. if(m_pOutObj)
  1651. {
  1652. pOut = GetInstPtr(L"__PARAMETERS", pNamespace, m_pOutObj, pCtx);
  1653. if(pOut == NULL)
  1654. return FALSE;
  1655. }
  1656. SCODE sc = pObject->PutMethod(GetName(), 0, pIn, pOut);
  1657. if(pIn)
  1658. pIn->Release();
  1659. if(pOut)
  1660. pOut->Release();
  1661. if(FAILED(sc))
  1662. {
  1663. m_pDbg->hresError = sc;
  1664. return FALSE;
  1665. }
  1666. if(!GetQualifiers()->AddToPropOrMeth(pObject, m_wszName, bClass, FALSE))
  1667. {
  1668. return FALSE;
  1669. }
  1670. return sc == S_OK;
  1671. }
  1672. /////////////////////////////////////////////////////////////////////////////////////////////
  1673. //
  1674. // Creates a new qualifier set which is a copy of the source.
  1675. //
  1676. /////////////////////////////////////////////////////////////////////////////////////////////
  1677. CMoQualifierArray * CreateArgQualifierList(BOOL bInput, CMoQualifierArray *pSrcQualifiers, PDBG pDbg)
  1678. {
  1679. if(pSrcQualifiers == NULL)
  1680. return NULL;
  1681. std::auto_ptr<CMoQualifierArray> pRet (new CMoQualifierArray (pDbg));
  1682. if (pRet.get() == NULL)
  1683. return NULL;
  1684. for(int iCnt = 0; iCnt < pSrcQualifiers->GetSize(); iCnt++)
  1685. {
  1686. CMoQualifier* pSrc = pSrcQualifiers->GetAt(iCnt);
  1687. if(pSrc == NULL)
  1688. continue;
  1689. // If this is for input, dont copy out qualifiers, and vice versa!
  1690. if(bInput && !wbem_wcsicmp(pSrc->GetName(), L"OUT"))
  1691. continue;
  1692. if(!bInput && !wbem_wcsicmp(pSrc->GetName(), L"IN"))
  1693. continue;
  1694. // Create the new qualifier, copy the values from the existing one
  1695. std::auto_ptr<CMoQualifier> pQual (new CMoQualifier(pDbg));
  1696. if(pQual.get() == NULL)
  1697. return NULL;
  1698. // if(pSrc->IsRestricted())
  1699. // pQual->SetRestricted();
  1700. pQual->SetFlavor(pSrc->GetFlavor());
  1701. // if(pSrc->IsOverrideSet())
  1702. // pQual->OverrideSet();
  1703. if(FAILED(pQual->SetQualName(pSrc->GetName())))
  1704. return NULL;
  1705. pQual->SetType(pSrc->GetType());
  1706. VARIANT * pSrcVar = pSrc->GetpVar();
  1707. HRESULT hr = WbemVariantChangeType(pQual->GetpVar(), pSrcVar, pSrcVar->vt);
  1708. if (SUCCEEDED (hr))
  1709. {
  1710. // Add the new qualifier to the new set
  1711. pRet->Add (pQual.release());
  1712. }
  1713. else
  1714. {
  1715. return NULL;
  1716. }
  1717. }
  1718. return pRet.release();
  1719. }
  1720. bool CMethodProperty::IsIDSpecified(CMoQualifierArray * paQualifiers)
  1721. {
  1722. int iSize = paQualifiers->GetSize();
  1723. for(int iCnt = 0; iCnt < iSize; iCnt++)
  1724. {
  1725. CMoQualifier* pTest = paQualifiers->GetAt(iCnt);
  1726. if(pTest == NULL || wbem_wcsicmp(pTest->GetName(), L"ID"))
  1727. continue;
  1728. VARIANT * pVar = pTest->GetpVar();
  1729. if(pVar->vt != VT_I4)
  1730. m_IDType = INVALID;
  1731. return true;
  1732. }
  1733. return false;
  1734. }
  1735. /////////////////////////////////////////////////////////////////////////////////////////////
  1736. //
  1737. // This takes a method argument and adds it to either the input or output arguement object
  1738. //
  1739. /////////////////////////////////////////////////////////////////////////////////////////////
  1740. BOOL CMethodProperty::AddIt(WString & sName, CMoType & Type, BOOL bInput,
  1741. CMoQualifierArray * paQualifiers, VARIANT * pVar,
  1742. CMoValue & Value, BOOL bRetValue, BOOL bSecondPass)
  1743. {
  1744. HRESULT hr;
  1745. // Except for the return value, all parameters must have an ID. We support both the automatic
  1746. // generation of IDs, as well as allowing the explicit settings of IDs. However, doing both
  1747. // in a method is not allowed
  1748. if(!bRetValue && !bSecondPass)
  1749. {
  1750. // Better have a qual set!
  1751. if(paQualifiers == NULL)
  1752. return FALSE;
  1753. if(IsIDSpecified(paQualifiers)) // find it was explicitly set
  1754. {
  1755. // Explicity set. Just pass it along to fastprox as is. Note that if we
  1756. if(m_IDType == AUTOMATIC || m_IDType == INVALID)
  1757. return FALSE;
  1758. m_IDType = MANUAL;
  1759. }
  1760. else
  1761. {
  1762. // The IDs must be set automatically
  1763. if(m_IDType == MANUAL || m_IDType == INVALID)
  1764. return FALSE;
  1765. m_IDType = AUTOMATIC;
  1766. // Add a new qualifier to this
  1767. CMoQualifier * pNew = new CMoQualifier(m_pDbg);
  1768. if(pNew == NULL)
  1769. return FALSE;
  1770. if(FAILED(pNew->SetQualName(L"ID")))
  1771. {
  1772. delete pNew;
  1773. return FALSE;
  1774. }
  1775. pNew->SetFlavor(WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE |
  1776. WBEM_FLAVOR_NOT_OVERRIDABLE);
  1777. VARIANT * pVar2 = pNew->GetpVar();
  1778. pVar2->vt = VT_I4;
  1779. pVar2->lVal = m_NextAutoID++;
  1780. paQualifiers->Add(pNew);
  1781. }
  1782. }
  1783. // Get a pointer to either the input or output object. In either case, the object
  1784. // will need to be created if this is the first property being added to it.
  1785. CMoInstance * pObj = NULL;
  1786. if(bInput)
  1787. {
  1788. if(m_pInObj == NULL)
  1789. {
  1790. m_pInObj = new CMoInstance(L"__PARAMETERS", m_pDbg, true);
  1791. if(m_pInObj == NULL)
  1792. return FALSE;
  1793. if(m_pInObj->IsOK() == false)
  1794. {
  1795. delete m_pInObj;
  1796. return FALSE;
  1797. }
  1798. }
  1799. pObj = m_pInObj;
  1800. }
  1801. else
  1802. {
  1803. if(m_pOutObj == NULL)
  1804. {
  1805. m_pOutObj = new CMoInstance(L"__PARAMETERS", m_pDbg ,true);
  1806. if(m_pOutObj == NULL)
  1807. return FALSE;
  1808. if(m_pOutObj->IsOK() == false)
  1809. {
  1810. delete m_pOutObj;
  1811. return FALSE;
  1812. }
  1813. }
  1814. pObj = m_pOutObj;
  1815. }
  1816. if(pObj == NULL)
  1817. return FALSE;
  1818. // If the property doesnt have a qualifier set, as would be the case for the retvalue,
  1819. // create one
  1820. CMoQualifierArray * pQualifiers = NULL;
  1821. if(paQualifiers == NULL)
  1822. pQualifiers = new CMoQualifierArray(m_pDbg);
  1823. else
  1824. pQualifiers = CreateArgQualifierList(bInput, paQualifiers, m_pDbg);
  1825. if(pQualifiers == NULL)
  1826. return FALSE;
  1827. // Create a new value property
  1828. CValueProperty * pNewProp = new CValueProperty(pQualifiers, m_pDbg);
  1829. if(pNewProp == NULL){
  1830. delete pQualifiers;
  1831. return FALSE;
  1832. }
  1833. VARTYPE vt = Type.GetCIMType();
  1834. if(FAILED(pNewProp->SetPropName(sName)))
  1835. {
  1836. delete pNewProp;
  1837. return FALSE;
  1838. }
  1839. pNewProp->SetAsArg();
  1840. Type.StoreIntoQualifiers(pQualifiers);
  1841. VARIANT * pDest;
  1842. pDest = pNewProp->GetpVar();
  1843. if(pVar && pVar->vt != VT_EMPTY && pVar->vt != VT_NULL)
  1844. {
  1845. VARTYPE vtSimple = pVar->vt & ~VT_ARRAY;
  1846. if(vtSimple != VT_EMBEDDED_OBJECT || pVar->vt == (VT_EMBEDDED_OBJECT | VT_ARRAY))
  1847. {
  1848. hr = VariantCopy(pDest, pVar);
  1849. if(FAILED(hr))
  1850. return FALSE;
  1851. }
  1852. else
  1853. {
  1854. pDest->vt = VT_EMBEDDED_OBJECT;
  1855. pDest->punkVal = pVar->punkVal;
  1856. }
  1857. }
  1858. pNewProp->SetType(vt);
  1859. // If the original value contains some aliases, make sure they get added
  1860. CMoValue & Dest = pNewProp->AccessValue();
  1861. for(int i = 0; i < Value.GetNumAliases(); i++)
  1862. {
  1863. LPWSTR wszAlias;
  1864. int nArrayIndex;
  1865. if(Value.GetAlias(i, wszAlias, nArrayIndex))
  1866. {
  1867. hr = Dest.AddAlias(wszAlias, nArrayIndex);
  1868. if(FAILED(hr))
  1869. return FALSE;
  1870. }
  1871. }
  1872. pObj->AddProperty(pNewProp);
  1873. return TRUE;
  1874. }
  1875. BOOL CMethodProperty::AddToArgObjects(CMoQualifierArray * paQualifiers, WString & sName,
  1876. CMoType & Type, BOOL bRetValue, int & ErrCtx, VARIANT * pVar,
  1877. CMoValue & Value)
  1878. {
  1879. // if return value and it is null or void, just bail out
  1880. if(Type.IsDefined() == FALSE && bRetValue)
  1881. return TRUE;
  1882. // Determine which arg list this goes into
  1883. BOOL bGoesIntoInputs = FALSE;
  1884. BOOL bGoesIntoOutputs = FALSE;
  1885. if( bRetValue)
  1886. bGoesIntoOutputs = TRUE;
  1887. else
  1888. {
  1889. // Loop through the arg list.
  1890. if(paQualifiers == NULL)
  1891. return FALSE;
  1892. if(paQualifiers->Find(L"IN"))
  1893. bGoesIntoInputs = TRUE;
  1894. if(paQualifiers->Find(L"OUT"))
  1895. bGoesIntoOutputs = TRUE;
  1896. }
  1897. // make sure it isnt already on the list
  1898. if(bGoesIntoInputs && m_pInObj && m_pInObj->GetPropertyByName(sName))
  1899. return FALSE;
  1900. if(bGoesIntoOutputs && m_pOutObj && m_pOutObj->GetPropertyByName(sName))
  1901. return FALSE;
  1902. if(bGoesIntoInputs == FALSE && bGoesIntoOutputs == FALSE)
  1903. {
  1904. ErrCtx = WBEMMOF_E_MUST_BE_IN_OR_OUT;
  1905. return FALSE;
  1906. }
  1907. // Create the object(s) if necessary
  1908. if(bGoesIntoInputs)
  1909. if(!AddIt(sName, Type, TRUE, paQualifiers, pVar, Value, bRetValue, FALSE))
  1910. return FALSE;
  1911. if(bGoesIntoOutputs)
  1912. return AddIt(sName, Type, FALSE, paQualifiers, pVar, Value, bRetValue, bGoesIntoInputs);
  1913. else
  1914. return TRUE;
  1915. }
  1916. CMoActionPragma::CMoActionPragma(COPY LPCWSTR wszClassName, PDBG pDbg, bool bFail, BOOL bClass)
  1917. {
  1918. m_pDbg = pDbg;
  1919. m_wszClassName = Macro_CloneStr(wszClassName);
  1920. if(m_wszClassName == NULL && wszClassName != NULL)
  1921. m_bOK = false;
  1922. m_bFail = bFail;
  1923. m_bClass = bClass;
  1924. }
  1925. CMoActionPragma::~CMoActionPragma()
  1926. {
  1927. delete [] m_wszClassName;
  1928. }
  1929. HRESULT CMoActionPragma::StoreWbemObject(READ_ONLY IWbemClassObject* pObject,
  1930. long lClassFlags, long lInstanceFlags,
  1931. OLE_MODIFY IWbemServices* pNamespace, IWbemContext * pCtx,
  1932. WCHAR * pUserName, WCHAR * pPassword, WCHAR * pAuthority)
  1933. {
  1934. if(m_wszClassName == NULL || wcslen(m_wszClassName) < 1)
  1935. return WBEM_E_FAILED;
  1936. BSTR bstr = SysAllocString(m_wszClassName);
  1937. if(bstr)
  1938. {
  1939. SCODE sc;
  1940. if(m_bClass)
  1941. sc = pNamespace->DeleteClass(bstr, 0, NULL, NULL);
  1942. else
  1943. sc = pNamespace->DeleteInstance(bstr, 0, NULL, NULL);
  1944. SysFreeString(bstr);
  1945. if(!m_bFail)
  1946. return S_OK;
  1947. else
  1948. {
  1949. if(FAILED(sc))
  1950. wcsncpy(m_pDbg->m_wcError, m_wszClassName, 99);
  1951. return sc;
  1952. }
  1953. }
  1954. else
  1955. return WBEM_E_OUT_OF_MEMORY;
  1956. }