// THClassFactory.h ///////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1999 Simon Fell // All rights reserved. // // 10 March 99 - Initial release, // inspired by Chris Sells & Keith Brown, thanks guys ! // // // NO WARRANTIES ARE EXTENDED. USE AT YOUR OWN RISK. // // To contact the author with suggestions or comments, use simon@zaks.demon.co.uk // ///////////////////////////////////////////////////////////////////////////// // // THClassFactory provides an overriden implemention of IClassFactory::CreateInstance // that attatches a TraceHook to the newly created object // // You'll need to modify your object's definition to use this class factory // rather than the ATL provided ones, like // // As the template overrides an existing Class Factory, you still get to use all // the funky ATL provided class factories. // /* class ATL_NO_VTABLE CFoo : public CComObjectRootEx, public CComCoClass, public IFoo { public: CFoo() { } DECLARE_REGISTRY_RESOURCEID(IDR_FOO) DECLARE_GET_CONTROLLING_UNKNOWN() DECLARE_PROTECT_FINAL_CONSTRUCT() DECLARE_CLASSFACTORY_EX(CTHClassFactory) BEGIN_COM_MAP(CFoo) COM_INTERFACE_ENTRY(IFoo) END_COM_MAP() */ #include #include #ifndef HR2 #define HR2(_e) { HRESULT _hr = _e; if( FAILED(_hr) ) return; } #endif // HR2 inline void TraceHook(LPCOLESTR pszObjectName, REFIID riid, void** ppItf) { // This parameter is [in, out] //assert(ppItf && *ppItf); // Create an instance of the UD Trace Hook and hand it the object name CComPtr spHook; HR2(spHook.CoCreateInstance(OLESTR("UDTraceHookSvr.TraceHook"))); HR2(spHook->SetObjectName(pszObjectName && *pszObjectName ? pszObjectName : OLESTR(""))); // Get the UD class object CComPtr spFactory; HR2(CoGetClassObject(__uuidof(CoDelegator21), CLSCTX_INPROC, 0, __uuidof(IDelegatorFactory), (void**)&spFactory)); // Delegate! CComPtr spitfDelegator; IUnknown* punk = reinterpret_cast(*ppItf); HR2(spFactory->CreateDelegator(0, punk, 0, spHook, 0, riid, (void**)&spitfDelegator)); // Replace the original ppItf with the delegator punk->Release(); *ppItf = spitfDelegator.Detach(); } template class CTHClassFactory : public baseCF { STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj) { HRESULT hr = baseCF::CreateInstance(pUnkOuter, riid, ppvObj); // you could of course check some registry key here before deciding // to attach the hook if (SUCCEEDED(hr)) TraceHook(NULL, riid, ppvObj) ; return hr ; } };