r5764: add support for embedded ref pointers
authorStefan Metzmacher <metze@samba.org>
Sat, 12 Mar 2005 08:29:54 +0000 (08:29 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:11:01 +0000 (13:11 -0500)
metze
(This used to be commit 112043b1809a96b1a39ade71ea2885c0d792c79f)

source4/build/pidl/ndr.pm
source4/build/pidl/validator.pm
source4/librpc/ndr/ndr_basic.c

index fcd6f6d6ddbd1ee34b89ac171cb1673ea61ad4dc..1e862f5c231602203687004bec2cc14ad07679b1 100644 (file)
@@ -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");
index bbef008ee50c95839ea5b3c6335ad29ab29a2195..e8a42c6031b38e22efdbe7d10df53f1392e23102 100644 (file)
@@ -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);
        }
index 24ca8dcd0e4b8fca751f25dccc49153d4ed21a60..0ea38c21c2c03cf49face8cf80d11ca52459fbd7 100644 (file)
@@ -118,6 +118,18 @@ NTSTATUS ndr_pull_unique_ptr(struct ndr_pull *ndr, uint32_t *v)
        return status;
 }
 
+/*
+  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
 */
@@ -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