|
|
#include "faxrtp.h"
#pragma hdrstop
HINSTANCE g_hModule; HINSTANCE g_hResource; WCHAR FaxReceiveDir[MAX_PATH];
CFaxCriticalSection g_csRoutingStrings;
PFAXROUTEADDFILE FaxRouteAddFile; PFAXROUTEDELETEFILE FaxRouteDeleteFile; PFAXROUTEGETFILE FaxRouteGetFile; PFAXROUTEENUMFILES FaxRouteEnumFiles;
//
// Private callback functions
//
PGETRECIEPTSCONFIGURATION g_pGetRecieptsConfiguration; PFREERECIEPTSCONFIGURATION g_pFreeRecieptsConfiguration;
extern PFAX_EXT_GET_DATA g_pFaxExtGetData; extern PFAX_EXT_FREE_BUFFER g_pFaxExtFreeBuffer;
extern "C" DWORD DllMain( HINSTANCE hInstance, DWORD Reason, LPVOID Context ) { if (Reason == DLL_PROCESS_ATTACH) { g_hModule = hInstance; g_hResource = GetResInstance(hInstance); if(!g_hResource) { return FALSE; } FXSEVENTInitialize(); DisableThreadLibraryCalls( hInstance ); }
if (Reason == DLL_PROCESS_DETACH) { FXSEVENTFree(); HeapCleanup(); FreeResInstance(); } return TRUE; }
BOOL WINAPI FaxRouteInitialize( IN HANDLE HeapHandle, IN PFAX_ROUTE_CALLBACKROUTINES FaxRouteCallbackRoutines ) { PFAX_ROUTE_CALLBACKROUTINES_P pFaxRouteCallbackRoutinesP = (PFAX_ROUTE_CALLBACKROUTINES_P)FaxRouteCallbackRoutines; DEBUG_FUNCTION_NAME(TEXT("FaxRouteInitialize"));
//
// HeapHandle - is unused. We use the process default heap!
//
ZeroMemory (FaxReceiveDir, sizeof(FaxReceiveDir));
FaxRouteAddFile = FaxRouteCallbackRoutines->FaxRouteAddFile; FaxRouteDeleteFile = FaxRouteCallbackRoutines->FaxRouteDeleteFile; FaxRouteGetFile = FaxRouteCallbackRoutines->FaxRouteGetFile; FaxRouteEnumFiles = FaxRouteCallbackRoutines->FaxRouteEnumFiles;
if (!g_csRoutingStrings.InitializeAndSpinCount()) { DebugPrintEx(DEBUG_ERR, L"InitializeAndSpinCount failed with: %ld", GetLastError()); return FALSE; }
if (sizeof (FAX_ROUTE_CALLBACKROUTINES_P) == FaxRouteCallbackRoutines->SizeOfStruct) { //
// This is a special hack - the service is giving us its private callbacks
//
g_pGetRecieptsConfiguration = pFaxRouteCallbackRoutinesP->GetRecieptsConfiguration; g_pFreeRecieptsConfiguration = pFaxRouteCallbackRoutinesP->FreeRecieptsConfiguration; _tcsncpy ( FaxReceiveDir, pFaxRouteCallbackRoutinesP->lptstrFaxQueueDir, ARR_SIZE(FaxReceiveDir)-1 ); } else { //
// The service MUST provide us with the private structure containing CsConfig.
// Otherwise, when we call LoadReceiptsSettings(), we might read half-baked data.
//
ASSERT_FALSE; } Assert (_tcslen (FaxReceiveDir));
PREG_FAX_SERVICE pFaxReg = NULL;
if (!InitializeEventLog(&pFaxReg)) { DebugPrintEx(DEBUG_ERR, L"InitializeEventLog failed with: %ld", GetLastError()); return FALSE; } FreeFaxRegistry(pFaxReg);
InitializeStringTable(); DWORD dwRes = g_DevicesMap.Init (); if (ERROR_SUCCESS != dwRes) { SetLastError (dwRes); return FALSE; }
return TRUE; } // FaxRouteInitialize
BOOL WINAPI FaxRoutePrint( const FAX_ROUTE *FaxRoute, PVOID *FailureData, LPDWORD FailureDataSize ) { CDeviceRoutingInfo *pDevInfo; WCHAR NameBuffer[MAX_PATH]; LPCWSTR FBaseName; WCHAR TiffFileName[MAX_PATH]; DWORD Size; wstring strPrint;
DEBUG_FUNCTION_NAME(TEXT("FaxRoutePrint"));
pDevInfo = g_DevicesMap.GetDeviceRoutingInfo ( FaxRoute->DeviceId ); if (!pDevInfo) { DebugPrintEx (DEBUG_ERR, L"GetDeviceRoutingInfo failed with %ld", GetLastError ()); return FALSE; }
if (!pDevInfo->IsPrintEnabled()) { DebugPrintEx (DEBUG_MSG, L"Routing to printer is disabled for device %ld", FaxRoute->DeviceId); return TRUE; }
Size = sizeof(TiffFileName); if (!FaxRouteGetFile( FaxRoute->JobId, 1, TiffFileName, &Size)) { DebugPrintEx (DEBUG_MSG, L"FaxRouteGetFile failed with %ld", GetLastError ()); return FALSE; }
//
// print the fax in requested to do so
//
//
// NOTICE: If the supplied printer name is an empty string,
// the code retrieves the name of the default printer installed.
//
if (!pDevInfo->GetPrinter(strPrint)) { DebugPrintEx ( DEBUG_ERR, L"GetPrinter failed with %ld", GetLastError ()); return FALSE; }
if (strPrint.length() == 0) { GetProfileString( L"windows", L"device", L",,,", (LPWSTR) NameBuffer, MAX_PATH ); FBaseName = NameBuffer; } else { FBaseName = strPrint.c_str(); } return TiffRoutePrint( TiffFileName, (LPTSTR)FBaseName ); } // FaxRoutePrint
BOOL WINAPI FaxRouteStore( const FAX_ROUTE *FaxRoute, PVOID *FailureData, LPDWORD FailureDataSize ) { CDeviceRoutingInfo *pDevInfo; WCHAR TiffFileName[MAX_PATH * 2]={0}; DWORD Size; LPTSTR FullPath = NULL; DWORD StrCount; wstring strFolder;
DEBUG_FUNCTION_NAME(TEXT("FaxRouteStore"));
pDevInfo = g_DevicesMap.GetDeviceRoutingInfo( FaxRoute->DeviceId ); if (!pDevInfo) { DebugPrintEx (DEBUG_ERR, L"GetDeviceRoutingInfo failed with %ld", GetLastError ()); return FALSE; }
if (!pDevInfo->IsStoreEnabled()) { DebugPrintEx (DEBUG_MSG, L"Routing to folder is disabled for device %ld", FaxRoute->DeviceId); return TRUE; }
//
// Get the file name
//
Size = sizeof(TiffFileName); if (!FaxRouteGetFile( FaxRoute->JobId, 1, TiffFileName, &Size)) { DebugPrintEx (DEBUG_MSG, L"FaxRouteGetFile failed with %ld", GetLastError ()); return FALSE; }
if (!pDevInfo->GetStoreFolder(strFolder)) { DebugPrintEx ( DEBUG_ERR, L"GetStoreFolder failed with %ld", GetLastError ()); return FALSE; }
if (strFolder.length() == 0) { SetLastError (ERROR_BAD_CONFIGURATION); DebugPrintEx (DEBUG_MSG, L"Folder name is empty - no configuration", FaxRoute->DeviceId); FaxLog( FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MIN, 3, MSG_FAX_SAVE_FAILED, TiffFileName, TEXT(""), DWORD2HEX(ERROR_BAD_CONFIGURATION) ); return FALSE; }
StrCount = ExpandEnvironmentStrings( strFolder.c_str(), FullPath, 0 ); FullPath = (LPWSTR) MemAlloc( StrCount * sizeof(WCHAR) ); if (!FullPath) { DebugPrintEx (DEBUG_ERR, L"Failed to allocate %ld bytes", StrCount * sizeof(WCHAR)); return FALSE; }
ExpandEnvironmentStrings( strFolder.c_str(), FullPath, StrCount );
if (lstrlen (FullPath) > MAX_PATH) { DebugPrintEx (DEBUG_ERR, L"Store folder name exceeds MAX_PATH chars"); SetLastError (ERROR_BUFFER_OVERFLOW); FaxLog( FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MIN, 3, MSG_FAX_SAVE_FAILED, TiffFileName, FullPath, DWORD2HEX(ERROR_BUFFER_OVERFLOW) ); MemFree( FullPath ); return FALSE; } //
// If we are moving the fax to the directory that is was received into, do nothing to the file
//
if (_wcsicmp( FullPath, FaxReceiveDir ) == 0) { FaxLog( FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MAX, 2, MSG_FAX_SAVE_SUCCESS, TiffFileName, TiffFileName ); } else if (!FaxMoveFile ( TiffFileName, FullPath )) { MemFree( FullPath ); return FALSE; } MemFree( FullPath ); return TRUE; } // FaxRouteStore
BOOL CreateMailBodyAndSubject ( const FAX_ROUTE *pFaxRoute, LPTSTR *plptstrSubject, LPTSTR *plptstrBody ) /*++
Routine name : CreateMailBodyAndSubject
Routine description:
Creates the SMTP mail subject and body. Used by route by SMTP routing method
Author:
Eran Yariv (EranY), Jul, 2000
Arguments:
pFaxRoute [in] - Routing information plptstrSubject [out] - Allocated subject. Free with LocalFree plptstrBody [out] - Allocated body. Free with LocalFree
Return Value:
TRUE if successful, FALSE otherwise.
--*/ { WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1]; WCHAR wszElapsedTimeStr[512]; WCHAR wszStartTimeStr[512]; LPCTSTR lpctstrRecipientStr; LPCTSTR lpctstrSenderStr; LPDWORD MsgPtr[7]; DWORD MsgCount; LPWSTR lpwstrMsgBody = NULL; LPWSTR lpwstrMsgSubject = NULL;
DEBUG_FUNCTION_NAME(TEXT("CreateMailBodyAndSubject"));
Assert (pFaxRoute && plptstrSubject && plptstrBody); //
// Get computer name
//
DWORD dwComputerNameSize = sizeof (wszComputerName) / sizeof (wszComputerName[0]); if (!GetComputerName (wszComputerName, &dwComputerNameSize)) { DebugPrintEx (DEBUG_ERR, L"GetComputerName failed. ec = %ld", GetLastError ()); goto error; } //
// Create elapsed time string
//
if (!FormatElapsedTimeStr( (FILETIME*)&pFaxRoute->ElapsedTime, wszElapsedTimeStr, ARR_SIZE(wszElapsedTimeStr))) { DebugPrintEx (DEBUG_ERR, L"FormatElapsedTimeStr failed. ec = %ld", GetLastError ()); goto error; } //
// Create start time string
//
SYSTEMTIME stStartTime; FILETIME tmLocalTime; //
// Convert time from UTC to local time zone
//
if (!FileTimeToLocalFileTime( (FILETIME*)&(pFaxRoute->ReceiveTime), &tmLocalTime )) { DebugPrintEx( DEBUG_ERR, TEXT("FileTimeToLocalFileTime failed. (ec: %ld)"), GetLastError()); goto error; } if (!FileTimeToSystemTime( &tmLocalTime, &stStartTime )) { DebugPrintEx( DEBUG_ERR, TEXT("FileTimeToSystemTime failed. (ec: %ld)"), GetLastError()); goto error; } if (!FaxTimeFormat ( LOCALE_SYSTEM_DEFAULT, 0, &stStartTime, NULL, wszStartTimeStr, sizeof (wszStartTimeStr) / sizeof (wszStartTimeStr[0]))) { DebugPrintEx (DEBUG_ERR, L"FaxTimeFormat failed. ec = %ld", GetLastError ()); goto error; } //
// Extract recipient name
//
if (!pFaxRoute->RoutingInfo || !pFaxRoute->RoutingInfo[0]) { if (pFaxRoute->Csid && lstrlen (pFaxRoute->Csid)) { //
// Use CSID as recipient name
//
lpctstrRecipientStr = pFaxRoute->Csid; } else { //
// No routing info and no CSID: use string from resource
//
lpctstrRecipientStr = GetString (IDS_UNKNOWN_RECIPIENT); } } else { //
// Use routing info as recipient name
//
lpctstrRecipientStr = pFaxRoute->RoutingInfo; } //
// Extract sender name
//
if (pFaxRoute->Tsid && lstrlen (pFaxRoute->Tsid)) { //
// Use TSID as sender
//
lpctstrSenderStr = pFaxRoute->Tsid; } else { //
// No TSID: use string from resource
//
lpctstrSenderStr = GetString(IDS_UNKNOWN_SENDER); } //
// Create mail body
//
MsgPtr[0] = (LPDWORD) (lpctstrSenderStr ? lpctstrSenderStr : TEXT("")); // Sender
MsgPtr[1] = (LPDWORD) (pFaxRoute->CallerId ? pFaxRoute->CallerId : TEXT("")); // CallerID
MsgPtr[2] = (LPDWORD) (lpctstrRecipientStr ? lpctstrRecipientStr : TEXT("")); // Recipient name
MsgPtr[3] = (LPDWORD) ULongToPtr((pFaxRoute->PageCount)); // Pages
MsgPtr[4] = (LPDWORD) wszStartTimeStr; // Transmission time
MsgPtr[5] = (LPDWORD) wszElapsedTimeStr; // Transmission duration
MsgPtr[6] = (LPDWORD) (pFaxRoute->DeviceName ? pFaxRoute->DeviceName : TEXT("")); // Device name
MsgCount = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER, g_hResource, MSG_MAIL_MSG_BODY, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), (LPWSTR)&lpwstrMsgBody, 0, (va_list *) MsgPtr ); if (!MsgCount) { DebugPrintEx (DEBUG_ERR, L"FormatMessage failed. ec = %ld", GetLastError ()); goto error; } //
// Create subject line
//
MsgPtr[0] = (LPDWORD) wszComputerName; // Computer name
MsgPtr[1] = (LPDWORD) (lpctstrSenderStr ? lpctstrSenderStr : TEXT("")); // Sender
MsgCount = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER, g_hResource, MSG_SUBJECT_LINE, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), (LPWSTR)&lpwstrMsgSubject, 0, (va_list *) MsgPtr ); if (!MsgCount) { DebugPrintEx (DEBUG_ERR, L"FormatMessage failed. ec = %ld", GetLastError ()); goto error; } //
// Success
//
*plptstrSubject = lpwstrMsgSubject; *plptstrBody = lpwstrMsgBody; return TRUE;
error:
if (lpwstrMsgSubject) { LocalFree (lpwstrMsgSubject); } if (lpwstrMsgBody) { LocalFree (lpwstrMsgBody); } return FALSE; } // CreateMailBodyAndSubject
BOOL MailIncomingJob( const FAX_ROUTE *pFaxRoute, LPCWSTR lpcwstrMailTo, LPCWSTR TiffFileName ) /*++
Routine Description:
Mails a TIFF file using CDO2
Arguments:
pFaxRoute [in] - Routing information lpcwstrMailTo [in] - Email recipient address TiffFileName [in] - Name of TIFF file to mail
Return Value:
TRUE for success, FALSE on error
--*/ { LPWSTR lpwstrMsgBody = NULL; LPWSTR lpwstrMsgSubject = NULL; HRESULT hr; BOOL bRes = FALSE; DWORD dwRes; PFAX_SERVER_RECEIPTS_CONFIGW pReceiptsConfiguration = NULL; DEBUG_FUNCTION_NAME(TEXT("MailIncomingJob"));
//
// Read current mail configuration
//
dwRes = g_pGetRecieptsConfiguration (&pReceiptsConfiguration, TRUE); if (ERROR_SUCCESS != dwRes) { DebugPrintEx( DEBUG_ERR, TEXT("GetRecieptsConfiguration failed with %ld"), dwRes); goto exit; } //
// Get body and subject
//
if (!CreateMailBodyAndSubject (pFaxRoute, &lpwstrMsgSubject, &lpwstrMsgBody)) { dwRes = GetLastError (); DebugPrintEx( DEBUG_ERR, TEXT("CreateMailBodyAndSubject failed with %ld"), dwRes); goto exit; } //
// Send the mail
//
hr = SendMail ( pReceiptsConfiguration->lptstrSMTPFrom, // From
lpcwstrMailTo, // To
lpwstrMsgSubject, // Subject
lpwstrMsgBody, // Body
NULL, // HTML Body
TiffFileName, // Attachment
TEXT("FAX.TIF"), // Attachment description
pReceiptsConfiguration->lptstrSMTPServer, // SMTP server
pReceiptsConfiguration->dwSMTPPort, // SMTP port
(pReceiptsConfiguration->SMTPAuthOption == FAX_SMTP_AUTH_ANONYMOUS) ? CDO_AUTH_ANONYMOUS : (pReceiptsConfiguration->SMTPAuthOption == FAX_SMTP_AUTH_BASIC) ? CDO_AUTH_BASIC : CDO_AUTH_NTLM, // Authentication type
pReceiptsConfiguration->lptstrSMTPUserName, // User name
pReceiptsConfiguration->lptstrSMTPPassword, // Password
pReceiptsConfiguration->hLoggedOnUser); // Logged on user token
if (FAILED(hr)) { DebugPrintEx( DEBUG_ERR, TEXT("SendMail failed. (hr: 0x%08x)"), hr); dwRes = hr; goto exit; }
bRes = TRUE;
exit: if (lpwstrMsgSubject) { LocalFree (lpwstrMsgSubject); } if (lpwstrMsgBody) { LocalFree (lpwstrMsgBody); } if (NULL != pReceiptsConfiguration) { g_pFreeRecieptsConfiguration( pReceiptsConfiguration, TRUE); } if (bRes) { //
// Mail is sent OK
//
FaxLog(FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MAX, 1, MSG_FAX_ROUTE_EMAIL_SUCCESS, TiffFileName); } else { FaxLog(FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MIN, 2, MSG_FAX_ROUTE_EMAIL_FAILED, TiffFileName, DWORD2HEX(dwRes)); }
return bRes; } // MailIncomingJob
BOOL WINAPI FaxRouteEmail( const FAX_ROUTE *pFaxRoute, PVOID *FailureData, LPDWORD FailureDataSize ) { CDeviceRoutingInfo *pDevInfo; WCHAR wszTiffFileName[MAX_PATH]; DWORD dwSize; wstring strSMTP;
DEBUG_FUNCTION_NAME(TEXT("FaxRouteEmail"));
pDevInfo = g_DevicesMap.GetDeviceRoutingInfo( pFaxRoute->DeviceId ); if (!pDevInfo) { DebugPrintEx (DEBUG_ERR, L"Could not retrieve routing info for device %ld. ec = %ld", pFaxRoute->DeviceId, GetLastError ()); return FALSE; } if (!pDevInfo->GetSMTPTo(strSMTP)) { DebugPrintEx ( DEBUG_ERR, L"GetSMTPTo failed with %ld", GetLastError ()); return FALSE; }
if (!pDevInfo->IsEmailEnabled()) { DebugPrintEx (DEBUG_MSG, L"email is disabled for device %ld. Not sending", pFaxRoute->DeviceId); return TRUE; } //
// Get full TIFF file
//
dwSize = sizeof(wszTiffFileName); if (!FaxRouteGetFile( pFaxRoute->JobId, 1, wszTiffFileName, &dwSize)) { DebugPrintEx (DEBUG_ERR, L"FaxRouteGetFile for job %ld. ec = %ld", pFaxRoute->JobId, GetLastError ()); return FALSE; } if (strSMTP.length() == 0) { SetLastError (ERROR_BAD_CONFIGURATION); DebugPrintEx (DEBUG_MSG, L"address is empty for device %ld. Not sending", pFaxRoute->DeviceId);
FaxLog( FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MAX, 2, MSG_FAX_ROUTE_EMAIL_FAILED, wszTiffFileName, DWORD2HEX(ERROR_BAD_CONFIGURATION) ); return FALSE; } //
// Mail the new fax TIFF
//
if (!MailIncomingJob( pFaxRoute, strSMTP.c_str(), wszTiffFileName )) { DebugPrintEx (DEBUG_ERR, L"MailIncomingJob for job %ld. ec = %ld", pFaxRoute->JobId, GetLastError ()); return FALSE; } return TRUE; } // FaxRouteEmail
BOOL WINAPI FaxRouteConfigure( OUT HPROPSHEETPAGE *PropSheetPage ) { return TRUE; }
BOOL WINAPI FaxRouteDeviceEnable( IN LPCWSTR lpcwstrRoutingGuid, IN DWORD dwDeviceId, IN LONG bEnabled ) { DEBUG_FUNCTION_NAME(TEXT("FaxRouteDeviceEnable"));
DWORD MaskBit = GetMaskBit( lpcwstrRoutingGuid ); if (MaskBit == 0) { return FALSE; }
CDeviceRoutingInfo *pDeviceProp = g_DevicesMap.GetDeviceRoutingInfo (dwDeviceId); if (!pDeviceProp) { return FALSE; } DWORD dwRes;
switch (MaskBit) { case LR_EMAIL: if (QUERY_STATUS == bEnabled) { return pDeviceProp->IsEmailEnabled (); } dwRes = pDeviceProp->EnableEmail (bEnabled); break; case LR_STORE: if (QUERY_STATUS == bEnabled) { return pDeviceProp->IsStoreEnabled (); } dwRes = pDeviceProp->EnableStore (bEnabled); break; case LR_PRINT: if (QUERY_STATUS == bEnabled) { return pDeviceProp->IsPrintEnabled (); } dwRes = pDeviceProp->EnablePrint (bEnabled); break; default: ASSERT_FALSE; SetLastError (ERROR_GEN_FAILURE); return FALSE; } SetLastError (dwRes); return ERROR_SUCCESS == dwRes ? TRUE : FALSE; } // FaxRouteDeviceEnable
BOOL WINAPI FaxRouteDeviceChangeNotification( IN DWORD dwDeviceId, IN BOOL bNewDevice ) { DEBUG_FUNCTION_NAME(TEXT("FaxRouteDeviceChangeNotification")); //
// We don't care about new devices now.
// We're using a late-discovery cache so we'll discover the device once
// we route something from it or once it is configured for routing.
//
return TRUE; UNREFERENCED_PARAMETER (dwDeviceId); UNREFERENCED_PARAMETER (bNewDevice); } // FaxRouteDeviceChangeNotification
|