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>
Tue, 4 Jun 2019 11:14:55 +0000 (13:14 +0200)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm

index 8e2e0656f5c253b74b3135c70b786b729b40a21c..f9d743f82b5b6ab551c80717d00dee091f7ab5e3 100644 (file)
@@ -52,8 +52,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("};");
@@ -114,9 +132,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);");
@@ -138,6 +205,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;
@@ -148,7 +228,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;
@@ -738,24 +822,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});