Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

397 lines
9.2 KiB

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989 Microsoft Corporation
Module Name:
pungent.cxx
Abstract:
Implementations of the pointer cg class unmarshalling methods.
Notes:
The pointer unmarshalling is a bit tricky, so put into another file.
History:
Dec-10-1993 VibhasC Created
----------------------------------------------------------------------------*/
/****************************************************************************
* include files
***************************************************************************/
#include "becls.hxx"
#pragma hdrstop
/****************************************************************************
* local definitions
***************************************************************************/
/****************************************************************************
* local data
***************************************************************************/
/****************************************************************************
* externs
***************************************************************************/
/****************************************************************************/
CG_STATUS
CG_POINTER::GenUnMarshall(
CCB * pCCB )
{
expr_node * pExprDest = pCCB->GetDestExpression();
expr_node * pExprSource = pCCB->GetSourceExpression();
short CurEmbedLevel = pCCB->GetCurrentEmbeddingLevel();
STM_ACTION Action;
// If a reference is allocated for this pointer, generate the proper
// address by derefing it.
if( pCCB->IsRefAllocDone() )
{
pCCB->SetDestExpression(
MakeDereferentExpressionIfNecessary(pCCB->GetDestExpression()));
}
pExprDest = pCCB->GetDestExpression();
pExprSource = pCCB->GetSourceExpression();
// If the pointer is not a ref pointer, then it gets shipped
// and needs to be aligned before unmarshall.
if( !IsRef() && (CurEmbedLevel == 0) )
{
pCCB->Advance( AL_4,
&Action,
(RPC_BUF_SIZE_PROPERTY *)0,
(RPC_BUFFER_SIZE *)0
);
Out_AlignmentOrAddAction( pCCB, pCCB->GetSourceExpression(), Action );
}
// Check for pointer being null or non-null, in the buffer and memory
// if necessary.
PointerChecks( pCCB );
// Generate the core unmarshalling routine, which is an allocate and
// and an unmarshall.
GenBasicUnMarshall( pCCB );
// emit the closing brace if the pointer needed to be checked for null
// or non-null.
EndPointerChecks( pCCB );
return CG_OK;
}
CG_STATUS
CG_POINTER::GenBasicUnMarshall(
CCB * pCCB )
{
CG_NDR * pC = (CG_NDR *)GetChild();
short CurIndLevel = pCCB->GetCurrentIndirectionLevel();
short CurEmbedLevel = pCCB->GetCurrentEmbeddingLevel();
BOOL fAllocate = TRUE;
// We call this a special allocateforunmarshall method. The name of this
// method is special. This method is ignored by types which decide to
// collapse allocate along with unmarshall. Others may choose to allocate
// and unmarshall separately.
pCCB->PushIndirectionLevel();
pCCB->ResetMemoryAllocDone();
pCCB->SetRefAllocDone();
pCCB->ResetEmbeddingLevel();
// If this is the client side, and this is a top level unique ptr and
// the child is a pointer, do dont allocate.
if( (IsUnique()) &&
(pCCB->GetCodeGenSide() == CGSIDE_CLIENT ) &&
(CurIndLevel == 0) && (CurEmbedLevel == 0) &&
(!pCCB->IsReturnContext())
)
{
fAllocate = FALSE;
}
// Allocate the child. If the child wants to handle the allocation
// along with the unmarshall, then this message is ignored.
if( fAllocate == TRUE )
{
pC->GenAllocateForUnMarshall( pCCB );
}
// Now unmarshall into the allocated area.
pC->GenUnMarshall( pCCB );
pCCB->PopIndirectionLevel();
return CG_OK;
}
//
// This method is also supposed to init any embedded pointers.
//
CG_STATUS
CG_POINTER::GenAllocateForUnMarshall(
CCB * pCCB )
{
if( IsRef() )
{
Out_If_IfAllocRef(pCCB,
pCCB->GetDestExpression(),
pCCB->GetSourceExpression(),
// FinalSizeExpression( pCCB )
new expr_constant( 4L )
);
}
else
{
Out_If_IfAlloc(pCCB,
pCCB->GetDestExpression(),
pCCB->GetSourceExpression(),
// FinalSizeExpression( pCCB )
new expr_constant( 4L )
);
}
Out_Assign( pCCB,
MakeDereferentExpressionIfNecessary(pCCB->GetDestExpression()),
new expr_constant( 0L ) );
Out_Endif( pCCB );
return CG_OK;
}
void
CG_POINTER::PointerChecks(
CCB * pCCB )
{
short CILevel = pCCB->GetCurrentIndirectionLevel();
short CELevel = pCCB->GetCurrentEmbeddingLevel();
BOOL fClientSideTopLevelPtr = FALSE;
if( !IsRef() )
{
if( (pCCB->GetCodeGenSide() == CGSIDE_CLIENT ) && (CILevel == 0) &&
!pCCB->IsReturnContext()
)
fClientSideTopLevelPtr = TRUE;
if( fClientSideTopLevelPtr )
{
Out_Comment( pCCB, "(Check TopLevelPtrInBufferOnly )" );
Out_TLUPDecisionBufferOnly( pCCB,
pCCB->GetPtrToPtrInBuffer(),
MakeAddressOfPointer( pCCB->GetDestExpression() ) );
}
else if( CELevel == 0 )
{
Out_Comment( pCCB, "if( CheckTopLevelPtrInBufferAndMem )" );
Out_TLUPDecision( pCCB,
pCCB->GetPtrToPtrInBuffer(),
MakeAddressOfPointer(pCCB->GetDestExpression()));
}
else
{
Out_UPDecision( pCCB,
pCCB->GetPtrToPtrInBuffer(),
MakeAddressOfPointer(pCCB->GetDestExpression()));
}
}
}
void
CG_POINTER::EndPointerChecks(
CCB * pCCB )
{
// If it is a ref pointer, no checks were made in the first place.
if( !IsRef() )
Out_Endif( pCCB );
}
CG_STATUS
CG_QUALIFIED_POINTER::GenBasicUnMarshall(
CCB * pCCB )
{
return GenQPUnMarshall( pCCB );
}
CG_STATUS
CG_QUALIFIED_POINTER::GenQPUnMarshall(
CCB * pCCB )
{
ALIGNMENT_PROPERTY Al;
STM_ACTION Action;
expr_node * pSource = pCCB->GetSourceExpression();
expr_node * pDest = pCCB->GetDestExpression();
node_skl * pType;
expr_node * pFirstExpr;
expr_node * XmittedLengthExpr;
long SizeOfElement;
BOOL fNeedsMaxCount = NeedsMaxCountMarshall();
BOOL fNeedsFirstAndLength = NeedsFirstAndLengthMarshall();
BOOL fBufferCanBeReUsed = FALSE;
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
// Pick up the size of the transmitted type.
//
// Buffer can be re-used for a pure string, but for no other type which
// has variance, the buffer can be re-used.
if( !pCCB->IsReturnContext() )
{
if( (GetCGID() == ID_CG_STRING_PTR ) || !fNeedsFirstAndLength )
{
fBufferCanBeReUsed = TRUE;
}
}
if( fNeedsMaxCount )
{
pCCB->Advance( AL_4, &Action, 0, 0 );
Out_AlignmentOrAddAction( pCCB, pSource, Action );
Out_UnMarshallBaseType( pCCB,
pType,
GetSizeResource(),
pSource );
//
// Allocate space for the stuff. If this has variance of any sort,
// the buffer cannot be re-used.
//
if( fBufferCanBeReUsed )
{
Out_IfAlloc( pCCB,
pDest,
pSource,
GetSizeResource() );
}
else
{
Out_Alloc( pCCB,
pDest,
pSource,
GetSizeResource() );
}
XmittedLengthExpr = GetSizeResource();
}
if( fNeedsFirstAndLength )
{
pCCB->Advance( AL_4, &Action, 0, 0 );
Out_AlignmentOrAddAction( pCCB, pSource, Action );
if( NeedsExplicitFirst() )
{
Out_UnMarshallBaseType( pCCB,
pType,
GetFirstResource(),
pSource );
pFirstExpr = GetFirstResource();
}
else
{
Out_AddToBufferPointer( pCCB,
pSource,
new expr_constant( 4L ));
pFirstExpr = new expr_constant( 0L );
}
Out_UnMarshallBaseType( pCCB,
pType,
GetLengthResource(),
pSource );
XmittedLengthExpr = GetLengthResource();
}
// Depending upon the alignment of each of the element of the string,
// advance the state machine and prepare for a memcopy.
if( ((CG_NDR *)GetChild())->IsBlockCopyPossible() )
{
Al = ((CG_NDR *)GetChild())->GetWireAlignment();
SizeOfElement = ((CG_NDR *)GetChild())->GetType()->GetSize(0);
if( SizeOfElement > 1 )
{
XmittedLengthExpr = new expr_b_arithmetic( OP_STAR,
XmittedLengthExpr,
new expr_constant(SizeOfElement)
);
}
pCCB->Advance( Al,
&Action,
(RPC_BUF_SIZE_PROPERTY *)0,
(RPC_BUFFER_SIZE *)0
);
Out_AlignmentOrAddAction( pCCB,
pSource,
Action
);
if( fBufferCanBeReUsed )
{
Out_IfCopy( pCCB,
MakeAddressExpressionNoMatterWhat(pDest),
pSource,
XmittedLengthExpr);
}
else
{
Out_Copy( pCCB,
pDest,
pSource,
XmittedLengthExpr,
pSource );
}
}
else
{
// Do a member by member unmarshall.
}
pCCB->SetCurAlignmentState( MAKE_WC_ALIGNMENT( Al ) );
return CG_OK;
}
CG_STATUS
CG_STRING_POINTER::GenBasicUnMarshall(
CCB * pCCB )
{
expr_node * pSource = pCCB->GetSourceExpression();
expr_node * pDest = pCCB->GetDestExpression();
ALIGNMENT_PROPERTY Al = ((CG_NDR *)GetChild())->GetWireAlignment();
expr_node * pSizeExpr;
pSizeExpr = new expr_constant( ((CG_NDR *)GetChild())->GetMemorySize() );
Out_StringUnMarshall( pCCB, pDest, pSizeExpr );
pCCB->SetCurAlignmentState( MAKE_WC_ALIGNMENT( Al ) );
return CG_OK;
}
CG_STATUS
CG_SIZE_STRING_POINTER::GenBasicUnMarshall(
CCB * pCCB )
{
return GenQPUnMarshall( pCCB );
}