rpcrt4: Factorise conformant string functions into array_* functions.
This allows conformant string array types to be marshalled/unmarshalled when embedded in a complex type.
This commit is contained in:
parent
9e3260847a
commit
b2305adc3c
|
@ -30,7 +30,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "windef.h"
|
||||
|
@ -734,396 +733,6 @@ static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULO
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
ULONG esize, size;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
|
||||
|
||||
if (*pFormat == RPC_FC_C_CSTRING) {
|
||||
TRACE("string=%s\n", debugstr_a((char*)pszMessage));
|
||||
pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
|
||||
esize = 1;
|
||||
}
|
||||
else if (*pFormat == RPC_FC_C_WSTRING) {
|
||||
TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
|
||||
pStubMsg->ActualCount = 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_STRING_SIZED)
|
||||
pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
|
||||
else
|
||||
pStubMsg->MaxCount = pStubMsg->ActualCount;
|
||||
pStubMsg->Offset = 0;
|
||||
WriteConformance(pStubMsg);
|
||||
WriteVariance(pStubMsg);
|
||||
|
||||
size = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
|
||||
|
||||
/* success */
|
||||
return NULL; /* is this always right? */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrConformantStringBufferSize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char* pMemory, PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG esize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
|
||||
|
||||
SizeConformance(pStubMsg);
|
||||
SizeVariance(pStubMsg);
|
||||
|
||||
if (*pFormat == RPC_FC_C_CSTRING) {
|
||||
TRACE("string=%s\n", debugstr_a((char*)pMemory));
|
||||
pStubMsg->ActualCount = strlen((char*)pMemory)+1;
|
||||
esize = 1;
|
||||
}
|
||||
else if (*pFormat == RPC_FC_C_WSTRING) {
|
||||
TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
|
||||
pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
|
||||
esize = 2;
|
||||
}
|
||||
else {
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
/* FIXME: raise an exception */
|
||||
return;
|
||||
}
|
||||
|
||||
if (pFormat[1] == RPC_FC_STRING_SIZED)
|
||||
pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
|
||||
else
|
||||
pStubMsg->MaxCount = pStubMsg->ActualCount;
|
||||
|
||||
safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrConformantStringMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat )
|
||||
{
|
||||
ULONG bufsize, memsize, esize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
|
||||
|
||||
ReadConformance(pStubMsg, NULL);
|
||||
ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
|
||||
|
||||
if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
|
||||
{
|
||||
ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
|
||||
pStubMsg->ActualCount, pStubMsg->MaxCount);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
if (pStubMsg->Offset)
|
||||
{
|
||||
ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
memsize = safe_multiply(esize, pStubMsg->MaxCount);
|
||||
bufsize = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
|
||||
validate_string_data(pStubMsg, bufsize, esize);
|
||||
|
||||
safe_buffer_increment(pStubMsg, bufsize);
|
||||
pStubMsg->MemorySize += memsize;
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrConformantStringUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
|
||||
{
|
||||
ULONG bufsize, memsize, esize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
|
||||
pStubMsg, *ppMemory, pFormat, fMustAlloc);
|
||||
|
||||
assert(pFormat && ppMemory && pStubMsg);
|
||||
|
||||
ReadConformance(pStubMsg, NULL);
|
||||
ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
|
||||
|
||||
if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
|
||||
{
|
||||
ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
|
||||
pStubMsg->ActualCount, pStubMsg->MaxCount);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
return NULL;
|
||||
}
|
||||
if (pStubMsg->Offset)
|
||||
{
|
||||
ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
memsize = safe_multiply(esize, pStubMsg->MaxCount);
|
||||
bufsize = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
|
||||
validate_string_data(pStubMsg, bufsize, esize);
|
||||
|
||||
if (fMustAlloc)
|
||||
*ppMemory = NdrAllocate(pStubMsg, memsize);
|
||||
else
|
||||
{
|
||||
if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
|
||||
/* if the data in the RPC buffer is big enough, we just point straight
|
||||
* into it */
|
||||
*ppMemory = pStubMsg->Buffer;
|
||||
else if (!*ppMemory)
|
||||
*ppMemory = NdrAllocate(pStubMsg, memsize);
|
||||
}
|
||||
|
||||
if (*ppMemory == pStubMsg->Buffer)
|
||||
safe_buffer_increment(pStubMsg, bufsize);
|
||||
else
|
||||
safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
|
||||
|
||||
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)
|
||||
{
|
||||
ULONG esize, size, maxsize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
|
||||
|
||||
maxsize = *(USHORT *)&pFormat[2];
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING)
|
||||
{
|
||||
ULONG i;
|
||||
const char *str = (const char *)pMemory;
|
||||
for (i = 0; i < maxsize && *str; i++, str++)
|
||||
;
|
||||
TRACE("string=%s\n", debugstr_an(str, i));
|
||||
pStubMsg->ActualCount = i + 1;
|
||||
esize = 1;
|
||||
}
|
||||
else if (*pFormat == RPC_FC_WSTRING)
|
||||
{
|
||||
ULONG i;
|
||||
const WCHAR *str = (const WCHAR *)pMemory;
|
||||
for (i = 0; i < maxsize && *str; i++, str++)
|
||||
;
|
||||
TRACE("string=%s\n", debugstr_wn(str, i));
|
||||
pStubMsg->ActualCount = i + 1;
|
||||
esize = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
pStubMsg->Offset = 0;
|
||||
WriteVariance(pStubMsg);
|
||||
|
||||
size = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrNonConformantStringUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char **ppMemory,
|
||||
PFORMAT_STRING pFormat,
|
||||
unsigned char fMustAlloc)
|
||||
{
|
||||
ULONG bufsize, memsize, esize, maxsize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
|
||||
pStubMsg, *ppMemory, pFormat, fMustAlloc);
|
||||
|
||||
maxsize = *(USHORT *)&pFormat[2];
|
||||
|
||||
ReadVariance(pStubMsg, NULL, maxsize);
|
||||
if (pStubMsg->Offset)
|
||||
{
|
||||
ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING) esize = 1;
|
||||
else if (*pFormat == RPC_FC_WSTRING) esize = 2;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
memsize = esize * maxsize;
|
||||
bufsize = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
|
||||
validate_string_data(pStubMsg, bufsize, esize);
|
||||
|
||||
if (fMustAlloc || !*ppMemory)
|
||||
*ppMemory = NdrAllocate(pStubMsg, memsize);
|
||||
|
||||
safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING) {
|
||||
TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
|
||||
}
|
||||
else if (*pFormat == RPC_FC_WSTRING) {
|
||||
TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrNonConformantStringBufferSize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG esize, maxsize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
|
||||
|
||||
maxsize = *(USHORT *)&pFormat[2];
|
||||
|
||||
SizeVariance(pStubMsg);
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING)
|
||||
{
|
||||
ULONG i;
|
||||
const char *str = (const char *)pMemory;
|
||||
for (i = 0; i < maxsize && *str; i++, str++)
|
||||
;
|
||||
TRACE("string=%s\n", debugstr_an(str, i));
|
||||
pStubMsg->ActualCount = i + 1;
|
||||
esize = 1;
|
||||
}
|
||||
else if (*pFormat == RPC_FC_WSTRING)
|
||||
{
|
||||
ULONG i;
|
||||
const WCHAR *str = (const WCHAR *)pMemory;
|
||||
for (i = 0; i < maxsize && *str; i++, str++)
|
||||
;
|
||||
TRACE("string=%s\n", debugstr_wn(str, i));
|
||||
pStubMsg->ActualCount = i + 1;
|
||||
esize = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrNonConformantStringMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG bufsize, memsize, esize, maxsize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
|
||||
|
||||
maxsize = *(USHORT *)&pFormat[2];
|
||||
|
||||
ReadVariance(pStubMsg, NULL, maxsize);
|
||||
|
||||
if (pStubMsg->Offset)
|
||||
{
|
||||
ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING) esize = 1;
|
||||
else if (*pFormat == RPC_FC_WSTRING) esize = 2;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
memsize = esize * maxsize;
|
||||
bufsize = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
|
||||
validate_string_data(pStubMsg, bufsize, esize);
|
||||
|
||||
safe_buffer_increment(pStubMsg, bufsize);
|
||||
pStubMsg->MemorySize += memsize;
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
static inline void dump_pointer_attr(unsigned char attr)
|
||||
{
|
||||
if (attr & RPC_FC_P_ALLOCALLNODES)
|
||||
|
@ -2143,6 +1752,26 @@ static inline void array_compute_and_size_conformance(
|
|||
pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
|
||||
SizeConformance(pStubMsg);
|
||||
break;
|
||||
case RPC_FC_C_CSTRING:
|
||||
case RPC_FC_C_WSTRING:
|
||||
if (pFormat[0] == RPC_FC_C_CSTRING)
|
||||
{
|
||||
TRACE("string=%s\n", debugstr_a((const char *)pMemory));
|
||||
pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
|
||||
pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
|
||||
}
|
||||
|
||||
if (fc == RPC_FC_STRING_SIZED)
|
||||
pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
|
||||
else
|
||||
pStubMsg->MaxCount = pStubMsg->ActualCount;
|
||||
|
||||
SizeConformance(pStubMsg);
|
||||
break;
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
|
@ -2189,6 +1818,18 @@ static inline void array_buffer_size(
|
|||
|
||||
EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
|
||||
break;
|
||||
case RPC_FC_C_CSTRING:
|
||||
case RPC_FC_C_WSTRING:
|
||||
if (fc == RPC_FC_C_CSTRING)
|
||||
esize = 1;
|
||||
else
|
||||
esize = 2;
|
||||
|
||||
SizeVariance(pStubMsg);
|
||||
|
||||
size = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
safe_buffer_length_increment(pStubMsg, size);
|
||||
break;
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
|
@ -2210,6 +1851,25 @@ static inline void array_compute_and_write_conformance(
|
|||
pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
|
||||
WriteConformance(pStubMsg);
|
||||
break;
|
||||
case RPC_FC_C_CSTRING:
|
||||
case RPC_FC_C_WSTRING:
|
||||
if (fc == RPC_FC_C_CSTRING)
|
||||
{
|
||||
TRACE("string=%s\n", debugstr_a((const char *)pMemory));
|
||||
pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
|
||||
pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
|
||||
}
|
||||
if (pFormat[1] == RPC_FC_STRING_SIZED)
|
||||
pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
|
||||
else
|
||||
pStubMsg->MaxCount = pStubMsg->ActualCount;
|
||||
pStubMsg->Offset = 0;
|
||||
WriteConformance(pStubMsg);
|
||||
break;
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
|
@ -2260,6 +1920,18 @@ static inline void array_write_variance_and_marshall(
|
|||
|
||||
EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
|
||||
break;
|
||||
case RPC_FC_C_CSTRING:
|
||||
case RPC_FC_C_WSTRING:
|
||||
if (fc == RPC_FC_C_CSTRING)
|
||||
esize = 1;
|
||||
else
|
||||
esize = 2;
|
||||
|
||||
WriteVariance(pStubMsg);
|
||||
|
||||
size = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
|
||||
break;
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
|
@ -2281,6 +1953,18 @@ static inline ULONG array_read_conformance(
|
|||
esize = *(const WORD*)(pFormat+2);
|
||||
pFormat = ReadConformance(pStubMsg, pFormat+4);
|
||||
return safe_multiply(esize, pStubMsg->MaxCount);
|
||||
case RPC_FC_C_CSTRING:
|
||||
case RPC_FC_C_WSTRING:
|
||||
if (fc == RPC_FC_C_CSTRING)
|
||||
esize = 1;
|
||||
else
|
||||
esize = 2;
|
||||
|
||||
if (pFormat[1] == RPC_FC_STRING_SIZED)
|
||||
ReadConformance(pStubMsg, pFormat + 2);
|
||||
else
|
||||
ReadConformance(pStubMsg, NULL);
|
||||
return safe_multiply(esize, pStubMsg->MaxCount);
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
|
@ -2352,6 +2036,55 @@ static inline void array_read_variance_and_unmarshall(
|
|||
|
||||
memcpy(*ppMemory + offset, saved_buffer, bufsize);
|
||||
break;
|
||||
case RPC_FC_C_CSTRING:
|
||||
case RPC_FC_C_WSTRING:
|
||||
if (fc == RPC_FC_C_CSTRING)
|
||||
esize = 1;
|
||||
else
|
||||
esize = 2;
|
||||
|
||||
ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
|
||||
|
||||
if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
|
||||
{
|
||||
ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
|
||||
pStubMsg->ActualCount, pStubMsg->MaxCount);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
if (pStubMsg->Offset)
|
||||
{
|
||||
ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
|
||||
memsize = safe_multiply(esize, pStubMsg->MaxCount);
|
||||
bufsize = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
|
||||
validate_string_data(pStubMsg, bufsize, esize);
|
||||
|
||||
if (fMustAlloc)
|
||||
*ppMemory = NdrAllocate(pStubMsg, memsize);
|
||||
else
|
||||
{
|
||||
if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
|
||||
!*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
|
||||
/* if the data in the RPC buffer is big enough, we just point straight
|
||||
* into it */
|
||||
*ppMemory = pStubMsg->Buffer;
|
||||
else if (!*ppMemory)
|
||||
*ppMemory = NdrAllocate(pStubMsg, memsize);
|
||||
}
|
||||
|
||||
if (*ppMemory == pStubMsg->Buffer)
|
||||
safe_buffer_increment(pStubMsg, bufsize);
|
||||
else
|
||||
safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
|
||||
|
||||
if (*pFormat == RPC_FC_C_CSTRING)
|
||||
TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
|
||||
else
|
||||
TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
|
||||
break;
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
|
@ -2400,6 +2133,35 @@ static inline void array_memory_size(
|
|||
|
||||
EmbeddedPointerMemorySize(pStubMsg, pFormat);
|
||||
break;
|
||||
case RPC_FC_C_CSTRING:
|
||||
case RPC_FC_C_WSTRING:
|
||||
if (fc == RPC_FC_C_CSTRING)
|
||||
esize = 1;
|
||||
else
|
||||
esize = 2;
|
||||
|
||||
ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
|
||||
|
||||
if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
|
||||
{
|
||||
ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
|
||||
pStubMsg->ActualCount, pStubMsg->MaxCount);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
if (pStubMsg->Offset)
|
||||
{
|
||||
ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
|
||||
memsize = safe_multiply(esize, pStubMsg->MaxCount);
|
||||
bufsize = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
|
||||
validate_string_data(pStubMsg, bufsize, esize);
|
||||
|
||||
safe_buffer_increment(pStubMsg, bufsize);
|
||||
pStubMsg->MemorySize += memsize;
|
||||
break;
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
|
@ -2431,6 +2193,311 @@ static inline void array_free(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
|
||||
|
||||
if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
|
||||
ERR("Unhandled string type: %#x\n", pFormat[0]);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
/* allow compiler to optimise inline function by passing constant into
|
||||
* these functions */
|
||||
if (pFormat[0] == RPC_FC_C_CSTRING) {
|
||||
array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage, pFormat);
|
||||
array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage, pFormat);
|
||||
} else {
|
||||
array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage, pFormat);
|
||||
array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage, pFormat);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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);
|
||||
|
||||
if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
|
||||
ERR("Unhandled string type: %#x\n", pFormat[0]);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
/* allow compiler to optimise inline function by passing constant into
|
||||
* these functions */
|
||||
if (pFormat[0] == RPC_FC_C_CSTRING) {
|
||||
array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat);
|
||||
array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat);
|
||||
} else {
|
||||
array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat);
|
||||
array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrConformantStringMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat )
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
|
||||
|
||||
if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
|
||||
ERR("Unhandled string type: %#x\n", pFormat[0]);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
/* allow compiler to optimise inline function by passing constant into
|
||||
* these functions */
|
||||
if (pFormat[0] == RPC_FC_C_CSTRING) {
|
||||
array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
|
||||
array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat);
|
||||
} else {
|
||||
array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
|
||||
array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat);
|
||||
}
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrConformantStringUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
|
||||
pStubMsg, *ppMemory, pFormat, fMustAlloc);
|
||||
|
||||
if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
/* allow compiler to optimise inline function by passing constant into
|
||||
* these functions */
|
||||
if (pFormat[0] == RPC_FC_C_CSTRING) {
|
||||
array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
|
||||
array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
|
||||
pFormat, fMustAlloc,
|
||||
TRUE /* fUseBufferMemoryServer */);
|
||||
} else {
|
||||
array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
|
||||
array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
|
||||
pFormat, fMustAlloc,
|
||||
TRUE /* fUseBufferMemoryServer */);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrNonConformantStringMarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG esize, size, maxsize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
|
||||
|
||||
maxsize = *(USHORT *)&pFormat[2];
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING)
|
||||
{
|
||||
ULONG i;
|
||||
const char *str = (const char *)pMemory;
|
||||
for (i = 0; i < maxsize && *str; i++, str++)
|
||||
;
|
||||
TRACE("string=%s\n", debugstr_an(str, i));
|
||||
pStubMsg->ActualCount = i + 1;
|
||||
esize = 1;
|
||||
}
|
||||
else if (*pFormat == RPC_FC_WSTRING)
|
||||
{
|
||||
ULONG i;
|
||||
const WCHAR *str = (const WCHAR *)pMemory;
|
||||
for (i = 0; i < maxsize && *str; i++, str++)
|
||||
;
|
||||
TRACE("string=%s\n", debugstr_wn(str, i));
|
||||
pStubMsg->ActualCount = i + 1;
|
||||
esize = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
pStubMsg->Offset = 0;
|
||||
WriteVariance(pStubMsg);
|
||||
|
||||
size = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrNonConformantStringUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char **ppMemory,
|
||||
PFORMAT_STRING pFormat,
|
||||
unsigned char fMustAlloc)
|
||||
{
|
||||
ULONG bufsize, memsize, esize, maxsize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
|
||||
pStubMsg, *ppMemory, pFormat, fMustAlloc);
|
||||
|
||||
maxsize = *(USHORT *)&pFormat[2];
|
||||
|
||||
ReadVariance(pStubMsg, NULL, maxsize);
|
||||
if (pStubMsg->Offset)
|
||||
{
|
||||
ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING) esize = 1;
|
||||
else if (*pFormat == RPC_FC_WSTRING) esize = 2;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
memsize = esize * maxsize;
|
||||
bufsize = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
|
||||
validate_string_data(pStubMsg, bufsize, esize);
|
||||
|
||||
if (fMustAlloc || !*ppMemory)
|
||||
*ppMemory = NdrAllocate(pStubMsg, memsize);
|
||||
|
||||
safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING) {
|
||||
TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
|
||||
}
|
||||
else if (*pFormat == RPC_FC_WSTRING) {
|
||||
TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrNonConformantStringBufferSize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG esize, maxsize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
|
||||
|
||||
maxsize = *(USHORT *)&pFormat[2];
|
||||
|
||||
SizeVariance(pStubMsg);
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING)
|
||||
{
|
||||
ULONG i;
|
||||
const char *str = (const char *)pMemory;
|
||||
for (i = 0; i < maxsize && *str; i++, str++)
|
||||
;
|
||||
TRACE("string=%s\n", debugstr_an(str, i));
|
||||
pStubMsg->ActualCount = i + 1;
|
||||
esize = 1;
|
||||
}
|
||||
else if (*pFormat == RPC_FC_WSTRING)
|
||||
{
|
||||
ULONG i;
|
||||
const WCHAR *str = (const WCHAR *)pMemory;
|
||||
for (i = 0; i < maxsize && *str; i++, str++)
|
||||
;
|
||||
TRACE("string=%s\n", debugstr_wn(str, i));
|
||||
pStubMsg->ActualCount = i + 1;
|
||||
esize = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrNonConformantStringMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG bufsize, memsize, esize, maxsize;
|
||||
|
||||
TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
|
||||
|
||||
maxsize = *(USHORT *)&pFormat[2];
|
||||
|
||||
ReadVariance(pStubMsg, NULL, maxsize);
|
||||
|
||||
if (pStubMsg->Offset)
|
||||
{
|
||||
ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
|
||||
RpcRaiseException(RPC_S_INVALID_BOUND);
|
||||
}
|
||||
|
||||
if (*pFormat == RPC_FC_CSTRING) esize = 1;
|
||||
else if (*pFormat == RPC_FC_WSTRING) esize = 2;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled string type: %#x\n", *pFormat);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
}
|
||||
|
||||
memsize = esize * maxsize;
|
||||
bufsize = safe_multiply(esize, pStubMsg->ActualCount);
|
||||
|
||||
validate_string_data(pStubMsg, bufsize, esize);
|
||||
|
||||
safe_buffer_increment(pStubMsg, bufsize);
|
||||
pStubMsg->MemorySize += memsize;
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
/* Complex types */
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
|
Loading…
Reference in New Issue