NT4/private/ole32/com/util/olespy.cxx
2020-09-30 17:12:29 +02:00

583 lines
13 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: rpcspy.cxx
//
// Contents: rpcspy functions
//
// Classes:
//
// Functions:
//
// History: 7-06-95 JohannP (Johann Posch) Created
//
//----------------------------------------------------------------------------
#include <ole2int.h>
#pragma hdrstop
#if DBG==1
#include <smmutex.hxx>
#ifdef DCOM
#include <dscm.h>
#include <getif.h>
#include <objsrv.h>
#include <remunk.h>
#include <odeth.h>
#endif // DCOM
#include <outfuncs.h>
#include "srvhdl.h"
#include "OleSpy.hxx"
#include "SpyClnt.hxx"
#include <trace.hxx>
void SetTraceInfoLevel(DWORD dwLevel);
int OleSpySendEntry(char * szOutBuf);
char szOutBuffer[2048];
typedef enum
{
OleSpy_None = 0
,OleSpy_Rpc = 1
,OleSpy_API = 2
,OleSpy_Method = 4
,OleSpy_OleThk = 8
} OleSpy;
// OleSpy output options
typedef enum
{
OleSpyOut_None = 0
,OleSpyOut_Debugger = 1
,OleSpyOut_OleSpy = 2
} OleSpyOut;
// interface to interface name and method mapping
typedef struct _tagIIDMethodNames
{
IID const *piid;
char *pszInterface;
char **ppszMethodNames;
} IIDMethodNames;
DWORD nInCount = 0;
DWORD nOutCount = 0;
DWORD OleSpyOpt = OleSpy_None;
DWORD OleSpyOutput = OleSpyOut_None;
DWORD OleSpyBreakForUnknownCalls = 0;
// internal interfaces
IID IID_IRpcService = {0x0000001aL, 0, 0};
IID IID_IRpcSCM = {0x0000001bL, 0, 0};
IID IID_IRpcCoAPI = {0x0000001cL, 0, 0};
IID IID_IRpcDragDrop= {0x0000001dL, 0, 0};
CHAR szSendBuf[OUT_BUF_SIZE] = ""; // Buffer used to modify message.
IIDMethodNames *GetIIDMethodName(REFIID riid);
//
// switch on to trace rpc calls
// by setting CairoleInfoLevel = DEB_USER1;
//
//
#define NESTING_SPACES 32
#define SPACES_PER_LEVEL 3
static char achSpaces[NESTING_SPACES+1] = " ";
WORD wlevel = 0;
char tabs[128];
//+---------------------------------------------------------------------------
//
// Method: PushLevel
//
// Synopsis:
//
// Arguments: (none)
//
// History: 3-31-95 JohannP (Johann Posch) Created
//
//----------------------------------------------------------------------------
void PushLevel()
{
wlevel++;
}
//+---------------------------------------------------------------------------
//
// Method: PopLevel
//
// Synopsis:
//
// History: 3-31-95 JohannP (Johann Posch) Created
//
//----------------------------------------------------------------------------
void PopLevel()
{
if (wlevel)
wlevel--;
}
//+---------------------------------------------------------------------------
//
// Method: NestingSpaces
//
// Synopsis:
//
// Arguments: [psz] --
//
// Returns:
//
// History: 3-31-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
void NestingSpaces(char *psz)
{
int iSpaces, i;
iSpaces = wlevel * SPACES_PER_LEVEL;
while (iSpaces > 0)
{
i = min(iSpaces, NESTING_SPACES);
memcpy(psz, achSpaces, i);
psz += i;
*psz = 0;
iSpaces -= i;
}
}
//+---------------------------------------------------------------------------
//
// Method: GetTabs
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 3-31-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
LPSTR GetTabs()
{
static char ach[256];
char *psz;
wsprintfA(ach, "%2d:", wlevel);
psz = ach+strlen(ach);
if (sizeof(ach)/SPACES_PER_LEVEL <= wlevel)
{
strcpy(psz, "...");
}
else
{
NestingSpaces(psz);
}
return ach;
}
//+---------------------------------------------------------------------------
//
// Function: UninitializeOleSpy
//
// Synopsis:
//
// Arguments: [dwLevel] --
//
// Returns:
//
// History: 11-22-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT UninitializeOleSpy(DWORD dwLevel)
{
if (dwLevel == OLESPY_TRACE)
{
CleanupTraceInfo();
}
return NOERROR;
}
//+---------------------------------------------------------------------------
//
// Function: InitializeOleSpy
//
// Synopsis:
//
// Arguments: [dwReserved] --
//
// Returns:
//
// History: 11-18-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT InitializeOleSpy(DWORD dwLevel)
{
CHAR szOleSpyInfo[] = "OleSpy";
CHAR szServerName[SERVERNAMEMAX] = ".";
CHAR *pszServerName = szServerName;
CHAR szValue[20];
DWORD cbValue = sizeof(szValue);
ULONG ulValue = 0x0003;
if (dwLevel == OLESPY_TRACE)
{
InitializeTraceInfo();
return NOERROR;
}
if (GetProfileStringA(szOleSpyInfo,"Output","",szServerName,SERVERNAMEMAX) )
{
// check if debugger was specified
if (_stricmp(szServerName, "debugger") == 0)
{
// output should go to the debugger
OleSpyOutput = OleSpyOut_Debugger;
AddOutputFunction((StringOutFunc) OutputDebugStringA);
}
else
{
pszServerName = szServerName;
// "." means OleSpy on local machine
// strip of the leading backslash
while(*pszServerName == '\\')
{
pszServerName++;
}
if (strlen(pszServerName))
{
OleSpyOutput = OleSpyOut_OleSpy;
AddOutputFunction((StringOutFunc) SendEntry);
}
}
}
if (OleSpyOutput == OleSpyOut_None)
{
// nothing to do
return NOERROR;
}
//
if (GetProfileStringA(szOleSpyInfo, "TraceRpc", "0x0000", szValue,cbValue))
{
ulValue = strtoul (szValue, NULL, 16);
if (ulValue)
{
OleSpyOpt |= OleSpy_Rpc;
}
}
if (GetProfileStringA(szOleSpyInfo, "TraceAPI", "0x0000", szValue,cbValue))
{
ulValue = strtoul (szValue, NULL, 16);
if (ulValue)
{
OleSpyOpt |= OleSpy_API;
SetTraceInfoLevel(ulValue);
}
}
if (GetProfileStringA(szOleSpyInfo, "TraceMethod", "0x0000", szValue,cbValue))
{
ulValue = strtoul (szValue, NULL, 16);
if (ulValue)
{
OleSpyOpt |= OleSpy_Method;
}
}
if (GetProfileStringA(szOleSpyInfo, "TraceOlethk", "0x0000", szValue,cbValue))
{
ulValue = strtoul (szValue, NULL, 16);
if (ulValue)
{
OleSpyOpt |= OleSpy_OleThk;
}
}
if (GetProfileStringA(szOleSpyInfo, "BreakForUnknownCalls", "0x0000", szValue,cbValue))
{
ulValue = strtoul (szValue, NULL, 16);
if (ulValue)
{
OleSpyBreakForUnknownCalls = 1;
}
}
if (OleSpyOutput == OleSpyOut_OleSpy)
{
// initialize client if output goes to OleSpy
InitClient(pszServerName);
}
return NOERROR;
}
//+---------------------------------------------------------------------------
//
// Function: OutputToOleSpy
//
// Synopsis:
//
// Arguments: [iOption] --
// [pscFormat] --
//
// Returns:
//
// History: 11-18-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
void OutputToOleSpy(int iOption, const char *pscFormat, ...)
{
va_list args;
va_start(args, pscFormat);
wvsprintfA(szOutBuffer, pscFormat, args);
va_end(args);
switch (OleSpyOutput)
{
default:
case OleSpyOut_None:
break;
case OleSpyOut_Debugger:
OutputDebugStringA(szSendBuf);
break;
case OleSpyOut_OleSpy:
SendEntry(szOutBuffer);
break;
}
}
//+---------------------------------------------------------------------------
//
// Method: RpcSpyOutput
//
// Synopsis:
//
// Arguments: [mode] -- in or out call
// [iid] -- interface id
// [dwMethod] -- called method
// [hres] -- hresult of finished call
//
// Returns:
//
// History: 3-31-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
void RpcSpyOutput(RPCSPYMODE mode , LPVOID pv, REFIID iid, DWORD dwMethod, HRESULT hres)
{
WCHAR wszName[100];
if(OleSpyOutput == OleSpyOut_None)
{
// nothing to do
return;
}
// turn of the 800xx in dwMethod
WORD wMethod = (WORD) (dwMethod & 0x000000FF);
char * szInterfaceName = "Unknown";
char * szMethodName = "Unknown";
IIDMethodNames *pIidMethName = 0;
if (pIidMethName = GetIIDMethodName(iid) )
{
szInterfaceName = pIidMethName->pszInterface;
if (wMethod > 32)
{
szMethodName = "InvalidMethod";
}
else
{
szMethodName = pIidMethName->ppszMethodNames[wMethod];
}
}
else
{
if (OleSpyBreakForUnknownCalls)
{
DebugBreak();
}
}
switch (mode)
{
default:
return;
case CALLIN_BEGIN:
wsprintfA(szSendBuf,"%4ld,%s<<< %s (%lx), %s \n",nInCount, GetTabs(), szInterfaceName, pv, szMethodName );
PushLevel();
nInCount++;
break;
case CALLIN_END:
PopLevel();
wsprintfA(szSendBuf,"%4ld,%s=== %s (%lx), %s (%lx) \n", nInCount-1, GetTabs(), szInterfaceName, pv, szMethodName, hres);
break;
case CALLIN_TRACE:
wsprintfA(szSendBuf," %s\n",(LPSTR) hres);
break;
case CALLIN_QI:
{
PopLevel();
wsprintfA(szSendBuf," %s!!! QI for: %s, %s (%lx) \n",GetTabs(), szInterfaceName, dwMethod ? "S_OK" : "E_NOINTERFACE", hres);
PushLevel();
}
break;
case CALLIN_ERROR:
break;
case CALLOUT_BEGIN:
wsprintfA(szSendBuf,"%4ld,%s>>> %s (%lx), %s \n",nOutCount, GetTabs(), szInterfaceName, pv, szMethodName );
nOutCount++;
PushLevel();
break;
case CALLOUT_TRACE:
break;
case CALLOUT_ERROR:
wsprintfA(szSendBuf,"%s!!! %s, %s, error:%lx \n",GetTabs(), szInterfaceName, szMethodName, hres);
break;
case CALLOUT_END:
PopLevel();
wsprintfA(szSendBuf,"%4ld,%s=== %s (%lx), %s (%lx) \n",nOutCount-1,GetTabs(), szInterfaceName, pv, szMethodName, hres);
break;
}
switch (OleSpyOutput)
{
default:
case OleSpyOut_None:
break;
case OleSpyOut_Debugger:
OutputDebugStringA(szSendBuf);
break;
case OleSpyOut_OleSpy:
SendEntry(szSendBuf);
break;
}
}
//+---------------------------------------------------------------------------
//
// Function: OleSpySendEntry
//
// Synopsis:
//
// Arguments: [szOutBuf] --
//
// Returns:
//
// History: 09-22-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
int OleSpySendEntry(char * szOutBuf)
{
switch (OleSpyOutput)
{
default:
case OleSpyOut_None:
break;
case OleSpyOut_Debugger:
OutputDebugStringA(szOutBuf);
break;
case OleSpyOut_OleSpy:
SendEntry(szOutBuf);
break;
}
return 1;
}
#include "ifnames.cxx"
//+---------------------------------------------------------------------------
//
// Function: GetIIDMethodName
//
// Synopsis:
//
// Arguments: [riid] --
//
// Returns:
//
// History: 06-18-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
IIDMethodNames *GetIIDMethodName(REFIID riid)
{
int idx;
int cElements = sizeof(IidMethodNames) / sizeof(IidMethodNames[0]);
for (idx = 0; idx < cElements; idx++)
{
if (IsEqualIID(riid, *IidMethodNames[idx].piid))
{
return &(IidMethodNames[idx]);
}
}
return NULL;
}
//+---------------------------------------------------------------------------
//
// Function: GetInterfaceName
//
// Synopsis:
//
// Arguments: [iid] --
//
// Returns:
//
// History: 06-18-95 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
LPSTR GetInterfaceName(REFIID iid)
{
IIDMethodNames *pIidMethName = 0;
LPSTR szInterfaceName = NULL;
if (pIidMethName = GetIIDMethodName(iid) )
{
szInterfaceName = pIidMethName->pszInterface;
}
if (szInterfaceName == NULL)
{
// look up the interface name in the registry
}
return szInterfaceName;
}
#endif // DBG==1