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.

501 lines
13 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. CEventLogger.cpp
  5. Abstract:
  6. This file contains implementation of the CEventLogger class which is
  7. used to log events across threads and processes.
  8. Revision History:
  9. Eugene Mesgar (eugenem) 6/16/99
  10. created
  11. Weiyou Cui (weiyouc) 31/Jan/2000
  12. Set time resolution to milliseconds
  13. ******************************************************************************/
  14. #include <windows.h>
  15. #include <tchar.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <dbgtrace.h>
  19. #include "CEventLogger.h"
  20. #ifdef THIS_FILE
  21. #undef THIS_FILE
  22. #endif
  23. static char __szTraceSourceFile[] = __FILE__;
  24. #define THIS_FILE __szTraceSourceFile
  25. #define TRACE_FILEID (LPARAM)this
  26. /*
  27. * Basic constructor
  28. */
  29. CEventLogger::CEventLogger()
  30. {
  31. TraceFunctEnter("CEventLogger");
  32. m_hSemaphore = NULL;
  33. // m_hLogFile = NULL;
  34. m_pszFileName = NULL;
  35. TraceFunctLeave();
  36. }
  37. /*
  38. * Destructor
  39. */
  40. CEventLogger::~CEventLogger()
  41. {
  42. TraceFunctEnter("~CEventLogger");
  43. if(m_pszFileName)
  44. {
  45. free(m_pszFileName);
  46. }
  47. if ( m_hSemaphore )
  48. {
  49. CloseHandle( m_hSemaphore );
  50. }
  51. // if( m_hLogFile )
  52. // {
  53. // CloseHandle( m_hLogFile );
  54. // }
  55. TraceFunctLeave();
  56. }
  57. /*
  58. * Init method
  59. */
  60. DWORD CEventLogger::Init(LPCTSTR szFileName, DWORD dwLogLevel)
  61. {
  62. TCHAR szBuf[MAX_BUFFER];
  63. TCHAR *pTemp;
  64. TraceFunctEnter("Init");
  65. //Set the logging level
  66. m_dwLoggingLevel = dwLogLevel;
  67. //Get our own copy of the file name
  68. m_pszFileName = _tcsdup( szFileName );
  69. if(!m_pszFileName)
  70. {
  71. _ASSERT(0);
  72. TraceFunctLeave();
  73. return(ERROR_INVALID_PARAMETER);
  74. }
  75. //brijeshk: open and close file everytime we want to log
  76. // if( (m_hLogFile = CreateFile(m_pszFileName,
  77. // GENERIC_READ | GENERIC_WRITE,
  78. // FILE_SHARE_READ | FILE_SHARE_WRITE,
  79. // NULL, // security attributes
  80. // OPEN_ALWAYS,
  81. // FILE_FLAG_RANDOM_ACCESS,
  82. // NULL) // template file
  83. // ) == INVALID_HANDLE_VALUE)
  84. // {
  85. // DWORD dwError;
  86. // dwError = GetLastError();
  87. // DebugTrace( TRACE_FILEID, "CreateFile Failed 0x%x", dwError);
  88. // TraceFunctLeave();
  89. // return(dwError);
  90. // }
  91. // fix the semaphore name problem -- all uppercase, remove backslashes
  92. _tcscpy( szBuf, m_pszFileName );
  93. CharUpper( szBuf );
  94. pTemp = szBuf;
  95. while( *pTemp != 0 )
  96. {
  97. if( *pTemp == _TEXT('\\') )
  98. {
  99. *pTemp = _TEXT(' ');
  100. }
  101. pTemp++;
  102. }
  103. // create the semaphore, it if dosn't already exist, we are the first
  104. // logger app created.. so we can prune the logfile if needed.
  105. if( (m_hSemaphore = CreateSemaphore(NULL, 0,1,szBuf)) == NULL )
  106. {
  107. DWORD dwError;
  108. dwError = GetLastError();
  109. // NOT 64-bits complaint!! DebugTrace( TRACE_FILEID,"CreateSemaphore Failed 0x%x",dwError);
  110. TraceFunctLeave();
  111. return(dwError);
  112. }
  113. // we now know we are the first process to open the file
  114. if( GetLastError() != ERROR_ALREADY_EXISTS )
  115. {
  116. /*
  117. * This is the place where we should "trim" the file.
  118. *
  119. */
  120. TruncateFileSize();
  121. ReleaseSemaphore( m_hSemaphore, 1, NULL );
  122. }
  123. TraceFunctLeave();
  124. return(ERROR_SUCCESS);
  125. }
  126. /*
  127. * Init Method
  128. */
  129. DWORD CEventLogger::Init(LPCTSTR szFileName)
  130. {
  131. return( Init(szFileName,LEVEL_NORMAL) );
  132. }
  133. DWORD WINAPI ShowDialogBox( LPVOID lpParameter) // thread data
  134. {
  135. MessageBox(NULL,
  136. (TCHAR *)lpParameter,
  137. _TEXT("Windows System File Protection"),
  138. MB_ICONEXCLAMATION | MB_OK );
  139. free( lpParameter );
  140. return ERROR_SUCCESS;
  141. }
  142. // we log in ascii
  143. DWORD CEventLogger::LogEvent(DWORD dwEventLevel, LPCTSTR pszEventDesc, BOOL fPopUp)
  144. {
  145. TCHAR szBuf[500];
  146. DWORD dwWritten;
  147. SYSTEMTIME SystemTime;
  148. DWORD dwError = ERROR_SUCCESS;
  149. HANDLE hLogFile = NULL;
  150. TraceFunctEnter("LogEvent");
  151. // brijeshk : open and close file everytime we log to it
  152. if( (hLogFile = CreateFile(m_pszFileName,
  153. GENERIC_READ | GENERIC_WRITE,
  154. FILE_SHARE_READ | FILE_SHARE_WRITE,
  155. NULL, // security attributes
  156. OPEN_ALWAYS,
  157. FILE_FLAG_RANDOM_ACCESS,
  158. NULL) // template file
  159. ) == INVALID_HANDLE_VALUE)
  160. {
  161. dwError = GetLastError();
  162. // NOT 64-bits complaint!! DebugTrace( TRACE_FILEID, "CreateFile Failed 0x%x", dwError);
  163. goto exit;
  164. }
  165. if (!m_hSemaphore)
  166. {
  167. _ASSERT(0);
  168. dwError = ERROR_INVALID_PARAMETER;
  169. goto exit;
  170. }
  171. if( dwEventLevel > m_dwLoggingLevel)
  172. {
  173. dwError = ERROR_SUCCESS;
  174. goto exit;
  175. }
  176. // Lets try to get ahold of the logfile
  177. if(WaitForSingleObject( m_hSemaphore, 900 ) == WAIT_TIMEOUT )
  178. {
  179. dwError = WAIT_TIMEOUT;
  180. goto exit;
  181. }
  182. __try {
  183. if( SetFilePointer(hLogFile, 0, 0, FILE_END ) == 0xFFFFFFFF )
  184. {
  185. // NOT 64-bits complaint!! DebugTrace(TRACE_FILEID,"SetFilePointer Failed 0x%x", GetLastError());
  186. dwError = GetLastError();
  187. goto exit;
  188. }
  189. GetLocalTime( &SystemTime );
  190. // LEVEL [wMonth/wDay/wYear wHour:wMinute] Message\n
  191. _stprintf(szBuf,_TEXT("%s [%02d/%02d/%d %02d:%02d:%02d:%03d] %s\r\n"),
  192. m_aszERROR_LEVELS[dwEventLevel],
  193. SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear,
  194. SystemTime.wHour, SystemTime.wMinute,
  195. SystemTime.wSecond, SystemTime.wMilliseconds,
  196. pszEventDesc);
  197. if(WriteFile(hLogFile,
  198. szBuf,
  199. _tcslen(szBuf) * sizeof(TCHAR),
  200. &dwWritten,
  201. NULL) == 0)
  202. {
  203. dwError = GetLastError();
  204. // NOT 64-bits complaint!! DebugTrace( TRACE_FILEID, "WriteFile Failed 0x%x", dwError);
  205. goto exit;
  206. }
  207. }
  208. __finally {
  209. ReleaseSemaphore( m_hSemaphore, 1, NULL );
  210. }
  211. // show a message
  212. if( fPopUp )
  213. {
  214. DWORD dwThreadId;
  215. HANDLE hThread;
  216. LPTSTR pszTempStr=NULL;
  217. if( (pszTempStr = _tcsdup( pszEventDesc )) == NULL)
  218. {
  219. dwError = GetLastError();
  220. // NOT 64-bits complaint!! ErrorTrace( TRACE_FILEID, "Error duplicating string for file popup ec: %d", dwError);
  221. dwError = ERROR_INTERNAL_ERROR;
  222. goto exit;
  223. }
  224. hThread = CreateThread( NULL, // pointer to security attributes
  225. 0, // default initial thread stack size
  226. (LPTHREAD_START_ROUTINE) ShowDialogBox,
  227. // pointer to thread function
  228. (LPVOID)pszTempStr, //argument for new thread
  229. 0, // creation flags
  230. &dwThreadId); // pointer to receive thread ID
  231. if (INVALID_HANDLE_VALUE != hThread)
  232. {
  233. CloseHandle(hThread);
  234. }
  235. }
  236. exit:
  237. // brijeshk : open and close log file each time we log to it
  238. if (NULL != hLogFile && INVALID_HANDLE_VALUE != hLogFile)
  239. {
  240. CloseHandle(hLogFile);
  241. }
  242. TraceFunctLeave();
  243. return dwError;
  244. }
  245. /*
  246. * If the file is bigger than 40k, cut off the begining to leave the last 20k
  247. * of the file
  248. * --> the file should be locked at this point <--
  249. */
  250. BOOL CEventLogger::TruncateFileSize()
  251. {
  252. DWORD dwSize = 0, dwNewSize = 0;
  253. DWORD dwRead = 0, dwWritten = 0;
  254. LPTSTR pcStr = NULL, pcEnd = NULL, pData = NULL;
  255. HANDLE hLogFile = NULL;
  256. BOOL fRc = TRUE;
  257. TraceFunctEnter("TruncateFileSize");
  258. // brijeshk : open the file as and when we need it
  259. if( (hLogFile = CreateFile(m_pszFileName,
  260. GENERIC_READ | GENERIC_WRITE,
  261. FILE_SHARE_READ | FILE_SHARE_WRITE,
  262. NULL, // security attributes
  263. OPEN_ALWAYS,
  264. FILE_FLAG_RANDOM_ACCESS,
  265. NULL) // template file
  266. ) == INVALID_HANDLE_VALUE)
  267. {
  268. DWORD dwError;
  269. dwError = GetLastError();
  270. // NOT 64-bits complaint!! DebugTrace( TRACE_FILEID, "CreateFile Failed 0x%x", dwError);
  271. fRc = FALSE;
  272. goto exit;
  273. }
  274. dwSize = GetFileSize( hLogFile, NULL );
  275. if( dwSize < TRIM_AT_SIZE )
  276. {
  277. goto exit;
  278. }
  279. // goto the last portion of the file we want to preserve
  280. if (FALSE == SetFilePointer(hLogFile, 0-NEW_FILE_SIZE, 0, FILE_END))
  281. {
  282. DWORD dwError;
  283. dwError = GetLastError();
  284. // NOT 64-bits complaint!! ErrorTrace(TRACE_FILEID, "SetFilePointer failed 0x%x", dwError);
  285. fRc = FALSE;
  286. goto exit;
  287. }
  288. // allocate memory to store this block
  289. pData = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, NEW_FILE_SIZE);
  290. if (NULL == pData)
  291. {
  292. // NOT 64-bits complaint!! ErrorTrace(TRACE_FILEID, "Out of memory");
  293. fRc = FALSE;
  294. goto exit;
  295. }
  296. // read this block into memory
  297. if (FALSE == ReadFile(hLogFile, pData, NEW_FILE_SIZE, &dwRead, NULL) ||
  298. dwRead != NEW_FILE_SIZE)
  299. {
  300. DWORD dwError;
  301. dwError = GetLastError();
  302. // NOT 64-bits complaint!! ErrorTrace(TRACE_FILEID, "ReadFile failed 0x%x", dwError);
  303. fRc = FALSE;
  304. goto exit;
  305. }
  306. // set the beginning and end of the block
  307. pcStr = pData;
  308. pcEnd = (LPTSTR) pData + NEW_FILE_SIZE - 1;
  309. // move forward until we find a newline and then go one more!
  310. while( (pcStr != pcEnd) && *(pcStr++) != _TEXT('\r') );
  311. // this is a weird file- 20k and no newlines
  312. if( pcStr == pcEnd )
  313. {
  314. // NOT 64-bits complaint!! ErrorTrace(TRACE_FILEID, "No newline found");
  315. fRc = FALSE;
  316. goto exit;
  317. }
  318. // skip the /n as well
  319. if (*pcStr == _TEXT('\n'))
  320. {
  321. pcStr++;
  322. }
  323. // close and open the file, purging everything in it
  324. if (FALSE == CloseHandle(hLogFile))
  325. {
  326. DWORD dwError;
  327. dwError = GetLastError();
  328. // NOT 64-bits complaint!! ErrorTrace( TRACE_FILEID, "CloseHandle failed 0x%x", dwError);
  329. fRc = FALSE;
  330. goto exit;
  331. }
  332. hLogFile = NULL;
  333. if( (hLogFile = CreateFile(m_pszFileName,
  334. GENERIC_READ | GENERIC_WRITE,
  335. FILE_SHARE_READ | FILE_SHARE_WRITE,
  336. NULL, // security attributes
  337. CREATE_ALWAYS, // lose everything inside
  338. FILE_FLAG_RANDOM_ACCESS,
  339. NULL) // template file
  340. ) == INVALID_HANDLE_VALUE)
  341. {
  342. DWORD dwError;
  343. dwError = GetLastError();
  344. // NOT 64-bits complaint!! ErrorTrace( TRACE_FILEID, "CreateFile Failed 0x%x", dwError);
  345. fRc = FALSE;
  346. goto exit;
  347. }
  348. // now write back this block
  349. // get the new size of the block
  350. dwNewSize = (DWORD)(pcEnd - pcStr + 1);
  351. if (FALSE == WriteFile(hLogFile, pcStr, dwNewSize, &dwWritten, NULL))
  352. {
  353. DWORD dwError;
  354. dwError = GetLastError();
  355. // NOT 64-bits complaint!! DebugTrace( TRACE_FILEID, "WriteFile failed 0x%x", dwError);
  356. fRc = FALSE;
  357. goto exit;
  358. }
  359. exit:
  360. if (pData)
  361. {
  362. HeapFree(GetProcessHeap(), 0, pData);
  363. }
  364. if (hLogFile != NULL && hLogFile != INVALID_HANDLE_VALUE)
  365. {
  366. CloseHandle(hLogFile);
  367. }
  368. TraceFunctLeave();
  369. return fRc;
  370. }
  371. /*
  372. * Error level indentifiers
  373. */
  374. LPCTSTR CEventLogger::m_aszERROR_LEVELS[] = {
  375. "None :",
  376. "CRITICAL:",
  377. "UNDEF :",
  378. "NORMAL :",
  379. "MINIMAL :",
  380. "DEBUG :"
  381. };