Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

844 lines
23 KiB

#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