/********************************************************************** Copyright (c) 1993-2000 Microsoft Corporation Module Name : unmrshl.cxx Abstract : This file contains the unmarshalling routines called by MIDL generated stubs and the interpreter. Author : David Kays dkays September 1993. Revision History : **********************************************************************/ #include "precomp.hxx" #include "..\..\ndr20\ndrole.h" void Ndr64UDTSimpleTypeUnmarshall1( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) { // // Align the buffer. // ALIGN( pStubMsg->Buffer, NDR64_SIMPLE_TYPE_BUFALIGN(*(PFORMAT_STRING)pFormat) ); // Initialize the memory pointer if needed. if ( fMustAlloc ) { *ppMemory = (uchar *) NdrAllocate( pStubMsg, NDR64_SIMPLE_TYPE_MEMSIZE(*(PFORMAT_STRING)pFormat) ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } else if ( !*ppMemory ) { // Set pointer into buffer. *ppMemory = pStubMsg->Buffer; } Ndr64SimpleTypeUnmarshall( pStubMsg, *ppMemory, *(PFORMAT_STRING)pFormat ); } void Ndr64SimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar * pMemory, uchar FormatChar ) /*++ Routine Description : Unmarshalls a simple type. Arguments : pStubMsg - Pointer to the stub message. pMemory - Memory pointer to unmarshall into. FormatChar - Simple type format character. Return : None. --*/ { switch ( FormatChar ) { case FC64_CHAR : case FC64_UINT8 : case FC64_INT8 : *pMemory = *(pStubMsg->Buffer)++; break; case FC64_WCHAR : case FC64_UINT16 : case FC64_INT16 : ALIGN(pStubMsg->Buffer,1); *((NDR64_UINT16 *)pMemory) = *((NDR64_UINT16 *)pStubMsg->Buffer); pStubMsg->Buffer += sizeof(NDR64_UINT16); break; case FC64_INT32 : case FC64_UINT32 : case FC64_FLOAT32 : case FC64_ERROR_STATUS_T: ALIGN(pStubMsg->Buffer,3); *((NDR64_UINT32 *)pMemory) = *((NDR64_UINT32 *)pStubMsg->Buffer); pStubMsg->Buffer += sizeof(NDR64_UINT32); break; case FC64_UINT64 : case FC64_INT64 : case FC64_FLOAT64 : ALIGN(pStubMsg->Buffer,7); *((NDR64_UINT64 *)pMemory) = *((NDR64_UINT64 *)pStubMsg->Buffer); pStubMsg->Buffer += sizeof(NDR64_UINT64); break; case FC64_IGNORE : break; default : NDR_ASSERT(0,"Ndr64SimpleTypeUnmarshall : bad format char"); RpcRaiseException( RPC_S_INTERNAL_ERROR ); return; } } void Ndr64RangeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Unmarshals a range FC64_RANGE descriptor. --*/ { const NDR64_RANGE_FORMAT * pRangeFormat = (const NDR64_RANGE_FORMAT*)pFormat; Ndr64UDTSimpleTypeUnmarshall1( pStubMsg, ppMemory, (PNDR64_FORMAT)&pRangeFormat->RangeType, fMustAlloc ); EXPR_VALUE Value = Ndr64pSimpleTypeToExprValue( pRangeFormat->RangeType, *ppMemory ); if ( Value < (EXPR_VALUE)pRangeFormat->MinValue || Value > (EXPR_VALUE)pRangeFormat->MaxValue ) RpcRaiseException( RPC_X_INVALID_BOUND ); } IUnknown * Ndr64pInterfacePointerUnmarshall ( PMIDL_STUB_MESSAGE pStubMsg, PNDR64_FORMAT pFormat) /*++ Routine Description : Unmarshalls an interface pointer. Arguments : pStubMsg - Pointer to the stub message. pFormat - Interface pointer's format string description. Return : None. Notes : Here is the data representation. // wire representation of a marshalled interface pointer typedef struct tagMInterfacePointer { ULONG ulCntData; // size of data [size_is(ulCntData)] BYTE abData[]; // data (OBJREF) } MInterfacePointer; --*/ { const NDR64_CONSTANT_IID_FORMAT *pConstInterfaceFormat = (NDR64_CONSTANT_IID_FORMAT*)pFormat; const NDR64_IID_FORMAT *pInterfaceFormat = (NDR64_IID_FORMAT*)pFormat; // Unmarshal the conformant size and the count field. ALIGN( pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN ); CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, (sizeof(NDR64_WIRE_COUNT_TYPE)+sizeof(ulong)) ); NDR64_UINT32 MaxCount = Ndr64pConvertTo2GB( *(NDR64_WIRE_COUNT_TYPE *) pStubMsg->Buffer ); pStubMsg->Buffer += sizeof(NDR64_WIRE_COUNT_TYPE); ulong ulCntData = *(ulong *) pStubMsg->Buffer; pStubMsg->Buffer += sizeof(ulong); if ( MaxCount != ulCntData ) { RpcRaiseException( RPC_X_BAD_STUB_DATA ); return NULL; } if ( !MaxCount ) { return NULL; } CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, MaxCount ); // Get a pointer to the IID hidden in the interface pointer // representation in the buffer with Rick's IRpcHelper. // IID *piidValue; NdrpGetIIDFromBuffer( pStubMsg, & piidValue ); // // Validate the IID. // if ( ((NDR64_IID_FLAGS*)&pConstInterfaceFormat->Flags)->ConstantIID ) { if ( memcmp( &pConstInterfaceFormat->Guid, piidValue, sizeof(GUID)) != 0) { RpcRaiseException( RPC_X_BAD_STUB_DATA ); return NULL; } } else { Ndr64pCheckCorrelation(pStubMsg, (EXPR_VALUE)piidValue, pInterfaceFormat->IIDDescriptor, EXPR_IID ); } IStream *pStream = (*NdrpCreateStreamOnMemory)(pStubMsg->Buffer, MaxCount); if(pStream == 0) { RpcRaiseException(RPC_S_OUT_OF_MEMORY); return NULL; } IUnknown * punk = NULL; HRESULT hr = (*pfnCoUnmarshalInterface)(pStream, IID_NULL, (void**)&punk ); pStream->Release(); if(FAILED(hr)) { RpcRaiseException(hr); return NULL; } pStubMsg->Buffer += MaxCount; return punk; } class FINDONTFREE_CONTEXT { PMIDL_STUB_MESSAGE const pStubMsg; const int fInDontFreeSave; public: __forceinline FINDONTFREE_CONTEXT( PMIDL_STUB_MESSAGE pStubMsg ) : pStubMsg( pStubMsg ), fInDontFreeSave(pStubMsg->fInDontFree) {} __forceinline FINDONTFREE_CONTEXT( PMIDL_STUB_MESSAGE pStubMsg, int fInDontFree ) : pStubMsg( pStubMsg ), fInDontFreeSave(pStubMsg->fInDontFree) { pStubMsg->fInDontFree = fInDontFree; } __forceinline ~FINDONTFREE_CONTEXT() { pStubMsg->fInDontFree = fInDontFreeSave; } }; void Ndr64pFreeOlePointer( PMIDL_STUB_MESSAGE pStubMsg, uchar * pMemory, PNDR64_FORMAT pFormat ) { NDR_POINTER_QUEUE *pOldQueue = NULL; if ( pStubMsg->pPointerQueueState ) { pOldQueue = pStubMsg->pPointerQueueState->GetActiveQueue(); pStubMsg->pPointerQueueState->SetActiveQueue(pOldQueue); } RpcTryFinally { Ndr64PointerFree( pStubMsg, pMemory, pFormat ); } RpcFinally { if ( pStubMsg->pPointerQueueState ) { pStubMsg->pPointerQueueState->SetActiveQueue( pOldQueue ); } } RpcEndFinally } NDR_ALLOC_ALL_NODES_CONTEXT * Ndr64pGetAllocateAllNodesContext( PMIDL_STUB_MESSAGE pStubMsg, PNDR64_FORMAT pFormat ) { uchar *pBuffer = pStubMsg->Buffer; // Clear memory size before calling mem size routine. pStubMsg->MemorySize = 0; // // Get the allocate all nodes memory size. // { NDR_POINTER_QUEUE *pOldQueue = NULL; if (pStubMsg->pPointerQueueState) { pOldQueue = pStubMsg->pPointerQueueState->GetActiveQueue(); pStubMsg->pPointerQueueState->SetActiveQueue(NULL); } RpcTryFinally { Ndr64TopLevelTypeMemorySize( pStubMsg, pFormat ); } RpcFinally { if ( pStubMsg->pPointerQueueState ) { pStubMsg->pPointerQueueState->SetActiveQueue( pOldQueue ); } } RpcEndFinally } ulong AllocSize = pStubMsg->MemorySize; pStubMsg->MemorySize = 0; LENGTH_ALIGN( AllocSize, __alignof(NDR_ALLOC_ALL_NODES_CONTEXT) - 1); uchar *pAllocMemory = (uchar*)NdrAllocate( pStubMsg, AllocSize + sizeof(NDR_ALLOC_ALL_NODES_CONTEXT) ); NDR_ALLOC_ALL_NODES_CONTEXT *pAllocContext = (NDR_ALLOC_ALL_NODES_CONTEXT*)(pAllocMemory + AllocSize); pAllocContext->AllocAllNodesMemory = pAllocMemory; pAllocContext->AllocAllNodesMemoryBegin = pAllocMemory; pAllocContext->AllocAllNodesMemoryEnd = (uchar*)pAllocContext; pStubMsg->Buffer = pBuffer; return pAllocContext; } __forceinline void Ndr64pPointerUnmarshallInternal( PMIDL_STUB_MESSAGE pStubMsg, NDR64_PTR_WIRE_TYPE WirePtr, uchar ** ppMemory, uchar * pMemory, PNDR64_FORMAT pFormat ) /*++ Routine Description : Private routine for unmarshalling a pointer to anything. This is the entry point for pointers embedded in structures, arrays, and unions. Used for FC64_RP, FC64_UP, FC64_FP, FC64_OP. Arguments : pStubMsg - Pointer to the stub message. ppBufferPointer - Address of the location in the buffer which holds the incomming pointer's value and will hold the final unmarshalled pointer's value. pMemory - Current memory pointer's value which we want to unmarshall into. If this value is valid the it will be copied to *ppBufferPointer and this is where stuff will get unmarshalled into. pFormat - Pointer's format string description. pStubMsg->Buffer - set to the pointee. Return : None. --*/ { const NDR64_POINTER_FORMAT *pPointerFormat = (NDR64_POINTER_FORMAT*) pFormat; bool fPointeeAlloc; bool fNewAllocAllNodes = false; // make sure we are not out out of bound. We need this check for embedded pointers / pointer // to pointer cases. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer ); SAVE_CONTEXT FullPtrRefIdSave( pStubMsg->FullPtrRefId ); FINDONTFREE_CONTEXT fInDontFreeSave( pStubMsg ); if ( NDR64_IS_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags) ) { pMemory = 0; } // // Check the pointer type. // switch ( *(PFORMAT_STRING)pFormat ) { case FC64_RP : break; case FC64_OP : // // Burn some instructions for OLE unique pointer support. // if ( pStubMsg->IsClient ) { // // It's ok if this is an [out] unique pointer. It will get // zeroed before this routine is called and Ndr64PointerFree // will simply return. // Ndr64pFreeOlePointer( pStubMsg, pMemory, pFormat ); // Set the current memory pointer to 0 so that we'll alloc. pMemory = 0; } // Fall through. case FC64_UP : // // Check for a null incomming pointer. Routines which call this // routine insure that the memory pointer gets nulled. // if ( ! WirePtr ) { *ppMemory = NULL; return; } break; case FC64_IP: if ( pStubMsg->IsClient ) { Ndr64PointerFree( pStubMsg, pMemory, pFormat ); pMemory = 0; } if ( ! WirePtr ) { *ppMemory = NULL; return; } *(IUnknown **)ppMemory = (IUnknown*) Ndr64pInterfacePointerUnmarshall( pStubMsg, pPointerFormat->Pointee ); return; case FC64_FP : { // // We have to remember the incomming ref id because we overwrite // it during the QueryRefId call. // ulong FullPtrRefId = Ndr64pWirePtrToRefId( WirePtr ); if ( !FullPtrRefId ) { *ppMemory = NULL; return; } // // Lookup the ref id. // if ( Ndr64pFullPointerQueryRefId( pStubMsg, FullPtrRefId, FULL_POINTER_UNMARSHALLED, (void**)ppMemory ) ) { return; } // // If our query returned false then check if the returned pointer // is 0. If so then we have to scribble away the ref id in the // stub message FullPtrRefId field so that we can insert the // pointer translation later, after we've allocated the pointer. // If the returned pointer was non-null then we leave the stub // message FullPtrRefId field alone so that we don't try to // re-insert the pointer to ref id translation later. // // We also copy the returned pointer value into pMemory. This // will allow our allocation decision to be made correctly. // if ( ! ( pMemory = *ppMemory ) ) { // // Put the unmarshalled ref id into the stub message to // be used later in a call to Ndr64FullPointerInsertRefId. // pStubMsg->FullPtrRefId = FullPtrRefId; } } break; default : NDR_ASSERT(0,"Ndr64pPointerUnmarshall : bad pointer type"); RpcRaiseException( RPC_S_INTERNAL_ERROR ); return; } // // Make the initial "must allocate" decision. // // The fPointeeAlloc flag is set on the client side if the current memory // pointer is null, and on the server side it is set if the current memory // pointer has the allocate don't free attribute applied to it. // // On the client side we also set the pointer's value in the buffer equal // to the current memory pointer. // // On the server side we explicitly null out the pointer's value in the // buffer as long as it's not allocated on the stack, otherwise we set it // equal to the current memory pointer (stack allocated). // if ( pStubMsg->IsClient ) { *ppMemory = pMemory; fPointeeAlloc = ! pMemory; } else { if ( ! NDR64_ALLOCED_ON_STACK( pPointerFormat->Flags ) ) *ppMemory = 0; else *ppMemory = pMemory; // // If this is a don't free pointer or a parent pointer of this pointer // was a don't free pointer then we set the alloc flag. // if ( fPointeeAlloc = (NDR64_DONT_FREE( pPointerFormat->Flags ) || pStubMsg->fInDontFree || pStubMsg->ReuseBuffer ) ) { pStubMsg->fInDontFree = TRUE; } // // We also set the alloc flag for object interface pointers. // if ( *(PFORMAT_STRING)pFormat == FC64_OP ) fPointeeAlloc = true; } // // Check if this is an allocate all nodes pointer AND that we're // not already in an allocate all nodes context. // if ( NDR64_ALLOCATE_ALL_NODES( pPointerFormat->Flags ) && ! pStubMsg->pAllocAllNodesContext ) { fNewAllocAllNodes = true; pStubMsg->pAllocAllNodesContext = Ndr64pGetAllocateAllNodesContext( pStubMsg, pPointerFormat->Pointee ); *ppMemory = 0; fPointeeAlloc = true; } if ( NDR64_POINTER_DEREF( pPointerFormat->Flags ) ) { // // Re-align the buffer. This is to cover embedded pointer to // pointers. // ALIGN(pStubMsg->Buffer, NDR64_PTR_WIRE_ALIGN ); // // We can't re-use the buffer for a pointer to a pointer // because we can't null out the pointee before we've unmarshalled // it. We need the stubs to alloc pointers to pointers on the // stack. // if ( ! *ppMemory && ! pStubMsg->IsClient ) fPointeeAlloc = true; if ( fPointeeAlloc ) { *ppMemory = (uchar*)NdrAllocate( pStubMsg, PTR_MEM_SIZE ); *((void **)*ppMemory) = 0; } if ( pStubMsg->FullPtrRefId ) FULL_POINTER_INSERT( pStubMsg, *ppMemory ); ppMemory = (uchar **) *ppMemory; } SAVE_CONTEXT uFlagsSave( pStubMsg->uFlags ); NDR64_RESET_EMBEDDED_FLAGS_TO_STANDALONE(pStubMsg->uFlags); if ( fPointeeAlloc ) NDR64_SET_SKIP_REF_CHECK( pStubMsg->uFlags ); PNDR64_FORMAT pPointee = pPointerFormat->Pointee; if ( NDR64_IS_SIMPLE_TYPE( *(PFORMAT_STRING)pPointee) ) { ALIGN(pStubMsg->Buffer,NDR64_SIMPLE_TYPE_BUFALIGN(*(PFORMAT_STRING)pPointee) ); CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + NDR64_SIMPLE_TYPE_BUFSIZE( *(PFORMAT_STRING)pPointee ) ); } // we don't need to check for buffer over run here. For non simple types, // unmarshal routines have checks available; for pointer to pointer, we have // the check at the beginning of this routine; and for pointer to simple types, // we'll unmarshal in place, but that's in current pStubMsg->Buffer, which is // covered by the above check too. Ndr64TopLevelTypeUnmarshall( pStubMsg, ppMemory, pPointerFormat->Pointee, fPointeeAlloc ); // Insert full pointer to ref id translation if needed. if ( pStubMsg->FullPtrRefId ) FULL_POINTER_INSERT( pStubMsg, *ppMemory ); // // Reset the memory allocator and allocate all nodes flag if this was // an allocate all nodes case. // if ( fNewAllocAllNodes ) { pStubMsg->pAllocAllNodesContext = 0; } } NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT::NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT( MIDL_STUB_MESSAGE *pStubMsg, uchar ** ppMemoryNew, uchar * pMemoryNew, NDR64_PTR_WIRE_TYPE WirePtrNew, PFORMAT_STRING pFormatNew ) : WirePtr(WirePtrNew), ppMemory(ppMemoryNew), pMemory(pMemoryNew), pFormat(pFormatNew), pCorrMemory(pStubMsg->pCorrMemory), pAllocAllNodesContext(pStubMsg->pAllocAllNodesContext), fInDontFree(pStubMsg->fInDontFree), uFlags(pStubMsg->uFlags) { } void NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT::Dispatch( PMIDL_STUB_MESSAGE pStubMsg ) { CORRELATION_CONTEXT CorrCtxt( pStubMsg, pCorrMemory ); SAVE_CONTEXT AllocNodesSave(pStubMsg->pAllocAllNodesContext,pAllocAllNodesContext ); FINDONTFREE_CONTEXT fInDoneFreeSave( pStubMsg, fInDontFree ); SAVE_CONTEXT uFlagsSave( pStubMsg->uFlags, uFlags ); Ndr64pPointerUnmarshallInternal( pStubMsg, WirePtr, ppMemory, pMemory, pFormat ); } #if defined(DBG) void NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT::Print() { DbgPrint("NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT:\n"); DbgPrint("pNext: %p\n", pNext ); DbgPrint("WirePtr: %I64u\n", WirePtr ); DbgPrint("ppMemory: %p\n", ppMemory ); DbgPrint("pMemory: %p\n", pMemory ); DbgPrint("pFormat: %p\n", pFormat ); DbgPrint("pCorrMemory: %p\n", pCorrMemory ); DbgPrint("pAllocAllNodesContext: %p\n", pAllocAllNodesContext ); DbgPrint("fInDontFree: %u\n", fInDontFree ); DbgPrint("uFlags: %u\n", uFlags ); } #endif void Ndr64pEnquePointerUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, NDR64_PTR_WIRE_TYPE WirePtr, uchar ** ppMemory, uchar * pMemory, PNDR64_FORMAT pFormat ) { NDR64_POINTER_CONTEXT PointerContext( pStubMsg ); RpcTryFinally { NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT*pElement = new(pStubMsg->pPointerQueueState) NDR64_UNMRSHL_POINTER_QUEUE_ELEMENT(pStubMsg, ppMemory, pMemory, WirePtr, (PFORMAT_STRING)pFormat ); PointerContext.Enque( pElement ); PointerContext.DispatchIfRequired(); } RpcFinally { PointerContext.EndContext(); } RpcEndFinally } void Ndr64pPointerUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, NDR64_PTR_WIRE_TYPE WirePtr, uchar ** ppMemory, uchar * pMemory, PNDR64_FORMAT pFormat ) { if ( !NdrIsLowStack( pStubMsg ) ) { Ndr64pPointerUnmarshallInternal( pStubMsg, WirePtr, ppMemory, pMemory, pFormat ); return; } Ndr64pEnquePointerUnmarshall( pStubMsg, WirePtr, ppMemory, pMemory, pFormat ); } __forceinline void Ndr64EmbeddedPointerUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool /*fSkipRefCheck*/ ) { ALIGN( pStubMsg->Buffer, NDR64_PTR_WIRE_ALIGN ); NDR64_PTR_WIRE_TYPE WirePtr = *(NDR64_PTR_WIRE_TYPE*) pStubMsg->Buffer; pStubMsg->Buffer += sizeof(NDR64_PTR_WIRE_TYPE); POINTER_BUFFER_SWAP_CONTEXT SwapContext(pStubMsg); Ndr64pPointerUnmarshall( pStubMsg, WirePtr, *(uchar***)ppMemory, **(uchar***)ppMemory, pFormat ); } __forceinline void Ndr64TopLevelPointerUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool /* fSkipRefCheck */) { if ( *(PFORMAT_STRING)pFormat != FC64_RP ) { ALIGN( pStubMsg->Buffer, NDR64_PTR_WIRE_ALIGN ); NDR64_PTR_WIRE_TYPE WirePtr = *(NDR64_PTR_WIRE_TYPE*) pStubMsg->Buffer; pStubMsg->Buffer += sizeof(NDR64_PTR_WIRE_TYPE); Ndr64pPointerUnmarshall( pStubMsg, WirePtr, ppMemory, *ppMemory, pFormat ); return; } // // If we're on the client unmarshalling a top level [out] ref pointer, // we have to make sure that it is non-null. if ( pStubMsg->IsClient && !NDR64_IS_SKIP_REF_CHECK( pStubMsg->uFlags ) && ! *ppMemory ) RpcRaiseException( RPC_X_NULL_REF_POINTER ); Ndr64pPointerUnmarshall( pStubMsg, 0, ppMemory, *ppMemory, pFormat ); } void Ndr64SimpleStructUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine description : Unmarshalls a simple structure. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Double pointer to the structure being unmarshalled. pFormat - Structure's format string description. fMustAlloc - TRUE if the structure must be allocate, FALSE otherwise. --*/ { const NDR64_STRUCTURE_HEADER_FORMAT * const pStructFormat = (NDR64_STRUCTURE_HEADER_FORMAT*) pFormat; SAVE_CONTEXT uFlagsSave( pStubMsg->uFlags ); // Align the buffer. ALIGN(pStubMsg->Buffer, pStructFormat->Alignment); CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, pStructFormat->MemorySize ); uchar *pBufferSave = pStubMsg->Buffer; pStubMsg->Buffer += pStructFormat->MemorySize; if ( fMustAlloc ) { *ppMemory = (uchar *) NdrAllocate( pStubMsg, pStructFormat->MemorySize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } else if ( !*ppMemory ) { *ppMemory = pBufferSave; NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } if ( pStructFormat->Flags.HasPointerInfo ) { CORRELATION_CONTEXT CorrCtxt( pStubMsg, pBufferSave ); Ndr64pPointerLayoutUnmarshall( pStubMsg, pStructFormat + 1, 0, *ppMemory, pBufferSave ); } // Copy the struct if we're not using the rpc buffer. if ( *ppMemory != pBufferSave ) { RpcpMemoryCopy( *ppMemory, pBufferSave, pStructFormat->MemorySize ); } } void Ndr64ConformantStructUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine description : Unmarshalls a conformant structure. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Double pointer to where the structure should be unmarshalled. pFormat - Structure's format string description. fMustAlloc - TRUE if the structure must be allocate, FALSE otherwise. Return : None. --*/ { const NDR64_CONF_STRUCTURE_HEADER_FORMAT * const pStructFormat = (NDR64_CONF_STRUCTURE_HEADER_FORMAT*) pFormat; const NDR64_CONF_ARRAY_HEADER_FORMAT * const pArrayFormat = (NDR64_CONF_ARRAY_HEADER_FORMAT *) pStructFormat->ArrayDescription; SAVE_CONTEXT uFlagsSave(pStubMsg->uFlags ); NDR64_WIRE_COUNT_TYPE MaxCount; if ( !NDR64_IS_CONF_MARK_VALID( pStubMsg->uFlags ) ) { // Align the buffer for unmarshalling the conformance count. ALIGN(pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN); MaxCount = *((NDR64_WIRE_COUNT_TYPE *)pStubMsg->Buffer); pStubMsg->Buffer += sizeof(NDR64_WIRE_COUNT_TYPE); } else MaxCount = *((NDR64_WIRE_COUNT_TYPE *)pStubMsg->ConformanceMark); // Re-align the buffer ALIGN(pStubMsg->Buffer, pStructFormat->Alignment ); uchar *pBufferStart = pStubMsg->Buffer; CHECK_EOB_RAISE_IB( pBufferStart + pStructFormat->MemorySize ); CORRELATION_CONTEXT CorrCtxt( pStubMsg, pBufferStart ); Ndr64pCheckCorrelation( pStubMsg, MaxCount, pArrayFormat->ConfDescriptor, EXPR_MAXCOUNT ); NDR64_UINT32 StructSize = Ndr64pConvertTo2GB( (NDR64_UINT64)pStructFormat->MemorySize + ( MaxCount * (NDR64_UINT64)pArrayFormat->ElementSize ) ); CHECK_EOB_WITH_WRAP_RAISE_IB( pBufferStart, StructSize ); pStubMsg->Buffer += StructSize; if ( fMustAlloc ) { *ppMemory = (uchar *) NdrAllocate( pStubMsg, StructSize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } else if ( !*ppMemory ) { *ppMemory = pBufferStart; NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } if ( pStructFormat->Flags.HasPointerInfo ) { Ndr64pPointerLayoutUnmarshall( pStubMsg, pStructFormat + 1, (NDR64_UINT32)MaxCount, *ppMemory, pBufferStart ); } if ( *ppMemory != pBufferStart ) { RpcpMemoryCopy( *ppMemory, pBufferStart, StructSize ); } } void Ndr64ComplexStructUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine description : Unmarshalls a complex structure. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Double pointer to where the structure should be unmarshalled. pFormat - Structure's format string description. fMustAlloc - Ignored. Return : None. --*/ { const NDR64_BOGUS_STRUCTURE_HEADER_FORMAT * pStructFormat = (NDR64_BOGUS_STRUCTURE_HEADER_FORMAT*) pFormat; const NDR64_CONF_BOGUS_STRUCTURE_HEADER_FORMAT * pConfStructFormat = (NDR64_CONF_BOGUS_STRUCTURE_HEADER_FORMAT*) pFormat; bool fSetPointerBufferMark = !pStubMsg->PointerBufferMark; if ( fSetPointerBufferMark ) { uchar *pBufferSave = pStubMsg->Buffer; BOOL fOldIgnore = pStubMsg->IgnoreEmbeddedPointers; pStubMsg->IgnoreEmbeddedPointers = TRUE; pStubMsg->MemorySize = 0; Ndr64ComplexStructMemorySize( pStubMsg, pFormat ); // check buffer overrun for flat part of the struct. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer ); pStubMsg->PointerBufferMark = pStubMsg->Buffer; pStubMsg->IgnoreEmbeddedPointers = fOldIgnore; pStubMsg->Buffer = pBufferSave; } uchar * pMemory; PFORMAT_STRING pFormatPointers = (PFORMAT_STRING)pStructFormat->PointerLayout; PFORMAT_STRING pFormatArray = NULL; bool fIsFullBogus = ( *(PFORMAT_STRING)pFormat == FC64_BOGUS_STRUCT || *(PFORMAT_STRING)pFormat == FC64_CONF_BOGUS_STRUCT ); PFORMAT_STRING pMemberLayout = ( *(PFORMAT_STRING)pFormat == FC64_CONF_BOGUS_STRUCT || *(PFORMAT_STRING)pFormat == FC64_FORCED_CONF_BOGUS_STRUCT ) ? (PFORMAT_STRING)( pConfStructFormat + 1) : (PFORMAT_STRING)( pStructFormat + 1); SAVE_CONTEXT ConformanceMarkSave( pStubMsg->ConformanceMark ); SAVE_CONTEXT uFlagsSave( pStubMsg->uFlags ); // Get conformant array description. if ( pStructFormat->Flags.HasConfArray ) { pFormatArray = (PFORMAT_STRING)pConfStructFormat->ConfArrayDescription; } // // Now check if there is a conformant array and mark where the conformance // will be unmarshalled from. // if ( pFormatArray && !NDR64_IS_CONF_MARK_VALID( pStubMsg->uFlags ) ) { ALIGN(pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN); pStubMsg->ConformanceMark = pStubMsg->Buffer; // // Increment the buffer pointer for every dimension in the // conformant array. // pStubMsg->Buffer += pConfStructFormat->Dimensions * sizeof(NDR64_WIRE_COUNT_TYPE); NDR64_SET_CONF_MARK_VALID( pStubMsg->uFlags ); } // Align the buffer on the struct's alignment. ALIGN( pStubMsg->Buffer, pStructFormat->Alignment ); bool fMustCopy; if ( fMustAlloc || ( fIsFullBogus && ! *ppMemory ) ) { NDR64_UINT32 StructSize = Ndr64pMemorySize( pStubMsg, pFormat, TRUE ); *ppMemory = (uchar*)NdrAllocate( pStubMsg, StructSize ); memset( *ppMemory, 0, StructSize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION( pStubMsg->uFlags ); fMustCopy = true; } else if ( ! *ppMemory ) { *ppMemory = pStubMsg->Buffer; NDR64_SET_NEW_EMBEDDED_ALLOCATION( pStubMsg->uFlags ); fMustCopy = false; } else // reuse the clients memory fMustCopy = true; if ( pStubMsg->FullPtrRefId ) FULL_POINTER_INSERT( pStubMsg, *ppMemory ); // Get the beginning memory pointer. pMemory = *ppMemory; CORRELATION_CONTEXT CorrCtxt( pStubMsg, pMemory ); for ( ; ; ) { switch ( *pMemberLayout ) { case FC64_STRUCT: { const NDR64_SIMPLE_REGION_FORMAT *pRegion = (NDR64_SIMPLE_REGION_FORMAT*) pMemberLayout; ALIGN( pStubMsg->Buffer, pRegion->Alignment ); CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + pRegion->RegionSize ); if ( fMustCopy ) RpcpMemoryCopy( pMemory, pStubMsg->Buffer, pRegion->RegionSize ); pStubMsg->Buffer += pRegion->RegionSize; pMemory += pRegion->RegionSize; pMemberLayout += sizeof( *pRegion ); break; } case FC64_STRUCTPADN : { const NDR64_MEMPAD_FORMAT *pMemPad = (NDR64_MEMPAD_FORMAT*)pMemberLayout; pMemory += pMemPad->MemPad; pMemberLayout += sizeof(*pMemPad); break; } case FC64_POINTER : { Ndr64EmbeddedTypeUnmarshall( pStubMsg, &pMemory, pFormatPointers ); pMemory += PTR_MEM_SIZE; pFormatPointers += sizeof(NDR64_POINTER_FORMAT); pMemberLayout += sizeof(NDR64_SIMPLE_MEMBER_FORMAT); break; } case FC64_EMBEDDED_COMPLEX : { const NDR64_EMBEDDED_COMPLEX_FORMAT * pEmbeddedFormat = (NDR64_EMBEDDED_COMPLEX_FORMAT*) pMemberLayout; Ndr64EmbeddedTypeUnmarshall( pStubMsg, &pMemory, pEmbeddedFormat->Type ); pMemory = Ndr64pMemoryIncrement( pStubMsg, pMemory, pEmbeddedFormat->Type, TRUE ); pMemberLayout += sizeof(*pEmbeddedFormat); break; } case FC64_BUFFER_ALIGN: { const NDR64_BUFFER_ALIGN_FORMAT *pBufAlign = (NDR64_BUFFER_ALIGN_FORMAT*) pMemberLayout; ALIGN( pStubMsg->Buffer, pBufAlign->Alignment ); pMemberLayout += sizeof( *pBufAlign ); break; } case FC64_CHAR : case FC64_WCHAR : case FC64_INT8: case FC64_UINT8: case FC64_INT16: case FC64_UINT16: case FC64_INT32: case FC64_UINT32: case FC64_INT64: case FC64_UINT64: case FC64_FLOAT32 : case FC64_FLOAT64 : case FC64_ERROR_STATUS_T: Ndr64SimpleTypeUnmarshall( pStubMsg, pMemory, *pMemberLayout ); pMemory += NDR64_SIMPLE_TYPE_MEMSIZE(*pMemberLayout); pMemberLayout += sizeof(NDR64_SIMPLE_MEMBER_FORMAT); break; case FC64_IGNORE : ALIGN(pStubMsg->Buffer, NDR64_PTR_WIRE_ALIGN); pStubMsg->Buffer += sizeof(NDR64_PTR_WIRE_TYPE); if ( NDR64_IS_NEW_EMBEDDED_ALLOCATION( pStubMsg->uFlags ) ) { *(char**)pMemory = (char*)0; } pMemory += PTR_MEM_SIZE; pMemberLayout += sizeof(NDR64_SIMPLE_MEMBER_FORMAT); break; case FC64_END : goto ComplexUnmarshallEnd; default : NDR_ASSERT(0,"Ndr64ComplexStructUnmarshall : bad format char"); RpcRaiseException( RPC_S_INTERNAL_ERROR ); return; } } ComplexUnmarshallEnd: if ( pFormatArray ) { Ndr64EmbeddedTypeUnmarshall( pStubMsg, &pMemory, pFormatArray ); } else { // If the structure doesn't have a conformant array, align it again ALIGN( pStubMsg->Buffer, pStructFormat->Alignment ); } if ( fSetPointerBufferMark ) { pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = 0; } } void Ndr64pCommonStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, const NDR64_STRING_HEADER_FORMAT *pStringFormat, bool fMustAlloc, NDR64_UINT32 MemorySize ) { ALIGN(pStubMsg->Buffer,NDR64_WIRE_COUNT_ALIGN); NDR64_WIRE_COUNT_TYPE Offset = ((NDR64_WIRE_COUNT_TYPE *)pStubMsg->Buffer)[0]; NDR64_WIRE_COUNT_TYPE Count = ((NDR64_WIRE_COUNT_TYPE *)pStubMsg->Buffer)[1]; pStubMsg->Buffer += sizeof(NDR64_WIRE_COUNT_TYPE) * 2; NDR64_UINT32 TransmittedSize = Ndr64pConvertTo2GB( (NDR64_UINT64)pStringFormat->ElementSize * Count ); if ( ( Offset != 0 ) || ( 0 == Count ) || ( TransmittedSize > MemorySize ) ) RpcRaiseException( RPC_X_INVALID_BOUND ); CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, TransmittedSize ); // In this code, we check that a terminator is // where the marshaller tells us it is. We could check // if another terminator exists in addition to the other // terminator, but it doesn't make sense to do this // since it wouldn't close any attacks. switch( pStringFormat->FormatCode ) { case FC64_CHAR_STRING: case FC64_CONF_CHAR_STRING: { char *p = (char *) pStubMsg->Buffer; NDR64_WIRE_COUNT_TYPE ActualChars = Count - 1; if ( '\0' != p[ActualChars] ) { RpcRaiseException( RPC_X_INVALID_BOUND ); return; } break; } case FC64_WCHAR_STRING: case FC64_CONF_WCHAR_STRING: { wchar_t *p = ( wchar_t* ) pStubMsg->Buffer; NDR64_WIRE_COUNT_TYPE ActualChars = Count - 1; if ( L'\0' != p[ActualChars] ) { RpcRaiseException( RPC_X_INVALID_BOUND ); return; } break; } case FC64_STRUCT_STRING: case FC64_CONF_STRUCT_STRING: { NDR64_UINT8 *p = (NDR64_UINT8 *) pStubMsg->Buffer; NDR64_WIRE_COUNT_TYPE ActualChars = Count - 1; NDR64_UINT32 ElementSize = pStringFormat->ElementSize; NDR64_UINT8 *t = p + Ndr64pConvertTo2GB( ActualChars * ElementSize ); if ( !Ndr64pIsStructStringTerminator( t, ElementSize ) ) { RpcRaiseException( RPC_X_INVALID_BOUND ); return; } break; } } if ( fMustAlloc ) { *ppMemory = (uchar *) NdrAllocate( pStubMsg, MemorySize ); } else if ( ! *ppMemory ) { *ppMemory = ( TransmittedSize == MemorySize ) ? pStubMsg->Buffer : (uchar *) NdrAllocate( pStubMsg, MemorySize ); } if ( *ppMemory != pStubMsg->Buffer ) { RpcpMemoryCopy( *ppMemory, pStubMsg->Buffer, TransmittedSize ); } pStubMsg->Buffer += TransmittedSize; return; } void Ndr64NonConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine description : Unmarshalls a non conformant string. Arguments : pStubMsg - Pointer to the stub message. pMemory - Double pointer to the string should be unmarshalled. pFormat - String's format string description. fMustAlloc - Ignored. Return : None. --*/ { const NDR64_NON_CONFORMANT_STRING_FORMAT * pStringFormat = (NDR64_NON_CONFORMANT_STRING_FORMAT*) pFormat; Ndr64pCommonStringUnmarshall( pStubMsg, ppMemory, &pStringFormat->Header, fMustAlloc, pStringFormat->TotalSize ); } void Ndr64ConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine description : Unmarshalls a top level conformant string. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Double pointer to where the string should be unmarshalled. pFormat - String's format string description. fMustAlloc - TRUE if the string must be allocated, FALSE otherwise. Return : None. --*/ { const NDR64_CONFORMANT_STRING_FORMAT * pStringFormat = (const NDR64_CONFORMANT_STRING_FORMAT*) pFormat; const NDR64_SIZED_CONFORMANT_STRING_FORMAT *pSizedStringFormat = (const NDR64_SIZED_CONFORMANT_STRING_FORMAT*) pFormat; NDR64_WIRE_COUNT_TYPE MaxCount; if ( !NDR64_IS_CONF_MARK_VALID( pStubMsg->uFlags ) ) { ALIGN( pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN ); MaxCount = *((NDR64_WIRE_COUNT_TYPE*)pStubMsg->Buffer); pStubMsg->Buffer += sizeof(NDR64_WIRE_COUNT_TYPE); } else { MaxCount = *(NDR64_WIRE_COUNT_TYPE*)pStubMsg->ConformanceMark; } NDR64_UINT32 AllocationSize = Ndr64pConvertTo2GB( MaxCount * (NDR64_UINT64)pStringFormat->Header.ElementSize ); if ( pStringFormat->Header.Flags.IsSized ) { Ndr64pCheckCorrelation( pStubMsg, MaxCount, pSizedStringFormat->SizeDescription, EXPR_MAXCOUNT ); } return Ndr64pCommonStringUnmarshall( pStubMsg, ppMemory, &pStringFormat->Header, fMustAlloc, AllocationSize ); } void Ndr64FixedArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine Description : Unmarshalls a fixed array of any number of dimensions. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Pointer to the array to unmarshall. pFormat - Array's format string description. fMustAlloc - TRUE if the array must be allocated, FALSE otherwise. Return : None. --*/ { const NDR64_FIX_ARRAY_HEADER_FORMAT * pArrayFormat = (NDR64_FIX_ARRAY_HEADER_FORMAT*) pFormat; SAVE_CONTEXT uFlagsSave( pStubMsg->uFlags ); ALIGN(pStubMsg->Buffer, pArrayFormat->Alignment ); uchar *pBufferStart = pStubMsg->Buffer; CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + pArrayFormat->TotalSize ); pStubMsg->Buffer += pArrayFormat->TotalSize; if ( fMustAlloc ) { *ppMemory = (uchar *) NdrAllocate( pStubMsg, pArrayFormat->TotalSize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } else if ( !*ppMemory ) { *ppMemory = pBufferStart; NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } if ( pArrayFormat->Flags.HasPointerInfo ) { Ndr64pPointerLayoutUnmarshall( pStubMsg, pArrayFormat + 1, 0, *ppMemory, pBufferStart ); } if ( *ppMemory != pBufferStart ) { RpcpMemoryCopy( *ppMemory, pBufferStart, pArrayFormat->TotalSize ); } } void Ndr64ConformantArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine Description : Unmarshalls a top level one dimensional conformant array. Used for FC64_CARRAY. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Pointer to array to be unmarshalled. pFormat - Array's format string description. Return : None. --*/ { const NDR64_CONF_ARRAY_HEADER_FORMAT *pArrayFormat = (NDR64_CONF_ARRAY_HEADER_FORMAT*) pFormat; SAVE_CONTEXT uFlagsSave( pStubMsg->uFlags ); NDR64_WIRE_COUNT_TYPE MaxCount; if ( ! NDR64_IS_CONF_MARK_VALID( pStubMsg->uFlags ) ) { // Align the buffer for conformance marshalling. ALIGN(pStubMsg->Buffer,NDR64_WIRE_COUNT_ALIGN); MaxCount = *((NDR64_WIRE_COUNT_TYPE*)pStubMsg->Buffer); pStubMsg->Buffer += sizeof(NDR64_WIRE_COUNT_TYPE); } else { MaxCount = *pStubMsg->ConformanceMark; } NDR64_UINT32 CopySize = Ndr64pConvertTo2GB( MaxCount * (NDR64_UINT64)pArrayFormat->ElementSize ); Ndr64pCheckCorrelation( pStubMsg, MaxCount, pArrayFormat->ConfDescriptor, EXPR_MAXCOUNT ); ALIGN( pStubMsg->Buffer, pArrayFormat->Alignment ); uchar *pBufferStart = pStubMsg->Buffer; CHECK_EOB_WITH_WRAP_RAISE_IB( pStubMsg->Buffer, CopySize); pStubMsg->Buffer += CopySize; // Unmarshall embedded pointers. if ( fMustAlloc ) { *ppMemory = (uchar *) NdrAllocate( pStubMsg, CopySize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } else if ( !*ppMemory ) { *ppMemory = pBufferStart; NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } if ( pArrayFormat->Flags.HasPointerInfo ) { Ndr64pPointerLayoutUnmarshall( pStubMsg, pArrayFormat + 1, (NDR64_UINT32)MaxCount, *ppMemory, pBufferStart ); } if ( *ppMemory != pBufferStart ) { RpcpMemoryCopy( *ppMemory, pBufferStart, CopySize ); } } void Ndr64ConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine Description : Unmarshalls a top level one dimensional conformant varying array. Used for FC64_CVARRAY. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Pointer to the array being unmarshalled. pFormat - Array's format string description. fMustAlloc - Ignored. Return : None. --*/ { const NDR64_CONF_VAR_ARRAY_HEADER_FORMAT * pArrayFormat = (NDR64_CONF_VAR_ARRAY_HEADER_FORMAT*) pFormat; SAVE_CONTEXT uFlagsSave(pStubMsg->uFlags); NDR64_WIRE_COUNT_TYPE MaxCount; if ( ! NDR64_IS_CONF_MARK_VALID( pStubMsg->uFlags ) ) { // Align the buffer for conformance unmarshalling. ALIGN(pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN ); MaxCount = *((NDR64_WIRE_COUNT_TYPE*)pStubMsg->Buffer); pStubMsg->Buffer += sizeof(NDR64_WIRE_COUNT_TYPE); } else { MaxCount = *(NDR64_WIRE_COUNT_TYPE*)pStubMsg->ConformanceMark; } ALIGN( pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN ); NDR64_WIRE_COUNT_TYPE Offset = ((NDR64_WIRE_COUNT_TYPE*)pStubMsg->Buffer)[0]; NDR64_WIRE_COUNT_TYPE ActualCount = ((NDR64_WIRE_COUNT_TYPE*)pStubMsg->Buffer)[1]; pStubMsg->Buffer += sizeof(NDR64_WIRE_COUNT_TYPE) * 2; NDR64_UINT32 AllocSize = Ndr64pConvertTo2GB( MaxCount * (NDR64_UINT64)pArrayFormat->ElementSize ); NDR64_UINT32 CopySize = Ndr64pConvertTo2GB( ActualCount * (NDR64_UINT64)pArrayFormat->ElementSize ); if ( ( Offset != 0 ) || ActualCount > MaxCount ) RpcRaiseException( RPC_X_INVALID_BOUND ); Ndr64pCheckCorrelation( pStubMsg, MaxCount, pArrayFormat->ConfDescriptor, EXPR_MAXCOUNT ); Ndr64pCheckCorrelation( pStubMsg, ActualCount, pArrayFormat->VarDescriptor, EXPR_ACTUALCOUNT ); // // For a conformant varying array, we can't reuse the buffer // because it doesn't hold the total size of the array. if ( fMustAlloc || !*ppMemory ) { *ppMemory = (uchar *) NdrAllocate( pStubMsg, AllocSize ); memset( *ppMemory, 0, AllocSize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } ALIGN( pStubMsg->Buffer, pArrayFormat->Alignment ); CHECK_EOB_WITH_WRAP_RAISE_IB( pStubMsg->Buffer, CopySize); uchar *pBufferStart = pStubMsg->Buffer; pStubMsg->Buffer += CopySize; if ( pArrayFormat->Flags.HasPointerInfo ) { Ndr64pPointerLayoutUnmarshall( pStubMsg, pArrayFormat + 1, (NDR64_UINT32)ActualCount, *ppMemory, pBufferStart ); } RpcpMemoryCopy( *ppMemory, pBufferStart, CopySize ); } void Ndr64VaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine Description : Unmarshalls top level or embedded a one dimensional varying array. Arguments : pStubMsg - Pointer to the stub message. pMemory - Array being unmarshalled. pFormat - Array's format string description. fMustAlloc - Ignored. --*/ { const NDR64_VAR_ARRAY_HEADER_FORMAT * pArrayFormat = (NDR64_VAR_ARRAY_HEADER_FORMAT*) pFormat; SAVE_CONTEXT uFlagsSave( pStubMsg->uFlags ); ALIGN(pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN ); NDR64_WIRE_COUNT_TYPE Offset = ((NDR64_WIRE_COUNT_TYPE *)pStubMsg->Buffer)[0]; NDR64_WIRE_COUNT_TYPE ActualCount = ((NDR64_WIRE_COUNT_TYPE *)pStubMsg->Buffer)[1]; pStubMsg->Buffer += sizeof(NDR64_WIRE_COUNT_TYPE) * 2; NDR64_UINT32 CopySize = Ndr64pConvertTo2GB( ActualCount * (NDR64_UINT64)pArrayFormat->ElementSize ); if ( ( Offset != 0 ) || ( CopySize > pArrayFormat->TotalSize ) ) RpcRaiseException( RPC_X_INVALID_BOUND ); Ndr64pCheckCorrelation( pStubMsg, ActualCount, pArrayFormat->VarDescriptor, EXPR_ACTUALCOUNT ); if ( fMustAlloc || !*ppMemory ) { *ppMemory = (uchar *) NdrAllocate( pStubMsg, pArrayFormat->TotalSize ); memset( *ppMemory, 0, pArrayFormat->TotalSize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } ALIGN(pStubMsg->Buffer, pArrayFormat->Alignment ); CHECK_EOB_WITH_WRAP_RAISE_IB( pStubMsg->Buffer, CopySize ); uchar *pBufferStart = pStubMsg->Buffer; pStubMsg->Buffer += CopySize; if ( pArrayFormat->Flags.HasPointerInfo ) { Ndr64pPointerLayoutUnmarshall( pStubMsg, pArrayFormat + 1, (NDR64_UINT32)ActualCount, *ppMemory, pBufferStart ); } RpcpMemoryCopy( *ppMemory, pBufferStart, CopySize ); } void Ndr64ComplexArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine Description : Unmarshalls a top level complex array. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Pointer to the array being unmarshalled. pFormat - Array's format string description. fMustAlloc - Ignored. Return : None. --*/ { const NDR64_BOGUS_ARRAY_HEADER_FORMAT *pArrayFormat = (NDR64_BOGUS_ARRAY_HEADER_FORMAT *) pFormat; bool fSetPointerBufferMark = ! pStubMsg->PointerBufferMark; if ( fSetPointerBufferMark ) { uchar *pBuffer = pStubMsg->Buffer; BOOL fOldIgnore = pStubMsg->IgnoreEmbeddedPointers; pStubMsg->IgnoreEmbeddedPointers = TRUE; pStubMsg->MemorySize = 0; Ndr64ComplexArrayMemorySize( pStubMsg, pFormat ); // make sure we haven't overflow for the flat part. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer ); pStubMsg->PointerBufferMark = pStubMsg->Buffer; pStubMsg->IgnoreEmbeddedPointers = fOldIgnore; pStubMsg->Buffer = pBuffer; } BOOL IsFixed = ( pArrayFormat->FormatCode == FC64_FIX_BOGUS_ARRAY ) || ( pArrayFormat->FormatCode == FC64_FIX_FORCED_BOGUS_ARRAY ); SAVE_CONTEXT uFlagsSave(pStubMsg->uFlags); SAVE_CONTEXT ConformanceMarkSave( pStubMsg->ConformanceMark ); SAVE_CONTEXT VarianceMarkSave( pStubMsg->VarianceMark ); PFORMAT_STRING pElementFormat = (PFORMAT_STRING)pArrayFormat->Element; NDR64_WIRE_COUNT_TYPE Elements = pArrayFormat->NumberElements; NDR64_WIRE_COUNT_TYPE Count = Elements; NDR64_WIRE_COUNT_TYPE Offset = 0; if ( !IsFixed ) { const NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT* pConfVarFormat= (NDR64_CONF_VAR_BOGUS_ARRAY_HEADER_FORMAT*)pFormat; // // Check for conformance description. // if ( pConfVarFormat->ConfDescription ) { if ( ! NDR64_IS_CONF_MARK_VALID( pStubMsg->uFlags ) ) { // // Outer most dimension sets the conformance marker. // // Align the buffer for conformance marshalling. ALIGN(pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN); // Mark where the conformance count(s) will be marshalled. pStubMsg->ConformanceMark = pStubMsg->Buffer; // Increment past where the conformance will go. pStubMsg->Buffer += pArrayFormat->NumberDims * sizeof(NDR64_WIRE_COUNT_TYPE); NDR64_SET_CONF_MARK_VALID( pStubMsg->uFlags ); } Elements = *(NDR64_WIRE_COUNT_TYPE*)pStubMsg->ConformanceMark; pStubMsg->ConformanceMark += sizeof(NDR64_WIRE_COUNT_TYPE); Ndr64pCheckCorrelation( pStubMsg, Elements, pConfVarFormat->ConfDescription, EXPR_MAXCOUNT ); Offset = 0; Count = Elements; } // // Check for variance description. // if ( pConfVarFormat->VarDescription ) { if ( ! NDR64_IS_VAR_MARK_VALID( pStubMsg->uFlags ) ) { NDR64_UINT32 Dimensions; ALIGN(pStubMsg->Buffer, NDR64_WIRE_COUNT_ALIGN ); Dimensions = ( pArrayFormat->Flags.IsArrayofStrings ) ? ( pArrayFormat->NumberDims - 1) : ( pArrayFormat->NumberDims ); pStubMsg->VarianceMark = pStubMsg->Buffer; pStubMsg->Buffer += Dimensions * sizeof(NDR64_WIRE_COUNT_TYPE) * 2; if ( NDR64_IS_ARRAY_OR_STRING( *pElementFormat ) ) NDR64_SET_VAR_MARK_VALID( pStubMsg->uFlags ); } else if ( !NDR64_IS_ARRAY_OR_STRING( *pElementFormat ) ) NDR64_RESET_VAR_MARK_VALID( pStubMsg->uFlags ); Offset = ((NDR64_WIRE_COUNT_TYPE*)pStubMsg->VarianceMark)[0]; Count = ((NDR64_WIRE_COUNT_TYPE*)pStubMsg->VarianceMark)[1]; pStubMsg->VarianceMark += sizeof(NDR64_WIRE_COUNT_TYPE) * 2; Ndr64pCheckCorrelation( pStubMsg, Count, pConfVarFormat->VarDescription, EXPR_ACTUALCOUNT ); Ndr64pCheckCorrelation( pStubMsg, Offset, pConfVarFormat->OffsetDescription, EXPR_OFFSET ); } } NDR64_UINT32 ElementMemorySize = Ndr64pMemorySize( pStubMsg, pElementFormat, TRUE ); NDR64_UINT32 ArraySize = Ndr64pConvertTo2GB( Elements * (NDR64_UINT64)ElementMemorySize ); Ndr64pConvertTo2GB( Count * (NDR64_UINT64)ElementMemorySize ); if ( fMustAlloc || ! *ppMemory ) { *ppMemory = (uchar*)NdrAllocate( pStubMsg, (uint) ArraySize ); memset( *ppMemory, 0, ArraySize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } if ( pStubMsg->FullPtrRefId ) FULL_POINTER_INSERT( pStubMsg, *ppMemory ); uchar *pMemory = *ppMemory; pMemory += Ndr64pConvertTo2GB(Offset * (NDR64_UINT64)ElementMemorySize); ALIGN(pStubMsg->Buffer, pArrayFormat->Alignment); for( ; Count--; ) { Ndr64EmbeddedTypeUnmarshall( pStubMsg, &pMemory, pElementFormat ); pMemory += ElementMemorySize; } if ( fSetPointerBufferMark ) { pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = 0; } } void Ndr64UnionUnmarshall ( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) /*++ Routine Description : Unmarshalls an encapsulated array. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Double pointer to where the union should be unmarshalled. pFormat - Union's format string description. fMustAlloc - Ignored. Return : None. --*/ { const NDR64_UNION_ARM_SELECTOR* pArmSelector; SAVE_CONTEXT uFlagsSave( pStubMsg->uFlags ); EXPR_VALUE SwitchIs; uchar* pArmMemory; switch(*(PFORMAT_STRING)pFormat) { case FC64_NON_ENCAPSULATED_UNION: { const NDR64_NON_ENCAPSULATED_UNION* pNonEncapUnionFormat = (const NDR64_NON_ENCAPSULATED_UNION*) pFormat; ALIGN(pStubMsg->Buffer, pNonEncapUnionFormat->Alignment); pArmSelector = (NDR64_UNION_ARM_SELECTOR*)(pNonEncapUnionFormat + 1); if ( fMustAlloc || ! *ppMemory ) { *ppMemory = (uchar*)NdrAllocate( pStubMsg, pNonEncapUnionFormat->MemorySize ); // // We must zero out all of the new memory in case there are pointers // in any of the arms. // MIDL_memset( *ppMemory, 0, pNonEncapUnionFormat->MemorySize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } SwitchIs = Ndr64pSimpleTypeToExprValue( pNonEncapUnionFormat->SwitchType, pStubMsg->Buffer ); pStubMsg->Buffer += NDR64_SIMPLE_TYPE_BUFSIZE( pNonEncapUnionFormat->SwitchType ); Ndr64pCheckCorrelation( pStubMsg, SwitchIs, pNonEncapUnionFormat->Switch, EXPR_SWITCHIS ); pArmMemory = *ppMemory; break; } case FC64_ENCAPSULATED_UNION: { const NDR64_ENCAPSULATED_UNION* pEncapUnionFormat = (const NDR64_ENCAPSULATED_UNION*)pFormat; ALIGN(pStubMsg->Buffer, pEncapUnionFormat->Alignment); pArmSelector = (NDR64_UNION_ARM_SELECTOR*)(pEncapUnionFormat + 1); if ( fMustAlloc || ! *ppMemory ) { *ppMemory = (uchar*)NdrAllocate( pStubMsg, pEncapUnionFormat->MemorySize ); // // We must zero out all of the new memory in case there are pointers // in any of the arms. // MIDL_memset( *ppMemory, 0, pEncapUnionFormat->MemorySize ); NDR64_SET_NEW_EMBEDDED_ALLOCATION(pStubMsg->uFlags); } SwitchIs = Ndr64pSimpleTypeToExprValue( pEncapUnionFormat->SwitchType, pStubMsg->Buffer ); Ndr64SimpleTypeUnmarshall( pStubMsg, *ppMemory, pEncapUnionFormat->SwitchType ); pArmMemory = *ppMemory + pEncapUnionFormat->MemoryOffset; break; } default: NDR_ASSERT("Bad union format\n", 0); return; } if ( pStubMsg->FullPtrRefId ) FULL_POINTER_INSERT( pStubMsg, *ppMemory ); ALIGN(pStubMsg->Buffer, pArmSelector->Alignment); PNDR64_FORMAT pArmFormat = Ndr64pFindUnionArm( pStubMsg, pArmSelector, SwitchIs ); // check we aren't EOB after unmarshalling arm selector // we won't corrupt memory as there is no in place unmarshall here. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer ); if ( pArmFormat ) { Ndr64EmbeddedTypeUnmarshall( pStubMsg, &pArmMemory, pArmFormat ); } } void Ndr64XmitOrRepAsUnmarshall ( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool /*fMustAlloc*/, bool bIsEmbedded ) /*++ Routine Description : Unmarshalls a transmit as (or represent as)object. Means: allocate the transmitted object, unmarshall transmitted object, translate the transmitted into presented free the transmitted. See mrshl.c for the description of the FC layout. Arguments : pStubMsg - a pointer to the stub message ppMemory - pointer to the presented type where to put data pFormat - format string description fMustAlloc - allocate flag Note. fMustAlloc is ignored as we always allocate outside of the buffer. --*/ { unsigned char * pPresentedType = *ppMemory; const XMIT_ROUTINE_QUINTUPLE * pQuintuple = pStubMsg->StubDesc->aXmitQuintuple; NDR64_TRANSMIT_AS_FORMAT *pTransFormat = ( NDR64_TRANSMIT_AS_FORMAT *) pFormat; NDR_ASSERT( pTransFormat->FormatCode == FC64_TRANSMIT_AS || pTransFormat->FormatCode , "invalid format string for user marshal" ); unsigned short QIndex = pTransFormat->RoutineIndex; unsigned long PresentedTypeSize = pTransFormat->PresentedTypeMemorySize; if ( ! pPresentedType ) { pPresentedType = (uchar*)NdrAllocate( pStubMsg, (uint) PresentedTypeSize ); MIDL_memset( pPresentedType, 0, (uint) PresentedTypeSize ); } // Allocate the transmitted object outside of the buffer // and unmarshall into it if ( NDR64_IS_SIMPLE_TYPE( *(PFORMAT_STRING)pTransFormat->TransmittedType )) { __int64 SimpleTypeValueBuffer[2]; unsigned char * pTransmittedType = (unsigned char *)SimpleTypeValueBuffer; Ndr64SimpleTypeUnmarshall( pStubMsg, pTransmittedType, *(PFORMAT_STRING)pTransFormat->TransmittedType ); // Translate from the transmitted type into the presented type. pStubMsg->pTransmitType = pTransmittedType; pStubMsg->pPresentedType = pPresentedType; pQuintuple[ QIndex ].pfnTranslateFromXmit( pStubMsg ); *ppMemory = pStubMsg->pPresentedType; } else { // Save the current state of the memory list so that the temporary // memory allocated for the transmitted type can be easily removed // from the list. This assumes that the memory allocated here // will not have any linkes to other blocks of memory. This is true // as long as full pointers are not used. Fortunatly, full pointers // do not work correctly in the current code. void *pMemoryListSave = pStubMsg->pMemoryList; unsigned char *pTransmittedType = NULL; // asking the engine to allocate // In NDR64, Xmit/Rep cannot be a pointer or contain a pointer. // So we don't need to worry about the pointer queue here. if ( bIsEmbedded ) { Ndr64EmbeddedTypeUnmarshall( pStubMsg, &pTransmittedType, pTransFormat->TransmittedType ); } else { Ndr64TopLevelTypeUnmarshall( pStubMsg, &pTransmittedType, pTransFormat->TransmittedType, TRUE ); } // Translate from the transmitted type into the presented type. pStubMsg->pTransmitType = pTransmittedType; pStubMsg->pPresentedType = pPresentedType; pQuintuple[ QIndex ].pfnTranslateFromXmit( pStubMsg ); *ppMemory = pStubMsg->pPresentedType; // Free the transmitted object (it was allocated by the engine) // and its pointees. The call through the table frees the pointees // only (plus it'd free the object itself if it were a pointer). // As the transmitted type is not a pointer here, we need to free it // explicitely later. // Remove the memory that will be freed from the allocated memory // list by restoring the memory list pointer. // If an exception occures during one of these free routines, we // are in trouble anyway. pStubMsg->pMemoryList = pMemoryListSave; if ( bIsEmbedded ) { Ndr64EmbeddedTypeFree( pStubMsg, pTransmittedType, pTransFormat->TransmittedType ); } else { Ndr64ToplevelTypeFree( pStubMsg, pTransmittedType, pTransFormat->TransmittedType ); } // The buffer reusage check. if ( pTransmittedType < pStubMsg->BufferStart || pTransmittedType > pStubMsg->BufferEnd ) (*pStubMsg->pfnFree)( pTransmittedType ); } } void Ndr64TopLevelXmitOrRepAsUnmarshall ( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) { Ndr64XmitOrRepAsUnmarshall( pStubMsg, ppMemory, pFormat, fMustAlloc, false ); } void Ndr64EmbeddedXmitOrRepAsUnmarshall ( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) { Ndr64XmitOrRepAsUnmarshall( pStubMsg, ppMemory, pFormat, fMustAlloc, true ); } void Ndr64UserMarshallUnmarshallInternal( PMIDL_STUB_MESSAGE pStubMsg, uchar * pMemory, PNDR64_FORMAT pFormat ) { NDR64_USER_MARSHAL_FORMAT *pUserFormat = ( NDR64_USER_MARSHAL_FORMAT *) pFormat; unsigned char * pUserBuffer = pStubMsg->Buffer; unsigned char * pUserBufferSaved = pUserBuffer; USER_MARSHAL_CB UserMarshalCB; Ndr64pInitUserMarshalCB( pStubMsg, pUserFormat, USER_MARSHAL_CB_UNMARSHALL, & UserMarshalCB ); unsigned short QIndex = pUserFormat->RoutineIndex; const USER_MARSHAL_ROUTINE_QUADRUPLE * pQuadruple = (const USER_MARSHAL_ROUTINE_QUADRUPLE * ) ( ( NDR_PROC_CONTEXT *)pStubMsg->pContext )->pSyntaxInfo->aUserMarshalQuadruple; if ((pUserBufferSaved < (uchar *) pStubMsg->RpcMsg->Buffer) || ((unsigned long) (pUserBufferSaved - (uchar *) pStubMsg->RpcMsg->Buffer) > pStubMsg->RpcMsg->BufferLength)) { RpcRaiseException( RPC_X_INVALID_BUFFER ); } pUserBuffer = pQuadruple[ QIndex ].pfnUnmarshall( (ulong*) &UserMarshalCB, pUserBuffer, pMemory ); if ((pUserBufferSaved > pUserBuffer) || ((unsigned long) (pUserBuffer - (uchar *) pStubMsg->RpcMsg->Buffer) > pStubMsg->RpcMsg->BufferLength )) { RpcRaiseException( RPC_X_INVALID_BUFFER ); } // Step over the pointee. pStubMsg->Buffer = pUserBuffer; } void NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT::Dispatch(MIDL_STUB_MESSAGE *pStubMsg) { Ndr64UserMarshallUnmarshallInternal( pStubMsg, pMemory, pFormat ); } #if defined(DBG) void NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT::Print() { DbgPrint("NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT\n"); DbgPrint("pMemory: %p\n", pMemory ); DbgPrint("pFormat: %p\n", pFormat ); } #endif void Ndr64UserMarshallPointeeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, uchar * pMemory, PNDR64_FORMAT pFormat ) { if ( !pStubMsg->pPointerQueueState || !pStubMsg->pPointerQueueState->GetActiveQueue() ) { POINTER_BUFFER_SWAP_CONTEXT SwapContext(pStubMsg); Ndr64UserMarshallUnmarshallInternal( pStubMsg, pMemory, pFormat ); return; } NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT*pElement = new(pStubMsg->pPointerQueueState) NDR64_USR_MRSHL_UNMRSHL_POINTER_QUEUE_ELEMENT(pMemory, (PFORMAT_STRING)pFormat ); pStubMsg->pPointerQueueState->GetActiveQueue()->Enque( pElement ); } void Ndr64UserMarshalUnmarshall ( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc, bool bIsEmbedded ) /*++ Routine Description : Unmarshals a user_marshal object. The layout is described in marshalling. Arguments : pStubMsg - Pointer to the stub message. ppMemory - Pointer to pointer to the usr_marshall object to unmarshall. pFormat - Object's format string description. Return : None. --*/ { NDR64_USER_MARSHAL_FORMAT *pUserFormat = ( NDR64_USER_MARSHAL_FORMAT *) pFormat; NDR_ASSERT( pUserFormat->FormatCode == FC64_USER_MARSHAL, "invalid format string for user marshal" ); // Align for the object or a pointer to it. ALIGN( pStubMsg->Buffer, pUserFormat->TransmittedTypeWireAlignment ); // Take care of the pointer, if any. NDR64_PTR_WIRE_TYPE PointerMarker; if ( ( pUserFormat->Flags & USER_MARSHAL_UNIQUE) || (( pUserFormat->Flags & USER_MARSHAL_REF) && bIsEmbedded) ) { PointerMarker = *((NDR64_PTR_WIRE_TYPE *)pStubMsg->Buffer); pStubMsg->Buffer += sizeof(NDR64_PTR_WIRE_TYPE); } // We always call user's routine to unmarshall the user object. // However, the top level object is allocated by the engine. // Thus, the behavior is exactly the same as for represent_as(), // with regard to the top level presented type. if ( *ppMemory == NULL ) { // Allocate a presented type object first. uint MemSize = pUserFormat->UserTypeMemorySize; *ppMemory = (uchar *) NdrAllocate( pStubMsg, MemSize ); MIDL_memset( *ppMemory, 0, MemSize ); } if ( ( pUserFormat->Flags & USER_MARSHAL_UNIQUE) && (0 == PointerMarker )) { // The user type is a unique pointer, and it is 0. So, we are done. return; } if ( pUserFormat->Flags & USER_MARSHAL_POINTER ) { Ndr64UserMarshallPointeeUnmarshall( pStubMsg, *ppMemory, pFormat ); return; } Ndr64UserMarshallUnmarshallInternal( pStubMsg, *ppMemory, pFormat ); } void Ndr64TopLevelUserMarshalUnmarshall ( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) { Ndr64UserMarshalUnmarshall( pStubMsg, ppMemory, pFormat, fMustAlloc, false ); } void Ndr64EmbeddedUserMarshalUnmarshall ( PMIDL_STUB_MESSAGE pStubMsg, uchar ** ppMemory, PNDR64_FORMAT pFormat, bool fMustAlloc ) { Ndr64UserMarshalUnmarshall( pStubMsg, ppMemory, pFormat, fMustAlloc, true ); } void Ndr64ClientContextUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, NDR_CCONTEXT * pContextHandle, RPC_BINDING_HANDLE BindHandle ) /*++ Routine Description : Unmarshalls a context handle on the client side. Arguments : pStubMsg - Pointer to stub message. pContextHandle - Pointer to context handle to unmarshall. BindHandle - The handle value used by the client for binding. Return : None. --*/ { // Note, this is a routine called directly from -Os stubs. // The routine called by interpreter is called Ndr64UnmarshallHandle // and can be found in hndl.c ALIGN(pStubMsg->Buffer,3); // All 20 bytes of the buffer are touched so a check is not needed here. CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + CONTEXT_HANDLE_WIRE_SIZE ); NDRCContextUnmarshall( pContextHandle, BindHandle, pStubMsg->Buffer, pStubMsg->RpcMsg->DataRepresentation ); pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE; } NDR_SCONTEXT Ndr64ServerContextUnmarshall( PMIDL_STUB_MESSAGE pStubMsg ) /*++ Routine Description : Unmarshalls a context handle on the server side. Arguments : pStubMsg - Pointer to stub message. Return : The unmarshalled context handle. --*/ { // Note, this is a routine called directly from -Os stubs. // The routine called by interpreter is called Ndr64UnmarshallHandle // and can be found in hndl.c NDR_SCONTEXT Context; ALIGN(pStubMsg->Buffer,3); // All 20 bytes of the buffer are touched so a check is not needed here. // we could corrupt memory if it's out of bound CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + CONTEXT_HANDLE_WIRE_SIZE ); Context = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, pStubMsg->Buffer, pStubMsg->RpcMsg->DataRepresentation, RPC_CONTEXT_HANDLE_DEFAULT_GUARD, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS ); if ( ! Context ) RpcRaiseException( RPC_X_SS_CONTEXT_MISMATCH ); pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE; return Context; } NDR_SCONTEXT Ndr64ContextHandleInitialize ( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) /* This routine is to initialize a context handle with a new NT5 flavor. It is used in conjunction with Ndr64ContextHandleUnmarshal. */ { NDR_SCONTEXT SContext; void * pGuard = RPC_CONTEXT_HANDLE_DEFAULT_GUARD; DWORD Flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS; NDR64_CONTEXT_HANDLE_FORMAT * pContextFormat; pContextFormat = ( NDR64_CONTEXT_HANDLE_FORMAT * )pFormat; NDR_ASSERT( pContextFormat->FormatCode == FC64_BIND_CONTEXT, "invalid format char " ); // NT5 beta2 features: strict context handle, serialize and noserialize. if ( pContextFormat->ContextFlags & NDR_STRICT_CONTEXT_HANDLE ) { pGuard = pStubMsg->StubDesc->RpcInterfaceInformation; pGuard = & ((PRPC_SERVER_INTERFACE)pGuard)->InterfaceId; } if ( pContextFormat->ContextFlags & NDR_CONTEXT_HANDLE_NOSERIALIZE ) { Flags = RPC_CONTEXT_HANDLE_DONT_SERIALIZE; } else if ( pContextFormat->ContextFlags & NDR_CONTEXT_HANDLE_SERIALIZE ) { Flags = RPC_CONTEXT_HANDLE_SERIALIZE; } SContext = NDRSContextUnmarshall2( pStubMsg->RpcMsg->Handle, (void *)0, // buffer pStubMsg->RpcMsg->DataRepresentation, pGuard, Flags ); return SContext; } NDR_SCONTEXT Ndr64ServerContextNewUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) /* This routine to unmarshal a context handle with a new NT5 flavor. For the old style handles, we call an optimized routine Ndr64ServerContextUnmarshall below. Interpreter calls Ndr64UnmarshallHandle from hndl.c ppMemory - note, this is not a pointer to user's context handle but a pointer to NDR_SCONTEXT pointer to the runtime internal object. User's handle is a field of that object. */ { void * pGuard = RPC_CONTEXT_HANDLE_DEFAULT_GUARD; DWORD Flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS; NDR64_CONTEXT_HANDLE_FORMAT *pContextFormat = ( NDR64_CONTEXT_HANDLE_FORMAT * )pFormat; NDR_ASSERT( pContextFormat->FormatCode == FC64_BIND_CONTEXT, "invalid format char " ); // Anti-attack defense for servers, NT5 beta3 feature. if ( pContextFormat->ContextFlags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL ) { // Check the incoming context handle on the server. // Context handle wire layout: ulong with version (always 0), then a uuid. // if ( !pStubMsg->IsClient && 0 == memcmp( pStubMsg->Buffer + 4, &GUID_NULL, sizeof(GUID) ) ) RpcRaiseException( RPC_X_BAD_STUB_DATA ); } // NT5 beta2 features: strict context handle, serialize and noserialize. if ( pContextFormat->ContextFlags & NDR_STRICT_CONTEXT_HANDLE ) { pGuard = pStubMsg->StubDesc->RpcInterfaceInformation; pGuard = & ((PRPC_SERVER_INTERFACE)pGuard)->InterfaceId; } if ( pContextFormat->ContextFlags & NDR_CONTEXT_HANDLE_NOSERIALIZE ) { Flags = RPC_CONTEXT_HANDLE_DONT_SERIALIZE; } else if ( pContextFormat->ContextFlags & NDR_CONTEXT_HANDLE_SERIALIZE ) { Flags = RPC_CONTEXT_HANDLE_SERIALIZE; } ALIGN( pStubMsg->Buffer, 0x3 ); // All 20 bytes of the buffer are touched so a check is not needed here. NDR_SCONTEXT SContext = NDRSContextUnmarshall2( pStubMsg->RpcMsg->Handle, pStubMsg->Buffer, pStubMsg->RpcMsg->DataRepresentation, pGuard, Flags ); if ( ! SContext ) RpcRaiseException( RPC_X_SS_CONTEXT_MISMATCH ); pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE; return SContext; } // define the jump table #define NDR64_BEGIN_TABLE \ PNDR64_UNMARSHALL_ROUTINE extern const Ndr64UnmarshallRoutinesTable[] = \ { #define NDR64_TABLE_END \ }; #define NDR64_ZERO_ENTRY NULL #define NDR64_UNUSED_TABLE_ENTRY( number, tokenname ) ,NULL #define NDR64_UNUSED_TABLE_ENTRY_NOSYM( number ) ,NULL #define NDR64_TABLE_ENTRY( number, tokenname, marshall, embeddedmarshall, unmarshall, embeddedunmarshall, buffersize, embeddedbuffersize, memsize, embeddedmemsize, free, embeddedfree, typeflags ) \ ,unmarshall #define NDR64_SIMPLE_TYPE_TABLE_ENTRY( number, tokenname, buffersize, memorysize) \ ,Ndr64UDTSimpleTypeUnmarshall1 #include "tokntbl.h" C_ASSERT( sizeof(Ndr64UnmarshallRoutinesTable)/sizeof(PNDR64_UNMARSHALL_ROUTINE) == 256 ); #undef NDR64_BEGIN_TABLE #undef NDR64_TABLE_ENTRY #define NDR64_BEGIN_TABLE \ PNDR64_UNMARSHALL_ROUTINE extern const Ndr64EmbeddedUnmarshallRoutinesTable[] = \ { #define NDR64_TABLE_ENTRY( number, tokenname, marshall, embeddedmarshall, unmarshall, embeddedunmarshall, buffersize, embeddedbuffersize, memsize, embeddedmemsize, free, embeddedfree, typeflags ) \ ,embeddedunmarshall #include "tokntbl.h" C_ASSERT( sizeof(Ndr64EmbeddedUnmarshallRoutinesTable)/sizeof(PNDR64_UNMARSHALL_ROUTINE) == 256 );