Leaked source code of windows server 2003
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.

1682 lines
50 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: WIADBG.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 9/6/1999
  12. *
  13. * DESCRIPTION: Implementation of debug code
  14. *
  15. *******************************************************************************/
  16. //
  17. // need to define this so we don't get any recursion on our calls to "new"
  18. //
  19. #define WIA_DONT_DO_LEAK_CHECKS 1
  20. //
  21. // Maximum number of stack entries
  22. //
  23. #define MAX_STACK_DEPTH 32
  24. #include <nt.h>
  25. #include <ntrtl.h>
  26. #include <nturtl.h>
  27. #include <windows.h>
  28. #include "wianew.h"
  29. #include "wiadebug.h"
  30. #include "simstr.h"
  31. #include "miscutil.h"
  32. #include <shlguid.h>
  33. #include <shlobj.h>
  34. #include <shellapi.h>
  35. #include <shlwapi.h>
  36. #include <wia.h>
  37. #include <dbghelp.h>
  38. #define STACK_TRACE_DB_NAME TEXT("ntdll!RtlpStackTraceDataBase")
  39. #define SYMBOL_BUFFER_LEN 256
  40. #define READVM(Addr, Buf, Sz) ReadVa(__FILE__, __LINE__, (Globals.Target), (Addr), (Buf), (Sz))
  41. #ifdef UNICODE
  42. #define PrintDebugMessage PrintDebugMessageW
  43. #else
  44. #define PrintDebugMessage PrintDebugMessageA
  45. #endif
  46. /******************************************************************************
  47. *
  48. * Class definitions
  49. *
  50. ******************************************************************************/
  51. static CGlobalDebugState g_GlobalDebugState;
  52. class CWiaDebugWindowThreadState
  53. {
  54. private:
  55. int m_nIndentLevel;
  56. DWORD m_nDebugMask;
  57. private:
  58. // Not implemented
  59. CWiaDebugWindowThreadState( const CWiaDebugWindowThreadState & );
  60. CWiaDebugWindowThreadState &operator=( const CWiaDebugWindowThreadState & );
  61. public:
  62. CWiaDebugWindowThreadState(void);
  63. DWORD DebugMask(void) const;
  64. DWORD DebugMask( DWORD nDebugMask );
  65. int IndentLevel(void) const;
  66. int IncrementIndentLevel(void);
  67. int DecrementIndentLevel(void);
  68. };
  69. class CProcessGlobalDebugData
  70. {
  71. private:
  72. DWORD m_dwTlsIndex;
  73. BOOL m_bSymLookupInitialized;
  74. PVOID m_pDatabase;
  75. HANDLE m_hProcess;
  76. CSimpleCriticalSection m_CriticalSection;
  77. typedef struct _STACK_NODE
  78. {
  79. LPVOID pKeyAddress;
  80. size_t Size;
  81. PVOID aStack[MAX_STACK_DEPTH];
  82. ULONG ulNumTraces;
  83. _STACK_NODE * pNext;
  84. } STACK_NODE, *PSTACK_NODE;
  85. PSTACK_NODE m_pStackList;
  86. PSTACK_NODE m_pStackListEnd;
  87. LONG m_Leaks;
  88. private:
  89. static CProcessGlobalDebugData *m_pTheProcessGlobalDebugData;
  90. private:
  91. // Not implemented
  92. CProcessGlobalDebugData( const CProcessGlobalDebugData & );
  93. CProcessGlobalDebugData &operator=( const CProcessGlobalDebugData & );
  94. private:
  95. // Sole implemented constructor
  96. CProcessGlobalDebugData(void);
  97. // resolve symbols address into symbols names...
  98. LPTSTR GetSymbolicNameForAddress( ULONG_PTR Address );
  99. BOOL IsSymbolLookupInitialized();
  100. public:
  101. ~CProcessGlobalDebugData(void);
  102. DWORD TlsIndex(void) const;
  103. bool IsValid(void) const;
  104. void DoRecordAllocation( LPVOID pv, size_t Size );
  105. void DoRecordFree( LPVOID pv );
  106. void GenerateLeakReport( LPTSTR pszModuleName );
  107. HANDLE ProcessHandle( ) { return m_hProcess; }
  108. static CProcessGlobalDebugData *Allocate(void);
  109. static CProcessGlobalDebugData *ProcessData(void);
  110. static void Free(void);
  111. };
  112. /******************************************************************************
  113. *
  114. * Symbol functions
  115. *
  116. ******************************************************************************/
  117. BOOL
  118. EnumerateModules(
  119. IN LPSTR ModuleName,
  120. IN ULONG_PTR BaseOfDll,
  121. IN PVOID UserContext
  122. )
  123. /*
  124. * EnumerateModules
  125. *
  126. * Module enumeration 'proc' for imagehlp. Call SymLoadModule on the
  127. * specified module and if that succeeds cache the module name.
  128. *
  129. * ModuleName is an LPSTR indicating the name of the module imagehlp is
  130. * enumerating for us;
  131. * BaseOfDll is the load address of the DLL, which we don't care about, but
  132. * SymLoadModule does;
  133. * UserContext is a pointer to the relevant SYMINFO, which identifies
  134. * our connection.
  135. */
  136. {
  137. DWORD64 Result;
  138. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  139. if (pProcessData && pProcessData->IsValid())
  140. {
  141. Result = SymLoadModule(pProcessData->ProcessHandle(),
  142. NULL, // hFile not used
  143. NULL, // use symbol search path
  144. ModuleName, // ModuleName from Enum
  145. BaseOfDll, // LoadAddress from Enum
  146. 0); // Let ImageHlp figure out DLL size
  147. // SilviuC: need to understand exactly what does this function return
  148. if (Result)
  149. {
  150. return FALSE;
  151. }
  152. return TRUE;
  153. }
  154. return FALSE;
  155. }
  156. /******************************************************************************
  157. *
  158. * CWiaDebugWindowThreadState
  159. *
  160. ******************************************************************************/
  161. CWiaDebugWindowThreadState::CWiaDebugWindowThreadState(void)
  162. : m_nIndentLevel(0),
  163. m_nDebugMask(0xFFFFFFFF)
  164. {
  165. }
  166. DWORD CWiaDebugWindowThreadState::DebugMask(void) const
  167. {
  168. return m_nDebugMask;
  169. }
  170. DWORD CWiaDebugWindowThreadState::DebugMask( DWORD nDebugMask )
  171. {
  172. DWORD nOldDebugMask = m_nDebugMask;
  173. m_nDebugMask = nDebugMask;
  174. return nOldDebugMask;
  175. }
  176. int CWiaDebugWindowThreadState::IndentLevel(void) const
  177. {
  178. return m_nIndentLevel;
  179. }
  180. int CWiaDebugWindowThreadState::IncrementIndentLevel(void)
  181. {
  182. return (++m_nIndentLevel);
  183. }
  184. int CWiaDebugWindowThreadState::DecrementIndentLevel(void)
  185. {
  186. --m_nIndentLevel;
  187. if (m_nIndentLevel < 0)
  188. m_nIndentLevel = 0;
  189. return m_nIndentLevel;
  190. }
  191. /******************************************************************************
  192. *
  193. * CProcessGlobalDebugData
  194. *
  195. ******************************************************************************/
  196. // Sole implemented constructor
  197. CProcessGlobalDebugData::CProcessGlobalDebugData(void)
  198. : m_dwTlsIndex(TLS_OUT_OF_INDEXES),
  199. m_hProcess(NULL),
  200. m_pDatabase(NULL),
  201. m_bSymLookupInitialized(FALSE),
  202. m_pStackList(NULL),
  203. m_pStackListEnd(NULL),
  204. m_Leaks(0)
  205. {
  206. m_dwTlsIndex = TlsAlloc();
  207. }
  208. CProcessGlobalDebugData::~CProcessGlobalDebugData(void)
  209. {
  210. if (m_dwTlsIndex != TLS_OUT_OF_INDEXES)
  211. TlsFree(m_dwTlsIndex);
  212. m_dwTlsIndex = TLS_OUT_OF_INDEXES;
  213. if (m_hProcess)
  214. {
  215. CloseHandle(m_hProcess);
  216. m_hProcess = NULL;
  217. }
  218. m_bSymLookupInitialized = FALSE;
  219. CAutoCriticalSection cs(m_CriticalSection);
  220. if (m_pStackList)
  221. {
  222. PSTACK_NODE pNextNode = NULL;
  223. for (PSTACK_NODE pNode = m_pStackList; pNode; )
  224. {
  225. if (pNode)
  226. {
  227. pNextNode = pNode->pNext;
  228. LocalFree( pNode );
  229. }
  230. pNode = pNextNode;
  231. pNextNode = NULL;
  232. }
  233. }
  234. }
  235. DWORD CProcessGlobalDebugData::TlsIndex(void) const
  236. {
  237. return m_dwTlsIndex;
  238. }
  239. bool CProcessGlobalDebugData::IsValid(void) const
  240. {
  241. return (m_dwTlsIndex != TLS_OUT_OF_INDEXES);
  242. }
  243. //
  244. // Caller must free returned string via LocalFree
  245. //
  246. LPTSTR CProcessGlobalDebugData::GetSymbolicNameForAddress( ULONG_PTR Address )
  247. {
  248. IMAGEHLP_MODULE ModuleInfo;
  249. TCHAR SymbolBuffer[512];
  250. PIMAGEHLP_SYMBOL Symbol;
  251. ULONG_PTR Offset;
  252. LPTSTR pName;
  253. BOOL bResult;
  254. if (!IsSymbolLookupInitialized())
  255. {
  256. return NULL;
  257. }
  258. if (Address == (ULONG_PTR)-1)
  259. {
  260. *SymbolBuffer = 0;
  261. lstrcpyn( SymbolBuffer, TEXT("<< FUZZY STACK TRACE >>"), ARRAYSIZE(SymbolBuffer) );
  262. pName = (LPTSTR)LocalAlloc( LPTR, (lstrlen( SymbolBuffer ) + 1) * sizeof(TCHAR) );
  263. if (pName)
  264. {
  265. lstrcpy( pName, SymbolBuffer );
  266. }
  267. return pName;
  268. }
  269. ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
  270. if (!SymGetModuleInfo( m_hProcess, Address, &ModuleInfo ))
  271. {
  272. //
  273. // can't get the module info, so give back an error message...
  274. //
  275. *SymbolBuffer = 0;
  276. wnsprintf( SymbolBuffer, ARRAYSIZE(SymbolBuffer), TEXT("<< cannot identify module for address %p >>"), Address );
  277. pName = (LPTSTR)LocalAlloc( LPTR, (lstrlen( SymbolBuffer ) + 1) * sizeof(TCHAR) );
  278. if (pName)
  279. {
  280. lstrcpy( pName, SymbolBuffer );
  281. }
  282. return pName;
  283. }
  284. Symbol = (PIMAGEHLP_SYMBOL)SymbolBuffer;
  285. Symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL) - 1;
  286. if (SymGetSymFromAddr( m_hProcess, Address, &Offset, Symbol ))
  287. {
  288. IMAGEHLP_LINE LineInfo;
  289. DWORD Displacement;
  290. BOOL bLineInfoPresent;
  291. CHAR szString[ 1024 ];
  292. bLineInfoPresent = SymGetLineFromAddr (m_hProcess,
  293. Address,
  294. &Displacement,
  295. &LineInfo);
  296. if (bLineInfoPresent)
  297. {
  298. //
  299. // construct string w/filename & linenumber...
  300. //
  301. wsprintfA( szString, "%s!%s (%s, line %u)", ModuleInfo.ModuleName, Symbol->Name, LineInfo.FileName, LineInfo.LineNumber );
  302. }
  303. else
  304. {
  305. //
  306. // no line numbers, so just show symbol + offset
  307. //
  308. wsprintfA( szString, "%s!%s+%08X", ModuleInfo.ModuleName, Symbol->Name, Offset );
  309. }
  310. INT iLen = (lstrlenA(szString)+1);
  311. pName = (LPTSTR) LocalAlloc( LPTR, (iLen * sizeof(TCHAR)) );
  312. if (pName == NULL)
  313. {
  314. return NULL;
  315. }
  316. #ifdef UNICODE
  317. MultiByteToWideChar( CP_ACP, 0, szString, -1, pName, iLen );
  318. #else
  319. lstrcpy( pName, szString);
  320. #endif
  321. return pName;
  322. }
  323. else
  324. {
  325. //
  326. // can't get the address info, so give back an error message...
  327. //
  328. *SymbolBuffer = 0;
  329. #ifdef UNICODE
  330. TCHAR szModW[ MAX_PATH ];
  331. MultiByteToWideChar( CP_ACP, 0, ModuleInfo.ModuleName, -1, szModW, ARRAYSIZE(szModW) );
  332. wnsprintf( SymbolBuffer, ARRAYSIZE(SymbolBuffer), TEXT("<< incorrect symbols for module %s (address %p)"), szModW, Address );
  333. #else
  334. wnsprintf( SymbolBuffer, ARRAYSIZE(SymbolBuffer), TEXT("<< incorrect symbols for module %s (address %p)"), ModuleInfo.ModuleName, Address );
  335. #endif
  336. pName = (LPTSTR)LocalAlloc( LPTR, (lstrlen( SymbolBuffer ) + 1) * sizeof(TCHAR) );
  337. if (pName)
  338. {
  339. lstrcpy( pName, SymbolBuffer );
  340. }
  341. return pName;
  342. }
  343. return NULL;
  344. }
  345. void CProcessGlobalDebugData::DoRecordAllocation( LPVOID pv, size_t Size )
  346. {
  347. if (!pv)
  348. {
  349. return;
  350. }
  351. PVOID StackTrace[MAX_STACK_DEPTH];
  352. ULONG Count;
  353. ULONG Index;
  354. ULONG Hash;
  355. //
  356. // Capture stack trace up to MAX_STACK_DEPTH items deep, but skip last three items
  357. // (because they'll always be the same)
  358. //
  359. Count = RtlCaptureStackBackTrace( 4, MAX_STACK_DEPTH, StackTrace, NULL );
  360. if (Count)
  361. {
  362. CAutoCriticalSection cs(m_CriticalSection);
  363. //
  364. // Add this stack trace to list
  365. //
  366. PSTACK_NODE pNewNode = (PSTACK_NODE)LocalAlloc( LPTR, sizeof(STACK_NODE) );
  367. if (pNewNode)
  368. {
  369. pNewNode->pKeyAddress = pv;
  370. pNewNode->Size = Size;
  371. pNewNode->ulNumTraces = Count;
  372. memcpy( pNewNode->aStack, StackTrace, sizeof(pNewNode->aStack) );
  373. }
  374. if (!m_pStackList)
  375. {
  376. m_pStackList = pNewNode;
  377. m_pStackListEnd = pNewNode;
  378. }
  379. else
  380. {
  381. m_pStackListEnd->pNext = pNewNode;
  382. m_pStackListEnd = pNewNode;
  383. }
  384. m_Leaks++;
  385. }
  386. }
  387. void CProcessGlobalDebugData::DoRecordFree( LPVOID pv )
  388. {
  389. if (!pv)
  390. {
  391. return;
  392. }
  393. CAutoCriticalSection cs(m_CriticalSection);
  394. //
  395. // Find item in allocation list...
  396. //
  397. PSTACK_NODE pNode = NULL;
  398. PSTACK_NODE pTrail = NULL;
  399. for ( pNode = m_pStackList;
  400. pNode && (pNode->pKeyAddress!=pv);
  401. pTrail = pNode, pNode = pNode->pNext
  402. )
  403. {
  404. ;
  405. }
  406. if (pNode)
  407. {
  408. //
  409. // Remove this node from the list...
  410. //
  411. if (!pTrail)
  412. {
  413. //
  414. // It's the first item in list
  415. //
  416. m_pStackList = pNode->pNext;
  417. if (m_pStackListEnd == pNode)
  418. {
  419. m_pStackListEnd = NULL;
  420. }
  421. LocalFree( (HLOCAL) pNode );
  422. m_Leaks--;
  423. }
  424. else
  425. {
  426. //
  427. // We're somewhere in the middle of the list...
  428. //
  429. pTrail->pNext = pNode->pNext;
  430. if (m_pStackListEnd == pNode)
  431. {
  432. m_pStackListEnd = pTrail;
  433. }
  434. LocalFree( (HLOCAL) pNode );
  435. m_Leaks--;
  436. }
  437. }
  438. }
  439. void CProcessGlobalDebugData::GenerateLeakReport(LPTSTR pszModuleName)
  440. {
  441. CAutoCriticalSection cs(m_CriticalSection);
  442. //
  443. // Report the numer of leaks...
  444. //
  445. TCHAR sz[ 512 ];
  446. TCHAR szNewLine[ 3 ] = TEXT("\n");
  447. COLORREF crFore = static_cast<COLORREF>(0xFFFFFFFF), crBack = static_cast<COLORREF>(0xFFFFFFFF);
  448. if (m_Leaks > 0)
  449. {
  450. crFore = RGB(0x00,0x00,0x00);
  451. crBack = RGB(0xFF,0x7F,0x7F);
  452. }
  453. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, szNewLine );
  454. wnsprintf( sz, ARRAYSIZE(sz), TEXT("**** Reporting leaks -- %d leaks found ****"), m_Leaks );
  455. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, sz );
  456. //
  457. // Loop through the list...
  458. //
  459. LPTSTR pSymbol = NULL;
  460. PSTACK_NODE pNode = m_pStackList;
  461. INT i = 1;
  462. while (pNode)
  463. {
  464. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, szNewLine );
  465. wnsprintf( sz, ARRAYSIZE(sz), TEXT("Leak %d - %d bytes allocated by:"), i++, pNode->Size );
  466. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, sz );
  467. for (INT j=0; (j < (INT)pNode->ulNumTraces) && (pNode->aStack[j]); j++)
  468. {
  469. pSymbol = GetSymbolicNameForAddress( (ULONG_PTR)pNode->aStack[j] );
  470. if (pSymbol)
  471. {
  472. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, pSymbol );
  473. LocalFree( (HLOCAL)pSymbol );
  474. }
  475. else
  476. {
  477. wnsprintf( sz, ARRAYSIZE(sz), TEXT("< could not resolve symbols for address %p >"),pNode->aStack[j] );
  478. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, sz );
  479. }
  480. }
  481. pNode = pNode->pNext;
  482. }
  483. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, szNewLine );
  484. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, TEXT("**** End Leak Report ****") );
  485. PrintDebugMessage( 2, 0xFFFFFFFF, crFore, crBack, pszModuleName, szNewLine );
  486. }
  487. BOOL
  488. CProcessGlobalDebugData::IsSymbolLookupInitialized()
  489. {
  490. CAutoCriticalSection cs(m_CriticalSection);
  491. if (!m_bSymLookupInitialized)
  492. {
  493. if (m_hProcess)
  494. {
  495. CloseHandle( m_hProcess );
  496. m_hProcess = NULL;
  497. }
  498. m_hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
  499. FALSE,
  500. GetCurrentProcessId()
  501. );
  502. if (m_hProcess)
  503. {
  504. if (SymInitialize( m_hProcess, NULL, TRUE ))
  505. {
  506. SymSetOptions(SYMOPT_CASE_INSENSITIVE |
  507. SYMOPT_DEFERRED_LOADS |
  508. SYMOPT_LOAD_LINES |
  509. SYMOPT_UNDNAME);
  510. if (SymEnumerateModules( m_hProcess, EnumerateModules, m_hProcess))
  511. {
  512. m_bSymLookupInitialized = TRUE;
  513. }
  514. }
  515. }
  516. }
  517. return m_bSymLookupInitialized;
  518. }
  519. CProcessGlobalDebugData *CProcessGlobalDebugData::Allocate(void)
  520. {
  521. if (!m_pTheProcessGlobalDebugData)
  522. m_pTheProcessGlobalDebugData = new CProcessGlobalDebugData;
  523. return (m_pTheProcessGlobalDebugData);
  524. }
  525. CProcessGlobalDebugData *CProcessGlobalDebugData::ProcessData(void)
  526. {
  527. return Allocate();
  528. }
  529. void CProcessGlobalDebugData::Free(void)
  530. {
  531. if (m_pTheProcessGlobalDebugData)
  532. {
  533. delete m_pTheProcessGlobalDebugData;
  534. m_pTheProcessGlobalDebugData = NULL;
  535. }
  536. }
  537. CProcessGlobalDebugData *CProcessGlobalDebugData::m_pTheProcessGlobalDebugData = NULL;
  538. /******************************************************************************
  539. *
  540. * DllMain
  541. *
  542. ******************************************************************************/
  543. BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID )
  544. {
  545. BOOL bResult = FALSE;
  546. switch (dwReason)
  547. {
  548. case DLL_PROCESS_ATTACH:
  549. {
  550. bResult = (CProcessGlobalDebugData::Allocate() != NULL);
  551. }
  552. break;
  553. case DLL_PROCESS_DETACH:
  554. {
  555. CProcessGlobalDebugData::Free();
  556. bResult = TRUE;
  557. }
  558. break;
  559. case DLL_THREAD_ATTACH:
  560. {
  561. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  562. if (pProcessData && pProcessData->IsValid())
  563. {
  564. CWiaDebugWindowThreadState *pThreadData = new CWiaDebugWindowThreadState;
  565. TlsSetValue( pProcessData->TlsIndex(), pThreadData );
  566. bResult = (pThreadData != NULL);
  567. }
  568. }
  569. break;
  570. case DLL_THREAD_DETACH:
  571. {
  572. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  573. if (pProcessData && pProcessData->IsValid())
  574. {
  575. CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState*>(TlsGetValue( pProcessData->TlsIndex()));
  576. if (pThreadData)
  577. {
  578. delete pThreadData;
  579. TlsSetValue( pProcessData->TlsIndex(), NULL );
  580. }
  581. }
  582. bResult = TRUE;
  583. }
  584. break;
  585. }
  586. return bResult;
  587. }
  588. /******************************************************************************
  589. *
  590. * Global Helper Functions
  591. *
  592. ******************************************************************************/
  593. static bool IsProcessDebugFlagSet( DWORD dwModuleMask )
  594. {
  595. bool bResult = false;
  596. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  597. if (pProcessData && pProcessData->IsValid())
  598. {
  599. CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex()));
  600. if (pThreadData)
  601. {
  602. bResult = ((pThreadData->DebugMask() & dwModuleMask) != 0);
  603. }
  604. }
  605. return (bResult);
  606. }
  607. static CWiaDebugWindowThreadState *ThreadData(void)
  608. {
  609. CWiaDebugWindowThreadState *pThreadData = NULL;
  610. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  611. if (pProcessData && pProcessData->IsValid())
  612. {
  613. pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex()));
  614. if (!pThreadData)
  615. {
  616. pThreadData = new CWiaDebugWindowThreadState;
  617. TlsSetValue( pProcessData->TlsIndex(), pThreadData );
  618. }
  619. }
  620. return (pThreadData);
  621. }
  622. template <class T>
  623. static BOOL ContainsNonWhitespace( T *lpszMsg )
  624. {
  625. for (T *lpszPtr = lpszMsg;*lpszPtr;lpszPtr++)
  626. if (*lpszPtr != ' ' && *lpszPtr != '\n' && *lpszPtr != '\r' && *lpszPtr != '\t')
  627. return TRUE;
  628. return FALSE;
  629. }
  630. static void InsertStackLevelIndent( LPSTR lpszMsg, int nStackLevel )
  631. {
  632. const LPSTR lpszIndent = " ";
  633. CHAR szTmp[1024], *pstrTmp, *pstrPtr;
  634. pstrTmp=szTmp;
  635. pstrPtr=lpszMsg;
  636. while (pstrPtr && *pstrPtr)
  637. {
  638. // if the current character is a newline and it isn't the
  639. // last character, append the indent string
  640. if (*pstrPtr=='\n' && ContainsNonWhitespace(pstrPtr))
  641. {
  642. *pstrTmp++ = *pstrPtr++;
  643. for (int i=0;i<WiaUiUtil::Min(nStackLevel,20);i++)
  644. {
  645. lstrcpyA(pstrTmp,lpszIndent);
  646. pstrTmp += lstrlenA(lpszIndent);
  647. }
  648. }
  649. // If this is the first character, insert the indent string before the
  650. // first character
  651. else if (pstrPtr == lpszMsg && ContainsNonWhitespace(pstrPtr))
  652. {
  653. for (int i=0;i<WiaUiUtil::Min(nStackLevel,20);i++)
  654. {
  655. lstrcpyA(pstrTmp,lpszIndent);
  656. pstrTmp += lstrlenA(lpszIndent);
  657. }
  658. *pstrTmp++ = *pstrPtr++;
  659. }
  660. else *pstrTmp++ = *pstrPtr++;
  661. }
  662. *pstrTmp = '\0';
  663. lstrcpyA( lpszMsg, szTmp );
  664. }
  665. static void InsertStackLevelIndent( LPWSTR lpszMsg, int nStackLevel )
  666. {
  667. const LPWSTR lpszIndent = L" ";
  668. WCHAR szTmp[1024], *pstrTmp, *pstrPtr;
  669. pstrTmp=szTmp;
  670. pstrPtr=lpszMsg;
  671. while (pstrPtr && *pstrPtr)
  672. {
  673. // if the current character is a newline and it isn't the
  674. // last character, append the indent string
  675. if (*pstrPtr==L'\n' && ContainsNonWhitespace(pstrPtr))
  676. {
  677. *pstrTmp++ = *pstrPtr++;
  678. for (int i=0;i<WiaUiUtil::Min(nStackLevel,20);i++)
  679. {
  680. lstrcpyW(pstrTmp,lpszIndent);
  681. pstrTmp += lstrlenW(lpszIndent);
  682. }
  683. }
  684. // If this is the first character, insert the indent string before the
  685. // first character
  686. else if (pstrPtr == lpszMsg && ContainsNonWhitespace(pstrPtr))
  687. {
  688. for (int i=0;i<WiaUiUtil::Min(nStackLevel,20);i++)
  689. {
  690. lstrcpyW(pstrTmp,lpszIndent);
  691. pstrTmp += lstrlenW(lpszIndent);
  692. }
  693. *pstrTmp++ = *pstrPtr++;
  694. }
  695. else *pstrTmp++ = *pstrPtr++;
  696. }
  697. *pstrTmp = L'\0';
  698. lstrcpyW( lpszMsg, szTmp );
  699. }
  700. static void PrependString( LPTSTR lpszTgt, LPCTSTR lpszStr )
  701. {
  702. if (ContainsNonWhitespace(lpszTgt))
  703. {
  704. int iLen = lstrlen(lpszTgt);
  705. int iThreadIdLen = lstrlen(lpszStr);
  706. LPTSTR lpszTmp = (LPTSTR)LocalAlloc( LPTR, (iLen + iThreadIdLen + 2)*sizeof(TCHAR));
  707. if (lpszTmp)
  708. {
  709. lstrcpy( lpszTmp, lpszStr );
  710. lstrcat( lpszTmp, TEXT(" ") );
  711. lstrcat( lpszTmp, lpszTgt );
  712. lstrcpy( lpszTgt, lpszTmp );
  713. LocalFree(lpszTmp);
  714. }
  715. }
  716. }
  717. static void PrependThreadId( LPTSTR lpszMsg )
  718. {
  719. if (ContainsNonWhitespace(lpszMsg))
  720. {
  721. TCHAR szThreadId[20];
  722. wnsprintf( szThreadId, ARRAYSIZE(szThreadId), TEXT("[%08X]"), GetCurrentThreadId() );
  723. PrependString( lpszMsg, szThreadId );
  724. }
  725. }
  726. /******************************************************************************
  727. *
  728. * Exported Functions
  729. *
  730. ******************************************************************************/
  731. int WINAPI IncrementDebugIndentLevel(void)
  732. {
  733. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  734. if (pProcessData && pProcessData->IsValid())
  735. {
  736. CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex()));
  737. if (pThreadData)
  738. {
  739. return pThreadData->IncrementIndentLevel();
  740. }
  741. }
  742. return 0;
  743. }
  744. int WINAPI DecrementDebugIndentLevel(void)
  745. {
  746. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  747. if (pProcessData && pProcessData->IsValid())
  748. {
  749. CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex()));
  750. if (pThreadData)
  751. {
  752. return pThreadData->DecrementIndentLevel();
  753. }
  754. }
  755. return 0;
  756. }
  757. DWORD WINAPI GetDebugMask(void)
  758. {
  759. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  760. if (pProcessData && pProcessData->IsValid())
  761. {
  762. CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex()));
  763. if (pThreadData)
  764. {
  765. return pThreadData->DebugMask();
  766. }
  767. }
  768. return 0;
  769. }
  770. DWORD WINAPI SetDebugMask( DWORD dwNewMask )
  771. {
  772. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  773. if (pProcessData && pProcessData->IsValid())
  774. {
  775. CWiaDebugWindowThreadState *pThreadData = reinterpret_cast<CWiaDebugWindowThreadState *>(TlsGetValue(pProcessData->TlsIndex()));
  776. if (pThreadData)
  777. {
  778. return pThreadData->DebugMask(dwNewMask);
  779. }
  780. }
  781. return 0;
  782. }
  783. BOOL WINAPI PrintDebugMessageW( DWORD dwSeverity, DWORD dwModuleMask, COLORREF crForeground, COLORREF crBackground, LPCWSTR pszModuleName, LPCWSTR pszMsg )
  784. {
  785. BOOL bResult = FALSE;
  786. #ifdef UNICODE
  787. CWiaDebugWindowThreadState *pThreadData = ThreadData();
  788. if (pThreadData && (dwSeverity || IsProcessDebugFlagSet(dwModuleMask)))
  789. {
  790. WCHAR szMsg[1024]=L"";
  791. // Print thread id
  792. wsprintfW( szMsg, L"[%ws-%08X] %ws", pszModuleName, GetCurrentThreadId(), pszMsg );
  793. InsertStackLevelIndent( szMsg, pThreadData->IndentLevel() );
  794. lstrcatW( szMsg, L"\n" );
  795. OutputDebugStringW( szMsg );
  796. // Make sure it is a valid window
  797. if (g_GlobalDebugState.DebugWindow())
  798. {
  799. CDebugStringMessageData DebugStringMessageData;
  800. DebugStringMessageData.crBackground = crBackground;
  801. DebugStringMessageData.crForeground = crForeground;
  802. DebugStringMessageData.bUnicode = TRUE;
  803. lstrcpyW( reinterpret_cast<LPWSTR>(DebugStringMessageData.szString), szMsg );
  804. COPYDATASTRUCT CopyDataStruct;
  805. CopyDataStruct.dwData = COPYDATA_DEBUG_MESSAGE_ID;
  806. CopyDataStruct.cbData = sizeof(DebugStringMessageData);
  807. CopyDataStruct.lpData = &DebugStringMessageData;
  808. g_GlobalDebugState.SendDebugWindowMessage( WM_COPYDATA, 0, reinterpret_cast<LPARAM>(&CopyDataStruct) );
  809. }
  810. bResult = TRUE;
  811. }
  812. #else
  813. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  814. #endif
  815. return bResult;
  816. }
  817. BOOL WINAPI PrintDebugMessageA( DWORD dwSeverity, DWORD dwModuleMask, COLORREF crForeground, COLORREF crBackground, LPCSTR pszModuleName, LPCSTR pszMsg )
  818. {
  819. BOOL bResult = FALSE;
  820. CWiaDebugWindowThreadState *pThreadData = ThreadData();
  821. if (pThreadData && (dwSeverity || IsProcessDebugFlagSet(dwModuleMask)))
  822. {
  823. CHAR szMsg[1024]="";
  824. // Print thread id
  825. wsprintfA( szMsg, "[%hs-%08X] %hs", pszModuleName, GetCurrentThreadId(), pszMsg );
  826. InsertStackLevelIndent( szMsg, pThreadData->IndentLevel() );
  827. lstrcatA( szMsg, "\n" );
  828. OutputDebugStringA( szMsg );
  829. // Make sure it is a valid window
  830. if (g_GlobalDebugState.DebugWindow())
  831. {
  832. CDebugStringMessageData DebugStringMessageData;
  833. DebugStringMessageData.crBackground = crBackground;
  834. DebugStringMessageData.crForeground = crForeground;
  835. DebugStringMessageData.bUnicode = FALSE;
  836. lstrcpyA( static_cast<LPSTR>(DebugStringMessageData.szString), szMsg );
  837. COPYDATASTRUCT CopyDataStruct;
  838. CopyDataStruct.dwData = COPYDATA_DEBUG_MESSAGE_ID;
  839. CopyDataStruct.cbData = sizeof(DebugStringMessageData);
  840. CopyDataStruct.lpData = &DebugStringMessageData;
  841. g_GlobalDebugState.SendDebugWindowMessage( WM_COPYDATA, 0, reinterpret_cast<LPARAM>(&CopyDataStruct) );
  842. }
  843. bResult = TRUE;
  844. }
  845. return bResult;
  846. }
  847. COLORREF WINAPI AllocateDebugColor(void)
  848. {
  849. DWORD dwIndex = g_GlobalDebugState.AllocateNextColorIndex();
  850. return g_GlobalDebugState.GetColorFromIndex( dwIndex );
  851. }
  852. #define GUID_DEBUG_ENTRY(guid) { &guid, ""#guid }
  853. static const struct
  854. {
  855. const GUID *pGuid;
  856. LPCSTR pszName;
  857. }
  858. s_GuidDebugStrings[] =
  859. {
  860. GUID_DEBUG_ENTRY(IID_IClassFactory),
  861. GUID_DEBUG_ENTRY(IID_ICommDlgBrowser),
  862. GUID_DEBUG_ENTRY(IID_IContextMenu),
  863. GUID_DEBUG_ENTRY(IID_IContextMenu2),
  864. GUID_DEBUG_ENTRY(IID_IDataObject),
  865. GUID_DEBUG_ENTRY(IID_IDropTarget),
  866. GUID_DEBUG_ENTRY(IID_IEnumIDList),
  867. GUID_DEBUG_ENTRY(IID_IExtractIconA),
  868. GUID_DEBUG_ENTRY(IID_IExtractIconW),
  869. GUID_DEBUG_ENTRY(IID_IFileViewerA),
  870. GUID_DEBUG_ENTRY(IID_IFileViewerSite),
  871. GUID_DEBUG_ENTRY(IID_IFileViewerW),
  872. GUID_DEBUG_ENTRY(IID_IMoniker),
  873. GUID_DEBUG_ENTRY(IID_INewShortcutHookA),
  874. GUID_DEBUG_ENTRY(IID_INewShortcutHookW),
  875. GUID_DEBUG_ENTRY(IID_IOleWindow),
  876. GUID_DEBUG_ENTRY(IID_IPersist),
  877. GUID_DEBUG_ENTRY(IID_IPersistFile),
  878. GUID_DEBUG_ENTRY(IID_IPersistFolder),
  879. GUID_DEBUG_ENTRY(IID_IPersistFolder2),
  880. GUID_DEBUG_ENTRY(IID_IPropSheetPage),
  881. GUID_DEBUG_ENTRY(IID_IQueryInfo),
  882. GUID_DEBUG_ENTRY(IID_ISequentialStream),
  883. GUID_DEBUG_ENTRY(IID_IShellBrowser),
  884. GUID_DEBUG_ENTRY(IID_IShellCopyHookA),
  885. GUID_DEBUG_ENTRY(IID_IShellCopyHookW),
  886. GUID_DEBUG_ENTRY(IID_IShellDetails),
  887. GUID_DEBUG_ENTRY(IID_IShellExecuteHookA),
  888. GUID_DEBUG_ENTRY(IID_IShellExecuteHookW),
  889. GUID_DEBUG_ENTRY(IID_IShellExtInit),
  890. GUID_DEBUG_ENTRY(IID_IShellExtInit),
  891. GUID_DEBUG_ENTRY(IID_IShellFolder),
  892. GUID_DEBUG_ENTRY(IID_IShellIcon),
  893. GUID_DEBUG_ENTRY(IID_IShellIconOverlay),
  894. GUID_DEBUG_ENTRY(IID_IShellIconOverlay),
  895. GUID_DEBUG_ENTRY(IID_IShellLinkA),
  896. GUID_DEBUG_ENTRY(IID_IShellLinkW),
  897. GUID_DEBUG_ENTRY(IID_IShellPropSheetExt),
  898. GUID_DEBUG_ENTRY(IID_IShellPropSheetExt),
  899. GUID_DEBUG_ENTRY(IID_IShellView),
  900. GUID_DEBUG_ENTRY(IID_IShellView2),
  901. GUID_DEBUG_ENTRY(IID_IShellView2),
  902. GUID_DEBUG_ENTRY(IID_IStream),
  903. GUID_DEBUG_ENTRY(IID_IUniformResourceLocator),
  904. GUID_DEBUG_ENTRY(IID_IUnknown),
  905. GUID_DEBUG_ENTRY(WiaImgFmt_UNDEFINED),
  906. GUID_DEBUG_ENTRY(WiaImgFmt_MEMORYBMP),
  907. GUID_DEBUG_ENTRY(WiaImgFmt_BMP),
  908. GUID_DEBUG_ENTRY(WiaImgFmt_EMF),
  909. GUID_DEBUG_ENTRY(WiaImgFmt_WMF),
  910. GUID_DEBUG_ENTRY(WiaImgFmt_JPEG),
  911. GUID_DEBUG_ENTRY(WiaImgFmt_PNG),
  912. GUID_DEBUG_ENTRY(WiaImgFmt_GIF),
  913. GUID_DEBUG_ENTRY(WiaImgFmt_TIFF),
  914. GUID_DEBUG_ENTRY(WiaImgFmt_EXIF),
  915. GUID_DEBUG_ENTRY(WiaImgFmt_PHOTOCD),
  916. GUID_DEBUG_ENTRY(WiaImgFmt_FLASHPIX),
  917. GUID_DEBUG_ENTRY(WiaImgFmt_ICO),
  918. GUID_DEBUG_ENTRY(WiaImgFmt_CIFF),
  919. GUID_DEBUG_ENTRY(WiaImgFmt_PICT),
  920. GUID_DEBUG_ENTRY(WiaImgFmt_JPEG2K),
  921. GUID_DEBUG_ENTRY(WiaImgFmt_JPEG2KX),
  922. GUID_DEBUG_ENTRY(WiaImgFmt_RTF),
  923. GUID_DEBUG_ENTRY(WiaImgFmt_XML),
  924. GUID_DEBUG_ENTRY(WiaImgFmt_HTML),
  925. GUID_DEBUG_ENTRY(WiaImgFmt_TXT),
  926. GUID_DEBUG_ENTRY(WiaImgFmt_MPG),
  927. GUID_DEBUG_ENTRY(WiaImgFmt_AVI),
  928. GUID_DEBUG_ENTRY(WiaImgFmt_ASF),
  929. GUID_DEBUG_ENTRY(WiaImgFmt_SCRIPT),
  930. GUID_DEBUG_ENTRY(WiaImgFmt_EXEC),
  931. GUID_DEBUG_ENTRY(WiaImgFmt_UNICODE16),
  932. GUID_DEBUG_ENTRY(WiaImgFmt_DPOF),
  933. GUID_DEBUG_ENTRY(WiaAudFmt_WAV),
  934. GUID_DEBUG_ENTRY(WiaAudFmt_MP3),
  935. GUID_DEBUG_ENTRY(WiaAudFmt_AIFF),
  936. GUID_DEBUG_ENTRY(WiaAudFmt_WMA),
  937. GUID_DEBUG_ENTRY(WIA_EVENT_DEVICE_DISCONNECTED),
  938. GUID_DEBUG_ENTRY(WIA_EVENT_DEVICE_CONNECTED),
  939. GUID_DEBUG_ENTRY(WIA_EVENT_ITEM_DELETED),
  940. GUID_DEBUG_ENTRY(WIA_EVENT_ITEM_CREATED),
  941. GUID_DEBUG_ENTRY(WIA_EVENT_TREE_UPDATED),
  942. GUID_DEBUG_ENTRY(WIA_EVENT_VOLUME_INSERT),
  943. GUID_DEBUG_ENTRY(WIA_EVENT_SCAN_IMAGE),
  944. GUID_DEBUG_ENTRY(WIA_EVENT_SCAN_PRINT_IMAGE),
  945. GUID_DEBUG_ENTRY(WIA_EVENT_SCAN_FAX_IMAGE),
  946. GUID_DEBUG_ENTRY(WIA_EVENT_STORAGE_CREATED),
  947. GUID_DEBUG_ENTRY(WIA_EVENT_STORAGE_DELETED),
  948. GUID_DEBUG_ENTRY(WIA_EVENT_STI_PROXY),
  949. GUID_DEBUG_ENTRY(WIA_EVENT_HANDLER_NO_ACTION),
  950. GUID_DEBUG_ENTRY(WIA_EVENT_HANDLER_PROMPT),
  951. GUID_DEBUG_ENTRY(WIA_CMD_SYNCHRONIZE),
  952. GUID_DEBUG_ENTRY(WIA_CMD_TAKE_PICTURE),
  953. GUID_DEBUG_ENTRY(WIA_CMD_DELETE_ALL_ITEMS),
  954. GUID_DEBUG_ENTRY(WIA_CMD_CHANGE_DOCUMENT),
  955. GUID_DEBUG_ENTRY(WIA_CMD_UNLOAD_DOCUMENT),
  956. GUID_DEBUG_ENTRY(WIA_CMD_DIAGNOSTIC),
  957. GUID_DEBUG_ENTRY(WIA_CMD_DELETE_DEVICE_TREE),
  958. GUID_DEBUG_ENTRY(WIA_CMD_BUILD_DEVICE_TREE),
  959. GUID_DEBUG_ENTRY(IID_IWiaDevMgr),
  960. GUID_DEBUG_ENTRY(IID_IEnumWIA_DEV_INFO),
  961. GUID_DEBUG_ENTRY(IID_IWiaEventCallback),
  962. GUID_DEBUG_ENTRY(IID_IWiaDataCallback),
  963. GUID_DEBUG_ENTRY(IID_IWiaDataTransfer),
  964. GUID_DEBUG_ENTRY(IID_IWiaItem),
  965. GUID_DEBUG_ENTRY(IID_IWiaPropertyStorage),
  966. GUID_DEBUG_ENTRY(IID_IEnumWiaItem),
  967. GUID_DEBUG_ENTRY(IID_IEnumWIA_DEV_CAPS),
  968. GUID_DEBUG_ENTRY(IID_IEnumWIA_FORMAT_INFO),
  969. GUID_DEBUG_ENTRY(IID_IWiaLog),
  970. GUID_DEBUG_ENTRY(IID_IWiaLogEx),
  971. GUID_DEBUG_ENTRY(IID_IWiaNotifyDevMgr),
  972. GUID_DEBUG_ENTRY(LIBID_WiaDevMgr),
  973. GUID_DEBUG_ENTRY(CLSID_WiaDevMgr),
  974. GUID_DEBUG_ENTRY(CLSID_WiaLog),
  975. GUID_DEBUG_ENTRY(IID_IExtractImage2),
  976. GUID_DEBUG_ENTRY(IID_IExtractImage),
  977. GUID_DEBUG_ENTRY(IID_IShellDetails3),
  978. GUID_DEBUG_ENTRY(IID_IShellFolder2)
  979. };
  980. #define GUID_DEBUG_MAP_SIZE (sizeof(s_GuidDebugStrings)/sizeof(s_GuidDebugStrings[0]))
  981. BOOL WINAPI GetStringFromGuidA( const IID *pGuid, LPSTR pszString, int nMaxLen )
  982. {
  983. if (!pGuid || !pszString || !nMaxLen)
  984. return FALSE;
  985. for (int i=0;i<GUID_DEBUG_MAP_SIZE;i++)
  986. {
  987. if (*pGuid == *s_GuidDebugStrings[i].pGuid)
  988. {
  989. lstrcpynA( pszString, s_GuidDebugStrings[i].pszName, nMaxLen );
  990. return TRUE;
  991. }
  992. }
  993. LPOLESTR pszGuid = NULL;
  994. HRESULT hr = StringFromCLSID( *pGuid, &pszGuid );
  995. if (SUCCEEDED(hr))
  996. {
  997. if (pszGuid)
  998. {
  999. CSimpleStringAnsi strGuid = CSimpleStringConvert::AnsiString(CSimpleStringWide(pszGuid));
  1000. lstrcpynA( pszString, strGuid, nMaxLen );
  1001. CoTaskMemFree(pszGuid);
  1002. return TRUE;
  1003. }
  1004. }
  1005. return FALSE;
  1006. }
  1007. BOOL WINAPI GetStringFromGuidW( const IID *pGuid, LPWSTR pszString, int nMaxLen )
  1008. {
  1009. BOOL bResult = FALSE;
  1010. #ifdef UNICODE
  1011. if (!pGuid || !pszString || !nMaxLen)
  1012. return FALSE;
  1013. CHAR szGuid[MAX_PATH];
  1014. if (!GetStringFromGuidA(pGuid,szGuid,MAX_PATH))
  1015. return FALSE;
  1016. lstrcpynW( pszString, CSimpleStringConvert::WideString(CSimpleStringAnsi(szGuid)), nMaxLen );
  1017. bResult = TRUE;
  1018. #else
  1019. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1020. #endif
  1021. return bResult;
  1022. }
  1023. #define MSG_DEBUG_ENTRY(msg) { msg, ""#msg }
  1024. static const struct
  1025. {
  1026. UINT uMsg;
  1027. LPCSTR pszName;
  1028. }
  1029. s_MsgDebugStrings[] =
  1030. {
  1031. MSG_DEBUG_ENTRY(BM_CLICK),
  1032. MSG_DEBUG_ENTRY(BM_GETCHECK),
  1033. MSG_DEBUG_ENTRY(BM_GETIMAGE),
  1034. MSG_DEBUG_ENTRY(BM_GETSTATE),
  1035. MSG_DEBUG_ENTRY(BM_SETCHECK),
  1036. MSG_DEBUG_ENTRY(BM_SETIMAGE),
  1037. MSG_DEBUG_ENTRY(BM_SETSTATE),
  1038. MSG_DEBUG_ENTRY(BM_SETSTYLE),
  1039. MSG_DEBUG_ENTRY(CB_ADDSTRING),
  1040. MSG_DEBUG_ENTRY(CB_DELETESTRING),
  1041. MSG_DEBUG_ENTRY(CB_DIR),
  1042. MSG_DEBUG_ENTRY(CB_FINDSTRING),
  1043. MSG_DEBUG_ENTRY(CB_FINDSTRINGEXACT),
  1044. MSG_DEBUG_ENTRY(CB_GETCOMBOBOXINFO),
  1045. MSG_DEBUG_ENTRY(CB_GETCOUNT),
  1046. MSG_DEBUG_ENTRY(CB_GETCURSEL),
  1047. MSG_DEBUG_ENTRY(CB_GETDROPPEDCONTROLRECT),
  1048. MSG_DEBUG_ENTRY(CB_GETDROPPEDSTATE),
  1049. MSG_DEBUG_ENTRY(CB_GETEDITSEL),
  1050. MSG_DEBUG_ENTRY(CB_GETEXTENDEDUI),
  1051. MSG_DEBUG_ENTRY(CB_GETITEMDATA),
  1052. MSG_DEBUG_ENTRY(CB_GETITEMHEIGHT),
  1053. MSG_DEBUG_ENTRY(CB_GETLBTEXT),
  1054. MSG_DEBUG_ENTRY(CB_GETLBTEXTLEN),
  1055. MSG_DEBUG_ENTRY(CB_GETLOCALE),
  1056. MSG_DEBUG_ENTRY(CB_INITSTORAGE),
  1057. MSG_DEBUG_ENTRY(CB_INSERTSTRING),
  1058. MSG_DEBUG_ENTRY(CB_LIMITTEXT),
  1059. MSG_DEBUG_ENTRY(CB_MSGMAX),
  1060. MSG_DEBUG_ENTRY(CB_MSGMAX),
  1061. MSG_DEBUG_ENTRY(CB_MSGMAX),
  1062. MSG_DEBUG_ENTRY(CB_MSGMAX),
  1063. MSG_DEBUG_ENTRY(CB_RESETCONTENT),
  1064. MSG_DEBUG_ENTRY(CB_SELECTSTRING),
  1065. MSG_DEBUG_ENTRY(CB_SETCURSEL),
  1066. MSG_DEBUG_ENTRY(CB_SETDROPPEDWIDTH),
  1067. MSG_DEBUG_ENTRY(CB_SETEDITSEL),
  1068. MSG_DEBUG_ENTRY(CB_SETEXTENDEDUI),
  1069. MSG_DEBUG_ENTRY(CB_SETITEMDATA),
  1070. MSG_DEBUG_ENTRY(CB_SETITEMHEIGHT),
  1071. MSG_DEBUG_ENTRY(CB_SETLOCALE),
  1072. MSG_DEBUG_ENTRY(CB_SHOWDROPDOWN),
  1073. MSG_DEBUG_ENTRY(EM_CANUNDO),
  1074. MSG_DEBUG_ENTRY(EM_CHARFROMPOS),
  1075. MSG_DEBUG_ENTRY(EM_EMPTYUNDOBUFFER),
  1076. MSG_DEBUG_ENTRY(EM_FMTLINES),
  1077. MSG_DEBUG_ENTRY(EM_GETFIRSTVISIBLELINE),
  1078. MSG_DEBUG_ENTRY(EM_GETHANDLE),
  1079. MSG_DEBUG_ENTRY(EM_GETIMESTATUS),
  1080. MSG_DEBUG_ENTRY(EM_GETLIMITTEXT),
  1081. MSG_DEBUG_ENTRY(EM_GETLINE),
  1082. MSG_DEBUG_ENTRY(EM_GETLINECOUNT),
  1083. MSG_DEBUG_ENTRY(EM_GETMARGINS),
  1084. MSG_DEBUG_ENTRY(EM_GETMODIFY),
  1085. MSG_DEBUG_ENTRY(EM_GETPASSWORDCHAR),
  1086. MSG_DEBUG_ENTRY(EM_GETRECT),
  1087. MSG_DEBUG_ENTRY(EM_GETSEL),
  1088. MSG_DEBUG_ENTRY(EM_GETTHUMB),
  1089. MSG_DEBUG_ENTRY(EM_GETWORDBREAKPROC),
  1090. MSG_DEBUG_ENTRY(EM_LIMITTEXT),
  1091. MSG_DEBUG_ENTRY(EM_LINEFROMCHAR),
  1092. MSG_DEBUG_ENTRY(EM_LINEINDEX),
  1093. MSG_DEBUG_ENTRY(EM_LINELENGTH),
  1094. MSG_DEBUG_ENTRY(EM_LINESCROLL),
  1095. MSG_DEBUG_ENTRY(EM_POSFROMCHAR),
  1096. MSG_DEBUG_ENTRY(EM_REPLACESEL),
  1097. MSG_DEBUG_ENTRY(EM_SCROLL),
  1098. MSG_DEBUG_ENTRY(EM_SCROLLCARET),
  1099. MSG_DEBUG_ENTRY(EM_SETHANDLE),
  1100. MSG_DEBUG_ENTRY(EM_SETIMESTATUS),
  1101. MSG_DEBUG_ENTRY(EM_SETMARGINS),
  1102. MSG_DEBUG_ENTRY(EM_SETMODIFY),
  1103. MSG_DEBUG_ENTRY(EM_SETPASSWORDCHAR),
  1104. MSG_DEBUG_ENTRY(EM_SETREADONLY),
  1105. MSG_DEBUG_ENTRY(EM_SETRECT),
  1106. MSG_DEBUG_ENTRY(EM_SETRECTNP),
  1107. MSG_DEBUG_ENTRY(EM_SETSEL),
  1108. MSG_DEBUG_ENTRY(EM_SETTABSTOPS),
  1109. MSG_DEBUG_ENTRY(EM_SETWORDBREAKPROC),
  1110. MSG_DEBUG_ENTRY(EM_UNDO),
  1111. MSG_DEBUG_ENTRY(LB_ADDFILE),
  1112. MSG_DEBUG_ENTRY(LB_ADDSTRING),
  1113. MSG_DEBUG_ENTRY(LB_DELETESTRING),
  1114. MSG_DEBUG_ENTRY(LB_DIR),
  1115. MSG_DEBUG_ENTRY(LB_FINDSTRING),
  1116. MSG_DEBUG_ENTRY(LB_FINDSTRINGEXACT),
  1117. MSG_DEBUG_ENTRY(LB_GETANCHORINDEX),
  1118. MSG_DEBUG_ENTRY(LB_GETCARETINDEX),
  1119. MSG_DEBUG_ENTRY(LB_GETCOUNT),
  1120. MSG_DEBUG_ENTRY(LB_GETCURSEL),
  1121. MSG_DEBUG_ENTRY(LB_GETHORIZONTALEXTENT),
  1122. MSG_DEBUG_ENTRY(LB_GETITEMDATA),
  1123. MSG_DEBUG_ENTRY(LB_GETITEMHEIGHT),
  1124. MSG_DEBUG_ENTRY(LB_GETITEMRECT),
  1125. MSG_DEBUG_ENTRY(LB_GETLISTBOXINFO),
  1126. MSG_DEBUG_ENTRY(LB_GETLOCALE),
  1127. MSG_DEBUG_ENTRY(LB_GETSEL),
  1128. MSG_DEBUG_ENTRY(LB_GETSELCOUNT),
  1129. MSG_DEBUG_ENTRY(LB_GETSELITEMS),
  1130. MSG_DEBUG_ENTRY(LB_GETTEXT),
  1131. MSG_DEBUG_ENTRY(LB_GETTEXTLEN),
  1132. MSG_DEBUG_ENTRY(LB_GETTOPINDEX),
  1133. MSG_DEBUG_ENTRY(LB_INITSTORAGE),
  1134. MSG_DEBUG_ENTRY(LB_INSERTSTRING),
  1135. MSG_DEBUG_ENTRY(LB_ITEMFROMPOINT),
  1136. MSG_DEBUG_ENTRY(LB_MSGMAX),
  1137. MSG_DEBUG_ENTRY(LB_MSGMAX),
  1138. MSG_DEBUG_ENTRY(LB_MSGMAX),
  1139. MSG_DEBUG_ENTRY(LB_MSGMAX),
  1140. MSG_DEBUG_ENTRY(LB_RESETCONTENT),
  1141. MSG_DEBUG_ENTRY(LB_SELECTSTRING),
  1142. MSG_DEBUG_ENTRY(LB_SELITEMRANGE),
  1143. MSG_DEBUG_ENTRY(LB_SELITEMRANGEEX),
  1144. MSG_DEBUG_ENTRY(LB_SETANCHORINDEX),
  1145. MSG_DEBUG_ENTRY(LB_SETCARETINDEX),
  1146. MSG_DEBUG_ENTRY(LB_SETCOLUMNWIDTH),
  1147. MSG_DEBUG_ENTRY(LB_SETCOUNT),
  1148. MSG_DEBUG_ENTRY(LB_SETCURSEL),
  1149. MSG_DEBUG_ENTRY(LB_SETHORIZONTALEXTENT),
  1150. MSG_DEBUG_ENTRY(LB_SETITEMDATA),
  1151. MSG_DEBUG_ENTRY(LB_SETITEMHEIGHT),
  1152. MSG_DEBUG_ENTRY(LB_SETLOCALE),
  1153. MSG_DEBUG_ENTRY(LB_SETSEL),
  1154. MSG_DEBUG_ENTRY(LB_SETTABSTOPS),
  1155. MSG_DEBUG_ENTRY(LB_SETTOPINDEX),
  1156. MSG_DEBUG_ENTRY(PBT_APMBATTERYLOW),
  1157. MSG_DEBUG_ENTRY(PBT_APMOEMEVENT),
  1158. MSG_DEBUG_ENTRY(PBT_APMPOWERSTATUSCHANGE),
  1159. MSG_DEBUG_ENTRY(PBT_APMQUERYSTANDBY),
  1160. MSG_DEBUG_ENTRY(PBT_APMQUERYSTANDBYFAILED),
  1161. MSG_DEBUG_ENTRY(PBT_APMQUERYSUSPEND),
  1162. MSG_DEBUG_ENTRY(PBT_APMQUERYSUSPENDFAILED),
  1163. MSG_DEBUG_ENTRY(PBT_APMRESUMEAUTOMATIC),
  1164. MSG_DEBUG_ENTRY(PBT_APMRESUMECRITICAL),
  1165. MSG_DEBUG_ENTRY(PBT_APMRESUMESTANDBY),
  1166. MSG_DEBUG_ENTRY(PBT_APMRESUMESUSPEND),
  1167. MSG_DEBUG_ENTRY(PBT_APMSTANDBY),
  1168. MSG_DEBUG_ENTRY(PBT_APMSUSPEND),
  1169. MSG_DEBUG_ENTRY(SBM_GETSCROLLBARINFO),
  1170. MSG_DEBUG_ENTRY(SBM_GETSCROLLINFO),
  1171. MSG_DEBUG_ENTRY(SBM_SETSCROLLINFO),
  1172. MSG_DEBUG_ENTRY(STM_GETICON),
  1173. MSG_DEBUG_ENTRY(STM_GETIMAGE),
  1174. MSG_DEBUG_ENTRY(STM_MSGMAX),
  1175. MSG_DEBUG_ENTRY(STM_SETICON),
  1176. MSG_DEBUG_ENTRY(STM_SETIMAGE),
  1177. MSG_DEBUG_ENTRY(WM_ACTIVATE),
  1178. MSG_DEBUG_ENTRY(WM_ACTIVATEAPP),
  1179. MSG_DEBUG_ENTRY(WM_APP),
  1180. MSG_DEBUG_ENTRY(WM_APPCOMMAND),
  1181. MSG_DEBUG_ENTRY(WM_ASKCBFORMATNAME),
  1182. MSG_DEBUG_ENTRY(WM_CANCELJOURNAL),
  1183. MSG_DEBUG_ENTRY(WM_CANCELMODE),
  1184. MSG_DEBUG_ENTRY(WM_CAPTURECHANGED),
  1185. MSG_DEBUG_ENTRY(WM_CHANGECBCHAIN),
  1186. MSG_DEBUG_ENTRY(WM_CHANGEUISTATE),
  1187. MSG_DEBUG_ENTRY(WM_CHAR),
  1188. MSG_DEBUG_ENTRY(WM_CHARTOITEM),
  1189. MSG_DEBUG_ENTRY(WM_CHILDACTIVATE),
  1190. MSG_DEBUG_ENTRY(WM_CLEAR),
  1191. MSG_DEBUG_ENTRY(WM_CLOSE),
  1192. MSG_DEBUG_ENTRY(WM_COMMAND),
  1193. MSG_DEBUG_ENTRY(WM_COMPACTING),
  1194. MSG_DEBUG_ENTRY(WM_COMPAREITEM),
  1195. MSG_DEBUG_ENTRY(WM_CONTEXTMENU),
  1196. MSG_DEBUG_ENTRY(WM_COPY),
  1197. MSG_DEBUG_ENTRY(WM_COPYDATA),
  1198. MSG_DEBUG_ENTRY(WM_CREATE),
  1199. MSG_DEBUG_ENTRY(WM_CTLCOLORBTN),
  1200. MSG_DEBUG_ENTRY(WM_CTLCOLORDLG),
  1201. MSG_DEBUG_ENTRY(WM_CTLCOLOREDIT),
  1202. MSG_DEBUG_ENTRY(WM_CTLCOLORLISTBOX),
  1203. MSG_DEBUG_ENTRY(WM_CTLCOLORMSGBOX),
  1204. MSG_DEBUG_ENTRY(WM_CTLCOLORSCROLLBAR),
  1205. MSG_DEBUG_ENTRY(WM_CTLCOLORSTATIC),
  1206. MSG_DEBUG_ENTRY(WM_CUT),
  1207. MSG_DEBUG_ENTRY(WM_DEADCHAR),
  1208. MSG_DEBUG_ENTRY(WM_DELETEITEM),
  1209. MSG_DEBUG_ENTRY(WM_DESTROY),
  1210. MSG_DEBUG_ENTRY(WM_DESTROYCLIPBOARD),
  1211. MSG_DEBUG_ENTRY(WM_DEVICECHANGE),
  1212. MSG_DEBUG_ENTRY(WM_DEVMODECHANGE),
  1213. MSG_DEBUG_ENTRY(WM_DISPLAYCHANGE),
  1214. MSG_DEBUG_ENTRY(WM_DRAWCLIPBOARD),
  1215. MSG_DEBUG_ENTRY(WM_DRAWITEM),
  1216. MSG_DEBUG_ENTRY(WM_DROPFILES),
  1217. MSG_DEBUG_ENTRY(WM_ENABLE),
  1218. MSG_DEBUG_ENTRY(WM_ENDSESSION),
  1219. MSG_DEBUG_ENTRY(WM_ENTERIDLE),
  1220. MSG_DEBUG_ENTRY(WM_ENTERMENULOOP),
  1221. MSG_DEBUG_ENTRY(WM_ENTERSIZEMOVE),
  1222. MSG_DEBUG_ENTRY(WM_ERASEBKGND),
  1223. MSG_DEBUG_ENTRY(WM_EXITMENULOOP),
  1224. MSG_DEBUG_ENTRY(WM_EXITSIZEMOVE),
  1225. MSG_DEBUG_ENTRY(WM_FONTCHANGE),
  1226. MSG_DEBUG_ENTRY(WM_GETDLGCODE),
  1227. MSG_DEBUG_ENTRY(WM_GETFONT),
  1228. MSG_DEBUG_ENTRY(WM_GETHOTKEY),
  1229. MSG_DEBUG_ENTRY(WM_GETICON),
  1230. MSG_DEBUG_ENTRY(WM_GETMINMAXINFO),
  1231. MSG_DEBUG_ENTRY(WM_GETOBJECT),
  1232. MSG_DEBUG_ENTRY(WM_GETTEXT),
  1233. MSG_DEBUG_ENTRY(WM_GETTEXTLENGTH),
  1234. MSG_DEBUG_ENTRY(WM_HELP),
  1235. MSG_DEBUG_ENTRY(WM_HOTKEY),
  1236. MSG_DEBUG_ENTRY(WM_HSCROLL),
  1237. MSG_DEBUG_ENTRY(WM_HSCROLLCLIPBOARD),
  1238. MSG_DEBUG_ENTRY(WM_ICONERASEBKGND),
  1239. MSG_DEBUG_ENTRY(WM_IME_CHAR),
  1240. MSG_DEBUG_ENTRY(WM_IME_COMPOSITION),
  1241. MSG_DEBUG_ENTRY(WM_IME_COMPOSITIONFULL),
  1242. MSG_DEBUG_ENTRY(WM_IME_CONTROL),
  1243. MSG_DEBUG_ENTRY(WM_IME_ENDCOMPOSITION),
  1244. MSG_DEBUG_ENTRY(WM_IME_KEYDOWN),
  1245. MSG_DEBUG_ENTRY(WM_IME_KEYLAST),
  1246. MSG_DEBUG_ENTRY(WM_IME_KEYUP),
  1247. MSG_DEBUG_ENTRY(WM_IME_NOTIFY),
  1248. MSG_DEBUG_ENTRY(WM_IME_REQUEST),
  1249. MSG_DEBUG_ENTRY(WM_IME_SELECT),
  1250. MSG_DEBUG_ENTRY(WM_IME_SETCONTEXT),
  1251. MSG_DEBUG_ENTRY(WM_IME_STARTCOMPOSITION),
  1252. MSG_DEBUG_ENTRY(WM_INITDIALOG),
  1253. MSG_DEBUG_ENTRY(WM_INITMENU),
  1254. MSG_DEBUG_ENTRY(WM_INITMENUPOPUP),
  1255. MSG_DEBUG_ENTRY(WM_INPUT),
  1256. MSG_DEBUG_ENTRY(WM_INPUTLANGCHANGE),
  1257. MSG_DEBUG_ENTRY(WM_INPUTLANGCHANGEREQUEST),
  1258. MSG_DEBUG_ENTRY(WM_KEYDOWN),
  1259. MSG_DEBUG_ENTRY(WM_KEYUP),
  1260. MSG_DEBUG_ENTRY(WM_KILLFOCUS),
  1261. MSG_DEBUG_ENTRY(WM_LBUTTONDBLCLK),
  1262. MSG_DEBUG_ENTRY(WM_LBUTTONDOWN),
  1263. MSG_DEBUG_ENTRY(WM_LBUTTONUP),
  1264. MSG_DEBUG_ENTRY(WM_MBUTTONDBLCLK),
  1265. MSG_DEBUG_ENTRY(WM_MBUTTONDOWN),
  1266. MSG_DEBUG_ENTRY(WM_MBUTTONUP),
  1267. MSG_DEBUG_ENTRY(WM_MDIACTIVATE),
  1268. MSG_DEBUG_ENTRY(WM_MDICASCADE),
  1269. MSG_DEBUG_ENTRY(WM_MDICREATE),
  1270. MSG_DEBUG_ENTRY(WM_MDIDESTROY),
  1271. MSG_DEBUG_ENTRY(WM_MDIGETACTIVE),
  1272. MSG_DEBUG_ENTRY(WM_MDIICONARRANGE),
  1273. MSG_DEBUG_ENTRY(WM_MDIMAXIMIZE),
  1274. MSG_DEBUG_ENTRY(WM_MDINEXT),
  1275. MSG_DEBUG_ENTRY(WM_MDIREFRESHMENU),
  1276. MSG_DEBUG_ENTRY(WM_MDIRESTORE),
  1277. MSG_DEBUG_ENTRY(WM_MDISETMENU),
  1278. MSG_DEBUG_ENTRY(WM_MDITILE),
  1279. MSG_DEBUG_ENTRY(WM_MEASUREITEM),
  1280. MSG_DEBUG_ENTRY(WM_MENUCHAR),
  1281. MSG_DEBUG_ENTRY(WM_MENUCOMMAND),
  1282. MSG_DEBUG_ENTRY(WM_MENUDRAG),
  1283. MSG_DEBUG_ENTRY(WM_MENUGETOBJECT),
  1284. MSG_DEBUG_ENTRY(WM_MENURBUTTONUP),
  1285. MSG_DEBUG_ENTRY(WM_MENUSELECT),
  1286. MSG_DEBUG_ENTRY(WM_MOUSEACTIVATE),
  1287. MSG_DEBUG_ENTRY(WM_MOUSEHOVER),
  1288. MSG_DEBUG_ENTRY(WM_MOUSELEAVE),
  1289. MSG_DEBUG_ENTRY(WM_MOUSEMOVE),
  1290. MSG_DEBUG_ENTRY(WM_MOUSEWHEEL),
  1291. MSG_DEBUG_ENTRY(WM_MOVE),
  1292. MSG_DEBUG_ENTRY(WM_MOVING),
  1293. MSG_DEBUG_ENTRY(WM_NCACTIVATE),
  1294. MSG_DEBUG_ENTRY(WM_NCCALCSIZE),
  1295. MSG_DEBUG_ENTRY(WM_NCCREATE),
  1296. MSG_DEBUG_ENTRY(WM_NCDESTROY),
  1297. MSG_DEBUG_ENTRY(WM_NCHITTEST),
  1298. MSG_DEBUG_ENTRY(WM_NCLBUTTONDBLCLK),
  1299. MSG_DEBUG_ENTRY(WM_NCLBUTTONDOWN),
  1300. MSG_DEBUG_ENTRY(WM_NCLBUTTONUP),
  1301. MSG_DEBUG_ENTRY(WM_NCMBUTTONDBLCLK),
  1302. MSG_DEBUG_ENTRY(WM_NCMBUTTONDOWN),
  1303. MSG_DEBUG_ENTRY(WM_NCMBUTTONUP),
  1304. MSG_DEBUG_ENTRY(WM_NCMOUSEHOVER),
  1305. MSG_DEBUG_ENTRY(WM_NCMOUSELEAVE),
  1306. MSG_DEBUG_ENTRY(WM_NCMOUSEMOVE),
  1307. MSG_DEBUG_ENTRY(WM_NCPAINT),
  1308. MSG_DEBUG_ENTRY(WM_NCRBUTTONDBLCLK),
  1309. MSG_DEBUG_ENTRY(WM_NCRBUTTONDOWN),
  1310. MSG_DEBUG_ENTRY(WM_NCRBUTTONUP),
  1311. MSG_DEBUG_ENTRY(WM_NCXBUTTONDBLCLK),
  1312. MSG_DEBUG_ENTRY(WM_NCXBUTTONDOWN),
  1313. MSG_DEBUG_ENTRY(WM_NCXBUTTONUP),
  1314. MSG_DEBUG_ENTRY(WM_NEXTDLGCTL),
  1315. MSG_DEBUG_ENTRY(WM_NEXTMENU),
  1316. MSG_DEBUG_ENTRY(WM_NOTIFY),
  1317. MSG_DEBUG_ENTRY(WM_NOTIFYFORMAT),
  1318. MSG_DEBUG_ENTRY(WM_NULL),
  1319. MSG_DEBUG_ENTRY(WM_PAINT),
  1320. MSG_DEBUG_ENTRY(WM_PAINTCLIPBOARD),
  1321. MSG_DEBUG_ENTRY(WM_PAINTICON),
  1322. MSG_DEBUG_ENTRY(WM_PALETTECHANGED),
  1323. MSG_DEBUG_ENTRY(WM_PALETTEISCHANGING),
  1324. MSG_DEBUG_ENTRY(WM_PARENTNOTIFY),
  1325. MSG_DEBUG_ENTRY(WM_PASTE),
  1326. MSG_DEBUG_ENTRY(WM_POWER),
  1327. MSG_DEBUG_ENTRY(WM_POWERBROADCAST),
  1328. MSG_DEBUG_ENTRY(WM_PRINT),
  1329. MSG_DEBUG_ENTRY(WM_PRINTCLIENT),
  1330. MSG_DEBUG_ENTRY(WM_QUERYDRAGICON),
  1331. MSG_DEBUG_ENTRY(WM_QUERYENDSESSION),
  1332. MSG_DEBUG_ENTRY(WM_QUERYNEWPALETTE),
  1333. MSG_DEBUG_ENTRY(WM_QUERYOPEN),
  1334. MSG_DEBUG_ENTRY(WM_QUERYUISTATE),
  1335. MSG_DEBUG_ENTRY(WM_QUEUESYNC),
  1336. MSG_DEBUG_ENTRY(WM_QUIT),
  1337. MSG_DEBUG_ENTRY(WM_RBUTTONDBLCLK),
  1338. MSG_DEBUG_ENTRY(WM_RBUTTONDOWN),
  1339. MSG_DEBUG_ENTRY(WM_RBUTTONUP),
  1340. MSG_DEBUG_ENTRY(WM_RENDERALLFORMATS),
  1341. MSG_DEBUG_ENTRY(WM_RENDERFORMAT),
  1342. MSG_DEBUG_ENTRY(WM_SETCURSOR),
  1343. MSG_DEBUG_ENTRY(WM_SETFOCUS),
  1344. MSG_DEBUG_ENTRY(WM_SETFONT),
  1345. MSG_DEBUG_ENTRY(WM_SETHOTKEY),
  1346. MSG_DEBUG_ENTRY(WM_SETICON),
  1347. MSG_DEBUG_ENTRY(WM_SETREDRAW),
  1348. MSG_DEBUG_ENTRY(WM_SETTEXT),
  1349. MSG_DEBUG_ENTRY(WM_SHOWWINDOW),
  1350. MSG_DEBUG_ENTRY(WM_SIZE),
  1351. MSG_DEBUG_ENTRY(WM_SIZECLIPBOARD),
  1352. MSG_DEBUG_ENTRY(WM_SIZING),
  1353. MSG_DEBUG_ENTRY(WM_SPOOLERSTATUS),
  1354. MSG_DEBUG_ENTRY(WM_STYLECHANGED),
  1355. MSG_DEBUG_ENTRY(WM_STYLECHANGING),
  1356. MSG_DEBUG_ENTRY(WM_SYNCPAINT),
  1357. MSG_DEBUG_ENTRY(WM_SYSCHAR),
  1358. MSG_DEBUG_ENTRY(WM_SYSCOLORCHANGE),
  1359. MSG_DEBUG_ENTRY(WM_SYSCOMMAND),
  1360. MSG_DEBUG_ENTRY(WM_SYSDEADCHAR),
  1361. MSG_DEBUG_ENTRY(WM_SYSKEYDOWN),
  1362. MSG_DEBUG_ENTRY(WM_SYSKEYUP),
  1363. MSG_DEBUG_ENTRY(WM_TCARD),
  1364. MSG_DEBUG_ENTRY(WM_THEMECHANGED),
  1365. MSG_DEBUG_ENTRY(WM_TIMECHANGE),
  1366. MSG_DEBUG_ENTRY(WM_TIMER),
  1367. MSG_DEBUG_ENTRY(WM_UNDO),
  1368. MSG_DEBUG_ENTRY(WM_UNICHAR),
  1369. MSG_DEBUG_ENTRY(WM_UNINITMENUPOPUP),
  1370. MSG_DEBUG_ENTRY(WM_UPDATEUISTATE),
  1371. MSG_DEBUG_ENTRY(WM_USER),
  1372. MSG_DEBUG_ENTRY(WM_USERCHANGED),
  1373. MSG_DEBUG_ENTRY(WM_VKEYTOITEM),
  1374. MSG_DEBUG_ENTRY(WM_VSCROLL),
  1375. MSG_DEBUG_ENTRY(WM_VSCROLLCLIPBOARD),
  1376. MSG_DEBUG_ENTRY(WM_WINDOWPOSCHANGED),
  1377. MSG_DEBUG_ENTRY(WM_WINDOWPOSCHANGING),
  1378. MSG_DEBUG_ENTRY(WM_WININICHANGE),
  1379. MSG_DEBUG_ENTRY(WM_WTSSESSION_CHANGE),
  1380. MSG_DEBUG_ENTRY(WM_XBUTTONDBLCLK),
  1381. MSG_DEBUG_ENTRY(WM_XBUTTONDOWN),
  1382. MSG_DEBUG_ENTRY(WM_XBUTTONUP)
  1383. };
  1384. #define MSG_DEBUG_MAP_SIZE (sizeof(s_MsgDebugStrings)/sizeof(s_MsgDebugStrings[0]))
  1385. BOOL WINAPI GetStringFromMsgA( UINT uMsg, LPSTR pszString, int nMaxLen )
  1386. {
  1387. if (!pszString || !nMaxLen)
  1388. {
  1389. return FALSE;
  1390. }
  1391. for (int i=0;i<MSG_DEBUG_MAP_SIZE;i++)
  1392. {
  1393. if (uMsg == s_MsgDebugStrings[i].uMsg)
  1394. {
  1395. lstrcpynA( pszString, s_MsgDebugStrings[i].pszName, nMaxLen );
  1396. return TRUE;
  1397. }
  1398. }
  1399. lstrcpynA( pszString, CSimpleStringAnsi().Format("Unknown Message: 0x%08X", uMsg ), nMaxLen );
  1400. return TRUE;
  1401. }
  1402. BOOL WINAPI GetStringFromMsgW( UINT uMsg, LPWSTR pszString, int nMaxLen )
  1403. {
  1404. BOOL bResult = FALSE;
  1405. #ifdef UNICODE
  1406. if (!pszString || !nMaxLen)
  1407. {
  1408. return FALSE;
  1409. }
  1410. CHAR szMessage[MAX_PATH];
  1411. if (!GetStringFromMsgA(uMsg,szMessage,MAX_PATH))
  1412. {
  1413. return FALSE;
  1414. }
  1415. lstrcpynW( pszString, CSimpleStringConvert::WideString(CSimpleStringAnsi(szMessage)), nMaxLen );
  1416. bResult = TRUE;
  1417. #else
  1418. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1419. #endif
  1420. return bResult;
  1421. }
  1422. VOID WINAPI DoRecordAllocation( LPVOID pv, size_t Size )
  1423. {
  1424. if (pv)
  1425. {
  1426. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  1427. if (pProcessData && pProcessData->IsValid())
  1428. {
  1429. pProcessData->DoRecordAllocation( pv, Size );
  1430. }
  1431. }
  1432. }
  1433. VOID WINAPI DoRecordFree( LPVOID pv )
  1434. {
  1435. if (pv)
  1436. {
  1437. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  1438. if (pProcessData && pProcessData->IsValid())
  1439. {
  1440. pProcessData->DoRecordFree( pv );
  1441. }
  1442. }
  1443. }
  1444. VOID WINAPI DoReportLeaks( LPTSTR pszModuleName )
  1445. {
  1446. if (pszModuleName)
  1447. {
  1448. CProcessGlobalDebugData *pProcessData = CProcessGlobalDebugData::ProcessData();
  1449. if (pProcessData && pProcessData->IsValid())
  1450. {
  1451. pProcessData->GenerateLeakReport( pszModuleName );
  1452. }
  1453. }
  1454. }