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.

1186 lines
26 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. Component: Viper Integration Objects
  6. File: viperint.cpp
  7. Owner: DmitryR
  8. This file contains the implementation of viper integration classes
  9. ===================================================================*/
  10. #include "denpre.h"
  11. #pragma hdrstop
  12. #include "Context.h"
  13. #include "package.h"
  14. #include "memchk.h"
  15. extern HDESK ghDesktop;
  16. //
  17. // COM holds the last reference to a CViperAsyncRequest
  18. // we need to track these objects to ensure that we don't
  19. // exit before the activity threads have released them.
  20. //
  21. volatile LONG g_nViperRequests = 0;
  22. /*===================================================================
  23. C V i p e r A s y n c R e q u e s t
  24. ===================================================================*/
  25. /*===================================================================
  26. CViperAsyncRequest::CViperAsyncRequest
  27. CViperAsyncRequest constructor
  28. Parameters:
  29. Returns:
  30. ===================================================================*/
  31. CViperAsyncRequest::CViperAsyncRequest()
  32. : m_cRefs(1), m_pHitObj(NULL), m_hrOnError(S_OK), m_pActivity(NULL), m_dwRepostAttempts(0)
  33. {
  34. InterlockedIncrement( (LONG *)&g_nViperRequests );
  35. }
  36. /*===================================================================
  37. CViperAsyncRequest::~CViperAsyncRequest
  38. CViperAsyncRequest destructor
  39. Parameters:
  40. Returns:
  41. ===================================================================*/
  42. CViperAsyncRequest::~CViperAsyncRequest()
  43. {
  44. InterlockedDecrement( (LONG *)&g_nViperRequests );
  45. }
  46. /*===================================================================
  47. CViperAsyncRequest::Init
  48. Initialize CViperAsyncRequest with CHitObj object
  49. Parameters:
  50. CHitObj *pHitObj Denali HitObj
  51. Returns:
  52. HRESULT
  53. ===================================================================*/
  54. HRESULT CViperAsyncRequest::Init
  55. (
  56. CHitObj *pHitObj,
  57. IServiceActivity *pActivity
  58. )
  59. {
  60. Assert(m_pHitObj == NULL);
  61. m_pHitObj = pHitObj;
  62. m_pActivity = pActivity;
  63. return S_OK;
  64. }
  65. #ifdef DBG
  66. /*===================================================================
  67. CViperAsyncRequest::AssertValid
  68. Test to make sure that this is currently correctly formed
  69. and assert if it is not.
  70. Returns:
  71. ===================================================================*/
  72. void CViperAsyncRequest::AssertValid() const
  73. {
  74. Assert(m_pHitObj);
  75. Assert(m_cRefs > 0);
  76. }
  77. #endif
  78. /*===================================================================
  79. CViperAsyncRequest::QueryInterface
  80. Standard IUnknown method
  81. Parameters:
  82. REFIID iid
  83. void **ppv
  84. Returns:
  85. HRESULT
  86. ===================================================================*/
  87. STDMETHODIMP CViperAsyncRequest::QueryInterface
  88. (
  89. REFIID iid,
  90. void **ppv
  91. )
  92. {
  93. if (iid == IID_IUnknown || iid == IID_IServiceCall)
  94. {
  95. *ppv = this;
  96. AddRef();
  97. return S_OK;
  98. }
  99. return E_NOINTERFACE;
  100. }
  101. /*===================================================================
  102. CViperAsyncRequest::AddRef
  103. Standard IUnknown method
  104. Parameters:
  105. Returns:
  106. Ref count
  107. ===================================================================*/
  108. STDMETHODIMP_(ULONG) CViperAsyncRequest::AddRef()
  109. {
  110. return ++m_cRefs;
  111. }
  112. /*===================================================================
  113. CViperAsyncRequest::Release
  114. Standard IUnknown method
  115. Parameters:
  116. Returns:
  117. Ref count
  118. ===================================================================*/
  119. STDMETHODIMP_(ULONG) CViperAsyncRequest::Release()
  120. {
  121. if (--m_cRefs != 0)
  122. return m_cRefs;
  123. delete this;
  124. return 0;
  125. }
  126. /*===================================================================
  127. CViperAsyncRequest::OnCall
  128. IMTSCall method implementation. This method is called by Viper
  129. from the right thread when it's time to process a request
  130. Parameters:
  131. Returns:
  132. HRESULT
  133. ===================================================================*/
  134. STDMETHODIMP CViperAsyncRequest::OnCall()
  135. {
  136. Assert(m_pHitObj);
  137. CIsapiReqInfo *pIReq = m_pHitObj->PIReq();
  138. BOOL fRequestReposted = FALSE;
  139. // add an extra addref here to prevent the deletion of the
  140. // hitobj deleting the CIsapiReqInfo for this request.
  141. if (pIReq)
  142. pIReq->AddRef();
  143. // Bracket ViperAsyncCallback
  144. if (SUCCEEDED(StartISAThreadBracket(pIReq)))
  145. {
  146. m_pHitObj->ViperAsyncCallback(&fRequestReposted);
  147. // Make sure there always is DONE_WITH_SESSION
  148. if (m_pHitObj->FIsBrowserRequest() && !fRequestReposted)
  149. {
  150. if (!m_pHitObj->FDoneWithSession())
  151. m_pHitObj->ReportServerError(IDE_UNEXPECTED);
  152. }
  153. if (!fRequestReposted)
  154. delete m_pHitObj; // don't delete if reposted
  155. EndISAThreadBracket(pIReq);
  156. }
  157. else
  158. {
  159. // DONE_WITH_SESSION -- ServerSupportFunction
  160. // does not need bracketing
  161. if (m_pHitObj->FIsBrowserRequest())
  162. m_pHitObj->ReportServerError(0);
  163. // We never called to process request, there should
  164. // be no state and it's probably save to delete it
  165. // outside of bracketing
  166. delete m_pHitObj;
  167. }
  168. m_pHitObj = NULL; // set to NULL even if not deleted
  169. Release(); // release this, Viper holds another ref
  170. if (pIReq)
  171. pIReq->Release();
  172. return S_OK;
  173. }
  174. /*===================================================================
  175. CViperAsyncRequest::OnError
  176. Called by COM+ when it is unable to dispatch the request properly
  177. on the configured thread
  178. Parameters:
  179. Returns:
  180. HRESULT
  181. ===================================================================*/
  182. STDMETHODIMP CViperAsyncRequest::OnError(HRESULT hrViperError)
  183. {
  184. Assert(m_pHitObj);
  185. CIsapiReqInfo *pIReq = m_pHitObj->PIReq();
  186. HRESULT hr = S_OK;
  187. if (pIReq)
  188. pIReq->AddRef();
  189. m_dwRepostAttempts++;
  190. // attempt to repost the request if it hasn't errored out three
  191. // times yet.
  192. if (m_dwRepostAttempts <= 3) {
  193. hr = m_pActivity->AsynchronousCall(this);
  194. Assert(SUCCEEDED(hr));
  195. }
  196. // if it has errored out three times or the repost failed,
  197. // pitch the request
  198. if (FAILED(hr) || (m_dwRepostAttempts > 3)) {
  199. // DONE_WITH_SESSION -- ServerSupportFunction
  200. // does not need bracketing
  201. if (m_pHitObj->FIsBrowserRequest())
  202. m_pHitObj->ReportServerError(IDE_UNEXPECTED);
  203. // We never called to process request, there should
  204. // be no state and it's probably save to delete it
  205. // outside of bracketing
  206. delete m_pHitObj;
  207. m_pHitObj = NULL; // set to NULL even if not deleted
  208. Release(); // release this, Viper holds another ref
  209. }
  210. if (pIReq)
  211. pIReq->Release();
  212. return S_OK;
  213. }
  214. /*===================================================================
  215. C V i p e r A c t i v i t y
  216. ===================================================================*/
  217. /*===================================================================
  218. CViperActivity::CViperActivity
  219. CViperActivity constructor
  220. Parameters:
  221. Returns:
  222. ===================================================================*/
  223. CViperActivity::CViperActivity()
  224. : m_pActivity(NULL), m_cBind(0)
  225. {
  226. }
  227. /*===================================================================
  228. CViperActivity::~CViperActivity
  229. CViperActivity destructor
  230. Parameters:
  231. Returns:
  232. ===================================================================*/
  233. CViperActivity::~CViperActivity()
  234. {
  235. UnInit();
  236. }
  237. /*===================================================================
  238. CViperActivity::Init
  239. Create actual Viper activity using MTSCreateActivity()
  240. Parameters:
  241. Returns:
  242. HRESULT
  243. ===================================================================*/
  244. HRESULT CViperActivity::Init(IUnknown *pServicesConfig)
  245. {
  246. Assert(!FInited());
  247. HRESULT hr = S_OK;
  248. hr = CoCreateActivity(pServicesConfig, IID_IServiceActivity, (void **)&m_pActivity);
  249. if (FAILED(hr))
  250. return hr;
  251. m_cBind = 1;
  252. return S_OK;
  253. }
  254. /*===================================================================
  255. CViperActivity::InitClone
  256. Clone Viper activity (AddRef() it)
  257. Parameters:
  258. CViperActivity *pActivity activity to clone from
  259. Returns:
  260. HRESULT
  261. ===================================================================*/
  262. HRESULT CViperActivity::InitClone
  263. (
  264. CViperActivity *pActivity
  265. )
  266. {
  267. Assert(!FInited());
  268. Assert(pActivity);
  269. pActivity->AssertValid();
  270. m_pActivity = pActivity->m_pActivity;
  271. m_pActivity->AddRef();
  272. m_cBind = 1;
  273. return S_OK;
  274. }
  275. /*===================================================================
  276. CViperActivity::UnInit
  277. Release Viper activity
  278. Parameters:
  279. Returns:
  280. HRESULT
  281. ===================================================================*/
  282. HRESULT CViperActivity::UnInit()
  283. {
  284. if (m_pActivity)
  285. {
  286. while (m_cBind > 1) // 1 is for inited flag
  287. {
  288. m_pActivity->UnbindFromThread();
  289. m_cBind--;
  290. }
  291. m_pActivity->Release();
  292. m_pActivity = NULL;
  293. }
  294. m_cBind = 0;
  295. return S_OK;
  296. }
  297. /*===================================================================
  298. CViperActivity::BindToThread
  299. Bind Activity to current thread using IMTSActivity method
  300. Parameters:
  301. Returns:
  302. HRESULT
  303. ===================================================================*/
  304. HRESULT CViperActivity::BindToThread()
  305. {
  306. Assert(FInited());
  307. m_pActivity->BindToCurrentThread();
  308. m_cBind++;
  309. return S_OK;
  310. }
  311. /*===================================================================
  312. CViperActivity::UnBindFromThread
  313. UnBind Activity from using IMTSActivity method
  314. Parameters:
  315. Returns:
  316. HRESULT
  317. ===================================================================*/
  318. HRESULT CViperActivity::UnBindFromThread()
  319. {
  320. Assert(FInited());
  321. Assert(m_cBind > 1);
  322. m_pActivity->UnbindFromThread();
  323. m_cBind--;
  324. return S_OK;
  325. }
  326. /*===================================================================
  327. CViperActivity::PostAsyncRequest
  328. Call HitObj Async.
  329. Creates IMTSCCall object to do it.
  330. Parameters:
  331. CHitObj *pHitObj Denali's HitObj
  332. Returns:
  333. HRESULT
  334. ===================================================================*/
  335. HRESULT CViperActivity::PostAsyncRequest
  336. (
  337. CHitObj *pHitObj
  338. )
  339. {
  340. AssertValid();
  341. HRESULT hr = S_OK;
  342. CViperAsyncRequest *pViperCall = new CViperAsyncRequest;
  343. if (!pViperCall)
  344. hr = E_OUTOFMEMORY;
  345. if (SUCCEEDED(hr))
  346. hr = pViperCall->Init(pHitObj, m_pActivity);
  347. RevertToSelf();
  348. if (SUCCEEDED(hr))
  349. hr = m_pActivity->AsynchronousCall(pViperCall);
  350. if (FAILED(hr) && pViperCall) // cleanup if failed
  351. pViperCall->Release();
  352. return hr;
  353. }
  354. /*===================================================================
  355. CViperActivity::PostGlobalAsyncRequest
  356. Static method.
  357. Post async request without an activity.
  358. Creates temporary activity
  359. Parameters:
  360. CHitObj *pHitObj Denali's HitObj
  361. Returns:
  362. HRESULT
  363. ===================================================================*/
  364. HRESULT CViperActivity::PostGlobalAsyncRequest
  365. (
  366. CHitObj *pHitObj
  367. )
  368. {
  369. HRESULT hr = S_OK;
  370. CViperActivity *pTmpActivity = new CViperActivity;
  371. if (!pTmpActivity)
  372. hr = E_OUTOFMEMORY;
  373. if (SUCCEEDED(hr))
  374. hr = pTmpActivity->Init(pHitObj->PAppln()->PServicesConfig());
  375. if (SUCCEEDED(hr))
  376. {
  377. // remember this activity as HitObj's activity
  378. // HitObj will get rid of it on its destructor
  379. pHitObj->SetActivity(pTmpActivity);
  380. hr = pTmpActivity->PostAsyncRequest(pHitObj);
  381. pTmpActivity = NULL; // don't delete, HitObj will
  382. }
  383. if (pTmpActivity)
  384. delete pTmpActivity;
  385. return hr;
  386. }
  387. #ifdef DBG
  388. /*===================================================================
  389. CViperAsyncRequest::AssertValid
  390. Test to make sure that this is currently correctly formed
  391. and assert if it is not.
  392. Returns:
  393. ===================================================================*/
  394. void CViperActivity::AssertValid() const
  395. {
  396. Assert(FInited());
  397. Assert(m_pActivity);
  398. }
  399. #endif
  400. #ifdef UNUSED
  401. /*===================================================================
  402. C V i p e r T h r e a d E v e n t s
  403. ===================================================================*/
  404. /*===================================================================
  405. CViperThreadEvents::CViperThreadEvents
  406. CViperThreadEvents constructor
  407. Parameters:
  408. Returns:
  409. ===================================================================*/
  410. CViperThreadEvents::CViperThreadEvents()
  411. : m_cRefs(1)
  412. {
  413. }
  414. #ifdef DBG
  415. /*===================================================================
  416. CViperThreadEvents::AssertValid
  417. Test to make sure that this is currently correctly formed
  418. and assert if it is not.
  419. Returns:
  420. ===================================================================*/
  421. void CViperThreadEvents::AssertValid() const
  422. {
  423. Assert(m_cRefs > 0);
  424. Assert(ghDesktop != NULL);
  425. }
  426. #endif
  427. /*===================================================================
  428. CViperThreadEvents::QueryInterface
  429. Standard IUnknown method
  430. Parameters:
  431. REFIID iid
  432. void **ppv
  433. Returns:
  434. HRESULT
  435. ===================================================================*/
  436. STDMETHODIMP CViperThreadEvents::QueryInterface
  437. (
  438. REFIID iid,
  439. void **ppv
  440. )
  441. {
  442. if (iid == IID_IUnknown || iid == IID_IThreadEvents)
  443. {
  444. *ppv = this;
  445. AddRef();
  446. return S_OK;
  447. }
  448. return E_NOINTERFACE;
  449. }
  450. /*===================================================================
  451. CViperThreadEvents::AddRef
  452. Standard IUnknown method
  453. Parameters:
  454. Returns:
  455. Ref count
  456. ===================================================================*/
  457. STDMETHODIMP_(ULONG) CViperThreadEvents::AddRef()
  458. {
  459. DWORD cRefs = InterlockedIncrement((LPLONG)&m_cRefs);
  460. return cRefs;
  461. }
  462. /*===================================================================
  463. CViperThreadEvents::Release
  464. Standard IUnknown method
  465. Parameters:
  466. Returns:
  467. Ref count
  468. ===================================================================*/
  469. STDMETHODIMP_(ULONG) CViperThreadEvents::Release()
  470. {
  471. DWORD cRefs = InterlockedDecrement((LPLONG)&m_cRefs);
  472. if (cRefs)
  473. return cRefs;
  474. delete this;
  475. return 0;
  476. }
  477. /*===================================================================
  478. CViperThreadEvents::OnStartup
  479. IThreadEvents method implementation. This method is called by Viper
  480. whenever they start up a thread.
  481. Parameters:
  482. None
  483. Returns:
  484. HRESULT
  485. ===================================================================*/
  486. STDMETHODIMP CViperThreadEvents::OnStartup()
  487. {
  488. HRESULT hr;
  489. AssertValid();
  490. // Set the desktop for this thread
  491. hr = SetDesktop();
  492. return hr;
  493. }
  494. /*===================================================================
  495. CViperThreadEvents::OnShutdown
  496. IThreadEvents method implementation. This method is called by Viper
  497. whenever they shut down a thread.
  498. Parameters:
  499. None
  500. Returns:
  501. HRESULT
  502. ===================================================================*/
  503. STDMETHODIMP CViperThreadEvents::OnShutdown()
  504. {
  505. AssertValid();
  506. return S_OK;
  507. }
  508. #endif //UNUSED
  509. /*===================================================================
  510. G l o b a l F u n c t i o n s
  511. ===================================================================*/
  512. /*===================================================================
  513. ViperSetContextProperty
  514. Static utility function.
  515. Set Viper context property by BSTR and IDispatch*.
  516. The real interface takes BSTR and VARIANT.
  517. Parameters
  518. IContextProperties *pContextProperties Context
  519. BSTR bstrPropertyName Name
  520. IDispatch *pdispPropertyValue Value
  521. Returns:
  522. HRESULT
  523. ===================================================================*/
  524. static HRESULT ViperSetContextProperty
  525. (
  526. IContextProperties *pContextProperties,
  527. BSTR bstrPropertyName,
  528. IDispatch *pdispPropertyValue
  529. )
  530. {
  531. // Make VARIANT from IDispatch*
  532. pdispPropertyValue->AddRef();
  533. VARIANT Variant;
  534. VariantInit(&Variant);
  535. V_VT(&Variant) = VT_DISPATCH;
  536. V_DISPATCH(&Variant) = pdispPropertyValue;
  537. // Call Viper to set the property
  538. HRESULT hr = pContextProperties->SetProperty
  539. (
  540. bstrPropertyName,
  541. Variant
  542. );
  543. // Cleanup
  544. VariantClear(&Variant);
  545. return hr;
  546. }
  547. /*===================================================================
  548. ViperAttachIntrinsicsToContext
  549. Attach ASP intrinsic objects as Viper context properties
  550. Parameters - Intrinsics as interface pointers
  551. IApplicationObject *pAppln Application (required)
  552. ISessionObject *pSession Session (optional)
  553. IRequest *pRequest Request (optional)
  554. IResponse *pResponse Response (optional)
  555. IServer *pServer Server (optional)
  556. Returns:
  557. HRESULT
  558. ===================================================================*/
  559. HRESULT ViperAttachIntrinsicsToContext
  560. (
  561. IApplicationObject *pAppln,
  562. ISessionObject *pSession,
  563. IRequest *pRequest,
  564. IResponse *pResponse,
  565. IServer *pServer
  566. )
  567. {
  568. Assert(pAppln);
  569. HRESULT hr = S_OK;
  570. // Get Viper Context
  571. IObjectContext *pViperContext = NULL;
  572. hr = GetObjectContext(&pViperContext);
  573. // Get IContextPoperties interface
  574. IContextProperties *pContextProperties = NULL;
  575. if (SUCCEEDED(hr))
  576. hr = pViperContext->QueryInterface
  577. (
  578. IID_IContextProperties,
  579. (void **)&pContextProperties
  580. );
  581. // Set properties
  582. if (SUCCEEDED(hr))
  583. hr = ViperSetContextProperty
  584. (
  585. pContextProperties,
  586. BSTR_OBJ_APPLICATION,
  587. pAppln
  588. );
  589. if (SUCCEEDED(hr) && pSession)
  590. hr = ViperSetContextProperty
  591. (
  592. pContextProperties,
  593. BSTR_OBJ_SESSION,
  594. pSession
  595. );
  596. if (SUCCEEDED(hr) && pRequest)
  597. hr = ViperSetContextProperty
  598. (
  599. pContextProperties,
  600. BSTR_OBJ_REQUEST,
  601. pRequest
  602. );
  603. if (SUCCEEDED(hr) && pResponse)
  604. hr = ViperSetContextProperty
  605. (
  606. pContextProperties,
  607. BSTR_OBJ_RESPONSE,
  608. pResponse
  609. );
  610. if (SUCCEEDED(hr) && pServer)
  611. hr = ViperSetContextProperty
  612. (
  613. pContextProperties,
  614. BSTR_OBJ_SERVER,
  615. pServer
  616. );
  617. // Cleanup
  618. if (pContextProperties)
  619. pContextProperties->Release();
  620. if (pViperContext)
  621. pViperContext->Release();
  622. return hr;
  623. }
  624. /*===================================================================
  625. ViperGetObjectFromContext
  626. Get Viper context property by LPWSTR and
  627. return it as IDispatch*.
  628. The real interface takes BSTR and VARIANT.
  629. Parameters
  630. BSTR bstrName Property Name
  631. IDispatch **ppdisp [out] Object (Property Value)
  632. Returns:
  633. HRESULT
  634. ===================================================================*/
  635. HRESULT ViperGetObjectFromContext
  636. (
  637. BSTR bstrName,
  638. IDispatch **ppdisp
  639. )
  640. {
  641. Assert(ppdisp);
  642. HRESULT hr = S_OK;
  643. // Get Viper Context
  644. IObjectContext *pViperContext = NULL;
  645. hr = GetObjectContext(&pViperContext);
  646. // Get IContextPoperties interface
  647. IContextProperties *pContextProperties = NULL;
  648. if (SUCCEEDED(hr))
  649. hr = pViperContext->QueryInterface
  650. (
  651. IID_IContextProperties,
  652. (void **)&pContextProperties
  653. );
  654. // Get property Value as variant
  655. VARIANT Variant;
  656. VariantInit(&Variant);
  657. if (SUCCEEDED(hr))
  658. hr = pContextProperties->GetProperty(bstrName, &Variant);
  659. // Convert Variant to IDispatch*
  660. if (SUCCEEDED(hr))
  661. {
  662. IDispatch *pDisp = NULL;
  663. if (V_VT(&Variant) == VT_DISPATCH)
  664. pDisp = V_DISPATCH(&Variant);
  665. if (pDisp)
  666. {
  667. pDisp->AddRef();
  668. *ppdisp = pDisp;
  669. }
  670. else
  671. hr = E_FAIL;
  672. }
  673. // Cleanup
  674. VariantClear(&Variant);
  675. if (pContextProperties)
  676. pContextProperties->Release();
  677. if (pViperContext)
  678. pViperContext->Release();
  679. if (FAILED(hr))
  680. *ppdisp = NULL;
  681. return hr;
  682. }
  683. /*===================================================================
  684. ViperGetHitObjFromContext
  685. Get Server from Viper context property and get
  686. it's current HitObj
  687. Parameters
  688. CHitObj **ppHitObj [out]
  689. Returns:
  690. HRESULT
  691. ===================================================================*/
  692. HRESULT ViperGetHitObjFromContext
  693. (
  694. CHitObj **ppHitObj
  695. )
  696. {
  697. *ppHitObj = NULL;
  698. IDispatch *pdispServer = NULL;
  699. HRESULT hr = ViperGetObjectFromContext(BSTR_OBJ_SERVER, &pdispServer);
  700. if (FAILED(hr))
  701. return hr;
  702. if (pdispServer)
  703. {
  704. CServer *pServer = static_cast<CServer *>(pdispServer);
  705. *ppHitObj = pServer->PHitObj();
  706. pdispServer->Release();
  707. }
  708. return *ppHitObj ? S_OK : S_FALSE;
  709. }
  710. /*===================================================================
  711. ViperCreateInstance
  712. Viper's implementation of CoCreateInstance
  713. Parameters
  714. REFCLSID rclsid class id
  715. REFIID riid interface
  716. void **ppv [out] pointer to interface
  717. Returns:
  718. HRESULT
  719. ===================================================================*/
  720. HRESULT ViperCreateInstance
  721. (
  722. REFCLSID rclsid,
  723. REFIID riid,
  724. void **ppv
  725. )
  726. {
  727. /*
  728. DWORD dwClsContext = (Glob(fAllowOutOfProcCmpnts)) ?
  729. CLSCTX_INPROC_SERVER | CLSCTX_SERVER :
  730. CLSCTX_INPROC_SERVER;
  731. */
  732. // The reasons for supporting ASPAllowOutOfProcComponents seem to have
  733. // vanished. Because this only partially worked in II4 and we changed
  734. // the default in IIS5 this was causing problems with upgrades. So
  735. // we're going to ignore the fAllowOutOfProcCmpnts setting.
  736. DWORD dwClsContext = CLSCTX_INPROC_SERVER | CLSCTX_SERVER;
  737. return CoCreateInstance(rclsid, NULL, dwClsContext, riid, ppv);
  738. }
  739. /*===================================================================
  740. ViperConfigure
  741. Viper settings: # of threads, queue len,
  742. in-proc failfast,
  743. allow oop components
  744. Parameters
  745. cThreads -- number of threads
  746. fAllowOopComponents -- TRUE or FALSE
  747. Returns:
  748. HRESULT
  749. ===================================================================*/
  750. HRESULT ViperConfigure
  751. (
  752. DWORD cThreads,
  753. BOOL fAllowOopComponents
  754. )
  755. {
  756. HRESULT hr = S_OK;
  757. IMTSPackage *pPackage = NULL;
  758. //
  759. // Get hold of the package
  760. //
  761. hr = CoCreateInstance(CLSID_MTSPackage,
  762. NULL,
  763. CLSCTX_INPROC_SERVER,
  764. IID_IMTSPackage,
  765. (void **)&pPackage);
  766. if (SUCCEEDED(hr) && !pPackage)
  767. hr = E_FAIL;
  768. //
  769. // Set knobs
  770. //
  771. if (SUCCEEDED(hr))
  772. {
  773. #define MTS_STYLE_THREAD_POOL
  774. #ifdef MTS_STYLE_THREAD_POOL
  775. IComStaThreadPoolKnobs *pKnobs = NULL;
  776. hr = pPackage->QueryInterface(IID_IComStaThreadPoolKnobs, (void **)&pKnobs);
  777. #else
  778. IThreadPoolKnobs *pKnobs = NULL;
  779. hr = pPackage->QueryInterface(IID_IThreadPoolKnobs, (void **)&pKnobs);
  780. #endif
  781. if (SUCCEEDED(hr) && pKnobs)
  782. {
  783. // number of threads
  784. SYSTEM_INFO si;
  785. GetSystemInfo(&si);
  786. cThreads *= si.dwNumberOfProcessors;
  787. #ifdef MTS_STYLE_THREAD_POOL
  788. pKnobs->SetMaxThreadCount(cThreads);
  789. pKnobs->SetMinThreadCount(si.dwNumberOfProcessors + 7);
  790. // queue length
  791. pKnobs->SetQueueDepth(30000);
  792. pKnobs->SetActivityPerThread(1);
  793. #else
  794. pKnobs->SetMaxThreads(cThreads);
  795. pKnobs->SetMinThreads(si.dwNumberOfProcessors + 7);
  796. // queue length
  797. pKnobs->SetMaxQueuedRequests(30000);
  798. #endif
  799. pKnobs->Release();
  800. }
  801. }
  802. //
  803. // Bug 111008: Tell Viper that we do impersonations
  804. //
  805. if (SUCCEEDED(hr))
  806. {
  807. IImpersonationControl *pImpControl = NULL;
  808. hr = pPackage->QueryInterface(IID_IImpersonationControl, (void **)&pImpControl);
  809. if (SUCCEEDED(hr) && pImpControl)
  810. {
  811. hr = pImpControl->ClientsImpersonate(TRUE);
  812. pImpControl->Release();
  813. }
  814. }
  815. //
  816. // Disable FAILFAST for in-proc case
  817. //
  818. if (SUCCEEDED(hr) && !g_fOOP)
  819. {
  820. IFailfastControl *pFFControl = NULL;
  821. hr = pPackage->QueryInterface(IID_IFailfastControl, (void **)&pFFControl);
  822. if (SUCCEEDED(hr) && pFFControl)
  823. {
  824. pFFControl->SetApplFailfast(FALSE);
  825. pFFControl->Release();
  826. }
  827. }
  828. /*
  829. //
  830. // Set Allow OOP Components
  831. //
  832. if (SUCCEEDED(hr))
  833. {
  834. INonMTSActivation *pNonMTSActivation = NULL;
  835. hr = pPackage->QueryInterface(IID_INonMTSActivation, (void **)&pNonMTSActivation);
  836. if (SUCCEEDED(hr) && pNonMTSActivation)
  837. {
  838. pNonMTSActivation->OutOfProcActivationAllowed(fAllowOopComponents);
  839. pNonMTSActivation->Release();
  840. }
  841. }
  842. */
  843. //
  844. // Clean-up
  845. //
  846. if (pPackage)
  847. pPackage->Release();
  848. return hr;
  849. }
  850. /*===================================================================
  851. C O M H e l p e r A P I
  852. ===================================================================*/
  853. /*===================================================================
  854. ViperCoObjectIsaProxy
  855. Checks if the given IUnknown* points to a proxy
  856. Parameters
  857. IUnknown* pUnk pointer to check
  858. Returns:
  859. BOOL (TRUE if Proxy)
  860. ===================================================================*/
  861. BOOL ViperCoObjectIsaProxy
  862. (
  863. IUnknown* pUnk
  864. )
  865. {
  866. HRESULT hr;
  867. IUnknown *pUnk2;
  868. hr = pUnk->QueryInterface(IID_IProxyManager, (void**)&pUnk2);
  869. if (FAILED(hr))
  870. return FALSE;
  871. pUnk2->Release();
  872. return TRUE;
  873. }
  874. /*===================================================================
  875. ViperCoObjectAggregatesFTM
  876. Checks if the given object agregates free threaded marshaller
  877. (is agile)
  878. Parameters
  879. IUnknown* pUnk pointer to check
  880. Returns:
  881. BOOL (TRUE if Agile)
  882. ===================================================================*/
  883. BOOL ViperCoObjectAggregatesFTM
  884. (
  885. IUnknown *pUnk
  886. )
  887. {
  888. HRESULT hr;
  889. IMarshal *pMarshal;
  890. GUID guidClsid;
  891. hr = pUnk->QueryInterface(IID_IMarshal, (void**)&pMarshal);
  892. if (FAILED(hr))
  893. return FALSE;
  894. hr = pMarshal->GetUnmarshalClass(IID_IUnknown, pUnk, MSHCTX_INPROC,
  895. NULL, MSHLFLAGS_NORMAL, &guidClsid);
  896. pMarshal->Release();
  897. if (FAILED(hr))
  898. return FALSE;
  899. return (guidClsid == CLSID_InProcFreeMarshaler);
  900. }