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
148 lines
3.6 KiB
#include "priv.h"
|
|
#include "dochost.h"
|
|
|
|
#define DM_CACHEOLESERVER DM_TRACE
|
|
|
|
#define HACK_CACHE_OBJECT_TOO
|
|
|
|
class CClassHolder : IUnknown
|
|
{
|
|
public:
|
|
CClassHolder();
|
|
|
|
HRESULT Initialize(const CLSID* pclsid);
|
|
|
|
// *** 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);
|
|
|
|
protected:
|
|
~CClassHolder();
|
|
|
|
UINT _cRef;
|
|
IClassFactory* _pcf;
|
|
DWORD _dwAppHack;
|
|
|
|
#ifdef HACK_CACHE_OBJECT_TOO
|
|
IUnknown* _punk;
|
|
#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() : _cRef(1)
|
|
{
|
|
}
|
|
|
|
HRESULT CClassHolder::Initialize(const CLSID *pclsid)
|
|
{
|
|
// we need local server here for word, excel, ...
|
|
HRESULT hr = CoGetClassObject(*pclsid, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, 0, IID_PPV_ARG(IClassFactory, &_pcf));
|
|
|
|
TraceMsg(DM_CACHEOLESERVER, "CCH::CCH Just called CoGetClassObject %x", hr);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
::GetAppHackFlags(NULL, pclsid, &_dwAppHack);
|
|
|
|
_pcf->LockServer(TRUE);
|
|
|
|
#ifdef HACK_CACHE_OBJECT_TOO
|
|
hr = _pcf->CreateInstance(NULL, IID_PPV_ARG(IUnknown, &_punk));
|
|
if ((_dwAppHack & BROWSERFLAG_INITNEWTOKEEP) && SUCCEEDED(hr))
|
|
{
|
|
TraceMsg(TF_SHDAPPHACK, "CCH::CCH hack for Excel. Call InitNew to keep it running");
|
|
|
|
//
|
|
// This InitNew keeps Excel running
|
|
//
|
|
IPersistStorage* pps;
|
|
HRESULT hrT = _punk->QueryInterface(IID_PPV_ARG(IPersistStorage, &pps));
|
|
if (SUCCEEDED(hrT))
|
|
{
|
|
IStorage* pstg;
|
|
hrT = StgCreateDocfile(NULL,
|
|
STGM_DIRECT | STGM_CREATE | STGM_READWRITE
|
|
| STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE,
|
|
0, &pstg);
|
|
if (SUCCEEDED(hrT))
|
|
{
|
|
TraceMsg(DM_TRACE, "CCLH::ctor calling InitNew()");
|
|
pps->InitNew(pstg);
|
|
pstg->Release();
|
|
}
|
|
else
|
|
{
|
|
TraceMsg(DM_TRACE, "CCLH::ctor StgCreateDocfile failed %x", hrT);
|
|
}
|
|
pps->Release();
|
|
}
|
|
else
|
|
{
|
|
TraceMsg(DM_TRACE, "CCLH::ctor QI to IPersistStorage failed %x", hrT);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
CClassHolder::~CClassHolder()
|
|
{
|
|
if (_pcf)
|
|
{
|
|
#ifdef HACK_CACHE_OBJECT_TOO
|
|
if (_punk)
|
|
{
|
|
_punk->Release();
|
|
}
|
|
#endif
|
|
_pcf->LockServer(FALSE);
|
|
ATOMICRELEASE(_pcf);
|
|
}
|
|
}
|
|
|
|
IUnknown* ClassHolder_Create(const CLSID* pclsid)
|
|
{
|
|
IUnknown *punk = NULL;
|
|
CClassHolder *pch = new CClassHolder();
|
|
if (pch)
|
|
{
|
|
if (SUCCEEDED(pch->Initialize(pclsid)))
|
|
{
|
|
pch->QueryInterface(IID_PPV_ARG(IUnknown, &punk));
|
|
}
|
|
pch->Release();
|
|
}
|
|
return punk;
|
|
}
|
|
|
|
|
|
|