398 lines
11 KiB
C++
398 lines
11 KiB
C++
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name :
|
||
|
|
||
|
pointer.cxx
|
||
|
|
||
|
Abstract :
|
||
|
|
||
|
This file contains the routines for handling pointers and pointer
|
||
|
layouts.
|
||
|
|
||
|
Author :
|
||
|
|
||
|
Mike Zoran mzoran January 2000.
|
||
|
|
||
|
Revision History :
|
||
|
|
||
|
---------------------------------------------------------------------*/
|
||
|
#include "precomp.hxx"
|
||
|
|
||
|
#if !defined(DBG)
|
||
|
// Optimize for time to force inlining.
|
||
|
#pragma optimize("gt", on)
|
||
|
|
||
|
#endif
|
||
|
|
||
|
typedef enum
|
||
|
{
|
||
|
NDR64_CORRELATION_NONE=0,
|
||
|
NDR64_CORRELATION_MEMORY=1,
|
||
|
NDR64_CORRELATION_BUFFER=2
|
||
|
} NDR64_CORRELATION_TYPE;
|
||
|
|
||
|
template<class Function>
|
||
|
static __forceinline void
|
||
|
Ndr64pProcessPointerLayout(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
PNDR64_FORMAT pLayoutFormat,
|
||
|
NDR64_UINT32 ArrayIterations,
|
||
|
uchar * pMemory,
|
||
|
uchar * pBuffer,
|
||
|
const NDR64_CORRELATION_TYPE CorrType,
|
||
|
Function func )
|
||
|
/*++
|
||
|
|
||
|
Routine Description :
|
||
|
|
||
|
Marshalls an array's or a structure's embedded pointers.
|
||
|
|
||
|
Arguments :
|
||
|
|
||
|
pStubMsg - Pointer to the stub message.
|
||
|
pFormat - The format string pointer layout.
|
||
|
ArrayIterations - Numbers of iterations for variable sized arrays.
|
||
|
pMemory - Pointer to the structure or array whose embedded pointers
|
||
|
are being marshalled.
|
||
|
pBuffer - Pointer to the buffer for the structure or arrays
|
||
|
CorrType - Determines how to set pCorrMemory.
|
||
|
func - Function to call to do the processing
|
||
|
|
||
|
|
||
|
Return :
|
||
|
|
||
|
Format string pointer after the pointer layout.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
PFORMAT_STRING pFormat = (PFORMAT_STRING)pLayoutFormat;
|
||
|
|
||
|
for (;;)
|
||
|
{
|
||
|
|
||
|
const NDR64_REPEAT_FORMAT *pRepeatFormat;
|
||
|
NDR64_UINT32 Iterations;
|
||
|
|
||
|
switch( *pFormat )
|
||
|
{
|
||
|
|
||
|
case FC64_NO_REPEAT:
|
||
|
{
|
||
|
const NDR64_NO_REPEAT_FORMAT *pNoRepeatHeader =
|
||
|
(NDR64_NO_REPEAT_FORMAT*)pFormat;
|
||
|
|
||
|
const NDR64_POINTER_INSTANCE_HEADER_FORMAT *pPointerInstance =
|
||
|
(NDR64_POINTER_INSTANCE_HEADER_FORMAT *)(pNoRepeatHeader + 1);
|
||
|
|
||
|
const NDR64_POINTER_FORMAT *pPointerFormat =
|
||
|
(NDR64_POINTER_FORMAT*)(pPointerInstance + 1);
|
||
|
|
||
|
uchar *pMemPtr = pMemory + pPointerInstance->Offset;
|
||
|
uchar *pBufPtr = pBuffer + pPointerInstance->Offset;
|
||
|
|
||
|
func( pStubMsg,
|
||
|
pMemPtr,
|
||
|
pBufPtr ,
|
||
|
pPointerFormat );
|
||
|
|
||
|
pFormat += sizeof(NDR64_NO_REPEAT_FORMAT) +
|
||
|
sizeof(NDR64_POINTER_INSTANCE_HEADER_FORMAT) +
|
||
|
sizeof(NDR64_POINTER_FORMAT);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case FC64_FIXED_REPEAT:
|
||
|
Iterations = ((NDR64_FIXED_REPEAT_FORMAT*)pFormat)->Iterations;
|
||
|
pRepeatFormat = (NDR64_REPEAT_FORMAT*)pFormat;
|
||
|
pFormat += sizeof(NDR64_FIXED_REPEAT_FORMAT);
|
||
|
goto RepeatCommon;
|
||
|
|
||
|
case FC64_VARIABLE_REPEAT:
|
||
|
Iterations = ArrayIterations;
|
||
|
pRepeatFormat = (NDR64_REPEAT_FORMAT*)pFormat;
|
||
|
pFormat += sizeof(NDR64_REPEAT_FORMAT);
|
||
|
// Fall through to Repeat Common
|
||
|
RepeatCommon:
|
||
|
{
|
||
|
|
||
|
uchar *pArrayMemory = pMemory + pRepeatFormat->OffsetToArray;
|
||
|
uchar *pArrayBuffer = pBuffer + pRepeatFormat->OffsetToArray;
|
||
|
PFORMAT_STRING pFormatSave = pFormat;
|
||
|
|
||
|
uchar *pCorrMemorySave;
|
||
|
if ( CorrType )
|
||
|
pCorrMemorySave = pStubMsg->pCorrMemory;
|
||
|
|
||
|
{
|
||
|
// Loop over the array elements
|
||
|
for( ; Iterations;
|
||
|
Iterations--,
|
||
|
pArrayMemory += pRepeatFormat->Increment,
|
||
|
pArrayBuffer += pRepeatFormat->Increment)
|
||
|
{
|
||
|
|
||
|
pFormat = pFormatSave;
|
||
|
|
||
|
if ( CorrType )
|
||
|
{
|
||
|
if ( CorrType == NDR64_CORRELATION_MEMORY )
|
||
|
{
|
||
|
if (pRepeatFormat->Flags.SetCorrMark)
|
||
|
pStubMsg->pCorrMemory = pArrayMemory;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pRepeatFormat->Flags.SetCorrMark)
|
||
|
pStubMsg->pCorrMemory = pArrayBuffer;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Loop over the pointers per element
|
||
|
for ( NDR64_UINT32 Pointers = pRepeatFormat->NumberOfPointers;
|
||
|
Pointers; Pointers-- )
|
||
|
{
|
||
|
|
||
|
const NDR64_POINTER_INSTANCE_HEADER_FORMAT *pPointerInstance =
|
||
|
(NDR64_POINTER_INSTANCE_HEADER_FORMAT *)pFormat;
|
||
|
const NDR64_POINTER_FORMAT *pPointerFormat =
|
||
|
(NDR64_POINTER_FORMAT*)(pPointerInstance + 1);
|
||
|
|
||
|
uchar *pMemPtr = pArrayMemory + pPointerInstance->Offset;
|
||
|
uchar *pBufPtr = pArrayBuffer + pPointerInstance->Offset;
|
||
|
|
||
|
func( pStubMsg,
|
||
|
pMemPtr,
|
||
|
pBufPtr,
|
||
|
pPointerFormat );
|
||
|
|
||
|
pFormat += sizeof(NDR64_POINTER_INSTANCE_HEADER_FORMAT) +
|
||
|
sizeof(NDR64_POINTER_FORMAT);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( CorrType )
|
||
|
pStubMsg->pCorrMemory = pCorrMemorySave;
|
||
|
|
||
|
}
|
||
|
|
||
|
case FC64_END:
|
||
|
|
||
|
return;
|
||
|
|
||
|
default :
|
||
|
NDR_ASSERT(0,"Ndr64pProcessPointerLayout : bad format char");
|
||
|
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
||
|
|
||
|
} // switch
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static __forceinline void
|
||
|
Ndr64pPointerLayoutMarshallCallback(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
uchar* pMemPtr,
|
||
|
uchar* pBufPtr,
|
||
|
PNDR64_FORMAT pFormat )
|
||
|
{
|
||
|
|
||
|
Ndr64pPointerMarshall
|
||
|
( pStubMsg,
|
||
|
(NDR64_PTR_WIRE_TYPE*)pBufPtr,
|
||
|
*(uchar**)pMemPtr,
|
||
|
(PFORMAT_STRING)pFormat );
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
Ndr64pPointerLayoutMarshall(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
PNDR64_FORMAT pFormat,
|
||
|
NDR64_UINT32 ArrayIterations,
|
||
|
uchar * pMemory,
|
||
|
uchar * pBuffer )
|
||
|
{
|
||
|
|
||
|
POINTER_BUFFER_SWAP_CONTEXT SwapContext( pStubMsg );
|
||
|
|
||
|
Ndr64pProcessPointerLayout(
|
||
|
pStubMsg,
|
||
|
pFormat,
|
||
|
ArrayIterations,
|
||
|
pMemory,
|
||
|
pBuffer,
|
||
|
NDR64_CORRELATION_MEMORY,
|
||
|
Ndr64pPointerLayoutMarshallCallback);
|
||
|
|
||
|
}
|
||
|
|
||
|
static __forceinline void
|
||
|
Ndr64pPointerLayoutUnmarshallCallback(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
uchar* pMemPtr,
|
||
|
uchar* pBufPtr,
|
||
|
PNDR64_FORMAT pFormat )
|
||
|
{
|
||
|
|
||
|
Ndr64pPointerUnmarshall(
|
||
|
pStubMsg,
|
||
|
*(NDR64_PTR_WIRE_TYPE*)pBufPtr,
|
||
|
(uchar **)pMemPtr,
|
||
|
*(uchar**)pMemPtr,
|
||
|
pFormat );
|
||
|
|
||
|
// Need to copy the value written to the memory pointer back to
|
||
|
// the buffer pointer since the buffer will be block copied to the memory.
|
||
|
*(uchar **)pBufPtr = *(uchar **)pMemPtr;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Ndr64pPointerLayoutUnmarshall(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
PNDR64_FORMAT pFormat,
|
||
|
NDR64_UINT32 ArrayIterations,
|
||
|
uchar * pMemory,
|
||
|
uchar * pBuffer )
|
||
|
{
|
||
|
|
||
|
POINTER_BUFFER_SWAP_CONTEXT SwapContext( pStubMsg );
|
||
|
|
||
|
uchar *pBufferSave = 0;
|
||
|
|
||
|
// Insert full pointer to ref id translation if needed.
|
||
|
if ( pStubMsg->FullPtrRefId )
|
||
|
FULL_POINTER_INSERT( pStubMsg, pMemory );
|
||
|
|
||
|
Ndr64pProcessPointerLayout(
|
||
|
pStubMsg,
|
||
|
pFormat,
|
||
|
ArrayIterations,
|
||
|
pMemory,
|
||
|
pBuffer,
|
||
|
NDR64_CORRELATION_BUFFER,
|
||
|
Ndr64pPointerLayoutUnmarshallCallback);
|
||
|
|
||
|
}
|
||
|
|
||
|
static __forceinline void
|
||
|
Ndr64pPointerLayoutMemorySizeCallback(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
uchar* pMemPtr,
|
||
|
uchar* pBufPtr,
|
||
|
PNDR64_FORMAT pFormat )
|
||
|
{
|
||
|
|
||
|
// Discard the pMemPtr
|
||
|
Ndr64pPointerMemorySize(
|
||
|
pStubMsg,
|
||
|
(NDR64_PTR_WIRE_TYPE*)pBufPtr,
|
||
|
pFormat );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
Ndr64pPointerLayoutMemorySize (
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
PNDR64_FORMAT pFormat,
|
||
|
NDR64_UINT32 ArrayIterations,
|
||
|
uchar * pBuffer )
|
||
|
{
|
||
|
|
||
|
if ( pStubMsg->IgnoreEmbeddedPointers )
|
||
|
return;
|
||
|
|
||
|
POINTER_MEMSIZE_SWAP_CONTEXT SwapContext( pStubMsg );
|
||
|
|
||
|
Ndr64pProcessPointerLayout(
|
||
|
pStubMsg,
|
||
|
pFormat,
|
||
|
ArrayIterations,
|
||
|
pBuffer,
|
||
|
pBuffer,
|
||
|
NDR64_CORRELATION_NONE,
|
||
|
Ndr64pPointerLayoutMemorySizeCallback );
|
||
|
|
||
|
}
|
||
|
|
||
|
static __forceinline void
|
||
|
Ndr64pPointerLayoutBufferSizeCallback(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
uchar* pMemPtr,
|
||
|
uchar* pBufPtr,
|
||
|
PNDR64_FORMAT pFormat )
|
||
|
{
|
||
|
|
||
|
// Discard the BufferPointer
|
||
|
Ndr64pPointerBufferSize(
|
||
|
pStubMsg,
|
||
|
*(uchar**)pMemPtr,
|
||
|
pFormat );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
Ndr64pPointerLayoutBufferSize (
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
PNDR64_FORMAT pFormat,
|
||
|
NDR64_UINT32 ArrayIterations,
|
||
|
uchar * pMemory )
|
||
|
{
|
||
|
|
||
|
if ( pStubMsg->IgnoreEmbeddedPointers )
|
||
|
return;
|
||
|
|
||
|
POINTER_BUFFERLENGTH_SWAP_CONTEXT SwapContext( pStubMsg );
|
||
|
|
||
|
Ndr64pProcessPointerLayout(
|
||
|
pStubMsg,
|
||
|
pFormat,
|
||
|
ArrayIterations,
|
||
|
pMemory,
|
||
|
pMemory,
|
||
|
NDR64_CORRELATION_MEMORY,
|
||
|
Ndr64pPointerLayoutBufferSizeCallback );
|
||
|
|
||
|
}
|
||
|
|
||
|
static __forceinline void
|
||
|
Ndr64pPointerLayoutFreeCallback(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
uchar* pMemPtr,
|
||
|
uchar* pBufPtr,
|
||
|
PNDR64_FORMAT pFormat )
|
||
|
{
|
||
|
|
||
|
Ndr64PointerFree(
|
||
|
pStubMsg,
|
||
|
*(uchar**)pMemPtr,
|
||
|
pFormat );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
Ndr64pPointerLayoutFree(
|
||
|
PMIDL_STUB_MESSAGE pStubMsg,
|
||
|
PNDR64_FORMAT pFormat,
|
||
|
NDR64_UINT32 ArrayIterations,
|
||
|
uchar * pMemory )
|
||
|
|
||
|
{
|
||
|
Ndr64pProcessPointerLayout(
|
||
|
pStubMsg,
|
||
|
pFormat,
|
||
|
ArrayIterations,
|
||
|
pMemory,
|
||
|
pMemory,
|
||
|
NDR64_CORRELATION_MEMORY,
|
||
|
Ndr64pPointerLayoutFreeCallback );
|
||
|
|
||
|
}
|
||
|
|