|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORPORATION, 1998 * * TITLE: WIADBG.CPP * * VERSION: 1.0 * * AUTHOR: ShaunIv * * DATE: 9/6/1999 * * DESCRIPTION: Implementation of debug code * *******************************************************************************/
//
// need to define this so we don't get any recursion on our calls to "new"
//
#define WIA_DONT_DO_LEAK_CHECKS 1
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include "wianew.h"
#include "wiadebug.h"
#include "simstr.h"
#include "miscutil.h"
#include <shlguid.h>
#include <shlobj.h>
#include <shellapi.h>
#include <wia.h>
#include <dbghelp.h>
#define STACK_TRACE_DB_NAME TEXT("ntdll!RtlpStackTraceDataBase")
#define SYMBOL_BUFFER_LEN 256
#define READVM(Addr, Buf, Sz) ReadVa(__FILE__, __LINE__, (Globals.Target), (Addr), (Buf), (Sz))
#ifdef UNICODE
#define PrintDebugMessage PrintDebugMessageW
#else
#define PrintDebugMessage PrintDebugMessageA
#endif
/******************************************************************************
* * Class definitions * ******************************************************************************/
static CGlobalDebugState g_GlobalDebugState;
class CWiaDebugWindowThreadState { private: int m_nIndentLevel; DWORD m_nDebugMask;
private: // Not implemented
CWiaDebugWindowThreadState( const CWiaDebugWindowThreadState & ); CWiaDebugWindowThreadState &operator=( const CWiaDebugWindowThreadState & );
public: CWiaDebugWindowThreadState(void); DWORD DebugMask(void) const; DWORD DebugMask( DWORD nDebugMask ); int IndentLevel(void) const; int IncrementIndentLevel(void); int DecrementIndentLevel(void); };
class CProcessGlobalDebugData { private: DWORD m_dwTlsIndex; BOOL m_bSymLookupInitialized; PVOID m_pDatabase; HANDLE m_hProcess; CSimpleCriticalSection m_CriticalSection;
typedef struct _STACK_NODE { LPVOID pKeyAddress; size_t Size; PVOID aStack[32]; ULONG ulNumTraces; _STACK_NODE * pNext; } STACK_NODE, *PSTACK_NODE;
PSTACK_NODE m_pStackList; PSTACK_NODE m_pStackListEnd; LONG m_Leaks;
private: static CProcessGlobalDebugData *m_pTheProcessGlobalDebugData;
private: // Not implemented
CProcessGlobalDebugData( const CProcessGlobalDebugData & ); CProcessGlobalDebugData &operator=( const CProcessGlobalDebugData & );
private: // Sole implemented constructor
CProcessGlobalDebugData(void);
// resolve symbols address into symbols names...
LPTSTR GetSymbolicNameForAddress( ULONG_PTR Address ); BOOL IsSymbolLookupInitialized();
public: ~CProcessGlobalDebugData(void); DWORD TlsIndex(void) const; bool IsValid(void) const; void DoRecordAllocation( LPVOID pv, size_t Size ); void DoRecordFree( LPVOID pv ); void GenerateLeakReport( LPTSTR pszModuleName ); HANDLE ProcessHandle( ) { return m_hProcess; } static CProcessGlobalDebugData *Allocate(void); static CProcessGlobalDebugData *ProcessData(void); static void Free(void); };
/******************************************************************************
* * Symbol functions * ******************************************************************************/
BOOL EnumerateModules( IN LPSTR ModuleName, IN ULONG_PTR BaseOfDll, IN PVOID UserContext ) /*
* EnumerateModules * * Module enumeration 'proc' for imagehlp. Call SymLoadModule on the * specified module and if that succeeds cache the module name. * * ModuleName is an LPSTR indicating the name of the module imagehlp is * enumerating for us; * BaseOfDll is the load address of the DLL, which we don't care about, but * SymLoadModule does; * UserContext is a pointer to the relevant SYMINFO, which identifies * our connection. */ { DWORD64 Result; CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
if (pProcessData && pProcessData->IsValid()) { Result = SymLoadModule(pProcessData->ProcessHandle(), NULL, // hFile not used
NULL, // use symbol search path
ModuleName, // ModuleName from Enum
BaseOfDll, // LoadAddress from Enum
0); // Let ImageHlp figure out DLL size
// SilviuC: need to understand exactly what does this function return
if (Result) { return FALSE; }
return TRUE; }
return FALSE;
}
/******************************************************************************
* * CWiaDebugWindowThreadState * ******************************************************************************/ CWiaDebugWindowThreadState::CWiaDebugWindowThreadState(void) : m_nIndentLevel(0), m_nDebugMask(0xFFFFFFFF) { }
DWORD CWiaDebugWindowThreadState::DebugMask(void) const { return m_nDebugMask; }
DWORD CWiaDebugWindowThreadState::DebugMask( DWORD nDebugMask ) { DWORD nOldDebugMask = m_nDebugMask; m_nDebugMask = nDebugMask; return nOldDebugMask; }
int CWiaDebugWindowThreadState::IndentLevel(void) const { return m_nIndentLevel; }
int CWiaDebugWindowThreadState::IncrementIndentLevel(void) { return (++m_nIndentLevel); }
int CWiaDebugWindowThreadState::DecrementIndentLevel(void) { --m_nIndentLevel; if (m_nIndentLevel < 0) m_nIndentLevel = 0; return m_nIndentLevel; }
/******************************************************************************
* * CProcessGlobalDebugData * ******************************************************************************/ // Sole implemented constructor
CProcessGlobalDebugData::CProcessGlobalDebugData(void) : m_dwTlsIndex(TLS_OUT_OF_INDEXES), m_hProcess(NULL), m_pDatabase(NULL), m_bSymLookupInitialized(FALSE), m_pStackList(NULL), m_pStackListEnd(NULL), m_Leaks(0) { m_dwTlsIndex = TlsAlloc(); }
CProcessGlobalDebugData::~CProcessGlobalDebugData(void) { if (m_dwTlsIndex != TLS_OUT_OF_INDEXES) TlsFree(m_dwTlsIndex); m_dwTlsIndex = TLS_OUT_OF_INDEXES;
if (m_hProcess) { CloseHandle(m_hProcess); m_hProcess = NULL; }
m_bSymLookupInitialized = FALSE;
CAutoCriticalSection cs(m_CriticalSection);
if (m_pStackList) { PSTACK_NODE pNextNode = NULL; for (PSTACK_NODE pNode = m_pStackList; pNode; ) { if (pNode) { pNextNode = pNode->pNext; LocalFree( pNode ); }
pNode = pNextNode; pNextNode = NULL; } } }
DWORD CProcessGlobalDebugData::TlsIndex(void) const { return m_dwTlsIndex; }
bool CProcessGlobalDebugData::IsValid(void) const { return (m_dwTlsIndex != TLS_OUT_OF_INDEXES); }
//
// Caller must free returned string via LocalFree
//
LPTSTR CProcessGlobalDebugData::GetSymbolicNameForAddress( ULONG_PTR Address ) { IMAGEHLP_MODULE ModuleInfo; TCHAR SymbolBuffer[512]; PIMAGEHLP_SYMBOL Symbol; ULONG_PTR Offset; LPTSTR pName; BOOL bResult;
if (!IsSymbolLookupInitialized()) { return NULL; }
if (Address == (ULONG_PTR)-1) { *SymbolBuffer = 0; lstrcpy( SymbolBuffer, TEXT("<< FUZZY STACK TRACE >>") );
pName = (LPTSTR)LocalAlloc( LPTR, (lstrlen( SymbolBuffer ) + 1) * sizeof(TCHAR) ); if (pName) { lstrcpy( pName, SymbolBuffer ); }
return pName; }
ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
if (!SymGetModuleInfo( m_hProcess, Address, &ModuleInfo )) { //
// can't get the module info, so give back an error message...
//
*SymbolBuffer = 0; wsprintf( SymbolBuffer, TEXT("<< cannot identify module for address %p >>"), Address );
pName = (LPTSTR)LocalAlloc( LPTR, (lstrlen( SymbolBuffer ) + 1) * sizeof(TCHAR) ); if (pName) { lstrcpy( pName, SymbolBuffer ); }
return pName; }
Symbol = (PIMAGEHLP_SYMBOL)SymbolBuffer; Symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL) - 1;
if (SymGetSymFromAddr( m_hProcess, Address, &Offset, Symbol )) {
IMAGEHLP_LINE LineInfo; DWORD Displacement; BOOL bLineInfoPresent; CHAR szString[ 1024 ];
bLineInfoPresent = SymGetLineFromAddr (m_hProcess, Address, &Displacement, &LineInfo);
if (bLineInfoPresent) { //
// construct string w/filename & linenumber...
//
wsprintfA( szString, "%s!%s (%s, line %u)", ModuleInfo.ModuleName, Symbol->Name, LineInfo.FileName, LineInfo.LineNumber ); } else { //
// no line numbers, so just show symbol + offset
//
wsprintfA( szString, "%s!%s+%08X", ModuleInfo.ModuleName, Symbol->Name, Offset ); }
INT iLen = (lstrlenA(szString)+1);
pName = (LPTSTR) LocalAlloc( LPTR, (iLen * sizeof(TCHAR)) );
if (pName == NULL) { return NULL; }
#ifdef UNICODE
MultiByteToWideChar( CP_ACP, 0, szString, -1, pName, iLen ); #else
lstrcpy( pName, szString); #endif
return pName; } else {
//
// can't get the address info, so give back an error message...
//
*SymbolBuffer = 0;
#ifdef UNICODE
TCHAR szModW[ MAX_PATH ];
MultiByteToWideChar( CP_ACP, 0, ModuleInfo.ModuleName, -1, szModW, MAX_PATH ); wsprintf( SymbolBuffer, TEXT("<< incorrect symbols for module %s (address %p)"), szModW, Address ); #else
wsprintf( SymbolBuffer, TEXT("<< incorrect symbols for module %s (address %p)"), ModuleInfo.ModuleName, Address ); #endif
pName = (LPTSTR)LocalAlloc( LPTR, (lstrlen( SymbolBuffer ) + 1) * sizeof(TCHAR) ); if (pName) { lstrcpy( pName, SymbolBuffer ); }
return pName;
}
return NULL; }
void CProcessGlobalDebugData::DoRecordAllocation( LPVOID pv, size_t Size ) { if (!pv) { return; }
PVOID StackTrace[32]; ULONG Count; ULONG Index; ULONG Hash;
//
// Capture stack trace up to 32 items deep, but skip last three items
// (because they'll always be the same)
//
Count = RtlCaptureStackBackTrace( 4, 32, StackTrace, NULL );
if (Count) { CAutoCriticalSection cs(m_CriticalSection);
//
// Add this stack trace to list
//
PSTACK_NODE pNewNode = (PSTACK_NODE)LocalAlloc( LPTR, sizeof(STACK_NODE) ); if (pNewNode) { pNewNode->pKeyAddress = pv; pNewNode->Size = Size; pNewNode->ulNumTraces = Count; memcpy( pNewNode->aStack, StackTrace, sizeof(pNewNode->aStack) ); }
if (!m_pStackList) { m_pStackList = pNewNode; m_pStackListEnd = pNewNode; } else { m_pStackListEnd->pNext = pNewNode; m_pStackListEnd = pNewNode; }
m_Leaks++; }
}
void CProcessGlobalDebugData::DoRecordFree( LPVOID pv ) { if (!pv) { return; }
CAutoCriticalSection cs(m_CriticalSection);
//
// Find item in allocation list...
//
PSTACK_NODE pNode = NULL; PSTACK_NODE pTrail = NULL;
for ( pNode = m_pStackList; pNode && (pNode->pKeyAddress!=pv); pTrail = pNode, pNode = pNode->pNext ) { ; }
if (pNode) { //
// Remove this node from the list...
//
if (!pTrail) { //
// It's the first item in list
//
m_pStackList = pNode->pNext; if (m_pStackListEnd == pNode) { m_pStackListEnd = NULL; }
LocalFree( (HLOCAL) pNode );
m_Leaks--; } else { //
// We're somewhere in the middle of the list...
//
pTrail->pNext = pNode->pNext; if (m_pStackListEnd == pNode) { m_pStackListEnd = pTrail; }
LocalFree( (HLOCAL) pNode ); m_Leaks--; }
}
}
void CProcessGlobalDebugData::GenerateLeakReport(LPTSTR pszModuleName) { CAutoCriticalSection cs(m_CriticalSection);
//
// Report the numer of leaks...
//
TCHAR sz[ 512 ]; TCHAR szNewLine[ 3 ]; COLORREF crFore = static_cast<COLORREF>(0xFFFFFFFF), crBack = static_cast<COLORREF>(0xFFFFFFFF); if (m_Leaks > 0) { crFore = RGB(0x00,0x00,0x00); crBack = RGB(0xFF,0x7F,0x7F); }
lstrcpy( szNewLine, TEXT("\n") );
PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, szNewLine );
wsprintf( sz, TEXT("**** Reporting leaks -- %d leaks found ****"), m_Leaks );
PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, sz );
//
// Loop through the list...
//
LPTSTR pSymbol = NULL; PSTACK_NODE pNode = m_pStackList; INT i = 1; while (pNode) { PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, szNewLine ); wsprintf( sz, TEXT("Leak %d - %d bytes allocated by:"), i++, pNode->Size ); PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, sz );
for (INT j=0; (j < (INT)pNode->ulNumTraces) && (pNode->aStack[j]); j++) { pSymbol = GetSymbolicNameForAddress( (ULONG_PTR)pNode->aStack[j] ); if (pSymbol) { PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, pSymbol ); LocalFree( (HLOCAL)pSymbol ); } else { wsprintf( sz, TEXT("< could not resolve symbols for address %p >"),pNode->aStack[j] ); PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, sz ); }
}
pNode = pNode->pNext; }
PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, szNewLine ); PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, TEXT("**** End Leak Report ****") ); PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, szNewLine );
}
BOOL CProcessGlobalDebugData::IsSymbolLookupInitialized() {
CAutoCriticalSection cs(m_CriticalSection); if (!m_bSymLookupInitialized) { if (m_hProcess) { CloseHandle( m_hProcess ); m_hProcess = NULL; }
m_hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId() );
if (m_hProcess) { if (SymInitialize( m_hProcess, NULL, TRUE )) { SymSetOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
if (SymEnumerateModules( m_hProcess, EnumerateModules, m_hProcess)) { m_bSymLookupInitialized = TRUE; }
}
} }
return m_bSymLookupInitialized; }
CProcessGlobalDebugData *CProcessGlobalDebugData::Allocate(void) { if (!m_pTheProcessGlobalDebugData) m_pTheProcessGlobalDebugData = new CProcessGlobalDebugData; return (m_pTheProcessGlobalDebugData); }
CProcessGlobalDebugData *CProcessGlobalDebugData::ProcessData(void) { return Allocate(); }
void CProcessGlobalDebugData::Free(void) { if (m_pTheProcessGlobalDebugData) { delete m_pTheProcessGlobalDebugData; m_pTheProcessGlobalDebugData = NULL; } }
CProcessGlobalDebugData *CProcessGlobalDebugData::m_pTheProcessGlobalDebugData = NULL;
/******************************************************************************
* * DllMain * ******************************************************************************/ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID ) { BOOL bResult = FALSE; switch (dwReason) { case DLL_PROCESS_ATTACH: { bResult = (CProcessGlobalDebugData::Allocate() != NULL); } break;
case DLL_PROCESS_DETACH: { CProcessGlobalDebugData::Free(); bResult = TRUE; } break;
case DLL_THREAD_ATTACH: { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { CWiaDebugWindowThreadState *pThreadData = new CWiaDebugWindowThreadState; TlsSetValue( pProcessData->TlsIndex(), pThreadData ); bResult = (pThreadData != NULL); } } break;
case DLL_THREAD_DETACH: { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState*>(TlsGetValue( pProcessData->TlsIndex())); if (pThreadData) { delete pThreadData; TlsSetValue( pProcessData->TlsIndex(), NULL ); } } bResult = TRUE; } break; } return bResult; }
/******************************************************************************
* * Global Helper Functions * ******************************************************************************/ static bool IsProcessDebugFlagSet( DWORD dwModuleMask ) { bool bResult = false;
CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex())); if (pThreadData) { bResult = ((pThreadData->DebugMask() & dwModuleMask) != 0); } } return (bResult); }
static CWiaDebugWindowThreadState *ThreadData(void) { CWiaDebugWindowThreadState *pThreadData = NULL;
CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex())); if (!pThreadData) { pThreadData = new CWiaDebugWindowThreadState; TlsSetValue( pProcessData->TlsIndex(), pThreadData ); } } return (pThreadData); }
template <class T> static BOOL ContainsNonWhitespace( T *lpszMsg ) { for (T *lpszPtr = lpszMsg;*lpszPtr;lpszPtr++) if (*lpszPtr != ' ' && *lpszPtr != '\n' && *lpszPtr != '\r' && *lpszPtr != '\t') return TRUE; return FALSE; }
static void InsertStackLevelIndent( LPSTR lpszMsg, int nStackLevel ) { const LPSTR lpszIndent = " "; CHAR szTmp[1024], *pstrTmp, *pstrPtr; pstrTmp=szTmp; pstrPtr=lpszMsg; while (pstrPtr && *pstrPtr) { // if the current character is a newline and it isn't the
// last character, append the indent string
if (*pstrPtr=='\n' && ContainsNonWhitespace(pstrPtr)) { *pstrTmp++ = *pstrPtr++; for (int i=0;i<WiaUiUtil::Min(nStackLevel,20);i++) { lstrcpyA(pstrTmp,lpszIndent); pstrTmp += lstrlenA(lpszIndent); } } // If this is the first character, insert the indent string before the
// first character
else if (pstrPtr == lpszMsg && ContainsNonWhitespace(pstrPtr)) { for (int i=0;i<WiaUiUtil::Min(nStackLevel,20);i++) { lstrcpyA(pstrTmp,lpszIndent); pstrTmp += lstrlenA(lpszIndent); } *pstrTmp++ = *pstrPtr++; } else *pstrTmp++ = *pstrPtr++; } *pstrTmp = '\0'; lstrcpyA( lpszMsg, szTmp ); }
static void InsertStackLevelIndent( LPWSTR lpszMsg, int nStackLevel ) { const LPWSTR lpszIndent = L" "; WCHAR szTmp[1024], *pstrTmp, *pstrPtr; pstrTmp=szTmp; pstrPtr=lpszMsg; while (pstrPtr && *pstrPtr) { // if the current character is a newline and it isn't the
// last character, append the indent string
if (*pstrPtr==L'\n' && ContainsNonWhitespace(pstrPtr)) { *pstrTmp++ = *pstrPtr++; for (int i=0;i<WiaUiUtil::Min(nStackLevel,20);i++) { lstrcpyW(pstrTmp,lpszIndent); pstrTmp += lstrlenW(lpszIndent); } } // If this is the first character, insert the indent string before the
// first character
else if (pstrPtr == lpszMsg && ContainsNonWhitespace(pstrPtr)) { for (int i=0;i<WiaUiUtil::Min(nStackLevel,20);i++) { lstrcpyW(pstrTmp,lpszIndent); pstrTmp += lstrlenW(lpszIndent); } *pstrTmp++ = *pstrPtr++; } else *pstrTmp++ = *pstrPtr++; } *pstrTmp = L'\0'; lstrcpyW( lpszMsg, szTmp ); }
static void PrependString( LPTSTR lpszTgt, LPCTSTR lpszStr ) { if (ContainsNonWhitespace(lpszTgt)) { int iLen = lstrlen(lpszTgt); int iThreadIdLen = lstrlen(lpszStr); LPTSTR lpszTmp = (LPTSTR)LocalAlloc( LPTR, (iLen + iThreadIdLen + 2)*sizeof(TCHAR)); if (lpszTmp) { lstrcpy( lpszTmp, lpszStr ); lstrcat( lpszTmp, TEXT(" ") ); lstrcat( lpszTmp, lpszTgt ); lstrcpy( lpszTgt, lpszTmp ); LocalFree(lpszTmp); } } }
static void PrependThreadId( LPTSTR lpszMsg ) { if (ContainsNonWhitespace(lpszMsg)) { TCHAR szThreadId[20]; wsprintf( szThreadId, TEXT("[%08X]"), GetCurrentThreadId() ); PrependString( lpszMsg, szThreadId ); } }
/******************************************************************************
* * Exported Functions * ******************************************************************************/ int WINAPI IncrementDebugIndentLevel(void) { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex())); if (pThreadData) { return pThreadData->IncrementIndentLevel(); } } return 0; }
int WINAPI DecrementDebugIndentLevel(void) { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex())); if (pThreadData) { return pThreadData->DecrementIndentLevel(); } } return 0; }
DWORD WINAPI GetDebugMask(void) { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex())); if (pThreadData) { return pThreadData->DebugMask(); } } return 0; }
DWORD WINAPI SetDebugMask( DWORD dwNewMask ) { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex())); if (pThreadData) { return pThreadData->DebugMask(dwNewMask); } } return 0; }
BOOL WINAPI PrintDebugMessageW( DWORD dwSeverity, DWORD dwModuleMask, COLORREF crForeground, COLORREF crBackground, LPCWSTR pszModuleName, LPCWSTR pszMsg ) { BOOL bResult = FALSE; #ifdef UNICODE
CWiaDebugWindowThreadState *pThreadData = ThreadData(); if (pThreadData && (dwSeverity || IsProcessDebugFlagSet(dwModuleMask))) { WCHAR szMsg[1024]=L"";
// Print thread id
wsprintfW( szMsg, L"[%ws-%08X] %ws", pszModuleName, GetCurrentThreadId(), pszMsg );
InsertStackLevelIndent( szMsg, pThreadData->IndentLevel() );
lstrcatW( szMsg, L"\n" );
OutputDebugStringW( szMsg );
// Make sure it is a valid window
if (g_GlobalDebugState.DebugWindow()) { CDebugStringMessageData DebugStringMessageData; DebugStringMessageData.crBackground = crBackground; DebugStringMessageData.crForeground = crForeground; DebugStringMessageData.bUnicode = TRUE; lstrcpyW( reinterpret_cast<LPWSTR>(DebugStringMessageData.szString), szMsg );
COPYDATASTRUCT CopyDataStruct; CopyDataStruct.dwData = COPYDATA_DEBUG_MESSAGE_ID; CopyDataStruct.cbData = sizeof(DebugStringMessageData); CopyDataStruct.lpData = &DebugStringMessageData;
g_GlobalDebugState.SendDebugWindowMessage( WM_COPYDATA, 0, reinterpret_cast<LPARAM>(&CopyDataStruct) ); } bResult = TRUE; } #else
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); #endif
return bResult; }
BOOL WINAPI PrintDebugMessageA( DWORD dwSeverity, DWORD dwModuleMask, COLORREF crForeground, COLORREF crBackground, LPCSTR pszModuleName, LPCSTR pszMsg ) { BOOL bResult = FALSE; CWiaDebugWindowThreadState *pThreadData = ThreadData(); if (pThreadData && (dwSeverity || IsProcessDebugFlagSet(dwModuleMask))) { CHAR szMsg[1024]="";
// Print thread id
wsprintfA( szMsg, "[%hs-%08X] %hs", pszModuleName, GetCurrentThreadId(), pszMsg );
InsertStackLevelIndent( szMsg, pThreadData->IndentLevel() );
lstrcatA( szMsg, "\n" );
OutputDebugStringA( szMsg );
// Make sure it is a valid window
if (g_GlobalDebugState.DebugWindow()) { CDebugStringMessageData DebugStringMessageData; DebugStringMessageData.crBackground = crBackground; DebugStringMessageData.crForeground = crForeground; DebugStringMessageData.bUnicode = FALSE; lstrcpyA( static_cast<LPSTR>(DebugStringMessageData.szString), szMsg );
COPYDATASTRUCT CopyDataStruct; CopyDataStruct.dwData = COPYDATA_DEBUG_MESSAGE_ID; CopyDataStruct.cbData = sizeof(DebugStringMessageData); CopyDataStruct.lpData = &DebugStringMessageData;
g_GlobalDebugState.SendDebugWindowMessage( WM_COPYDATA, 0, reinterpret_cast<LPARAM>(&CopyDataStruct) ); } bResult = TRUE; } return bResult; }
COLORREF WINAPI AllocateDebugColor(void) { DWORD dwIndex = g_GlobalDebugState.AllocateNextColorIndex(); return g_GlobalDebugState.GetColorFromIndex( dwIndex ); }
#define GUID_DEBUG_ENTRY(guid) { &guid, ""#guid }
static const struct { const GUID *pGuid; LPCSTR pszName; } s_GuidDebugStrings[] = { GUID_DEBUG_ENTRY(IID_IClassFactory), GUID_DEBUG_ENTRY(IID_ICommDlgBrowser), GUID_DEBUG_ENTRY(IID_IContextMenu), GUID_DEBUG_ENTRY(IID_IContextMenu2), GUID_DEBUG_ENTRY(IID_IDataObject), GUID_DEBUG_ENTRY(IID_IDropTarget), GUID_DEBUG_ENTRY(IID_IEnumIDList), GUID_DEBUG_ENTRY(IID_IExtractIconA), GUID_DEBUG_ENTRY(IID_IExtractIconW), GUID_DEBUG_ENTRY(IID_IFileViewerA), GUID_DEBUG_ENTRY(IID_IFileViewerSite), GUID_DEBUG_ENTRY(IID_IFileViewerW), GUID_DEBUG_ENTRY(IID_IMoniker), GUID_DEBUG_ENTRY(IID_INewShortcutHookA), GUID_DEBUG_ENTRY(IID_INewShortcutHookW), GUID_DEBUG_ENTRY(IID_IOleWindow), GUID_DEBUG_ENTRY(IID_IPersist), GUID_DEBUG_ENTRY(IID_IPersistFile), GUID_DEBUG_ENTRY(IID_IPersistFolder), GUID_DEBUG_ENTRY(IID_IPersistFolder2), GUID_DEBUG_ENTRY(IID_IPropSheetPage), GUID_DEBUG_ENTRY(IID_IQueryInfo), GUID_DEBUG_ENTRY(IID_ISequentialStream), GUID_DEBUG_ENTRY(IID_IShellBrowser), GUID_DEBUG_ENTRY(IID_IShellCopyHookA), GUID_DEBUG_ENTRY(IID_IShellCopyHookW), GUID_DEBUG_ENTRY(IID_IShellDetails), GUID_DEBUG_ENTRY(IID_IShellExecuteHookA), GUID_DEBUG_ENTRY(IID_IShellExecuteHookW), GUID_DEBUG_ENTRY(IID_IShellExtInit), GUID_DEBUG_ENTRY(IID_IShellExtInit), GUID_DEBUG_ENTRY(IID_IShellFolder), GUID_DEBUG_ENTRY(IID_IShellIcon), GUID_DEBUG_ENTRY(IID_IShellIconOverlay), GUID_DEBUG_ENTRY(IID_IShellIconOverlay), GUID_DEBUG_ENTRY(IID_IShellLinkA), GUID_DEBUG_ENTRY(IID_IShellLinkW), GUID_DEBUG_ENTRY(IID_IShellPropSheetExt), GUID_DEBUG_ENTRY(IID_IShellPropSheetExt), GUID_DEBUG_ENTRY(IID_IShellView), GUID_DEBUG_ENTRY(IID_IShellView2), GUID_DEBUG_ENTRY(IID_IShellView2), GUID_DEBUG_ENTRY(IID_IStream), GUID_DEBUG_ENTRY(IID_IUniformResourceLocator), GUID_DEBUG_ENTRY(IID_IUnknown), GUID_DEBUG_ENTRY(WiaImgFmt_UNDEFINED), GUID_DEBUG_ENTRY(WiaImgFmt_MEMORYBMP), GUID_DEBUG_ENTRY(WiaImgFmt_BMP), GUID_DEBUG_ENTRY(WiaImgFmt_EMF), GUID_DEBUG_ENTRY(WiaImgFmt_WMF), GUID_DEBUG_ENTRY(WiaImgFmt_JPEG), GUID_DEBUG_ENTRY(WiaImgFmt_PNG), GUID_DEBUG_ENTRY(WiaImgFmt_GIF), GUID_DEBUG_ENTRY(WiaImgFmt_TIFF), GUID_DEBUG_ENTRY(WiaImgFmt_EXIF), GUID_DEBUG_ENTRY(WiaImgFmt_PHOTOCD), GUID_DEBUG_ENTRY(WiaImgFmt_FLASHPIX), GUID_DEBUG_ENTRY(WiaImgFmt_ICO), GUID_DEBUG_ENTRY(WiaImgFmt_CIFF), GUID_DEBUG_ENTRY(WiaImgFmt_PICT), GUID_DEBUG_ENTRY(WiaImgFmt_JPEG2K), GUID_DEBUG_ENTRY(WiaImgFmt_JPEG2KX), GUID_DEBUG_ENTRY(WiaImgFmt_RTF), GUID_DEBUG_ENTRY(WiaImgFmt_XML), GUID_DEBUG_ENTRY(WiaImgFmt_HTML), GUID_DEBUG_ENTRY(WiaImgFmt_TXT), GUID_DEBUG_ENTRY(WiaImgFmt_MPG), GUID_DEBUG_ENTRY(WiaImgFmt_AVI), GUID_DEBUG_ENTRY(WiaImgFmt_ASF), GUID_DEBUG_ENTRY(WiaImgFmt_SCRIPT), GUID_DEBUG_ENTRY(WiaImgFmt_EXEC), GUID_DEBUG_ENTRY(WiaImgFmt_UNICODE16), GUID_DEBUG_ENTRY(WiaImgFmt_DPOF), GUID_DEBUG_ENTRY(WiaAudFmt_WAV), GUID_DEBUG_ENTRY(WiaAudFmt_MP3), GUID_DEBUG_ENTRY(WiaAudFmt_AIFF), GUID_DEBUG_ENTRY(WiaAudFmt_WMA), GUID_DEBUG_ENTRY(WIA_EVENT_DEVICE_DISCONNECTED), GUID_DEBUG_ENTRY(WIA_EVENT_DEVICE_CONNECTED), GUID_DEBUG_ENTRY(WIA_EVENT_ITEM_DELETED), GUID_DEBUG_ENTRY(WIA_EVENT_ITEM_CREATED), GUID_DEBUG_ENTRY(WIA_EVENT_TREE_UPDATED), GUID_DEBUG_ENTRY(WIA_EVENT_VOLUME_INSERT), GUID_DEBUG_ENTRY(WIA_EVENT_SCAN_IMAGE), GUID_DEBUG_ENTRY(WIA_EVENT_SCAN_PRINT_IMAGE), GUID_DEBUG_ENTRY(WIA_EVENT_SCAN_FAX_IMAGE), GUID_DEBUG_ENTRY(WIA_EVENT_STORAGE_CREATED), GUID_DEBUG_ENTRY(WIA_EVENT_STORAGE_DELETED), GUID_DEBUG_ENTRY(WIA_EVENT_STI_PROXY), GUID_DEBUG_ENTRY(WIA_EVENT_HANDLER_NO_ACTION), GUID_DEBUG_ENTRY(WIA_EVENT_HANDLER_PROMPT), GUID_DEBUG_ENTRY(WIA_CMD_SYNCHRONIZE), GUID_DEBUG_ENTRY(WIA_CMD_TAKE_PICTURE), GUID_DEBUG_ENTRY(WIA_CMD_DELETE_ALL_ITEMS), GUID_DEBUG_ENTRY(WIA_CMD_CHANGE_DOCUMENT), GUID_DEBUG_ENTRY(WIA_CMD_UNLOAD_DOCUMENT), GUID_DEBUG_ENTRY(WIA_CMD_DIAGNOSTIC), GUID_DEBUG_ENTRY(WIA_CMD_DELETE_DEVICE_TREE), GUID_DEBUG_ENTRY(WIA_CMD_BUILD_DEVICE_TREE), GUID_DEBUG_ENTRY(IID_IWiaDevMgr), GUID_DEBUG_ENTRY(IID_IEnumWIA_DEV_INFO), GUID_DEBUG_ENTRY(IID_IWiaEventCallback), GUID_DEBUG_ENTRY(IID_IWiaDataCallback), GUID_DEBUG_ENTRY(IID_IWiaDataTransfer), GUID_DEBUG_ENTRY(IID_IWiaItem), GUID_DEBUG_ENTRY(IID_IWiaPropertyStorage), GUID_DEBUG_ENTRY(IID_IEnumWiaItem), GUID_DEBUG_ENTRY(IID_IEnumWIA_DEV_CAPS), GUID_DEBUG_ENTRY(IID_IEnumWIA_FORMAT_INFO), GUID_DEBUG_ENTRY(IID_IWiaLog), GUID_DEBUG_ENTRY(IID_IWiaLogEx), GUID_DEBUG_ENTRY(IID_IWiaNotifyDevMgr), GUID_DEBUG_ENTRY(LIBID_WiaDevMgr), GUID_DEBUG_ENTRY(CLSID_WiaDevMgr), GUID_DEBUG_ENTRY(CLSID_WiaLog), GUID_DEBUG_ENTRY(IID_IExtractImage2), GUID_DEBUG_ENTRY(IID_IExtractImage), GUID_DEBUG_ENTRY(IID_IShellDetails3), GUID_DEBUG_ENTRY(IID_IShellFolder2) };
#define GUID_DEBUG_MAP_SIZE (sizeof(s_GuidDebugStrings)/sizeof(s_GuidDebugStrings[0]))
BOOL WINAPI GetStringFromGuidA( const IID *pGuid, LPSTR pszString, int nMaxLen ) { if (!pGuid || !pszString || !nMaxLen) return FALSE; for (int i=0;i<GUID_DEBUG_MAP_SIZE;i++) { if (*pGuid == *s_GuidDebugStrings[i].pGuid) { lstrcpynA( pszString, s_GuidDebugStrings[i].pszName, nMaxLen ); return TRUE; } } LPOLESTR pszGuid = NULL; HRESULT hr = StringFromCLSID( *pGuid, &pszGuid ); if (SUCCEEDED(hr)) { if (pszGuid) { CSimpleStringAnsi strGuid = CSimpleStringConvert::AnsiString(CSimpleStringWide(pszGuid)); lstrcpynA( pszString, strGuid, nMaxLen ); CoTaskMemFree(pszGuid); return TRUE; } } return FALSE; }
BOOL WINAPI GetStringFromGuidW( const IID *pGuid, LPWSTR pszString, int nMaxLen ) { BOOL bResult = FALSE; #ifdef UNICODE
if (!pGuid || !pszString || !nMaxLen) return FALSE; CHAR szGuid[MAX_PATH]; if (!GetStringFromGuidA(pGuid,szGuid,MAX_PATH)) return FALSE; lstrcpynW( pszString, CSimpleStringConvert::WideString(CSimpleStringAnsi(szGuid)), nMaxLen ); bResult = TRUE; #else
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); #endif
return bResult; }
#define MSG_DEBUG_ENTRY(msg) { msg, ""#msg }
static const struct { UINT uMsg; LPCSTR pszName; } s_MsgDebugStrings[] = { MSG_DEBUG_ENTRY(BM_CLICK), MSG_DEBUG_ENTRY(BM_GETCHECK), MSG_DEBUG_ENTRY(BM_GETIMAGE), MSG_DEBUG_ENTRY(BM_GETSTATE), MSG_DEBUG_ENTRY(BM_SETCHECK), MSG_DEBUG_ENTRY(BM_SETIMAGE), MSG_DEBUG_ENTRY(BM_SETSTATE), MSG_DEBUG_ENTRY(BM_SETSTYLE), MSG_DEBUG_ENTRY(CB_ADDSTRING), MSG_DEBUG_ENTRY(CB_DELETESTRING), MSG_DEBUG_ENTRY(CB_DIR), MSG_DEBUG_ENTRY(CB_FINDSTRING), MSG_DEBUG_ENTRY(CB_FINDSTRINGEXACT), MSG_DEBUG_ENTRY(CB_GETCOMBOBOXINFO), MSG_DEBUG_ENTRY(CB_GETCOUNT), MSG_DEBUG_ENTRY(CB_GETCURSEL), MSG_DEBUG_ENTRY(CB_GETDROPPEDCONTROLRECT), MSG_DEBUG_ENTRY(CB_GETDROPPEDSTATE), MSG_DEBUG_ENTRY(CB_GETEDITSEL), MSG_DEBUG_ENTRY(CB_GETEXTENDEDUI), MSG_DEBUG_ENTRY(CB_GETITEMDATA), MSG_DEBUG_ENTRY(CB_GETITEMHEIGHT), MSG_DEBUG_ENTRY(CB_GETLBTEXT), MSG_DEBUG_ENTRY(CB_GETLBTEXTLEN), MSG_DEBUG_ENTRY(CB_GETLOCALE), MSG_DEBUG_ENTRY(CB_INITSTORAGE), MSG_DEBUG_ENTRY(CB_INSERTSTRING), MSG_DEBUG_ENTRY(CB_LIMITTEXT), MSG_DEBUG_ENTRY(CB_MSGMAX), MSG_DEBUG_ENTRY(CB_MSGMAX), MSG_DEBUG_ENTRY(CB_MSGMAX), MSG_DEBUG_ENTRY(CB_MSGMAX), MSG_DEBUG_ENTRY(CB_RESETCONTENT), MSG_DEBUG_ENTRY(CB_SELECTSTRING), MSG_DEBUG_ENTRY(CB_SETCURSEL), MSG_DEBUG_ENTRY(CB_SETDROPPEDWIDTH), MSG_DEBUG_ENTRY(CB_SETEDITSEL), MSG_DEBUG_ENTRY(CB_SETEXTENDEDUI), MSG_DEBUG_ENTRY(CB_SETITEMDATA), MSG_DEBUG_ENTRY(CB_SETITEMHEIGHT), MSG_DEBUG_ENTRY(CB_SETLOCALE), MSG_DEBUG_ENTRY(CB_SHOWDROPDOWN), MSG_DEBUG_ENTRY(EM_CANUNDO), MSG_DEBUG_ENTRY(EM_CHARFROMPOS), MSG_DEBUG_ENTRY(EM_EMPTYUNDOBUFFER), MSG_DEBUG_ENTRY(EM_FMTLINES), MSG_DEBUG_ENTRY(EM_GETFIRSTVISIBLELINE), MSG_DEBUG_ENTRY(EM_GETHANDLE), MSG_DEBUG_ENTRY(EM_GETIMESTATUS), MSG_DEBUG_ENTRY(EM_GETLIMITTEXT), MSG_DEBUG_ENTRY(EM_GETLINE), MSG_DEBUG_ENTRY(EM_GETLINECOUNT), MSG_DEBUG_ENTRY(EM_GETMARGINS), MSG_DEBUG_ENTRY(EM_GETMODIFY), MSG_DEBUG_ENTRY(EM_GETPASSWORDCHAR), MSG_DEBUG_ENTRY(EM_GETRECT), MSG_DEBUG_ENTRY(EM_GETSEL), MSG_DEBUG_ENTRY(EM_GETTHUMB), MSG_DEBUG_ENTRY(EM_GETWORDBREAKPROC), MSG_DEBUG_ENTRY(EM_LIMITTEXT), MSG_DEBUG_ENTRY(EM_LINEFROMCHAR), MSG_DEBUG_ENTRY(EM_LINEINDEX), MSG_DEBUG_ENTRY(EM_LINELENGTH), MSG_DEBUG_ENTRY(EM_LINESCROLL), MSG_DEBUG_ENTRY(EM_POSFROMCHAR), MSG_DEBUG_ENTRY(EM_REPLACESEL), MSG_DEBUG_ENTRY(EM_SCROLL), MSG_DEBUG_ENTRY(EM_SCROLLCARET), MSG_DEBUG_ENTRY(EM_SETHANDLE), MSG_DEBUG_ENTRY(EM_SETIMESTATUS), MSG_DEBUG_ENTRY(EM_SETMARGINS), MSG_DEBUG_ENTRY(EM_SETMODIFY), MSG_DEBUG_ENTRY(EM_SETPASSWORDCHAR), MSG_DEBUG_ENTRY(EM_SETREADONLY), MSG_DEBUG_ENTRY(EM_SETRECT), MSG_DEBUG_ENTRY(EM_SETRECTNP), MSG_DEBUG_ENTRY(EM_SETSEL), MSG_DEBUG_ENTRY(EM_SETTABSTOPS), MSG_DEBUG_ENTRY(EM_SETWORDBREAKPROC), MSG_DEBUG_ENTRY(EM_UNDO), MSG_DEBUG_ENTRY(LB_ADDFILE), MSG_DEBUG_ENTRY(LB_ADDSTRING), MSG_DEBUG_ENTRY(LB_DELETESTRING), MSG_DEBUG_ENTRY(LB_DIR), MSG_DEBUG_ENTRY(LB_FINDSTRING), MSG_DEBUG_ENTRY(LB_FINDSTRINGEXACT), MSG_DEBUG_ENTRY(LB_GETANCHORINDEX), MSG_DEBUG_ENTRY(LB_GETCARETINDEX), MSG_DEBUG_ENTRY(LB_GETCOUNT), MSG_DEBUG_ENTRY(LB_GETCURSEL), MSG_DEBUG_ENTRY(LB_GETHORIZONTALEXTENT), MSG_DEBUG_ENTRY(LB_GETITEMDATA), MSG_DEBUG_ENTRY(LB_GETITEMHEIGHT), MSG_DEBUG_ENTRY(LB_GETITEMRECT), MSG_DEBUG_ENTRY(LB_GETLISTBOXINFO), MSG_DEBUG_ENTRY(LB_GETLOCALE), MSG_DEBUG_ENTRY(LB_GETSEL), MSG_DEBUG_ENTRY(LB_GETSELCOUNT), MSG_DEBUG_ENTRY(LB_GETSELITEMS), MSG_DEBUG_ENTRY(LB_GETTEXT), MSG_DEBUG_ENTRY(LB_GETTEXTLEN), MSG_DEBUG_ENTRY(LB_GETTOPINDEX), MSG_DEBUG_ENTRY(LB_INITSTORAGE), MSG_DEBUG_ENTRY(LB_INSERTSTRING), MSG_DEBUG_ENTRY(LB_ITEMFROMPOINT), MSG_DEBUG_ENTRY(LB_MSGMAX), MSG_DEBUG_ENTRY(LB_MSGMAX), MSG_DEBUG_ENTRY(LB_MSGMAX), MSG_DEBUG_ENTRY(LB_MSGMAX), MSG_DEBUG_ENTRY(LB_RESETCONTENT), MSG_DEBUG_ENTRY(LB_SELECTSTRING), MSG_DEBUG_ENTRY(LB_SELITEMRANGE), MSG_DEBUG_ENTRY(LB_SELITEMRANGEEX), MSG_DEBUG_ENTRY(LB_SETANCHORINDEX), MSG_DEBUG_ENTRY(LB_SETCARETINDEX), MSG_DEBUG_ENTRY(LB_SETCOLUMNWIDTH), MSG_DEBUG_ENTRY(LB_SETCOUNT), MSG_DEBUG_ENTRY(LB_SETCURSEL), MSG_DEBUG_ENTRY(LB_SETHORIZONTALEXTENT), MSG_DEBUG_ENTRY(LB_SETITEMDATA), MSG_DEBUG_ENTRY(LB_SETITEMHEIGHT), MSG_DEBUG_ENTRY(LB_SETLOCALE), MSG_DEBUG_ENTRY(LB_SETSEL), MSG_DEBUG_ENTRY(LB_SETTABSTOPS), MSG_DEBUG_ENTRY(LB_SETTOPINDEX), MSG_DEBUG_ENTRY(PBT_APMBATTERYLOW), MSG_DEBUG_ENTRY(PBT_APMOEMEVENT), MSG_DEBUG_ENTRY(PBT_APMPOWERSTATUSCHANGE), MSG_DEBUG_ENTRY(PBT_APMQUERYSTANDBY), MSG_DEBUG_ENTRY(PBT_APMQUERYSTANDBYFAILED), MSG_DEBUG_ENTRY(PBT_APMQUERYSUSPEND), MSG_DEBUG_ENTRY(PBT_APMQUERYSUSPENDFAILED), MSG_DEBUG_ENTRY(PBT_APMRESUMEAUTOMATIC), MSG_DEBUG_ENTRY(PBT_APMRESUMECRITICAL), MSG_DEBUG_ENTRY(PBT_APMRESUMESTANDBY), MSG_DEBUG_ENTRY(PBT_APMRESUMESUSPEND), MSG_DEBUG_ENTRY(PBT_APMSTANDBY), MSG_DEBUG_ENTRY(PBT_APMSUSPEND), MSG_DEBUG_ENTRY(SBM_GETSCROLLBARINFO), MSG_DEBUG_ENTRY(SBM_GETSCROLLINFO), MSG_DEBUG_ENTRY(SBM_SETSCROLLINFO), MSG_DEBUG_ENTRY(STM_GETICON), MSG_DEBUG_ENTRY(STM_GETIMAGE), MSG_DEBUG_ENTRY(STM_MSGMAX), MSG_DEBUG_ENTRY(STM_SETICON), MSG_DEBUG_ENTRY(STM_SETIMAGE), MSG_DEBUG_ENTRY(WM_ACTIVATE), MSG_DEBUG_ENTRY(WM_ACTIVATEAPP), MSG_DEBUG_ENTRY(WM_APP), MSG_DEBUG_ENTRY(WM_APPCOMMAND), MSG_DEBUG_ENTRY(WM_ASKCBFORMATNAME), MSG_DEBUG_ENTRY(WM_CANCELJOURNAL), MSG_DEBUG_ENTRY(WM_CANCELMODE), MSG_DEBUG_ENTRY(WM_CAPTURECHANGED), MSG_DEBUG_ENTRY(WM_CHANGECBCHAIN), MSG_DEBUG_ENTRY(WM_CHANGEUISTATE), MSG_DEBUG_ENTRY(WM_CHAR), MSG_DEBUG_ENTRY(WM_CHARTOITEM), MSG_DEBUG_ENTRY(WM_CHILDACTIVATE), MSG_DEBUG_ENTRY(WM_CLEAR), MSG_DEBUG_ENTRY(WM_CLOSE), MSG_DEBUG_ENTRY(WM_COMMAND), MSG_DEBUG_ENTRY(WM_COMPACTING), MSG_DEBUG_ENTRY(WM_COMPAREITEM), MSG_DEBUG_ENTRY(WM_CONTEXTMENU), MSG_DEBUG_ENTRY(WM_COPY), MSG_DEBUG_ENTRY(WM_COPYDATA), MSG_DEBUG_ENTRY(WM_CREATE), MSG_DEBUG_ENTRY(WM_CTLCOLORBTN), MSG_DEBUG_ENTRY(WM_CTLCOLORDLG), MSG_DEBUG_ENTRY(WM_CTLCOLOREDIT), MSG_DEBUG_ENTRY(WM_CTLCOLORLISTBOX), MSG_DEBUG_ENTRY(WM_CTLCOLORMSGBOX), MSG_DEBUG_ENTRY(WM_CTLCOLORSCROLLBAR), MSG_DEBUG_ENTRY(WM_CTLCOLORSTATIC), MSG_DEBUG_ENTRY(WM_CUT), MSG_DEBUG_ENTRY(WM_DEADCHAR), MSG_DEBUG_ENTRY(WM_DELETEITEM), MSG_DEBUG_ENTRY(WM_DESTROY), MSG_DEBUG_ENTRY(WM_DESTROYCLIPBOARD), MSG_DEBUG_ENTRY(WM_DEVICECHANGE), MSG_DEBUG_ENTRY(WM_DEVMODECHANGE), MSG_DEBUG_ENTRY(WM_DISPLAYCHANGE), MSG_DEBUG_ENTRY(WM_DRAWCLIPBOARD), MSG_DEBUG_ENTRY(WM_DRAWITEM), MSG_DEBUG_ENTRY(WM_DROPFILES), MSG_DEBUG_ENTRY(WM_ENABLE), MSG_DEBUG_ENTRY(WM_ENDSESSION), MSG_DEBUG_ENTRY(WM_ENTERIDLE), MSG_DEBUG_ENTRY(WM_ENTERMENULOOP), MSG_DEBUG_ENTRY(WM_ENTERSIZEMOVE), MSG_DEBUG_ENTRY(WM_ERASEBKGND), MSG_DEBUG_ENTRY(WM_EXITMENULOOP), MSG_DEBUG_ENTRY(WM_EXITSIZEMOVE), MSG_DEBUG_ENTRY(WM_FONTCHANGE), MSG_DEBUG_ENTRY(WM_GETDLGCODE), MSG_DEBUG_ENTRY(WM_GETFONT), MSG_DEBUG_ENTRY(WM_GETHOTKEY), MSG_DEBUG_ENTRY(WM_GETICON), MSG_DEBUG_ENTRY(WM_GETMINMAXINFO), MSG_DEBUG_ENTRY(WM_GETOBJECT), MSG_DEBUG_ENTRY(WM_GETTEXT), MSG_DEBUG_ENTRY(WM_GETTEXTLENGTH), MSG_DEBUG_ENTRY(WM_HELP), MSG_DEBUG_ENTRY(WM_HOTKEY), MSG_DEBUG_ENTRY(WM_HSCROLL), MSG_DEBUG_ENTRY(WM_HSCROLLCLIPBOARD), MSG_DEBUG_ENTRY(WM_ICONERASEBKGND), MSG_DEBUG_ENTRY(WM_IME_CHAR), MSG_DEBUG_ENTRY(WM_IME_COMPOSITION), MSG_DEBUG_ENTRY(WM_IME_COMPOSITIONFULL), MSG_DEBUG_ENTRY(WM_IME_CONTROL), MSG_DEBUG_ENTRY(WM_IME_ENDCOMPOSITION), MSG_DEBUG_ENTRY(WM_IME_KEYDOWN), MSG_DEBUG_ENTRY(WM_IME_KEYLAST), MSG_DEBUG_ENTRY(WM_IME_KEYUP), MSG_DEBUG_ENTRY(WM_IME_NOTIFY), MSG_DEBUG_ENTRY(WM_IME_REQUEST), MSG_DEBUG_ENTRY(WM_IME_SELECT), MSG_DEBUG_ENTRY(WM_IME_SETCONTEXT), MSG_DEBUG_ENTRY(WM_IME_STARTCOMPOSITION), MSG_DEBUG_ENTRY(WM_INITDIALOG), MSG_DEBUG_ENTRY(WM_INITMENU), MSG_DEBUG_ENTRY(WM_INITMENUPOPUP), MSG_DEBUG_ENTRY(WM_INPUT), MSG_DEBUG_ENTRY(WM_INPUTLANGCHANGE), MSG_DEBUG_ENTRY(WM_INPUTLANGCHANGEREQUEST), MSG_DEBUG_ENTRY(WM_KEYDOWN), MSG_DEBUG_ENTRY(WM_KEYUP), MSG_DEBUG_ENTRY(WM_KILLFOCUS), MSG_DEBUG_ENTRY(WM_LBUTTONDBLCLK), MSG_DEBUG_ENTRY(WM_LBUTTONDOWN), MSG_DEBUG_ENTRY(WM_LBUTTONUP), MSG_DEBUG_ENTRY(WM_MBUTTONDBLCLK), MSG_DEBUG_ENTRY(WM_MBUTTONDOWN), MSG_DEBUG_ENTRY(WM_MBUTTONUP), MSG_DEBUG_ENTRY(WM_MDIACTIVATE), MSG_DEBUG_ENTRY(WM_MDICASCADE), MSG_DEBUG_ENTRY(WM_MDICREATE), MSG_DEBUG_ENTRY(WM_MDIDESTROY), MSG_DEBUG_ENTRY(WM_MDIGETACTIVE), MSG_DEBUG_ENTRY(WM_MDIICONARRANGE), MSG_DEBUG_ENTRY(WM_MDIMAXIMIZE), MSG_DEBUG_ENTRY(WM_MDINEXT), MSG_DEBUG_ENTRY(WM_MDIREFRESHMENU), MSG_DEBUG_ENTRY(WM_MDIRESTORE), MSG_DEBUG_ENTRY(WM_MDISETMENU), MSG_DEBUG_ENTRY(WM_MDITILE), MSG_DEBUG_ENTRY(WM_MEASUREITEM), MSG_DEBUG_ENTRY(WM_MENUCHAR), MSG_DEBUG_ENTRY(WM_MENUCOMMAND), MSG_DEBUG_ENTRY(WM_MENUDRAG), MSG_DEBUG_ENTRY(WM_MENUGETOBJECT), MSG_DEBUG_ENTRY(WM_MENURBUTTONUP), MSG_DEBUG_ENTRY(WM_MENUSELECT), MSG_DEBUG_ENTRY(WM_MOUSEACTIVATE), MSG_DEBUG_ENTRY(WM_MOUSEHOVER), MSG_DEBUG_ENTRY(WM_MOUSELEAVE), MSG_DEBUG_ENTRY(WM_MOUSEMOVE), MSG_DEBUG_ENTRY(WM_MOUSEWHEEL), MSG_DEBUG_ENTRY(WM_MOVE), MSG_DEBUG_ENTRY(WM_MOVING), MSG_DEBUG_ENTRY(WM_NCACTIVATE), MSG_DEBUG_ENTRY(WM_NCCALCSIZE), MSG_DEBUG_ENTRY(WM_NCCREATE), MSG_DEBUG_ENTRY(WM_NCDESTROY), MSG_DEBUG_ENTRY(WM_NCHITTEST), MSG_DEBUG_ENTRY(WM_NCLBUTTONDBLCLK), MSG_DEBUG_ENTRY(WM_NCLBUTTONDOWN), MSG_DEBUG_ENTRY(WM_NCLBUTTONUP), MSG_DEBUG_ENTRY(WM_NCMBUTTONDBLCLK), MSG_DEBUG_ENTRY(WM_NCMBUTTONDOWN), MSG_DEBUG_ENTRY(WM_NCMBUTTONUP), MSG_DEBUG_ENTRY(WM_NCMOUSEHOVER), MSG_DEBUG_ENTRY(WM_NCMOUSELEAVE), MSG_DEBUG_ENTRY(WM_NCMOUSEMOVE), MSG_DEBUG_ENTRY(WM_NCPAINT), MSG_DEBUG_ENTRY(WM_NCRBUTTONDBLCLK), MSG_DEBUG_ENTRY(WM_NCRBUTTONDOWN), MSG_DEBUG_ENTRY(WM_NCRBUTTONUP), MSG_DEBUG_ENTRY(WM_NCXBUTTONDBLCLK), MSG_DEBUG_ENTRY(WM_NCXBUTTONDOWN), MSG_DEBUG_ENTRY(WM_NCXBUTTONUP), MSG_DEBUG_ENTRY(WM_NEXTDLGCTL), MSG_DEBUG_ENTRY(WM_NEXTMENU), MSG_DEBUG_ENTRY(WM_NOTIFY), MSG_DEBUG_ENTRY(WM_NOTIFYFORMAT), MSG_DEBUG_ENTRY(WM_NULL), MSG_DEBUG_ENTRY(WM_PAINT), MSG_DEBUG_ENTRY(WM_PAINTCLIPBOARD), MSG_DEBUG_ENTRY(WM_PAINTICON), MSG_DEBUG_ENTRY(WM_PALETTECHANGED), MSG_DEBUG_ENTRY(WM_PALETTEISCHANGING), MSG_DEBUG_ENTRY(WM_PARENTNOTIFY), MSG_DEBUG_ENTRY(WM_PASTE), MSG_DEBUG_ENTRY(WM_POWER), MSG_DEBUG_ENTRY(WM_POWERBROADCAST), MSG_DEBUG_ENTRY(WM_PRINT), MSG_DEBUG_ENTRY(WM_PRINTCLIENT), MSG_DEBUG_ENTRY(WM_QUERYDRAGICON), MSG_DEBUG_ENTRY(WM_QUERYENDSESSION), MSG_DEBUG_ENTRY(WM_QUERYNEWPALETTE), MSG_DEBUG_ENTRY(WM_QUERYOPEN), MSG_DEBUG_ENTRY(WM_QUERYUISTATE), MSG_DEBUG_ENTRY(WM_QUEUESYNC), MSG_DEBUG_ENTRY(WM_QUIT), MSG_DEBUG_ENTRY(WM_RBUTTONDBLCLK), MSG_DEBUG_ENTRY(WM_RBUTTONDOWN), MSG_DEBUG_ENTRY(WM_RBUTTONUP), MSG_DEBUG_ENTRY(WM_RENDERALLFORMATS), MSG_DEBUG_ENTRY(WM_RENDERFORMAT), MSG_DEBUG_ENTRY(WM_SETCURSOR), MSG_DEBUG_ENTRY(WM_SETFOCUS), MSG_DEBUG_ENTRY(WM_SETFONT), MSG_DEBUG_ENTRY(WM_SETHOTKEY), MSG_DEBUG_ENTRY(WM_SETICON), MSG_DEBUG_ENTRY(WM_SETREDRAW), MSG_DEBUG_ENTRY(WM_SETTEXT), MSG_DEBUG_ENTRY(WM_SHOWWINDOW), MSG_DEBUG_ENTRY(WM_SIZE), MSG_DEBUG_ENTRY(WM_SIZECLIPBOARD), MSG_DEBUG_ENTRY(WM_SIZING), MSG_DEBUG_ENTRY(WM_SPOOLERSTATUS), MSG_DEBUG_ENTRY(WM_STYLECHANGED), MSG_DEBUG_ENTRY(WM_STYLECHANGING), MSG_DEBUG_ENTRY(WM_SYNCPAINT), MSG_DEBUG_ENTRY(WM_SYSCHAR), MSG_DEBUG_ENTRY(WM_SYSCOLORCHANGE), MSG_DEBUG_ENTRY(WM_SYSCOMMAND), MSG_DEBUG_ENTRY(WM_SYSDEADCHAR), MSG_DEBUG_ENTRY(WM_SYSKEYDOWN), MSG_DEBUG_ENTRY(WM_SYSKEYUP), MSG_DEBUG_ENTRY(WM_TCARD), MSG_DEBUG_ENTRY(WM_THEMECHANGED), MSG_DEBUG_ENTRY(WM_TIMECHANGE), MSG_DEBUG_ENTRY(WM_TIMER), MSG_DEBUG_ENTRY(WM_UNDO), MSG_DEBUG_ENTRY(WM_UNICHAR), MSG_DEBUG_ENTRY(WM_UNINITMENUPOPUP), MSG_DEBUG_ENTRY(WM_UPDATEUISTATE), MSG_DEBUG_ENTRY(WM_USER), MSG_DEBUG_ENTRY(WM_USERCHANGED), MSG_DEBUG_ENTRY(WM_VKEYTOITEM), MSG_DEBUG_ENTRY(WM_VSCROLL), MSG_DEBUG_ENTRY(WM_VSCROLLCLIPBOARD), MSG_DEBUG_ENTRY(WM_WINDOWPOSCHANGED), MSG_DEBUG_ENTRY(WM_WINDOWPOSCHANGING), MSG_DEBUG_ENTRY(WM_WININICHANGE), MSG_DEBUG_ENTRY(WM_WTSSESSION_CHANGE), MSG_DEBUG_ENTRY(WM_XBUTTONDBLCLK), MSG_DEBUG_ENTRY(WM_XBUTTONDOWN), MSG_DEBUG_ENTRY(WM_XBUTTONUP) };
#define MSG_DEBUG_MAP_SIZE (sizeof(s_MsgDebugStrings)/sizeof(s_MsgDebugStrings[0]))
BOOL WINAPI GetStringFromMsgA( UINT uMsg, LPSTR pszString, int nMaxLen ) { if (!pszString || !nMaxLen) { return FALSE; } for (int i=0;i<MSG_DEBUG_MAP_SIZE;i++) { if (uMsg == s_MsgDebugStrings[i].uMsg) { lstrcpynA( pszString, s_MsgDebugStrings[i].pszName, nMaxLen ); return TRUE; } } lstrcpynA( pszString, CSimpleStringAnsi().Format("Unknown Message: 0x%08X", uMsg ), nMaxLen );
return TRUE; }
BOOL WINAPI GetStringFromMsgW( UINT uMsg, LPWSTR pszString, int nMaxLen ) { BOOL bResult = FALSE; #ifdef UNICODE
if (!pszString || !nMaxLen) { return FALSE; } CHAR szMessage[MAX_PATH]; if (!GetStringFromMsgA(uMsg,szMessage,MAX_PATH)) { return FALSE; } lstrcpynW( pszString, CSimpleStringConvert::WideString(CSimpleStringAnsi(szMessage)), nMaxLen ); bResult = TRUE; #else
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); #endif
return bResult; }
VOID WINAPI DoRecordAllocation( LPVOID pv, size_t Size ) { if (pv) { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { pProcessData->DoRecordAllocation( pv, Size ); } } }
VOID WINAPI DoRecordFree( LPVOID pv ) { if (pv) { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { pProcessData->DoRecordFree( pv ); } } }
VOID WINAPI DoReportLeaks( LPTSTR pszModuleName ) { if (pszModuleName) { CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData(); if (pProcessData && pProcessData->IsValid()) { pProcessData->GenerateLeakReport( pszModuleName ); } } }
|