mirror of https://github.com/lianthony/NT4.0
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.
221 lines
4.6 KiB
221 lines
4.6 KiB
/*++
|
|
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
union.cxx
|
|
|
|
Abstract:
|
|
|
|
|
|
Author:
|
|
|
|
David Kays (dkays) August 1 1994
|
|
|
|
Revision History:
|
|
|
|
RyszardK Sep 16, 94 Encapsulated unions, union arms
|
|
Ryszardk Nov 12, 94 Array of unions, pointer issues
|
|
|
|
--*/
|
|
|
|
#include <sysinc.h>
|
|
#include <rpc.h>
|
|
#include <rpcndr.h>
|
|
|
|
#include <ntsdexts.h>
|
|
#include <ntdbg.h>
|
|
|
|
extern "C" {
|
|
#include <ndrtypes.h>
|
|
#include <ndrp.h>
|
|
}
|
|
|
|
#include "misc.hxx"
|
|
#include "bufout.hxx"
|
|
|
|
|
|
void
|
|
UNION::OutputArms(
|
|
long ArmFO,
|
|
long SwitchIs
|
|
)
|
|
{
|
|
uchar Format[1024];
|
|
long CurrentOffset, Arms, Alignment;
|
|
NDR * Ndr;
|
|
uchar * pFormat;
|
|
|
|
if ( fOutputLimitReached )
|
|
return;
|
|
|
|
//
|
|
// Get the union's arm descriptions.
|
|
//
|
|
FormatString->Read( ArmFO + 2, Format, 2 );
|
|
|
|
Arms = GET_SHORT(Format) & 0x0fff;
|
|
Alignment = GET_SHORT(Format) >> 12;
|
|
|
|
CurrentOffset = ArmFO + 4;
|
|
|
|
FormatString->Read( CurrentOffset, Format, (Arms * 6) + 2 );
|
|
|
|
pFormat = (uchar *) &Format[0];
|
|
|
|
Buffer->Align( Alignment );
|
|
|
|
for ( ; Arms--; pFormat += 6, CurrentOffset += 6 )
|
|
{
|
|
if ( SwitchIs == GET_LONG(pFormat) )
|
|
{
|
|
CurrentOffset += 4;
|
|
pFormat += 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
IndentInc();
|
|
|
|
//
|
|
// Check for default arm cases.
|
|
//
|
|
if ( Arms < 0 )
|
|
{
|
|
if ( *((short *)pFormat) == 0xffff )
|
|
ABORT( "Undefined union default arm taken\n" );
|
|
|
|
if ( *((short *)pFormat) == 0 )
|
|
{
|
|
PrintIndent();
|
|
Print( "Empty default arm\n" );
|
|
IndentDec();
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( IS_MAGIC_UNION_BYTE(pFormat) )
|
|
{
|
|
BASETYPE * Basetype;
|
|
|
|
Basetype = new BASETYPE( this, pFormat[0] );
|
|
Basetype->Output();
|
|
delete Basetype;
|
|
}
|
|
else
|
|
{
|
|
long ArmOffset = GET_SHORT( pFormat );
|
|
|
|
if ( ArmOffset == 0 )
|
|
{
|
|
PrintIndent();
|
|
Print("Empty arm\n");
|
|
}
|
|
else
|
|
{
|
|
CurrentOffset += ArmOffset;
|
|
FormatString->Read( CurrentOffset, Format, 4 );
|
|
|
|
if ( IS_POINTER_TYPE( Format[0] ) )
|
|
{
|
|
char PtrValue[4];
|
|
long PtrBO;
|
|
POINTER * pMember;
|
|
|
|
// Read thru the pointer field.
|
|
|
|
Buffer->Align( 0x3 );
|
|
PtrBO = Buffer->GetCurrentOffset();
|
|
Buffer->Read( PtrValue, 4);
|
|
|
|
pMember = new POINTER( this, CurrentOffset, PtrBO );
|
|
|
|
PrintIndent();
|
|
Print( "%s %08x\t<id= %d>\n",
|
|
FcTypeName[ Format[0] ],
|
|
*(unsigned long *)PtrValue,
|
|
pMember->GetPointerId() );
|
|
|
|
PointerDict.Register( PtrBO, pMember );
|
|
}
|
|
else
|
|
{
|
|
Ndr = Create( CurrentOffset, this );
|
|
Ndr->Output();
|
|
delete Ndr;
|
|
}
|
|
|
|
PointerDict.OutputPointees( this );
|
|
}
|
|
}
|
|
|
|
IndentDec();
|
|
}
|
|
|
|
|
|
void
|
|
UNION::Output()
|
|
{
|
|
uchar Format[8];
|
|
long CurrentOffset;
|
|
long SwitchIs;
|
|
|
|
if ( fOutputLimitReached )
|
|
return;
|
|
|
|
CurrentOffset = FormatOffset;
|
|
|
|
// Read the fixed part of the union's description.
|
|
|
|
FormatString->Read( CurrentOffset, &Format[0], 8 );
|
|
|
|
Buffer->Align( SIMPLE_TYPE_ALIGNMENT(Format[1]) );
|
|
|
|
SwitchIs = 0;
|
|
|
|
Buffer->Read( (char *) &SwitchIs, SIMPLE_TYPE_BUFSIZE(Format[1]) );
|
|
|
|
PrintIndent();
|
|
Print( "Non-encapsulated union (switch is == 0x%x (%s)) : \n",
|
|
SwitchIs,
|
|
(unsigned long) FormatCharNames[Format[1]] );
|
|
|
|
//
|
|
// Get the union's arm descriptions.
|
|
//
|
|
CurrentOffset += 6;
|
|
CurrentOffset += GET_SHORT( Format + 6 );
|
|
|
|
OutputArms( CurrentOffset, SwitchIs );
|
|
}
|
|
|
|
void
|
|
ENCAPSULATED_UNION::Output()
|
|
{
|
|
uchar Format[2];
|
|
long SwitchIs;
|
|
char SwitchType;
|
|
|
|
if ( fOutputLimitReached )
|
|
return;
|
|
|
|
// Read the fixed part of the union's description.
|
|
|
|
FormatString->Read( FormatOffset, Format, 2 );
|
|
|
|
SwitchType = (char)(0xf & Format[1]);
|
|
Buffer->Align( SIMPLE_TYPE_ALIGNMENT( SwitchType ));
|
|
|
|
SwitchIs = 0;
|
|
|
|
Buffer->Read( (char *) &SwitchIs, SIMPLE_TYPE_BUFSIZE( SwitchType ) );
|
|
|
|
PrintIndent();
|
|
Print( "Encapsulated union (switch is == 0x%x (%s)) : \n",
|
|
SwitchIs,
|
|
(unsigned long) FormatCharNames[ SwitchType ] );
|
|
|
|
OutputArms( FormatOffset + 2, SwitchIs );
|
|
}
|
|
|