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