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.

810 lines
20 KiB

  1. /****************************************************************************
  2. Copyright (c) Microsoft Corporation 1997
  3. All rights reserved
  4. File: DEBUG.CPP
  5. Debugging utilities
  6. ***************************************************************************/
  7. #include "pch.h"
  8. #include <shlwapi.h>
  9. DEFINE_MODULE("IMADMUI")
  10. #ifdef DEBUG
  11. // Constants
  12. #define DEBUG_OUTPUT_BUFFER_SIZE 512
  13. // Globals
  14. DWORD g_TraceMemoryIndex = 0;
  15. DWORD g_dwCounter = 0;
  16. DWORD g_dwTraceFlags = 0;
  17. CRITICAL_SECTION g_DebugCS;
  18. BOOL g_fDebugInitialized = FALSE;
  19. WCHAR g_DebugBuffer[DEBUG_OUTPUT_BUFFER_SIZE];
  20. WCHAR g_DebugFormatBuffer[DEBUG_OUTPUT_BUFFER_SIZE];
  21. // Statics
  22. static const TCHAR g_szNULL[] = TEXT("");
  23. static const TCHAR g_szTrue[] = TEXT("True");
  24. static const TCHAR g_szFalse[] = TEXT("False");
  25. static const TCHAR g_szFormat[] = TEXT("%-50s %-10.10s ");
  26. static const TCHAR g_szUnknown[] = TEXT("<unknown>");
  27. //
  28. // DebugInitializeTraceFlags( )
  29. //
  30. void
  31. DebugInitializeTraceFlags( )
  32. {
  33. TCHAR szPath[ MAX_PATH ];
  34. LPTSTR pszExtension;
  35. GetModuleFileName( g_hInstance, szPath, ARRAYSIZE( szPath ) );
  36. pszExtension = &szPath[ lstrlen( szPath ) - 3 ];
  37. StrCpy( pszExtension, TEXT("ini") );
  38. DebugMsg( "Reading %s for debug settings...\n", szPath );
  39. g_dwTraceFlags = GetPrivateProfileInt( __MODULE__, TEXT("TraceFlags"), 0, szPath );
  40. DebugMsg( "g_dwTraceFlags = 0x%08x\n", g_dwTraceFlags );
  41. }
  42. //
  43. // Debugging strrchr( )
  44. //
  45. LPCTSTR
  46. dbgstrrchr( LPCTSTR lpsz, char ch )
  47. {
  48. LPCTSTR psz = lpsz;
  49. while ( *psz )
  50. ++psz;
  51. while ( psz >= lpsz && *psz != ch )
  52. --psz;
  53. return psz;
  54. }
  55. //
  56. // Adds 'g_dwCounter' spaces to debug spew
  57. //
  58. void
  59. dbgspace( void )
  60. {
  61. for ( DWORD dw = 1; dw < g_dwCounter; dw++ )
  62. OutputDebugStringA( "| " );
  63. }
  64. //
  65. // Makes sure multiple threads don't trample debugging output.
  66. //
  67. void
  68. dbgEnterCS( void )
  69. {
  70. if ( !g_fDebugInitialized ) {
  71. //
  72. // The critical section is deleted DeleteCriticalSection( )
  73. // on process detach.
  74. //
  75. InitializeCriticalSection( &g_DebugCS );
  76. g_fDebugInitialized = TRUE;
  77. }
  78. EnterCriticalSection( &g_DebugCS );
  79. }
  80. void
  81. dbgExitCS( void )
  82. {
  83. LeaveCriticalSection( &g_DebugCS );
  84. }
  85. //
  86. // Takes the filename and line number and put them into a string buffer.
  87. //
  88. // NOTE: the buffer is assumed to be of size DEBUG_OUTPUT_BUFFER_SIZE.
  89. //
  90. LPTSTR
  91. dbgmakefilelinestring(
  92. LPTSTR pszBuf,
  93. LPCTSTR pszFile,
  94. const int uLine )
  95. {
  96. LPVOID args[2];
  97. args[0] = (LPVOID) pszFile;
  98. args[1] = IntToPtr(uLine);
  99. FormatMessage(
  100. FORMAT_MESSAGE_FROM_STRING |
  101. FORMAT_MESSAGE_ARGUMENT_ARRAY,
  102. TEXT("%1(%2!u!):"),
  103. 0, // error code
  104. 0, // default language
  105. (LPTSTR) pszBuf, // output buffer
  106. DEBUG_OUTPUT_BUFFER_SIZE, // size of buffer
  107. (va_list*) args ); // arguments
  108. return pszBuf;
  109. }
  110. //
  111. // TraceMsg() - ascii
  112. //
  113. void
  114. TraceMsg(
  115. DWORD dwCheckFlags,
  116. LPCSTR pszFormat,
  117. ... )
  118. {
  119. va_list valist;
  120. if (( dwCheckFlags == TF_ALWAYS
  121. || !!( g_dwTraceFlags & dwCheckFlags ) )) {
  122. dbgEnterCS( );
  123. mbstowcs( g_DebugFormatBuffer, pszFormat, lstrlenA( pszFormat ) + 1 );
  124. va_start( valist, pszFormat );
  125. wvsprintf( g_DebugBuffer, g_DebugFormatBuffer, valist );
  126. va_end( valist );
  127. OutputDebugString( g_DebugBuffer );
  128. dbgExitCS( );
  129. }
  130. }
  131. //
  132. // TraceMsg() - unicode
  133. //
  134. void
  135. TraceMsg(
  136. DWORD dwCheckFlags,
  137. LPCWSTR pszFormat,
  138. ... )
  139. {
  140. va_list valist;
  141. if (( dwCheckFlags == TF_ALWAYS
  142. || !!( g_dwTraceFlags & dwCheckFlags ) )) {
  143. dbgEnterCS( );
  144. va_start( valist, pszFormat );
  145. wvsprintf( g_DebugBuffer, pszFormat, valist);
  146. va_end( valist );
  147. OutputDebugString( g_DebugBuffer );
  148. dbgExitCS( );
  149. }
  150. }
  151. //
  152. // TraceMessage()
  153. //
  154. void
  155. TraceMessage(
  156. LPCTSTR pszFile,
  157. const int uLine,
  158. LPCTSTR pszModule,
  159. DWORD dwCheckFlags,
  160. LPCTSTR pszFormat,
  161. ... )
  162. {
  163. va_list valist;
  164. if (( dwCheckFlags == TF_ALWAYS
  165. || !!( g_dwTraceFlags & dwCheckFlags ) )) {
  166. dbgEnterCS( );
  167. if ( !pszModule ) {
  168. pszModule = g_szUnknown;
  169. }
  170. if ( !pszFile ) {
  171. wsprintf( g_DebugBuffer, g_szFormat, g_szNULL, pszModule );
  172. } else {
  173. dbgmakefilelinestring( g_DebugFormatBuffer, pszFile, uLine );
  174. wsprintf( g_DebugBuffer, g_szFormat, g_DebugFormatBuffer, pszModule );
  175. }
  176. OutputDebugString( g_DebugBuffer );
  177. dbgspace( );
  178. va_start( valist, pszFormat );
  179. wvsprintf( g_DebugBuffer, pszFormat, valist );
  180. va_end( valist );
  181. OutputDebugString( g_DebugBuffer );
  182. dbgExitCS( );
  183. }
  184. }
  185. //
  186. // TraceMessageDo()
  187. //
  188. void
  189. TraceMessageDo(
  190. LPCTSTR pszFile,
  191. const int uLine,
  192. LPCTSTR pszModule,
  193. DWORD dwCheckFlags,
  194. LPCTSTR pszFormat,
  195. LPCTSTR pszFunc,
  196. ... )
  197. {
  198. va_list valist;
  199. if (( dwCheckFlags == TF_ALWAYS
  200. || !!( g_dwTraceFlags & dwCheckFlags ) )) {
  201. LPCTSTR psz = pszFunc;
  202. dbgEnterCS( );
  203. if ( !pszModule ) {
  204. pszModule = g_szUnknown;
  205. }
  206. if ( !pszFile ) {
  207. wsprintf( g_DebugBuffer, g_szFormat, g_szNULL, pszModule );
  208. } else {
  209. dbgmakefilelinestring( g_DebugFormatBuffer, pszFile, uLine );
  210. wsprintf( g_DebugBuffer, g_szFormat, g_DebugFormatBuffer, pszModule );
  211. }
  212. OutputDebugString( g_DebugBuffer );
  213. dbgspace( );
  214. while ( *psz && *psz != TEXT('='))
  215. psz++;
  216. lstrcpyn( g_DebugFormatBuffer, pszFunc, (size_t)(1 + psz - pszFunc) );
  217. wsprintf( g_DebugBuffer, TEXT("V %s= "), g_DebugFormatBuffer );
  218. OutputDebugString( g_DebugBuffer );
  219. va_start( valist, pszFunc );
  220. wvsprintf( g_DebugBuffer, pszFormat, valist );
  221. va_end( valist );
  222. OutputDebugString( g_DebugBuffer );
  223. OutputDebugString( L"\n" );
  224. dbgExitCS( );
  225. }
  226. }
  227. //
  228. // DebugMessage()
  229. //
  230. void
  231. DebugMessage(
  232. LPCTSTR pszFile,
  233. const int uLine,
  234. LPCTSTR pszModule,
  235. LPCTSTR pszFormat,
  236. ... )
  237. {
  238. va_list valist;
  239. dbgEnterCS( );
  240. if ( !pszModule ) {
  241. pszModule = g_szUnknown;
  242. }
  243. if ( !pszFile ) {
  244. wsprintf( g_DebugBuffer, g_szFormat, g_szNULL, pszModule );
  245. } else {
  246. dbgmakefilelinestring( g_DebugFormatBuffer, pszFile, uLine );
  247. wsprintf( g_DebugBuffer, g_szFormat, g_DebugFormatBuffer, pszModule );
  248. }
  249. OutputDebugString( g_DebugBuffer );
  250. dbgspace( );
  251. va_start( valist, pszFormat );
  252. wvsprintf( g_DebugBuffer, pszFormat, valist );
  253. va_end( valist );
  254. OutputDebugString( g_DebugBuffer );
  255. dbgExitCS( );
  256. }
  257. //
  258. // DebugMessageDo()
  259. //
  260. void
  261. DebugMessageDo(
  262. LPCTSTR pszFile,
  263. const int uLine,
  264. LPCTSTR pszModule,
  265. LPCTSTR pszFormat,
  266. LPCTSTR pszFunc,
  267. ... )
  268. {
  269. va_list valist;
  270. LPCTSTR psz = pszFunc;
  271. dbgEnterCS( );
  272. if ( !pszModule ) {
  273. pszModule = g_szUnknown;
  274. }
  275. if ( !pszFile ) {
  276. wsprintf( g_DebugBuffer, g_szFormat, g_szNULL, pszModule );
  277. } else {
  278. dbgmakefilelinestring( g_DebugFormatBuffer, pszFile, uLine );
  279. wsprintf( g_DebugBuffer, g_szFormat, g_DebugFormatBuffer, pszModule );
  280. }
  281. OutputDebugString( g_DebugBuffer );
  282. dbgspace( );
  283. while ( *psz && *psz != TEXT('='))
  284. psz++;
  285. lstrcpyn( g_DebugFormatBuffer, pszFunc, (size_t)(1 + psz - pszFunc) );
  286. wsprintf( g_DebugBuffer, TEXT("V %s= "), g_DebugFormatBuffer );
  287. OutputDebugString( g_DebugBuffer );
  288. va_start( valist, pszFunc );
  289. wvsprintf( g_DebugBuffer, pszFormat, valist );
  290. va_end( valist );
  291. OutputDebugString( g_DebugBuffer );
  292. OutputDebugString( TEXT("\n") );
  293. dbgExitCS( );
  294. }
  295. //
  296. // DebugMsg()
  297. //
  298. void
  299. DebugMsg(
  300. LPCSTR pszFormat,
  301. ... )
  302. {
  303. va_list valist;
  304. dbgEnterCS( );
  305. mbstowcs( g_DebugFormatBuffer, pszFormat, lstrlenA( pszFormat ) + 1 );
  306. va_start( valist, pszFormat );
  307. wvsprintf( g_DebugBuffer, g_DebugFormatBuffer, valist);
  308. va_end( valist );
  309. OutputDebugString( g_DebugBuffer );
  310. dbgExitCS( );
  311. }
  312. //
  313. // DebugMsg()
  314. //
  315. void
  316. DebugMsg(
  317. LPCWSTR pszFormat,
  318. ... )
  319. {
  320. va_list valist;
  321. dbgEnterCS( );
  322. va_start( valist, pszFormat );
  323. wvsprintf( g_DebugBuffer, pszFormat, valist);
  324. va_end( valist );
  325. OutputDebugString( g_DebugBuffer );
  326. dbgExitCS( );
  327. }
  328. //
  329. // Displays a dialog box with the failed assertion. User has the option of
  330. // breaking.
  331. //
  332. BOOL
  333. AssertMessage(
  334. LPCTSTR pszFile,
  335. const int uLine,
  336. LPCTSTR pszModule,
  337. LPCTSTR pszfn,
  338. BOOL fTrue )
  339. {
  340. if ( !fTrue ) {
  341. WCHAR szBuf[ DEBUG_OUTPUT_BUFFER_SIZE ];
  342. dbgEnterCS( );
  343. // Make sure everything is cool before we blow up somewhere else.
  344. if ( pszFile == NULL ) {
  345. pszFile = g_szNULL;
  346. }
  347. if ( pszModule == NULL ) {
  348. pszModule = g_szNULL;
  349. }
  350. if ( pszfn == NULL ) {
  351. pszfn = g_szNULL;
  352. }
  353. dbgmakefilelinestring( g_DebugFormatBuffer, pszFile, uLine );
  354. wsprintf( g_DebugBuffer, TEXT("%-50s %-10s ASSERT: %s\n"),
  355. g_DebugFormatBuffer, pszModule, pszfn );
  356. OutputDebugString( g_DebugBuffer );
  357. dbgExitCS( );
  358. wsprintf( szBuf, TEXT("Module:\t%s\t\nLine:\t%u\t\nFile:\t%s\t\n\nAssertion:\t%s\t\n\nDo you want to break here?"),
  359. pszModule, uLine, pszFile, pszfn );
  360. if ( IDNO == MessageBox( NULL, szBuf, TEXT("Assertion Failed!"),
  361. MB_YESNO|MB_ICONWARNING ) )
  362. fTrue = !FALSE; // don't break
  363. }
  364. return !fTrue;
  365. }
  366. //
  367. // Traces HRESULT errors. A dialog will appear is there is an error
  368. // in the hr.
  369. //
  370. HRESULT
  371. TraceHR(
  372. LPCTSTR pszFile,
  373. const int uLine,
  374. LPCTSTR pszModule,
  375. LPCTSTR pszfn,
  376. HRESULT hr )
  377. {
  378. if ( hr != S_OK) {
  379. TCHAR szBuf[ DEBUG_OUTPUT_BUFFER_SIZE ];
  380. TCHAR szFileLine[ DEBUG_OUTPUT_BUFFER_SIZE ];
  381. LPTSTR pszMsgBuf = NULL;
  382. BOOLEAN bDelete=TRUE;
  383. switch ( hr ) {
  384. case S_FALSE:
  385. pszMsgBuf = TEXT("S_FALSE\n");
  386. break;
  387. default:
  388. FormatMessage(
  389. FORMAT_MESSAGE_ALLOCATE_BUFFER
  390. | FORMAT_MESSAGE_FROM_SYSTEM,
  391. NULL,
  392. hr,
  393. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  394. (LPTSTR)&pszMsgBuf,
  395. 0,
  396. NULL
  397. );
  398. }
  399. // Make sure everything is cool before we blow up somewhere else.
  400. if ( pszMsgBuf == NULL ) {
  401. pszMsgBuf = TEXT("<unknown error code returned>\n");
  402. bDelete = FALSE;
  403. }
  404. Assert( pszFile != NULL );
  405. Assert( pszModule != NULL );
  406. Assert( pszfn != NULL );
  407. dbgmakefilelinestring( szFileLine, pszFile, uLine );
  408. wsprintf( szBuf, TEXT("%-50s %-10s HRESULT: hr = 0x%08x - %s"),
  409. szFileLine, pszModule, hr, pszMsgBuf );
  410. dbgEnterCS( );
  411. OutputDebugString( szBuf );
  412. dbgExitCS( );
  413. wsprintf( szBuf, TEXT("Module:\t%s\t\nLine:\t%u\t\nFile:\t%s\t\n\nFunction:\t%s\t\nhr =\t0x%08x - %s\t\nDo you want to break here?"),
  414. pszModule, uLine, pszFile, pszfn, hr, pszMsgBuf );
  415. if ( IDYES == MessageBox( NULL, szBuf, TEXT("Trace HRESULT"),
  416. MB_YESNO|MB_ICONWARNING ) )
  417. DEBUG_BREAK;
  418. if ( hr != S_OK && hr != S_FALSE && bDelete) {
  419. LocalFree( pszMsgBuf );
  420. }
  421. }
  422. return hr;
  423. }
  424. //
  425. // Memory allocation and tracking
  426. //
  427. typedef struct _MEMORYBLOCK {
  428. HGLOBAL hglobal;
  429. DWORD dwBytes;
  430. UINT uFlags;
  431. LPCTSTR pszFile;
  432. int uLine;
  433. LPCTSTR pszModule;
  434. LPCTSTR pszComment;
  435. _MEMORYBLOCK *pNext;
  436. } MEMORYBLOCK, *LPMEMORYBLOCK;
  437. //
  438. // Adds a MEMORYBLOCK to the memory tracking list.
  439. //
  440. HGLOBAL
  441. DebugMemoryAdd(
  442. HGLOBAL hglobal,
  443. LPCTSTR pszFile,
  444. const int uLine,
  445. LPCTSTR pszModule,
  446. UINT uFlags,
  447. DWORD dwBytes,
  448. LPCTSTR pszComment )
  449. {
  450. if ( hglobal ) {
  451. LPMEMORYBLOCK pmbHead = (LPMEMORYBLOCK) TlsGetValue( g_TraceMemoryIndex );
  452. LPMEMORYBLOCK pmb = (LPMEMORYBLOCK) GlobalAlloc(
  453. GMEM_FIXED,
  454. sizeof(MEMORYBLOCK) );
  455. if ( !pmb ) {
  456. GlobalFree( hglobal );
  457. return NULL;
  458. }
  459. pmb->hglobal = hglobal;
  460. pmb->dwBytes = dwBytes;
  461. pmb->uFlags = uFlags;
  462. pmb->pszFile = pszFile;
  463. pmb->uLine = uLine;
  464. pmb->pszModule = pszModule;
  465. pmb->pszComment = pszComment;
  466. pmb->pNext = pmbHead;
  467. TlsSetValue( g_TraceMemoryIndex, pmb );
  468. TraceMessage( pmb->pszFile,
  469. pmb->uLine,
  470. pmb->pszModule,
  471. TF_MEMORYALLOCS,
  472. L"Alloced %s - %u bytes at 0x%08x (pmb=0x%08x)\n",
  473. pszComment,
  474. dwBytes,
  475. pmb->hglobal,
  476. pmb );
  477. }
  478. return hglobal;
  479. }
  480. //
  481. // Removes a MEMORYBLOCK to the memory tracking list.
  482. //
  483. void
  484. DebugMemoryDelete(
  485. HGLOBAL hglobal )
  486. {
  487. if ( hglobal ) {
  488. LPMEMORYBLOCK pmbHead = (LPMEMORYBLOCK) TlsGetValue( g_TraceMemoryIndex );
  489. LPMEMORYBLOCK pmbLast = NULL;
  490. while ( pmbHead && pmbHead->hglobal != hglobal ) {
  491. pmbLast = pmbHead;
  492. pmbHead = pmbLast->pNext;
  493. }
  494. if ( pmbHead ) {
  495. if ( pmbLast ) {
  496. pmbLast->pNext = pmbHead->pNext;
  497. } else {
  498. TlsSetValue( g_TraceMemoryIndex, pmbHead->pNext );
  499. }
  500. TraceMessage( pmbHead->pszFile,
  501. pmbHead->uLine,
  502. pmbHead->pszModule,
  503. TF_MEMORYALLOCS,
  504. L"Freeing %s - %u bytes from 0x%08x (pmb=0x%08x)\n",
  505. pmbHead->pszComment,
  506. pmbHead->dwBytes,
  507. pmbHead->hglobal,
  508. pmbHead );
  509. memset( pmbHead->hglobal, 0xFA, pmbHead->dwBytes );
  510. GlobalFree( pmbHead );
  511. } else {
  512. DebugMsg( "\n**** Attempted to free memory at 0x%08x (ThreadID = 0x%08x) ****\n\n",
  513. hglobal, GetCurrentThreadId( ) );
  514. }
  515. }
  516. }
  517. //
  518. // Allocates memory and adds the MEMORYBLOCK to the memory tracking list.
  519. //
  520. HGLOBAL
  521. DebugAlloc(
  522. LPCTSTR pszFile,
  523. const int uLine,
  524. LPCTSTR pszModule,
  525. UINT uFlags,
  526. DWORD dwBytes,
  527. LPCTSTR pszComment )
  528. {
  529. HGLOBAL hglobal = GlobalAlloc( uFlags, dwBytes );
  530. return DebugMemoryAdd( hglobal, pszFile, uLine, pszModule, uFlags, dwBytes, pszComment );
  531. }
  532. //
  533. // Remove the MEMORYBLOCK to the memory tracking list, memsets the
  534. // memory to 0xFE and then frees the memory.
  535. //
  536. HGLOBAL
  537. DebugFree(
  538. HGLOBAL hglobal )
  539. {
  540. DebugMemoryDelete( hglobal );
  541. return GlobalFree( hglobal );
  542. }
  543. //
  544. // Checks the memory tracking list. If it is not empty, it will dump the
  545. // list and break.
  546. //
  547. void
  548. DebugMemoryCheck( )
  549. {
  550. BOOL fFoundLeak = FALSE;
  551. LPMEMORYBLOCK pmb = (LPMEMORYBLOCK) TlsGetValue( g_TraceMemoryIndex );
  552. dbgEnterCS( );
  553. while ( pmb ) {
  554. LPVOID args[ 5 ];
  555. TCHAR szOutput[ DEBUG_OUTPUT_BUFFER_SIZE ];
  556. TCHAR szFileLine[ DEBUG_OUTPUT_BUFFER_SIZE ];
  557. if ( fFoundLeak == FALSE ) {
  558. DebugMsg("\n******** Memory leak detected ******** ThreadID = 0x%08x ******** \n\n", GetCurrentThreadId( ) );
  559. //OutputDebugString("12345678901234567890123456789012345678901234567890 1234567890 X 0x12345678 12345 1...");
  560. OutputDebugString(TEXT("Filename(Line Number): Module Addr/HGLOBAL Size String\n"));
  561. fFoundLeak = TRUE;
  562. }
  563. dbgmakefilelinestring( szFileLine, pmb->pszFile, pmb->uLine );
  564. args[0] = (LPVOID) pmb->hglobal;
  565. args[1] = (LPVOID) szFileLine;
  566. args[2] = (LPVOID) pmb->pszComment;
  567. args[3] = UlongToPtr(pmb->dwBytes);
  568. args[4] = (LPVOID) pmb->pszModule;
  569. if ( !!(pmb->uFlags & GMEM_MOVEABLE) ) {
  570. FormatMessage(
  571. FORMAT_MESSAGE_FROM_STRING |
  572. FORMAT_MESSAGE_ARGUMENT_ARRAY,
  573. TEXT("%2!-50s! %5!-10s! H 0x%1!08x! %4!-5u! \"%3\"\n"),
  574. 0, // error code
  575. 0, // default language
  576. (LPTSTR) szOutput, // output buffer
  577. ARRAYSIZE( szOutput ), // size of buffer
  578. (va_list*) args ); // arguments
  579. } else {
  580. FormatMessage(
  581. FORMAT_MESSAGE_FROM_STRING |
  582. FORMAT_MESSAGE_ARGUMENT_ARRAY,
  583. TEXT("%2!-50s! %5!-10s! A 0x%1!08x! %4!-5u! \"%3\"\n"),
  584. 0, // error code
  585. 0, // default language
  586. (LPTSTR) szOutput, // output buffer
  587. ARRAYSIZE( szOutput ), // size of buffer
  588. (va_list*) args ); // arguments
  589. }
  590. OutputDebugString( szOutput );
  591. pmb = pmb->pNext;
  592. }
  593. if ( fFoundLeak == TRUE ) {
  594. OutputDebugString(TEXT("\n***************************** Memory leak detected *****************************\n\n"));
  595. }
  596. dbgExitCS( );
  597. if (g_dwTraceFlags & TF_MEMORYALLOCS) {
  598. Assert( !fFoundLeak );
  599. }
  600. }
  601. //
  602. // Global Management Functions -
  603. //
  604. // These are in debug and retail but internally they change
  605. // depending on the build.
  606. //
  607. #undef new
  608. void* __cdecl operator new( size_t nSize, LPCTSTR pszFile, const int iLine, LPCTSTR pszModule )
  609. {
  610. return DebugAlloc( pszFile, iLine, pszModule, GPTR, nSize, L"new()" );
  611. }
  612. void * __cdecl operator new(size_t t_size )
  613. {
  614. return DebugAlloc( L"Unknown", 0, L"Unknown", GPTR, t_size, L"unmapped new()" );
  615. }
  616. void __cdecl operator delete(void *pv)
  617. {
  618. TraceFree( pv );
  619. }
  620. int __cdecl _purecall(void)
  621. {
  622. return 0;
  623. }
  624. #else // ! DEBUG -- It's retail
  625. //
  626. // Global Management Functions -
  627. //
  628. // These are in debug and retail but are internally they change
  629. // depending on the build.
  630. //
  631. void * __cdecl operator new(size_t t_size )
  632. {
  633. return LocalAlloc( GPTR, t_size );
  634. }
  635. void __cdecl operator delete(void *pv)
  636. {
  637. LocalFree( pv );
  638. }
  639. int __cdecl _purecall(void)
  640. {
  641. return 0;
  642. }
  643. #endif // DEBUG