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.

373 lines
12 KiB

  1. #include "stdafx.h"
  2. #include "resource.h"
  3. #include "log.h"
  4. #include "acl.hxx"
  5. // critical section needed to safely write to the logfile
  6. CRITICAL_SECTION critical_section;
  7. //***************************************************************************
  8. //*
  9. //* purpose: constructor
  10. //*
  11. //***************************************************************************
  12. MyLogFile::MyLogFile(void)
  13. {
  14. _tcscpy(m_szLogFileName, _T(""));
  15. _tcscpy(m_szLogFileName_Full, _T(""));
  16. _tcscpy(m_szLogPreLineInfo, _T(""));
  17. _tcscpy(m_szLogPreLineInfo2, _T(""));
  18. m_bDisplayTimeStamp = TRUE;
  19. m_bDisplayPreLineInfo = TRUE;
  20. m_bFlushLogToDisk = FALSE;
  21. m_hFile = NULL;
  22. // initialize the critical section
  23. INITIALIZE_CRITICAL_SECTION( &critical_section );
  24. }
  25. //***************************************************************************
  26. //*
  27. //* purpose: destructor
  28. //*
  29. //***************************************************************************
  30. MyLogFile::~MyLogFile(void)
  31. {
  32. DeleteCriticalSection( &critical_section );
  33. }
  34. //***************************************************************************
  35. //*
  36. //* purpose:
  37. //*
  38. //***************************************************************************
  39. int MyLogFile::LogFileCreate(TCHAR *lpLogFileName )
  40. {
  41. int iReturn = FALSE;
  42. TSTR strDriveOnly( _MAX_DRIVE );
  43. TSTR strPathOnly( MAX_PATH );
  44. TSTR strFileNameOnly( MAX_PATH );
  45. TSTR strFileNameBackup( MAX_PATH );
  46. LPWSTR pwsz = NULL;
  47. CSecurityDescriptor LogFileSD;
  48. // because of the global flags and such, we'll make this critical
  49. EnterCriticalSection( &critical_section );
  50. if (lpLogFileName == NULL)
  51. {
  52. TSTR strModuleFileName;
  53. if ( !strFileNameOnly.Resize( MAX_PATH ) )
  54. {
  55. return FALSE;
  56. }
  57. // if a logfilename was not specified then use the module name.
  58. if (0 == GetModuleFileName(NULL, strModuleFileName.QueryStr(), _MAX_PATH))
  59. {
  60. // Use Default Name
  61. if ( !strFileNameOnly.Copy( _T("iis6.log") ) )
  62. {
  63. return FALSE;
  64. }
  65. }
  66. else
  67. {
  68. // get only the filename
  69. _tsplitpath( strModuleFileName.QueryStr() , NULL, NULL, strFileNameOnly.QueryStr(), NULL);
  70. if ( !strFileNameOnly.Append( _T(".LOG") ) )
  71. {
  72. return FALSE;
  73. }
  74. }
  75. _tcsncpy( m_szLogFileName,
  76. strFileNameOnly.QueryStr(),
  77. sizeof(m_szLogFileName)/sizeof(m_szLogFileName[0]) );
  78. m_szLogFileName[ ( sizeof(m_szLogFileName) / sizeof(m_szLogFileName[0]) ) - 1 ] = _T('\0');
  79. }
  80. else
  81. {
  82. _tcsncpy( m_szLogFileName,
  83. lpLogFileName,
  84. sizeof(m_szLogFileName)/sizeof(m_szLogFileName[0]) );
  85. m_szLogFileName[ ( sizeof(m_szLogFileName) / sizeof(m_szLogFileName[0]) ) - 1 ] = _T('\0');
  86. }
  87. if (GetWindowsDirectory(m_szLogFileName_Full, sizeof(m_szLogFileName_Full)/sizeof(m_szLogFileName_Full[0])))
  88. {
  89. AddPath(m_szLogFileName_Full, m_szLogFileName);
  90. if (GetFileAttributes(m_szLogFileName_Full) != 0xFFFFFFFF)
  91. {
  92. // there is a current .log file already there.
  93. // if it is larger than 2megs then rename it.
  94. DWORD dwSize1 = ReturnFileSize(m_szLogFileName_Full);
  95. if (dwSize1 == 0xFFFFFFFF || dwSize1 > 2000000)
  96. {
  97. // unable to retrieve the size of one of those files
  98. // or the size is bigger than 2megs.
  99. // backup the old one.
  100. // Make a backup of the current log file
  101. _tsplitpath( m_szLogFileName_Full,
  102. strDriveOnly.QueryStr(),
  103. strPathOnly.QueryStr(),
  104. strFileNameOnly.QueryStr(),
  105. NULL);
  106. if ( !strFileNameBackup.Copy( strDriveOnly ) &&
  107. !strFileNameBackup.Append( strPathOnly ) &&
  108. !strFileNameBackup.Append( strFileNameOnly ) &&
  109. !strFileNameBackup.Append( _T(".bak") ) )
  110. {
  111. return FALSE;
  112. }
  113. SetFileAttributes(strFileNameBackup.QueryStr(), FILE_ATTRIBUTE_NORMAL);
  114. DeleteFile( strFileNameBackup.QueryStr() );
  115. if ( MoveFile(m_szLogFileName_Full, strFileNameBackup.QueryStr()) == 0 )
  116. {
  117. // This failed
  118. //MyMessageBox(NULL,_T("LogFile MoveFile Failed"),_T("LogFile Error"), MB_OK | MB_SETFOREGROUND);
  119. }
  120. }
  121. }
  122. #if defined(UNICODE) || defined(_UNICODE)
  123. pwsz = m_szLogFileName_Full;
  124. #else
  125. pwsz = MakeWideStrFromAnsi( m_szLogFileName_Full);
  126. #endif
  127. // Create a Security Descriptor with only Administrators and Local System, then open
  128. // the file with it
  129. if ( LogFileSD.AddAccessAcebyWellKnownID( CSecurityDescriptor::GROUP_ADMINISTRATORS,
  130. CSecurityDescriptor::ACCESS_FULL,
  131. TRUE,
  132. FALSE ) &&
  133. LogFileSD.AddAccessAcebyWellKnownID( CSecurityDescriptor::USER_LOCALSYSTEM,
  134. CSecurityDescriptor::ACCESS_FULL,
  135. TRUE,
  136. FALSE )
  137. )
  138. {
  139. // Open existing file or create a new one.
  140. m_hFile = CreateFile( m_szLogFileName_Full,
  141. GENERIC_READ | GENERIC_WRITE | WRITE_DAC,
  142. FILE_SHARE_READ | FILE_SHARE_WRITE,
  143. LogFileSD.QuerySA(), //NULL,
  144. OPEN_ALWAYS,
  145. FILE_ATTRIBUTE_NORMAL,
  146. NULL);
  147. if (m_hFile == INVALID_HANDLE_VALUE)
  148. {
  149. m_hFile = NULL;
  150. //MyMessageBox(NULL, _T("Unable to create iis setup log file"), _T("LogFile Error"), MB_OK | MB_SETFOREGROUND);
  151. }
  152. else
  153. {
  154. SetFilePointer( m_hFile, NULL, NULL, FILE_END );
  155. iReturn = TRUE;
  156. }
  157. //LogFileTimeStamp();
  158. LogFileWrite(_T("LogFile Open. [***** Search on FAIL/MessageBox keywords for failures *****].\r\n"));
  159. }
  160. }
  161. // safe to leave the critical section
  162. LeaveCriticalSection( &critical_section );
  163. return iReturn;
  164. }
  165. //***************************************************************************
  166. //*
  167. //* purpose:
  168. //*
  169. //***************************************************************************
  170. int MyLogFile::LogFileClose(void)
  171. {
  172. if (m_hFile)
  173. {
  174. LogFileWrite(_T("LogFile Close.\r\n"));
  175. CloseHandle(m_hFile);
  176. m_hFile = NULL;
  177. return TRUE;
  178. }
  179. return FALSE;
  180. }
  181. //***************************************************************************
  182. //*
  183. //* purpose: add stuff to logfile
  184. //*
  185. //***************************************************************************
  186. void MyLogFile::LogFileTimeStamp()
  187. {
  188. SYSTEMTIME SystemTime;
  189. GetLocalTime(&SystemTime);
  190. m_bDisplayTimeStamp = FALSE;
  191. m_bDisplayPreLineInfo = FALSE;
  192. LogFileWrite(_T("[%d/%d/%d %d:%d:%d]\r\n"),SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear,SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
  193. m_bDisplayTimeStamp = TRUE;
  194. m_bDisplayPreLineInfo = TRUE;
  195. }
  196. //***************************************************************************
  197. //*
  198. //* purpose:
  199. //*
  200. //***************************************************************************
  201. #define LOG_STRING_LEN 1000
  202. void MyLogFile::LogFileWrite(TCHAR *pszFormatString, ...)
  203. {
  204. if (m_hFile)
  205. {
  206. // because of the global flags and such, we'll make this critical
  207. EnterCriticalSection( &critical_section );
  208. va_list args;
  209. TCHAR pszFullErrMsg[ LOG_STRING_LEN ];
  210. char pszFullErrMsgA[ LOG_STRING_LEN ];
  211. strcpy(pszFullErrMsgA, "");
  212. DWORD dwBytesWritten = 0;
  213. if (_tcslen(pszFormatString) > LOG_STRING_LEN)
  214. {
  215. // this will overrun our buffer, just get out
  216. goto MyLogFile_LogFileWrite_Exit;
  217. }
  218. __try
  219. {
  220. va_start(args, pszFormatString);
  221. if (!_vsntprintf(pszFullErrMsg, LOG_STRING_LEN, pszFormatString, args))
  222. {
  223. goto MyLogFile_LogFileWrite_Exit;
  224. }
  225. // Null terminate just incase _vsntprintf did not
  226. pszFullErrMsg[ LOG_STRING_LEN - 1 ] = '\0';
  227. va_end(args);
  228. }
  229. __except(EXCEPTION_EXECUTE_HANDLER)
  230. {
  231. goto MyLogFile_LogFileWrite_Exit;
  232. }
  233. if (*pszFullErrMsg)
  234. {
  235. #if defined(UNICODE) || defined(_UNICODE)
  236. // convert to ascii then write to stream
  237. WideCharToMultiByte( CP_ACP, 0, (TCHAR *)pszFullErrMsg, -1, pszFullErrMsgA, LOG_STRING_LEN, NULL, NULL );
  238. #else
  239. // the is already ascii so just copy the pointer
  240. strcpy(pszFullErrMsgA,pszFullErrMsg);
  241. #endif
  242. // If the Display timestap is set then display the timestamp
  243. if (m_bDisplayTimeStamp == TRUE)
  244. {
  245. // Get timestamp
  246. SYSTEMTIME SystemTime;
  247. GetLocalTime(&SystemTime);
  248. char szDateandtime[50];
  249. sprintf(szDateandtime,"[%d/%d/%d %d:%d:%d] ",SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear,SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
  250. // Write time to stream
  251. if (m_hFile) {WriteFile(m_hFile,szDateandtime,strlen(szDateandtime),&dwBytesWritten,NULL);}
  252. }
  253. char szPrelineWriteString[100];
  254. char szPrelineWriteString2[100];
  255. // If the Display timestap is set then display the timestamp
  256. if (m_bDisplayPreLineInfo == TRUE)
  257. {
  258. if (_tcscmp(m_szLogPreLineInfo,_T("")) != 0)
  259. {
  260. #if defined(UNICODE) || defined(_UNICODE)
  261. // convert to ascii
  262. WideCharToMultiByte( CP_ACP, 0, (TCHAR *)m_szLogPreLineInfo, -1, szPrelineWriteString, 100, NULL, NULL );
  263. #else
  264. // the is already ascii so just copy
  265. strcpy(szPrelineWriteString, m_szLogPreLineInfo);
  266. #endif
  267. if (m_hFile) {WriteFile(m_hFile,szPrelineWriteString,strlen(szPrelineWriteString),&dwBytesWritten,NULL);}
  268. }
  269. if (_tcscmp(m_szLogPreLineInfo2,_T("")) != 0)
  270. {
  271. #if defined(UNICODE) || defined(_UNICODE)
  272. // convert to ascii
  273. WideCharToMultiByte( CP_ACP, 0, (TCHAR *)m_szLogPreLineInfo2, -1, szPrelineWriteString2, 100, NULL, NULL );
  274. #else
  275. // the is already ascii so just copy
  276. strcpy(szPrelineWriteString2, m_szLogPreLineInfo2);
  277. #endif
  278. if (m_hFile) {WriteFile(m_hFile,szPrelineWriteString2,strlen(szPrelineWriteString2),&dwBytesWritten,NULL);}
  279. }
  280. }
  281. // if it does not end if '\r\n' then make one.
  282. int nLen = strlen(pszFullErrMsgA);
  283. if ( ( nLen >=1 ) &&
  284. ( nLen < ( sizeof(pszFullErrMsgA) - sizeof("\r\n") ) ) &&
  285. ( pszFullErrMsgA[nLen-1] != '\n' )
  286. )
  287. {
  288. strcat(pszFullErrMsgA, "\r\n");
  289. }
  290. else
  291. {
  292. if ( ( nLen >= 2 ) &&
  293. ( nLen < ( sizeof(pszFullErrMsgA) - sizeof("\r\n") ) ) &&
  294. ( pszFullErrMsgA[nLen-2] != '\r' )
  295. )
  296. {
  297. char * pPointer = NULL;
  298. pPointer = pszFullErrMsgA + (nLen-1);
  299. strcpy(pPointer, "\r\n");
  300. }
  301. }
  302. // Write Regular data to stream
  303. if (m_hFile)
  304. {
  305. WriteFile(m_hFile,pszFullErrMsgA,strlen(pszFullErrMsgA),&dwBytesWritten,NULL);
  306. // since setup can get the rug pulled out from under it from anything
  307. // make sure the file is flushed to disk
  308. if (m_bFlushLogToDisk)
  309. {
  310. FlushFileBuffers(m_hFile);
  311. }
  312. } // if m_hFile
  313. }
  314. } // if m_hFile
  315. MyLogFile_LogFileWrite_Exit:
  316. // safe to leave the critical section
  317. LeaveCriticalSection( &critical_section );
  318. }