/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Copyright (c) 1995 - 2000 Microsoft Corporation Module Name : pipes.cxx Abstract : This file contains the 64bit specified pipe code. Author : Mike Zoran (mzoran) Feb 2000 Revision History : ---------------------------------------------------------------------*/ #include "precomp.hxx" #include "..\ndr20\pipendr.h" class NDR_PIPE_HELPER64 : public NDR_PIPE_HELPER { private: PMIDL_STUB_MESSAGE pStubMsg; char *pStackTop; unsigned long NumberParameters; NDR64_PARAM_FORMAT* pFirstParameter; NDR64_PARAM_FORMAT* pCurrentParameter; unsigned long CurrentParamNumber; NDR_PIPE_DESC PipeDesc; public: void *operator new( size_t stAllocateBlock, PNDR_ALLOCA_CONTEXT pAllocContext ) { return NdrpAlloca( pAllocContext, (UINT)stAllocateBlock ); } // Do nothing since the memory will be deleted automatically void operator delete(void *pMemory) {} NDR_PIPE_HELPER64( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING Params, char * pStackTop, unsigned long NumberParams ) { NDR_PIPE_HELPER64::pStubMsg = pStubMsg; NDR_PIPE_HELPER64::pStackTop = pStackTop; pFirstParameter = (NDR64_PARAM_FORMAT*)Params; NumberParameters = NumberParams; } virtual PNDR_PIPE_DESC GetPipeDesc() { return &PipeDesc; } virtual bool InitParamEnum() { pCurrentParameter = pFirstParameter; CurrentParamNumber = 0; return NumberParameters > 0; } virtual bool GotoNextParam() { if ( CurrentParamNumber + 1 >= NumberParameters ) { return false; } CurrentParamNumber++; pCurrentParameter = pFirstParameter + CurrentParamNumber; return true; } virtual unsigned short GetParamPipeFlags() { NDR64_PARAM_FLAGS *pParamFlags = (NDR64_PARAM_FLAGS *)&pCurrentParameter->Attributes; if ( !pParamFlags->IsPipe ) return 0; unsigned short Flags = 0; if ( pParamFlags->IsIn ) Flags |= NDR_IN_PIPE; if ( pParamFlags->IsOut ) Flags |= NDR_OUT_PIPE; if ( pParamFlags->IsSimpleRef ) Flags |= NDR_REF_PIPE; return Flags; } virtual PFORMAT_STRING GetParamTypeFormat() { return (PFORMAT_STRING)pCurrentParameter->Type; } virtual char *GetParamArgument() { return pStackTop + pCurrentParameter->StackOffset; } virtual void InitPipeStateWithType( PNDR_PIPE_MESSAGE pPipeMsg ) { NDR64_PIPE_FORMAT* pPipeFc = (NDR64_PIPE_FORMAT *) pPipeMsg->pTypeFormat; NDR_PIPE_STATE *pState = & PipeDesc.RuntimeState; NDR64_PIPE_FLAGS *pPipeFlags = (NDR64_PIPE_FLAGS*)&pPipeFc->Flags; NDR64_RANGE_PIPE_FORMAT *pRangePipeFc = (NDR64_RANGE_PIPE_FORMAT*)pPipeFc; pState->LowChunkLimit = 0; pState->HighChunkLimit = NDR_DEFAULT_PIPE_HIGH_CHUNK_LIMIT; pState->ElemAlign = pPipeFc->Alignment; pState->ElemMemSize = pPipeFc->MemorySize; pState->ElemWireSize = pPipeFc->BufferSize; if ( pPipeFlags->HasRange ) { pState->LowChunkLimit = pRangePipeFc->MinValue; pState->HighChunkLimit = pRangePipeFc->MaxValue; } pState->ElemPad = WIRE_PAD( pState->ElemWireSize, pState->ElemAlign ); pState->fBlockCopy = pPipeFlags->BlockCopy; } virtual void MarshallType( PNDR_PIPE_MESSAGE pPipeMsg, uchar *pMemory, unsigned long Elements ) { unsigned long ElemMemSize = PipeDesc.RuntimeState.ElemMemSize; NDR64_PIPE_FORMAT* pPipeFc = (NDR64_PIPE_FORMAT *) pPipeMsg->pTypeFormat; while( Elements-- ) { Ndr64TopLevelTypeMarshall( pPipeMsg->pStubMsg, pMemory, pPipeFc->Type ); pMemory += ElemMemSize; } } virtual void UnmarshallType( PNDR_PIPE_MESSAGE pPipeMsg, uchar *pMemory, unsigned long Elements ) { unsigned long ElemMemSize = PipeDesc.RuntimeState.ElemMemSize; NDR64_PIPE_FORMAT* pPipeFc = (NDR64_PIPE_FORMAT *) pPipeMsg->pTypeFormat; while( Elements-- ) { Ndr64TopLevelTypeUnmarshall( pPipeMsg->pStubMsg, &pMemory, pPipeFc->Type, false ); pMemory += ElemMemSize; } } virtual void BufferSizeType( PNDR_PIPE_MESSAGE pPipeMsg, uchar *pMemory, unsigned long Elements ) { unsigned long ElemMemSize = PipeDesc.RuntimeState.ElemMemSize; NDR64_PIPE_FORMAT* pPipeFc = (NDR64_PIPE_FORMAT *) pPipeMsg->pTypeFormat; while( Elements-- ) { Ndr64TopLevelTypeSize( pPipeMsg->pStubMsg, pMemory, pPipeFc->Type ); pMemory += ElemMemSize; } } virtual void ConvertType( PNDR_PIPE_MESSAGE /* pPipeMsg */, unsigned long /* Elements */ ) { } virtual void BufferSizeChunkCounter( PNDR_PIPE_MESSAGE pPipeMsg ) { PMIDL_STUB_MESSAGE pStubMsg = pPipeMsg->pStubMsg; LENGTH_ALIGN( pStubMsg->BufferLength, sizeof(NDR64_UINT64)-1 ); pStubMsg->BufferLength += sizeof(NDR64_UINT64); } virtual bool UnmarshallChunkCounter( PNDR_PIPE_MESSAGE pPipeMsg, ulong *pOut ) { PMIDL_STUB_MESSAGE pStubMsg = pPipeMsg->pStubMsg; ALIGN( pStubMsg->Buffer, sizeof(NDR64_UINT64)-1); if ( 0 == REMAINING_BYTES() ) { return false; } // transition: end of src if (REMAINING_BYTES() < sizeof(NDR64_UINT64)) { // with packet sizes being a multiple of 8, // this cannot happen. NDR_ASSERT( 0, "Chunk counter split is not possible."); NdrpRaisePipeException( &PipeDesc, RPC_S_INTERNAL_ERROR ); return false; } NDR64_UINT64 Counter = *(NDR64_UINT64*)pStubMsg->Buffer; pStubMsg->Buffer += sizeof(NDR64_UINT64); *pOut = Ndr64pConvertTo2GB( Counter ); return true; } virtual void MarshallChunkCounter( PNDR_PIPE_MESSAGE pPipeMsg, ulong Counter ) { PMIDL_STUB_MESSAGE pStubMsg = pPipeMsg->pStubMsg; ALIGN( pStubMsg->Buffer, sizeof(NDR64_UINT64)-1); Ndr64pConvertTo2GB( Counter ); *(NDR64_UINT64*)pStubMsg->Buffer = (NDR64_UINT64)Counter; pStubMsg->Buffer += sizeof(NDR64_UINT64); } virtual void BufferSizeChunkTailCounter( PNDR_PIPE_MESSAGE pPipeMsg ) { BufferSizeChunkCounter( pPipeMsg ); } virtual void MarshallChunkTailCounter( PNDR_PIPE_MESSAGE pPipeMsg, ulong Counter ) { PMIDL_STUB_MESSAGE pStubMsg = pPipeMsg->pStubMsg; ALIGN( pStubMsg->Buffer, sizeof(NDR64_UINT64)-1); Ndr64pConvertTo2GB( Counter ); NDR64_UINT64 TailCounter = (NDR64_UINT64)-(NDR64_INT64)(NDR64_UINT64)Counter; *(NDR64_UINT64*)pStubMsg->Buffer = TailCounter; pStubMsg->Buffer += sizeof(NDR64_UINT64); } virtual bool VerifyChunkTailCounter( PNDR_PIPE_MESSAGE pPipeMsg, ulong HeaderCounter ) { PMIDL_STUB_MESSAGE pStubMsg = pPipeMsg->pStubMsg; ALIGN( pStubMsg->Buffer, sizeof(NDR64_UINT64)-1); if ( 0 == REMAINING_BYTES() ) { return false; } // transition: end of src if (REMAINING_BYTES() < sizeof(NDR64_UINT64)) { // with packet sizes being a multiple of 8, // this cannot happen. NDR_ASSERT( 0, "Chunk counter split is not possible."); NdrpRaisePipeException( &PipeDesc, RPC_S_INTERNAL_ERROR ); return false; } NDR64_UINT64 TailCounter = *(NDR64_UINT64*)pStubMsg->Buffer; pStubMsg->Buffer += sizeof(NDR64_UINT64); Ndr64pConvertTo2GB( HeaderCounter ); NDR64_UINT64 TailCounterChk = (NDR64_UINT64)-(NDR64_INT64)(NDR64_UINT64)HeaderCounter; if ( TailCounterChk != TailCounter ) { RpcRaiseException( RPC_X_INVALID_BOUND ); } return true; } virtual bool HasChunkTailCounter() { return TRUE; } }; void NdrpPipesInitialize64( PMIDL_STUB_MESSAGE pStubMsg, PNDR_ALLOCA_CONTEXT pAllocContext, PFORMAT_STRING Params, char * pStackTop, unsigned long NumberParams ) { /* C wrapper to initialize the 32 pipe helper and call NdrPipesInitialize*/ NDR_PIPE_HELPER64 *pPipeHelper = new( pAllocContext ) NDR_PIPE_HELPER64( pStubMsg, Params, pStackTop, NumberParams ); NdrPipesInitialize( pStubMsg, pPipeHelper, pAllocContext ); }