/* * RPC endpoint mapper server * * Copyright (C) 2001 Ove Kåven, TransGaming Technologies Inc, * Copyright (C) 2002 Greg Turner * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "rpcss.h" #include "rpc.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); struct epmap_entry { struct epmap_entry *next; RPC_SYNTAX_IDENTIFIER iface; UUID object; char *protseq; char *endpoint; }; static struct epmap_entry *epmap; static const UUID nil_object; char *mystrdup(const char *str) { char *rval; rval = LocalAlloc(LPTR, strlen(str)+1); CopyMemory(rval, str, strlen(str)+1); return rval; } static struct epmap_entry *find_endpoint(const RPC_SYNTAX_IDENTIFIER *iface, const char *protseq, const UUID *object) { struct epmap_entry *map; for (map=epmap; map; map=map->next) { if (memcmp(&map->iface, iface, sizeof(RPC_SYNTAX_IDENTIFIER))) continue; if (memcmp(&map->object, object, sizeof(UUID))) continue; if (strcmp(map->protseq, protseq)) continue; WINE_TRACE("found.\n"); return map; } WINE_TRACE("not found.\n"); return NULL; } static void register_endpoint(const RPC_SYNTAX_IDENTIFIER *iface, const char *protseq, const char *endpoint, const UUID *objects, int objcount, int no_replace) { int c; WINE_TRACE("(protseq == %s, endpoint == %s, objcount == %i, no_replace == %i)\n", wine_dbgstr_a(protseq), wine_dbgstr_a(endpoint), objcount, no_replace); if (!objcount) { objects = &nil_object; objcount = 1; } for (c=0; cendpoint); } else { map = LocalAlloc(LPTR, sizeof(struct epmap_entry)); memcpy(&map->iface, iface, sizeof(RPC_SYNTAX_IDENTIFIER)); memcpy(&map->object, &objects[c], sizeof(UUID)); map->protseq = mystrdup(protseq); map->next = epmap; epmap = map; } WINE_TRACE(" mapping endpoint (protseq == %s, endpoint == %s, uuid == %s)\n", wine_dbgstr_a(protseq), wine_dbgstr_a(endpoint), wine_dbgstr_guid(&objects[c])); map->endpoint = mystrdup(endpoint); } } static void unregister_endpoint(const RPC_SYNTAX_IDENTIFIER *iface, const char *protseq, const char *endpoint, const UUID *objects, int objcount) { struct epmap_entry *map, *prev, *nprev, *next; int c; WINE_TRACE("(protseq == %s, endpoint == %s, objcount == %i)\n", wine_dbgstr_a(protseq), wine_dbgstr_a(endpoint), objcount); if (!objcount) { objects = &nil_object; objcount = 1; } prev=NULL; nprev=NULL; map=epmap; while(map) { next = map->next; nprev = map; if (memcmp(&map->iface, iface, sizeof(RPC_SYNTAX_IDENTIFIER))) goto cont; for (c=0; cobject, &objects[c], sizeof(UUID))) break; if (c==objcount) goto cont; if (strcmp(map->protseq, protseq)) goto cont; WINE_TRACE(" unmapping: (protseq == %s, endpoint == %s, uuid == %s)\n", wine_dbgstr_a(map->protseq), wine_dbgstr_a(map->endpoint), wine_dbgstr_guid(&map->object)); if (prev) prev->next = map->next; else epmap = map->next; nprev = prev; LocalFree(map->protseq); LocalFree(map->endpoint); LocalFree(map); cont: prev = nprev; map = next; } } static void resolve_endpoint(const RPC_SYNTAX_IDENTIFIER *iface, const char *protseq, const UUID *object, char *rslt_ep) { size_t len; struct epmap_entry *map; if (!(map = find_endpoint(iface, protseq, object))) return; len = min( MAX_RPCSS_NP_REPLY_STRING_LEN, strlen(map->endpoint)+1 ); if (len) memcpy(rslt_ep, map->endpoint, len); } static const char *get_string(const char**ptr, const char*end) { const char *str = *ptr, *nptr = str; while (nptr < end && *nptr) nptr++; if (nptr == end) return NULL; *ptr = nptr + 1; return str; } BOOL RPCSS_EpmapEmpty(void) { return (!epmap); } void RPCSS_RegisterRpcEndpoints(RPC_SYNTAX_IDENTIFIER iface, int object_count, int binding_count, int no_replace, char *vardata, long vardata_size) { const char *data = vardata; const char *end = data + vardata_size; UUID *objects = (UUID *)data; int c; data += object_count * sizeof(UUID); for (c=0; c < binding_count; c++) { const char *protseq = get_string(&data, end); const char *endpoint = get_string(&data, end); if (protseq && endpoint) register_endpoint(&iface, protseq, endpoint, objects, object_count, no_replace); } } void RPCSS_UnregisterRpcEndpoints(RPC_SYNTAX_IDENTIFIER iface, int object_count, int binding_count, char *vardata, long vardata_size) { const char *data = vardata; const char *end = data + vardata_size; const UUID *objects = (UUID *)data; int c; data += object_count * sizeof(UUID); for (c=0; c < binding_count; c++) { const char *protseq = get_string(&data, end); const char *endpoint = get_string(&data, end); if (protseq && endpoint) unregister_endpoint(&iface, protseq, endpoint, objects, object_count); } } void RPCSS_ResolveRpcEndpoints(RPC_SYNTAX_IDENTIFIER iface, UUID object, char *protseq, char *rslt_ep) { resolve_endpoint(&iface, protseq, &object, rslt_ep); }