Robert Shearman : rpcrt4: Handle marshaling/unmarshaling full
pointers.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue May 30 05:56:47 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: ff9fd9c430fc4d5144372fae09f005e718085ff0
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=ff9fd9c430fc4d5144372fae09f005e718085ff0
Author: Robert Shearman <rob at codeweavers.com>
Date: Mon May 29 16:27:27 2006 +0100
rpcrt4: Handle marshaling/unmarshaling full pointers.
---
dlls/rpcrt4/ndr_marshall.c | 58 ++++++++++++++++++++++++++++++++++++++++----
1 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c
index f9164df..8b66899 100644
--- a/dlls/rpcrt4/ndr_marshall.c
+++ b/dlls/rpcrt4/ndr_marshall.c
@@ -749,6 +749,8 @@ static void PointerMarshall(PMIDL_STUB_M
unsigned type = pFormat[0], attr = pFormat[1];
PFORMAT_STRING desc;
NDR_MARSHALL m;
+ unsigned long pointer_id;
+ int pointer_needs_marshaling;
TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
@@ -762,21 +764,33 @@ #if 0 /* this causes problems for Instal
if (!Pointer)
RpcRaiseException(RPC_X_NULL_REF_POINTER);
#endif
+ pointer_needs_marshaling = 1;
break;
case RPC_FC_UP: /* unique pointer */
case RPC_FC_OP: /* object pointer - same as unique here */
- TRACE("writing %p to buffer\n", Pointer);
- NDR_LOCAL_UINT32_WRITE(Buffer, (unsigned long)Pointer);
+ if (Pointer)
+ pointer_needs_marshaling = 1;
+ else
+ pointer_needs_marshaling = 0;
+ pointer_id = (unsigned long)Pointer;
+ TRACE("writing 0x%08lx to buffer\n", pointer_id);
+ NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
break;
case RPC_FC_FP:
+ pointer_needs_marshaling = !NdrFullPointerQueryPointer(
+ pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
+ TRACE("writing 0x%08lx to buffer\n", pointer_id);
+ NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
+ break;
default:
FIXME("unhandled ptr type=%02x\n", type);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
+ return;
}
TRACE("calling marshaller for type 0x%x\n", (int)*desc);
- if (Pointer) {
+ if (pointer_needs_marshaling) {
if (attr & RPC_FC_P_DEREF) {
Pointer = *(unsigned char**)Pointer;
TRACE("deref => %p\n", Pointer);
@@ -802,6 +816,7 @@ static void PointerUnmarshall(PMIDL_STUB
PFORMAT_STRING desc;
NDR_UNMARSHALL m;
DWORD pointer_id = 0;
+ int pointer_needs_unmarshaling;
TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
@@ -811,25 +826,39 @@ static void PointerUnmarshall(PMIDL_STUB
switch (type) {
case RPC_FC_RP: /* ref pointer (always non-null) */
- pointer_id = ~0UL;
+ pointer_needs_unmarshaling = 1;
break;
case RPC_FC_UP: /* unique pointer */
pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
TRACE("pointer_id is 0x%08lx\n", pointer_id);
+ if (pointer_id)
+ pointer_needs_unmarshaling = 1;
+ else
+ pointer_needs_unmarshaling = 0;
break;
case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
TRACE("pointer_id is 0x%08lx\n", pointer_id);
if (!fMustAlloc && *pPointer)
FIXME("free object pointer %p\n", *pPointer);
+ if (pointer_id)
+ pointer_needs_unmarshaling = 1;
+ else
+ pointer_needs_unmarshaling = 0;
break;
case RPC_FC_FP:
+ pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
+ TRACE("pointer_id is 0x%08lx\n", pointer_id);
+ pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
+ pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
+ break;
default:
FIXME("unhandled ptr type=%02x\n", type);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
+ return;
}
- if (pointer_id) {
+ if (pointer_needs_unmarshaling) {
if (attr & RPC_FC_P_DEREF) {
if (!*pPointer || fMustAlloc)
*pPointer = NdrAllocate(pStubMsg, sizeof(void *));
@@ -839,6 +868,10 @@ static void PointerUnmarshall(PMIDL_STUB
m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
else FIXME("no unmarshaller for data type=%02x\n", *desc);
+
+ if (type == RPC_FC_FP)
+ NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
+ *pPointer);
}
TRACE("pointer=%p\n", *pPointer);
@@ -854,6 +887,8 @@ static void PointerBufferSize(PMIDL_STUB
unsigned type = pFormat[0], attr = pFormat[1];
PFORMAT_STRING desc;
NDR_BUFFERSIZE m;
+ int pointer_needs_sizing;
+ unsigned long pointer_id;
TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
@@ -871,9 +906,15 @@ static void PointerBufferSize(PMIDL_STUB
return;
break;
case RPC_FC_FP:
+ pointer_needs_sizing = !NdrFullPointerQueryPointer(
+ pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
+ if (!pointer_needs_sizing)
+ return;
+ break;
default:
FIXME("unhandled ptr type=%02x\n", type);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
+ return;
}
if (attr & RPC_FC_P_DEREF) {
@@ -942,6 +983,13 @@ static void PointerFree(PMIDL_STUB_MESSA
if (!Pointer) return;
+ if (type == RPC_FC_FP) {
+ int pointer_needs_freeing = NdrFullPointerFree(
+ pStubMsg->FullPtrXlatTables, Pointer);
+ if (!pointer_needs_freeing)
+ return;
+ }
+
if (attr & RPC_FC_P_DEREF) {
Pointer = *(unsigned char**)Pointer;
TRACE("deref => %p\n", Pointer);
More information about the wine-cvs
mailing list