• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/pidl/lib/Parse/Pidl/Samba4/COM/
1###################################################
2# DCOM stub boilerplate generator
3# Copyright jelmer@samba.org 2004-2005
4# Copyright tridge@samba.org 2003
5# Copyright metze@samba.org 2004
6# released under the GNU GPL
7
8package Parse::Pidl::Samba4::COM::Stub;
9
10use Parse::Pidl::Util qw(has_property);
11use strict;
12
13use vars qw($VERSION);
14$VERSION = '0.01';
15
16my($res);
17
18sub pidl($)
19{
20	$res .= shift;
21}
22
23#####################################################
24# generate the switch statement for function dispatch
25sub gen_dispatch_switch($)
26{
27	my $data = shift;
28
29	my $count = 0;
30	foreach my $d (@{$data}) {
31		next if ($d->{TYPE} ne "FUNCTION");
32
33		pidl "\tcase $count: {\n";
34		if ($d->{RETURN_TYPE} && $d->{RETURN_TYPE} ne "void") {
35			pidl "\t\tNTSTATUS result;\n";
36		}
37		pidl "\t\tstruct $d->{NAME} *r2 = r;\n";
38		pidl "\t\tif (DEBUGLEVEL > 10) {\n";
39		pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($d->{NAME}, NDR_IN, r2);\n";
40		pidl "\t\t}\n";
41		if ($d->{RETURN_TYPE} && $d->{RETURN_TYPE} ne "void") {
42			pidl "\t\tresult = vtable->$d->{NAME}(iface, mem_ctx, r2);\n";
43		} else {
44			pidl "\t\tvtable->$d->{NAME}(iface, mem_ctx, r2);\n";
45		}
46		pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n";
47		pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} will reply async\\n\"));\n";
48		pidl "\t\t}\n";
49		pidl "\t\tbreak;\n\t}\n";
50		$count++;
51	}
52}
53
54#####################################################
55# generate the switch statement for function reply
56sub gen_reply_switch($)
57{
58	my $data = shift;
59
60	my $count = 0;
61	foreach my $d (@{$data}) {
62		next if ($d->{TYPE} ne "FUNCTION");
63
64		pidl "\tcase $count: {\n";
65		pidl "\t\tstruct $d->{NAME} *r2 = r;\n";
66		pidl "\t\tif (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {\n";
67		pidl "\t\t\tDEBUG(5,(\"function $d->{NAME} replied async\\n\"));\n";
68		pidl "\t\t}\n";
69		pidl "\t\tif (DEBUGLEVEL > 10 && dce_call->fault_code == 0) {\n";
70		pidl "\t\t\tNDR_PRINT_FUNCTION_DEBUG($d->{NAME}, NDR_OUT | NDR_SET_VALUES, r2);\n";
71		pidl "\t\t}\n";
72		pidl "\t\tif (dce_call->fault_code != 0) {\n";
73		pidl "\t\t\tDEBUG(2,(\"dcerpc_fault %s in $d->{NAME}\\n\", dcerpc_errstr(mem_ctx, dce_call->fault_code)));\n";
74		pidl "\t\t}\n";
75		pidl "\t\tbreak;\n\t}\n";
76		$count++;
77	}
78}
79
80#####################################################################
81# produce boilerplate code for a interface
82sub Boilerplate_Iface($)
83{
84	my($interface) = shift;
85	my($data) = $interface->{DATA};
86	my $name = $interface->{NAME};
87	my $uname = uc $name;
88	my $uuid = Parse::Pidl::Util::make_str($interface->{PROPERTIES}->{uuid});
89	my $if_version = $interface->{PROPERTIES}->{version};
90
91	pidl "
92static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
93{
94#ifdef DCESRV_INTERFACE_$uname\_BIND
95	return DCESRV_INTERFACE_$uname\_BIND(dce_call,iface);
96#else
97	return NT_STATUS_OK;
98#endif
99}
100
101static void $name\__op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
102{
103#ifdef DCESRV_INTERFACE_$uname\_UNBIND
104	DCESRV_INTERFACE_$uname\_UNBIND(context, iface);
105#else
106	return;
107#endif
108}
109
110static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)
111{
112	NTSTATUS status;
113	uint16_t opnum = dce_call->pkt.u.request.opnum;
114
115	dce_call->fault_code = 0;
116
117	if (opnum >= dcerpc_table_$name.num_calls) {
118		dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
119		return NT_STATUS_NET_WRITE_FAULT;
120	}
121
122	*r = talloc_size(mem_ctx, dcerpc_table_$name.calls[opnum].struct_size);
123	NT_STATUS_HAVE_NO_MEMORY(*r);
124
125        /* unravel the NDR for the packet */
126	status = dcerpc_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r);
127	if (!NT_STATUS_IS_OK(status)) {
128		dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
129				  &dce_call->pkt.u.request.stub_and_verifier);
130		dce_call->fault_code = DCERPC_FAULT_NDR;
131		return NT_STATUS_NET_WRITE_FAULT;
132	}
133
134	return NT_STATUS_OK;
135}
136
137static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
138{
139	uint16_t opnum = dce_call->pkt.u.request.opnum;
140	struct GUID ipid = dce_call->pkt.u.request.object.object;
141	struct dcom_interface_p *iface = dcom_get_local_iface_p(&ipid);
142	const struct dcom_$name\_vtable *vtable = iface->vtable;
143
144	switch (opnum) {
145";
146	gen_dispatch_switch($data);
147
148pidl "
149	default:
150		dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
151		break;
152	}
153
154	if (dce_call->fault_code != 0) {
155		dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
156				  &dce_call->pkt.u.request.stub_and_verifier);
157		return NT_STATUS_NET_WRITE_FAULT;
158	}
159
160	return NT_STATUS_OK;
161}
162
163static NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
164{
165	uint16_t opnum = dce_call->pkt.u.request.opnum;
166
167	switch (opnum) {
168";
169	gen_reply_switch($data);
170
171pidl "
172	default:
173		dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
174		break;
175	}
176
177	if (dce_call->fault_code != 0) {
178		dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
179				  &dce_call->pkt.u.request.stub_and_verifier);
180		return NT_STATUS_NET_WRITE_FAULT;
181	}
182
183	return NT_STATUS_OK;
184}
185
186static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r)
187{
188	NTSTATUS status;
189	uint16_t opnum = dce_call->pkt.u.request.opnum;
190
191	status = dcerpc_table_$name.calls[opnum].ndr_push(push, NDR_OUT, r);
192	if (!NT_STATUS_IS_OK(status)) {
193		dce_call->fault_code = DCERPC_FAULT_NDR;
194		return NT_STATUS_NET_WRITE_FAULT;
195	}
196
197	return NT_STATUS_OK;
198}
199
200static const struct dcesrv_interface $name\_interface = {
201	.name		= \"$name\",
202	.uuid		= $uuid,
203	.if_version	= $if_version,
204	.bind		= $name\__op_bind,
205	.unbind		= $name\__op_unbind,
206	.ndr_pull	= $name\__op_ndr_pull,
207	.dispatch	= $name\__op_dispatch,
208	.reply		= $name\__op_reply,
209	.ndr_push	= $name\__op_ndr_push
210};
211
212";
213}
214
215#####################################################################
216# produce boilerplate code for an endpoint server
217sub Boilerplate_Ep_Server($)
218{
219	my($interface) = shift;
220	my $name = $interface->{NAME};
221	my $uname = uc $name;
222
223	pidl "
224static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
225{
226	int i;
227
228	for (i=0;i<dcerpc_table_$name.endpoints->count;i++) {
229		NTSTATUS ret;
230		const char *name = dcerpc_table_$name.endpoints->names[i];
231
232		ret = dcesrv_interface_register(dce_ctx, name, &$name\_interface, NULL);
233		if (!NT_STATUS_IS_OK(ret)) {
234			DEBUG(1,(\"$name\_op_init_server: failed to register endpoint \'%s\'\\n\",name));
235			return ret;
236		}
237	}
238
239	return NT_STATUS_OK;
240}
241
242static BOOL $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32_t if_version)
243{
244	if (dcerpc_table_$name.if_version == if_version &&
245		strcmp(dcerpc_table_$name.uuid, uuid)==0) {
246		memcpy(iface,&dcerpc_table_$name, sizeof(*iface));
247		return True;
248	}
249
250	return False;
251}
252
253static BOOL $name\__op_interface_by_name(struct dcesrv_interface *iface, const char *name)
254{
255	if (strcmp(dcerpc_table_$name.name, name)==0) {
256		memcpy(iface,&dcerpc_table_$name, sizeof(*iface));
257		return True;
258	}
259
260	return False;
261}
262
263NTSTATUS dcerpc_server_$name\_init(void)
264{
265	NTSTATUS ret;
266	struct dcesrv_endpoint_server ep_server;
267
268	/* fill in our name */
269	ep_server.name = \"$name\";
270
271	/* fill in all the operations */
272	ep_server.init_server = $name\__op_init_server;
273
274	ep_server.interface_by_uuid = $name\__op_interface_by_uuid;
275	ep_server.interface_by_name = $name\__op_interface_by_name;
276
277	/* register ourselves with the DCERPC subsystem. */
278	ret = dcerpc_register_ep_server(&ep_server);
279
280	if (!NT_STATUS_IS_OK(ret)) {
281		DEBUG(0,(\"Failed to register \'$name\' endpoint server!\\n\"));
282		return ret;
283	}
284
285	return ret;
286}
287
288";
289}
290
291#####################################################################
292# dcom interface stub from a parsed IDL structure
293sub ParseInterface($)
294{
295	my($interface) = shift;
296
297	return "" if has_property($interface, "local");
298
299	my($data) = $interface->{DATA};
300	my $count = 0;
301
302	$res = "";
303
304	if (!defined $interface->{PROPERTIES}->{uuid}) {
305		return $res;
306	}
307
308	if (!defined $interface->{PROPERTIES}->{version}) {
309		$interface->{PROPERTIES}->{version} = "0.0";
310	}
311
312	foreach my $d (@{$data}) {
313		if ($d->{TYPE} eq "FUNCTION") { $count++; }
314	}
315
316	if ($count == 0) {
317		return $res;
318	}
319
320	$res = "/* dcom interface stub generated by pidl */\n\n";
321	Boilerplate_Iface($interface);
322	Boilerplate_Ep_Server($interface);
323
324	return $res;
325}
326
3271;
328