Little known COM feature: CoGetInterceptor. This function provides you with a universal interception mechanism that lets you dynamically inspect all aspects of a call and that feels a lot like .NET Remoting Context interception sinks (which unfortunately went from documented to "internal only" in .NET FW RTM)
I don't have the cycles right now to provide an isolated sample or an in-depth explanation, but it works something like that:
IUnknown * pItfToBeIntercepted;ICallInterceptor * pInterceptor;// ... get pItfToBeIntercepted from somewhereMyEventHandler * myEventHandler = new MyEventHandler( pItfToBeIntercepted ); // implements ICallFrameEventsCoGetInterceptor(iidToBeIntercepted, NULL, IID_IContextInterceptor, (void**)&pInterceptor); // get interceptorpInterceptor->RegisterSink( myEventHandler ); // register
with myEventHandler being an instance of a class that implements ICallFrameEvents. That interface has a method OnCall that gives you the ICallFrame info. You forward the call to the actual target object using ICallFrame::Invoke or you can just consume the call right there and not forward.
To get between the caller and the object, you call QueryInterface for iidToBeIntercepted on pInterceptor and hand this reference to the client instead of the actual interface.The actual "inner" interface is wrapped by the class that handles ICallFrameEvents and which forwads the call to it inside OnCall using ICallFrame::Invoke. (as shown in the pseudo-code constructor above).
If the target object is aggregatable, you can do all of this in an outer QueryInterface, proxying each interface being asked for and therefore construct a fully transparent interception layer.