diff options
Diffstat (limited to 'private/ole32/com/util/olespy.cxx')
-rw-r--r-- | private/ole32/com/util/olespy.cxx | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/private/ole32/com/util/olespy.cxx b/private/ole32/com/util/olespy.cxx new file mode 100644 index 000000000..3e9257e3e --- /dev/null +++ b/private/ole32/com/util/olespy.cxx @@ -0,0 +1,582 @@ +//+--------------------------------------------------------------------------- +// +// 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 + |