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

#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;
}