||This is used for stabilizing a COM object's reference count during
construction when that object aggregates other objects. Since the aggregated
object(s) may AddRef() or Release(), we need to artifically boost the
refcount to prevent premature destruction. Note that we increment/decrement
instead of AddRef()/Release() in this class because we want to adjust the
refcount without causing any other side effects (like object destruction).
||This class encapsulates an "agile reference." These are references that
allow you to pass COM interfaces between apartments. When you have an
interface that you would like to pass between apartments, you wrap that
interface in an AgileReference and pass the agile reference instead. Then
you unwrap the interface by calling AgileReference::Resolve.
// In the multithreaded apartment, foo is an IFoo*
auto myAgileRef = MakeUnique<AgileReference>(IID_IFoo, foo);
// myAgileRef is passed to our main thread, which runs in a single-threaded
HRESULT hr = myAgileRef->Resolve(IID_IFoo, getter_AddRefs(foo));
// Now foo may be called from the main thread
||This constructor is to be used when we want to instantiate the object but
we do not yet know which type of apartment we want. Call Init() to
||Synchronously run |aClosure| on a thread living in the COM multithreaded
apartment. If the current thread lives inside the COM MTA, then it runs
|aClosure| immediately unless |aOpt| ==
||From this point forward, all threads in this process are implicitly
members of the multi-threaded apartment, with the following exceptions:
1. If any Win32 GUI APIs were called on the current thread prior to
executing this constructor, then this thread has already been implicitly
initialized as the process's main STA thread; or
2. A thread explicitly and successfully calls CoInitialize(Ex) to specify
||@return 0 if call is in-process or resolving the calling thread failed,
otherwise contains the thread id of the calling thread.
||IChannelHook exposes six methods: The Client* methods are called when
a client is sending an IPC request, whereas the Server* methods are called
when a server is receiving an IPC request.
For our purposes, we only care about the client-side methods. The COM
runtime invokes the methods in the following order:
1. ClientGetSize, where the hook specifies the size of its payload;
2. ClientFillBuffer, where the hook fills the channel's buffer with its
payload information. NOTE: This method is only called when ClientGetSize
specifies a non-zero payload size. For our purposes, since we are not
sending a payload, this method will never be called!
3. ClientNotify, when the response has been received from the server.
Since we want to use these hooks to record the beginning and end of a COM
IPC call, we use ClientGetSize for logging the start, and ClientNotify for
logging the end.
Finally, our implementation responds to any request matching our extension
ID, however we only care about main thread COM calls.
||Given a buffer, create a new IStream object.
@param aBuf Buffer containing data to initialize the stream. This parameter
may be nullptr, causing the stream to be created with aBufLen
bytes of uninitialized data.
@param aBufLen Length of data in aBuf, or desired stream size if aBuf is
@param aOutStream Outparam to receive the newly created stream.
@return HRESULT error code.