Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Ethereal-dev: Re: [Ethereal-dev] Nspi interface

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Luke Kenneth Casson Leighton <lkcl@xxxxxxxx>
Date: Tue, 1 Feb 2005 22:43:32 +0000
http://hands.com/~lkcl - mapifirst.CAP and mapisecond.CAP.

ironically, the data structures are identical

On Wed, Feb 02, 2005 at 08:43:54AM +1100, ronnie sahlberg wrote:
> Cool.
> 
> Do you have an example capture with a few of these commands in it for
> me to test with?
> 
> I can then try throwing my idl compiler at it and generate a full dissector.

 COOOL!

> I want to verify it with a capture first though since the idl contains
> some constructs my
> compiler has not encountered before.

 it's utterly utterly insanely complex.

 i'd be delighted if you could correct the IDL file and tell me what the
 IDL format of SPropTagArray is _supposed_ to be.

 attached is another version.

 if you get it working i'd be DELIGHTED to have a go testing
 what you're using because i am fed up with staring at
 hard-coded values - these are _unbelievably_ complex data
 structures.

 it's a database, basically.

 l.

 p.s. did i mention that it's virtually identical data structures to
 mapidefs.h, in /usr/include/wine/windows/mapidefs.h?

 p.p.s. what on _earth_ are you doing writing your own NDR IDL compiler??

	 et tu brute!  so that's:

	 1) the samba team's samba 4 idl compiler, which does on-wire
	    interoperability but doesn't give you "developer"
	    interoperability - i.e. it doesn't generate useable c
	    client or server stubs

	 2) the Wine team's MSRPC idl compiler, which gives "binary"
	    level interoperability (with rpcrt4.dll) including being
	    able to interpret the same "type strings" that muddle
	    also understands, but doesn't give you "on-wire" NDR
	    format!!!!

	 3) _your_ IDL compiler for doing "decodes"

	 4) the _original_ DCE/RPC compiler - now known as dceidl
	    in FreeDCE

	 5) MIDL - which if you've got the money can be _bought_ from
	    The Open Group - see http://opengroup.org/comsource!!!
	    and it's NT4 SP3 source code licensed to The Open Group!!!

   i'm going to crawl into a corner and cower at the amount of man-hours
   being wasted, here, just because some dickhead two-bit corporation
   wants to make a few extra percentage points of profit.


[ uuid(f5cc5a18-4264-101a-8c59-08002b2f8426),
version(56.0),
implicit_handle(handle_t rpc_binding)
] interface emsabp
{

/* this is mostly identical to wine/include/mapidefs.h,
 * up until MAPIERROR, at which point it looks completely
 * unfamiliar and alien.
 *
 * the functions in the IMAPITable only look _vaguely_
 * familiar but are like, utterly different.
 * really odd.  same data structures.  different functions.
 * oh well.
 */
 
  typedef unsigned short WCHAR;

  typedef struct {
    long element_1;
    long element_2;
    long element_3;
    long element_4;
    long element_5;
    long element_6;
    long element_7;
    long element_8;
    long element_9;
  } MAPI_UNIDENTIFIED;

  typedef struct {
    char ab[16];
  } MAPIUID;

  typedef [context_handle] void *emsabp_hnd_t;

  long NspiBind(
        [in] handle_t element_11,
        [in] long element_12,
        [in, ref] MAPI_UNIDENTIFIED *element_13,
    [in,out, unique] MAPIUID *element_14,
       [out] emsabp_hnd_t *element_15
  );

  long NspiUnbind(
    [in,out] emsabp_hnd_t *element_16,
        [in] long element_17
  );

  long NspiUpdateStat(
        [in] emsabp_hnd_t element_18,
        [in] long element_19,
    [in,out, ref] MAPI_UNIDENTIFIED *element_20,
    [in,out, unique] long *element_21
  );

/* typedef [ptr, string] unsigned long *SPropTagArray;*/

  /* this is probably an SPropTagArray.  although it doesn't match
   * up with the definition in wine/includes/mapidefs.h, it also
   * is the data structure i've had the most difficulty with, matching
   * it to on-wire format (muddle didn't wanna know...)
   */
  typedef struct {
    [unique, length_is(cValues), size_is(cValues)] long *aulPropTag;
    long cValues;
    /*long element_24;*/
  } SPropTagArray;

  typedef [unique] SPropTagArray *LPSPropTagArray ;

  typedef struct {
    long cb;
    [size_is(cb), ptr] char *lpb;
  } SBinary;

  typedef struct {
    long dwLowDateTime;
    long dwHighDateTime;
  } FILETIME;

  typedef struct {
    long cValues;
    [size_is(cValues), ptr] short *lpi;
  } SShortArray;

  typedef struct {
    long cValues;
    [size_is(cValues), ptr] long *lpl; 
  } MULTIVALUE_LONG_STRUCT;

  typedef struct {
    long cValues;
    [size_is(cValues), ptr] long *lppszA; /* this doesn't look right: should be a LPSTR */
  } SLPSTRArray;

  typedef struct {
    long cValues;
    [size_is(cValues), ptr] SBinary *lpbin;
  } SBinaryArray;

  typedef struct {
    long cValues;
    [size_is(cValues), ptr] long *lpguid; /* this doesn't look right: it should be a GUID* */
  } SGuidArray;

  typedef struct {
    long cValues;
    [size_is(cValues), ptr] long *lpi; /* this doesn't look right: it should be a LPWSTR* */
  } MULTIVALUE_UNICODE_STRUCT;

  typedef struct {
    long cValues;
    [size_is(cValues), ptr] FILETIME *lpft;
  } SDateTimeArray;

  typedef [ptr, string] unsigned short *WSTRING;
  typedef [ptr, string] char *STRING;

/* Flags for abFlags[0] */
#define MAPI_NOTRESERVED 0x08
#define MAPI_NOW         0x10
#define MAPI_THISSESSION 0x20
#define MAPI_NOTRECIP    0x40
#define MAPI_SHORTTERM   0x80

/* Flags for abFlags[1]  */
#define MAPI_COMPOUND    0x80

#define IsEqualMAPIUID(pl,pr) (!memcmp((pl),(pr),sizeof(MAPIUID)))

#define MAPI_ONE_OFF_UID { 0x81,0x2b,0x1f,0xa4,0xbe,0xa3,0x10,0x19,0x9d,0x6e, \
                           0x00,0xdd,0x01,0x0f,0x54,0x02 }
#define MAPI_ONE_OFF_UNICODE      0x8000
#define MAPI_ONE_OFF_NO_RICH_INFO 0x0001

/* Object types */
#define MAPI_STORE    1U
#define MAPI_ADDRBOOK 2U
#define MAPI_FOLDER   3U
#define MAPI_ABCONT   4U
#define MAPI_MESSAGE  5U
#define MAPI_MAILUSER 6U
#define MAPI_ATTACH   7U
#define MAPI_DISTLIST 8U
#define MAPI_PROFSECT 9U
#define MAPI_STATUS   10U
#define MAPI_SESSION  11U
#define MAPI_FORMINFO 12U

/* Flags for various calls */
#define MAPI_MODIFY                   0x00000001U /* Object can be modified */
#define MAPI_ACCESS_MODIFY            MAPI_MODIFY /* Want write access */
#define MAPI_ACCESS_READ              0x00000002U /* Want read access */
#define MAPI_ACCESS_DELETE            0x00000004U /* Want delete access */
#define MAPI_ACCESS_CREATE_HIERARCHY  0x00000008U
#define MAPI_ACCESS_CREATE_CONTENTS   0x00000010U
#define MAPI_ACCESS_CREATE_ASSOCIATED 0x00000020U
#define MAPI_UNICODE                  0x80000000U /* Strings in this call are Unicode */

#if defined (UNICODE) || defined (__WINESRC__)
#define fMapiUnicode MAPI_UNICODE
#else
#define fMapiUnicode 0U
#endif

/* Types of message receivers */
#ifndef MAPI_ORIG
#define MAPI_ORIG      0          /* The original author */
#define MAPI_TO        1          /* The primary message receiver */
#define MAPI_CC        2          /* A carbon copy receiver */
#define MAPI_BCC       3          /* A blind carbon copy receiver */
#define MAPI_P1        0x10000000 /* A message resend */
#define MAPI_SUBMITTED 0x80000000 /* This message has already been sent */
#endif

#ifndef cchProfileNameMax
#define cchProfileNameMax 64 /* Maximum length of a profile name */
#define cchProfilePassMax 64 /* Maximum length of a profile password */
#endif

/* Properties: The are the contents of cells in MAPI tables, as well as the
 * values returned when object properties are queried.
 */

/* Property types */
#define PT_UNSPECIFIED 0U
#define PT_NULL        1U
#define PT_I2          2U
#define PT_SHORT       PT_I2
#define PT_LONG        3U
#define PT_I4          PT_LONG
#define PT_R4          4U
#define PT_FLOAT       PT_R4
#define PT_DOUBLE      5U
#define PT_R8          PT_DOUBLE
#define PT_CURRENCY    6U
#define PT_APPTIME     7U
#define PT_ERROR       10U
#define PT_BOOLEAN     11U
#define PT_OBJECT      13U
#define PT_I8          20U
#define PT_LONGLONG    PT_I8
#define PT_STRING8     30U
#define PT_UNICODE     31U
#define PT_SYSTIME     64U
#define PT_CLSID       72U
#define PT_BINARY      258U

#define MV_FLAG     0x1000 /* This property type is multi-valued (an array) */
#define MV_INSTANCE 0x2000
#define MVI_FLAG    (MV_FLAG|MV_INSTANCE)
#define MVI_PROP(t) ((t)|MVI_FLAG)

#ifndef __WINESRC__
# ifdef UNICODE
# define PT_TSTRING      PT_UNICODE
# define PT_MV_TSTRING   (MV_FLAG|PT_UNICODE)
# define LPSZ            lpszW
# define LPPSZ           lppszW
# define MVSZ            MVszW
# else
# define PT_TSTRING      PT_STRING8
# define PT_MV_TSTRING   (MV_FLAG|PT_STRING8)
# define LPSZ            lpszA
# define LPPSZ           lppszA
# define MVSZ            MVszA
# endif
#endif

#define PROP_TYPE_MASK  0xFFFFU
#define PROP_TYPE(t)    ((t) & PROP_TYPE_MASK)
#define PROP_ID(t)      ((t) >> 16)
#define PROP_TAG(t,id)  (((id) << 16) | t)
#define PROP_ID_NULL    0
#define PROP_ID_INVALID 0xFFFF
#define PR_NULL         PROP_TAG(PT_NULL, PROP_ID_NULL)

#define CHANGE_PROP_TYPE(t,typ) ((0xFFFF0000 & t) | typ)

/* Multi-valued property types */
#define PT_MV_I2       (MV_FLAG|PT_I2)
#define PT_MV_SHORT    PT_MV_I2
#define PT_MV_LONG     (MV_FLAG|PT_LONG)
#define PT_MV_I4       PT_MV_LONG
#define PT_MV_R4       (MV_FLAG|PT_R4)
#define PT_MV_FLOAT    PT_MV_R4
#define PT_MV_DOUBLE   (MV_FLAG|PT_DOUBLE)
#define PT_MV_R8       PT_MV_DOUBLE
#define PT_MV_CURRENCY (MV_FLAG|PT_CURRENCY)
#define PT_MV_APPTIME  (MV_FLAG|PT_APPTIME)
#define PT_MV_SYSTIME  (MV_FLAG|PT_SYSTIME)
#define PT_MV_STRING8  (MV_FLAG|PT_STRING8)
#define PT_MV_BINARY   (MV_FLAG|PT_BINARY)
#define PT_MV_UNICODE  (MV_FLAG|PT_UNICODE)
#define PT_MV_CLSID    (MV_FLAG|PT_CLSID)
#define PT_MV_I8       (MV_FLAG|PT_I8)
#define PT_MV_LONGLONG PT_MV_I8


  typedef [switch_type(long)] union {
    [case(PT_I2)] short i;
    [case(PT_LONG)] long l;
    [case(PT_BOOLEAN)] short b;
    [case(PT_STRING8)] STRING lpszA;
    [case(PT_BINARY)] SBinary bin;
    [case(PT_UNICODE)] WSTRING lpszW;
    [case(PT_CLSID), ptr] MAPIUID *lpguid;
    [case(PT_SYSTIME)] FILETIME ft;
    [case(PT_ERROR)] long err;
    [case(PT_MV_I2)] SShortArray MVi;
    [case(PT_MV_LONG)] MULTIVALUE_LONG_STRUCT MVl;
    [case(PT_MV_STRING8)] SLPSTRArray MVszA;
    [case(PT_MV_BINARY)] SBinaryArray MVbin;
    [case(PT_MV_CLSID)] SGuidArray MVguid;
    [case(PT_MV_UNICODE)] MULTIVALUE_UNICODE_STRUCT MVszW;
    [case(PT_MV_SYSTIME)] SDateTimeArray MVft;
    [case(PT_NULL)] long null;
    [case(PT_OBJECT)] long object;
  } SPropValue_CTR;

  typedef struct {
    long ulPropTag;
    long dwAlignPad;
    [switch_is(ulPropTag)] SPropValue_CTR Value; 
  } SPropValue;

  typedef struct {
    long ulAdrEntryPad;
    long cValues;
    [size_is(cValues), unique] SPropValue *lpProps;
  } SRow;

  typedef [unique] SRow *SRow_PTR ;

  typedef struct {
    long cRows;
    [size_is(cRows)] SRow aRow[*];
  } SRowSet;

  typedef [unique] SRowSet *SRowSet_PTR ;

  long NspiQueryRows(
        [in] emsabp_hnd_t element_69,
        [in] long element_70,
    [in,out, ref] MAPI_UNIDENTIFIED *element_71,
        [in] long lRows,
        [in, size_is(lRows), unique] long *element_73,
        [in] long element_74,
        [in, ref] SPropTagArray *element_75,
       [out, ref] SRowSet_PTR *p_rowset
  );

  long NspiSeekEntries(
        [in] emsabp_hnd_t element_77,
        [in] long element_78,
    [in,out, ref] MAPI_UNIDENTIFIED *element_79,
        [in, ref] SPropValue *element_80,
        [in, unique] SPropTagArray *element_81,
        [in, unique] SPropTagArray *element_82,
       [out, ref] SRowSet_PTR *element_83
  );

  typedef [ptr] struct _SRestriction *LPSRestriction;

  typedef struct {
    long cRes;
    [size_is(cRes)] LPSRestriction lpRes;
  } SAndRestriction;

  typedef struct {
    long cRes;
    [size_is(cRes)] LPSRestriction lpRes;
  } SOrRestriction;

  typedef struct {
    /* ULONG ulReserved - perhaps an [ignore] property on this one? */
    LPSRestriction lpRes;
  } SNotRestriction;

  typedef struct {
    long ulFuzzyLevel;
    long ulPropTag;
    [ptr] SPropValue *lpProp;
  } SContentRestriction;

  typedef struct {
    long relop;
    long ulPropTag;
    [ptr] SPropValue *lpProp;
  } SPropertyRestriction;

  typedef struct {
    long ulReserved1;
    long ulPropTag;
    long ulReserved2;
  } SExistRestriction;

  typedef struct {
    long relop;
    long ulPropTag;
    long cb;
  } SSizeRestriction;

  typedef struct {
    long relBMR;
    long ulPropTag;
    long ulMask;
  } SBitMaskRestriction;

  typedef struct {
    long relop;
    long ulPropTag1;
    long ulPropTag2;
  } SComparePropsRestriction;

  typedef struct {
    long ulSubObject;
    LPSRestriction lpRes;
  } SSubRestriction;

  typedef struct {
    [unique] MAPIUID *lpguid;
    long ulKind;
    long lID; /* this is actually a union in mapidefs.h */
  } MAPINAMEID;

/* Restriction types */
#define RES_AND            0U
#define RES_OR             1U
#define RES_NOT            2U
#define RES_CONTENT        3U
#define RES_PROPERTY       4U
#define RES_COMPAREPROPS   5U
#define RES_BITMASK        6U
#define RES_SIZE           7U
#define RES_EXIST          8U
#define RES_SUBRESTRICTION 9U
#define RES_COMMENT        10U


  typedef [switch_type(long)] union {
    [case(RES_AND)           ] SAndRestriction resAnd;
    [case(RES_OR)            ] SOrRestriction resOr;
    [case(RES_NOT)           ] SNotRestriction resNot;
    [case(RES_CONTENT)       ] SContentRestriction resContent;
    [case(RES_PROPERTY)      ] SPropertyRestriction resProperty;
    [case(RES_COMPAREPROPS)  ] SComparePropsRestriction resCompareProps;
    [case(RES_BITMASK)       ] SBitMaskRestriction resBitMask;
    [case(RES_SUBRESTRICTION)] SSubRestriction resSub;
    [case(RES_SIZE)          ] SSizeRestriction resSize;
    [case(RES_EXIST)         ] SExistRestriction resExist;
    /* case SCommentRestriction is missing! */
  } SRestriction_CTR;

  typedef struct _SRestriction {
    long rt;
    [switch_is(rt)] SRestriction_CTR res;
  } SRestriction;

  long NspiGetMatches(
        [in] emsabp_hnd_t element_110,
        [in] long element_111,
    [in,out, ref] MAPI_UNIDENTIFIED *element_112,
        [in, unique] SPropTagArray *element_113,
        [in] long element_114,
        [in, unique] SRestriction *element_115,
        [in, unique] MAPINAMEID *element_116,
        [in] long element_117,
       [out, ref] SPropTagArray *element_118,
        [in, ref] SPropTagArray *element_119,
       [out, ref] SRowSet_PTR *element_120
  );

  long NspiResortRestriction(
        [in] emsabp_hnd_t element_121,
        [in] long element_122,
    [in,out, ref] MAPI_UNIDENTIFIED *element_123,
        [in, ref] SPropTagArray *element_124,
    [in,out, ref] LPSPropTagArray *element_125
  );

  typedef struct {
    long element_126;
    [unique, string] char *element_127;
  } NAME_STRING;

  long NspiDNToEph(
        [in] emsabp_hnd_t element_128,
        [in] long element_129,
        [in, ref] NAME_STRING *element_130,
       [out, ref] SPropTagArray *element_131
  );

  long NspiGetPropList(
        [in] emsabp_hnd_t element_132,
        [in] long element_133,
        [in] long element_134,
        [in] long element_135,
       [out, ref] LPSPropTagArray *element_136
  );

  long NspiGetProps(
        [in] emsabp_hnd_t element_137,
        [in] long element_138,
        [in, ref] MAPI_UNIDENTIFIED *element_139,
        [in, unique] SPropTagArray *element_140,
       [out, ref] SRow_PTR *element_141
  );

  long NspiCompareDNTs(
        [in] emsabp_hnd_t element_142,
        [in] long element_143,
        [in, ref] MAPI_UNIDENTIFIED *element_144,
        [in] long element_145,
        [in] long element_146,
       [out, ref] long *element_147
  );

  long NspiModProps(
        [in] emsabp_hnd_t element_148,
        [in] long element_149,
        [in, ref] MAPI_UNIDENTIFIED *element_150,
        [in, unique] SPropTagArray *element_151,
        [in, ref] SRow *element_152
  );

  long NspiGetHierarchyInfo(
        [in] emsabp_hnd_t element_153,
        [in] long element_154,
        [in, ref] MAPI_UNIDENTIFIED *element_155,
    [in,out, ref] long *element_156,
       [out, ref] SRowSet_PTR *element_157
  );

  long NspiGetTemplateInfo(
        [in] emsabp_hnd_t element_158,
        [in] long element_159,
        [in] long element_160,
        [in, unique, string] char *element_161,
        [in] long element_162,
        [in] long element_163,
       [out, ref] SRow_PTR *element_164
  );

  long NspiModLInkAtt(
        [in] emsabp_hnd_t element_165,
        [in] long element_166,
        [in] long element_167,
        [in] long element_168,
        [in, ref] SBinaryArray *element_169
  );

  long NspiDeleteEntries(
        [in] emsabp_hnd_t element_170,
        [in] long element_171,
        [in] long element_172,
        [in, ref] SBinaryArray *element_173
  );

  long NspiQueryColumns(
        [in] emsabp_hnd_t element_174,
        [in] long element_175,
        [in] long element_176,
       [out, ref] LPSPropTagArray *element_177
  );

  typedef struct {
    long element_178;
    [unique] MAPIUID *element_179;
  } NAME_CLSID;

  typedef [ptr] NAME_CLSID *NAME_CLSID_PTR;

  long NspiGetNamesFromIDs(
        [in] emsabp_hnd_t element_180,
        [in] long element_181,
        [in, unique] MAPIUID *element_182,
        [in, unique] SPropTagArray *element_183,
       [out, ref] LPSPropTagArray *element_184,
       [out, ref] NAME_CLSID_PTR *element_185
  );

  long NspiGetIDsFromNames(
        [in] emsabp_hnd_t element_186,
        [in] long element_187,
        [in] long element_188,
        [in] long element_189,
        [in, size_is(element_189), ref] long *element_190,
       [out, ref] LPSPropTagArray *element_191
  );

  long NspiResolveNames(
        [in] emsabp_hnd_t element_192,
        [in] long element_193,
        [in, ref] MAPI_UNIDENTIFIED *element_194,
        [in, unique] SPropTagArray *element_195,
        [in, ref] NAME_STRING *element_196,
       [out, ref] LPSPropTagArray *element_197,
       [out, ref] SRowSet_PTR *element_198
  );

  typedef struct {
    long element_199;
    [unique, string] WCHAR *element_200;
  } NAME_UNICODE;

  long NspiResolveNamesW(
        [in] emsabp_hnd_t element_201,
        [in] long element_202,
        [in, ref] MAPI_UNIDENTIFIED *element_203,
        [in, unique] SPropTagArray *element_204,
        [in, ref] NAME_UNICODE *element_205,
       [out, ref] LPSPropTagArray *element_206,
       [out, ref] SRowSet_PTR *element_207
  );

}