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.

394 lines
9.8 KiB

  1. //*************************************************************
  2. //
  3. // Debugging functions
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1995
  7. // All rights reserved
  8. //
  9. //*************************************************************
  10. #include "uenv.h"
  11. #include "rsopdbg.h"
  12. //
  13. // Global Variable containing the debugging level.
  14. //
  15. DWORD dwDebugLevel;
  16. DWORD dwRsopLoggingLevel = 1; // Rsop logging setting
  17. //
  18. // Debug strings
  19. //
  20. const TCHAR c_szUserEnv[] = TEXT("USERENV(%x.%x) %02d:%02d:%02d:%03d ");
  21. const TCHAR c_szCRLF[] = TEXT("\r\n");
  22. //
  23. // Registry debug information
  24. //
  25. #define DEBUG_REG_LOCATION TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\winlogon")
  26. #define DEBUG_KEY_NAME TEXT("UserEnvDebugLevel")
  27. #define RSOP_KEY_NAME TEXT("RsopLogging")
  28. //
  29. // Log files
  30. //
  31. TCHAR szLogFileName[] = L"%SystemRoot%\\Debug\\UserMode\\userenv.log"; // Current log
  32. TCHAR szBackupLogFileName[] = L"%SystemRoot%\\Debug\\UserMode\\userenv.bak"; // Backup/previous log
  33. CDebug dbgCommon;
  34. //*************************************************************
  35. //
  36. // InitDebugSupport()
  37. //
  38. // Purpose: Sets the debugging level.
  39. // Also checks the registry for a debugging level.
  40. //
  41. // Parameters: dwLoadFlags - If this is being loaded by winlogon
  42. // or setup.exe
  43. //
  44. // Return: void
  45. //
  46. // Comments:
  47. //
  48. //
  49. // History: Date Author Comment
  50. // 5/25/95 ericflo Created
  51. //
  52. //*************************************************************
  53. void InitDebugSupport( DWORD dwLoadFlags )
  54. {
  55. LONG lResult;
  56. HKEY hKey;
  57. DWORD dwType, dwSize, dwRet;
  58. TCHAR szExpLogDirectory[MAX_PATH+1];
  59. WIN32_FILE_ATTRIBUTE_DATA FileData;
  60. //
  61. // Initialize the debug level to normal for checked builds, and
  62. // none for retail builds. Enable warning output in retail builds.
  63. // Enable Enable logfile output in both retail and checked builds.
  64. //
  65. #if DBG
  66. dwDebugLevel = DL_NORMAL | DL_LOGFILE | DL_DEBUGGER;
  67. #else
  68. OSVERSIONINFOEX version;
  69. dwDebugLevel = DL_NORMAL | DL_LOGFILE;
  70. version.dwOSVersionInfoSize = sizeof(version);
  71. if ( GetVersionEx( (LPOSVERSIONINFO) &version ) )
  72. {
  73. if ( ( version.wSuiteMask & VER_SUITE_PERSONAL ) != 0 )
  74. {
  75. //
  76. // no logging on personal
  77. //
  78. dwDebugLevel = DL_NONE;
  79. }
  80. }
  81. #endif
  82. dwRsopLoggingLevel = 1;
  83. //
  84. // Check the registry
  85. //
  86. lResult = RegOpenKey (HKEY_LOCAL_MACHINE, DEBUG_REG_LOCATION,
  87. &hKey);
  88. if (lResult == ERROR_SUCCESS) {
  89. dwSize = sizeof(dwDebugLevel);
  90. RegQueryValueEx(hKey, DEBUG_KEY_NAME, NULL, &dwType,
  91. (LPBYTE)&dwDebugLevel, &dwSize);
  92. dwSize = sizeof(dwRsopLoggingLevel);
  93. RegQueryValueEx(hKey, RSOP_KEY_NAME, NULL, &dwType,
  94. (LPBYTE)&dwRsopLoggingLevel, &dwSize);
  95. RegCloseKey(hKey);
  96. }
  97. lResult = RegOpenKey (HKEY_LOCAL_MACHINE, SYSTEM_POLICIES_KEY,
  98. &hKey);
  99. if (lResult == ERROR_SUCCESS) {
  100. dwSize = sizeof(dwDebugLevel);
  101. RegQueryValueEx(hKey, DEBUG_KEY_NAME, NULL, &dwType,
  102. (LPBYTE)&dwDebugLevel, &dwSize);
  103. dwSize = sizeof(dwRsopLoggingLevel);
  104. RegQueryValueEx(hKey, RSOP_KEY_NAME, NULL, &dwType,
  105. (LPBYTE)&dwRsopLoggingLevel, &dwSize);
  106. RegCloseKey(hKey);
  107. }
  108. //
  109. // Initialize the common logging with userenv values
  110. //
  111. dbgCommon.Initialize( DEBUG_REG_LOCATION,
  112. DEBUG_KEY_NAME,
  113. L"userenv.log",
  114. L"userenv.bak",
  115. FALSE );
  116. dbgCommon.Initialize( SYSTEM_POLICIES_KEY,
  117. DEBUG_KEY_NAME,
  118. L"userenv.log",
  119. L"userenv.bak",
  120. FALSE );
  121. if ( dwLoadFlags == WINLOGON_LOAD ) {
  122. //
  123. // To avoid a huge log file, copy current log file to backup
  124. // file if the log file is over 300K
  125. //
  126. TCHAR szExpLogFileName[MAX_PATH+1];
  127. TCHAR szExpBackupLogFileName[MAX_PATH+1];
  128. dwRet = ExpandEnvironmentStrings ( szLogFileName, szExpLogFileName, MAX_PATH+1);
  129. if ( dwRet == 0 || dwRet > MAX_PATH)
  130. return;
  131. if (!GetFileAttributesEx(szExpLogFileName, GetFileExInfoStandard, &FileData)) {
  132. return;
  133. }
  134. if ( FileData.nFileSizeLow < (300 * 1024) ) {
  135. return;
  136. }
  137. dwRet = ExpandEnvironmentStrings ( szBackupLogFileName, szExpBackupLogFileName, MAX_PATH+1);
  138. if ( dwRet == 0 || dwRet > MAX_PATH)
  139. return;
  140. dwRet = MoveFileEx( szExpLogFileName, szExpBackupLogFileName, MOVEFILE_REPLACE_EXISTING);
  141. if ( dwRet == 0 ) {
  142. DebugMsg((DM_VERBOSE, TEXT("Moving log file to backup failed with 0x%x"), GetLastError()));
  143. return;
  144. }
  145. }
  146. }
  147. //*************************************************************
  148. //
  149. // DebugMsg()
  150. //
  151. // Purpose: Displays debug messages based on the debug level
  152. // and type of debug message.
  153. //
  154. // Parameters: mask - debug message type
  155. // pszMsg - debug message
  156. // ... - variable number of parameters
  157. //
  158. // Return: void
  159. //
  160. //
  161. // Comments:
  162. //
  163. //
  164. // History: Date Author Comment
  165. // 5/25/95 ericflo Created
  166. //
  167. //*************************************************************
  168. void _DebugMsg(UINT mask, LPCTSTR pszMsg, ...)
  169. {
  170. BOOL bOutput;
  171. TCHAR szDebugTitle[60];
  172. LPTSTR lpDebugBuffer;
  173. va_list marker;
  174. DWORD dwErrCode;
  175. SYSTEMTIME systime;
  176. BOOL bDebugOutput = FALSE;
  177. BOOL bLogfileOutput = FALSE;
  178. //
  179. // Save the last error code (so the debug output doesn't change it).
  180. //
  181. dwErrCode = GetLastError();
  182. //
  183. // Determine the correct amount of debug output
  184. //
  185. switch (LOWORD(dwDebugLevel)) {
  186. case DL_VERBOSE:
  187. bOutput = TRUE;
  188. break;
  189. case DL_NORMAL:
  190. //
  191. // Normal debug output. Don't
  192. // display verbose stuff, but
  193. // do display warnings/asserts.
  194. //
  195. if (mask != DM_VERBOSE) {
  196. bOutput = TRUE;
  197. } else {
  198. bOutput = FALSE;
  199. }
  200. break;
  201. case DL_NONE:
  202. default:
  203. //
  204. // Only display asserts
  205. //
  206. if (mask == DM_ASSERT) {
  207. bOutput = TRUE;
  208. } else {
  209. bOutput = FALSE;
  210. }
  211. break;
  212. }
  213. //
  214. // Display the error message if appropriate
  215. //
  216. bDebugOutput = dwDebugLevel & DL_DEBUGGER;
  217. bLogfileOutput = dwDebugLevel & DL_LOGFILE;
  218. if (bOutput) {
  219. INT iChars;
  220. lpDebugBuffer = (LPTSTR) LocalAlloc (LPTR, 2048 * sizeof(TCHAR));
  221. if (lpDebugBuffer) {
  222. GetLocalTime (&systime);
  223. wsprintf (szDebugTitle, c_szUserEnv,
  224. GetCurrentProcessId(), GetCurrentThreadId(),
  225. systime.wHour, systime.wMinute, systime.wSecond,
  226. systime.wMilliseconds);
  227. if ( bDebugOutput)
  228. OutputDebugString(szDebugTitle);
  229. va_start(marker, pszMsg);
  230. iChars = wvsprintf(lpDebugBuffer, pszMsg, marker);
  231. DmAssert( iChars < 2048 );
  232. if ( bDebugOutput) {
  233. OutputDebugString(lpDebugBuffer);
  234. OutputDebugString(c_szCRLF);
  235. }
  236. va_end(marker);
  237. if ( bLogfileOutput ) {
  238. HANDLE hFile;
  239. DWORD dwBytesWritten;
  240. TCHAR szExpLogFileName[MAX_PATH+1];
  241. DWORD dwRet = ExpandEnvironmentStrings ( szLogFileName, szExpLogFileName, MAX_PATH+1);
  242. if ( dwRet != 0 && dwRet <= MAX_PATH) {
  243. hFile = CreateFile( szExpLogFileName,
  244. FILE_WRITE_DATA | FILE_APPEND_DATA,
  245. FILE_SHARE_READ,
  246. NULL,
  247. OPEN_ALWAYS,
  248. FILE_ATTRIBUTE_NORMAL,
  249. NULL);
  250. if (hFile != INVALID_HANDLE_VALUE) {
  251. if (SetFilePointer (hFile, 0, NULL, FILE_END) != 0xFFFFFFFF) {
  252. WriteFile (hFile, (LPCVOID) szDebugTitle,
  253. lstrlen (szDebugTitle) * sizeof(TCHAR),
  254. &dwBytesWritten,
  255. NULL);
  256. WriteFile (hFile, (LPCVOID) lpDebugBuffer,
  257. lstrlen (lpDebugBuffer) * sizeof(TCHAR),
  258. &dwBytesWritten,
  259. NULL);
  260. WriteFile (hFile, (LPCVOID) c_szCRLF,
  261. lstrlen (c_szCRLF) * sizeof(TCHAR),
  262. &dwBytesWritten,
  263. NULL);
  264. }
  265. CloseHandle (hFile);
  266. }
  267. }
  268. }
  269. LocalFree (lpDebugBuffer);
  270. }
  271. }
  272. //
  273. // Restore the last error code
  274. //
  275. SetLastError(dwErrCode);
  276. //
  277. // Break to the debugger if appropriate
  278. //
  279. #if DBG
  280. if (mask == DM_ASSERT) {
  281. DebugBreak();
  282. }
  283. #endif
  284. }
  285. //*************************************************************
  286. //
  287. // RsopLoggingEnabled()
  288. //
  289. // Purpose: Checks if Rsop logging is enabled.
  290. //
  291. //*************************************************************
  292. extern "C"
  293. BOOL RsopLoggingEnabled()
  294. {
  295. return dwRsopLoggingLevel != 0;
  296. }