/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 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 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 ); }