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.

340 lines
8.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: outfuncs.cxx
  7. //
  8. // Contents: functions for log/trace output
  9. //
  10. // Functions: AddOutputFunction
  11. // DelOutputFunction
  12. // CallOutputFunctions
  13. //
  14. // History: 09-Jan-96 murthys Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. #include <stdarg.h>
  22. #include <tchar.h>
  23. #if DBG==1
  24. #include "outfuncs.h"
  25. // *** Global Data ***
  26. static StringOutFunc debugscrfn = (StringOutFunc)OutputDebugStringA;
  27. StringOutFunc gpfunc[BUFFER_MAX_FUNCTIONS] = {
  28. (StringOutFunc)OutputDebugStringA,
  29. NULL
  30. };
  31. HANDLE ghLogFile = INVALID_HANDLE_VALUE;
  32. CRITICAL_SECTION g_LogFileCS;
  33. BOOL g_LogFileLockValid = FALSE;
  34. //+---------------------------------------------------------------------------
  35. //
  36. // Function: AddOutputFunction
  37. //
  38. // Synopsis:
  39. //
  40. // Arguments: [pfunc] --
  41. //
  42. // Returns:
  43. //
  44. // History: 09-Jan-96 murthys Created
  45. //
  46. // Notes:
  47. //
  48. //----------------------------------------------------------------------------
  49. void AddOutputFunction(StringOutFunc pfunc)
  50. {
  51. int i, at = -1;
  52. for (i = 0; i < BUFFER_MAX_FUNCTIONS; i++)
  53. {
  54. if ((at == -1) && (gpfunc[i] == NULL))
  55. {
  56. at = i; // Insert it here
  57. }
  58. else
  59. {
  60. if (gpfunc[i] == pfunc) // check for dups
  61. {
  62. return;
  63. }
  64. }
  65. }
  66. if (at != -1)
  67. {
  68. gpfunc[at] = pfunc;
  69. }
  70. }
  71. //+---------------------------------------------------------------------------
  72. //
  73. // Function: DelOutputFunction
  74. //
  75. // Synopsis:
  76. //
  77. // Arguments: [pfunc]
  78. //
  79. // Returns:
  80. //
  81. // History: 09-Jan-96 murthys Created
  82. //
  83. // Notes:
  84. //
  85. //----------------------------------------------------------------------------
  86. void DelOutputFunction(StringOutFunc pfunc)
  87. {
  88. int i;
  89. for (i = 0; i < BUFFER_MAX_FUNCTIONS; i++)
  90. {
  91. if (gpfunc[i] == pfunc)
  92. {
  93. gpfunc[i] = NULL;
  94. }
  95. }
  96. }
  97. //+---------------------------------------------------------------------------
  98. //
  99. // Function: CallOutputFunctions
  100. //
  101. // Synopsis:
  102. //
  103. // Arguments: (none)
  104. //
  105. // Returns:
  106. //
  107. // History: 09-Jan-96 murthys Created
  108. //
  109. // Notes:
  110. //
  111. //----------------------------------------------------------------------------
  112. void CallOutputFunctions(const char *buffer)
  113. {
  114. int i;
  115. for (i = 0; i < BUFFER_MAX_FUNCTIONS; i++)
  116. {
  117. if (gpfunc[i] != NULL)
  118. {
  119. gpfunc[i](buffer);
  120. }
  121. }
  122. }
  123. //+---------------------------------------------------------------------------
  124. //
  125. // Function: WriteToDebugScreen
  126. //
  127. // Synopsis:
  128. //
  129. // Arguments: [flag] - TRUE/FALSE to turn ON/OFF
  130. //
  131. // Returns:
  132. //
  133. // History: 09-Jan-96 murthys Created
  134. //
  135. // Notes:
  136. //
  137. //----------------------------------------------------------------------------
  138. void WriteToDebugScreen(BOOL flag)
  139. {
  140. if (flag)
  141. {
  142. AddOutputFunction(debugscrfn);
  143. }
  144. else
  145. {
  146. DelOutputFunction(debugscrfn);
  147. }
  148. }
  149. //+---------------------------------------------------------------------------
  150. //
  151. // Function: WriteToLogFile
  152. //
  153. // Synopsis:
  154. //
  155. // Arguments: [logfile] - path of file to write to
  156. //
  157. // Returns:
  158. //
  159. // History: 09-Jan-96 murthys Created
  160. //
  161. // Notes:
  162. //
  163. //----------------------------------------------------------------------------
  164. void WriteToLogFile(LPCTSTR lpfn)
  165. {
  166. if (!g_LogFileLockValid)
  167. return;
  168. EnterCriticalSection(&g_LogFileCS);
  169. if (ghLogFile != INVALID_HANDLE_VALUE)
  170. {
  171. CloseHandle(ghLogFile);
  172. DelOutputFunction(OutputLogFileA);
  173. ghLogFile = INVALID_HANDLE_VALUE;
  174. }
  175. if ((lpfn) && (lpfn[0] != _TEXT('\0')))
  176. {
  177. SECURITY_ATTRIBUTES sattr;
  178. sattr.nLength = sizeof(sattr);
  179. sattr.lpSecurityDescriptor = NULL;
  180. sattr.bInheritHandle = FALSE;
  181. #ifdef _CHICAGO_
  182. ghLogFile = CreateFileA(lpfn, GENERIC_READ|GENERIC_WRITE,
  183. FILE_SHARE_READ|FILE_SHARE_WRITE,
  184. &sattr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  185. #else
  186. ghLogFile = CreateFile(lpfn, GENERIC_READ|GENERIC_WRITE,
  187. FILE_SHARE_READ|FILE_SHARE_WRITE,
  188. &sattr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  189. #endif // _CHICAGO_
  190. if (ghLogFile == INVALID_HANDLE_VALUE)
  191. {
  192. OutputDebugStringA("OLE (WriteToLogFile):Unable to open log file!\n");
  193. }
  194. else
  195. {
  196. AddOutputFunction(OutputLogFileA);
  197. }
  198. }
  199. LeaveCriticalSection(&g_LogFileCS);
  200. }
  201. //+---------------------------------------------------------------------------
  202. //
  203. // Function: OutputLogFileA
  204. //
  205. // Synopsis:
  206. //
  207. // Arguments: [buf] - NULL terminated ANSI string to write
  208. //
  209. // Returns:
  210. //
  211. // History: 09-Jan-96 murthys Created
  212. //
  213. // Notes:
  214. //
  215. //----------------------------------------------------------------------------
  216. void OutputLogFileA(const char *buf)
  217. {
  218. DWORD dwtowrite = strlen(buf);
  219. DWORD dwwritten;
  220. LONG loffhigh = 0, lofflow;
  221. if (!g_LogFileLockValid)
  222. return;
  223. EnterCriticalSection(&g_LogFileCS);
  224. // Goto EOF, Lock, Write and Unlock
  225. lofflow = (LONG) SetFilePointer(ghLogFile, 0, &loffhigh, FILE_END);
  226. LockFile(ghLogFile, lofflow, loffhigh, dwtowrite, 0);
  227. WriteFile(ghLogFile, buf, dwtowrite, &dwwritten, NULL);
  228. UnlockFile(ghLogFile, lofflow, loffhigh, dwtowrite, 0);
  229. LeaveCriticalSection(&g_LogFileCS);
  230. }
  231. //+---------------------------------------------------------------------------
  232. //
  233. // Function: OpenDebugSinks()
  234. //
  235. // Synopsis:
  236. //
  237. // Arguments:
  238. //
  239. // Returns:
  240. //
  241. // History: 26-Jan-96 murthys Created
  242. //
  243. // Notes:
  244. //
  245. //----------------------------------------------------------------------------
  246. void OpenDebugSinks()
  247. {
  248. // Get LogFile name
  249. char tmpstr[MAX_PATH];
  250. DWORD cbtmpstr = sizeof(tmpstr);
  251. LPTSTR lptstr;
  252. NTSTATUS status = RtlInitializeCriticalSection(&g_LogFileCS);
  253. g_LogFileLockValid = NT_SUCCESS(status);
  254. if (!g_LogFileLockValid)
  255. return;
  256. GetProfileStringA("CairOLE InfoLevels", // section
  257. "LogFile", // key
  258. "", // default value
  259. tmpstr, // return buffer
  260. cbtmpstr);
  261. if (tmpstr[0] != '\0')
  262. {
  263. #ifdef _CHICAGO_
  264. lptstr = tmpstr;
  265. WriteToLogFile(lptstr);
  266. #else
  267. // convert ansi to unicode
  268. WCHAR wtmpstr[MAX_PATH];
  269. lptstr = wtmpstr;
  270. if (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, tmpstr, -1, wtmpstr, MAX_PATH))
  271. {
  272. WriteToLogFile(lptstr);
  273. }
  274. else
  275. {
  276. OutputDebugStringA("OLE32: MultiByteToWideChar failed for logfile!\n");
  277. }
  278. #endif
  279. }
  280. // See if Debug Screen should be turned off
  281. GetProfileStringA("CairOLE InfoLevels", // section
  282. "DebugScreen", // key
  283. "Yes", // default value
  284. tmpstr, // return buffer
  285. cbtmpstr);
  286. if ((tmpstr[0] == 'n') || (tmpstr[0] == 'N'))
  287. {
  288. WriteToDebugScreen(FALSE); // turn off output to debugger screen
  289. }
  290. }
  291. //+---------------------------------------------------------------------------
  292. //
  293. // Function: CloseDebugSinks()
  294. //
  295. // Synopsis:
  296. //
  297. // Arguments:
  298. //
  299. // Returns:
  300. //
  301. // History: 26-Jan-96 murthys Created
  302. //
  303. // Notes:
  304. //
  305. //----------------------------------------------------------------------------
  306. void CloseDebugSinks()
  307. {
  308. // close log file (if any)
  309. WriteToLogFile(NULL);
  310. if (g_LogFileLockValid)
  311. {
  312. DeleteCriticalSection(&g_LogFileCS);
  313. }
  314. }
  315. #endif // DBG == 1