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.

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