1 ###################################################
2 # DCOM parser for Samba
3 # Basically the glue between COM and DCE/RPC with NDR
4 # Copyright jelmer@samba.org 2003-2005
5 # released under the GNU GPL
7 package Parse::Pidl::Samba4::COM::Proxy;
9 use Parse::Pidl::Samba4::COM::Header;
10 use Parse::Pidl::Util qw(has_property);
12 use vars qw($VERSION);
21 my $interface = shift;
25 $res .="\tstruct $interface->{NAME}_vtable $name = {";
27 if (defined($interface->{BASE})) {
31 my $data = $interface->{DATA};
33 foreach my $d (@{$data}) {
34 if ($d->{TYPE} eq "FUNCTION") {
35 $res .= "\n\t\tdcom_proxy_$interface->{NAME}_$d->{NAME}";
45 my $interface = shift;
47 $res .= "static NTSTATUS dcom_proxy_$interface->{NAME}_init(void)
50 struct $interface->{NAME}_vtable *proxy_vtable = talloc(talloc_autofree_context(), struct $interface->{NAME}_vtable);
53 if (defined($interface->{BASE})) {
55 const void *base_vtable;
57 GUID_from_string(DCERPC_" . (uc $interface->{BASE}) . "_UUID, &base_iid);
59 base_vtable = dcom_proxy_vtable_by_iid(&base_iid);
60 if (base_vtable == NULL) {
61 DEBUG(0, (\"No proxy registered for base interface '$interface->{BASE}'\\n\"));
62 return NT_STATUS_FOOBAR;
65 memcpy(&proxy_vtable, base_vtable, sizeof(struct $interface->{BASE}_vtable));
69 foreach my $x (@{$interface->{DATA}}) {
70 next unless ($x->{TYPE} eq "FUNCTION");
72 $res .= "\tproxy_vtable.$x->{NAME} = dcom_proxy_$interface->{NAME}_$x->{NAME};\n";
76 GUID_from_string(DCERPC_" . (uc $interface->{NAME}) . "_UUID, &proxy_vtable.iid);
78 return dcom_register_proxy(&proxy_vtable);
82 #####################################################################
86 my $interface = shift;
88 my $name = $fn->{NAME};
92 static $fn->{RETURN_TYPE} dcom_proxy_$interface->{NAME}_$name(struct $interface->{NAME} *d, TALLOC_CTX *mem_ctx" . Parse::Pidl::Samba4::COM::Header::GetArgumentProtoList($fn) . ")
94 struct dcerpc_pipe *p;
95 NTSTATUS status = dcom_get_pipe(d, &p);
97 struct rpc_request *req;
99 if (NT_STATUS_IS_ERR(status)) {
103 ZERO_STRUCT(r.in.ORPCthis);
104 r.in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION;
105 r.in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION;
108 # Put arguments into r
109 foreach my $a (@{$fn->{ELEMENTS}}) {
110 next unless (has_property($a, "in"));
111 if (Parse::Pidl::Typelist::typeIs($a->{TYPE}, "INTERFACE")) {
112 $res .="\tNDR_CHECK(dcom_OBJREF_from_IUnknown(&r.in.$a->{NAME}.obj, $a->{NAME}));\n";
114 $res .= "\tr.in.$a->{NAME} = $a->{NAME};\n";
119 if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
120 NDR_PRINT_IN_DEBUG($name, &r);
123 status = dcerpc_ndr_request(p, &d->ipid, &dcerpc_table_$interface->{NAME}, DCERPC_$uname, mem_ctx, &r);
125 if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
126 NDR_PRINT_OUT_DEBUG($name, r);
131 # Put r info back into arguments
132 foreach my $a (@{$fn->{ELEMENTS}}) {
133 next unless (has_property($a, "out"));
135 if (Parse::Pidl::Typelist::typeIs($a->{TYPE}, "INTERFACE")) {
136 $res .="\tNDR_CHECK(dcom_IUnknown_from_OBJREF(d->ctx, &$a->{NAME}, r.out.$a->{NAME}.obj));\n";
138 $res .= "\t*$a->{NAME} = r.out.$a->{NAME};\n";
143 if ($fn->{RETURN_TYPE} eq "NTSTATUS") {
144 $res .= "\tif (NT_STATUS_IS_OK(status)) status = r.out.result;\n";
153 #####################################################################
154 # parse the interface definitions
155 sub ParseInterface($)
157 my($interface) = shift;
158 my($data) = $interface->{DATA};
159 $res = "/* DCOM proxy for $interface->{NAME} generated by pidl */\n\n";
160 foreach my $d (@{$data}) {
161 ($d->{TYPE} eq "FUNCTION") &&
162 ParseFunction($interface, $d);
165 ParseRegFunc($interface);
168 sub RegistrationFunction($$)
171 my $basename = shift;
173 my $res = "\n\nNTSTATUS dcom_$basename\_init(void)\n";
175 $res .="\tNTSTATUS status = NT_STATUS_OK;\n";
176 foreach my $interface (@{$idl}) {
177 next if $interface->{TYPE} ne "INTERFACE";
178 next if not has_property($interface, "object");
180 my $data = $interface->{DATA};
182 foreach my $d (@{$data}) {
183 if ($d->{TYPE} eq "FUNCTION") { $count++; }
186 next if ($count == 0);
188 $res .= "\tstatus = dcom_$interface->{NAME}_init();\n";
189 $res .= "\tif (NT_STATUS_IS_ERR(status)) {\n";
190 $res .= "\t\treturn status;\n";
193 $res .= "\treturn status;\n";
204 foreach my $x (@{$pidl}) {
205 next if ($x->{TYPE} ne "INTERFACE");
206 next if has_property($x, "local");
207 next unless has_property($x, "object");
209 $res .= ParseInterface($x);