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.

844 lines
25 KiB

  1. // asptxn.cpp : Implementation of DLL Exports.
  2. // Note: Proxy/Stub Information
  3. // To merge the proxy/stub code into the object DLL, add the file
  4. // dlldatax.c to the project. Make sure precompiled headers
  5. // are turned off for this file, and add _MERGE_PROXYSTUB to the
  6. // defines for the project.
  7. //
  8. // If you are not running WinNT4.0 or Win95 with DCOM, then you
  9. // need to remove the following define from dlldatax.c
  10. // #define _WIN32_WINNT 0x0400
  11. //
  12. // Further, if you are running MIDL without /Oicf switch, you also
  13. // need to remove the following define from dlldatax.c.
  14. // #define USE_STUBLESS_PROXY
  15. //
  16. // Modify the custom build rule for asptxn.idl by adding the following
  17. // files to the Outputs.
  18. // asptxn_p.c
  19. // dlldata.c
  20. // To build a separate proxy/stub DLL,
  21. // run nmake -f asptxnps.mk in the project directory.
  22. #include "stdafx.h"
  23. #include "resource.h"
  24. #include <initguid.h>
  25. #include "txnscrpt.h"
  26. #include "dlldatax.h"
  27. #include "txnscrpt_i.c"
  28. #include "txnobj.h"
  29. #include <dbgutil.h>
  30. #include <comadmin.h>
  31. #ifdef _MERGE_PROXYSTUB
  32. extern "C" HINSTANCE hProxyDll;
  33. #endif
  34. CComModule _Module;
  35. BEGIN_OBJECT_MAP(ObjectMap)
  36. OBJECT_ENTRY(CLSID_ASPObjectContextTxRequired, CASPObjectContext)
  37. OBJECT_ENTRY(CLSID_ASPObjectContextTxRequiresNew, CASPObjectContext)
  38. OBJECT_ENTRY(CLSID_ASPObjectContextTxSupported, CASPObjectContext)
  39. OBJECT_ENTRY(CLSID_ASPObjectContextTxNotSupported, CASPObjectContext)
  40. END_OBJECT_MAP()
  41. LPCSTR g_szModuleName = "ASPTXN";
  42. #ifdef _NO_TRACING_
  43. DECLARE_DEBUG_VARIABLE();
  44. #else
  45. #include <initguid.h>
  46. DEFINE_GUID(IisAspTxnGuid,
  47. 0x784d8908, 0xaa8c, 0x11d2, 0x92, 0x5e, 0x00, 0xc0, 0x4f, 0x72, 0xd9, 0x0e);
  48. #endif
  49. DECLARE_DEBUG_PRINTS_OBJECT();
  50. /////////////////////////////////////////////////////////////////////////////
  51. // DLL Entry Point
  52. extern "C"
  53. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  54. {
  55. lpReserved;
  56. #ifdef _MERGE_PROXYSTUB
  57. if (!PrxDllMain(hInstance, dwReason, lpReserved))
  58. return FALSE;
  59. #endif
  60. if (dwReason == DLL_PROCESS_ATTACH)
  61. {
  62. CREATE_DEBUG_PRINT_OBJECT( g_szModuleName, IisAspTxnGuid );
  63. if( !VALID_DEBUG_PRINT_OBJECT() )
  64. {
  65. return FALSE;
  66. }
  67. _Module.Init(ObjectMap, hInstance /*, ATL21 &LIBID_ASPTXNLib */);
  68. DisableThreadLibraryCalls(hInstance);
  69. }
  70. else if (dwReason == DLL_PROCESS_DETACH)
  71. {
  72. _Module.Term();
  73. DELETE_DEBUG_PRINT_OBJECT();
  74. }
  75. return TRUE; // ok
  76. }
  77. /////////////////////////////////////////////////////////////////////////////
  78. // Used to determine whether the DLL can be unloaded by OLE
  79. STDAPI DllCanUnloadNow(void)
  80. {
  81. #ifdef _MERGE_PROXYSTUB
  82. if (PrxDllCanUnloadNow() != S_OK)
  83. return S_FALSE;
  84. #endif
  85. return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
  86. }
  87. /////////////////////////////////////////////////////////////////////////////
  88. // Returns a class factory to create an object of the requested type
  89. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  90. {
  91. #ifdef _MERGE_PROXYSTUB
  92. if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
  93. return S_OK;
  94. #endif
  95. return _Module.GetClassObject(rclsid, riid, ppv);
  96. }
  97. /////////////////////////////////////////////////////////////////////////////
  98. // DllRegisterServer - Adds entries to the system registry
  99. // Forward references
  100. HRESULT ViperizeContextObject();
  101. HRESULT AddViperUtilPackage();
  102. HRESULT RemoveViperUtilPackage(ICatalogCollection* pPkgCollectionT);
  103. HRESULT AddContextObjectToViperPackage();
  104. STDAPI DllRegisterServer(void)
  105. {
  106. #ifdef _MERGE_PROXYSTUB
  107. HRESULT hRes = PrxDllRegisterServer();
  108. if (FAILED(hRes))
  109. return hRes;
  110. #endif
  111. HRESULT hr = NOERROR;
  112. // registers object, typelib and all interfaces in typelib
  113. hr = _Module.RegisterServer(TRUE);
  114. // create the iis utilities package
  115. if( SUCCEEDED(hr) )
  116. {
  117. HRESULT hrCoInit = CoInitialize( NULL );
  118. // This is kinda dopey, but remove the package if it exists
  119. // so we don't get bogus errors when we add. Ignore the return.
  120. RemoveViperUtilPackage(NULL);
  121. hr = ViperizeContextObject();
  122. if( SUCCEEDED(hrCoInit) )
  123. {
  124. CoUninitialize();
  125. }
  126. }
  127. return hr;
  128. }
  129. /////////////////////////////////////////////////////////////////////////////
  130. // DllUnregisterServer - Removes entries from the system registry
  131. STDAPI DllUnregisterServer(void)
  132. {
  133. #ifdef _MERGE_PROXYSTUB
  134. PrxDllUnregisterServer();
  135. #endif
  136. HRESULT hr = NOERROR;
  137. HRESULT hrCoInit = CoInitialize( NULL );
  138. // Remove the iis utilities package before unregistering the objects
  139. hr = RemoveViperUtilPackage(NULL);
  140. if( SUCCEEDED(hrCoInit) )
  141. {
  142. CoUninitialize();
  143. }
  144. // We don't really care about failures...
  145. hr = _Module.UnregisterServer(/* ATL21 TRUE */);
  146. // NOTE: ATL doesn't unregister the typelibrary. Since
  147. // the interfaces we are exposing are internal to asp we should
  148. // consider removing the typelibrary registry entries.
  149. return hr;
  150. }
  151. // Registration code to be pulled from asp.dll
  152. #define RELEASE(p) if ( p ) { p->Release(); p = NULL; }
  153. #define FREEBSTR(p) SysFreeString( p ); p = NULL;
  154. const WCHAR wszCLSID_ASPObjectContextTxRequired[] = L"{14D0916D-9CDC-11D1-8C4A-00C04FC324A4}";
  155. const WCHAR wszCLSID_ASPObjectContextTxRequiresNew[] = L"{14D0916E-9CDC-11D1-8C4A-00C04FC324A4}";
  156. const WCHAR wszCLSID_ASPObjectContextTxSupported[] = L"{14D0916F-9CDC-11D1-8C4A-00C04FC324A4}";
  157. const WCHAR wszCLSID_ASPObjectContextTxNotSupported[] = L"{14D09170-9CDC-11D1-8C4A-00C04FC324A4}";
  158. const WCHAR wszASPUtilitiesPackageID[] = L"{ADA44581-02C1-11D1-804A-0000F8036614}";
  159. /*===================================================================
  160. GetSafeArrayOfCLSIDs
  161. Get a SafeArray contains one ComponentCLSID
  162. Parameter:
  163. szComponentCLSID the CLSID need to be put in the safe array
  164. paCLSIDs pointer to a pointer of safe array(safe array provided by
  165. caller).
  166. Return: HRESULT
  167. Side Affect:
  168. Note:
  169. ===================================================================*/
  170. HRESULT GetSafeArrayOfCLSIDs
  171. (
  172. IN LPCWSTR szComponentCLSID,
  173. OUT SAFEARRAY** paCLSIDs
  174. )
  175. {
  176. SAFEARRAY* aCLSIDs = NULL;
  177. SAFEARRAYBOUND rgsaBound[1];
  178. LONG Indices[1];
  179. VARIANT varT;
  180. HRESULT hr = NOERROR;
  181. DBG_ASSERT(szComponentCLSID && paCLSIDs);
  182. DBG_ASSERT(*paCLSIDs == NULL);
  183. // PopulateByKey is expecting a SAFEARRAY parameter input,
  184. // Create a one element SAFEARRAY, the one element of the SAFEARRAY contains
  185. // the packageID.
  186. rgsaBound[0].cElements = 1;
  187. rgsaBound[0].lLbound = 0;
  188. aCLSIDs = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
  189. if (aCLSIDs)
  190. {
  191. Indices[0] = 0;
  192. VariantInit(&varT);
  193. varT.vt = VT_BSTR;
  194. varT.bstrVal = SysAllocString(szComponentCLSID);
  195. hr = SafeArrayPutElement(aCLSIDs, Indices, &varT);
  196. VariantClear(&varT);
  197. if (FAILED(hr))
  198. {
  199. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayPutElement, CLSID is %S, hr %08x\n",
  200. szComponentCLSID,
  201. hr));
  202. if (aCLSIDs != NULL)
  203. {
  204. HRESULT hrT = SafeArrayDestroy(aCLSIDs);
  205. if (FAILED(hrT))
  206. {
  207. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayDestroy(aCLSIDs), hr = %08x\n",
  208. hr));
  209. }
  210. aCLSIDs = NULL;
  211. }
  212. }
  213. }
  214. else
  215. {
  216. hr = HRESULT_FROM_WIN32(GetLastError());
  217. DBGPRINTF((DBG_CONTEXT, "Failed to call SafeArrayCreate, hr %08x\n",
  218. hr));
  219. }
  220. *paCLSIDs = aCLSIDs;
  221. return hr;
  222. }
  223. /*===================================================================
  224. ViperizeContextObject
  225. Creates a Viper package, and adds the Context object to that
  226. package, and marks the object as "InProc".
  227. Returns:
  228. HRESULT - NOERROR on success
  229. Side effects:
  230. Creates Viper package, Viperizes Context object
  231. ===================================================================*/
  232. HRESULT ViperizeContextObject(void)
  233. {
  234. HRESULT hr;
  235. // Add the IIS utility package
  236. hr = AddViperUtilPackage();
  237. // Add the context object to the package
  238. if (SUCCEEDED(hr))
  239. hr = AddContextObjectToViperPackage();
  240. return hr;
  241. }
  242. /*===================================================================
  243. AddViperUtilPackage
  244. Creates a Viper package named "IIS Utility"
  245. Returns:
  246. HRESULT - NOERROR on success
  247. Side effects:
  248. Creates Viper package
  249. ===================================================================*/
  250. HRESULT AddViperUtilPackage(void)
  251. {
  252. HRESULT hr;
  253. BSTR bstr = NULL;
  254. VARIANT varT;
  255. ICatalogCollection* pPkgCollection = NULL;
  256. ICatalogObject* pPackage = NULL;
  257. ICOMAdminCatalog* pCatalog = NULL;
  258. long lPkgCount, lChanges, i;
  259. VariantInit(&varT);
  260. // Create instance of the catalog object
  261. hr = CoCreateInstance(CLSID_COMAdminCatalog
  262. , NULL
  263. , CLSCTX_INPROC_SERVER
  264. , IID_ICOMAdminCatalog
  265. , (void**)&pCatalog);
  266. if (FAILED(hr))
  267. goto LErr;
  268. // Get the Packages collection
  269. bstr = SysAllocString(L"Applications");
  270. hr = pCatalog->GetCollection(bstr, (IDispatch**)&pPkgCollection);
  271. FREEBSTR(bstr);
  272. if (FAILED(hr))
  273. goto LErr;
  274. // Add new IIS Utilities package
  275. hr = pPkgCollection->Add((IDispatch**)&pPackage);
  276. if (FAILED(hr))
  277. goto LErr;
  278. // Set package ID to L"{ADA44581-02C1-11D1-804A-0000F8036614}",
  279. // MTS replication code looks for This fixed packageID
  280. bstr = SysAllocString(L"ID");
  281. varT.vt = VT_BSTR;
  282. varT.bstrVal = SysAllocString(wszASPUtilitiesPackageID);
  283. hr = pPackage->put_Value(bstr, varT);
  284. FREEBSTR(bstr);
  285. VariantClear(&varT);
  286. if (FAILED(hr))
  287. goto LErr;
  288. // Set package "Name" property to "IIS Utilities"
  289. bstr = SysAllocString(L"Name");
  290. varT.vt = VT_BSTR;
  291. varT.bstrVal = SysAllocString(L"IIS Utilities");
  292. hr = pPackage->put_Value(bstr, varT);
  293. FREEBSTR(bstr);
  294. VariantClear(&varT);
  295. if (FAILED(hr))
  296. goto LErr;
  297. // Set activation to InProc
  298. bstr = SysAllocString(L"Activation");
  299. varT.vt = VT_BSTR;
  300. varT.bstrVal = SysAllocString(L"InProc");
  301. hr = pPackage->put_Value(bstr, varT);
  302. FREEBSTR(bstr);
  303. VariantClear(&varT);
  304. if (FAILED(hr))
  305. goto LErr;
  306. // Set CreatedBy to MS IIS
  307. bstr = SysAllocString(L"CreatedBy");
  308. varT.vt = VT_BSTR;
  309. varT.bstrVal = SysAllocString(L"Microsoft Internet Information Services (tm)");
  310. hr = pPackage->put_Value(bstr, varT);
  311. FREEBSTR(bstr);
  312. VariantClear(&varT);
  313. if (FAILED(hr))
  314. goto LErr;
  315. // Set Deleteable = N property on package
  316. bstr = SysAllocString(L"Deleteable");
  317. varT.vt = VT_BSTR;
  318. varT.bstrVal = SysAllocString(L"N");
  319. hr = pPackage->put_Value(bstr, varT);
  320. FREEBSTR(bstr);
  321. VariantClear(&varT);
  322. if (FAILED(hr))
  323. goto LErr;
  324. bstr = SysAllocString(L"AccessChecksLevel");
  325. varT.vt = VT_BSTR;
  326. varT.bstrVal = SysAllocString(L"0");
  327. hr = pPackage->put_Value(bstr, varT);
  328. FREEBSTR(bstr);
  329. VariantClear(&varT);
  330. if (FAILED(hr))
  331. goto LErr;
  332. // Save changes
  333. hr = pPkgCollection->SaveChanges(&lChanges);
  334. if (FAILED(hr))
  335. goto LErr;
  336. LErr:
  337. RELEASE(pPkgCollection);
  338. RELEASE(pPackage);
  339. RELEASE(pCatalog);
  340. return hr;
  341. }
  342. /*===================================================================
  343. RemoveViperUtilPackage
  344. Removes the Viper package named "IIS Utility"
  345. Parameters:
  346. ICatalogCollection* pPkgCollection
  347. If non-null, will use this collection. Otherwise, will
  348. open its own collection
  349. Returns:
  350. HRESULT - NOERROR on success
  351. Side effects:
  352. Removes Viper package
  353. ===================================================================*/
  354. HRESULT RemoveViperUtilPackage(ICatalogCollection* pPkgCollectionT)
  355. {
  356. HRESULT hr;
  357. ICatalogCollection* pPkgCollection = NULL;
  358. ICatalogObject* pPackage = NULL;
  359. ICOMAdminCatalog* pCatalog = NULL;
  360. LONG lPkgCount, lChanges, i;
  361. SAFEARRAY* aCLSIDs = NULL;
  362. // if package collection was passed, use it
  363. if (pPkgCollectionT != NULL)
  364. {
  365. pPkgCollection = pPkgCollectionT;
  366. }
  367. else
  368. {
  369. BSTR bstr = NULL;
  370. // Create instance of the catalog object
  371. hr = CoCreateInstance(CLSID_COMAdminCatalog
  372. , NULL
  373. , CLSCTX_INPROC_SERVER
  374. , IID_ICOMAdminCatalog
  375. , (void**)&pCatalog);
  376. if (FAILED(hr))
  377. goto LErr;
  378. // Get the Packages collection
  379. bstr = SysAllocString(L"Applications");
  380. hr = pCatalog->GetCollection(bstr, (IDispatch**)&pPkgCollection);
  381. FREEBSTR(bstr);
  382. if (FAILED(hr))
  383. goto LErr;
  384. }
  385. hr = GetSafeArrayOfCLSIDs(wszASPUtilitiesPackageID, &aCLSIDs);
  386. if (FAILED(hr))
  387. {
  388. DBGPRINTF((DBG_CONTEXT, "Failed to get SafeArrayofCLSIDs, szPackageID is %S, hr %08x",
  389. wszASPUtilitiesPackageID,
  390. hr));
  391. goto LErr;
  392. }
  393. //
  394. // Populate it
  395. //
  396. hr = pPkgCollection->PopulateByKey(aCLSIDs);
  397. if (FAILED(hr))
  398. {
  399. DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
  400. hr));
  401. goto LErr;
  402. }
  403. // Delete any existing "IIS Utilities" package
  404. hr = pPkgCollection->get_Count(&lPkgCount);
  405. if (FAILED(hr))
  406. {
  407. DBGPRINTF((DBG_CONTEXT, "pPkgCollection->Populate() failed, hr = %08x\n",
  408. hr));
  409. goto LErr;
  410. }
  411. if (SUCCEEDED(hr) && lPkgCount == 1)
  412. {
  413. hr = pPkgCollection->get_Item(0, (IDispatch**)&pPackage);
  414. if (FAILED(hr))
  415. {
  416. goto LErr;
  417. }
  418. BSTR bstr = NULL;
  419. VARIANT varT;
  420. // Found it - remove it and call Save Changes
  421. // First, Set Deleteable = Y property on package
  422. bstr = SysAllocString(L"Deleteable");
  423. VariantInit(&varT);
  424. varT.vt = VT_BSTR;
  425. varT.bstrVal = SysAllocString(L"Y");
  426. hr = pPackage->put_Value(bstr, varT);
  427. FREEBSTR(bstr);
  428. VariantClear(&varT);
  429. if (FAILED(hr))
  430. {
  431. goto LErr;
  432. }
  433. RELEASE(pPackage);
  434. // Let save the Deletable settings
  435. hr = pPkgCollection->SaveChanges(&lChanges);
  436. if (FAILED(hr))
  437. {
  438. DBGPRINTF((DBG_CONTEXT, "Save the Deletable settings failed, hr = %08x\n",
  439. hr));
  440. goto LErr;
  441. }
  442. // Now we can delete
  443. hr = pPkgCollection->Remove(0);
  444. if (FAILED(hr))
  445. {
  446. DBGPRINTF((DBG_CONTEXT, "Remove the Component from package failed, hr = %08x\n",
  447. hr));
  448. goto LErr;
  449. }
  450. // Aha, we should be able to delete now.
  451. hr = pPkgCollection->SaveChanges(&lChanges);
  452. if (FAILED(hr))
  453. {
  454. DBGPRINTF((DBG_CONTEXT, "Save changes failed, hr = %08x\n",
  455. hr));
  456. goto LErr;
  457. }
  458. }
  459. LErr:
  460. if (aCLSIDs != NULL)
  461. {
  462. HRESULT hrT = SafeArrayDestroy(aCLSIDs);
  463. aCLSIDs = NULL;
  464. }
  465. if (pPkgCollectionT == NULL)
  466. RELEASE(pPkgCollection);
  467. RELEASE(pCatalog);
  468. RELEASE(pPackage);
  469. return hr;
  470. }
  471. /*===================================================================
  472. AddContextObjectToViperPackage
  473. Adds the Context object to the Viper package named "IIS Utility"
  474. Returns:
  475. HRESULT - NOERROR on success
  476. Side effects:
  477. Adds the object to the Viper package
  478. ===================================================================*/
  479. HRESULT AddContextObjectToViperPackage()
  480. {
  481. HRESULT hr;
  482. BSTR bstr = NULL;
  483. BSTR bstrAppGUID = NULL;
  484. BSTR bstrGUID = NULL;
  485. VARIANT varName;
  486. VARIANT varKey;
  487. VARIANT varT;
  488. ICatalogCollection* pPkgCollection = NULL;
  489. ICatalogCollection* pCompCollection = NULL;
  490. ICatalogObject* pComponent = NULL;
  491. ICatalogObject* pPackage = NULL;
  492. ICOMAdminCatalog* pCatalog = NULL;
  493. long lPkgCount, lCompCount, lChanges, iT;
  494. BOOL fFound;
  495. SAFEARRAY* aCLSIDs = NULL;
  496. VariantInit(&varKey);
  497. VariantClear(&varKey);
  498. VariantInit(&varName);
  499. VariantClear(&varName);
  500. VariantInit(&varT);
  501. VariantClear(&varT);
  502. // Create instance of the catalog object
  503. hr = CoCreateInstance(CLSID_COMAdminCatalog
  504. , NULL
  505. , CLSCTX_INPROC_SERVER
  506. , IID_ICOMAdminCatalog
  507. , (void**)&pCatalog);
  508. if (FAILED(hr))
  509. goto LErr;
  510. // Get the Packages collection
  511. bstr = SysAllocString(L"Applications");
  512. hr = pCatalog->GetCollection(bstr, (IDispatch**)&pPkgCollection);
  513. SysFreeString(bstr);
  514. if (FAILED(hr))
  515. goto LErr;
  516. hr = GetSafeArrayOfCLSIDs(wszASPUtilitiesPackageID, &aCLSIDs);
  517. if (FAILED(hr))
  518. {
  519. DBGPRINTF((DBG_CONTEXT, "Failed to get SafeArrayofCLSIDs, szPackageID is %S, hr %08x",
  520. wszASPUtilitiesPackageID,
  521. hr));
  522. goto LErr;
  523. }
  524. bstrAppGUID = SysAllocString(wszASPUtilitiesPackageID);
  525. // Actually put the components in the package
  526. bstrGUID = SysAllocString(wszCLSID_ASPObjectContextTxRequired);
  527. hr = pCatalog->ImportComponent(bstrAppGUID ,bstrGUID);
  528. SysFreeString(bstrGUID);
  529. if (FAILED(hr))
  530. goto LErr;
  531. bstrGUID = SysAllocString(wszCLSID_ASPObjectContextTxRequiresNew);
  532. hr = pCatalog->ImportComponent(bstrAppGUID ,bstrGUID);
  533. SysFreeString(bstrGUID);
  534. if (FAILED(hr))
  535. goto LErr;
  536. bstrGUID = SysAllocString(wszCLSID_ASPObjectContextTxSupported);
  537. hr = pCatalog->ImportComponent(bstrAppGUID ,bstrGUID);
  538. SysFreeString(bstrGUID);
  539. if (FAILED(hr))
  540. goto LErr;
  541. bstrGUID = SysAllocString(wszCLSID_ASPObjectContextTxNotSupported);
  542. hr = pCatalog->ImportComponent(bstrAppGUID ,bstrGUID);
  543. SysFreeString(bstrGUID);
  544. if (FAILED(hr))
  545. goto LErr;
  546. varKey.vt = VT_BSTR;
  547. varKey.bstrVal = SysAllocString(wszASPUtilitiesPackageID);
  548. //
  549. // Populate packages
  550. //
  551. hr = pPkgCollection->PopulateByKey(aCLSIDs);
  552. if (FAILED(hr))
  553. {
  554. DBGPRINTF((DBG_CONTEXT, "Failed to call PopulateByKey(), hr = %08x\n",
  555. hr));
  556. goto LErr;
  557. }
  558. // Find "IIS Utilities" package
  559. hr = pPkgCollection->get_Count(&lPkgCount);
  560. if (FAILED(hr))
  561. {
  562. DBGPRINTF((DBG_CONTEXT, "pPkgCollection->Populate() failed, hr = %08x\n",
  563. hr));
  564. goto LErr;
  565. }
  566. if (SUCCEEDED(hr) && lPkgCount == 1)
  567. {
  568. hr = pPkgCollection->get_Item(0, (IDispatch**)&pPackage);
  569. if (FAILED(hr))
  570. {
  571. goto LErr;
  572. }
  573. }
  574. DBG_ASSERT(pPackage != NULL);
  575. // Get the "ComponentsInPackage" collection.
  576. bstr = SysAllocString(L"Components");
  577. hr = pPkgCollection->GetCollection(bstr, varKey, (IDispatch**)&pCompCollection);
  578. SysFreeString(bstr);
  579. if (FAILED(hr))
  580. goto LErr;
  581. // Repopulate the collection so we can find our object and set properties on it
  582. hr = pCompCollection->Populate();
  583. if (FAILED(hr))
  584. goto LErr;
  585. // Find our components in the list (should be four)
  586. hr = pCompCollection->get_Count(&lCompCount);
  587. if (FAILED(hr))
  588. goto LErr;
  589. DBG_ASSERT(lCompCount == 4);
  590. RELEASE(pComponent);
  591. VariantClear(&varKey);
  592. for (iT = (lCompCount-1); iT >= 0 ; iT--)
  593. {
  594. hr = pCompCollection->get_Item(iT, (IDispatch**)&pComponent);
  595. if (FAILED(hr))
  596. goto LErr;
  597. hr = pComponent->get_Key(&varKey);
  598. if (FAILED(hr))
  599. goto LErr;
  600. DBG_ASSERT(varKey.bstrVal);
  601. fFound = FALSE;
  602. if (_wcsicmp(varKey.bstrVal, wszCLSID_ASPObjectContextTxRequired) == 0)
  603. {
  604. // Required
  605. bstr = SysAllocString(L"3");
  606. fFound = TRUE;
  607. }
  608. else if (_wcsicmp(varKey.bstrVal, wszCLSID_ASPObjectContextTxRequiresNew) == 0)
  609. {
  610. // Requires New
  611. bstr = SysAllocString(L"4");
  612. fFound = TRUE;
  613. }
  614. else if (_wcsicmp(varKey.bstrVal, wszCLSID_ASPObjectContextTxSupported) == 0)
  615. {
  616. // Supported
  617. bstr = SysAllocString(L"2");
  618. fFound = TRUE;
  619. }
  620. else if (_wcsicmp(varKey.bstrVal, wszCLSID_ASPObjectContextTxNotSupported) == 0)
  621. {
  622. // Not Supported
  623. bstr = SysAllocString(L"1");
  624. fFound = TRUE;
  625. }
  626. if (fFound)
  627. {
  628. varT.vt = VT_BSTR;
  629. varT.bstrVal = bstr;
  630. bstr = SysAllocString(L"Transaction");
  631. hr = pComponent->put_Value(bstr, varT);
  632. FREEBSTR(bstr);
  633. VariantClear(&varT);
  634. if (FAILED(hr))
  635. goto LErr;
  636. bstr = SysAllocString(L"Description");
  637. varT.vt = VT_BSTR;
  638. varT.bstrVal = SysAllocString(L"ASP Tx Script Context");
  639. hr = pComponent->put_Value(bstr, varT);
  640. FREEBSTR(bstr);
  641. VariantClear(&varT);
  642. if (FAILED(hr))
  643. goto LErr;
  644. bstr = SysAllocString(L"EventTrackingEnabled");
  645. varT.vt = VT_BSTR;
  646. varT.bstrVal = SysAllocString(L"N");
  647. hr = pComponent->put_Value(bstr, varT);
  648. FREEBSTR(bstr);
  649. VariantClear(&varT);
  650. if (FAILED(hr))
  651. goto LErr;
  652. }
  653. VariantClear(&varKey);
  654. RELEASE(pComponent);
  655. }
  656. // Save changes
  657. hr = pCompCollection->SaveChanges(&lChanges);
  658. if (FAILED(hr))
  659. goto LErr;
  660. bstr = SysAllocString(L"Activation");
  661. varT.vt = VT_BSTR;
  662. varT.bstrVal = SysAllocString(L"InProc");
  663. hr = pPackage->put_Value(bstr, varT);
  664. FREEBSTR(bstr);
  665. VariantClear(&varT);
  666. if (FAILED(hr))
  667. goto LErr;
  668. // Save changes
  669. hr = pPkgCollection->SaveChanges(&lChanges);
  670. if (FAILED(hr))
  671. goto LErr;
  672. hr = pPkgCollection->Populate();
  673. if (FAILED(hr))
  674. goto LErr;
  675. // Now that our one object is added to the package, set the Changeable property
  676. // on the package to "No", so no one can mess with it
  677. bstr = SysAllocString(L"Changeable");
  678. varT.vt = VT_BSTR;
  679. varT.bstrVal = SysAllocString(L"N");
  680. hr = pPackage->put_Value(bstr, varT);
  681. FREEBSTR(bstr);
  682. VariantClear(&varT);
  683. if (FAILED(hr))
  684. goto LErr;
  685. // Save changes
  686. hr = pPkgCollection->SaveChanges(&lChanges);
  687. if (FAILED(hr))
  688. goto LErr;
  689. LErr:
  690. DBG_ASSERT(SUCCEEDED(hr));
  691. if (aCLSIDs)
  692. {
  693. SafeArrayDestroy(aCLSIDs);
  694. aCLSIDs = NULL;
  695. }
  696. RELEASE(pCompCollection);
  697. RELEASE(pPkgCollection);
  698. RELEASE(pComponent);
  699. RELEASE(pPackage);
  700. RELEASE(pCatalog);
  701. FREEBSTR(bstrAppGUID);
  702. FREEBSTR(bstr);
  703. VariantClear(&varName);
  704. VariantClear(&varKey);
  705. VariantClear(&varT);
  706. return hr;
  707. } // AddContextObjectToViperPackage