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.
 
 
 
 
 
 

731 lines
18 KiB

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989 Microsoft Corporation
Module Name:
ptrana.cxx
Abstract:
Contains implementations of analysis routines for pointer types.
Notes:
History:
Oct-10-1993 VibhasC Created
----------------------------------------------------------------------------*/
/****************************************************************************
* include files
***************************************************************************/
#include "allana.hxx"
#pragma hdrstop
/****************************************************************************
* local definitions
***************************************************************************/
/****************************************************************************
* local data
***************************************************************************/
/****************************************************************************
* externs
***************************************************************************/
/****************************************************************************/
CG_STATUS
CG_POINTER::UnMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
CG_STATUS Status;
// Unmarshall the pointer body first. If the pointer needs to be deferred,
// then dont perform the pointee unmarshall analysis. Just indicate that
// there is a pointee that needs to be unmarshalled later.
Status = PtrUnMarshallAnalysis( pAna );
if( pAna->IsPointeeDeferred() )
{
pAna->SetHasAtLeastOneDeferredPointee();
}
else
Status = PteUnMarshallAnalysis( pAna );
return Status;
}
CG_STATUS
CG_POINTER::PtrUnMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
RPC_BUF_SIZE_PROPERTY BSizeProp = BSIZE_FIXED;
RPC_BUFFER_SIZE BufIncr = 0;
unsigned short EProp = E_SIZING_POSSIBLE |
E_UNMARSHALL_POSSIBLE;
long MarshallWeight = 0;
ALIGNMENT_PROPERTY CurAl = pAna->GetCurAlignmentState();
unsigned short CurEmbedLevel = pAna->GetCurrentEmbeddingLevel();
BOOL fTopLevelPtr = (CurEmbedLevel == 0);
// Perform the analysis for the pointer body. For a [ref] pointer, nothing
// needs to be done.
if( IsRef() && !pAna->IsMemoryAllocDone() )
{
SetUAction( RecommendUAction( pAna->GetCurrentSide(),
pAna->IsMemoryAllocDone(),
pAna->IsRefAllocDone(),
FALSE, // no buffer re-use for ref.
UAFLAGS_NONE
));
}
else // unique or ptr.
{
// Bump the marshalling pointer by the alignment of the pointer itself.
CurAl = pAna->Advance( GetWireAlignment(),
(STM_ACTION *)0,
&BSizeProp,
&BufIncr
);
}
pAna->SetEngineProperty( EProp );
pAna->AddMarshallWeight( MarshallWeight );
pAna->SetRpcBufSizeProperty( BSizeProp );
pAna->SetCurAlignmentState( CurAl );
return CG_OK;
}
CG_STATUS
CG_POINTER::PteUnMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
CG_STATUS Status;
pAna->PushIndirectionLevel();
Status = CorePteUnMarshallAnalysis( pAna );
pAna->PopIndirectionLevel();
pAna->IncrRpcBufferSize(pAna->Position(
pAna->GetNextWireAlignment(),
(STM_ACTION*)0 )
);
return Status;
}
CG_STATUS
CG_POINTER::MarshallAnalysis(
ANALYSIS_INFO * pAna )
{
CG_STATUS Status;
short EmbedLevel;
// Marshall the pointer body first. If the pointee needs to be deferred,
// dont perform marshall analysis on the pointee. Just indicate that a
// pointee needs to be marshalled later.
Status = PtrMarshallAnalysis( pAna );
if( pAna->IsPointeeDeferred() )
{
pAna->SetHasAtLeastOneDeferredPointee();
}
else
{
EmbedLevel = pAna->GetCurrentEmbeddingLevel();
pAna->ResetEmbeddingLevel();
Status = PteMarshallAnalysis( pAna );
pAna->SetCurrentEmbeddingLevel( EmbedLevel );
}
return Status;
}
CG_STATUS
CG_POINTER::PtrMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
ALIGNMENT_PROPERTY CurAl = pAna->GetCurAlignmentState();
RPC_BUFFER_SIZE BufIncr = 0;
RPC_BUF_SIZE_PROPERTY BSizeProp = BSIZE_FIXED;
unsigned short EProp =
E_SIZING_POSSIBLE | E_MARSHALL_POSSIBLE;
unsigned short MarshallWeight= IsRef() ? 0 :
IsUnique() ? MW_UNIQUE_PTR :
MW_FULL_PTR;
if( !IsRef() )
{
CurAl = pAna->Advance( AL_4,
(STM_ACTION *)0,
&BSizeProp,
&BufIncr
);
pAna->IncrRpcBufferSize( BufIncr + 4 );
}
pAna->SetCurAlignmentState( CurAl );
pAna->SetRpcBufSizeProperty( BSizeProp );
pAna->SetEngineProperty( EProp );
pAna->AddMarshallWeight( MarshallWeight );
// Set the alignment of the machine to be the next expected alignment
// After the pointer or pointee is unmarshalled, the next alignment state
// adjusted to.
return CG_OK;
}
CG_STATUS
CG_POINTER::PteMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
CG_STATUS Status;
pAna->PushIndirectionLevel();
pAna->SetMemoryAllocDone(); // Needed ?
Status = CorePteMarshallAnalysis( pAna );
pAna->PopIndirectionLevel();
return Status;
}
CG_STATUS
CG_POINTER::FollowerMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
return PteMarshallAnalysis( pAna );
}
CG_STATUS
CG_POINTER::FollowerUnMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
return PteUnMarshallAnalysis( pAna );
}
CG_STATUS
CG_POINTER::S_OutLocalAnalysis(
ANALYSIS_INFO * pAna )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform analysis for [out] params that need to be allocated as locals
on server stub.
Arguments:
pAna - The analysis block.
Return Value:
CG_OK if all is well
error otherwise.
Notes:
----------------------------------------------------------------------------*/
{
CG_STATUS Status = CG_OK;
CG_NDR * pC = (CG_NDR *)GetNonGenericHandleChild();
if( !pAna->IsMemoryAllocDone() )
{
if( pAna->GetCurrentSide() != C_SIDE )
{
PNAME pName = pAna->GenTempResourceName( 0 );
SetResource( pAna->AddLocalResource( pName,
MakeIDNode( pName, GetType() )
));
}
SetAllocatedOnStack( 1 );
}
// If it is a ref pointer, chase it further.
if( IsRef() && !IsQualifiedPointer() )
{
pAna->ResetMemoryAllocDone();
pAna->SetRefAllocDone();
Status = pC->S_OutLocalAnalysis( pAna );
}
// If this is the server side, and the pointee is allocated on stack,
// then dont free the pointee, else free it.
if( pC->IsAllocatedOnStack() )
{
SetPointerShouldFree( 0 );
}
return Status;
}
CG_STATUS
CG_POINTER::InLocalAnalysis(
ANALYSIS_INFO * pAna )
{
if( IsRef() )
{
((CG_NDR *)GetChild())->InLocalAnalysis( pAna );
}
return CG_OK;
}
/****************************************************************************
* CG_QUALIFIED_POINTER
***************************************************************************/
CG_STATUS
CG_QUALIFIED_POINTER::CorePteMarshallAnalysis(
ANALYSIS_INFO * pAna )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform the core pointee marshall analysis for a conformant string
Arguments:
pAna - The analysis block pointer.
Return Value:
CG_OK if all is well, error otherwise.
Notes:
The ndr for a conformant string (eg typedef [string] char *p ) is:
- MaxCount
- Offset from start of the valid character
- Actual Count.
We need to declare a local variable which will hold the length of the
string, so that the length can be used in the actual marshall for memcopy.
----------------------------------------------------------------------------*/
{
node_skl * pType;
ALIGNMENT_PROPERTY Al;
RPC_BUFFER_SIZE BufIncr = 0;
PNAME pResName;
BOOL fNeedsCount;
BOOL fNeedsFirstAndLength;
RPC_BUFFER_SIZE TotalHdrSize = 0;
if( pAna->IsArrayContext() )
{
SetUsedInArray();
}
if( fNeedsCount = NeedsMaxCountMarshall() )
{
if( !GetSizeResource() )
{
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pResName = pAna->GenTempResourceName(0);
pType = MakeIDNode( pResName, pType );
SetSizeResource( pAna->AddTransientResource( pResName, pType ) );
}
else
{
pAna->AddTransientResource( GetSizeResource()->GetResourceName(),
GetSizeResource()->GetType()
);
}
TotalHdrSize += 4;
}
if( fNeedsFirstAndLength = NeedsFirstAndLengthMarshall() )
{
if( !GetLengthResource() )
{
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pResName = pAna->GenTempResourceName(0);
pType = MakeIDNode( pResName, pType );
SetLengthResource( pAna->AddTransientResource( pResName, pType ) );
}
else
{
pAna->AddTransientResource( GetLengthResource()->GetResourceName(),
GetLengthResource()->GetType()
);
}
if( NeedsExplicitFirst() )
{
if( !GetFirstResource() )
{
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pResName = pAna->GenTempResourceName(0);
pType = MakeIDNode( pResName, pType );
SetFirstResource( pAna->AddTransientResource( pResName, pType ) );
}
else
{
pAna->AddTransientResource(GetLengthResource()->GetResourceName(),
GetLengthResource()->GetType()
);
}
}
TotalHdrSize += (4 + 4);
}
// Adjust alignment for the first long. The size is the alignment
// increment, and 4 longs. The buffer size property is unknown since
// the length of the string is unknown. Therefore the sizing code will
// have to be generated for this.
if( fNeedsCount )
pAna->Advance( AL_4, 0, 0, 0 );
if( fNeedsFirstAndLength )
{
pAna->Advance( AL_4, 0, 0, 0 );
pAna->Advance( AL_4, 0, 0, 0 );
}
// Depending upon the type of the string, figure out the worst case
// alignment after the string is marshalled.
Al = ((CG_NDR *)GetChild())->GetWireAlignment();
pAna->Advance( Al,
(STM_ACTION *)0,
(RPC_BUF_SIZE_PROPERTY *)0,
&BufIncr
);
pAna->SetCurAlignmentState( MAKE_WC_ALIGNMENT( Al ) );
pAna->SetRpcBufSizeProperty( BSIZE_UNKNOWN );
pAna->IncrRpcBufferSize( BufIncr + TotalHdrSize );
pAna->SetEngineProperty( E_SIZING_POSSIBLE | E_MARSHALL_POSSIBLE );
pAna->AddMarshallWeight( MW_CONFORMANT_STRING );
return CG_OK;
}
CG_STATUS
CG_QUALIFIED_POINTER::CorePteUnMarshallAnalysis(
ANALYSIS_INFO * pAna )
{
RPC_BUFFER_SIZE BufIncr = 0;
ALIGNMENT_PROPERTY Al;
node_skl * pType;
PNAME pResName;
BOOL fNeedsMaxCount;
BOOL fNeedsFirstAndLength;
// If a resource for the length has not already been allocated, allocate
// one.
if( fNeedsMaxCount = NeedsMaxCountMarshall() )
{
if( !GetSizeResource() )
{
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pResName = pAna->GenTempResourceName(0);
pType = MakeIDNode( pResName, pType );
SetSizeResource( pAna->AddTransientResource( pResName, pType ) );
}
else
pAna->AddTransientResource( GetSizeResource()->GetResourceName(),
GetSizeResource()->GetType()
);
pAna->Advance( AL_4, 0, 0, 0 );
}
if( fNeedsFirstAndLength = NeedsFirstAndLengthMarshall() )
{
if( !GetLengthResource() )
{
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pResName = pAna->GenTempResourceName(0);
pType = MakeIDNode( pResName, pType );
SetLengthResource( pAna->AddTransientResource( pResName, pType ) );
}
else
pAna->AddTransientResource( GetLengthResource()->GetResourceName(),
GetLengthResource()->GetType()
);
if( NeedsExplicitFirst() )
{
if( !GetFirstResource() )
{
GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
pResName = pAna->GenTempResourceName(0);
pType = MakeIDNode( pResName, pType );
SetFirstResource( pAna->AddTransientResource( pResName, pType ) );
}
else
pAna->AddTransientResource(GetFirstResource()->GetResourceName(),
GetFirstResource()->GetType()
);
}
pAna->Advance( AL_4, 0, 0, 0 );
pAna->Advance( AL_4, 0, 0, 0 );
}
// Depending upon the type of the pointee, figure out the worst case
// alignment after the string is marshalled.
Al = ((CG_NDR *)GetChild())->GetWireAlignment();
pAna->Advance( Al,
(STM_ACTION *)0,
(RPC_BUF_SIZE_PROPERTY * )0,
&BufIncr
);
// Set up the rest of the properties.
pAna->SetCurAlignmentState( MAKE_WC_ALIGNMENT( Al ) );
pAna->SetRpcBufSizeProperty( BSIZE_UNKNOWN );
pAna->SetEngineProperty( E_SIZING_POSSIBLE | E_MARSHALL_POSSIBLE );
pAna->AddMarshallWeight( MW_CONFORMANT_STRING );
return CG_OK;
}
CG_STATUS
CG_INTERFACE_POINTER::S_OutLocalAnalysis(
ANALYSIS_INFO * pAna )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform analysis for out params, allocated as locals on the server side.
Arguments:
pAna - A pointer to the analysis block.
Return Value:
CG_OK if all is well
error otherwise.
Notes:
----------------------------------------------------------------------------*/
{
if( pAna->IsRefAllocDone() )
{
if( pAna->GetCurrentSide() != C_SIDE )
{
PNAME pName = pAna->GenTempResourceName( 0 );
node_skl * pType = GetType();
node_skl * pActualType;
if ( pType->NodeKind() == NODE_DEF )
pActualType = MakeIDNode( pName, pType );
else
pActualType = MakePtrIDNode( pName, pType );
SetResource( pAna->AddLocalResource( pName,
pActualType ));
}
SetAllocatedOnStack( 1 );
}
return CG_OK;
}
CG_STATUS
CG_INTERFACE_POINTER::MarshallAnalysis(
ANALYSIS_INFO * pAna )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Perform marshall analysis for interface ptr.
Arguments:
pCCB - The code gen controller block.
Return Value:
CG_OK
Notes:
----------------------------------------------------------------------------*/
{
pAna->SetRpcBufSizeProperty( BSIZE_UNKNOWN );
return CG_OK;
}
/****************************************************************************
* utility functions
***************************************************************************/
U_ACTION
CG_POINTER::RecommendUAction(
SIDE CurrentSide,
BOOL fMemoryAllocated,
BOOL fRefAllocated,
BOOL fBufferReUsePossible,
UAFLAGS AdditionalFlags )
{
U_ACTION UAction = CG_NDR::RecommendUAction( CurrentSide,
fMemoryAllocated,
fRefAllocated,
fBufferReUsePossible,
AdditionalFlags );
return UAction;
}
#define a0 ADD_0
#define a1 ADD_1
#define a2 ADD_2
#define a3 ADD_3
#define a4 ADD_4
#define a5 ADD_5
#define a6 ADD_6
#define a7 ADD_7
#define f2 FAL_2
#define f4 FAL_4
#define f8 FAL_8
// Action mask specifying what to do within if, within else and outside the if
#define am(i,e,o) ((((i << 4) | e ) << 4) | o)
#define GET_WITHIN_IF( a ) ((a >> 8) & 0xf)
#define GET_WITHIN_ELSE( a ) ((a >> 4) & 0xf)
#define GET_OUTSIDE_IF( a ) (a & 0xf)
// NOTE:: the 6th row and column entry here (index 5) is a dummy entry
unsigned short AdjustArray[11][11] =
{
{
am(a0,a0,a0),am(a1,a0,a0),am(a2,a0,a0),am(a3,a0,a0),am(a4,a0,a0),am(a0,a0,a0)
,am(a6,a0,a0),am(a7,a0,a0),am(f2,a0,a0),am(f4,a0,a0),am(f8,a0,a0)
}
, {
am(a0,a1,a0),am(a0,a0,a1),am(a1,a0,a1),am(a2,a0,a1),am(a3,a0,a2),am(a0,a0,a0)
,am(a5,a0,a1),am(a6,a0,a1),am(f2,a1,a0),am(f4,a1,a0),am(f8,a1,a0)
}
, {
am(a0,a2,a0),am(a1,a2,a0),am(a0,a0,a2),am(a1,a0,a2),am(a2,a0,a2),am(a0,a0,a0)
,am(a4,a0,a2),am(a5,a0,a2),am(f2,a2,a0),am(f4,a2,a0),am(f8,a2,a0)
}
, {
am(a0,a3,a0),am(a1,a3,a0),am(a2,a3,a0),am(a0,a0,a3),am(a1,a0,a3),am(a0,a0,a0)
,am(a3,a0,a3),am(a4,a0,a3),am(f2,a3,a0),am(f4,a3,a0),am(f8,a3,a0)
}
, {
am(a0,a4,a0),am(a1,a4,a0),am(a2,a4,a0),am(a3,a4,a0),am(a0,a0,a4),am(a0,a0,a0)
,am(a2,a0,a4),am(a3,a0,a4),am(f2,a4,a0),am(f4,a4,a0),am(f8,a4,a0)
}
, {
am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0)
,am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0),am(a0,a0,a0)
}
, {
am(a0,a6,a0),am(a1,a6,a0),am(a2,a6,a0),am(a3,a6,a0),am(a4,a6,a0),am(a0,a0,a0)
,am(a0,a0,a6),am(a1,a0,a6),am(f2,a6,a0),am(f4,a6,a0),am(f8,a6,a0)
}
, {
am(a0,a7,a0),am(a1,a7,a0),am(a2,a7,a0),am(a3,a7,a0),am(a4,a7,a0),am(a0,a0,a0)
,am(a6,a7,a0),am(a0,a0,a7),am(f2,a7,a0),am(f4,a7,a0),am(f8,a7,a0)
}
, {
am(a0,f2,a0),am(a1,f2,a0),am(a2,f2,a0),am(a2,f2,a0),am(a4,f2,a0),am(a0,a0,a0)
,am(a6,f2,a0),am(a7,f2,a0),am(a0,a0,f2),am(f4,f2,a0),am(f8,f2,a0)
}
, {
am(a0,f4,a0),am(a1,f4,a0),am(a2,f4,a0),am(a3,f4,a0),am(a4,f4,a0),am(a0,a0,a0)
,am(a6,f4,a0),am(a7,f4,a0),am(f2,f4,a0),am(a0,a0,f4),am(f8,f4,a0)
}
, {
am(a0,f8,a0),am(a2,f8,a0),am(a2,f8,a0),am(a3,f8,a0),am(a4,f8,a0),am(a0,a0,a0)
,am(a6,f8,a0),am(a7,f8,a0),am(f2,f8,a0),am(f4,f8,a0),am(a0,a0,f8)
}
};
unsigned short FAXlat[] =
{
5 // dummy
,7 // FAL_2
,8 // FAL_4
,9 // FAL_8
};
void
CG_POINTER::RecommendAlignmentAdjustment(
ALIGNMENT_PROPERTY AlBeforePteMarshall,
ALIGNMENT_PROPERTY AlAfterPteMarshall,
ALIGNMENT_PROPERTY TargetAlignment,
STM_ACTION * ActionInIfClause,
STM_ACTION * ActionInElseClause,
STM_ACTION * ActionOutsideIfClause )
{
ALSTMC Al;
STM_ACTION ActionIfNoPteMarshall;
STM_ACTION ActionAfterPteMarshall;
unsigned short Index1,Index2;
unsigned short Entry;
Al.SetCurrentState( AlBeforePteMarshall );
Al.Position( TargetAlignment, &ActionIfNoPteMarshall );
Al.SetCurrentState( AlAfterPteMarshall );
Al.Position( TargetAlignment, &ActionAfterPteMarshall );
if( IS_FORCED_ALIGNMENT_ACTION( ActionIfNoPteMarshall ) )
Index1 = FAXlat[ (ActionIfNoPteMarshall & ~FAL_MASK ) ];
else
Index1 = ActionIfNoPteMarshall;
if( IS_FORCED_ALIGNMENT_ACTION( ActionAfterPteMarshall ) )
Index2 = FAXlat[ (ActionAfterPteMarshall & ~FAL_MASK ) ];
else
Index2 = ActionAfterPteMarshall;
Entry = AdjustArray[ Index1 ][ Index2 ];
*ActionInIfClause = GET_WITHIN_IF( Entry );
*ActionInElseClause = GET_WITHIN_ELSE( Entry );
*ActionOutsideIfClause = GET_OUTSIDE_IF( Entry );
}