MIDLC: The MIDL Compatible IDL Compiler

Michael B Allen mba2000 at ioplex.com
Thu Dec 30 00:08:23 GMT 2004


tridge at samba.org said:
> Mike,
>
> > Eventually I have to polish up the C stub emitter for
> > my compiler and try to push that. It handles the odd
> > constructs pretty well and it would be great
> > if we were all using midl compatible IDL.
>
> I agree that PIDL might not be the final solution for Samba, and I
> certainly would be happy to look at using your compiler when it is
> ready. PIDL is a bit too hackish in places, and supporting some of the
> more esoteric midl features is difficult.

Hi Tridge,

I'm glad to hear you're getting more interested in this. I really think it
would be a great decision to use the MIDLC compiler. Currently the C stub
emitter isn't there but I'll look at it ASAP. The only thing holding me
back was your lack of interest.

> I would like to keep the PIDL extensions, however. We have benefitted
> a lot from the builtin string conversion, the auto-generated print
> functions and some of the other additions, so before we switched
> compiler we'd need to add support for those.

Weeell, I don't know much about PIDL extensions so I'll leave those to
you. Note MIDLC does not interpret specific identifiers really so it will
read your custom attributes and types without a problem provided it sticks
to the general syntax. It's up to the "emitter" to actually decide what's
right and what to use from the parse tree. Also, realistically you'll
probably have to use both compilers for a while so ...

> I'd also like to keep the in/out structure interface. That is what
> gives us the ability to pass around generic pull/push functions, as C
> just can't handle variable argument functions being passed as function
> pointers

Of course. Right now the C server stub emitter call-glue is like the below
[1]. The function that generated it is trivial so if it's not what you
want it's very easy to change.

The real heavy lifting in MIDLC is done in two small highly recursive
functions called emit_encoder_fragment and emit_decoder_fragment (which
are largely mirrors of one another). Everything else is child's play by
comparison.

If you're curious to see what a MIDLC C stub actually looks like (so far)
I've attached lsarpc_s.c. You can also download MIDLC at the jcifs website
[2].

Mike

[1] MIDLC C server stub call-glue
int
lsarpc_LsarLookupSids(void *context,
            const unsigned char *src,
            const unsigned char *slim,
            unsigned char *dst,
            unsigned char *dlim)
{
    struct ndr ndr;
    unsigned char *deferred;
    struct params_LsarLookupSids params;

    memset(&ndr, 0, sizeof(ndr));
    deferred = src;
    dec_params_LsarLookupSids(&ndr, ¶ms, &src, &deferred, slim);

    params.retval = LsarLookupSids(context,
            params.handle,
            params.sids,
            params.domains,
            params.names,
            params.level,
            params.count);

    memset(&ndr, 0, sizeof(ndr));
    deferred = dst;
    enc_params_LsarLookupSids(&ndr, ¶ms, &dst, &deferred, dlim);

    return 0;
}

[2] http://jcifs.samba.org/src/midlc-0.5.2.tar.gz
    For C stubs do: $ midlc -v -t c idl/some.idl
-------------- next part --------------
int
enc_LsaQosInfo(struct ndr *ndr,
			LsaQosInfo *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_long(ndr, obj->length, dst, dlim);
    enc_ndr_short(ndr, obj->impersonation_level, dst, dlim);
    enc_ndr_small(ndr, obj->context_mode, dst, dlim);
    enc_ndr_small(ndr, obj->effective_only, dst, dlim);

    return 0;
}
int
enc_LsaObjectAttributes(struct ndr *ndr,
			LsaObjectAttributes *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_long(ndr, obj->length, dst, dlim);
    enc_ndr_referent(ndr, obj->root_directory, 1, dst, dlim);
    enc_ndr_referent(ndr, obj->object_name, 1, dst, dlim);
    enc_ndr_long(ndr, obj->attributes, dst, dlim);
    enc_ndr_long(ndr, obj->security_descriptor, dst, dlim);
    enc_ndr_referent(ndr, obj->security_quality_of_service, 1, dst, dlim);

    if (obj->root_directory) {
        dst = deferred;
        enc_ndr_small(ndr, *obj->root_directory, dst, dlim);
    }
    if (obj->object_name) {
        dst = deferred;
        enc_unicode_string(ndr, obj->object_name, dst, deferred, dlim);
    }
    if (obj->security_quality_of_service) {
        dst = deferred;
        enc_LsaQosInfo(ndr, obj->security_quality_of_service, dst, deferred, dlim);
    }
    return 0;
}
int
enc_LsaDomainInfo(struct ndr *ndr,
			LsaDomainInfo *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_unicode_string(ndr, obj->name, dst, deferred, dlim);
    enc_ndr_referent(ndr, obj->sid, 1, dst, dlim);

    if (obj->sid) {
        dst = deferred;
        enc_sid_t(ndr, obj->sid, dst, deferred, dlim);
    }
    return 0;
}
int
enc_lsa_SidPtr(struct ndr *ndr,
			lsa_SidPtr *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_referent(ndr, obj->sid, 1, dst, dlim);

    if (obj->sid) {
        dst = deferred;
        enc_sid_t(ndr, obj->sid, dst, deferred, dlim);
    }
    return 0;
}
int
enc_lsa_SidArray(struct ndr *ndr,
			lsa_SidArray *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_long(ndr, obj->num_sids, dst, dlim);
    enc_ndr_referent(ndr, obj->sids, 1, dst, dlim);

    if (obj->sids) {
        dst = deferred;
        int _sidss = obj->num_sids;
        enc_ndr_long(ndr, _sidss, dst, dlim);
        unsigned char *_sidsi = *dst;
        *dst += 4 * _sidss;

        dst = &_sidsi;
        for (int _i = 0; _i < _sidss; _i++) {
            enc_lsa_SidPtr(ndr, obj->sids + _i, dst, deferred, dlim);
        }
    }
    return 0;
}
int
enc_lsa_TrustInformation(struct ndr *ndr,
			lsa_TrustInformation *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_unicode_string(ndr, obj->name, dst, deferred, dlim);
    enc_ndr_referent(ndr, obj->sid, 1, dst, dlim);

    if (obj->sid) {
        dst = deferred;
        enc_sid_t(ndr, obj->sid, dst, deferred, dlim);
    }
    return 0;
}
int
enc_lsa_RefDomainList(struct ndr *ndr,
			lsa_RefDomainList *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_long(ndr, obj->count, dst, dlim);
    enc_ndr_referent(ndr, obj->domains, 1, dst, dlim);
    enc_ndr_long(ndr, obj->max_count, dst, dlim);

    if (obj->domains) {
        dst = deferred;
        int _domainss = obj->count;
        enc_ndr_long(ndr, _domainss, dst, dlim);
        unsigned char *_domainsi = *dst;
        *dst += 12 * _domainss;

        dst = &_domainsi;
        for (int _i = 0; _i < _domainss; _i++) {
            enc_lsa_TrustInformation(ndr, obj->domains + _i, dst, deferred, dlim);
        }
    }
    return 0;
}
int
enc_lsa_TranslatedName(struct ndr *ndr,
			lsa_TranslatedName *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_short(ndr, obj->sid_type, dst, dlim);
    enc_unicode_string(ndr, obj->name, dst, deferred, dlim);
    enc_ndr_long(ndr, obj->sid_index, dst, dlim);

    return 0;
}
int
enc_lsa_TransNameArray(struct ndr *ndr,
			lsa_TransNameArray *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_long(ndr, obj->count, dst, dlim);
    enc_ndr_referent(ndr, obj->names, 1, dst, dlim);

    if (obj->names) {
        dst = deferred;
        int _namess = obj->count;
        enc_ndr_long(ndr, _namess, dst, dlim);
        unsigned char *_namesi = *dst;
        *dst += 16 * _namess;

        dst = &_namesi;
        for (int _i = 0; _i < _namess; _i++) {
            enc_lsa_TranslatedName(ndr, obj->names + _i, dst, deferred, dlim);
        }
    }
    return 0;
}
int
enc_params_LsarClose(struct ndr *ndr,
			struct params_LsarClose *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    if (obj->handle) {
        dst = deferred;
        enc_policy_handle(ndr, obj->handle, dst, deferred, dlim);
    }
    return 0;
}
int
lsarpc_LsarClose(void *context,
			const unsigned char *src,
			const unsigned char *slim,
			unsigned char *dst,
			unsigned char *dlim)
{
    struct ndr ndr;
    unsigned char *deferred;
    struct params_LsarClose params;

    memset(&ndr, 0, sizeof(ndr));
    deferred = src;
    dec_params_LsarClose(&ndr, &params, &src, &deferred, slim);

    params.retval = LsarClose(context, params.handle);

    memset(&ndr, 0, sizeof(ndr));
    deferred = dst;
    enc_params_LsarClose(&ndr, &params, &dst, &deferred, dlim);

    return 0;
}
int
enc_params_LsarQueryInformationPolicy(struct ndr *ndr,
			struct params_LsarQueryInformationPolicy *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_referent(ndr, obj->info, 1, dst, dlim);
    if (obj->info) {
        dst = deferred;
        int _descr = obj->level;
        enc_ndr_long(ndr, _descr, dst, dlim);
        if (obj->info == NULL) {
            enc_ndr_referent(ndr, obj->info, 1, dst, dlim);
        } else {
            switch (_descr) {
                case POLICY_INFO_ACCOUNT_DOMAIN:
                    enc_LsaDomainInfo(ndr, obj->info, dst, deferred, dlim);
                    break;
            };
        }
    }
    return 0;
}
int
lsarpc_LsarQueryInformationPolicy(void *context,
			const unsigned char *src,
			const unsigned char *slim,
			unsigned char *dst,
			unsigned char *dlim)
{
    struct ndr ndr;
    unsigned char *deferred;
    struct params_LsarQueryInformationPolicy params;

    memset(&ndr, 0, sizeof(ndr));
    deferred = src;
    dec_params_LsarQueryInformationPolicy(&ndr, &params, &src, &deferred, slim);

    params.retval = LsarQueryInformationPolicy(context,
            params.handle,
            params.level,
            params.info);

    memset(&ndr, 0, sizeof(ndr));
    deferred = dst;
    enc_params_LsarQueryInformationPolicy(&ndr, &params, &dst, &deferred, dlim);

    return 0;
}
int
enc_params_LsarLookupSids(struct ndr *ndr,
			struct params_LsarLookupSids *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    enc_ndr_referent(ndr, obj->domains, 1, dst, dlim);
    if (obj->domains) {
        dst = deferred;
        enc_lsa_RefDomainList(ndr, obj->domains, dst, deferred, dlim);
    }
    if (obj->names) {
        dst = deferred;
        enc_lsa_TransNameArray(ndr, obj->names, dst, deferred, dlim);
    }
    if (obj->count) {
        dst = deferred;
        enc_ndr_long(ndr, *obj->count, dst, dlim);
    }
    return 0;
}
int
lsarpc_LsarLookupSids(void *context,
			const unsigned char *src,
			const unsigned char *slim,
			unsigned char *dst,
			unsigned char *dlim)
{
    struct ndr ndr;
    unsigned char *deferred;
    struct params_LsarLookupSids params;

    memset(&ndr, 0, sizeof(ndr));
    deferred = src;
    dec_params_LsarLookupSids(&ndr, &params, &src, &deferred, slim);

    params.retval = LsarLookupSids(context,
            params.handle,
            params.sids,
            params.domains,
            params.names,
            params.level,
            params.count);

    memset(&ndr, 0, sizeof(ndr));
    deferred = dst;
    enc_params_LsarLookupSids(&ndr, &params, &dst, &deferred, dlim);

    return 0;
}
int
enc_params_LsarOpenPolicy(struct ndr *ndr,
			struct params_LsarOpenPolicy *obj
			unsigned char **dst,
			unsigned char **deferred,
			unsigned char *dlim)
{
    if (obj->policy_handle) {
        dst = deferred;
        enc_policy_handle(ndr, obj->policy_handle, dst, deferred, dlim);
    }
    return 0;
}
int
lsarpc_LsarOpenPolicy(void *context,
			const unsigned char *src,
			const unsigned char *slim,
			unsigned char *dst,
			unsigned char *dlim)
{
    struct ndr ndr;
    unsigned char *deferred;
    struct params_LsarOpenPolicy params;

    memset(&ndr, 0, sizeof(ndr));
    deferred = src;
    dec_params_LsarOpenPolicy(&ndr, &params, &src, &deferred, slim);

    params.retval = LsarOpenPolicy(context,
            params.system_name,
            params.object_attributes,
            params.desired_access,
            params.policy_handle);

    memset(&ndr, 0, sizeof(ndr));
    deferred = dst;
    enc_params_LsarOpenPolicy(&ndr, &params, &dst, &deferred, dlim);

    return 0;
}


More information about the samba-technical mailing list