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.
2849 lines
82 KiB
2849 lines
82 KiB
/*
|
|
|
|
|
|
Module Name:
|
|
|
|
faxlog.c
|
|
|
|
Abstract:
|
|
|
|
This is the main fax service activity logging implementation.
|
|
|
|
Author:
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "faxsvc.h"
|
|
#include <string>
|
|
using namespace std;
|
|
|
|
|
|
LOG_STRING_TABLE g_OutboxTable[] =
|
|
{
|
|
{IDS_JOB_ID, FIELD_TYPE_TEXT, 18, NULL },
|
|
{IDS_PARENT_JOB_ID, FIELD_TYPE_TEXT, 18, NULL },
|
|
{IDS_SUBMITED, FIELD_TYPE_DATE, 0, NULL },
|
|
{IDS_SCHEDULED, FIELD_TYPE_DATE, 0, NULL },
|
|
{IDS_STATUS, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_ERROR_DESC, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_ERROR_CODE, FIELD_TYPE_TEXT, 10, NULL },
|
|
{IDS_START_TIME, FIELD_TYPE_DATE, 0, NULL },
|
|
{IDS_END_TIME, FIELD_TYPE_DATE, 0, NULL },
|
|
{IDS_DEVICE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_DIALED_NUMBER, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_CSID, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_TSID, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_PAGES, FIELD_TYPE_FLOAT, 0, NULL },
|
|
{IDS_TOTAL_PAGES, FIELD_TYPE_FLOAT, 0, NULL },
|
|
{IDS_FILE_NAME, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_DOCUMENT, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_FILE_SIZE, FIELD_TYPE_FLOAT, 0, NULL },
|
|
{IDS_RETRIES, FIELD_TYPE_FLOAT, 0, NULL },
|
|
{IDS_COVER_PAGE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SUBJECT, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_NOTE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_USER_NAME, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_NAME, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_FAX_NUMBER, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_COMPANY, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_STREET, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_CITY, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_ZIP, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_COUNTRY, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_TITLE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_DEPARTMENT, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_OFFICE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_H_PHONE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_O_PHONE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_SENDER_E_MAIL, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_NAME, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_FAX_NUMBER, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_COMPANY, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_STREET, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_CITY, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_ZIP, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_COUNTRY, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_TITLE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_DEPARTMENT, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_OFFICE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_H_PHONE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_O_PHONE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_RECIPIENT_E_MAIL, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_BILLING_CODE, FIELD_TYPE_TEXT, 255, NULL }
|
|
};
|
|
|
|
LOG_STRING_TABLE g_InboxTable[] =
|
|
{
|
|
{IDS_STATUS, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_ERROR_DESC, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_ERROR_CODE, FIELD_TYPE_TEXT, 10, NULL },
|
|
{IDS_START_TIME, FIELD_TYPE_DATE, 0, NULL },
|
|
{IDS_END_TIME, FIELD_TYPE_DATE, 0, NULL },
|
|
{IDS_DEVICE, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_FILE_NAME, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_FILE_SIZE, FIELD_TYPE_FLOAT, 0, NULL },
|
|
{IDS_CSID, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_TSID, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_CALLER_ID, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_ROUTING_INFO, FIELD_TYPE_TEXT, 255, NULL },
|
|
{IDS_PAGES, FIELD_TYPE_FLOAT, 0, NULL }
|
|
};
|
|
|
|
const DWORD gc_dwCountInboxTable = (sizeof(g_InboxTable)/sizeof(g_InboxTable[0]));
|
|
const DWORD gc_dwCountOutboxTable = (sizeof(g_OutboxTable)/sizeof(g_OutboxTable[0]));
|
|
|
|
HANDLE g_hInboxActivityLogFile;
|
|
HANDLE g_hOutboxActivityLogFile;
|
|
|
|
static
|
|
wstring
|
|
FilteredLogString (LPCWSTR lpcwstrSrc) throw (exception);
|
|
|
|
static
|
|
VOID
|
|
GetSchemaFileText(wstring &wstrRes) throw (exception);
|
|
|
|
static
|
|
VOID
|
|
GetTableColumnsText(
|
|
LPTSTR ptszTableName,
|
|
wstring &wstrResult
|
|
) throw (exception);
|
|
|
|
static
|
|
BOOL
|
|
GetFaxTimeAsString(
|
|
SYSTEMTIME* pFaxTime,
|
|
wstring &wstrTime
|
|
) throw (exception);
|
|
|
|
static
|
|
BOOL
|
|
GetInboundCommandText(
|
|
PJOB_QUEUE lpJobQueue,
|
|
LPCFSPI_JOB_STATUS lpcFaxStatus,
|
|
wstring &wstrCommandText
|
|
) throw (exception);
|
|
|
|
static
|
|
BOOL
|
|
GetOutboundCommandText(
|
|
PJOB_QUEUE lpJobQueue,
|
|
wstring &wstrCommandText
|
|
) throw (exception);
|
|
|
|
|
|
//
|
|
// Important!! - Always lock g_CsInboundActivityLogging and then g_CsOutboundActivityLogging
|
|
//
|
|
CFaxCriticalSection g_CsInboundActivityLogging;
|
|
CFaxCriticalSection g_CsOutboundActivityLogging;
|
|
|
|
BOOL g_fLogStringTableInit;
|
|
|
|
static DWORD CreateLogFile(DWORD dwFileType, LPCWSTR lpcwstrDBPath, LPHANDLE phFile);
|
|
static BOOL LogFileLimitReached(DWORD dwFileToCheck);
|
|
static DWORD LogFileLimitReachAction(DWORD dwFileType);
|
|
static DWORD DeleteLogActivityFile(DWORD dwFileType);
|
|
static DWORD ReplaceLogActivityFile(DWORD dwFileType);
|
|
static LPTSTR BuildFullFileName( LPCTSTR strPath,LPCTSTR strFileName );
|
|
static BOOL SetFileToCurrentTime(HANDLE hFile);
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: LogInboundActivity()
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 19, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Inserts new record into the Inbox Activity logging table.
|
|
//* Must be called inside critical section CsActivityLogging.
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN ] PJOB_QUEUE lpJobQueue
|
|
//* pointer to the job queue of the inbound job.
|
|
//*
|
|
//* [IN ] LPCFSPI_JOB_STATUS lpcFaxStatus
|
|
//* The status of the recieved job.
|
|
//*
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* TRUE
|
|
//* If no error occured.
|
|
//* FALSE
|
|
//* If an error occured.
|
|
//*********************************************************************************
|
|
BOOL
|
|
LogInboundActivity(
|
|
PJOB_QUEUE lpJobQueue,
|
|
LPCFSPI_JOB_STATUS lpcFaxStatus
|
|
)
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("LogInboundActivity"));
|
|
wstring wstrText;
|
|
DWORD dwBytesWritten;
|
|
|
|
if (!g_ActivityLoggingConfig.bLogIncoming)
|
|
{
|
|
//
|
|
// Inbound activity logging is disabled
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
Assert (g_hInboxActivityLogFile != INVALID_HANDLE_VALUE);
|
|
|
|
try
|
|
{
|
|
if (!GetInboundCommandText(lpJobQueue, lpcFaxStatus, wstrText))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("GetInboundCommandText failed )"));
|
|
dwRes = ERROR_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
dwRes = ERROR_OUTOFMEMORY;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetInboundCommandText caused exception (%S)"),
|
|
ex.what());
|
|
goto exit;
|
|
}
|
|
|
|
if (LogFileLimitReached(ACTIVITY_LOG_INBOX))
|
|
{
|
|
//
|
|
// Time to take action and replace/remove the old log file
|
|
//
|
|
DebugPrintEx(DEBUG_MSG,
|
|
TEXT("Inbox activity log file has reached it's limit. deleting/renaming the old file")
|
|
);
|
|
dwRes = LogFileLimitReachAction(ACTIVITY_LOG_INBOX);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("LogFileLimitReachAction for ACTIVITY_LOG_INBOX failed (ec: %ld). Inbound activity logging will halt"),
|
|
dwRes
|
|
);
|
|
|
|
//
|
|
// May happen if we couldn't create a new log file
|
|
// CreateLogFile() disables logging on failure
|
|
//
|
|
if (!g_ActivityLoggingConfig.bLogIncoming ||
|
|
g_hInboxActivityLogFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
|
|
//
|
|
// try to continue with the old log file
|
|
//
|
|
dwRes = ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!WriteFile( g_hInboxActivityLogFile,
|
|
wstrText.c_str(),
|
|
wstrText.length() * sizeof(WCHAR),
|
|
&dwBytesWritten,
|
|
NULL))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("WriteFile failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
SetLastError (dwRes);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
} // LogInboundActivity
|
|
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: LogOutboundActivity()
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 19, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Inserts new record into the Outbox Activity logging table.
|
|
//* Must be called inside critical section CsActivityLogging..
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN ] PJOB_QUEUE lpJobQueue
|
|
//* pointer to the job queue of the inbound job.
|
|
//*
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* TRUE
|
|
//* If no error occured.
|
|
//* FALSE
|
|
//* If an error occured.
|
|
//*********************************************************************************
|
|
BOOL
|
|
LogOutboundActivity(
|
|
PJOB_QUEUE lpJobQueue
|
|
)
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("LogOutboundActivity"));
|
|
wstring wstrText;
|
|
DWORD dwBytesWritten;
|
|
|
|
if (!g_ActivityLoggingConfig.bLogOutgoing)
|
|
{
|
|
//
|
|
// Outbound activity logging is disabled
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
Assert (g_hOutboxActivityLogFile != INVALID_HANDLE_VALUE);
|
|
try
|
|
{
|
|
if (!GetOutboundCommandText(lpJobQueue, wstrText))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("GetOutboundCommandText failed )"));
|
|
dwRes = ERROR_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
dwRes = ERROR_OUTOFMEMORY;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetOutboundCommandText caused exception (%S)"),
|
|
ex.what());
|
|
goto exit;
|
|
}
|
|
|
|
if (LogFileLimitReached(ACTIVITY_LOG_OUTBOX))
|
|
{
|
|
//
|
|
// Time to take action and replace/remove the old log file
|
|
//
|
|
DebugPrintEx(DEBUG_MSG,
|
|
TEXT("Outbox activity log file has reached it's limit. deleting/renaming the old file")
|
|
);
|
|
dwRes = LogFileLimitReachAction(ACTIVITY_LOG_OUTBOX);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("LogFileLimitReachAction for ACTIVITY_LOG_OUTBOX failed (ec: %ld)."),
|
|
dwRes
|
|
);
|
|
|
|
//
|
|
// May happen if we couldn't create a new log file
|
|
// CreateLogFile() disables logging on failure
|
|
//
|
|
if (!g_ActivityLoggingConfig.bLogOutgoing ||
|
|
g_hOutboxActivityLogFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
|
|
//
|
|
// try to continue with the old log file
|
|
//
|
|
dwRes = ERROR_SUCCESS;
|
|
|
|
}
|
|
}
|
|
|
|
if (!WriteFile( g_hOutboxActivityLogFile,
|
|
wstrText.c_str(),
|
|
wstrText.length() * sizeof(WCHAR),
|
|
&dwBytesWritten,
|
|
NULL))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("WriteFile failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
SetLastError (dwRes);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
} // LogOutboundActivity
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: GetTableColumnsText()
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 19, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Retrieves the first row of the log file (column names).
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN] LPTSTR TableName
|
|
//* Table name, can be Outbox or Inbox.
|
|
//*
|
|
//* [IN] wstring &wstrResult
|
|
//* Output result string
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* None
|
|
//*
|
|
//* NOTE: The function might throw STL string exceptions.
|
|
//*
|
|
//*********************************************************************************
|
|
static
|
|
VOID
|
|
GetTableColumnsText(
|
|
LPTSTR ptszTableName,
|
|
wstring &wstrResult
|
|
) throw (exception)
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("GetTableColumnsText"));
|
|
PLOG_STRING_TABLE Table = NULL;
|
|
DWORD Count = 0;
|
|
|
|
if (!_tcscmp(ptszTableName, INBOX_TABLE))
|
|
{
|
|
Table = g_InboxTable;
|
|
Count = gc_dwCountInboxTable;
|
|
}
|
|
else
|
|
{
|
|
Table = g_OutboxTable;
|
|
Count = gc_dwCountOutboxTable;
|
|
}
|
|
Assert(Table);
|
|
|
|
for (DWORD Index = 0; Index < Count; Index++)
|
|
{
|
|
wstrResult += TEXT("\"");
|
|
wstrResult += Table[Index].String;
|
|
wstrResult += TEXT("\"");
|
|
if (Index < Count - 1)
|
|
{
|
|
wstrResult += TEXT("\t");
|
|
}
|
|
}
|
|
wstrResult += TEXT("\r\n");
|
|
DebugPrintEx(DEBUG_MSG,
|
|
TEXT("First row (Columns names): %s"),
|
|
wstrResult.c_str());
|
|
} // GetTableColumnsText
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: GetSchemaFileText()
|
|
//* Author: Oded Sacher
|
|
//* Date: Jul 25, 2000
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Retrieves the scema.ini text buffer.
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN] wstring &wstrRes
|
|
//* Output result string
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* None.
|
|
//*
|
|
//* NOTE: The function might throw STL string exceptions.
|
|
//*
|
|
//*********************************************************************************
|
|
static
|
|
VOID
|
|
GetSchemaFileText(wstring &wstrRes) throw (exception)
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("GetSchemaFileText"));
|
|
DWORD Index;
|
|
//
|
|
// Inbox table
|
|
//
|
|
wstrRes += TEXT("[");
|
|
wstrRes += ACTIVITY_LOG_INBOX_FILE;
|
|
wstrRes += TEXT("]\r\n");
|
|
|
|
wstrRes += TEXT("ColNameHeader=True\r\n");
|
|
wstrRes += TEXT("Format=TabDelimited\r\n");
|
|
wstrRes += TEXT("CharacterSet=1200\r\n");
|
|
|
|
for (Index = 0; Index < gc_dwCountInboxTable; Index++)
|
|
{
|
|
TCHAR tszTemp[MAX_PATH * 2] = {0};
|
|
if (0 == wcscmp(g_InboxTable[Index].Type, FIELD_TYPE_TEXT))
|
|
{
|
|
_snwprintf(tszTemp,
|
|
ARR_SIZE(tszTemp)-1,
|
|
TEXT("Col%ld=%s %s Width %ld\r\n"),
|
|
Index + 1,
|
|
g_InboxTable[Index].String,
|
|
g_InboxTable[Index].Type,
|
|
g_InboxTable[Index].Size);
|
|
}
|
|
else
|
|
{
|
|
_snwprintf(tszTemp,
|
|
ARR_SIZE(tszTemp)-1,
|
|
TEXT("Col%ld=%s %s\r\n"),
|
|
Index + 1,
|
|
g_InboxTable[Index].String,
|
|
g_InboxTable[Index].Type);
|
|
}
|
|
wstrRes += tszTemp;
|
|
}
|
|
|
|
//
|
|
// Outbox table
|
|
//
|
|
wstrRes += TEXT("[");
|
|
wstrRes += ACTIVITY_LOG_OUTBOX_FILE;
|
|
wstrRes += TEXT("]\r\n");
|
|
|
|
wstrRes += TEXT("ColNameHeader=True\r\n");
|
|
wstrRes += TEXT("Format=TabDelimited\r\n");
|
|
wstrRes += TEXT("CharacterSet=1200\r\n");
|
|
|
|
for (Index = 0; Index < gc_dwCountOutboxTable; Index++)
|
|
{
|
|
TCHAR tszTemp[MAX_PATH * 2] = {0};
|
|
if (0 == wcscmp(g_OutboxTable[Index].Type, FIELD_TYPE_TEXT))
|
|
{
|
|
_snwprintf(tszTemp,
|
|
ARR_SIZE(tszTemp)-1,
|
|
TEXT("Col%ld=%s %s Width %ld\r\n"),
|
|
Index + 1,
|
|
g_OutboxTable[Index].String,
|
|
g_OutboxTable[Index].Type,
|
|
g_OutboxTable[Index].Size);
|
|
}
|
|
else
|
|
{
|
|
_snwprintf(tszTemp,
|
|
ARR_SIZE(tszTemp)-1,
|
|
TEXT("Col%ld=%s %s\r\n"),
|
|
Index + 1,
|
|
g_OutboxTable[Index].String,
|
|
g_OutboxTable[Index].Type);
|
|
}
|
|
wstrRes += tszTemp;
|
|
}
|
|
} // GetSchemaFileText
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: CreateLogDB()
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 19, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Creates the database files. Creates the Schema.ini file.
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN] LPCWSTR lpcwstrDBPath
|
|
//* Pointer to a NULL terminated string contains the DB path.
|
|
//* [OUT] LPHANDLE phInboxFile
|
|
//* Adress of a variable to receive the inbox file handle.
|
|
//* [OUT] LPHANDLE phOutboxFile
|
|
//* Adress of a variable to receive the outbox file handle.
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* Win32 error Code
|
|
//*********************************************************************************
|
|
DWORD
|
|
CreateLogDB (
|
|
LPCWSTR lpcwstrDBPath,
|
|
LPHANDLE phInboxFile,
|
|
LPHANDLE phOutboxFile
|
|
)
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("CreateLogDB"));
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HANDLE hInboxFile = INVALID_HANDLE_VALUE;
|
|
HANDLE hOutboxFile = INVALID_HANDLE_VALUE;
|
|
HANDLE hSchemaFile = INVALID_HANDLE_VALUE;
|
|
WCHAR wszFileName[MAX_PATH] = {0};
|
|
DWORD dwBytesWritten;
|
|
DWORD ec = ERROR_SUCCESS; // Used for Schema.ini
|
|
wstring wstrSchema;
|
|
|
|
INT iCount = 0;
|
|
|
|
Assert (lpcwstrDBPath && phInboxFile && phOutboxFile);
|
|
|
|
if (FALSE == g_fLogStringTableInit)
|
|
{
|
|
dwRes = InitializeLoggingStringTables();
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("Close connection failed (hr: 0x%08x)"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
g_fLogStringTableInit = TRUE;
|
|
}
|
|
|
|
dwRes = IsValidFaxFolder(lpcwstrDBPath);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("IsValidFaxFolder failed for folder : %s (ec=%lu)."),
|
|
lpcwstrDBPath,
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
|
|
//
|
|
// Create the logging files
|
|
//
|
|
dwRes = CreateLogFile(ACTIVITY_LOG_INBOX,lpcwstrDBPath,&hInboxFile);
|
|
if ( ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("CreateLogFile() Failed, for Inbox file. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
dwRes = CreateLogFile(ACTIVITY_LOG_OUTBOX,lpcwstrDBPath,&hOutboxFile);
|
|
if ( ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("CreateLogFile() Failed, for Outbox file. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
*phInboxFile = hInboxFile;
|
|
*phOutboxFile= hOutboxFile;
|
|
|
|
|
|
Assert (ERROR_SUCCESS == dwRes && ERROR_SUCCESS == ec);
|
|
|
|
//
|
|
// Create the Schema.ini file - Function do not fail if not succeeded
|
|
//
|
|
|
|
iCount = _snwprintf (wszFileName,
|
|
MAX_PATH - 1,
|
|
TEXT("%s\\%s"),
|
|
lpcwstrDBPath,
|
|
TEXT("schema.ini"));
|
|
if (0 > iCount)
|
|
{
|
|
//
|
|
// path and file name exceeds MAX_PATH
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("_snwprintf Failed, File name bigger than MAX_PATH"));
|
|
ec = ERROR_BUFFER_OVERFLOW;
|
|
goto exit;
|
|
}
|
|
hSchemaFile = SafeCreateFile(
|
|
wszFileName, // file name
|
|
GENERIC_WRITE, // access mode
|
|
0, // share mode
|
|
NULL, // SD
|
|
CREATE_ALWAYS, // how to create
|
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE == hSchemaFile)
|
|
{
|
|
ec = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CreateFile failed (ec: %ld)"),
|
|
ec);
|
|
goto exit;
|
|
}
|
|
|
|
try
|
|
{
|
|
GetSchemaFileText(wstrSchema);
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
dwRes = ERROR_OUTOFMEMORY;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetSchemaFileText caused exception (%S)"),
|
|
ex.what());
|
|
goto exit;
|
|
}
|
|
|
|
if (!WriteFile( hSchemaFile,
|
|
wstrSchema.c_str(),
|
|
wstrSchema.length() * sizeof(WCHAR),
|
|
&dwBytesWritten,
|
|
NULL))
|
|
{
|
|
ec = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("WriteFile failed (ec: %ld)"),
|
|
ec);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes && ERROR_SUCCESS == ec);
|
|
|
|
exit:
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
if (INVALID_HANDLE_VALUE != hOutboxFile)
|
|
{
|
|
if (!CloseHandle (hOutboxFile))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CloseHandle failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
|
|
if (INVALID_HANDLE_VALUE != hInboxFile)
|
|
{
|
|
if (!CloseHandle (hInboxFile))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CloseHandle failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (INVALID_HANDLE_VALUE != hSchemaFile)
|
|
{
|
|
if (!CloseHandle (hSchemaFile))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CloseHandle failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
|
|
if (ERROR_SUCCESS != ec)
|
|
{
|
|
FaxLog(
|
|
FAXLOG_CATEGORY_INIT,
|
|
FAXLOG_LEVEL_MED,
|
|
2,
|
|
MSG_FAX_ACTIVITY_LOG_FAILED_SCHEMA,
|
|
wszFileName,
|
|
DWORD2DECIMAL(ec)
|
|
);
|
|
}
|
|
return dwRes;
|
|
} // CreateLogDB
|
|
|
|
//*********************************************************************************
|
|
//* Name: InitializeLogging()
|
|
//* Author: Oded Sacher
|
|
//* Date: Jun 26, 2000
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Initializes the Activity Logging. Opens the files.
|
|
//*
|
|
//*
|
|
//* PARAMETERS: None
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* Win32 error code.
|
|
//*********************************************************************************
|
|
DWORD
|
|
InitializeLogging(
|
|
VOID
|
|
)
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("InitializeLogging"));
|
|
|
|
|
|
if (!g_ActivityLoggingConfig.lptstrDBPath)
|
|
{
|
|
//
|
|
// Activity logging is off
|
|
//
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
EnterCriticalSection (&g_CsInboundActivityLogging);
|
|
EnterCriticalSection (&g_CsOutboundActivityLogging);
|
|
|
|
Assert ( (INVALID_HANDLE_VALUE == g_hInboxActivityLogFile) &&
|
|
(INVALID_HANDLE_VALUE == g_hOutboxActivityLogFile) );
|
|
|
|
//
|
|
// Create the logging files
|
|
//
|
|
dwRes = CreateLogDB (g_ActivityLoggingConfig.lptstrDBPath,
|
|
&g_hInboxActivityLogFile,
|
|
&g_hOutboxActivityLogFile);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CreateLogDB failed (hr: 0x%08x)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
LeaveCriticalSection (&g_CsOutboundActivityLogging);
|
|
LeaveCriticalSection (&g_CsInboundActivityLogging);
|
|
return dwRes;
|
|
}
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: GetInboundCommandText()
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 19, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Retrieves a buffer with the new inbound record.
|
|
//* The function allocates the memory for the string that will contain the record.
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN ] PJOB_QUEUE lpJobQueue
|
|
//* pointer to the job queue of the inbound job.
|
|
//*
|
|
//* [IN ] LPCFSPI_JOB_STATUS lpcFaxStatus
|
|
//* The status of the recieved job.
|
|
//*
|
|
//* [OUT] wstring &wstrCommandText
|
|
//* String to compose
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* TRUE
|
|
//* If no error occured.
|
|
//* FALSE
|
|
//* If an error occured.
|
|
//*
|
|
//* NOTE: The function might throw STL string exceptions.
|
|
//*
|
|
//*********************************************************************************
|
|
static
|
|
BOOL
|
|
GetInboundCommandText(
|
|
PJOB_QUEUE lpJobQueue,
|
|
LPCFSPI_JOB_STATUS lpcFaxStatus,
|
|
wstring &wstrCommandText
|
|
) throw (exception)
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("GetInboundCommandText"));
|
|
BOOL bStartTime;
|
|
BOOL bEndTime;
|
|
SYSTEMTIME tmStart;
|
|
SYSTEMTIME tmEnd;
|
|
HINSTANCE hLoadInstance = NULL;
|
|
|
|
Assert (lpJobQueue->JobEntry);
|
|
Assert (lpJobQueue->JobEntry->LineInfo);
|
|
|
|
bStartTime = GetRealFaxTimeAsSystemTime (lpJobQueue->JobEntry, FAX_TIME_TYPE_START, &tmStart);
|
|
if (bStartTime == FALSE)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("GetRealFaxTimeAsSystemTime (Start time) Failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
|
|
bEndTime = GetRealFaxTimeAsSystemTime (lpJobQueue->JobEntry, FAX_TIME_TYPE_END, &tmEnd);
|
|
if (bEndTime == FALSE)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("GetRealFaxTimeAsSystemTime (End time) Failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
|
|
//
|
|
// Status
|
|
//
|
|
wstrCommandText += TEXT("\"");
|
|
switch (lpcFaxStatus->dwJobStatus)
|
|
{
|
|
case FSPI_JS_FAILED:
|
|
wstrCommandText += FilteredLogString(GetString(IDS_FAILED_RECEIVE));
|
|
break;
|
|
|
|
case FSPI_JS_COMPLETED:
|
|
wstrCommandText += FilteredLogString(GetString(FPS_COMPLETED));
|
|
break;
|
|
|
|
case FSPI_JS_ABORTED:
|
|
wstrCommandText += FilteredLogString(GetString(IDS_CANCELED));
|
|
break;
|
|
|
|
default:
|
|
ASSERT_FALSE;
|
|
}
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// ErrorDesc
|
|
//
|
|
wstring wstrErr;
|
|
if (lstrlen(lpJobQueue->JobEntry->ExStatusString))
|
|
{
|
|
//
|
|
// The FSP provided extended status string
|
|
//
|
|
wstrErr = lpJobQueue->JobEntry->ExStatusString;
|
|
}
|
|
else if (lpcFaxStatus->dwExtendedStatus == 0)
|
|
{
|
|
//
|
|
// No extended status
|
|
//
|
|
wstrErr = TEXT(" ");
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Well known extended status
|
|
//
|
|
LPTSTR ResStr = MapFSPIJobExtendedStatusToString(lpcFaxStatus->dwExtendedStatus);
|
|
if (NULL == ResStr)
|
|
{
|
|
ASSERT_FALSE;
|
|
wstrErr = TEXT(" ");
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Unexpected extended status. Extended Status: %ld, Provider: %s"),
|
|
lpcFaxStatus->dwExtendedStatus,
|
|
lpJobQueue->JobEntry->LineInfo->Provider->ImageName);
|
|
}
|
|
else
|
|
{
|
|
if (FSPI_ES_PARTIALLY_RECEIVED == lpcFaxStatus->dwExtendedStatus && // This is a partially received fax
|
|
lstrlen(lpJobQueue->ExStatusString)) // The original extended status string is not empty)
|
|
{
|
|
//
|
|
// copy both the partially received and original extended status strings
|
|
//
|
|
wstrErr = ResStr;
|
|
wstrErr += TEXT(" - ");
|
|
wstrErr += lpJobQueue->ExStatusString;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Copy just the extended status string
|
|
//
|
|
wstrErr = ResStr;
|
|
}
|
|
}
|
|
}
|
|
wstrCommandText += FilteredLogString(wstrErr.c_str());
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Error Code
|
|
//
|
|
if (lpcFaxStatus->dwExtendedStatus == 0)
|
|
{
|
|
wstrErr = TEXT(" ");
|
|
}
|
|
else
|
|
{
|
|
TCHAR tszHexNum [40];
|
|
swprintf(tszHexNum, TEXT("0x%08x"), lpcFaxStatus->dwExtendedStatus);
|
|
wstrErr = tszHexNum;
|
|
}
|
|
wstrCommandText += wstrErr;
|
|
wstrCommandText += TEXT("\"\t");
|
|
|
|
//
|
|
// StartTime
|
|
//
|
|
if (bStartTime)
|
|
{
|
|
wstring wstrTime;
|
|
if (!GetFaxTimeAsString (&tmStart, wstrTime))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetFaxTimeAsString Failed (ec: %ld)"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
wstrCommandText += FilteredLogString(wstrTime.c_str());
|
|
}
|
|
wstrCommandText += TEXT("\t");
|
|
|
|
//
|
|
// EndTime
|
|
//
|
|
if (bEndTime)
|
|
{
|
|
wstring wstrTime;
|
|
|
|
if (!GetFaxTimeAsString (&tmEnd, wstrTime))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetFaxTimeAsString Failed (ec: %ld)"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
wstrCommandText += FilteredLogString(wstrTime.c_str());
|
|
}
|
|
wstrCommandText += TEXT("\t\"");
|
|
|
|
//
|
|
// Device
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->JobEntry->LineInfo->DeviceName);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// File name
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->FileName);
|
|
wstrCommandText += TEXT("\"\t");
|
|
|
|
//
|
|
// File size
|
|
//
|
|
TCHAR tszSize[40];
|
|
swprintf(tszSize,TEXT("%ld"), lpJobQueue->FileSize);
|
|
wstrCommandText += tszSize;
|
|
wstrCommandText += TEXT("\t\"");
|
|
|
|
//
|
|
// CSID
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->JobEntry->LineInfo->Csid);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// TSID
|
|
//
|
|
wstrCommandText += FilteredLogString(lpcFaxStatus->lpwstrRemoteStationId);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Caller ID
|
|
//
|
|
wstrCommandText += FilteredLogString(lpcFaxStatus->lpwstrCallerId);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Routing information
|
|
//
|
|
wstrCommandText += FilteredLogString(lpcFaxStatus->lpwstrRoutingInfo);
|
|
wstrCommandText += TEXT("\"\t");
|
|
|
|
//
|
|
// Pages
|
|
//
|
|
TCHAR tszPages[40];
|
|
swprintf(tszPages,TEXT("%ld"),lpcFaxStatus->dwPageCount);
|
|
wstrCommandText += tszPages;
|
|
wstrCommandText += TEXT("\r\n");
|
|
|
|
DebugPrintEx(DEBUG_MSG,
|
|
TEXT("Inbound SQL statement: %s"),
|
|
wstrCommandText.c_str());
|
|
return TRUE;
|
|
} // GetInboundCommandText
|
|
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: GetOutboundCommandText()
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 19, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Retrieves a buffer that contains the new outbound record.
|
|
//* The function allocates the memory for the buffer that will contain the new record.
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN ] PJOB_QUEUE lpJobQueue
|
|
//* pointer to the job queue of the inbound job.
|
|
//*
|
|
//* [OUT] wstring &wstrCommandText
|
|
//* String to compose
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* TRUE
|
|
//* If no error occured.
|
|
//* FALSE
|
|
//* If an error occured.
|
|
//*
|
|
//* NOTE: The function might throw STL string exceptions.
|
|
//*
|
|
//*********************************************************************************
|
|
static
|
|
BOOL
|
|
GetOutboundCommandText(
|
|
PJOB_QUEUE lpJobQueue,
|
|
wstring &wstrCommandText
|
|
) throw (exception)
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("GetOutboundCommandText"));
|
|
BOOL bStartTime;
|
|
BOOL bEndTime;
|
|
BOOL bOriginalTime;
|
|
BOOL bSubmissionTime;
|
|
SYSTEMTIME tmStart;
|
|
SYSTEMTIME tmEnd;
|
|
SYSTEMTIME tmOriginal;
|
|
SYSTEMTIME tmSubmission;
|
|
HINSTANCE hLoadInstance = NULL;
|
|
|
|
Assert (lpJobQueue->lpParentJob->SubmissionTime);
|
|
Assert (lpJobQueue->lpParentJob->OriginalScheduleTime);
|
|
|
|
bSubmissionTime = FileTimeToSystemTime ((FILETIME*)&(lpJobQueue->lpParentJob->SubmissionTime), &tmSubmission);
|
|
if (bSubmissionTime == FALSE)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("FileTimeToSystemTime (Submission time) Failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
|
|
bOriginalTime = FileTimeToSystemTime ((FILETIME*)&(lpJobQueue->lpParentJob->SubmissionTime), &tmOriginal);
|
|
if (bOriginalTime == FALSE)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("FileTimeToSystemTime (Original schduled time) Failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
|
|
if (NULL != lpJobQueue->JobEntry)
|
|
{
|
|
bStartTime = GetRealFaxTimeAsSystemTime (lpJobQueue->JobEntry, FAX_TIME_TYPE_START, &tmStart);
|
|
if (bStartTime == FALSE)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("GetRealFaxTimeAsSystemTime (Start time) Failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
|
|
bEndTime = GetRealFaxTimeAsSystemTime (lpJobQueue->JobEntry, FAX_TIME_TYPE_END, &tmEnd);
|
|
if (bEndTime == FALSE)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("GetRealFaxTimeAsSystemTime (End time) Failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
|
|
//
|
|
// JobID
|
|
//
|
|
TCHAR tszTemp[100];
|
|
|
|
swprintf(tszTemp,TEXT("0x%016I64x"), lpJobQueue->UniqueId);
|
|
wstrCommandText += TEXT("\"");
|
|
wstrCommandText += tszTemp;
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Parent JobID
|
|
//
|
|
swprintf(tszTemp,TEXT("0x%016I64x"), lpJobQueue->lpParentJob->UniqueId);
|
|
wstrCommandText += tszTemp;
|
|
wstrCommandText += TEXT("\"\t");
|
|
|
|
//
|
|
// Submition time
|
|
//
|
|
if (bSubmissionTime)
|
|
{
|
|
wstring wstrTime;
|
|
if (!GetFaxTimeAsString (&tmSubmission, wstrTime))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetFaxTimeAsString Failed (ec: %ld)"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
wstrCommandText += FilteredLogString(wstrTime.c_str());
|
|
}
|
|
wstrCommandText += TEXT("\t");
|
|
|
|
//
|
|
// Originaly scheduled time
|
|
//
|
|
if (bOriginalTime)
|
|
{
|
|
wstring wstrTime;
|
|
if (!GetFaxTimeAsString (&tmOriginal, wstrTime))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetFaxTimeAsString Failed (ec: %ld)"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
wstrCommandText += FilteredLogString(wstrTime.c_str());
|
|
}
|
|
wstrCommandText += TEXT("\t\"");
|
|
|
|
//
|
|
// Status
|
|
//
|
|
if (JS_CANCELED == lpJobQueue->JobStatus)
|
|
{
|
|
wstrCommandText += FilteredLogString(GetString(IDS_CANCELED));
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
//
|
|
// Fill the empty columns with NULL information
|
|
//
|
|
wstrCommandText += TEXT("\"\t\""); // ErrorDesc
|
|
wstrCommandText += TEXT("\"\t"); // Error Code
|
|
|
|
wstrCommandText += TEXT("\t"); // StartTime
|
|
wstrCommandText += TEXT("\t\""); // EndTime
|
|
|
|
wstrCommandText += TEXT("\"\t\""); // Device
|
|
wstrCommandText += TEXT("\"\t\""); // DialedNumber
|
|
wstrCommandText += TEXT("\"\t\""); // CSID
|
|
wstrCommandText += TEXT("\"\t"); // TSID
|
|
wstrCommandText += TEXT("\t"); // Pages
|
|
}
|
|
else
|
|
{
|
|
// Completed/Failed/Aborted jobs only
|
|
Assert (lpJobQueue->JobEntry);
|
|
Assert (lpJobQueue->JobEntry->LineInfo);
|
|
|
|
switch (lpJobQueue->JobEntry->FSPIJobStatus.dwJobStatus)
|
|
{
|
|
case FSPI_JS_FAILED:
|
|
case FSPI_JS_FAILED_NO_RETRY:
|
|
case FSPI_JS_DELETED:
|
|
wstrCommandText += FilteredLogString(GetString(IDS_FAILED_SEND));
|
|
break;
|
|
|
|
case FSPI_JS_COMPLETED :
|
|
wstrCommandText += FilteredLogString(GetString(FPS_COMPLETED));
|
|
break;
|
|
|
|
case FSPI_JS_ABORTED :
|
|
wstrCommandText += FilteredLogString(GetString(IDS_CANCELED));
|
|
break;
|
|
|
|
default:
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Invalid FSPI_JS status: 0x%08X for JobId: %ld"),
|
|
lpJobQueue->JobStatus,
|
|
lpJobQueue->JobId);
|
|
Assert(FSPI_JS_DELETED == lpJobQueue->JobEntry->FSPIJobStatus.dwJobStatus); // ASSERT_FALSE
|
|
}
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// ErrorDesc
|
|
//
|
|
wstring wstrErr;
|
|
|
|
if (lstrlen(lpJobQueue->JobEntry->ExStatusString))
|
|
{
|
|
//
|
|
// The FSP provided extended status string
|
|
//
|
|
wstrErr = lpJobQueue->JobEntry->ExStatusString;
|
|
}
|
|
else if (lpJobQueue->JobEntry->FSPIJobStatus.dwExtendedStatus == 0)
|
|
{
|
|
//
|
|
// No extended status
|
|
//
|
|
wstrErr = TEXT(" ");
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Well known extended status
|
|
//
|
|
LPTSTR ResStr = MapFSPIJobExtendedStatusToString(lpJobQueue->JobEntry->FSPIJobStatus.dwExtendedStatus);
|
|
if (NULL == ResStr)
|
|
{
|
|
ASSERT_FALSE;
|
|
wstrErr = TEXT(" ");
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Unexpected extended status. Extended Status: %ld, Provider: %s"),
|
|
lpJobQueue->JobEntry->FSPIJobStatus.dwExtendedStatus,
|
|
lpJobQueue->JobEntry->LineInfo->Provider->ImageName);
|
|
}
|
|
else
|
|
{
|
|
wstrErr = ResStr;
|
|
}
|
|
}
|
|
wstrCommandText += FilteredLogString(wstrErr.c_str());
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Error Code
|
|
//
|
|
if (lpJobQueue->JobEntry->FSPIJobStatus.dwExtendedStatus == 0)
|
|
{
|
|
wstrErr = TEXT(" ");
|
|
}
|
|
else
|
|
{
|
|
swprintf(tszTemp, TEXT("0x%08x"), lpJobQueue->JobEntry->FSPIJobStatus.dwExtendedStatus);
|
|
wstrErr = tszTemp;
|
|
}
|
|
wstrCommandText += wstrErr;
|
|
wstrCommandText += TEXT("\"\t");
|
|
|
|
//
|
|
// StartTime
|
|
//
|
|
if (bStartTime)
|
|
{
|
|
wstring wstrTime;
|
|
if (!GetFaxTimeAsString (&tmStart, wstrTime))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetFaxTimeAsString Failed (ec: %ld)"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
wstrCommandText += FilteredLogString(wstrTime.c_str());
|
|
}
|
|
wstrCommandText += TEXT("\t");
|
|
|
|
//
|
|
// EndTime
|
|
//
|
|
if (bEndTime)
|
|
{
|
|
wstring wstrTime;
|
|
if (!GetFaxTimeAsString (&tmEnd, wstrTime))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetFaxTimeAsString Failed (ec: %ld)"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
wstrCommandText += FilteredLogString(wstrTime.c_str());
|
|
}
|
|
wstrCommandText += TEXT("\t\"");
|
|
|
|
//
|
|
// Device
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->JobEntry->LineInfo->DeviceName);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// DialedNumber
|
|
//
|
|
if (wcslen (lpJobQueue->JobEntry->DisplayablePhoneNumber))
|
|
{
|
|
// The canonical number was translated to displayable number
|
|
wstrCommandText += FilteredLogString(lpJobQueue->JobEntry->DisplayablePhoneNumber);
|
|
}
|
|
else
|
|
{
|
|
// The canonical number was not translated
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrFaxNumber);
|
|
}
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// CSID
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->JobEntry->FSPIJobStatus.lpwstrRemoteStationId);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// TSID
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->JobEntry->LineInfo->Tsid);
|
|
wstrCommandText += TEXT("\"\t");
|
|
|
|
//
|
|
// Pages
|
|
//
|
|
swprintf(tszTemp, TEXT("%ld"),lpJobQueue->JobEntry->FSPIJobStatus.dwPageCount);
|
|
wstrCommandText += tszTemp;
|
|
wstrCommandText += TEXT("\t");
|
|
}
|
|
// Common for Canceled and Failed/Completed/Aborted Jobs
|
|
|
|
//
|
|
// Total pages
|
|
//
|
|
swprintf(tszTemp, TEXT("%ld"),lpJobQueue->lpParentJob->PageCount);
|
|
wstrCommandText += tszTemp;
|
|
wstrCommandText += TEXT("\t\"");
|
|
|
|
//
|
|
// Queue file name
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->QueueFileName);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Document
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->JobParamsEx.lptstrDocumentName);
|
|
wstrCommandText += TEXT("\"\t");
|
|
|
|
//
|
|
// File size
|
|
//
|
|
swprintf(tszTemp, TEXT("%ld"), lpJobQueue->lpParentJob->FileSize);
|
|
wstrCommandText += tszTemp;
|
|
wstrCommandText += TEXT("\t");
|
|
|
|
//
|
|
// Retries
|
|
//
|
|
swprintf(tszTemp, TEXT("%d"), lpJobQueue->SendRetries);
|
|
wstrCommandText += tszTemp;
|
|
wstrCommandText += TEXT("\t\"");
|
|
|
|
//
|
|
// ServerCoverPage
|
|
//
|
|
if (lpJobQueue->lpParentJob->CoverPageEx.bServerBased == TRUE)
|
|
{
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->CoverPageEx.lptstrCoverPageFileName);
|
|
}
|
|
else
|
|
{
|
|
wstrCommandText += TEXT(" ");
|
|
}
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Cover page subject
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->CoverPageEx.lptstrSubject);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Cover page note
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->CoverPageEx.lptstrNote);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// User Name
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->UserName);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender Name
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrName);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender FaxNumber
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrFaxNumber);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender Company
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrCompany);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender Street
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrStreetAddress);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender City
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrCity);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender ZipCode
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrZip);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender Country
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrCountry);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender Title
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrTitle);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender Department
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrDepartment);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender Office
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrOfficeLocation);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender HomePhone
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrHomePhone);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender OfficePhone
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrOfficePhone);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Sender EMail
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->lpParentJob->SenderProfile.lptstrEmail);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient Name
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrName);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient FaxNumber
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrFaxNumber);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient Company
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrCompany);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient Street
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrStreetAddress);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient City
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrCity);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient ZipCode
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrZip);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient Country
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrCountry);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient Title
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrTitle);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient Department
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrDepartment);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient Office
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrOfficeLocation);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient HomePhone
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrHomePhone);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient OfficePhone
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrOfficePhone);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// Recipient EMail
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->RecipientProfile.lptstrEmail);
|
|
wstrCommandText += TEXT("\"\t\"");
|
|
|
|
//
|
|
// BillingCode
|
|
//
|
|
wstrCommandText += FilteredLogString(lpJobQueue->SenderProfile.lptstrBillingCode);
|
|
wstrCommandText += TEXT("\"\r\n");
|
|
|
|
DebugPrintEx(DEBUG_MSG,
|
|
TEXT("Outboun SQL statement: %s"),
|
|
wstrCommandText.c_str());
|
|
return TRUE;
|
|
} // GetOutboundCommandText
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: InitializeLoggingStringTables()
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 19, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* Initializes the Activity Logging string tables (Inbox and Outbox)
|
|
//*
|
|
//*
|
|
//* PARAMETERS: None
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* Win32 error code.
|
|
//*********************************************************************************
|
|
DWORD
|
|
InitializeLoggingStringTables(
|
|
VOID
|
|
)
|
|
{
|
|
DWORD i;
|
|
DWORD err = ERROR_SUCCESS;
|
|
HINSTANCE hInstance;
|
|
TCHAR Buffer[MAX_PATH];
|
|
DEBUG_FUNCTION_NAME(TEXT("InitializeLoggingStringTables"));
|
|
|
|
hInstance = GetResInstance(NULL);
|
|
if(!hInstance)
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
for (i=0; i<gc_dwCountInboxTable; i++)
|
|
{
|
|
if (LoadString(hInstance,
|
|
g_InboxTable[i].FieldStringResourceId,
|
|
Buffer,
|
|
sizeof(Buffer)/sizeof(TCHAR)))
|
|
{
|
|
g_InboxTable[i].String = (LPTSTR) MemAlloc( StringSize( Buffer ) );
|
|
if (!g_InboxTable[i].String)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("Failed to allocate memory"));
|
|
err = ERROR_OUTOFMEMORY;
|
|
goto CleanUp;
|
|
}
|
|
else
|
|
{
|
|
_tcscpy( g_InboxTable[i].String, Buffer );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("LoadString failed, Code:%d"),err);
|
|
goto CleanUp;
|
|
}
|
|
}
|
|
|
|
for (i=0; i<gc_dwCountOutboxTable; i++)
|
|
{
|
|
if (LoadString(hInstance,
|
|
g_OutboxTable[i].FieldStringResourceId,
|
|
Buffer,
|
|
sizeof(Buffer)/sizeof(TCHAR)))
|
|
{
|
|
g_OutboxTable[i].String = (LPTSTR) MemAlloc( StringSize( Buffer ) );
|
|
if (!g_OutboxTable[i].String)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("Failed to allocate memory"));
|
|
err = ERROR_OUTOFMEMORY;
|
|
goto CleanUp;
|
|
}
|
|
else
|
|
{
|
|
_tcscpy( g_OutboxTable[i].String, Buffer );
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
err = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("LoadString failed, Code:%d"),err);
|
|
goto CleanUp;
|
|
}
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == err);
|
|
return ERROR_SUCCESS;
|
|
|
|
CleanUp:
|
|
Assert (err != ERROR_SUCCESS);
|
|
|
|
for (i=0; i<gc_dwCountInboxTable; i++)
|
|
{
|
|
MemFree (g_InboxTable[i].String);
|
|
g_InboxTable[i].String = NULL;
|
|
}
|
|
|
|
|
|
for (i=0; i<gc_dwCountOutboxTable; i++)
|
|
{
|
|
MemFree (g_OutboxTable[i].String);
|
|
g_OutboxTable[i].String = NULL;
|
|
}
|
|
return err;
|
|
} // InitializeLoggingStringTables
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************
|
|
//* Name: FilteredLogString
|
|
//* Author: Eran Yariv
|
|
//* Date: Feb 19, 2002
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* This function is used to filter strings that go into the log files.
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN] LPCWSTR lpcwstrSrc
|
|
//* The string to filter
|
|
//*
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* Filtered string
|
|
//*
|
|
//* NOTE: The function might throw STL string exceptions.
|
|
//*
|
|
//*********************************************************************************
|
|
static
|
|
wstring
|
|
FilteredLogString (LPCWSTR lpcwstrSrc) throw (exception)
|
|
{
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("FilteredLogString"));
|
|
|
|
if (!lpcwstrSrc)
|
|
{
|
|
return EMPTY_LOG_STRING;
|
|
}
|
|
wstring wstrResult = lpcwstrSrc;
|
|
//
|
|
// Replace new lines ('\n') with one space (' ')
|
|
//
|
|
wstring::size_type position;
|
|
while (wstring::npos != (position = wstrResult.find (TEXT('\n'))))
|
|
{
|
|
wstrResult[position] = TEXT(' ');
|
|
}
|
|
//
|
|
// Replace carriage returns ('\r') with one space (' ')
|
|
//
|
|
while (wstring::npos != (position = wstrResult.find (TEXT('\r'))))
|
|
{
|
|
wstrResult[position] = TEXT(' ');
|
|
}
|
|
//
|
|
// Replace double quotes ('"') with single quotes ('\'')
|
|
//
|
|
while (wstring::npos != (position = wstrResult.find (TEXT('"'))))
|
|
{
|
|
wstrResult[position] = TEXT('\'');
|
|
}
|
|
//
|
|
// Replace tabs ('"') with 4 spaces (" ")
|
|
//
|
|
while (wstring::npos != (position = wstrResult.find (TEXT('\t'))))
|
|
{
|
|
wstrResult.replace (position, 1, 4, TEXT(' '));
|
|
}
|
|
return wstrResult;
|
|
} // FilteredLogString
|
|
|
|
//*********************************************************************************
|
|
//* Name: GetFaxTimeAsString
|
|
//* Author: Oded Sacher
|
|
//* Date: Oct 19, 1999
|
|
//*********************************************************************************
|
|
//* DESCRIPTION:
|
|
//* This function is used to convert a fax time to a string.
|
|
//*
|
|
//* PARAMETERS:
|
|
//* [IN] SYSTEMTIME* UniversalTime
|
|
//* Fax time
|
|
//*
|
|
//* [OUT] wstring &wstrTime
|
|
//* The output string.
|
|
//*
|
|
//*
|
|
//* RETURN VALUE:
|
|
//* TRUE for success, FALSE otherwise.
|
|
//*
|
|
//* NOTE: The function might throw STL string exceptions.
|
|
//*
|
|
//*********************************************************************************
|
|
static
|
|
BOOL
|
|
GetFaxTimeAsString(
|
|
SYSTEMTIME* UniversalTime,
|
|
wstring &wstrTime) throw (exception)
|
|
{
|
|
DWORD Res;
|
|
SYSTEMTIME LocalTime;
|
|
TIME_ZONE_INFORMATION LocalTimeZone;
|
|
DEBUG_FUNCTION_NAME(TEXT("GetFaxTimeAsString"));
|
|
|
|
Res = GetTimeZoneInformation(&LocalTimeZone);
|
|
if (Res == TIME_ZONE_ID_INVALID)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to get local time zone info (ec: %ld)"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (!SystemTimeToTzSpecificLocalTime( &LocalTimeZone, UniversalTime, &LocalTime))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to convert universal system time to local system time (ec: %ld)"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
}
|
|
TCHAR tszTime[100];
|
|
_stprintf(tszTime,
|
|
TEXT("%d/%d/%d %02d:%02d:%02d"),
|
|
LocalTime.wMonth,
|
|
LocalTime.wDay,
|
|
LocalTime.wYear,
|
|
LocalTime.wHour,
|
|
LocalTime.wMinute,
|
|
LocalTime.wSecond);
|
|
wstrTime = tszTime;
|
|
return TRUE;
|
|
} // GetFaxTimeAsString
|
|
|
|
|
|
static
|
|
DWORD
|
|
CreateLogFile(DWORD dwFileType,LPCWSTR lpcwstrDBPath, LPHANDLE phFile)
|
|
/*++
|
|
|
|
Routine name : CreateLogFile
|
|
|
|
Routine description:
|
|
|
|
According to the selected dwFileType, this function creates an activity log file
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Nov, 2001
|
|
|
|
Arguments:
|
|
|
|
dwFileType [in] - the file to create (inbox or outbox)
|
|
o ACTIVITY_LOG_INBOX for inbox
|
|
o ACTIVITY_LOG_OUTBOX for outbox
|
|
|
|
lpcwstrDBPath [in] - the path to the activity logging folder
|
|
|
|
|
|
phFile [out] - handle to the created log file
|
|
|
|
Return Value:
|
|
|
|
Win32 Error codes
|
|
|
|
|
|
Remarks:
|
|
|
|
|
|
--*/
|
|
{
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
WCHAR wszFileName[MAX_PATH] = {0};
|
|
LARGE_INTEGER FileSize= {0};
|
|
DWORD dwBytesWritten;
|
|
DWORD dwFilePointer;
|
|
int Count = 0 ;
|
|
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("CreateLogFile"));
|
|
|
|
Assert (phFile);
|
|
Assert (lpcwstrDBPath);
|
|
Assert ( (dwFileType==ACTIVITY_LOG_INBOX) || (dwFileType==ACTIVITY_LOG_OUTBOX) );
|
|
|
|
Count = _snwprintf (wszFileName,
|
|
MAX_PATH -1,
|
|
TEXT("%s\\%s"),
|
|
lpcwstrDBPath,
|
|
((dwFileType == ACTIVITY_LOG_INBOX) ? ACTIVITY_LOG_INBOX_FILE : ACTIVITY_LOG_OUTBOX_FILE)
|
|
);
|
|
if (Count < 0)
|
|
{
|
|
//
|
|
// We already checked for max dir path name.
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("_snwprintf Failed, File name bigger than MAX_PATH"));
|
|
dwRes = ERROR_BUFFER_OVERFLOW;
|
|
goto exit;
|
|
|
|
}
|
|
|
|
hFile = SafeCreateFile(
|
|
wszFileName, // file name
|
|
GENERIC_WRITE, // access mode
|
|
FILE_SHARE_READ, // share mode
|
|
NULL, // SD
|
|
OPEN_ALWAYS, // how to create
|
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE == hFile)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CreateFile failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
if (!GetFileSizeEx (hFile, &FileSize))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("GetFileSizeEx failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if (0 == FileSize.QuadPart)
|
|
{
|
|
//
|
|
// New file was created, add UNICODE header
|
|
//
|
|
USHORT UnicodeHeader = 0xfeff;
|
|
|
|
if (!WriteFile( hFile,
|
|
&UnicodeHeader,
|
|
sizeof(UnicodeHeader),
|
|
&dwBytesWritten,
|
|
NULL))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("WriteFile failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Add the first line (Columns name)
|
|
//
|
|
wstring wstrHeader;
|
|
|
|
try
|
|
{
|
|
GetTableColumnsText((dwFileType == ACTIVITY_LOG_INBOX) ? INBOX_TABLE : OUTBOX_TABLE, wstrHeader);
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
dwRes = ERROR_OUTOFMEMORY;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetTableColumnsText caused exception (%S)"),
|
|
ex.what());
|
|
goto exit;
|
|
}
|
|
|
|
if (!WriteFile( hFile,
|
|
wstrHeader.c_str(),
|
|
wstrHeader.length() * sizeof(WCHAR),
|
|
&dwBytesWritten,
|
|
NULL))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("WriteFile failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwFilePointer = SetFilePointer( hFile, // handle to file
|
|
0, // bytes to move pointer
|
|
NULL, // bytes to move pointer
|
|
FILE_END // starting point
|
|
);
|
|
if (INVALID_SET_FILE_POINTER == dwFilePointer)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("SetFilePointer failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
*phFile = hFile;
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
exit:
|
|
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
//
|
|
// The activity logging will halt because we couldn't complete CreateLogFile().
|
|
//
|
|
if (*phFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(*phFile);
|
|
*phFile = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
|
|
if (dwFileType == ACTIVITY_LOG_INBOX)
|
|
{
|
|
g_ActivityLoggingConfig.bLogIncoming = FALSE;
|
|
}
|
|
else
|
|
{
|
|
g_ActivityLoggingConfig.bLogOutgoing = FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// Post an event log entry
|
|
//
|
|
FaxLog(
|
|
FAXLOG_CATEGORY_INIT,
|
|
(dwFileType == ACTIVITY_LOG_INBOX)?FAXLOG_CATEGORY_INBOUND:FAXLOG_CATEGORY_OUTBOUND,
|
|
2,
|
|
MSG_LOGGING_NOT_INITIALIZED,
|
|
g_ActivityLoggingConfig.lptstrDBPath,
|
|
DWORD2DECIMAL(dwRes)
|
|
);
|
|
|
|
if (INVALID_HANDLE_VALUE != hFile)
|
|
{
|
|
if (!CloseHandle (hFile))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CloseHandle failed (ec: %ld)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
}
|
|
return dwRes;
|
|
} // CreateLogFile
|
|
|
|
|
|
static
|
|
BOOL
|
|
LogFileLimitReached(DWORD dwFileToCheck)
|
|
/*++
|
|
|
|
Routine name : LogFileLimitReached
|
|
|
|
Routine description:
|
|
|
|
According to the selected log limit criteria, this function checks to see wheter Activity log file
|
|
have reached it's limit.
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Nov, 2001
|
|
|
|
Arguments:
|
|
|
|
dwFileToCheck [in] - the file to be checked (inbox or outbox)
|
|
o ACTIVITY_LOG_INBOX for inbox
|
|
o ACTIVITY_LOG_OUTBOX for outbox
|
|
|
|
|
|
Return Value:
|
|
|
|
TRUE - if the limit have been reached
|
|
|
|
|
|
Remarks:
|
|
|
|
Call this function only if activity logging is enabled for checked the log file !
|
|
|
|
--*/
|
|
{
|
|
BOOL bActivityLogEnabled = FALSE;
|
|
HANDLE hLogFile = INVALID_HANDLE_VALUE;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("LogFileLimitReached"));
|
|
|
|
Assert ( (dwFileToCheck==ACTIVITY_LOG_INBOX) || (dwFileToCheck==ACTIVITY_LOG_OUTBOX) );
|
|
Assert ( g_ActivityLoggingConfig.bLogIncoming || g_ActivityLoggingConfig.bLogOutgoing );
|
|
|
|
|
|
if ( g_ActivityLoggingConfig.dwLogLimitCriteria == ACTIVITY_LOG_LIMIT_CRITERIA_NONE )
|
|
{
|
|
//
|
|
// activity logging limiting is disabled so no limit checking is needed
|
|
//
|
|
goto Exit;
|
|
}
|
|
|
|
hLogFile = (dwFileToCheck==ACTIVITY_LOG_INBOX)? g_hInboxActivityLogFile : g_hOutboxActivityLogFile;
|
|
|
|
//
|
|
// activity logging is enabled so the handle must be valid
|
|
//
|
|
Assert (hLogFile != INVALID_HANDLE_VALUE);
|
|
|
|
if ( g_ActivityLoggingConfig.dwLogLimitCriteria == ACTIVITY_LOG_LIMIT_CRITERIA_SIZE )
|
|
{
|
|
//
|
|
// Checking limit according to file size in Mbytes
|
|
//
|
|
|
|
|
|
LARGE_INTEGER FileSize = {0};
|
|
|
|
//
|
|
// Check the file size
|
|
//
|
|
if( !GetFileSizeEx( hLogFile,&FileSize ) )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("GetFileSizeEx failed (ec=%ld))"),
|
|
GetLastError()
|
|
);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Compare it to limit
|
|
//
|
|
if (FileSize.QuadPart >= ( g_ActivityLoggingConfig.dwLogSizeLimit * 1I64 * 1024I64 * 1024I64 )) // dwLogSizeLimit is in Mbytes
|
|
{
|
|
//
|
|
// File exceeded the given size limit
|
|
//
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
if ( g_ActivityLoggingConfig.dwLogLimitCriteria == ACTIVITY_LOG_LIMIT_CRITERIA_AGE)
|
|
{
|
|
//
|
|
// Checking limit according to file age in months
|
|
//
|
|
|
|
FILETIME FileTimeCreationTime;
|
|
|
|
//
|
|
// Check file creation time (the creation time is the first time that something was writen into this file)
|
|
//
|
|
if ( !GetFileTime( hLogFile, // handle to file
|
|
&FileTimeCreationTime, // creation time
|
|
NULL, // last access time
|
|
NULL // last write time
|
|
)
|
|
)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("GetFileTime failed (ec=%ld))"),
|
|
GetLastError()
|
|
);
|
|
goto Exit;
|
|
}
|
|
|
|
SYSTEMTIME SystemTimeCreationTime = {0};
|
|
|
|
if ( !FileTimeToSystemTime( &FileTimeCreationTime, // file time to convert
|
|
&SystemTimeCreationTime // receives system time
|
|
)
|
|
)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FileTimeToSystemTime failed (ec=%ld))"),
|
|
GetLastError()
|
|
);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Find out current time
|
|
//
|
|
SYSTEMTIME CurrentTime = {0};
|
|
GetSystemTime(&CurrentTime);
|
|
|
|
//
|
|
// Calculate monthe diff between current time and the time of the first write to the log file.
|
|
//
|
|
DWORD dwMonthDiff = (CurrentTime.wYear - SystemTimeCreationTime.wYear) * 12 + CurrentTime.wMonth - SystemTimeCreationTime.wMonth;
|
|
|
|
if (dwMonthDiff >= g_ActivityLoggingConfig.dwLogAgeLimit)
|
|
{
|
|
//
|
|
// the file reached the age limit
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Bad parameter in g_ActivityLoggingConfig.dwLogLimitCriteria
|
|
//
|
|
ASSERT_FALSE;
|
|
}
|
|
|
|
|
|
Exit:
|
|
return FALSE;
|
|
} // LogFileLimitReached
|
|
|
|
|
|
static
|
|
DWORD
|
|
LogFileLimitReachAction(DWORD dwFileType)
|
|
/*++
|
|
|
|
Routine name : LogFileLimitReachAction
|
|
|
|
Routine description:
|
|
|
|
According to the selected log limit reached action criteria, take the action.
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Nov, 2001
|
|
|
|
Arguments:
|
|
|
|
dwFileType [in] - the file to handle (inbox or outbox)
|
|
o ACTIVITY_LOG_INBOX for inbox
|
|
o ACTIVITY_LOG_OUTBOX for outbox
|
|
|
|
Return Value:
|
|
|
|
TRUE - if the limit have been reached
|
|
|
|
|
|
Remarks:
|
|
|
|
Call this function only if activity logging is enabled *and* Limiting the activity files is enabled
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
HANDLE hLogFile = INVALID_HANDLE_VALUE;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("LogFileLimitReachAction"));
|
|
|
|
//
|
|
// Parameter check (Private function)
|
|
//
|
|
Assert ( (dwFileType==ACTIVITY_LOG_INBOX) || (dwFileType==ACTIVITY_LOG_OUTBOX) );
|
|
Assert ( (dwFileType==ACTIVITY_LOG_INBOX && g_ActivityLoggingConfig.bLogIncoming) ||
|
|
(dwFileType==ACTIVITY_LOG_OUTBOX && g_ActivityLoggingConfig.bLogOutgoing) );
|
|
|
|
Assert ( g_ActivityLoggingConfig.dwLogLimitCriteria != ACTIVITY_LOG_LIMIT_CRITERIA_NONE );
|
|
|
|
hLogFile = (dwFileType==ACTIVITY_LOG_INBOX)? g_hInboxActivityLogFile : g_hOutboxActivityLogFile;
|
|
|
|
if (g_ActivityLoggingConfig.dwLimitReachedAction == ACTIVITY_LOG_LIMIT_REACHED_ACTION_DELETE)
|
|
{
|
|
//
|
|
// Delete the log file
|
|
//
|
|
dwRes = DeleteLogActivityFile(dwFileType);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("DeleteLogActivityFile failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
else
|
|
if (g_ActivityLoggingConfig.dwLimitReachedAction == ACTIVITY_LOG_LIMIT_REACHED_ACTION_COPY)
|
|
{
|
|
//
|
|
// Replace the log file with a fresh copy
|
|
//
|
|
dwRes = ReplaceLogActivityFile(dwFileType);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("DeleteLogActivityFile failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Bad parameter in g_ActivityLoggingConfig.dwLimitReachedAction
|
|
//
|
|
ASSERT_FALSE;
|
|
}
|
|
|
|
Assert(ERROR_SUCCESS == dwRes);
|
|
exit:
|
|
return dwRes;
|
|
} // LogFileLimitReachAction
|
|
|
|
|
|
|
|
static
|
|
DWORD
|
|
DeleteLogActivityFile(DWORD dwFileType)
|
|
/*++
|
|
|
|
Routine name : DeleteLogActivityFile
|
|
|
|
Routine description:
|
|
|
|
According to dwFileType delete the proper activity log file and create a new one
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Nov, 2001
|
|
|
|
Arguments:
|
|
|
|
dwFileType [in] - the file to Delete (inbox or outbox)
|
|
o ACTIVITY_LOG_INBOX for inbox
|
|
o ACTIVITY_LOG_OUTBOX for outbox
|
|
|
|
Return Value:
|
|
|
|
TRUE - if the limit have been reached
|
|
|
|
|
|
Remarks:
|
|
|
|
Call this function only if activity logging is enabled *and* Limiting the activity files is enabled
|
|
|
|
|
|
--*/
|
|
{
|
|
LPWSTR strFullFileName = NULL;
|
|
LPHANDLE phFile=NULL;
|
|
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("DeleteLogActivityFile"));
|
|
|
|
Assert ( (dwFileType==ACTIVITY_LOG_INBOX) || (dwFileType==ACTIVITY_LOG_OUTBOX) );
|
|
Assert ( g_ActivityLoggingConfig.dwLimitReachedAction == ACTIVITY_LOG_LIMIT_REACHED_ACTION_DELETE );
|
|
Assert ( (dwFileType==ACTIVITY_LOG_INBOX && g_ActivityLoggingConfig.bLogIncoming) ||
|
|
(dwFileType==ACTIVITY_LOG_OUTBOX && g_ActivityLoggingConfig.bLogOutgoing) );
|
|
Assert ( g_ActivityLoggingConfig.lptstrDBPath );
|
|
|
|
|
|
strFullFileName = BuildFullFileName(g_ActivityLoggingConfig.lptstrDBPath, ((dwFileType == ACTIVITY_LOG_INBOX)? ACTIVITY_LOG_INBOX_FILE : ACTIVITY_LOG_OUTBOX_FILE) );
|
|
if (NULL == strFullFileName)
|
|
{
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("BuildFullFileName() failed.")
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
phFile = (dwFileType == ACTIVITY_LOG_INBOX) ? &g_hInboxActivityLogFile : &g_hOutboxActivityLogFile ;
|
|
|
|
Assert(*phFile);
|
|
|
|
if (!CloseHandle(*phFile))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CloseHandle failed (ec=%ld)."),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
*phFile = INVALID_HANDLE_VALUE;
|
|
|
|
if (!DeleteFile(strFullFileName))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("DeleteFile failed (ec=%ld)."),
|
|
dwRes
|
|
);
|
|
//
|
|
// Try to roll back and use the old file
|
|
//
|
|
}
|
|
|
|
//
|
|
// Create new logging file
|
|
//
|
|
dwRes = CreateLogFile(dwFileType,g_ActivityLoggingConfig.lptstrDBPath,phFile);
|
|
if ( ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("CreateLogFile() Failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Because the creation time of the file is important for log limit
|
|
// mechanism, we make sure to update the file creation time that may
|
|
// not be updated (Due to file system caching mechanism for example)
|
|
//
|
|
|
|
if (!SetFileToCurrentTime(*phFile))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("SetFileToCurrentTime() Failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
}
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
TEXT("Activity log file was deleted and replaced with fresh copy.")
|
|
);
|
|
|
|
Assert(ERROR_SUCCESS == dwRes);
|
|
exit:
|
|
|
|
|
|
MemFree(strFullFileName);
|
|
return dwRes;
|
|
} // DeleteLogActivityFile
|
|
|
|
|
|
|
|
static
|
|
DWORD
|
|
ReplaceLogActivityFile(DWORD dwFileType)
|
|
/*++
|
|
|
|
Routine name : ReplaceLogActivityFile
|
|
|
|
Routine description:
|
|
|
|
According to dwFileType copy the proper activity log file and create a new one
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Nov, 2001
|
|
|
|
Arguments:
|
|
|
|
dwFileType [in] - the file to Replace (inbox or outbox)
|
|
o ACTIVITY_LOG_INBOX for inbox
|
|
o ACTIVITY_LOG_OUTBOX for outbox
|
|
|
|
Return Value:
|
|
|
|
Win32 error code
|
|
|
|
Remarks:
|
|
|
|
Call this function only if activity logging is enabled *and* Limiting the activity files is enabled
|
|
|
|
|
|
--*/
|
|
{
|
|
SYSTEMTIME LogStartTime = {0};
|
|
SYSTEMTIME LogEndTime = {0};
|
|
|
|
FILETIME FirstWriteTime = {0};
|
|
FILETIME LastWriteTime= {0};
|
|
|
|
LPWSTR strOldFileName = NULL;
|
|
WCHAR strNewFileName[MAX_PATH] = {0};
|
|
LPWSTR strNameTemplate = NULL;
|
|
LPWSTR strNewFullFileName = NULL;
|
|
|
|
LPHANDLE phFile=NULL;
|
|
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("ReplaceLogActivityFile"));
|
|
|
|
Assert ( (dwFileType==ACTIVITY_LOG_INBOX) || (dwFileType==ACTIVITY_LOG_OUTBOX) );
|
|
Assert ( g_ActivityLoggingConfig.dwLimitReachedAction == ACTIVITY_LOG_LIMIT_REACHED_ACTION_COPY );
|
|
Assert ( (dwFileType==ACTIVITY_LOG_INBOX && g_ActivityLoggingConfig.bLogIncoming) ||
|
|
(dwFileType==ACTIVITY_LOG_OUTBOX && g_ActivityLoggingConfig.bLogOutgoing) );
|
|
Assert ( g_ActivityLoggingConfig.lptstrDBPath );
|
|
|
|
|
|
phFile = (dwFileType == ACTIVITY_LOG_INBOX) ? &g_hInboxActivityLogFile : &g_hOutboxActivityLogFile;
|
|
|
|
Assert (INVALID_HANDLE_VALUE != *phFile);
|
|
|
|
//
|
|
// find out the file's first and last write time
|
|
//
|
|
if (!GetFileTime( *phFile, // handle to file
|
|
&FirstWriteTime, // creation time
|
|
NULL, // last access time
|
|
&LastWriteTime // last write time
|
|
)
|
|
)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("GetFileTime() failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
if (!FileTimeToSystemTime( &FirstWriteTime, // file time to convert
|
|
&LogStartTime // receives system time
|
|
)
|
|
)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FileTimeToSystemTime() failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
if (!FileTimeToSystemTime( &LastWriteTime, // file time to convert
|
|
&LogEndTime // receives system time
|
|
)
|
|
)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FileTimeToSystemTime() failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
//
|
|
// build the current log file name
|
|
//
|
|
strOldFileName = BuildFullFileName(g_ActivityLoggingConfig.lptstrDBPath, ((dwFileType == ACTIVITY_LOG_INBOX)? ACTIVITY_LOG_INBOX_FILE : ACTIVITY_LOG_OUTBOX_FILE) );
|
|
if (NULL == strOldFileName)
|
|
{
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("BuildFullFileName() failed.")
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// build the copy file name according to the first and last write times
|
|
//
|
|
strNameTemplate = (dwFileType == ACTIVITY_LOG_INBOX) ? ACTIVITY_LOG_INBOX_FILENAME_TEMPLATE : ACTIVITY_LOG_OUTBOX_FILENAME_TEMPLATE;
|
|
|
|
_snwprintf ( strNewFileName,
|
|
ARR_SIZE(strNewFileName)-1,
|
|
strNameTemplate, // TEXT("??boxLOG %04d-%02d-%02d through %04d-%02d-%02d.txt") ?? - is "In" or "Out"
|
|
LogStartTime.wYear,
|
|
LogStartTime.wMonth,
|
|
LogStartTime.wDay,
|
|
LogEndTime.wYear,
|
|
LogEndTime.wMonth,
|
|
LogEndTime.wDay
|
|
);
|
|
|
|
|
|
|
|
strNewFullFileName = BuildFullFileName(g_ActivityLoggingConfig.lptstrDBPath,strNewFileName);
|
|
if (NULL == strNewFullFileName)
|
|
{
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("BuildFullFileName() failed.")
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
if ( !CloseHandle(*phFile) )
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("CloseHandle() failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
*phFile = INVALID_HANDLE_VALUE;
|
|
|
|
if ( !MoveFile ( strOldFileName, // file name
|
|
strNewFullFileName // new file name
|
|
)
|
|
)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("MoveFileEx() failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
//
|
|
// Try to roll back and use the old file
|
|
//
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Create the logging file that was renamed
|
|
//
|
|
dwRes = CreateLogFile(dwFileType,g_ActivityLoggingConfig.lptstrDBPath,phFile);
|
|
if ( ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("CreateLogFile() Failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Because the creation time of the file is important for log limit
|
|
// mechanism, we make sure to update the file creation time that may
|
|
// not be updated (Due to file system caching mechanism for example)
|
|
//
|
|
|
|
if (!SetFileToCurrentTime(*phFile))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("SetFileToCurrentTime() Failed. (ec=%ld)"),
|
|
dwRes
|
|
);
|
|
}
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
TEXT("Activity log file was copied and replaced with fresh copy.")
|
|
);
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
|
|
MemFree(strOldFileName);
|
|
MemFree(strNewFullFileName);
|
|
return dwRes;
|
|
} // ReplaceLogActivityFile
|
|
|
|
|
|
static
|
|
LPTSTR
|
|
BuildFullFileName( LPCWSTR strPath,
|
|
LPCWSTR strFileName )
|
|
/*++
|
|
|
|
Routine name : BuildFullFileName
|
|
|
|
Routine description:
|
|
|
|
Utility function to concat path and file name. -> strPath\strFileName
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Nov, 2001
|
|
|
|
Arguments:
|
|
|
|
strPath [in] - file path
|
|
strFileName [in] - file name
|
|
|
|
Return Value:
|
|
|
|
the full file name string
|
|
|
|
Remarks:
|
|
|
|
Caller must MemFree the return string
|
|
This function works for UNICODE and ANSI (not for MBCS)
|
|
|
|
|
|
--*/
|
|
{
|
|
LPWSTR strFullFileName = NULL;
|
|
DWORD dwNewNameLen = 0;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("BuildFullFileName"));
|
|
|
|
Assert (strPath && strFileName);
|
|
|
|
dwNewNameLen = wcslen(strPath) + wcslen(strFileName) + 2; // sizeof path\fileName and null terminator
|
|
|
|
strFullFileName = (LPTSTR)MemAlloc(dwNewNameLen * sizeof(TCHAR));
|
|
if (NULL == strFullFileName)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("MemAlloc failed.")
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
strFullFileName[dwNewNameLen-1] = TEXT('\0');
|
|
|
|
//
|
|
// Build the full file name
|
|
//
|
|
_snwprintf (strFullFileName,
|
|
dwNewNameLen-1,
|
|
TEXT("%s\\%s"),
|
|
strPath,
|
|
strFileName);
|
|
|
|
exit:
|
|
return strFullFileName;
|
|
|
|
} // BuildFullFileName
|
|
|
|
|
|
static
|
|
BOOL
|
|
SetFileToCurrentTime(HANDLE hFile)
|
|
/*++
|
|
|
|
Routine name : SetFileToCurrentTime
|
|
|
|
Routine description:
|
|
|
|
Utility function set the creation time of file into current time
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Nov, 2001
|
|
|
|
Arguments:
|
|
|
|
hFile [in] - file handle
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE otherwise
|
|
|
|
Remarks:
|
|
|
|
hFile - must be a valid file handle
|
|
|
|
--*/
|
|
{
|
|
FILETIME ft={0};
|
|
SYSTEMTIME st={0};
|
|
BOOL bRet = TRUE;
|
|
DWORD dwRes;
|
|
DEBUG_FUNCTION_NAME(TEXT("SetFileToCurrentTime"));
|
|
|
|
Assert (INVALID_HANDLE_VALUE != hFile);
|
|
//
|
|
// Because the creation time of the file is important for log limit
|
|
// mechanism, we make sure to update the file creation time that may
|
|
// not be updated (Due to file system caching mechanism for example)
|
|
//
|
|
|
|
|
|
GetSystemTime(&st); // gets current time
|
|
|
|
|
|
bRet = SystemTimeToFileTime(&st, &ft);
|
|
if (FALSE == bRet) // converts to file time format
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("SystemTimeToFileTime failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
bRet = SetFileTime( hFile, // sets creation time for file
|
|
&ft,
|
|
(LPFILETIME) NULL,
|
|
(LPFILETIME) NULL);
|
|
if (FALSE == bRet)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("SetFileTime failed (ec: %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (TRUE == bRet);
|
|
exit:
|
|
return bRet;
|
|
} // SetFileToCurrentTime
|