📄 ndr_marshall.c
字号:
}
default:
break;
}
switch (dtype) {
case RPC_FC_LONG:
case RPC_FC_ULONG:
data = *(DWORD*)ptr;
break;
case RPC_FC_SHORT:
data = *(SHORT*)ptr;
break;
case RPC_FC_USHORT:
data = *(USHORT*)ptr;
break;
case RPC_FC_SMALL:
data = *(CHAR*)ptr;
break;
case RPC_FC_USMALL:
data = *(UCHAR*)ptr;
break;
default:
FIXME("unknown conformance data type %x\n", dtype);
goto done_conf_grab;
}
TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
done_conf_grab:
switch (pFormat[1]) {
case 0: /* no op */
*pCount = data;
break;
case RPC_FC_DEREFERENCE:
/* already handled */
break;
default:
FIXME("unknown conformance op %d\n", pFormat[1]);
goto finish_conf;
}
finish_conf:
TRACE("resulting conformance is %ld\n", *pCount);
if (pStubMsg->fHasNewCorrDesc)
return pFormat+6;
else
return pFormat+4;
}
/*
* NdrConformantString:
*
* What MS calls a ConformantString is, in DCE terminology,
* a Varying-Conformant String.
* [
* maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
* offset: DWORD (actual string data begins at (offset) CHARTYPE's
* into unmarshalled string)
* length: DWORD (# of CHARTYPE characters, inclusive of '\0')
* [
* data: CHARTYPE[maxlen]
* ]
* ], where CHARTYPE is the appropriate character type (specified externally)
*
*/
/***********************************************************************
* NdrConformantStringMarshall [RPCRT4.@]
*/
unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
unsigned char *pszMessage, PFORMAT_STRING pFormat)
{
unsigned long len, esize;
unsigned char *c;
TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
assert(pFormat);
if (pszMessage == NULL) {
TRACE("string=%s\n", debugstr_a(pszMessage));
len = 0;
esize = 0;
}
else if (*pFormat == RPC_FC_C_CSTRING) {
TRACE("string=%s\n", debugstr_a(pszMessage));
len = strlen(pszMessage)+1;
esize = 1;
}
else if (*pFormat == RPC_FC_C_WSTRING) {
TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
len = strlenW((LPWSTR)pszMessage)+1;
esize = 2;
}
else {
ERR("Unhandled string type: %#x\n", *pFormat);
/* FIXME: raise an exception. */
return NULL;
}
if (pFormat[1] != RPC_FC_PAD) {
FIXME("sized string format=%d\n", pFormat[1]);
}
assert( (pStubMsg->BufferLength >= (len*esize + 13)) && (pStubMsg->Buffer != NULL) );
c = pStubMsg->Buffer;
memset(c, 0, 12);
NDR_LOCAL_UINT32_WRITE(c, len); /* max length: strlen + 1 (for '\0') */
c += 8; /* offset: 0 */
NDR_LOCAL_UINT32_WRITE(c, len); /* actual length: (same) */
c += 4;
if (len != 0) {
memcpy(c, pszMessage, len*esize); /* the string itself */
c += len*esize;
}
pStubMsg->Buffer = c;
STD_OVERFLOW_CHECK(pStubMsg);
/* success */
return NULL; /* is this always right? */
}
/***********************************************************************
* NdrConformantStringBufferSize [RPCRT4.@]
*/
void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char* pMemory, PFORMAT_STRING pFormat)
{
TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
assert(pFormat);
if (pMemory == NULL) {
/* we need 12 octets for the [maxlen, offset, len] DWORDS */
TRACE("string=NULL\n");
pStubMsg->BufferLength += 12 + BUFFER_PARANOIA;
}
else if (*pFormat == RPC_FC_C_CSTRING) {
/* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
TRACE("string=%s\n", debugstr_a((char*)pMemory));
pStubMsg->BufferLength += strlen((char*)pMemory) + 13 + BUFFER_PARANOIA;
}
else if (*pFormat == RPC_FC_C_WSTRING) {
/* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 14 + BUFFER_PARANOIA;
}
else {
ERR("Unhandled string type: %#x\n", *pFormat);
/* FIXME: raise an exception */
}
if (pFormat[1] != RPC_FC_PAD) {
FIXME("sized string format=%d\n", pFormat[1]);
}
}
/************************************************************************
* NdrConformantStringMemorySize [RPCRT4.@]
*/
unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
PFORMAT_STRING pFormat )
{
unsigned long rslt = 0;
TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
assert(pStubMsg && pFormat);
if (*pFormat == RPC_FC_C_CSTRING) {
rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
}
else if (*pFormat == RPC_FC_C_WSTRING) {
rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
}
else {
ERR("Unhandled string type: %#x\n", *pFormat);
/* FIXME: raise an exception */
}
if (pFormat[1] != RPC_FC_PAD) {
FIXME("sized string format=%d\n", pFormat[1]);
}
TRACE(" --> %lu\n", rslt);
return rslt;
}
/************************************************************************
* NdrConformantStringUnmarshall [RPCRT4.@]
*/
unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
{
unsigned long len, esize, ofs;
TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
pStubMsg, *ppMemory, pFormat, fMustAlloc);
assert(pFormat && ppMemory && pStubMsg);
pStubMsg->Buffer += 4;
ofs = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4;
len = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4;
if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
else {
ERR("Unhandled string type: %#x\n", *pFormat);
/* FIXME: raise an exception */
esize = 0;
}
if (pFormat[1] != RPC_FC_PAD) {
FIXME("sized string format=%d\n", pFormat[1]);
}
if (fMustAlloc || !*ppMemory)
*ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
memcpy(*ppMemory, pStubMsg->Buffer, len*esize);
pStubMsg->Buffer += len*esize;
if (*pFormat == RPC_FC_C_CSTRING) {
TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
}
else if (*pFormat == RPC_FC_C_WSTRING) {
TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
}
return NULL; /* FIXME: is this always right? */
}
/***********************************************************************
* NdrNonConformantStringMarshall [RPCRT4.@]
*/
unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char *pMemory,
PFORMAT_STRING pFormat)
{
FIXME("stub\n");
return NULL;
}
/***********************************************************************
* NdrNonConformantStringUnmarshall [RPCRT4.@]
*/
unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char **ppMemory,
PFORMAT_STRING pFormat,
unsigned char fMustAlloc)
{
FIXME("stub\n");
return NULL;
}
/***********************************************************************
* NdrNonConformantStringBufferSize [RPCRT4.@]
*/
void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char *pMemory,
PFORMAT_STRING pFormat)
{
FIXME("stub\n");
}
/***********************************************************************
* NdrNonConformantStringMemorySize [RPCRT4.@]
*/
unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
PFORMAT_STRING pFormat)
{
FIXME("stub\n");
return 0;
}
static inline void dump_pointer_attr(unsigned char attr)
{
if (attr & RPC_FC_P_ALLOCALLNODES)
TRACE(" RPC_FC_P_ALLOCALLNODES");
if (attr & RPC_FC_P_DONTFREE)
TRACE(" RPC_FC_P_DONTFREE");
if (attr & RPC_FC_P_ONSTACK)
TRACE(" RPC_FC_P_ONSTACK");
if (attr & RPC_FC_P_SIMPLEPOINTER)
TRACE(" RPC_FC_P_SIMPLEPOINTER");
if (attr & RPC_FC_P_DEREF)
TRACE(" RPC_FC_P_DEREF");
TRACE("\n");
}
/***********************************************************************
* PointerMarshall
*/
void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char *Buffer,
unsigned char *Pointer,
PFORMAT_STRING pFormat)
{
unsigned type = pFormat[0], attr = pFormat[1];
PFORMAT_STRING desc;
NDR_MARSHALL m;
TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, 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;
if (attr & RPC_FC_P_DEREF) {
Pointer = *(unsigned char**)Pointer;
TRACE("deref => %p\n", Pointer);
}
switch (type) {
case RPC_FC_RP: /* ref pointer (always non-null) */
#if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
if (!Pointer)
RpcRaiseException(RPC_X_NULL_REF_POINTER);
#endif
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(pStubMsg->Buffer, (unsigned long)Pointer);
pStubMsg->Buffer += 4;
break;
case RPC_FC_FP:
default:
FIXME("unhandled ptr type=%02x\n", type);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
TRACE("calling marshaller for type 0x%x\n", (int)*desc);
if (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
*/
void WINAPI 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;
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;
if (attr & RPC_FC_P_DEREF) {
pPointer = *(unsigned char***)pPointer;
TRACE("deref => %p\n", pPointer);
}
switch (type) {
case RPC_FC_RP: /* ref pointer (always non-null) */
pointer_id = ~0UL;
break;
case RPC_FC_UP: /* unique pointer */
pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4;
break;
case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4;
if (*pPointer)
FIXME("free object pointer %p\n", *pPointer);
break;
case RPC_FC_FP:
default:
FIXME("unhandled ptr type=%02x\n", type);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
if (pointer_id) {
m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
else FIXME("no unmarshaller for data type=%02x\n", *desc);
}
TRACE("pointer=%p\n", *pPointer);
}
/***********************************************************************
* PointerBufferSize
*/
void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char *Pointer,
PFORMAT_STRING pFormat)
{
unsigned type = pFormat[0], attr = pFormat[1];
PFORMAT_STRING desc;
NDR_BUFFERSIZE m;
TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -