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
260 lines
7.9 KiB
#include "kdMonSvcMessages.h"
|
|
#include <atlbase.h>
|
|
#include "global.h"
|
|
|
|
// The name of current service
|
|
_TCHAR szServiceName[MAX_PATH];
|
|
|
|
// whenever somebody uses GetError(), they use this variable
|
|
_TCHAR szError[MAX_PATH];
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
// Event Logging functions
|
|
|
|
// Setup the necessary registry keys in Event Log
|
|
// Without these registry keys, EventLog will not recognize this service as event source
|
|
LONG SetupEventLog(BOOL bSetKey)
|
|
{
|
|
LONG lResult;
|
|
|
|
_TCHAR szKey[MAX_PATH];
|
|
_stprintf(szKey, _T("%s\\%s"), _T(cszEventLogKey), szServiceName);
|
|
// we have to delete the key if bSetKey == FALSE
|
|
if (bSetKey == FALSE) {
|
|
lResult = RegDeleteKey(HKEY_LOCAL_MACHINE, szKey);
|
|
return lResult;
|
|
} else {
|
|
CRegKey regKey;
|
|
// try to open/create the key
|
|
lResult = regKey.Create(HKEY_LOCAL_MACHINE, szKey);
|
|
if (lResult != ERROR_SUCCESS) {
|
|
return lResult;
|
|
}
|
|
|
|
//
|
|
// create certain values under the key
|
|
//
|
|
|
|
// get path for the file containing the current process
|
|
_TCHAR szModuleFileName[MAX_PATH];
|
|
DWORD dwRetVal;
|
|
dwRetVal = GetModuleFileName( NULL,
|
|
szModuleFileName,
|
|
sizeof(szModuleFileName)/sizeof(_TCHAR)); // length in _TCHARs
|
|
if ( dwRetVal == 0 ) {
|
|
GetError(szError);
|
|
AddServiceLog(_T("Error: SetupEventLog->GetModuleFileName: %s\r\n"), szError);
|
|
LogEvent(_T("SetupEventLog: GetModuleFileName: %s"), szError);
|
|
return (LONG) GetLastError();
|
|
}
|
|
|
|
lResult = regKey.SetValue(szModuleFileName, _T("EventMessageFile"));
|
|
if (lResult != ERROR_SUCCESS) {
|
|
return lResult;
|
|
}
|
|
|
|
lResult = regKey.SetValue(EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE,
|
|
_T("TypesSupported"));
|
|
if (lResult != ERROR_SUCCESS) {
|
|
return lResult;
|
|
}
|
|
|
|
// close the key
|
|
lResult = regKey.Close();
|
|
if (lResult != ERROR_SUCCESS) {
|
|
return lResult;
|
|
}
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
// Log an event with EVENTLOG_INFORMATION_TYPE and eventID = EVENT_MESSAGE
|
|
void LogEvent(_TCHAR pFormat[MAX_PATH * 4], ...)
|
|
{
|
|
_TCHAR chMsg[4 * MAX_PATH];
|
|
HANDLE hEventSource;
|
|
LPTSTR lpszStrings[1];
|
|
va_list pArg;
|
|
|
|
va_start(pArg, pFormat);
|
|
_vstprintf(chMsg, pFormat, pArg);
|
|
va_end(pArg);
|
|
|
|
lpszStrings[0] = chMsg;
|
|
|
|
/* Get a handle to use with ReportEvent(). */
|
|
hEventSource = RegisterEventSource(NULL, szServiceName);
|
|
if (hEventSource != NULL)
|
|
{
|
|
/* Write to event log. */
|
|
ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, EVENT_MESSAGE, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
|
|
DeregisterEventSource(hEventSource);
|
|
}
|
|
else
|
|
{
|
|
// As we are not running as a service, just write the error to the console.
|
|
_putts(chMsg);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
// Log an event with EVENTLOG_ERROR_TYPE and eventID = EVENT_ERROR
|
|
void LogFatalEvent(_TCHAR pFormat[MAX_PATH * 4], ...)
|
|
{
|
|
_TCHAR chMsg[4 * MAX_PATH];
|
|
HANDLE hEventSource;
|
|
LPTSTR lpszStrings[1];
|
|
va_list pArg;
|
|
|
|
va_start(pArg, pFormat);
|
|
_vstprintf(chMsg, pFormat, pArg);
|
|
va_end(pArg);
|
|
|
|
lpszStrings[0] = chMsg;
|
|
|
|
|
|
/* Get a handle to use with ReportEvent(). */
|
|
hEventSource = RegisterEventSource(NULL, szServiceName);
|
|
if (hEventSource != NULL)
|
|
{
|
|
/* Write to event log. */
|
|
ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, EVENT_ERROR, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
|
|
DeregisterEventSource(hEventSource);
|
|
}
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
// Logging to file functions
|
|
// This logging is used for personal debugging
|
|
|
|
// Log the string to log file
|
|
void AddServiceLog(_TCHAR pFormat[MAX_PATH * 4], ...){
|
|
|
|
va_list pArg;
|
|
va_start(pArg, pFormat);
|
|
_TCHAR chMsg[10 * MAX_PATH];
|
|
_vstprintf(chMsg, pFormat, pArg);
|
|
va_end(pArg);
|
|
|
|
AppendToFile(_T(cszLogFile), chMsg);
|
|
}
|
|
|
|
// appends the specified string to the specified file
|
|
// here we reopen the file for writing everytime.
|
|
// so we can not directly use WriteFile() function.
|
|
// WriteFile() writes to file from current pointer position.
|
|
// So fisrt we have to reach to the file end. And then write there.
|
|
void AppendToFile(_TCHAR szFileName[], _TCHAR szbuff[]){
|
|
|
|
HANDLE hFile;
|
|
hFile = CreateFile( szFileName,
|
|
GENERIC_WRITE,
|
|
0, // No sharing of file
|
|
NULL, // No security
|
|
OPEN_ALWAYS, // Open if exist, else create and open
|
|
FILE_ATTRIBUTE_NORMAL, // Normal file
|
|
NULL); // No attr. template
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
GetError(szError);
|
|
LogEvent(_T("AppendToFile: CreateFile: %s"), szError);
|
|
return;
|
|
}
|
|
|
|
DWORD dwPos;
|
|
// Reach the file end
|
|
dwPos = SetFilePointer( hFile,
|
|
0, // Low 32 bits of distance to move
|
|
NULL, // High 32 bits of distance to move
|
|
FILE_END); // Starting point
|
|
// If High Word is NULL, error meas dwPos = INVALID_SET_FILE_POINTER
|
|
if(dwPos == INVALID_SET_FILE_POINTER){
|
|
GetError(szError);
|
|
LogEvent(_T("AppendToFile: SetFilePointer: %s"), szError);
|
|
goto done;
|
|
}
|
|
|
|
// Lock the region in file to prevent another process from accessing
|
|
// it while writing to it.
|
|
|
|
// create an OVERLAPPED structure
|
|
OVERLAPPED overlapRegion;
|
|
overlapRegion.Offset = dwPos; // Low order word of offset
|
|
overlapRegion.OffsetHigh = 0; // High order word of offset
|
|
overlapRegion.hEvent = 0;
|
|
|
|
BOOL bRet;
|
|
bRet = LockFileEx( hFile,
|
|
LOCKFILE_EXCLUSIVE_LOCK, // dwFlags
|
|
0, // reserved
|
|
_tcsclen(szbuff) * sizeof(_TCHAR), // Low order word of length
|
|
0, // High order word of length
|
|
&overlapRegion);
|
|
if(bRet == 0){
|
|
GetError(szError);
|
|
LogEvent(_T("AppendToFile: LockFile: %s"), szError);
|
|
goto done;
|
|
}
|
|
|
|
DWORD dwBytesWritten;
|
|
bRet = WriteFile( hFile,
|
|
szbuff, // Buffer to write
|
|
// 4 hours wasted for the following :-)
|
|
_tcslen(szbuff) * sizeof(_TCHAR), // Number of "bytes" to write
|
|
&dwBytesWritten, // Number of "bytes" written
|
|
NULL); // Pointer to OVERLAPPED structure
|
|
if(bRet == 0){
|
|
GetError(szError);
|
|
LogEvent( _T("AppendToFile: WriteFile: %s"), szError);
|
|
goto done;
|
|
}
|
|
|
|
// Unlock the file if you have locked previously
|
|
// Unlock the file when writing is finished.
|
|
bRet = UnlockFile( hFile,
|
|
dwPos, // Low order word of offset
|
|
0, // High order word of offset
|
|
_tcsclen(szbuff) * sizeof(_TCHAR), // Low order word of length
|
|
0); // High order word of length
|
|
if(bRet == 0){
|
|
GetError(szError);
|
|
LogEvent(_T("AppendToFile: UnLockFile: %s"), szError);
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
CloseHandle(hFile);
|
|
}
|
|
|
|
//
|
|
//This is valid to use only when the MSDN help suggests use of GetLastError() to get error
|
|
//from that particular function.
|
|
//Some functions set the error system variable and only in that case, GetLastError() can be
|
|
//used. Else it will show the error occured in a function that had set the error variable.
|
|
//
|
|
void GetError(_TCHAR szError[]){
|
|
LPVOID lpMsgBuf;
|
|
|
|
UINT uiRet;
|
|
uiRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
GetLastError(),
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPTSTR) &lpMsgBuf,
|
|
// If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter
|
|
// specifies the minimum number of _TCHARs to allocate for
|
|
// an output buffer
|
|
0,
|
|
NULL );
|
|
if(uiRet == 0){
|
|
LogEvent(_T("GetError->FormatMessage : %d"), GetLastError());
|
|
_tcscpy(szError, _T(" "));
|
|
return;
|
|
}
|
|
_tcscpy(szError, (LPTSTR)lpMsgBuf);
|
|
// Free the buffer.
|
|
LocalFree( lpMsgBuf );
|
|
}
|