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.

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