pidl:NDR/Client.pm: use dcerpc_binding_handl_call_params* if a dcerpc pipe is used
authorStefan Metzmacher <metze@samba.org>
Tue, 5 Oct 2010 18:57:45 +0000 (20:57 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 17 Oct 2013 05:18:01 +0000 (07:18 +0200)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm

index 59ec07552256fa8acb11fcfece3131ddc27f6134..360266c77114fce555df8141271fd4699de6a247 100644 (file)
@@ -61,8 +61,26 @@ sub ParseFunction_r_State($$$$)
        my ($self, $if, $fn, $name) = @_;
        my $uname = uc $name;
 
+       my $in_pipes = 0;
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               next unless grep(/in/, @{$e->{DIRECTION}});
+               next unless ContainsPipe($e, $e->{LEVELS}[0]);
+               $in_pipes++;
+       }
+       my $out_pipes = 0;
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               next unless grep(/out/, @{$e->{DIRECTION}});
+               next unless ContainsPipe($e, $e->{LEVELS}[0]);
+               $out_pipes++;
+       }
+
        $self->pidl("struct dcerpc_$name\_r_state {");
        $self->indent;
+       if ($in_pipes > 0 or $out_pipes > 0) {
+               $self->pidl("struct dcerpc_pipe_handle_connection *in_pipes[$in_pipes];") if ($in_pipes > 0);
+               $self->pidl("struct dcerpc_pipe_handle_connection *out_pipes[$out_pipes];") if ($out_pipes > 0);
+               $self->pidl("struct dcerpc_binding_handle_call_params params;");
+       }
        $self->pidl("TALLOC_CTX *out_mem_ctx;");
        $self->deindent;
        $self->pidl("};");
@@ -123,9 +141,58 @@ sub ParseFunction_r_Send($$$$)
        }
        $self->pidl("");
 
-       $self->pidl("subreq = dcerpc_binding_handle_call_send(state, ev, h,");
-       $self->pidl("\t\tNULL, &ndr_table_$if->{NAME},");
-       $self->pidl("\t\tNDR_$uname, $submem, r);");
+       my $in_pipes = 0;
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               next unless grep(/in/, @{$e->{DIRECTION}});
+               next unless ContainsPipe($e, $e->{LEVELS}[0]);
+               $self->pidl("if (r->in.$e->{NAME} == NULL) {");
+               $self->indent;
+               $self->pidl("tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);");
+               $self->pidl("return tevent_req_post(req, ev);");
+               $self->deindent;
+               $self->pidl("}");
+               $self->pidl("state->in_pipes[$in_pipes] = r->in.".$e->{NAME}."->pc;");
+               $in_pipes++;
+       }
+       my $out_pipes = 0;
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               next unless grep(/out/, @{$e->{DIRECTION}});
+               next unless ContainsPipe($e, $e->{LEVELS}[0]);
+               $self->pidl("if (r->out.$e->{NAME} == NULL) {");
+               $self->indent;
+               $self->pidl("tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);");
+               $self->pidl("return tevent_req_post(req, ev);");
+               $self->deindent;
+               $self->pidl("}");
+               $self->pidl("state->out_pipes[$out_pipes] = r->out.".$e->{NAME}."->pc;");
+               $out_pipes++;
+       }
+
+       if ($in_pipes > 0 or $out_pipes > 0) {
+               $self->pidl("state->params.r_mem = $submem;");
+               $self->pidl("state->params.r_ptr = r;");
+               $self->pidl("state->params.in.num_pipes = $in_pipes;");
+               if ($in_pipes > 0) {
+                       $self->pidl("state->params.in.pipes = state->in_pipes;");
+               } else {
+                       $self->pidl("state->params.in.pipes = NULL;");
+               }
+               $self->pidl("state->params.out.num_pipes = $out_pipes;");
+               if ($out_pipes > 0) {
+                       $self->pidl("state->params.out.pipes = state->out_pipes;");
+               } else {
+                       $self->pidl("state->params.out.pipes = NULL;");
+               }
+               $self->pidl("");
+
+               $self->pidl("subreq = dcerpc_binding_handle_call_params_send(state, ev, h,");
+               $self->pidl("\t\tNULL, &ndr_table_$if->{NAME},");
+               $self->pidl("\t\tNDR_$uname, &state->params);");
+       } else {
+               $self->pidl("subreq = dcerpc_binding_handle_call_send(state, ev, h,");
+               $self->pidl("\t\tNULL, &ndr_table_$if->{NAME},");
+               $self->pidl("\t\tNDR_$uname, $submem, r);");
+       }
        $self->pidl("if (tevent_req_nomem(subreq, req)) {");
        $self->indent;
        $self->pidl("return tevent_req_post(req, ev);");
@@ -147,6 +214,19 @@ sub ParseFunction_r_Done($$$$)
 
        my $proto = "static void dcerpc_$name\_r_done(struct tevent_req *subreq)";
 
+       my $in_pipes = 0;
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               next unless grep(/in/, @{$e->{DIRECTION}});
+               next unless ContainsPipe($e, $e->{LEVELS}[0]);
+               $in_pipes++;
+       }
+       my $out_pipes = 0;
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               next unless grep(/out/, @{$e->{DIRECTION}});
+               next unless ContainsPipe($e, $e->{LEVELS}[0]);
+               $out_pipes++;
+       }
+
        $self->pidl("$proto");
        $self->pidl("{");
        $self->indent;
@@ -157,7 +237,11 @@ sub ParseFunction_r_Done($$$$)
        $self->pidl("NTSTATUS status;");
        $self->pidl("");
 
-       $self->pidl("status = dcerpc_binding_handle_call_recv(subreq);");
+       if ($in_pipes > 0 or $out_pipes > 0) {
+               $self->pidl("status = dcerpc_binding_handle_call_params_recv(subreq);");
+       } else {
+               $self->pidl("status = dcerpc_binding_handle_call_recv(subreq);");
+       }
        $self->pidl("TALLOC_FREE(subreq);");
        $self->pidl("if (tevent_req_nterror(req, status)) {");
        $self->indent;
@@ -747,24 +831,6 @@ 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});