Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1798 lines
54 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name :
ilogcls.cxx
Abstract:
This file contains member functions for Logging classes:
INET_BASIC_LOG and INET_FILE_LOG
Author:
Murali R. Krishnan ( MuraliK ) 3-Feb-1995
Environment:
User Mode -- Win32
Project:
Internet Services Common DLL
Functions Exported:
INET_BASIC_LOG::INET_BASIC_LOG()
INET_BASIC_LOG::SetServerName()
INET_BASIC_LOG::SetLogRecordFormat()
INET_BASIC_LOG::LogInformation()
INET_FILE_LOG::INET_FILE_LOG()
INET_FILE_LOG::~INET_FILE_LOG()
INET_FILE_LOG::LogInformation()
INET_FILE_LOG::GetConfig()
Revision History:
MuraliK 15-May-1995 Extended LogInformation structure +
file names changed to use sequence numbers.
MuraliK 07-Jun-1995 Week numbers calculated differently.
MuraliK 28-Jun-1995 Added ANSI API for LogInformation()
MuraliK 26-Feb-1996 speed up formatting and improve file buffering
--*/
/************************************************************
* Include Headers
************************************************************/
# include <tcpdllp.hxx>
# include "inetlog.h"
# include "ilogcls.hxx"
/************************************************************
* Symbolic Constants
************************************************************/
# define DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A (',')
const CHAR G_PSZ_DELIMITER[3] =
{ DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A, ' ', '\0'};
# define LEN_PSZ_DELIMITER ( sizeof(G_PSZ_DELIMITER)/sizeof(CHAR) - 1)
inline VOID
CopyLogDelimiter( IN CHAR * pchBuffer)
{
lstrcpyA( pchBuffer, G_PSZ_DELIMITER);
} // CopyLogDelimiter()
# define DEFAULT_LOG_FILE_NAME_W L"inetsvcs"
# define DEFAULT_NCSA_FILE_NAME_W L"NCSA"
# define DEFAULT_LOG_FILE_EXTENSION_W L"log"
//
// For the present the data written to file is always ANSI
// so undefine the UNICODE output flag
//
# ifdef INTERNET_LOG_IN_UNICODE
# undef INTERNET_LOG_IN_UNICODE
# endif
//
// lstrcpyn() has a bug that disallows the copy of last character.
// This is a bug as per the documentation. till that is fixed use following
//
# undef LSTRCPYN_DEBUGGED
# define DEFAULT_SERVER_NAME_W L"InternetServer"
# define DEFAULT_LOG_RECORD_FORMAT_W L"Internet Standard Log"
# define DEFAULT_LOG_RECORD_FORMAT_TYPE InternetStdLogFormat
# define PSZ_UNKNOWN_FIELD_W L"-"
# define PSZ_UNKNOWN_FIELD_A "-"
//
// class static data
//
WCHAR * INET_BASIC_LOG::sm_pwszDefaultUser = L"-";
CHAR * INET_BASIC_LOG::sm_pszDefaultUser = "-";
extern TCHAR * s_rgchMonths[];
inline BOOL
IsEmptyStr( IN LPCWSTR psz)
{ return ( psz == NULL || *psz == L'\0'); }
inline BOOL
IsEmptyStr(IN LPCSTR psz)
{ return ( psz == NULL || *psz == '\0'); }
/************************************************************
* Functions
************************************************************/
static BOOL
IsBeginningOfNewPeriod(
IN INETLOG_PERIOD ilPeriod,
IN LPSYSTEMTIME pstCurrentFile,
IN LPSYSTEMTIME pstNow);
VOID
CopyUnicodeStringToBuffer(
OUT WCHAR * pwchBuffer,
IN DWORD cchMaxSize,
IN LPCWSTR pwszSource)
/*
copies at most cbMaxSize-1 characters from pwszSource to pwchBuffer
*/
{
DBG_ASSERT( pwszSource != NULL);
DWORD cchLen = lstrlenW( pwszSource);
if ( cchLen >= cchMaxSize) {
DBGPRINTF( ( DBG_CONTEXT,
"Long String ( %d chars) %ws given."
" Truncating to %d chars\n",
cchLen, pwszSource,
cchMaxSize - 1));
// There is a bug in the lstrcpyn. hence need to work around it.
#ifndef LSTRCPYN_DEBUGGED
cchLen = cchMaxSize - 2;
# else
cchLen = cchMaxSize -1;
# endif
}
#ifndef LSTRCPYN_DEBUGGED
lstrcpynW( pwchBuffer, pwszSource, cchLen + 1);
# else
lstrcpynW( pwchBuffer, pwszSource, cchLen );
# endif
return;
} // CopyUnicodeStringToBuffer()
/**************************************************
* Member Functions of class INET_BASIC_LOG
**************************************************/
INET_BASIC_LOG::INET_BASIC_LOG( IN LPCWSTR pszServiceName,
IN EVENT_LOG * pEventLog)
/*++
This function creates a new INET_BASIC_LOG object.
It obtains the name of the server by using GetCompterName()
--*/
: m_logFormat ( DEFAULT_LOG_RECORD_FORMAT_TYPE),
m_pEventLog ( pEventLog)
{
CopyUnicodeStringToBuffer( m_rgchServiceName, MAX_SERVICE_NAME_LEN,
pszServiceName);
//
// Set the computer name to be some default value.
// Actual value will be set by INET_BASIC_LOG::SetServerName()
//
lstrcpyW( m_rgchServerName, DEFAULT_SERVER_NAME_W);
lstrcpyW( m_rgchLogRecordFormat, DEFAULT_LOG_RECORD_FORMAT_W);
// includes 2 ulonglongs, 5 dwords, spaces etc.
m_cchMinForLogRecord = ( 80 + lstrlenW(m_rgchServerName) +
lstrlenW( m_rgchServiceName));
// cached service-server name string
m_cchRgchSSName =
wsprintfA(m_rgchServiceServerName, "%ws%c %ws%c ",
m_rgchServiceName,
DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A,
m_rgchServerName,
DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A
);
wsprintfW(m_rgwchServiceServerName, L"%ws%c %ws%c ",
m_rgchServiceName,
DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A,
m_rgchServerName,
DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A
);
// set the time zone offset
TIME_ZONE_INFORMATION tzTimeZone;
DWORD dwError = GetTimeZoneInformation(&tzTimeZone);
switch (dwError)
{
case TIME_ZONE_ID_UNKNOWN:
lstrcpyA( m_szGMTOffset, "");
break;
default:
{
float fOffset = (float)tzTimeZone.Bias/(float)60;
int nOffset = tzTimeZone.Bias/60;
if ((tzTimeZone.Bias*tzTimeZone.DaylightBias)<0)
{
lstrcpyA(m_szGMTOffset,"-");
} else
{
lstrcpyA(m_szGMTOffset,"+");
}
// set up the "+0800" or "-0800" NCSA information
CHAR szTmp[MAX_PATH];
wsprintfA(szTmp,"%02ld",abs(nOffset));
lstrcatA(m_szGMTOffset,szTmp);
int nMinOffset = abs((int)((fOffset-nOffset)*60));
wsprintf(szTmp,"%02ld",nMinOffset);
lstrcatA(m_szGMTOffset,szTmp);
}
break;
}
return;
} // INET_BASIC_LOG::INET_BASIC_LOG()
DWORD
INET_BASIC_LOG::LogInformation(IN const INETLOG_INFORMATIONA * pInetLogInfo,
OUT LPSTR pszErrorMessage,
IN OUT LPDWORD lpcchErrorMessage
)
/*++
Same as the following function:
LogInformation( IN const INETLOG_INFORMATIONW * pInetLogInfo).
Keep the two functions consistent.
This functions performs the action of logging information for InetNoLog.
Essentially, does not produce any logging entry at all.
Arguments:
pInetLogInfo pointer to structure containing the Information to be logged.
Returns:
Win32 Error Code
--*/
{
IF_DEBUG( INETLOG) {
DBGPRINTF( ( DBG_CONTEXT,
"%s(%08x)::LogInformation( pInetLogInfo = %08x) called.\n",
QueryClassIdString(),
this,
pInetLogInfo));
}
//
// Equivalent of no logging case. Do Nothing.
//
return ( NO_ERROR);
} // INET_BASIC_LOG::LogInformation()
DWORD
INET_BASIC_LOG::LogInformation( IN const INETLOG_INFORMATIONW * pInetLogInfo,
OUT LPWSTR pszErrorMessage,
IN OUT LPDWORD lpcchErrorMessage
)
/*++
This functions performs the action of logging information for InetNoLog.
Essentially, does not produce any logging entry at all.
Arguments:
pInetLogInfo pointer to structure containing the Information to be logged.
Returns:
Win32 Error Code
--*/
{
IF_DEBUG( INETLOG) {
DBGPRINTF( ( DBG_CONTEXT,
"%s(%08x)::LogInformation( pInetLogInfo = %08x) called.\n",
QueryClassIdString(),
this,
pInetLogInfo));
}
//
// Equivalent of no logging case. Do Nothing.
//
return ( NO_ERROR);
} // INET_BASIC_LOG::LogInformation()
BOOL
INET_BASIC_LOG::SetLogRecordFormat( IN LPCWSTR pszLogFormat)
/*++
This functions stores the new log record format into buffer and
sets the parsed log format for subsequent output.
Arguments:
pszLogFormat pointer to wide char string containing the
new log record format to be used.
Returns:
TRUE on success and FALSE on failure.
Note:
The log record formats specified can be one of the standard formats.
Or be a totally new custom format. In case of custom formats.
we use a parser to construct the appropriate log format.
For now only the standard formats are allowed, each specified by a name.
--*/
{
CopyUnicodeStringToBuffer( m_rgchLogRecordFormat,
MAX_LOG_RECORD_FORMAT_LEN,
pszLogFormat);
//
// Parse the format if necessary and construct intermediate structures.
// NYI
//
return ( TRUE);
} // INET_BASIC_LOG::SetLogRecordFormat()
VOID
INET_BASIC_LOG::SetServerName( IN LPCWSTR pszServerName)
/*++
This functions stores the server name for the log object. The server
name should be the name of the server on which the given service is running.
Arguments:
pszServerName pointer to Unicode string containing the server name.
Returns:
TRUE on success and FALSE on failure.
--*/
{
DWORD lenDiff = lstrlenW(pszServerName) - lstrlenW(m_rgchServerName);
CopyUnicodeStringToBuffer( m_rgchServerName, MAX_SERVER_NAME_LEN,
pszServerName);
// since we cache the minimum chars required, update the length required.
m_cchMinForLogRecord += lenDiff;
// cached service-server name string
m_cchRgchSSName =
wsprintfA(m_rgchServiceServerName, "%ws%c %ws%c ",
m_rgchServiceName,
DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A,
m_rgchServerName,
DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A
);
wsprintfW(m_rgwchServiceServerName, L"%ws%c %ws%c ",
m_rgchServiceName,
DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A,
m_rgchServerName,
DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A
);
return ;
} // INET_BASIC_LOG::SetServerName()
BOOL
INET_BASIC_LOG::FormatLogInformation(
IN const INETLOG_INFORMATIONA * pInetLogInfo,
IN const SYSTEMTIME * pstCurrentTime,
IN OUT CHAR * pchBuffer,
IN OUT LPDWORD lpcchBuffer
) const
/*++
This function same as the other FormatLogInformation() function just that
this works with CHARs.
NOTE: If any changes are made to this function, also update the other
function.
--*/
{
BOOL fReturn = FALSE;
CHAR rgchDateTime[30]; // buffer to print date
int cchDateTime;
LPCSTR pszUserName = pInetLogInfo->pszClientUserName;
LPCSTR pszOperation = pInetLogInfo->pszOperation;
LPCSTR pszTarget = pInetLogInfo->pszTarget;
LPCSTR pszParameters= pInetLogInfo->pszParameters;
LPCSTR pszServerAddr= pInetLogInfo->pszServerIpAddress;
int cchPartial;
int cchUserName;
int cchOperation;
int cchTarget;
int cchServerAddr;
int cchBytesSent;
int cchBytesRecvd;
int cchParameters;
//
// Format the Date and Time for logging.
// Date & Time fields + log records may need to be localized. NYI
//
DBG_ASSERT( pstCurrentTime != NULL);
cchDateTime = IslFormatDateTime( pstCurrentTime, dftLog, rgchDateTime);
// If strings are empty set them to default values.
if ( IsEmptyStr(pszUserName)) { pszUserName = QueryDefaultUserNameA();}
if ( IsEmptyStr(pszOperation)) { pszOperation = PSZ_UNKNOWN_FIELD_A; }
if ( IsEmptyStr(pszParameters)) { pszParameters= PSZ_UNKNOWN_FIELD_A; }
if ( IsEmptyStr(pszTarget)) { pszTarget = PSZ_UNKNOWN_FIELD_A; }
if ( IsEmptyStr(pszServerAddr)) { pszServerAddr= PSZ_UNKNOWN_FIELD_A; }
//
// Initialize the buffer.
//
DBG_ASSERT( pchBuffer != NULL && lpcchBuffer != NULL);
*pchBuffer = '\0';
switch ( m_logFormat) {
case InternetStdLogFormat: {
CHAR rgchBytesSent[32] = "";
CHAR rgchBytesRecvd[32] = "";
DWORD cchReqd;
DWORD dwError;
dwError = IsLargeIntegerToDecimalChar( &pInetLogInfo->liBytesSent,
rgchBytesSent);
DBG_ASSERT( dwError == NO_ERROR);
dwError = IsLargeIntegerToDecimalChar( &pInetLogInfo->liBytesRecvd,
rgchBytesRecvd);
DBG_ASSERT( dwError == NO_ERROR);
//
// Format is:
// Host UserName Date Time ProcessingTime BytesRecvd BytesSent
// ServiceName ServerName ServiceStatus Win32Status
// Operation Target Parameters
//
cchReqd = (QueryCchMinimum() +
lstrlenA( pInetLogInfo->pszClientHostName) +
(cchUserName = lstrlenA( pszUserName)) +
(cchServerAddr = lstrlenA( pszServerAddr)) +
(cchOperation = lstrlenA( pszOperation)) +
(cchTarget = lstrlenA( pszTarget)) +
(cchParameters = lstrlenA( pszParameters)) +
(cchBytesSent = lstrlenA( rgchBytesSent)) +
(cchBytesRecvd = lstrlenA( rgchBytesRecvd)) +
cchDateTime
);
if ( ( fReturn = ( cchReqd < *lpcchBuffer))) {
DWORD cchStored = 0;
CHAR pszPartial[200];
#if 0
//
// Optimize the common case using lstrcpy() & lstrcat()
//
CHAR chDelimiter = DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A;
cchStored =
wsprintfA(pchBuffer,
"%s%c %s%c %hs%c %hs%c %ws%c %ws%c "
"%s%c %u%c %hs%c %hs%c %u%c %u%c "
"%s%c %s%c %s%c",
pInetLogInfo->pszClientHostName, chDelimiter,
pszUserName, chDelimiter,
rgchDateTime,
m_rgchServiceName, chDelimiter,
m_rgchServerName, chDelimiter,
pszServerAddr, chDelimiter,
pInetLogInfo->msTimeForProcessing, chDelimiter,
rgchBytesRecvd, chDelimiter,
rgchBytesSent, chDelimiter,
pInetLogInfo->dwServiceSpecificStatus, chDelimiter,
pInetLogInfo->dwWin32Status, chDelimiter,
pszOperation, chDelimiter,
pszTarget, chDelimiter,
pszParameters, chDelimiter
);
# endif
// get client host name
lstrcpyA( pchBuffer, pInetLogInfo->pszClientHostName);
// append UserName
cchPartial = lstrlenA( pchBuffer);
CopyLogDelimiter( pchBuffer + cchPartial);
lstrcpyA( pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
pszUserName);
// append DateTime
cchPartial += LEN_PSZ_DELIMITER + cchUserName;
CopyLogDelimiter( pchBuffer + cchPartial);
lstrcpyA( pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
rgchDateTime);
// append Service/ServerName :
// do not append delimiter, since rgchDateTime already has it
cchPartial += cchDateTime;
lstrcpyA(pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
m_rgchServiceServerName);
// append ServerAddr
cchPartial += LEN_PSZ_DELIMITER + m_cchRgchSSName;
lstrcpyA(pchBuffer + cchPartial, pszServerAddr);
// append processing time (in milliseconds)
cchPartial += cchServerAddr;
CopyLogDelimiter( pchBuffer + cchPartial);
cchPartial += LEN_PSZ_DELIMITER +
wsprintfA(pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
"%u",
pInetLogInfo->msTimeForProcessing
);
// append Bytes Received
CopyLogDelimiter( pchBuffer + cchPartial);
lstrcpyA( pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
rgchBytesRecvd);
// append Bytes Sent
cchPartial += cchBytesRecvd + LEN_PSZ_DELIMITER;
CopyLogDelimiter( pchBuffer + cchPartial);
lstrcpyA( pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
rgchBytesSent);
// append Service Status & Win32 Status
cchPartial += cchBytesSent + LEN_PSZ_DELIMITER;
CopyLogDelimiter( pchBuffer + cchPartial);
cchPartial += LEN_PSZ_DELIMITER +
wsprintfA(pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
"%u%s%u",
pInetLogInfo->dwServiceSpecificStatus,
G_PSZ_DELIMITER,
pInetLogInfo->dwWin32Status
);
// append Operation
CopyLogDelimiter( pchBuffer + cchPartial);
lstrcpyA( pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
pszOperation);
// append Target
cchPartial += cchOperation + LEN_PSZ_DELIMITER;
CopyLogDelimiter( pchBuffer + cchPartial);
lstrcpyA( pchBuffer + cchPartial + LEN_PSZ_DELIMITER, pszTarget);
// append Parameters
cchPartial += cchTarget + LEN_PSZ_DELIMITER;
CopyLogDelimiter( pchBuffer + cchPartial);
lstrcpyA( pchBuffer + cchPartial + LEN_PSZ_DELIMITER,
pszParameters);
cchPartial += cchParameters + LEN_PSZ_DELIMITER;
CopyLogDelimiter( pchBuffer + cchPartial);
cchStored = ( cchPartial + LEN_PSZ_DELIMITER);
DBG_ASSERT( cchStored < *lpcchBuffer);
*lpcchBuffer = cchStored;
} else {
SetLastError( ERROR_INSUFFICIENT_BUFFER);
*lpcchBuffer = cchReqd;
}
break;
} // case InternetStdLogFormat:
case NCSALogFormat:
{
CHAR rgchBytesSent[ 32]="";
CHAR rgchServiceStatus[32]="";
DWORD dwError;
DWORD cchStored = 0;
dwError = IsLargeIntegerToDecimalChar( &pInetLogInfo->liBytesSent,
rgchBytesSent);
DBG_ASSERT( dwError == NO_ERROR);
wsprintfA( rgchServiceStatus, "%d", pInetLogInfo->dwServiceSpecificStatus );
if ( 0 != strcmp( pszParameters, "-"))
{
cchStored = wsprintfA(pchBuffer,
"%s - %s [%02d/%s/%d:%02d:%02d:%02d %s] \"%s %s?%s HTTP/1.0\" %s %s",
pInetLogInfo->pszClientHostName,
pszUserName,
pstCurrentTime->wDay,
s_rgchMonths[pstCurrentTime->wMonth-1],
pstCurrentTime->wYear,
pstCurrentTime->wHour,
pstCurrentTime->wMinute,
pstCurrentTime->wSecond,
m_szGMTOffset,
pszOperation,
pszTarget,
pszParameters,
rgchServiceStatus,
rgchBytesSent
);
} else
{
cchStored = wsprintfA(pchBuffer,
"%s - %s [%02d/%s/%d:%02d:%02d:%02d %s] \"%s %s HTTP/1.0\" %s %s",
pInetLogInfo->pszClientHostName,
pszUserName,
pstCurrentTime->wDay,
s_rgchMonths[pstCurrentTime->wMonth-1],
pstCurrentTime->wYear,
pstCurrentTime->wHour,
pstCurrentTime->wMinute,
pstCurrentTime->wSecond,
m_szGMTOffset,
pszOperation,
pszTarget,
rgchServiceStatus,
rgchBytesSent
);
}
*lpcchBuffer = cchStored;
fReturn = TRUE;
}
break; // NCSALogFormat
default:
DBGPRINTF( ( DBG_CONTEXT,
" %d Formatting of log records not implemented.\n",
m_logFormat));
*lpcchBuffer = 0; // Nothing stored.
break;
} // switch()
return ( fReturn);
} // INET_BASIC_LOG::FormatLogInformation()
BOOL
INET_BASIC_LOG::FormatLogInformation(
IN const INETLOG_INFORMATIONW * pInetLogInfo,
IN const SYSTEMTIME * pstCurrentTime,
IN OUT WCHAR * pwchBuffer,
IN OUT LPDWORD lpcchBuffer
) const
/*++
This function formats the log record using the information in pInetLogInfo
and stores the same in pbBuffer.
Arguments:
pInetLogInfo pointer to Log Information structure
pstCurrentTime pointer to SystemTime structure containing the current time
used in generation of the time stamp.
pwchBuffer pointer to byte buffer which will contain the log record
on successful completion of this function.
lpcchBuffer pointer to count of Wide characters stored in buffer
When this function is called it contains the size of buffer
On return it contains the number of bytes of data written.
Returns:
TRUE on success and FALSE on failure.
Use GetLastError() for detailed error code.
--*/
{
BOOL fReturn = FALSE;
CHAR rgchDateTime[30]; // buffer to print date
LPCWSTR pszUserName = pInetLogInfo->pszClientUserName;
LPCWSTR pszOperation = pInetLogInfo->pszOperation;
LPCWSTR pszTarget = pInetLogInfo->pszTarget;
LPCWSTR pszParameters= pInetLogInfo->pszParameters;
LPCWSTR pszServerAddr= pInetLogInfo->pszServerIpAddress;
CHAR chDelimiter = DEFAULT_DELIMITER_CHAR_IN_LOG_RECORD_A;
//
// Format the Date and Time for logging.
// Date & Time fields + log records may need to be localized. NYI
//
DBG_ASSERT( pstCurrentTime != NULL);
IslFormatDateTime( pstCurrentTime, dftLog, rgchDateTime);
// If strings are empty set them to default values.
if ( IsEmptyStr(pszUserName)) { pszUserName = QueryDefaultUserName(); }
if ( IsEmptyStr(pszOperation)) { pszOperation = PSZ_UNKNOWN_FIELD_W; }
if ( IsEmptyStr(pszParameters)) { pszParameters= PSZ_UNKNOWN_FIELD_W; }
if ( IsEmptyStr(pszTarget)) { pszTarget = PSZ_UNKNOWN_FIELD_W; }
if ( IsEmptyStr(pszServerAddr)) { pszServerAddr= PSZ_UNKNOWN_FIELD_W; }
//
// Initialize the buffer.
//
DBG_ASSERT( pwchBuffer != NULL && lpcchBuffer != NULL);
*pwchBuffer = L'\0';
switch ( m_logFormat) {
case InternetStdLogFormat: {
CHAR rgchBytesSent[ 32];
CHAR rgchBytesRecvd[ 32];
DWORD cchReqd;
DWORD dwError;
dwError = IsLargeIntegerToDecimalChar( &pInetLogInfo->liBytesSent,
rgchBytesSent);
DBG_ASSERT( dwError == NO_ERROR);
dwError = IsLargeIntegerToDecimalChar( &pInetLogInfo->liBytesRecvd,
rgchBytesRecvd);
DBG_ASSERT( dwError == NO_ERROR);
//
// Format is:
// Host UserName Date Time ProcessingTime BytesRecvd BytesSent
// ServiceName ServerName ServiceStatus Win32Status
// Operation Target Parameters
//
cchReqd = (QueryCchMinimum() +
lstrlenW( pInetLogInfo->pszClientHostName) +
lstrlenW( pszUserName) +
lstrlenW( pszServerAddr) +
lstrlenW( pszOperation) +
lstrlenW( pszTarget) +
lstrlenW( pszParameters) +
strlen( rgchBytesSent) +
strlen( rgchBytesRecvd) +
strlen( rgchDateTime)
);
if ( ( fReturn = ( cchReqd < *lpcchBuffer))) {
DWORD cchStored = 0;
cchStored =
wsprintfW( pwchBuffer,
#ifndef CHICAGO
L"%ws%c %ws%c %hs%c %hs%ws"
L"%ws%c %d%c %hs%c %hs%c %u%c %u%c "
L"%ws%c %ws%c %ws%c",
#else
L"%s%c %s%c %S%c %S%c %s%c "
L"%s%c %s%c %d%c %S%c %S%c %u%c %u%c "
L"%s%c %s%c %s%c",
#endif
pInetLogInfo->pszClientHostName, chDelimiter,
pszUserName, chDelimiter,
rgchDateTime,
m_rgwchServiceServerName,
pszServerAddr, chDelimiter,
pInetLogInfo->msTimeForProcessing, chDelimiter,
rgchBytesRecvd, chDelimiter,
rgchBytesSent, chDelimiter,
pInetLogInfo->dwServiceSpecificStatus, chDelimiter,
pInetLogInfo->dwWin32Status, chDelimiter,
pszOperation, chDelimiter,
pszTarget, chDelimiter,
pszParameters, chDelimiter
);
DBG_ASSERT( cchStored < *lpcchBuffer);
*lpcchBuffer = cchStored;
} else {
SetLastError( ERROR_INSUFFICIENT_BUFFER);
*lpcchBuffer = cchReqd;
}
break;
} // case InternetStdLogFormat:
case NCSALogFormat:
{
CHAR rgchBytesSent[32]="";
WCHAR rgchServiceStatus[32]=L"";
DWORD dwError;
DWORD cchStored = 0;
dwError = IsLargeIntegerToDecimalChar( &pInetLogInfo->liBytesSent,
rgchBytesSent);
DBG_ASSERT( dwError == NO_ERROR);
wsprintfW( (WCHAR*)rgchServiceStatus, L"%d", pInetLogInfo->dwServiceSpecificStatus );
if ( 0 != lstrcmpW( pszParameters, L"-"))
{
cchStored = wsprintfW(pwchBuffer,
L"%s - %s [%02d/%s/%d:%02d:%02d:%02d %s] \"%s %s?%s HTTP/1.0\" %s %s",
pInetLogInfo->pszClientHostName,
pszUserName,
pstCurrentTime->wDay,
s_rgchMonths[pstCurrentTime->wMonth-1],
pstCurrentTime->wYear,
pstCurrentTime->wHour,
pstCurrentTime->wMinute,
pstCurrentTime->wSecond,
m_szGMTOffset,
pszOperation,
pszTarget,
pszParameters,
rgchServiceStatus,
rgchBytesSent
);
} else
{
cchStored = wsprintfW(pwchBuffer,
L"%s - %s [%02d/%s/%d:%02d:%02d:%02d %s] \"%s %s HTTP/1.0\" %s %s",
pInetLogInfo->pszClientHostName,
pszUserName,
pstCurrentTime->wDay,
s_rgchMonths[pstCurrentTime->wMonth-1],
pstCurrentTime->wYear,
pstCurrentTime->wHour,
pstCurrentTime->wMinute,
pstCurrentTime->wSecond,
m_szGMTOffset,
pszOperation,
pszTarget,
rgchServiceStatus,
rgchBytesSent
);
}
*lpcchBuffer = cchStored;
fReturn = TRUE;
}
break; // NCSALogFormat
default:
DBGPRINTF( ( DBG_CONTEXT,
" %d Formatting of log records not implemented.\n",
m_logFormat));
*lpcchBuffer = 0; // Nothing stored.
break;
} // switch()
return ( fReturn);
} // INET_BASIC_LOG::FormatLogInformation()
# if DBG
VOID
INET_BASIC_LOG::Print( VOID) const
{
DBGPRINTF( ( DBG_CONTEXT,
" Printing %s ( %08x)."
" ServiceName = %ws, ServerName = %ws."
" LogFormat = %d = %ws.\n",
QueryClassIdString(),
this,
m_rgchServiceName,
m_rgchServerName,
m_logFormat,
m_rgchLogRecordFormat));
return;
} // INET_BASIC_LOG::Print()
# endif // DBG
/**************************************************
* Member Functions of class INET_FILE_LOG
**************************************************/
INET_FILE_LOG::INET_FILE_LOG(
IN LPCWSTR pszServiceName,
IN EVENT_LOG * pEventLog,
IN LPCWSTR pszLogFileDirectory,
IN INETLOG_PERIOD ilPeriod, // Default is InetLogNoPeriod
IN INETLOG_FORMAT iLogFormat // default is InternetStdLogFormat
)
/*++
Constructs a file logging object. Log records from server are sent to
file ( or files for periodic logging). The log files are stored in
the logging directory specified in the constructor. The logging period
specifies the manner in which log files are written.
For example: In daily logging mode, a separate log file is generated
for each day.
Arguments:
pszServiceName pointer to string containing the service name.
pszLogFileDirectory pointer to string containing the directory
in which to store the log record.
Returns:
constructed INET_FILE_LOG object.
--*/
: INET_BASIC_LOG( pszServiceName, pEventLog),
m_ilPeriod ( ilPeriod),
m_sequence ( 1),
m_pLogFile ( NULL),
m_cbTotalWritten ( 0),
m_cbSizeForTruncation( MAX_FILE_TRUNCATION_SIZE) // set to default
{
DBG_ASSERT( pszLogFileDirectory != NULL);
CopyUnicodeStringToBuffer( m_rgchLogFileDirectory, MAX_PATH,
pszLogFileDirectory);
InitializeCriticalSection( &m_csLock);
memset( &m_stCurrentFile, 0, sizeof( m_stCurrentFile));
memset( m_rgchLogFileName, 0, sizeof(m_rgchLogFileName));
SetInetLogFormat( iLogFormat );
return;
} // INET_FILE_LOG::INET_FILE_LOG()
INET_FILE_LOG::~INET_FILE_LOG( VOID)
/*++
This frees dynamic memory acquired for INET_FILE_LOG and also closes file
handles which may require to be closed.
Arguments:
None
--*/
{
//
// No Dynamic memory. No action needs to be taken.
//
Lock();
//
// Close Log File handle for the file into which log record is sent.
//
CloseLogFile();
Unlock();
DeleteCriticalSection( &m_csLock);
IF_DEBUG( INETLOG) {
DBGPRINTF((DBG_CONTEXT, "INET_FILE_LOG(%08x) is destroyed\n",
this));
}
return;
} // INET_FILE_LOG::~INET_FILE_LOG()
DWORD
INET_FILE_LOG::LogInformation( IN const INETLOG_INFORMATIONA * pInetLogInfo,
OUT LPSTR pszErrorMessage,
IN OUT LPDWORD lpcchErrorMessage
)
/*++
See comments in INET_FILE_LOG::LogInformation(
IN const INETLOG_INFORMATIONA * );
NOTE:
This function should be similar to that other function, to ensure
correct functionality. Both are similar execept that one uses
ANSI and the other uses UNICODE.
--*/
{
DWORD dwError = NO_ERROR;
SYSTEMTIME stNow;
GetLocalTime( &stNow);
//
// 1. Format the log record to contain the information to be logged.
//
CHAR rgchBuffer[ MAX_LOG_RECORD_LEN];
DWORD cchBufferLen = MAX_LOG_RECORD_LEN - 3;
BOOL fReturn = FormatLogInformation( pInetLogInfo, &stNow,
rgchBuffer, &cchBufferLen);
if ( fReturn) {
//
// Append a new line char at the end of the log record.
//
DBG_ASSERT( cchBufferLen <= MAX_LOG_RECORD_LEN - 3);
rgchBuffer[ cchBufferLen++] = '\r';
rgchBuffer[ cchBufferLen++] = '\n';
rgchBuffer[ cchBufferLen] = '\0'; // terminate the string
//
// 2. Check and change file for writing the log record.
//
// A new log file has to be opened if:
// it is a beginning of new period or
// the file has overflown max size for truncation or
// if this is the first log entry.
//
BOOL fOpenNewFile = ( IsBeginningOfNewPeriod( m_ilPeriod,
&m_stCurrentFile, &stNow) ||
( m_pLogFile == NULL));
BOOL fBackup = ( !fOpenNewFile &&
IsFileOverFlowForCB( cchBufferLen*sizeof( CHAR)));
Lock();
if ( fOpenNewFile || fBackup) {
//
// 0. Check to see if the opening of new file is still required.
// Reason: Some other thread could have done the same before
// this thread cruised through the lock.
// 1. Close existing log file.
// 2. Form the new log file name.
// 3. Open the new log file.
//
BOOL fOpenNewFile2 =
( IsFileOverFlowForCB( cchBufferLen * sizeof( WCHAR)) ||
( IsBeginningOfNewPeriod( m_ilPeriod,
&m_stCurrentFile, &stNow) ||
( m_pLogFile == NULL)));
if ( fOpenNewFile2) {
fReturn = (CloseLogFile() &&
FormNewLogFileName( &stNow, fBackup) &&
OpenLogFile());
if ( fReturn) {
// record the time of opening of this new file
m_stCurrentFile = stNow;
}
}
} // opening new log file or making backups.
//
// 3. Write the log record to file ( using given handle).
//
// TBD: We can move the write outside the critical section
// --> this could be achieved by using ref counts on
// pLogFile object.
//
DBG_ASSERT( m_pLogFile != NULL || !fReturn);
fReturn = (fReturn &&
m_pLogFile->Write((PVOID ) rgchBuffer,
cchBufferLen*sizeof(CHAR))
);
if ( fReturn) {
IncrementBytesWritten( cchBufferLen * sizeof(CHAR));
}
Unlock();
} // successful log record has been written.
if ( !fReturn ) {
dwError = GetLastError();
if ( pszErrorMessage != NULL && lpcchErrorMessage != NULL) {
// For file logging we will not store any error message.
lstrcpyA( pszErrorMessage, "");
*lpcchErrorMessage = 0;
}
}
IF_DEBUG( INETLOG) {
DBGPRINTF( ( DBG_CONTEXT,
"%s(%08x)::LogInformation() returns %d. Error = %d\n",
QueryClassIdString(),
this,
fReturn,
dwError));
}
return ( dwError);
} // INET_FILE_LOG::LogInformation()
DWORD
INET_FILE_LOG::LogInformation( IN const INETLOG_INFORMATIONW * pInetLogInfo,
OUT LPWSTR pszErrorMessage,
IN OUT LPDWORD lpcchErrorMessage
)
/*++
This functions performs the action of logging information for
InetLogtoFile and InetLogToPeriodicFile. It also checks for following:
1) If the file size is greater than specified MAX_TRUNCATION_SIZE,
then it closes the file, renames it as backup file
( after deleting backup) and reopens a new file.
2) If the period the file has been in existence > period specified,
then the current file is closed, new file is opened with the new name
( specified by period) and log record will continue to
be written there. ( This is only for InetLogToPeriodicFile.)
Arguments:
pInetLogInfo pointer to structure containing the
Information to be logged.
Returns:
Win32 Error code
--*/
{
DWORD dwError = NO_ERROR;
SYSTEMTIME stNow;
GetLocalTime( &stNow);
//
// 1. Format the log record to contain the information to be logged.
//
WCHAR rgchBuffer[ MAX_LOG_RECORD_LEN];
DWORD cchBufferLen = MAX_LOG_RECORD_LEN - 3;
BOOL fReturn = FormatLogInformation( pInetLogInfo, &stNow,
rgchBuffer, &cchBufferLen);
if ( fReturn) {
//
// Append a new line char at the end of the log record.
//
DBG_ASSERT( cchBufferLen <= MAX_LOG_RECORD_LEN - 3);
rgchBuffer[ cchBufferLen++] = L'\r';
rgchBuffer[ cchBufferLen++] = L'\n';
rgchBuffer[ cchBufferLen] = L'\0'; // terminate the string
//
// 2. Check and change file handle for writing the log record.
//
// A new log file has to be opened if:
// it is a beginning of new period or
// the file has overflown max size for truncation or
// if this is the first log entry.
//
BOOL fOpenNewFile = ( IsBeginningOfNewPeriod( m_ilPeriod,
&m_stCurrentFile, &stNow) ||
( m_pLogFile == NULL ));
BOOL fBackup = ( !fOpenNewFile &&
IsFileOverFlowForCB( cchBufferLen*sizeof( WCHAR)));
Lock();
if ( fOpenNewFile || fBackup) {
//
// 0. Check to see if the opening of new file is still required.
// Reason: Some other thread could have done the same before
// this thread cruised through the lock.
// 1. Close existing log file.
// 2. Form the new log file name.
// 3. Open the new log file.
//
BOOL fOpenNewFile2 =
( IsFileOverFlowForCB( cchBufferLen * sizeof( WCHAR)) ||
( IsBeginningOfNewPeriod( m_ilPeriod,
&m_stCurrentFile, &stNow) ||
( m_pLogFile == NULL)));
if ( fOpenNewFile2) {
fReturn = (CloseLogFile() &&
FormNewLogFileName( &stNow, fBackup) &&
OpenLogFile());
if ( fReturn) {
// record the time of opening of this new file
m_stCurrentFile = stNow;
}
}
} // opening new log file or making backups.
//
// 3. Write the log record to file ( using given handle).
//
// TBD: We can move the write outside the critical section
// --> this could be achieved by using ref counts on
// pLogFile object.
//
DBG_ASSERT( m_pLogFile != NULL);
fReturn = (fReturn &&
m_pLogFile->Write((PVOID ) rgchBuffer,
cchBufferLen*sizeof(WCHAR))
);
if ( fReturn) {
IncrementBytesWritten( cchBufferLen * sizeof(WCHAR));
}
Unlock();
} // successful log record has been written.
if ( !fReturn ) {
dwError = GetLastError();
if ( pszErrorMessage != NULL && lpcchErrorMessage != NULL) {
// For file logging we will not store any error message.
lstrcpyW( pszErrorMessage, L"");
*lpcchErrorMessage = 0;
}
}
IF_DEBUG( INETLOG) {
DBGPRINTF( ( DBG_CONTEXT,
"%s(%08x)::LogInformation() returns %d. Error = %d\n",
QueryClassIdString(),
this,
fReturn,
dwError));
}
return ( dwError);
} // INET_FILE_LOG::LogInformation()
BOOL
INET_FILE_LOG::OpenLogFile( VOID)
/*++
This functions is called when a new log file needs to be opened.
It forms the name of the log file using service name and logging period
selected. Then it opens a handle for the approapriate file.
The file path is extracted from
<LogFileDirectory>\<LogFileName>
LogFileName is formed before calling this function.
This INET_FILE_LOG object should be locked before calling this function.
Arguments:
None
Returns:
TRUE if successful and FALSE if there is a failure.
Use GetLastError() to get the error codes for error.
--*/
{
BOOL fReturn = TRUE;
WCHAR rgchPath[ MAX_PATH + 1];
if ( m_pLogFile != NULL) {
//
// already a log file is open. return silently
//
DBGPRINTF( ( DBG_CONTEXT,
" Log File %ws is already open ( %08x)\n",
m_rgchLogFileName, m_pLogFile));
DBG_ASSERT( fReturn == TRUE);
} else {
//
// Append log file name to path to form the path of file to be opened.
//
if ( lstrlenW( m_rgchLogFileName) + lstrlenW( m_rgchLogFileDirectory)
>= MAX_PATH) {
SetLastError( ERROR_FILE_NOT_FOUND);
DBG_ASSERT( m_pLogFile == NULL);
fReturn = FALSE;
} else {
#ifndef CHICAGO
// wsprintfW( rgchPath, L"%ws\\%ws",
lstrcpyW( rgchPath, m_rgchLogFileDirectory);
lstrcatW( rgchPath, L"\\");
lstrcatW( rgchPath, m_rgchLogFileName);
IF_DEBUG( INETLOG) {
DBGPRINTF( ( DBG_CONTEXT,
"Opening New File %ws\n", rgchPath));
}
m_pLogFile = ILOG_FILE::OpenFileForAppend(rgchPath);
if (m_pLogFile != NULL) {
m_cbTotalWritten = 0;
#else
CHAR szDirA[MAX_PATH+1];
CHAR szFileA[MAX_PATH+1];
DWORD cch;
*szDirA = '0';
cch = WideCharToMultiByte(CP_ACP,
0,
m_rgchLogFileDirectory,
-1,
szDirA,
sizeof(szDirA)/sizeof(CHAR),
NULL,NULL
);
*szFileA = '0';
cch = WideCharToMultiByte(CP_ACP,
0,
m_rgchLogFileName,
-1,
szFileA,
sizeof(szFileA)/sizeof(CHAR),
NULL,NULL
);
wsprintfA( (LPSTR)rgchPath, "%s\\%s",
szDirA,szFileA);
IF_DEBUG( INETLOG) {
DBGPRINTF( ( DBG_CONTEXT,
"Opening New File %s\n", rgchPath));
}
m_hLogFile = CreateFile((LPCSTR) rgchPath, GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL, // security attributes
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); // template file handle
if ( ( fReturn = (m_hLogFile != INVALID_HANDLE_VALUE))) {
m_cbTotalWritten = 0;
// set the file pointer at the end of the file (append mode)
if ( SetFilePointer( m_hLogFile, 0, NULL, FILE_END)
== (DWORD) -1L) {
DBGPRINTF(( DBG_CONTEXT,
"SetFilePointer(%ws, End) failed. Error=%u\n",
rgchPath, GetLastError()));
fReturn = FALSE;
CloseLogFile();
m_hLogFile = INVALID_HANDLE_VALUE;
}
# endif // CHICAGO
} else {
fReturn = FALSE;
}
}
if ( !fReturn) {
DBGPRINTF( ( DBG_CONTEXT,
" Failed to Open File %ws\\%ws. Error = %u.\n",
m_rgchLogFileDirectory,
m_rgchLogFileName,
GetLastError()));
}
}
return ( fReturn);
} // INET_FILE_LOG::OpenLogFile()
BOOL
INET_FILE_LOG::CloseLogFile( VOID)
/*++
Closes the current log file.
The INET_FILE_LOG object should be locked before calling this function.
If there is no valid file open, then this function silently returns TRUE.
Arguments:
None
Returns:
TRUE on success and FALSE if there is a failure.
--*/
{
BOOL fReturn = TRUE;
if ( m_pLogFile != NULL) {
DWORD dwError = ILOG_FILE::CloseFile( &m_pLogFile);
if ( dwError != NO_ERROR) {
fReturn = FALSE;
SetLastError( dwError);
}
}
return ( fReturn);
} // INET_FILE_LOG::CloseLogFile()
inline DWORD WeekOfMonth(IN LPSYSTEMTIME pstNow)
/*++
Finds the ordinal number of the week of current month.
The numbering of weeks starts from 1 and run through 5 per month (max).
The week number changes only on sundays.
The calculation to be use is:
1 + ( dayOfMonth - 1)/7 + (( dayOfMonth - 1) % 7 > dayOfWeek);
(a) (b) (c) (d)
(a) to set the week numbers to begin from week numbered "1"
(b) used to calculate the rough number of the week on which a given
day falls based on the date.
(c) calculates what is the offset from the start of week for a given
day based on the fact that a week had 7 days.
(d) is the raw day of week given to us.
(c) > (d) indicates that the week is rolling forward and hence
the week count should be offset by 1 more.
--*/
{
DWORD dwTmp;
dwTmp = (pstNow->wDay - 1);
dwTmp = ( 1 + dwTmp/7 + (((dwTmp % 7) > pstNow->wDayOfWeek) ? 1 : 0));
return ( dwTmp);
} // WeekOfMonth()
BOOL
INET_FILE_LOG::FormNewLogFileName(
IN LPSYSTEMTIME pstNow,
IN BOOL fBackup)
/*++
This function that forms the new log file name based on
type of periodic logging done.
Arguments:
pstNow pointer to SystemTime which contains the current time.
fBackup flag indicating if we want to make current file a backup.
Returns:
TRUE on success in forming the name or FALSE if there is any error.
--*/
{
if ( fBackup || m_ilPeriod == InetLogNoPeriod) {
//
// Make current file a backup file. Rename the current file as backup
//
DBGPRINTF( ( DBG_CONTEXT,
" Backing up the log file %ws not implemented.\n",
m_rgchLogFileName));
#ifndef CHICAGO
wsprintfW(m_rgchLogFileName, L"%.6ws%u.%ws",
#else
wsprintfW(m_rgchLogFileName, L"%.6s%u.%s",
#endif
( QueryInetLogFormat() == NCSALogFormat )?
DEFAULT_NCSA_FILE_NAME_W : DEFAULT_LOG_FILE_NAME_W,
m_sequence,
DEFAULT_LOG_FILE_EXTENSION_W);
// cycle sequence number through 1 thru 99.
m_sequence = (m_sequence < 99) ? (m_sequence + 1) : 1;
} else {
//
// switch case and generate a new name
//
WORD wYear = ( pstNow->wYear % 100); // retain just last 2 digits.
switch ( m_ilPeriod) {
case InetLogDaily:
#ifndef CHICAGO
wsprintfW( m_rgchLogFileName, L"%.2ws%02.2u%02u%02u.%ws",
#else
wsprintfW( m_rgchLogFileName, L"%.2s%02.2u%02u%02u.%s",
#endif
( QueryInetLogFormat() == NCSALogFormat )?
DEFAULT_NCSA_FILE_NAME_W : DEFAULT_LOG_FILE_NAME_W,
wYear,
pstNow->wMonth,
pstNow->wDay,
DEFAULT_LOG_FILE_EXTENSION_W);
break;
case InetLogWeekly:
#ifndef CHICAGO
wsprintfW( m_rgchLogFileName, L"%.2ws%02.2u%02u%02u.%ws",
#else
wsprintfW( m_rgchLogFileName, L"%.2s%02.2u%02u%02u.%s",
#endif
( QueryInetLogFormat() == NCSALogFormat )?
DEFAULT_NCSA_FILE_NAME_W : DEFAULT_LOG_FILE_NAME_W,
wYear,
pstNow->wMonth,
WeekOfMonth(pstNow),
DEFAULT_LOG_FILE_EXTENSION_W);
break;
case InetLogMonthly:
#ifndef CHICAGO
wsprintfW( m_rgchLogFileName, L"%.2ws%02u%02u.%ws",
#else
wsprintfW( m_rgchLogFileName, L"%.2s%02u%02u.%s",
#endif
( QueryInetLogFormat() == NCSALogFormat )?
DEFAULT_NCSA_FILE_NAME_W : DEFAULT_LOG_FILE_NAME_W,
wYear,
pstNow->wMonth,
DEFAULT_LOG_FILE_EXTENSION_W);
break;
case InetLogYearly:
#ifndef CHICAGO
wsprintfW( m_rgchLogFileName, L"%.2ws%02u.%ws",
#else
wsprintfW( m_rgchLogFileName, L"%.2s%02u.%s",
#endif
( QueryInetLogFormat() == NCSALogFormat )?
DEFAULT_NCSA_FILE_NAME_W : DEFAULT_LOG_FILE_NAME_W,
wYear,
DEFAULT_LOG_FILE_EXTENSION_W);
break;
default:
DBG_ASSERT( FALSE);
break;
} // switch()
}
IF_DEBUG( INETLOG) {
DBGPRINTF( ( DBG_CONTEXT,
"INET_FILE_LOG(%08x)::FormNewLogFileName() ==> file %ws."
" Returns %d.\n",
this,
m_rgchLogFileName,
TRUE));
}
return ( TRUE);
} // INET_FILE_LOG::FormNewLogFileName()
BOOL
INET_FILE_LOG::GetConfig(OUT PINETLOG_CONFIGURATIONW pLogConfig) const
{
BOOL fReturn;
DBG_ASSERT( pLogConfig != NULL);
fReturn = INET_BASIC_LOG::GetConfig(pLogConfig);
if (fReturn) {
// Store other file specific configuration informtaion
pLogConfig->u.logFile.ilPeriod = m_ilPeriod;
pLogConfig->u.logFile.cbSizeForTruncation = m_cbSizeForTruncation;
pLogConfig->u.logFile.ilFormat = QueryInetLogFormat();
CopyUnicodeStringToBuffer(pLogConfig->u.logFile.rgchLogFileDirectory,
MAX_PATH, m_rgchLogFileDirectory);
}
return (fReturn);
} // INET_FILE_LOG::GetConfig()
# if DBG
VOID
INET_FILE_LOG::Print( VOID) const
{
DBGPRINTF( ( DBG_CONTEXT,
" Printing %s ( %08x).\n",
QueryClassIdString(),
this));
INET_BASIC_LOG::Print();
DBGPRINTF( ( DBG_CONTEXT,
" LogFileDirectory = %ws\n TruncationSize = %u\n",
m_rgchLogFileDirectory, m_cbSizeForTruncation));
DBGPRINTF( ( DBG_CONTEXT,
" Logging Period = %d. Sequence = %d\n"
" LogFile Object = %08x. FileName = %ws. BytesWritten = %u.\n",
m_ilPeriod,
m_sequence,
m_pLogFile,
m_rgchLogFileName,
m_cbTotalWritten));
DBGPRINTF( ( DBG_CONTEXT,
" Critical Section at %08x\n",
&m_csLock));
if ( m_pLogFile != NULL) {
m_pLogFile->Print();
}
return;
} // INET_FILE_LOG::Print()
# endif // DBG
/**************************************************
* Auxiliary Functions
**************************************************/
static BOOL
IsBeginningOfNewPeriod(
IN INETLOG_PERIOD ilPeriod,
IN LPSYSTEMTIME pstCurrentFile,
IN LPSYSTEMTIME pstNow)
/*++
This function checks to see if we are beginning a new period for
a given periodic interval type ( specified using ilPeriod).
Arguments:
ilPeriod INETLOG_PERIOD specifying the periodic interval.
pstCurrentFile pointer to SYSTEMTIME for the current file.
pstNow pointer to SYSTEMTIME for the present time.
Returns:
TRUE if a new period is beginning ( ie pstNow > pstCurrentFile).
FALSE otherwise.
--*/
{
BOOL fNewPeriod = FALSE;
switch ( ilPeriod) {
case InetLogNoPeriod:
break;
case InetLogDaily:
fNewPeriod = fNewPeriod || pstCurrentFile->wDay != pstNow->wDay;
//
// Fall Through
//
case InetLogMonthly:
fNewPeriod = fNewPeriod || pstCurrentFile->wMonth != pstNow->wMonth;
//
// Fall Through
//
case InetLogYearly:
fNewPeriod = fNewPeriod || pstCurrentFile->wYear != pstNow->wYear;
break;
case InetLogWeekly:
fNewPeriod = pstNow->wDayOfWeek == 0;
break;
default:
DBG_ASSERT( FALSE);
break;
} // switch()
return ( fNewPeriod);
} // IsBeginningOfNewPeriod()
/************************ End of File ***********************/