Source code of Windows XP (NT5)
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.

1572 lines
39 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. pusher.cpp
  5. Abstract:
  6. This file contains the implementation of the CPusher class.
  7. This class contains the logic for pushing schema to the repository.
  8. Author:
  9. Mohit Srivastava 28-Nov-00
  10. Revision History:
  11. --*/
  12. #include "iisprov.h"
  13. #include "pusher.h"
  14. #include "MultiSzData.h"
  15. extern CDynSchema* g_pDynSch; // Initialized to NULL in schemadynamic.cpp
  16. HRESULT CPusher::RepositoryInSync(
  17. const CSchemaExtensions* i_pCatalog,
  18. bool* io_pbInSync)
  19. {
  20. DBG_ASSERT(m_bInitSuccessful == true);
  21. DBG_ASSERT(io_pbInSync != NULL);
  22. DBG_ASSERT(i_pCatalog != NULL);
  23. HRESULT hr = WBEM_S_NO_ERROR;
  24. CComBSTR sbstrTemp;
  25. CComVariant svtTimeStamp;
  26. CComPtr<IWbemClassObject> spObjIIsComputer;
  27. sbstrTemp = WMI_CLASS_DATA::s_Computer.pszClassName;
  28. if(sbstrTemp.m_str == NULL)
  29. {
  30. return WBEM_E_OUT_OF_MEMORY;
  31. }
  32. hr = m_pNamespace->GetObject(sbstrTemp, 0, m_pCtx, &spObjIIsComputer, NULL);
  33. if(FAILED(hr))
  34. {
  35. return hr;
  36. }
  37. //
  38. // Try to get timestamp from repository
  39. //
  40. hr = CUtils::GetQualifiers(spObjIIsComputer, &g_wszCq_SchemaTS, &svtTimeStamp, 1);
  41. if(FAILED(hr) || svtTimeStamp.vt != VT_BSTR)
  42. {
  43. *io_pbInSync = false;
  44. return WBEM_S_NO_ERROR;
  45. }
  46. //
  47. // Get timestamp of mbschema.xml
  48. //
  49. FILETIME FileTime;
  50. hr = i_pCatalog->GetMbSchemaTimeStamp(&FileTime);
  51. if(FAILED(hr))
  52. {
  53. return hr;
  54. }
  55. //
  56. // Finally, compare the timestamps
  57. //
  58. WCHAR wszFileTime[30];
  59. CUtils::FileTimeToWchar(&FileTime, wszFileTime);
  60. if(_wcsicmp(wszFileTime, svtTimeStamp.bstrVal) == 0)
  61. {
  62. *io_pbInSync = true;
  63. }
  64. else
  65. {
  66. *io_pbInSync = false;
  67. }
  68. return hr;
  69. }
  70. HRESULT CPusher::SetTimeStamp(
  71. const CSchemaExtensions* i_pCatalog)
  72. {
  73. DBG_ASSERT(m_bInitSuccessful == true);
  74. DBG_ASSERT(i_pCatalog != NULL);
  75. HRESULT hr = WBEM_S_NO_ERROR;
  76. CComBSTR sbstrTemp;
  77. CComVariant svtTimeStamp;
  78. CComPtr<IWbemClassObject> spObjIIsComputer;
  79. sbstrTemp = WMI_CLASS_DATA::s_Computer.pszClassName;
  80. if(sbstrTemp.m_str == NULL)
  81. {
  82. return WBEM_E_OUT_OF_MEMORY;
  83. }
  84. hr = m_pNamespace->GetObject(sbstrTemp, 0, m_pCtx, &spObjIIsComputer, NULL);
  85. if(FAILED(hr))
  86. {
  87. return hr;
  88. }
  89. //
  90. // Get timestamp of mbschema.xml
  91. //
  92. FILETIME FileTime;
  93. hr = i_pCatalog->GetMbSchemaTimeStamp(&FileTime);
  94. if(FAILED(hr))
  95. {
  96. return hr;
  97. }
  98. WCHAR wszFileTime[30];
  99. CUtils::FileTimeToWchar(&FileTime, wszFileTime);
  100. //
  101. // Finally, Set the timestamp in the repository
  102. //
  103. svtTimeStamp = wszFileTime;
  104. if(svtTimeStamp.vt != VT_BSTR || svtTimeStamp.bstrVal == NULL)
  105. {
  106. return WBEM_E_OUT_OF_MEMORY;
  107. }
  108. hr = CUtils::SetQualifiers(
  109. spObjIIsComputer,
  110. &g_wszCq_SchemaTS,
  111. &svtTimeStamp,
  112. 1,
  113. 0);
  114. if(FAILED(hr))
  115. {
  116. return hr;
  117. }
  118. //
  119. // Finally, put the class
  120. //
  121. hr = m_pNamespace->PutClass(spObjIIsComputer, WBEM_FLAG_OWNER_UPDATE, m_pCtx, NULL);
  122. if(FAILED(hr))
  123. {
  124. return hr;
  125. }
  126. return hr;
  127. }
  128. HRESULT CPusher::Initialize(CWbemServices* i_pNamespace,
  129. IWbemContext* i_pCtx)
  130. /*++
  131. Synopsis:
  132. Only call once.
  133. Arguments: [i_pNamespace] -
  134. [i_pCtx] -
  135. Return Value:
  136. --*/
  137. {
  138. DBG_ASSERT(i_pNamespace != NULL);
  139. DBG_ASSERT(i_pCtx != NULL);
  140. DBG_ASSERT(m_bInitCalled == false);
  141. DBG_ASSERT(m_bInitSuccessful == false);
  142. HRESULT hr = WBEM_S_NO_ERROR;
  143. CComBSTR bstrTemp;
  144. m_bInitCalled = true;
  145. m_pCtx = i_pCtx;
  146. m_pNamespace = i_pNamespace;
  147. m_awszClassQualNames[1] = g_wszCq_Dynamic;
  148. m_avtClassQualValues[1] = (bool)true;
  149. m_awszClassQualNames[0] = g_wszCq_Provider;
  150. m_avtClassQualValues[0] = g_wszCqv_Provider;;
  151. if(m_avtClassQualValues[0].bstrVal == NULL)
  152. {
  153. hr = WBEM_E_OUT_OF_MEMORY;
  154. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  155. goto exit;
  156. }
  157. //
  158. // Get pointers to most commonly used base classes
  159. //
  160. bstrTemp = g_wszExtElementParent;
  161. if(bstrTemp.m_str == NULL)
  162. {
  163. hr = WBEM_E_OUT_OF_MEMORY;
  164. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  165. goto exit;
  166. }
  167. hr = m_pNamespace->GetObject(bstrTemp, 0, m_pCtx, &m_spBaseElementObject, NULL);
  168. if(FAILED(hr))
  169. {
  170. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  171. goto exit;
  172. }
  173. bstrTemp = g_wszExtSettingParent;
  174. if(bstrTemp.m_str == NULL)
  175. {
  176. hr = WBEM_E_OUT_OF_MEMORY;
  177. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  178. goto exit;
  179. }
  180. hr = m_pNamespace->GetObject(bstrTemp, 0, m_pCtx, &m_spBaseSettingObject, NULL);
  181. if(FAILED(hr))
  182. {
  183. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  184. goto exit;
  185. }
  186. bstrTemp = g_wszExtElementSettingAssocParent;
  187. if(bstrTemp.m_str == NULL)
  188. {
  189. hr = WBEM_E_OUT_OF_MEMORY;
  190. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  191. goto exit;
  192. }
  193. hr = m_pNamespace->GetObject(bstrTemp, 0, m_pCtx, &m_spBaseElementSettingObject, NULL);
  194. if(FAILED(hr))
  195. {
  196. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  197. goto exit;
  198. }
  199. bstrTemp = g_wszExtGroupPartAssocParent;
  200. if(bstrTemp.m_str == NULL)
  201. {
  202. hr = WBEM_E_OUT_OF_MEMORY;
  203. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  204. goto exit;
  205. }
  206. hr = m_pNamespace->GetObject(bstrTemp, 0, m_pCtx, &m_spBaseGroupPartObject, NULL);
  207. if(FAILED(hr))
  208. {
  209. DBGPRINTF((DBG_CONTEXT, "CPusher::Initialize failed, hr=0x%x\n", hr));
  210. goto exit;
  211. }
  212. exit:
  213. if(SUCCEEDED(hr))
  214. {
  215. m_bInitSuccessful = true;
  216. }
  217. return hr;
  218. }
  219. CPusher::~CPusher()
  220. {
  221. }
  222. HRESULT CPusher::Push(
  223. const CSchemaExtensions* i_pCatalog,
  224. CHashTable<WMI_CLASS *>* i_phashClasses,
  225. CHashTable<WMI_ASSOCIATION*>* i_phashAssocs)
  226. {
  227. DBG_ASSERT(i_pCatalog != NULL);
  228. DBG_ASSERT(i_phashClasses != NULL);
  229. DBG_ASSERT(i_phashAssocs != NULL);
  230. DBG_ASSERT(m_bInitSuccessful == true);
  231. HRESULT hr = WBEM_S_NO_ERROR;
  232. bool bInSync= false;
  233. hr = RepositoryInSync(i_pCatalog, &bInSync);
  234. if(FAILED(hr))
  235. {
  236. return hr;
  237. }
  238. if(!bInSync)
  239. {
  240. hr = PushClasses(i_phashClasses);
  241. if(FAILED(hr))
  242. {
  243. DBGPRINTF((DBG_CONTEXT, "CPusher::Push failed, hr=0x%x\n", hr));
  244. return hr;
  245. }
  246. hr = PushAssocs(i_phashAssocs);
  247. if(FAILED(hr))
  248. {
  249. DBGPRINTF((DBG_CONTEXT, "CPusher::Push failed, hr=0x%x\n", hr));
  250. return hr;
  251. }
  252. hr = SetTimeStamp(i_pCatalog);
  253. if(FAILED(hr))
  254. {
  255. DBGPRINTF((DBG_CONTEXT, "CPusher::Push failed, hr=0x%x\n", hr));
  256. return hr;
  257. }
  258. }
  259. return hr;
  260. }
  261. HRESULT CPusher::PushClasses(
  262. CHashTable<WMI_CLASS *>* i_phashTable)
  263. /*++
  264. Synopsis:
  265. Public function to push classes to repository.
  266. 1) Precondition: All USER_DEFINED_TO_REPOSITORY classes are not in repository.
  267. 2) Pushes all USER_DEFINED_TO_REPOSITORY classes to repository.
  268. 3) Deletes and recreates SHIPPED_TO_MOF, SHIPPED_NOT_TO_MOF, and
  269. EXTENDED classes if necessary.
  270. Arguments: [i_phashTable] -
  271. Return Value:
  272. --*/
  273. {
  274. DBG_ASSERT(i_phashTable != NULL);
  275. DBG_ASSERT(m_pNamespace != NULL);
  276. DBG_ASSERT(m_bInitSuccessful == true);
  277. HRESULT hr = WBEM_S_NO_ERROR;
  278. CComPtr<IWbemClassObject> spObject = NULL;
  279. CComPtr<IWbemClassObject> spChildObject = NULL;
  280. //
  281. // Vars needed for iteration
  282. //
  283. CHashTable<WMI_CLASS*>::Record* pRec = NULL;
  284. CHashTable<WMI_CLASS*>::iterator iter;
  285. CHashTable<WMI_CLASS*>::iterator iterEnd;
  286. CComVariant v;
  287. //
  288. // DeleteChildren of extended base classes
  289. //
  290. LPWSTR awszBaseClasses[] = {
  291. g_wszExtElementParent,
  292. g_wszExtSettingParent,
  293. NULL };
  294. for(ULONG idx = 0; awszBaseClasses[idx] != NULL; idx++)
  295. {
  296. hr = DeleteChildren(awszBaseClasses[idx]);
  297. if(FAILED(hr))
  298. {
  299. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  300. goto exit;
  301. }
  302. }
  303. //
  304. // Walk thru the hashtable of classes
  305. //
  306. bool bPutNeeded;
  307. iterEnd = i_phashTable->end();
  308. for(iter = i_phashTable->begin(); iter != iterEnd; ++iter)
  309. {
  310. pRec = iter.Record();
  311. DBG_ASSERT(pRec != NULL);
  312. //
  313. // Deletes SHIPPED_TO_MOF, SHIPPED_NOT_TO_MOF, EXTENDED classes if necessary.
  314. //
  315. hr = PrepareForPutClass(pRec->m_data, &bPutNeeded);
  316. if(FAILED(hr))
  317. {
  318. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  319. goto exit;
  320. }
  321. if(bPutNeeded)
  322. {
  323. hr = GetObject(pRec->m_data->pszParentClass, &spObject);
  324. if(FAILED(hr))
  325. {
  326. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  327. goto exit;
  328. }
  329. hr = spObject->SpawnDerivedClass(0, &spChildObject);
  330. if(FAILED(hr))
  331. {
  332. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  333. goto exit;
  334. }
  335. spObject = NULL;
  336. //
  337. // Push class qualifiers and special __CLASS property.
  338. //
  339. hr = SetClassInfo(
  340. spChildObject,
  341. pRec->m_wszKey,
  342. pRec->m_data->dwExtended);
  343. if(FAILED(hr))
  344. {
  345. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  346. goto exit;
  347. }
  348. //
  349. // Name property and corresponding qualifier
  350. // Base class may contain Name. Handle this case
  351. //
  352. bool bPutNameProperty = true;
  353. for(ULONG j = 0; g_awszParentClassWithNamePK[j] != NULL; j++)
  354. {
  355. //
  356. // Deliberate ==
  357. //
  358. if(g_awszParentClassWithNamePK[j] == pRec->m_data->pszParentClass)
  359. {
  360. bPutNameProperty = false;
  361. }
  362. }
  363. if( bPutNameProperty )
  364. {
  365. hr = spChildObject->Put(g_wszProp_Name, 0, NULL, CIM_STRING);
  366. if(FAILED(hr))
  367. {
  368. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  369. goto exit;
  370. }
  371. v = (bool)true;
  372. hr = CUtils::SetPropertyQualifiers(
  373. spChildObject,
  374. g_wszProp_Name, // Property name
  375. &g_wszPq_Key, // Array of qual names
  376. &v, // Array of qual values
  377. 1 // Nr of quals
  378. );
  379. if(FAILED(hr))
  380. {
  381. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  382. goto exit;
  383. }
  384. }
  385. //
  386. // All other properties
  387. //
  388. hr = SetProperties(pRec->m_data, spChildObject);
  389. if(FAILED(hr))
  390. {
  391. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  392. goto exit;
  393. }
  394. //
  395. // Any methods
  396. //
  397. hr = SetMethods(pRec->m_data, spChildObject);
  398. if(FAILED(hr))
  399. {
  400. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  401. goto exit;
  402. }
  403. //
  404. // Finally, put the class
  405. //
  406. hr = m_pNamespace->PutClass(spChildObject, WBEM_FLAG_OWNER_UPDATE, m_pCtx, NULL);
  407. if(FAILED(hr))
  408. {
  409. DBGPRINTF((DBG_CONTEXT, "CPusher::PushClasses failed, hr=0x%x\n", hr));
  410. goto exit;
  411. }
  412. spChildObject = NULL;
  413. }
  414. }
  415. exit:
  416. return hr;
  417. }
  418. HRESULT CPusher::PushAssocs(
  419. CHashTable<WMI_ASSOCIATION*>* i_phashTable)
  420. /*++
  421. Synopsis:
  422. Public function to push assocs to repository.
  423. - Precondition: All USER_DEFINED_TO_REPOSITORY assocs are not in repository.
  424. - Pushes all USER_DEFINED_TO_REPOSITORY assocs to repository.
  425. Arguments: [i_phashTable] -
  426. Return Value:
  427. --*/
  428. {
  429. DBG_ASSERT(i_phashTable != NULL);
  430. DBG_ASSERT(m_pNamespace != NULL);
  431. DBG_ASSERT(m_bInitSuccessful == true);
  432. HRESULT hr = WBEM_S_NO_ERROR;
  433. CComPtr<IWbemClassObject> spObject = NULL;
  434. CComPtr<IWbemClassObject> spChildObject = NULL;
  435. //
  436. // Vars needed for iteration
  437. //
  438. CHashTable<WMI_ASSOCIATION*>::Record* pRec = NULL;
  439. CHashTable<WMI_ASSOCIATION*>::iterator iter;
  440. CHashTable<WMI_ASSOCIATION*>::iterator iterEnd;
  441. //
  442. // DeleteChildren of extended base classes
  443. //
  444. LPWSTR awszBaseClasses[] = {
  445. g_wszExtElementSettingAssocParent,
  446. g_wszExtGroupPartAssocParent,
  447. NULL };
  448. for(ULONG idx = 0; awszBaseClasses[idx] != NULL; idx++)
  449. {
  450. hr = DeleteChildren(awszBaseClasses[idx]);
  451. if(FAILED(hr))
  452. {
  453. DBGPRINTF((DBG_CONTEXT, "CPusher::PushAssocs failed, hr=0x%x\n", hr));
  454. goto exit;
  455. }
  456. }
  457. //
  458. // Walk thru the hashtable of assocs
  459. //
  460. for(iter = i_phashTable->begin(), iterEnd = i_phashTable->end();
  461. iter != iterEnd;
  462. ++iter)
  463. {
  464. pRec = iter.Record();
  465. if(FAILED(hr))
  466. {
  467. DBGPRINTF((DBG_CONTEXT, "CPusher::PushAssocs failed, hr=0x%x\n", hr));
  468. goto exit;
  469. }
  470. if(pRec->m_data->dwExtended == USER_DEFINED_TO_REPOSITORY)
  471. {
  472. hr = GetObject(pRec->m_data->pszParentClass, &spObject);
  473. if(FAILED(hr))
  474. {
  475. DBGPRINTF((DBG_CONTEXT, "CPusher::PushAssocs failed, hr=0x%x\n", hr));
  476. goto exit;
  477. }
  478. hr = spObject->SpawnDerivedClass(0, &spChildObject);
  479. if(FAILED(hr))
  480. {
  481. DBGPRINTF((DBG_CONTEXT, "CPusher::PushAssocs failed, hr=0x%x\n", hr));
  482. goto exit;
  483. }
  484. spObject = NULL;
  485. //
  486. // Push class qualifiers and special __CLASS property.
  487. //
  488. hr = SetClassInfo(
  489. spChildObject,
  490. pRec->m_wszKey,
  491. pRec->m_data->dwExtended);
  492. if(FAILED(hr))
  493. {
  494. DBGPRINTF((DBG_CONTEXT, "CPusher::PushAssocs failed, hr=0x%x\n", hr));
  495. goto exit;
  496. }
  497. //
  498. // Push the two ref properties of the association.
  499. //
  500. hr = SetAssociationComponent(
  501. spChildObject,
  502. pRec->m_data->pType->pszLeft,
  503. pRec->m_data->pcLeft->pszClassName);
  504. if(FAILED(hr))
  505. {
  506. DBGPRINTF((DBG_CONTEXT, "CPusher::PushAssocs failed, hr=0x%x\n", hr));
  507. goto exit;
  508. }
  509. hr = SetAssociationComponent(
  510. spChildObject,
  511. pRec->m_data->pType->pszRight,
  512. pRec->m_data->pcRight->pszClassName);
  513. if(FAILED(hr))
  514. {
  515. DBGPRINTF((DBG_CONTEXT, "CPusher::PushAssocs failed, hr=0x%x\n", hr));
  516. goto exit;
  517. }
  518. hr = m_pNamespace->PutClass(
  519. spChildObject,
  520. WBEM_FLAG_OWNER_UPDATE | WBEM_FLAG_CREATE_ONLY,
  521. m_pCtx,
  522. NULL);
  523. if(FAILED(hr))
  524. {
  525. if(hr == WBEM_E_ALREADY_EXISTS)
  526. {
  527. hr = WBEM_S_NO_ERROR;
  528. }
  529. else
  530. {
  531. DBGPRINTF((DBG_CONTEXT, "CPusher::PushAssocs failed, hr=0x%x\n", hr));
  532. goto exit;
  533. }
  534. }
  535. spChildObject = NULL;
  536. }
  537. }
  538. exit:
  539. return hr;
  540. }
  541. HRESULT CPusher::PrepareForPutClass(
  542. const WMI_CLASS* i_pClass,
  543. bool* io_pbPutNeeded)
  544. /*++
  545. Synopsis:
  546. Deletes and recreates SHIPPED_TO_MOF, SHIPPED_NOT_TO_MOF, and
  547. EXTENDED classes if necessary. Sets io_pbPutNeeded accordingly.
  548. Arguments: [i_pClass] -
  549. Return Value:
  550. --*/
  551. {
  552. DBG_ASSERT(m_bInitSuccessful == true);
  553. DBG_ASSERT(i_pClass != NULL);
  554. DBG_ASSERT(io_pbPutNeeded != NULL);
  555. HRESULT hr = WBEM_S_NO_ERROR;
  556. CComPtr<IWbemClassObject> spObj;
  557. CComBSTR bstrClass = i_pClass->pszClassName;
  558. if(bstrClass.m_str == NULL)
  559. {
  560. return WBEM_E_OUT_OF_MEMORY;
  561. }
  562. bool bExtendedQual = false;
  563. bool bPutNeeded = false;
  564. HRESULT hrGetObject = m_pNamespace->GetObject(
  565. bstrClass,
  566. WBEM_FLAG_RETURN_WBEM_COMPLETE,
  567. m_pCtx,
  568. &spObj,
  569. NULL);
  570. if( hrGetObject != WBEM_E_INVALID_CLASS &&
  571. hrGetObject != WBEM_E_NOT_FOUND)
  572. {
  573. hr = hrGetObject;
  574. }
  575. if(FAILED(hr))
  576. {
  577. return hr;
  578. }
  579. //
  580. // Determine if the [extended] qualifier is set.
  581. //
  582. if(SUCCEEDED(hrGetObject))
  583. {
  584. VARIANT vtExtended;
  585. VariantInit(&vtExtended);
  586. HRESULT hrGetQuals =
  587. CUtils::GetQualifiers(spObj, &g_wszCq_Extended, &vtExtended, 1);
  588. if(FAILED(hrGetQuals))
  589. {
  590. bExtendedQual = false;
  591. }
  592. else if(vtExtended.vt == VT_BOOL)
  593. {
  594. bExtendedQual = vtExtended.boolVal ? true : false;
  595. }
  596. }
  597. //
  598. // Pretty much, don't do a Put class if both the catalog and repository
  599. // versions are shipped. This is an optimization for the normal case.
  600. //
  601. switch(i_pClass->dwExtended)
  602. {
  603. case EXTENDED:
  604. if( hrGetObject != WBEM_E_INVALID_CLASS &&
  605. hrGetObject != WBEM_E_NOT_FOUND)
  606. {
  607. hr = m_pNamespace->DeleteClass(
  608. bstrClass,
  609. WBEM_FLAG_OWNER_UPDATE,
  610. m_pCtx,
  611. NULL);
  612. if(FAILED(hr))
  613. {
  614. return hr;
  615. }
  616. }
  617. bPutNeeded = true;
  618. break;
  619. case USER_DEFINED_NOT_TO_REPOSITORY:
  620. bPutNeeded = false;
  621. break;
  622. case USER_DEFINED_TO_REPOSITORY:
  623. if( hrGetObject != WBEM_E_INVALID_CLASS &&
  624. hrGetObject != WBEM_E_NOT_FOUND)
  625. {
  626. //
  627. // There is already a class in the repository with the same name
  628. // as this user-defined class.
  629. // TODO: Log an error.
  630. //
  631. bPutNeeded = false;
  632. }
  633. else
  634. {
  635. bPutNeeded = true;
  636. }
  637. break;
  638. case SHIPPED_TO_MOF:
  639. case SHIPPED_NOT_TO_MOF:
  640. if(bExtendedQual)
  641. {
  642. if( hrGetObject != WBEM_E_INVALID_CLASS &&
  643. hrGetObject != WBEM_E_NOT_FOUND)
  644. {
  645. hr = m_pNamespace->DeleteClass(
  646. bstrClass,
  647. WBEM_FLAG_OWNER_UPDATE,
  648. m_pCtx,
  649. NULL);
  650. if(FAILED(hr))
  651. {
  652. return hr;
  653. }
  654. }
  655. bPutNeeded = true;
  656. }
  657. else
  658. {
  659. bPutNeeded = (hrGetObject == WBEM_E_INVALID_CLASS ||
  660. hrGetObject == WBEM_E_NOT_FOUND) ? true : false;
  661. }
  662. break;
  663. default:
  664. DBG_ASSERT(false && "Unknown i_pClass->dwExtended");
  665. break;
  666. }
  667. *io_pbPutNeeded = bPutNeeded;
  668. return hr;
  669. }
  670. HRESULT CPusher::SetClassInfo(
  671. IWbemClassObject* i_pObj,
  672. LPCWSTR i_wszClassName,
  673. ULONG i_iShipped)
  674. /*++
  675. Synopsis:
  676. Sets class qualifiers and special __CLASS property on i_pObj
  677. Arguments: [i_pObj] - The class or association
  678. [i_wszClassName] - Will be value of __CLASS property
  679. [i_iShipped] - Determines if we set g_wszCq_Extended qualifier
  680. Return Value:
  681. --*/
  682. {
  683. DBG_ASSERT(i_pObj != NULL);
  684. DBG_ASSERT(i_wszClassName != NULL);
  685. DBG_ASSERT(m_bInitSuccessful == true);
  686. HRESULT hr;
  687. CComVariant v;
  688. //
  689. // Class qualifiers (propagated to instance)
  690. //
  691. hr = CUtils::SetQualifiers(
  692. i_pObj,
  693. m_awszClassQualNames,
  694. m_avtClassQualValues,
  695. 2,
  696. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE);
  697. if(FAILED(hr))
  698. {
  699. goto exit;
  700. }
  701. //
  702. // Another class qualifier (not propagated to instance)
  703. //
  704. if(i_iShipped == EXTENDED)
  705. {
  706. v = (bool)true;
  707. hr = CUtils::SetQualifiers(
  708. i_pObj,
  709. &g_wszCq_Extended,
  710. &v,
  711. 1,
  712. 0);
  713. if(FAILED(hr))
  714. {
  715. goto exit;
  716. }
  717. }
  718. //
  719. // Special __CLASS property
  720. //
  721. v = i_wszClassName;
  722. if(v.bstrVal == NULL)
  723. {
  724. hr = WBEM_E_OUT_OF_MEMORY;
  725. goto exit;
  726. }
  727. hr = i_pObj->Put(g_wszProp_Class, 0, &v, 0);
  728. if(FAILED(hr))
  729. {
  730. goto exit;
  731. }
  732. exit:
  733. return hr;
  734. }
  735. HRESULT CPusher::SetMethods(
  736. const WMI_CLASS* i_pElement,
  737. IWbemClassObject* i_pObject) const
  738. /*++
  739. Synopsis:
  740. Called by PushClasses.
  741. Sets the methods in i_pObject using i_pElement
  742. Arguments: [i_pElement] -
  743. [i_pObject] -
  744. Return Value:
  745. --*/
  746. {
  747. DBG_ASSERT(i_pElement != NULL);
  748. DBG_ASSERT(i_pObject != NULL);
  749. DBG_ASSERT(m_bInitSuccessful == true);
  750. HRESULT hr = WBEM_S_NO_ERROR;
  751. if(i_pElement->ppMethod == NULL)
  752. {
  753. return WBEM_S_NO_ERROR;
  754. }
  755. CComPtr<IWbemClassObject> spParamsIn;
  756. CComPtr<IWbemClassObject> spParamsOut;
  757. //
  758. // Run thru all the methods
  759. //
  760. WMI_METHOD* pMethCurrent = NULL;
  761. for(ULONG i = 0; i_pElement->ppMethod[i] != NULL; i++)
  762. {
  763. pMethCurrent = i_pElement->ppMethod[i];
  764. spParamsIn = NULL;
  765. spParamsOut = NULL;
  766. if(pMethCurrent->ppParams != NULL)
  767. {
  768. WMI_METHOD_PARAM* pParamCur = NULL;
  769. //
  770. // The index to indicate to WMI the order of the parameters
  771. // wszId is the qualifier name. svtId is a variant so we can give to WMI.
  772. //
  773. static LPCWSTR wszId = L"ID";
  774. CComVariant svtId = (int)0;
  775. //
  776. // Run thru all the parameters
  777. //
  778. for(ULONG j = 0; pMethCurrent->ppParams[j] != NULL; j++)
  779. {
  780. //
  781. // This will just hold spParamsIn and spParamsOut so we
  782. // don't need to duplicate the code.
  783. //
  784. IWbemClassObject* apParamInOut[] = { NULL, NULL };
  785. //
  786. // Create the WMI instance for the in and/or out params as needed.
  787. //
  788. pParamCur = pMethCurrent->ppParams[j];
  789. if( pParamCur->iInOut == PARAM_IN ||
  790. pParamCur->iInOut == PARAM_INOUT )
  791. {
  792. if(spParamsIn == NULL)
  793. {
  794. hr = m_pNamespace->GetObject(L"__Parameters", 0, m_pCtx, &spParamsIn, NULL);
  795. if(FAILED(hr))
  796. {
  797. DBGPRINTF((DBG_CONTEXT, "CPusher::SetMethods failed, hr=0x%x\n", hr));
  798. goto exit;
  799. }
  800. }
  801. apParamInOut[0] = spParamsIn;
  802. }
  803. if( pParamCur->iInOut == PARAM_OUT ||
  804. pParamCur->iInOut == PARAM_INOUT )
  805. {
  806. if(spParamsOut == NULL)
  807. {
  808. hr = m_pNamespace->GetObject(L"__Parameters", 0, m_pCtx, &spParamsOut, NULL);
  809. if(FAILED(hr))
  810. {
  811. DBGPRINTF((DBG_CONTEXT, "CPusher::SetMethods failed, hr=0x%x\n", hr));
  812. goto exit;
  813. }
  814. }
  815. apParamInOut[1] = spParamsOut;
  816. }
  817. //
  818. // Finally set them. First ins then outs.
  819. //
  820. for(ULONG k = 0; k < 2; k++)
  821. {
  822. if(apParamInOut[k] == NULL)
  823. {
  824. continue;
  825. }
  826. hr = apParamInOut[k]->Put(
  827. pParamCur->pszParamName, 0, NULL, pParamCur->type);
  828. if(FAILED(hr))
  829. {
  830. DBGPRINTF((DBG_CONTEXT, "CPusher::SetMethods failed, hr=0x%x\n", hr));
  831. goto exit;
  832. }
  833. hr = CUtils::SetPropertyQualifiers(
  834. apParamInOut[k], pParamCur->pszParamName, &wszId, &svtId, 1);
  835. if(FAILED(hr))
  836. {
  837. DBGPRINTF((DBG_CONTEXT, "CPusher::SetMethods failed, hr=0x%x\n", hr));
  838. goto exit;
  839. }
  840. }
  841. if(apParamInOut[0] || apParamInOut[1])
  842. {
  843. svtId.lVal++;
  844. }
  845. }
  846. }
  847. //
  848. // Put the method.
  849. //
  850. hr = i_pObject->PutMethod(
  851. pMethCurrent->pszMethodName, 0, spParamsIn, spParamsOut);
  852. if(FAILED(hr))
  853. {
  854. DBGPRINTF((DBG_CONTEXT, "CPusher::SetMethods failed, hr=0x%x\n", hr));
  855. goto exit;
  856. }
  857. VARIANT vImplemented;
  858. vImplemented.boolVal = VARIANT_TRUE;
  859. vImplemented.vt = VT_BOOL;
  860. hr = CUtils::SetMethodQualifiers(
  861. i_pObject,
  862. pMethCurrent->pszMethodName,
  863. &g_wszMq_Implemented,
  864. &vImplemented,
  865. 1);
  866. if(FAILED(hr))
  867. {
  868. DBGPRINTF((DBG_CONTEXT, "CPusher::SetMethods failed, hr=0x%x\n", hr));
  869. goto exit;
  870. }
  871. /*if(pMethCurrent->pszDescription)
  872. {
  873. VARIANT vDesc;
  874. vDesc.bstrVal = pMethCurrent->pszDescription;
  875. vDesc.vt = VT_BSTR;
  876. hr = CUtils::SetMethodQualifiers(
  877. i_pObject,
  878. pMethCurrent->pszMethodName,
  879. &g_wszMq_Description,
  880. &vDesc,
  881. 1);
  882. if(FAILED(hr))
  883. {
  884. DBGPRINTF((DBG_CONTEXT, "CPusher::SetMethods failed, hr=0x%x\n", hr));
  885. goto exit;
  886. }
  887. }*/
  888. }
  889. exit:
  890. return hr;
  891. }
  892. HRESULT CPusher::SetProperties(
  893. const WMI_CLASS* i_pElement,
  894. IWbemClassObject* i_pObject) const
  895. /*++
  896. Synopsis:
  897. Called by PushClasses.
  898. Sets the properties in i_pObject using i_pElement
  899. Arguments: [i_pElement] -
  900. [i_pObject] -
  901. Return Value:
  902. --*/
  903. {
  904. DBG_ASSERT(i_pElement != NULL);
  905. DBG_ASSERT(i_pObject != NULL);
  906. DBG_ASSERT(m_bInitSuccessful == true);
  907. HRESULT hr = WBEM_S_NO_ERROR;
  908. METABASE_PROPERTY* pPropCurrent = NULL;
  909. TFormattedMultiSz* pFormattedMultiSz = NULL;
  910. CIMTYPE typeProp;
  911. CComPtr<IWbemQualifierSet> spQualSet;
  912. VARIANT v;
  913. VariantInit(&v);
  914. if(i_pElement->ppmbp == NULL)
  915. {
  916. return hr;
  917. }
  918. for(ULONG i = 0; i_pElement->ppmbp[i] != NULL; i++)
  919. {
  920. pPropCurrent = i_pElement->ppmbp[i];
  921. pFormattedMultiSz = NULL;
  922. switch(pPropCurrent->dwMDDataType)
  923. {
  924. case DWORD_METADATA:
  925. if(pPropCurrent->dwMDMask != 0)
  926. {
  927. typeProp = CIM_BOOLEAN;
  928. }
  929. else
  930. {
  931. typeProp = CIM_SINT32;
  932. }
  933. break;
  934. case STRING_METADATA:
  935. case EXPANDSZ_METADATA:
  936. typeProp = CIM_STRING;
  937. break;
  938. case MULTISZ_METADATA:
  939. typeProp = VT_ARRAY | CIM_STRING;
  940. pFormattedMultiSz =
  941. TFormattedMultiSzData::Find(pPropCurrent->dwMDIdentifier);
  942. if(pFormattedMultiSz)
  943. {
  944. typeProp = VT_ARRAY | CIM_OBJECT;
  945. }
  946. break;
  947. case BINARY_METADATA:
  948. typeProp = VT_ARRAY | CIM_UINT8;
  949. break;
  950. default:
  951. //
  952. // Non fatal if we cannot recognize type
  953. //
  954. continue;
  955. }
  956. hr = i_pObject->Put(pPropCurrent->pszPropName, 0, NULL, typeProp);
  957. if(FAILED(hr))
  958. {
  959. goto exit;
  960. }
  961. //
  962. // qualifiers
  963. //
  964. hr = i_pObject->GetPropertyQualifierSet(pPropCurrent->pszPropName, &spQualSet);
  965. if(FAILED(hr))
  966. {
  967. goto exit;
  968. }
  969. //
  970. // qualifier for read-only
  971. //
  972. V_VT(&v) = VT_BOOL;
  973. V_BOOL(&v) = (pPropCurrent->fReadOnly) ? VARIANT_FALSE : VARIANT_TRUE;
  974. hr = spQualSet->Put(g_wszPq_Write, &v, 0);
  975. if(FAILED(hr))
  976. {
  977. goto exit;
  978. }
  979. V_BOOL(&v) = VARIANT_TRUE;
  980. hr = spQualSet->Put(g_wszPq_Read, &v, 0);
  981. if(FAILED(hr))
  982. {
  983. goto exit;
  984. }
  985. VariantClear(&v);
  986. //
  987. // CIMType qualifier
  988. //
  989. if(pFormattedMultiSz)
  990. {
  991. DBG_ASSERT(typeProp == (VT_ARRAY | CIM_OBJECT));
  992. CComBSTR sbstrValue = L"object:";
  993. if(sbstrValue.m_str == NULL)
  994. {
  995. hr = WBEM_E_OUT_OF_MEMORY;
  996. goto exit;
  997. }
  998. sbstrValue += pFormattedMultiSz->wszWmiClassName;
  999. if(sbstrValue.m_str == NULL)
  1000. {
  1001. hr = WBEM_E_OUT_OF_MEMORY;
  1002. goto exit;
  1003. }
  1004. //
  1005. // Deliberately not smart variant. We will let sbstrValue do deconstruction.
  1006. //
  1007. VARIANT vValue;
  1008. vValue.vt = VT_BSTR;
  1009. vValue.bstrVal = sbstrValue;
  1010. hr = spQualSet->Put(g_wszPq_CimType, &vValue, 0);
  1011. if(FAILED(hr))
  1012. {
  1013. goto exit;
  1014. }
  1015. }
  1016. spQualSet = NULL;
  1017. }
  1018. exit:
  1019. VariantClear(&v);
  1020. return hr;
  1021. }
  1022. HRESULT CPusher::SetAssociationComponent(
  1023. IWbemClassObject* i_pObject,
  1024. LPCWSTR i_wszComp,
  1025. LPCWSTR i_wszClass) const
  1026. /*++
  1027. Synopsis:
  1028. Called by PushAssocs
  1029. Sets a ref property of an association, i_pObj, using i_wszComp and i_wszClass
  1030. Arguments: [i_pObject] - the association
  1031. [i_wszComp] - property name (Eg. Group, Part)
  1032. [i_wszClass] - the class we are "ref"fing to.
  1033. Return Value:
  1034. --*/
  1035. {
  1036. DBG_ASSERT(i_pObject != NULL);
  1037. DBG_ASSERT(i_wszComp != NULL);
  1038. DBG_ASSERT(i_wszClass != NULL);
  1039. DBG_ASSERT(m_bInitSuccessful == true);
  1040. HRESULT hr = WBEM_S_NO_ERROR;
  1041. CComPtr<IWbemQualifierSet> spQualSet;
  1042. VARIANT v;
  1043. VariantInit(&v);
  1044. //
  1045. // Store "Ref:[class name]" in a bstr.
  1046. //
  1047. ULONG cchClass = wcslen(i_wszClass);
  1048. CComBSTR sbstrClass(4 + cchClass);
  1049. if(sbstrClass.m_str == NULL)
  1050. {
  1051. hr = WBEM_E_OUT_OF_MEMORY;
  1052. goto exit;
  1053. }
  1054. memcpy(sbstrClass.m_str , L"Ref:", sizeof(WCHAR)*4);
  1055. memcpy(sbstrClass.m_str + 4, i_wszClass, sizeof(WCHAR)*(cchClass+1));
  1056. //
  1057. // Put the property (Eg. Group, Part, etc.)
  1058. //
  1059. hr = i_pObject->Put(i_wszComp, 0, NULL, CIM_REFERENCE);
  1060. if(FAILED(hr))
  1061. {
  1062. goto exit;
  1063. }
  1064. //
  1065. // Set Qualifiers on the property
  1066. //
  1067. hr = i_pObject->GetPropertyQualifierSet(i_wszComp, &spQualSet);
  1068. if(FAILED(hr))
  1069. {
  1070. goto exit;
  1071. }
  1072. V_VT(&v) = VT_BOOL;
  1073. V_BOOL(&v) = VARIANT_TRUE;
  1074. hr = spQualSet->Put(g_wszPq_Key, &v, 0);
  1075. if(FAILED(hr))
  1076. {
  1077. goto exit;
  1078. }
  1079. V_VT(&v) = VT_BSTR;
  1080. V_BSTR(&v) = sbstrClass.m_str;
  1081. if(V_BSTR(&v) == NULL)
  1082. {
  1083. V_VT(&v) = VT_EMPTY;
  1084. hr = WBEM_E_OUT_OF_MEMORY;
  1085. goto exit;
  1086. }
  1087. hr = spQualSet->Put(g_wszPq_CimType, &v, 0);
  1088. V_VT(&v) = VT_EMPTY;
  1089. V_BSTR(&v) = NULL;
  1090. if(FAILED(hr))
  1091. {
  1092. goto exit;
  1093. }
  1094. exit:
  1095. return hr;
  1096. }
  1097. bool CPusher::NeedToDeleteAssoc(
  1098. IWbemClassObject* i_pObj) const
  1099. /*++
  1100. Synopsis:
  1101. Sees if the association i_pObj is already in hashtable.
  1102. If it is, no point in deleting i_pObj from repository only to recreate
  1103. it later.
  1104. Arguments: [i_pObj] - An IWbemClassObject representation of an assoc
  1105. Return Value:
  1106. true if i_pObj not in hashtable
  1107. false otherwise
  1108. --*/
  1109. {
  1110. DBG_ASSERT(i_pObj != NULL);
  1111. DBG_ASSERT(g_pDynSch != NULL);
  1112. DBG_ASSERT(m_bInitSuccessful == true);
  1113. HRESULT hr = WBEM_S_NO_ERROR;
  1114. bool bMatch = false;
  1115. CComVariant vt;
  1116. LPWSTR wsz;
  1117. CComPtr<IWbemQualifierSet> spQualSet;
  1118. CHashTable<WMI_ASSOCIATION *>* pHash = g_pDynSch->GetHashAssociations();
  1119. WMI_ASSOCIATION* pAssoc;
  1120. DBG_ASSERT(pHash != NULL);
  1121. //
  1122. // Compare the association names
  1123. //
  1124. hr = i_pObj->Get(g_wszProp_Class, 0, &vt, NULL, NULL);
  1125. if(FAILED(hr) || vt.vt != VT_BSTR)
  1126. {
  1127. goto exit;
  1128. }
  1129. hr = pHash->Wmi_GetByKey(vt.bstrVal, &pAssoc);
  1130. if(FAILED(hr))
  1131. {
  1132. goto exit;
  1133. }
  1134. vt.Clear();
  1135. //
  1136. // This is the only case we care about
  1137. //
  1138. if(pAssoc->dwExtended != USER_DEFINED_TO_REPOSITORY)
  1139. {
  1140. goto exit;
  1141. }
  1142. //
  1143. // Compare the left association component
  1144. //
  1145. hr = i_pObj->GetPropertyQualifierSet(
  1146. pAssoc->pType->pszLeft,
  1147. &spQualSet);
  1148. if(FAILED(hr))
  1149. {
  1150. goto exit;
  1151. }
  1152. spQualSet->Get(g_wszPq_CimType, 0, &vt, NULL);
  1153. spQualSet = NULL;
  1154. if(FAILED(hr) || vt.vt != VT_BSTR)
  1155. {
  1156. goto exit;
  1157. }
  1158. if( (wsz = wcschr(vt.bstrVal, L':')) == NULL )
  1159. {
  1160. goto exit;
  1161. }
  1162. wsz++;
  1163. if(_wcsicmp(wsz, pAssoc->pcLeft->pszClassName) != 0)
  1164. {
  1165. goto exit;
  1166. }
  1167. vt.Clear();
  1168. //
  1169. // Compare the right association component
  1170. //
  1171. hr = i_pObj->GetPropertyQualifierSet(
  1172. pAssoc->pType->pszRight,
  1173. &spQualSet);
  1174. if(FAILED(hr))
  1175. {
  1176. goto exit;
  1177. }
  1178. spQualSet->Get(g_wszPq_CimType, 0, &vt, NULL);
  1179. spQualSet = NULL;
  1180. if(FAILED(hr) || vt.vt != VT_BSTR)
  1181. {
  1182. goto exit;
  1183. }
  1184. if( (wsz = wcschr(vt.bstrVal, L':')) == NULL )
  1185. {
  1186. goto exit;
  1187. }
  1188. wsz++;
  1189. if(_wcsicmp(wsz, pAssoc->pcRight->pszClassName) != 0)
  1190. {
  1191. goto exit;
  1192. }
  1193. vt.Clear();
  1194. bMatch = true;
  1195. pAssoc->dwExtended = USER_DEFINED_NOT_TO_REPOSITORY;
  1196. exit:
  1197. return !bMatch;
  1198. }
  1199. HRESULT CPusher::DeleteChildren(LPCWSTR i_wszExtSuperClass)
  1200. {
  1201. DBG_ASSERT(i_wszExtSuperClass != NULL);
  1202. DBG_ASSERT(m_bInitSuccessful == true);
  1203. //
  1204. // Only can be called from inside Initialize
  1205. //
  1206. DBG_ASSERT(m_bInitCalled == true);
  1207. DBG_ASSERT(m_bInitSuccessful == true);
  1208. IEnumWbemClassObject*pEnum = NULL;
  1209. HRESULT hr = WBEM_S_NO_ERROR;
  1210. IWbemClassObject* apObj[10] = {0};
  1211. ULONG nrObj = 0;
  1212. ULONG i = 0;
  1213. VARIANT v;
  1214. VariantInit(&v);
  1215. CComBSTR bstrExtSuperClass = i_wszExtSuperClass;
  1216. if(bstrExtSuperClass.m_str == NULL)
  1217. {
  1218. hr = WBEM_E_OUT_OF_MEMORY;
  1219. goto exit;
  1220. }
  1221. hr = m_pNamespace->CreateClassEnum(
  1222. bstrExtSuperClass,
  1223. WBEM_FLAG_FORWARD_ONLY,
  1224. m_pCtx,
  1225. &pEnum);
  1226. if(FAILED(hr))
  1227. {
  1228. goto exit;
  1229. }
  1230. hr = pEnum->Next(WBEM_INFINITE, 10, apObj, &nrObj);
  1231. while(SUCCEEDED(hr) && nrObj > 0)
  1232. {
  1233. for(i = 0; i < nrObj; i++)
  1234. {
  1235. bool bDelete;
  1236. if( i_wszExtSuperClass == g_wszExtElementSettingAssocParent ||
  1237. i_wszExtSuperClass == g_wszExtGroupPartAssocParent)
  1238. {
  1239. bDelete = NeedToDeleteAssoc(apObj[i]);
  1240. }
  1241. else
  1242. {
  1243. bDelete = true;
  1244. }
  1245. if(bDelete)
  1246. {
  1247. hr = apObj[i]->Get(g_wszProp_Class, 0, &v, NULL, NULL);
  1248. if(FAILED(hr))
  1249. {
  1250. goto exit;
  1251. }
  1252. hr = m_pNamespace->DeleteClass(v.bstrVal, WBEM_FLAG_OWNER_UPDATE, m_pCtx, NULL);
  1253. if(FAILED(hr))
  1254. {
  1255. goto exit;
  1256. }
  1257. VariantClear(&v);
  1258. }
  1259. apObj[i]->Release();
  1260. apObj[i] = NULL;
  1261. }
  1262. hr = pEnum->Next(WBEM_INFINITE, 10, apObj, &nrObj);
  1263. }
  1264. if(FAILED(hr))
  1265. {
  1266. goto exit;
  1267. }
  1268. exit:
  1269. if(pEnum)
  1270. {
  1271. pEnum->Release();
  1272. pEnum = NULL;
  1273. }
  1274. VariantClear(&v);
  1275. for(i = 0; i < 10; i++)
  1276. {
  1277. if(apObj[i])
  1278. {
  1279. apObj[i]->Release();
  1280. }
  1281. }
  1282. return hr;
  1283. }
  1284. HRESULT CPusher::GetObject(
  1285. LPCWSTR i_wszClass,
  1286. IWbemClassObject** o_ppObj)
  1287. {
  1288. DBG_ASSERT(o_ppObj != NULL);
  1289. DBG_ASSERT(m_bInitCalled == true);
  1290. DBG_ASSERT(m_bInitSuccessful == true);
  1291. HRESULT hr = WBEM_S_NO_ERROR;
  1292. IWbemClassObject* pObject;
  1293. if(i_wszClass == g_wszExtElementParent)
  1294. {
  1295. *o_ppObj = m_spBaseElementObject;
  1296. (*o_ppObj)->AddRef();
  1297. }
  1298. else if(i_wszClass == g_wszExtSettingParent)
  1299. {
  1300. *o_ppObj = m_spBaseSettingObject;
  1301. (*o_ppObj)->AddRef();
  1302. }
  1303. else if(i_wszClass == g_wszExtElementSettingAssocParent)
  1304. {
  1305. *o_ppObj = m_spBaseElementSettingObject;
  1306. (*o_ppObj)->AddRef();
  1307. }
  1308. else if(i_wszClass == g_wszExtGroupPartAssocParent)
  1309. {
  1310. *o_ppObj = m_spBaseGroupPartObject;
  1311. (*o_ppObj)->AddRef();
  1312. }
  1313. else
  1314. {
  1315. const CComBSTR sbstrClass = i_wszClass;
  1316. if(sbstrClass.m_str == NULL)
  1317. {
  1318. hr = WBEM_E_OUT_OF_MEMORY;
  1319. goto exit;
  1320. }
  1321. hr = m_pNamespace->GetObject(sbstrClass, 0, m_pCtx, &pObject, NULL);
  1322. if(FAILED(hr))
  1323. {
  1324. goto exit;
  1325. }
  1326. *o_ppObj = pObject;
  1327. }
  1328. exit:
  1329. return hr;
  1330. }
  1331. /*HRESULT CPusher::NeedToPutAssoc(
  1332. WMI_ASSOCIATION* i_pAssoc,
  1333. bool* io_pbPutNeeded)
  1334. {
  1335. DBG_ASSERT(m_bInitCalled == true);
  1336. DBG_ASSERT(m_bInitSuccessful == true);
  1337. DBG_ASSERT(i_pAssoc != NULL);
  1338. DBG_ASSERT(io_pbPutNeeded != NULL);
  1339. HRESULT hr = WBEM_S_NO_ERROR;
  1340. CComBSTR bstrAssoc;
  1341. bool bExtendedQual = false;
  1342. bool bPutNeeded = false;
  1343. if(i_pAssoc->dwExtended != USER_DEFINED_TO_REPOSITORY)
  1344. {
  1345. goto exit;
  1346. }
  1347. bstrAssoc = i_pAssoc->pszAssociationName;
  1348. if(bstrAssoc.m_str == NULL)
  1349. {
  1350. hr = WBEM_E_OUT_OF_MEMORY;
  1351. goto exit;
  1352. }
  1353. HRESULT hrGetObject = m_pNamespace->GetObject(
  1354. bstrAssoc,
  1355. WBEM_FLAG_RETURN_WBEM_COMPLETE,
  1356. m_pCtx,
  1357. NULL,
  1358. NULL);
  1359. if( hrGetObject != WBEM_E_INVALID_CLASS &&
  1360. hrGetObject != WBEM_E_NOT_FOUND)
  1361. {
  1362. hr = hrGetObject;
  1363. }
  1364. if(FAILED(hr))
  1365. {
  1366. goto exit;
  1367. }
  1368. if( hrGetObject == WBEM_E_INVALID_CLASS ||
  1369. hrGetObject == WBEM_E_NOT_FOUND )
  1370. {
  1371. bPutNeeded = true;
  1372. }
  1373. exit:
  1374. if(SUCCEEDED(hr))
  1375. {
  1376. *io_pbPutNeeded = bPutNeeded;
  1377. }
  1378. return hr;
  1379. }*/