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.

1799 lines
48 KiB

  1. /*===================================================================
  2. Microsoft IIS
  3. Microsoft Confidential.
  4. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. Component: WAMREG
  6. File: mtsconfig.cpp
  7. implementation of supporting functions for WAMREG, including
  8. interface to Add/Remove Component from a MTS package,
  9. History: LeiJin created on 9/24/1997
  10. Note:
  11. ===================================================================*/
  12. #include "common.h"
  13. #include "auxfunc.h"
  14. #include "comadmii.c"
  15. #include "dbgutil.h"
  16. #include "export.h"
  17. /*===================================================================
  18. Define the global variables and types
  19. ======================================================================*/
  20. //
  21. // Following is a list of all the WAMREG/MTS properties for Package creation
  22. // Format:
  23. // (prop-symbolic-name, property-name-string)
  24. //
  25. // WAMREG_MTS_PROPERTY() -> means property for NT & Win9x
  26. // WAMREG_MTS_NTPROPERTY() -> means property for NT only
  27. //
  28. # define ALL_WAMREG_MTS_PROPERTY() \
  29. WAMREG_MTS_PROPERTY( WM_ID, L"ID") \
  30. WAMREG_MTS_PROPERTY( WM_NAME, L"Name") \
  31. WAMREG_MTS_PROPERTY( WM_CREATED_BY, L"CreatedBy") \
  32. WAMREG_MTS_PROPERTY( WM_RUN_FOREVER, L"RunForever") \
  33. WAMREG_MTS_NTPROPERTY( WM_IDENTITY, L"Identity") \
  34. WAMREG_MTS_NTPROPERTY( WM_PASSWORD, L"Password") \
  35. WAMREG_MTS_PROPERTY( WM_ACTIVATION, L"Activation") \
  36. WAMREG_MTS_PROPERTY( WM_CHANGEABLE, L"Changeable") \
  37. WAMREG_MTS_PROPERTY( WM_DELETABLE, L"Deleteable") \
  38. WAMREG_MTS_PROPERTY( WM_SECSUPP, L"AccessChecksLevel") \
  39. //
  40. // Let us expand the macros here for defining the symbolic-name
  41. //
  42. //
  43. # define WAMREG_MTS_PROPERTY( symName, pwsz) symName,
  44. # define WAMREG_MTS_NTPROPERTY( symName, pwsz) symName,
  45. enum WAMREG_MTS_PROP_NAMES {
  46. ALL_WAMREG_MTS_PROPERTY()
  47. MAX_WAMREG_MTS_PROP_NAMES // sentinel element
  48. };
  49. # undef WAMREG_MTS_PROPERTY
  50. # undef WAMREG_MTS_NTPROPERTY
  51. struct MtsProperty {
  52. LPCWSTR m_pszPropName;
  53. BOOL m_fWinNTOnly;
  54. };
  55. //
  56. // Let us expand the macros here for defining the property strings
  57. //
  58. //
  59. # define WAMREG_MTS_PROPERTY( symName, pwsz) { pwsz, FALSE },
  60. # define WAMREG_MTS_NTPROPERTY( symName, pwsz) { pwsz, TRUE },
  61. static const MtsProperty g_rgWamRegMtsProperties[]= {
  62. ALL_WAMREG_MTS_PROPERTY()
  63. { NULL, FALSE} // sentinel element
  64. };
  65. # define NUM_WAMREG_MTS_PROPERTIES \
  66. ((sizeof(g_rgWamRegMtsProperties)/sizeof(g_rgWamRegMtsProperties[0])) - 1)
  67. # undef WAMREG_MTS_PROPERTY
  68. # undef WAMREG_MTS_NTPROPERTY
  69. /*===================================================================
  70. WamRegPackageConfig
  71. Constructor.
  72. Parameter:
  73. NONE;
  74. ===================================================================*/
  75. WamRegPackageConfig::WamRegPackageConfig()
  76. : m_pCatalog(NULL),
  77. m_pPkgCollection(NULL),
  78. m_pCompCollection(NULL),
  79. m_pPackage(NULL)
  80. {
  81. }
  82. /*===================================================================
  83. ~WamRegPackageConfig
  84. Destructor.
  85. By the time the object gets destructed, all resources should be freed.
  86. We do most of the cleanup inside WamReqPackageConfig::Cleanup() so
  87. that callers call that function separately to cleanup state
  88. especially if the caller also calls CoUninitialize().
  89. WamRegPackageConfig should be cleaned up before CoUninitialize()
  90. Parameter:
  91. NONE;
  92. ===================================================================*/
  93. WamRegPackageConfig::~WamRegPackageConfig()
  94. {
  95. Cleanup();
  96. // insane checks to ensure everything is happy here
  97. DBG_ASSERT(m_pCatalog == NULL);
  98. DBG_ASSERT(m_pPkgCollection == NULL);
  99. DBG_ASSERT(m_pCompCollection == NULL);
  100. DBG_ASSERT(m_pPackage == NULL);
  101. }
  102. VOID
  103. WamRegPackageConfig::Cleanup(VOID)
  104. {
  105. if (m_pPackage != NULL ) {
  106. RELEASE( m_pPackage);
  107. m_pPackage = NULL;
  108. }
  109. if (m_pCompCollection != NULL) {
  110. RELEASE (m_pCompCollection);
  111. m_pCompCollection = NULL;
  112. }
  113. if (m_pPkgCollection != NULL ) {
  114. RELEASE(m_pPkgCollection);
  115. m_pPkgCollection = NULL;
  116. }
  117. if (m_pCatalog != NULL ) {
  118. RELEASE(m_pCatalog);
  119. m_pCatalog = NULL;
  120. }
  121. } // WamPackageConfig::Cleanup()
  122. /*===================================================================
  123. ReleaseAll
  124. Release all resources.
  125. Parameter:
  126. NONE;
  127. ===================================================================*/
  128. VOID WamRegPackageConfig::ReleaseAll
  129. (
  130. )
  131. {
  132. RELEASE(m_pPackage);
  133. RELEASE(m_pCompCollection);
  134. //
  135. // NOTE: I am not releasing m_pCatalog, m_pPkgCollection
  136. // These will be released by the Cleanup().
  137. //
  138. }
  139. /*===================================================================
  140. CreateCatalog
  141. CoCreateObject of an MTS Catalog object if the Catalog object has not been
  142. created.
  143. Parameter:
  144. NONE;
  145. ===================================================================*/
  146. HRESULT WamRegPackageConfig::CreateCatalog
  147. (
  148. VOID
  149. )
  150. {
  151. HRESULT hr = NOERROR;
  152. DBG_ASSERT(m_pCatalog == NULL);
  153. DBG_ASSERT(m_pPkgCollection == NULL);
  154. // Create instance of the catalog object
  155. hr = CoCreateInstance(CLSID_COMAdminCatalog
  156. , NULL
  157. , CLSCTX_SERVER
  158. , IID_ICOMAdminCatalog
  159. , (void**)&m_pCatalog);
  160. if (FAILED(hr)) {
  161. DBGPRINTF((DBG_CONTEXT,
  162. "Failed to CoCreateInstance of Catalog Object.,hr = %08x\n",
  163. hr));
  164. }
  165. else {
  166. DBG_ASSERT(m_pCatalog != NULL);
  167. BSTR bstr;
  168. //
  169. // Get the Packages collection
  170. //
  171. bstr = SysAllocString(L"Applications");
  172. hr = m_pCatalog->GetCollection(bstr, (IDispatch**)&m_pPkgCollection);
  173. FREEBSTR(bstr);
  174. if (FAILED(hr)) {
  175. DBGPRINTF((DBG_CONTEXT,
  176. "m_pCatalog(%08x)->GetCollection() failed, hr = %08x\n",
  177. m_pCatalog,
  178. hr));
  179. } else {
  180. DBG_ASSERT( m_pPkgCollection != NULL);
  181. }
  182. }
  183. return hr;
  184. } // WamRegPackageConfig::CreateCatalog()
  185. /*===================================================================
  186. SetCatalogObjectProperty
  187. Get a SafeArray contains one ComponentCLSID
  188. Parameter:
  189. szComponentCLSID the CLSID need to be put in the safe array
  190. paCLSIDs pointer to a pointer of safe array(safe array provided by caller).
  191. Return: HRESULT
  192. Side Affect:
  193. Note:
  194. ===================================================================*/
  195. HRESULT WamRegPackageConfig::GetSafeArrayOfCLSIDs
  196. (
  197. IN LPCWSTR szComponentCLSID,
  198. OUT SAFEARRAY** paCLSIDs
  199. )
  200. {
  201. SAFEARRAY* aCLSIDs = NULL;
  202. SAFEARRAYBOUND rgsaBound[1];
  203. LONG Indices[1];
  204. VARIANT varT;
  205. HRESULT hr = NOERROR;
  206. DBG_ASSERT(szComponentCLSID && paCLSIDs);
  207. DBG_ASSERT(*paCLSIDs == NULL);
  208. // PopulateByKey is expecting a SAFEARRAY parameter input,
  209. // Create a one element SAFEARRAY, the one element of the SAFEARRAY contains
  210. // the packageID.
  211. rgsaBound[0].cElements = 1;
  212. rgsaBound[0].lLbound = 0;
  213. aCLSIDs = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
  214. if (aCLSIDs)
  215. {
  216. Indices[0] = 0;
  217. VariantInit(&varT);
  218. varT.vt = VT_BSTR;
  219. varT.bstrVal = SysAllocString(szComponentCLSID);
  220. hr = SafeArrayPutElement(aCLSIDs, Indices, &varT);
  221. VariantClear(&varT);
  222. if (FAILED(hr))
  223. {
  224. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayPutElement, CLSID is %S, hr %08x\n",
  225. szComponentCLSID,
  226. hr));
  227. if (aCLSIDs != NULL)
  228. {
  229. HRESULT hrT = SafeArrayDestroy(aCLSIDs);
  230. if (FAILED(hrT))
  231. {
  232. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
  233. hr));
  234. }
  235. aCLSIDs = NULL;
  236. }
  237. }
  238. }
  239. else
  240. {
  241. hr = HRESULT_FROM_WIN32(GetLastError());
  242. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayCreate, hr %08x\n",
  243. hr));
  244. }
  245. *paCLSIDs = aCLSIDs;
  246. return hr;
  247. }
  248. /*===================================================================
  249. SetComponentObjectProperty
  250. Set component level property.
  251. Parameter:
  252. pComponent - pointer to the ICatalogObject(MTS) used to update property
  253. szPropertyName - Name of the property
  254. szPropertyValue- Value of the property
  255. fPropertyValue - If szPropertyValue is NULL, use fPropertyValue
  256. Return: HRESULT
  257. Side Affect:
  258. Note:
  259. ===================================================================*/
  260. HRESULT WamRegPackageConfig::SetComponentObjectProperty
  261. (
  262. IN ICatalogObject * pComponent,
  263. IN LPCWSTR szPropertyName,
  264. IN LPCWSTR szPropertyValue,
  265. BOOL fPropertyValue
  266. )
  267. {
  268. BSTR bstr = NULL;
  269. HRESULT hr = NOERROR;
  270. VARIANT varT;
  271. VariantInit(&varT);
  272. bstr = SysAllocString(szPropertyName);
  273. if (szPropertyValue != NULL)
  274. {
  275. varT.vt = VT_BSTR;
  276. varT.bstrVal = SysAllocString(szPropertyValue);
  277. }
  278. else
  279. {
  280. //
  281. // COM+ regcongize -1 as TRUE, and 0 as FALSE. I believe the root is from VB.
  282. //
  283. varT.vt = VT_BOOL;
  284. varT.boolVal = (fPropertyValue) ? -1 : 0;
  285. }
  286. hr = pComponent->put_Value(bstr, varT);
  287. FREEBSTR(bstr);
  288. VariantClear(&varT);
  289. if (FAILED(hr))
  290. {
  291. DBGPRINTF((DBG_CONTEXT,
  292. "MTS-Component(%08x)::SetProperty(%S => %S) failed;"
  293. " hr %08x\n",
  294. pComponent, szPropertyName, szPropertyValue, hr));
  295. }
  296. return hr;
  297. }
  298. /*===================================================================
  299. WamRegPackageConfig::SetComponentObjectProperties()
  300. Sets the componnet properties for newly created component that houses
  301. the WAM unit
  302. Parameter:
  303. szComponentCLSID - CLSID for the component that is newly created
  304. Return: HRESULT
  305. Side Affect:
  306. If there is a failure all the previously set values are not cleared.
  307. The caller should make sure that the proper cleanup of package happens
  308. on partial errors.
  309. Note:
  310. ===================================================================*/
  311. HRESULT
  312. WamRegPackageConfig::SetComponentObjectProperties(
  313. IN LPCWSTR szComponentCLSID
  314. )
  315. {
  316. HRESULT hr;
  317. SAFEARRAY* aCLSIDs = NULL;
  318. long lCompCount = 0;
  319. ICatalogObject* pComponent = NULL;
  320. BOOL fFound;
  321. DBG_ASSERT( m_pCompCollection != NULL);
  322. //
  323. // Create the array containing the CLSIDs from the component name
  324. // this will be used to find our object in MTS and set properties
  325. // on the same
  326. //
  327. hr = GetSafeArrayOfCLSIDs(szComponentCLSID, &aCLSIDs);
  328. if (FAILED(hr))
  329. {
  330. DBGPRINTF((DBG_CONTEXT,
  331. "Failed in GetSafeArrayOfCLSIDs(%S). hr=%08x\n",
  332. szComponentCLSID, hr));
  333. goto LErrExit;
  334. }
  335. hr = m_pCompCollection->PopulateByKey(aCLSIDs);
  336. if (FAILED(hr))
  337. {
  338. DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
  339. hr));
  340. goto LErrExit;
  341. }
  342. // Find our component in the list (should be the only one)
  343. hr = m_pCompCollection->get_Count(&lCompCount);
  344. if (FAILED(hr))
  345. {
  346. DBGPRINTF((DBG_CONTEXT,
  347. "Failed in CompCollection(%08x)::get_Count(). hr = %08x\n",
  348. m_pCompCollection, hr));
  349. goto LErrExit;
  350. }
  351. //
  352. // Load the component object so that we can set properties
  353. //
  354. fFound = FALSE;
  355. if (SUCCEEDED(hr) && lCompCount == 1)
  356. {
  357. hr = m_pCompCollection->get_Item(0, (IDispatch**)&pComponent);
  358. if (FAILED(hr))
  359. {
  360. DBGPRINTF((DBG_CONTEXT,
  361. "Failed in CompCollection(%08x)::get component() hr=%08x\n",
  362. m_pCompCollection, hr));
  363. goto LErrExit;
  364. }
  365. else
  366. {
  367. // Found it
  368. DBG_ASSERT(pComponent);
  369. fFound = TRUE;
  370. }
  371. }
  372. if (fFound)
  373. {
  374. //
  375. // Component Properties InProc OutOfProc
  376. // --------------------- -------- ----------
  377. // Synchronization 0 same
  378. // Transaction "Not Supported" same
  379. // JustInTimeActivation N same
  380. // IISIntrinsics N same
  381. // COMTIIntrinsics N same
  382. // ComponentAccessChecksEnabled 0 same
  383. hr = SetComponentObjectProperty( pComponent, L"Synchronization", L"0");
  384. if (FAILED(hr))
  385. {
  386. goto LErrExit;
  387. }
  388. hr = SetComponentObjectProperty( pComponent, L"ComponentAccessChecksEnabled", L"0");
  389. if (FAILED(hr))
  390. {
  391. goto LErrExit;
  392. }
  393. hr = SetComponentObjectProperty( pComponent, L"Transaction", L"0");
  394. if (FAILED(hr))
  395. {
  396. goto LErrExit;
  397. }
  398. hr = SetComponentObjectProperty( pComponent, L"JustInTimeActivation",NULL,FALSE);
  399. if (FAILED(hr))
  400. {
  401. goto LErrExit;
  402. }
  403. hr = SetComponentObjectProperty( pComponent, L"IISIntrinsics", NULL, FALSE);
  404. if (FAILED(hr))
  405. {
  406. goto LErrExit;
  407. }
  408. hr = SetComponentObjectProperty( pComponent, L"COMTIIntrinsics", NULL, FALSE);
  409. if (FAILED(hr))
  410. {
  411. goto LErrExit;
  412. }
  413. hr = SetComponentObjectProperty(pComponent, L"EventTrackingEnabled", L"N");
  414. if (FAILED(hr))
  415. {
  416. goto LErrExit;
  417. }
  418. }
  419. else
  420. {
  421. DBGPRINTF((DBG_CONTEXT,
  422. "Unable to find newly create WAM component in package\n"));
  423. DBG_ASSERT(FALSE);
  424. }
  425. LErrExit:
  426. RELEASE(pComponent);
  427. if (aCLSIDs != NULL) {
  428. HRESULT hrT = SafeArrayDestroy(aCLSIDs);
  429. if (FAILED(hrT)) {
  430. DBGPRINTF((DBG_CONTEXT,
  431. "Failed to call SafeArrayDestroy(aCLSIDs=%08x),"
  432. " hr = %08x\n",
  433. aCLSIDs, hr));
  434. }
  435. aCLSIDs = NULL;
  436. }
  437. return ( hr);
  438. } // // WamRegPackageConfig::SetComponentObjectProperties()
  439. /*===================================================================
  440. SetPackageObjectProperty
  441. Set package level property.
  442. Parameter:
  443. szPropertyName Name of the property
  444. szPropertyValue Value of the property
  445. Return: HRESULT
  446. Side Affect:
  447. Note:
  448. ===================================================================*/
  449. HRESULT WamRegPackageConfig::SetPackageObjectProperty
  450. (
  451. IN LPCWSTR szPropertyName,
  452. IN LPCWSTR szPropertyValue
  453. )
  454. {
  455. BSTR bstr = NULL;
  456. HRESULT hr = NOERROR;
  457. VARIANT varT;
  458. VariantInit(&varT);
  459. bstr = SysAllocString(szPropertyName);
  460. varT.vt = VT_BSTR;
  461. varT.bstrVal = SysAllocString(szPropertyValue);
  462. DBG_ASSERT(m_pPackage != NULL);
  463. hr = m_pPackage->put_Value(bstr, varT);
  464. FREEBSTR(bstr);
  465. VariantClear(&varT);
  466. if (FAILED(hr))
  467. {
  468. DBGPRINTF((DBG_CONTEXT,
  469. "Set Catalog Object Property failed, "
  470. "Component is %S, hr %08x\n",
  471. szPropertyName,
  472. hr));
  473. }
  474. return hr;
  475. } // WamRegPackageConfig::SetPackageObjectProperty()
  476. /*===================================================================
  477. WamRegPackageConfig::SetPackageProperties()
  478. Sets package properties for all WAMREG properties.
  479. Parameter:
  480. rgpszValues: An array containing pointers to string values to be used
  481. for setting up the WAMREG related properites for MTS catalog.
  482. Return: HRESULT
  483. Side Affect:
  484. If there is a failure all the previously set values are not cleared.
  485. The caller should make sure that the proper cleanup of package happens
  486. on partial errors.
  487. Note:
  488. ===================================================================*/
  489. HRESULT WamRegPackageConfig::SetPackageProperties
  490. (
  491. IN LPCWSTR * rgpszValues
  492. )
  493. {
  494. HRESULT hr = NOERROR;
  495. DBG_ASSERT( m_pPackage);
  496. //
  497. // Loop through all properties and set the values for these
  498. // properties using the passed in array of strings.
  499. // UGLY: MTS likes to have string properties which need to be
  500. // fed in as BSTRs => very inefficient.
  501. //
  502. for (DWORD i = 0; i < NUM_WAMREG_MTS_PROPERTIES; i++) {
  503. if ( (TsIsWindows95() && g_rgWamRegMtsProperties[i].m_fWinNTOnly) ||
  504. (rgpszValues[i] == NULL)
  505. ) {
  506. //
  507. // This parameter is for Win95 only
  508. // Or this parameter is required only for certain cases.
  509. // Skip this parameter.
  510. //
  511. continue;
  512. }
  513. DBG_ASSERT( rgpszValues[i] != NULL);
  514. IF_DEBUG( WAMREG_MTS) {
  515. DBGPRINTF(( DBG_CONTEXT,
  516. "In Package(%08x) setting property %S to value %S\n",
  517. m_pPackage,
  518. g_rgWamRegMtsProperties[i].m_pszPropName,
  519. rgpszValues[i]
  520. ));
  521. }
  522. //
  523. // Now let us set up the property in the MTS package
  524. //
  525. hr = SetPackageObjectProperty(g_rgWamRegMtsProperties[i].m_pszPropName,
  526. rgpszValues[i]);
  527. if ( FAILED (hr)) {
  528. DBGPRINTF((DBG_CONTEXT, "Failed to set property %S, value is %S\n",
  529. g_rgWamRegMtsProperties[i].m_pszPropName,
  530. rgpszValues[i]));
  531. break;
  532. }
  533. } // for all properties
  534. return (hr);
  535. } // WamRegPackageConfig::SetPackageProperties()
  536. BOOL WamRegPackageConfig::IsPackageInstalled
  537. (
  538. IN LPCWSTR szPackageID,
  539. IN LPCWSTR szComponentCLSID
  540. )
  541. /*++
  542. Routine Description:
  543. Determine if the WAM package is installed and is valid. Currently this
  544. is only called by setup.
  545. Parameters
  546. IN LPCWSTR szPackageID - Package ID
  547. IN LPCWSTR szComponentCLSID - Component CLSID
  548. Return Value
  549. BOOL - True if package contains the component. False otherwise.
  550. --*/
  551. {
  552. HRESULT hr;
  553. SAFEARRAY* aCLSIDs = NULL;
  554. SAFEARRAY* aCLSIDsComponent = NULL;
  555. DBG_ASSERT( m_pCatalog != NULL);
  556. DBG_ASSERT( m_pPkgCollection != NULL);
  557. long lPkgCount;
  558. BOOL fFound = FALSE;
  559. ICatalogCollection* pCompCollection = NULL;
  560. // Only use the trace macro here, even for error conditions.
  561. // This routine may fail in a variety of ways, but we expect
  562. // to be able to fix any of them, only report an error if
  563. // the failure is likely to impair the functionality of the
  564. // server.
  565. SETUP_TRACE((
  566. DBG_CONTEXT,
  567. "CALL - IsPackageInstalled, Package(%S) Component(%S)\n",
  568. szPackageID,
  569. szComponentCLSID
  570. ));
  571. //
  572. // Get the package
  573. //
  574. hr = GetSafeArrayOfCLSIDs(szPackageID, &aCLSIDs);
  575. if (FAILED(hr))
  576. {
  577. SETUP_TRACE((
  578. DBG_CONTEXT,
  579. "Failed to GetSafeArrayOfCLSIDs for %S, hr = %08x\n",
  580. szPackageID,
  581. hr
  582. ));
  583. goto LErrExit;
  584. }
  585. hr = m_pPkgCollection->PopulateByKey(aCLSIDs);
  586. if (FAILED(hr))
  587. {
  588. SETUP_TRACE((
  589. DBG_CONTEXT,
  590. "Failed in m_pPkgCollection(%p)->PopulateByKey(), hr = %08x\n",
  591. m_pPkgCollection,
  592. hr
  593. ));
  594. goto LErrExit;
  595. }
  596. hr = m_pPkgCollection->get_Count(&lPkgCount);
  597. if (SUCCEEDED(hr) && lPkgCount == 1)
  598. {
  599. //
  600. // We found the package. Now verify that it contains our component.
  601. //
  602. SETUP_TRACE((
  603. DBG_CONTEXT,
  604. "Successfully retrieved package (%S).\n",
  605. szPackageID
  606. ));
  607. VARIANT varKey;
  608. BSTR bstrComponentCollection;
  609. VariantInit(&varKey);
  610. varKey.vt = VT_BSTR;
  611. varKey.bstrVal = SysAllocString(szPackageID);
  612. // Get the "ComponentsInPackage" collection.
  613. bstrComponentCollection = SysAllocString(L"Components");
  614. hr = m_pPkgCollection->GetCollection(
  615. bstrComponentCollection,
  616. varKey,
  617. (IDispatch**)&pCompCollection
  618. );
  619. FREEBSTR(bstrComponentCollection);
  620. VariantClear(&varKey);
  621. if (FAILED(hr))
  622. {
  623. SETUP_TRACE((
  624. DBG_CONTEXT,
  625. "Failed in m_pPkgCollection(%p)->GetCollection(), hr = %08x\n",
  626. m_pPkgCollection,
  627. hr
  628. ));
  629. goto LErrExit;
  630. }
  631. hr = GetSafeArrayOfCLSIDs(szComponentCLSID, &aCLSIDsComponent);
  632. if (FAILED(hr))
  633. {
  634. SETUP_TRACE((
  635. DBG_CONTEXT,
  636. "Failed to GetSafeArrayOfCLSIDs for %S, hr = %08x\n",
  637. szComponentCLSID,
  638. hr
  639. ));
  640. goto LErrExit;
  641. }
  642. hr = pCompCollection->PopulateByKey( aCLSIDsComponent );
  643. if( FAILED(hr) )
  644. {
  645. SETUP_TRACE((
  646. DBG_CONTEXT,
  647. "Failed in pCompCollection(%p)->PopulateByKey, hr = %08x\n",
  648. pCompCollection,
  649. hr
  650. ));
  651. goto LErrExit;
  652. }
  653. hr = pCompCollection->get_Count( &lPkgCount );
  654. if( SUCCEEDED(hr) && lPkgCount == 1 )
  655. {
  656. // Success! We found the package and it contains the
  657. // correct component.
  658. SETUP_TRACE((
  659. DBG_CONTEXT,
  660. "Successfully retrieved component (%S) from package (%S).\n",
  661. szComponentCLSID,
  662. szPackageID
  663. ));
  664. fFound = TRUE;
  665. }
  666. }
  667. LErrExit:
  668. if (aCLSIDs != NULL)
  669. {
  670. SafeArrayDestroy(aCLSIDs);
  671. aCLSIDs = NULL;
  672. }
  673. if( aCLSIDsComponent != NULL )
  674. {
  675. SafeArrayDestroy(aCLSIDsComponent);
  676. aCLSIDsComponent = NULL;
  677. }
  678. RELEASE( pCompCollection );
  679. SETUP_TRACE((
  680. DBG_CONTEXT,
  681. "RETURN - IsPackageInstalled, hr=%08x\n",
  682. hr
  683. ));
  684. return fFound;
  685. }
  686. /*===================================================================
  687. RemovePackage
  688. Remove a Viper Package.
  689. Parameter:
  690. szPackageID: an MTS package ID.
  691. Return: HRESULT
  692. Side Affect:
  693. Note:
  694. Remove an IIS package from MTS. So far, only been called from RemoveIISPackage.
  695. RemoveComponentFromPackage() also removes a IIS package sometimes.
  696. Refer to that function header for info.
  697. ===================================================================*/
  698. HRESULT WamRegPackageConfig::RemovePackage
  699. (
  700. IN LPCWSTR szPackageID
  701. )
  702. {
  703. HRESULT hr = NOERROR;
  704. long lPkgCount = 0;
  705. long lChanges;
  706. SAFEARRAY* aCLSIDs = NULL;
  707. DBG_ASSERT(szPackageID);
  708. DBG_ASSERT( m_pCatalog != NULL);
  709. DBG_ASSERT( m_pPkgCollection != NULL);
  710. hr = GetSafeArrayOfCLSIDs(szPackageID, &aCLSIDs);
  711. if (FAILED(hr))
  712. {
  713. DBGPRINTF((DBG_CONTEXT, "Failed to get SafeArrayofCLSIDs, szPackageID is %S, hr %08x",
  714. szPackageID,
  715. hr));
  716. goto LErrExit;
  717. }
  718. //
  719. // Populate it
  720. //
  721. hr = m_pPkgCollection->PopulateByKey(aCLSIDs);
  722. if (FAILED(hr))
  723. {
  724. DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
  725. hr));
  726. goto LErrExit;
  727. }
  728. hr = m_pPkgCollection->get_Count(&lPkgCount);
  729. if (FAILED(hr))
  730. {
  731. IF_DEBUG(ERROR)
  732. {
  733. DBGPRINTF((DBG_CONTEXT, "pPkgCollection->Populate() failed, hr = %08x\n",
  734. hr));
  735. }
  736. goto LErrExit;
  737. }
  738. if (SUCCEEDED(hr) && lPkgCount == 1)
  739. {
  740. hr = m_pPkgCollection->get_Item(0, (IDispatch**)&m_pPackage);
  741. if (FAILED(hr))
  742. {
  743. goto LErrExit;
  744. }
  745. // Found it - remove it and call Save Changes
  746. // First, Set Deleteable = Y property on package
  747. hr = SetPackageObjectProperty(L"Deleteable", L"Y");
  748. if (FAILED(hr))
  749. {
  750. goto LErrExit;
  751. }
  752. RELEASE(m_pPackage);
  753. // Let save the Deletable settings
  754. hr = m_pPkgCollection->SaveChanges(&lChanges);
  755. if (FAILED(hr))
  756. {
  757. DBGPRINTF((DBG_CONTEXT, "Save the Deletable settings failed, hr = %08x\n",
  758. hr));
  759. goto LErrExit;
  760. }
  761. // Now we can delete
  762. hr = m_pPkgCollection->Remove(0);
  763. if (FAILED(hr))
  764. {
  765. DBGPRINTF((DBG_CONTEXT, "Remove the Component from package failed, hr = %08x\n",
  766. hr));
  767. goto LErrExit;
  768. }
  769. // Aha, we should be able to delete now.
  770. hr = m_pPkgCollection->SaveChanges(&lChanges);
  771. if (FAILED(hr))
  772. {
  773. DBGPRINTF((DBG_CONTEXT, "Save changes failed, hr = %08x\n",
  774. hr));
  775. goto LErrExit;
  776. }
  777. }
  778. LErrExit:
  779. if (aCLSIDs != NULL)
  780. {
  781. HRESULT hrT = SafeArrayDestroy(aCLSIDs);
  782. if (FAILED(hrT))
  783. {
  784. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
  785. hr));
  786. }
  787. aCLSIDs = NULL;
  788. }
  789. ReleaseAll();
  790. return hr;
  791. }
  792. /*===================================================================
  793. CreatePackage
  794. Create a viper package.
  795. Parameter:
  796. szPackageID: [in] Viper Package ID.
  797. szPackageName: [in] the name of the package.
  798. szIdentity: [in] Pakcage identity
  799. szIdPassword: [in] Package idneitty password
  800. fInProc: [in] Inproc or outproc package
  801. Return: HRESULT
  802. Side Affect:
  803. NONE.
  804. ===================================================================*/
  805. HRESULT WamRegPackageConfig::CreatePackage
  806. (
  807. IN LPCWSTR szPackageID,
  808. IN LPCWSTR szPackageName,
  809. IN LPCWSTR szIdentity,
  810. IN LPCWSTR szIdPassword,
  811. IN BOOL fInProc
  812. )
  813. {
  814. HRESULT hr;
  815. SAFEARRAY* aCLSIDs = NULL;
  816. DBG_ASSERT( m_pCatalog != NULL);
  817. DBG_ASSERT( m_pPkgCollection != NULL);
  818. long lPkgCount;
  819. BOOL fFound = FALSE;
  820. SETUP_TRACE((
  821. DBG_CONTEXT,
  822. "CALL - CreatePackage ID(%S) Name(%S)\n",
  823. szPackageID,
  824. szPackageName
  825. ));
  826. //
  827. // Try to get the package.
  828. //
  829. SETUP_TRACE((
  830. DBG_CONTEXT,
  831. "Checking to see if package ID(%S) Name(%S) exists.\n",
  832. szPackageID,
  833. szPackageName
  834. ));
  835. hr = GetSafeArrayOfCLSIDs(szPackageID, &aCLSIDs);
  836. if (FAILED(hr))
  837. {
  838. SETUP_TRACE_ERROR((
  839. DBG_CONTEXT,
  840. "Failed to GetSafeArrayOfCLSIDs for %S, hr = %08x\n",
  841. szPackageID,
  842. hr
  843. ));
  844. goto LErrExit;
  845. }
  846. hr = m_pPkgCollection->PopulateByKey(aCLSIDs);
  847. if (FAILED(hr))
  848. {
  849. SETUP_TRACE_ERROR((
  850. DBG_CONTEXT,
  851. "Failed in m_pPkgCollection(%p)->PopulateByKey(), hr = %08x\n",
  852. m_pPkgCollection,
  853. hr
  854. ));
  855. goto LErrExit;
  856. }
  857. hr = m_pPkgCollection->get_Count(&lPkgCount);
  858. if (SUCCEEDED(hr) && lPkgCount == 1)
  859. {
  860. //
  861. // Found the CLSID in PopulateByKey().
  862. //
  863. hr = m_pPkgCollection->get_Item(0, (IDispatch**)&m_pPackage);
  864. if (FAILED(hr))
  865. {
  866. SETUP_TRACE_ERROR((
  867. DBG_CONTEXT,
  868. "Failed in m_pPkgCollection(%p)->get_Item(). Err=%08x\n",
  869. m_pPkgCollection,
  870. hr
  871. ));
  872. goto LErrExit;
  873. }
  874. else
  875. {
  876. SETUP_TRACE((
  877. DBG_CONTEXT,
  878. "CreatePackage - Package already exists, ID(%S), Name(%S)\n",
  879. szPackageID,
  880. szPackageName
  881. ));
  882. DBG_ASSERT(m_pPackage);
  883. fFound = TRUE;
  884. }
  885. }
  886. if ( SUCCEEDED(hr) )
  887. {
  888. if( !fFound )
  889. {
  890. SETUP_TRACE((
  891. DBG_CONTEXT,
  892. "Package ID(%S) Name(%S) does not exist. Attempting to create it.\n",
  893. szPackageID,
  894. szPackageName
  895. ));
  896. //
  897. // The package does not already exist, we need to call Add() to
  898. // add this package and then set it's properties.
  899. //
  900. hr = m_pPkgCollection->Add((IDispatch**)&m_pPackage);
  901. if ( FAILED(hr))
  902. {
  903. SETUP_TRACE_ERROR((
  904. DBG_CONTEXT,
  905. "Failed in m_pPkgCollection(%p)->Add(). Err=%08x\n",
  906. m_pPkgCollection,
  907. hr
  908. ));
  909. goto LErrExit;
  910. }
  911. }
  912. DBG_ASSERT( SUCCEEDED( hr));
  913. DBG_ASSERT( m_pPackage != NULL);
  914. if( SUCCEEDED(hr) && m_pPackage != NULL )
  915. {
  916. //
  917. // Set the Package properties
  918. // first by initializing the array of values and then
  919. // calling SetPackageProperties()
  920. //
  921. LPCWSTR rgpszValues[ MAX_WAMREG_MTS_PROP_NAMES];
  922. ZeroMemory( rgpszValues, sizeof( rgpszValues));
  923. if( fFound )
  924. {
  925. // For an existing package, we don't want to set the ID
  926. rgpszValues[ WM_ID] = NULL;
  927. }
  928. else
  929. {
  930. rgpszValues[ WM_ID] = szPackageID;
  931. }
  932. rgpszValues[ WM_NAME] = szPackageName;
  933. rgpszValues[ WM_CREATED_BY] =
  934. L"Microsoft Internet Information Services";
  935. rgpszValues[ WM_RUN_FOREVER] = L"Y";
  936. rgpszValues[ WM_IDENTITY] = szIdentity;
  937. rgpszValues[ WM_PASSWORD] = szIdPassword;
  938. rgpszValues[ WM_ACTIVATION] =
  939. ((fInProc) ? L"InProc" : L"Local");
  940. rgpszValues[ WM_CHANGEABLE] = L"Y";
  941. rgpszValues[ WM_DELETABLE] = L"N";
  942. rgpszValues[ WM_SECSUPP] = L"0";
  943. //
  944. // Now that we have the properties setup, let us
  945. // now set the properties in the MTS using catalog
  946. // object
  947. //
  948. hr = SetPackageProperties( rgpszValues);
  949. if ( FAILED( hr))
  950. {
  951. SETUP_TRACE_ERROR((
  952. DBG_CONTEXT,
  953. "Failed to set properties for package %p. Err=%08x\n",
  954. m_pPackage,
  955. hr
  956. ));
  957. goto LErrExit;
  958. }
  959. long lChanges;
  960. hr = m_pPkgCollection->SaveChanges(&lChanges);
  961. if (FAILED(hr))
  962. {
  963. SETUP_TRACE_ERROR((
  964. DBG_CONTEXT,
  965. "Failed in m_pPkgCollection(%p)->SaveChanges. error = %08x\n",
  966. m_pPkgCollection,
  967. hr
  968. ));
  969. goto LErrExit;
  970. }
  971. }
  972. }
  973. LErrExit:
  974. if (aCLSIDs != NULL)
  975. {
  976. SafeArrayDestroy(aCLSIDs);
  977. aCLSIDs = NULL;
  978. }
  979. if (FAILED(hr))
  980. {
  981. SETUP_TRACE_ERROR((
  982. DBG_CONTEXT,
  983. "Failed to Create Package. Package Name = %S, Package ID = %S, error = %08x\n",
  984. szPackageName,
  985. szPackageID,
  986. hr
  987. ));
  988. }
  989. SETUP_TRACE_ASSERT(SUCCEEDED(hr));
  990. ReleaseAll();
  991. SETUP_TRACE((
  992. DBG_CONTEXT,
  993. "RETURN - CreatePackage ID(%S) Name(%S)\n",
  994. szPackageID,
  995. szPackageName
  996. ));
  997. return hr;
  998. }
  999. /*===================================================================
  1000. AddComponentFromPackage
  1001. Add a Component (a WAM CLSID) from a Viper Package. Assume the package
  1002. is already existed.
  1003. Parameter:
  1004. szPackageID: [in] Viper Package ID.
  1005. szComponentCLSID: [in] Component CLSID.
  1006. fInProc: [in] if TRUE, we set certain property on the Component.
  1007. Return: HRESULT
  1008. Side Affect:
  1009. NONE.
  1010. ===================================================================*/
  1011. HRESULT WamRegPackageConfig::AddComponentToPackage
  1012. (
  1013. IN LPCWSTR szPackageID,
  1014. IN LPCWSTR szComponentCLSID
  1015. )
  1016. {
  1017. HRESULT hr;
  1018. BSTR bstrGUID = NULL;
  1019. BSTR bstr = NULL;
  1020. VARIANT varKey;
  1021. long lChanges;
  1022. BOOL fFound;
  1023. long lPkgCount;
  1024. BOOL fImported = FALSE;
  1025. SETUP_TRACE((
  1026. DBG_CONTEXT,
  1027. "CALL - AddComponentToPackage, Package(%S) Component(%S)\n",
  1028. szPackageID,
  1029. szComponentCLSID
  1030. ));
  1031. DBG_ASSERT(szPackageID);
  1032. DBG_ASSERT(szComponentCLSID);
  1033. VariantInit(&varKey);
  1034. VariantClear(&varKey);
  1035. DBG_ASSERT( m_pCatalog != NULL);
  1036. DBG_ASSERT( m_pPkgCollection != NULL);
  1037. varKey.vt = VT_BSTR;
  1038. varKey.bstrVal = SysAllocString(szPackageID);
  1039. bstr = SysAllocString(szPackageID);
  1040. bstrGUID = SysAllocString(szComponentCLSID);
  1041. hr = m_pCatalog->ImportComponent(bstr, bstrGUID);
  1042. FREEBSTR(bstr);
  1043. FREEBSTR(bstrGUID);
  1044. if (FAILED(hr))
  1045. {
  1046. SETUP_TRACE_ERROR((
  1047. DBG_CONTEXT,
  1048. "Failed in m_pCatalog(%p)->ImportComponent(). error %08x\n",
  1049. m_pCatalog,
  1050. hr
  1051. ));
  1052. goto LErrExit;
  1053. }
  1054. else
  1055. {
  1056. fImported = TRUE;
  1057. }
  1058. // Get the "ComponentsInPackage" collection.
  1059. bstr = SysAllocString(L"Components");
  1060. hr = m_pPkgCollection->GetCollection(bstr, varKey, (IDispatch**)&m_pCompCollection);
  1061. FREEBSTR(bstr);
  1062. VariantClear(&varKey);
  1063. if (FAILED(hr))
  1064. {
  1065. SETUP_TRACE_ERROR((
  1066. DBG_CONTEXT,
  1067. "Failed in m_pPkgCollection(%p)->GetCollection(). error %08x\n",
  1068. m_pPkgCollection,
  1069. hr
  1070. ));
  1071. goto LErrExit;
  1072. }
  1073. //
  1074. // Find and Set properties on the component object
  1075. //
  1076. hr = SetComponentObjectProperties( szComponentCLSID);
  1077. if ( FAILED(hr))
  1078. {
  1079. SETUP_TRACE_ERROR((
  1080. DBG_CONTEXT,
  1081. "Failed to SetComponentObjectProperties. error %08x\n",
  1082. hr
  1083. ));
  1084. goto LErrExit;
  1085. }
  1086. LErrExit:
  1087. // Save changes
  1088. if (SUCCEEDED(hr))
  1089. {
  1090. hr = m_pCompCollection->SaveChanges(&lChanges);
  1091. if (FAILED(hr))
  1092. {
  1093. SETUP_TRACE_ERROR((
  1094. DBG_CONTEXT,
  1095. "Failed in m_pCompCollection(%p)->SaveChanges(), error = %08x\n",
  1096. m_pCompCollection,
  1097. hr
  1098. ));
  1099. }
  1100. }
  1101. else
  1102. {
  1103. // CODEWORK - This seems like a bad idea. The release should drop any
  1104. // changes we made, so this cleanup code seems to be asking for trouble.
  1105. // Need to remove component from the package
  1106. if (fImported && m_pCompCollection )
  1107. {
  1108. SETUP_TRACE_ERROR((
  1109. DBG_CONTEXT,
  1110. "Failed in AddComponentToPackage, removing the component, error = %08x\n",
  1111. hr
  1112. ));
  1113. HRESULT hrT;
  1114. long lCompCount;
  1115. // Find our component in the list (should be the only one)
  1116. hrT = m_pCompCollection->get_Count(&lCompCount);
  1117. if (SUCCEEDED(hrT))
  1118. {
  1119. fFound = FALSE;
  1120. if (SUCCEEDED(hrT) && lCompCount == 1)
  1121. {
  1122. // Found it
  1123. fFound = TRUE;
  1124. hrT = m_pCompCollection->Remove(0);
  1125. if (SUCCEEDED(hrT))
  1126. {
  1127. hrT = m_pCompCollection->SaveChanges(&lChanges);
  1128. if (FAILED(hrT))
  1129. {
  1130. SETUP_TRACE_ERROR((
  1131. DBG_CONTEXT,
  1132. "Failed in m_pCompCollection->SaveChanges() during cleanup, error = %08x\n",
  1133. hrT
  1134. ));
  1135. }
  1136. }
  1137. else
  1138. {
  1139. SETUP_TRACE_ERROR((
  1140. DBG_CONTEXT,
  1141. "Failed in m_pCompCollection->Remove() during cleanup, hr = %08x\n",
  1142. hrT
  1143. ));
  1144. }
  1145. }
  1146. }
  1147. }
  1148. }
  1149. FREEBSTR(bstr);
  1150. VariantClear(&varKey);
  1151. ReleaseAll();
  1152. SETUP_TRACE((
  1153. DBG_CONTEXT,
  1154. "RETURN - AddComponentToPackage, Package(%S) Component(%S), hr=%08x\n",
  1155. szPackageID,
  1156. szComponentCLSID,
  1157. hr
  1158. ));
  1159. return hr;
  1160. }
  1161. /*===================================================================
  1162. RemoveComponentFromPackage
  1163. Remove a Component (a WAM CLSID) from a Viper Package.
  1164. Parameter:
  1165. szPackageID: [in] Viper Package ID.
  1166. szComponentCLSID: [in] Component CLSID.
  1167. fDeletePackage: [in] if TRUE, we delete the package always. (be very careful, with in-proc
  1168. package).
  1169. Return: HRESULT
  1170. Side Affect:
  1171. After remove the component from the package, if the component count in the
  1172. package is 0, then delete the whole package.
  1173. ===================================================================*/
  1174. HRESULT WamRegPackageConfig::RemoveComponentFromPackage
  1175. (
  1176. IN LPCWSTR szPackageID,
  1177. IN LPCWSTR szComponentCLSID,
  1178. IN DWORD dwAppIsolated
  1179. )
  1180. {
  1181. HRESULT hr;
  1182. BSTR bstr = NULL;
  1183. BSTR bstrGUID = NULL;
  1184. VARIANT varKey;
  1185. VARIANT varT;
  1186. SAFEARRAY* aCLSIDs = NULL;
  1187. LONG Indices[1];
  1188. long lPkgCount, lCompCount, lChanges;
  1189. long lPkgIndex = 0;
  1190. BOOL fFound;
  1191. VariantInit(&varKey);
  1192. VariantClear(&varKey);
  1193. VariantInit(&varT);
  1194. VariantClear(&varT);
  1195. DBG_ASSERT( m_pCatalog != NULL);
  1196. DBG_ASSERT( m_pPkgCollection != NULL);
  1197. hr = GetSafeArrayOfCLSIDs(szPackageID, &aCLSIDs);
  1198. //
  1199. // Populate it
  1200. //
  1201. hr = m_pPkgCollection->PopulateByKey(aCLSIDs);
  1202. if (FAILED(hr))
  1203. {
  1204. DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
  1205. hr));
  1206. goto LErrExit;
  1207. }
  1208. // Find our component in the list (should be the only one)
  1209. hr = m_pPkgCollection->get_Count(&lPkgCount);
  1210. if (FAILED(hr))
  1211. {
  1212. DBGPRINTF((DBG_CONTEXT, "Failed to call MTS Admin API. error %08x\n", hr));
  1213. goto LErrExit;
  1214. }
  1215. fFound = FALSE;
  1216. if (SUCCEEDED(hr) && lPkgCount == 1)
  1217. {
  1218. hr = m_pPkgCollection->get_Item(0, (IDispatch**)&m_pPackage);
  1219. if (FAILED(hr))
  1220. {
  1221. DBGPRINTF((DBG_CONTEXT, "Failed to call MTS Admin API. error %08x\n", hr));
  1222. goto LErrExit;
  1223. }
  1224. hr = m_pPackage->get_Key(&varKey);
  1225. if (SUCCEEDED(hr))
  1226. {
  1227. // Found it
  1228. DBG_ASSERT(m_pPackage);
  1229. fFound = TRUE;
  1230. }
  1231. }
  1232. // Get the "Components" collection.
  1233. bstr = SysAllocString(L"Components");
  1234. hr = m_pPkgCollection->GetCollection(bstr, varKey, (IDispatch**)&m_pCompCollection);
  1235. FREEBSTR(bstr);
  1236. VariantClear(&varKey);
  1237. if (FAILED(hr))
  1238. {
  1239. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1240. goto LErrExit;
  1241. }
  1242. // Repopulate the collection so we can find our object and set properties on it
  1243. Indices[0] = 0;
  1244. VariantInit(&varT);
  1245. varT.vt = VT_BSTR;
  1246. varT.bstrVal = SysAllocString(szComponentCLSID);
  1247. hr = SafeArrayPutElement(aCLSIDs, Indices, &varT);
  1248. VariantClear(&varT);
  1249. if (FAILED(hr))
  1250. {
  1251. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
  1252. hr));
  1253. }
  1254. //
  1255. // Populate it
  1256. //
  1257. hr = m_pCompCollection->PopulateByKey(aCLSIDs);
  1258. if (FAILED(hr))
  1259. {
  1260. DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
  1261. hr));
  1262. goto LErrExit;
  1263. }
  1264. // Find our component in the list (should be the only one)
  1265. hr = m_pCompCollection->get_Count(&lCompCount);
  1266. if (FAILED(hr))
  1267. {
  1268. DBGPRINTF((DBG_CONTEXT, "Failed to call MTS Admin API. error %08x\n", hr));
  1269. goto LErrExit;
  1270. }
  1271. fFound = FALSE;
  1272. if (SUCCEEDED(hr) && lCompCount == 1)
  1273. {
  1274. // Found it
  1275. fFound = TRUE;
  1276. hr = m_pCompCollection->Remove(0);
  1277. if (FAILED(hr))
  1278. {
  1279. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1280. goto LErrExit;
  1281. }
  1282. }
  1283. DBG_ASSERT(fFound);
  1284. // Save changes
  1285. hr = m_pCompCollection->SaveChanges(&lChanges);
  1286. if (FAILED(hr))
  1287. {
  1288. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1289. goto LErrExit;
  1290. }
  1291. //
  1292. // Need to populate again to get the Component count after remove the component from
  1293. // the package. The populatebykey only populate 1 component a time.
  1294. // However, if this package is the default package hosting all in-proc WAM components,
  1295. // we know that there is at least one component W3SVC always in this package, therefore
  1296. // we skip the GetComponentCount call here.
  1297. // The component count for the default package must be at least one,
  1298. //
  1299. // Set lCompCount = 1, so that the only case that lCompCount becomes 0 is the OutProc
  1300. // Islated package has 0 components.
  1301. lCompCount = 1;
  1302. if (dwAppIsolated == static_cast<DWORD>(eAppRunOutProcIsolated))
  1303. {
  1304. hr = m_pCompCollection->Populate();
  1305. if (FAILED(hr))
  1306. {
  1307. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1308. goto LErrExit;
  1309. }
  1310. // Find our component in the list (should be the only one)
  1311. hr = m_pCompCollection->get_Count(&lCompCount);
  1312. if (FAILED(hr))
  1313. {
  1314. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1315. goto LErrExit;
  1316. }
  1317. // Component count is 0, remove the package.
  1318. if (lCompCount == 0)
  1319. {
  1320. // Found it - remove it and call Save Changes
  1321. // First, Set Deleteable = Y property on package
  1322. hr = SetPackageObjectProperty(L"Deleteable", L"Y");
  1323. if (FAILED(hr))
  1324. {
  1325. goto LErrExit;
  1326. }
  1327. RELEASE(m_pPackage);
  1328. // Let save the Deletable settings
  1329. hr = m_pPkgCollection->SaveChanges(&lChanges);
  1330. if (FAILED(hr))
  1331. {
  1332. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1333. goto LErrExit;
  1334. }
  1335. hr = m_pPkgCollection->Remove(0);
  1336. if (FAILED(hr))
  1337. {
  1338. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1339. goto LErrExit;
  1340. }
  1341. }
  1342. else
  1343. {
  1344. // Set Attribute Deleteable = "Y"
  1345. hr = SetPackageObjectProperty(L"Deleteable", L"Y");
  1346. if (FAILED(hr))
  1347. {
  1348. goto LErrExit;
  1349. }
  1350. // Set CreatedBy = ""
  1351. hr = SetPackageObjectProperty(L"CreatedBy", L"");
  1352. if (FAILED(hr))
  1353. {
  1354. goto LErrExit;
  1355. }
  1356. // Set Identity to Interactive User. MTS might use that package with "Interactive User"
  1357. // as the indentity.
  1358. hr = SetPackageObjectProperty(L"Identity", L"Interactive User");
  1359. if (FAILED(hr))
  1360. {
  1361. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1362. goto LErrExit;
  1363. }
  1364. RELEASE(m_pPackage);
  1365. }
  1366. hr = m_pPkgCollection->SaveChanges(&lChanges);
  1367. if (FAILED(hr))
  1368. {
  1369. DBGPRINTF((DBG_CONTEXT, "Failed to Call MTS Admin API, hr = %08x\n", hr));
  1370. goto LErrExit;
  1371. }
  1372. }
  1373. LErrExit:
  1374. if (aCLSIDs != NULL)
  1375. {
  1376. HRESULT hrT;
  1377. hrT = SafeArrayDestroy(aCLSIDs);
  1378. if (FAILED(hrT))
  1379. {
  1380. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
  1381. hr));
  1382. }
  1383. aCLSIDs = NULL;
  1384. }
  1385. FREEBSTR(bstr);
  1386. VariantClear(&varKey);
  1387. VariantClear(&varT);
  1388. ReleaseAll();
  1389. return hr;
  1390. }
  1391. #if 0
  1392. // OBSOLETE - This fix (335422) was implemented in script but
  1393. // some of the code is general enough that it might be worth
  1394. // keeping around for a while.
  1395. HRESULT
  1396. WamRegPackageConfig::ResetPackageActivation
  1397. (
  1398. IN LPCWSTR wszPackageID,
  1399. IN LPCWSTR wszIWamUser,
  1400. IN LPCWSTR wszIWamPass
  1401. )
  1402. /*+
  1403. Routine Description:
  1404. Retrieve the specified package and reset its activation
  1405. identity.
  1406. This is really a crummy method, but this whole class is
  1407. not really designed to provide a wrapper for the com admin
  1408. api, so it's much safer just to make this a specific method.
  1409. Arguments:
  1410. IN LPCWSTR wszPackageID - the package to reset
  1411. IN LPCWSTR wszIWamUser - IWAM_*
  1412. IN LPCWSTR wszIWamPass - password for IWAM_*
  1413. Returns:
  1414. HRESULT
  1415. -*/
  1416. {
  1417. HRESULT hr = NOERROR;
  1418. LONG nChanges = 0;
  1419. DBG_ASSERT( m_pCatalog != NULL);
  1420. DBG_ASSERT( m_pPkgCollection != NULL);
  1421. DBG_ASSERT( m_pPackage == NULL );
  1422. hr = LoadPackage( wszPackageID );
  1423. if( SUCCEEDED(hr) )
  1424. {
  1425. DBG_ASSERT( m_pPackage != NULL );
  1426. LPCWSTR rgpszValues[ MAX_WAMREG_MTS_PROP_NAMES ];
  1427. ZeroMemory( rgpszValues, sizeof(rgpszValues) );
  1428. rgpszValues[WM_IDENTITY] = wszIWamUser;
  1429. rgpszValues[WM_PASSWORD] = wszIWamPass;
  1430. hr = SetPackageProperties( rgpszValues );
  1431. if( SUCCEEDED(hr) )
  1432. {
  1433. hr = m_pPkgCollection->SaveChanges( &nChanges );
  1434. }
  1435. }
  1436. ReleaseAll();
  1437. return hr;
  1438. }
  1439. HRESULT
  1440. WamRegPackageConfig::LoadPackage
  1441. (
  1442. IN LPCWSTR wszPackageID
  1443. )
  1444. /*+
  1445. Routine Description:
  1446. Retrieve the specified package into m_pPackage
  1447. TODO - Use this when creating as well. Need to add
  1448. the necessary debug/setuplog traces.
  1449. Arguments:
  1450. IN LPCWSTR wszPackageID - the package to load
  1451. Returns:
  1452. HRESULT
  1453. -*/
  1454. {
  1455. HRESULT hr = NOERROR;
  1456. SAFEARRAY* psaPackageClsid = NULL;
  1457. DBG_ASSERT( m_pCatalog != NULL);
  1458. DBG_ASSERT( m_pPkgCollection != NULL);
  1459. DBG_ASSERT( m_pPackage == NULL );
  1460. hr = GetSafeArrayOfCLSIDs( wszPackageID, &psaPackageClsid );
  1461. if( SUCCEEDED(hr) )
  1462. {
  1463. hr = m_pPkgCollection->PopulateByKey( psaPackageClsid );
  1464. DBG_CODE(
  1465. if( SUCCEEDED(hr) )
  1466. {
  1467. LONG nPackages;
  1468. hr = m_pPkgCollection->get_Count( &nPackages );
  1469. DBG_ASSERT( SUCCEEDED(hr) );
  1470. DBG_ASSERT( nPackages == 1 );
  1471. }
  1472. );
  1473. if( SUCCEEDED(hr) )
  1474. {
  1475. hr = m_pPkgCollection->get_Item( 0, (IDispatch **)&m_pPackage );
  1476. }
  1477. }
  1478. if( psaPackageClsid ) SafeArrayDestroy( psaPackageClsid );
  1479. return hr;
  1480. }
  1481. // OBSOLETE
  1482. #endif