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.
 
 
 
 
 
 

776 lines
25 KiB

#include "stdafx.h"
#include "global.h"
// to include CkdMonINI class definition
#include "ini.h"
#include "SMTP.h"
// The name of current service
// This variable is declared in global.cpp
extern _TCHAR szServiceName[MAX_PATH];
// just to get any kind of error through GetError() routine
// This variable is declared in global.cpp
extern _TCHAR szError[MAX_PATH];
// this is used by LoadINI function also. So it is made global
CkdMonINI kdMonINI;
void kdMon() {
// SMTP object
CSMTP smtpObj;
// This variable is used by IsSignaledToStop() function.
// open the stop event which is created by kdMonSvc
// For any event, the name of the event matters and the handle does not.
HANDLE hStopEvent = NULL;
// open the cszStopEvent which is meant to signal this thread to stop.
// this signalling is done by main service thread when WM_QUIT is received
hStopEvent = OpenEvent( EVENT_ALL_ACCESS,
FALSE, // = handle can not be inherited
(LPCTSTR)_T(cszStopEvent));
if ( hStopEvent == NULL ) {
GetError(szError);
LogFatalEvent(_T("kdMon->OpenEvent: %s"), szError);
AddServiceLog(_T("Error: kdMon->OpenEvent: %s\r\n"), szError);
goto endkdMon;
}
BOOL bLoop;
bLoop = TRUE;
while(bLoop) {
AddServiceLog(_T("\r\n- - - - - - @ @ @ @ @ @ @ @ @ @ - - - - - - - - - - - @ @ @ @ @ @ @ @ @ @ @ - - - - - - - \r\n"));
// temperory boolean to receive return values from functions
BOOL bRet;
// load the values from INI file
// since INI file is read each time the loop gets executed,
// we can change the running parameters of the service on the fly
// If values loading is not successful then close the service : bLoop = FALSE;
bRet = LoadINI();
if ( bRet == FALSE ) {
bLoop = FALSE;
goto closeandwait;
}
bRet = smtpObj.InitSMTP();
// if SMTP can not be initiated, then do nothing. try in next database cycle.
if ( bRet == FALSE ) {
goto closeandwait;
}
// generate an array to store failure counts for each server
ULONG *pulFailureCounts;
pulFailureCounts = NULL;
pulFailureCounts = (ULONG *) malloc (kdMonINI.dwServerCount * sizeof(ULONG));
if ( pulFailureCounts == NULL ) {
AddServiceLog(_T("Error: kdMon->malloc: Insufficient memory\r\n"));
LogFatalEvent(_T("kdMon->malloc: Insufficient memory"));
bLoop = FALSE;
goto closeandwait;
}
// generate an array to store timestamp for count from each server
ULONG *pulTimeStamps;
pulTimeStamps = NULL;
pulTimeStamps = (ULONG *) malloc (kdMonINI.dwServerCount * sizeof(ULONG));
if ( pulTimeStamps == NULL ) {
AddServiceLog(_T("Error: kdMon->malloc: Insufficient memory\r\n"));
LogFatalEvent(_T("kdMon->malloc: Insufficient memory"));
bLoop = FALSE;
goto closeandwait;
}
// load the values from registry for the server to be monitored
// since INI file is read each time the loop gets executed,
// we can change the server names on the fly
// we get counts for each server in pulFailureCounts
// we get corresponding TimeStamps in pulTimeStamps
bRet = ReadRegValues( kdMonINI.ppszServerNameArray,
kdMonINI.dwServerCount,
pulFailureCounts,
pulTimeStamps);
if ( bRet == FALSE )
goto closeandwait;
// counter to go through server names
UINT uiServerCtr;
for( uiServerCtr = 0; uiServerCtr < kdMonINI.dwServerCount; uiServerCtr++) {
// prepare Log File Name on the server
_TCHAR szKDFailureLogFile[MAX_PATH * 2];
_stprintf(szKDFailureLogFile, _T("\\\\%s\\%s"),
kdMonINI.ppszServerNameArray[uiServerCtr],
kdMonINI.szDebuggerLogFile);
ULONG ulRet;
// scan the log file and get the count of number of lines
ulRet = ScanLogFile(szKDFailureLogFile);
// AddServiceLog(_T("ulRet = %ld\r\n"), ulRet);
if ( ulRet == E_FILE_NOT_FOUND ) {
// file not found means there are no Debugger errors
// So put count = 0 and go on with next server
pulFailureCounts[uiServerCtr] = 0;
continue;
}
if ( ulRet == E_PATH_NOT_FOUND ) {
// path not found means there is some network error
// So put count = -1 so next time this count wont be valid
// and go on with next server
pulFailureCounts[uiServerCtr] = -1;
continue;
}
// some other error occurred
if ( ulRet == E_OTHER_FILE_ERROR ) {
// So put count = -1 so next time this count wont be valid
// and go on with next server
pulFailureCounts[uiServerCtr] = -1;
continue;
}
ULONG ulNumLines;
ulNumLines = ulRet;
// if previous count was -1 i.e. invalid, just put new count and move on
// similar if previous TimeStamp was invalid
if ( (pulFailureCounts[uiServerCtr] == -1) ||
pulTimeStamps[uiServerCtr] == -1) {
pulFailureCounts[uiServerCtr] = ulNumLines;
continue;
}
// get the current system time
// ulTimeStamp is like 200112171558
ULONG ulCurrentTimeStamp;
ulCurrentTimeStamp = GetCurrentTimeStamp();
if ( ulCurrentTimeStamp == -1 ) {
pulFailureCounts[uiServerCtr] = ulNumLines;
continue;
}
// we have kdMonINI.dwRepeatTime in minutes (say 78)
// take out hours and minutes (1 Hr 18 Min)
// between 0112181608 and 0112181726 there is difference of 1 Hr 18 Min
// but decimal difference is 118
// between 0112181650 and 0112181808 there is difference of 1 Hr 18 Min
// but decimal difference is 158
// so we have some calculation here
// what we will do is add the kdMonINI.dwRepeatTime to OldTS
// modify the previous timestamp to do the comparison
ULONG ulModifiedTS;
ulModifiedTS = AddTime(pulTimeStamps[uiServerCtr], kdMonINI.dwRepeatTime);
AddServiceLog(_T("Server: %s, OldTS: %ld, NewTS: %ld, OldCnt: %ld, NewCnt: %ld, ulModifiedTS = %ld\r\n"),
kdMonINI.ppszServerNameArray[uiServerCtr],
pulTimeStamps[uiServerCtr],
ulCurrentTimeStamp,
pulFailureCounts[uiServerCtr],
ulNumLines, ulModifiedTS);
// check the timestamp difference. Keep margin of 3
// if the previous timestamp was > dwRepeatTime ago then dont do anything
// just record the new count This case happens when there is a Servername in
// INI, then it is removed for some time and then it is added again
// this helps to send false mails out
if ( ulCurrentTimeStamp > (ulModifiedTS + 3) ) {
AddServiceLog(_T("Previous record invalid. ulCurrentTimeStamp: %ld, ulModifiedTS: %ld"),
ulCurrentTimeStamp, ulModifiedTS);
pulFailureCounts[uiServerCtr] = ulNumLines;
continue;
}
// check the difference between current and previous counts
ULONG ulFailures;
ulFailures = ulNumLines - pulFailureCounts[uiServerCtr];
if ( ulFailures >= kdMonINI.dwDebuggerThreshold ) {
AddServiceLog(_T("KD failed. %ld errors in %ld minutes\r\n"),
ulFailures, kdMonINI.dwRepeatTime);
// fill the mail parameters structure
StructMailParams stMailParams;
_tcscpy(stMailParams.szFrom, kdMonINI.szFromMailID);
_tcscpy(stMailParams.szTo, kdMonINI.szToMailID);
_tcscpy(stMailParams.szServerName, kdMonINI.ppszServerNameArray[uiServerCtr]);
stMailParams.ulFailures = ulFailures;
stMailParams.ulInterval = kdMonINI.dwRepeatTime;
stMailParams.ulCurrentTimestamp = ulCurrentTimeStamp;
BOOL bRet;
bRet = smtpObj.SendMail(stMailParams);
// dont care even if you were not able to send mail
//if ( bRet == FALSE )
// goto nextserver;
}
// store new count in the array
pulFailureCounts[uiServerCtr] = ulNumLines;
// see if the date has changed, if yes then move the previous logfile to
// new location
// example of date change OldTS: 200112182348, NewTS: 200112190048
// so divide timestamp by 10000 and you get 20011218 and 20011219 compare
ULONG ulOldDate, ulNewDate;
ulOldDate = pulTimeStamps[uiServerCtr]/10000;
ulNewDate = ulCurrentTimeStamp/10000;
if ( (ulNewDate - ulOldDate) >= 1 ) {
AddServiceLog(_T("Day changed. Oldday: %ld, Newday: %ld\r\n"),
ulOldDate, ulNewDate);
// Log File Name
_TCHAR szKDFailureLogFile[MAX_PATH * 2];
_stprintf(szKDFailureLogFile, _T("\\\\%s\\%s"),
kdMonINI.ppszServerNameArray[uiServerCtr],
kdMonINI.szDebuggerLogFile);
// now since date has changed, prepare archive filename
_TCHAR szTimeStamp[MAX_PATH];
_ltot(ulOldDate, szTimeStamp, 10);
// prepare Archive Log File Name on the server
_TCHAR szKDFailureArchiveFile[MAX_PATH * 2];
_stprintf(szKDFailureArchiveFile, _T("%s\\%s_FailedAddCrash%s.log"),
kdMonINI.szDebuggerLogArchiveDir,
kdMonINI.ppszServerNameArray[uiServerCtr],
szTimeStamp);
AddServiceLog(_T("Moving file (%s -> %s)\r\n"),
szKDFailureLogFile, szKDFailureArchiveFile);
// copy file to destination
if ( CopyFile(szKDFailureLogFile, szKDFailureArchiveFile, FALSE) ) {
// try to delete the original kd failure log file
if ( DeleteFile(szKDFailureLogFile) ) {
// set new count to 0 since log has been moved successfully
pulFailureCounts[uiServerCtr] = 0;
}
else {
GetError(szError);
AddServiceLog(_T("Error: kdMon->DeleteFile(%s): %s \r\n"),
szKDFailureLogFile, szError);
LogEvent(_T("Error: kdMon->DeleteFile(%s): %s"),
szKDFailureLogFile, szError);
// try to delete the copied file
if ( DeleteFile(szKDFailureArchiveFile) ) {
;
}
else {
GetError(szError);
AddServiceLog(_T("Error: kdMon->DeleteFile(%s): %s \r\n"),
szKDFailureArchiveFile, szError);
LogEvent(_T("Error: kdMon->DeleteFile(%s): %s"),
szKDFailureArchiveFile, szError);
}
}
}
else {
GetError(szError);
AddServiceLog(_T("Error: kdMon->CopyFile(%s, %s): %s \r\n"),
szKDFailureLogFile, szKDFailureArchiveFile, szError);
LogEvent(_T("Error: kdMon->CopyFile(%s, %s): %s"),
szKDFailureLogFile, szKDFailureArchiveFile, szError);
}
}
}
// write the values to registry for the servers to be monitored
// counts for each server are in pulFailureCounts
// timestamp is current time
bRet = WriteRegValues( kdMonINI.ppszServerNameArray,
kdMonINI.dwServerCount,
pulFailureCounts);
if ( bRet == FALSE )
goto closeandwait;
closeandwait:
// cleanup SMTP resources
bRet = smtpObj.SMTPCleanup();
if( bRet == FALSE ) {
AddServiceLog(_T("Error: smtpObj.SMTPCleanup failed\r\n"));
LogFatalEvent(_T("smtpObj.SMTPCleanup failed"));
}
// free uiFailureCounts
if (pulFailureCounts != NULL)
free(pulFailureCounts);
// free pulTimeStamps
if (pulTimeStamps != NULL)
free(pulTimeStamps);
// break the while loop if bLoop is false
if (bLoop == FALSE) {
goto endkdMon;
}
bRet = IsSignaledToStop(hStopEvent, kdMonINI.dwRepeatTime * 60 * 1000);
if (bRet == TRUE) {
goto endkdMon;
}
} // while(bLoop)
endkdMon:
if (hStopEvent != NULL) CloseHandle(hStopEvent);
return;
}
BOOL IsSignaledToStop(const HANDLE hStopEvent, DWORD dwMilliSeconds)
{
DWORD dwRetVal;
dwRetVal = WaitForSingleObject( hStopEvent, dwMilliSeconds );
if ( dwRetVal == WAIT_FAILED ) {
GetError(szError);
LogFatalEvent(_T("IsSignaledToStop->WaitForSingleObject: %s"), szError);
AddServiceLog(_T("Error: IsSignaledToStop->WaitForSingleObject: %s\r\n"), szError);
// thread is supposed to stop now since there is a fatal error
return TRUE;
}
if ( dwRetVal == WAIT_OBJECT_0 ) {
LogEvent(_T("Worker Thread received Stop Event."));
AddServiceLog(_T("Worker Thread received Stop Event.\r\n"));
// thread is supposed to stop now since there is a stop event occured
return TRUE;
}
// thread is not yet signaled to stop
return FALSE;
}
// this procedure loads the values from INI file
BOOL LoadINI() {
DWORD dwRetVal;
//
// prepare INI file path
//
_TCHAR szCurrentDirectory[MAX_PATH];
dwRetVal = GetCurrentDirectory( sizeof(szCurrentDirectory) / sizeof(_TCHAR),
(LPTSTR) szCurrentDirectory);
if ( dwRetVal == 0 ) {
LogFatalEvent(_T("LoadINI->GetCurrentDirectory: %s"), szError);
AddServiceLog(_T("Error: LoadINI->GetCurrentDirectory: %s\r\n"), szError);
// return FALSE indicating some error has occurred
return FALSE;
}
_TCHAR szINIFilePath[MAX_PATH];
_stprintf(szINIFilePath, _T("%s\\%s"), szCurrentDirectory, _T(cszkdMonINIFile));
// check if the kdMon INI file is there or not
HANDLE hINIFile;
WIN32_FIND_DATA w32FindData = {0};
// try to get the handle to the file
hINIFile = FindFirstFile( (LPCTSTR) szINIFilePath,
&w32FindData);
// if file is not there then the handle is invalid
if(hINIFile == INVALID_HANDLE_VALUE){
LogFatalEvent(_T("There is no kdMon INI file : %s"), szINIFilePath);
AddServiceLog(_T("Error: There is no kdMon INI file : %s \r\n"), szINIFilePath);
return FALSE;
}
else{
FindClose(hINIFile);
}
BOOL bRetVal;
bRetVal = kdMonINI.LoadValues(szINIFilePath);
if ( bRetVal == FALSE ) return bRetVal;
//
// check if values are getting in properly from INI file
//
AddServiceLog(_T("\r\n============== I N I V A L U E S ==============\r\n"));
AddServiceLog(_T("szToMailID : %s \r\n"), kdMonINI.szToMailID);
AddServiceLog(_T("szFromMailID : %s \r\n"), kdMonINI.szFromMailID);
AddServiceLog(_T("dwRepeatTime : %ld \r\n"), kdMonINI.dwRepeatTime);
AddServiceLog(_T("szDebuggerLogFile : %s \r\n"), kdMonINI.szDebuggerLogFile);
AddServiceLog(_T("szDebuggerLogArchiveDir : %s \r\n"), kdMonINI.szDebuggerLogArchiveDir);
AddServiceLog(_T("dwDebuggerThreshold : %ld \r\n"), kdMonINI.dwDebuggerThreshold);
AddServiceLog(_T("szServers : %s \r\n"), kdMonINI.szServers);
AddServiceLog(_T("dwServerCount : %ld \r\n"), kdMonINI.dwServerCount);
for ( UINT i = 0; i < kdMonINI.dwServerCount; i++ ) {
AddServiceLog(_T("kdMonINI.ppszServerNameArray[%ld] : %s \r\n"), i, kdMonINI.ppszServerNameArray[i]);
}
AddServiceLog(_T("\r\n===================================================\r\n"));
// successfully loaded INI file
return TRUE;
}
// each server name in ppszNames, get the count and corresponding timestamp
// store the count in the pulCounts array
// store the timestamp in the pulTimeStamps array
BOOL ReadRegValues(_TCHAR **ppszNames, DWORD dwTotalNames, ULONG *pulCounts, ULONG *pulTimeStamps)
{
// open HKEY_LOCAL_MACHINE\Software\Microsoft\kdMon registry key
CRegKey keyServerName;
LONG lRes;
_TCHAR szKeyName[MAX_PATH];
_tcscpy(szKeyName, _T("Software\\Microsoft\\"));
_tcscat(szKeyName, szServiceName);
lRes = keyServerName.Create(HKEY_LOCAL_MACHINE, szKeyName);
if ( lRes != ERROR_SUCCESS ) {
AddServiceLog(_T("Error: ReadRegValues->keyServerName.Create: Unable to open the key\r\n"));
LogFatalEvent(_T("ReadRegValues->keyServerName.Create: Unable to open the key"));
return FALSE;
}
// for each server name, get the previous count and timestamp value from registry
for (DWORD i = 0; i < dwTotalNames; i++){
_TCHAR szValue[MAX_PATH];
DWORD dwBufferSize;
dwBufferSize = MAX_PATH;
lRes = keyServerName.QueryValue(szValue, ppszNames[i], &dwBufferSize);
if ( lRes != ERROR_SUCCESS ) {
// means there is no such value
AddServiceLog(_T("ReadRegValues->keyServerName.QueryValue: Unable to query value %s\r\n"), ppszNames[i]);
LogEvent(_T("ReadRegValues->keyServerName.QueryValue: Unable to query value %s"), ppszNames[i]);
// There was no entry for server name in registry
// set the count to -1
pulCounts[i] = -1;
// set timestamp to -1
pulTimeStamps[i] = -1;
// go on with the next server name
continue;
}
// the value got is of the form <count>|<datetime>
// # strtok returns pointer to the next token found in szValue
// # while the pointer is returned, the '|' is replaced by '\0'
// # so if u print strToken then it will print the characters till the null
// # character
// get the first token which is the previous count
_TCHAR* pszToken;
pszToken = NULL;
pszToken = _tcstok(szValue, _T("|"));
if(pszToken == NULL){
AddServiceLog(_T("Error: ReadRegValues: Wrong value retrieved for %s\r\n"), ppszNames[i]);
LogEvent(_T("ReadRegValues: Wrong value retrieved for %s"), ppszNames[i]);
// Previous count was an invalid value
// set the count to -1
pulCounts[i] = -1;
// set timestamp to -1
pulTimeStamps[i] = -1;
// go on with the next server name
continue;
}
// set the count
pulCounts[i] = _ttoi(pszToken);
// get the second token which is the timestamp of the count
pszToken = _tcstok(NULL, _T("|"));
if(pszToken == NULL){
AddServiceLog(_T("Error: ReadRegValues: No timestamp found for %s\r\n"), ppszNames[i]);
LogEvent(_T("ReadRegValues: No timestamp found for %s"), ppszNames[i]);
// no timestamp found
// set timestamp to -1
pulTimeStamps[i] = -1;
// dont do timestamp validation, go on with the next server name
continue;
}
// set the timestamp
pulTimeStamps[i] = _ttol(pszToken);
}
// for (i = 0; i < dwTotalNames; i++){
// AddServiceLog(_T("%s Value : %ld %ld\r\n"), ppszNames[i], pulCounts[i], pulTimeStamps[i]);
// }
return TRUE;
}
// write values in the pulCounts to registry. Timestamp is current timestamp
BOOL WriteRegValues(_TCHAR **ppszNames, DWORD dwTotalNames, ULONG *pulCounts)
{
// open HKEY_LOCAL_MACHINE\Software\Microsoft\kdMon registry key
CRegKey keyServerName;
LONG lRes;
_TCHAR szKeyName[MAX_PATH];
_tcscpy(szKeyName, _T("Software\\Microsoft\\"));
_tcscat(szKeyName, szServiceName);
lRes = keyServerName.Create(HKEY_LOCAL_MACHINE, szKeyName);
if ( lRes != ERROR_SUCCESS ) {
AddServiceLog(_T("Error: ReadRegValues->keyServerName.Create: Unable to open the key\r\n"));
LogFatalEvent(_T("ReadRegValues->keyServerName.Create: Unable to open the key"));
return FALSE;
}
// for each server name, write the current count and timestamp value in registry
for (DWORD i = 0; i < dwTotalNames; i++){
// prepare the value to write
_TCHAR szValue[MAX_PATH];
// get integer count in a string
_itot(pulCounts[i], szValue, 10);
// put delemiter
_tcscat(szValue, _T("|"));
// prepare the timestamp
// get the current system time
// ulTimeStamp is like 200112171558
ULONG ulTimeStamp;
ulTimeStamp = GetCurrentTimeStamp();
_TCHAR szTimeStamp[MAX_PATH];
_ltot(ulTimeStamp, szTimeStamp, 10);
// prepare final KeyValue
_tcscat(szValue, szTimeStamp);
lRes = keyServerName.SetValue(szValue, ppszNames[i]);
if ( lRes != ERROR_SUCCESS ) {
// means there is no value
AddServiceLog(_T("Error: WriteRegValues->keyServerName.SetValue: Unable to set value %s\r\n"), ppszNames[i]);
LogFatalEvent(_T("WriteRegValues->keyServerName.SetValue: Unable to set value %s"), ppszNames[i]);
return FALSE;
}
}
return TRUE;
}
ULONG ScanLogFile(_TCHAR *pszFileName)
{
ULONG ulRet = -1;
HANDLE hFile;
hFile = CreateFile( pszFileName,
GENERIC_READ,
0, // No sharing of file
NULL, // No security
OPEN_EXISTING, // Open if exist
FILE_ATTRIBUTE_NORMAL, // Normal file
NULL); // No attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
// DWORD to get an error
DWORD dwError;
dwError = GetLastError();
GetError(szError);
AddServiceLog(_T("Error: ScanLogFile->CreateFile(%s): %s"), pszFileName, szError);
LogEvent(_T("ScanLogFile->CreateFile(%s): %s"), pszFileName, szError);
// ERROR_PATH_NOT_FOUND is Win32 Error Code
// E_PATH_NOT_FOUND is locally defined code
if ( dwError == ERROR_PATH_NOT_FOUND ) {
return (ULONG)E_PATH_NOT_FOUND;
}
if ( dwError == ERROR_FILE_NOT_FOUND ) {
return (ULONG)E_FILE_NOT_FOUND;
}
return (ULONG)E_OTHER_FILE_ERROR;
}
DWORD dwPos;
// Reach the file start
dwPos = SetFilePointer( hFile,
0, // Low 32 bits of distance to move
NULL, // High 32 bits of distance to move
FILE_BEGIN); // Starting point
// If High Word is NULL, error meas dwPos = INVALID_SET_FILE_POINTER
if(dwPos == INVALID_SET_FILE_POINTER){
GetError(szError);
AddServiceLog(_T("Error: ScanLogFile->SetFilePointer: %s\r\n"), szError);
LogFatalEvent(_T("ScanLogFile->SetFilePointer: %s"), szError);
goto endScanLogFile;
}
// to get status of the read operation
// If the function succeeds and the number of bytes read is zero,
// the file pointer was beyond the current end of the file
DWORD dwBytesRead;
// buffer to read from file
// **** THIS NEEDS TO BE char* since the file is in ASCII and not UNICODE
char szBuffer[MAX_PATH * 2];
// count for Number of lines
ULONG ulNumberOfLines;
ulNumberOfLines = 0;
// loop till the fileend is reached
while(1) {
BOOL bRet;
bRet = ReadFile( hFile,
szBuffer,
sizeof(szBuffer) * sizeof(char), // number of BYTES to read
&dwBytesRead, // BYTES read
NULL); // OVERLAPPED structure
// return if read failed
if ( bRet == FALSE ) {
GetError(szError);
AddServiceLog(_T("Error: ScanLogFile->ReadFile(%s): %s\r\n"), pszFileName, szError);
LogFatalEvent(_T("ScanLogFile->ReadFile(%s): %s"), pszFileName, szError);
goto endScanLogFile;
}
// means file end is reached
if ( dwBytesRead == 0 ) {
ulRet = ulNumberOfLines;
break;
}
// **** THIS NEEDS TO BE char* since the file is in ASCII and not UNICODE
char *pszBuffPtr;
pszBuffPtr = szBuffer;
// to denote that a line has started
BOOL bLineStarted;
bLineStarted = FALSE;
// read buffer one by one till dwBytesRead bytes are read
for ( ; dwBytesRead > 0; dwBytesRead-- ) {
// **** _T('\n') not needed since the file is in ASCII and not UNICODE
// if endof line is encountered and line has started then increase line number
if ( (*pszBuffPtr == '\n') && (bLineStarted == TRUE) ) {
ulNumberOfLines++;
bLineStarted = FALSE;
} else if ( (*pszBuffPtr != '\n') &&
(*pszBuffPtr != '\t') &&
(*pszBuffPtr != '\r') &&
(*pszBuffPtr != ' ') ) {
// if a non widespace character is encountered then line has started
bLineStarted = TRUE;
}
// goto next character
pszBuffPtr++;
}
}
endScanLogFile :
CloseHandle(hFile);
return ulRet;
}
ULONG GetCurrentTimeStamp() {
// prepare the timestamp
// get the current system time
SYSTEMTIME UniversalTime;
GetSystemTime(&UniversalTime);
SYSTEMTIME systime;
BOOL bRet;
bRet = SystemTimeToTzSpecificLocalTime ( NULL, // current local settings
&UniversalTime,
&systime);
if ( bRet == 0 ) {
GetError(szError);
AddServiceLog(_T("Error: GetCurrentTimeStamp->SystemTimeToTzSpecificLocalTime: %s \r\n"),
szError);
LogFatalEvent(_T("GetCurrentTimeStamp->SystemTimeToTzSpecificLocalTime: %s"),
szError);
return (ULONG) -1;
}
// ulTimeStamp is like 200112171558
ULONG ulTimeStamp;
ulTimeStamp = 0;
ulTimeStamp += systime.wMinute;
ulTimeStamp += systime.wHour * 100;
ulTimeStamp += systime.wDay * 10000;
ulTimeStamp += systime.wMonth * 1000000;
ulTimeStamp += (systime.wYear - 2000) * 100000000;
return ulTimeStamp;
}
// to add a specific time to a timestamp
ULONG AddTime(ULONG ulTimeStamp, ULONG ulMinutes){
// we have kdMonINI.dwRepeatTime in minutes (say 78)
// take out hours and minutes (1 Hr 18 Min)
// between 0112181608 and 0112181726 there is difference of 1 Hr 18 Min
// but decimal difference is 118
// between 0112181650 and 0112181808 there is difference of 1 Hr 18 Min
// but decimal difference is 158
// so we have some calculation here
// what we will do is add the kdMonINI.dwRepeatTime to OldTS
ULONG ulTmpHr, ulTmpMin;
ulTmpHr = (ULONG) (ulMinutes / 60);
ulTmpMin = (ULONG) (ulMinutes % 60);
ULONG ulPrevYr, ulPrevMon, ulPrevDate, ulPrevHr, ulPrevMin;
ulPrevMin = ulTimeStamp % 100;
ulTimeStamp = ulTimeStamp / 100;
ulPrevHr = ulTimeStamp % 100;
ulTimeStamp = ulTimeStamp / 100;
ulPrevDate = ulTimeStamp % 100;
ulTimeStamp = ulTimeStamp / 100;
ulPrevMon = ulTimeStamp % 100;
ulTimeStamp = ulTimeStamp / 100;
ulPrevYr = ulTimeStamp % 100;
ULONG ulNewYr, ulNewMon, ulNewDate, ulNewHr, ulNewMin;
ulNewYr = ulNewMon = ulNewDate = ulNewHr = ulNewMin = 0;
ulNewMin = ulPrevMin + ulTmpMin;
ulNewHr = ulPrevHr + ulTmpHr;
ulNewDate = ulPrevDate;
ulNewMon = ulPrevMon;
ulNewYr = ulPrevYr;
if ( ulNewMin >= 60 ) {
ulNewHr++;
ulNewMin = ulNewMin - 60;
}
if ( ulNewHr >= 24 ) {
ulNewDate++;
ulNewHr = ulNewHr - 24;
}
if ( ulPrevMon == 1 || ulPrevMon == 3 || ulPrevMon == 5 || ulPrevMon == 7 ||
ulPrevMon == 8 || ulPrevMon == 10 || ulPrevMon == 12 ) {
if ( ulNewDate >= 32 ) {
ulNewMon++;
ulNewDate = 1;
}
} else if ( ulPrevMon == 4 || ulPrevMon == 6 || ulPrevMon == 9 || ulPrevMon == 11 ) {
if ( ulNewDate >= 31 ) {
ulNewMon++;
ulNewDate = 1;
}
} else if ( ulPrevMon == 2 && (ulPrevYr % 4) == 0 ) {
// leap year
if ( ulNewDate >= 30 ) {
ulNewMon++;
ulNewDate = 1;
}
} else if ( ulPrevMon == 2 && (ulPrevYr % 4) != 0 ) {
// not a leap year
if ( ulNewDate >= 29 ) {
ulNewMon++;
ulNewDate = 1;
}
}
if ( ulNewMon >= 13 ) {
ulNewYr++;
ulNewMon = 1;
}
ULONG ulModifiedTS;
ulModifiedTS = ulNewYr;
ulModifiedTS = ulModifiedTS * 100 + ulNewMon;
ulModifiedTS = ulModifiedTS * 100 + ulNewDate;
ulModifiedTS = ulModifiedTS * 100 + ulNewHr;
ulModifiedTS = ulModifiedTS * 100 + ulNewMin;
return ulModifiedTS;
}