summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2004-10-15 09:22:21 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:59:55 -0500
commitfe15b46d61ee50f4225458faf963c818cde3e283 (patch)
tree379b76701f6b9b20341953eae9f344c397ee7008
parent42c810cea660f59cae8c30b12a5419450e923a2b (diff)
downloadsamba-fe15b46d61ee50f4225458faf963c818cde3e283.tar.gz
samba-fe15b46d61ee50f4225458faf963c818cde3e283.tar.bz2
samba-fe15b46d61ee50f4225458faf963c818cde3e283.zip
r2990: Add support to pidl for autogenerating ndr_size_*() functions. Adding
the [gensize] property to a struct or union will make pidl generate a ndr_size_*() function. (not all nasty bits of NDR are completely covered yet by the ndr_size*() functions, support for those will be added when necessary) I also have a local patch (not applied now) that simplifies the pidl output and eliminates the number of functions required. It would, however, make pidl more complex. (This used to be commit 7c823f886afd0c4c6ee838f17882ca0658417011)
-rw-r--r--source4/build/pidl/parser.pm130
-rw-r--r--source4/librpc/idl/epmapper.idl4
-rw-r--r--source4/librpc/ndr/libndr.h5
-rw-r--r--source4/librpc/ndr/ndr_basic.c12
-rw-r--r--source4/librpc/rpc/dcerpc_util.c52
5 files changed, 148 insertions, 55 deletions
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index bbebe50cac..7d7ee7a163 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -2,6 +2,7 @@
# Samba4 parser generator for IDL structures
# Copyright tridge@samba.org 2000-2003
# Copyright tpot@samba.org 2001
+# Copyright jelmer@samba.org 2004
# released under the GNU GPL
package IdlParser;
@@ -830,6 +831,65 @@ sub ParseStructPull($)
end_flags($struct);
}
+#####################################################################
+# calculate size of ndr struct
+
+sub ParseStructNdrSize($)
+{
+ my $t = shift;
+ my $static = fn_prefix($t);
+ my $sizevar;
+
+ pidl $static . "size_t ndr_size_$t->{NAME}(int ret, struct $t->{NAME} *r, int flags)\n";
+ pidl "{\n";
+
+ if (util::has_property($t->{DATA}, "flag")) {
+
+ pidl "\tflags = flags | " . $t->{DATA}->{PROPERTIES}->{flag} . ";\n";
+ }
+
+ pidl "\tif(!r) return 0;\n";
+
+ pidl "\tret = NDR_SIZE_ALIGN(ret, " . struct_alignment($t->{DATA}) . ", flags);\n";
+
+ for my $e (@{$t->{DATA}->{ELEMENTS}}) {
+ my $switch = "";
+
+ if (util::has_property($e, "subcontext")) {
+ pidl "\tret += $e->{PROPERTIES}->{subcontext}; /* Subcontext length */\n";
+ }
+
+ if (util::has_property($e, "switch_is")) {
+ $switch = ", r->$e->{PROPERTIES}->{switch_is}";
+ }
+
+ if ($e->{POINTERS} > 0) {
+ pidl "\tret = ndr_size_ptr(ret, &r->$e->{NAME}, flags); \n";
+ } elsif (util::is_inline_array($e)) {
+ $sizevar = find_size_var($e, util::array_size($e), "r->");
+ pidl "\t{\n";
+ pidl "\t\tint i;\n";
+ pidl "\t\tfor(i = 0; i < $sizevar; i++) {\n";
+ pidl "\t\t\tret = ndr_size_$e->{TYPE}(ret, &r->" . $e->{NAME} . "[i], flags);\n";
+ pidl "\t\t}\n";
+ pidl "\t}\n";
+ } else {
+ pidl "\tret = ndr_size_$e->{TYPE}(ret, &r->$e->{NAME}$switch, flags); \n";
+ }
+ }
+
+ # Add lengths of relative members
+ for my $e (@{$t->{DATA}->{ELEMENTS}}) {
+ next unless (util::has_property($e, "relative"));
+
+ pidl "\tif (r->$e->{NAME}) {\n";
+ pidl "\t\tret = ndr_size_$e->{TYPE}(ret, r->$e->{NAME}, flags); \n";
+ pidl "\t}\n";
+ }
+
+ pidl "\treturn ret;\n";
+ pidl "}\n\n";
+}
#####################################################################
# parse a union - push side
@@ -982,6 +1042,43 @@ sub ParseUnionPull($)
}
#####################################################################
+# calculate size of ndr union
+
+sub ParseUnionNdrSize($)
+{
+ my $t = shift;
+ my $static = fn_prefix($t);
+
+ pidl $static . "size_t ndr_size_$t->{NAME}(int ret, union $t->{NAME} *data, uint16 level, int flags)\n";
+ pidl "{\n";
+ if (util::has_property($t->{DATA}, "flag")) {
+ pidl "\tflags = flags | " . $t->{DATA}->{PROPERTIES}->{flag} . ";\n";
+ }
+ pidl "\tif(!data) return 0;\n\n";
+
+ pidl "\tret = NDR_SIZE_ALIGN(ret, " . union_alignment($t->{DATA}) . ", flags);\n";
+
+ pidl "\tswitch(level) {\n";
+
+ for my $e (@{$t->{DATA}->{DATA}}) {
+ if ($e->{TYPE} eq "UNION_ELEMENT") {
+
+ if ($e->{CASE} eq "default") {
+ pidl "\t\tdefault:";
+ } else {
+ pidl "\t\tcase $e->{CASE}:";
+ }
+
+ pidl " return ndr_size_$e->{DATA}->{TYPE}(ret, &data->$e->{DATA}->{NAME}, flags); \n";
+
+ }
+ }
+ pidl "\t}\n";
+ pidl "\treturn ret;\n";
+ pidl "}\n\n";
+}
+
+#####################################################################
# parse a type
sub ParseTypePush($)
{
@@ -1107,6 +1204,23 @@ sub ParseTypedefPrint($)
}
#####################################################################
+## calculate the size of a structure
+sub ParseTypedefNdrSize($)
+{
+ my($t) = shift;
+ if (! $needed{"ndr_size_$t->{NAME}"}) {
+ return;
+ }
+
+ ($t->{DATA}->{TYPE} eq "STRUCT") &&
+ ParseStructNdrSize($t);
+
+ ($t->{DATA}->{TYPE} eq "UNION") &&
+ ParseUnionNdrSize($t);
+
+}
+
+#####################################################################
# parse a function - print side
sub ParseFunctionPrint($)
{
@@ -1413,7 +1527,10 @@ sub ParseInterface($)
}
}
-
+ foreach my $d (@{$data}) {
+ ($d->{TYPE} eq "TYPEDEF") &&
+ ParseTypedefNdrSize($d);
+ }
foreach my $d (@{$data}) {
($d->{TYPE} eq "TYPEDEF") &&
@@ -1461,7 +1578,12 @@ sub NeededTypedef($)
$needed{"pull_$t->{NAME}"} = 1;
$needed{"push_$t->{NAME}"} = 1;
}
+
if ($t->{DATA}->{TYPE} eq "STRUCT") {
+ if (util::has_property($t->{DATA}, "gensize")) {
+ $needed{"ndr_size_$t->{NAME}"} = 1;
+ }
+
for my $e (@{$t->{DATA}->{ELEMENTS}}) {
$e->{PARENT} = $t->{DATA};
if ($needed{"pull_$t->{NAME}"}) {
@@ -1470,6 +1592,9 @@ sub NeededTypedef($)
if ($needed{"push_$t->{NAME}"}) {
$needed{"push_$e->{TYPE}"} = 1;
}
+ if ($needed{"ndr_size_$t->{NAME}"}) {
+ $needed{"ndr_size_$e->{TYPE}"} = 1;
+ }
}
}
if ($t->{DATA}->{TYPE} eq "UNION") {
@@ -1482,6 +1607,9 @@ sub NeededTypedef($)
if ($needed{"push_$t->{NAME}"}) {
$needed{"push_$e->{DATA}->{TYPE}"} = 1;
}
+ if ($needed{"ndr_size_$t->{NAME}"}) {
+ $needed{"ndr_size_$e->{DATA}->{TYPE}"} = 1;
+ }
}
}
}
diff --git a/source4/librpc/idl/epmapper.idl b/source4/librpc/idl/epmapper.idl
index 7ea58e354f..18bb6bf7d7 100644
--- a/source4/librpc/idl/epmapper.idl
+++ b/source4/librpc/idl/epmapper.idl
@@ -193,8 +193,8 @@ interface epmapper
epm_floor floors[num_floors];
} epm_towers;
- typedef struct {
- [value(ndr_size_epm_towers(&r->towers))] uint32 tower_length;
+ typedef [gensize] struct {
+ [value(ndr_size_epm_towers(0, &r->towers,ndr->flags))] uint32 tower_length;
[subcontext(4)] epm_towers towers;
} epm_twr_t;
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
index 59e8b744df..306e480c98 100644
--- a/source4/librpc/ndr/libndr.h
+++ b/source4/librpc/ndr/libndr.h
@@ -188,6 +188,11 @@ enum ndr_err_code {
} \
} while(0)
+#define NDR_SIZE_ALIGN(t, n, flags) ((flags & LIBNDR_FLAG_NOALIGN)?(t):(((t) + (n-1)) & ~(n-1)))
+#define ndr_size_uint8(t, p, flags) (NDR_SIZE_ALIGN(t, 1, flags) + 1)
+#define ndr_size_uint16(t, p, flags) (NDR_SIZE_ALIGN(t, 2, flags) + 2)
+#define ndr_size_uint32(t, p, flags) (NDR_SIZE_ALIGN(t, 4, flags) + 4)
+#define ndr_size_ptr(t, p, flags) (NDR_SIZE_ALIGN(t, 4, flags) + 4)
/* these are used to make the error checking on each element in libndr
less tedious, hopefully making the code more readable */
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index edb1590489..5808ae7452 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -1130,3 +1130,15 @@ NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, DATA_BLOB *blob)
ndr->offset += length;
return NT_STATUS_OK;
}
+
+uint32 ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
+{
+ return ret + data->length;
+}
+
+uint32 ndr_size_string(int ret, const char **string, int flags)
+{
+ /* FIXME: Is this correct for all strings ? */
+ if(!(*string)) return ret;
+ return ret+strlen(*string)+1;
+}
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index fad8417c3f..5f3d911d15 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -23,58 +23,6 @@
#include "includes.h"
/*
- this ndr_size_* stuff should really be auto-generated ....
-*/
-
-static size_t ndr_size_epm_floor(struct epm_floor *fl)
-{
- size_t ret = 5;
- if (fl->lhs.protocol == EPM_PROTOCOL_UUID) {
- ret += 18;
- } else {
- ret += fl->lhs.info.lhs_data.length;
- }
- switch (fl->lhs.protocol) {
- case EPM_PROTOCOL_TCP:
- case EPM_PROTOCOL_UDP:
- case EPM_PROTOCOL_HTTP:
- case EPM_PROTOCOL_UUID:
- ret += 2;
- break;
- case EPM_PROTOCOL_IP:
- ret += 4;
- break;
- case EPM_PROTOCOL_NCADG:
- case EPM_PROTOCOL_NCACN:
- case EPM_PROTOCOL_NCALRPC:
- ret += 2;
- break;
-
- case EPM_PROTOCOL_SMB:
- ret += strlen(fl->rhs.smb.unc)+1;
- break;
- case EPM_PROTOCOL_PIPE:
- ret += strlen(fl->rhs.pipe.path)+1;
- break;
- case EPM_PROTOCOL_NETBIOS:
- ret += strlen(fl->rhs.netbios.name)+1;
- break;
- }
-
- return ret;
-}
-
-size_t ndr_size_epm_towers(struct epm_towers *towers)
-{
- size_t ret = 2;
- int i;
- for (i=0;i<towers->num_floors;i++) {
- ret += ndr_size_epm_floor(&towers->floors[i]);
- }
- return ret;
-}
-
-/*
work out what TCP port to use for a given interface on a given host
*/
NTSTATUS dcerpc_epm_map_tcp_port(const char *server,