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.

292 lines
7.4 KiB

  1. //*************************************************************
  2. //
  3. // Debugging functions
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1995
  7. // All rights reserved
  8. //
  9. //*************************************************************
  10. #include "fdeploy.hxx"
  11. //
  12. // Global Variable containing the debugging level. The debug level can be
  13. // modified by both the debug init routine and the event logging init
  14. // routine. Debugging can be enabled even on retail systems through
  15. // registry settings.
  16. //
  17. DWORD gDebugLevel = DL_NONE;
  18. DWORD gDebugBreak = 0;
  19. //
  20. // Debug strings
  21. //
  22. const WCHAR cwszTitle[] = L"FDEPLOY (%x) ";
  23. const WCHAR cwszTime[] = L"%02d:%02d:%02d:%03d ";
  24. const WCHAR cwszLogfile[] = L"%SystemRoot%\\Debug\\UserMode\\fdeploy.log";
  25. const WCHAR cwszCRLF[] = L"\r\n";
  26. //
  27. // Registry debug information
  28. //
  29. #define DEBUG_REG_LOCATION L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Diagnostics"
  30. #define DEBUG_KEY_NAME L"FDeployDebugLevel"
  31. #define DEBUGBREAK_KEY_NAME L"FDeployDebugBreak"
  32. //*************************************************************
  33. //
  34. // InitDebugSupport()
  35. //
  36. // Sets the debugging level.
  37. // Also checks the registry for a debugging level.
  38. //
  39. //*************************************************************
  40. void InitDebugSupport()
  41. {
  42. HKEY hKey;
  43. DWORD Size;
  44. DWORD Type;
  45. BOOL bVerbose;
  46. DWORD Status;
  47. #if DBG
  48. gDebugLevel = DL_NORMAL;
  49. #else
  50. gDebugLevel = DL_NONE;
  51. #endif
  52. gDebugBreak = 0;
  53. Status = RegOpenKeyEx(
  54. HKEY_LOCAL_MACHINE,
  55. DIAGNOSTICS_KEY,
  56. 0,
  57. KEY_READ,
  58. &hKey );
  59. bVerbose = FALSE;
  60. Size = sizeof(bVerbose);
  61. if ( ERROR_SUCCESS == Status )
  62. {
  63. Status = RegQueryValueEx(
  64. hKey,
  65. DIAGNOSTICS_POLICY_VALUE,
  66. NULL,
  67. &Type,
  68. (LPBYTE) &bVerbose,
  69. &Size );
  70. if ( (ERROR_SUCCESS == Status) && (Type != REG_DWORD) )
  71. bVerbose = FALSE;
  72. RegCloseKey(hKey);
  73. }
  74. Status = RegOpenKey(
  75. HKEY_LOCAL_MACHINE,
  76. DEBUG_REG_LOCATION,
  77. &hKey );
  78. if ( ERROR_SUCCESS == Status )
  79. {
  80. Size = sizeof(gDebugLevel);
  81. RegQueryValueEx(
  82. hKey,
  83. DEBUG_KEY_NAME,
  84. NULL,
  85. &Type,
  86. (LPBYTE)&gDebugLevel,
  87. &Size );
  88. Size = sizeof(gDebugBreak);
  89. RegQueryValueEx(
  90. hKey,
  91. DEBUGBREAK_KEY_NAME,
  92. NULL,
  93. &Type,
  94. (LPBYTE)&gDebugBreak,
  95. &Size );
  96. RegCloseKey(hKey);
  97. }
  98. if ( bVerbose )
  99. gDebugLevel |= DL_VERBOSE | DL_EVENTLOG;
  100. }
  101. void ConditionalBreakIntoDebugger()
  102. {
  103. if (gDebugBreak)
  104. {
  105. DebugBreak();
  106. }
  107. }
  108. BOOL DebugLevelOn( DWORD mask )
  109. {
  110. BOOL bOutput = FALSE;
  111. if ( gDebugLevel & DL_VERBOSE )
  112. bOutput = TRUE;
  113. else if ( gDebugLevel & DL_NORMAL )
  114. bOutput = ! (mask & DM_VERBOSE);
  115. #if DBG
  116. else // DL_NONE
  117. bOutput = (mask & DM_ASSERT);
  118. #endif
  119. return bOutput;
  120. }
  121. //*************************************************************
  122. //
  123. // _DebugMsg()
  124. //
  125. // Displays debug messages based on the debug level
  126. // and type of debug message.
  127. //
  128. // Parameters :
  129. // mask - debug message type
  130. // MsgID - debug message id from resource file
  131. // ... - variable number of parameters
  132. //
  133. //*************************************************************
  134. void _DebugMsg(DWORD mask, DWORD MsgID, ...)
  135. {
  136. BOOL bEventLogOK;
  137. WCHAR wszDebugTitle[30];
  138. WCHAR wszDebugTime [30];
  139. WCHAR wszDebugBuffer[4*MAX_PATH];
  140. WCHAR wszMsg[MAX_PATH];
  141. va_list VAList;
  142. DWORD dwErrCode;
  143. SYSTEMTIME systime;
  144. bEventLogOK = ! (mask & DM_NO_EVENTLOG);
  145. if ( ! DebugLevelOn( mask ) )
  146. return;
  147. //
  148. // Save the last error code (so the debug output doesn't change it).
  149. //
  150. dwErrCode = GetLastError();
  151. va_start(VAList, MsgID);
  152. //
  153. // Event log message ids start at 101. For these we must call
  154. // FormatMessage. For other verbose debug output, we use
  155. // LoadString to get the string resource.
  156. //
  157. if ( MsgID < 100 )
  158. {
  159. if ( ! LoadString( ghDllInstance, MsgID, wszMsg, MAX_PATH) )
  160. {
  161. SetLastError(dwErrCode);
  162. return;
  163. }
  164. wvsprintf(wszDebugBuffer, wszMsg, VAList);
  165. }
  166. else
  167. {
  168. DWORD CharsWritten;
  169. CharsWritten = FormatMessage(
  170. FORMAT_MESSAGE_FROM_HMODULE,
  171. ghDllInstance,
  172. MsgID,
  173. 0,
  174. wszDebugBuffer,
  175. sizeof(wszDebugBuffer) / sizeof(WCHAR),
  176. &VAList );
  177. if ( 0 == CharsWritten )
  178. {
  179. SetLastError(dwErrCode);
  180. return;
  181. }
  182. }
  183. va_end(VAList);
  184. GetLocalTime( &systime );
  185. wsprintf( wszDebugTitle, cwszTitle, GetCurrentProcessId() );
  186. wsprintf( wszDebugTime, cwszTime, systime.wHour, systime.wMinute,
  187. systime.wSecond, systime.wMilliseconds);
  188. OutputDebugString( wszDebugTitle );
  189. OutputDebugString( wszDebugTime );
  190. OutputDebugString( wszDebugBuffer );
  191. OutputDebugString( cwszCRLF );
  192. if ( gDebugLevel & DL_LOGFILE )
  193. {
  194. HANDLE hFile;
  195. TCHAR cwszExpLogfile [MAX_PATH + 1];
  196. DWORD dwRet = ExpandEnvironmentStrings (cwszLogfile, cwszExpLogfile,
  197. MAX_PATH + 1);
  198. if (0 != dwRet && dwRet <= MAX_PATH)
  199. {
  200. hFile = CreateFile(cwszExpLogfile,
  201. FILE_WRITE_DATA | FILE_APPEND_DATA,
  202. FILE_SHARE_READ,
  203. NULL,
  204. OPEN_ALWAYS,
  205. FILE_ATTRIBUTE_NORMAL,
  206. NULL);
  207. if ( hFile != INVALID_HANDLE_VALUE )
  208. {
  209. if ( SetFilePointer (hFile, 0, NULL, FILE_END) != 0xFFFFFFFF )
  210. {
  211. WCHAR * wszBuffer;
  212. DWORD Size;
  213. Size = lstrlen(wszDebugBuffer) + lstrlen (wszDebugTime) + 1;
  214. wszBuffer = (WCHAR *) alloca (Size * sizeof (WCHAR));
  215. if (wszBuffer)
  216. {
  217. wcscpy (wszBuffer, wszDebugTime);
  218. wcscat (wszBuffer, wszDebugBuffer);
  219. WriteFile(
  220. hFile,
  221. (LPCVOID) wszBuffer,
  222. lstrlen(wszBuffer) * sizeof(WCHAR),
  223. &Size,
  224. NULL );
  225. WriteFile(
  226. hFile,
  227. (LPCVOID) cwszCRLF,
  228. lstrlen(cwszCRLF) * sizeof(WCHAR),
  229. &Size,
  230. NULL );
  231. }
  232. }
  233. CloseHandle (hFile);
  234. }
  235. }
  236. }
  237. if ( bEventLogOK && gpEvents && (gDebugLevel & DL_EVENTLOG) )
  238. gpEvents->Report( EVENT_FDEPLOY_VERBOSE, 1, wszDebugBuffer );
  239. //
  240. // Restore the last error code
  241. //
  242. SetLastError(dwErrCode);
  243. #if DBG
  244. if ( mask & DM_ASSERT )
  245. DebugBreak();
  246. #endif
  247. }