$self->pidl_hdr("");
}
+sub ParsePipeCreate($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ $self->pidl_both("/* $t->{NAME} */");
+
+ $self->pidl_hdr("struct $t->{NAME};");
+ $self->pidl("struct $t->{NAME} {");
+ $self->indent;
+ $self->pidl("struct dcerpc_pipe_handle_connection *pc;");
+ $self->deindent;
+ $self->pidl("};");
+ $self->pidl("");
+
+ my $proto = "struct $t->{NAME} *dcerpc_$t->{NAME}\_create(TALLOC_CTX *mem_ctx)";
+
+ $self->pidl_hdr("$proto;");
+ $self->pidl("$proto");
+ $self->pidl("{");
+ $self->indent;
+
+ $self->pidl("struct $t->{NAME} *p;");
+ $self->pidl("");
+
+ $self->pidl("p = talloc_zero(mem_ctx, struct $t->{NAME});");
+ $self->pidl("if (p == NULL) {");
+ $self->indent;
+ $self->pidl("return NULL;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ my $cname = "$t->{NAME}_chunk";
+
+ $self->pidl("/* the pipe is disconnected by default */");
+ $self->pidl("p->pc = dcerpc_pipe_handle_connection_create(p,");
+ $self->pidl("\t\t\t\"$cname\",");
+ $self->pidl("\t\t\tsizeof(struct $cname));");
+ $self->pidl("if (p->pc == NULL) {");
+ $self->indent;
+ $self->pidl("TALLOC_FREE(p);");
+ $self->pidl("return NULL;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("return p;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipeChunkPush_State($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ my $state_str = "struct dcerpc_$cname\_push_state";
+ my $done_fn = "dcerpc_$cname\_push_done";
+
+ $self->pidl("$state_str {");
+ $self->indent;
+ $self->pidl("uint8_t dummy;");
+ $self->deindent;
+ $self->pidl("};");
+ $self->pidl("");
+
+ $self->pidl("static void $done_fn(struct tevent_req *subreq);");
+ $self->pidl("");
+}
+
+sub ParsePipeChunkPush_Send($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ my $fn_args = "";
+ my $state_str = "struct dcerpc_$cname\_push_state";
+ my $done_fn = "dcerpc_$cname\_push_done";
+ my $fn_str = "struct tevent_req *dcerpc_$cname\_push_send";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "TALLOC_CTX *mem_ctx";
+ $fn_args .= ",\n" . $pad . "struct tevent_context *ev";
+ $fn_args .= ",\n" . $pad . "struct $t->{NAME} *p";
+ $fn_args .= ",\n" . $pad . "const struct $cname *chunk";
+
+ $self->fn_declare("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("struct tevent_req *req;");
+ $self->pidl("$state_str *state;");
+ $self->pidl("struct tevent_req *subreq;");
+ $self->pidl("");
+
+ $self->pidl("req = tevent_req_create(mem_ctx, &state,");
+ $self->pidl("\t\t\t$state_str);");
+ $self->pidl("if (req == NULL) {");
+ $self->indent;
+ $self->pidl("return NULL;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("subreq = dcerpc_pipe_handle_push_send(state, ev,");
+ $self->pidl("\t\t\tp->pc, chunk);");
+ $self->pidl("if (tevent_req_nomem(subreq, req)) {");
+ $self->indent;
+ $self->pidl("return tevent_req_post(req, ev);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("tevent_req_set_callback(subreq, $done_fn, req);");
+ $self->pidl("");
+
+ $self->pidl("return req;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipeChunkPush_Done($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ my $fn_args = "";
+ my $state_str = "struct dcerpc_$cname\_push_state";
+ my $fn_str = "static void dcerpc_$cname\_push_done";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "struct tevent_req *subreq";
+
+ $self->pidl("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("struct tevent_req *req =");
+ $self->pidl("\ttevent_req_callback_data(subreq,");
+ $self->pidl("\tstruct tevent_req);");
+ # unused
+ #$self->pidl("$state_str *state =");
+ #$self->pidl("\ttevent_req_data(req,");
+ #$self->pidl("\t$state_str);");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
+
+ $self->pidl("status = dcerpc_pipe_handle_push_recv(subreq);");
+ $self->pidl("TALLOC_FREE(subreq);");
+ $self->pidl("if (tevent_req_nterror(req, status)) {");
+ $self->indent;
+ $self->pidl("return;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("tevent_req_done(req);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipeChunkPush_Recv($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ my $fn_args = "";
+ my $state_str = "struct dcerpc_$cname\_push_state";
+ my $fn_str = "NTSTATUS dcerpc_$cname\_push_recv";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "struct tevent_req *req";
+
+ $self->fn_declare("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("$state_str *state =");
+ $self->pidl("\ttevent_req_data(req,");
+ $self->pidl("\t$state_str);");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
+
+ $self->pidl("if (tevent_req_is_nterror(req, &status)) {");
+ $self->indent;
+ $self->pidl("/*");
+ $self->pidl(" * We want the tevent_req_data() protection,");
+ $self->pidl(" * but don't need 'state', so just pretend we use it");
+ $self->pidl(" * in order to avoid compiler warnings.");
+ $self->pidl(" */");
+ $self->pidl("state->dummy = 0;");
+ $self->pidl("tevent_req_received(req);");
+ $self->pidl("return status;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("tevent_req_received(req);");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipeChunkPull_State($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ my $state_str = "struct dcerpc_$cname\_pull_state";
+ my $done_fn = "dcerpc_$cname\_pull_done";
+
+ $self->pidl("$state_str {");
+ $self->indent;
+ $self->pidl("struct $cname *chunk;");
+ $self->deindent;
+ $self->pidl("};");
+ $self->pidl("");
+
+ $self->pidl("static void $done_fn(struct tevent_req *subreq);");
+ $self->pidl("");
+}
+
+sub ParsePipeChunkPull_Send($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ my $fn_args = "";
+ my $state_str = "struct dcerpc_$cname\_pull_state";
+ my $done_fn = "dcerpc_$cname\_pull_done";
+ my $fn_str = "struct tevent_req *dcerpc_$cname\_pull_send";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "TALLOC_CTX *mem_ctx";
+ $fn_args .= ",\n" . $pad . "struct tevent_context *ev";
+ $fn_args .= ",\n" . $pad . "struct $t->{NAME} *p";
+
+ $self->fn_declare("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("struct tevent_req *req;");
+ $self->pidl("$state_str *state;");
+ $self->pidl("struct tevent_req *subreq;");
+ $self->pidl("");
+
+ $self->pidl("req = tevent_req_create(mem_ctx, &state,");
+ $self->pidl("\t\t\t$state_str);");
+ $self->pidl("if (req == NULL) {");
+ $self->indent;
+ $self->pidl("return NULL;");
+ $self->deindent;
+ $self->pidl("}");
+
+ $self->pidl("state->chunk = talloc_zero(state, struct $cname);");
+ $self->pidl("if (tevent_req_nomem(state->chunk, req)) {");
+ $self->indent;
+ $self->pidl("return tevent_req_post(req, ev);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("subreq = dcerpc_pipe_handle_pull_send(state, ev,");
+ $self->pidl("\t\t\tp->pc, state->chunk, state->chunk);");
+ $self->pidl("if (tevent_req_nomem(subreq, req)) {");
+ $self->indent;
+ $self->pidl("return tevent_req_post(req, ev);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("tevent_req_set_callback(subreq, $done_fn, req);");
+ $self->pidl("");
+
+ $self->pidl("return req;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipeChunkPull_Done($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ my $fn_args = "";
+ my $state_str = "struct dcerpc_$cname\_pull_state";
+ my $fn_str = "static void dcerpc_$cname\_pull_done";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "struct tevent_req *subreq";
+
+ $self->pidl("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("struct tevent_req *req =");
+ $self->pidl("\ttevent_req_callback_data(subreq,");
+ $self->pidl("\tstruct tevent_req);");
+ # unused
+ #$self->pidl("$state_str *state =");
+ #$self->pidl("\ttevent_req_data(req,");
+ #$self->pidl("\t$state_str);");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
+
+ $self->pidl("status = dcerpc_pipe_handle_pull_recv(subreq);");
+ $self->pidl("TALLOC_FREE(subreq);");
+ $self->pidl("if (tevent_req_nterror(req, status)) {");
+ $self->indent;
+ $self->pidl("return;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("tevent_req_done(req);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipeChunkPull_Recv($$$)
+{
+ my ($self, $t, $cname) = @_;
+
+ my $fn_args = "";
+ my $state_str = "struct dcerpc_$cname\_pull_state";
+ my $fn_str = "NTSTATUS dcerpc_$cname\_pull_recv";
+ my $pad = genpad($fn_str);
+
+ $fn_args .= "struct tevent_req *req";
+ $fn_args .= ",\n" . $pad . "TALLOC_CTX *mem_ctx";
+ $fn_args .= ",\n" . $pad . "struct $cname **chunk";
+
+ $self->fn_declare("$fn_str($fn_args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("$state_str *state =");
+ $self->pidl("\ttevent_req_data(req,");
+ $self->pidl("\t$state_str);");
+ $self->pidl("NTSTATUS status;");
+ $self->pidl("");
+
+ $self->pidl("if (tevent_req_is_nterror(req, &status)) {");
+ $self->indent;
+ $self->pidl("tevent_req_received(req);");
+ $self->pidl("return status;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("*chunk = talloc_move(mem_ctx, &state->chunk);");
+ $self->pidl("");
+
+ $self->pidl("tevent_req_received(req);");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipe($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+
+ $self->ParsePipeCreate($t, $name);
+
+ $self->ParsePipeChunkPush_State($t, $name);
+ $self->ParsePipeChunkPush_Send($t, $name);
+ $self->ParsePipeChunkPush_Done($t, $name);
+ $self->ParsePipeChunkPush_Recv($t, $name);
+
+ $self->ParsePipeChunkPull_State($t, $name);
+ $self->ParsePipeChunkPull_Send($t, $name);
+ $self->ParsePipeChunkPull_Done($t, $name);
+ $self->ParsePipeChunkPull_Recv($t, $name);
+ $self->pidl_both("");
+}
+
my %done;
#####################################################################
$self->pidl("/* $if->{NAME} - client functions generated by pidl */");
$self->pidl("");
+ foreach my $t (reverse @{$if->{TYPES}}) {
+ next unless Parse::Pidl::Typelist::typeIs($t, "PIPE");
+
+ $self->ParsePipe($t);
+ $done{$t->{NAME}} = 1;
+ }
+
foreach my $fn (@{$if->{FUNCTIONS}}) {
next if defined($done{$fn->{NAME}});
next if has_property($fn, "noopnum");