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.

349 lines
9.0 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. //
  19. // Debug strings
  20. //
  21. const WCHAR cwszTitle[] = L"FDEPLOY (%x) ";
  22. const WCHAR cwszTime[] = L"%02d:%02d:%02d:%03d ";
  23. const WCHAR cwszLogfile[] = L"%SystemRoot%\\Debug\\UserMode\\fdeploy.log";
  24. const WCHAR cwszCRLF[] = L"\r\n";
  25. //
  26. // Registry debug information
  27. //
  28. #define DEBUG_REG_LOCATION L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Diagnostics"
  29. #define DEBUG_KEY_NAME L"FDeployDebugLevel"
  30. //*************************************************************
  31. //
  32. // InitDebugSupport()
  33. //
  34. // Sets the debugging level.
  35. // Also checks the registry for a debugging level.
  36. //
  37. //*************************************************************
  38. void InitDebugSupport()
  39. {
  40. HKEY hKey;
  41. DWORD Size;
  42. DWORD Type;
  43. BOOL bVerbose;
  44. DWORD Status;
  45. #if DBG
  46. gDebugLevel = DL_NORMAL;
  47. #else
  48. gDebugLevel = DL_NONE;
  49. #endif
  50. Status = RegOpenKeyEx(
  51. HKEY_LOCAL_MACHINE,
  52. DIAGNOSTICS_KEY,
  53. 0,
  54. KEY_READ,
  55. &hKey );
  56. bVerbose = FALSE;
  57. Size = sizeof(bVerbose);
  58. if ( ERROR_SUCCESS == Status )
  59. {
  60. Status = RegQueryValueEx(
  61. hKey,
  62. DIAGNOSTICS_POLICY_VALUE,
  63. NULL,
  64. &Type,
  65. (LPBYTE) &bVerbose,
  66. &Size );
  67. if ( (ERROR_SUCCESS == Status) && (Type != REG_DWORD) )
  68. bVerbose = FALSE;
  69. RegCloseKey(hKey);
  70. }
  71. Status = RegOpenKey(
  72. HKEY_LOCAL_MACHINE,
  73. DEBUG_REG_LOCATION,
  74. &hKey );
  75. if ( ERROR_SUCCESS == Status )
  76. {
  77. Size = sizeof(gDebugLevel);
  78. RegQueryValueEx(
  79. hKey,
  80. DEBUG_KEY_NAME,
  81. NULL,
  82. &Type,
  83. (LPBYTE)&gDebugLevel,
  84. &Size );
  85. RegCloseKey(hKey);
  86. }
  87. if ( bVerbose )
  88. gDebugLevel |= DL_VERBOSE | DL_EVENTLOG;
  89. }
  90. BOOL DebugLevelOn( DWORD mask )
  91. {
  92. BOOL bOutput = FALSE;
  93. if ( gDebugLevel & DL_VERBOSE )
  94. bOutput = TRUE;
  95. else if ( gDebugLevel & DL_NORMAL )
  96. bOutput = ! (mask & DM_VERBOSE);
  97. #if DBG
  98. else // DL_NONE
  99. bOutput = (mask & DM_ASSERT);
  100. #endif
  101. return bOutput;
  102. }
  103. //*************************************************************
  104. //
  105. // _DebugMsg()
  106. //
  107. // Displays debug messages based on the debug level
  108. // and type of debug message.
  109. //
  110. // Parameters :
  111. // mask - debug message type
  112. // MsgID - debug message id from resource file
  113. // ... - variable number of parameters
  114. //
  115. //*************************************************************
  116. void _DebugMsg(DWORD mask, DWORD MsgID, ...)
  117. {
  118. BOOL bEventLogOK;
  119. WCHAR wszDebugTitle[30];
  120. WCHAR wszDebugTime [30];
  121. WCHAR wszDebugBuffer[4*MAX_PATH];
  122. WCHAR wszMsg[MAX_PATH];
  123. va_list VAList;
  124. DWORD dwErrCode;
  125. SYSTEMTIME systime;
  126. bEventLogOK = ! (mask & DM_NO_EVENTLOG);
  127. if ( ! DebugLevelOn( mask ) )
  128. return;
  129. //
  130. // Save the last error code (so the debug output doesn't change it).
  131. //
  132. dwErrCode = GetLastError();
  133. va_start(VAList, MsgID);
  134. //
  135. // Event log message ids start at 101. For these we must call
  136. // FormatMessage. For other verbose debug output, we use
  137. // LoadString to get the string resource.
  138. //
  139. if ( MsgID < 100 )
  140. {
  141. if ( ! LoadString( ghDllInstance, MsgID, wszMsg, MAX_PATH) )
  142. {
  143. SetLastError(dwErrCode);
  144. return;
  145. }
  146. (void) StringCbVPrintf(wszDebugBuffer, sizeof(wszDebugBuffer), wszMsg, VAList);
  147. }
  148. else
  149. {
  150. DWORD CharsWritten;
  151. CharsWritten = FormatMessage(
  152. FORMAT_MESSAGE_FROM_HMODULE,
  153. ghDllInstance,
  154. MsgID,
  155. 0,
  156. wszDebugBuffer,
  157. sizeof(wszDebugBuffer) / sizeof(WCHAR) - 1,
  158. &VAList );
  159. if ( 0 == CharsWritten )
  160. {
  161. SetLastError(dwErrCode);
  162. return;
  163. }
  164. wszDebugBuffer[wcslen(wszDebugBuffer)] = L'\0';
  165. }
  166. va_end(VAList);
  167. GetLocalTime( &systime );
  168. (void) StringCbPrintf( wszDebugTitle, sizeof(wszDebugTitle), cwszTitle, GetCurrentProcessId() );
  169. (void) StringCbPrintf( wszDebugTime, sizeof(wszDebugTime), cwszTime, systime.wHour, systime.wMinute,
  170. systime.wSecond, systime.wMilliseconds);
  171. OutputDebugString( wszDebugTitle );
  172. OutputDebugString( wszDebugTime );
  173. OutputDebugString( wszDebugBuffer );
  174. OutputDebugString( cwszCRLF );
  175. if ( gDebugLevel & DL_LOGFILE )
  176. {
  177. HANDLE hFile;
  178. TCHAR cwszExpLogfile [MAX_PATH + 1];
  179. DWORD dwRet = ExpandEnvironmentStrings (cwszLogfile, cwszExpLogfile,
  180. MAX_PATH + 1);
  181. if (0 != dwRet && dwRet <= MAX_PATH)
  182. {
  183. hFile = OpenUnicodeLogFile(cwszExpLogfile);
  184. if ( hFile != INVALID_HANDLE_VALUE )
  185. {
  186. if ( SetFilePointer (hFile, 0, NULL, FILE_END) != 0xFFFFFFFF )
  187. {
  188. WCHAR * wszBuffer;
  189. DWORD Size;
  190. Size = lstrlen(wszDebugBuffer) + lstrlen (wszDebugTime) + 1;
  191. __try
  192. {
  193. wszBuffer = (WCHAR *) alloca (Size * sizeof (WCHAR));
  194. }
  195. __except(GetExceptionCode() == STATUS_STACK_OVERFLOW)
  196. {
  197. _resetstkoflw();
  198. wszBuffer = NULL;
  199. }
  200. if (wszBuffer)
  201. {
  202. (void) StringCchCopy(wszBuffer, Size, wszDebugTime);
  203. (void) StringCchCat(wszBuffer, Size, wszDebugBuffer);
  204. WriteFile(
  205. hFile,
  206. (LPCVOID) wszBuffer,
  207. lstrlen(wszBuffer) * sizeof(WCHAR),
  208. &Size,
  209. NULL );
  210. WriteFile(
  211. hFile,
  212. (LPCVOID) cwszCRLF,
  213. lstrlen(cwszCRLF) * sizeof(WCHAR),
  214. &Size,
  215. NULL );
  216. }
  217. }
  218. CloseHandle (hFile);
  219. }
  220. }
  221. }
  222. if ( bEventLogOK && gpEvents && (gDebugLevel & DL_EVENTLOG) )
  223. gpEvents->Report( EVENT_FDEPLOY_VERBOSE, 1, wszDebugBuffer );
  224. //
  225. // Restore the last error code
  226. //
  227. SetLastError(dwErrCode);
  228. #if DBG
  229. if ( mask & DM_ASSERT )
  230. DebugBreak();
  231. #endif
  232. }
  233. HANDLE OpenUnicodeLogFile (LPCTSTR lpszFilePath)
  234. {
  235. HANDLE hFile;
  236. DWORD Status;
  237. DWORD dwWritten;
  238. Status = ERROR_SUCCESS;
  239. hFile = CreateFile(
  240. lpszFilePath,
  241. FILE_WRITE_DATA | FILE_APPEND_DATA,
  242. FILE_SHARE_READ,
  243. NULL,
  244. OPEN_EXISTING,
  245. FILE_ATTRIBUTE_NORMAL,
  246. NULL);
  247. if ( INVALID_HANDLE_VALUE == hFile )
  248. {
  249. Status = GetLastError();
  250. }
  251. if ( ERROR_FILE_NOT_FOUND == Status )
  252. {
  253. //
  254. // The file doesn't exist, so we'll try to create it
  255. // with the byte order marker
  256. //
  257. hFile = CreateFile(
  258. lpszFilePath,
  259. FILE_WRITE_DATA | FILE_APPEND_DATA,
  260. FILE_SHARE_READ,
  261. NULL,
  262. OPEN_ALWAYS,
  263. FILE_ATTRIBUTE_NORMAL,
  264. NULL);
  265. if ( INVALID_HANDLE_VALUE != hFile )
  266. {
  267. BOOL bWritten;
  268. //
  269. // Add the unicode byte order marker to the beginning of the file
  270. // so that APIs know for sure that it is a unicode file.
  271. //
  272. bWritten = WriteFile(
  273. hFile,
  274. L"\xfeff\r\n",
  275. 4 * sizeof(WCHAR),
  276. &dwWritten,
  277. NULL);
  278. if ( ! bWritten )
  279. {
  280. CloseHandle( hFile );
  281. hFile = INVALID_HANDLE_VALUE;
  282. }
  283. }
  284. }
  285. return hFile;
  286. }