RPC Merge (E_PL0)

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

 




This duplicates D_PL0 (the server stuff).  Don't apply both.  
Not a "hint" to apply, just keeping my tree up-to-date against cvs.
Applies with some fuzz.

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

-- 
gmt
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	18 Oct 2002 16:00:57 -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.30
diff -u -r1.30 rpcrt4.spec
--- dlls/rpcrt4/rpcrt4.spec	18 Oct 2002 03:56:57 -0000	1.30
+++ dlls/rpcrt4/rpcrt4.spec	18 Oct 2002 16:00:58 -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.45
diff -u -r1.45 server_protocol.h
--- include/wine/server_protocol.h	17 Oct 2002 01:24:33 -0000	1.45
+++ include/wine/server_protocol.h	18 Oct 2002 16:00:59 -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;
@@ -3018,6 +3060,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,
@@ -3189,6 +3234,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;
@@ -3358,6 +3406,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;
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	18 Oct 2002 16:00:59 -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.46
diff -u -r1.46 protocol.def
--- server/protocol.def	17 Oct 2002 01:24:33 -0000	1.46
+++ server/protocol.def	18 Oct 2002 16:01:00 -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.77
diff -u -r1.77 request.h
--- server/request.h	17 Oct 2002 01:24:33 -0000	1.77
+++ server/request.h	18 Oct 2002 16:01:00 -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);
@@ -429,6 +432,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.142
diff -u -r1.142 trace.c
--- server/trace.c	17 Oct 2002 01:24:33 -0000	1.142
+++ server/trace.c	18 Oct 2002 16:01:01 -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 );
@@ -2439,6 +2468,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,
@@ -2607,6 +2639,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,
@@ -2773,6 +2808,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",
Index: include/wine/server_protocol.h
===================================================================
RCS file: /home/wine/wine/include/wine/server_protocol.h,v
retrieving revision 1.45
diff -u -r1.45 server_protocol.h
--- include/wine/server_protocol.h	17 Oct 2002 01:24:33 -0000	1.45
+++ include/wine/server_protocol.h	18 Oct 2002 22:04:04 -0000
@@ -3368,6 +3368,6 @@
     struct set_caret_info_reply set_caret_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 88
+#define SERVER_PROTOCOL_VERSION 89
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
--- /dev/null	1969-12-31 18:00:00.000000000 -0600
+++ server/rpc_epmap.c	2002-10-18 14:36:25.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);
+    }
+}
--- /dev/null	1969-12-31 18:00:00.000000000 -0600
+++ dlls/rpcrt4/rpc_epmap.c	2002-10-18 14:35: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);
+}
+

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

  Powered by Linux