You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2762 lines
85 KiB
2762 lines
85 KiB
/**********************************************************************
|
|
|
|
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(NULL);
|
|
}
|
|
|
|
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<ulong> 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<uchar> 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<NDR_ALLOC_ALL_NODES_CONTEXT*>
|
|
AllocNodesSave(pStubMsg->pAllocAllNodesContext,pAllocAllNodesContext );
|
|
FINDONTFREE_CONTEXT fInDoneFreeSave( pStubMsg, fInDontFree );
|
|
SAVE_CONTEXT<uchar> 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<uchar> 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<uchar> 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 = pStructFormat->MemorySize + Ndr64pMultiplyUpTo2GB(
|
|
MaxCount , 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<uchar*> ConformanceMarkSave( pStubMsg->ConformanceMark );
|
|
SAVE_CONTEXT<uchar> 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_WITH_WRAP_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 =
|
|
Ndr64pMultiplyUpTo2GB( Count, pStringFormat->ElementSize );
|
|
|
|
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 + Ndr64pMultiplyUpTo2GB( 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 =
|
|
Ndr64pMultiplyUpTo2GB( MaxCount ,
|
|
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<uchar> uFlagsSave( pStubMsg->uFlags );
|
|
|
|
ALIGN(pStubMsg->Buffer, pArrayFormat->Alignment );
|
|
|
|
uchar *pBufferStart = pStubMsg->Buffer;
|
|
|
|
CHECK_EOB_WITH_WRAP_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<uchar> 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 =
|
|
Ndr64pMultiplyUpTo2GB( MaxCount , 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<uchar> 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 = Ndr64pMultiplyUpTo2GB( MaxCount , pArrayFormat->ElementSize );
|
|
NDR64_UINT32 CopySize = Ndr64pMultiplyUpTo2GB( ActualCount , 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<uchar> 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
|
|
= Ndr64pMultiplyUpTo2GB( ActualCount , 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<uchar> uFlagsSave(pStubMsg->uFlags);
|
|
SAVE_CONTEXT<uchar*> ConformanceMarkSave( pStubMsg->ConformanceMark );
|
|
SAVE_CONTEXT<uchar*> 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.
|
|
NDR64_UINT32 ConfSize = pArrayFormat->NumberDims*sizeof(NDR64_WIRE_COUNT_TYPE) ;
|
|
CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, ConfSize);
|
|
pStubMsg->Buffer += ConfSize;
|
|
|
|
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;
|
|
|
|
NDR64_UINT32 VaryingSize = Dimensions * sizeof(NDR64_WIRE_COUNT_TYPE) * 2 ;
|
|
CHECK_EOB_WITH_WRAP_RAISE_BSD( pStubMsg->Buffer, VaryingSize);
|
|
pStubMsg->Buffer += VaryingSize;
|
|
|
|
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 = Ndr64pMultiplyUpTo2GB( Elements , ElementMemorySize );
|
|
Ndr64pMultiplyUpTo2GB( Count , 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 += Ndr64pMultiplyUpTo2GB(Offset , 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<uchar> 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);
|
|
|
|
// 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;
|
|
|
|
ALIGN( pStubMsg->Buffer, 0x3 );
|
|
|
|
// we might corrupt the memory during the byte swap
|
|
CHECK_EOB_RAISE_BSD( pStubMsg->Buffer + CONTEXT_HANDLE_WIRE_SIZE );
|
|
|
|
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;
|
|
}
|
|
|
|
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 );
|