1040 lines
24 KiB
C
1040 lines
24 KiB
C
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
util.c
|
|
|
|
Abstract:
|
|
|
|
This module contains various utility functions.
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 16-Jan-1996
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "faxsvc.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
#if DBG
|
|
extern HANDLE hLogFile;
|
|
extern LIST_ENTRY CritSecListHead;
|
|
#endif
|
|
|
|
typedef struct _STRING_TABLE {
|
|
DWORD ResourceId;
|
|
DWORD InternalId;
|
|
LPTSTR String;
|
|
} STRING_TABLE, *PSTRING_TABLE;
|
|
|
|
|
|
static STRING_TABLE StringTable[] =
|
|
{
|
|
{ IDS_DIALING, FPS_DIALING, NULL },
|
|
{ IDS_SENDING, FPS_SENDING, NULL },
|
|
{ IDS_RECEIVING, FPS_RECEIVING, NULL },
|
|
{ IDS_COMPLETED, FPS_COMPLETED, NULL },
|
|
{ IDS_HANDLED, FPS_HANDLED, NULL },
|
|
{ IDS_BUSY, FPS_BUSY, NULL },
|
|
{ IDS_NO_ANSWER, FPS_NO_ANSWER, NULL },
|
|
{ IDS_BAD_ADDRESS, FPS_BAD_ADDRESS, NULL },
|
|
{ IDS_NO_DIAL_TONE, FPS_NO_DIAL_TONE, NULL },
|
|
{ IDS_DISCONNECTED, FPS_DISCONNECTED, NULL },
|
|
{ IDS_FATAL_ERROR, FPS_FATAL_ERROR, NULL },
|
|
{ IDS_NOT_FAX_CALL, FPS_NOT_FAX_CALL, NULL },
|
|
{ IDS_CALL_DELAYED, FPS_CALL_DELAYED, NULL },
|
|
{ IDS_CALL_BLACKLISTED, FPS_CALL_BLACKLISTED, NULL },
|
|
{ IDS_UNAVAILABLE, FPS_UNAVAILABLE, NULL },
|
|
{ IDS_AVAILABLE, FPS_AVAILABLE, NULL },
|
|
{ IDS_ABORTING, FPS_ABORTING, NULL },
|
|
{ IDS_ROUTING, FPS_ROUTING, NULL },
|
|
{ IDS_INITIALIZING, FPS_INITIALIZING, NULL },
|
|
{ IDS_SENDFAILED, FPS_SENDFAILED, NULL },
|
|
{ IDS_SENDRETRY, FPS_SENDRETRY, NULL },
|
|
{ IDS_BLANKSTR, FPS_BLANKSTR, NULL },
|
|
{ IDS_ROUTERETRY, FPS_ROUTERETRY, NULL },
|
|
{ IDS_ANSWERED, FPS_ANSWERED, NULL },
|
|
{ IDS_DR_SUBJECT, IDS_DR_SUBJECT, NULL },
|
|
{ IDS_DR_FILENAME, IDS_DR_FILENAME, NULL },
|
|
{ IDS_NDR_SUBJECT, IDS_NDR_SUBJECT, NULL },
|
|
{ IDS_NDR_FILENAME, IDS_NDR_FILENAME, NULL },
|
|
{ IDS_POWERED_OFF_MODEM, IDS_POWERED_OFF_MODEM, NULL },
|
|
{ IDS_SERVICE_NAME, IDS_SERVICE_NAME, NULL },
|
|
{ IDS_NO_MAPI_LOGON, IDS_NO_MAPI_LOGON, NULL },
|
|
{ IDS_DEFAULT, IDS_DEFAULT, NULL },
|
|
{ IDS_SERVER_NAME, IDS_SERVER_NAME, NULL },
|
|
{ IDS_FAX_LOG_CATEGORY_INIT_TERM, IDS_FAX_LOG_CATEGORY_INIT_TERM, NULL },
|
|
{ IDS_FAX_LOG_CATEGORY_OUTBOUND, IDS_FAX_LOG_CATEGORY_OUTBOUND, NULL },
|
|
{ IDS_FAX_LOG_CATEGORY_INBOUND, IDS_FAX_LOG_CATEGORY_INBOUND, NULL },
|
|
{ IDS_FAX_LOG_CATEGORY_UNKNOWN, IDS_FAX_LOG_CATEGORY_UNKNOWN, NULL },
|
|
{ IDS_SET_CONFIG, IDS_SET_CONFIG, NULL },
|
|
{ IDS_NO_SEND_DEVICES, IDS_NO_SEND_DEVICES, NULL},
|
|
{ IDS_MODEM_PROVIDER_NAME, IDS_MODEM_PROVIDER_NAME, NULL}
|
|
|
|
};
|
|
|
|
#define CountStringTable (sizeof(StringTable)/sizeof(STRING_TABLE))
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
InitializeStringTable(
|
|
VOID
|
|
)
|
|
{
|
|
DWORD i;
|
|
HINSTANCE hInstance;
|
|
TCHAR Buffer[256];
|
|
|
|
|
|
hInstance = GetModuleHandle(NULL);
|
|
|
|
for (i=0; i<CountStringTable; i++) {
|
|
|
|
if (LoadString(
|
|
hInstance,
|
|
StringTable[i].ResourceId,
|
|
Buffer,
|
|
sizeof(Buffer)/sizeof(TCHAR)
|
|
)) {
|
|
|
|
StringTable[i].String = (LPTSTR) MemAlloc( StringSize( Buffer ) );
|
|
if (!StringTable[i].String) {
|
|
StringTable[i].String = TEXT("");
|
|
} else {
|
|
_tcscpy( StringTable[i].String, Buffer );
|
|
}
|
|
|
|
} else {
|
|
|
|
StringTable[i].String = TEXT("");
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
LogMessage(
|
|
DWORD FormatId,
|
|
...
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Prints a pre-formatted message to stdout.
|
|
|
|
Arguments:
|
|
|
|
FormatId - Resource id for a printf style format string
|
|
... - all other arguments
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
TCHAR buf[1024];
|
|
DWORD Count;
|
|
va_list args;
|
|
|
|
va_start( args, FormatId );
|
|
|
|
Count = FormatMessage(
|
|
FORMAT_MESSAGE_FROM_HMODULE,
|
|
NULL,
|
|
FormatId,
|
|
0,
|
|
buf,
|
|
sizeof(buf),
|
|
&args
|
|
);
|
|
|
|
va_end( args );
|
|
|
|
DebugPrint(( TEXT("%s"), buf ));
|
|
}
|
|
|
|
LPTSTR
|
|
GetLastErrorText(
|
|
DWORD ErrorCode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets a string for a given WIN32 error code.
|
|
|
|
Arguments:
|
|
|
|
ErrorCode - WIN32 error code.
|
|
|
|
Return Value:
|
|
|
|
Pointer to a string representing the ErrorCode.
|
|
|
|
--*/
|
|
|
|
{
|
|
static TCHAR ErrorBuf[256];
|
|
DWORD Count;
|
|
|
|
Count = FormatMessage(
|
|
FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
NULL,
|
|
ErrorCode,
|
|
LANG_NEUTRAL,
|
|
ErrorBuf,
|
|
sizeof(ErrorBuf),
|
|
NULL
|
|
);
|
|
|
|
if (Count) {
|
|
if (ErrorBuf[Count-1] == TEXT('\n')) {
|
|
ErrorBuf[Count-1] = 0;
|
|
}
|
|
if ((Count>1) && (ErrorBuf[Count-2] == TEXT('\r'))) {
|
|
ErrorBuf[Count-2] = 0;
|
|
}
|
|
}
|
|
|
|
return ErrorBuf;
|
|
}
|
|
|
|
LPTSTR
|
|
GetString(
|
|
DWORD InternalId
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Loads a resource string and returns a pointer to the string.
|
|
The caller must free the memory.
|
|
|
|
Arguments:
|
|
|
|
ResourceId - resource string id
|
|
|
|
Return Value:
|
|
|
|
pointer to the string
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
|
|
for (i=0; i<CountStringTable; i++) {
|
|
if (StringTable[i].InternalId == InternalId) {
|
|
return StringTable[i].String;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
BOOL
|
|
InitializeFaxDirectories(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initializes the directories that fax will use.
|
|
We call into the shell to get the correct base path for fax directories and then tack on a relative path.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful. modifies path globals
|
|
|
|
--*/
|
|
{
|
|
if (!GetSpecialPath( CSIDL_COMMON_APPDATA, FaxDir ) ) {
|
|
DebugPrint(( TEXT("Couldn't GetSpecialPath, ec = %d\n"), GetLastError() ));
|
|
return FALSE;
|
|
}
|
|
|
|
wcscpy(FaxReceiveDir,FaxDir);
|
|
wcscpy(FaxQueueDir,FaxDir);
|
|
|
|
ConcatenatePaths(FaxDir, FAX_DIR);
|
|
ConcatenatePaths(FaxReceiveDir, FAX_RECEIVE_DIR);
|
|
ConcatenatePaths(FaxQueueDir, FAX_QUEUE_DIR);
|
|
|
|
//
|
|
// BugBug remove me
|
|
//
|
|
DebugPrint(( TEXT("FaxDir : %s\n"), FaxDir ));
|
|
DebugPrint(( TEXT("FaxReceiveDir : %s\n"), FaxReceiveDir ));
|
|
DebugPrint(( TEXT("FaxQueueDir : %s\n"), FaxQueueDir ));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
DWORDLONG
|
|
GenerateUniqueFileName(
|
|
LPTSTR Directory,
|
|
LPTSTR Extension,
|
|
LPTSTR FileName,
|
|
DWORD FileNameSize
|
|
)
|
|
{
|
|
SYSTEMTIME SystemTime;
|
|
FILETIME FileTime;
|
|
DWORD i;
|
|
WORD FatDate;
|
|
WORD FatTime;
|
|
TCHAR TempPath[MAX_PATH];
|
|
|
|
FileName[0] = '\0';
|
|
|
|
GetLocalTime( &SystemTime );
|
|
SystemTimeToFileTime( &SystemTime, &FileTime );
|
|
FileTimeToDosDateTime( &FileTime, &FatDate, &FatTime );
|
|
|
|
if (!Directory) {
|
|
GetTempPath( sizeof(TempPath)/sizeof(TCHAR), TempPath );
|
|
Directory = TempPath;
|
|
}
|
|
|
|
if (Directory[_tcslen(Directory)-1] == TEXT('\\')) {
|
|
Directory[_tcslen(Directory)-1] = 0;
|
|
}
|
|
|
|
if (!Extension) {
|
|
Extension = TEXT("tif");
|
|
}
|
|
|
|
//
|
|
// directory + '\' + 10 character filename + '.' + extension + NULL
|
|
// terminator
|
|
//
|
|
if ((_tcslen(Directory)+1+10+1+_tcslen(Extension)+1) > FileNameSize) {
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
return 0;
|
|
}
|
|
|
|
for (i=0; i<256; i++) {
|
|
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
|
|
_stprintf(
|
|
FileName,
|
|
TEXT("%s\\%04x%04x%02x.%s"),
|
|
Directory,
|
|
FatTime,
|
|
FatDate,
|
|
i,
|
|
Extension
|
|
);
|
|
|
|
hFile = CreateFile(
|
|
FileName,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_NEW,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|
|
|
DWORD Error = GetLastError();
|
|
|
|
if (Error == ERROR_ALREADY_EXISTS || Error == ERROR_FILE_EXISTS) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
CloseHandle( hFile );
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
if (i == 256) {
|
|
SetLastError( ERROR_TOO_MANY_OPEN_FILES );
|
|
return 0;
|
|
}
|
|
|
|
return MAKELONGLONG( MAKELONG( FatDate, FatTime ), i );
|
|
}
|
|
|
|
DWORD
|
|
MessageBoxThread(
|
|
IN PMESSAGEBOX_DATA MsgBox
|
|
)
|
|
{
|
|
DWORD Answer = (DWORD) MessageBox(
|
|
NULL,
|
|
MsgBox->Text,
|
|
GetString( IDS_SERVICE_NAME ),
|
|
MsgBox->Type | MB_SERVICE_NOTIFICATION
|
|
);
|
|
|
|
if (MsgBox->Response) {
|
|
*MsgBox->Response = Answer;
|
|
}
|
|
|
|
MemFree( MsgBox->Text );
|
|
MemFree( MsgBox );
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ServiceMessageBox(
|
|
IN LPCTSTR MsgString,
|
|
IN DWORD Type,
|
|
IN BOOL UseThread,
|
|
IN LPDWORD Response,
|
|
IN ...
|
|
)
|
|
{
|
|
#define BUFSIZE 1024
|
|
PMESSAGEBOX_DATA MsgBox;
|
|
DWORD ThreadId;
|
|
HANDLE hThread;
|
|
DWORD Answer;
|
|
LPTSTR buf;
|
|
va_list arg_ptr;
|
|
|
|
|
|
|
|
buf = (LPTSTR) MemAlloc( BUFSIZE );
|
|
if (!buf) {
|
|
return FALSE;
|
|
}
|
|
|
|
va_start( arg_ptr, Response );
|
|
_vsntprintf( buf, BUFSIZE, MsgString, arg_ptr );
|
|
va_end( arg_ptr );
|
|
|
|
if (UseThread) {
|
|
|
|
MsgBox = MemAlloc( sizeof(MESSAGEBOX_DATA) );
|
|
if (!MsgBox) {
|
|
MemFree( buf );
|
|
return FALSE;
|
|
}
|
|
|
|
MsgBox->Text = buf;
|
|
MsgBox->Response = Response;
|
|
MsgBox->Type = Type;
|
|
|
|
hThread = CreateThread(
|
|
NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE) MessageBoxThread,
|
|
(LPVOID) MsgBox,
|
|
0,
|
|
&ThreadId
|
|
);
|
|
|
|
if (!hThread) {
|
|
MemFree( buf );
|
|
MemFree( MsgBox );
|
|
return FALSE;
|
|
}
|
|
|
|
CloseHandle( hThread );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Answer = MessageBox(
|
|
NULL,
|
|
buf,
|
|
GetString( IDS_SERVICE_NAME ),
|
|
Type | MB_SERVICE_NOTIFICATION
|
|
);
|
|
if (Response) {
|
|
*Response = Answer;
|
|
}
|
|
|
|
MemFree( buf );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CreateFaxEvent(
|
|
DWORD DeviceId,
|
|
DWORD EventId,
|
|
DWORD JobId
|
|
)
|
|
{
|
|
PFAX_EVENT FaxEvent;
|
|
|
|
Assert(EventId != 0);
|
|
|
|
FaxEvent = MemAlloc( sizeof(FAX_EVENT) );
|
|
if (!FaxEvent) {
|
|
return FALSE;
|
|
}
|
|
|
|
FaxEvent->SizeOfStruct = sizeof(FAX_EVENT);
|
|
GetSystemTimeAsFileTime( &FaxEvent->TimeStamp );
|
|
FaxEvent->EventId = EventId;
|
|
FaxEvent->DeviceId = DeviceId;
|
|
FaxEvent->JobId = JobId;
|
|
|
|
PostQueuedCompletionStatus(
|
|
StatusCompletionPortHandle,
|
|
sizeof(FAX_EVENT),
|
|
EVENT_COMPLETION_KEY,
|
|
(LPOVERLAPPED) FaxEvent
|
|
);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DWORD
|
|
MapStatusIdToEventId(
|
|
DWORD StatusId
|
|
)
|
|
{
|
|
DWORD EventId = 0;
|
|
|
|
switch( StatusId ) {
|
|
case FS_INITIALIZING:
|
|
EventId = FEI_INITIALIZING;
|
|
break;
|
|
case FS_DIALING:
|
|
EventId = FEI_DIALING;
|
|
break;
|
|
case FS_TRANSMITTING:
|
|
EventId = FEI_SENDING;
|
|
break;
|
|
case FS_RECEIVING:
|
|
EventId = FEI_RECEIVING;
|
|
break;
|
|
case FS_COMPLETED:
|
|
EventId = FEI_COMPLETED;
|
|
break;
|
|
case FS_HANDLED:
|
|
EventId = FEI_HANDLED;
|
|
break;
|
|
case FS_LINE_UNAVAILABLE:
|
|
EventId = FEI_LINE_UNAVAILABLE;
|
|
break;
|
|
case FS_BUSY:
|
|
EventId = FEI_BUSY;
|
|
break;
|
|
case FS_NO_ANSWER:
|
|
EventId = FEI_NO_ANSWER;
|
|
break;
|
|
case FS_BAD_ADDRESS:
|
|
EventId = FEI_BAD_ADDRESS;
|
|
break;
|
|
case FS_NO_DIAL_TONE:
|
|
EventId = FEI_NO_DIAL_TONE;
|
|
break;
|
|
case FS_DISCONNECTED:
|
|
EventId = FEI_DISCONNECTED;
|
|
break;
|
|
case FS_FATAL_ERROR:
|
|
EventId = FEI_FATAL_ERROR;
|
|
break;
|
|
case FS_NOT_FAX_CALL:
|
|
EventId = FEI_NOT_FAX_CALL;
|
|
break;
|
|
case FS_CALL_DELAYED:
|
|
EventId = FEI_CALL_DELAYED;
|
|
break;
|
|
case FS_CALL_BLACKLISTED:
|
|
EventId = FEI_CALL_BLACKLISTED;
|
|
break;
|
|
case FS_USER_ABORT:
|
|
EventId = FEI_ABORTING;
|
|
break;
|
|
case FS_ANSWERED:
|
|
EventId = FEI_ANSWERED;
|
|
break;
|
|
|
|
}
|
|
|
|
return EventId;
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
FaxLogSend(
|
|
PFAX_SEND_ITEM FaxSendItem,
|
|
BOOL Rslt,
|
|
PFAX_DEV_STATUS FaxStatus,
|
|
BOOL Retrying
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Log a fax send event.
|
|
|
|
Arguments:
|
|
|
|
FaxSendItem - Pointer to FAX_SEND_ITEM structure for this fax.
|
|
Rslt - BOOL returned from device provider. TRUE means fax was sent.
|
|
FaxStatus - Pointer to FAX_DEV_STATUS for this fax.
|
|
PrinterName - Name of fax printer.
|
|
Retrying - TRUE if another send attempt will be made.
|
|
|
|
|
|
Return Value:
|
|
|
|
VOID
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
DWORD Level;
|
|
DWORD FormatId;
|
|
TCHAR PageCountStr[64];
|
|
TCHAR TimeStr[128];
|
|
BOOL fLog = TRUE;
|
|
|
|
FormatElapsedTimeStr(
|
|
(FILETIME*)&FaxSendItem->JobEntry->ElapsedTime,
|
|
TimeStr,
|
|
128
|
|
);
|
|
_ltot((LONG) FaxStatus->PageCount, PageCountStr, 10);
|
|
if (Rslt) {
|
|
FaxLog(
|
|
FAXLOG_CATEGORY_OUTBOUND,
|
|
FAXLOG_LEVEL_MED,
|
|
10,
|
|
MSG_FAX_SEND_SUCCESS,
|
|
FaxSendItem->SenderName,
|
|
FaxSendItem->BillingCode,
|
|
FaxSendItem->SenderCompany,
|
|
FaxSendItem->SenderDept,
|
|
FaxSendItem->RecipientName,
|
|
FaxSendItem->JobEntry->PhoneNumber,
|
|
FaxStatus->CSI,
|
|
PageCountStr,
|
|
TimeStr,
|
|
FaxSendItem->JobEntry->LineInfo->DeviceName
|
|
);
|
|
}
|
|
else {
|
|
switch (FaxStatus->StatusId) {
|
|
case FS_FATAL_ERROR:
|
|
Level = Retrying ? FAXLOG_LEVEL_MED : FAXLOG_LEVEL_MIN;
|
|
FormatId = Retrying ? MSG_FAX_SEND_FATAL_RETRY : MSG_FAX_SEND_FATAL_ABORT;
|
|
break;
|
|
case FS_NO_DIAL_TONE:
|
|
Level = Retrying ? FAXLOG_LEVEL_MED : FAXLOG_LEVEL_MIN;
|
|
FormatId = Retrying ? MSG_FAX_SEND_NDT_RETRY : MSG_FAX_SEND_NDT_ABORT;
|
|
break;
|
|
case FS_NO_ANSWER:
|
|
Level = Retrying ? FAXLOG_LEVEL_MED : FAXLOG_LEVEL_MIN;
|
|
FormatId = Retrying ? MSG_FAX_SEND_NA_RETRY : MSG_FAX_SEND_NA_ABORT;
|
|
break;
|
|
case FS_DISCONNECTED:
|
|
Level = Retrying ? FAXLOG_LEVEL_MED : FAXLOG_LEVEL_MIN;
|
|
FormatId = Retrying ? MSG_FAX_SEND_INTERRUPT_RETRY : MSG_FAX_SEND_INTERRUPT_ABORT;
|
|
break;
|
|
case FS_NOT_FAX_CALL:
|
|
Level = Retrying ? FAXLOG_LEVEL_MED : FAXLOG_LEVEL_MIN;
|
|
FormatId = Retrying ? MSG_FAX_SEND_NOTFAX_RETRY : MSG_FAX_SEND_NOTFAX_ABORT;
|
|
break;
|
|
case FS_BUSY:
|
|
Level = Retrying ? FAXLOG_LEVEL_MAX : FAXLOG_LEVEL_MIN;
|
|
FormatId = Retrying ? MSG_FAX_SEND_BUSY_RETRY : MSG_FAX_SEND_BUSY_ABORT;
|
|
break;
|
|
case FS_USER_ABORT:
|
|
Level = FAXLOG_LEVEL_MED;
|
|
FormatId = MSG_FAX_SEND_USER_ABORT;
|
|
break;
|
|
default:
|
|
fLog = FALSE;
|
|
}
|
|
|
|
if(fLog) {
|
|
FaxLog(
|
|
FAXLOG_CATEGORY_OUTBOUND,
|
|
Level,
|
|
7,
|
|
FormatId,
|
|
FaxSendItem->SenderName,
|
|
FaxSendItem->BillingCode,
|
|
FaxSendItem->SenderCompany,
|
|
FaxSendItem->SenderDept,
|
|
FaxSendItem->RecipientName,
|
|
FaxSendItem->JobEntry->PhoneNumber,
|
|
FaxSendItem->JobEntry->LineInfo->DeviceName
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
SetServiceStart(
|
|
LPTSTR ServiceName,
|
|
DWORD StartType
|
|
)
|
|
{
|
|
BOOL rVal = FALSE;
|
|
SC_HANDLE hSvcMgr;
|
|
SC_HANDLE hService;
|
|
|
|
|
|
hSvcMgr = OpenSCManager(
|
|
NULL,
|
|
NULL,
|
|
SC_MANAGER_ALL_ACCESS
|
|
);
|
|
if (!hSvcMgr) {
|
|
DebugPrint(( TEXT("could not open service manager: error code = %u"), GetLastError() ));
|
|
goto exit;
|
|
}
|
|
|
|
hService = OpenService(
|
|
hSvcMgr,
|
|
ServiceName,
|
|
SERVICE_ALL_ACCESS
|
|
);
|
|
|
|
if (!hService) {
|
|
DebugPrint((
|
|
TEXT("could not open the %s service: error code = %u"),
|
|
ServiceName,
|
|
GetLastError()
|
|
));
|
|
goto exit;
|
|
}
|
|
|
|
|
|
if (!ChangeServiceConfig(
|
|
hService, // handle to service
|
|
SERVICE_NO_CHANGE, // type of service
|
|
StartType, // when to start service
|
|
SERVICE_NO_CHANGE, // severity if service fails to start
|
|
NULL, // pointer to service binary file name
|
|
NULL, // pointer to load ordering group name
|
|
NULL, // pointer to variable to get tag identifier
|
|
NULL, // pointer to array of dependency names
|
|
NULL, // pointer to account name of service
|
|
NULL, // pointer to password for service account
|
|
NULL // pointer to display name
|
|
))
|
|
{
|
|
DebugPrint(( TEXT("could not open change service configuration, ec=%d"), GetLastError() ));
|
|
goto exit;
|
|
}
|
|
|
|
rVal = TRUE;
|
|
|
|
exit:
|
|
CloseServiceHandle( hService );
|
|
CloseServiceHandle( hSvcMgr );
|
|
|
|
return rVal;
|
|
}
|
|
|
|
|
|
|
|
DWORD MyGetFileSize(LPCTSTR FileName)
|
|
{
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
DWORD sizelow=0, sizehigh=0;
|
|
|
|
hFile = CreateFile(
|
|
FileName,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|
return 0;
|
|
}
|
|
|
|
sizelow = GetFileSize(hFile,&sizehigh);
|
|
|
|
if (sizehigh == 0xFFFFFFFFF) {
|
|
sizelow = 0;
|
|
} else if (sizehigh!=0) {
|
|
sizelow=0xFFFFFFFF;
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
|
|
return sizelow;
|
|
}
|
|
|
|
extern CRITICAL_SECTION CsClients;
|
|
extern CRITICAL_SECTION CsHandleTable;
|
|
extern CRITICAL_SECTION CsJob;
|
|
extern CRITICAL_SECTION CsLine;
|
|
extern CRITICAL_SECTION CsPerfCounters;
|
|
extern CRITICAL_SECTION CsQueue;
|
|
extern CRITICAL_SECTION CsRouting;
|
|
LPCWSTR szCsClients = L"CsClients";
|
|
LPCWSTR szCsHandleTable = L"CsHandleTable";
|
|
LPCWSTR szCsJob = L"CsJob";
|
|
LPCWSTR szCsLine = L"CsLine";
|
|
LPCWSTR szCsPerfCounters = L"CsPerfCounters";
|
|
LPCWSTR szCsQueue = L"CsQueue";
|
|
LPCWSTR szCsRouting = L"CsRouting";
|
|
LPCWSTR szCsUnknown = L"Other CS";
|
|
|
|
LPCWSTR GetSzCs(
|
|
LPCRITICAL_SECTION cs
|
|
)
|
|
{
|
|
|
|
|
|
|
|
if (cs == &CsClients) {
|
|
return szCsClients;
|
|
} else if (cs == &CsHandleTable) {
|
|
return szCsHandleTable;
|
|
} else if (cs == &CsJob) {
|
|
return szCsJob;
|
|
} else if (cs == &CsLine) {
|
|
return szCsLine;
|
|
} else if (cs == &CsPerfCounters) {
|
|
return szCsPerfCounters;
|
|
} else if (cs == &CsQueue) {
|
|
return szCsQueue;
|
|
} else if (cs == &CsRouting) {
|
|
return szCsRouting;
|
|
}
|
|
|
|
return szCsUnknown;
|
|
|
|
|
|
}
|
|
|
|
#if DBG
|
|
VOID AppendToLogFile(
|
|
LPWSTR String
|
|
)
|
|
{
|
|
DWORD BytesWritten;
|
|
LPSTR AnsiBuffer = UnicodeStringToAnsiString( String );
|
|
|
|
if (hLogFile != INVALID_HANDLE_VALUE) {
|
|
WriteFile(hLogFile,(LPBYTE)AnsiBuffer,strlen(AnsiBuffer) * sizeof(CHAR),&BytesWritten,NULL);
|
|
}
|
|
|
|
MemFree(AnsiBuffer);
|
|
|
|
}
|
|
|
|
VOID AppendFuncToLogFile(
|
|
LPCRITICAL_SECTION cs,
|
|
LPTSTR szFunc,
|
|
DWORD line,
|
|
LPTSTR file,
|
|
PDBGCRITSEC CritSec
|
|
)
|
|
{
|
|
WCHAR Buffer[300];
|
|
LPWSTR FileName;
|
|
LPCWSTR szcs = GetSzCs(cs);
|
|
|
|
FileName = wcsrchr(file,'\\');
|
|
if (!FileName) {
|
|
FileName = TEXT("Unknown ");
|
|
} else {
|
|
FileName += 1;
|
|
}
|
|
if (CritSec) {
|
|
wsprintf(Buffer,TEXT("%d\t%x\t%s\t%s\t%s\t%d\t%d\r\n"),
|
|
GetTickCount(),
|
|
(PULONG_PTR)cs,
|
|
szcs,
|
|
szFunc,
|
|
FileName,
|
|
line,
|
|
CritSec->ReleasedTime - CritSec->AquiredTime);
|
|
} else {
|
|
wsprintf(Buffer,TEXT("%d\t%x\t%s\t%s\t%s\t%d\r\n"),GetTickCount(),(PULONG_PTR)cs,szcs,szFunc, FileName,line);
|
|
}
|
|
|
|
AppendToLogFile( Buffer );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
VOID pEnterCriticalSection(
|
|
LPCRITICAL_SECTION cs,
|
|
DWORD line,
|
|
LPTSTR file
|
|
)
|
|
{
|
|
extern CRITICAL_SECTION CsJob;
|
|
extern CRITICAL_SECTION CsQueue;
|
|
//PDBGCRITSEC CritSec;
|
|
|
|
PDBGCRITSEC pCritSec = MemAlloc(sizeof(DBGCRITSEC));
|
|
pCritSec->CritSecAddr = (ULONG_PTR) cs;
|
|
pCritSec->AquiredTime = GetTickCount();
|
|
pCritSec->ThreadId = GetCurrentThreadId();
|
|
|
|
InsertHeadList( &CritSecListHead, &pCritSec->ListEntry );
|
|
|
|
AppendFuncToLogFile(cs,TEXT("EnterCriticalSection"), line, file, NULL );
|
|
|
|
#ifdef EnterCriticalSection
|
|
#undef EnterCriticalSection
|
|
//
|
|
// check ordering of threads. ALWAYS aquire CsJob before aquiring CsQueue!!!
|
|
//
|
|
if ((LPCRITICAL_SECTION)cs == (LPCRITICAL_SECTION)&CsQueue) {
|
|
if ((DWORD)GetCurrentThreadId() != PtrToUlong(CsJob.OwningThread)) {
|
|
WCHAR DebugBuf[300];
|
|
wsprintf(DebugBuf, TEXT("%d : Attempting to aquire CsQueue (thread %x) without aquiring CsJob (thread %x, lock count %x) first, possible deadlock!\r\n"),
|
|
GetTickCount(),
|
|
GetCurrentThreadId(),
|
|
CsJob.OwningThread,
|
|
CsJob.LockCount );
|
|
AppendToLogFile( DebugBuf );
|
|
}
|
|
}
|
|
EnterCriticalSection(cs);
|
|
#endif
|
|
}
|
|
|
|
VOID pLeaveCriticalSection(
|
|
LPCRITICAL_SECTION cs,
|
|
DWORD line,
|
|
LPTSTR file
|
|
)
|
|
{
|
|
PDBGCRITSEC CritSec;
|
|
PLIST_ENTRY Next = CritSecListHead.Flink;
|
|
|
|
while ((ULONG_PTR)Next != (ULONG_PTR) &CritSecListHead) {
|
|
CritSec = CONTAINING_RECORD( Next, DBGCRITSEC, ListEntry );
|
|
if ((ULONG_PTR)CritSec->CritSecAddr == (ULONG_PTR) cs &&
|
|
( GetCurrentThreadId() == CritSec->ThreadId ) ) {
|
|
CritSec->ReleasedTime = GetTickCount();
|
|
break;
|
|
}
|
|
Next = Next->Flink;
|
|
}
|
|
|
|
AppendFuncToLogFile(cs,TEXT("LeaveCriticalSection"),line, file, CritSec );
|
|
|
|
if (CritSec) {
|
|
RemoveEntryList( &CritSec->ListEntry );
|
|
MemFree( CritSec );
|
|
}
|
|
|
|
#ifdef LeaveCriticalSection
|
|
#undef LeaveCriticalSection
|
|
LeaveCriticalSection(cs);
|
|
#endif
|
|
|
|
}
|
|
|
|
VOID pInitializeCriticalSection(
|
|
LPCRITICAL_SECTION cs,
|
|
DWORD line,
|
|
LPTSTR file
|
|
)
|
|
{
|
|
|
|
AppendFuncToLogFile(cs,TEXT("InitializeCriticalSection"),line, file, NULL);
|
|
|
|
|
|
|
|
#ifdef InitializeCriticalSection
|
|
#undef InitializeCriticalSection
|
|
InitializeCriticalSection(cs);
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
DWORD
|
|
ValidateTiffFile(
|
|
LPCWSTR TifFileName
|
|
)
|
|
{
|
|
|
|
HANDLE hTiff;
|
|
DWORD rc = ERROR_SUCCESS;
|
|
TIFF_INFO TiffInfo;
|
|
|
|
//
|
|
// impersonate the client
|
|
//
|
|
if (RpcImpersonateClient(NULL) != RPC_S_OK) {
|
|
rc = GetLastError();
|
|
goto e0;
|
|
}
|
|
|
|
//
|
|
// make sure the client can see the file
|
|
//
|
|
if (GetFileAttributes(TifFileName) == 0xFFFFFFFF) {
|
|
rc = GetLastError();
|
|
goto e1;
|
|
}
|
|
|
|
//
|
|
// make sure the client has read-write access to the file
|
|
//
|
|
hTiff = TiffOpen( (LPWSTR)TifFileName, &TiffInfo, FALSE, FILLORDER_MSB2LSB );
|
|
if (!hTiff) {
|
|
rc = GetLastError();
|
|
goto e1;
|
|
}
|
|
|
|
TiffClose( hTiff );
|
|
e1:
|
|
RpcRevertToSelf();
|
|
e0:
|
|
return rc;
|
|
|
|
}
|
|
|