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