Mike McCormack : rpcrt4: Implement NDRCContext(Un) marshall and NDRCContextBinding.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jun 1 06:48:53 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 7f98594f75823057aedb6ece689921d301882ac9
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=7f98594f75823057aedb6ece689921d301882ac9

Author: Mike McCormack <mike at codeweavers.com>
Date:   Thu Jun  1 13:09:49 2006 +0900

rpcrt4: Implement NDRCContext(Un)marshall and NDRCContextBinding.

---

 dlls/rpcrt4/ndr_marshall.c |  116 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 112 insertions(+), 4 deletions(-)

diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c
index 582851b..83fc9be 100644
--- a/dlls/rpcrt4/ndr_marshall.c
+++ b/dlls/rpcrt4/ndr_marshall.c
@@ -49,6 +49,7 @@ #include "wine/unicode.h"
 #include "wine/rpcfc.h"
 
 #include "wine/debug.h"
+#include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
@@ -4406,15 +4407,113 @@ NDR_SCONTEXT WINAPI NdrServerContextNewU
     return NULL;
 }
 
-RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
+#define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
+
+typedef struct ndr_context_handle
+{
+    DWORD      attributes;
+    GUID       uuid;
+} ndr_context_handle;
+
+struct context_handle_entry
+{
+    struct list entry;
+    DWORD magic;
+    RPC_BINDING_HANDLE handle;
+    ndr_context_handle wire_data;
+};
+
+static struct list context_handle_list = LIST_INIT(context_handle_list);
+
+static CRITICAL_SECTION ndr_context_cs;
+static CRITICAL_SECTION_DEBUG ndr_context_debug =
 {
-    FIXME("(%p): stub\n", CContext);
+    0, 0, &ndr_context_cs,
+    { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
+};
+static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
+
+static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
+{
+    struct context_handle_entry *che = (struct context_handle_entry*) CContext;
+
+    if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
+        return NULL;
+    return che;
+}
+
+static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
+{
+    struct context_handle_entry *che;
+    LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
+        if (IsEqualGUID(&che->wire_data.uuid, uuid))
+            return che;
     return NULL;
 }
 
+RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
+{
+    struct context_handle_entry *che;
+    RPC_BINDING_HANDLE handle = NULL;
+
+    TRACE("%p\n", CContext);
+
+    EnterCriticalSection(&ndr_context_cs);
+    che = get_context_entry(CContext);
+    if (che)
+        handle = che->handle;
+    LeaveCriticalSection(&ndr_context_cs);
+
+    if (!handle)
+        RpcRaiseException(ERROR_INVALID_HANDLE);
+    return handle;
+}
+
 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
 {
-    FIXME("(%p %p): stub\n", CContext, pBuff);
+    struct context_handle_entry *che;
+
+    TRACE("%p %p\n", CContext, pBuff);
+
+    EnterCriticalSection(&ndr_context_cs);
+    che = get_context_entry(CContext);
+    memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
+    LeaveCriticalSection(&ndr_context_cs);
+}
+
+static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
+                                      RPC_BINDING_HANDLE hBinding,
+                                      ndr_context_handle *chi)
+{
+    static const GUID zeroguid = {0,0,0,{0,0,0,0,0,0,0,0}};
+    struct context_handle_entry *che = NULL;
+
+    /* a null UUID means we should free the context handle */
+    if (IsEqualGUID(&chi->uuid, &zeroguid))
+    {
+        che = get_context_entry(*CContext);
+        if (!che)
+            return ERROR_INVALID_HANDLE;
+        list_remove(&che->entry);
+        HeapFree(GetProcessHeap(), 0, che);
+        che = NULL;
+    }
+    /* if there's no existing entry matching the GUID, allocate one */
+    else if (!(che = context_entry_from_guid(&chi->uuid)))
+    {
+        che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
+        if (!che)
+            return ERROR_NOT_ENOUGH_MEMORY;
+        che->magic = NDR_CONTEXT_HANDLE_MAGIC;
+        che->handle = hBinding;
+        list_add_tail(&context_handle_list, &che->entry);
+        memcpy(&che->wire_data, chi, sizeof *chi);
+    }
+
+    *CContext = che;
+
+    return ERROR_SUCCESS;
 }
 
 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
@@ -4422,7 +4521,16 @@ void WINAPI NDRCContextUnmarshall(NDR_CC
                                   void *pBuff,
                                   unsigned long DataRepresentation)
 {
-    FIXME("(%p %p %p %08lx): stub\n", CContext, hBinding, pBuff, DataRepresentation);
+    UINT r;
+
+    TRACE("*%p=(%p) %p %p %08lx\n",
+          CContext, *CContext, hBinding, pBuff, DataRepresentation);
+
+    EnterCriticalSection(&ndr_context_cs);
+    r = ndr_update_context_handle(CContext, hBinding, pBuff);
+    LeaveCriticalSection(&ndr_context_cs);
+    if (r)
+        RpcRaiseException(r);
 }
 
 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,




More information about the wine-cvs mailing list