windows-nt/Source/XPSP1/NT/printscan/fax/service/server/util.c

1040 lines
24 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}