1/* 2 Unix SMB/CIFS implementation. 3 COM class tables 4 Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org> 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*/ 20 21#include "includes.h" 22#include "../lib/util/dlinklist.h" 23#include "lib/com/com.h" 24#include "librpc/gen_ndr/ndr_misc.h" 25 26/* Specific implementation of one or more interfaces */ 27struct com_class 28{ 29 const char *progid; 30 struct GUID clsid; 31 32 struct IUnknown *class_object; 33 struct com_class *prev, *next; 34} * running_classes = NULL; 35 36static struct IUnknown *get_com_class_running(const struct GUID *clsid) 37{ 38 struct com_class *c = running_classes; 39 40 while(c) { 41 42 if (GUID_equal(clsid, &c->clsid)) { 43 return c->class_object; 44 } 45 46 c = c->next; 47 } 48 49 return NULL; 50} 51 52static struct IUnknown *get_com_class_so(TALLOC_CTX *mem_ctx, const struct GUID *clsid) 53{ 54 char *module_name; 55 char *clsid_str; 56 void *mod; 57 get_class_object_function f; 58 59 clsid_str = GUID_string(mem_ctx, clsid); 60 module_name = talloc_asprintf(mem_ctx, "%s.so", clsid_str); 61 talloc_free(clsid_str); 62 63 mod = dlopen(module_name, 0); 64 65 if (!mod) { 66 return NULL; 67 } 68 69 f = dlsym(mod, "get_class_object"); 70 71 if (!f) { 72 return NULL; 73 } 74 75 return f(clsid); 76} 77 78struct IUnknown *com_class_by_clsid(struct com_context *ctx, const struct GUID *clsid) 79{ 80 struct IUnknown *c; 81 82 /* Check list of running COM classes first */ 83 c = get_com_class_running(clsid); 84 85 if (c != NULL) { 86 return c; 87 } 88 89 c = get_com_class_so(ctx, clsid); 90 91 if (c != NULL) { 92 return c; 93 } 94 95 return NULL; 96} 97 98NTSTATUS com_register_running_class(struct GUID *clsid, const char *progid, struct IUnknown *p) 99{ 100 struct com_class *l = talloc_zero(running_classes?running_classes:talloc_autofree_context(), struct com_class); 101 102 l->clsid = *clsid; 103 l->progid = talloc_strdup(l, progid); 104 l->class_object = p; 105 106 DLIST_ADD(running_classes, l); 107 108 return NT_STATUS_OK; 109} 110