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.

433 lines
11 KiB

  1. //============================================================================
  2. // Copyright (c) 1995, Microsoft Corporation
  3. //
  4. // File: config.c
  5. //
  6. // History:
  7. // t-abolag 7/22/95 Created.
  8. //
  9. // contains client configuration functions for tracing dll
  10. //============================================================================
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdlib.h>
  16. #include <rtutils.h>
  17. #include "trace.h"
  18. //----------------------------------------------------------------------------
  19. // Function: TraceEnableClient
  20. //
  21. // Parameters:
  22. // LPTRACE_CLIENT *lpclient
  23. // BOOL bFirstTime
  24. //
  25. // This function is called when a client first registers,
  26. // every time a client is re-enabled after having been disabled,
  27. // and every time a client's settings change.
  28. // it assumes the client specified has been locked for writing
  29. // and thus that the server is locked for writing
  30. //----------------------------------------------------------------------------
  31. DWORD
  32. TraceEnableClient(
  33. LPTRACE_SERVER lpserver,
  34. LPTRACE_CLIENT lpclient,
  35. BOOL bFirstTime
  36. ) {
  37. DWORD dwErr, dwOldFlags, dwCache;
  38. // enable by clearing disabled flag
  39. lpclient->TC_Flags &= ~TRACEFLAGS_DISABLED;
  40. dwCache = 0;
  41. dwOldFlags = lpclient->TC_Flags;
  42. //
  43. // if the client uses registry settings, load them
  44. //
  45. if (TRACE_CLIENT_USES_REGISTRY(lpclient)) {
  46. dwErr = TraceRegConfigClient(lpclient, bFirstTime);
  47. if (dwErr != 0) { return dwErr; }
  48. }
  49. //
  50. // if console tracing enabled and client had no console buffer
  51. // open a console buffer for the client
  52. //
  53. if (TRACE_CLIENT_USES_CONSOLE(lpclient)) {
  54. //
  55. // open the console only if it wasn't already open
  56. //
  57. if (bFirstTime || (dwOldFlags & TRACEFLAGS_USECONSOLE) == 0) {
  58. TraceOpenClientConsole(lpserver, lpclient);
  59. }
  60. dwCache |= (lpclient->TC_ConsoleMask | TRACEFLAGS_USECONSOLE);
  61. }
  62. else {
  63. //
  64. // console isn't enabled; if it WAS enabled,
  65. // close the old console
  66. //
  67. if (!bFirstTime && (dwOldFlags & TRACEFLAGS_USECONSOLE)) {
  68. //
  69. // used to use the console,
  70. // the buffer handle should be closed and active buffer
  71. // set to be someone else
  72. //
  73. TraceCloseClientConsole(lpserver, lpclient);
  74. }
  75. }
  76. //
  77. // if this client was using a file, close it even if
  78. // file tracing is still enabled for the client.
  79. // the path of the tracing file may have been changed
  80. //
  81. if (!bFirstTime && (dwOldFlags & TRACEFLAGS_USEFILE)) {
  82. TraceCloseClientFile(lpclient);
  83. }
  84. //
  85. // if file tracing enabled open the client's tracing file
  86. //
  87. if (TRACE_CLIENT_USES_FILE(lpclient)) {
  88. TraceCreateClientFile(lpclient);
  89. dwCache |= (lpclient->TC_FileMask | TRACEFLAGS_USEFILE);
  90. }
  91. InterlockedExchange(
  92. lpserver->TS_FlagsCache + lpclient->TC_ClientID, dwCache
  93. );
  94. return 0;
  95. }
  96. //----------------------------------------------------------------------------
  97. // Function: TraceDisableClient
  98. //
  99. // Parameters:
  100. // LPTRACE_CLIENT *lpclient
  101. //
  102. // This function is called when a client is disabled
  103. // it assumes the client specified has been locked for writing
  104. //----------------------------------------------------------------------------
  105. DWORD
  106. TraceDisableClient(
  107. LPTRACE_SERVER lpserver,
  108. LPTRACE_CLIENT lpclient
  109. ) {
  110. // disable by setting the disabled flag
  111. lpclient->TC_Flags |= TRACEFLAGS_DISABLED;
  112. InterlockedExchange(lpserver->TS_FlagsCache + lpclient->TC_ClientID, 0);
  113. return 0;
  114. }
  115. //----------------------------------------------------------------------------
  116. // Function: TraceRegConfigClient
  117. //
  118. // Parameters:
  119. // LPTRACE_CLIENT *lpclient
  120. // BOOL bFirstTime
  121. //
  122. // This function loads the client's tracing configuration
  123. // for the registry under
  124. // Software
  125. // \\Microsoft
  126. // \\Tracing
  127. // \\<client_name>
  128. // EnableFileTracing REG_DWORD
  129. // EnableConsoleTracing REG_DWORD
  130. // MaxFileSize REG_DWORD
  131. // FileDirectory REG_EXPAND_SZ
  132. //----------------------------------------------------------------------------
  133. DWORD
  134. TraceRegConfigClient(
  135. LPTRACE_CLIENT lpclient,
  136. BOOL bFirstTime
  137. ) {
  138. HKEY hkeyTracing;
  139. TCHAR szTracing[MAX_PATH];
  140. TCHAR szFileDir[MAX_PATH];
  141. DWORD dwErr, dwType, dwValue, dwSize;
  142. if (bFirstTime) {
  143. lstrcpy(szTracing, REGKEY_TRACING);
  144. lstrcat(szTracing, STR_DIRSEP);
  145. lstrcat(szTracing, lpclient->TC_ClientName);
  146. //
  147. // open the registry key for the client
  148. //
  149. dwErr = RegOpenKeyEx(
  150. HKEY_LOCAL_MACHINE, szTracing, 0, KEY_READ, &hkeyTracing
  151. );
  152. //
  153. // if that failed, try to create it
  154. //
  155. if (dwErr != ERROR_SUCCESS) {
  156. dwErr = TraceRegCreateDefaults(szTracing, &hkeyTracing);
  157. if (dwErr != ERROR_SUCCESS) {
  158. lpclient->TC_ConfigKey = NULL;
  159. return dwErr;
  160. }
  161. }
  162. lpclient->TC_ConfigKey = hkeyTracing;
  163. }
  164. else {
  165. hkeyTracing = lpclient->TC_ConfigKey;
  166. }
  167. //
  168. // read the file-tracing flag
  169. //
  170. dwSize = sizeof(DWORD);
  171. dwErr = RegQueryValueEx(
  172. hkeyTracing, REGVAL_ENABLEFILETRACING, NULL,
  173. &dwType, (LPBYTE)&dwValue, &dwSize
  174. );
  175. if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
  176. dwValue = DEF_ENABLEFILETRACING;
  177. }
  178. if (dwValue != 0) { lpclient->TC_Flags |= TRACEFLAGS_USEFILE; }
  179. else { lpclient->TC_Flags &= ~TRACEFLAGS_USEFILE; }
  180. //
  181. // read the file-tracing mask
  182. //
  183. dwSize = sizeof(DWORD);
  184. dwErr = RegQueryValueEx(
  185. hkeyTracing, REGVAL_FILETRACINGMASK, NULL,
  186. &dwType, (LPBYTE)&dwValue, &dwSize
  187. );
  188. if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
  189. dwValue = DEF_FILETRACINGMASK;
  190. }
  191. lpclient->TC_FileMask = (dwValue & 0xffff0000);
  192. //
  193. // read the console-tracing flag
  194. //
  195. dwSize = sizeof(DWORD);
  196. dwErr = RegQueryValueEx(
  197. hkeyTracing, REGVAL_ENABLECONSOLETRACING, NULL,
  198. &dwType, (LPBYTE)&dwValue, &dwSize
  199. );
  200. if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
  201. dwValue = DEF_ENABLECONSOLETRACING;
  202. }
  203. if (dwValue != 0) { lpclient->TC_Flags |= TRACEFLAGS_USECONSOLE; }
  204. else { lpclient->TC_Flags &= ~TRACEFLAGS_USECONSOLE; }
  205. //
  206. // read the console-tracing mask
  207. //
  208. dwSize = sizeof(DWORD);
  209. dwErr = RegQueryValueEx(
  210. hkeyTracing, REGVAL_CONSOLETRACINGMASK, NULL,
  211. &dwType, (LPBYTE)&dwValue, &dwSize
  212. );
  213. if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
  214. dwValue = DEF_CONSOLETRACINGMASK;
  215. }
  216. lpclient->TC_ConsoleMask = (dwValue & 0xffff0000);
  217. //
  218. // read the maximum file size
  219. //
  220. dwSize = sizeof(DWORD);
  221. dwErr = RegQueryValueEx(
  222. hkeyTracing, REGVAL_MAXFILESIZE, NULL,
  223. &dwType, (LPBYTE)&dwValue, &dwSize
  224. );
  225. if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
  226. dwValue = DEF_MAXFILESIZE;
  227. }
  228. lpclient->TC_MaxFileSize = dwValue;
  229. //
  230. // read the tracing file directory
  231. //
  232. dwSize = MAX_PATH * sizeof(TCHAR);
  233. dwErr = RegQueryValueEx(hkeyTracing, REGVAL_FILEDIRECTORY,
  234. NULL, &dwType, (LPBYTE)szFileDir, &dwSize);
  235. if (dwErr != ERROR_SUCCESS ||
  236. (dwType != REG_EXPAND_SZ && dwType != REG_SZ)) {
  237. lstrcpy(szFileDir, DEF_FILEDIRECTORY);
  238. }
  239. ExpandEnvironmentStrings(szFileDir, lpclient->TC_FileDir, MAX_PATH);
  240. #ifdef UNICODE
  241. wcstombs(
  242. lpclient->TC_FileDirA, lpclient->TC_FileDirW,
  243. lstrlenW(lpclient->TC_FileDirW) + 1
  244. );
  245. #else
  246. mbstowcs(
  247. lpclient->TC_FileDirW, lpclient->TC_FileDirA,
  248. lstrlenA(lpclient->TC_FileDirA) + 1
  249. );
  250. #endif
  251. //
  252. // request registry change notification
  253. //
  254. if (lpclient->TC_ConfigEvent == NULL) {
  255. lpclient->TC_ConfigEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  256. }
  257. dwErr = RegNotifyChangeKeyValue(
  258. lpclient->TC_ConfigKey, FALSE,
  259. REG_NOTIFY_CHANGE_ATTRIBUTES |
  260. REG_NOTIFY_CHANGE_LAST_SET |
  261. REG_NOTIFY_CHANGE_SECURITY,
  262. lpclient->TC_ConfigEvent, TRUE
  263. );
  264. return 0;
  265. }
  266. DWORD
  267. TraceRegCreateDefaults(
  268. LPCTSTR lpszTracing,
  269. PHKEY phkeyTracing
  270. ) {
  271. DWORD dwSize, dwValue;
  272. DWORD dwErr, dwDisposition;
  273. TCHAR szFileDir[MAX_PATH];
  274. //
  275. // create \\Microsoft\\Tracing
  276. //
  277. dwErr = RegCreateKeyEx(
  278. HKEY_LOCAL_MACHINE, REGKEY_TRACING, 0, NULL,
  279. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  280. phkeyTracing, &dwDisposition
  281. );
  282. RegCloseKey(*phkeyTracing);
  283. //
  284. // create \\Microsoft\\Tracing
  285. //
  286. dwErr = RegCreateKeyEx(
  287. HKEY_LOCAL_MACHINE, lpszTracing, 0, NULL,
  288. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  289. phkeyTracing, &dwDisposition
  290. );
  291. if (dwErr != ERROR_SUCCESS) { return dwErr; }
  292. dwSize = sizeof(DWORD);
  293. dwValue = DEF_ENABLEFILETRACING;
  294. dwErr = RegSetValueEx(
  295. *phkeyTracing, REGVAL_ENABLEFILETRACING, 0,
  296. REG_DWORD, (LPBYTE)&dwValue, dwSize
  297. );
  298. dwValue = DEF_ENABLECONSOLETRACING;
  299. dwErr = RegSetValueEx(
  300. *phkeyTracing, REGVAL_ENABLECONSOLETRACING, 0,
  301. REG_DWORD, (LPBYTE)&dwValue, dwSize
  302. );
  303. dwValue = DEF_FILETRACINGMASK;
  304. dwErr = RegSetValueEx(
  305. *phkeyTracing, REGVAL_FILETRACINGMASK, 0,
  306. REG_DWORD, (LPBYTE)&dwValue, dwSize
  307. );
  308. dwValue = DEF_CONSOLETRACINGMASK;
  309. dwErr = RegSetValueEx(
  310. *phkeyTracing, REGVAL_CONSOLETRACINGMASK, 0,
  311. REG_DWORD, (LPBYTE)&dwValue, dwSize
  312. );
  313. dwValue = DEF_MAXFILESIZE;
  314. dwErr = RegSetValueEx(
  315. *phkeyTracing, REGVAL_MAXFILESIZE, 0,
  316. REG_DWORD, (LPBYTE)&dwValue, dwSize
  317. );
  318. lstrcpy(szFileDir, DEF_FILEDIRECTORY);
  319. dwSize = lstrlen(szFileDir) * sizeof(TCHAR);
  320. dwErr = RegSetValueEx(
  321. *phkeyTracing, REGVAL_FILEDIRECTORY, 0,
  322. REG_EXPAND_SZ, (LPBYTE)&szFileDir, dwSize
  323. );
  324. return ERROR_SUCCESS;
  325. }
  326. //
  327. // assumes client is locked for reading
  328. //
  329. DWORD
  330. TraceUpdateConsoleTitle(
  331. LPTRACE_CLIENT lpclient
  332. ) {
  333. TCHAR szTitle[MAX_PATH];
  334. if (TRACE_CLIENT_IS_DISABLED(lpclient)) {
  335. wsprintf(szTitle, TEXT("%s [Tracing Inactive]"),
  336. lpclient->TC_ClientName);
  337. }
  338. else {
  339. wsprintf(szTitle, TEXT("%s [Tracing Active]"), lpclient->TC_ClientName);
  340. }
  341. SetConsoleTitle(szTitle);
  342. return 0;
  343. }