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.

260 lines
7.9 KiB

  1. #include "kdMonSvcMessages.h"
  2. #include <atlbase.h>
  3. #include "global.h"
  4. // The name of current service
  5. _TCHAR szServiceName[MAX_PATH];
  6. // whenever somebody uses GetError(), they use this variable
  7. _TCHAR szError[MAX_PATH];
  8. ///////////////////////////////////////////////////////////////////////////////////////
  9. // Event Logging functions
  10. // Setup the necessary registry keys in Event Log
  11. // Without these registry keys, EventLog will not recognize this service as event source
  12. LONG SetupEventLog(BOOL bSetKey)
  13. {
  14. LONG lResult;
  15. _TCHAR szKey[MAX_PATH];
  16. _stprintf(szKey, _T("%s\\%s"), _T(cszEventLogKey), szServiceName);
  17. // we have to delete the key if bSetKey == FALSE
  18. if (bSetKey == FALSE) {
  19. lResult = RegDeleteKey(HKEY_LOCAL_MACHINE, szKey);
  20. return lResult;
  21. } else {
  22. CRegKey regKey;
  23. // try to open/create the key
  24. lResult = regKey.Create(HKEY_LOCAL_MACHINE, szKey);
  25. if (lResult != ERROR_SUCCESS) {
  26. return lResult;
  27. }
  28. //
  29. // create certain values under the key
  30. //
  31. // get path for the file containing the current process
  32. _TCHAR szModuleFileName[MAX_PATH];
  33. DWORD dwRetVal;
  34. dwRetVal = GetModuleFileName( NULL,
  35. szModuleFileName,
  36. sizeof(szModuleFileName)/sizeof(_TCHAR)); // length in _TCHARs
  37. if ( dwRetVal == 0 ) {
  38. GetError(szError);
  39. AddServiceLog(_T("Error: SetupEventLog->GetModuleFileName: %s\r\n"), szError);
  40. LogEvent(_T("SetupEventLog: GetModuleFileName: %s"), szError);
  41. return (LONG) GetLastError();
  42. }
  43. lResult = regKey.SetValue(szModuleFileName, _T("EventMessageFile"));
  44. if (lResult != ERROR_SUCCESS) {
  45. return lResult;
  46. }
  47. lResult = regKey.SetValue(EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE,
  48. _T("TypesSupported"));
  49. if (lResult != ERROR_SUCCESS) {
  50. return lResult;
  51. }
  52. // close the key
  53. lResult = regKey.Close();
  54. if (lResult != ERROR_SUCCESS) {
  55. return lResult;
  56. }
  57. }
  58. return ERROR_SUCCESS;
  59. }
  60. // Log an event with EVENTLOG_INFORMATION_TYPE and eventID = EVENT_MESSAGE
  61. void LogEvent(_TCHAR pFormat[MAX_PATH * 4], ...)
  62. {
  63. _TCHAR chMsg[4 * MAX_PATH];
  64. HANDLE hEventSource;
  65. LPTSTR lpszStrings[1];
  66. va_list pArg;
  67. va_start(pArg, pFormat);
  68. _vstprintf(chMsg, pFormat, pArg);
  69. va_end(pArg);
  70. lpszStrings[0] = chMsg;
  71. /* Get a handle to use with ReportEvent(). */
  72. hEventSource = RegisterEventSource(NULL, szServiceName);
  73. if (hEventSource != NULL)
  74. {
  75. /* Write to event log. */
  76. ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, EVENT_MESSAGE, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
  77. DeregisterEventSource(hEventSource);
  78. }
  79. else
  80. {
  81. // As we are not running as a service, just write the error to the console.
  82. _putts(chMsg);
  83. }
  84. }
  85. ///////////////////////////////////////////////////////////////////////////////////////
  86. // Log an event with EVENTLOG_ERROR_TYPE and eventID = EVENT_ERROR
  87. void LogFatalEvent(_TCHAR pFormat[MAX_PATH * 4], ...)
  88. {
  89. _TCHAR chMsg[4 * MAX_PATH];
  90. HANDLE hEventSource;
  91. LPTSTR lpszStrings[1];
  92. va_list pArg;
  93. va_start(pArg, pFormat);
  94. _vstprintf(chMsg, pFormat, pArg);
  95. va_end(pArg);
  96. lpszStrings[0] = chMsg;
  97. /* Get a handle to use with ReportEvent(). */
  98. hEventSource = RegisterEventSource(NULL, szServiceName);
  99. if (hEventSource != NULL)
  100. {
  101. /* Write to event log. */
  102. ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, EVENT_ERROR, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
  103. DeregisterEventSource(hEventSource);
  104. }
  105. }
  106. ///////////////////////////////////////////////////////////////////////////////////////
  107. // Logging to file functions
  108. // This logging is used for personal debugging
  109. // Log the string to log file
  110. void AddServiceLog(_TCHAR pFormat[MAX_PATH * 4], ...){
  111. va_list pArg;
  112. va_start(pArg, pFormat);
  113. _TCHAR chMsg[10 * MAX_PATH];
  114. _vstprintf(chMsg, pFormat, pArg);
  115. va_end(pArg);
  116. AppendToFile(_T(cszLogFile), chMsg);
  117. }
  118. // appends the specified string to the specified file
  119. // here we reopen the file for writing everytime.
  120. // so we can not directly use WriteFile() function.
  121. // WriteFile() writes to file from current pointer position.
  122. // So fisrt we have to reach to the file end. And then write there.
  123. void AppendToFile(_TCHAR szFileName[], _TCHAR szbuff[]){
  124. HANDLE hFile;
  125. hFile = CreateFile( szFileName,
  126. GENERIC_WRITE,
  127. 0, // No sharing of file
  128. NULL, // No security
  129. OPEN_ALWAYS, // Open if exist, else create and open
  130. FILE_ATTRIBUTE_NORMAL, // Normal file
  131. NULL); // No attr. template
  132. if (hFile == INVALID_HANDLE_VALUE)
  133. {
  134. GetError(szError);
  135. LogEvent(_T("AppendToFile: CreateFile: %s"), szError);
  136. return;
  137. }
  138. DWORD dwPos;
  139. // Reach the file end
  140. dwPos = SetFilePointer( hFile,
  141. 0, // Low 32 bits of distance to move
  142. NULL, // High 32 bits of distance to move
  143. FILE_END); // Starting point
  144. // If High Word is NULL, error meas dwPos = INVALID_SET_FILE_POINTER
  145. if(dwPos == INVALID_SET_FILE_POINTER){
  146. GetError(szError);
  147. LogEvent(_T("AppendToFile: SetFilePointer: %s"), szError);
  148. goto done;
  149. }
  150. // Lock the region in file to prevent another process from accessing
  151. // it while writing to it.
  152. // create an OVERLAPPED structure
  153. OVERLAPPED overlapRegion;
  154. overlapRegion.Offset = dwPos; // Low order word of offset
  155. overlapRegion.OffsetHigh = 0; // High order word of offset
  156. overlapRegion.hEvent = 0;
  157. BOOL bRet;
  158. bRet = LockFileEx( hFile,
  159. LOCKFILE_EXCLUSIVE_LOCK, // dwFlags
  160. 0, // reserved
  161. _tcsclen(szbuff) * sizeof(_TCHAR), // Low order word of length
  162. 0, // High order word of length
  163. &overlapRegion);
  164. if(bRet == 0){
  165. GetError(szError);
  166. LogEvent(_T("AppendToFile: LockFile: %s"), szError);
  167. goto done;
  168. }
  169. DWORD dwBytesWritten;
  170. bRet = WriteFile( hFile,
  171. szbuff, // Buffer to write
  172. // 4 hours wasted for the following :-)
  173. _tcslen(szbuff) * sizeof(_TCHAR), // Number of "bytes" to write
  174. &dwBytesWritten, // Number of "bytes" written
  175. NULL); // Pointer to OVERLAPPED structure
  176. if(bRet == 0){
  177. GetError(szError);
  178. LogEvent( _T("AppendToFile: WriteFile: %s"), szError);
  179. goto done;
  180. }
  181. // Unlock the file if you have locked previously
  182. // Unlock the file when writing is finished.
  183. bRet = UnlockFile( hFile,
  184. dwPos, // Low order word of offset
  185. 0, // High order word of offset
  186. _tcsclen(szbuff) * sizeof(_TCHAR), // Low order word of length
  187. 0); // High order word of length
  188. if(bRet == 0){
  189. GetError(szError);
  190. LogEvent(_T("AppendToFile: UnLockFile: %s"), szError);
  191. goto done;
  192. }
  193. done:
  194. CloseHandle(hFile);
  195. }
  196. //
  197. //This is valid to use only when the MSDN help suggests use of GetLastError() to get error
  198. //from that particular function.
  199. //Some functions set the error system variable and only in that case, GetLastError() can be
  200. //used. Else it will show the error occured in a function that had set the error variable.
  201. //
  202. void GetError(_TCHAR szError[]){
  203. LPVOID lpMsgBuf;
  204. UINT uiRet;
  205. uiRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  206. FORMAT_MESSAGE_IGNORE_INSERTS,
  207. NULL,
  208. GetLastError(),
  209. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  210. (LPTSTR) &lpMsgBuf,
  211. // If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter
  212. // specifies the minimum number of _TCHARs to allocate for
  213. // an output buffer
  214. 0,
  215. NULL );
  216. if(uiRet == 0){
  217. LogEvent(_T("GetError->FormatMessage : %d"), GetLastError());
  218. _tcscpy(szError, _T(" "));
  219. return;
  220. }
  221. _tcscpy(szError, (LPTSTR)lpMsgBuf);
  222. // Free the buffer.
  223. LocalFree( lpMsgBuf );
  224. }