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.

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