this is it: RPC Merge (D_PL0)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




This should be about the last of the stuff from Ove's partial RPC
implementation.  I'm not sure this should, or will, go in as-is, as
it includes the controversial wineserver portions.

From Jürgen Schmied's RPC patches.
Minor changes may exist between this and the original 
patch but it's intended to be basically the same stuff.

LICENSE: X11

CHANGELOG:

* dlls/rpcrt4: rpcrt4.spec, Makefile.in, rpc_epmap.c (new);
  include/wine/server_protocol.h;
  server: Makefile.in, trace.c, request.h, protocol.def, 
  rpc_epmap.c (new): Ove Kåven <ovek@transgaming.com>
- implement RpcEpRegisterA, RpcEpResolveBinding, and 
  RpcEpUnregister
- extend the wineserver to do endpoint mapping

===============
Notes on this:

So far, I've tested the "hello world" example from the latest
Platform SDK (compiled native).  The server bumps
up against the lack of a RpcMgmtWaitServerListen() function:

greg@yodull midled $ wine hellos.exe
fixme:win32:PE_CreateModule Security directory ignored
RpcServerUseProtseqEp returned 0x0
RpcServerRegisterIf returned 0x0
Calling RpcServerListen
fixme:ole:RpcServerListen can't wait yet
RpcServerListen returned: 0x0

The client fails due to the stubby RPCRT4_NdrClientCall2,
and raises some exception:

greg@yodull midled $ wine -- helloc -n 10.10.1.96
fixme:win32:PE_CreateModule Security directory ignored
RpcStringBindingCompose returned 0x0
pszStringBinding = ncacn_np:10.10.1.96[\pipe\hello]
RpcBindingFromStringBinding returned 0x0
Calling the remote procedure 'HelloProc'
Print the string 'hello, world' on the server
fixme:ole:RPCRT4_NdrClientCall2 (0x4020c2,0x406f2d90,...)
Runtime reported exception 0xc0000005 = -1073741819
RpcStringFree returned 0x0
RpcBindingFree returned 0x0

Not sure I'm even using the right transport ("\pipe\hello" looks
about right tho), I've just begun to play with it... nevertheless,
here you are.  I'll do a final audit of the patches to make sure 
nothing was left out from the originals.  Barring that, further 
work will attempt to start filling in these gaps, extend widl to
provide for RPC needs, and establish some meaningful tests,
or at least that's the direction I'd like to head in if I prove 
sufficiently competent :)

Any advice, help, tips, harsh criticism, or kind words would be
appreciated.  Have fun,

-- 
gmt

"It has been well said that really up-to-date liberals
do not care what people do, as long as it is compulsory."

-George F. Will
Index: dlls/rpcrt4/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/rpcrt4/Makefile.in,v
retrieving revision 1.18
diff -u -r1.18 Makefile.in
--- dlls/rpcrt4/Makefile.in	11 Oct 2002 18:45:02 -0000	1.18
+++ dlls/rpcrt4/Makefile.in	12 Oct 2002 18:41:02 -0000
@@ -20,6 +20,7 @@
 	rpc_binding.c \
 	rpc_message.c \
 	rpc_server.c \
+	rpc_epmap.c \
 	rpcrt4_main.c
 
 SUBDIRS = tests
Index: dlls/rpcrt4/rpcrt4.spec
===================================================================
RCS file: /home/wine/wine/dlls/rpcrt4/rpcrt4.spec,v
retrieving revision 1.29
diff -u -r1.29 rpcrt4.spec
--- dlls/rpcrt4/rpcrt4.spec	11 Oct 2002 18:45:02 -0000	1.29
+++ dlls/rpcrt4/rpcrt4.spec	12 Oct 2002 18:41:02 -0000
@@ -55,12 +55,12 @@
 @ stub RpcCertGeneratePrincipalNameA
 @ stub RpcCertGeneratePrincipalNameW
 @ stub RpcCompleteAsyncCall
-@ stub RpcEpRegisterA
+@ stdcall RpcEpRegisterA(ptr ptr ptr str) RpcEpRegisterA
 @ stub RpcEpRegisterW
 @ stub RpcEpRegisterNoReplaceA
 @ stub RpcEpRegisterNoReplaceW
-@ stub RpcEpResolveBinding
-@ stub RpcEpUnregister
+@ stdcall RpcEpResolveBinding(ptr ptr) RpcEpResolveBinding
+@ stdcall RpcEpUnregister(ptr ptr ptr) RpcEpUnregister
 @ stub RpcGetAsyncCallStatus
 @ stub RpcIfIdVectorFree
 @ stub RpcIfInqId
Index: include/wine/server_protocol.h
===================================================================
RCS file: /home/wine/wine/include/wine/server_protocol.h,v
retrieving revision 1.44
diff -u -r1.44 server_protocol.h
--- include/wine/server_protocol.h	12 Oct 2002 01:24:37 -0000	1.44
+++ include/wine/server_protocol.h	12 Oct 2002 18:41:03 -0000
@@ -2731,6 +2731,48 @@
 
 
 
+struct register_rpc_endpoints_request
+{
+    struct request_header __header;
+    int            objects;
+    int            bindings;
+    int            no_replace;
+    /* VARARG(eps,bytes); */
+};
+struct register_rpc_endpoints_reply
+{
+    struct reply_header __header;
+};
+
+
+
+struct unregister_rpc_endpoints_request
+{
+    struct request_header __header;
+    int            objects;
+    int            bindings;
+    /* VARARG(eps,bytes); */
+};
+struct unregister_rpc_endpoints_reply
+{
+    struct reply_header __header;
+};
+
+
+
+struct resolve_rpc_endpoint_request
+{
+    struct request_header __header;
+    /* VARARG(binding,bytes); */
+};
+struct resolve_rpc_endpoint_reply
+{
+    struct reply_header __header;
+    /* VARARG(ep,bytes); */
+};
+
+
+
 struct attach_thread_input_request
 {
     struct request_header __header;
@@ -2976,6 +3018,9 @@
     REQ_remove_window_property,
     REQ_get_window_property,
     REQ_get_window_properties,
+    REQ_register_rpc_endpoints,
+    REQ_unregister_rpc_endpoints,
+    REQ_resolve_rpc_endpoint,
     REQ_attach_thread_input,
     REQ_get_thread_input,
     REQ_set_foreground_window,
@@ -3145,6 +3190,9 @@
     struct remove_window_property_request remove_window_property_request;
     struct get_window_property_request get_window_property_request;
     struct get_window_properties_request get_window_properties_request;
+    struct register_rpc_endpoints_request register_rpc_endpoints_request;
+    struct unregister_rpc_endpoints_request unregister_rpc_endpoints_request;
+    struct resolve_rpc_endpoint_request resolve_rpc_endpoint_request;
     struct attach_thread_input_request attach_thread_input_request;
     struct get_thread_input_request get_thread_input_request;
     struct set_foreground_window_request set_foreground_window_request;
@@ -3312,6 +3360,9 @@
     struct remove_window_property_reply remove_window_property_reply;
     struct get_window_property_reply get_window_property_reply;
     struct get_window_properties_reply get_window_properties_reply;
+    struct register_rpc_endpoints_reply register_rpc_endpoints_reply;
+    struct unregister_rpc_endpoints_reply unregister_rpc_endpoints_reply;
+    struct resolve_rpc_endpoint_reply resolve_rpc_endpoint_reply;
     struct attach_thread_input_reply attach_thread_input_reply;
     struct get_thread_input_reply get_thread_input_reply;
     struct set_foreground_window_reply set_foreground_window_reply;
@@ -3320,6 +3371,6 @@
     struct set_capture_window_reply set_capture_window_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 87
+#define SERVER_PROTOCOL_VERSION 88
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
Index: server/Makefile.in
===================================================================
RCS file: /home/wine/wine/server/Makefile.in,v
retrieving revision 1.34
diff -u -r1.34 Makefile.in
--- server/Makefile.in	17 Aug 2002 01:19:06 -0000	1.34
+++ server/Makefile.in	12 Oct 2002 18:41:04 -0000
@@ -29,6 +29,7 @@
 	queue.c \
 	registry.c \
 	request.c \
+	rpc_epmap.c \
 	select.c \
 	semaphore.c \
 	serial.c \
Index: server/protocol.def
===================================================================
RCS file: /home/wine/wine/server/protocol.def,v
retrieving revision 1.45
diff -u -r1.45 protocol.def
--- server/protocol.def	12 Oct 2002 01:24:37 -0000	1.45
+++ server/protocol.def	12 Oct 2002 18:41:05 -0000
@@ -1911,6 +1911,31 @@
 @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
+
+
 /* Attach (or detach) thread inputs */
 @REQ(attach_thread_input)
     thread_id_t    tid_from;       /* thread to be attached */
Index: server/request.h
===================================================================
RCS file: /home/wine/wine/server/request.h,v
retrieving revision 1.76
diff -u -r1.76 request.h
--- server/request.h	12 Oct 2002 01:24:37 -0000	1.76
+++ server/request.h	12 Oct 2002 18:41:05 -0000
@@ -259,6 +259,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);
 DECL_HANDLER(attach_thread_input);
 DECL_HANDLER(get_thread_input);
 DECL_HANDLER(set_foreground_window);
@@ -427,6 +430,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,
     (req_handler)req_attach_thread_input,
     (req_handler)req_get_thread_input,
     (req_handler)req_set_foreground_window,
Index: server/trace.c
===================================================================
RCS file: /home/wine/wine/server/trace.c,v
retrieving revision 1.141
diff -u -r1.141 trace.c
--- server/trace.c	12 Oct 2002 01:24:37 -0000	1.141
+++ server/trace.c	12 Oct 2002 18:41:06 -0000
@@ -2176,6 +2176,35 @@
     dump_varargs_properties( cur_size );
 }
 
+static void dump_register_rpc_endpoints_request( const struct register_rpc_endpoints_request *req )
+{
+    fprintf( stderr, " objects=%d,", req->objects );
+    fprintf( stderr, " bindings=%d,", req->bindings );
+    fprintf( stderr, " no_replace=%d,", req->no_replace );
+    fprintf( stderr, " eps=" );
+    dump_varargs_bytes( cur_size );
+}
+
+static void dump_unregister_rpc_endpoints_request( const struct unregister_rpc_endpoints_request *req )
+{
+    fprintf( stderr, " objects=%d,", req->objects );
+    fprintf( stderr, " bindings=%d,", req->bindings );
+    fprintf( stderr, " eps=" );
+    dump_varargs_bytes( cur_size );
+}
+
+static void dump_resolve_rpc_endpoint_request( const struct resolve_rpc_endpoint_request *req )
+{
+    fprintf( stderr, " binding=" );
+    dump_varargs_bytes( cur_size );
+}
+
+static void dump_resolve_rpc_endpoint_reply( const struct resolve_rpc_endpoint_reply *req )
+{
+    fprintf( stderr, " ep=" );
+    dump_varargs_bytes( cur_size );
+}
+
 static void dump_attach_thread_input_request( const struct attach_thread_input_request *req )
 {
     fprintf( stderr, " tid_from=%08x,", req->tid_from );
@@ -2402,6 +2431,9 @@
     (dump_func)dump_remove_window_property_request,
     (dump_func)dump_get_window_property_request,
     (dump_func)dump_get_window_properties_request,
+    (dump_func)dump_register_rpc_endpoints_request,
+    (dump_func)dump_unregister_rpc_endpoints_request,
+    (dump_func)dump_resolve_rpc_endpoint_request,
     (dump_func)dump_attach_thread_input_request,
     (dump_func)dump_get_thread_input_request,
     (dump_func)dump_set_foreground_window_request,
@@ -2568,6 +2600,9 @@
     (dump_func)dump_get_window_property_reply,
     (dump_func)dump_get_window_properties_reply,
     (dump_func)0,
+    (dump_func)0,
+    (dump_func)dump_resolve_rpc_endpoint_reply,
+    (dump_func)0,
     (dump_func)dump_get_thread_input_reply,
     (dump_func)dump_set_foreground_window_reply,
     (dump_func)dump_set_focus_window_reply,
@@ -2732,6 +2767,9 @@
     "remove_window_property",
     "get_window_property",
     "get_window_properties",
+    "register_rpc_endpoints",
+    "unregister_rpc_endpoints",
+    "resolve_rpc_endpoint",
     "attach_thread_input",
     "get_thread_input",
     "set_foreground_window",
--- /dev/null	1969-12-31 18:00:00.000000000 -0600
+++ dlls/rpcrt4/rpc_epmap.c	2002-10-12 12:48:49.000000000 -0500
@@ -0,0 +1,172 @@
+/*
+ * RPC endpoint mapper
+ *
+ * Copyright 2001 Ove Kåven, TransGaming Technologies
+ *
+ * TODO:
+ *  - actually do things right
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "winreg.h"
+
+#include "wine/server.h"
+#include "rpc.h"
+
+#include "wine/debug.h"
+
+#include "rpc_binding.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+/* The "real" RPC portmapper endpoints that I know of are:
+ *
+ *  ncadg_ip_udp: 135
+ *  ncacn_ip_tcp: 135
+ *  ncacn_np: \\pipe\epmapper (?)
+ *  ncalrpc: epmapper
+ *
+ * If the user's machine ran a DCE RPC daemon, it would
+ * probably be possible to connect to it, but there are many
+ * reasons not to, like:
+ *  - the user probably does *not* run one, and probably
+ *    shouldn't be forced to run one just for local COM
+ *  - very few Unix systems use DCE RPC... if they run a RPC
+ *    daemon at all, it's usually Sun RPC
+ *  - DCE RPC registrations are persistent and saved on disk,
+ *    while MS-RPC registrations are documented as non-persistent
+ *    and stored only in RAM, and auto-destroyed when the process
+ *    dies (something DCE RPC can't do)
+ *
+ * Of course, if the user *did* want to run a DCE RPC daemon anyway,
+ * there would be interoperability advantages, like the possibility
+ * of running a fully functional DCOM server using Wine...
+ *
+ * But for now, I'll just use the wineserver...
+ */
+
+/***********************************************************************
+ *             RpcEpRegisterA (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector,
+                                  UUID_VECTOR* UuidVector, LPSTR Annotation )
+{
+  NTSTATUS ret;
+  PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
+  unsigned long c;
+
+  TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a(Annotation));
+  TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
+  for (c=0; c<BindingVector->Count; c++) {
+    RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
+    TRACE(" protseq[%ld]=%s\n", c, bind->Protseq);
+    TRACE(" endpoint[%ld]=%s\n", c, bind->Endpoint);
+  }
+  if (UuidVector) {
+    for (c=0; c<UuidVector->Count; c++)
+      TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c]));
+  }
+
+  SERVER_START_REQ( register_rpc_endpoints )
+  {
+    wine_server_add_data( req, &If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER) );
+    if (UuidVector) {
+      req->objects = UuidVector->Count;
+      for (c=0; c<req->objects; c++)
+        wine_server_add_data( req, UuidVector->Uuid[c], sizeof(UUID) );
+    }
+    else req->objects = 0;
+    req->bindings = BindingVector->Count;
+    for (c=0; c<req->bindings; c++) {
+      RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
+      wine_server_add_data( req, bind->Protseq, strlen(bind->Protseq)+1 );
+      wine_server_add_data( req, bind->Endpoint, strlen(bind->Endpoint)+1 );
+    }
+    req->no_replace = 0;
+    /* FIXME: annotation */
+    ret = wine_server_call( req );
+  }
+  SERVER_END_REQ;
+
+  return RtlNtStatusToDosError(ret);
+}
+
+/***********************************************************************
+ *             RpcEpUnregister (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector,
+                                   UUID_VECTOR* UuidVector )
+{
+  NTSTATUS ret;
+  PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
+  unsigned long c;
+
+  TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector);
+  TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
+  for (c=0; c<BindingVector->Count; c++) {
+    RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
+    TRACE(" protseq[%ld]=%s\n", c, bind->Protseq);
+    TRACE(" endpoint[%ld]=%s\n", c, bind->Endpoint);
+  }
+  if (UuidVector) {
+    for (c=0; c<UuidVector->Count; c++)
+      TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c]));
+  }
+
+  SERVER_START_REQ( unregister_rpc_endpoints )
+  {
+    wine_server_add_data( req, &If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER) );
+    if (UuidVector) {
+      req->objects = UuidVector->Count;
+      for (c=0; c<req->objects; c++)
+        wine_server_add_data( req, UuidVector->Uuid[c], sizeof(UUID) );
+    }
+    else req->objects = 0;
+    req->bindings = BindingVector->Count;
+    for (c=0; c<req->bindings; c++) {
+      RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
+      wine_server_add_data( req, bind->Protseq, strlen(bind->Protseq)+1 );
+      wine_server_add_data( req, bind->Endpoint, strlen(bind->Endpoint)+1 );
+    }
+    ret = wine_server_call( req );
+  }
+  SERVER_END_REQ;
+
+  return RtlNtStatusToDosError(ret);
+}
+
+/***********************************************************************
+ *             RpcEpResolveBinding (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec )
+{
+  NTSTATUS ret;
+  PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec;
+  RpcBinding* bind = (RpcBinding*)Binding;
+  char Endpoint[64];
+
+  TRACE("(%p,%p)\n", Binding, IfSpec);
+  TRACE(" protseq=%s\n", bind->Protseq);
+  TRACE(" obj=%s\n", debugstr_guid(&bind->ObjectUuid));
+  TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
+
+  SERVER_START_REQ( resolve_rpc_endpoint )
+  {
+    wine_server_add_data( req, &If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER) );
+    wine_server_add_data( req, &bind->ObjectUuid, sizeof(UUID) );
+    wine_server_add_data( req, bind->Protseq, strlen(bind->Protseq)+1 );
+    wine_server_set_reply( req, Endpoint, sizeof(Endpoint) );
+    ret = wine_server_call( req );
+  }
+  SERVER_END_REQ;
+
+  if (ret) return RtlNtStatusToDosError(ret);
+
+  return RPCRT4_ResolveBinding(Binding, Endpoint);
+}
+
--- /dev/null	1969-12-31 18:00:00.000000000 -0600
+++ server/rpc_epmap.c	2002-10-12 12:48:59.000000000 -0500
@@ -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);
+    }
+}

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux