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.
1130 lines
29 KiB
1130 lines
29 KiB
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
frmtstr.hxx
|
|
|
|
Abstract:
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
History:
|
|
|
|
DKays Oct-1993 Created.
|
|
----------------------------------------------------------------------------*/
|
|
|
|
#include "becls.hxx"
|
|
#pragma hdrstop
|
|
|
|
|
|
extern CMD_ARG * pCommand;
|
|
|
|
|
|
#ifdef FSDEBUG
|
|
static char * pFormatCharNames[] =
|
|
{
|
|
"", // FC_ZERO
|
|
"FC_BYTE",
|
|
"FC_CHAR",
|
|
"FC_SMALL",
|
|
"FC_USMALL",
|
|
"FC_WCHAR",
|
|
"FC_SHORT",
|
|
"FC_USHORT",
|
|
"FC_LONG",
|
|
"FC_ULONG",
|
|
"FC_FLOAT",
|
|
"FC_HYPER",
|
|
"FC_DOUBLE",
|
|
|
|
"FC_ENUM16",
|
|
"FC_ENUM32",
|
|
"FC_IGNORE",
|
|
"FC_ERROR_STATUS_T",
|
|
|
|
"FC_RP",
|
|
"FC_UP",
|
|
"FC_OP",
|
|
"FC_FP",
|
|
|
|
"FC_STRUCT",
|
|
"FC_PSTRUCT",
|
|
"FC_CSTRUCT",
|
|
"FC_CPSTRUCT",
|
|
"FC_CVSTRUCT",
|
|
"FC_BOGUS_STRUCT",
|
|
|
|
"FC_CARRAY",
|
|
"FC_CVARRAY",
|
|
"FC_SMFARRAY",
|
|
"FC_LGFARRAY",
|
|
"FC_SMVARRAY",
|
|
"FC_LGVARRAY",
|
|
"FC_BOGUS_ARRAY",
|
|
|
|
"FC_C_CSTRING",
|
|
"FC_C_BSTRING",
|
|
"FC_C_SSTRING",
|
|
"FC_C_WSTRING",
|
|
|
|
"FC_CSTRING",
|
|
"FC_BSTRING",
|
|
"FC_SSTRING",
|
|
"FC_WSTRING",
|
|
|
|
"FC_ENCAPSULATED_UNION",
|
|
"FC_NON_ENCAPSULATED_UNION",
|
|
|
|
"FC_BYTE_COUNT_POINTER",
|
|
|
|
"FC_TRANSMIT_AS",
|
|
"FC_REPRESENT_AS",
|
|
|
|
"FC_IP",
|
|
|
|
"FC_BIND_CONTEXT",
|
|
"FC_BIND_GENERIC",
|
|
"FC_BIND_PRIMITIVE",
|
|
"FC_AUTO_HANDLE",
|
|
"FC_CALLBACK_HANDLE",
|
|
"FC_UNUSED1",
|
|
|
|
"FC_POINTER",
|
|
|
|
"FC_ALIGNM2",
|
|
"FC_ALIGNM4",
|
|
"FC_ALIGNM8",
|
|
"FC_UNUSED2",
|
|
"FC_UNUSED3",
|
|
"FC_UNUSED4",
|
|
|
|
"FC_STRUCTPAD1",
|
|
"FC_STRUCTPAD2",
|
|
"FC_STRUCTPAD3",
|
|
"FC_STRUCTPAD4",
|
|
"FC_STRUCTPAD5",
|
|
"FC_STRUCTPAD6",
|
|
"FC_STRUCTPAD7",
|
|
|
|
"FC_STRING_SIZED",
|
|
"FC_UNUSED5",
|
|
|
|
"FC_NO_REPEAT",
|
|
"FC_FIXED_REPEAT",
|
|
"FC_VARIABLE_REPEAT",
|
|
"FC_FIXED_OFFSET",
|
|
"FC_VARIABLE_OFFSET",
|
|
|
|
"FC_PP",
|
|
|
|
"FC_EMBEDDED_COMPLEX",
|
|
|
|
"FC_IN_PARAM",
|
|
"FC_IN_PARAM_BASETYPE",
|
|
"FC_IN_PARAM_NO_FREE_INST",
|
|
"FC_IN_OUT_PARAM",
|
|
"FC_OUT_PARAM",
|
|
"FC_RETURN_PARAM",
|
|
"FC_RETURN_PARAM_BASETYPE",
|
|
|
|
"FC_DEREFERENCE",
|
|
"FC_DIV_2",
|
|
"FC_MULT_2",
|
|
"FC_ADD_1",
|
|
"FC_SUB_1",
|
|
"FC_CALLBACK",
|
|
|
|
"FC_CONSTANT_IID",
|
|
|
|
"FC_END",
|
|
"FC_PAD",
|
|
|
|
0,
|
|
0,
|
|
0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0,
|
|
|
|
"FC_HARD_STRUCT",
|
|
|
|
"FC_TRANSMIT_AS_PTR",
|
|
"FC_REPRESENT_AS_PTR",
|
|
|
|
"FC_USER_MARSHAL",
|
|
|
|
"FC_PIPE",
|
|
|
|
"FC_BLKHOLE",
|
|
|
|
"FC_END_OF_UNIVERSE"
|
|
};
|
|
#endif
|
|
|
|
//
|
|
// This table is indexed by FORMAT_CHARACTER (see midl20\include\ndrtypes.h).
|
|
// To construct the correct name concatenate the name in this table with
|
|
// "Marshall", "Unmarshall", "BufferSize" etc.
|
|
//
|
|
char * pNdrRoutineNames[] =
|
|
{
|
|
"", // FC_ZERO
|
|
"NdrSimpleType", // FC_BYTE
|
|
"NdrSimpleType", // FC_CHAR
|
|
"NdrSimpleType", // FC_SMALL
|
|
"NdrSimpleType", // FC_USMALL
|
|
"NdrSimpleType", // FC_WCHAR
|
|
"NdrSimpleType", // FC_SHORT
|
|
"NdrSimpleType", // FC_USHORT
|
|
"NdrSimpleType", // FC_LONG
|
|
"NdrSimpleType", // FC_ULONG
|
|
"NdrSimpleType", // FC_FLOAT
|
|
"NdrSimpleType", // FC_HYPER
|
|
"NdrSimpleType", // FC_DOUBLE
|
|
|
|
"NdrSimpleType", // FC_ENUM16
|
|
"NdrSimpleType", // FC_ENUM32
|
|
"NdrSimpleType", // FC_IGNORE
|
|
"NdrSimpleType", // FC_ERROR_STATUS_T
|
|
|
|
"NdrPointer", // FC_RP
|
|
"NdrPointer", // FC_UP
|
|
"NdrPointer", // FC_OP
|
|
"NdrPointer", // FC_FP
|
|
|
|
"NdrSimpleStruct", // FC_STRUCT
|
|
"NdrSimpleStruct", // FC_PSTRUCT
|
|
"NdrConformantStruct", // FC_CSTRUCT
|
|
"NdrConformantStruct", // FC_CPSTRUCT
|
|
"NdrConformantVaryingStruct", // FC_CVSTRUCT
|
|
|
|
"NdrComplexStruct", // FC_BOGUS_STRUCT
|
|
|
|
"NdrConformantArray", // FC_CARRAY
|
|
"NdrConformantVaryingArray", // FC_CVARRAY
|
|
"NdrFixedArray", // FC_SMFARRAY
|
|
"NdrFixedArray", // FC_LGFARRAY
|
|
"NdrVaryingArray", // FC_SMVARRAY
|
|
"NdrVaryingArray", // FC_LGVARRAY
|
|
|
|
"NdrComplexArray", // FC_BOGUS_ARRAY
|
|
|
|
"NdrConformantString", // FC_C_CSTRING
|
|
"NdrConformantString", // FC_C_BSTRING
|
|
"NdrConformantString", // FC_C_SSTRING
|
|
"NdrConformantString", // FC_C_WSTRING
|
|
|
|
"NdrNonConformantString", // FC_CSTRING
|
|
"NdrNonConformantString", // FC_BSTRING
|
|
"NdrNonConformantString", // FC_SSTRING
|
|
"NdrNonConformantString", // FC_WSTRING
|
|
|
|
"NdrEncapsulatedUnion", // FC_ENCAPSULATED_UNION
|
|
"NdrNonEncapsulatedUnion", // FC_NON_ENCAPSULATED_UNION
|
|
|
|
"NdrByteCountPointer", // FC_BYTE_COUNT_POINTER
|
|
|
|
"NdrXmitOrRepAs", // FC_TRANSMIT_AS
|
|
"NdrXmitOrRepAs", // FC_REPRESENT_AS
|
|
|
|
"NdrInterfacePointer", // FC_INTERFACE_POINTER
|
|
|
|
0, 0, 0, 0, 0, 0,
|
|
|
|
0,
|
|
|
|
0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0,
|
|
|
|
0, 0, 0, 0, 0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0,
|
|
|
|
0,
|
|
|
|
0, 0, // FC_END & FC_PAD
|
|
|
|
0,
|
|
0,
|
|
0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0,
|
|
|
|
"NdrHardStruct", // FC_HARD_STRUCT
|
|
|
|
"NdrXmitOrRepAs", // FC_TRANSMIT_AS_PTR
|
|
"NdrXmitOrRepAs", // FC_REPRESENT_AS_PTR
|
|
|
|
"NdrUserMarshal", // FC_USER_MARSHAL
|
|
|
|
"NdrPipe", // FC_PIPE
|
|
|
|
0
|
|
};
|
|
|
|
//
|
|
// the constructor
|
|
FORMAT_STRING::FORMAT_STRING()
|
|
{
|
|
// Allocate the buffer and align it on a short boundary.
|
|
pBuffer = new unsigned char[ DEFAULT_FORMAT_STRING_SIZE ];
|
|
pBuffer = (unsigned char *)((long)(pBuffer + 1) & ~ 0x1);
|
|
|
|
#ifdef FSDEBUG
|
|
// Allocate the cousin buffer type array. This does not need to
|
|
// be aligned.
|
|
pBufferType = new unsigned char[ DEFAULT_FORMAT_STRING_SIZE ];
|
|
#endif
|
|
|
|
BufferSize = DEFAULT_FORMAT_STRING_SIZE;
|
|
CurrentOffset = 0;
|
|
LastOffset = 0;
|
|
pReuseDict = new FRMTREG_DICT( this );
|
|
}
|
|
|
|
void
|
|
FORMAT_STRING::CheckSize()
|
|
/*++
|
|
|
|
Routine Description :
|
|
|
|
Reallocates a new format string buffer if the current buffer is within
|
|
4 bytes of overflowing.
|
|
|
|
Arguments :
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Allocate a new buffer if we're within 4 bytes of
|
|
// overflowing the current buffer.
|
|
//
|
|
if ( CurrentOffset + 3 > BufferSize )
|
|
{
|
|
unsigned char * pBufferNew;
|
|
|
|
pBufferNew = new unsigned char[ BufferSize * 2 ];
|
|
pBufferNew = (unsigned char *)((long)(pBufferNew + 1) & ~ 0x1);
|
|
|
|
memcpy( pBufferNew,
|
|
pBuffer,
|
|
(unsigned int) BufferSize );
|
|
|
|
delete pBuffer;
|
|
|
|
pBuffer = pBufferNew;
|
|
|
|
#ifdef FSDEBUG
|
|
pBufferNew = new unsigned char[ BufferSize * 2 ];
|
|
|
|
memcpy( pBufferNew,
|
|
pBufferType,
|
|
(unsigned int) BufferSize );
|
|
|
|
delete pBufferType;
|
|
|
|
pBufferType = pBufferNew;
|
|
#endif
|
|
|
|
BufferSize *= 2;
|
|
}
|
|
}
|
|
|
|
void
|
|
FORMAT_STRING::Output(
|
|
ISTREAM * pStream,
|
|
char * pTypeName,
|
|
char * pName,
|
|
RepAsPadExprDict * pPadDict,
|
|
RepAsSizeDict * pSizeDict )
|
|
/*++
|
|
|
|
Routine Description :
|
|
|
|
Outputs the format string structure.
|
|
|
|
Arguments :
|
|
|
|
pStream - Stream to output the format string to.
|
|
|
|
--*/
|
|
{
|
|
unsigned long Offset;
|
|
unsigned long LastPrinted = 0;
|
|
char Buf[102];
|
|
BOOL InPP = FALSE;
|
|
REP_AS_PAD_EXPR_DESC * pPadExprDesc;
|
|
REP_AS_SIZE_DESC * pSizeDesc;
|
|
unsigned long AlphaOffset;
|
|
unsigned long MipsOffset;
|
|
unsigned long i386Offset;
|
|
unsigned long PpcOffset;
|
|
unsigned long MacOffset;
|
|
char * pComment;
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "static const " );
|
|
pStream->Write( pTypeName );
|
|
pStream->Write( ' ' );
|
|
pStream->Write( pName );
|
|
pStream->Write( " =");
|
|
pStream->IndentInc();
|
|
pStream->NewLine();
|
|
|
|
pStream->Write( '{' );
|
|
pStream->IndentInc();
|
|
pStream->NewLine();
|
|
|
|
pStream->Write( "0," );
|
|
pStream->NewLine();
|
|
|
|
pStream->Write( '{' );
|
|
pStream->IndentInc();
|
|
|
|
// Reset the pad and size macro dictionaries
|
|
|
|
pPadExprDesc = pPadDict->GetFirst();
|
|
pSizeDesc = pSizeDict->GetFirst();
|
|
|
|
pStream->IndentDec();
|
|
pStream->IndentDec();
|
|
pStream->IndentDec();
|
|
|
|
BOOL f32bitServer = (pCommand->GetEnv() != ENV_DOS) &&
|
|
(pCommand->GetEnv() != ENV_WIN16) &&
|
|
(! pCommand->IsAnyMac() );
|
|
BOOL fMac = pCommand->IsAnyMac();
|
|
|
|
|
|
for ( Offset = 0; Offset < LastOffset; )
|
|
{
|
|
pStream->NewLine();
|
|
|
|
pComment = CommentDict.GetComments( (short) Offset );
|
|
|
|
if ( pComment )
|
|
pStream->Write( pComment );
|
|
|
|
if ( (pBufferType[Offset] == FS_SHORT_STACK_OFFSET) ||
|
|
(pBufferType[Offset] == FS_SMALL_STACK_OFFSET) )
|
|
{
|
|
AlphaOffset = OffsetDict.LookupAlphaOffset( (short) Offset );
|
|
MipsOffset = OffsetDict.LookupMipsOffset( (short) Offset );
|
|
PpcOffset = OffsetDict.LookupPpcOffset( (short) Offset );
|
|
MacOffset = OffsetDict.LookupMacOffset( (short) Offset );
|
|
|
|
// A Mac offset can be different from a Mips offset,
|
|
// but doesn't have to.
|
|
// When it is, mips and ppc may be the same and mac may be
|
|
// different than both.
|
|
|
|
if ( pBufferType[Offset] == FS_SHORT_STACK_OFFSET )
|
|
i386Offset = *((short UNALIGNED *)(pBuffer + Offset));
|
|
else
|
|
i386Offset = pBuffer[Offset];
|
|
|
|
if ( f32bitServer )
|
|
{
|
|
pStream->Write( "#ifndef _ALPHA_" );
|
|
pStream->NewLine();
|
|
|
|
if ( (i386Offset != MipsOffset) || (i386Offset != PpcOffset) )
|
|
{
|
|
if ( MipsOffset != PpcOffset )
|
|
{
|
|
pStream->Write( "#if !defined(_MIPS_)" );
|
|
pStream->NewLine();
|
|
pStream->Write( "#ifndef _PPC_" );
|
|
pStream->NewLine();
|
|
}
|
|
else
|
|
{
|
|
pStream->Write(
|
|
"#if !defined(_MIPS_) && !defined(_PPC_)" );
|
|
pStream->NewLine();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( pBufferType[Offset] == FS_SMALL_STACK_SIZE )
|
|
{
|
|
if ( f32bitServer )
|
|
{
|
|
pStream->Write( "#ifndef _ALPHA_" );
|
|
pStream->NewLine();
|
|
}
|
|
}
|
|
|
|
if ( ! (Offset % 2) && ( Offset != LastPrinted ) )
|
|
{
|
|
sprintf(Buf,"/* %2d */\t",Offset);
|
|
LastPrinted = Offset;
|
|
pStream->Write(Buf);
|
|
}
|
|
else
|
|
{
|
|
pStream->Write("\t\t\t");
|
|
}
|
|
|
|
switch ( pBufferType[Offset] )
|
|
{
|
|
case FS_FORMAT_CHARACTER :
|
|
// Make the format string readable.
|
|
switch ( pBuffer[Offset] )
|
|
{
|
|
case FC_IN_PARAM :
|
|
case FC_IN_OUT_PARAM :
|
|
case FC_OUT_PARAM :
|
|
case FC_RETURN_PARAM :
|
|
case FC_STRUCT :
|
|
case FC_PSTRUCT :
|
|
case FC_CSTRUCT :
|
|
case FC_CPSTRUCT :
|
|
case FC_CVSTRUCT :
|
|
case FC_BOGUS_STRUCT :
|
|
case FC_NO_REPEAT :
|
|
case FC_FIXED_REPEAT :
|
|
case FC_VARIABLE_REPEAT :
|
|
case FC_CARRAY :
|
|
case FC_CVARRAY :
|
|
case FC_SMFARRAY :
|
|
case FC_LGFARRAY :
|
|
case FC_SMVARRAY :
|
|
case FC_LGVARRAY :
|
|
case FC_BOGUS_ARRAY :
|
|
case FC_C_CSTRING :
|
|
case FC_C_SSTRING :
|
|
case FC_C_WSTRING :
|
|
case FC_CSTRING :
|
|
case FC_SSTRING :
|
|
case FC_WSTRING :
|
|
case FC_ENCAPSULATED_UNION :
|
|
case FC_NON_ENCAPSULATED_UNION :
|
|
case FC_IP :
|
|
pStream->NewLine();
|
|
pStream->Write("\t\t\t");
|
|
break;
|
|
|
|
case FC_RP :
|
|
case FC_UP :
|
|
case FC_OP :
|
|
case FC_FP :
|
|
//
|
|
// If we're not in a pointer layout, and the previous
|
|
// format char was not a param/result char then print
|
|
// a new line.
|
|
//
|
|
if ( ! InPP &&
|
|
( Offset &&
|
|
pBuffer[Offset - 1] != FC_IN_PARAM &&
|
|
pBuffer[Offset - 1] != FC_IN_OUT_PARAM &&
|
|
pBuffer[Offset - 1] != FC_OUT_PARAM &&
|
|
pBuffer[Offset - 1] != FC_IN_PARAM_NO_FREE_INST &&
|
|
pBuffer[Offset - 1] != FC_RETURN_PARAM )
|
|
)
|
|
{
|
|
pStream->NewLine();
|
|
pStream->Write("\t\t\t");
|
|
}
|
|
break;
|
|
|
|
case FC_PP :
|
|
InPP = TRUE;
|
|
pStream->NewLine();
|
|
pStream->Write("\t\t\t");
|
|
break;
|
|
|
|
case FC_END :
|
|
if ( InPP )
|
|
{
|
|
pStream->NewLine();
|
|
pStream->Write("\t\t\t");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA( pBuffer[Offset], Buf, 16 ) );
|
|
pStream->Write( ",\t\t/* ");
|
|
pStream->Write( pFormatCharNames[pBuffer[Offset]] );
|
|
pStream->Write( " */");
|
|
|
|
if ( (pBuffer[Offset] == FC_END) && InPP )
|
|
{
|
|
pStream->NewLine();
|
|
InPP = FALSE;
|
|
}
|
|
|
|
Offset++;
|
|
break;
|
|
|
|
case FS_POINTER_FORMAT_CHARACTER :
|
|
//
|
|
// If we're not in a pointer layout, and the previous
|
|
// format char was not a param/result char then print
|
|
// a new line.
|
|
//
|
|
if ( ! InPP &&
|
|
( Offset &&
|
|
pBuffer[Offset - 1] != FC_IN_PARAM &&
|
|
pBuffer[Offset - 1] != FC_IN_OUT_PARAM &&
|
|
pBuffer[Offset - 1] != FC_OUT_PARAM &&
|
|
pBuffer[Offset - 1] != FC_RETURN_PARAM )
|
|
)
|
|
{
|
|
pStream->NewLine();
|
|
pStream->Write("\t\t\t");
|
|
}
|
|
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA( pBuffer[Offset], Buf, 16 ) );
|
|
pStream->Write( ", 0x" );
|
|
pStream->Write( MIDL_ITOA( pBuffer[Offset + 1] & 0x00ff, Buf, 16 ) );
|
|
pStream->Write( ",\t/* ");
|
|
pStream->Write( pFormatCharNames[pBuffer[Offset]] );
|
|
|
|
if ( pBuffer[Offset+1] & FC_ALLOCATE_ALL_NODES )
|
|
pStream->Write( " [all_nodes]");
|
|
|
|
if ( pBuffer[Offset+1] & FC_DONT_FREE )
|
|
pStream->Write( " [dont_free]");
|
|
|
|
if ( pBuffer[Offset+1] & FC_ALLOCED_ON_STACK )
|
|
pStream->Write( " [alloced_on_stack]");
|
|
|
|
if ( pBuffer[Offset+1] & FC_SIMPLE_POINTER )
|
|
pStream->Write( " [simple_pointer]");
|
|
|
|
pStream->Write( " */");
|
|
|
|
Offset += 2;
|
|
break;
|
|
|
|
case FS_SMALL :
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA( pBuffer[Offset] & 0x00ff, Buf, 16 ) );
|
|
pStream->Write( ",\t\t/* ");
|
|
pStream->Write( MIDL_ITOA( pBuffer[Offset], Buf, 10 ) );
|
|
pStream->Write( " */");
|
|
|
|
Offset++;
|
|
|
|
break;
|
|
|
|
case FS_SHORT :
|
|
pStream->Write( "NdrFcShort( 0x" );
|
|
pStream->Write(
|
|
MIDL_ITOA(*((short UNALIGNED *)(pBuffer+Offset)), Buf, 16));
|
|
pStream->Write( " ),\t/* ");
|
|
pStream->Write(
|
|
MIDL_ITOA(*((short UNALIGNED *)(pBuffer+Offset)), Buf, 10));
|
|
pStream->Write( " */");
|
|
|
|
Offset += 2;
|
|
|
|
break;
|
|
|
|
case FS_SHORT_OFFSET :
|
|
{
|
|
short ItsOffset = *((short UNALIGNED *)(pBuffer + Offset));
|
|
|
|
pStream->Write( "NdrFcShort( 0x" );
|
|
pStream->Write( MIDL_ITOA( ItsOffset, Buf, 16 ) );
|
|
pStream->Write( " ),\t/* Offset= ");
|
|
pStream->Write( MIDL_ITOA( ItsOffset, Buf, 10 ) );
|
|
pStream->Write( " (");
|
|
pStream->Write( MIDL_ITOA( ItsOffset+Offset, Buf, 10 ) );
|
|
pStream->Write( ") */");
|
|
|
|
Offset += 2;
|
|
|
|
break;
|
|
}
|
|
case FS_SHORT_TYPE_OFFSET :
|
|
{
|
|
short ItsOffset = *((short UNALIGNED *)(pBuffer + Offset));
|
|
|
|
pStream->Write( "NdrFcShort( 0x" );
|
|
pStream->Write( MIDL_ITOA( ItsOffset, Buf, 16 ) );
|
|
pStream->Write( " ),\t/* Type Offset=");
|
|
pStream->Write( MIDL_ITOA( ItsOffset, Buf, 10 ) );
|
|
pStream->Write( " */");
|
|
|
|
Offset += 2;
|
|
|
|
break;
|
|
}
|
|
case FS_SHORT_STACK_OFFSET :
|
|
case FS_SMALL_STACK_OFFSET :
|
|
{
|
|
char * pString;
|
|
BOOL IsShortOffset;
|
|
|
|
IsShortOffset = (pBufferType[Offset] == FS_SHORT_STACK_OFFSET);
|
|
|
|
//
|
|
// For a 32 bit platform, we have already emitted
|
|
// the #ifndef _ALPHA_, the #ifndef _MIPS_ (if needed),
|
|
// and the #ifndef _PPC_ (if needed).
|
|
//
|
|
// Note that PPC, MIPS, i386 & Alpha constitute 32 platform.
|
|
// This is actually a server group.
|
|
// Mac clusters with DOS and WIN16.
|
|
//
|
|
|
|
if ( f32bitServer )
|
|
{
|
|
//
|
|
// The i386 and possibly MIPS and PPC offset.
|
|
//
|
|
|
|
if ( (i386Offset == PpcOffset) && (i386Offset == MipsOffset) )
|
|
pString = "x86, MIPS, PPC";
|
|
else if ( i386Offset == MipsOffset )
|
|
pString = "x86, MIPS";
|
|
else if ( i386Offset == PpcOffset )
|
|
pString = "x86 & PPC";
|
|
else
|
|
pString = "x86";
|
|
}
|
|
else
|
|
pString = "";
|
|
|
|
// Emit plain i386 offset, including Dos and Win16, or Mac.
|
|
|
|
unsigned long OffsetValue = (fMac) ? MacOffset
|
|
: i386Offset;
|
|
|
|
if ( IsShortOffset )
|
|
pStream->Write( "NdrFcShort( " );
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA( OffsetValue, Buf, 16) );
|
|
if ( IsShortOffset )
|
|
pStream->Write( " )" );
|
|
pStream->Write( ",\t/* " );
|
|
pStream->Write( pString );
|
|
pStream->Write( " Stack size/offset = " );
|
|
pStream->Write( MIDL_ITOA( OffsetValue, Buf, 10) );
|
|
pStream->Write( " */");
|
|
|
|
if ( f32bitServer )
|
|
{
|
|
//
|
|
// Do a separate PPC and MIPS-Mac offset if needed.
|
|
//
|
|
if ( (i386Offset != PpcOffset) || (i386Offset != MipsOffset) )
|
|
{
|
|
if ( PpcOffset != MipsOffset )
|
|
{
|
|
pStream->NewLine();
|
|
pStream->Write( "#else" );
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "\t\t\t" );
|
|
|
|
if ( IsShortOffset )
|
|
pStream->Write( "NdrFcShort( " );
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA( PpcOffset, Buf, 16));
|
|
if ( IsShortOffset )
|
|
pStream->Write( " )");
|
|
pStream->Write( ",\t/* PPC Stack size/offset = ");
|
|
pStream->Write( MIDL_ITOA( PpcOffset, Buf, 10));
|
|
pStream->Write( " */");
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "#endif" );
|
|
}
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "#else" );
|
|
|
|
pString = (PpcOffset == MipsOffset) ? "MIPS & PPC"
|
|
: "MIPS";
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "\t\t\t" );
|
|
|
|
if ( IsShortOffset )
|
|
pStream->Write( "NdrFcShort( " );
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA( MipsOffset, Buf, 16));
|
|
if ( IsShortOffset )
|
|
pStream->Write( " )" );
|
|
pStream->Write( ",\t/* " );
|
|
pStream->Write( pString );
|
|
pStream->Write( " Stack size/offset = " );
|
|
pStream->Write( MIDL_ITOA( MipsOffset, Buf, 10));
|
|
pStream->Write( " */");
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "#endif" );
|
|
}
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "#else" );
|
|
pStream->NewLine();
|
|
|
|
//
|
|
// The Alpha Offset.
|
|
//
|
|
|
|
pStream->Write( "\t\t\t" );
|
|
|
|
if ( IsShortOffset )
|
|
pStream->Write( "NdrFcShort( " );
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA( AlphaOffset, Buf, 16));
|
|
if ( IsShortOffset )
|
|
pStream->Write( " )");
|
|
pStream->Write( ",\t/* Alpha Stack size/offset = ");
|
|
pStream->Write( MIDL_ITOA( AlphaOffset, Buf, 10));
|
|
pStream->Write( " */");
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "#endif" );
|
|
|
|
} // if f32bitServer
|
|
|
|
Offset += IsShortOffset ? 2 : 1;
|
|
|
|
break;
|
|
}
|
|
case FS_SMALL_STACK_SIZE :
|
|
{
|
|
long StackSize;
|
|
|
|
StackSize = (long) pBuffer[Offset];
|
|
|
|
//
|
|
// Non-Alpha stack size.
|
|
//
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA(StackSize, Buf, 16) );
|
|
|
|
if ( f32bitServer )
|
|
pStream->Write( ",\t\t/* x86, MIPS & PPC Stack size = ");
|
|
else
|
|
pStream->Write( ",\t\t/* Stack size = ");
|
|
pStream->Write( MIDL_ITOA(StackSize, Buf, 10) );
|
|
pStream->Write( " */");
|
|
|
|
pStream->NewLine();
|
|
|
|
if ( f32bitServer )
|
|
{
|
|
pStream->Write( "#else" );
|
|
pStream->NewLine();
|
|
|
|
//
|
|
// Alpha stack size.
|
|
//
|
|
StackSize = (StackSize + 1) & ~ 0x1;
|
|
|
|
pStream->Write( "\t\t\t" );
|
|
pStream->Write( "0x" );
|
|
pStream->Write( MIDL_ITOA(StackSize, Buf, 16) );
|
|
pStream->Write( ",\t\t/* Alpha Stack size = ");
|
|
pStream->Write( MIDL_ITOA(StackSize, Buf, 10) );
|
|
pStream->Write( " */");
|
|
|
|
pStream->NewLine();
|
|
pStream->Write( "#endif" );
|
|
}
|
|
Offset++;
|
|
|
|
break;
|
|
}
|
|
case FS_LONG :
|
|
pStream->Write( "NdrFcLong( 0x" );
|
|
pStream->Write(
|
|
MIDL_LTOA( *((long UNALIGNED *)(pBuffer+Offset)), Buf, 16));
|
|
pStream->Write( " ),\t/* ");
|
|
pStream->Write(
|
|
MIDL_LTOA(*((long UNALIGNED *)(pBuffer+Offset)), Buf, 10));
|
|
pStream->Write( " */");
|
|
|
|
Offset += 4;
|
|
|
|
break;
|
|
|
|
case FS_PAD_MACRO :
|
|
|
|
if ( pPadExprDesc )
|
|
{
|
|
assert( Offset == pPadExprDesc->KeyOffset );
|
|
|
|
pPadDict->WriteCurrentPadDesc( pStream );
|
|
pPadExprDesc = pPadDict->GetNext();
|
|
}
|
|
else
|
|
{
|
|
pStream->Write( "0x0,\t\t/* macro */" );
|
|
assert( 0 && "Pad macro missing" );
|
|
}
|
|
|
|
Offset++;
|
|
break;
|
|
|
|
case FS_SIZE_MACRO :
|
|
|
|
if ( pSizeDesc )
|
|
{
|
|
assert( Offset == pSizeDesc->KeyOffset );
|
|
|
|
pSizeDict->WriteCurrentSizeDesc( pStream );
|
|
pSizeDesc = pSizeDict->GetNext();
|
|
}
|
|
else
|
|
{
|
|
pStream->Write( "0x0, 0x0,\t\t// macro" );
|
|
assert( 0 && "Size macro missing" );
|
|
}
|
|
|
|
Offset += 2;
|
|
break;
|
|
|
|
case FS_UNKNOWN_STACK_SIZE :
|
|
{
|
|
char * LongBuf = Buf;
|
|
long NameLen = strlen(
|
|
StackSizeDict.LookupTypeName( (short) Offset ));
|
|
if ( NameLen > 25 )
|
|
LongBuf = new char[ 75 + NameLen ];
|
|
|
|
sprintf(
|
|
LongBuf,
|
|
"%s ( (sizeof(%s) + %s) & ~ (%s) ),",
|
|
"(unsigned char)",
|
|
StackSizeDict.LookupTypeName( (short) Offset ),
|
|
"sizeof(int) - 1",
|
|
"sizeof(int) - 1" );
|
|
|
|
pStream->Write( LongBuf );
|
|
}
|
|
Offset++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pStream->NewLine( 2 );
|
|
|
|
//
|
|
// Spit out a terminating 0 so we don't ever fall off the end
|
|
// of the world.
|
|
//
|
|
pStream->Write( "\t\t\t0x0" );
|
|
|
|
pStream->IndentInc();
|
|
pStream->IndentInc();
|
|
pStream->IndentInc();
|
|
|
|
pStream->IndentDec();
|
|
pStream->NewLine();
|
|
|
|
pStream->Write( '}' );
|
|
pStream->IndentDec();
|
|
pStream->NewLine();
|
|
|
|
pStream->Write( "};" );
|
|
pStream->IndentDec();
|
|
pStream->NewLine();
|
|
|
|
// fprintf(stdout, "Total Format String size = %d\n", LastOffset );
|
|
}
|
|
|
|
|
|
unsigned short
|
|
FORMAT_STRING::OptimizeFragment(
|
|
CG_NDR * pNode )
|
|
/*++
|
|
|
|
Routine Description :
|
|
|
|
Optimize a format string fragment away.
|
|
|
|
Arguments :
|
|
|
|
pNode - CG_NDR node, with format string start
|
|
and end offsets already set.
|
|
|
|
--*/
|
|
{
|
|
unsigned short StartOffset = (unsigned short)
|
|
pNode->GetFormatStringOffset();
|
|
unsigned short EndOffset = (unsigned short)
|
|
pNode->GetFormatStringEndOffset();
|
|
FRMTREG_ENTRY NewFragment( StartOffset, EndOffset );
|
|
FRMTREG_ENTRY * pOldFragment;
|
|
|
|
// perform format string optimization
|
|
|
|
if ( pCommand->IsSwitchDefined( SWITCH_NO_FMT_OPT ) )
|
|
return StartOffset;
|
|
|
|
assert( ( ((short) StartOffset) >= 0 ) &&
|
|
( ((short) EndOffset) >= 0 ) );
|
|
assert ( EndOffset <= LastOffset );
|
|
|
|
// add to dictionary
|
|
|
|
// if match found, reset format string offset back to our start
|
|
if ( GetReuseDict()->GetReUseEntry( pOldFragment, &NewFragment ) )
|
|
{
|
|
unsigned short OldStartOffset = pOldFragment->GetStartOffset();
|
|
|
|
// if we are not the end, we can't do anything about ourselves
|
|
// similarly, if we match ourselves, don't do anything
|
|
if ( ( GetCurrentOffset() == EndOffset ) &&
|
|
( OldStartOffset != StartOffset ) )
|
|
{
|
|
// move format string offset back
|
|
SetCurrentOffset( StartOffset );
|
|
pNode->SetFormatStringOffset( OldStartOffset );
|
|
pNode->SetFormatStringEndOffset( pOldFragment->GetEndOffset() );
|
|
return OldStartOffset;
|
|
}
|
|
} // duplicate found
|
|
|
|
return StartOffset;
|
|
|
|
}
|
|
|
|
|
|
unsigned short
|
|
FORMAT_STRING::RegisterFragment(
|
|
CG_NDR * pNode )
|
|
/*++
|
|
|
|
Routine Description :
|
|
|
|
Register, but do not remove, a format string fragment.
|
|
|
|
Arguments :
|
|
|
|
pNode - CG_NDR node, with format string start offset already set.
|
|
EndOffset - end offset of format string fragment
|
|
|
|
--*/
|
|
{
|
|
unsigned short StartOffset = (unsigned short)
|
|
pNode->GetFormatStringOffset();
|
|
unsigned short EndOffset = (unsigned short)
|
|
pNode->GetFormatStringEndOffset();
|
|
FRMTREG_ENTRY NewFragment( StartOffset, EndOffset );
|
|
FRMTREG_ENTRY * pOldFragment;
|
|
|
|
// perform format string optimization
|
|
if ( pCommand->IsSwitchDefined( SWITCH_NO_FMT_OPT ) )
|
|
return StartOffset;
|
|
|
|
assert( ( ((short) StartOffset) != -1 ) &&
|
|
( ((short) EndOffset) != -1 ) );
|
|
assert ( EndOffset <= LastOffset );
|
|
|
|
// add to dictionary, or return pointer to old entry
|
|
GetReuseDict()->GetReUseEntry( pOldFragment, &NewFragment );
|
|
|
|
return StartOffset;
|
|
|
|
}
|
|
|
|
char *
|
|
CommentDictionary::GetComments(
|
|
short Offset
|
|
)
|
|
{
|
|
CommentDictElem Elem;
|
|
CommentDictElem * pHead;
|
|
CommentDictElem * pElem;
|
|
Dict_Status DictStatus;
|
|
char * Comments;
|
|
long Length;
|
|
|
|
Elem.FormatStringOffset = Offset;
|
|
|
|
DictStatus = Dict_Find( &Elem );
|
|
|
|
if ( DictStatus != SUCCESS )
|
|
return 0;
|
|
|
|
pHead = (CommentDictElem *) Dict_Item();
|
|
|
|
Length = 0;
|
|
|
|
for ( pElem = pHead; pElem; pElem = pElem->Next )
|
|
Length += strlen( pElem->Comment );
|
|
|
|
Comments = new char[Length+1];
|
|
Comments[0] = 0;
|
|
|
|
for ( pElem = pHead; pElem; pElem = pElem->Next )
|
|
strcat( Comments, pElem->Comment );
|
|
|
|
return Comments;
|
|
}
|
|
|
|
void
|
|
CommentDictionary::Insert(
|
|
short FormatStringOffset,
|
|
char * Comment
|
|
)
|
|
{
|
|
CommentDictElem Elem;
|
|
CommentDictElem * pHead;
|
|
CommentDictElem * pElem;
|
|
Dict_Status DictStatus;
|
|
|
|
Elem.FormatStringOffset = FormatStringOffset;
|
|
|
|
DictStatus = Dict_Find( &Elem );
|
|
|
|
if ( DictStatus == SUCCESS )
|
|
pHead = (CommentDictElem *) Dict_Item();
|
|
else
|
|
pHead = 0;
|
|
|
|
pElem = new CommentDictElem;
|
|
|
|
pElem->Next = pHead;
|
|
pElem->FormatStringOffset = FormatStringOffset;
|
|
pElem->Comment = Comment;
|
|
|
|
//
|
|
// We delete any current entry and add a new entry so that comments
|
|
// are always prepended to the list.
|
|
//
|
|
if ( pHead )
|
|
Dict_Delete( (pUserType *) &pHead );
|
|
|
|
Dict_Insert( pElem );
|
|
}
|
|
|