|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996.
//
// File: oleprint.cxx
//
// Contents: printf for API/Method trace
//
// Functions: oleprintf
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
#include <windows.h>
#include <stdarg.h>
#include <ole2sp.h>
#include <ole2com.h>
#if DBG==1
#include "outfuncs.h"
#include "oleprint.hxx"
// *** Constants ***
const char *pscTabString = " "; // 3 space tabs
// *** Types and Enums ***
// Enumeration of basic types
enum { TYP_INT = 0, TYP_UNSIGNED, TYP_HEX, TYP_HEXCAPS, TYP_LARGE, TYP_BOOL, TYP_BOOLCAPS, TYP_POINTER, TYP_POINTERCAPS, TYP_HANDLE, TYP_HANDLECAPS, TYP_STR, TYP_WIDESTR, TYP_GUID, TYP_STRUCT, NO_TYPE };
// Type of parameter printing functions
typedef void (*ParamFunc) (CTextBufferA &buf, va_list ¶m, char *&ppstr);
// Enumeration of Structure types
enum { STRUCT_BIND_OPTS=0, STRUCT_DVTARGETDEVICE, STRUCT_FORMATETC, STRUCT_FILETIME, STRUCT_INTERFACEINFO, STRUCT_LOGPALETTE, STRUCT_MSG, STRUCT_OLEINPLACEFRAMEINFO, STRUCT_OLEMENUGROUPWIDTHS, STRUCT_POINT, STRUCT_RECT, STRUCT_STGMEDIUM, STRUCT_STATSTG, STRUCT_SIZE, NO_STRUCT };
// Type of structure printing functions
typedef void (*WriteFunc) (CTextBufferA &buf, void *pParam);
// *** Prototypes ***
// Functions to handle writing out parameters
static void WriteInt(CTextBufferA &buf, va_list &, char *&); static void WriteUnsigned(CTextBufferA &buf, va_list &, char *&); static void WriteHex(CTextBufferA &buf, va_list &, char *&); static void WriteHexCaps(CTextBufferA &buf, va_list &, char *&); static void WriteLarge(CTextBufferA &buf, va_list &, char *&); static void WriteBool(CTextBufferA &buf, va_list &, char *&); static void WriteBoolCaps(CTextBufferA &buf, va_list &, char *&); static void WritePointer(CTextBufferA &buf, va_list &, char *&); static void WritePointerCaps(CTextBufferA &buf, va_list &, char *&); static void WriteString(CTextBufferA &buf, va_list &, char *&); static void WriteWideString(CTextBufferA &buf, va_list &, char *&); static void WriteGUID(CTextBufferA &buf, va_list &, char *&); static void WriteStruct(CTextBufferA &buf, va_list &, char *&);
// *** Global Data ***
char gPidString[20];
// this table holds the functions for writing base types
static ParamFunc g_pFuncs[] = {WriteInt, WriteUnsigned, WriteHex, WriteHexCaps, WriteLarge, WriteBool, WriteBoolCaps,WritePointer,WritePointerCaps, WriteHex,WriteHexCaps,WriteString, WriteWideString, WriteGUID, WriteStruct, NULL};
// this table starts at 'A' == 65
// This is the base type lookup table -> tells what kind of base type to print out
static const BYTE g_tcLookup[] = {NO_TYPE, TYP_BOOLCAPS, NO_TYPE, TYP_INT, NO_TYPE, // 'A' - 'E'
NO_TYPE, NO_TYPE, NO_TYPE, TYP_GUID, NO_TYPE, // 'F' - 'J'
NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, // 'K' - 'O'
TYP_POINTERCAPS, NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, // 'P' - 'T'
TYP_UNSIGNED, NO_TYPE, NO_TYPE, TYP_HEXCAPS, NO_TYPE, // 'U' - 'Y'
NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, // 'Z' - '^'
NO_TYPE, NO_TYPE, NO_TYPE, TYP_BOOL, NO_TYPE, // '_' - 'c'
TYP_INT, NO_TYPE, NO_TYPE, NO_TYPE, TYP_HANDLE, // 'd' - 'h'
NO_TYPE, NO_TYPE, NO_TYPE, TYP_LARGE, NO_TYPE, // 'i' - 'm'
NO_TYPE, NO_TYPE, TYP_POINTER, NO_TYPE, NO_TYPE, // 'n' - 'r'
TYP_STR, TYP_STRUCT, TYP_UNSIGNED, NO_TYPE, TYP_WIDESTR, // 's' - 'w'
TYP_HEX, NO_TYPE, NO_TYPE}; // 'x' - 'z'
// This holds the functions for writing out structures
static WriteFunc g_pStructFuncs[] = {(WriteFunc) WriteBIND_OPTS, (WriteFunc) WriteDVTARGETDEVICE, (WriteFunc) WriteFORMATETC, (WriteFunc) WriteFILETIME, (WriteFunc) WriteINTERFACEINFO, (WriteFunc) WriteLOGPALETTE, (WriteFunc) WriteMSG, (WriteFunc) WriteOLEINPLACEFRAMEINFO, (WriteFunc) WriteOLEMENUGROUPWIDTHS, (WriteFunc) WritePOINT, (WriteFunc) WriteRECT, (WriteFunc) WriteSTGMEDIUM, (WriteFunc) WriteSTATSTG, (WriteFunc) WriteSIZE, NULL };
// this table starts at 'a' == 97
// this table holds what type of structure to print out
static const BYTE g_structLookup[] = {NO_STRUCT, STRUCT_BIND_OPTS, NO_STRUCT, STRUCT_DVTARGETDEVICE, // 'a' - 'd'
STRUCT_FORMATETC, STRUCT_FILETIME, NO_STRUCT, NO_STRUCT, // 'e' - 'h'
STRUCT_INTERFACEINFO, NO_STRUCT, NO_STRUCT, STRUCT_LOGPALETTE, // 'i' - 'l'
STRUCT_MSG, NO_STRUCT, STRUCT_OLEINPLACEFRAMEINFO, STRUCT_POINT,// 'm' - 'p'
NO_STRUCT, STRUCT_RECT, STRUCT_STGMEDIUM, STRUCT_STATSTG , // 'q' - 't'
NO_STRUCT, NO_STRUCT, STRUCT_OLEMENUGROUPWIDTHS, NO_STRUCT, // 'u' - 'x'
NO_STRUCT, STRUCT_SIZE }; // 'y' - 'z'
//+---------------------------------------------------------------------------
//
// Function: oleprintf
//
// Synopsis: Prints out trace information using a given function, given a
// nesting depth (for indenting), an API/Method name, a format string,
// and a variable number of arguments
//
// Arguments: [depth] - nesting/indentation level
// [pscApiName] - name of API/Method traced
// [pscFormat] - format string
// [argptr] - variable argument list
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void __cdecl oleprintf(int depth, const char *pscApiName, const char *pscFormat, va_list argptr) { // buffer all output so that multithreaded traces look right
CTextBufferA buf; char temp[20]; char *pscPos;
// first print out the process id
buf << gPidString;
buf << '.';
// now print out the thread id
_itoa(GetCurrentThreadId(), temp, 10);
buf << temp; buf << "> ";
// tab to nesting/indent depth
while(depth-- > 0) { buf << pscTabString; }
// now print out API name
buf << pscApiName;
// now we are ready to print out what was passed
pscPos = strchr(pscFormat, '%');
while(pscPos != NULL) { // insert the text up to the found '%' character into the buffer
buf.Insert(pscFormat, (int)(pscPos-pscFormat));
if(*(pscPos+1) == '%') // this is '%%', we only print one '%' and don't print an argument
{ buf << *pscPos; pscFormat = pscPos+2; } else { BYTE argType = NO_TYPE;
// advance pscPos to type specifier
pscPos++;
// we need to take an argument and handle it
if(*pscPos >= 'A' && *pscPos <= 'z') { argType = g_tcLookup[*pscPos- 'A']; }
if(argType != NO_TYPE) { // handle argument
// function will advance pscPos past format specifier
g_pFuncs[argType](buf, argptr, pscPos); } else { // assume we've got a one character format specifier
pscPos++; // unknown type, assume size of int
va_arg(argptr, int); }
// advance search pointer past type specifier
pscFormat = pscPos; }
pscPos = strchr(pscFormat, '%'); }
// print out remainder of string
buf << pscFormat;
// destructor will flush buffer for us
}
//+---------------------------------------------------------------------------
//
// Function: WriteHex
//
// Synopsis: Prints out a lower case hex value
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteHex(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteHexCommon(buf, va_arg(param, unsigned long), FALSE);
//advance format pointer
pFormat++; }
//+---------------------------------------------------------------------------
//
// Function: WriteHexCaps
//
// Synopsis: Prints out an upper case hex value
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteHexCaps(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteHexCommon(buf, va_arg(param, unsigned long), TRUE);
//advance format pointer
pFormat++; }
//+---------------------------------------------------------------------------
//
// Function: WriteInt
//
// Synopsis: Prints out a signed integer value
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteInt(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteIntCommon(buf, va_arg(param, unsigned int), FALSE);
// advance pointer
pFormat++; }
//+---------------------------------------------------------------------------
//
// Function: WriteUnsigned
//
// Synopsis: Prints out a unsigned value, may be 64 bit or 32 bit
// depending on next character in format specifier
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteUnsigned(CTextBufferA &buf, va_list ¶m, char *&pFormat) { switch(*(pFormat+1)) // next character determines type
{ case 'd': // 32-bit
case 'D': WriteIntCommon(buf, va_arg(param, unsigned long), TRUE);
// Advance format pointer
pFormat+=2; break;
case 'l': // 64-bit
case 'L': WriteLargeCommon(buf, va_arg(param, __int64 *), TRUE);
// advance format pointer
if(*(pFormat+2) == 'd' || *(pFormat+2) == 'D') { pFormat+=3; } else { pFormat+=2; } break;
default: pFormat++; // assume it's just one char-type specifier
break; } }
//+---------------------------------------------------------------------------
//
// Function: WritePointer
//
// Synopsis: Prints out a lower case pointer value,
// checks to make sure pointer is good value
// prints out symbol if a symbol maps to pointer
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WritePointer(CTextBufferA &buf, va_list ¶m, char *&pFormat) { if(*(pFormat+1) != 'p') { WritePointerCommon(buf, va_arg(param, void *), FALSE, FALSE, FALSE);
pFormat++; } else { void **pPointer; BufferContext bc;
// take snapshot of buffer
buf.SnapShot(bc);
// write pointer to pointer
// first validate this pointer
__try { pPointer = va_arg(param, void **);
WritePointerCommon(buf, *pPointer, FALSE, FALSE, FALSE); } __except(ExceptionFilter(_exception_code())) { // try to revert buffer
buf.Revert(bc);
WritePointerCommon(buf, pPointer, FALSE, TRUE, FALSE); }
pFormat +=2; } }
//+---------------------------------------------------------------------------
//
// Function: WritePointerCaps
//
// Synopsis: Prints out an upper case pointer value,
// checks to make sure pointer is good value
// prints out symbol if a symbol maps to pointer
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WritePointerCaps(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WritePointerCommon(buf, va_arg(param, void *), TRUE, FALSE, FALSE);
pFormat++; }
//+---------------------------------------------------------------------------
//
// Function: WriteLarge
//
// Synopsis: Prints out a 64-bit integer
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteLarge(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteLargeCommon(buf, va_arg(param, __int64 *), FALSE);
if(*(pFormat+1) == 'd' || *(pFormat+1) == 'D') { pFormat+=2; } else { pFormat++; }
}
//+---------------------------------------------------------------------------
//
// Function: WriteBool
//
// Synopsis: Prints out a lower case boolean value
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteBool(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteBoolCommon(buf, va_arg(param, BOOL), FALSE);
pFormat++; }
//+---------------------------------------------------------------------------
//
// Function: WriteBoolCaps
//
// Synopsis: Prints out an upper case boolean value
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteBoolCaps(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteBoolCommon(buf, va_arg(param, BOOL), TRUE);
pFormat++; }
//+---------------------------------------------------------------------------
//
// Function: WriteString
//
// Synopsis: Prints out an ASCII string
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteString(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteStringCommon(buf, va_arg(param, const char *));
// Advance format pointer
pFormat++; }
//+---------------------------------------------------------------------------
//
// Function: WriteWideString
//
// Synopsis: Prints out a UNICODE string, but only supports ASCII characters
// if character > 256 is encountered, an "unprintable character" char
// is printed
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteWideString(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteWideStringCommon(buf, va_arg(param, const WCHAR *));
// Advance format pointer
if(*(pFormat+1) == 's') { pFormat+=2; } else { pFormat++; } }
//+---------------------------------------------------------------------------
//
// Function: WriteGUID
//
// Synopsis: Prints out a GUID
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteGUID(CTextBufferA &buf, va_list ¶m, char *&pFormat) { WriteGUIDCommon(buf, va_arg(param, GUID *));
// Advance format pointer
pFormat++; }
//+---------------------------------------------------------------------------
//
// Function: WriteStuct
//
// Synopsis: Prints out a structure. If structure expansion is enabled
// expands the structure depending on it's type
//
// Arguments: [buf] - reference to text buffer to write text to
// [param] - reference to variable argument list
// [pFormat] - reference to a char * to the format string,
// used to advance string past specifier string
//
// Returns: nothing
//
// History: 11-Jul-95 t-stevan Created
//
//----------------------------------------------------------------------------
void WriteStruct(CTextBufferA &buf, va_list ¶m, char *&pFormat) { void *pArg; BYTE bType = NO_STRUCT;
pArg = va_arg(param, void *);
if(*(pFormat+1) >= 'a' && *(pFormat+1) <= 'z') { bType = g_structLookup[*(pFormat+1) - 'a']; }
if(bType != NO_STRUCT) // only print out known structures
{ BufferContext bc;
buf.SnapShot(bc); // take a snapshot of the buffer
__try { g_pStructFuncs[bType](buf, pArg); } __except (ExceptionFilter(_exception_code())) { buf.Revert(bc); // try to revert to the old buffer
// bad pointer
WritePointerCommon(buf, pArg, FALSE, TRUE, FALSE); } } else { // write out the pointer
WritePointerCommon(buf, pArg, FALSE, FALSE, FALSE); }
// increment format pointer
pFormat += 2; }
#endif // DBG==1
|