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.

389 lines
9.0 KiB

  1. /*----------------------------------------------------------------------
  2. REGISTRY.C
  3. Async tracing Registry reading routines
  4. Copyright (C) 1994 Microsoft Corporation
  5. All rights reserved.
  6. Authors:
  7. gordm Gord Mangione
  8. History:
  9. 01/30/95 gordm Created.
  10. ----------------------------------------------------------------------*/
  11. #ifndef WIN32_LEAN_AND_MEAN
  12. #define WIN32_LEAN_AND_MEAN
  13. #endif
  14. #include <windows.h>
  15. #include "traceint.h"
  16. char szTraceFileName[MAX_PATH];
  17. char szDebugAsyncTrace[] = "SOFTWARE\\Microsoft\\MosTrace\\CurrentVersion\\DebugAsyncTrace";
  18. __inline BOOL GetRegDword( HKEY hKey, LPSTR pszValue, LPDWORD pdw )
  19. {
  20. DWORD cbData = sizeof( DWORD );
  21. DWORD dwType = REG_DWORD;
  22. return RegQueryValueEx(hKey,
  23. pszValue,
  24. NULL,
  25. &dwType,
  26. (LPBYTE)pdw,
  27. &cbData ) == ERROR_SUCCESS && dwType == REG_DWORD;
  28. }
  29. __inline BOOL GetRegString( HKEY hKey, LPSTR pszValue, LPBYTE buf, LPDWORD lpcbData )
  30. {
  31. DWORD dwType = REG_SZ;
  32. return RegQueryValueEx(hKey,
  33. pszValue,
  34. NULL,
  35. &dwType,
  36. buf,
  37. lpcbData ) == ERROR_SUCCESS && dwType == REG_SZ;
  38. }
  39. BOOL GetTraceFlagsFromRegistry( void )
  40. {
  41. static char szNewTraceFileName[MAX_PATH];
  42. DWORD dwNewEnabledTraces;
  43. DWORD dwNewTraceOutputType;
  44. DWORD dwNewAsyncTraceFlag;
  45. DWORD dwNewHeapIncrementCount;
  46. int nNewThreadPriority;
  47. HKEY hkConfig = NULL;
  48. BOOL bRC = FALSE;
  49. DWORD cbData;
  50. __try
  51. {
  52. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  53. szDebugAsyncTrace,
  54. 0,
  55. KEY_READ,
  56. &hkConfig ) == ERROR_SUCCESS )
  57. {
  58. if ( GetRegDword( hkConfig,
  59. "MaxTraceFileSize",
  60. &dwMaxFileSize ) == FALSE )
  61. {
  62. dwMaxFileSize = DEFAULT_MAX_FILE_SIZE;
  63. }
  64. //
  65. // determine threshold count based on how we can fit in the file
  66. //
  67. PendQ.dwThresholdCount = dwMaxFileSize / AVERAGE_TRACE_SIZE;
  68. INT_TRACE( "PendQ.dwThresholdCount: %d\n", PendQ.dwThresholdCount );
  69. if ( GetRegDword( hkConfig,
  70. "EnabledTraces",
  71. &dwNewEnabledTraces ) == FALSE )
  72. {
  73. INT_TRACE( "GetRegDword: EnabledTraces failed: %d\n", GetLastError() );
  74. return bRC = FALSE;
  75. }
  76. if ( GetRegDword( hkConfig,
  77. "OutputTraceType",
  78. &dwNewTraceOutputType ) == FALSE )
  79. {
  80. INT_TRACE( "GetRegDword: OutputTraceType failed: %d\n", GetLastError() );
  81. return bRC = FALSE;
  82. }
  83. if ( GetRegDword( hkConfig,
  84. "AsyncTraceFlag",
  85. &dwNewAsyncTraceFlag ) == FALSE )
  86. {
  87. INT_TRACE( "GetRegDword: AsyncTraceFlag failed: %d\n", GetLastError() );
  88. return bRC = FALSE;
  89. }
  90. if (GetRegDword(hkConfig,
  91. "HeapIncrementCount",
  92. (LPDWORD)&dwNewHeapIncrementCount ) == FALSE ||
  93. dwNewHeapIncrementCount == 0 )
  94. {
  95. //
  96. // optional reg entry
  97. // default is the number buffers in 64KB
  98. //
  99. dwNewHeapIncrementCount = 0x10000 / sizeof(TRACEBUF);
  100. }
  101. InterlockedExchange( (long *)&dwIncrementSize, (long)dwNewHeapIncrementCount );
  102. if ( GetRegDword( hkConfig,
  103. "AsyncThreadPriority",
  104. (LPDWORD)&nNewThreadPriority ) == FALSE )
  105. {
  106. //
  107. // optional reg entry
  108. //
  109. nNewThreadPriority = THREAD_PRIORITY_BELOW_NORMAL;
  110. }
  111. else switch( nNewThreadPriority )
  112. {
  113. //
  114. // if successful verify the resulting value
  115. //
  116. case THREAD_PRIORITY_IDLE:
  117. case THREAD_PRIORITY_BELOW_NORMAL:
  118. case THREAD_PRIORITY_NORMAL:
  119. case THREAD_PRIORITY_ABOVE_NORMAL:
  120. case THREAD_PRIORITY_HIGHEST:
  121. break;
  122. default:
  123. ASSERT( FALSE );
  124. nNewThreadPriority = THREAD_PRIORITY_BELOW_NORMAL;
  125. }
  126. cbData = sizeof(szNewTraceFileName);
  127. if ( GetRegString( hkConfig,
  128. "TraceFile",
  129. szNewTraceFileName,
  130. &cbData ) == FALSE )
  131. {
  132. //
  133. // Only fail if user specifies FILE based tracing
  134. //
  135. if ( dwNewTraceOutputType & TRACE_OUTPUT_FILE )
  136. {
  137. INT_TRACE( "GetRegString: TraceFile failed: %d\n", GetLastError() );
  138. return bRC = FALSE;
  139. }
  140. }
  141. bRC = TRUE;
  142. }
  143. }
  144. __finally
  145. {
  146. //
  147. // preserve the original error code
  148. //
  149. DWORD dwLastError = GetLastError();
  150. BOOL fLeaveCritSec = FALSE;
  151. if ( bRC == TRUE )
  152. {
  153. BOOL bNewFileName = lstrcmpi( szNewTraceFileName, szTraceFileName ) != 0;
  154. BOOL bNewTraces = dwNewEnabledTraces != *INTERNAL__dwEnabledTraces;
  155. BOOL bNewFlags = dwNewAsyncTraceFlag != dwAsyncTraceFlag;
  156. BOOL bNewOutput = dwNewTraceOutputType != dwTraceOutputType;
  157. INT_TRACE( "GetTraceFlags... 0x%08X, 0x%08X, 0x%08X, %s\n",
  158. dwNewAsyncTraceFlag,
  159. dwNewEnabledTraces,
  160. dwNewTraceOutputType,
  161. szNewTraceFileName );
  162. INT_TRACE( "bNewFileName:%d bNewTraces:%d bNewOutput:%d bNewFlags:%d\n",
  163. bNewFileName,
  164. bNewTraces,
  165. bNewOutput,
  166. bNewFlags );
  167. if ( bNewFileName || bNewTraces || bNewOutput || bNewFlags )
  168. {
  169. if ( *INTERNAL__dwEnabledTraces )
  170. {
  171. //
  172. // not the initial time thru
  173. //
  174. fLeaveCritSec = TRUE;
  175. if ( dwAsyncTraceFlag )
  176. {
  177. INTERNAL__FlushAsyncTrace();
  178. }
  179. EnterCriticalSection( &critSecWrite );
  180. }
  181. if ( PendQ.hFile != INVALID_HANDLE_VALUE )
  182. {
  183. //
  184. // if the file name changed or tracing was disabled or the
  185. // file tracing disabled, then close the currently open file
  186. //
  187. if( bNewFileName ||
  188. dwNewEnabledTraces == 0 ||
  189. IsTraceFile( dwNewTraceOutputType ) == FALSE )
  190. {
  191. BOOL bSuccess;
  192. EnterCriticalSection( &critSecWrite );
  193. bSuccess = CloseHandle( PendQ.hFile );
  194. INT_TRACE( "CloseHandle: %d, GetLastError: %d\n",
  195. bSuccess, GetLastError() );
  196. PendQ.hFile = INVALID_HANDLE_VALUE;
  197. LeaveCriticalSection( &critSecWrite );
  198. }
  199. }
  200. if ( IsTraceFile( dwNewTraceOutputType ) )
  201. {
  202. if (bNewFileName ||
  203. IsTraceFile( dwTraceOutputType ) == FALSE ||
  204. dwNewEnabledTraces != 0 &&
  205. PendQ.hFile == INVALID_HANDLE_VALUE )
  206. {
  207. PendQ.hFile = CreateFile(szNewTraceFileName,
  208. GENERIC_WRITE,
  209. FILE_SHARE_READ|FILE_SHARE_WRITE,
  210. NULL,
  211. OPEN_ALWAYS,
  212. FILE_ATTRIBUTE_NORMAL,
  213. NULL );
  214. if ( PendQ.hFile != INVALID_HANDLE_VALUE )
  215. {
  216. lstrcpy( szTraceFileName, szNewTraceFileName );
  217. }
  218. else
  219. {
  220. INT_TRACE( "CreateFile failed for %s 0x%X\n",
  221. szNewTraceFileName,
  222. GetLastError() );
  223. }
  224. }
  225. }
  226. //
  227. // set the new priority for the writer thread
  228. //
  229. if ( nNewThreadPriority != nAsyncThreadPriority )
  230. {
  231. nAsyncThreadPriority = nNewThreadPriority;
  232. SetThreadPriority( PendQ.hWriteThread, nAsyncThreadPriority );
  233. }
  234. dwTraceOutputType = dwNewTraceOutputType;
  235. dwAsyncTraceFlag = dwNewAsyncTraceFlag;
  236. InterlockedExchange( INTERNAL__dwEnabledTraces, dwNewEnabledTraces );
  237. if ( fLeaveCritSec )
  238. {
  239. //
  240. // not the initial time thru
  241. //
  242. LeaveCriticalSection( &critSecWrite );
  243. }
  244. }
  245. }
  246. if ( hkConfig != NULL )
  247. {
  248. RegCloseKey( hkConfig );
  249. }
  250. SetLastError( dwLastError );
  251. }
  252. return bRC;
  253. }
  254. #define NUM_REG_THREAD_OBJECTS 2
  255. DWORD RegNotifyThread( LPDWORD lpdw )
  256. {
  257. HANDLE Handles[NUM_REG_THREAD_OBJECTS];
  258. HKEY hKey;
  259. DWORD dw;
  260. Handles[0] = hShutdownEvent;
  261. INT_TRACE( "RegNotifyThread 0x%X\n", GetCurrentThreadId() );
  262. Handles[1] = CreateEvent( NULL, FALSE, FALSE, NULL );
  263. if ( Handles[1] == NULL )
  264. {
  265. ASSERT( FALSE );
  266. INT_TRACE( "RegNotifyThread CreateEvent failed 0x%X\n", GetLastError() );
  267. return 1;
  268. }
  269. if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  270. szDebugAsyncTrace,
  271. 0,
  272. KEY_READ,
  273. &hKey ) != ERROR_SUCCESS )
  274. {
  275. INT_TRACE( "RegNotifyThread RegOpenKeyEx failed 0x%X\n", GetLastError() );
  276. CloseHandle( Handles[1] );
  277. return 1;
  278. }
  279. for ( ;; )
  280. {
  281. if ( RegNotifyChangeKeyValue(hKey,
  282. FALSE,
  283. REG_NOTIFY_CHANGE_ATTRIBUTES |
  284. REG_NOTIFY_CHANGE_LAST_SET,
  285. Handles[1],
  286. TRUE ) != ERROR_SUCCESS )
  287. {
  288. INT_TRACE( "RegNotifyThread RegNotify... failed 0x%X\n", GetLastError() );
  289. RegCloseKey( hKey );
  290. CloseHandle( Handles[1] );
  291. return 1;
  292. }
  293. dw = WaitForMultipleObjects(NUM_REG_THREAD_OBJECTS,
  294. Handles,
  295. FALSE,
  296. INFINITE );
  297. switch( dw )
  298. {
  299. //
  300. // normal signalled event
  301. //
  302. case WAIT_OBJECT_0:
  303. RegCloseKey( hKey );
  304. CloseHandle( Handles[1] );
  305. INT_TRACE( "Exiting RegNotifyThread for hShutdownEvent\n" );
  306. return 0;
  307. //
  308. // signalled that our registry keys have changed
  309. //
  310. case WAIT_OBJECT_0+1:
  311. GetTraceFlagsFromRegistry();
  312. break;
  313. default:
  314. INT_TRACE( "RegNotifyThread WFMO: dw: 0x%X, Error: 0x%X\n", dw, GetLastError() );
  315. ASSERT( FALSE );
  316. RegCloseKey( hKey );
  317. CloseHandle( Handles[1] );
  318. return 1;
  319. }
  320. }
  321. INT_TRACE( "Exiting RegNotifyThread abnormally\n" );
  322. RegCloseKey( hKey );
  323. CloseHandle( Handles[1] );
  324. return 2;
  325. }