summaryrefslogtreecommitdiff
path: root/source4/build/pidl/proxy.pm
diff options
context:
space:
mode:
Diffstat (limited to 'source4/build/pidl/proxy.pm')
-rw-r--r--source4/build/pidl/proxy.pm166
1 files changed, 166 insertions, 0 deletions
diff --git a/source4/build/pidl/proxy.pm b/source4/build/pidl/proxy.pm
new file mode 100644
index 0000000000..b6d9733419
--- /dev/null
+++ b/source4/build/pidl/proxy.pm
@@ -0,0 +1,166 @@
+###################################################
+# DCOM proxy generator
+# Copyright jelmer@samba.org 2003
+# released under the GNU GPL
+
+package IdlProxy;
+
+use strict;
+
+my($res);
+
+sub ParseVTable($$)
+{
+ my $interface = shift;
+ my $name = shift;
+
+ # Generate the vtable
+ $res .="\tstruct dcom_$interface->{NAME}_vtable $name = {";
+
+ if (defined($interface->{BASE})) {
+ $res .= "\n\t\t{},";
+ }
+
+ my $data = $interface->{DATA};
+
+ foreach my $d (@{$data}) {
+ if ($d->{TYPE} eq "FUNCTION") {
+ $res .= "\n\t\tdcom_proxy_$interface->{NAME}_$d->{NAME}";
+ $res .= ",";
+ }
+ }
+
+ $res .= "\n\t};\n\n";
+}
+
+sub ParseRegFunc($)
+{
+ my $interface = shift;
+
+ $res .= "NTSTATUS dcom_$interface->{NAME}_init(void)
+{
+ struct dcom_interface iface;
+";
+
+ ParseVTable($interface, "proxy");
+
+ if (defined($interface->{BASE})) {
+ $res.= "
+ const void *base_vtable;
+
+ GUID_from_string(DCERPC_" . (uc $interface->{BASE}) . "_UUID, &iface.base_iid);
+
+ base_vtable = dcom_proxy_vtable_by_iid(&iface.base_iid);
+ if (base_vtable == NULL) {
+ return NT_STATUS_FOOBAR;
+ }
+
+ proxy.base = *((const struct dcom_$interface->{BASE}_vtable *)base_vtable);
+ ";
+ } else {
+ $res .= "\tZERO_STRUCT(iface.base_iid);\n";
+ }
+
+ $res.= "
+ iface.num_methods = DCERPC_" . (uc $interface->{NAME}) . "_CALL_COUNT;
+ GUID_from_string(DCERPC_" . (uc $interface->{NAME}) . "_UUID, &iface.iid);
+ iface.proxy_vtable = talloc_memdup(NULL, &proxy, sizeof(struct dcom_$interface->{NAME}_vtable));
+
+ return register_backend(\"dcom_interface\", &iface);
+}\n\n";
+}
+
+#####################################################################
+# parse a function
+sub ParseFunction($$)
+{
+ my $interface = shift;
+ my $fn = shift;
+ my $name = $fn->{NAME};
+ my $uname = uc $name;
+
+ if (util::has_property($fn, "local")) {
+ $res .= "
+static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
+{
+ /* FIXME */
+ return NT_STATUS_NOT_SUPPORTED;
+}\n";
+ } else {
+ $res .= "
+static struct rpc_request *dcom_proxy_$interface->{NAME}_$name\_send(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
+{
+ struct dcerpc_pipe *p;
+ NTSTATUS status = dcom_get_pipe(d, &p);
+
+ if (NT_STATUS_IS_ERR(status)) {
+ return NULL;
+ }
+
+ ZERO_STRUCT(r->in.ORPCthis);
+ r->in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION;
+ r->in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION;
+
+ if (p->flags & DCERPC_DEBUG_PRINT_IN) {
+ NDR_PRINT_IN_DEBUG($name, r);
+ }
+
+ return dcerpc_ndr_request_send(p, &d->ipid, DCERPC_$uname, mem_ctx,
+ (ndr_push_flags_fn_t) ndr_push_$name,
+ (ndr_pull_flags_fn_t) ndr_pull_$name,
+ r, sizeof(*r));
+}
+
+static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
+{
+ struct dcerpc_pipe *p;
+ NTSTATUS status = dcom_get_pipe(d, &p);
+ struct rpc_request *req;
+
+ if (NT_STATUS_IS_ERR(status)) {
+ return status;
+ }
+
+ req = dcom_proxy_$interface->{NAME}_$name\_send(d, mem_ctx, r);
+ if (req == NULL) return NT_STATUS_NO_MEMORY;
+
+ status = dcerpc_ndr_request_recv(req);
+
+ if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) {
+ NDR_PRINT_OUT_DEBUG($name, r);
+ }
+ ";
+ if ($fn->{RETURN_TYPE} eq "NTSTATUS") {
+ $res .= "\tif (NT_STATUS_IS_OK(status)) status = r->out.result;\n";
+ }
+ $res .=
+ "
+ return status;
+}";
+ }
+
+ $res .="
+NTSTATUS dcom_$interface->{NAME}_$name (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r)
+{
+ return ((const struct dcom_$interface->{NAME}_vtable *)d->vtable)->$name (d, mem_ctx, r);
+}
+";
+}
+
+
+#####################################################################
+# parse the interface definitions
+sub ParseInterface($)
+{
+ my($interface) = shift;
+ my($data) = $interface->{DATA};
+ $res = "/* DCOM stubs generated by pidl */\n\n";
+ foreach my $d (@{$data}) {
+ ($d->{TYPE} eq "FUNCTION") &&
+ ParseFunction($interface, $d);
+ }
+
+ ParseRegFunc($interface);
+}
+
+1;