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.

196 lines
6.1 KiB

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. /*
  3. Implementation of Win95 tracing facility to mimic that of NT. Works on both.
  4. */
  5. #pragma warning(disable:4201) // allows nameless structs and unions
  6. #pragma warning(disable:4514) // don't care when unreferenced inline functions are removed
  7. #pragma warning(disable:4706) // we are allowed to assign within a conditional
  8. #include "windows.h"
  9. #include <stdio.h>
  10. #include <stdarg.h>
  11. #include <process.h>
  12. #include "w95trace.h"
  13. // Uncomment the following line if you need debugging but can't use the mutex
  14. //#define NOMUTEX
  15. #if defined( _DEBUG ) ||defined( DEBUG ) || defined( DBG )
  16. #ifdef __cplusplus
  17. extern "C" {
  18. #endif
  19. static HANDLE g_hSpewFile = INVALID_HANDLE_VALUE;
  20. __inline BOOL TestMutex()
  21. {
  22. #ifndef NOMUTEX
  23. HANDLE hTestMutex = OpenMutex( SYNCHRONIZE, FALSE, TEXT("oleacc-msaa-use-dbwin") );
  24. if( ! hTestMutex )
  25. return FALSE;
  26. CloseHandle( hTestMutex );
  27. #endif
  28. return TRUE;
  29. }
  30. void OutputDebugStringW95( LPCTSTR lpOutputString, ...)
  31. {
  32. // Only produce output if this mutex is set...
  33. if (TestMutex())
  34. {
  35. HANDLE heventDBWIN; /* DBWIN32 synchronization object */
  36. HANDLE heventData; /* data passing synch object */
  37. HANDLE hSharedFile; /* memory mapped file shared data */
  38. LPTSTR lpszSharedMem;
  39. TCHAR achBuffer[500];
  40. int cch;
  41. /* create the output buffer */
  42. va_list args;
  43. va_start(args, lpOutputString);
  44. cch = wvsprintf(achBuffer, lpOutputString, args);
  45. va_end(args);
  46. /*
  47. Do a regular OutputDebugString so that the output is
  48. still seen in the debugger window if it exists.
  49. This ifdef is necessary to avoid infinite recursion
  50. from the inclusion of W95TRACE.H
  51. */
  52. #ifdef UNICODE
  53. OutputDebugStringW(achBuffer);
  54. #else
  55. ::OutputDebugStringA(achBuffer);
  56. #endif
  57. // Uncomment the following lines if you need DBPRINTF lines to go to a file
  58. // (your code will have to open and close the file)
  59. // if (g_hSpewFile && g_hSpewFile != INVALID_HANDLE_VALUE)
  60. // {
  61. // SpewToFile(achBuffer);
  62. // }
  63. /* bail if it's not Win95 */
  64. {
  65. OSVERSIONINFO VerInfo;
  66. VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  67. GetVersionEx(&VerInfo);
  68. if ( VerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS )
  69. return;
  70. }
  71. /* make sure DBWIN is open and waiting */
  72. heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("DBWIN_BUFFER_READY"));
  73. if ( !heventDBWIN )
  74. {
  75. //MessageBox(NULL, TEXT("DBWIN_BUFFER_READY nonexistent"), NULL, MB_OK);
  76. return;
  77. }
  78. /* get a handle to the data synch object */
  79. heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("DBWIN_DATA_READY"));
  80. if ( !heventData )
  81. {
  82. // MessageBox(NULL, TEXT("DBWIN_DATA_READY nonexistent"), NULL, MB_OK);
  83. CloseHandle(heventDBWIN);
  84. return;
  85. }
  86. hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, TEXT("DBWIN_BUFFER"));
  87. if (!hSharedFile)
  88. {
  89. //MessageBox(NULL, TEXT("DebugTrace: Unable to create file mapping object DBWIN_BUFFER"), TEXT("Error"), MB_OK);
  90. CloseHandle(heventDBWIN);
  91. CloseHandle(heventData);
  92. return;
  93. }
  94. lpszSharedMem = (LPTSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
  95. if (!lpszSharedMem)
  96. {
  97. //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
  98. CloseHandle(heventDBWIN);
  99. CloseHandle(heventData);
  100. return;
  101. }
  102. /* wait for buffer event */
  103. WaitForSingleObject(heventDBWIN, INFINITE);
  104. /* write it to the shared memory */
  105. *((LPDWORD)lpszSharedMem) = _getpid();
  106. wsprintf(lpszSharedMem + sizeof(DWORD), TEXT("%s"), achBuffer);
  107. /* signal data ready event */
  108. SetEvent(heventData);
  109. /* clean up handles */
  110. CloseHandle(hSharedFile);
  111. CloseHandle(heventData);
  112. CloseHandle(heventDBWIN);
  113. }
  114. return;
  115. }
  116. void SpewOpenFile(LPCTSTR pszSpewFile)
  117. {
  118. #ifdef UNICODE // only works for unicode
  119. // Only produce output if this mutex is set...
  120. if (g_hSpewFile == INVALID_HANDLE_VALUE && TestMutex())
  121. {
  122. TCHAR szSpewFile[MAX_PATH] = TEXT("C:\\");
  123. #ifndef NOMUTEX
  124. // if NOMUTEX is defined most likely you are debugging when
  125. // there's no interactive user (so no temp path)
  126. GetTempPath(MAX_PATH, szSpewFile);
  127. #endif
  128. if (lstrlen(szSpewFile)+lstrlen(pszSpewFile) >= MAX_PATH)
  129. {
  130. MessageBox(NULL, TEXT("SpewOpenFile: Name will be longer than MAX_PATH"), TEXT("OOPS"), MB_OK);
  131. return;
  132. }
  133. lstrcat(szSpewFile, pszSpewFile);
  134. g_hSpewFile = CreateFile(szSpewFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  135. if (INVALID_HANDLE_VALUE == g_hSpewFile)
  136. {
  137. // MessageBox(NULL, TEXT("SpewOpenFile: Unable to open spew file"), TEXT("Error"), MB_OK);
  138. }
  139. }
  140. #endif
  141. }
  142. void SpewToFile( LPCTSTR lpOutputString, ...)
  143. {
  144. #ifdef UNICODE // only works for unicode
  145. if (g_hSpewFile != INVALID_HANDLE_VALUE && TestMutex())
  146. {
  147. TCHAR achBuffer[1025];
  148. CHAR achAnsiBuf[500];
  149. DWORD dwcBytesWr, dwcBytes;
  150. va_list args;
  151. va_start(args, lpOutputString);
  152. wvsprintf(achBuffer, lpOutputString, args);
  153. dwcBytes = WideCharToMultiByte(CP_ACP, 0, achBuffer, -1, achAnsiBuf, sizeof(achAnsiBuf)*sizeof(CHAR), NULL, NULL);
  154. if (!WriteFile(g_hSpewFile, achAnsiBuf, dwcBytes-1, &dwcBytesWr, NULL))
  155. {
  156. // MessageBox(NULL, TEXT("SpewToFile: Unable to write to spew file"), TEXT("Error"), MB_OK);
  157. }
  158. va_end(args);
  159. }
  160. #endif
  161. }
  162. void SpewCloseFile()
  163. {
  164. #ifdef UNICODE // only works for unicode
  165. if (g_hSpewFile != INVALID_HANDLE_VALUE && TestMutex())
  166. CloseHandle(g_hSpewFile);
  167. #endif
  168. }
  169. #ifdef __cplusplus
  170. }
  171. #endif
  172. #endif