windows-nt/Source/XPSP1/NT/com/rpc/ndr20/unmrshlp.cxx

268 lines
7.6 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1993 Microsoft Corporation
Module Name :
unmrshlp.c
Abstract :
This file contains the routines for unmarshalling an array's or a
structure's embedded pointers.
Author :
David Kays dkays September 1993.
Revision History :
---------------------------------------------------------------------*/
#include "ndrp.h"
#include "attack.h"
#include "pointerq.h"
PFORMAT_STRING
NdrpEmbeddedPointerUnmarshall(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PFORMAT_STRING pFormat,
uchar fNewMemory )
/*++
Routine Description :
Unmarshalls an array's or a structure's embedded pointers.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to the structure or array whose embedded pointers
are being unmarshalled.
pFormat - Pointer layout format string description.
fNewMemory - TRUE if the array or structure was allocated during
unmarshalling, FALSE otherwise.
Return :
Format string pointer after the pointer layout.
--*/
{
uchar ** ppMemPtr;
uchar ** ppBufPtr;
uchar * pBufferMark;
ULONG_PTR MaxCountSave;
long OffsetSave;
MaxCountSave = pStubMsg->MaxCount;
OffsetSave = pStubMsg->Offset;
pStubMsg->Memory = pMemory;
POINTER_BUFFER_SWAP_CONTEXT SwapContext(pStubMsg);
// Save BufferMark in a local.
pBufferMark = pStubMsg->BufferMark;
// Increment past FC_PP and FC_PAD.
pFormat += 2;
for (;;)
{
if ( *pFormat == FC_END )
{
return pFormat;
}
// Check for FC_FIXED_REPEAT or FC_VARIABLE_REPEAT.
if ( *pFormat != FC_NO_REPEAT )
{
pStubMsg->MaxCount = MaxCountSave;
pStubMsg->Offset = OffsetSave;
pStubMsg->BufferMark = pBufferMark;
pFormat = NdrpEmbeddedRepeatPointerUnmarshall( pStubMsg,
pMemory,
pFormat,
fNewMemory );
// Continue to the next pointer.
continue;
}
// Compute the pointer to the current memory pointer to the data.
ppMemPtr = (uchar **)( pMemory + *((signed short *)(pFormat + 2)) );
// Compute the pointer to the pointer in the buffer.
ppBufPtr = (uchar **)(pBufferMark + *((signed short *)(pFormat + 4)));
// Increment to the pointer description.
pFormat += 6;
//
// If the incomming encapsulating memory pointer was just allocated,
// then explicitly null out the current pointer.
//
if ( fNewMemory )
*ppMemPtr = 0;
NdrpPointerUnmarshall(
pStubMsg,
(uchar**)ppMemPtr, // Memory rep written here
*ppMemPtr,
(long *)ppBufPtr, // Wire rep written here
pFormat );
// Increment to the next pointer description.
pFormat += 4;
}
}
PFORMAT_STRING
NdrpEmbeddedRepeatPointerUnmarshall(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PFORMAT_STRING pFormat,
uchar fNewMemory )
/*++
Routine Description :
Unmarshalls an array's embedded pointers.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to the array whose embedded pointers are being
unmarshalled.
pFormat - Pointer layout format string description.
fNewMemory - TRUE if the array was allocated during unmarshalling,
FALSE otherwise.
Return :
Format string pointer after the pointer layout.
--*/
{
uchar ** ppMemPtr;
uchar ** ppBufPtr;
PFORMAT_STRING pFormatSave;
uchar * pBufferMark;
uchar * pArrayElement;
ulong RepeatCount, RepeatIncrement, Pointers, PointersSave;
CORRELATION_RESOURCE_SAVE;
SAVE_CORRELATION_MEMORY();
// Get the beginning of the contained structure in the buffer.
pBufferMark = pStubMsg->BufferMark;
// Get the repeat count.
switch ( *pFormat )
{
case FC_FIXED_REPEAT :
pFormat += 2;
RepeatCount = *((ushort *)pFormat);
break;
case FC_VARIABLE_REPEAT :
RepeatCount = (ulong)pStubMsg->MaxCount;
//
// Check if this variable repeat instance also has a variable
// offset (this would be the case for a conformant varying array
// of pointers, or structures which contain pointers). If so then
// increment the format string to point to the actual first array
// element which is being marshalled.
//
if ( pFormat[1] == FC_VARIABLE_OFFSET )
pMemory += *((ushort *)(pFormat + 2)) * pStubMsg->Offset;
// else pFormat[1] == FC_FIXED_OFFSET - do nothing
break;
default :
NDR_ASSERT(0,"NdrpEmbeddedRepeatPointerUnmarshall : bad format");
RpcRaiseException( RPC_S_INTERNAL_ERROR );
return 0;
}
// Increment format string to increment field.
pFormat += 2;
// Get the increment amount between successive pointers.
RepeatIncrement = *((ushort * &)pFormat)++;
// Load up pointer to first element of embedded array.
pArrayElement = pBufferMark + *((ushort * &)pFormat)++;
// Get number of pointers in each array element.
PointersSave = Pointers = *((ushort * &)pFormat)++;
pFormatSave = pFormat;
//
// Loop over the number of shipped array elements.
//
for ( ; RepeatCount--;
pBufferMark += RepeatIncrement,
pMemory += RepeatIncrement,
pArrayElement += RepeatIncrement )
{
pFormat = pFormatSave;
Pointers = PointersSave;
// Set the correlation check context to be the beginning of each element
// in the array. This is necessary since other functions will assume that
// the context points to the top of the flat part of the containing structure.
// If the containing structure is embedded in another structure, the offset
// for correlation checks will be relative to the topmost structure.
pStubMsg->pCorrMemory = pArrayElement;
//
// Loop over the number of pointer per array element (which can
// be greater than one for an array of structures).
//
for ( ; Pointers--; )
{
// Pointer to the pointer in memory.
ppMemPtr = (uchar **)(pMemory + *((signed short * &)pFormat)++);
// Pointer to the pointer's id in the buffer.
ppBufPtr = (uchar **)(pBufferMark + *((signed short * &)pFormat)++);
//
// If the incomming encapsulating memory pointer was just
// allocated, then explicitly null out the current pointer.
//
if ( fNewMemory )
*ppMemPtr = 0;
NdrpPointerUnmarshall(
pStubMsg,
(uchar**)ppMemPtr, // Memory rep written here
*ppMemPtr,
(long *)ppBufPtr, // Wire rep written here
pFormat );
// Increment past the pointer description.
pFormat += 4;
}
}
RESET_CORRELATION_MEMORY();
// Return the format string pointer past the array's pointer description.
return pFormatSave + PointersSave * 8;
}