midl types ---------- pidl uses slightly different types to midl by default. The following defines in your MS IDL may make things easier to use the same IDL on both platforms. #define unistr [string] wchar_t * #define uint8 char #define uint16 short #define uint32 long #define HYPER_T hyper Let's look at the mutliple ways you can encode an array. CONFORMANT ARRAYS ----------------- A conformant array is one with that ends in [*] or []. The strange things about conformant arrays are: * they can only appear as the last element of a structure * the array size appears before the structure itself on the wire. So, in this example: typedef struct { long abc; long count; long foo; [size_is(count)] long s[*]; } Struct1; it appears like this: [size_is] [abc] [count] [foo] [s...] the first [size_is] field is the allocation size of the array, and occurs before the array elements and even before the structure alignment. Note that size_is() can refer to a constant, but that doesn't change the wire representation. It does not make the array a fixed array. midl.exe would write the above array as the following C header: typedef struct { long abc; long count; long foo; long s[1]; } Struct1; pidl takes a different approach, and writes it like this: typedef struct { long abc; long count; long foo; long *s; } Struct1; VARYING ARRAYS -------------- A varying array looks like this: typedef struct { long abc; long count; long foo; [size_is(count)] long *s; } Struct1; This will look like this on the wire: [abc] [count] [foo] [PTR_s] [count] [s...] FIXED ARRAYS ------------ A fixed array looks like this: typedef struct { long s[10]; } Struct1; The NDR representation looks just like 10 separate long declarations. The array size is not encoded on the wire. pidl also supports "inline" arrays, which are not part of the IDL/NDR standard. These are declared like this: typedef struct { uint32 foo; uint32 count; uint32 bar; long s[count]; } Struct1; This appears like this: [foo] [count] [bar] [s...] Fixed arrays are an extension added to support some of the strange embedded structures in security descriptors and spoolss. Supported MIDL-compatible properties (attributes is the MIDL term) ------------------------------------ in out ref public length_is switch_is size_is uuid case default string unique PIDL Specific properties --------------- noprint value relative subcontext flag Unsupported MIDL properties --------------------------- aggregatable appobject async_uuid bindable call_as coclass control cpp_quote defaultbind defaultcollelem defaultvalue defaultvtable dispinterface displaybind dual entry first_is helpcontext helpfile helpstringcontext helpstringdll helpstring hidden idl_module idl_quote id iid_is immediatebind importlib import include includelib last_is lcid licensed local max_is module ms_union no_injected_text nonbrowsable noncreatable nonextensible object odl oleautomation optional pointer_default pragma progid propget propputref propput ptr range readonly requestedit restricted retval source switch_type transmit_as uidefault usesgetlasterror v1_enum vararg vi_progid wire_marshal [public] property ----------------- The [public] property on a structure or union is a pidl extension that forces the generated pull/push functions to be non-static. This allows you to declare types that can be used between modules. If you don't specify [public] then pull/push functions for other than top-level functions are declared static. [relative] property ------------------- The [relative] property can be supplied on a pointer. When it is used it declares the pointer as a spoolss style "relative" pointer, which means it appears on the wire as an offset within the current encapsulating structure. This is not part of normal IDL/NDR, but it is a very useful extension as it avoids the manual encoding of many complex structures. [noprint] property ------------------ The [noprint] property is a pidl extension that allows you to specify that pidl should not generate a ndr_print_*() function for that structure or union. This is used when you wish to define your own print function that prints a structure in a nicer manner. A good example is the use of [noprint] on dom_sid, which allows the pretty-printing of SIDs. [value] property ---------------- The [value(expression)] property is a pidl extension that allows you to specify the value of a field when it is put on the wire. This allows fields that always have a well-known value to be automatically filled in, thus making the API more programmer friendly. The expression can be any C expression, although if you refer to variables in the current structure you will need to dereference them with r->. See samr_Name as a good example. [nodiscriminant] property ------------------------- The [nodiscriminant] property on a union means that the usual uint16 discriminent field at the start of the union on the wire is omitted. This is not normally allowed in IDL/NDR, but is used for some spoolss structures. VALIDATOR --------- We need to write an IDL validator, so we know that we are writing valid IDL. Right now the compiler sails on regardless in many cases even if the IDL is invalid (for example, I don't check that conformant arrays are always the last element in any structure). There are dozens of rules that should be checked.