From 5130e664b91636a9ca31a52897ba1d121d0252a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Aug 2010 21:01:25 +0200 Subject: pidl:Samba3/ClientNDR: implement rpccli_ stubs on top of dcerpc_ stubs metze --- pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm | 122 ++++++++++---------------------- pidl/pidl | 7 +- pidl/tests/samba3-cli.pl | 102 ++++++-------------------- 3 files changed, 62 insertions(+), 169 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm index cb6c1f252a..24f87b6063 100644 --- a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm +++ b/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::Typelist qw(mapTypeName); use Parse::Pidl::Samba4 qw(DeclLong); use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv); @@ -166,10 +167,10 @@ sub ParseFunctionAsyncState($$$) $self->pidl("$state_str {"); $self->indent; - $self->pidl("struct $fn->{NAME} orig;"); - $self->pidl("struct $fn->{NAME} tmp;"); $self->pidl("TALLOC_CTX *out_mem_ctx;"); - $self->pidl("NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);"); + if (defined($fn->{RETURN_TYPE})) { + $self->pidl(mapTypeName($fn->{RETURN_TYPE}). " result;"); + } $self->deindent; $self->pidl("};"); $self->pidl(""); @@ -215,32 +216,14 @@ sub ParseFunctionAsyncSend($$$) $self->deindent; $self->pidl("}"); $self->pidl("state->out_mem_ctx = NULL;"); - $self->pidl("state->dispatch_recv = cli->dispatch_recv;"); - $self->pidl(""); - - $self->pidl("/* In parameters */"); - foreach (@{$fn->{ELEMENTS}}) { - if (grep(/in/, @{$_->{DIRECTION}})) { - $self->pidl("state->orig.in.$_->{NAME} = _$_->{NAME};"); - } - } $self->pidl(""); my $out_params = 0; - $self->pidl("/* Out parameters */"); foreach (@{$fn->{ELEMENTS}}) { if (grep(/out/, @{$_->{DIRECTION}})) { - $self->pidl("state->orig.out.$_->{NAME} = _$_->{NAME};"); $out_params++; } } - $self->pidl(""); - - if (defined($fn->{RETURN_TYPE})) { - $self->pidl("/* Result */"); - $self->pidl("ZERO_STRUCT(state->orig.out.result);"); - $self->pidl(""); - } if ($out_params > 0) { $self->pidl("state->out_mem_ctx = talloc_named_const(state, 0,"); @@ -253,14 +236,14 @@ sub ParseFunctionAsyncSend($$$) $self->pidl(""); } - $self->pidl("/* make a temporary copy, that we pass to the dispatch function */"); - $self->pidl("state->tmp = state->orig;"); - $self->pidl(""); + $fn_str = "subreq = dcerpc_$fn->{NAME}_send"; + $pad = "\t" . genpad($fn_str); + $fn_args = "state,\n" . $pad . "ev,\n" . $pad . "cli->binding_handle"; + foreach (@{$fn->{ELEMENTS}}) { + $fn_args .= ",\n" . $pad . "_". $_->{NAME}; + } - $self->pidl("subreq = cli->dispatch_send(state, ev, cli,"); - $self->pidl("\t\t\t &ndr_table_$if,"); - $self->pidl("\t\t\t $ufn,"); - $self->pidl("\t\t\t &state->tmp);"); + $self->pidl("$fn_str($fn_args);"); $self->pidl("if (tevent_req_nomem(subreq, req)) {"); $self->indent; $self->pidl("return tevent_req_post(req, ev);"); @@ -302,7 +285,14 @@ sub ParseFunctionAsyncDone($$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("status = state->dispatch_recv(subreq, mem_ctx);"); + my $fn_str = "status = dcerpc_$fn->{NAME}_recv"; + my $pad = "\t" . genpad($fn_str); + my $fn_args = "subreq,\n" . $pad . "mem_ctx"; + if (defined($fn->{RETURN_TYPE})) { + $fn_args .= ",\n" . $pad . "&state->result"; + } + + $self->pidl("$fn_str($fn_args);"); $self->pidl("TALLOC_FREE(subreq);"); $self->pidl("if (!NT_STATUS_IS_OK(status)) {"); $self->indent; @@ -312,27 +302,6 @@ sub ParseFunctionAsyncDone($$$) $self->pidl("}"); $self->pidl(""); - $self->pidl("/* Copy out parameters */"); - foreach my $e (@{$fn->{ELEMENTS}}) { - next unless (grep(/out/, @{$e->{DIRECTION}})); - - $self->ParseOutputArgument($fn, $e, - "state->tmp.", - "state->orig.out.", - "async"); - } - $self->pidl(""); - - if (defined($fn->{RETURN_TYPE})) { - $self->pidl("/* Copy result */"); - $self->pidl("state->orig.out.result = state->tmp.out.result;"); - $self->pidl(""); - } - - $self->pidl("/* Reset temporary structure */"); - $self->pidl("ZERO_STRUCT(state->tmp);"); - $self->pidl(""); - $self->pidl("tevent_req_done(req);"); $self->deindent; $self->pidl("}"); @@ -375,7 +344,7 @@ sub ParseFunctionAsyncRecv($$$) if (defined($fn->{RETURN_TYPE})) { $self->pidl("/* Return result */"); - $self->pidl("*result = state->orig.out.result;"); + $self->pidl("*result = state->result;"); $self->pidl(""); } @@ -401,7 +370,7 @@ sub ParseFunctionSync($$$) foreach (@{$fn->{ELEMENTS}}) { my $dir = ElementDirection($_); my $prop = HeaderProperties($_->{PROPERTIES}, ["in", "out"]); - $fn_args .= ",\n" . $pad . DeclLong($_) . " /* $dir $prop */"; + $fn_args .= ",\n" . $pad . DeclLong($_, "_") . " /* $dir $prop */"; } if (defined($fn->{RETURN_TYPE}) && ($fn->{RETURN_TYPE} eq "WERROR")) { @@ -411,60 +380,43 @@ sub ParseFunctionSync($$$) $self->fn_declare("$fn_str($fn_args)"); $self->pidl("{"); $self->indent; - $self->pidl("struct $fn->{NAME} r;"); + if (defined($fn->{RETURN_TYPE})) { + $self->pidl(mapTypeName($fn->{RETURN_TYPE})." result;"); + } $self->pidl("NTSTATUS status;"); $self->pidl(""); - $self->pidl("/* In parameters */"); + $fn_str = "status = dcerpc_$fn->{NAME}"; + $pad = "\t" . genpad($fn_str); + $fn_args = "cli->binding_handle,\n" . $pad . "mem_ctx"; foreach (@{$fn->{ELEMENTS}}) { - if (grep(/in/, @{$_->{DIRECTION}})) { - $self->pidl("r.in.$_->{NAME} = $_->{NAME};"); - } + $fn_args .= ",\n" . $pad . "_". $_->{NAME}; + } + if (defined($fn->{RETURN_TYPE})) { + $fn_args .= ",\n" . $pad . "&result"; } - $self->pidl(""); - $self->pidl("status = cli->dispatch(cli,"); - $self->pidl("\t\t\tmem_ctx,"); - $self->pidl("\t\t\t&ndr_table_$if,"); - $self->pidl("\t\t\t$ufn,"); - $self->pidl("\t\t\t&r);"); - $self->pidl(""); - + $self->pidl("$fn_str($fn_args);"); $self->pidl("if (!NT_STATUS_IS_OK(status)) {"); $self->indent; $self->pidl("return status;"); $self->deindent; $self->pidl("}"); - $self->pidl(""); - $self->pidl("if (NT_STATUS_IS_ERR(status)) {"); - $self->indent; - $self->pidl("return status;"); - $self->deindent; - $self->pidl("}"); - $self->pidl(""); - $self->pidl("/* Return variables */"); - foreach my $e (@{$fn->{ELEMENTS}}) { - next unless (grep(/out/, @{$e->{DIRECTION}})); - - $self->ParseOutputArgument($fn, $e); - } - - $self->pidl(""); $self->pidl("/* Return result */"); if (not $fn->{RETURN_TYPE}) { $self->pidl("return NT_STATUS_OK;"); } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") { - $self->pidl("return r.out.result;"); + $self->pidl("return result;"); } elsif ($fn->{RETURN_TYPE} eq "WERROR") { $self->pidl("if (werror) {"); $self->indent; - $self->pidl("*werror = r.out.result;"); + $self->pidl("*werror = result;"); $self->deindent; $self->pidl("}"); $self->pidl(""); - $self->pidl("return werror_to_ntstatus(r.out.result);"); + $self->pidl("return werror_to_ntstatus(result);"); } else { warning($fn->{ORIGINAL}, "Unable to convert $fn->{RETURN_TYPE} to NTSTATUS"); $self->pidl("return NT_STATUS_OK;"); @@ -505,7 +457,7 @@ sub ParseInterface($$) sub Parse($$$$) { - my($self,$ndr,$header,$ndr_header) = @_; + my($self,$ndr,$header,$c_header) = @_; $self->pidl("/*"); $self->pidl(" * Unix SMB/CIFS implementation."); @@ -514,7 +466,7 @@ sub Parse($$$$) $self->pidl(""); $self->pidl("#include \"includes.h\""); $self->pidl("#include \"$header\""); - $self->pidl_hdr("#include \"$ndr_header\""); + $self->pidl_hdr("#include \"$c_header\""); $self->pidl(""); foreach (@$ndr) { diff --git a/pidl/pidl b/pidl/pidl index c64ea959b1..2a46e92925 100755 --- a/pidl/pidl +++ b/pidl/pidl @@ -692,10 +692,11 @@ sub process_file($) } my $h_filename = "$outputdir/ndr_$basename.h"; - if (defined($opt_client)) { + my $c_header = "$outputdir/ndr_$basename\_c.h"; + if (defined($opt_client) or defined($opt_samba3_ndr_client)) { require Parse::Pidl::Samba4::NDR::Client; my ($c_client) = ($opt_client or "$outputdir/ndr_$basename\_c.c"); - my ($c_header) = $c_client; + $c_header = $c_client; $c_header =~ s/\.c$/.h/; my $generator = new Parse::Pidl::Samba4::NDR::Client(); @@ -772,7 +773,7 @@ sub process_file($) my $header = $client; $header =~ s/\.c$/\.h/; require Parse::Pidl::Samba3::ClientNDR; my $generator = new Parse::Pidl::Samba3::ClientNDR(); - my ($c_code,$h_code) = $generator->Parse($ndr, $header, $h_filename); + my ($c_code,$h_code) = $generator->Parse($ndr, $header, $c_header); FileSave($client, $c_code); FileSave($header, $h_code); } diff --git a/pidl/tests/samba3-cli.pl b/pidl/tests/samba3-cli.pl index fcf1fb171b..367922a36b 100755 --- a/pidl/tests/samba3-cli.pl +++ b/pidl/tests/samba3-cli.pl @@ -31,10 +31,7 @@ $fn = { NAME => "bar", ELEMENTS => [ ] }; $x->ParseFunction("foo", $fn); is($x->{res}, "struct rpccli_bar_state { - struct bar orig; - struct bar tmp; TALLOC_CTX *out_mem_ctx; - NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx); }; static void rpccli_bar_done(struct tevent_req *subreq); @@ -53,19 +50,10 @@ struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx, return NULL; } state->out_mem_ctx = NULL; - state->dispatch_recv = cli->dispatch_recv; - /* In parameters */ - - /* Out parameters */ - - /* make a temporary copy, that we pass to the dispatch function */ - state->tmp = state->orig; - - subreq = cli->dispatch_send(state, ev, cli, - &ndr_table_foo, - NDR_BAR, - &state->tmp); + subreq = dcerpc_bar_send(state, + ev, + cli->binding_handle); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -88,18 +76,14 @@ static void rpccli_bar_done(struct tevent_req *subreq) mem_ctx = state; } - status = state->dispatch_recv(subreq, mem_ctx); + status = dcerpc_bar_recv(subreq, + mem_ctx); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; } - /* Copy out parameters */ - - /* Reset temporary structure */ - ZERO_STRUCT(state->tmp); - tevent_req_done(req); } @@ -125,27 +109,14 @@ NTSTATUS rpccli_bar_recv(struct tevent_req *req, NTSTATUS rpccli_bar(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx) { - struct bar r; NTSTATUS status; - /* In parameters */ - - status = cli->dispatch(cli, - mem_ctx, - &ndr_table_foo, - NDR_BAR, - &r); - + status = dcerpc_bar(cli->binding_handle, + mem_ctx); if (!NT_STATUS_IS_OK(status)) { return status; } - if (NT_STATUS_IS_ERR(status)) { - return status; - } - - /* Return variables */ - /* Return result */ return NT_STATUS_OK; } @@ -158,10 +129,8 @@ $fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" }; $x->ParseFunction("foo", $fn); is($x->{res}, "struct rpccli_bar_state { - struct bar orig; - struct bar tmp; TALLOC_CTX *out_mem_ctx; - NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx); + WERROR result; }; static void rpccli_bar_done(struct tevent_req *subreq); @@ -180,22 +149,10 @@ struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx, return NULL; } state->out_mem_ctx = NULL; - state->dispatch_recv = cli->dispatch_recv; - - /* In parameters */ - /* Out parameters */ - - /* Result */ - ZERO_STRUCT(state->orig.out.result); - - /* make a temporary copy, that we pass to the dispatch function */ - state->tmp = state->orig; - - subreq = cli->dispatch_send(state, ev, cli, - &ndr_table_foo, - NDR_BAR, - &state->tmp); + subreq = dcerpc_bar_send(state, + ev, + cli->binding_handle); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -218,21 +175,15 @@ static void rpccli_bar_done(struct tevent_req *subreq) mem_ctx = state; } - status = state->dispatch_recv(subreq, mem_ctx); + status = dcerpc_bar_recv(subreq, + mem_ctx, + &state->result); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; } - /* Copy out parameters */ - - /* Copy result */ - state->orig.out.result = state->tmp.out.result; - - /* Reset temporary structure */ - ZERO_STRUCT(state->tmp); - tevent_req_done(req); } @@ -253,7 +204,7 @@ NTSTATUS rpccli_bar_recv(struct tevent_req *req, talloc_steal(mem_ctx, state->out_mem_ctx); /* Return result */ - *result = state->orig.out.result; + *result = state->result; tevent_req_received(req); return NT_STATUS_OK; @@ -263,33 +214,22 @@ NTSTATUS rpccli_bar(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, WERROR *werror) { - struct bar r; + WERROR result; NTSTATUS status; - /* In parameters */ - - status = cli->dispatch(cli, - mem_ctx, - &ndr_table_foo, - NDR_BAR, - &r); - + status = dcerpc_bar(cli->binding_handle, + mem_ctx, + &result); if (!NT_STATUS_IS_OK(status)) { return status; } - if (NT_STATUS_IS_ERR(status)) { - return status; - } - - /* Return variables */ - /* Return result */ if (werror) { - *werror = r.out.result; + *werror = result; } - return werror_to_ntstatus(r.out.result); + return werror_to_ntstatus(result); } "); -- cgit