Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1049 lines
27 KiB

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1993 - 1999 Microsoft Corporation
Module Name :
free.c
Abstract :
This file contains the routines called by MIDL 2.0 stubs and the
interpreter for freeing unmarshalled data on the server.
Author :
David Kays dkays September 1993.
Revision History :
---------------------------------------------------------------------*/
#include "precomp.hxx"
#include "..\..\ndr20\ndrole.h"
__forceinline void
Ndr64FreeTypeMemory(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory )
{
if ( !pStubMsg->pPointerQueueState ||
!pStubMsg->pPointerQueueState->GetActiveQueue() )
{
(*pStubMsg->pfnFree)(pMemory);
return;
}
NDR_PFNFREE_POINTER_QUEUE_ELEMENT*pElement =
new(pStubMsg->pPointerQueueState)
NDR_PFNFREE_POINTER_QUEUE_ELEMENT(pStubMsg->pfnFree,
pMemory );
pStubMsg->pPointerQueueState->GetActiveQueue()->Enque( pElement );
}
NDR64_FREE_POINTER_QUEUE_ELEMENT::NDR64_FREE_POINTER_QUEUE_ELEMENT(
MIDL_STUB_MESSAGE *pStubMsg,
uchar * const pMemoryNew,
const PFORMAT_STRING pFormatNew) :
pMemory(pMemoryNew),
pFormat(pFormatNew),
uFlags(pStubMsg->uFlags),
pCorrMemory(pStubMsg->pCorrMemory)
{
}
void
NDR64_FREE_POINTER_QUEUE_ELEMENT::Dispatch(
MIDL_STUB_MESSAGE *pStubMsg)
{
SAVE_CONTEXT<uchar> uFlagsSave( pStubMsg->uFlags, uFlags );
CORRELATION_CONTEXT CorrContext( pStubMsg, pCorrMemory );
Ndr64ToplevelTypeFree( pStubMsg,
pMemory,
pFormat );
}
#if defined(DBG)
void
NDR64_FREE_POINTER_QUEUE_ELEMENT::Print()
{
DbgPrint("NDR_FREE_POINTER_QUEUE_ELEMENT\n");
DbgPrint("pNext: %p\n", pNext );
DbgPrint("pMemory: %p\n", pMemory );
DbgPrint("pFormat: %p\n", pFormat );
DbgPrint("uFlags: %x\n", uFlags );
DbgPrint("pCorrMemory: %p\n", pCorrMemory );
}
#endif
void
Ndr64EnquePointeeFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
{
NDR64_POINTER_CONTEXT PointerContext( pStubMsg );
RpcTryFinally
{
NDR64_FREE_POINTER_QUEUE_ELEMENT*pElement =
new(PointerContext.GetActiveState())
NDR64_FREE_POINTER_QUEUE_ELEMENT(pStubMsg,
(uchar*)pMemory,
(PFORMAT_STRING)pFormat);
PointerContext.Enque( pElement );
PointerContext.DispatchIfRequired();
}
RpcFinally
{
PointerContext.EndContext();
}
RpcEndFinally
}
__forceinline void
Ndr64PointeeFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
{
SAVE_CONTEXT<uchar> uFlagsSave( pStubMsg->uFlags );
NDR64_RESET_EMBEDDED_FLAGS_TO_STANDALONE(pStubMsg->uFlags);
if ( !NdrIsLowStack( pStubMsg ) )
{
Ndr64ToplevelTypeFree( pStubMsg,
pMemory,
pFormat );
return;
}
Ndr64EnquePointeeFree(
pStubMsg,
pMemory,
pFormat );
}
void
Ndr64pNoopFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
{
return;
}
__forceinline void
Ndr64PointerFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a top level or embedded pointer to anything.
Used for FC64_RP, FC64_UP, FC64_FP, FC64_OP.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_POINTER_FORMAT *pPointerFormat = (NDR64_POINTER_FORMAT*) pFormat;
uchar * pMemoryPointee = pMemory;
if ( ! pMemory )
return;
if ( *(PFORMAT_STRING)pFormat == FC64_IP )
{
((IUnknown *)pMemory)->Release();
return;
}
if ( *(PFORMAT_STRING)pFormat == FC64_FP )
{
//
// Check if we've already freed this full pointer.
//
if ( ! NdrFullPointerFree( pStubMsg->FullPtrXlatTables,
pMemory ) )
return;
}
if ( 0 == pPointerFormat->Flags )
goto FreeEmbeddedPointers;
//
// Check if this pointer and any possible embedded pointers should not
// be freed.
//
if ( NDR64_DONT_FREE( pPointerFormat->Flags) )
return;
//
// Just go free a pointer to a simple type.
//
if ( NDR64_SIMPLE_POINTER( pPointerFormat->Flags ) )
goto FreeTopPointer;
//
// Check if this is an allocate all nodes pointer.
// IDL symantics say that we only free the top most allocate all nodes
// pointer on the server even in the [out] only case. So jump to the
// check for the pointer free at the end of the routine.
//
if ( NDR64_ALLOCATE_ALL_NODES( pPointerFormat->Flags ) )
goto FreeTopPointer;
if ( NDR64_POINTER_DEREF( pPointerFormat->Flags ) )
pMemoryPointee = *((uchar **)pMemory);
FreeEmbeddedPointers:
Ndr64PointeeFree( pStubMsg,
pMemoryPointee,
pPointerFormat->Pointee );
FreeTopPointer:
//
// Now free the pointer. Pointer guaranteed to be non-null here.
//
// We only free the pointer if it lies outside of the message buffer
// that the server stub received from the RPC runtime. Otherwise we
// used the RPC buffer to hold the pointer's data and should not free it.
//
if ( (pMemory < pStubMsg->BufferStart) || (pMemory > pStubMsg->BufferEnd) )
{
//
// Also check to make sure that the pointer was not allocated on the
// server stub's stack (this may happen for ref pointers).
//
// full pointer can't be allocated on stack
if ( ! NDR64_ALLOCED_ON_STACK( pPointerFormat->Flags ) ||
*(PFORMAT_STRING)pFormat == FC64_FP )
{
Ndr64FreeTypeMemory( pStubMsg, pMemory );
}
}
}
__forceinline void
Ndr64TopLevelPointerFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a top level or embedded pointer to anything.
Used for FC64_RP, FC64_UP, FC64_FP, FC64_OP.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
Ndr64PointerFree( pStubMsg,
pMemory,
pFormat );
}
__forceinline void
Ndr64EmbeddedPointerFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
{
Ndr64PointerFree( pStubMsg,
*(uchar**)pMemory,
pFormat );
}
void
Ndr64pRangeFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
--*/
{
return;
}
void
Ndr64SimpleStructFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a simple structure's embedded pointers which were allocated during
a remote call.
Used for FC64_STRUCT and FC64_PSTRUCT.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_STRUCTURE_HEADER_FORMAT * const pStructFormat =
(NDR64_STRUCTURE_HEADER_FORMAT*) pFormat;
if ( !pMemory || !pStructFormat->Flags.HasPointerInfo )
return;
CORRELATION_CONTEXT CorrCtxt( pStubMsg, pMemory );
Ndr64pPointerLayoutFree( pStubMsg,
pStructFormat + 1,
0,
pMemory );
}
void
Ndr64ConformantStructFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a conformant structure's embedded pointers which were allocated
during a remote call.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
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;
if ( !pMemory || !pStructFormat->Flags.HasPointerInfo )
return;
CORRELATION_CONTEXT CorrCtxt( pStubMsg, pMemory );
NDR64_UINT32 MaxCount = (NDR64_UINT32)
Ndr64EvaluateExpr( pStubMsg,
pArrayFormat->ConfDescriptor,
EXPR_MAXCOUNT );
Ndr64pPointerLayoutFree( pStubMsg,
pStructFormat + 1,
MaxCount,
pMemory );
}
void
Ndr64ComplexStructFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a complex structure's embedded pointers which were allocated during
a remote call.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
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;
PFORMAT_STRING pFormatPointers = (PFORMAT_STRING)(pStructFormat->PointerLayout );
PFORMAT_STRING pFormatArray = NULL;
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);
if ( !pMemory )
return;
CORRELATION_CONTEXT CorrCtxt( pStubMsg, pMemory );
if ( pStructFormat->Flags.HasConfArray )
{
pFormatArray = (PFORMAT_STRING)pConfStructFormat->ConfArrayDescription;
}
for ( ; ; )
{
switch ( *pMemberLayout )
{
case FC64_STRUCT:
{
const NDR64_SIMPLE_REGION_FORMAT *pRegion =
(NDR64_SIMPLE_REGION_FORMAT*) pMemberLayout;
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 :
Ndr64EmbeddedPointerFree( 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;
Ndr64EmbeddedTypeFree( pStubMsg,
pMemory,
pEmbeddedFormat->Type );
pMemory = Ndr64pMemoryIncrement( pStubMsg,
pMemory,
pEmbeddedFormat->Type,
FALSE );
pMemberLayout += sizeof( *pEmbeddedFormat );
break;
}
case FC64_BUFFER_ALIGN:
{
const NDR64_BUFFER_ALIGN_FORMAT *pBufAlign =
(NDR64_BUFFER_ALIGN_FORMAT*) pMemberLayout;
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:
pMemory += NDR64_SIMPLE_TYPE_MEMSIZE(*pMemberLayout);
pMemberLayout += sizeof(NDR64_SIMPLE_MEMBER_FORMAT);
break;
case FC64_IGNORE :
pMemory += PTR_MEM_SIZE;
pMemberLayout += sizeof(NDR64_SIMPLE_MEMBER_FORMAT);
break;
case FC64_END :
goto ComplexFreeEnd;
default :
NDR_ASSERT(0,"Ndr64ComplexStructFree : bad format char");
RpcRaiseException( RPC_S_INTERNAL_ERROR );
return;
} // switch
} // for
ComplexFreeEnd :
if ( pFormatArray )
{
Ndr64EmbeddedTypeFree( pStubMsg,
pMemory,
pFormatArray );
}
}
void
Ndr64FixedArrayFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a fixed array's embedded pointers which were allocated during
a remote call.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_FIX_ARRAY_HEADER_FORMAT * pArrayFormat =
(NDR64_FIX_ARRAY_HEADER_FORMAT*) pFormat;
if ( ! pMemory || !pArrayFormat->Flags.HasPointerInfo )
return;
Ndr64pPointerLayoutFree( pStubMsg,
pArrayFormat + 1,
0,
pMemory );
}
void
Ndr64ConformantArrayFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a one dimensional conformant array's embedded pointers which were
allocated during a remote call. Called for both top level and embedded
conformant arrays.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_CONF_ARRAY_HEADER_FORMAT *pArrayFormat =
(NDR64_CONF_ARRAY_HEADER_FORMAT*) pFormat;
if ( ! pMemory || !pArrayFormat->Flags.HasPointerInfo )
return;
NDR64_UINT32 MaxCount = (NDR64_UINT32)
Ndr64EvaluateExpr( pStubMsg,
pArrayFormat->ConfDescriptor,
EXPR_MAXCOUNT );
Ndr64pPointerLayoutFree( pStubMsg,
pArrayFormat + 1,
MaxCount,
pMemory );
}
void
Ndr64ConformantVaryingArrayFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a one dimensional conformant varying array's embedded pointers which
were allocated during a remote call. Called for both top level and
embedded conformant varying arrays.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_CONF_VAR_ARRAY_HEADER_FORMAT * pArrayFormat =
(NDR64_CONF_VAR_ARRAY_HEADER_FORMAT*) pFormat;
if ( ! pMemory || !pArrayFormat->Flags.HasPointerInfo)
return;
NDR64_UINT32 ActualCount = (NDR64_UINT32)
Ndr64EvaluateExpr( pStubMsg,
pArrayFormat->VarDescriptor,
EXPR_ACTUALCOUNT );
Ndr64pPointerLayoutFree( pStubMsg,
pArrayFormat + 1,
ActualCount,
pMemory );
}
void
Ndr64VaryingArrayFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a varying array's embedded pointers which were allocated
during a remote call. Called for both top level and embedded varying
arrays.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_VAR_ARRAY_HEADER_FORMAT * pArrayFormat =
(NDR64_VAR_ARRAY_HEADER_FORMAT*) pFormat;
if ( ! pMemory || !pArrayFormat->Flags.HasPointerInfo)
return;
NDR64_UINT32 ActualCount = (NDR64_UINT32)
Ndr64EvaluateExpr( pStubMsg,
pArrayFormat->VarDescriptor,
EXPR_ACTUALCOUNT );
Ndr64pPointerLayoutFree( pStubMsg,
pArrayFormat + 1,
ActualCount,
pMemory );
}
void
Ndr64ComplexArrayFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees a complex array's embedded pointers which were allocated
during a remote call. Called for both top level and embedded complex
arrays.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_BOGUS_ARRAY_HEADER_FORMAT *pArrayFormat =
(NDR64_BOGUS_ARRAY_HEADER_FORMAT *) pFormat;
BOOL IsFixed = ( pArrayFormat->FormatCode == FC64_FIX_BOGUS_ARRAY ) ||
( pArrayFormat->FormatCode == FC64_FIX_FORCED_BOGUS_ARRAY );
PFORMAT_STRING pElementFormat = (PFORMAT_STRING)pArrayFormat->Element;
//
// We have to check this in case we get an exception before actually
// unmarshalling the array.
//
if ( ! pMemory )
return;
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 )
{
Elements = (NDR64_UINT32)Ndr64EvaluateExpr( pStubMsg,
pConfVarFormat->ConfDescription,
EXPR_MAXCOUNT );
Offset = 0;
Count = Elements;
}
//
// Check for variance description.
//
if ( pConfVarFormat->VarDescription )
{
Count = (NDR64_UINT32)
Ndr64EvaluateExpr( pStubMsg,
pConfVarFormat->VarDescription,
EXPR_ACTUALCOUNT );
Offset = (NDR64_UINT32)
Ndr64EvaluateExpr( pStubMsg,
pConfVarFormat->OffsetDescription,
EXPR_OFFSET );
}
}
NDR64_UINT32 ElementMemorySize =
Ndr64pMemorySize( pStubMsg,
pElementFormat,
FALSE );
pMemory += Ndr64pConvertTo2GB((NDR64_UINT64)Offset *
(NDR64_UINT64)ElementMemorySize);
Ndr64pConvertTo2GB( (NDR64_UINT64)Elements *
(NDR64_UINT64)ElementMemorySize );
Ndr64pConvertTo2GB( (NDR64_UINT64)Count *
(NDR64_UINT64)ElementMemorySize );
for ( ; Count--; )
{
Ndr64EmbeddedTypeFree( pStubMsg,
pMemory,
pElementFormat );
pMemory += ElementMemorySize;
}
}
void
Ndr64UnionFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees an encapsulated union's embedded pointers which were allocated
during a remote call.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_UNION_ARM_SELECTOR* pArmSelector;
EXPR_VALUE SwitchIs;
NDR64_FORMAT_CHAR SwitchType;
uchar *pArmMemory;
if ( !pMemory )
return;
switch(*(PFORMAT_STRING)pFormat)
{
case FC64_NON_ENCAPSULATED_UNION:
{
const NDR64_NON_ENCAPSULATED_UNION* pNonEncapUnionFormat =
(const NDR64_NON_ENCAPSULATED_UNION*) pFormat;
SwitchType = pNonEncapUnionFormat->SwitchType;
pArmSelector = (NDR64_UNION_ARM_SELECTOR*)(pNonEncapUnionFormat + 1);
SwitchIs = Ndr64EvaluateExpr( pStubMsg,
pNonEncapUnionFormat->Switch,
EXPR_SWITCHIS );
pArmMemory = pMemory;
break;
}
case FC64_ENCAPSULATED_UNION:
{
const NDR64_ENCAPSULATED_UNION* pEncapUnionFormat =
(const NDR64_ENCAPSULATED_UNION*)pFormat;
SwitchType = pEncapUnionFormat->SwitchType;
pArmSelector = (NDR64_UNION_ARM_SELECTOR*)(pEncapUnionFormat + 1);
SwitchIs = Ndr64pSimpleTypeToExprValue( SwitchType,
pMemory );
pArmMemory = pMemory + pEncapUnionFormat->MemoryOffset;
break;
}
default:
NDR_ASSERT("Bad union format\n", 0);
return;
}
PNDR64_FORMAT pArmFormat =
Ndr64pFindUnionArm( pStubMsg,
pArmSelector,
SwitchIs );
if ( !pArmFormat )
return;
Ndr64EmbeddedTypeFree( pStubMsg,
pArmMemory,
pArmFormat );
}
void
Ndr64XmitOrRepAsFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees the transmit-as object (actually the presented type instance)
and steps over the object.
There is an exceptional situation where the spec forbids stub to free
the instance. This happens when there is an [in] only parameter with
a [transmit_as()] on a component of the parameter, and the presented
typedef is composed of one or more pointers.
We have a flag in the stub msg that is set when this happens.
See mrshl.c for the description of the FC layout.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer's format string description.
Return :
None.
--*/
{
const NDR64_TRANSMIT_AS_FORMAT *pTransFormat =
( const NDR64_TRANSMIT_AS_FORMAT *) pFormat;
if ( !pMemory )
return;
NDR_ASSERT( pTransFormat->FormatCode == FC64_TRANSMIT_AS || pTransFormat->FormatCode , "invalid format string for user marshal" );
unsigned short QIndex = pTransFormat->RoutineIndex;
const XMIT_ROUTINE_QUINTUPLE * pQuintuple = pStubMsg->StubDesc->aXmitQuintuple;
// Free the presented type instance unless forbidden explicitely.
if ( ! pStubMsg->fDontCallFreeInst )
{
pStubMsg->pPresentedType = pMemory;
pQuintuple[ QIndex ].pfnFreeInst( pStubMsg );
}
}
void
Ndr64UserMarshalFree(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pMemory,
PNDR64_FORMAT pFormat )
/*++
Routine Description :
Frees the usr_marshal object and steps over the object.
See mrshl.c for the description of the layouts.
Arguments :
pStubMsg - Pointer to the stub message.
pMemory - Pointer to be freed.
pFormat - Pointer'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" );
unsigned short QIndex = pUserFormat->RoutineIndex;
const USER_MARSHAL_ROUTINE_QUADRUPLE * pQuadruple =
(const USER_MARSHAL_ROUTINE_QUADRUPLE *)( ( NDR_PROC_CONTEXT *)pStubMsg->pContext )->pSyntaxInfo->aUserMarshalQuadruple;
// Call the user to free his stuff.
USER_MARSHAL_CB UserMarshalCB;
Ndr64pInitUserMarshalCB( pStubMsg,
pUserFormat,
USER_MARSHAL_CB_FREE,
& UserMarshalCB);
// The user shouldn't ever free the top level object as we free it.
// He should free only pointees of his top level object.
pQuadruple[ QIndex ].pfnFree( (ulong*) &UserMarshalCB, pMemory );
// Ndr64pMemoryIncrement steps over the memory object.
}
// define the jump table
#define NDR64_BEGIN_TABLE \
PNDR64_FREE_ROUTINE extern const Ndr64FreeRoutinesTable[] = \
{
#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 ) \
,free
#define NDR64_SIMPLE_TYPE_TABLE_ENTRY( number, tokenname, buffersize, memorysize) \
,Ndr64pNoopFree
#include "tokntbl.h"
C_ASSERT( sizeof(Ndr64FreeRoutinesTable)/sizeof(PNDR64_FREE_ROUTINE) == 256 );
#undef NDR64_BEGIN_TABLE
#undef NDR64_TABLE_ENTRY
#define NDR64_BEGIN_TABLE \
PNDR64_FREE_ROUTINE extern const Ndr64EmbeddedFreeRoutinesTable[] = \
{
#define NDR64_TABLE_ENTRY( number, tokenname, marshall, embeddedmarshall, unmarshall, embeddedunmarshall, buffersize, embeddedbuffersize, memsize, embeddedmemsize, free, embeddedfree, typeflags ) \
,embeddedfree
#include "tokntbl.h"
C_ASSERT( sizeof(Ndr64EmbeddedFreeRoutinesTable) / sizeof(PNDR64_FREE_ROUTINE) == 256 );