summaryrefslogtreecommitdiff
path: root/source4/lib/com
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-02-21 14:30:49 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:10:50 -0500
commit80d3047333fceb3805ccd10a08cdf95021f57ff4 (patch)
tree16ccb10ace9efe6b52d80e8bfd3f0fd483762f23 /source4/lib/com
parent6b4cac2c00bd77c34bfe47f35729a60782b8c9c2 (diff)
downloadsamba-80d3047333fceb3805ccd10a08cdf95021f57ff4.tar.gz
samba-80d3047333fceb3805ccd10a08cdf95021f57ff4.tar.bz2
samba-80d3047333fceb3805ccd10a08cdf95021f57ff4.zip
r5490: The big (D)COM commit! :-) Contains most of the changes described in the
DCOM paper in lorikeet. This is the result of 1.5 months work (mainly figuring out how things *really* work) at the end of 2004. In general: - Clearer distinction between COM and DCOM. DCOM is now merely the glue between DCE/RPC+ORPC and COM. COM can also work without DCOM now. This makes the code a lot clearer. - Clearer distinction between NDR and DCOM. Before, NDR had a couple of "if"s to cope with DCOM, which are now gone. - Use "real" arguments rather then structures for function arguments in COM, mainly because most of these calls are local so packing/unpacking data for every call is too much overhead (both speed- and code-wise) - Support several mechanisms to load class objects: - from memory (e.g. part of the current executable, registered at start-up) - from shared object files - remotely - Most things are now also named COM rather then DCOM because that's what it really is. After an object is created, it no longer matters whether it was created locally or remotely. There is a very simple example class that contains both a class factory and a class that implements the IStream interface. It can be tested (locally only, remotely is broken at the moment) by running the COM-SIMPLE smbtorture test. Still to-do: - Autogenerate parts of the class implementation code (using the coclass definitions in IDL) - Test server-side - Implement some of the common classes, add definitions for common interfaces. (This used to be commit 71fd3e5c3aac5f0002001ab29d2248e6c6842d6f)
Diffstat (limited to 'source4/lib/com')
-rw-r--r--source4/lib/com/classes/simple.c116
-rw-r--r--source4/lib/com/com.h30
-rw-r--r--source4/lib/com/config.mk10
-rw-r--r--source4/lib/com/main.c85
-rw-r--r--source4/lib/com/rot.c34
-rw-r--r--source4/lib/com/tables.c107
6 files changed, 382 insertions, 0 deletions
diff --git a/source4/lib/com/classes/simple.c b/source4/lib/com/classes/simple.c
new file mode 100644
index 0000000000..2c72d56f94
--- /dev/null
+++ b/source4/lib/com/classes/simple.c
@@ -0,0 +1,116 @@
+/*
+ Unix SMB/CIFS implementation.
+ Simple class
+ Copyright (C) 2004-2005 Jelmer Vernooij <jelmer@samba.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "lib/com/com.h"
+#include "librpc/gen_ndr/com_dcom.h"
+
+
+static WERROR simple_QueryInterface (struct IUnknown *d, TALLOC_CTX *mem_ctx, struct GUID *iid, struct IUnknown **iun)
+{
+ *iun = d;
+ return WERR_OK;
+}
+
+static uint32_t simple_AddRef (struct IUnknown *d, TALLOC_CTX *mem_ctx)
+{
+ return 1;
+}
+
+static uint32_t simple_Release (struct IUnknown *d, TALLOC_CTX *mem_ctx)
+{
+ return 1;
+}
+
+static WERROR simple_Read (struct IStream *d, TALLOC_CTX *mem_ctx, uint8_t *pv, uint32_t num_requested, uint32_t *num_readx, uint32_t num_read)
+{
+ printf("%d bytes are being read\n", num_read);
+ return WERR_OK;
+}
+
+static WERROR simple_Write (struct IStream *d, TALLOC_CTX *mem_ctx, uint8_t *data, uint32_t num_requested, uint32_t num_written)
+{
+ printf("%d bytes are being written\n", num_requested);
+ return WERR_OK;
+}
+
+static struct IStream_vtable simple_istream_vtable = {
+ simple_QueryInterface,
+ simple_AddRef,
+ simple_Release,
+ simple_Read,
+ simple_Write
+};
+
+static WERROR simpleclass_QueryInterface (struct IUnknown *d, TALLOC_CTX *mem_ctx, struct GUID *iid, struct IUnknown **iun)
+{
+ /* FIXME: Return WERR_IFACE_NOT_SUPPORTED if IID != IID_IUNKNOWN and IID != IID_CLASSFACTORY */
+ *iun = d;
+ return WERR_OK;
+}
+
+static WERROR simpleclass_CreateInstance (struct IClassFactory *d, TALLOC_CTX *mem_ctx, struct IUnknown *iunk, struct GUID *iid, struct IUnknown **ppv)
+{
+ struct IStream *ret;
+ /* FIXME: Check whether IID == ISTREAM_IID */
+ ret = talloc(mem_ctx, struct IStream);
+ ret->ctx = NULL;
+ ret->vtable = &simple_istream_vtable;
+ ret->object_data = NULL;
+
+ *ppv = ret;
+
+ return WERR_OK;
+}
+
+static uint32_t simpleclass_AddRef (struct IUnknown *d, TALLOC_CTX *mem_ctx)
+{
+ return 1;
+}
+
+static uint32_t simpleclass_Release (struct IUnknown *d, TALLOC_CTX *mem_ctx)
+{
+ return 1;
+}
+
+/* Everything below this line should be autogenerated later on */
+static struct IClassFactory_vtable simple_classobject_vtable = {
+ simpleclass_QueryInterface,
+ simpleclass_AddRef,
+ simpleclass_Release,
+ simpleclass_CreateInstance,
+ NULL,
+ NULL,
+ NULL
+};
+
+NTSTATUS com_simple_init(void)
+{
+ struct GUID clsid;
+ struct IUnknown *class_object = talloc(talloc_autofree_context(), struct IUnknown);
+
+ class_object->ctx = NULL;
+ class_object->object_data = NULL;
+ class_object->vtable = (struct IUnknown_vtable *)&simple_classobject_vtable;
+
+ GUID_from_string("5e9ddec7-5767-11cf-beab-00aa006c3606", &clsid);
+
+ return com_register_running_class(&clsid, "Samba.Simple", class_object);
+}
diff --git a/source4/lib/com/com.h b/source4/lib/com/com.h
new file mode 100644
index 0000000000..be7dcde5b5
--- /dev/null
+++ b/source4/lib/com/com.h
@@ -0,0 +1,30 @@
+/*
+ Unix SMB/CIFS implementation.
+ COM standard objects
+ Copyright (C) Jelmer Vernooij 2004-2005.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _COM_H /* _COM_H */
+#define _COM_H
+
+struct com_context
+{
+};
+
+typedef struct IUnknown *(*get_class_object_function) (const struct GUID *clsid);
+
+#endif /* _COM_H */
diff --git a/source4/lib/com/config.mk b/source4/lib/com/config.mk
new file mode 100644
index 0000000000..006ea212c1
--- /dev/null
+++ b/source4/lib/com/config.mk
@@ -0,0 +1,10 @@
+[SUBSYSTEM::LIBCOM]
+INIT_OBJ_FILES = \
+ lib/com/tables.o \
+ lib/com/rot.o \
+ lib/com/main.o
+
+[MODULE::com_simple]
+SUBSYSTEM = LIBCOM
+INIT_OBJ_FILES = lib/com/classes/simple.o
+INIT_FUNCTION = com_simple_init
diff --git a/source4/lib/com/main.c b/source4/lib/com/main.c
new file mode 100644
index 0000000000..378c3738b9
--- /dev/null
+++ b/source4/lib/com/main.c
@@ -0,0 +1,85 @@
+/*
+ Unix SMB/CIFS implementation.
+ Main COM functionality
+ Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "dlinklist.h"
+#include "lib/com/com.h"
+#include "librpc/gen_ndr/com_dcom.h"
+
+WERROR com_init(struct com_context **ctx)
+{
+ *ctx = talloc(NULL, struct com_context);
+ return WERR_OK;
+}
+
+WERROR com_create_object(struct com_context *ctx, struct GUID *clsid, int num_ifaces, struct GUID *iid, struct IUnknown **ip, WERROR *results)
+{
+ struct IUnknown *iunk = NULL;
+ struct IClassFactory *factory;
+ WERROR error;
+ int i;
+ struct GUID classfact_iid;
+
+ GUID_from_string(DCERPC_ICLASSFACTORY_UUID, &classfact_iid);
+
+ /* Obtain class object */
+ error = com_get_class_object(ctx, clsid, &classfact_iid, (struct IUnknown **)&factory);
+ if (!W_ERROR_IS_OK(error)) {
+ DEBUG(3, ("Unable to obtain class object for %s\n", GUID_string(NULL, clsid)));
+ return error;
+ }
+
+ /* Run IClassFactory::CreateInstance() */
+ error = IClassFactory_CreateInstance(factory, ctx, NULL, &classfact_iid, &iunk);
+ if (!W_ERROR_IS_OK(error)) {
+ DEBUG(3, ("Error while calling IClassFactory::CreateInstance : %s\n", win_errstr(error)));
+ return error;
+ }
+
+ if (!iunk) {
+ DEBUG(0, ("IClassFactory_CreateInstance returned success but result pointer is still NULL!\n"));
+ return WERR_GENERAL_FAILURE;
+ }
+
+ /* Release class object */
+ IUnknown_Release(factory, ctx);
+
+ error = WERR_OK;
+
+ /* Do one or more QueryInterface calls */
+ for (i = 0; i < num_ifaces; i++) {
+ results[i] = IUnknown_QueryInterface(iunk, ctx, &iid[i], &ip[i]);
+ if (!W_ERROR_IS_OK(results[i])) error = results[i];
+ }
+
+ return error;
+}
+
+WERROR com_get_class_object(struct com_context *ctx, struct GUID *clsid, struct GUID *iid, struct IUnknown **ip)
+{
+ struct IUnknown *iu;
+
+ iu = com_class_by_clsid(ctx, clsid);
+ if (!iu) {
+ return WERR_CLASS_NOT_REGISTERED;
+ }
+
+ return IUnknown_QueryInterface(iu, ctx, iid, ip);
+}
diff --git a/source4/lib/com/rot.c b/source4/lib/com/rot.c
new file mode 100644
index 0000000000..34a5671f5b
--- /dev/null
+++ b/source4/lib/com/rot.c
@@ -0,0 +1,34 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Running object table functions
+
+ Copyright (C) Jelmer Vernooij 2004-2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+struct dcom_interface_p *dcom_get_local_iface_p(struct GUID *ipid)
+{
+ /* FIXME: Call the local ROT and do a
+ * rot_get_interface_pointer call */
+
+ /* FIXME: Perhaps have a local (thread-local) table with
+ * local DCOM objects so that not every DCOM call requires a lookup
+ * to the ROT? */
+ return NULL;
+}
diff --git a/source4/lib/com/tables.c b/source4/lib/com/tables.c
new file mode 100644
index 0000000000..cf63e7e9a2
--- /dev/null
+++ b/source4/lib/com/tables.c
@@ -0,0 +1,107 @@
+/*
+ Unix SMB/CIFS implementation.
+ COM class tables
+ Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "dlinklist.h"
+
+/* Specific implementation of one or more interfaces */
+struct com_class
+{
+ const char *progid;
+ struct GUID clsid;
+
+ struct IUnknown *class_object;
+ struct com_class *prev, *next;
+} * running_classes = NULL;
+
+static struct IUnknown *get_com_class_running(const struct GUID *clsid)
+{
+ struct com_class *c = running_classes;
+
+ while(c) {
+
+ if (GUID_equal(clsid, &c->clsid)) {
+ return c->class_object;
+ }
+
+ c = c->next;
+ }
+
+ return NULL;
+}
+
+static struct IUnknown *get_com_class_so(TALLOC_CTX *mem_ctx, const struct GUID *clsid)
+{
+ char *mod_name;
+ char *clsid_str;
+ void *mod;
+ get_class_object_function f;
+
+ clsid_str = GUID_string(mem_ctx, clsid);
+ mod_name = talloc_asprintf(mem_ctx, "%s.so", clsid_str);
+ talloc_free(clsid_str);
+
+ mod = sys_dlopen(mod_name, 0);
+
+ if (!mod) {
+ return NULL;
+ }
+
+ f = sys_dlsym(mod, "get_class_object");
+
+ if (!f) {
+ return NULL;
+ }
+
+ return f(clsid);
+}
+
+struct IUnknown *com_class_by_clsid(struct com_context *ctx, const struct GUID *clsid)
+{
+ struct IUnknown *c;
+
+ /* Check list of running COM classes first */
+ c = get_com_class_running(clsid);
+
+ if (c != NULL) {
+ return c;
+ }
+
+ c = get_com_class_so(ctx, clsid);
+
+ if (c != NULL) {
+ return c;
+ }
+
+ return NULL;
+}
+
+NTSTATUS com_register_running_class(struct GUID *clsid, const char *progid, struct IUnknown *p)
+{
+ struct com_class *l = talloc_zero(running_classes?running_classes:talloc_autofree_context(), struct com_class);
+
+ l->clsid = *clsid;
+ l->progid = talloc_strdup(l, progid);
+ l->class_object = p;
+
+ DLIST_ADD(running_classes, l);
+
+ return NT_STATUS_OK;
+}