Implementing and Activating a Handler with No Extra Server Data

To create an instance of your handler, if it is one that gets no extra server data, the server must implement IStdMarshalInfo, but not IMarshal. IStdMarshalInfo has one method, GetClassForHandler, which retrieves the CLSID of the object handler to be used in the destination process. COM calls this when it calls CoMarshalInterface for you, and activates the handler on the client side.

Next, both the server and handler implementations must call a function new in Windows NT5.0, CoGetStdMarshalEx. This function creates a standard marshaler on each side (called a proxy manager on the client side, and a stub manager on the server side).

The server calls CoGetStdMarshalEx passing in the flag SMEXF_SERVER. This creates a server side standard marshaler (stub manager). The server side structure looks like this:

Server Side Structure

The handler calls CoGetStdMarshalEx passing in the flag SMEXF_HANDLER. This creates a client side standard marshaler (proxy manager), and aggregates it with the handler on the client side. The lifetime of both are managed by the controlling identity object (implementing IUnknown) that the system implements as well when the handler calls CoGetStdMarshalEx (refer to this function for more information). The client side structure looks like this:

Client Side Structure. Solid blue circles are exposed interfaces.

As seen in this figure, the handler is actually sandwiched between the proxy manager and the identity/controlling unknown. This gives the system control over the lifetime of the object, while giving the handler control over the exposed interfaces. The dashed line between the Identity and Proxy Manager indicates that the two share tight integration through internal private interfaces.

When COM calls CoUnmarshalInterface for the client, it will create the handler instance, aggregating it with the Identity. The handler will create the standard marshaler (through the call to CoGetStdMarshalEx, passing in the controlling unknown it received when it was created. The handler does not implement IMarshal, but will just return the IMarshal from the standard marshaler. Note that even if the handler does implement IMarshal, it will not get called during an unmarshal.

If two threads simultaneously unmarshal the same object for the first time, it is possible for two handlers to get created temporarily. One will subsequently be Released.