#ifndef _OBJREF_H_
#define _OBJREF_H_
#include <atlbase.h>
#include <atlconv.h>
//------------------------------------------------------------------------
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 440
#endif
#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
#include "oaidl.h"
#include "ocidl.h"
///// Basic Definitions
#define RPC_E_INVALID_OXID ( 0x80010151 )
#define RPC_E_INVALID_SET ( 0x80010152 )
#define MSHLFLAGS_NOPING ( 4 )
#define MSHLFLAGS_SIMPLEIPID ( 8 )
#define MSHLFLAGS_KEEPALIVE ( 16 )
typedef unsigned hyper ID;
typedef ID MID;
typedef ID OXID;
typedef ID OID;
typedef ID SETID;
typedef GUID IPID;
typedef GUID CID;
typedef REFGUID REFIPID;
#define COM_MAJOR_VERSION ( 5 )
#define COM_MINOR_VERSION ( 1 )
//////////////////////////////////////////////////////////////////
// ORPC Call Packet Format
//////////////////////////////////////////////////////////////////
typedef struct tagCOMVERSION
{
unsigned short MajorVersion; // Major version number
unsigned short MinorVersion; // Minor version number
} COMVERSION;
const unsigned long ORPCF_NULL = 0; // no additional info in packet
const unsigned long ORPCF_LOCAL = 1; // call is local to this machine
const unsigned long ORPCF_RESERVED1 = 2; // reserved for local use
const unsigned long ORPCF_RESERVED2 = 4; // reserved for local use
const unsigned long ORPCF_RESERVED3 = 8; // reserved for local use
const unsigned long ORPCF_RESERVED4 = 16; // reserved for local use
// Extension to implicit parameters.
typedef struct tagORPC_EXTENT
{
GUID id; // Extension identifier
unsigned long size; // Extension size
byte data[1]; // [size_is((size+7)&~7)]
} ORPC_EXTENT;
// Array of extensions.
typedef struct tagORPC_EXTENT_ARRAY
{
unsigned long size; // Num extents.
unsigned long reserved; // Must be zero.
ORPC_EXTENT** extent; // [size_is((size+1)&~1), unique]
} ORPC_EXTENT_ARRAY;
// implicit 'this' pointer which is the first [in] parameter on
// every ORPC call.
typedef struct tagORPCTHIS
{
COMVERSION version; // COM version number
unsigned long flags; // ORPCF flags for presence of other data
unsigned long reserved1; // set to zero
CID cid; // causality id of caller
ORPC_EXTENT_ARRAY* extensions; // [unique] extensions
} ORPCTHIS;
// implicit 'that' pointer which is the first [out] parameter on
// every ORPC call.
typedef struct tagORPCTHAT
{
unsigned long flags; // ORPCF flags for presence of other data
ORPC_EXTENT_ARRAY *extensions; // [unique] extensions
} ORPCTHAT;
// Marshaled COM Interface Wire Format
/*typedef enum tagMSHLFLAGS
{
MSHLFLAGS_NORMAL = 0,
MSHLFLAGS_TABLESTRONG = 1,
MSHLFLAGS_TABLEWEAK = 2,
} MSHLFLAGS;*/
// Tower IDs for common protocols
#define NCADG_IP_UDP 0x08;
#define NCACN_IP_TCP 0x07;
#define NCADG_IPX 0x0E;
#define NCACN_SPX 0x0C;
#define NCACN_NB_NB 0x12;
#define NCACN_NB_IPX 0x0D;
#define NCACN_DNET_NSP 0x04;
#define NCALRPC 0x10;
// This is the return type for arrays of string bindings or protseqs
// used by many ORPC interfaces.
typedef struct tagSTRINGBINDING
{
unsigned short wTowerId; // Cannot be zero.
unsigned short aNetworkAddr; // Zero terminated.
} STRINGBINDING;
// this value (invalid in DCE RPC) indicates to use default authz
#define COM_C_AUTHZ_NONE 0xffff;
typedef struct tagSECURITYBINDING
{
unsigned short wAuthnSvc; // Must not be zero
unsigned short wAuthzSvc; // Must not be zero
unsigned short aPrincName; // NULL terminated
} SECURITYBINDING;
// DUALSTRINGARRAYS are the return type for arrays of network
// addresses, arrays of endpoints and arrays of both used in
// many ORPC interfaces
typedef struct tagDUALSTRINGARRAY
{
unsigned short wNumEntries; // # of entries in array
unsigned short wSecurityOffset; // Offset of security info
// The array contains two parts, a set of STRINGBINDINGs
// and a set of SECURITYBINDINGs. Each set is terminated by an
// extra zero. The shortest array contains four zeros.
unsigned short aStringArray[1]; // [size_is(wNumEntries)]
} DUALSTRINGARRAY;// arbitrary value to help ensure validity
#define OBJREF_SIGNATURE 0x574f454d
#define OBJREF_STANDARD 0x1
#define OBJREF_HANDLER 0x2
#define OBJREF_CUSTOM 0x4
// Flag values for a STDOBJREF (standard part of an OBJREF).
// SORF_OXRES1 - SORF_OXRES8 are reserved for the object exporters
// use only, object importers must ignore them and must not enforce// MBZ.
#define SORF_NULL = 0x0000; // convenient for init
#define SORF_OXRES1 = 0x0001; // reserved by exporter
#define SORF_OXRES2 = 0x0020; // reserved by exporter
#define SORF_OXRES3 = 0x0040; // reserved by exporter
#define SORF_OXRES4 = 0x0080; // reserved by exporter
#define SORF_OXRES5 = 0x0100; // reserved by exporter
#define SORF_OXRES6 = 0x0200; // reserved by exporter
#define SORF_OXRES7 = 0x0400; // reserved by exporter
#define SORF_OXRES8 = 0x0800; // reserved by exporter
#define SORF_NOPING = 0x1000; // Pinging not required
typedef struct tagSTDOBJREF
{
unsigned long flags; // SORF_ flags (see above)
unsigned long cPublicRefs; // count of references passed
OXID oxid; // oxid of server with this oid
OID oid; // oid of object with this ipid
IPID ipid; // ipid of Interface
} STDOBJREF;
// although this structure is conformant, it is always marshaled
// in little-endian byte-order.
typedef struct tagOBJREF
{
unsigned long signature; // must be OBJREF_SIGNATURE
unsigned long objRefflags; // OBJREF flags (see above)
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;// wire representation of a marshalled interface pointer,
// always the little-endian form of an OBJREF
typedef struct tagMInterfacePointer
{
ULONG ulCntData; // size of data
byte abData[1]; // [size_is(ulCntData)] data
} MInterfacePointer, *PMInterfacePointer;
// OXID Resolver information associated with each OXID.
typedef struct tagOXID_INFO
{
DWORD dwTid; // thread id of object exporter
DWORD dwPid; // process id of obj exporter
IPID ipidRemUnknown; // IRemUnknown IPID for objectexporter
DWORD dwAuthnHint;
DUALSTRINGARRAY *psa; // protocol and security info
} OXID_INFO;
//-----------------------------------------------------------------------
void DumpGUID(GUID& guid, LPTSTR pszMessage)
{
TCHAR psz[1024]; //TODO
LPOLESTR pszGUID = NULL;
StringFromCLSID(guid, &pszGUID);
USES_CONVERSION;
lstrcpy(psz,pszMessage);
lstrcat(psz,"--");
lstrcat(psz,OLE2T(pszGUID));
::CoTaskMemFree(pszGUID);
OutputDebugString(psz);
}
//-----------------------------------------------------------------------
HRESULT ShowMeMyOBJREF(/*[in]*/IStream* pStm)
{
if(!pStm)
{
return E_POINTER;
}
HGLOBAL hg = 0;
HRESULT hr = ::GetHGlobalFromStream(pStm,&hg);
OBJREF *pObj = (OBJREF*)GlobalLock(hg);
if(!pObj)
{
return RPC_E_INVALID_OBJREF;
}
//Signature (always MEOW but anyway)
if(pObj->signature == OBJREF_SIGNATURE)
{
ATLTRACE(_T("The signature is
MEOW\n"));
}
//IID
DumpGUID(pObj->iid,_T("\nThe IID getting marshaled is "));
//Type of OBJREF
switch(pObj->objRefflags)
{
case 1:
{
ATLTRACE(_T("\nThe
Reference is STANDARD"));
//STDOBJREF Begins
//SORF flags
ATLTRACE(_T("\nThe
SORF flags for the OBJREF are %d "),pObj->u_objref.u_standard.std.flags);
//RefCounts
ATLTRACE(_T("\nThe
Reference Counts on the OBJREF is %d
"),pObj->u_objref.u_standard.std.cPublicRefs);
//OXID
_ui64toa(pObj->u_objref.u_standard.std.oxid,psz,10);
ATLTRACE(_T("\nThe
OXID of the STDOBJREF is %s "),psz);
//OID
_ui64toa(pObj->u_objref.u_standard.std.oid,psz,10);
ATLTRACE(_T("\nThe
OID of the STDOBJREF is %s"),psz);
//IPID
DumpGUID(pObj->u_objref.u_standard.std.ipid,_T("\nIPID of the STDOBJREF"));
//TODO :Dualstring
array
//DUALSTRINGARRAY da =
pObj->u_objref.u_standard.saResAddr;
break;
}
case 2:
{
ATLTRACE(_T("\nThe
Reference is HANDLER\n"));
//STDOBJREF part of the
custom handler
//SORF flags
ATLTRACE(_T("\nThe
SORF flags for the OBJREF are %d "),pObj->u_objref.u_handler.std.flags);
//RefCounts
ATLTRACE(_T("\nThe
Reference Counts on the OBJREF is %d "),pObj->u_objref.u_handler.std.cPublicRefs);
//OXID
_ui64toa(pObj->u_objref.u_handler.std.oxid,psz,10);
ATLTRACE(_T("\nThe
OXID of the STDOBJREF is %s "),psz);
//OID
_ui64toa(pObj->u_objref.u_handler.std.oid,psz,10);
ATLTRACE(_T("\nThe
OID of the STDOBJREF is %s"),psz);
//IPID
DumpGUID(pObj->u_objref.u_handler.std.ipid,_T("\nIPID of the Custom
OBJREF"));
//clsid of the handler
DumpGUID(pObj->u_objref.u_handler.clsid,_T("\nCLSID of the Custom Handler"));
//TODO :Dualstring
array
//DUALSTRINGARRAY da =
pObj->u_objref.u_standard.saResAddr;
break;
}
case 4:
{
ATLTRACE(_T("\nThe
Reference is CUSTOM"));
//clsid of the handler
DumpGUID(pObj->u_objref.u_custom.clsid,_T("\nCLSID of the Custom Proxy"));
break;
}
default:
{
ATLTRACE(_T("\nThe
Reference is of Unknown type"));
break;
}
}
GlobalUnlock(hg);
return hr;
}
#endif //_OBJREF_H_