merged rpcrt-server part from transgaming (Ove) --- juergen.schmied@debitel.net
Index: wine/server/Makefile.in =================================================================== RCS file: /home/wine/wine/server/Makefile.in,v retrieving revision 1.33 diff -d -u -r1.33 Makefile.in --- wine/server/Makefile.in 9 May 2002 04:31:40 -0000 1.33 +++ wine/server/Makefile.in 16 Jun 2002 10:54:05 -0000 @@ -28,6 +28,7 @@ queue.c \ registry.c \ request.c \ + rpc_epmap.c \ select.c \ semaphore.c \ serial.c \ Index: wine/server/protocol.def =================================================================== RCS file: /home/wine/wine/server/protocol.def,v retrieving revision 1.39 diff -d -u -r1.39 protocol.def --- wine/server/protocol.def 2 Jun 2002 21:22:22 -0000 1.39 +++ wine/server/protocol.def 16 Jun 2002 10:54:09 -0000 @@ -1904,3 +1904,28 @@ int total; /* total number of properties */ VARARG(props,properties); /* list of properties */ @END + + +/* Register RPC endpoints */ +@REQ(register_rpc_endpoints) + int objects; /* number of objects */ + int bindings; /* number of bindings */ + int no_replace; /* don't replace existing endpoints */ + VARARG(eps,bytes); /* list of bindings and objects */ +@END + + +/* Unregister RPC endpoints */ +@REQ(unregister_rpc_endpoints) + int objects; /* number of objects */ + int bindings; /* number of bindings */ + VARARG(eps,bytes); /* list of bindings and objects */ +@END + + +/* Resolve RPC endpoint */ +@REQ(resolve_rpc_endpoint) + VARARG(binding,bytes); /* unmapped binding */ +@REPLY + VARARG(ep,bytes); /* mapped endpoint */ +@END Index: wine/server/request.h =================================================================== RCS file: /home/wine/wine/server/request.h,v retrieving revision 1.71 diff -d -u -r1.71 request.h --- wine/server/request.h 2 Jun 2002 21:22:22 -0000 1.71 +++ wine/server/request.h 16 Jun 2002 10:54:13 -0000 @@ -257,6 +257,9 @@ DECL_HANDLER(remove_window_property); DECL_HANDLER(get_window_property); DECL_HANDLER(get_window_properties); +DECL_HANDLER(register_rpc_endpoints); +DECL_HANDLER(unregister_rpc_endpoints); +DECL_HANDLER(resolve_rpc_endpoint); #ifdef WANT_REQUEST_HANDLERS @@ -419,6 +422,9 @@ (req_handler)req_remove_window_property, (req_handler)req_get_window_property, (req_handler)req_get_window_properties, + (req_handler)req_register_rpc_endpoints, + (req_handler)req_unregister_rpc_endpoints, + (req_handler)req_resolve_rpc_endpoint, }; #endif /* WANT_REQUEST_HANDLERS */ --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/server/rpc_epmap.c Thu Jun 13 17:23:20 2002 @@ -0,0 +1,191 @@ +/* + * RPC endpoint mapper + * + * Copyright (C) 2001 Ove Kåven, TransGaming Technologies Inc. + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "unicode.h" +#include "request.h" +#include "process.h" + +#include "rpc.h" + +struct epmap_entry +{ + struct epmap_entry *next; + RPC_SYNTAX_IDENTIFIER iface; + UUID object; + char *protseq; + char *endpoint; +}; + +struct epmap_entry *epmap; + +static const UUID nil_object; + +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; + return map; + } + 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; + + 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) { + free(map->endpoint); + } + else { + map = mem_alloc(sizeof(struct epmap_entry)); + memcpy(&map->iface, iface, sizeof(RPC_SYNTAX_IDENTIFIER)); + memcpy(&map->object, &objects[c], sizeof(UUID)); + map->protseq = strdup(protseq); + map->next = epmap; + epmap = map; + } + map->endpoint = strdup(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; + + if (!objcount) { + objects = &nil_object; + objcount = 1; + } + + for (prev=NULL,nprev=NULL,map=epmap,next=map->next; map; prev=nprev,map=next,next=map->next) { + nprev = map; + if (memcmp(&map->iface, iface, sizeof(RPC_SYNTAX_IDENTIFIER))) continue; + for (c=0; c<objcount; c++) + if (!memcmp(&map->object, &objects[c], sizeof(UUID))) break; + if (c==objcount) continue; + if (strcmp(map->protseq, protseq)) continue; + + if (prev) prev->next = map->next; + else epmap = map->next; + nprev = prev; + + free(map->protseq); + free(map->endpoint); + free(map); + } +} + +static void resolve_endpoint(const RPC_SYNTAX_IDENTIFIER *iface, const char *protseq, + const UUID *object) +{ + size_t len; + char *data; + struct epmap_entry *map; + + if (!(map = find_endpoint(iface, protseq, object))) { + set_error( EPT_NT_NOT_REGISTERED ); + return; + } + + len = min( get_reply_max_size(), strlen(map->endpoint)+1 ); + if (len && ((data = set_reply_data_size(len)))) + memcpy(data, map->endpoint, len); +} + +static const void *get_struct(const char**ptr, const char*end, size_t size) +{ + const char *data = *ptr; + + *ptr = data + size; + if (*ptr > end) { + set_error( STATUS_INVALID_PARAMETER ); + return NULL; + } + + return data; +} + +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) { + set_error( STATUS_INVALID_PARAMETER ); + return NULL; + } + *ptr = nptr + 1; + + return str; +} + +DECL_HANDLER(register_rpc_endpoints) +{ + const char *data = get_req_data(); + const char *end = data + get_req_data_size(); + const RPC_SYNTAX_IDENTIFIER *iface = get_struct(&data, end, sizeof(RPC_SYNTAX_IDENTIFIER)); + const UUID *objects = get_struct(&data, end, req->objects * sizeof(UUID)); + if (iface && objects) { + int c; + for (c=0; c<req->bindings; c++) { + const char *protseq = get_string(&data, end); + const char *endpoint = get_string(&data, end); + if (protseq && endpoint) + register_endpoint(iface, protseq, endpoint, objects, req->objects, req->no_replace); + } + } +} + +DECL_HANDLER(unregister_rpc_endpoints) +{ + const char *data = get_req_data(); + const char *end = data + get_req_data_size(); + const RPC_SYNTAX_IDENTIFIER *iface = get_struct(&data, end, sizeof(RPC_SYNTAX_IDENTIFIER)); + const UUID *objects = get_struct(&data, end, req->objects * sizeof(UUID)); + if (iface && objects) { + int c; + for (c=0; c<req->bindings; c++) { + const char *protseq = get_string(&data, end); + const char *endpoint = get_string(&data, end); + if (protseq && endpoint) + unregister_endpoint(iface, protseq, endpoint, objects, req->objects); + } + } +} + +DECL_HANDLER(resolve_rpc_endpoint) +{ + const char *data = get_req_data(); + const char *end = data + get_req_data_size(); + const RPC_SYNTAX_IDENTIFIER *iface = get_struct(&data, end, sizeof(RPC_SYNTAX_IDENTIFIER)); + const UUID *object = get_struct(&data, end, sizeof(UUID)); + const char *protseq = get_string(&data, end); + if (iface && object && protseq) { + resolve_endpoint(iface, protseq, object); + } +}