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.

148 lines
3.6 KiB

  1. #include "priv.h"
  2. #include "dochost.h"
  3. #define DM_CACHEOLESERVER DM_TRACE
  4. #define HACK_CACHE_OBJECT_TOO
  5. class CClassHolder : IUnknown
  6. {
  7. public:
  8. CClassHolder();
  9. HRESULT Initialize(const CLSID* pclsid);
  10. // *** IUnknown methods ***
  11. virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
  12. virtual STDMETHODIMP_(ULONG) AddRef(void) ;
  13. virtual STDMETHODIMP_(ULONG) Release(void);
  14. friend IUnknown* ClassHolder_Create(const CLSID* pclsid);
  15. protected:
  16. ~CClassHolder();
  17. UINT _cRef;
  18. IClassFactory* _pcf;
  19. DWORD _dwAppHack;
  20. #ifdef HACK_CACHE_OBJECT_TOO
  21. IUnknown* _punk;
  22. #endif // HACK_CACHE_OBJECT_TOO
  23. };
  24. HRESULT CClassHolder::QueryInterface(REFIID riid, LPVOID * ppvObj)
  25. {
  26. static const QITAB qit[] = {
  27. QITABENTMULTI(CClassHolder, IDiscardableBrowserProperty, IUnknown),
  28. { 0 },
  29. };
  30. return QISearch(this, qit, riid, ppvObj);
  31. }
  32. ULONG CClassHolder::AddRef()
  33. {
  34. _cRef++;
  35. return _cRef;
  36. }
  37. ULONG CClassHolder::Release()
  38. {
  39. _cRef--;
  40. if (_cRef > 0)
  41. return _cRef;
  42. delete this;
  43. return 0;
  44. }
  45. CClassHolder::CClassHolder() : _cRef(1)
  46. {
  47. }
  48. HRESULT CClassHolder::Initialize(const CLSID *pclsid)
  49. {
  50. // we need local server here for word, excel, ...
  51. HRESULT hr = CoGetClassObject(*pclsid, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, 0, IID_PPV_ARG(IClassFactory, &_pcf));
  52. TraceMsg(DM_CACHEOLESERVER, "CCH::CCH Just called CoGetClassObject %x", hr);
  53. if (SUCCEEDED(hr))
  54. {
  55. ::GetAppHackFlags(NULL, pclsid, &_dwAppHack);
  56. _pcf->LockServer(TRUE);
  57. #ifdef HACK_CACHE_OBJECT_TOO
  58. hr = _pcf->CreateInstance(NULL, IID_PPV_ARG(IUnknown, &_punk));
  59. if ((_dwAppHack & BROWSERFLAG_INITNEWTOKEEP) && SUCCEEDED(hr))
  60. {
  61. TraceMsg(TF_SHDAPPHACK, "CCH::CCH hack for Excel. Call InitNew to keep it running");
  62. //
  63. // This InitNew keeps Excel running
  64. //
  65. IPersistStorage* pps;
  66. HRESULT hrT = _punk->QueryInterface(IID_PPV_ARG(IPersistStorage, &pps));
  67. if (SUCCEEDED(hrT))
  68. {
  69. IStorage* pstg;
  70. hrT = StgCreateDocfile(NULL,
  71. STGM_DIRECT | STGM_CREATE | STGM_READWRITE
  72. | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE,
  73. 0, &pstg);
  74. if (SUCCEEDED(hrT))
  75. {
  76. TraceMsg(DM_TRACE, "CCLH::ctor calling InitNew()");
  77. pps->InitNew(pstg);
  78. pstg->Release();
  79. }
  80. else
  81. {
  82. TraceMsg(DM_TRACE, "CCLH::ctor StgCreateDocfile failed %x", hrT);
  83. }
  84. pps->Release();
  85. }
  86. else
  87. {
  88. TraceMsg(DM_TRACE, "CCLH::ctor QI to IPersistStorage failed %x", hrT);
  89. }
  90. }
  91. #endif
  92. }
  93. return hr;
  94. }
  95. CClassHolder::~CClassHolder()
  96. {
  97. if (_pcf)
  98. {
  99. #ifdef HACK_CACHE_OBJECT_TOO
  100. if (_punk)
  101. {
  102. _punk->Release();
  103. }
  104. #endif
  105. _pcf->LockServer(FALSE);
  106. ATOMICRELEASE(_pcf);
  107. }
  108. }
  109. IUnknown* ClassHolder_Create(const CLSID* pclsid)
  110. {
  111. IUnknown *punk = NULL;
  112. CClassHolder *pch = new CClassHolder();
  113. if (pch)
  114. {
  115. if (SUCCEEDED(pch->Initialize(pclsid)))
  116. {
  117. pch->QueryInterface(IID_PPV_ARG(IUnknown, &punk));
  118. }
  119. pch->Release();
  120. }
  121. return punk;
  122. }