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.

421 lines
12 KiB

  1. #ifdef DEBUG
  2. #include "rbdebug.h"
  3. #include <objbase.h>
  4. #include <strsafe.h>
  5. BOOL CRBDebug::_fInited = FALSE;
  6. DWORD CRBDebug::_dwFlags = 0;
  7. DWORD CRBDebug::_dwTraceFlags = 0;
  8. TCHAR CRBDebug::_szTraceFile[] = TEXT("");
  9. TCHAR CRBDebug::_szModuleName[] = TEXT("");
  10. HANDLE CRBDebug::_hfileTraceFile = INVALID_HANDLE_VALUE;
  11. TCHAR CRBDebug::_szTracePipe[] = TEXT("");
  12. TCHAR CRBDebug::_szFileAndLine[] = TEXT("");
  13. CRITICAL_SECTION CRBDebug::_cs = {0};
  14. #define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
  15. HRESULT CRBDebug::_InitFile(HKEY hkeyRoot)
  16. {
  17. HRESULT hres = E_FAIL;
  18. HKEY hkeyFile;
  19. if (ERROR_SUCCESS == RegOpenKeyEx(hkeyRoot, TEXT("File"), 0,
  20. MAXIMUM_ALLOWED, &hkeyFile))
  21. {
  22. DWORD dwSize = sizeof(_szTraceFile);
  23. if (ERROR_SUCCESS == RegQueryValueEx(hkeyFile, TEXT("FileName"),
  24. 0, NULL, (PBYTE)_szTraceFile, &dwSize))
  25. {
  26. _hfileTraceFile = CreateFile(_szTraceFile,
  27. GENERIC_WRITE, FILE_SHARE_READ, NULL,
  28. OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  29. if (INVALID_HANDLE_VALUE != _hfileTraceFile)
  30. {
  31. SetFilePointer(_hfileTraceFile, 0, 0,
  32. FILE_END);
  33. hres = S_OK;
  34. }
  35. }
  36. RegCloseKey(hkeyFile);
  37. }
  38. return hres;
  39. }
  40. HRESULT CRBDebug::_InitPipe(HKEY hkeyRoot)
  41. {
  42. HRESULT hres = S_OK;
  43. HKEY hkeyFile;
  44. TCHAR szMachineName[MAX_PATH];
  45. TCHAR szPipeName[MAX_PATH];
  46. if (ERROR_SUCCESS == RegOpenKeyEx(hkeyRoot, TEXT("Pipe"), 0,
  47. MAXIMUM_ALLOWED, &hkeyFile))
  48. {
  49. DWORD dwSize = sizeof(szMachineName);
  50. if (ERROR_SUCCESS != RegQueryValueEx(hkeyFile, TEXT("MachineName"),
  51. 0, NULL, (PBYTE)szMachineName, &dwSize))
  52. {
  53. hres = StringCchCopy(szMachineName, ARRAYSIZE(szMachineName),
  54. TEXT("."));
  55. }
  56. if (SUCCEEDED(hres))
  57. {
  58. dwSize = sizeof(szPipeName);
  59. if (ERROR_SUCCESS != RegQueryValueEx(hkeyFile, TEXT("PipeName"),
  60. 0, NULL, (PBYTE)szPipeName, &dwSize))
  61. {
  62. hres = StringCchCopy(szPipeName, ARRAYSIZE(szPipeName),
  63. _szModuleName);
  64. }
  65. }
  66. RegCloseKey(hkeyFile);
  67. }
  68. else
  69. {
  70. // Defaults
  71. hres = StringCchCopy(szMachineName, ARRAYSIZE(szMachineName),
  72. TEXT("."));
  73. if (SUCCEEDED(hres))
  74. {
  75. hres = StringCchCopy(szPipeName, ARRAYSIZE(szPipeName),
  76. _szModuleName);
  77. }
  78. }
  79. if (SUCCEEDED(hres))
  80. {
  81. hres = StringCchPrintf(_szTracePipe, ARRAYSIZE(_szTracePipe),
  82. TEXT("\\\\%s\\pipe\\%s"), szMachineName, szPipeName);
  83. }
  84. return hres;
  85. }
  86. // static
  87. HRESULT CRBDebug::_Init()
  88. {
  89. HRESULT hres = S_FALSE;
  90. if (!_fInited)
  91. {
  92. // Read the flags
  93. WCHAR szKey[MAX_PATH];
  94. WCHAR szModule[MAX_PATH];
  95. BOOL fKeyExist = FALSE;
  96. hres = E_FAIL;
  97. if (InitializeCriticalSectionAndSpinCount(&_cs, 0))
  98. {
  99. hres = StringCchCopy(szKey, ARRAYSIZE(szKey), L"Software\\Microsoft\\Debug\\");
  100. if (SUCCEEDED(hres))
  101. {
  102. hres = E_FAIL;
  103. if (GetModuleFileName(GetModuleHandle(NULL), szModule,
  104. ARRAYSIZE(szModule)))
  105. {
  106. HKEY hkey;
  107. LONG lSuccess;
  108. int c = lstrlen(szModule);
  109. while (c && (L'\\' != szModule[c]))
  110. {
  111. --c;
  112. }
  113. hres = StringCchCopy(_szModuleName, ARRAYSIZE(_szModuleName),
  114. szModule + c + 1);
  115. if (SUCCEEDED(hres))
  116. {
  117. hres = StringCchCat(szKey, ARRAYSIZE(szKey), _szModuleName);
  118. }
  119. if (SUCCEEDED(hres))
  120. {
  121. hres = E_FAIL;
  122. lSuccess = RegOpenKeyEx(HKEY_CURRENT_USER, szKey, 0,
  123. MAXIMUM_ALLOWED, &hkey);
  124. if (ERROR_SUCCESS != lSuccess)
  125. {
  126. lSuccess = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0,
  127. MAXIMUM_ALLOWED, &hkey);
  128. }
  129. if (ERROR_SUCCESS == lSuccess)
  130. {
  131. DWORD dwSize = sizeof(DWORD);
  132. fKeyExist = TRUE;
  133. if (ERROR_SUCCESS == RegQueryValueEx(hkey, L"RBD_FLAGS", 0,
  134. NULL, (PBYTE)&_dwFlags, &dwSize))
  135. {
  136. if (_dwFlags & RBD_TRACE_OUTPUTDEBUG)
  137. {
  138. hres = S_OK;
  139. }
  140. if ((_dwFlags & RBD_TRACE_TOFILE) ||
  141. (_dwFlags & RBD_TRACE_TOFILEANSI))
  142. {
  143. hres = _InitFile(hkey);
  144. if (FAILED(hres))
  145. {
  146. _dwFlags &= ~RBD_TRACE_TOFILE;
  147. }
  148. }
  149. if (_dwFlags & RBD_TRACE_TOPIPE)
  150. {
  151. hres = _InitPipe(hkey);
  152. if (FAILED(hres))
  153. {
  154. _dwFlags &= ~RBD_TRACE_TOPIPE;
  155. }
  156. }
  157. }
  158. else
  159. {
  160. _dwFlags = RBD_TRACE_OUTPUTDEBUG | RBD_ASSERT_STOP;
  161. hres = S_FALSE;
  162. }
  163. if (ERROR_SUCCESS != RegQueryValueEx(hkey, L"TRACE_FLAGS", 0,
  164. NULL, (PBYTE)&_dwTraceFlags, &dwSize))
  165. {
  166. // Default...
  167. _dwTraceFlags = 0;
  168. }
  169. RegCloseKey(hkey);
  170. }
  171. }
  172. }
  173. if (!fKeyExist)
  174. {
  175. // If we can't find a key for this app then we revert to default
  176. // behavior
  177. _dwFlags = RBD_TRACE_OUTPUTDEBUG | RBD_ASSERT_STOP;
  178. hres = S_FALSE;
  179. }
  180. }
  181. }
  182. if (SUCCEEDED(hres))
  183. {
  184. _fInited = TRUE;
  185. }
  186. }
  187. return hres;
  188. }
  189. // static
  190. void __cdecl CRBDebug::TraceMsg(DWORD dwFlags, LPTSTR pszMsg, ...)
  191. {
  192. HRESULT hres = S_OK;
  193. if (!_fInited)
  194. {
  195. hres = _Init();
  196. }
  197. if (SUCCEEDED(hres))
  198. {
  199. if ((_dwTraceFlags & dwFlags) &&
  200. (TF_NOFILEANDLINE != (_dwTraceFlags & dwFlags)))
  201. {
  202. if (!((_dwTraceFlags & TF_NOFILEANDLINE) ||
  203. (dwFlags & TF_NOFILEANDLINE)))
  204. {
  205. // File and line
  206. _Trace(_szFileAndLine);
  207. }
  208. {
  209. TCHAR szBuf[4096];
  210. va_list vArgs;
  211. LPTSTR pszNext;
  212. size_t cchLeft;
  213. va_start(vArgs, pszMsg);
  214. hres = StringCchVPrintfEx(szBuf, ARRAYSIZE(szBuf),
  215. &pszNext, &cchLeft, 0, pszMsg, vArgs);
  216. va_end(vArgs);
  217. if (SUCCEEDED(hres))
  218. {
  219. hres = StringCchCopy(pszNext, cchLeft, TEXT("\r\n"));
  220. }
  221. _Trace(szBuf);
  222. }
  223. }
  224. }
  225. if (_cs.DebugInfo)
  226. {
  227. LeaveCriticalSection(&_cs);
  228. }
  229. }
  230. // static
  231. void CRBDebug::SetTraceFileAndLine(LPCSTR pszFile, const int iLine)
  232. {
  233. HRESULT hres = S_OK;
  234. if (!_fInited)
  235. {
  236. hres = _Init();
  237. }
  238. if (_cs.DebugInfo)
  239. {
  240. EnterCriticalSection(&_cs);
  241. }
  242. if (SUCCEEDED(hres))
  243. {
  244. LPTSTR pszFinal;
  245. WCHAR szwBuf[MAX_PATH + 12 + 17];
  246. CHAR szBuf[MAX_PATH + 12 + 17];
  247. int c = lstrlenA(pszFile);
  248. LPCSTR pszFileName;
  249. DWORD dwTimeOffset = 0;
  250. while (c && ('\\' != *(pszFile + c)))
  251. {
  252. --c;
  253. }
  254. pszFileName = pszFile + c + 1;
  255. if (_dwTraceFlags & TF_TIME)
  256. {
  257. DWORD dwTick = GetTickCount();
  258. DWORD dwMilliSec = dwTick % 1000;
  259. dwTick -= dwMilliSec;
  260. dwTick /= 1000;
  261. DWORD dwSec = dwTick % 60;
  262. dwTick -= dwSec;
  263. dwTick /= 60;
  264. DWORD dwMin = dwTick % 60;
  265. dwTick -= dwMin;
  266. dwTick /= 60;
  267. DWORD dwHour = dwTick;
  268. hres = StringCchPrintfA(szBuf, ARRAYSIZE(szBuf),
  269. "{%04d:%02d:%02d.%03d}", dwHour, dwMin, dwSec, dwMilliSec);
  270. dwTimeOffset = 16;
  271. }
  272. if (SUCCEEDED(hres))
  273. {
  274. if (_dwTraceFlags & TF_THREADID)
  275. {
  276. hres = StringCchPrintfA(szBuf + dwTimeOffset,
  277. ARRAYSIZE(szBuf) - dwTimeOffset, "~0x%08X~[%s, %d]",
  278. GetCurrentThreadId(), pszFileName, iLine);
  279. }
  280. else
  281. {
  282. hres = StringCchPrintfA(szBuf + dwTimeOffset,
  283. ARRAYSIZE(szBuf) - dwTimeOffset, "[%s, %d] ", pszFileName,
  284. iLine);
  285. }
  286. if (SUCCEEDED(hres))
  287. {
  288. #ifdef UNICODE
  289. pszFinal = szwBuf;
  290. MultiByteToWideChar(CP_ACP, 0, szBuf, lstrlenA(szBuf) + 1, szwBuf,
  291. sizeof(szwBuf) / sizeof(WCHAR));
  292. #else
  293. pszFinal = szBuf;
  294. #endif
  295. hres = StringCchCopy(_szFileAndLine, ARRAYSIZE(_szFileAndLine),
  296. pszFinal);
  297. }
  298. }
  299. }
  300. }
  301. void CRBDebug::_Trace(LPTSTR pszMsg)
  302. {
  303. if (RBD_TRACE_OUTPUTDEBUG & _dwFlags)
  304. {
  305. OutputDebugString(pszMsg);
  306. }
  307. #ifdef UNICODE
  308. if (RBD_TRACE_TOFILE & _dwFlags)
  309. #else
  310. if ((RBD_TRACE_TOFILE & _dwFlags) || (RBD_TRACE_TOFILEANSI & _dwFlags))
  311. #endif
  312. {
  313. DWORD dwWritten = 0;
  314. WriteFile(_hfileTraceFile, pszMsg, lstrlen(pszMsg) * sizeof(TCHAR),
  315. &dwWritten, NULL);
  316. }
  317. else
  318. {
  319. #ifdef UNICODE
  320. if (RBD_TRACE_TOFILEANSI & _dwFlags)
  321. {
  322. CHAR szBuf[4096];
  323. DWORD dwWritten = 0;
  324. WideCharToMultiByte(CP_ACP, 0, pszMsg,
  325. (lstrlen(pszMsg) + 1), szBuf, sizeof(szBuf), NULL,
  326. NULL);
  327. WriteFile(_hfileTraceFile, szBuf, lstrlenA(szBuf), &dwWritten,
  328. NULL);
  329. }
  330. #endif
  331. }
  332. if (RBD_TRACE_TOPIPE & _dwFlags)
  333. {
  334. CallNamedPipe(_szTracePipe, pszMsg, lstrlen(pszMsg) * sizeof(TCHAR),
  335. NULL, 0, NULL, NMPWAIT_NOWAIT);
  336. }
  337. }
  338. // static
  339. HRESULT CRBDebug::Init()
  340. {
  341. return CRBDebug::_Init();
  342. }
  343. #endif