use Parse::Pidl qw(warning error fatal);
use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
use Parse::Pidl::Util qw(ParseExpr has_property is_constant);
-use Parse::Pidl::NDR qw(GetNextLevel);
+use Parse::Pidl::NDR qw(GetNextLevel ContainsPipe);
use Parse::Pidl::Samba4 qw(ElementStars DeclLong);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionOutEnv);
my $res;
my $res_hdr;
my $tabs = "";
+sub pidl_reset() { $res=""; $res_hdr="", $tabs=""; }
+sub pidl_return() { my $s = $res; my $h = $res_hdr; pidl_reset(); return ($s, $h) }
sub indent() { $tabs.="\t"; }
sub deindent() { $tabs = substr($tabs, 1); }
sub pidl($) { my ($txt) = @_; $res .= $txt?$tabs.(shift)."\n":"\n"; }
return $res;
}
-sub AllocOutVar($$$$$)
+sub AllocOutVar($$$$$$$)
{
- my ($e, $mem_ctx, $name, $env, $fail) = @_;
+ my ($e, $mem_ctx, $name, $env, $check, $cleanup, $return) = @_;
my $l = $e->{LEVELS}[0];
pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");";
}
- pidl "if ($name == NULL) {";
- $fail->();
+ pidl "if (" . $check->($name) . ") {";
+ indent;
+ pidl $cleanup->($name) if defined($cleanup);
+ pidl $return->($name) if defined($return);
+ deindent;
pidl "}";
pidl "";
}
-sub CallWithStruct($$$$)
+sub CallWithStruct($$$$$$)
{
- my ($pipes_struct, $mem_ctx, $fn, $fail) = @_;
+ my ($pipes_struct, $mem_ctx, $fn, $check, $cleanup, $return) = @_;
my $env = GenerateFunctionOutEnv($fn);
my $hasout = 0;
foreach (@{$fn->{ELEMENTS}}) {
if (grep(/out/, @{$_->{DIRECTION}})) { $hasout = 1; }
}
- pidl "ZERO_STRUCT(r->out);" if ($hasout);
+ pidl "NDR_ZERO_STRUCT(r->out);" if ($hasout);
- my $proto = "_$fn->{NAME}(pipes_struct *p, struct $fn->{NAME} *r";
- my $ret = "_$fn->{NAME}($pipes_struct, r";
foreach (@{$fn->{ELEMENTS}}) {
my @dir = @{$_->{DIRECTION}};
if (grep(/in/, @dir) and grep(/out/, @dir)) {
}
foreach (@{$fn->{ELEMENTS}}) {
+ next if ContainsPipe($_, $_->{LEVELS}[0]);
my @dir = @{$_->{DIRECTION}};
if (grep(/in/, @dir) and grep(/out/, @dir)) {
# noop
} elsif (grep(/out/, @dir) and not
has_property($_, "represent_as")) {
- AllocOutVar($_, $mem_ctx, "r->out.$_->{NAME}", $env, $fail);
+ AllocOutVar($_, $mem_ctx, "r->out.$_->{NAME}", $env,
+ $check, $cleanup, $return);
}
}
- $ret .= ")";
- $proto .= ");";
+
+ my $proto = "_$fn->{NAME}(struct pipes_struct *p, struct $fn->{NAME} *r)";
+ my $ret = "_$fn->{NAME}($pipes_struct, r)";
if ($fn->{RETURN_TYPE}) {
$ret = "r->out.result = $ret";
- $proto = "$fn->{RETURN_TYPE} $proto";
+ $proto = mapTypeName($fn->{RETURN_TYPE})." $proto";
} else {
$proto = "void $proto";
}
- pidl_hdr "$proto";
+ pidl_hdr "$proto;";
pidl "$ret;";
}
my $op = "NDR_".uc($fn->{NAME});
- pidl "static bool api_$fn->{NAME}(pipes_struct *p)";
+ pidl "static bool api_$fn->{NAME}(struct pipes_struct *p)";
pidl "{";
indent;
pidl "const struct ndr_interface_call *call;";
pidl "}";
pidl "";
pidl "if (DEBUGLEVEL >= 10) {";
- pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, r);";
+ pidl "\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_IN, r);";
pidl "}";
pidl "";
- CallWithStruct("p", "r", $fn,
- sub {
- pidl "\ttalloc_free(r);";
- pidl "\treturn false;";
+ CallWithStruct("p", "r", $fn,
+ sub ($) {
+ my ($name) = @_;
+ return "${name} == NULL";
+ },
+ sub ($) {
+ my ($name) = @_;
+ return "talloc_free(r);";
+ },
+ sub ($) {
+ my ($name) = @_;
+ return "return false;";
}
);
pidl "";
- pidl "if (p->rng_fault_state) {";
+ pidl "if (p->fault_state) {";
pidl "\ttalloc_free(r);";
pidl "\t/* Return true here, srv_pipe_hnd.c will take care */";
pidl "\treturn true;";
pidl "}";
pidl "";
pidl "if (DEBUGLEVEL >= 10) {";
- pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, r);";
+ pidl "\tNDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_OUT | NDR_SET_VALUES, r);";
pidl "}";
pidl "";
pidl "push = ndr_push_init_ctx(r);";
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);";
pidl "";
pidl "/* Tables */";
- pidl "static struct api_struct api_$if->{NAME}_cmds[] = ";
+ pidl "static const struct api_struct api_$if->{NAME}_cmds[] = ";
pidl "{";
indent;
pidl "";
- pidl_hdr "void $if->{NAME}_get_pipe_fns(struct api_struct **fns, int *n_fns);";
- pidl "void $if->{NAME}_get_pipe_fns(struct api_struct **fns, int *n_fns)";
+ pidl_hdr "const struct api_struct *$if->{NAME}_get_pipe_fns(int *n_fns);";
+ pidl "const struct api_struct *$if->{NAME}_get_pipe_fns(int *n_fns)";
pidl "{";
indent;
- pidl "*fns = api_$if->{NAME}_cmds;";
pidl "*n_fns = sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct);";
+ pidl "return api_$if->{NAME}_cmds;";
deindent;
pidl "}";
pidl "";
if (not has_property($if, "no_srv_register")) {
- pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);";
- pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
+ pidl_hdr "struct rpc_srv_callbacks;";
+ pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb);";
+ pidl "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb)";
+ pidl "{";
+ pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct), rpc_srv_cb);";
+ pidl "}";
+
+ pidl "";
+
+ pidl_hdr "NTSTATUS rpc_$if->{NAME}_shutdown(void);";
+ pidl "NTSTATUS rpc_$if->{NAME}_shutdown(void)";
pidl "{";
- pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));";
+ pidl "\treturn rpc_srv_unregister(\&ndr_table_$if->{NAME});";
pidl "}";
}
pidl_hdr "#endif /* __SRV_$uif\__ */";
{
my($ndr,$header,$ndr_header) = @_;
- $res = "";
- $res_hdr = "";
+ pidl_reset();
pidl "/*";
pidl " * Unix SMB/CIFS implementation.";
pidl " */";
pidl "";
pidl "#include \"includes.h\"";
+ pidl "#include \"ntdomain.h\"";
pidl "#include \"$header\"";
pidl_hdr "#include \"$ndr_header\"";
pidl "";
ParseInterface($_) if ($_->{TYPE} eq "INTERFACE");
}
- return ($res, $res_hdr);
+ return pidl_return();
}
1;