211 lines
6.3 KiB
C
211 lines
6.3 KiB
C
/*
|
|
* 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 <assert.h>
|
|
#include <string.h>
|
|
|
|
#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; c<objcount; c++) {
|
|
struct epmap_entry *map = NULL;
|
|
if (!no_replace)
|
|
map = find_endpoint(iface, protseq, &objects[c]);
|
|
if (map) {
|
|
LocalFree(map->endpoint);
|
|
}
|
|
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; c<objcount; c++)
|
|
if (!memcmp(&map->object, &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);
|
|
}
|