Module: wine Branch: refs/heads/master Commit: ff9fd9c430fc4d5144372fae09f005e718085ff0 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=ff9fd9c430fc4d5144372fae...
Author: Robert Shearman rob@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);