summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/build/pidl/ndr.pm14
-rw-r--r--source4/build/pidl/validator.pm4
-rw-r--r--source4/librpc/ndr/ndr_basic.c25
3 files changed, 34 insertions, 9 deletions
diff --git a/source4/build/pidl/ndr.pm b/source4/build/pidl/ndr.pm
index fcd6f6d6dd..1e862f5c23 100644
--- a/source4/build/pidl/ndr.pm
+++ b/source4/build/pidl/ndr.pm
@@ -183,7 +183,7 @@ sub need_alloc($)
{
my $e = shift;
- return 0 if (util::has_property($e, "ref"));
+ return 0 if (util::has_property($e, "ref") && $e->{PARENT}->{TYPE} eq "FUNCTION");
return 1 if ($e->{POINTERS} || util::array_size($e));
return 0;
}
@@ -707,7 +707,9 @@ sub ParsePtrPush($$)
my $e = shift;
my $var_prefix = shift;
- if (util::has_property($e, "relative")) {
+ if (util::has_property($e, "ref")) {
+ pidl "NDR_CHECK(ndr_push_ref_ptr(ndr, $var_prefix$e->{NAME}));";
+ } elsif (util::has_property($e, "relative")) {
pidl "NDR_CHECK(ndr_push_relative_ptr1(ndr, $var_prefix$e->{NAME}));";
} else {
pidl "NDR_CHECK(ndr_push_unique_ptr(ndr, $var_prefix$e->{NAME}));";
@@ -855,7 +857,11 @@ sub ParsePtrPull($$)
my($e) = shift;
my($var_prefix) = shift;
- pidl "NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_$e->{NAME}));";
+ if (util::has_property($e, "ref")) {
+ pidl "NDR_CHECK(ndr_pull_ref_ptr(ndr, &_ptr_$e->{NAME}));";
+ } else {
+ pidl "NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_$e->{NAME}));";
+ }
pidl "if (_ptr_$e->{NAME}) {";
indent;
pidl "NDR_ALLOC(ndr, $var_prefix$e->{NAME});";
@@ -1777,7 +1783,7 @@ sub ParseFunctionElementPush($$)
if (util::array_size($e)) {
if (need_wire_pointer($e)) {
- pidl "NDR_CHECK(ndr_push_unique_ptr(ndr, r->$inout.$e->{NAME}));";
+ ParsePtrPush($e, "r->$inout.");
pidl "if (r->$inout.$e->{NAME}) {";
indent;
ParseArrayPush($e, "ndr", "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
diff --git a/source4/build/pidl/validator.pm b/source4/build/pidl/validator.pm
index bbef008ee5..e8a42c6031 100644
--- a/source4/build/pidl/validator.pm
+++ b/source4/build/pidl/validator.pm
@@ -88,10 +88,6 @@ sub ValidStruct($)
my($struct) = shift;
foreach my $e (@{$struct->{ELEMENTS}}) {
- if (util::has_property($e, "ref")) {
- fatal(el_name($e) . " : embedded ref pointers are not supported yet\n");
- }
-
$e->{PARENT} = $struct;
ValidElement($e);
}
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index 24ca8dcd0e..0ea38c21c2 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -119,6 +119,18 @@ NTSTATUS ndr_pull_unique_ptr(struct ndr_pull *ndr, uint32_t *v)
}
/*
+ parse a ref pointer referent identifier
+*/
+NTSTATUS ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
+{
+ NTSTATUS status;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v));
+ /* ref pointers always point to data */
+ *v = 1;
+ return status;
+}
+
+/*
parse a udlong
*/
NTSTATUS ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
@@ -506,7 +518,7 @@ void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save)
}
/*
- push a 1 if a pointer is non-NULL, otherwise 0
+ push a unique non-zero value if a pointer is non-NULL, otherwise 0
*/
NTSTATUS ndr_push_unique_ptr(struct ndr_push *ndr, const void *p)
{
@@ -518,6 +530,17 @@ NTSTATUS ndr_push_unique_ptr(struct ndr_push *ndr, const void *p)
return ndr_push_uint32(ndr, NDR_SCALARS, ptr);
}
+/*
+ push always a 0, if a pointer is NULL it's a fatal error
+*/
+NTSTATUS ndr_push_ref_ptr(struct ndr_push *ndr, const void *p)
+{
+ uint32_t ptr = 0;
+ if (p == NULL) {
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ }
+ return ndr_push_uint32(ndr, NDR_SCALARS, 0);
+}
/*
pull a general string from the wire