ole32, combase: Add tests for COM context switching and delayed marshaling.
When RoGetAgileReference is used with AGILEREFERENCE_DELAYEDMARSHAL, the returned IAgileReference also contains a reference to the apartment the object belongs to. Thus, when IAgileReference::Resolve() gets called, the object will get marshaled inside the owning apartment, not the caller's apartment.
This seems to be made possible by the IContextCallback interface. It provides a way to (ab)use the marshaller to execute arbitrary code inside a COM context, which is an additional bit of state nested inside apartments. An apartment can contain multiple COM contexts, and the standard marshaller will keep track of which context a marshaled interface is bound to. All method calls through that marshalled pointer will be wrapped around a context-switch, even when the caller is in the same apartment. Additionally, creating an instance of the class CLSID_IContextCallback allows us to create new contexts inside an apartment.
C++/WinRT makes use of IContextCallback to implement support for C++ coroutines (co_await, et al) inside application STA code. Another use of COM contexts seems to be the UI code in WinRT applications, where certain objects can only be Released/destructed from the apartment they were created in.
(I was able to find another instance of IContextCallback usage in the wild here, to get an IAccessible implementation that has apartment-affinity).