windows-nt/Source/XPSP1/NT/com/rpc/ndr64/pointer.cxx
2020-09-26 16:20:57 +08:00

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 );
}