4. IRemUnknown and IRemUnknown2 interfaces

The IRemUnknown interface is used by remote clients for manipulating reference counts on the IPIDs that they hold and for obtaining additional interfaces on the objects on which those IPIDs are found.

References are kept per interface rather then per object.

This interface is implemented by the COM "OXID object" associated with each OXID (i.e. each Object Exporter). The IPID for the IRemUnknown interface on this object is returned from IOXIDResolver::ResolveOxid (see Section 5.2.1), or when an object is activated with IRemoteActivation::RemoteActivation (see section 6.2.1). An OXID object need never be pinged; its interfaces (this IPID included) need never be reference counted. IRemUnknown is specified as follows:

The IRemUnknown2 interface introduced in version 5.2 of the DCOM protocol inherits from IRemUnknown and adds an extra method -- RemoteQueryInterface2 -- which allows clients to retrieve interface pointers to objects which supply additional data beyond the STDOBJREF in their marshaled interface packets.

//  The remote version of IUnknown.  This interface exists on every
//  OXID (whether an OXID represents either a thread or a process is
//  implementation specific).  It is used by clients to query for new 
//  interfaces, get additional references (for marshaling), and release
//  outstanding references.  
//  This interface is passed along during OXID resolution.
//
[
   object,
   uuid(00000131-0000-0000-C000-000000000046)
]
interface IRemUnknown : IUnknown
{
    typedef struct tagREMQIRESULT

    {
       HRESULT      hResult;            // result of call
       STDOBJREF    std;                // data for returned interface
    } REMQIRESULT;

    HRESULT RemQueryInterface
    (
        [in] REFIPID        ripid,      // interface to QI on
        [in] unsigned long  cRefs,      // count of AddRefs requested
        [in] unsigned short cIids,      // count of IIDs that follow
        [in, size_is(cIids)]
        IID*                iids,       // IIDs to QI for
        [out, size_is(,cIids)]
        REMQIRESULT**       ppQIResults // results returned
    );

    typedef struct tagREMINTERFACEREF
    {
        IPID           ipid;           // ipid to AddRef/Release
        unsigned long  cPublicRefs;
        unsigned long  cPrivateRefs;
    } REMINTERFACEREF;

    HRESULT RemAddRef
    (
        [in] unsigned short    cInterfaceRefs,
        [in, size_is(cInterfaceRefs)]
        REMINTERFACEREF        InterfaceRefs[],
        [out, size_is(cInterfaceRefs)]
        HRESULT*               pResults
    );

    HRESULT RemRelease
    (
        [in] unsigned short    cInterfaceRefs,
        [in, size_is(cInterfaceRefs)]
        REMINTERFACEREF        InterfaceRefs[]
    );
}

//  Derived from IRemUnknown, this interface supports Remote Query interface
//  for objects that supply additional data beyond the STDOBJREF in their
//  marshaled interface packets.

[
    object,
    uuid(00000142-0000-0000-C000-000000000046)
]

interface IRemUnknown2 : IRemUnknown
{
#ifndef DO_NO_IMPORTS
    import "unknwn.idl";
    import "obase.idl";
#endif

    HRESULT RemQueryInterface2
    (
        [in] REFIPID     ripid,
        [in] unsigned short                     cIids,
        [in, size_is(cIids)] IID                *iids,
        [out, size_is(cIids)] HRESULT           *phr,
        [out, size_is(cIids)] MInterfacePointer **ppMIF
    );
}