MIDLC IDL Compiler

Andrew Tridgell tridge at osdl.org
Sat Jan 15 07:06:17 GMT 2005


Mike,

 > To fix the problem I can replace 'unsigned char **dst, unsigned char
 > **deferred, unsigned char *dlim' with a buf_t structure something like:
 > 
 >   typedef struct {
 >       unsigned char *data;
 >       unsigned char *dst;
 >       unsigned char *deferred;
 >       unsigned char *dlim;
 >   } buf_t;

that's certainly much better. The equivalent structure in the Samba4
NDR library is this:

 struct ndr_push {
	uint32_t flags; /* LIBNDR_FLAG_* */
	uint8_t *data;
	uint32_t alloc_size;
	uint32_t offset;

	struct ndr_token_list *relative_list;

	/* this is used to ensure we generate unique reference IDs */
	uint32_t ptr_count;
 };

I should point out why I chose this layout.

First off, you need 'flags' there to cope with quite a number of our
NDR extensions. For example, LIBNDR_FLAG_NOALIGN allows us to encode
the basic dcerpc PDU frames as IDL. That makes things much neater. We
also encode all of the epmapper stuff as extended IDL, which again
makes things much simpler. The designers of dce/rpc really should have
chosen a NDR compatible format for these things in the first place,
but we are stuck with it now, so we might as well make the best of it
by extending IDL and NDR to cope.

We also put the LIBNDR_FLAG_BIGENDIAN flag there, so that this layer
can know the PDU chosen machine encoding flags without having to be
tied to the dce/rpc layer. Another useful flag is
LIBNDR_FLAG_PAD_CHECK, which tells the NDR layer to do strict checking
of pad bytes to ensure they were zero. This allows us to find bugs,
and also tell when we think something is padding but the windows IDL
disagrees.

Next, notice we have an 'alloc_size', this allows us to easily
overallocate the buffer to save on realloc calls. It is the equivalent
of your 'dlim' pointer. 

The 'offset' field is like your 'dst' field, but its an offset
relative to the base data pointer, so it doesn't need to be updated
after a realloc, which arguably makes it less error prone.

The 'relative_list' is needed to support relative pointers, which are
a very useful pidl extension used in spoolss and for
security_descriptors. I like the fact that we can encode just about 

The 'ptr_count' is used to cope with full NDR pointers, mostly so that
ethereal doesn't choke on them (it wants them to increment in the
exact way given in the spec, tho it seems that Microsofts NDR layer
doesn't care).

What strategy do you plan to use for big/little endian? I chose quite
a different method to MIDL, and each has its advantages. 

Cheers, Tridge


More information about the samba-technical mailing list