268 lines
7.6 KiB
C++
268 lines
7.6 KiB
C++
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
|