934 lines
25 KiB
C++
934 lines
25 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1998 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
faxsiren.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
sample routing extension. Sets an event when a fax is received, writes routing data into a log file.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <tchar.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <faxroute.h>
|
||
|
#include <winfax.h>
|
||
|
|
||
|
//
|
||
|
// macros
|
||
|
//
|
||
|
#define ValidString( String ) ((String) ? (String) : L"" )
|
||
|
|
||
|
#ifdef DBG
|
||
|
#define MYDEBUG( parm ) DebugPrint parm
|
||
|
#else
|
||
|
#define MYDEBUG( parm )
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// constants
|
||
|
//
|
||
|
#define ROUTEITGUID L"{5797dee0-e738-11d0-83c0-00c04fb6e984}"
|
||
|
#define FAXSIREN L"FaxSirenEvent"
|
||
|
#define LOGNAME L"%temp%\\ReceiveLog.txt"
|
||
|
#define ININAME L"%temp%\\FaxRoute.ini"
|
||
|
#define SIRENDIR L"FaxSirenFolder"
|
||
|
|
||
|
#define EXTENSIONNAME L"FaxSiren Routing Extension"
|
||
|
#define EXTENSIONFRIENDLYNAME L"Fax Siren"
|
||
|
#define EXTENSIONPATH L"%systemroot%\\system32\\faxsiren.dll"
|
||
|
|
||
|
#define FAXSIRENMETHOD L"Siren"
|
||
|
#define FAXSIRENFRIENDLYNAME L"Routing Siren"
|
||
|
#define FAXSIRENFUNCTION L"RouteIt"
|
||
|
|
||
|
|
||
|
//
|
||
|
// forward declarations
|
||
|
//
|
||
|
BOOL
|
||
|
WriteRoutingInfoIntoIniFile(
|
||
|
LPWSTR TiffFileName,
|
||
|
PFAX_ROUTE FaxRoute
|
||
|
);
|
||
|
|
||
|
BOOL
|
||
|
AppendFileNametoLogFile(
|
||
|
LPWSTR TiffFileName,
|
||
|
PFAX_ROUTE FaxRoute
|
||
|
);
|
||
|
|
||
|
void
|
||
|
DebugPrint(
|
||
|
LPWSTR,
|
||
|
...
|
||
|
);
|
||
|
|
||
|
BOOL WINAPI
|
||
|
ExtensionCallback(
|
||
|
IN HANDLE FaxHandle,
|
||
|
IN LPVOID Context,
|
||
|
IN OUT LPWSTR MethodName,
|
||
|
IN OUT LPWSTR FriendlyName,
|
||
|
IN OUT LPWSTR FunctionName,
|
||
|
IN OUT LPWSTR Guid
|
||
|
);
|
||
|
|
||
|
|
||
|
//
|
||
|
// globals
|
||
|
//
|
||
|
PFAXROUTEADDFILE FaxRouteAddFile;
|
||
|
PFAXROUTEDELETEFILE FaxRouteDeleteFile;
|
||
|
PFAXROUTEGETFILE FaxRouteGetFile;
|
||
|
PFAXROUTEENUMFILES FaxRouteEnumFiles;
|
||
|
PFAXROUTEMODIFYROUTINGDATA FaxRouteModifyRoutingData;
|
||
|
|
||
|
HANDLE hHeap;
|
||
|
HANDLE hReceiveEvent;
|
||
|
CRITICAL_SECTION csRoute;
|
||
|
LPWSTR IniFile = NULL;
|
||
|
LPWSTR LogFile = NULL;
|
||
|
HINSTANCE MyhInstance;
|
||
|
|
||
|
extern "C"
|
||
|
DWORD
|
||
|
DllEntry(
|
||
|
HINSTANCE hInstance,
|
||
|
DWORD Reason,
|
||
|
LPVOID Context
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
dll entrypoint
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
hInstance - Module handle
|
||
|
Reason - Reason for being called
|
||
|
Context - Register context
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE for success, otherwise FALSE.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
switch (Reason) {
|
||
|
case DLL_PROCESS_ATTACH:
|
||
|
MyhInstance = hInstance;
|
||
|
DisableThreadLibraryCalls(hInstance);
|
||
|
break;
|
||
|
case DLL_PROCESS_DETACH:
|
||
|
|
||
|
//
|
||
|
// cleanup
|
||
|
//
|
||
|
if (hReceiveEvent) CloseHandle(hReceiveEvent);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
STDAPI
|
||
|
DllRegisterServer(
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Function for the in-process server to create its registry entries
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
S_OK on success
|
||
|
|
||
|
Notes:
|
||
|
We leverage the DllRegisterServer entrypoint as an easy way to configure
|
||
|
our routing extension for use on the system. Note that the extension doesn't
|
||
|
have any COM code in it per se, but this makes installation much simpler since
|
||
|
the setup code doesn't have to use custom code to setup the routing extension.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HRESULT RetCode;
|
||
|
HMODULE hWinFax;
|
||
|
PFAXREGISTERROUTINGEXTENSION pFaxRegisterRoutingExtension;
|
||
|
PFAXCONNECTFAXSERVER pFaxConnectFaxServer;
|
||
|
PFAXCLOSE pFaxClose;
|
||
|
HANDLE hFax;
|
||
|
DWORD ExtensionCount = 0;
|
||
|
|
||
|
//
|
||
|
// we assume that the routing extension has already been installed into the
|
||
|
// proper location by the setup code.
|
||
|
//
|
||
|
hWinFax = LoadLibrary( L"winfax.dll" );
|
||
|
if (!hWinFax) {
|
||
|
MYDEBUG(( L"LoadLibrary failed, ec = %d\n", GetLastError() ));
|
||
|
RetCode = E_UNEXPECTED;
|
||
|
goto e0;
|
||
|
}
|
||
|
|
||
|
pFaxRegisterRoutingExtension = (PFAXREGISTERROUTINGEXTENSION) GetProcAddress(
|
||
|
hWinFax,
|
||
|
"FaxRegisterRoutingExtensionW" );
|
||
|
pFaxConnectFaxServer = (PFAXCONNECTFAXSERVER) GetProcAddress(
|
||
|
hWinFax,
|
||
|
"FaxConnectFaxServerW" );
|
||
|
pFaxClose = (PFAXCLOSE) GetProcAddress(
|
||
|
hWinFax,
|
||
|
"FaxClose" );
|
||
|
|
||
|
if (!pFaxRegisterRoutingExtension || !pFaxConnectFaxServer || !pFaxClose) {
|
||
|
MYDEBUG(( L"GetProcAddress failed, ec = %d\n", GetLastError() ));
|
||
|
RetCode = E_UNEXPECTED;
|
||
|
goto e1;
|
||
|
}
|
||
|
|
||
|
if (!pFaxConnectFaxServer( NULL, &hFax )) {
|
||
|
MYDEBUG(( L"FaxConnectFaxServer failed, ec = %d\n", GetLastError() ));
|
||
|
RetCode = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
goto e1;
|
||
|
}
|
||
|
|
||
|
if (!pFaxRegisterRoutingExtension(
|
||
|
hFax,
|
||
|
EXTENSIONNAME,
|
||
|
EXTENSIONFRIENDLYNAME,
|
||
|
EXTENSIONPATH,
|
||
|
ExtensionCallback,
|
||
|
(LPVOID) &ExtensionCount
|
||
|
)) {
|
||
|
MYDEBUG(( L"FaxRegisterRoutingExtension failed, ec = %d\n", GetLastError() ));
|
||
|
RetCode = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
goto e2;
|
||
|
}
|
||
|
|
||
|
RetCode = S_OK;
|
||
|
|
||
|
e2:
|
||
|
pFaxClose( hFax );
|
||
|
e1:
|
||
|
FreeLibrary( hWinFax );
|
||
|
e0:
|
||
|
return RetCode;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL WINAPI
|
||
|
ExtensionCallback(
|
||
|
IN HANDLE FaxHandle,
|
||
|
IN LPVOID Context,
|
||
|
IN OUT LPWSTR MethodName,
|
||
|
IN OUT LPWSTR FriendlyName,
|
||
|
IN OUT LPWSTR FunctionName,
|
||
|
IN OUT LPWSTR Guid
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Callback function for adding our routing extensions
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if we added another extension, FALSE if we're done adding extensions
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PDWORD ExtensionCount = (PDWORD) Context;
|
||
|
|
||
|
//
|
||
|
// since we only have one extension, this is a really simple function
|
||
|
// --we don't really need the context data above, it's just here to
|
||
|
// illustrate what you might use the context data for.
|
||
|
//
|
||
|
|
||
|
if (ExtensionCount) {
|
||
|
MYDEBUG(( L"ExtensionCallback called for extension %d\n", *ExtensionCount ));
|
||
|
} else {
|
||
|
MYDEBUG(( L"context data is NULL, can't continue\n", *ExtensionCount ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (*ExtensionCount != 0) {
|
||
|
//
|
||
|
// we've added all of our methods, return FALSE to signify that we're done
|
||
|
//
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
wcscpy(MethodName, FAXSIRENMETHOD );
|
||
|
wcscpy(FriendlyName, FAXSIRENFRIENDLYNAME );
|
||
|
wcscpy(FunctionName, FAXSIRENFUNCTION );
|
||
|
wcscpy(Guid, ROUTEITGUID );
|
||
|
|
||
|
*ExtensionCount += 1;
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// required exports
|
||
|
//
|
||
|
|
||
|
|
||
|
BOOL WINAPI
|
||
|
FaxRouteInitialize(
|
||
|
IN HANDLE HeapHandle,
|
||
|
IN PFAX_ROUTE_CALLBACKROUTINES FaxRouteCallbackRoutines
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This functions is called by the fax service to initialize the routing extension. This function
|
||
|
should only be called once per instantiation of the fax service
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
HeapHandle - Heap handle for memory all allocations
|
||
|
FaxRouteCallbackRoutines - structure containing callback functions
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE for success, otherwise FALSE.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
DWORD dwNeeded;
|
||
|
SECURITY_DESCRIPTOR sd;
|
||
|
SECURITY_ATTRIBUTES sa;
|
||
|
|
||
|
//
|
||
|
// make sure we can understand the structure
|
||
|
//
|
||
|
if ( FaxRouteCallbackRoutines->SizeOfStruct < sizeof(FAX_ROUTE_CALLBACKROUTINES) ) {
|
||
|
MYDEBUG ((L"The passed in SizeOfStruct (%d) is smaller than expected (%d) ",
|
||
|
FaxRouteCallbackRoutines->SizeOfStruct,
|
||
|
sizeof(FAX_ROUTE_CALLBACKROUTINES) ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
hHeap = HeapHandle;
|
||
|
FaxRouteAddFile = FaxRouteCallbackRoutines->FaxRouteAddFile;
|
||
|
FaxRouteDeleteFile = FaxRouteCallbackRoutines->FaxRouteDeleteFile;
|
||
|
FaxRouteGetFile = FaxRouteCallbackRoutines->FaxRouteGetFile;
|
||
|
FaxRouteEnumFiles = FaxRouteCallbackRoutines->FaxRouteEnumFiles;
|
||
|
FaxRouteModifyRoutingData = FaxRouteCallbackRoutines->FaxRouteModifyRoutingData;
|
||
|
|
||
|
InitializeCriticalSection( &csRoute );
|
||
|
|
||
|
//
|
||
|
// create a named event
|
||
|
//
|
||
|
// note that we need to create a security descriptor with a NULL DACL (all access) because we want the named
|
||
|
// event to be opened by programs that might not be running in same context as the fax service
|
||
|
//
|
||
|
if ( !InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION) ) {
|
||
|
MYDEBUG(( L"InitializeSecurityDecriptor failed, ec = %d\n", GetLastError() ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if ( !SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE) ) {
|
||
|
MYDEBUG(( L"SetSecurityDescriptorDacl failed, ec = %d\n", GetLastError() ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||
|
sa.lpSecurityDescriptor = &sd;
|
||
|
sa.bInheritHandle = FALSE;
|
||
|
hReceiveEvent = CreateEvent(&sa,FALSE,FALSE,FAXSIREN);
|
||
|
|
||
|
if (!hReceiveEvent) {
|
||
|
if (GetLastError() != ERROR_ALREADY_EXISTS) {
|
||
|
MYDEBUG (( L"CreateEvent failed, ec = %d\n", GetLastError() ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get path to files for logging, etc.
|
||
|
//
|
||
|
dwNeeded = ExpandEnvironmentStrings(ININAME,IniFile,0);
|
||
|
IniFile = (LPWSTR) HeapAlloc(hHeap,HEAP_ZERO_MEMORY,(dwNeeded)*sizeof(WCHAR));
|
||
|
if (!IniFile) {
|
||
|
MYDEBUG((L"HeapAlloc failed, ec = %d\n", GetLastError() ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
DWORD dwSuccess = ExpandEnvironmentStrings(ININAME,IniFile,dwNeeded);
|
||
|
|
||
|
if (dwSuccess == 0) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
dwNeeded = ExpandEnvironmentStrings(LOGNAME,LogFile,0);
|
||
|
LogFile = (LPWSTR) HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(WCHAR)*(dwNeeded));
|
||
|
if (!LogFile) {
|
||
|
MYDEBUG(( L"HeapAlloc failed, ec = %d\n", GetLastError() ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
dwSuccess = ExpandEnvironmentStrings(LOGNAME,LogFile,dwNeeded);
|
||
|
|
||
|
if (dwSuccess == 0) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
MYDEBUG (( L"Logfile : %s\n", LogFile ));
|
||
|
MYDEBUG (( L"Inifile : %s\n", IniFile ));
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL WINAPI
|
||
|
FaxRouteGetRoutingInfo(
|
||
|
IN LPWSTR RoutingGuid,
|
||
|
IN DWORD DeviceId,
|
||
|
IN LPBYTE RoutingInfo,
|
||
|
OUT LPDWORD RoutingInfoSize
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This functions is called by the fax service to
|
||
|
get routing configuration data.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RoutingGuid - Unique identifier for the requested routing method
|
||
|
DeviceId - Device that is being configured
|
||
|
RoutingInfo - Routing info buffer
|
||
|
RoutingInfoSize - Size of the buffer (in bytes)
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE for success, otherwise FALSE.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
//
|
||
|
// the sample doesn't have any per device routing data, so this function is
|
||
|
// just stubbed out -- if you have per device routing data, it would be
|
||
|
// retrieved here.
|
||
|
//
|
||
|
if (RoutingInfoSize) {
|
||
|
*RoutingInfoSize = 0;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL WINAPI
|
||
|
FaxRouteSetRoutingInfo(
|
||
|
IN LPWSTR RoutingGuid,
|
||
|
IN DWORD DeviceId,
|
||
|
IN LPBYTE RoutingInfo,
|
||
|
IN DWORD RoutingInfoSize
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This functions is called by the fax service to
|
||
|
set routing configuration data.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RoutingGuid - Unique identifier for the requested routing method
|
||
|
DeviceId - Device that is being configured
|
||
|
RoutingInfo - Routing info buffer
|
||
|
RoutingInfoSize - Size of the buffer (in bytes)
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE for success, otherwise FALSE.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
//
|
||
|
// the sample doesn't have any per device routing data, so this function is
|
||
|
// just stubbed out -- if you have per device routing data, it would be
|
||
|
// commited to storage here.
|
||
|
//
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL WINAPI
|
||
|
FaxRouteDeviceEnable(
|
||
|
IN LPWSTR RoutingGuid,
|
||
|
IN DWORD DeviceId,
|
||
|
IN LONG Enabled
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This functions is called by the fax service to determine if a routing extension is enabled or
|
||
|
to enable a routing extension
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
RoutingGuid - Unique identifier for the requested routing method
|
||
|
DeviceId - Device that is being configured
|
||
|
Enabled - meaning differs based on context (see FAXROUTE_ENABLE enumerated type)
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
depends on context.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
//
|
||
|
// -note that we make the assumption that there are never more than 4 devices in this sample
|
||
|
// -also note that this isn't thread safe
|
||
|
// -a real routing extension wouldn't make these assumptions, and would probably have some
|
||
|
// persistent store which kept track of the enabled state of an extension per-routing method
|
||
|
//
|
||
|
static long MyEnabled[4] = {STATUS_ENABLE,STATUS_ENABLE,STATUS_ENABLE,STATUS_ENABLE};
|
||
|
static DWORD DeviceIdIndex[4] = {0,0,0,0};
|
||
|
DWORD count;
|
||
|
|
||
|
//
|
||
|
// make sure that we're dealing with our routing method
|
||
|
//
|
||
|
if (wcscmp(RoutingGuid,ROUTEITGUID) != 0) {
|
||
|
MYDEBUG (( L"Passed a GUID (%s) for a method not in this extension!\n", RoutingGuid ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
for (count = 0 ; count <4; count ++) {
|
||
|
if (DeviceIdIndex[count] == DeviceId) {
|
||
|
break;
|
||
|
} else if (DeviceIdIndex[count] == 0) {
|
||
|
DeviceIdIndex[count] = DeviceId;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Enabled == QUERY_STATUS) {
|
||
|
return MyEnabled[count];
|
||
|
}
|
||
|
|
||
|
MYDEBUG (( L"Setting enabled state to %s\n",
|
||
|
(Enabled == STATUS_DISABLE) ? L"STATUS_DISABLE" : L"STATUS_ENABLE"
|
||
|
));
|
||
|
|
||
|
MyEnabled[count] = Enabled;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL WINAPI
|
||
|
FaxRouteDeviceChangeNotification(
|
||
|
IN DWORD DeviceId,
|
||
|
IN BOOL NewDevice
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This functions is called by the fax service to alert the routing extension that a device
|
||
|
has changed
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
DeviceId - Device that has changed
|
||
|
NewDevice - TRUE means device was added, FALSE means a device was removed
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE for success
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
//
|
||
|
// We don't have any per device routing data, so this is just stubbed out
|
||
|
//
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// routing method(s)
|
||
|
//
|
||
|
|
||
|
|
||
|
BOOL WINAPI
|
||
|
RouteIt(
|
||
|
PFAX_ROUTE FaxRoute,
|
||
|
PVOID *FailureData,
|
||
|
LPDWORD FailureDataSize
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This functions is called by the fax service to
|
||
|
route a received fax.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
FaxRoute - Routing information
|
||
|
FailureData - Failure data buffer
|
||
|
FailureDataSize - Size of failure data buffer
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE for success, otherwise FALSE.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
WCHAR TiffFileName[MAX_PATH];
|
||
|
WCHAR Dir[MAX_PATH],Drive[10],File[MAX_PATH],Ext[10];
|
||
|
WCHAR CopyOfTiff[MAX_PATH];
|
||
|
|
||
|
DWORD Size = sizeof(TiffFileName);
|
||
|
|
||
|
//
|
||
|
// serialize access to this function so that data is written into the logfile accurately
|
||
|
//
|
||
|
EnterCriticalSection( &csRoute );
|
||
|
|
||
|
if (!FaxRouteGetFile(
|
||
|
FaxRoute->JobId,
|
||
|
0,
|
||
|
TiffFileName,
|
||
|
&Size))
|
||
|
{
|
||
|
MYDEBUG(( L"Couldn't FaxRouteGetFile, ec = %d", GetLastError() ));
|
||
|
LeaveCriticalSection( &csRoute );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
MYDEBUG ((L"Received fax %s\n\tCSID :%s\n\t Name : %s\n\t #: %s\n\tDevice: %s\n",
|
||
|
TiffFileName,
|
||
|
ValidString ( FaxRoute->Csid ),
|
||
|
ValidString ( FaxRoute->ReceiverName),
|
||
|
ValidString ( FaxRoute->ReceiverNumber),
|
||
|
ValidString ( FaxRoute->DeviceName )
|
||
|
));
|
||
|
|
||
|
_wsplitpath(TiffFileName, Drive, Dir, File, Ext );
|
||
|
wsprintf(CopyOfTiff,L"%s\\%s\\%s%s",Drive,SIRENDIR,File,Ext);
|
||
|
|
||
|
//
|
||
|
// copy the tiff so it persists after this routine exits
|
||
|
//
|
||
|
CopyFile(TiffFileName,CopyOfTiff,FALSE);
|
||
|
|
||
|
//
|
||
|
// write some logging data
|
||
|
//
|
||
|
WriteRoutingInfoIntoIniFile(CopyOfTiff,FaxRoute);
|
||
|
AppendFileNametoLogFile(TiffFileName, FaxRoute);
|
||
|
|
||
|
//
|
||
|
// signal event -- another application could use this named event to do something
|
||
|
// with the file that was just copied into this directory
|
||
|
// (note that the INI file isn't thread-safe accross applications, we could have the routing data overwritten by
|
||
|
// another fax being received)
|
||
|
//
|
||
|
SetEvent(hReceiveEvent);
|
||
|
|
||
|
//
|
||
|
// service needs to be able to interact with the current desktop for this to work
|
||
|
//
|
||
|
MessageBeep(MB_ICONEXCLAMATION);
|
||
|
|
||
|
LeaveCriticalSection( &csRoute );
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// utility fcn's
|
||
|
//
|
||
|
|
||
|
BOOL WriteRoutingInfoIntoIniFile(LPWSTR TiffFileName,PFAX_ROUTE FaxRoute)
|
||
|
{
|
||
|
WCHAR Buffer[MAX_PATH*2];
|
||
|
|
||
|
|
||
|
//
|
||
|
// write each routing info member into ini file
|
||
|
//
|
||
|
|
||
|
//filename
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%s",ValidString (TiffFileName) );
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"FileName",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
|
||
|
//jobid
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%u",FaxRoute->JobId);
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"JobId",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//elapsedtime
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%u",FaxRoute->ElapsedTime);
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"ElapsedTime",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//receivetime
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%u",FaxRoute->ReceiveTime);
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"ReceiveTime",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
//pagecount
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%u",FaxRoute->PageCount);
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"PageCount",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//Csid
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%s",ValidString (FaxRoute->Csid ));
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"Csid",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//CallerId
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%s",ValidString (FaxRoute->CallerId ));
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"CallerId",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//RoutingInfo
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%s",ValidString (FaxRoute->RoutingInfo ));
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"RoutingInfo",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//ReceiverName
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%s",ValidString (FaxRoute->ReceiverName ));
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"ReceiverName",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//ReceiverNumber
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%s",ValidString (FaxRoute->ReceiverNumber ));
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"ReceiverNumber",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//DeviceName
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%s",ValidString (FaxRoute->DeviceName ));
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"DeviceName",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
//DeviceId
|
||
|
ZeroMemory(Buffer,MAX_PATH*2);
|
||
|
wsprintf(Buffer, L"%u",FaxRoute->DeviceId );
|
||
|
WritePrivateProfileString( L"RoutingInfo",// pointer to section name
|
||
|
L"DeviceId",// pointer to key name
|
||
|
Buffer, // pointer to string to add
|
||
|
IniFile // pointer to initialization filename
|
||
|
);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL AppendFileNametoLogFile (LPWSTR TiffFileName,PFAX_ROUTE FaxRoute)
|
||
|
{
|
||
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
|
WCHAR Buffer[MAX_PATH];
|
||
|
WCHAR szDateTime[104];
|
||
|
WCHAR lpDate[50];
|
||
|
WCHAR lpTime[50];
|
||
|
|
||
|
DWORD dwWrote = 0;
|
||
|
|
||
|
hFile = CreateFile(LogFile,
|
||
|
GENERIC_WRITE,
|
||
|
FILE_SHARE_WRITE,
|
||
|
NULL,
|
||
|
OPEN_ALWAYS,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
NULL);
|
||
|
|
||
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||
|
MYDEBUG (( L"CreateFile failed, ec = %d\n", GetLastError() ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if ( !GetDateFormat( LOCALE_SYSTEM_DEFAULT,
|
||
|
DATE_SHORTDATE,
|
||
|
NULL, // use system date
|
||
|
NULL, // use locale format
|
||
|
lpDate,
|
||
|
sizeof(lpDate) ) ) {
|
||
|
MYDEBUG(( L"GetDateFormat failed, ec = %d\n", GetLastError() ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
if ( !GetTimeFormat( LOCALE_SYSTEM_DEFAULT,
|
||
|
TIME_NOSECONDS,
|
||
|
NULL, // use system time
|
||
|
NULL, // use locale format
|
||
|
lpTime,
|
||
|
sizeof(lpTime) ) ) {
|
||
|
MYDEBUG(( L"GetTimeFormat failed, ec = %d\n", GetLastError() ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
wsprintf( szDateTime, TEXT("%-8s %-8s"), lpDate, lpTime);
|
||
|
|
||
|
wsprintf(Buffer, L"%s :Received %s\r\n",ValidString(szDateTime),ValidString(TiffFileName));
|
||
|
|
||
|
SetFilePointer(hFile,0,0,FILE_END);
|
||
|
|
||
|
if (!WriteFile(hFile,Buffer,lstrlen(Buffer)*sizeof(WCHAR),&dwWrote,NULL)) {
|
||
|
MYDEBUG (( L"WriteFile() failed, ec = %d\n", GetLastError() ));
|
||
|
CloseHandle(hFile);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
CloseHandle(hFile);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
DebugPrint(
|
||
|
LPTSTR Format,
|
||
|
...
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Prints a debug string
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
format - wsprintf() format string
|
||
|
... - Variable data
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
TCHAR Buffer[1024];
|
||
|
TCHAR AppName[MAX_PATH];
|
||
|
TCHAR ShortName[MAX_PATH];
|
||
|
SYSTEMTIME CurrentTime;
|
||
|
int len=0;
|
||
|
|
||
|
va_list marker;
|
||
|
|
||
|
ZeroMemory(AppName,MAX_PATH);
|
||
|
ZeroMemory(ShortName,MAX_PATH);
|
||
|
|
||
|
if ( GetModuleFileName(NULL, // handle to module to find filename for
|
||
|
AppName,
|
||
|
MAX_PATH) ) {
|
||
|
_tsplitpath(AppName,NULL,NULL,ShortName,NULL);
|
||
|
}
|
||
|
|
||
|
ZeroMemory(&CurrentTime,sizeof(SYSTEMTIME));
|
||
|
|
||
|
GetLocalTime(&CurrentTime);
|
||
|
|
||
|
wsprintf(Buffer, TEXT ("%02d.%02d.%02d.%03d %s: "),CurrentTime.wHour,
|
||
|
CurrentTime.wMinute,
|
||
|
CurrentTime.wSecond,
|
||
|
CurrentTime.wMilliseconds,
|
||
|
ShortName );
|
||
|
|
||
|
// init arg list
|
||
|
va_start(marker,Format);
|
||
|
|
||
|
// point to rest of blank buffer
|
||
|
len = lstrlen(Buffer);
|
||
|
|
||
|
_vsntprintf(&Buffer[len], // don't want to overwrite the start of the string!
|
||
|
sizeof(Buffer)-len, //size of the rest of the buffer
|
||
|
Format,
|
||
|
marker);
|
||
|
|
||
|
len = lstrlen(Buffer);
|
||
|
|
||
|
if (Buffer[len-1] == L'\n' ) {
|
||
|
Buffer[len-1] = L'\r';
|
||
|
Buffer[len] = L'\n';
|
||
|
Buffer[len+1] = 0;
|
||
|
}
|
||
|
else {
|
||
|
Buffer[len] = L'\r';
|
||
|
Buffer[len+1] = L'\n';
|
||
|
Buffer[len+2] = 0;
|
||
|
}
|
||
|
|
||
|
OutputDebugString(Buffer);
|
||
|
|
||
|
va_end(marker);
|
||
|
|
||
|
}
|