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.

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