transmit_as, user_marshal, and automagic LSA_UNICODE_STRING conversion

Michael B Allen mba2000 at
Thu May 11 06:45:36 GMT 2006

Here's a neat trick. No doubt you guys worked out something for this
already but consider the following:

    typedef struct {
        uint16_t length;
        uint16_t maximum_length;
        [length_is(length / 2),size_is(maximum_length / 2)] uint16_t *buffer;
    } unicode_string;

    typedef [xmit_as(unicode_string)] uint8_t *uint8_as_unicode_string;

    typedef struct {
        uint16_t sid_type;
        uint8_as_unicode_string name;
        uint32_t sid_index;
    } lsa_TranslatedName;

With appropriate
uint8_as_unicode_string_{to_xmit,from_xmit,free_xmit,free_inst} functions
you can directly convert between those painful LSA_UNICODE_STRING
blocks and your internal encoding. Meaning you can then access
translated_name->name like a regular char *. That'll simplify things!

I used "xmit_as" instead of "transmit_as" because the DCE version doesn't
support pointers in the xmit type. Does anyone know why that is? When
I implemented this it all Just Worked but I'm wondering if I'm missing
something. You can't use pointers with wire_marshal either. It seems
that under the DCE spec, there's no way to manually marshal anything
that might be broken up due to a deferred location. Meaning the xmit type
must be encoded into one continuous block.

Also, remember when we speculated that transmit_as might be used
for security descriptors and spoolss stuff? It can't because theres
variable width data structures which implies a varrying conformant
array which again, like pointers, is not allowed. MIDL will accept an
embedded conformant varrying array but that would result in 8 bytes of
conformance at the beginning and you don't see that in situ. For
security descriptors and spoolss you must use user_marshal or possibly
wire_marshal. Even though user_marshal uses an xmit type the actual data
encoded doesn't need to follow the xmit type.


More information about the samba-technical mailing list