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.

431 lines
12 KiB

  1. /*/////////////////////////////////////////////////////////////////////////
  2. //
  3. // INTEL Corporation Proprietary Information
  4. // Copyright (c) Intel Corporation
  5. //
  6. // This listing is supplied under the terms of a license aggreement
  7. // with INTEL Corporation and may not be used, copied nor disclosed
  8. // except in accordance with that agreement.
  9. //
  10. //////////////////////////////////////////////////////////////////////////
  11. ///////////////////////////////////////////////////////////////////
  12. // $Workfile: TRACE.C $
  13. // $Revision: 1.3 $
  14. // $Modtime: 27 Nov 1995 08:38:08 $
  15. //
  16. // DESCRIPTION:
  17. // This file contains the output function for the tracing facility
  18. // used in PII DLL
  19. //////////////////////////////////////////////////////////////////
  20. */
  21. /* Single Line Comments */
  22. #pragma warning(disable: 4001)
  23. // Disable some more benign warnings for compiling at warning level 4
  24. // nonstandard extension used : nameless struct/union
  25. #pragma warning(disable: 4201)
  26. // nonstandard extension used : bit field types other than int
  27. #pragma warning(disable: 4214)
  28. // Note: Creating precompiled header
  29. #pragma warning(disable: 4699)
  30. // unreferenced inline function has been removed
  31. #pragma warning(disable: 4514)
  32. // unreferenced formal parameter
  33. //#pragma warning(disable: 4100)
  34. // 'type' differs in indirection to slightly different base
  35. // types from 'other type'
  36. #pragma warning(disable: 4057)
  37. // named type definition in parentheses
  38. #pragma warning(disable: 4115)
  39. // nonstandard extension used : benign typedef redefinition
  40. #pragma warning(disable: 4209)
  41. #include <nt.h>
  42. #include <ntrtl.h>
  43. #include <nturtl.h>
  44. #include <windows.h>
  45. #include <memory.h>
  46. #include <stdio.h>
  47. #include <stdarg.h>
  48. #include <io.h>
  49. /* because windows.h turns this one back on */
  50. #pragma warning(disable: 4001)
  51. #include "trace.h"
  52. #include "osdef.h"
  53. #ifdef TRACING
  54. BOOL InitMemoryBuffers(VOID);
  55. LPSTR g_CurrentMessage=NULL;
  56. CRITICAL_SECTION g_OutputRoutine;
  57. int iTraceDestination=TRACE_TO_AUX;
  58. char TraceFile[] = "trace.log";
  59. DWORD debugLevel=DBG_ERR;
  60. HANDLE g_OutputFile = NULL; // file descriptor for file output
  61. BOOL g_LogOpened = FALSE; // have we opened the file for output
  62. BOOL g_TraceInited = FALSE;
  63. VOID
  64. __cdecl
  65. PrintDebugString(
  66. char *Format,
  67. ...
  68. )
  69. /*++
  70. Routine Description:
  71. This routine outputs a debug messages. Debug messages are routed
  72. to a file or a debug window depnding on the value of a global
  73. variable defined in this module
  74. Arguments:
  75. Format - A "printf()" compatible format specification.
  76. ... - Additional arguments to "printf()" format specification.
  77. Returns:
  78. NONE
  79. --*/
  80. {
  81. va_list ArgumentList; // argument list for varargs processing
  82. DWORD BytesWritten;
  83. if (!g_TraceInited)
  84. {
  85. #define INIT_MUTEX_BASE_NAME "WS2_32TraceMutex-"
  86. HANDLE InitMutex;
  87. CHAR InitMutexName[sizeof(INIT_MUTEX_BASE_NAME)+8];
  88. // Generate a name unique for a process so we can't cross other processes.
  89. sprintf (InitMutexName, INIT_MUTEX_BASE_NAME "%8.8lx", GetCurrentProcessId());
  90. // Create the mutex to protect the rest of the init code
  91. InitMutex = CreateMutex(
  92. NULL, // Use default security attributes
  93. FALSE, // We don't want automatic ownership
  94. InitMutexName);
  95. if (!InitMutex)
  96. {
  97. // We failed to create the mutex there is nothign else we
  98. // can do so return. This will cause the debug output to
  99. // be silently lost.
  100. return;
  101. } //if
  102. // Wait on mutex (just a little and bail if we can't get it)
  103. if (WaitForSingleObject( InitMutex, 10000)==WAIT_OBJECT_0) {
  104. // Check to see if init is still needed
  105. if (!g_TraceInited)
  106. {
  107. // Init the critical section to be used to protect the
  108. // output portion of this routine.
  109. __try {
  110. InitializeCriticalSection( &g_OutputRoutine );
  111. }
  112. __except (EXCEPTION_EXECUTE_HANDLER) {
  113. goto Release;
  114. }
  115. // allocate buffers to hold debug messages
  116. if (InitMemoryBuffers()) {
  117. g_TraceInited = TRUE;
  118. } //if
  119. else {
  120. DeleteCriticalSection ( &g_OutputRoutine );
  121. }
  122. Release:
  123. ;
  124. } //if
  125. // Signal the mutex
  126. ReleaseMutex(InitMutex);
  127. }
  128. // delete this threads handle to the mutex
  129. CloseHandle(InitMutex);
  130. // Bail out if we couldn't init memory buffers or critical section
  131. if (!g_TraceInited)
  132. {
  133. return;
  134. }
  135. }
  136. // Here is where all the heavy lifting starts
  137. EnterCriticalSection( &g_OutputRoutine );
  138. // print the user message to our buffer
  139. va_start(ArgumentList, Format);
  140. _vsnprintf(g_CurrentMessage, TRACE_OUTPUT_BUFFER_SIZE, Format, ArgumentList);
  141. va_end(ArgumentList);
  142. if (iTraceDestination == TRACE_TO_FILE)
  143. {
  144. if (!g_LogOpened)
  145. {
  146. g_OutputFile =
  147. CreateFile( TraceFile,
  148. GENERIC_WRITE, // open for writing
  149. FILE_SHARE_WRITE, // Share the file with others
  150. NULL, // default security
  151. OPEN_ALWAYS, // Use file if it exsits
  152. FILE_ATTRIBUTE_NORMAL, // Use a normal file
  153. NULL); // No template
  154. if (g_OutputFile != INVALID_HANDLE_VALUE)
  155. {
  156. g_LogOpened = TRUE;
  157. } //if
  158. } //if
  159. if (g_LogOpened)
  160. {
  161. // Write the current message to the trace file
  162. WriteFile(g_OutputFile,
  163. g_CurrentMessage,
  164. lstrlen(g_CurrentMessage),
  165. &BytesWritten,
  166. NULL);
  167. // Flush debug output to file
  168. FlushFileBuffers( TraceFile );
  169. } //if
  170. }
  171. if( iTraceDestination == TRACE_TO_AUX)
  172. {
  173. // Send message to AUX device
  174. OutputDebugString(g_CurrentMessage);
  175. }
  176. LeaveCriticalSection( &g_OutputRoutine );
  177. }
  178. BOOL
  179. InitMemoryBuffers(
  180. VOID
  181. )
  182. /*++
  183. Routine Description:
  184. Initailizes the memory buffers used by this module.
  185. Arguments:
  186. NONE
  187. Returns:
  188. TRUE if all memory buffers are successfully created, Otherwise FALSE.
  189. --*/
  190. {
  191. BOOL ReturnCode=FALSE;
  192. g_CurrentMessage = GlobalAlloc (GPTR, TRACE_OUTPUT_BUFFER_SIZE);
  193. if (g_CurrentMessage)
  194. {
  195. ZeroMemory( g_CurrentMessage, TRACE_OUTPUT_BUFFER_SIZE );
  196. ReturnCode=TRUE;
  197. } //if
  198. return(ReturnCode);
  199. }
  200. VOID
  201. TraceCleanup (
  202. )
  203. {
  204. if (g_LogOpened) {
  205. CloseHandle (g_OutputFile);
  206. g_OutputFile = NULL;
  207. g_LogOpened = FALSE;
  208. }
  209. if (g_TraceInited) {
  210. GlobalFree (g_CurrentMessage);
  211. g_CurrentMessage = NULL;
  212. DeleteCriticalSection (&g_OutputRoutine);
  213. g_TraceInited = FALSE;
  214. }
  215. }
  216. LONG
  217. Ws2ExceptionFilter(
  218. LPEXCEPTION_POINTERS ExceptionPointers,
  219. LPSTR SourceFile,
  220. LONG LineNumber
  221. )
  222. {
  223. LPSTR fileName;
  224. DWORD i;
  225. //
  226. // Protect ourselves in case the process is totally messed up.
  227. //
  228. __try {
  229. //
  230. // Exceptions should never be thrown in a properly functioning
  231. // system, so this is bad. To ensure that someone will see this,
  232. // print to the debugger directly
  233. //
  234. fileName = strrchr( SourceFile, '\\' );
  235. if( fileName == NULL ) {
  236. fileName = SourceFile;
  237. } else {
  238. fileName++;
  239. }
  240. //
  241. // Whine about the exception.
  242. //
  243. PrintDebugString(
  244. "-| WS2_32 EXCEPTION: %08lx @ %p %d params, caught in %s:%d\n",
  245. ExceptionPointers->ExceptionRecord->ExceptionCode,
  246. ExceptionPointers->ExceptionRecord->ExceptionAddress,
  247. ExceptionPointers->ExceptionRecord->NumberParameters,
  248. fileName, LineNumber );
  249. if (ExceptionPointers->ExceptionRecord->NumberParameters) {
  250. PrintDebugString (
  251. " Params:");
  252. for (i=0; i<ExceptionPointers->ExceptionRecord->NumberParameters; i++) {
  253. PrintDebugString(" %p", ExceptionPointers->ExceptionRecord->ExceptionInformation[i]);
  254. }
  255. PrintDebugString ("\n");
  256. }
  257. }
  258. __except( EXCEPTION_EXECUTE_HANDLER ) {
  259. //
  260. // Not much we can do here...
  261. //
  262. ;
  263. }
  264. return EXCEPTION_EXECUTE_HANDLER;
  265. } // Ws2ExceptionFilter
  266. LONG
  267. Ws2ProviderExceptionFilter(
  268. LPEXCEPTION_POINTERS ExceptionPointers,
  269. LPSTR pFunc,
  270. LPWSTR pDll,
  271. LPWSTR pName,
  272. LPGUID pGuid
  273. )
  274. /*++
  275. Routine Description:
  276. Special exception filter for exceptions in critical calls to provider DLLs,
  277. such as startup and cleanup.
  278. Arguments:
  279. Exception and provider information
  280. Returns:
  281. whatever lower-level exception handler returns with EXCEPTION_CONTINUE_SEARCH
  282. filtered out since exception handler cannot be bypassed with current logic
  283. in ws2_32.dll
  284. --*/
  285. {
  286. LONG result;
  287. //
  288. // Protect ourselves in case the process is totally messed up.
  289. //
  290. __try {
  291. PrintDebugString(
  292. "-| WS2_32 Unhandled Exception: %08lx @ %p, caught in %s of %ls"
  293. " (provider:%ls GUID:(%8.8x-%4.4x-%4.4x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x) |-\n",
  294. ExceptionPointers->ExceptionRecord->ExceptionCode,
  295. ExceptionPointers->ExceptionRecord->ExceptionAddress,
  296. pFunc, pDll, pName, pGuid->Data1, pGuid->Data2, pGuid->Data3,
  297. pGuid->Data4[0],pGuid->Data4[1],pGuid->Data4[2],pGuid->Data4[3],
  298. pGuid->Data4[4],pGuid->Data4[5],pGuid->Data4[6],pGuid->Data4[7]
  299. );
  300. }
  301. __except( EXCEPTION_EXECUTE_HANDLER ) {
  302. //
  303. // Not much we can do here...
  304. //
  305. ;
  306. }
  307. //
  308. // Try standard handler for unhanled exceptions.
  309. // This will bring in a popup or launch the debugger if
  310. // just in time debugging is enabled.
  311. //
  312. result = UnhandledExceptionFilter (ExceptionPointers);
  313. if (result==EXCEPTION_CONTINUE_SEARCH) {
  314. //
  315. // It did not work, force break-in if debugger is attached at all.
  316. //
  317. result = RtlUnhandledExceptionFilter (ExceptionPointers);
  318. if (result==EXCEPTION_CONTINUE_SEARCH) {
  319. //
  320. // No luck, handle the exception.
  321. //
  322. result = EXCEPTION_EXECUTE_HANDLER;
  323. }
  324. }
  325. return result;
  326. }
  327. #endif // TRACING
  328. #if DBG
  329. VOID
  330. WsAssert(
  331. LPVOID FailedAssertion,
  332. LPVOID FileName,
  333. ULONG LineNumber
  334. )
  335. {
  336. PrintDebugString(
  337. "\n"
  338. "*** Assertion failed: %s\n"
  339. "*** Source file %s, line %lu\n\n",
  340. FailedAssertion,
  341. FileName,
  342. LineNumber
  343. );
  344. DebugBreak();
  345. } // WsAssert
  346. #endif