Figure 6   IRemoteActivation IDL
[ // no object here. Not a COM interface!
   uuid(4d9f4ab8-7d1c-11cf-861e-0020af6e7c57), 
   pointer_default(unique) 
]

interface IRemoteActivation
{
   const unsigned long MODE_GET_CLASS_OBJECT = 0xffffffff;

   HRESULT RemoteActivation(
     [in] handle_t                         hRpc,
     [in] ORPCTHIS                         *ORPCthis,
     [out] ORPCTHAT                        *ORPCthat,
     [in] const GUID                       *Clsid,
     [in, string, unique] WCHAR            *pwszObjectName,
     [in, unique] MInterfacePointer        *pObjectStorage,
     [in] DWORD                            ClientImpLevel,
     [in] DWORD                            Mode,
     [in] DWORD                            Interfaces,
     [in, unique, size_is(Interfaces)] IID *pIIDs,
     [in] unsigned short                   cRequestedProtseqs,
     [in, size_is(cRequestedProtseqs)]
          unsigned short                   RequestedProtseqs[],
     [out] OXID                            *pOxid,
     [out] DUALSTRINGARRAY                 **ppdsaOxidBindings,
     [out] IPID                            *pipidRemUnknown,
     [out] DWORD                           *pAuthnHint,
     [out] COMVERSION                      *pServerVersion,
     [out] HRESULT                         *phr,
     [out, size_is(Interfaces)]
           MInterfacePointer               **ppInterfaceData,
     [out, size_is(Interfaces)] HRESULT    *pResults
   );
}

Figure 7   SCM Endpoints

Protocol String Description Endpoint
Ncadg_ip_udp Connectionless over UDP 135
Ncacn_ip_tcp Connection-oriented over TCP 135
Ncacn_nb_tcp Connection-oriented using NetBIOS over TCP 135
Ncacn_http Connection-oriented over HTTP 80


Figure 9   PDU Types

PDU Type Protocol Type Value
Request CO/CL 0
Ping CL 1
Response CO/CL 2
Fault CO/CL 3
Working CL 4
Nocall CL 5
Reject CL 6
Ack CL 7
Cl_cancel CL 8
Fack CL 9
Cancel_ack CL 10
Bind CO 11
Bind_ack CO 12
Bind_nak CO 13
Alter_context CO 14
Alter_context_resp CO 15
Shutdown CO 17
Co_cancel CO 18
Orphaned CO 19


Figure 10   PDU Header


 typedef struct
 {
     unsigned small rpc_vers = 4; // RPC protocol major version
     unsigned small ptype; // packet type
     unsigned small flags1; // packet flags
     unsigned small flags2; // packet flags
     byte drep[3]; // data representation format label
     unsigned small serial_hi; // high byte of serial number
     GUID object; // object identifier (Contains the IPID)
     GUID if_id; // interface identifier (IID)
     GUID act_id; // activity identifier
     unsigned long server_boot; // server boot time
     unsigned long if_vers; // interface version
     unsigned long seqnum; // sequence number
     unsigned short opnum; // operation number
     unsigned short ihint; // interface hint
     unsigned short ahint; // activity hint
     unsigned short len; // length of packey body
     unsigned short fragnum; // fragment number
     unsigned small auth_proto; // authentication protocol id
     unsigned small serial_lo; // low byte of serial number
 } dc_rpc_cl_pkt_hdr_t;

Figure 11   OBJREF Structure


 // Although this structure is conformant, it is always 
 // marshaled in little-endian byte-order.
 typedef struct tagOBJREF {
    unsigned long  signature;        // Always MEOW
    unsigned long  flags;            // OBJREF flags
    GUID           iid;              // interface identifier
 
    union {    // [switch_is(flags), switch_type(unsigned long)]
       struct {    // [case(OBJREF_STANDARD)]
          STDOBJREF         std;        // standard objref
          DUALSTRINGARRAY   saResAddr;  // resolver address
       } u_standard;
 
       struct {    // [case(OBJREF_HANDLER)]
          STDOBJREF         std;        // standard objref
          CLSID             clsid;      // Clsid of handler code
          DUALSTRINGARRAY   saResAddr;  // resolver address
       } u_handler;
 
       struct {    // [case(OBJREF_CUSTOM)]
          CLSID           clsid;   // Clsid of unmarshaling code
          unsigned long cbExtension; // size of extension data
          unsigned long   size;     // size of data that follows
          byte  *pData;      // extension + class specific data
                             // [size_is(size), ref]
       } u_custom;
    } u_objref;
 } OBJREF;

Figure 13   Tower Identifiers

Tower Identifier Value Description
NCADG_IP_UDP 0x08 Connectionless User
Datagram Protocol
NCACN_IP_TCP 0x07 Connection-oriented
Transmission Control Protocol
NCADG_IPX 0x0E Connectionless Internetwork
Exchange Protocol
NCACN_SPX 0x0C Connection-oriented
Sequenced Exchange Protocol
NCACN_NB_NB 0x12 Connection-oriented NetBIOS
NCACN_NB_IPX 0x0D Connection-oriented NetBIOS
over IPX
NCACN_HTTP 0x1F Connection-oriented over HTTP


Figure 14   IRemUnknown IDL


 // The remote version of IUnknown. It is used by clients to 
 // query for new interfaces, get additional references (for 
 // marshaling), and release outstanding references.
 [
    object,
    uuid(00000131-0000-0000-C000-000000000046)
 ]
 interface IRemUnknown : IUnknown
 {
     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
     );
 
     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[]
     );
 }

Figure 17   IOXIDResolver IDL


 [ // no object here. Not a COM interface!
     uuid(99fcfec4-5260-101b-bbcb-00aa0021347a),
     pointer_default(unique)
 ]
 interface IOXIDResolver
 {
     // Method to get the protocol sequences, string bindings
     // and machine id for an object server given its OXID.
     [idempotent] error_status_t ResolveOxid
     (
     [in]       handle_t        hRpc,
     [in]       OXID           *pOxid,
     [in]       unsigned short  cRequestedProtseqs,
     [in,  ref, size_is(cRequestedProtseqs)]
                unsigned short  arRequestedProtseqs[],
     [out, ref] DUALSTRINGARRAY **ppdsaOxidBindings,
     [out, ref] IPID            *pipidRemUnknown,
     [out, ref] DWORD           *pAuthnHint
     );
 
     // Simple ping is used to ping a Set. Client machines use
     // this to inform the Object exporter that it is still
     // using the members of the set. Returns S_TRUE if the
     // SetId is known by the Object exporter, S_FALSE if not.
     [idempotent] error_status_t SimplePing
     (
     [in]  handle_t  hRpc,
     [in]  SETID    *pSetId  // Must not be zero
     );
 
     // Complex ping is used to create sets of OIDs to ping. The
     // whole set can subsequently be pinged using SimplePing,
     // thus reducing network traffic.
     [idempotent] error_status_t ComplexPing
     (
     [in]       handle_t        hRpc,
     [in, out]  SETID          *pSetId,  // In of 0 on first
                                         // call for new set.
     [in]       unsigned short  SequenceNum,
     [in]       unsigned short  cAddToSet,
     [in]       unsigned short  cDelFromSet,
     [in, unique, size_is(cAddToSet)]   OID AddToSet[],
                  // add the Se OIDs to the set
     [in, unique, size_is(cDelFromSet)] OID DelFromSet[],
                  // remove the Se OIDs from the set
     [out]      unsigned short *pPingBackoffFactor
                  // 2^factor = multipler
     );
 
     // In some cases the client may be unsure that a particular
     // binding will reach the server. For example, when the
     // oxid bindings have more then one TCP/IP binding. This
     // call can be used to validate the binding from the
     // client.
     [idempotent] error_status_t ServerAlive
     (
     [in]       handle_t        hRpc
     );
 }

Figure 18   Use of MSHLFLAGS_NOPING


 IMarshal* pMarshal = NULL;
 
 HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
 {
     if(pUnknownOuter != NULL)
         return CLASS_E_NOAGGREGATION;
 
     CObject *pObject = new CObject;
 
     if(pObject == NULL)
         return E_OUTOFMEMORY;
 
     IUnknown* pUnknown;
     pObject->QueryInterface(IID_IUnknown, (void**)&pUnknown);
     CoGetStandardMarshal(riid, pUnknown, 0, NULL, 
                          MSHLFLAGS_NOPING|MSHLFLAGS_NORMAL, &pMarshal);
     pUnknown->Release();
 
     // QueryInterface probably for IID_IUNKNOWN
     HRESULT hr = pObject->QueryInterface(riid, ppv);
     pObject->Release();
     return hr;
 }