Source code of Windows XP (NT5)
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.

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