aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/pidl/idl.yp36
-rw-r--r--tools/pidl/lib/Parse/Pidl/Expr.pm72
-rw-r--r--tools/pidl/lib/Parse/Pidl/IDL.pm96
-rw-r--r--tools/pidl/lib/Parse/Pidl/NDR.pm215
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm11
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm7
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4.pm9
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/Header.pm26
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm123
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm303
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm11
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/Python.pm93
-rw-r--r--tools/pidl/lib/Parse/Pidl/Typelist.pm36
-rw-r--r--tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm146
14 files changed, 911 insertions, 273 deletions
diff --git a/tools/pidl/idl.yp b/tools/pidl/idl.yp
index 30247f9ef3..b5c5185fbe 100644
--- a/tools/pidl/idl.yp
+++ b/tools/pidl/idl.yp
@@ -387,7 +387,31 @@ pipe:
{{
"TYPE" => "PIPE",
"PROPERTIES" => $_[1],
- "DATA" => $_[3],
+ "NAME" => undef,
+ "DATA" => {
+ "TYPE" => "STRUCT",
+ "PROPERTIES" => $_[1],
+ "NAME" => undef,
+ "ELEMENTS" => [{
+ "NAME" => "count",
+ "PROPERTIES" => $_[1],
+ "POINTERS" => 0,
+ "ARRAY_LEN" => [],
+ "TYPE" => "uint3264",
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ },{
+ "NAME" => "array",
+ "PROPERTIES" => $_[1],
+ "POINTERS" => 0,
+ "ARRAY_LEN" => [ "count" ],
+ "TYPE" => $_[3],
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ }],
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ },
"FILE" => $_[0]->YYData->{FILE},
"LINE" => $_[0]->YYData->{LINE},
}}
@@ -653,11 +677,17 @@ sub parse_file($$)
my $saved_delim = $/;
undef $/;
my $cpp = $ENV{CPP};
+ my $options = "";
if (! defined $cpp) {
- $cpp = "cpp";
+ if (defined $ENV{CC}) {
+ $cpp = "$ENV{CC}";
+ $options = "-E";
+ } else {
+ $cpp = "cpp";
+ }
}
my $includes = join('',map { " -I$_" } @$incdirs);
- my $data = `$cpp -D__PIDL__$includes -xc "$filename"`;
+ my $data = `$cpp $options -D__PIDL__$includes -xc "$filename"`;
$/ = $saved_delim;
return parse_string($data, $filename);
diff --git a/tools/pidl/lib/Parse/Pidl/Expr.pm b/tools/pidl/lib/Parse/Pidl/Expr.pm
index 1230a71a2b..24581d29f4 100644
--- a/tools/pidl/lib/Parse/Pidl/Expr.pm
+++ b/tools/pidl/lib/Parse/Pidl/Expr.pm
@@ -1127,7 +1127,7 @@ sub new {
[#Rule 2
'exp', 1,
sub
-#line 24 "./../pidl/expr.yp"
+#line 24 "expr.yp"
{ "\"$_[1]\"" }
],
[#Rule 3
@@ -1139,199 +1139,199 @@ sub
[#Rule 5
'exp', 2,
sub
-#line 30 "./../pidl/expr.yp"
+#line 30 "expr.yp"
{ "~$_[2]" }
],
[#Rule 6
'exp', 3,
sub
-#line 32 "./../pidl/expr.yp"
+#line 32 "expr.yp"
{ "$_[1] + $_[3]" }
],
[#Rule 7
'exp', 3,
sub
-#line 34 "./../pidl/expr.yp"
+#line 34 "expr.yp"
{ "$_[1] - $_[3]" }
],
[#Rule 8
'exp', 3,
sub
-#line 36 "./../pidl/expr.yp"
+#line 36 "expr.yp"
{ "$_[1] * $_[3]" }
],
[#Rule 9
'exp', 3,
sub
-#line 38 "./../pidl/expr.yp"
+#line 38 "expr.yp"
{ "$_[1] % $_[3]" }
],
[#Rule 10
'exp', 3,
sub
-#line 40 "./../pidl/expr.yp"
+#line 40 "expr.yp"
{ "$_[1] < $_[3]" }
],
[#Rule 11
'exp', 3,
sub
-#line 42 "./../pidl/expr.yp"
+#line 42 "expr.yp"
{ "$_[1] > $_[3]" }
],
[#Rule 12
'exp', 3,
sub
-#line 44 "./../pidl/expr.yp"
+#line 44 "expr.yp"
{ "$_[1] | $_[3]" }
],
[#Rule 13
'exp', 3,
sub
-#line 46 "./../pidl/expr.yp"
+#line 46 "expr.yp"
{ "$_[1] == $_[3]" }
],
[#Rule 14
'exp', 3,
sub
-#line 48 "./../pidl/expr.yp"
+#line 48 "expr.yp"
{ "$_[1] <= $_[3]" }
],
[#Rule 15
'exp', 3,
sub
-#line 50 "./../pidl/expr.yp"
+#line 50 "expr.yp"
{ "$_[1] => $_[3]" }
],
[#Rule 16
'exp', 3,
sub
-#line 52 "./../pidl/expr.yp"
+#line 52 "expr.yp"
{ "$_[1] << $_[3]" }
],
[#Rule 17
'exp', 3,
sub
-#line 54 "./../pidl/expr.yp"
+#line 54 "expr.yp"
{ "$_[1] >> $_[3]" }
],
[#Rule 18
'exp', 3,
sub
-#line 56 "./../pidl/expr.yp"
+#line 56 "expr.yp"
{ "$_[1] != $_[3]" }
],
[#Rule 19
'exp', 3,
sub
-#line 58 "./../pidl/expr.yp"
+#line 58 "expr.yp"
{ "$_[1] || $_[3]" }
],
[#Rule 20
'exp', 3,
sub
-#line 60 "./../pidl/expr.yp"
+#line 60 "expr.yp"
{ "$_[1] && $_[3]" }
],
[#Rule 21
'exp', 3,
sub
-#line 62 "./../pidl/expr.yp"
+#line 62 "expr.yp"
{ "$_[1] & $_[3]" }
],
[#Rule 22
'exp', 5,
sub
-#line 64 "./../pidl/expr.yp"
+#line 64 "expr.yp"
{ "$_[1]?$_[3]:$_[5]" }
],
[#Rule 23
'exp', 2,
sub
-#line 66 "./../pidl/expr.yp"
+#line 66 "expr.yp"
{ "~$_[1]" }
],
[#Rule 24
'exp', 2,
sub
-#line 68 "./../pidl/expr.yp"
+#line 68 "expr.yp"
{ "not $_[1]" }
],
[#Rule 25
'exp', 3,
sub
-#line 70 "./../pidl/expr.yp"
+#line 70 "expr.yp"
{ "$_[1] / $_[3]" }
],
[#Rule 26
'exp', 2,
sub
-#line 72 "./../pidl/expr.yp"
+#line 72 "expr.yp"
{ "-$_[2]" }
],
[#Rule 27
'exp', 2,
sub
-#line 74 "./../pidl/expr.yp"
+#line 74 "expr.yp"
{ "&$_[2]" }
],
[#Rule 28
'exp', 3,
sub
-#line 76 "./../pidl/expr.yp"
+#line 76 "expr.yp"
{ "$_[1]^$_[3]" }
],
[#Rule 29
'exp', 3,
sub
-#line 78 "./../pidl/expr.yp"
+#line 78 "expr.yp"
{ "($_[2])" }
],
[#Rule 30
'possible_pointer', 1,
sub
-#line 82 "./../pidl/expr.yp"
+#line 82 "expr.yp"
{ $_[0]->_Lookup($_[1]) }
],
[#Rule 31
'possible_pointer', 2,
sub
-#line 84 "./../pidl/expr.yp"
+#line 84 "expr.yp"
{ $_[0]->_Dereference($_[2]); "*$_[2]" }
],
[#Rule 32
'var', 1,
sub
-#line 88 "./../pidl/expr.yp"
+#line 88 "expr.yp"
{ $_[0]->_Use($_[1]) }
],
[#Rule 33
'var', 3,
sub
-#line 90 "./../pidl/expr.yp"
+#line 90 "expr.yp"
{ $_[0]->_Use("$_[1].$_[3]") }
],
[#Rule 34
'var', 3,
sub
-#line 92 "./../pidl/expr.yp"
+#line 92 "expr.yp"
{ "($_[2])" }
],
[#Rule 35
'var', 3,
sub
-#line 94 "./../pidl/expr.yp"
+#line 94 "expr.yp"
{ $_[0]->_Use("*$_[1]"); $_[1]."->".$_[3] }
],
[#Rule 36
'func', 4,
sub
-#line 99 "./../pidl/expr.yp"
+#line 99 "expr.yp"
{ "$_[1]($_[3])" }
],
[#Rule 37
'opt_args', 0,
sub
-#line 104 "./../pidl/expr.yp"
+#line 104 "expr.yp"
{ "" }
],
[#Rule 38
@@ -1349,7 +1349,7 @@ sub
[#Rule 42
'args', 3,
sub
-#line 118 "./../pidl/expr.yp"
+#line 118 "expr.yp"
{ "$_[1], $_[3]" }
]
],
@@ -1357,7 +1357,7 @@ sub
bless($self,$class);
}
-#line 121 "./../pidl/expr.yp"
+#line 121 "expr.yp"
package Parse::Pidl::Expr;
diff --git a/tools/pidl/lib/Parse/Pidl/IDL.pm b/tools/pidl/lib/Parse/Pidl/IDL.pm
index de605c7024..d4820ffe92 100644
--- a/tools/pidl/lib/Parse/Pidl/IDL.pm
+++ b/tools/pidl/lib/Parse/Pidl/IDL.pm
@@ -2249,7 +2249,31 @@ sub
{{
"TYPE" => "PIPE",
"PROPERTIES" => $_[1],
- "DATA" => $_[3],
+ "NAME" => undef,
+ "DATA" => {
+ "TYPE" => "STRUCT",
+ "PROPERTIES" => $_[1],
+ "NAME" => undef,
+ "ELEMENTS" => [{
+ "NAME" => "count",
+ "PROPERTIES" => $_[1],
+ "POINTERS" => 0,
+ "ARRAY_LEN" => [],
+ "TYPE" => "uint3264",
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ },{
+ "NAME" => "array",
+ "PROPERTIES" => $_[1],
+ "POINTERS" => 0,
+ "ARRAY_LEN" => [ "count" ],
+ "TYPE" => $_[3],
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ }],
+ "FILE" => $_[0]->YYData->{FILE},
+ "LINE" => $_[0]->YYData->{LINE},
+ },
"FILE" => $_[0]->YYData->{FILE},
"LINE" => $_[0]->YYData->{LINE},
}}
@@ -2257,13 +2281,13 @@ sub
[#Rule 78
'element_list1', 0,
sub
-#line 398 "idl.yp"
+#line 422 "idl.yp"
{ [] }
],
[#Rule 79
'element_list1', 3,
sub
-#line 400 "idl.yp"
+#line 424 "idl.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 80
@@ -2281,13 +2305,13 @@ sub
[#Rule 84
'element_list2', 2,
sub
-#line 414 "idl.yp"
+#line 438 "idl.yp"
{ [ $_[2] ] }
],
[#Rule 85
'element_list2', 4,
sub
-#line 416 "idl.yp"
+#line 440 "idl.yp"
{ push(@{$_[1]}, $_[4]); $_[1] }
],
[#Rule 86
@@ -2296,13 +2320,13 @@ sub
[#Rule 87
'array_len', 3,
sub
-#line 422 "idl.yp"
+#line 446 "idl.yp"
{ push(@{$_[3]}, "*"); $_[3] }
],
[#Rule 88
'array_len', 4,
sub
-#line 424 "idl.yp"
+#line 448 "idl.yp"
{ push(@{$_[4]}, "$_[2]"); $_[4] }
],
[#Rule 89
@@ -2311,31 +2335,31 @@ sub
[#Rule 90
'property_list', 4,
sub
-#line 430 "idl.yp"
+#line 454 "idl.yp"
{ FlattenHash([$_[1],$_[3]]); }
],
[#Rule 91
'properties', 1,
sub
-#line 434 "idl.yp"
+#line 458 "idl.yp"
{ $_[1] }
],
[#Rule 92
'properties', 3,
sub
-#line 436 "idl.yp"
+#line 460 "idl.yp"
{ FlattenHash([$_[1], $_[3]]); }
],
[#Rule 93
'property', 1,
sub
-#line 440 "idl.yp"
+#line 464 "idl.yp"
{{ "$_[1]" => "1" }}
],
[#Rule 94
'property', 4,
sub
-#line 442 "idl.yp"
+#line 466 "idl.yp"
{{ "$_[1]" => "$_[3]" }}
],
[#Rule 95
@@ -2344,13 +2368,13 @@ sub
[#Rule 96
'commalisttext', 3,
sub
-#line 448 "idl.yp"
+#line 472 "idl.yp"
{ "$_[1],$_[3]" }
],
[#Rule 97
'anytext', 0,
sub
-#line 453 "idl.yp"
+#line 477 "idl.yp"
{ "" }
],
[#Rule 98
@@ -2365,91 +2389,91 @@ sub
[#Rule 101
'anytext', 3,
sub
-#line 461 "idl.yp"
+#line 485 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 102
'anytext', 3,
sub
-#line 463 "idl.yp"
+#line 487 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 103
'anytext', 3,
sub
-#line 465 "idl.yp"
+#line 489 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 104
'anytext', 3,
sub
-#line 467 "idl.yp"
+#line 491 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 105
'anytext', 3,
sub
-#line 469 "idl.yp"
+#line 493 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 106
'anytext', 3,
sub
-#line 471 "idl.yp"
+#line 495 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 107
'anytext', 3,
sub
-#line 473 "idl.yp"
+#line 497 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 108
'anytext', 3,
sub
-#line 475 "idl.yp"
+#line 499 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 109
'anytext', 3,
sub
-#line 477 "idl.yp"
+#line 501 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 110
'anytext', 3,
sub
-#line 479 "idl.yp"
+#line 503 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 111
'anytext', 3,
sub
-#line 481 "idl.yp"
+#line 505 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 112
'anytext', 3,
sub
-#line 483 "idl.yp"
+#line 507 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 113
'anytext', 3,
sub
-#line 485 "idl.yp"
+#line 509 "idl.yp"
{ "$_[1]$_[2]$_[3]" }
],
[#Rule 114
'anytext', 5,
sub
-#line 487 "idl.yp"
+#line 511 "idl.yp"
{ "$_[1]$_[2]$_[3]$_[4]$_[5]" }
],
[#Rule 115
'anytext', 5,
sub
-#line 489 "idl.yp"
+#line 513 "idl.yp"
{ "$_[1]$_[2]$_[3]$_[4]$_[5]" }
],
[#Rule 116
@@ -2467,7 +2491,7 @@ sub
[#Rule 120
'text', 1,
sub
-#line 507 "idl.yp"
+#line 531 "idl.yp"
{ "\"$_[1]\"" }
],
[#Rule 121
@@ -2481,7 +2505,7 @@ sub
bless($self,$class);
}
-#line 519 "idl.yp"
+#line 543 "idl.yp"
use Parse::Pidl qw(error);
@@ -2619,11 +2643,17 @@ sub parse_file($$)
my $saved_delim = $/;
undef $/;
my $cpp = $ENV{CPP};
+ my $options = "";
if (! defined $cpp) {
- $cpp = "cpp";
+ if (defined $ENV{CC}) {
+ $cpp = "$ENV{CC}";
+ $options = "-E";
+ } else {
+ $cpp = "cpp";
+ }
}
my $includes = join('',map { " -I$_" } @$incdirs);
- my $data = `$cpp -D__PIDL__$includes -xc "$filename"`;
+ my $data = `$cpp $options -D__PIDL__$includes -xc "$filename"`;
$/ = $saved_delim;
return parse_string($data, $filename);
diff --git a/tools/pidl/lib/Parse/Pidl/NDR.pm b/tools/pidl/lib/Parse/Pidl/NDR.pm
index 21b75687a7..db776ae3ef 100644
--- a/tools/pidl/lib/Parse/Pidl/NDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/NDR.pm
@@ -34,12 +34,12 @@ require Exporter;
use vars qw($VERSION);
$VERSION = '0.01';
@ISA = qw(Exporter);
-@EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsString);
+@EXPORT = qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe ContainsString);
@EXPORT_OK = qw(GetElementLevelTable ParseElement ValidElement align_type mapToScalar ParseType can_contain_deferred is_charset_array);
use strict;
use Parse::Pidl qw(warning fatal);
-use Parse::Pidl::Typelist qw(hasType getType expandAlias mapScalarType);
+use Parse::Pidl::Typelist qw(hasType getType typeIs expandAlias mapScalarType is_fixed_size_scalar);
use Parse::Pidl::Util qw(has_property property_matches);
# Alignment of the built-in scalar types
@@ -66,6 +66,8 @@ my $scalar_alignment = {
'string' => 4,
'string_array' => 4, #???
'time_t' => 4,
+ 'uid_t' => 8,
+ 'gid_t' => 8,
'NTTIME' => 4,
'NTTIME_1sec' => 4,
'NTTIME_hyper' => 8,
@@ -81,9 +83,9 @@ my $scalar_alignment = {
'dnsp_string' => 1
};
-sub GetElementLevelTable($$)
+sub GetElementLevelTable($$$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
my $order = [];
my $is_deferred = 0;
@@ -113,6 +115,51 @@ sub GetElementLevelTable($$)
warning($e, "[out] argument `$e->{NAME}' not a pointer") if ($needptrs > $e->{POINTERS});
}
+ my $allow_pipe = ($e->{PARENT}->{TYPE} eq "FUNCTION");
+ my $is_pipe = typeIs($e->{TYPE}, "PIPE");
+
+ if ($is_pipe) {
+ if (not $allow_pipe) {
+ fatal($e, "argument `$e->{NAME}' is a pipe and not allowed on $e->{PARENT}->{TYPE}");
+ }
+
+ if ($e->{POINTERS} > 1) {
+ fatal($e, "$e->{POINTERS} are not allowed on pipe element $e->{NAME}");
+ }
+
+ if ($e->{POINTERS} < 0) {
+ fatal($e, "pipe element $e->{NAME} needs pointer");
+ }
+
+ if ($e->{POINTERS} == 1 and pointer_type($e) ne "ref") {
+ fatal($e, "pointer should be 'ref' on pipe element $e->{NAME}");
+ }
+
+ if (scalar(@size_is) > 0) {
+ fatal($e, "size_is() on pipe element");
+ }
+
+ if (scalar(@length_is) > 0) {
+ fatal($e, "length_is() on pipe element");
+ }
+
+ if (scalar(@bracket_array) > 0) {
+ fatal($e, "brackets on pipe element");
+ }
+
+ if (defined(has_property($e, "subcontext"))) {
+ fatal($e, "subcontext on pipe element");
+ }
+
+ if (has_property($e, "switch_is")) {
+ fatal($e, "switch_is on pipe element");
+ }
+
+ if (can_contain_deferred($e->{TYPE})) {
+ fatal($e, "$e->{TYPE} can_contain_deferred - not allowed on pipe element");
+ }
+ }
+
# Parse the [][][][] style array stuff
for my $i (0 .. $#bracket_array) {
my $d = $bracket_array[$#bracket_array - $i];
@@ -257,6 +304,19 @@ sub GetElementLevelTable($$)
}
}
+ if ($is_pipe) {
+ push (@$order, {
+ TYPE => "PIPE",
+ IS_DEFERRED => 0,
+ CONTAINS_DEFERRED => 0,
+ });
+
+ my $i = 0;
+ foreach (@$order) { $_->{LEVEL_INDEX} = $i; $i+=1; }
+
+ return $order;
+ }
+
if (defined(has_property($e, "subcontext"))) {
my $hdr_size = has_property($e, "subcontext");
my $subsize = has_property($e, "subcontext_size");
@@ -307,9 +367,9 @@ sub GetElementLevelTable($$)
return $order;
}
-sub GetTypedefLevelTable($$$)
+sub GetTypedefLevelTable($$$$)
{
- my ($e, $data, $pointer_default) = @_;
+ my ($e, $data, $pointer_default, $ms_union) = @_;
my $order = [];
@@ -427,35 +487,37 @@ sub align_type($)
# Struct/union without body: assume 4
return 4 unless (defined($dt->{ELEMENTS}));
return find_largest_alignment($dt);
+ } elsif (($dt->{TYPE} eq "PIPE")) {
+ return 5;
}
die("Unknown data type type $dt->{TYPE}");
}
-sub ParseElement($$)
+sub ParseElement($$$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
$e->{TYPE} = expandAlias($e->{TYPE});
if (ref($e->{TYPE}) eq "HASH") {
- $e->{TYPE} = ParseType($e->{TYPE}, $pointer_default);
+ $e->{TYPE} = ParseType($e->{TYPE}, $pointer_default, $ms_union);
}
return {
NAME => $e->{NAME},
TYPE => $e->{TYPE},
PROPERTIES => $e->{PROPERTIES},
- LEVELS => GetElementLevelTable($e, $pointer_default),
+ LEVELS => GetElementLevelTable($e, $pointer_default, $ms_union),
REPRESENTATION_TYPE => ($e->{PROPERTIES}->{represent_as} or $e->{TYPE}),
ALIGN => align_type($e->{TYPE}),
ORIGINAL => $e
};
}
-sub ParseStruct($$)
+sub ParseStruct($$$)
{
- my ($struct, $pointer_default) = @_;
+ my ($struct, $pointer_default, $ms_union) = @_;
my @elements = ();
my $surrounding = undef;
@@ -473,7 +535,7 @@ sub ParseStruct($$)
foreach my $x (@{$struct->{ELEMENTS}})
{
- my $e = ParseElement($x, $pointer_default);
+ my $e = ParseElement($x, $pointer_default, $ms_union);
if ($x != $struct->{ELEMENTS}[-1] and
$e->{LEVELS}[0]->{IS_SURROUNDING}) {
fatal($x, "conformant member not at end of struct");
@@ -510,8 +572,10 @@ sub ParseStruct($$)
sub ParseUnion($$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
my @elements = ();
+ my $is_ms_union = $ms_union;
+ $is_ms_union = 1 if has_property($e, "ms_union");
my $hasdefault = 0;
my $switch_type = has_property($e, "switch_type");
unless (defined($switch_type)) { $switch_type = "uint32"; }
@@ -524,6 +588,7 @@ sub ParseUnion($$)
ELEMENTS => undef,
PROPERTIES => $e->{PROPERTIES},
HAS_DEFAULT => $hasdefault,
+ IS_MS_UNION => $is_ms_union,
ORIGINAL => $e,
ALIGN => undef
} unless defined($e->{ELEMENTS});
@@ -536,7 +601,7 @@ sub ParseUnion($$)
if ($x->{TYPE} eq "EMPTY") {
$t = { TYPE => "EMPTY" };
} else {
- $t = ParseElement($x, $pointer_default);
+ $t = ParseElement($x, $pointer_default, $ms_union);
}
if (has_property($x, "default")) {
$t->{CASE} = "default";
@@ -561,6 +626,7 @@ sub ParseUnion($$)
ELEMENTS => \@elements,
PROPERTIES => $e->{PROPERTIES},
HAS_DEFAULT => $hasdefault,
+ IS_MS_UNION => $is_ms_union,
ORIGINAL => $e,
ALIGN => $align
};
@@ -568,7 +634,7 @@ sub ParseUnion($$)
sub ParseEnum($$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
return {
TYPE => "ENUM",
@@ -580,9 +646,9 @@ sub ParseEnum($$)
};
}
-sub ParseBitmap($$)
+sub ParseBitmap($$$)
{
- my ($e, $pointer_default) = @_;
+ my ($e, $pointer_default, $ms_union) = @_;
return {
TYPE => "BITMAP",
@@ -594,9 +660,60 @@ sub ParseBitmap($$)
};
}
-sub ParseType($$)
+sub ParsePipe($$$)
{
- my ($d, $pointer_default) = @_;
+ my ($pipe, $pointer_default, $ms_union) = @_;
+
+ my $pname = $pipe->{NAME};
+ $pname = $pipe->{PARENT}->{NAME} unless defined $pname;
+
+ if (not defined($pipe->{PROPERTIES})
+ and defined($pipe->{PARENT}->{PROPERTIES})) {
+ $pipe->{PROPERTIES} = $pipe->{PARENT}->{PROPERTIES};
+ }
+
+ if (ref($pipe->{DATA}) eq "HASH") {
+ if (not defined($pipe->{DATA}->{PROPERTIES})
+ and defined($pipe->{PROPERTIES})) {
+ $pipe->{DATA}->{PROPERTIES} = $pipe->{PROPERTIES};
+ }
+ }
+
+ my $struct = ParseStruct($pipe->{DATA}, $pointer_default, $ms_union);
+ $struct->{ALIGN} = 5;
+ $struct->{NAME} = "$pname\_chunk";
+
+ # 'count' is element [0] and 'array' [1]
+ my $e = $struct->{ELEMENTS}[1];
+ # level [0] is of type "ARRAY"
+ my $l = $e->{LEVELS}[1];
+
+ # here we check that pipe elements have a fixed size type
+ while (defined($l)) {
+ my $cl = $l;
+ $l = GetNextLevel($e, $cl);
+ if ($cl->{TYPE} ne "DATA") {
+ fatal($pipe, el_name($pipe) . ": pipe contains non DATA level");
+ }
+
+ # for now we only support scalars
+ next if is_fixed_size_scalar($cl->{DATA_TYPE});
+
+ fatal($pipe, el_name($pipe) . ": pipe contains non fixed size type[$cl->{DATA_TYPE}]");
+ }
+
+ return {
+ TYPE => "PIPE",
+ NAME => $pipe->{NAME},
+ DATA => $struct,
+ PROPERTIES => $pipe->{PROPERTIES},
+ ORIGINAL => $pipe,
+ };
+}
+
+sub ParseType($$$)
+{
+ my ($d, $pointer_default, $ms_union) = @_;
my $data = {
STRUCT => \&ParseStruct,
@@ -604,14 +721,15 @@ sub ParseType($$)
ENUM => \&ParseEnum,
BITMAP => \&ParseBitmap,
TYPEDEF => \&ParseTypedef,
- }->{$d->{TYPE}}->($d, $pointer_default);
+ PIPE => \&ParsePipe,
+ }->{$d->{TYPE}}->($d, $pointer_default, $ms_union);
return $data;
}
sub ParseTypedef($$)
{
- my ($d, $pointer_default) = @_;
+ my ($d, $pointer_default, $ms_union) = @_;
my $data;
@@ -621,7 +739,7 @@ sub ParseTypedef($$)
$d->{PROPERTIES} = $d->{DATA}->{PROPERTIES};
}
- $data = ParseType($d->{DATA}, $pointer_default);
+ $data = ParseType($d->{DATA}, $pointer_default, $ms_union);
$data->{ALIGN} = align_type($d->{NAME});
} else {
$data = getType($d->{DATA});
@@ -631,7 +749,7 @@ sub ParseTypedef($$)
NAME => $d->{NAME},
TYPE => $d->{TYPE},
PROPERTIES => $d->{PROPERTIES},
- LEVELS => GetTypedefLevelTable($d, $data, $pointer_default),
+ LEVELS => GetTypedefLevelTable($d, $data, $pointer_default, $ms_union),
DATA => $data,
ORIGINAL => $d
};
@@ -644,9 +762,9 @@ sub ParseConst($$)
return $d;
}
-sub ParseFunction($$$)
+sub ParseFunction($$$$)
{
- my ($ndr,$d,$opnum) = @_;
+ my ($ndr,$d,$opnum,$ms_union) = @_;
my @elements = ();
my $rettype = undef;
my $thisopnum = undef;
@@ -659,7 +777,7 @@ sub ParseFunction($$$)
}
foreach my $x (@{$d->{ELEMENTS}}) {
- my $e = ParseElement($x, $ndr->{PROPERTIES}->{pointer_default});
+ my $e = ParseElement($x, $ndr->{PROPERTIES}->{pointer_default}, $ms_union);
push (@{$e->{DIRECTION}}, "in") if (has_property($x, "in"));
push (@{$e->{DIRECTION}}, "out") if (has_property($x, "out"));
@@ -720,6 +838,8 @@ sub ParseInterface($)
my @endpoints;
my $opnum = 0;
my $version;
+ my $ms_union = 0;
+ $ms_union = 1 if has_property($idl, "ms_union");
if (not has_property($idl, "pointer_default")) {
# MIDL defaults to "ptr" in DCE compatible mode (/osf)
@@ -729,11 +849,11 @@ sub ParseInterface($)
foreach my $d (@{$idl->{DATA}}) {
if ($d->{TYPE} eq "FUNCTION") {
- push (@functions, ParseFunction($idl, $d, \$opnum));
+ push (@functions, ParseFunction($idl, $d, \$opnum, $ms_union));
} elsif ($d->{TYPE} eq "CONST") {
push (@consts, ParseConst($idl, $d));
} else {
- push (@types, ParseType($d, $idl->{PROPERTIES}->{pointer_default}));
+ push (@types, ParseType($d, $idl->{PROPERTIES}->{pointer_default}, $ms_union));
FindNestedTypes(\@types, $d);
}
}
@@ -823,6 +943,9 @@ sub ContainsString($)
{
my ($e) = @_;
+ if (property_matches($e, "flag", ".*STR_NULLTERM.*")) {
+ return 1;
+ }
foreach my $l (@{$e->{LEVELS}}) {
return 1 if ($l->{TYPE} eq "ARRAY" and $l->{IS_ZERO_TERMINATED});
}
@@ -845,6 +968,20 @@ sub ContainsDeferred($$)
return 0;
}
+sub ContainsPipe($$)
+{
+ my ($e,$l) = @_;
+
+ return 1 if ($l->{TYPE} eq "PIPE");
+
+ while ($l = GetNextLevel($e,$l))
+ {
+ return 1 if ($l->{TYPE} eq "PIPE");
+ }
+
+ return 0;
+}
+
sub el_name($)
{
my $e = shift;
@@ -920,14 +1057,14 @@ my %property_list = (
"gensize" => ["TYPEDEF", "STRUCT", "UNION"],
"value" => ["ELEMENT"],
- "flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
+ "flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
# generic
- "public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "nopush" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "nopull" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
+ "public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
+ "nopush" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
+ "nopull" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
"nosize" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "noprint" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "ELEMENT"],
+ "noprint" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "ELEMENT", "PIPE"],
"nopython" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
"todo" => ["FUNCTION"],
@@ -935,6 +1072,7 @@ my %property_list = (
"switch_is" => ["ELEMENT"],
"switch_type" => ["ELEMENT", "UNION"],
"nodiscriminant" => ["UNION"],
+ "ms_union" => ["INTERFACE", "UNION"],
"case" => ["ELEMENT"],
"default" => ["ELEMENT"],
@@ -1155,11 +1293,16 @@ sub ValidUnion($)
sub ValidPipe($)
{
my ($pipe) = @_;
- my $data = $pipe->{DATA};
+ my $struct = $pipe->{DATA};
ValidProperties($pipe, "PIPE");
- fatal($pipe, $pipe->{NAME} . ": 'pipe' is not yet supported by pidl");
+ $struct->{PARENT} = $pipe;
+
+ $struct->{FILE} = $pipe->{FILE} unless defined($struct->{FILE});
+ $struct->{LINE} = $pipe->{LINE} unless defined($struct->{LINE});
+
+ ValidType($struct);
}
#####################################################################
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
index 67051a8783..8142b35699 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
@@ -14,6 +14,7 @@ use Exporter;
use strict;
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(ContainsPipe);
use Parse::Pidl::Typelist qw(mapTypeName);
use Parse::Pidl::Samba4 qw(DeclLong);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
@@ -378,6 +379,16 @@ sub ParseInterface($$)
foreach my $fn (@{$if->{FUNCTIONS}}) {
next if has_property($fn, "noopnum");
next if has_property($fn, "todo");
+
+ my $skip = 0;
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ if (ContainsPipe($e, $e->{LEVELS}[0])) {
+ $skip = 1;
+ last;
+ }
+ }
+ next if $skip;
+
$self->ParseFunction($if->{NAME}, $fn);
}
$self->pidl_hdr("#endif /* __CLI_$uif\__ */");
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
index 0ebccf552c..c4374baf7c 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
@@ -199,6 +199,12 @@ sub ParseFunction($$)
pidl "\treturn false;";
pidl "}";
pidl "";
+ pidl "/*";
+ pidl " * carry over the pointer count to the reply in case we are";
+ pidl " * using full pointer. See NDR specification for full pointers";
+ pidl " */";
+ pidl "push->ptr_count = pull->ptr_count;";
+ pidl "";
pidl "ndr_err = call->ndr_push(push, NDR_OUT, r);";
pidl "if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {";
pidl "\ttalloc_free(r);";
@@ -288,6 +294,7 @@ sub Parse($$$)
pidl " */";
pidl "";
pidl "#include \"includes.h\"";
+ pidl "#include \"ntdomain.h\"";
pidl "#include \"$header\"";
pidl_hdr "#include \"$ndr_header\"";
pidl "";
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4.pm b/tools/pidl/lib/Parse/Pidl/Samba4.pm
index 1deb708689..b720ab9015 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4.pm
@@ -18,12 +18,17 @@ use strict;
use vars qw($VERSION);
$VERSION = '0.01';
+
+# return true if we are using pidl within the samba source tree. This changes
+# the names of include files, as some include files (such as ntstatus.h) have
+# different paths when installed to the patch in the source tree
sub is_intree()
{
my $srcdir = $ENV{srcdir};
$srcdir = $srcdir ? "$srcdir/" : "";
- return 4 if (-f "${srcdir}kdc/kdc.c");
- return 3 if (-f "${srcdir}include/smb.h");
+ return 1 if (-f "${srcdir}kdc/kdc.c");
+ return 1 if (-d "${srcdir}source4");
+ return 1 if (-f "${srcdir}include/smb.h");
return 0;
}
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm b/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm
index 9788b2c123..3736315120 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm
@@ -216,6 +216,30 @@ sub HeaderUnion($$;$)
}
#####################################################################
+# parse a pipe
+sub HeaderPipe($$;$)
+{
+ my($pipe,$name,$tail) = @_;
+
+ my $struct = $pipe->{DATA};
+ my $e = $struct->{ELEMENTS}[1];
+
+ pidl "struct $name;\n";
+ pidl "struct $struct->{NAME} {\n";
+ $tab_depth++;
+ pidl tabs()."uint32_t count;\n";
+ pidl tabs().mapTypeName($e->{TYPE})." *array;\n";
+ $tab_depth--;
+ pidl "}";
+
+ if (defined $struct->{PROPERTIES}) {
+ HeaderProperties($struct->{PROPERTIES}, []);
+ }
+
+ pidl $tail if defined($tail);
+}
+
+#####################################################################
# parse a type
sub HeaderType($$$;$)
{
@@ -225,6 +249,7 @@ sub HeaderType($$$;$)
($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name, $tail);
($data->{TYPE} eq "UNION") && HeaderUnion($data, $name, $tail);
+ ($data->{TYPE} eq "PIPE") && HeaderPipe($data, $name, $tail);
return;
}
@@ -385,6 +410,7 @@ sub HeaderInterface($)
HeaderUnion($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "UNION");
HeaderEnum($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "ENUM");
HeaderBitmap($t, $t->{NAME}) if ($t->{TYPE} eq "BITMAP");
+ HeaderPipe($t, $t->{NAME}, "\n\n") if ($t->{TYPE} eq "PIPE");
}
foreach my $fn (@{$interface->{FUNCTIONS}}) {
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
index 32309580f4..c796b466ad 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
@@ -12,6 +12,7 @@ use Exporter;
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property ParseExpr);
+use Parse::Pidl::NDR qw(ContainsPipe);
use Parse::Pidl::Typelist qw(mapTypeName);
use Parse::Pidl::Samba4 qw(choose_header is_intree DeclLong);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
@@ -44,6 +45,17 @@ sub new($)
bless($self, $class);
}
+sub ParseFunctionHasPipes($$)
+{
+ my ($self, $fn) = @_;
+
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ return 1 if ContainsPipe($e, $e->{LEVELS}[0]);
+ }
+
+ return 0;
+}
+
sub ParseFunction_r_State($$$$)
{
my ($self, $if, $fn, $name) = @_;
@@ -89,10 +101,11 @@ sub ParseFunction_r_Send($$$$)
$self->pidl("");
my $out_params = 0;
- foreach (@{$fn->{ELEMENTS}}) {
- if (grep(/out/, @{$_->{DIRECTION}})) {
- $out_params++;
- }
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless grep(/out/, @{$e->{DIRECTION}});
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
+ $out_params++;
+
}
my $submem;
@@ -200,6 +213,17 @@ sub ParseFunction_r_Sync($$$$)
my ($self, $if, $fn, $name) = @_;
my $uname = uc $name;
+ if ($self->ParseFunctionHasPipes($fn)) {
+ $self->pidl_both("/*");
+ $self->pidl_both(" * The following function is skipped because");
+ $self->pidl_both(" * it uses pipes:");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$name\_r()");
+ $self->pidl_both(" */");
+ $self->pidl_both("");
+ return;
+ }
+
my $proto = "NTSTATUS dcerpc_$name\_r(struct dcerpc_binding_handle *h, TALLOC_CTX *mem_ctx, struct $name *r)";
$self->fn_declare($proto);
@@ -220,49 +244,6 @@ sub ParseFunction_r_Sync($$$$)
$self->pidl("");
}
-sub ParseFunction_Compat_Sync($$$$)
-{
- my ($self, $if, $fn, $name) = @_;
- my $uname = uc $name;
-
- my $proto = "NTSTATUS dcerpc_$name\_compat(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)";
-
- $self->pidl_hdr("#ifdef DCERPC_CALL_$uname\_COMPAT");
- $self->pidl_hdr("#define dcerpc_$name(p, m, r) dcerpc_$name\_compat(p, m, r)");
- $self->pidl_hdr("#endif /* DCERPC_CALL_$uname\_COMPAT */");
-
- $self->fn_declare($proto);
- $self->pidl("{");
- $self->indent;
- $self->pidl("NTSTATUS status;");
- $self->pidl("");
-
- $self->pidl("status = dcerpc_$name\_r(p->binding_handle, mem_ctx, r);");
- $self->pidl("");
-
- $self->pidl("if (NT_STATUS_IS_RPC(status)) {");
- $self->indent;
- $self->pidl("status = NT_STATUS_NET_WRITE_FAULT;");
- $self->deindent;
- $self->pidl("}");
- $self->pidl("");
-
- if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") {
- $self->pidl("if (NT_STATUS_IS_OK(status)) {");
- $self->indent;
- $self->pidl("status = r->out.result;");
- $self->deindent;
- $self->pidl("}");
- $self->pidl("");
- }
-
- $self->pidl("return status;");
-
- $self->deindent;
- $self->pidl("}");
- $self->pidl("");
-}
-
sub ElementDirection($)
{
my ($e) = @_;
@@ -510,6 +491,9 @@ sub ParseFunction_Send($$$$)
next unless grep(/out/, @{$e->{DIRECTION}});
$self->ParseCopyArgument($fn, $e, "state->orig.out.", "_");
+
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
+
$out_params++;
}
$self->pidl("");
@@ -589,6 +573,7 @@ sub ParseFunction_Done($$$$)
$self->pidl("/* Copy out parameters */");
foreach my $e (@{$fn->{ELEMENTS}}) {
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
next unless (grep(/out/, @{$e->{DIRECTION}}));
$self->ParseOutputArgument($fn, $e,
@@ -665,6 +650,17 @@ sub ParseFunction_Sync($$$$)
{
my ($self, $if, $fn, $name) = @_;
+ if ($self->ParseFunctionHasPipes($fn)) {
+ $self->pidl_both("/*");
+ $self->pidl_both(" * The following function is skipped because");
+ $self->pidl_both(" * it uses pipes:");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$name()");
+ $self->pidl_both(" */");
+ $self->pidl_both("");
+ return;
+ }
+
my $uname = uc $name;
my $fn_args = "";
my $fn_str = "NTSTATUS dcerpc_$name";
@@ -682,9 +678,7 @@ sub ParseFunction_Sync($$$$)
$fn_args .= ",\n" . $pad . mapTypeName($fn->{RETURN_TYPE}). " *result";
}
- $self->pidl_hdr("#ifndef DCERPC_CALL_$uname\_COMPAT");
$self->fn_declare("$fn_str($fn_args)");
- $self->pidl_hdr("#endif /* DCERPC_CALL_$uname\_COMPAT */");
$self->pidl("{");
$self->indent;
$self->pidl("struct $name r;");
@@ -709,6 +703,7 @@ sub ParseFunction_Sync($$$$)
$self->pidl("/* Return variables */");
foreach my $e (@{$fn->{ELEMENTS}}) {
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
next unless (grep(/out/, @{$e->{DIRECTION}}));
$self->ParseOutputArgument($fn, $e, "r.", "_", "sync");
@@ -734,14 +729,30 @@ sub ParseFunction($$$)
{
my ($self, $if, $fn) = @_;
+ if ($self->ParseFunctionHasPipes($fn)) {
+ $self->pidl_both("/*");
+ $self->pidl_both(" * The following function is skipped because");
+ $self->pidl_both(" * it uses pipes:");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_r_send()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_r_recv()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_r()");
+ $self->pidl_both(" *");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_send()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}_recv()");
+ $self->pidl_both(" * dcerpc_$fn->{NAME}()");
+ $self->pidl_both(" */");
+ $self->pidl_both("");
+ warning($fn->{ORIGINAL}, "$fn->{NAME}: dcerpc client does not support pipe yet");
+ return;
+ }
+
$self->ParseFunction_r_State($if, $fn, $fn->{NAME});
$self->ParseFunction_r_Send($if, $fn, $fn->{NAME});
$self->ParseFunction_r_Done($if, $fn, $fn->{NAME});
$self->ParseFunction_r_Recv($if, $fn, $fn->{NAME});
$self->ParseFunction_r_Sync($if, $fn, $fn->{NAME});
- $self->ParseFunction_Compat_Sync($if, $fn, $fn->{NAME});
-
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless (grep(/out/, @{$e->{DIRECTION}}));
@@ -811,16 +822,6 @@ sub ParseInterface($$)
$self->pidl_hdr("");
}
- $self->pidl_hdr("#ifdef DCERPC_IFACE_$ifu\_COMPAT");
- foreach my $fn (@{$if->{FUNCTIONS}}) {
- next if has_property($fn, "noopnum");
- next if has_property($fn, "todo");
- my $fnu = uc($fn->{NAME});
- $self->pidl_hdr("#define DCERPC_CALL_$fnu\_COMPAT 1");
- }
- $self->pidl_hdr("#endif /* DCERPC_IFACE_$ifu\_COMPAT */");
- $self->pidl_hdr("");
-
$self->pidl("/* $if->{NAME} - client functions generated by pidl */");
$self->pidl("");
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index 09518f7cee..3d31366abf 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -15,7 +15,7 @@ use strict;
use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody);
use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid unmake_str);
use Parse::Pidl::CUtil qw(get_pointer_to get_value_of get_array_element);
-use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
use Parse::Pidl::Samba4 qw(is_intree choose_header ArrayDynamicallyAllocated);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
use Parse::Pidl qw(warning);
@@ -198,6 +198,12 @@ sub ParseArrayPushHeader($$$$$$)
} else {
$size = $length = "ndr_string_length($var_name, sizeof(*$var_name))";
}
+ if (defined($l->{SIZE_IS})) {
+ $size = ParseExpr($l->{SIZE_IS}, $env, $e);
+ }
+ if (defined($l->{LENGTH_IS})) {
+ $length = ParseExpr($l->{LENGTH_IS}, $env, $e);
+ }
} else {
$size = ParseExpr($l->{SIZE_IS}, $env, $e);
$length = ParseExpr($l->{LENGTH_IS}, $env, $e);
@@ -206,11 +212,11 @@ sub ParseArrayPushHeader($$$$$$)
if ((!$l->{IS_SURROUNDING}) and $l->{IS_CONFORMANT}) {
$self->pidl("NDR_CHECK(ndr_push_uint3264($ndr, NDR_SCALARS, $size));");
}
-
+
if ($l->{IS_VARYING}) {
$self->pidl("NDR_CHECK(ndr_push_uint3264($ndr, NDR_SCALARS, 0));"); # array offset
$self->pidl("NDR_CHECK(ndr_push_uint3264($ndr, NDR_SCALARS, $length));");
- }
+ }
return $length;
}
@@ -352,7 +358,7 @@ sub ParseArrayPullHeader($$$$$$)
$self->pidl("}");
}
- if ($l->{IS_CONFORMANT} and not $l->{IS_ZERO_TERMINATED}) {
+ if ($l->{IS_CONFORMANT} and (defined($l->{SIZE_IS}) or not $l->{IS_ZERO_TERMINATED})) {
$self->defer("if ($var_name) {");
$self->defer_indent;
my $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
@@ -364,7 +370,7 @@ sub ParseArrayPullHeader($$$$$$)
$self->defer("}");
}
- if ($l->{IS_VARYING} and not $l->{IS_ZERO_TERMINATED}) {
+ if ($l->{IS_VARYING} and (defined($l->{LENGTH_IS}) or not $l->{IS_ZERO_TERMINATED})) {
$self->defer("if ($var_name) {");
$self->defer_indent;
my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
@@ -630,6 +636,8 @@ sub ParseElementPush($$$$$$)
my $var_name = $env->{$e->{NAME}};
+ return if ContainsPipe($e, $e->{LEVELS}[0]);
+
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
# Representation type is different from transmit_as
@@ -683,6 +691,9 @@ sub ParsePtrPush($$$$$)
$self->pidl("NDR_CHECK(ndr_push_unique_ptr($ndr, $var_name));");
} elsif ($l->{POINTER_TYPE} eq "full") {
$self->pidl("NDR_CHECK(ndr_push_full_ptr($ndr, $var_name));");
+ } elsif ($l->{POINTER_TYPE} eq "ignore") {
+ # We don't want this pointer to appear on the wire at all
+ $self->pidl("NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, 0));");
} else {
die("Unhandled pointer type $l->{POINTER_TYPE}");
}
@@ -770,7 +781,7 @@ sub ParseElementPrint($$$$$)
$var_name = get_pointer_to($var_name);
}
- if ($l->{IS_ZERO_TERMINATED}) {
+ if ($l->{IS_ZERO_TERMINATED} and not defined($l->{LENGTH_IS})) {
$length = "ndr_string_length($var_name, sizeof(*$var_name))";
} else {
$length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
@@ -945,6 +956,7 @@ sub ParseMemCtxPullFlags($$$$)
if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
my $nl = GetNextLevel($e, $l);
+ return undef if ($nl->{TYPE} eq "PIPE");
return undef if ($nl->{TYPE} eq "ARRAY");
return undef if (($nl->{TYPE} eq "DATA") and ($nl->{DATA_TYPE} eq "string"));
@@ -1149,6 +1161,8 @@ sub ParseElementPull($$$$$$)
my $represent_name;
my $transmit_name;
+ return if ContainsPipe($e, $e->{LEVELS}[0]);
+
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
@@ -1194,7 +1208,7 @@ sub ParsePtrPull($$$$$)
$self->pidl("\tNDR_PULL_ALLOC($ndr, $var_name);");
$self->pidl("}");
}
-
+
return;
} elsif ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "EMBEDDED") {
$self->pidl("NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));");
@@ -1204,6 +1218,10 @@ sub ParsePtrPull($$$$$)
$self->pidl("NDR_CHECK(ndr_pull_generic_ptr($ndr, &_ptr_$e->{NAME}));");
} elsif ($l->{POINTER_TYPE} eq "relative_short") {
$self->pidl("NDR_CHECK(ndr_pull_relative_ptr_short($ndr, &_ptr_$e->{NAME}));");
+ } elsif ($l->{POINTER_TYPE} eq "ignore") {
+ #We want to consume the pointer bytes, but ignore the pointer value
+ $self->pidl("NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &_ptr_$e->{NAME}));");
+ $self->pidl("_ptr_$e->{NAME} = 0;");
} else {
die("Unhandled pointer type $l->{POINTER_TYPE}");
}
@@ -1211,16 +1229,22 @@ sub ParsePtrPull($$$$$)
$self->pidl("if (_ptr_$e->{NAME}) {");
$self->indent;
- # Don't do this for arrays, they're allocated at the actual level
- # of the array
- unless ($next_is_array or $next_is_string) {
- $self->pidl("NDR_PULL_ALLOC($ndr, $var_name);");
+ if ($l->{POINTER_TYPE} eq "ignore") {
+ # Don't do anything, we don't want to do the
+ # allocation, as we forced it to NULL just above, and
+ # we may not know the declared type anyway.
} else {
- # FIXME: Yes, this is nasty.
- # We allocate an array twice
- # - once just to indicate that it's there,
- # - then the real allocation...
- $self->pidl("NDR_PULL_ALLOC($ndr, $var_name);");
+ # Don't do this for arrays, they're allocated at the actual level
+ # of the array
+ unless ($next_is_array or $next_is_string) {
+ $self->pidl("NDR_PULL_ALLOC($ndr, $var_name);");
+ } else {
+ # FIXME: Yes, this is nasty.
+ # We allocate an array twice
+ # - once just to indicate that it's there,
+ # - then the real allocation...
+ $self->pidl("NDR_PULL_ALLOC($ndr, $var_name);");
+ }
}
#$self->pidl("memset($var_name, 0, sizeof($var_name));");
@@ -1255,6 +1279,9 @@ sub ParseStructPushPrimitives($$$$$)
} else {
$size = "ndr_string_length($varname->$e->{NAME}, sizeof(*$varname->$e->{NAME}))";
}
+ if (defined($e->{LEVELS}[0]->{SIZE_IS})) {
+ $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL});
+ }
} else {
$size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL});
}
@@ -1688,16 +1715,21 @@ sub ParseUnionPushPrimitives($$$$)
$self->pidl("uint32_t level = ndr_push_get_switch_value($ndr, $varname);");
- if (defined($e->{ALIGN})) {
- $self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
- }
-
if (defined($e->{SWITCH_TYPE})) {
+ if (defined($e->{ALIGN})) {
+ $self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
+ }
+
$self->pidl("NDR_CHECK(ndr_push_$e->{SWITCH_TYPE}($ndr, NDR_SCALARS, level));");
}
if (defined($e->{ALIGN})) {
- $self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
+ if ($e->{IS_MS_UNION}) {
+ $self->pidl("/* ms_union is always aligned to the largest union arm*/");
+ $self->pidl("NDR_CHECK(ndr_push_align($ndr, $e->{ALIGN}));");
+ } else {
+ $self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
+ }
}
$self->pidl("switch (level) {");
@@ -1837,11 +1869,12 @@ sub ParseUnionPullPrimitives($$$$$)
my ($self,$e,$ndr,$varname,$switch_type) = @_;
my $have_default = 0;
- if (defined($e->{ALIGN})) {
- $self->pidl("NDR_CHECK(ndr_pull_union_align($ndr, $e->{ALIGN}));");
- }
if (defined($switch_type)) {
+ if (defined($e->{ALIGN})) {
+ $self->pidl("NDR_CHECK(ndr_pull_union_align($ndr, $e->{ALIGN}));");
+ }
+
$self->pidl("NDR_CHECK(ndr_pull_$switch_type($ndr, NDR_SCALARS, &_level));");
$self->pidl("if (_level != level) {");
$self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $varname at \%s\", _level, __location__);");
@@ -1849,7 +1882,12 @@ sub ParseUnionPullPrimitives($$$$$)
}
if (defined($e->{ALIGN})) {
- $self->pidl("NDR_CHECK(ndr_pull_union_align($ndr, $e->{ALIGN}));");
+ if ($e->{IS_MS_UNION}) {
+ $self->pidl("/* ms_union is always aligned to the largest union arm*/");
+ $self->pidl("NDR_CHECK(ndr_pull_align($ndr, $e->{ALIGN}));");
+ } else {
+ $self->pidl("NDR_CHECK(ndr_pull_union_align($ndr, $e->{ALIGN}));");
+ }
}
$self->pidl("switch (level) {");
@@ -2051,6 +2089,99 @@ $typefamily{TYPEDEF} = {
SIZE_FN_BODY => \&ParseTypedefNdrSize,
};
+sub ParsePipePushChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "push", $name, $varname);
+
+ $self->fn_declare("push", $struct, "enum ndr_err_code ndr_push_$name(struct ndr_push *$ndr, int ndr_flags, $args)") or return;
+
+ return if has_property($t, "nopush");
+
+ $self->pidl("{");
+ $self->indent;
+
+ $self->ParseStructPush($struct, $ndr, $varname);
+ $self->pidl("");
+
+ $self->pidl("NDR_CHECK(ndr_push_pipe_chunk_trailer(ndr, ndr_flags, $varname->count));");
+ $self->pidl("");
+
+ $self->pidl("return NDR_ERR_SUCCESS;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipePullChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "pull", $name, $varname);
+
+ $self->fn_declare("pull", $struct, "enum ndr_err_code ndr_pull_$name(struct ndr_pull *$ndr, int ndr_flags, $args)") or return;
+
+ return if has_property($struct, "nopull");
+
+ $self->pidl("{");
+ $self->indent;
+
+ $self->ParseStructPull($struct, $ndr, $varname);
+ $self->pidl("");
+
+ $self->pidl("NDR_CHECK(ndr_check_pipe_chunk_trailer($ndr, ndr_flags, $varname->count));");
+ $self->pidl("");
+
+ $self->pidl("return NDR_ERR_SUCCESS;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipePrintChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "print", $name, $varname);
+
+ $self->pidl_hdr("void ndr_print_$name(struct ndr_print *ndr, const char *name, $args);");
+
+ return if (has_property($t, "noprint"));
+
+ $self->pidl("_PUBLIC_ void ndr_print_$name(struct ndr_print *$ndr, const char *name, $args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->ParseTypePrint($struct, $ndr, $varname);
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
#####################################################################
# parse a function - print side
sub ParseFunctionPrint($$)
@@ -2253,6 +2384,7 @@ sub ParseFunctionPull($$)
$e->{LEVELS}[0]->{POINTER_TYPE} eq "ref");
next if (($e->{LEVELS}[1]->{TYPE} eq "DATA") and
($e->{LEVELS}[1]->{DATA_TYPE} eq "string"));
+ next if ($e->{LEVELS}[1]->{TYPE} eq "PIPE");
next if (($e->{LEVELS}[1]->{TYPE} eq "ARRAY")
and $e->{LEVELS}[1]->{IS_ZERO_TERMINATED});
@@ -2268,6 +2400,12 @@ sub ParseFunctionPull($$)
} else {
$self->pidl("memset(r->out.$e->{NAME}, 0, ($size) * sizeof(*r->out.$e->{NAME}));");
}
+ } elsif ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") {
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $self->pidl("r->out.$e->{NAME} = r->in.$e->{NAME};");
+ } else {
+ $self->pidl("r->out.$e->{NAME} = NULL;");
+ }
} else {
$self->pidl("NDR_PULL_ALLOC($ndr, r->out.$e->{NAME});");
@@ -2326,16 +2464,102 @@ sub AuthServiceStruct($$$)
$self->pidl("");
}
+sub ParseGeneratePipeArray($$$)
+{
+ my ($self, $fn, $direction) = @_;
+
+ $self->pidl("static const struct ndr_interface_call_pipe $fn->{NAME}\_$direction\_pipes[] = {");
+ $self->indent;
+
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+ next unless (grep(/$direction/, @{$e->{DIRECTION}}));
+
+ my $cname = "$e->{TYPE}_chunk";
+
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("\"$direction.$e->{NAME}\",");
+ $self->pidl("\"$cname\",");
+ $self->pidl("sizeof(struct $cname),");
+ $self->pidl("(ndr_push_flags_fn_t) ndr_push_$cname,");
+ $self->pidl("(ndr_pull_flags_fn_t) ndr_pull_$cname,");
+ $self->pidl("(ndr_print_fn_t) ndr_print_$cname,");
+ $self->deindent;
+ $self->pidl("},");
+ }
+ $self->pidl("{ NULL, NULL, 0, NULL, NULL, NULL }");
+ $self->deindent;
+ $self->pidl("};");
+ $self->pidl("");
+}
+
+sub FunctionCallPipes($$)
+{
+ my ($self, $d) = @_;
+ return if not defined($d->{OPNUM});
+
+ my $in_pipes = 0;
+ my $out_pipes = 0;
+
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $in_pipes++;
+ }
+ if (grep(/out/, @{$e->{DIRECTION}})) {
+ $out_pipes++;
+ }
+ }
+
+ if ($in_pipes) {
+ $self->ParseGeneratePipeArray($d, "in");
+ }
+
+ if ($out_pipes) {
+ $self->ParseGeneratePipeArray($d, "out");
+ }
+}
+
sub FunctionCallEntry($$)
{
my ($self, $d) = @_;
return 0 if not defined($d->{OPNUM});
+
+ my $in_pipes = 0;
+ my $out_pipes = 0;
+
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $in_pipes++;
+ }
+ if (grep(/out/, @{$e->{DIRECTION}})) {
+ $out_pipes++;
+ }
+ }
+
+ my $in_pipes_ptr = "NULL";
+ my $out_pipes_ptr = "NULL";
+
+ if ($in_pipes) {
+ $in_pipes_ptr = "$d->{NAME}_in_pipes";
+ }
+
+ if ($out_pipes) {
+ $out_pipes_ptr = "$d->{NAME}_out_pipes";
+ }
+
$self->pidl("\t{");
$self->pidl("\t\t\"$d->{NAME}\",");
$self->pidl("\t\tsizeof(struct $d->{NAME}),");
$self->pidl("\t\t(ndr_push_flags_fn_t) ndr_push_$d->{NAME},");
$self->pidl("\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},");
$self->pidl("\t\t(ndr_print_function_t) ndr_print_$d->{NAME},");
+ $self->pidl("\t\t{ $in_pipes, $in_pipes_ptr },");
+ $self->pidl("\t\t{ $out_pipes, $out_pipes_ptr },");
$self->pidl("\t},");
return 1;
}
@@ -2351,6 +2575,10 @@ sub FunctionTable($$)
return if ($#{$interface->{FUNCTIONS}}+1 == 0);
return unless defined ($interface->{PROPERTIES}->{uuid});
+ foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
+ $self->FunctionCallPipes($d);
+ }
+
$self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {");
foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
@@ -2447,10 +2675,9 @@ sub HeaderInterface($$$)
if (defined $interface->{PROPERTIES}->{uuid}) {
my $name = uc $interface->{NAME};
$self->pidl_hdr("#define NDR_$name\_UUID " .
- Parse::Pidl::Util::make_str(lc($interface->{PROPERTIES}->{uuid})));
+ Parse::Pidl::Util::make_str(lc($interface->{UUID})));
- if(!defined $interface->{PROPERTIES}->{version}) { $interface->{PROPERTIES}->{version} = "0.0"; }
- $self->pidl_hdr("#define NDR_$name\_VERSION $interface->{PROPERTIES}->{version}");
+ $self->pidl_hdr("#define NDR_$name\_VERSION $interface->{VERSION}");
$self->pidl_hdr("#define NDR_$name\_NAME \"$interface->{NAME}\"");
@@ -2604,6 +2831,20 @@ sub ParseInterface($$$)
# Typedefs
foreach my $d (@{$interface->{TYPES}}) {
+ if (Parse::Pidl::Typelist::typeIs($d, "PIPE")) {
+ ($needed->{TypeFunctionName("ndr_push", $d)}) &&
+ $self->ParsePipePushChunk($d);
+ ($needed->{TypeFunctionName("ndr_pull", $d)}) &&
+ $self->ParsePipePullChunk($d);
+ ($needed->{TypeFunctionName("ndr_print", $d)}) &&
+ $self->ParsePipePrintChunk($d);
+
+ $needed->{TypeFunctionName("ndr_pull", $d)} = 0;
+ $needed->{TypeFunctionName("ndr_push", $d)} = 0;
+ $needed->{TypeFunctionName("ndr_print", $d)} = 0;
+ next;
+ }
+
next unless(typeHasBody($d));
($needed->{TypeFunctionName("ndr_push", $d)}) && $self->ParseTypePushFunction($d, "r");
@@ -2623,10 +2864,6 @@ sub ParseInterface($$$)
($needed->{"ndr_push_$d->{NAME}"}) && $self->ParseFunctionPush($d);
($needed->{"ndr_pull_$d->{NAME}"}) && $self->ParseFunctionPull($d);
($needed->{"ndr_print_$d->{NAME}"}) && $self->ParseFunctionPrint($d);
-
- # Make sure we don't generate a function twice...
- $needed->{"ndr_push_$d->{NAME}"} = $needed->{"ndr_pull_$d->{NAME}"} =
- $needed->{"ndr_print_$d->{NAME}"} = 0;
}
$self->FunctionTable($interface);
@@ -2749,6 +2986,7 @@ sub NeededType($$$)
my ($t,$needed,$req) = @_;
NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "TYPEDEF");
+ NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "PIPE");
if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "UNION") {
return unless defined($t->{ELEMENTS});
@@ -2770,6 +3008,7 @@ sub NeededInterface($$)
my ($interface,$needed) = @_;
NeededFunction($_, $needed) foreach (@{$interface->{FUNCTIONS}});
foreach (reverse @{$interface->{TYPES}}) {
+
if (has_property($_, "public")) {
$needed->{TypeFunctionName("ndr_pull", $_)} = $needed->{TypeFunctionName("ndr_push", $_)} =
$needed->{TypeFunctionName("ndr_print", $_)} = 1;
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
index 20c94c89e0..1d51fa1526 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
@@ -77,8 +77,8 @@ sub Boilerplate_Iface($)
my($interface) = shift;
my $name = $interface->{NAME};
my $uname = uc $name;
- my $uuid = lc($interface->{PROPERTIES}->{uuid});
- my $if_version = $interface->{PROPERTIES}->{version};
+ my $uuid = lc($interface->{UUID});
+ my $if_version = $interface->{VERSION};
pidl "
static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version)
@@ -251,9 +251,9 @@ static bool $name\__op_interface_by_name(struct dcesrv_interface *iface, const c
return true;
}
- return false;
+ return false;
}
-
+
NTSTATUS dcerpc_server_$name\_init(void)
{
NTSTATUS ret;
@@ -289,6 +289,9 @@ sub ParseInterface($)
my($interface) = shift;
my $count = 0;
+ $res .= "NTSTATUS dcerpc_server_$interface->{NAME}\_init(void);\n";
+ $res .= "\n";
+
if (!defined $interface->{PROPERTIES}->{uuid}) {
return $res;
}
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/Python.pm b/tools/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 3e9178b7e8..db2d79d2f6 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -12,7 +12,7 @@ use strict;
use Parse::Pidl qw(warning fatal error);
use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias);
use Parse::Pidl::Util qw(has_property ParseExpr unmake_str);
-use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
use Parse::Pidl::Samba4 qw(ArrayDynamicallyAllocated);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
@@ -297,9 +297,14 @@ sub PythonStruct($$$$$$)
$self->pidl("{");
$self->indent;
$self->pidl("$cname *object = ($cname *)py_talloc_get_ptr(py_obj);");
+ $self->pidl("PyObject *ret;");
$self->pidl("char *retstr;");
+ $self->pidl("");
$self->pidl("retstr = ndr_print_struct_string(py_talloc_get_mem_ctx(py_obj), (ndr_print_fn_t)ndr_print_$name, \"$name\", object);");
- $self->pidl("return PyString_FromString(retstr);");
+ $self->pidl("ret = PyString_FromString(retstr);");
+ $self->pidl("talloc_free(retstr);");
+ $self->pidl("");
+ $self->pidl("return ret;");
$self->deindent;
$self->pidl("}");
$self->pidl("");
@@ -662,6 +667,15 @@ sub Interface($$$)
next if has_property($d, "nopython");
next if has_property($d, "todo");
+ my $skip = 0;
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ if (ContainsPipe($e, $e->{LEVELS}[0])) {
+ $skip = 1;
+ last;
+ }
+ }
+ next if $skip;
+
my $prettyname = $d->{NAME};
$prettyname =~ s/^$interface->{NAME}_//;
@@ -890,7 +904,7 @@ sub ConvertObjectFromPythonData($$$$$$;$)
$self->pidl("}");
return;
}
- if (expandAlias($actual_ctype->{NAME}) =~ /^(char|u?int[0-9]*|time_t)$/) {
+ if (expandAlias($actual_ctype->{NAME}) =~ /^(char|u?int[0-9]*|time_t|uid_t|gid_t)$/) {
$self->pidl("PY_CHECK_TYPE(&PyInt_Type, $cvar, $fail);");
$self->pidl("$target = PyInt_AsLong($cvar);");
return;
@@ -979,12 +993,15 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
{
my ($self, $env, $mem_ctx, $py_var, $e, $l, $var_name, $fail) = @_;
my $nl = GetNextLevel($e, $l);
+ if ($nl and $nl->{TYPE} eq "SUBCONTEXT") {
+ $nl = GetNextLevel($e, $nl);
+ }
+ my $pl = GetPrevLevel($e, $l);
+ if ($pl and $pl->{TYPE} eq "SUBCONTEXT") {
+ $pl = GetPrevLevel($e, $pl);
+ }
if ($l->{TYPE} eq "POINTER") {
- if ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail);
- return;
- }
if ($l->{POINTER_TYPE} ne "ref") {
$self->pidl("if ($py_var == Py_None) {");
$self->indent;
@@ -997,16 +1014,21 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
# then this is where we would need to allocate it
if ($l->{POINTER_TYPE} eq "ref") {
$self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
+ } elsif ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::is_scalar($nl->{DATA_TYPE})
+ and not Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
+ $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
} else {
$self->pidl("$var_name = NULL;");
}
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, get_value_of($var_name), $fail);
+ unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
+ $var_name = get_value_of($var_name);
+ }
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail);
if ($l->{POINTER_TYPE} ne "ref") {
$self->deindent;
$self->pidl("}");
}
} elsif ($l->{TYPE} eq "ARRAY") {
- my $pl = GetPrevLevel($e, $l);
if ($pl && $pl->{TYPE} eq "POINTER") {
$var_name = get_pointer_to($var_name);
}
@@ -1024,7 +1046,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
$self->pidl("} else {");
$self->indent;
$self->pidl("PyErr_Format(PyExc_TypeError, \"Expected string or unicode object, got %s\", Py_TYPE($py_var)->tp_name);");
- $self->pidl("$fail;");
+ $self->pidl("$fail");
$self->deindent;
$self->pidl("}");
} else {
@@ -1040,7 +1062,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
}
$self->pidl("for ($counter = 0; $counter < PyList_GET_SIZE($py_var); $counter++) {");
$self->indent;
- $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GET_ITEM($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail);
+ $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, $var_name."[$counter]", $fail);
$self->deindent;
$self->pidl("}");
$self->deindent;
@@ -1057,15 +1079,15 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
my $switch_ptr = "$e->{NAME}_switch_$l->{LEVEL_INDEX}";
$self->pidl("{");
$self->indent;
- my $union_type = mapTypeName(GetNextLevel($e, $l)->{DATA_TYPE});
+ my $union_type = mapTypeName($nl->{DATA_TYPE});
$self->pidl("$union_type *$switch_ptr;");
- $self->pidl("$switch_ptr = py_export_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $py_var);");
- $self->pidl("if ($switch_ptr == NULL) { $fail }");
+ $self->pidl("$switch_ptr = py_export_" . $nl->{DATA_TYPE} . "($mem_ctx, $switch, $py_var);");
+ $self->fail_on_null($switch_ptr, $fail);
$self->assign($var_name, "$switch_ptr");
$self->deindent;
$self->pidl("}");
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
- $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail);
} else {
fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}");
}
@@ -1090,7 +1112,7 @@ sub ConvertScalarToPython($$$)
return "PyLong_FromLongLong($cvar)";
}
- if ($ctypename =~ /^(char|u?int[0-9]*|time_t)$/) {
+ if ($ctypename =~ /^(char|u?int[0-9]*|time_t|uid_t|gid_t)$/) {
return "PyInt_FromLong($cvar)";
}
@@ -1107,19 +1129,19 @@ sub ConvertScalarToPython($$$)
}
if (($ctypename eq "string" or $ctypename eq "nbt_string" or $ctypename eq "nbt_name" or $ctypename eq "wrepl_nbt_name")) {
- return "PyString_FromString_check_null($cvar)";
+ return "PyString_FromStringOrNULL($cvar)";
}
if (($ctypename eq "dns_string" or $ctypename eq "dns_name")) {
- return "PyString_FromString_check_null($cvar)";
+ return "PyString_FromStringOrNULL($cvar)";
}
# Not yet supported
if ($ctypename eq "string_array") { return "PyCObject_FromTallocPtr($cvar)"; }
- if ($ctypename eq "ipv4address") { return "PyString_FromString_check_null($cvar)"; }
- if ($ctypename eq "ipv6address") { return "PyString_FromString_check_null($cvar)"; }
- if ($ctypename eq "dnsp_name") { return "PyString_FromString_check_null($cvar)"; }
- if ($ctypename eq "dnsp_string") { return "PyString_FromString_check_null($cvar)"; }
+ if ($ctypename eq "ipv4address") { return "PyString_FromStringOrNULL($cvar)"; }
+ if ($ctypename eq "ipv6address") { return "PyString_FromStringOrNULL($cvar)"; }
+ if ($ctypename eq "dnsp_name") { return "PyString_FromStringOrNULL($cvar)"; }
+ if ($ctypename eq "dnsp_string") { return "PyString_FromStringOrNULL($cvar)"; }
if ($ctypename eq "pointer") {
return "PyCObject_FromTallocPtr($cvar)";
}
@@ -1174,12 +1196,15 @@ sub ConvertObjectToPythonLevel($$$$$$)
{
my ($self, $mem_ctx, $env, $e, $l, $var_name, $py_var, $fail) = @_;
my $nl = GetNextLevel($e, $l);
+ if ($nl and $nl->{TYPE} eq "SUBCONTEXT") {
+ $nl = GetNextLevel($e, $nl);
+ }
+ my $pl = GetPrevLevel($e, $l);
+ if ($pl and $pl->{TYPE} eq "SUBCONTEXT") {
+ $pl = GetPrevLevel($e, $pl);
+ }
if ($l->{TYPE} eq "POINTER") {
- if ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
- $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name, $py_var, $fail);
- return;
- }
if ($l->{POINTER_TYPE} ne "ref") {
$self->pidl("if ($var_name == NULL) {");
$self->indent;
@@ -1189,13 +1214,16 @@ sub ConvertObjectToPythonLevel($$$$$$)
$self->pidl("} else {");
$self->indent;
}
- $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, get_value_of($var_name), $py_var, $fail);
+ my $var_name2 = $var_name;
+ unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
+ $var_name2 = get_value_of($var_name);
+ }
+ $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name2, $py_var, $fail);
if ($l->{POINTER_TYPE} ne "ref") {
$self->deindent;
$self->pidl("}");
}
} elsif ($l->{TYPE} eq "ARRAY") {
- my $pl = GetPrevLevel($e, $l);
if ($pl && $pl->{TYPE} eq "POINTER") {
$var_name = get_pointer_to($var_name);
}
@@ -1230,7 +1258,7 @@ sub ConvertObjectToPythonLevel($$$$$$)
$self->indent;
my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}";
$self->pidl("PyObject *$member_var;");
- $self->ConvertObjectToPythonLevel($var_name, $env, $e, GetNextLevel($e, $l), $var_name."[$counter]", $member_var, $fail);
+ $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name."[$counter]", $member_var, $fail);
$self->pidl("PyList_SetItem($py_var, $counter, $member_var);");
$self->deindent;
$self->pidl("}");
@@ -1240,7 +1268,7 @@ sub ConvertObjectToPythonLevel($$$$$$)
} elsif ($l->{TYPE} eq "SWITCH") {
$var_name = get_pointer_to($var_name);
my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e);
- $self->pidl("$py_var = py_import_" . GetNextLevel($e, $l)->{DATA_TYPE} . "($mem_ctx, $switch, $var_name);");
+ $self->pidl("$py_var = py_import_" . $nl->{DATA_TYPE} . "($mem_ctx, $switch, $var_name);");
$self->fail_on_null($py_var, $fail);
} elsif ($l->{TYPE} eq "DATA") {
@@ -1250,7 +1278,7 @@ sub ConvertObjectToPythonLevel($$$$$$)
my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $e->{ORIGINAL});
$self->pidl("$py_var = $conv;");
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
- $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, GetNextLevel($e, $l), $var_name, $py_var, $fail);
+ $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, $nl, $var_name, $py_var, $fail);
} else {
fatal($e->{ORIGINAL}, "Unknown level type $l->{TYPE} $var_name");
}
@@ -1273,7 +1301,7 @@ sub Parse($$$$$)
/* Python wrapper functions auto-generated by pidl */
#include <Python.h>
#include \"includes.h\"
-#include \"lib/talloc/pytalloc.h\"
+#include <pytalloc.h>
#include \"librpc/rpc/pyrpc.h\"
#include \"librpc/rpc/pyrpc_util.h\"
#include \"$hdr\"
@@ -1299,6 +1327,7 @@ sub Parse($$$$$)
$self->pidl("");
+ $self->pidl_hdr("void init$basename(void);");
$self->pidl("void init$basename(void)");
$self->pidl("{");
$self->indent;
diff --git a/tools/pidl/lib/Parse/Pidl/Typelist.pm b/tools/pidl/lib/Parse/Pidl/Typelist.pm
index 4733f91565..4f26a92ed2 100644
--- a/tools/pidl/lib/Parse/Pidl/Typelist.pm
+++ b/tools/pidl/lib/Parse/Pidl/Typelist.pm
@@ -8,8 +8,8 @@ package Parse::Pidl::Typelist;
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(hasType getType resolveType mapTypeName scalar_is_reference expandAlias
- mapScalarType addType typeIs is_signed is_scalar enum_type_fn
- bitmap_type_fn mapType typeHasBody
+ mapScalarType addType typeIs is_signed is_scalar enum_type_fn
+ bitmap_type_fn mapType typeHasBody is_fixed_size_scalar
);
use vars qw($VERSION);
$VERSION = '0.01';
@@ -21,7 +21,13 @@ my %types = ();
my @reference_scalars = (
"string", "string_array", "nbt_string", "dns_string",
- "wrepl_nbt_name", "ipv4address", "ipv6address"
+ "wrepl_nbt_name", "dnsp_name", "dnsp_string",
+ "ipv4address", "ipv6address"
+);
+
+my @non_fixed_size_scalars = (
+ "string", "string_array", "nbt_string", "dns_string",
+ "wrepl_nbt_name", "dnsp_name", "dnsp_string"
);
# a list of known scalar types
@@ -48,6 +54,8 @@ my %scalars = (
"string" => "const char *",
"string_array" => "const char **",
"time_t" => "time_t",
+ "uid_t" => "uid_t",
+ "gid_t" => "gid_t",
"NTTIME" => "NTTIME",
"NTTIME_1sec" => "NTTIME",
"NTTIME_hyper" => "NTTIME",
@@ -128,6 +136,7 @@ sub getType($)
return $types{$t};
}
+sub typeIs($$);
sub typeIs($$)
{
my ($t,$tt) = @_;
@@ -187,6 +196,15 @@ sub is_scalar($)
return 0;
}
+sub is_fixed_size_scalar($)
+{
+ my $name = shift;
+
+ return 0 unless is_scalar($name);
+ return 0 if (grep(/^$name$/, @non_fixed_size_scalars));
+ return 1;
+}
+
sub scalar_is_reference($)
{
my $name = shift;
@@ -273,6 +291,7 @@ sub mapType($$)
return "struct $n" if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "INTERFACE");
return "union $n" if ($t->{TYPE} eq "UNION");
return mapScalarType(bitmap_type_fn($t)) if ($t->{TYPE} eq "BITMAP");
+ return "struct $n" if ($t->{TYPE} eq "PIPE");
die("Unknown type $t->{TYPE}");
}
@@ -311,11 +330,12 @@ sub LoadIdl($;$)
}) if (has_property($x, "object"));
foreach my $y (@{$x->{DATA}}) {
- if ($y->{TYPE} eq "TYPEDEF"
- or $y->{TYPE} eq "UNION"
- or $y->{TYPE} eq "STRUCT"
- or $y->{TYPE} eq "ENUM"
- or $y->{TYPE} eq "BITMAP") {
+ if ($y->{TYPE} eq "TYPEDEF"
+ or $y->{TYPE} eq "UNION"
+ or $y->{TYPE} eq "STRUCT"
+ or $y->{TYPE} eq "ENUM"
+ or $y->{TYPE} eq "BITMAP"
+ or $y->{TYPE} eq "PIPE") {
$y->{BASEFILE} = $basename;
addType($y);
}
diff --git a/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm b/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
index 64b8dcf18c..46c9850b56 100644
--- a/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
@@ -270,11 +270,9 @@ sub Bitmap($$$$)
$self->register_type($name, "offset = $dissectorname(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);", "FT_UINT$size", "BASE_HEX", "0", "NULL", $size/8);
}
-sub ElementLevel($$$$$$$)
+sub ElementLevel($$$$$$$$)
{
- my ($self,$e,$l,$hf,$myname,$pn,$ifname) = @_;
-
- my $param = 0;
+ my ($self,$e,$l,$hf,$myname,$pn,$ifname,$param) = @_;
if (defined($self->{conformance}->{dissectorparams}->{$myname})) {
$param = $self->{conformance}->{dissectorparams}->{$myname}->{PARAM};
@@ -323,9 +321,19 @@ sub ElementLevel($$$$$$$)
$self->pidl_code("proto_item_append_text(tree, \": %s\", data);");
} elsif (property_matches($e, "flag", ".*LIBNDR_FLAG_STR_SIZE4.*")) {
$self->pidl_code("offset = dissect_ndr_vstring(tvb, offset, pinfo, tree, drep, $bs, $hf, FALSE, NULL);");
+ } elsif (property_matches($e, "flag", ".*STR_NULLTERM.*")) {
+ if ($bs == 2) {
+ $self->pidl_code("offset = dissect_null_term_wstring(tvb, offset, pinfo, tree, drep, $hf , 0);")
+ } else {
+ $self->pidl_code("offset = dissect_null_term_string(tvb, offset, pinfo, tree, drep, $hf , 0);")
+ }
} else {
warn("Unable to handle string with flags $e->{PROPERTIES}->{flag}");
}
+ } elsif ($l->{DATA_TYPE} eq "DATA_BLOB") {
+ my $remain = 0;
+ $remain = 1 if (property_matches($e->{ORIGINAL}, "flag", ".*LIBNDR_FLAG_REMAINING.*"));
+ $self->pidl_code("offset = dissect_ndr_datablob(tvb, offset, pinfo, tree, drep, $hf, $remain);");
} else {
my $call;
@@ -350,27 +358,65 @@ sub ElementLevel($$$$$$$)
$self->pidl_code($call);
}
} elsif ($_->{TYPE} eq "SUBCONTEXT") {
+ my $varswitch;
+ if (has_property($e, "switch_is")) {
+ $varswitch = $e->{PROPERTIES}->{switch_is};
+ }
my $num_bits = ($l->{HEADER_SIZE}*8);
+ my $hf2 = $self->register_hf_field($hf."_", "Subcontext length", "$ifname.$pn.$_->{NAME}subcontext", "FT_UINT$num_bits", "BASE_HEX", "NULL", 0, "");
+ $self->{hf_used}->{$hf2} = 1;
+ $self->pidl_code("dcerpc_info *di = pinfo->private_data;");
$self->pidl_code("guint$num_bits size;");
- $self->pidl_code("int start_offset = offset;");
+ $self->pidl_code("int conformant = di->conformant_run;");
$self->pidl_code("tvbuff_t *subtvb;");
- $self->pidl_code("offset = dissect_ndr_uint$num_bits(tvb, offset, pinfo, tree, drep, $hf, &size);");
- $self->pidl_code("proto_tree_add_text(tree, tvb, start_offset, offset - start_offset + size, \"Subcontext size\");");
+ $self->pidl_code("");
+ # We need to be able to dissect the length of the context in every case
+ # and conformant run skips the dissections of scalars ...
+ $self->pidl_code("if (!conformant) {");
+ $self->indent;
+ $self->pidl_code("offset = dissect_ndr_uint$num_bits(tvb, offset, pinfo, tree, drep, $hf2, &size);");
$self->pidl_code("subtvb = tvb_new_subset(tvb, offset, size, -1);");
- $self->pidl_code("$myname\_(subtvb, 0, pinfo, tree, drep);");
+ if ($param ne 0) {
+ $self->pidl_code("$myname\_(subtvb, 0, pinfo, tree, drep, $param);");
+ } else {
+ $self->pidl_code("$myname\_(subtvb, 0, pinfo, tree, drep);");
+ }
+ $self->pidl_code("offset += size;");
+ $self->deindent;
+ $self->pidl_code("}");
} else {
die("Unknown type `$_->{TYPE}'");
}
}
-sub Element($$$)
+sub Element($$$$$)
{
- my ($self,$e,$pn,$ifname) = @_;
+ my ($self,$e,$pn,$ifname,$isoruseswitch) = @_;
my $dissectorname = "$ifname\_dissect\_element\_".StripPrefixes($pn, $self->{conformance}->{strip_prefixes})."\_".StripPrefixes($e->{NAME}, $self->{conformance}->{strip_prefixes});
- my $call_code = "offset = $dissectorname(tvb, offset, pinfo, tree, drep);";
+ my ($call_code, $moreparam);
+ my $param = 0;
+ if (defined $isoruseswitch) {
+ my $type = $isoruseswitch->[0];
+ my $name = $isoruseswitch->[1];
+
+ my $switch_dt = getType($type);
+ my $switch_type;
+ if ($switch_dt->{DATA}->{TYPE} eq "ENUM") {
+ $switch_type = "g".Parse::Pidl::Typelist::enum_type_fn($switch_dt->{DATA});
+ } elsif ($switch_dt->{DATA}->{TYPE} eq "SCALAR") {
+ $switch_type = "g$e->{SWITCH_TYPE}";
+ }
+ $moreparam = ", $switch_type *".$name;
+ $param = $name;
+ $call_code = "offset = $dissectorname(tvb, offset, pinfo, tree, drep, &$name);";
+ } else {
+ $moreparam = "";
+ $call_code = "offset = $dissectorname(tvb, offset, pinfo, tree, drep);";
+ }
+
my $type = $self->find_type($e->{TYPE});
@@ -403,16 +449,24 @@ sub Element($$$)
my $add = "";
+ my $oldparam = undef;
foreach (@{$e->{LEVELS}}) {
+ if (defined $_->{SWITCH_IS}) {
+ $oldparam = $param;
+ $param = "*$param";
+ }
next if ($_->{TYPE} eq "SWITCH");
- $self->pidl_def("static int $dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_);");
+ $self->pidl_def("static int $dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_$moreparam);");
$self->pidl_fn_start("$dissectorname$add");
$self->pidl_code("static int");
- $self->pidl_code("$dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_)");
+ $self->pidl_code("$dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_$moreparam)");
$self->pidl_code("{");
$self->indent;
- $self->ElementLevel($e,$_,$hf,$dissectorname.$add,$pn,$ifname);
+ $self->ElementLevel($e,$_,$hf,$dissectorname.$add,$pn,$ifname,$param);
+ if (defined $oldparam) {
+ $param = $oldparam;
+ }
$self->pidl_code("");
$self->pidl_code("return offset;");
@@ -433,7 +487,7 @@ sub Function($$$)
my %dissectornames;
foreach (@{$fn->{ELEMENTS}}) {
- $dissectornames{$_->{NAME}} = $self->Element($_, $fn->{NAME}, $ifname) if not defined($dissectornames{$_->{NAME}});
+ $dissectornames{$_->{NAME}} = $self->Element($_, $fn->{NAME}, $ifname, undef) if not defined($dissectornames{$_->{NAME}});
}
my $fn_name = $_->{NAME};
@@ -534,7 +588,40 @@ sub Struct($$$$)
$self->register_ett("ett_$ifname\_$name");
my $res = "";
- ($res.="\t".$self->Element($_, $name, $ifname)."\n\n") foreach (@{$e->{ELEMENTS}});
+ my $varswitchs = {};
+ # will contain the switch var declaration;
+ my $vars = [];
+ foreach (@{$e->{ELEMENTS}}) {
+ if (has_property($_, "switch_is")) {
+ $varswitchs->{$_->{PROPERTIES}->{switch_is}} = [];
+ }
+ }
+ foreach (@{$e->{ELEMENTS}}) {
+ my $switch_info = undef;
+
+ my $v = $_->{NAME};
+ if (scalar(grep {/$v/} keys(%$varswitchs)) == 1) {
+ # This element is one of the switch attribute
+ my $switch_dt = getType($_->{TYPE});
+ my $switch_type;
+ if ($switch_dt->{DATA}->{TYPE} eq "ENUM") {
+ $switch_type = "g".Parse::Pidl::Typelist::enum_type_fn($switch_dt->{DATA});
+ } elsif ($switch_dt->{DATA}->{TYPE} eq "SCALAR") {
+ $switch_type = "g$e->{SWITCH_TYPE}";
+ }
+
+ push @$vars, "$switch_type $v;";
+ $switch_info = [ $_->{TYPE}, $v ];
+ $varswitchs->{$v} = $switch_info;
+ }
+
+ if (has_property($_, "switch_is")) {
+ my $varswitch = $_->{PROPERTIES}->{switch_is};
+ $switch_info = $varswitchs->{$varswitch};
+ }
+
+ $res.="\t".$self->Element($_, $name, $ifname, $switch_info)."\n\n";
+ }
$self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_);");
@@ -543,6 +630,7 @@ sub Struct($$$$)
$self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)");
$self->pidl_code("{");
$self->indent;
+ $self->pidl_code($_) foreach (@$vars);
$self->pidl_code("proto_item *item = NULL;");
$self->pidl_code("proto_tree *tree = NULL;");
if ($e->{ALIGN} > 1) {
@@ -551,7 +639,7 @@ sub Struct($$$$)
$self->pidl_code("int old_offset;");
$self->pidl_code("");
- if ($e->{ALIGN} > 1) {
+ if ($e->{ALIGN} > 1 and not property_matches($e, "flag", ".*LIBNDR_FLAG_NOALIGN.*")) {
$self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
}
$self->pidl_code("");
@@ -599,7 +687,7 @@ sub Union($$$$)
foreach (@{$e->{ELEMENTS}}) {
$res.="\n\t\t$_->{CASE}:\n";
if ($_->{TYPE} ne "EMPTY") {
- $res.="\t\t\t".$self->Element($_, $name, $ifname)."\n";
+ $res.="\t\t\t".$self->Element($_, $name, $ifname, undef)."\n";
}
$res.="\t\tbreak;\n";
}
@@ -623,7 +711,11 @@ sub Union($$$$)
$self->pidl_code("proto_item *item = NULL;");
$self->pidl_code("proto_tree *tree = NULL;");
$self->pidl_code("int old_offset;");
- $self->pidl_code("$switch_type level;");
+ if (!defined $switch_type) {
+ $self->pidl_code("guint32 level = param;");
+ } else {
+ $self->pidl_code("$switch_type level;");
+ }
$self->pidl_code("");
$self->pidl_code("old_offset = offset;");
@@ -636,11 +728,13 @@ sub Union($$$$)
$self->pidl_code("");
- $self->pidl_code("offset = $switch_dissect(tvb, offset, pinfo, tree, drep, hf_index, &level);");
+ if (defined $switch_type) {
+ $self->pidl_code("offset = $switch_dissect(tvb, offset, pinfo, tree, drep, hf_index, &level);");
- if ($e->{ALIGN} > 1) {
- $self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
- $self->pidl_code("");
+ if ($e->{ALIGN} > 1) {
+ $self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
+ $self->pidl_code("");
+ }
}
@@ -770,8 +864,8 @@ sub ProcessImport
my @imports = @_;
foreach (@imports) {
next if($_ eq "security");
- s/\.idl\"$//;
s/^\"//;
+ s/\.idl"?$//;
$self->pidl_hdr("#include \"packet-dcerpc-$_\.h\"");
}
$self->pidl_hdr("");
@@ -811,7 +905,7 @@ sub ProcessInterface($$)
. ", 0x" . substr($if_uuid, 35, 2) . " }");
$self->pidl_def("};");
- my $maj = $x->{VERSION};
+ my $maj = 0x0000FFFF & $x->{VERSION};
$maj =~ s/\.(.*)$//g;
$self->pidl_def("static guint16 ver_dcerpc_$x->{NAME} = $maj;");
$self->pidl_def("");
@@ -820,7 +914,6 @@ sub ProcessInterface($$)
$return_types{$x->{NAME}} = {};
$self->Interface($x);
-
$self->pidl_code("\n".DumpFunctionTable($x));
foreach (keys %{$return_types{$x->{NAME}}}) {
@@ -879,6 +972,7 @@ sub Initialize($$)
$self->register_type("int$bits", "offset = PIDL_dissect_uint$bits(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);", "FT_INT$bits", "BASE_DEC", 0, "NULL", $bytes);
}
+ $self->register_type("hyper", "offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, drep, \@HF\@, NULL);", "FT_UINT64", "BASE_DEC", 0, "NULL", 8);
$self->register_type("udlong", "offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, drep, \@HF\@, NULL);", "FT_UINT64", "BASE_DEC", 0, "NULL", 4);
$self->register_type("bool8", "offset = PIDL_dissect_uint8(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_INT8", "BASE_DEC", 0, "NULL", 1);
$self->register_type("char", "offset = PIDL_dissect_uint8(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_INT8", "BASE_DEC", 0, "NULL", 1);