#include "priv.h" #include "dochost.h" #define DM_CACHEOLESERVER DM_TRACE #define HACK_CACHE_OBJECT_TOO // #define HACK_LOCKRUNNING_TOO class CClassHolder : IUnknown { protected: // *** IUnknown methods *** virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj); virtual STDMETHODIMP_(ULONG) AddRef(void) ; virtual STDMETHODIMP_(ULONG) Release(void); friend IUnknown* ClassHolder_Create(const CLSID* pclsid); CClassHolder(const CLSID* pclsid); ~CClassHolder(); UINT _cRef; IClassFactory* _pcf; DWORD _dwAppHack; #ifdef HACK_CACHE_OBJECT_TOO IUnknown* _punk; #ifdef HACK_LOCKRUNNING_TOO IRunnableObject* _pro; #endif #endif // HACK_CACHE_OBJECT_TOO }; HRESULT CClassHolder::QueryInterface(REFIID riid, LPVOID * ppvObj) { static const QITAB qit[] = { QITABENTMULTI(CClassHolder, IDiscardableBrowserProperty, IUnknown), { 0 }, }; return QISearch(this, qit, riid, ppvObj); } ULONG CClassHolder::AddRef() { _cRef++; return _cRef; } ULONG CClassHolder::Release() { _cRef--; if (_cRef > 0) return _cRef; delete this; return 0; } CClassHolder::CClassHolder(const CLSID* pclsid) : _cRef(1) { HRESULT hres; hres = CoGetClassObject(*pclsid, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, 0, IID_IClassFactory, (LPVOID*)&_pcf); TraceMsg(DM_CACHEOLESERVER, "CCH::CCH Just called CoGetClassObject %x", hres); if (SUCCEEDED(hres)) { ::GetAppHackFlags(NULL, pclsid, &_dwAppHack); _pcf->LockServer(TRUE); #ifdef HACK_CACHE_OBJECT_TOO hres = _pcf->CreateInstance(NULL, IID_IUnknown, (LPVOID*)&_punk); if ((_dwAppHack & BROWSERFLAG_INITNEWTOKEEP) && SUCCEEDED(hres)) { TraceMsg(TF_SHDAPPHACK, "CCH::CCH hack for Excel. Call InitNew to keep it running"); // // This InitNew keeps Excel running // IPersistStorage* pps; HRESULT hresT; hresT = _punk->QueryInterface(IID_IPersistStorage, (LPVOID*)&pps); if (SUCCEEDED(hresT)) { IStorage* pstg; hresT = StgCreateDocfile(NULL, STGM_DIRECT | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pstg); if (SUCCEEDED(hresT)) { TraceMsg(DM_TRACE, "CCLH::ctor calling InitNew()"); pps->InitNew(pstg); pstg->Release(); } else { TraceMsg(DM_TRACE, "CCLH::ctor StgCreateDocfile failed %x", hresT); } pps->Release(); } else { TraceMsg(DM_TRACE, "CCLH::ctor QI to IPersistStorage failed %x", hresT); } #ifdef HACK_LOCKRUNNING_TOO hres = _punk->QueryInterface(IID_IRunnableObject, (LPVOID*)&_pro); if (SUCCEEDED(hres)) { TraceMsg(DM_CACHEOLESERVER, "CCH::CCH This is runnable. Keep it running %x", _pro); OleRun(_pro); OleLockRunning(_pro, TRUE, TRUE); } #endif } #endif } } CClassHolder::~CClassHolder() { if (_pcf) { #ifdef HACK_CACHE_OBJECT_TOO if (_punk) { #ifdef HACK_LOCKRUNNING_TOO if (_pro) { OleLockRunning(_pro, FALSE, TRUE); _pro->Release(); } #endif _punk->Release(); } #endif _pcf->LockServer(FALSE); ATOMICRELEASE(_pcf); } } IUnknown* ClassHolder_Create(const CLSID* pclsid) { return new CClassHolder(pclsid); }