📄 ndr_marshall.c
字号:
pointer_needs_marshaling = !NdrFullPointerQueryPointer( pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id); TRACE("writing 0x%08x 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_needs_marshaling) { if (attr & RPC_FC_P_DEREF) { Pointer = *(unsigned char**)Pointer; TRACE("deref => %p\n", Pointer); } m = NdrMarshaller[*desc & NDR_TABLE_MASK]; if (m) m(pStubMsg, Pointer, desc); else FIXME("no marshaller for data type=%02x\n", *desc); } STD_OVERFLOW_CHECK(pStubMsg);}/*********************************************************************** * PointerUnmarshall [internal] */static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Buffer, unsigned char **pPointer, PFORMAT_STRING pFormat, unsigned char fMustAlloc){ unsigned type = pFormat[0], attr = pFormat[1]; 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); pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; else desc = pFormat + *(const SHORT*)pFormat; switch (type) { case RPC_FC_RP: /* ref pointer (always non-null) */ pointer_needs_unmarshaling = 1; break; case RPC_FC_UP: /* unique pointer */ pointer_id = NDR_LOCAL_UINT32_READ(Buffer); TRACE("pointer_id is 0x%08x\n", pointer_id); if (pointer_id) pointer_needs_unmarshaling = 1; else { *pPointer = NULL; 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%08x\n", pointer_id); if (!fMustAlloc && *pPointer) { FIXME("free object pointer %p\n", *pPointer); *pPointer = NULL; } 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%08x\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_needs_unmarshaling) { if (attr & RPC_FC_P_DEREF) { if (!*pPointer || fMustAlloc) *pPointer = NdrAllocate(pStubMsg, sizeof(void *)); pPointer = *(unsigned char***)pPointer; TRACE("deref => %p\n", pPointer); } 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);}/*********************************************************************** * PointerBufferSize [internal] */static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Pointer, PFORMAT_STRING pFormat){ unsigned type = pFormat[0], attr = pFormat[1]; PFORMAT_STRING desc; NDR_BUFFERSIZE m; int pointer_needs_sizing; ULONG pointer_id; TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; else desc = pFormat + *(const SHORT*)pFormat; switch (type) { case RPC_FC_RP: /* ref pointer (always non-null) */ break; case RPC_FC_OP: case RPC_FC_UP: /* NULL pointer has no further representation */ if (!Pointer) 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) { Pointer = *(unsigned char**)Pointer; TRACE("deref => %p\n", Pointer); } m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; if (m) m(pStubMsg, Pointer, desc); else FIXME("no buffersizer for data type=%02x\n", *desc);}/*********************************************************************** * PointerMemorySize [internal] */static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Buffer, PFORMAT_STRING pFormat){ unsigned type = pFormat[0], attr = pFormat[1]; PFORMAT_STRING desc; NDR_MEMORYSIZE m; FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat); TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; else desc = pFormat + *(const SHORT*)pFormat; switch (type) { case RPC_FC_RP: /* ref pointer (always non-null) */ break; default: FIXME("unhandled ptr type=%02x\n", type); RpcRaiseException(RPC_X_BAD_STUB_DATA); } if (attr & RPC_FC_P_DEREF) { TRACE("deref\n"); } m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; if (m) m(pStubMsg, desc); else FIXME("no memorysizer for data type=%02x\n", *desc); return 0;}/*********************************************************************** * PointerFree [internal] */static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Pointer, PFORMAT_STRING pFormat){ unsigned type = pFormat[0], attr = pFormat[1]; PFORMAT_STRING desc; NDR_FREE m; TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); if (attr & RPC_FC_P_DONTFREE) return; pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; else desc = pFormat + *(const SHORT*)pFormat; 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); } m = NdrFreer[*desc & NDR_TABLE_MASK]; if (m) m(pStubMsg, Pointer, desc); /* hmm... is this sensible? * perhaps we should check if the memory comes from NdrAllocate, * and deallocate only if so - checking if the pointer is between * BufferStart and BufferEnd is probably no good since the buffer * may be reallocated when the server wants to marshal the reply */ switch (*desc) { case RPC_FC_BOGUS_STRUCT: case RPC_FC_BOGUS_ARRAY: case RPC_FC_USER_MARSHAL: case RPC_FC_CARRAY: case RPC_FC_CVARRAY: break; default: FIXME("unhandled data type=%02x\n", *desc); break; case RPC_FC_C_CSTRING: case RPC_FC_C_WSTRING: if (pStubMsg->ReuseBuffer) goto notfree; break; case RPC_FC_IP: goto notfree; } if (attr & RPC_FC_P_ONSTACK) { TRACE("not freeing stack ptr %p\n", Pointer); return; } TRACE("freeing %p\n", Pointer); NdrFree(pStubMsg, Pointer); return;notfree: TRACE("not freeing %p\n", Pointer);}/*********************************************************************** * EmbeddedPointerMarshall */static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat){ unsigned char *Mark = pStubMsg->BufferMark; unsigned long Offset = pStubMsg->Offset; unsigned ofs, rep, count, stride, xofs; unsigned i; unsigned char *saved_buffer = NULL; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); if (*pFormat != RPC_FC_PP) return NULL; pFormat += 2; if (pStubMsg->PointerBufferMark) { saved_buffer = pStubMsg->Buffer; pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = NULL; } while (pFormat[0] != RPC_FC_END) { switch (pFormat[0]) { default: FIXME("unknown repeat type %d\n", pFormat[0]); case RPC_FC_NO_REPEAT: rep = 1; stride = 0; ofs = 0; count = 1; xofs = 0; pFormat += 2; break; case RPC_FC_FIXED_REPEAT: rep = *(const WORD*)&pFormat[2]; stride = *(const WORD*)&pFormat[4]; ofs = *(const WORD*)&pFormat[6]; count = *(const WORD*)&pFormat[8]; xofs = 0; pFormat += 10; break; case RPC_FC_VARIABLE_REPEAT: rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; stride = *(const WORD*)&pFormat[2]; ofs = *(const WORD*)&pFormat[4]; count = *(const WORD*)&pFormat[6]; xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0; pFormat += 8; break; } for (i = 0; i < rep; i++) { PFORMAT_STRING info = pFormat; unsigned char *membase = pMemory + ofs + (i * stride); unsigned char *bufbase = Mark + ofs + (i * stride); unsigned u; for (u=0; u<count; u++,info+=8) { unsigned char *memptr = membase + *(const SHORT*)&info[0]; unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; unsigned char *saved_memory = pStubMsg->Memory; pStubMsg->Memory = pMemory; PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4); pStubMsg->Memory = saved_memory; } } pFormat += 8 * count; } if (saved_buffer) { pStubMsg->PointerBufferMark = pStubMsg->Buffer; pStubMsg->Buffer = saved_buffer; } STD_OVERFLOW_CHECK(pStubMsg); return NULL;}/*********************************************************************** * EmbeddedPointerUnmarshall */static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc){ unsigned char *Mark = pStubMsg->BufferMark; unsigned long Offset = pStubMsg->Offset; unsigned ofs, rep, count, stride, xofs; unsigned i; unsigned char *saved_buffer = NULL; TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); if (*pFormat != RPC_FC_PP) return NULL; pFormat += 2; if (pStubMsg->PointerBufferMark) { saved_buffer = pStubMsg->Buffer; pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = NULL; } while (pFormat[0] != RPC_FC_END) { TRACE("pFormat[0] = 0x%x\n", pFormat[0]); switch (pFormat[0]) { default: FIXME("unknown repeat type %d\n", pFormat[0]); case RPC_FC_NO_REPEAT: rep = 1; stride = 0; ofs = 0; count = 1; xofs = 0; pFormat += 2; break; case RPC_FC_FIXED_REPEAT: rep = *(const WORD*)&pFormat[2]; stride = *(const WORD*)&pFormat[4]; ofs = *(const WORD*)&pFormat[6]; count = *(const WORD*)&pFormat[8]; xofs = 0; pFormat += 10; break; case RPC_FC_VARIABLE_REPEAT: rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; stride = *(const WORD*)&pFormat[2]; ofs = *(const WORD*)&pFormat[4]; count = *(const WORD*)&pFormat[6]; xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0; pFormat += 8; break; } /* ofs doesn't seem to matter in this context */ for (i = 0; i < rep; i++) { PFORMAT_STRING info = pFormat; unsigned char *membase = *ppMemory + ofs + (i * stride); unsigned char *bufbase = Mark + ofs + (i * stride); unsigned u; for (u=0; u<count; u++,info+=8) { unsigned char *memptr = membase + *(const SHORT*)&info[0]; unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE); } } pFormat += 8 * count; } if (saved_buffer) { pStubMsg->PointerBufferMark = pStubMsg->Buffer; pStubMsg->Buffer = saved_buffer; } return NULL;}/*********************************************************************** * EmbeddedPointerBufferSize */static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -