From b2e95101db1104ed22039be6e441f941c7c56df5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 6 Jun 2004 10:25:54 +0000 Subject: r1045: Wow - we actually compile (but not link) the autogenerated parser from samr. The array handling is a bit of a mess though. (This used to be commit 7ff7737832e0e5877ce8bcf329a123a2bce05370) --- source4/build/pidl/eparser.pm | 122 ++++++++++++++++++++--------- source4/build/pidl/packet-dcerpc-eparser.c | 43 ++++++++++ source4/build/pidl/packet-dcerpc-eparser.h | 43 +++++++++- 3 files changed, 170 insertions(+), 38 deletions(-) (limited to 'source4/build') diff --git a/source4/build/pidl/eparser.pm b/source4/build/pidl/eparser.pm index 20ac74f23f..9c96d63852 100644 --- a/source4/build/pidl/eparser.pm +++ b/source4/build/pidl/eparser.pm @@ -232,13 +232,14 @@ sub ParseArrayPull($$$) my $size = find_size_var($e, util::array_size($e), $var_prefix); my $alloc_size = $size; + pidl "\t{ guint32 _array_size;\n"; # if this is a conformant array then we use that size to allocate, and make sure # we allocate enough to pull the elements if (defined $e->{CONFORMANT_SIZE}) { $alloc_size = $e->{CONFORMANT_SIZE}; pidl "\tif ($size > $alloc_size) {\n"; - pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_CONFORMANT_SIZE, \"Bad conformant size %u should be %u\", $alloc_size, $size);\n"; + pidl "\t\treturn ndr_pull_error(ndr, \"Bad conformant size %u should be %u\", $alloc_size, $size);\n"; pidl "\t}\n"; } elsif (!util::is_inline_array($e)) { if ($var_prefix =~ /^r->out/ && $size =~ /^\*r->in/) { @@ -248,15 +249,14 @@ sub ParseArrayPull($$$) # non fixed arrays encode the size just before the array pidl "\t{\n"; - pidl "\t\tguint32 _array_size;\n"; - pidl "\t\tndr_pull_uint32(ndr, &_array_size);\n"; + pidl "\t\tdissect_ndr_uint32(ndr->tvb, ndr->offset, ndr->pinfo, ndr->tree, ndr->drep, hf_array_size, &_array_size);\n"; if ($size =~ /r->in/) { - pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _array_size != $size) {\n"; + pidl "\t\t// if (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _array_size != $size) {\n"; } else { - pidl "\t\tif ($size != _array_size) {\n"; + pidl "\t\t// if ($size != _array_size) {\n"; } - pidl "\t\t\treturn ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, \"Bad array size %u should be %u\", _array_size, $size);\n"; - pidl "\t\t}\n"; + pidl "\t\t\t// return ndr_pull_error(ndr, \"Bad array size %u should be %u\", _array_size, $size);\n"; + pidl "\t\t// }\n"; if ($size =~ /r->in/) { pidl "else { $size = _array_size; }\n"; } @@ -285,18 +285,19 @@ sub ParseArrayPull($$$) pidl "\t\tguint32 _offset, _length;\n"; pidl "\t\tndr_pull_uint32(ndr, &_offset);\n"; pidl "\t\tndr_pull_uint32(ndr, &_length);\n"; - pidl "\t\tif (_offset != 0) return ndr_pull_error(ndr, NDR_ERR_OFFSET, \"Bad array offset 0x%08x\", _offset);\n"; - pidl "\t\tif (_length > $size || _length != $length) return ndr_pull_error(ndr, NDR_ERR_LENGTH, \"Bad array length 0x%08x > size 0x%08x\", _offset, $size);\n\n"; + pidl "\t\tif (_offset != 0) return ndr_pull_error(ndr, \"Bad array offset 0x%08x\", _offset);\n"; + pidl "\t\t//if (_length > $size || _length != $length) return ndr_pull_error(ndr, \"Bad array length 0x%08x > size 0x%08x\", _offset, $size);\n\n"; $size = "_length"; } if (util::is_scalar_type($e->{TYPE})) { - pidl "\t\tndr_pull_array_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}, $size);\n"; + pidl "\t\tndr_pull_array_$e->{TYPE}(ndr, $ndr_flags, _array_size);\n"; } else { - pidl "\t\tndr_pull_array(ndr, $ndr_flags, (void **)$var_prefix$e->{NAME}, sizeof($var_prefix$e->{NAME}\[0]), $size, (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE});\n"; + pidl "\t\tndr_pull_array(ndr, $ndr_flags, /* sizeof($var_prefix$e->{NAME}\[0]), */ _array_size, ndr_pull_$e->{TYPE});\n"; } pidl "\t}\n"; + pidl "\t}\n"; } @@ -316,26 +317,26 @@ sub ParseElementPullSwitch($$$$) if (!defined $utype || !util::has_property($utype->{DATA}, "nodiscriminant")) { my $e2 = find_sibling($e, $switch); + pidl "\t g$e2->{TYPE} _level;\n"; pidl "\tif (($ndr_flags) & NDR_SCALARS) {\n"; - pidl "\t\t $e2->{TYPE} _level;\n"; pidl "\t\tndr_pull_$e2->{TYPE}(ndr, &_level);\n"; if ($switch_var =~ /r->in/) { - pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _level != $switch_var) {\n"; + pidl "\t\t // if (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _level != $switch_var) {\n"; } else { - pidl "\t\tif (_level != $switch_var) {\n"; + pidl "\t\t // if (_level != $switch_var) {\n"; } - pidl "\t\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u in $e->{NAME}\");\t\t}\n"; + pidl "\t\t\t // return ndr_pull_error(ndr, \"Bad switch value %u in $e->{NAME}\");\t\t}\n"; if ($switch_var =~ /r->/) { - pidl "else { $switch_var = _level; }\n"; + pidl "// else { $switch_var = _level;\n }\n"; } - pidl "\t}\n"; + pidl "\t// }\n"; } my $sub_size = util::has_property($e, "subcontext"); if (defined $sub_size) { pidl "\tndr_pull_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE});\n"; } else { - pidl "\tndr_pull_$e->{TYPE}(ndr, $ndr_flags, $switch_var);\n"; + pidl "\tndr_pull_$e->{TYPE}(ndr, $ndr_flags, _level);\n"; } @@ -420,9 +421,9 @@ sub ParseElementPullBuffer($$$) } elsif (defined $sub_size) { if ($e->{POINTERS}) { if (util::is_builtin_type($e->{TYPE})) { - pidl "\tndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_fn(ndr, $sub_size, _pull_$e->{TYPE});\n"; } else { - pidl "\tndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE});\n"; + pidl "\tndr_pull_subcontext_flags_fn(ndr, $sub_size, ndr_pull_$e->{TYPE});\n"; } } } elsif (util::is_builtin_type($e->{TYPE})) { @@ -496,7 +497,7 @@ sub ParseStructPull($) pidl "\tndr_pull_struct_end(ndr);\n"; - pidl "done:\n"; + pidl "done: ;\n"; end_flags($struct); } @@ -536,7 +537,7 @@ sub ParseUnionPull($) } if (! $have_default) { pidl "\tdefault:\n"; - pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n"; + pidl "\t\t// return ndr_pull_error(ndr, \"Bad switch value \%u\", level);\n"; } pidl "\t}\n"; pidl "buffers:\n"; @@ -555,7 +556,7 @@ sub ParseUnionPull($) } if (! $have_default) { pidl "\tdefault:\n"; - pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n"; + pidl "\t\t// return ndr_pull_error(ndr, \"Bad switch value \%u\", level);\n"; } pidl "\t}\n"; pidl "\tndr_pull_struct_end(ndr);\n"; @@ -563,6 +564,27 @@ sub ParseUnionPull($) end_flags($e); } +##################################################################### +# parse a enum - pull side +sub ParseEnumPull($) +{ + my $e = shift; + + my $name; + my $ndx = 0; + + for my $x (@{$e->{ELEMENTS}}) { + if ($x =~ /([a-zA-Z_]+)=([0-9]+)/) { + $name = $1; + $ndx = $2; + } else { + $name = $x; + } + pidl "#define $name $ndx\n"; + $ndx++; + } +} + ##################################################################### # parse a type sub ParseTypePull($) @@ -574,6 +596,8 @@ sub ParseTypePull($) ParseStructPull($data); ($data->{TYPE} eq "UNION") && ParseUnionPull($data); + ($data->{TYPE} eq "ENUM") && + ParseEnumPull($data); } } @@ -594,20 +618,21 @@ sub ParseTypedefPull($) pidl "*/\n\n"; if ($e->{DATA}->{TYPE} eq "STRUCT") { - pidl $static . "void dissect_$e->{NAME}(struct e_ndr_pull *ndr, int ndr_flags)"; + pidl $static . "void ndr_pull_$e->{NAME}(struct e_ndr_pull *ndr, int ndr_flags)"; pidl "\n{\n"; ParseTypePull($e->{DATA}); pidl "}\n\n"; } if ($e->{DATA}->{TYPE} eq "UNION") { - pidl $static . "void dissect_$e->{NAME}(struct e_ndr_pull *ndr, int ndr_flags, guint16 level)"; + pidl $static . "void ndr_pull_$e->{NAME}(struct e_ndr_pull *ndr, int ndr_flags, int level)"; pidl "\n{\n"; ParseTypePull($e->{DATA}); pidl "}\n\n"; } if ($e->{DATA}->{TYPE} eq "ENUM") { + ParseEnumPull($e->{DATA}); } } @@ -792,8 +817,6 @@ sub type2base($) sub NeededFunction($) { my $fn = shift; - $needed{"pull_$fn->{NAME}"} = 1; - $needed{"push_$fn->{NAME}"} = 1; foreach my $e (@{$fn->{DATA}}) { $needed{"hf_$e->{NAME}_$e->{TYPE}"} = { 'name' => $e->{NAME}, @@ -801,40 +824,48 @@ sub NeededFunction($) 'ft' => type2ft($e->{TYPE}), 'base' => type2base($e->{TYPE}) }; + $needed{"proto_$e->{TYPE}"} = 1, + if !util::is_builtin_type($e->{TYPE}); $e->{PARENT} = $fn; - $needed{"pull_$e->{TYPE}"} = 1; - $needed{"push_$e->{TYPE}"} = 1; } } sub NeededTypedef($) { my $t = shift; + if (util::has_property($t->{DATA}, "public")) { $needed{"pull_$t->{NAME}"} = 1; - $needed{"push_$t->{NAME}"} = 1; } + if ($t->{DATA}->{TYPE} eq "STRUCT") { for my $e (@{$t->{DATA}->{ELEMENTS}}) { + + $needed{"hf_$e->{NAME}_$e->{TYPE}"} = { + 'name' => $e->{NAME}, + 'type' => $e->{TYPE}, + 'ft' => type2ft($e->{TYPE}), + 'base' => type2base($e->{TYPE}) + }; + + $needed{"proto_$e->{TYPE}"} = 1, + if !util::is_builtin_type($e->{TYPE}); + $e->{PARENT} = $t->{DATA}; if ($needed{"pull_$t->{NAME}"}) { $needed{"pull_$e->{TYPE}"} = 1; } - if ($needed{"push_$t->{NAME}"}) { - $needed{"push_$e->{TYPE}"} = 1; - } } } if ($t->{DATA}->{TYPE} eq "UNION") { + $needed{"proto_$t->{NAME}"} = "union"; for my $e (@{$t->{DATA}->{DATA}}) { $e->{PARENT} = $t->{DATA}; if ($e->{TYPE} eq "UNION_ELEMENT") { + $needed{"proto_$e->{DATA}->{TYPE}"} = 1; if ($needed{"pull_$t->{NAME}"}) { $needed{"pull_$e->{DATA}->{TYPE}"} = 1; } - if ($needed{"push_$t->{NAME}"}) { - $needed{"push_$e->{DATA}->{TYPE}"} = 1; - } } } } @@ -894,6 +925,7 @@ sub Parse($$) pidl "static int hf_opnum = -1;\n"; pidl "static int hf_rc = -1;\n"; pidl "static int hf_ptr = -1;\n"; + pidl "static int hf_array_size = -1;\n"; pidl "static int hf_policy_handle = -1;\n"; foreach my $x (@{$idl}) { @@ -903,11 +935,26 @@ sub Parse($$) if ($x->{TYPE} eq "INTERFACE") { BuildNeeded($x); + # Declarations for hf variables + foreach my $y (keys(%needed)) { pidl "static int $y = -1;\n", if $y =~ /^hf_/; } - ParseInterface($x); + # Function prototypes + + foreach my $x (keys(%needed)) { + next, if !($x =~ /^proto_/); + my $name = $x; + $name =~ s/^proto_//; + pidl "void ndr_pull_$name(struct e_ndr_pull *ndr, int ndr_flags"; + + pidl ", int level", if $needed{$x} eq "union"; + + pidl ");\n"; + } + + ParseInterface($x); } } @@ -935,6 +982,7 @@ sub Parse($$) pidl "\t{ &hf_opnum, { \"Operation\", \"$module.opnum\", FT_UINT16, BASE_DEC, NULL, 0x0, \"Operation\", HFILL }},\n"; pidl "\t{ &hf_policy_handle, { \"Policy handle\", \"$module.policy\", FT_BYTES, BASE_NONE, NULL, 0x0, \"Policy handle\", HFILL }},\n"; pidl "\t{ &hf_rc, { \"Return code\", \"$module.rc\", FT_UINT32, BASE_HEX, VALS(NT_errors), 0x0, \"Return status code\", HFILL }},\n"; + pidl "\t{ &hf_array_size, { \"Operation\", \"$module.array_size\", FT_UINT32, BASE_DEC, NULL, 0x0, \"Array size\", HFILL }},\n"; pidl "\t{ &hf_ptr, { \"Pointer\", \"$module.ptr\", FT_UINT32, BASE_HEX, NULL, 0x0, \"Pointer\", HFILL }},\n"; foreach my $x (keys(%needed)) { diff --git a/source4/build/pidl/packet-dcerpc-eparser.c b/source4/build/pidl/packet-dcerpc-eparser.c index bafdf34006..f7cf575932 100644 --- a/source4/build/pidl/packet-dcerpc-eparser.c +++ b/source4/build/pidl/packet-dcerpc-eparser.c @@ -65,3 +65,46 @@ void ndr_pull_policy_handle(struct e_ndr_pull *e_ndr, int hf) e_ndr->tvb, e_ndr->offset, e_ndr->pinfo, e_ndr->tree, e_ndr->drep, hf, NULL, NULL, 0, 0); } + +void ndr_pull_advance(struct e_ndr_pull *ndr, int offset) +{ + e_ndr->offset += offset; +} + +void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, size_t sub_size, + void *base, + void (*fn)(struct e_ndr_pull *, + int ndr_flags)) +{ + struct e_ndr_pull ndr2; + + ndr_pull_subcontext_header(ndr, sub_size, &ndr2); + fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, base); + if (sub_size) { + ndr_pull_advance(ndr, ndr2.data_size); + } else { + ndr_pull_advance(ndr, ndr2.offset); + } +} + +/* + mark the start of a structure +*/ +void ndr_pull_struct_start(struct e_ndr_pull *ndr) +{ + struct ndr_ofs_list *ofs; + ofs = g_malloc(sizeof(*ofs)); + ofs->offset = ndr->offset; + ofs->next = ndr->ofs_list; + ndr->ofs_list = ofs; +} + +/* + mark the end of a structure +*/ +void ndr_pull_struct_end(struct e_ndr_pull *ndr) +{ + struct ndr_ofs_list *ofs = ndr->ofs_list->next; + g_free(ndr->ofs_list); + ndr->ofs_list = ofs; +} diff --git a/source4/build/pidl/packet-dcerpc-eparser.h b/source4/build/pidl/packet-dcerpc-eparser.h index 0d181c9c8a..598ae9b08e 100644 --- a/source4/build/pidl/packet-dcerpc-eparser.h +++ b/source4/build/pidl/packet-dcerpc-eparser.h @@ -1,6 +1,31 @@ #define NDR_SCALARS 1 #define NDR_BUFFERS 2 +#define LIBNDR_FLAG_BIGENDIAN (1<<0) +#define LIBNDR_FLAG_NOALIGN (1<<1) + +#define LIBNDR_FLAG_STR_ASCII (1<<2) +#define LIBNDR_FLAG_STR_LEN4 (1<<3) +#define LIBNDR_FLAG_STR_SIZE4 (1<<4) +#define LIBNDR_FLAG_STR_NOTERM (1<<5) +#define LIBNDR_FLAG_STR_NULLTERM (1<<6) +#define LIBNDR_FLAG_STR_SIZE2 (1<<7) +#define LIBNDR_STRING_FLAGS (0xFC) + +#define LIBNDR_FLAG_REF_ALLOC (1<<10) +#define LIBNDR_FLAG_REMAINING (1<<11) +#define LIBNDR_FLAG_ALIGN2 (1<<12) +#define LIBNDR_FLAG_ALIGN4 (1<<13) +#define LIBNDR_FLAG_ALIGN8 (1<<14) + +#define LIBNDR_ALIGN_FLAGS (LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8) + +#define LIBNDR_PRINT_ARRAY_HEX (1<<15) +#define LIBNDR_PRINT_SET_VALUES (1<<16) + +/* used to force a section of IDL to be little-endian */ +#define LIBNDR_FLAG_LITTLE_ENDIAN (1<<17) + /* Ethereal version of struct ndr_pull */ struct e_ndr_pull { @@ -9,6 +34,15 @@ struct e_ndr_pull { packet_info *pinfo; proto_tree *tree; guint8 *drep; + struct ndr_ofs_list *ofs_list; + int flags; +}; + +/* offset lists are used to allow a push/pull function to find the + start of an encapsulating structure */ +struct ndr_ofs_list { + guint32 offset; + struct ndr_ofs_list *next; }; /* Create a ndr_pull structure from data stored in a tvb at a given offset. */ @@ -20,4 +54,11 @@ void ndr_pull_ptr(struct e_ndr_pull *ndr, int hf, guint32 *ptr); void ndr_pull_NTSTATUS(struct e_ndr_pull *ndr, int hf); void ndr_pull_uint16(struct e_ndr_pull *ndr, int hf); void ndr_pull_uint32(struct e_ndr_pull *ndr, int hf); -void ndr_pull_policy_handle(struct e_ndr_pull *e_ndr, int hf); +void ndr_pull_policy_handle(struct e_ndr_pull *ndr, int hf); +void ndr_pull_advance(struct e_ndr_pull *ndr, int offset); +void ndr_pull_subcontext_flags_fn(struct e_ndr_pull *ndr, size_t sub_size, + void (*fn)(struct e_ndr_pull *, + int ndr_flags)); +void ndr_pull_struct_start(struct e_ndr_pull *ndr); +void ndr_pull_struct_end(struct e_ndr_pull *ndr); +void ndr_pull_align(struct e_ndr_pull *ndr, int size); -- cgit