r4086: - make dcerpc_ndr_request_table_send() the default and rename it to just
[samba.git] / source4 / build / pidl / proxy.pm
1 ###################################################
2 # DCOM proxy generator
3 # Copyright jelmer@samba.org 2003
4 # released under the GNU GPL
5
6 package IdlProxy;
7
8 use strict;
9
10 my($res);
11
12 sub ParseVTable($$)
13 {
14         my $interface = shift;
15         my $name = shift;
16
17         # Generate the vtable
18         $res .="\tstruct dcom_$interface->{NAME}_vtable $name = {";
19
20         if (defined($interface->{BASE})) {
21                 $res .= "\n\t\t{},";
22         }
23
24         my $data = $interface->{DATA};
25
26         foreach my $d (@{$data}) {
27                 if ($d->{TYPE} eq "FUNCTION") {
28                     $res .= "\n\t\tdcom_proxy_$interface->{NAME}_$d->{NAME}";
29                         $res .= ",";
30                 }
31         }
32
33         $res .= "\n\t};\n\n";
34 }
35
36 sub ParseRegFunc($)
37 {
38         my $interface = shift;
39
40         $res .= "static NTSTATUS dcom_$interface->{NAME}_init(void)
41 {
42         struct dcom_interface iface;
43 ";
44         
45         ParseVTable($interface, "proxy");
46
47         if (defined($interface->{BASE})) {
48                 $res.= "
49         const void *base_vtable;
50
51         GUID_from_string(DCERPC_" . (uc $interface->{BASE}) . "_UUID, &iface.base_iid);
52
53         base_vtable = dcom_proxy_vtable_by_iid(&iface.base_iid);
54         if (base_vtable == NULL) {
55                 return NT_STATUS_FOOBAR;
56         }
57
58         proxy.base = *((const struct dcom_$interface->{BASE}_vtable *)base_vtable);
59         ";
60         } else {
61                 $res .= "\tZERO_STRUCT(iface.base_iid);\n";
62         }
63
64         $res.= "
65         iface.num_methods = DCERPC_" . (uc $interface->{NAME}) . "_CALL_COUNT;
66         GUID_from_string(DCERPC_" . (uc $interface->{NAME}) . "_UUID, &iface.iid);
67         iface.proxy_vtable = talloc_memdup(NULL, &proxy, sizeof(struct dcom_$interface->{NAME}_vtable));
68
69         return dcom_register_interface(&iface);
70 }\n\n";
71 }
72
73 #####################################################################
74 # parse a function
75 sub ParseFunction($$)
76 {
77         my $interface = shift;
78         my $fn = shift;
79         my $name = $fn->{NAME};
80         my $uname = uc $name;
81
82         if (util::has_property($fn, "local")) {
83                 $res .= "
84 static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
85 {
86         /* FIXME */
87         return NT_STATUS_NOT_SUPPORTED;
88 }\n";
89         } else {
90                 $res .= "
91 static struct rpc_request *dcom_proxy_$interface->{NAME}_$name\_send(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
92 {
93         struct dcerpc_pipe *p;
94         NTSTATUS status = dcom_get_pipe(d, &p);
95
96         if (NT_STATUS_IS_ERR(status)) {
97                 return NULL;
98         }
99
100         ZERO_STRUCT(r->in.ORPCthis);
101         r->in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION;
102         r->in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION;
103
104         if (p->flags & DCERPC_DEBUG_PRINT_IN) {
105                 NDR_PRINT_IN_DEBUG($name, r);           
106         }
107
108         return dcerpc_ndr_request_send(p, &d->ipid, &dcerpc_table_$interface->{NAME}, DCERPC_$uname, mem_ctx, r);
109 }
110
111 static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
112 {
113         struct dcerpc_pipe *p;
114         NTSTATUS status = dcom_get_pipe(d, &p);
115         struct rpc_request *req;
116
117         if (NT_STATUS_IS_ERR(status)) {
118                 return status;
119         }
120
121         req = dcom_proxy_$interface->{NAME}_$name\_send(d, mem_ctx, r);
122         if (req == NULL) return NT_STATUS_NO_MEMORY;
123
124         status = dcerpc_ndr_request_recv(req);
125
126         if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) {
127                 NDR_PRINT_OUT_DEBUG($name, r);          
128         }
129         ";
130         if ($fn->{RETURN_TYPE} eq "NTSTATUS") {
131                 $res .= "\tif (NT_STATUS_IS_OK(status)) status = r->out.result;\n";
132         }
133         $res .= 
134         "
135         return status;
136 }";
137         }
138
139         $res .=" 
140 NTSTATUS dcom_$interface->{NAME}_$name (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
141 {
142         return ((const struct dcom_$interface->{NAME}_vtable *)d->vtable)->$name (d, mem_ctx, r);
143 }
144 ";
145 }
146
147
148 #####################################################################
149 # parse the interface definitions
150 sub ParseInterface($)
151 {
152         my($interface) = shift;
153         my($data) = $interface->{DATA};
154         $res = "/* DCOM stubs generated by pidl */\n\n";
155         foreach my $d (@{$data}) {
156                 ($d->{TYPE} eq "FUNCTION") && 
157                 ParseFunction($interface, $d);
158         }
159
160         ParseRegFunc($interface);
161 }
162
163 sub RegistrationFunction($$)
164 {
165         my $idl = shift;
166         my $basename = shift;
167
168         my $res = "NTSTATUS dcom_$basename\_init(void)\n";
169         $res .= "{\n";
170         $res .="\tNTSTATUS status = NT_STATUS_OK;\n";
171         foreach my $interface (@{$idl}) {
172                 next if $interface->{TYPE} ne "INTERFACE";
173                 next if not util::has_property($interface, "object");
174
175                 my $data = $interface->{INHERITED_DATA};
176                 my $count = 0;
177                 foreach my $d (@{$data}) {
178                         if ($d->{TYPE} eq "FUNCTION") { $count++; }
179                 }
180
181                 next if ($count == 0);
182
183                 $res .= "\tstatus = dcom_$interface->{NAME}_init();\n";
184                 $res .= "\tif (NT_STATUS_IS_ERR(status)) {\n";
185                 $res .= "\t\treturn status;\n";
186                 $res .= "\t}\n\n";
187         }
188         $res .= "\treturn status;\n";
189         $res .= "}\n\n";
190
191         return $res;
192 }
193
194 1;