r3689: Large number of COM updates:
[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 .= "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 register_backend(\"dcom_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_$uname, mem_ctx,
109         (ndr_push_flags_fn_t) ndr_push_$name,
110         (ndr_pull_flags_fn_t) ndr_pull_$name,
111         r, sizeof(*r));
112 }
113
114 static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
115 {
116         struct dcerpc_pipe *p;
117         NTSTATUS status = dcom_get_pipe(d, &p);
118         struct rpc_request *req;
119
120         if (NT_STATUS_IS_ERR(status)) {
121                 return status;
122         }
123
124         req = dcom_proxy_$interface->{NAME}_$name\_send(d, mem_ctx, r);
125         if (req == NULL) return NT_STATUS_NO_MEMORY;
126
127         status = dcerpc_ndr_request_recv(req);
128
129         if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) {
130                 NDR_PRINT_OUT_DEBUG($name, r);          
131         }
132         ";
133         if ($fn->{RETURN_TYPE} eq "NTSTATUS") {
134                 $res .= "\tif (NT_STATUS_IS_OK(status)) status = r->out.result;\n";
135         }
136         $res .= 
137         "
138         return status;
139 }";
140         }
141
142         $res .=" 
143 NTSTATUS dcom_$interface->{NAME}_$name (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
144 {
145         return ((const struct dcom_$interface->{NAME}_vtable *)d->vtable)->$name (d, mem_ctx, r);
146 }
147 ";
148 }
149
150
151 #####################################################################
152 # parse the interface definitions
153 sub ParseInterface($)
154 {
155         my($interface) = shift;
156         my($data) = $interface->{DATA};
157         $res = "/* DCOM stubs generated by pidl */\n\n";
158         foreach my $d (@{$data}) {
159                 ($d->{TYPE} eq "FUNCTION") && 
160                 ParseFunction($interface, $d);
161         }
162
163         ParseRegFunc($interface);
164 }
165
166 1;