- coders wanted to help with Exchange Replacement

Posted 22 Jan 2005 at 11:41 UTC by lkcl Share This

About four years ago I asked Mr Bill Gates for the IDL files necessary to produce a client and server that can interoperate with Exchange. The nice people at the European Union might actually kick him into answering.

In the meantime, there's a little program called "muddle" which is capable of digging out IDL files with no structure names and no function names - but that's okay, because the function names can be obtained by using QuickView on the DLL.

Then, there's FreeDCE, which is capable of turning that rather horrible looking IDL file into useable c code, both client and server side. Then it's a matter of going head-to-head between an nt client and your test client on one side, against an nt server and your test server on the other, in four different combinations, with a network sniffer.

Repeat, repeat, repeat until done, done, done.

If anyone would like to try this - several projects have attempted it e.g. - but with a proper runtime and developer environment that can take the burden of most of the work away, you can reach me at

In case you were wondering, the protocols involved are DCE/RPC (handled by FreeDCE including authentication), X-400 (handled by gawd only knows what) and MAPI (which i have some hints that this could just be TNEF - hence the yTNEF project should be able to decode it!

not too difficult then :)

Download the coooode...., posted 22 Jan 2005 at 11:43 UTC by lkcl » (Master) - necessary for "outsourcing" the authentication. - contains the IDL compiler and runtime

the bits for doing the exchangey stuff i am experimenting with and so have yet to set up a source repository.

*whistle* fuu fuu fuu tum tee tuummm..., posted 23 Jan 2005 at 00:15 UTC by lkcl » (Master)

oops, where did _these_ come from? ha, pfffh *snort*.

actually in case you _were_ wondering, they're from the DLLs.

the Wine team is in the process of interpreting the "type strings" as part of the interoperability with rpcrt4.dll.

part of rpcrt4.dll's "job" is to turn "type strings" into actual data on-wire, and vice-versa.

well, you see... FreeDCE (from which MSRPC and MIDL are derived) take an IDL file and turn it into intermediate interpreted "byte code" - known to the Wine team as "type strings".

and these "type strings" are one big monster struct in the DLLs, and they contain sufficient information - obviously - to interpret all the structs and all the functions.

... but you never get to know what the function names are nor what the structure names are, because that's been stripped out by the compiler.

... and so, consequently, there's a tool that's been around since oh about 1998 which can "unIDL" these "type strings" back into IDL files - with no function names and no structure names.

here's two "unIDL" files for two critical exchange services - more to follow.

p.s. bloody microsoft, give us the bloody idl files so we don't have to piss about like this.

[ uuid(a4f1db00-ca47-1067-b31f-00dd010662da), version(0.81), implicit_handle(handle_t rpc_binding) ] interface emsmdb { typedef [context_handle] void *emsmdb_hnd_t; typedef [string, ptr] char *emsmdb_str;

long EcDoConnect( [in] handle_t h, [out] emsmdb_hnd_t *hnd, [in, ref, string] char * element_2, [in] long element_3, [in] long element_4, [in] long element_5, [in] long element_6, [in] long element_7, [in] long element_8, [in] long element_9, [in] short element_10, [out, ref] long *element_11, [out, ref] long *element_12, [out, ref] long *element_13, [out, ref] short *element_14, [out, ref] emsmdb_str *element_15, [out, ref] emsmdb_str *element_16, [in] short element_17[6], [out] short element_18[6], [out] short element_19[6], [in,out, ref] long *status_or_something );

long EcDoDisconnect( [in,out] emsmdb_hnd_t *element_21 );

long EcDoRpc( [in,out] emsmdb_hnd_t *element_22, [in,out, size_is(element_24), length_is(*element_25)] char element_23[*], [in,out, ref] short *element_25, [in] short element_24 );

long EcGetMoreRpc( [in,out, context_handle] emsmdb_hnd_t *element_26, [in,out, size_is(element_28), length_is(*element_29)] char element_27[*], [in,out, ref] short *element_29, [in] short element_28 );

long EcRRegisterPushNotification( [in,out, context_handle] emsmdb_hnd_t *element_30, [in] long element_31, [in, size_is(element_33)] char element_32[*], [in] short element_33, [in] long element_34, [in, size_is(element_36)] char element_35[*], [in] short element_36, [out, ref] long *element_37 );

long EcRUnregisterPushNotification( [in,out, context_handle] emsmdb_hnd_t *element_38, [in] long element_39, [in] long element_40 );

long EcDummyRpc( void );

long EcRGetDCName( [in,out, context_handle] emsmdb_hnd_t *element_41, [in, ref, string] char *element_42, [out] char element_43[16] );

long EcRNetGetDCName( [in, ref, string] char *element_44, [out] char element_45[16] );

/* long EcDoRpcExt ( ... ) oops... appears to be missing ... */ }

another one..., posted 23 Jan 2005 at 00:16 UTC by lkcl » (Master)

[ uuid(f5cc5a18-4264-101a-8c59-08002b2f8426), version(56.0), implicit_handle(handle_t rpc_binding) ] interface emsabp { 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; } TYPE_1;

typedef struct { char element_10[16]; } TYPE_2;

long NspiBind( [in] handle_t element_11, [in] long element_12, [in] [ref] TYPE_1 *element_13, [in,out] [unique] TYPE_2 *element_14, [out] [context_handle] void **element_15 );

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

long NspiUpdateStat( [in] [context_handle] void *element_18, [in] long element_19, [in,out] [ref] TYPE_1 *element_20, [in,out] [unique] long *element_21 );

typedef struct { ??? element_22; ??? element_23; long element_24; } TYPE_3;

typedef struct { long element_25; [size_is(element_25)] TYPE_5 element_26[*]; } TYPE_4;

typedef struct { long element_27; long element_28; [size_is(element_28)] [unique] TYPE_6 *element_29; } TYPE_5;

typedef struct { long element_30; long element_31; TYPE_7 element_32; } TYPE_6;

typedef [switch_type(long)] union { [case(2)] short element_33; [case(3)] long element_34; [case(11)] short element_35; [case(30)] [unique] [string] char *element_36; [case(258)] TYPE_8 element_37; [case(31)] [unique] [string] wchar_t *element_38; [case(72)] [unique] TYPE_2 *element_39; [case(64)] TYPE_9 element_40; [case(10)] long element_41; [case(4098)] TYPE_10 element_42; [case(4099)] TYPE_11 element_43; [case(4126)] TYPE_12 element_44; [case(4354)] TYPE_13 element_45; [case(4168)] TYPE_14 element_46; [case(4127)] TYPE_15 element_47; [case(4160)] TYPE_16 element_48; [case(1)] long element_49; [case(13)] long element_50; } TYPE_7;

typedef struct { long element_51; [size_is(element_51)] [unique] char *element_52; } TYPE_8;

typedef struct { long element_53; long element_54; } TYPE_9;

typedef struct { long element_55; [size_is(element_55)] [unique] short *element_56; } TYPE_10;

typedef struct { long element_57; [size_is(element_57)] [unique] long *element_58; } TYPE_11;

typedef struct { long element_59; [size_is(element_59)] [unique] long *element_60; } TYPE_12;

typedef struct { long element_61; [size_is(element_61)] [unique] TYPE_8 *element_62; } TYPE_13;

typedef struct { long element_63; [size_is(element_63)] [unique] long *element_64; } TYPE_14;

typedef struct { long element_65; [size_is(element_65)] [unique] long *element_66; } TYPE_15;

typedef struct { long element_67; [size_is(element_67)] [unique] TYPE_9 *element_68; } TYPE_16;

long NspiQueryRows( [in] [context_handle] void *element_69, [in] long element_70, [in,out] [ref] TYPE_1 *element_71, [in] long element_72, [in] [size_is(element_72)] [unique] long *element_73, [in] long element_74, [in] [unique] TYPE_3 *element_75, [out] [ref] TYPE_4 **element_76 );

long NspiSeekEntries( [in] [context_handle] void *element_77, [in] long element_78, [in,out] [ref] TYPE_1 *element_79, [in] [ref] TYPE_6 *element_80, [in] [unique] TYPE_3 *element_81, [in] [unique] TYPE_3 *element_82, [out] [ref] TYPE_4 **element_83 );

typedef struct { long element_84; TYPE_18 element_85; } TYPE_17;

typedef [switch_type(long)] union { [case(0)] TYPE_19 element_86; [case(1)] TYPE_19 element_87; [case(2)] TYPE_20 element_88; [case(3)] TYPE_21 element_89; [case(4)] TYPE_21 element_90; [case(5)] TYPE_22 element_91; [case(6)] TYPE_22 element_92; [case(9)] TYPE_23 element_93; [case(7)] TYPE_22 element_94; [case(8)] TYPE_22 element_95; } TYPE_18;

typedef struct { long element_96; [size_is(element_96)] [unique] TYPE_17 *element_97; } TYPE_19;

typedef struct { [unique] TYPE_17 *element_98; } TYPE_20;

typedef struct { long element_99; long element_100; [unique] TYPE_6 *element_101; } TYPE_21;

typedef struct { long element_102; long element_103; long element_104; } TYPE_22;

typedef struct { long element_105; [unique] TYPE_17 *element_106; } TYPE_23;

typedef struct { [unique] TYPE_2 *element_107; long element_108; long element_109; } TYPE_24;

long NspiGetMatches( [in] [context_handle] void *element_110, [in] long element_111, [in,out] [ref] TYPE_1 *element_112, [in] [unique] TYPE_3 *element_113, [in] long element_114, [in] [unique] TYPE_17 *element_115, [in] [unique] TYPE_24 *element_116, [in] long element_117, [out] [ref] TYPE_3 **element_118, [in] [unique] TYPE_3 *element_119, [out] [ref] TYPE_4 **element_120 );

long NspiResortRestriction( [in] [context_handle] void *element_121, [in] long element_122, [in,out] [ref] TYPE_1 *element_123, [in] [ref] TYPE_3 *element_124, [in,out] [ref] TYPE_3 **element_125 );

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

long NspiDNToEph( [in] [context_handle] void *element_128, [in] long element_129, [in] [ref] TYPE_25 *element_130, [out] [ref] TYPE_3 **element_131 );

long NspiGetPropList( [in] [context_handle] void *element_132, [in] long element_133, [in] long element_134, [in] long element_135, [out] [ref] TYPE_3 **element_136 );

long NspiGetProps( [in] [context_handle] void *element_137, [in] long element_138, [in] [ref] TYPE_1 *element_139, [in] [unique] TYPE_3 *element_140, [out] [ref] TYPE_5 **element_141 );

long NspiCompareDNTs( [in] [context_handle] void *element_142, [in] long element_143, [in] [ref] TYPE_1 *element_144, [in] long element_145, [in] long element_146, [out] [ref] long *element_147 );

long NspiModProps( [in] [context_handle] void *element_148, [in] long element_149, [in] [ref] TYPE_1 *element_150, [in] [unique] TYPE_3 *element_151, [in] [ref] TYPE_5 *element_152 );

long NspiGetHierarchyInfo( [in] [context_handle] void *element_153, [in] long element_154, [in] [ref] TYPE_1 *element_155, [in,out] [ref] long *element_156, [out] [ref] TYPE_4 **element_157 );

long NspiGetTemplateInfo( [in] [context_handle] void *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] TYPE_5 **element_164 );

long NspiModLInkAtt( [in] [context_handle] void *element_165, [in] long element_166, [in] long element_167, [in] long element_168, [in] [ref] TYPE_13 *element_169 );

long NspiDeleteEntries( [in] [context_handle] void *element_170, [in] long element_171, [in] long element_172, [in] [ref] TYPE_13 *element_173 );

long NspiQueryColumns( [in] [context_handle] void *element_174, [in] long element_175, [in] long element_176, [out] [ref] TYPE_3 **element_177 );

typedef struct { long element_178; [unique] TYPE_2 *element_179; } TYPE_26;

long NspiGetNamesFromIDs( [in] [context_handle] void *element_180, [in] long element_181, [in] [unique] TYPE_2 *element_182, [in] [unique] TYPE_3 *element_183, [out] [ref] TYPE_3 **element_184, [out] [ref] TYPE_26 **element_185 );

long NspiGetIDsFromNames( [in] [context_handle] void *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] TYPE_3 **element_191 );

long NspiResolveNames( [in] [context_handle] void *element_192, [in] long element_193, [in] [ref] TYPE_1 *element_194, [in] [unique] TYPE_3 *element_195, [in] [ref] TYPE_25 *element_196, [out] [ref] TYPE_3 **element_197, [out] [ref] TYPE_4 **element_198 );

typedef struct { long element_199; [unique] [string] wchar_t *element_200; } TYPE_27;

long NspiResolveNamesW( [in] [context_handle] void *element_201, [in] long element_202, [in] [ref] TYPE_1 *element_203, [in] [unique] TYPE_3 *element_204, [in] [ref] TYPE_27 *element_205, [out] [ref] TYPE_3 **element_206, [out] [ref] TYPE_4 **element_207 );


progress, posted 26 Feb 2005 at 00:02 UTC by lkcl » (Master)

i've since identified the structures in the Nspi interface - as MAPI data structures (SRestriction and SRowSet and it goes from there in a multi-layer hierarchical ... MESS basically).

also i've had to start decoding MAPI itself, proxied over the EcDoRpc() functions.

source repository here - see exch5.5 in cvs

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!

Share this page