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("};");
}
$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);");
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;
$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;
{
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});