131 lines
3.5 KiB
C++
131 lines
3.5 KiB
C++
#include "cabinet.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class factory for explorer.exe
|
|
//
|
|
// These objects do not exist in the registry but rather are registered dynamically at
|
|
// runtime. Since ClassFactory_Start is called on the the tray's thread, all objects
|
|
// will be registered on that thread.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef HRESULT (*LPFNCREATEOBJINSTANCE)(IUnknown* pUnkOuter, IUnknown** ppunk);
|
|
|
|
class CDynamicClassFactory : public IClassFactory
|
|
{
|
|
public:
|
|
// *** IUnknown ***
|
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
|
|
{
|
|
static const QITAB qit[] =
|
|
{
|
|
QITABENT(CDynamicClassFactory, IClassFactory),
|
|
{ 0 },
|
|
};
|
|
|
|
return QISearch(this, qit, riid, ppv);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) AddRef() { return ++_cRef; }
|
|
|
|
STDMETHODIMP_(ULONG) Release()
|
|
{
|
|
if (--_cRef > 0)
|
|
{
|
|
return _cRef;
|
|
}
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
// *** IClassFactory ***
|
|
STDMETHODIMP CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
IUnknown *punk;
|
|
HRESULT hr = _pfnCreate(punkOuter, &punk);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = punk->QueryInterface(riid, ppv);
|
|
punk->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP LockServer(BOOL) { return S_OK; }
|
|
|
|
// *** misc public methods ***
|
|
HRESULT Register()
|
|
{
|
|
return CoRegisterClassObject(*_pclsid, this, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
|
|
REGCLS_MULTIPLEUSE, &_dwClassObject);
|
|
}
|
|
|
|
HRESULT Revoke()
|
|
{
|
|
HRESULT hr = CoRevokeClassObject(_dwClassObject);
|
|
_dwClassObject = 0;
|
|
return hr;
|
|
}
|
|
|
|
CDynamicClassFactory(CLSID const* pclsid, LPFNCREATEOBJINSTANCE pfnCreate) : _pclsid(pclsid),
|
|
_pfnCreate(pfnCreate), _cRef(1) {}
|
|
|
|
|
|
private:
|
|
|
|
CLSID const* _pclsid;
|
|
LPFNCREATEOBJINSTANCE _pfnCreate;
|
|
DWORD _dwClassObject;
|
|
ULONG _cRef;
|
|
};
|
|
|
|
HRESULT CTaskBand_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk);
|
|
HRESULT CTrayBandSiteService_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk);
|
|
HRESULT CTrayNotifyStub_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk);
|
|
|
|
static const struct
|
|
{
|
|
CLSID const* pclsid;
|
|
LPFNCREATEOBJINSTANCE pfnCreate;
|
|
}
|
|
c_ClassParams[] =
|
|
{
|
|
{ &CLSID_TaskBand, CTaskBand_CreateInstance },
|
|
{ &CLSID_TrayBandSiteService, CTrayBandSiteService_CreateInstance },
|
|
{ &CLSID_TrayNotify, CTrayNotifyStub_CreateInstance },
|
|
};
|
|
|
|
CDynamicClassFactory* g_rgpcf[ARRAYSIZE(c_ClassParams)] = {0};
|
|
|
|
|
|
void ClassFactory_Start()
|
|
{
|
|
for (int i = 0; i < ARRAYSIZE(c_ClassParams); i++)
|
|
{
|
|
g_rgpcf[i] = new CDynamicClassFactory(c_ClassParams[i].pclsid, c_ClassParams[i].pfnCreate);
|
|
if (g_rgpcf[i])
|
|
{
|
|
g_rgpcf[i]->Register();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ClassFactory_Stop()
|
|
{
|
|
for (int i = 0; i < ARRAYSIZE(c_ClassParams); i++)
|
|
{
|
|
if (g_rgpcf[i])
|
|
{
|
|
g_rgpcf[i]->Revoke();
|
|
|
|
g_rgpcf[i]->Release();
|
|
g_rgpcf[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|