mirror of https://github.com/tongzx/nt5src
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
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 );
|
|
|