mirror of
https://github.com/reactos/wine.git
synced 2024-11-26 13:10:28 +00:00
rpcrt4: Add support for complex arrays in the generic array unmarshalling functions.
This commit is contained in:
parent
3243ee7e0b
commit
fe2f875aaf
@ -27,6 +27,7 @@
|
||||
* - Checks for integer addition overflow in user marshall functions
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -2046,7 +2047,8 @@ static inline void array_write_variance_and_marshall(
|
||||
static inline ULONG array_read_conformance(
|
||||
unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
|
||||
{
|
||||
DWORD esize;
|
||||
DWORD def, esize;
|
||||
unsigned char alignment;
|
||||
|
||||
switch (fc)
|
||||
{
|
||||
@ -2070,6 +2072,21 @@ static inline ULONG array_read_conformance(
|
||||
else
|
||||
ReadConformance(pStubMsg, NULL);
|
||||
return safe_multiply(esize, pStubMsg->MaxCount);
|
||||
case RPC_FC_BOGUS_ARRAY:
|
||||
alignment = pFormat[1] + 1;
|
||||
def = *(const WORD *)(pFormat + 2);
|
||||
pFormat += 4;
|
||||
if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
|
||||
else
|
||||
{
|
||||
pStubMsg->MaxCount = def;
|
||||
pFormat = SkipConformance( pStubMsg, pFormat );
|
||||
}
|
||||
pFormat = SkipVariance( pStubMsg, pFormat );
|
||||
|
||||
align_pointer(&pStubMsg->Buffer, alignment);
|
||||
esize = ComplexStructSize(pStubMsg, pFormat);
|
||||
return safe_multiply(pStubMsg->MaxCount, esize);
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
@ -2084,8 +2101,8 @@ static inline ULONG array_read_variance_and_unmarshall(
|
||||
ULONG bufsize, memsize;
|
||||
WORD esize;
|
||||
unsigned char alignment;
|
||||
unsigned char *saved_buffer;
|
||||
ULONG offset;
|
||||
unsigned char *saved_buffer, *pMemory;
|
||||
ULONG i, offset, count;
|
||||
|
||||
switch (fc)
|
||||
{
|
||||
@ -2204,6 +2221,31 @@ static inline ULONG array_read_variance_and_unmarshall(
|
||||
TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
|
||||
}
|
||||
return bufsize;
|
||||
|
||||
case RPC_FC_BOGUS_ARRAY:
|
||||
alignment = pFormat[1] + 1;
|
||||
pFormat = SkipConformance(pStubMsg, pFormat + 4);
|
||||
pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
|
||||
|
||||
esize = ComplexStructSize(pStubMsg, pFormat);
|
||||
memsize = safe_multiply(esize, pStubMsg->MaxCount);
|
||||
|
||||
assert( fUnmarshall );
|
||||
|
||||
if (!fMustAlloc && !*ppMemory)
|
||||
fMustAlloc = TRUE;
|
||||
if (fMustAlloc)
|
||||
*ppMemory = NdrAllocate(pStubMsg, memsize);
|
||||
|
||||
align_pointer(&pStubMsg->Buffer, alignment);
|
||||
saved_buffer = pStubMsg->Buffer;
|
||||
|
||||
pMemory = *ppMemory;
|
||||
count = pStubMsg->ActualCount;
|
||||
for (i = 0; i < count; i++)
|
||||
pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
|
||||
return pStubMsg->Buffer - saved_buffer;
|
||||
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
@ -2214,6 +2256,7 @@ static inline void array_memory_size(
|
||||
unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
|
||||
unsigned char fHasPointers)
|
||||
{
|
||||
ULONG i, count, SavedMemorySize;
|
||||
ULONG bufsize, memsize;
|
||||
DWORD esize;
|
||||
unsigned char alignment;
|
||||
@ -2286,6 +2329,24 @@ static inline void array_memory_size(
|
||||
safe_buffer_increment(pStubMsg, bufsize);
|
||||
pStubMsg->MemorySize += memsize;
|
||||
break;
|
||||
case RPC_FC_BOGUS_ARRAY:
|
||||
alignment = pFormat[1] + 1;
|
||||
pFormat = SkipConformance(pStubMsg, pFormat + 4);
|
||||
pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
|
||||
|
||||
align_pointer(&pStubMsg->Buffer, alignment);
|
||||
|
||||
SavedMemorySize = pStubMsg->MemorySize;
|
||||
|
||||
esize = ComplexStructSize(pStubMsg, pFormat);
|
||||
memsize = safe_multiply(pStubMsg->MaxCount, esize);
|
||||
|
||||
count = pStubMsg->ActualCount;
|
||||
for (i = 0; i < count; i++)
|
||||
ComplexStructMemorySize(pStubMsg, pFormat, NULL);
|
||||
|
||||
pStubMsg->MemorySize = SavedMemorySize + memsize;
|
||||
break;
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
@ -2296,6 +2357,8 @@ static inline void array_free(
|
||||
unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
|
||||
{
|
||||
DWORD i, count;
|
||||
|
||||
switch (fc)
|
||||
{
|
||||
case RPC_FC_CARRAY:
|
||||
@ -2313,6 +2376,15 @@ static inline void array_free(
|
||||
case RPC_FC_C_WSTRING:
|
||||
/* No embedded pointers so nothing to do */
|
||||
break;
|
||||
case RPC_FC_BOGUS_ARRAY:
|
||||
count = *(const WORD *)(pFormat + 2);
|
||||
pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
|
||||
pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
|
||||
|
||||
count = pStubMsg->ActualCount;
|
||||
for (i = 0; i < count; i++)
|
||||
pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
|
||||
break;
|
||||
default:
|
||||
ERR("unknown array format 0x%x\n", fc);
|
||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||
@ -4048,9 +4120,7 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat,
|
||||
unsigned char fMustAlloc)
|
||||
{
|
||||
ULONG i, count, size;
|
||||
unsigned char alignment;
|
||||
unsigned char *pMemory;
|
||||
ULONG size;
|
||||
unsigned char *saved_buffer;
|
||||
int pointer_buffer_mark_set = 0;
|
||||
int saved_ignore_embedded;
|
||||
@ -4064,8 +4134,6 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
alignment = pFormat[1] + 1;
|
||||
|
||||
saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
|
||||
/* save buffer pointer */
|
||||
saved_buffer = pStubMsg->Buffer;
|
||||
@ -4087,22 +4155,9 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
/* restore the original buffer */
|
||||
pStubMsg->Buffer = saved_buffer;
|
||||
|
||||
pFormat += 4;
|
||||
|
||||
pFormat = ReadConformance(pStubMsg, pFormat);
|
||||
pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
|
||||
|
||||
if (!fMustAlloc && !*ppMemory)
|
||||
fMustAlloc = TRUE;
|
||||
if (fMustAlloc)
|
||||
*ppMemory = NdrAllocate(pStubMsg, size);
|
||||
|
||||
align_pointer(&pStubMsg->Buffer, alignment);
|
||||
|
||||
pMemory = *ppMemory;
|
||||
count = pStubMsg->ActualCount;
|
||||
for (i = 0; i < count; i++)
|
||||
pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
|
||||
array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
|
||||
array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
|
||||
TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
|
||||
|
||||
if (pointer_buffer_mark_set)
|
||||
{
|
||||
@ -4174,9 +4229,6 @@ void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG i, count, esize, SavedMemorySize, MemorySize;
|
||||
unsigned char alignment;
|
||||
|
||||
TRACE("(%p,%p)\n", pStubMsg, pFormat);
|
||||
|
||||
if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
|
||||
@ -4186,29 +4238,9 @@ ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
alignment = pFormat[1] + 1;
|
||||
|
||||
pFormat += 4;
|
||||
|
||||
pFormat = ReadConformance(pStubMsg, pFormat);
|
||||
pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
|
||||
|
||||
align_pointer(&pStubMsg->Buffer, alignment);
|
||||
|
||||
SavedMemorySize = pStubMsg->MemorySize;
|
||||
|
||||
esize = ComplexStructSize(pStubMsg, pFormat);
|
||||
|
||||
MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
|
||||
|
||||
count = pStubMsg->ActualCount;
|
||||
for (i = 0; i < count; i++)
|
||||
ComplexStructMemorySize(pStubMsg, pFormat, NULL);
|
||||
|
||||
pStubMsg->MemorySize = SavedMemorySize;
|
||||
|
||||
pStubMsg->MemorySize += MemorySize;
|
||||
return MemorySize;
|
||||
array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
|
||||
array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user