rpc_N01

Gregory M. Turner gmturner007 at ameritech.net
Thu Nov 20 13:59:32 CST 2003


Here's hoping this doesn't break anything... :)  Let me know if
your favorite app stops working.  Also, I wasn't too pleased with
the extra function call just to create a per-new-process NULL pointer.
Anyone know a better way?

License: bugroff

Changelog:

* dlls/rpcrt4: rpc_misc.h, rpc_server.c, rpcrt4_main.c, rpcrt4.spec
  include: rpcdce.h
  Greg Turner <gmturner007 at ameritech.net>
- Implement RpcObjectSetType

--
diff -ur --minimal --exclude-from=/home/greg/bin/winetreediff_excl ../wine.test/dlls/rpcrt4/rpc_misc.h ./dlls/rpcrt4/rpc_misc.h
--- ../wine.test/dlls/rpcrt4/rpc_misc.h	2003-11-20 13:38:38.000000000 -0600
+++ ./dlls/rpcrt4/rpc_misc.h	2003-11-20 13:34:23.000000000 -0600
@@ -25,4 +25,6 @@
 /* flags for RPC_MESSAGE.RpcFlags */
 #define WINE_RPCFLAG_EXCEPTION 0x0001
 
+extern void InitObjTypeMapTable();
+
 #endif  /* __WINE_RPC_MISC_H */
diff -ur --minimal --exclude-from=/home/greg/bin/winetreediff_excl ../wine.test/dlls/rpcrt4/rpc_server.c ./dlls/rpcrt4/rpc_server.c
--- ../wine.test/dlls/rpcrt4/rpc_server.c	2003-11-20 13:38:38.000000000 -0600
+++ ./dlls/rpcrt4/rpc_server.c	2003-11-20 13:34:23.000000000 -0600
@@ -54,6 +54,16 @@
   void* buf;
 } RpcPacket;
 
+typedef struct _RpcObjTypeMap
+{
+  /* FIXME: a hash table would be better. */
+  struct _RpcObjTypeMap *next;
+  UUID Object;
+  UUID Type;
+} RpcObjTypeMap;
+
+RpcObjTypeMap *RpcObjTypeMaps;
+
 static RpcServerProtseq* protseqs;
 static RpcServerInterface* ifs;
 
@@ -94,13 +104,37 @@
 
 static DWORD worker_count, worker_free, worker_tls;
 
+static UUID uuid_nil;
+
+inline static RpcObjTypeMap *LookupObjTypeMap(UUID *ObjUuid)
+{
+  RpcObjTypeMap *rslt = RpcObjTypeMaps;
+  RPC_STATUS dummy;
+
+  while (rslt) {
+    if (! UuidCompare(ObjUuid, &rslt->Object, &dummy)) break;
+    rslt = rslt->next;
+  }
+
+  return rslt;
+}
+
+inline static UUID *LookupObjType(UUID *ObjUuid)
+{
+  RpcObjTypeMap *map = LookupObjTypeMap(ObjUuid);
+  if (map)
+    return &map->Type;
+  else
+    return &uuid_nil;
+}
+
 static RpcServerInterface* RPCRT4_find_interface(UUID* object, UUID* if_id)
 {
   UUID* MgrType = NULL;
   RpcServerInterface* cif = NULL;
   RPC_STATUS status;
 
-  /* FIXME: object -> MgrType */
+  MgrType = LookupObjType(object);
   EnterCriticalSection(&server_cs);
   cif = ifs;
   while (cif) {
@@ -168,6 +202,8 @@
   if (sif) {
     TRACE("packet received for interface %s\n", debugstr_guid(&hdr->if_id));
     msg.RpcInterfaceInformation = sif->If;
+    /* copy the endpoint vector from sif to msg so that midl-generated code will use it */
+    msg.ManagerEpv = sif->MgrEpv;
     /* create temporary binding for dispatch */
     RPCRT4_MakeBinding(&pbind, conn);
     RPCRT4_SetBindingObject(pbind, &hdr->object);
@@ -703,11 +739,13 @@
 
   sif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerInterface));
   sif->If           = If;
-  if (MgrTypeUuid)
+  if (MgrTypeUuid) {
     memcpy(&sif->MgrTypeUuid, MgrTypeUuid, sizeof(UUID));
-  else
+    sif->MgrEpv       = MgrEpv;
+  } else {
     memset(&sif->MgrTypeUuid, 0, sizeof(UUID));
-  sif->MgrEpv       = MgrEpv;
+    sif->MgrEpv       = If->DefaultManagerEpv;
+  }
   sif->Flags        = Flags;
   sif->MaxCalls     = MaxCalls;
   sif->MaxRpcSize   = MaxRpcSize;
@@ -748,6 +786,75 @@
   return RPC_S_OK;
 }
 
+void InitObjTypeMapTable()
+{
+  RpcObjTypeMaps = NULL;
+}
+
+/***********************************************************************
+ *             RpcObjectSetType (RPCRT4.@)
+ *
+ * PARAMS
+ *   ObjUuid  [I] "Object" UUID
+ *   TypeUuid [I] "Type" UUID
+ *
+ * RETURNS
+ *   RPC_S_OK                 The call succeeded
+ *   RPC_S_INVALID_OBJECT     The provided object (nil) is not valid
+ *   RPC_S_ALREADY_REGISTERED The provided object is already registered
+ *
+ * Maps "Object" UUIDs to "Type" UUID's.  Passing the nil UUID as the type
+ * resets the mapping for the specified object UUID to nil (the default).
+ * The nil object is always associated with the nil type and cannot be
+ * reassigned.  Servers can support multiple implementations on the same
+ * interface by registering different end-point vectors for the different
+ * types.  There's no need to call this if a server only supports the nil
+ * type, as is typical.
+ */
+RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid )
+{
+  RpcObjTypeMap *map = RpcObjTypeMaps, *prev = NULL;
+  RPC_STATUS dummy;
+
+  TRACE("(ObjUUID == %s, TypeUuid == %s).\n", debugstr_guid(ObjUuid), debugstr_guid(TypeUuid));
+  if ((! ObjUuid) || UuidIsNil(ObjUuid, &dummy)) {
+    /* nil uuid cannot be remapped */
+    return RPC_S_INVALID_OBJECT;
+  }
+
+  /* find the mapping for this object if there is one ... */
+  while (map) {
+    if (! UuidCompare(ObjUuid, &map->Object, &dummy)) break;
+    prev = map;
+    map = map->next;
+  }
+  if ((! TypeUuid) || UuidIsNil(TypeUuid, &dummy)) {
+    /* ... and drop it from the list */
+    if (map) {
+      if (prev) 
+        prev->next = map->next;
+      else
+        RpcObjTypeMaps = map->next;
+      HeapFree(GetProcessHeap(), 0, map);
+    }
+  } else {
+    /* ... , fail if we found it ... */
+    if (map)
+      return RPC_S_ALREADY_REGISTERED;
+    /* ... otherwise create a new one and add it in. */
+    map = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcObjTypeMap));
+    memcpy(&map->Object, ObjUuid, sizeof(UUID));
+    memcpy(&map->Type, TypeUuid, sizeof(UUID));
+    map->next = NULL;
+    if (prev)
+      prev->next = map; /* prev is the last map in the linklist */
+    else
+      RpcObjTypeMaps = map;
+  }
+
+  return RPC_S_OK;
+}
+
 /***********************************************************************
  *             RpcServerRegisterAuthInfoA (RPCRT4.@)
  */
diff -ur --minimal --exclude-from=/home/greg/bin/winetreediff_excl ../wine.test/dlls/rpcrt4/rpcrt4.spec ./dlls/rpcrt4/rpcrt4.spec
--- ../wine.test/dlls/rpcrt4/rpcrt4.spec	2003-11-20 13:38:38.000000000 -0600
+++ ./dlls/rpcrt4/rpcrt4.spec	2003-11-20 13:34:23.000000000 -0600
@@ -106,7 +106,7 @@
 @ stub RpcNsBindingInqEntryNameW
 @ stub RpcObjectInqType
 @ stub RpcObjectSetInqFn
-@ stub RpcObjectSetType
+@ stdcall RpcObjectSetType(ptr ptr)
 @ stub RpcProtseqVectorFreeA
 @ stub RpcProtseqVectorFreeW
 @ stdcall RpcRaiseException(long)
diff -ur --minimal --exclude-from=/home/greg/bin/winetreediff_excl ../wine.test/dlls/rpcrt4/rpcrt4_main.c ./dlls/rpcrt4/rpcrt4_main.c
--- ../wine.test/dlls/rpcrt4/rpcrt4_main.c	2003-11-20 13:38:38.000000000 -0600
+++ ./dlls/rpcrt4/rpcrt4_main.c	2003-11-20 13:34:23.000000000 -0600
@@ -135,6 +135,7 @@
 
 #include "rpc_binding.h"
 #include "rpcss_np_client.h"
+#include "rpc_misc.h"
 
 #include "wine/debug.h"
 
@@ -169,6 +170,7 @@
         master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME);
         if (!master_mutex)
           ERR("Failed to create master mutex\n");
+        InitObjTypeMapTable();
         break;
 
     case DLL_PROCESS_DETACH:
diff -ur --minimal --exclude-from=/home/greg/bin/winetreediff_excl ../wine.test/include/rpcdce.h ./include/rpcdce.h
--- ../wine.test/include/rpcdce.h	2003-11-20 13:38:38.000000000 -0600
+++ ./include/rpcdce.h	2003-11-20 13:34:23.000000000 -0600
@@ -114,6 +114,8 @@
   RpcBindingReset( RPC_BINDING_HANDLE Binding );
 RPCRTAPI RPC_STATUS RPC_ENTRY
   RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid );
+RPCRTAPI RPC_STATUS RPC_ENTRY
+  RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid );
 
 RPCRTAPI RPC_STATUS RPC_ENTRY
   RpcBindingFromStringBindingA( LPSTR StringBinding, RPC_BINDING_HANDLE* Binding );
-- 
gmt

"It is to be the assent and ratification of the several States,
derived from the supreme authority in each State, the authority
of the people themselves.  The act, therefore, establishing the
Constitution, will not be a NATIONAL, but a FEDERAL act." --James
Madison, Federalist No. 39





More information about the wine-patches mailing list