[PATCH 1/4] pidl: Introduce new dirrective: relative_short

Matthieu Patou mat at matws.net
Thu Dec 10 00:04:48 MST 2009


  relative_short is like relative but instead of having the offset coded on 4 bytes
  it's coded on 2 bytes. Such things happen in GET_DFS_REFERAL messages.
---
 librpc/ndr/ndr.c                         |   42 ++++++++++++++++++++++++++++++
 librpc/ndr/ndr_basic.c                   |   12 ++++++++
 pidl/lib/Parse/Pidl/NDR.pm               |    3 ++
 pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm |   20 +++++++++++---
 4 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
index 1969dec..a151994 100644
--- a/librpc/ndr/ndr.c
+++ b/librpc/ndr/ndr.c
@@ -1074,6 +1074,20 @@ _PUBLIC_ enum ndr_err_code ndr_push_relative_ptr1(struct ndr_push *ndr, const vo
 }
 
 /*
+  push a short relative object - stage1
+  this is called during SCALARS processing
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_short_relative_ptr1(struct ndr_push *ndr, const void *p)
+{
+	if (p == NULL) {
+		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 0));
+		return NDR_ERR_SUCCESS;
+	}
+	NDR_CHECK(ndr_push_align(ndr, 2));
+	NDR_CHECK(ndr_token_store(ndr, &ndr->relative_list, p, ndr->offset));
+	return ndr_push_uint16(ndr, NDR_SCALARS, 0xFFFF);
+}
+/*
   push a relative object - stage2
   this is called during buffers processing
 */
@@ -1101,6 +1115,34 @@ _PUBLIC_ enum ndr_err_code ndr_push_relative_ptr2(struct ndr_push *ndr, const vo
 	ndr->offset = save_offset;
 	return NDR_ERR_SUCCESS;
 }
+/*
+  push a short relative object - stage2
+  this is called during buffers processing
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_short_relative_ptr2(struct ndr_push *ndr, const void *p)
+{
+	uint32_t save_offset;
+	uint32_t ptr_offset = 0xFFFF;
+	if (p == NULL) {
+		return NDR_ERR_SUCCESS;
+	}
+	save_offset = ndr->offset;
+	NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &ptr_offset));
+	if (ptr_offset > ndr->offset) {
+		return ndr_push_error(ndr, NDR_ERR_BUFSIZE,
+				      "ndr_push_short_relative_ptr2 ptr_offset(%u) > ndr->offset(%u)",
+				      ptr_offset, ndr->offset);
+	}
+	ndr->offset = ptr_offset;
+	if (save_offset < ndr->relative_base_offset) {
+		return ndr_push_error(ndr, NDR_ERR_BUFSIZE,
+				      "ndr_push_relative_ptr2 save_offset(%u) < ndr->relative_base_offset(%u)",
+				      save_offset, ndr->relative_base_offset);
+	}
+	NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, save_offset - ndr->relative_base_offset));
+	ndr->offset = save_offset;
+	return NDR_ERR_SUCCESS;
+}
 
 /*
   get the current base for relative pointers for the pull
diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c
index 64fa5a6..1fd6fde 100644
--- a/librpc/ndr/ndr_basic.c
+++ b/librpc/ndr/ndr_basic.c
@@ -176,6 +176,18 @@ _PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags,
 }
 
 /*
+  parse a pointer referent identifier stored in 2 bytes
+*/
+_PUBLIC_ enum ndr_err_code ndr_pull_relative_ptr_short(struct ndr_pull *ndr, uint16_t *v)
+{
+	NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, v));
+	if (*v != 0) {
+		ndr->ptr_count++;
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+/*
   parse a pointer referent identifier
 */
 _PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v)
diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm
index 4e680b3..d326f67 100644
--- a/pidl/lib/Parse/Pidl/NDR.pm
+++ b/pidl/lib/Parse/Pidl/NDR.pm
@@ -351,6 +351,7 @@ sub pointer_type($)
 	return "sptr" if (has_property($e, "sptr"));
 	return "unique" if (has_property($e, "unique"));
 	return "relative" if (has_property($e, "relative"));
+	return "relative_short" if (has_property($e, "relative_short"));
 	return "ignore" if (has_property($e, "ignore"));
 
 	return undef;
@@ -902,6 +903,7 @@ my %property_list = (
 	"unique"		=> ["ELEMENT"],
 	"ignore"		=> ["ELEMENT"],
 	"relative"		=> ["ELEMENT"],
+	"relative_short"	=> ["ELEMENT"],
 	"null_is_ffffffff" => ["ELEMENT"],
 	"relative_base"		=> ["TYPEDEF", "STRUCT", "UNION"],
 
@@ -1059,6 +1061,7 @@ sub ValidElement($)
 		has_property($e, "ptr") or
 		has_property($e, "unique") or
 		has_property($e, "relative") or
+		has_property($e, "relative_short") or
 		has_property($e, "ref"))) {
 		fatal($e, el_name($e) . " : pointer properties on non-pointer element\n");	
 	}
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index af28bda..d574495 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -573,6 +573,9 @@ sub ParseElementPushLevel
 			if ($l->{POINTER_TYPE} eq "relative") {
 				$self->pidl("NDR_CHECK(ndr_push_relative_ptr2($ndr, $var_name));");
 			}
+			if ($l->{POINTER_TYPE} eq "relative_short") {
+				$self->pidl("NDR_CHECK(ndr_push_short_relative_ptr2($ndr, $var_name));");
+			}
 		}
 		$var_name = get_value_of($var_name);
 		$self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 1, 1);
@@ -670,6 +673,8 @@ sub ParsePtrPush($$$$$)
 		}
 	} elsif ($l->{POINTER_TYPE} eq "relative") {
 		$self->pidl("NDR_CHECK(ndr_push_relative_ptr1($ndr, $var_name));");
+	} elsif ($l->{POINTER_TYPE} eq "relative_short") {
+		$self->pidl("NDR_CHECK(ndr_push_short_relative_ptr1($ndr, $var_name));");
 	} elsif ($l->{POINTER_TYPE} eq "unique") {
 		$self->pidl("NDR_CHECK(ndr_push_unique_ptr($ndr, $var_name));");
 	} elsif ($l->{POINTER_TYPE} eq "full") {
@@ -1038,7 +1043,7 @@ sub ParseElementPullLevel
 			$self->pidl("if ($var_name) {");
 			$self->indent;
 
-			if ($l->{POINTER_TYPE} eq "relative") {
+			if ($l->{POINTER_TYPE} eq "relative" or $l->{POINTER_TYPE} eq "relative_short") {
 				$self->pidl("uint32_t _relative_save_offset;");
 				$self->pidl("_relative_save_offset = $ndr->offset;");
 				$self->pidl("NDR_CHECK(ndr_pull_relative_ptr2($ndr, $var_name));");
@@ -1170,7 +1175,10 @@ sub ParsePtrPull($$$$$)
 		 ($l->{POINTER_TYPE} eq "relative") or
 		 ($l->{POINTER_TYPE} eq "full")) {
 		$self->pidl("NDR_CHECK(ndr_pull_generic_ptr($ndr, &_ptr_$e->{NAME}));");
-	} else {
+	} elsif ($l->{POINTER_TYPE} eq "relative_short") {
+		$self->pidl("NDR_CHECK(ndr_pull_relative_ptr_short($ndr, &_ptr_$e->{NAME}));");
+  }
+  else {
 		die("Unhandled pointer type $l->{POINTER_TYPE}");
 	}
 
@@ -1190,7 +1198,7 @@ sub ParsePtrPull($$$$$)
 	}
 
 	#$self->pidl("memset($var_name, 0, sizeof($var_name));");
-	if ($l->{POINTER_TYPE} eq "relative") {
+	if ($l->{POINTER_TYPE} eq "relative" or $l->{POINTER_TYPE} eq "relative_short") {
 		$self->pidl("NDR_CHECK(ndr_pull_relative_ptr1($ndr, $var_name, _ptr_$e->{NAME}));");
 	}
 	$self->deindent;
@@ -1471,9 +1479,13 @@ sub DeclarePtrVariables($$)
 {
 	my ($self,$e) = @_;
 	foreach my $l (@{$e->{LEVELS}}) {
+		my $size = 32;
 		if ($l->{TYPE} eq "POINTER" and 
 			not ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP")) {
-			$self->pidl("uint32_t _ptr_$e->{NAME};");
+			if ($l->{POINTER_TYPE} eq "relative_short") {
+				$size = 16;
+			}
+			$self->pidl("uint${size}_t _ptr_$e->{NAME};");
 			last;
 		}
 	}
-- 
1.6.3.3


--------------080605080406060906090704
Content-Type: text/x-patch;
 name="0002-pidl-create-trans.idl-IDL-for-TRANSACTIONS2-extensio.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="0002-pidl-create-trans.idl-IDL-for-TRANSACTIONS2-extensio.pa";
 filename*1="tch"



More information about the samba-technical mailing list