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.
878 lines
16 KiB
878 lines
16 KiB
|
|
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
util.c
|
|
|
|
Abstract:
|
|
|
|
utility functions
|
|
|
|
Environment:
|
|
|
|
Fax configuration applet
|
|
|
|
Revision History:
|
|
|
|
05/26/00 -taoyuan-
|
|
Created it.
|
|
|
|
mm/dd/yy -author-
|
|
description
|
|
|
|
--*/
|
|
|
|
#include <stdio.h>
|
|
#include "faxui.h"
|
|
#include "resource.h"
|
|
|
|
typedef struct _STRING_TABLE {
|
|
DWORD ResourceId;
|
|
LPTSTR String;
|
|
} STRING_TABLE, *PSTRING_TABLE;
|
|
|
|
static STRING_TABLE StringTable[] =
|
|
{
|
|
{ IDS_DEVICE_ENABLED, NULL},
|
|
{ IDS_DEVICE_DISABLED, NULL},
|
|
{ IDS_DEVICE_AUTO_ANSWER, NULL},
|
|
{ IDS_DEVICE_MANUAL_ANSWER, NULL}
|
|
|
|
};
|
|
|
|
#define CountStringTable (sizeof(StringTable)/sizeof(STRING_TABLE))
|
|
|
|
VOID
|
|
InitializeStringTable(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize the string table for future use
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
TCHAR szBuffer[256];
|
|
|
|
for (i=0; i<CountStringTable; i++)
|
|
{
|
|
if (LoadString(
|
|
g_hResource,
|
|
StringTable[i].ResourceId,
|
|
szBuffer,
|
|
sizeof(szBuffer)/sizeof(TCHAR)))
|
|
{
|
|
StringTable[i].String = (LPTSTR) MemAlloc( StringSize( szBuffer ) );
|
|
if (!StringTable[i].String) {
|
|
StringTable[i].String = NULL;
|
|
} else {
|
|
_tcscpy( StringTable[i].String, szBuffer );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Error(( "LoadString failed, resource ID is %d.\n", StringTable[i].ResourceId ));
|
|
StringTable[i].String = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DeInitializeStringTable(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Deinitialize the string table and release allocated memory
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
|
|
for (i=0; i<CountStringTable; i++)
|
|
{
|
|
if(StringTable[i].String)
|
|
{
|
|
MemFree(StringTable[i].String);
|
|
StringTable[i].String = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
LPTSTR
|
|
GetString(
|
|
DWORD ResourceId
|
|
)
|
|
|
|
/*++
|
|
|
|
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].ResourceId == ResourceId)
|
|
{
|
|
return StringTable[i].String;
|
|
}
|
|
}
|
|
|
|
Assert(FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
INT
|
|
DisplayErrorMessage(
|
|
HWND hwndParent,
|
|
UINT uiType,
|
|
INT iErrorCode,
|
|
...
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Display an Error Message dialog box
|
|
|
|
Arguments:
|
|
|
|
hwndParent - Specifies a parent window for the error message dialog
|
|
type - Specifies the type of message box to be displayed
|
|
iErrorCode - Win32 Error Code
|
|
...
|
|
|
|
Return Value:
|
|
|
|
Same as the return value from MessageBox
|
|
|
|
--*/
|
|
|
|
{
|
|
LPTSTR pTitle = NULL;
|
|
LPTSTR pFormat = NULL;
|
|
LPTSTR pMessage = NULL;
|
|
INT result;
|
|
va_list ap;
|
|
INT iStringID = 0;
|
|
BOOL bOK = TRUE;
|
|
|
|
if ((pTitle = AllocStringZ(MAX_TITLE_LEN)) &&
|
|
(pFormat = AllocStringZ(MAX_STRING_LEN)) &&
|
|
(pMessage = AllocStringZ(MAX_MESSAGE_LEN)))
|
|
{
|
|
//
|
|
// Load Title String
|
|
//
|
|
if (!LoadString(g_hResource, IDS_MSG_TITLE, pTitle, MAX_TITLE_LEN))
|
|
{
|
|
Error(("Failed to load preview message string. (ec: %lc)",GetLastError()));
|
|
bOK = FALSE;
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Load Error Message
|
|
//
|
|
iStringID = GetErrorStringId(iErrorCode);
|
|
if (!LoadString(g_hResource, iStringID, pFormat, MAX_STRING_LEN))
|
|
{
|
|
Error(("Failed to load preview message string. (ec: %lc)",GetLastError()));
|
|
bOK = FALSE;
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Compose the message string
|
|
//
|
|
va_start(ap, iErrorCode);
|
|
wvsprintf(pMessage, pFormat, ap);
|
|
va_end(ap);
|
|
|
|
//
|
|
// Display the message box
|
|
//
|
|
if (uiType == 0)
|
|
{
|
|
uiType = MB_OK | MB_ICONERROR;
|
|
}
|
|
|
|
result = AlignedMessageBox(hwndParent, pMessage, pTitle, uiType);
|
|
}
|
|
else
|
|
{
|
|
bOK = FALSE;
|
|
}
|
|
|
|
Exit:
|
|
if (!bOK)
|
|
{
|
|
MessageBeep(MB_ICONHAND);
|
|
result = 0;
|
|
}
|
|
|
|
MemFree(pTitle);
|
|
MemFree(pFormat);
|
|
MemFree(pMessage);
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL IsLocalPrinter(
|
|
LPTSTR pPrinterName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check whether given printer is local
|
|
|
|
Arguments:
|
|
|
|
pPrinterName - giver printer name
|
|
|
|
Return Value:
|
|
|
|
TRUE if it's local, FALSE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD ErrorCode = 0;
|
|
BOOL Found = FALSE;
|
|
PPRINTER_INFO_4 pPrinterInfo = NULL;
|
|
DWORD BytesNeeded = 0;
|
|
DWORD NumPrinters = 0;
|
|
PPRINTER_INFO_4 pCurrPrinterInfo;
|
|
|
|
//
|
|
// enumerate local printers
|
|
//
|
|
if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &BytesNeeded, &NumPrinters))
|
|
{
|
|
// if succeeds, there are no printers
|
|
goto CleanUp;
|
|
}
|
|
else if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
|| !(pPrinterInfo = (PPRINTER_INFO_4) GlobalAlloc(GMEM_FIXED, BytesNeeded))
|
|
|| !EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (LPBYTE) pPrinterInfo,
|
|
BytesNeeded, &BytesNeeded, &NumPrinters))
|
|
{
|
|
ErrorCode = GetLastError();
|
|
goto CleanUp;
|
|
}
|
|
|
|
for (pCurrPrinterInfo = pPrinterInfo;
|
|
!Found && (pCurrPrinterInfo < (pPrinterInfo + NumPrinters));
|
|
pCurrPrinterInfo++)
|
|
{
|
|
// check for printer name
|
|
if (!lstrcmpi(pCurrPrinterInfo->pPrinterName, pPrinterName))
|
|
{
|
|
Found = TRUE;
|
|
}
|
|
}
|
|
|
|
CleanUp:
|
|
|
|
if (pPrinterInfo)
|
|
{
|
|
GlobalFree(pPrinterInfo);
|
|
}
|
|
|
|
SetLastError(ErrorCode);
|
|
return Found;
|
|
}
|
|
|
|
|
|
VOID
|
|
DisConnect(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Close current connection to the fax service
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (g_hFaxSvcHandle) {
|
|
FaxClose(g_hFaxSvcHandle);
|
|
g_hFaxSvcHandle = NULL;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
Connect(
|
|
HWND hDlg,
|
|
BOOL bDisplayErrorMessage
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Connect to the fax service
|
|
|
|
Arguments:
|
|
|
|
hDlg - the caller window handle
|
|
bDisplayErrorMessage - indicate whether display the error message to the user
|
|
|
|
Return Value:
|
|
|
|
TRUE if successfully connected, FALSE if there is an error.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD dwRes = 0;
|
|
|
|
//
|
|
// Check if already connected to the fax service
|
|
//
|
|
if (g_hFaxSvcHandle)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Connect to the fax service
|
|
//
|
|
if (!FaxConnectFaxServer(NULL, &g_hFaxSvcHandle))
|
|
{
|
|
dwRes = GetLastError();
|
|
|
|
Error(( "Can't connect to the fax server, ec = %d.\n", dwRes));
|
|
|
|
if(bDisplayErrorMessage)
|
|
{
|
|
DisplayErrorMessage(hDlg, 0, dwRes);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DirectoryExists(
|
|
LPTSTR pDirectoryName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check the existancy of given folder name
|
|
|
|
Arguments:
|
|
|
|
pDirectoryName - point to folder name
|
|
|
|
Return Value:
|
|
|
|
if the folder exists, return TRUE; else, return FALSE.
|
|
|
|
--*/
|
|
|
|
{
|
|
TCHAR pFullDirectoryName[MAX_PATH];
|
|
DWORD dwFileAttributes;
|
|
DWORD dwSize;
|
|
|
|
if(!pDirectoryName || lstrlen(pDirectoryName) == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
dwSize = ExpandEnvironmentStrings(pDirectoryName, pFullDirectoryName, MAX_PATH);
|
|
if(dwSize == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
dwFileAttributes = GetFileAttributes(pFullDirectoryName);
|
|
|
|
if ( dwFileAttributes != 0xffffffff &&
|
|
dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
FaxDeviceEnableRoutingMethod(
|
|
HANDLE hFaxHandle,
|
|
DWORD dwDeviceId,
|
|
LPCTSTR pRoutingGuid,
|
|
LONG Enabled
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get or set the current status of a routing method for specific device
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle - fax handle by FaxConnectFaxServer()
|
|
dwDeviceId - device ID
|
|
pRoutingGuid - GUID that identifies the fax routing method
|
|
Enabled - enabled status for the device and method, if Enabled is QUERY_STATUS,
|
|
it means return value is the current state
|
|
|
|
Return Value:
|
|
|
|
if Enabled is QUERY_STATUS, return the current state of routing method;
|
|
if Enabled is QUERY_ENABLE or QUERY_DISABLE, return TRUE for success, FALSE for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
HANDLE hFaxPortHandle = NULL;
|
|
BOOL bResult = FALSE;
|
|
LPBYTE pRoutingInfoBuffer = NULL;
|
|
DWORD dwRoutingInfoBufferSize;
|
|
|
|
Assert(hFaxHandle);
|
|
if(!hFaxHandle || !FaxOpenPort(hFaxHandle, dwDeviceId, PORT_OPEN_QUERY | PORT_OPEN_MODIFY, &hFaxPortHandle))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if(!FaxGetRoutingInfo(hFaxPortHandle, pRoutingGuid, &pRoutingInfoBuffer, &dwRoutingInfoBufferSize))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if(Enabled == QUERY_STATUS)
|
|
{
|
|
//
|
|
// for query status
|
|
//
|
|
bResult = *((LPDWORD)pRoutingInfoBuffer) > 0 ? TRUE : FALSE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// for set status
|
|
//
|
|
*((LPDWORD)pRoutingInfoBuffer) = (Enabled == STATUS_ENABLE) ? TRUE : FALSE;
|
|
if(FaxSetRoutingInfo(hFaxPortHandle, pRoutingGuid, pRoutingInfoBuffer, dwRoutingInfoBufferSize))
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
if(pRoutingInfoBuffer) { FaxFreeBuffer(pRoutingInfoBuffer); }
|
|
if(hFaxPortHandle) { FaxClose(hFaxPortHandle); }
|
|
return bResult;
|
|
}
|
|
|
|
int CALLBACK BrowseCallbackProc(
|
|
HWND hDlg,
|
|
UINT uMsg,
|
|
LPARAM lParam,
|
|
LPARAM dwData)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
We use this callback function to specify the initial folder
|
|
|
|
Arguments:
|
|
|
|
hDlg - Specifies the dialog window on which the Browse button is displayed
|
|
uMsg - Value identifying the event.
|
|
lParam - Value dependent upon the message contained in the uMsg parameter.
|
|
dwData - Application-defined value that was specified in the lParam member of the BROWSEINFO structure.
|
|
|
|
Return Value:
|
|
|
|
Returns zero.
|
|
|
|
--*/
|
|
|
|
{
|
|
switch(uMsg)
|
|
{
|
|
case BFFM_INITIALIZED:
|
|
SendMessage(hDlg, BFFM_SETSELECTION, TRUE, dwData);
|
|
break;
|
|
|
|
case BFFM_SELCHANGED:
|
|
{
|
|
BOOL bFolderIsOK = FALSE;
|
|
TCHAR szPath [MAX_PATH + 1];
|
|
|
|
if (SHGetPathFromIDList ((LPITEMIDLIST) lParam, szPath))
|
|
{
|
|
DWORD dwFileAttr = GetFileAttributes(szPath);
|
|
if (-1 != dwFileAttr && (dwFileAttr & FILE_ATTRIBUTE_DIRECTORY))
|
|
{
|
|
//
|
|
// The directory exists - enable the 'Ok' button
|
|
//
|
|
bFolderIsOK = TRUE;
|
|
}
|
|
}
|
|
//
|
|
// Enable / disable the 'ok' button
|
|
//
|
|
SendMessage(hDlg, BFFM_ENABLEOK , 0, (LPARAM)bFolderIsOK);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL
|
|
BrowseForDirectory(
|
|
HWND hDlg,
|
|
INT hResource,
|
|
DWORD dwMaxPath,
|
|
LPTSTR title
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Browse for a directory
|
|
|
|
Arguments:
|
|
|
|
hDlg - Specifies the dialog window on which the Browse button is displayed
|
|
hResource - resource id to receive the directory
|
|
dwMaxPath - max path length
|
|
title - the title to be shown in the browse dialog
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if the user presses Cancel
|
|
|
|
--*/
|
|
|
|
{
|
|
LPITEMIDLIST pidl;
|
|
TCHAR buffer[MAX_PATH];
|
|
BOOL bResult = FALSE;
|
|
LPMALLOC pMalloc = NULL;
|
|
|
|
BROWSEINFO bi = {
|
|
|
|
hDlg,
|
|
NULL,
|
|
buffer,
|
|
title,
|
|
BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE,
|
|
BrowseCallbackProc,
|
|
(LPARAM) buffer,
|
|
};
|
|
|
|
Verbose(("Entering BrowseForDirectory...\n"));
|
|
|
|
if (!GetDlgItemText( hDlg, hResource, buffer, MAX_PATH))
|
|
buffer[0] = 0;
|
|
|
|
if(E_FAIL == SHGetMalloc(&pMalloc))
|
|
{
|
|
return bResult;
|
|
}
|
|
|
|
if (pidl = SHBrowseForFolder(&bi))
|
|
{
|
|
if (SHGetPathFromIDList(pidl, buffer))
|
|
{
|
|
if (_tcslen(buffer) > dwMaxPath)
|
|
{
|
|
DisplayErrorMessage(hDlg, 0, FAXUI_ERROR_NAME_IS_TOO_LONG);
|
|
}
|
|
else
|
|
{
|
|
SetDlgItemText(hDlg, hResource, buffer);
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
|
|
pMalloc->lpVtbl->Free(pMalloc, (LPVOID)pidl);
|
|
|
|
}
|
|
|
|
pMalloc->lpVtbl->Release(pMalloc);
|
|
|
|
return bResult;
|
|
}
|
|
|
|
LPTSTR
|
|
ValidatePath(
|
|
LPTSTR szPath
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check and remove the '\' at the end of the string
|
|
|
|
Arguments:
|
|
|
|
szPath - string pointer
|
|
|
|
Return Value:
|
|
|
|
return the new string pointer
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
|
|
if (szPath == NULL || szPath[0] == 0)
|
|
{
|
|
return szPath;
|
|
}
|
|
|
|
i = lstrlen(szPath)-1;
|
|
for (; i>0; i--)
|
|
{
|
|
if (szPath[i] == TEXT('\\'))
|
|
{
|
|
szPath[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return szPath;
|
|
}
|
|
|
|
PFAX_PORT_INFO_EX
|
|
FindPortInfo(
|
|
DWORD dwDeviceId
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find FAX_PORT_INFO_EX by dwDeviceId in g_pFaxPortInfo
|
|
|
|
Arguments:
|
|
|
|
dwDeviceId - [in] device ID to find
|
|
|
|
Return Value:
|
|
|
|
pointer to FAX_PORT_INFO_EX structure if found
|
|
NULL otherwise
|
|
|
|
--*/
|
|
{
|
|
DWORD dw;
|
|
|
|
if(!g_pFaxPortInfo || !g_dwPortsNum)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for(dw=0; dw < g_dwPortsNum; ++dw)
|
|
{
|
|
if(g_pFaxPortInfo[dw].dwDeviceID == dwDeviceId)
|
|
{
|
|
return &g_pFaxPortInfo[dw];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
BOOL
|
|
CALLBACK
|
|
PageEnableProc(
|
|
HWND hwnd,
|
|
LPARAM lParam
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Disable each control of a property page
|
|
|
|
Arguments:
|
|
|
|
hwnd - [in] handle to child window
|
|
lParam - [in] BOOL bEnable
|
|
|
|
Return Value:
|
|
|
|
TRUE to continue enumeration
|
|
|
|
--*/
|
|
{
|
|
EnableWindow(hwnd, (BOOL)lParam);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void
|
|
PageEnable(
|
|
HWND hDlg,
|
|
BOOL bEnable
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Enumerate and enable/disable all controls of a property page
|
|
|
|
Arguments:
|
|
|
|
hDlg - [in] property page handle
|
|
bEnable - [in] TRUE for enable, FALSE for disable
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
if(!EnumChildWindows(hDlg, PageEnableProc, (LPARAM)bEnable))
|
|
{
|
|
Error(( "EnumChildWindows failed with %d\n", GetLastError()));
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
CountUsedFaxDevices()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Count the number of the devices configured to send or receive faxes
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
Number of the fax devices
|
|
|
|
--*/
|
|
{
|
|
DWORD dw;
|
|
DWORD dwNum=0;
|
|
|
|
if(!g_pFaxPortInfo || !g_dwPortsNum)
|
|
{
|
|
return dwNum;
|
|
}
|
|
|
|
for(dw=0; dw < g_dwPortsNum; ++dw)
|
|
{
|
|
if(g_pFaxPortInfo[dw].bSend || (FAX_DEVICE_RECEIVE_MODE_OFF != g_pFaxPortInfo[dw].ReceiveMode))
|
|
{
|
|
++dwNum;
|
|
}
|
|
}
|
|
return dwNum;
|
|
}
|
|
|
|
BOOL
|
|
IsDeviceInUse(
|
|
DWORD dwDeviceId
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determine whether the device is configured for send or receive
|
|
|
|
Arguments:
|
|
|
|
dwDeviceId - [in] Device ID
|
|
|
|
Return Value:
|
|
|
|
TRUE if the device is configured for send or receive
|
|
FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
PFAX_PORT_INFO_EX pPortInfo = FindPortInfo(dwDeviceId);
|
|
if(!pPortInfo)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(pPortInfo->bSend || (FAX_DEVICE_RECEIVE_MODE_OFF != pPortInfo->ReceiveMode))
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|