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.
689 lines
15 KiB
689 lines
15 KiB
/*++
|
|
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
bufout.cxx
|
|
|
|
Abstract:
|
|
|
|
|
|
Author:
|
|
|
|
David Kays (dkays) August 1 1994
|
|
|
|
Revision History:
|
|
|
|
Ryszardk Aug-Sep 94 A lot of pretty & silent printing
|
|
More FC codes.
|
|
|
|
--*/
|
|
|
|
#include <sysinc.h>
|
|
#include <rpc.h>
|
|
#include <rpcndr.h>
|
|
|
|
#include <ntsdexts.h>
|
|
#include <ntdbg.h>
|
|
|
|
extern "C" {
|
|
#include "global.c"
|
|
}
|
|
#include "ndrtypes.h"
|
|
#include "ndrp.h"
|
|
|
|
#include "bufout.hxx"
|
|
#include "regkeys.hxx"
|
|
|
|
long POINTER::IdCounter = 1;
|
|
|
|
char * FormatCharNames[] =
|
|
{
|
|
"FC_ZERO",
|
|
"byte",
|
|
"char",
|
|
"small",
|
|
"usmall",
|
|
"wchar",
|
|
"short",
|
|
"ushort",
|
|
"long",
|
|
"ulong",
|
|
"float",
|
|
"hyper",
|
|
"double",
|
|
"enum16",
|
|
"enum32",
|
|
"ignore",
|
|
"error_status_t",
|
|
"ref ptr",
|
|
"unique ptr",
|
|
"object ptr",
|
|
"full ptr",
|
|
|
|
"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_PICKLE_HANDLE",
|
|
|
|
"FC_POINTER",
|
|
|
|
"FC_ALIGNM2",
|
|
"FC_ALIGNM4",
|
|
"FC_ALIGNM8",
|
|
"FC_ALIGNB2",
|
|
"FC_ALIGNB4",
|
|
"FC_ALIGNB8",
|
|
|
|
"FC_STRUCTPAD1",
|
|
"FC_STRUCTPAD2",
|
|
"FC_STRUCTPAD3",
|
|
"FC_STRUCTPAD4",
|
|
"FC_STRUCTPAD5",
|
|
"FC_STRUCTPAD6",
|
|
"FC_STRUCTPAD7",
|
|
|
|
"FC_STRING_SIZED",
|
|
"FC_STRING_NO_SIZE",
|
|
|
|
"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",
|
|
|
|
// ** Gap before new format string types **
|
|
|
|
"FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES", "FC_RES",
|
|
"FC_RES",
|
|
|
|
// ** Gap before new format string types end **
|
|
|
|
//
|
|
// Post NT 3.5 format characters.
|
|
//
|
|
|
|
// Hard struct
|
|
|
|
"FC_HARD_STRUCT", // 0xb1
|
|
|
|
"FC_TRANSMIT_AS_PTR", // 0xb2
|
|
"FC_REPRESENT_AS_PTR", // 0xb3
|
|
|
|
"FC_END_OF_UNIVERSE", // 0xb4
|
|
|
|
""
|
|
};
|
|
|
|
//
|
|
// BUFFER
|
|
//
|
|
|
|
void
|
|
BUFFER::Align( long Mask )
|
|
{
|
|
BufferCurrent = (char *) (((long)BufferCurrent + Mask) & ~ Mask);
|
|
}
|
|
|
|
void
|
|
BUFFER::Read( char * Buffer, long Length )
|
|
{
|
|
for ( ; Length--; )
|
|
{
|
|
*Buffer++ = *BufferCurrent++;
|
|
}
|
|
}
|
|
|
|
void
|
|
BUFFER::Read( char * Buffer, long Length, long Offset )
|
|
{
|
|
for ( ; Length--; )
|
|
{
|
|
*Buffer++ = BufferBegin[ Offset++ ];
|
|
}
|
|
}
|
|
|
|
//
|
|
// FORMAT_STRING
|
|
//
|
|
|
|
BOOL
|
|
FORMAT_STRING::Read( long Offset, uchar * Buffer, long Length )
|
|
{
|
|
BOOL Status;
|
|
|
|
Status = ReadProcessMemory(
|
|
hProcessHandle,
|
|
(void *)((long)Address + Offset),
|
|
(char *)Buffer,
|
|
Length,
|
|
NULL );
|
|
|
|
return Status;
|
|
}
|
|
|
|
char *
|
|
FORMAT_STRING::GetFormatCharName( uchar FC )
|
|
{
|
|
return (0 <= FC && FC <= FC_END)
|
|
? FormatCharNames[ FC ]
|
|
: "FC unknown" ;
|
|
}
|
|
|
|
//
|
|
// NDR
|
|
//
|
|
|
|
NDR *
|
|
NDR::Create(
|
|
long FormatOffset,
|
|
NDR * ParentNdr )
|
|
{
|
|
uchar FormatType;
|
|
|
|
FormatString->Read( FormatOffset, &FormatType, 1 );
|
|
|
|
return( Create( FormatType,
|
|
FormatOffset,
|
|
ParentNdr ) );
|
|
}
|
|
|
|
NDR *
|
|
NDR::Create(
|
|
uchar FormatType,
|
|
long FormatOffset,
|
|
NDR * ParentNdr )
|
|
{
|
|
if ( IS_SIMPLE_TYPE(FormatType) )
|
|
{
|
|
return new BASETYPE( ParentNdr, FormatType );
|
|
}
|
|
|
|
if ( FormatType == FC_EMBEDDED_COMPLEX )
|
|
{
|
|
uchar Format[4];
|
|
|
|
FormatString->Read( FormatOffset, Format, 4 );
|
|
FormatOffset = FormatOffset + 2 + GET_SHORT(Format + 2);
|
|
FormatString->Read( FormatOffset, Format, 1 );
|
|
FormatType = Format[0];
|
|
}
|
|
|
|
switch ( (unsigned char)FormatType )
|
|
{
|
|
case FC_RP :
|
|
case FC_UP :
|
|
case FC_FP :
|
|
case FC_OP :
|
|
return new POINTER( ParentNdr, FormatOffset );
|
|
|
|
case FC_IP :
|
|
return new IF_POINTER( ParentNdr, FormatOffset );
|
|
|
|
case FC_STRUCT :
|
|
case FC_PSTRUCT :
|
|
|
|
case FC_HARD_STRUCT :
|
|
|
|
case FC_CSTRUCT :
|
|
case FC_CPSTRUCT :
|
|
|
|
case FC_CVSTRUCT:
|
|
case FC_BOGUS_STRUCT:
|
|
return new STRUCTURE( ParentNdr, FormatOffset );
|
|
|
|
case FC_SMFARRAY :
|
|
case FC_LGFARRAY :
|
|
|
|
case FC_CARRAY :
|
|
|
|
case FC_CVARRAY :
|
|
|
|
case FC_SMVARRAY :
|
|
case FC_LGVARRAY :
|
|
|
|
case FC_BOGUS_ARRAY :
|
|
return new ARRAY( ParentNdr, FormatOffset );
|
|
|
|
case FC_NON_ENCAPSULATED_UNION :
|
|
return new UNION( ParentNdr, FormatOffset );
|
|
|
|
case FC_ENCAPSULATED_UNION :
|
|
return new ENCAPSULATED_UNION( ParentNdr, FormatOffset );
|
|
|
|
case FC_C_CSTRING :
|
|
case FC_C_WSTRING :
|
|
case FC_C_BSTRING :
|
|
case FC_C_SSTRING :
|
|
case FC_CSTRING :
|
|
case FC_WSTRING :
|
|
case FC_BSTRING :
|
|
case FC_SSTRING :
|
|
return new NDRSTRING( ParentNdr, FormatOffset );
|
|
|
|
case FC_TRANSMIT_AS :
|
|
case FC_REPRESENT_AS :
|
|
return new XMIT_AS( ParentNdr, FormatOffset );
|
|
|
|
default :
|
|
{
|
|
ABORT2( "NDR::Create aborting, FormatType %s=0x%x not supported\n",
|
|
FormatString->GetFormatCharName( FormatType ),
|
|
FormatType );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
PTR_DICT *
|
|
NDR::GetParentDict()
|
|
{
|
|
if ( ParentNdr )
|
|
{
|
|
return( ParentNdr->GetPointerDict() );
|
|
}
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// PROCEDURE
|
|
//
|
|
|
|
void
|
|
PROCEDURE::Output()
|
|
{
|
|
PARAMETER * Param;
|
|
long ParamNumber;
|
|
char Format;
|
|
BOOL IsClient, IsServer;
|
|
BOOL CommonPrintMode;
|
|
|
|
if ( fOutputLimitReached )
|
|
return;
|
|
|
|
// Default setting of the debugger is such that we assume to be
|
|
// unmarshalling the buffer on the side indicating by the stub.
|
|
// This means that when on server side, display the [in] arguments
|
|
// and when on the client side, display the [out] argumets.
|
|
|
|
// However, the marshalling registry key reverses that, if set.
|
|
|
|
IsClient = pStubMsg->IsClient;
|
|
|
|
if ( NdrRegKeyMarshalling )
|
|
IsClient = ! IsClient;
|
|
|
|
IsServer = ! IsClient;
|
|
|
|
// For pickling, we need to skip the proc header in the format string.
|
|
|
|
if ( NdrRegKeyPickling == 1 )
|
|
{
|
|
ProcFormatString += ( *ProcFormatString == 0 ) ? 10 : 6;
|
|
}
|
|
|
|
CommonPrintMode = (ChosenParamNo == 0) ? NORMAL_PRINT
|
|
: SILENT_PRINT;
|
|
ParamNumber = 1;
|
|
|
|
for( ; ; ProcFormatString += (Format == FC_IN_PARAM_BASETYPE) ? 2 : 4,
|
|
ParamNumber++ )
|
|
{
|
|
if ( ParamNumber == ChosenParamNo )
|
|
SetPrintMode( NORMAL_PRINT );
|
|
else
|
|
SetPrintMode( CommonPrintMode );
|
|
|
|
switch ( Format = *ProcFormatString )
|
|
{
|
|
case FC_IN_PARAM :
|
|
case FC_IN_PARAM_BASETYPE :
|
|
case FC_IN_PARAM_NO_FREE_INST :
|
|
if ( IsServer )
|
|
{
|
|
Param = new PARAMETER(
|
|
this,
|
|
ProcFormatString,
|
|
ParamNumber );
|
|
Param->Output();
|
|
|
|
delete Param;
|
|
}
|
|
|
|
break;
|
|
|
|
case FC_IN_OUT_PARAM :
|
|
Param = new PARAMETER(
|
|
this,
|
|
ProcFormatString,
|
|
ParamNumber );
|
|
Param->Output();
|
|
|
|
delete Param;
|
|
break;
|
|
|
|
case FC_OUT_PARAM :
|
|
case FC_RETURN_PARAM_BASETYPE :
|
|
case FC_RETURN_PARAM :
|
|
if ( IsClient )
|
|
{
|
|
Param = new PARAMETER(
|
|
this,
|
|
ProcFormatString,
|
|
ParamNumber );
|
|
Param->Output();
|
|
|
|
delete Param;
|
|
}
|
|
|
|
if ( Format != FC_OUT_PARAM )
|
|
{
|
|
if ( ParamNumber <= ChosenParamNo )
|
|
{
|
|
SetPrintMode( NORMAL_PRINT );
|
|
Print( "There were only %d parameters\n",
|
|
ParamNumber - 1);
|
|
}
|
|
Print( "***** End of Parameters *****\n\n" );
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case FC_END :
|
|
if ( ParamNumber <= ChosenParamNo )
|
|
{
|
|
SetPrintMode( NORMAL_PRINT );
|
|
Print( "There were only %d parameters\n", ParamNumber - 1);
|
|
}
|
|
Print( "***** End of Parameters *****\n\n" );
|
|
return;
|
|
|
|
default :
|
|
Print( "PROCEDURE::Output Error\n" );
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// PARAMETER
|
|
//
|
|
|
|
void
|
|
PARAMETER::Output()
|
|
{
|
|
NDR * Ndr;
|
|
long Offset;
|
|
uchar FormatType;
|
|
char *ParamKind;
|
|
|
|
if ( fOutputLimitReached )
|
|
return;
|
|
|
|
switch ( *ParamFormatString )
|
|
{
|
|
case FC_IN_PARAM :
|
|
case FC_IN_PARAM_BASETYPE :
|
|
case FC_IN_PARAM_NO_FREE_INST :
|
|
ParamKind = "[in] only";
|
|
break;
|
|
case FC_IN_OUT_PARAM :
|
|
ParamKind = "[in,out]";
|
|
break;
|
|
case FC_OUT_PARAM :
|
|
ParamKind = "[out] only";
|
|
break;
|
|
case FC_RETURN_PARAM :
|
|
case FC_RETURN_PARAM_BASETYPE :
|
|
ParamKind = "the return value";
|
|
break;
|
|
default :
|
|
ABORT2( "Parameter aborting expected a parameter FC, found %s=0x%x.\n",
|
|
FormatString->GetFormatCharName( *ParamFormatString ),
|
|
*ParamFormatString );
|
|
break;
|
|
}
|
|
|
|
Print( "***** Parameter #%d is ", ParamNumber );
|
|
Print( "%s *****\n\n", ParamKind );
|
|
|
|
switch ( *ParamFormatString )
|
|
{
|
|
case FC_IN_PARAM_BASETYPE :
|
|
if ( ParamFormatString[1] == FC_IGNORE )
|
|
{
|
|
Print(" Primitive handle: ignored (nothing in the buffer)\n" );
|
|
break;
|
|
}
|
|
// else fall thru
|
|
|
|
case FC_RETURN_PARAM_BASETYPE :
|
|
Offset = -1;
|
|
FormatType = ParamFormatString[1];
|
|
break;
|
|
|
|
default :
|
|
ParamFormatString += 2;
|
|
Offset = (long) *((short *)ParamFormatString);
|
|
FormatString->Read( Offset, &FormatType, 1 );
|
|
break;
|
|
}
|
|
|
|
Ndr = Create( FormatType,
|
|
Offset,
|
|
this );
|
|
|
|
Ndr->Output();
|
|
|
|
Print( "\n" );
|
|
|
|
delete Ndr;
|
|
}
|
|
|
|
//
|
|
// BASETYPE
|
|
//
|
|
|
|
// Spaces needed for pretty printing.
|
|
|
|
char * FcTypeName[] =
|
|
{
|
|
"FC_ZERO??",
|
|
"byte ",
|
|
"char ",
|
|
"small ",
|
|
"usmall ",
|
|
"wchar ",
|
|
"short ",
|
|
"ushort ",
|
|
"long ",
|
|
"ulong ",
|
|
"float ",
|
|
"hyper ",
|
|
"double ",
|
|
"enum16 ",
|
|
"enum32 ",
|
|
"ignore ",
|
|
"err_st_t",
|
|
"ref ptr",
|
|
"uniq ptr",
|
|
"obj ptr",
|
|
"full ptr"
|
|
};
|
|
|
|
char * Layout[] =
|
|
{
|
|
"??\n",
|
|
" %02x",
|
|
" %04x",
|
|
"??\n",
|
|
" %08x",
|
|
"??\n",
|
|
"??\n",
|
|
"??\n",
|
|
" %08x"
|
|
};
|
|
|
|
long ArrPrintCount = -1;
|
|
|
|
void
|
|
BASETYPE::Output()
|
|
{
|
|
long ReadSize = 1, NoPerLine;
|
|
union
|
|
{
|
|
ulong Long;
|
|
_int64 Hyper;
|
|
} Value;
|
|
|
|
if ( fOutputLimitReached )
|
|
return;
|
|
|
|
Value.Hyper = 0;
|
|
|
|
if ( IS_SIMPLE_TYPE( Format ) )
|
|
{
|
|
Buffer->Align( SIMPLE_TYPE_ALIGNMENT(Format) );
|
|
ReadSize = SIMPLE_TYPE_BUFSIZE(Format);
|
|
}
|
|
else
|
|
ReadSize = 4;
|
|
Buffer->Read( (char *)&Value.Hyper, ReadSize );
|
|
|
|
if ( ReadSize == 0 )
|
|
{
|
|
// Something is wrong of course, I still would like to see it, though.
|
|
|
|
ReadSize = 1;
|
|
}
|
|
|
|
if ( ReadSize == 4 )
|
|
{
|
|
// Check if the long is a pointer in a struct.
|
|
|
|
POINTER * pPointer = NULL;
|
|
long PtrBO = Buffer->GetCurrentOffset() - 4;
|
|
|
|
if ( ParentNdr->GetID() == ID_STRUCT )
|
|
{
|
|
pPointer = ParentNdr->GetPointerDict()->GetPointerMember( PtrBO );
|
|
}
|
|
|
|
if ( pPointer )
|
|
{
|
|
PrintIndent();
|
|
Print( "%s %08x\t<id= %d>\n",
|
|
FcTypeName[ pPointer->GetPointerFC() ],
|
|
Value.Long,
|
|
pPointer->GetPointerId() );
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Print the simple type member.
|
|
// If in array, print several members per line.
|
|
|
|
if ( ParentNdr->GetID() == ID_ARRAY )
|
|
{
|
|
if ( ArrPrintCount == -1 )
|
|
ArrPrintCount = 0;
|
|
}
|
|
else
|
|
ArrPrintCount = -1;
|
|
|
|
NoPerLine = 16 / ReadSize;
|
|
|
|
if ( ArrPrintCount == -1 || (ArrPrintCount % NoPerLine) == 0 )
|
|
{
|
|
PrintIndent();
|
|
Print( "%s ", FcTypeName[ Format ] );
|
|
}
|
|
|
|
Print( Layout[ ReadSize ], Value.Long );
|
|
if ( ReadSize == 8 )
|
|
Print( "-%08x", (unsigned long) (Value.Hyper >> 32) );
|
|
|
|
if ( ArrPrintCount == -1 ||
|
|
ArrPrintCount != -1 && (++ArrPrintCount % NoPerLine) == 0 )
|
|
Print( "\n" );
|
|
}
|
|
|
|
|
|
|