windows-nt/Source/XPSP1/NT/printscan/fax/admin/faxadmin/ddevmain.cpp
2020-09-26 16:20:57 +08:00

607 lines
19 KiB
C++

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
dcomputer.cpp
Abstract:
This file contains implementation of
the computer selection dialog.
Environment:
WIN32 User Mode
Author:
Darwin Ouyang (t-darouy) 30-Sept-1997
--*/
#include "stdafx.h"
#include "faxcompd.h"
#include "faxcomp.h"
#include "ddevmain.h"
#include "inode.h"
#include "idevice.h"
#include "adminhlp.h"
#include "faxreg.h"
#pragma hdrstop
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Constructor and destructor
//
//
CFaxDeviceSettingsPropSheet::CFaxDeviceSettingsPropSheet(
IN HINSTANCE hInstance,
IN LONG_PTR hMmcNotify,
IN CInternalDevice * NodePtr,
IN CFaxComponent * pComp
)
: _hMmcNotify( hMmcNotify ),
_dwDeviceId( 0 ),
_hFaxServer( 0 ),
_pOwnNode( NodePtr ),
_pCompData( NULL ),
_pComp( pComp )
/*++
Routine Description:
Constructor
Arguments:
hInstance - the instance pointer
hMmcNotify - the MMC notify handle
NodePtr - a pointer to the owning node
Return Value:
None.
--*/
{
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(icex);
icex.dwICC = ICC_DATE_CLASSES;
InitCommonControlsEx(&icex);
DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet Created") ));
_PropSheet.dwSize = sizeof( *this );
_PropSheet.dwFlags = PSP_USETITLE | PSP_USECALLBACK;
_PropSheet.hInstance = hInstance;
_PropSheet.pszTemplate = MAKEINTRESOURCE(IDP_DEVICE_PROP_PAGE_1);
_PropSheet.pszTitle = MAKEINTRESOURCE(IDP_DEVICE_PROP_PAGE_1_TITLE);
_PropSheet.pfnDlgProc = CFaxDeviceSettingsPropSheet::DlgProc;
_PropSheet.lParam = (LONG_PTR)this;
_PropSheet.pfnCallback = &PropSheetPageProc;
_hPropSheet = NULL;
_hPropSheet = CreatePropertySheetPage( &_PropSheet );
assert(_hPropSheet != NULL );
assert( NodePtr != NULL );
assert( NodePtr->pDeviceInfo != NULL );
_hFaxServer = NodePtr->hFaxServer;
_dwDeviceId = NodePtr->pDeviceInfo->DeviceId;
_pCompData = NodePtr->m_pCompData;
}
CFaxDeviceSettingsPropSheet::~CFaxDeviceSettingsPropSheet()
/*++
Routine Description:
Destructor
Arguments:
None.
Return Value:
None.
--*/
{
DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet Destroyed") ));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Dialog Proc
//
//
INT_PTR
APIENTRY
CFaxDeviceSettingsPropSheet::DlgProc(
IN HWND hwndDlg,
IN UINT message,
IN WPARAM wParam,
IN LPARAM lParam
)
/*++
Routine Description:
Dialog Procedure
Arguments:
hwndDlg - the hwnd of the dialog
message - the message
wParam, lParam - the window message parameters
Return Value:
BOOL
--*/
{
// DebugPrint(( TEXT("Trace: CFaxDeviceSettingsPropSheet::DlgProc") ));
BOOL fRet = FALSE;
HWND hwnd = NULL;
HWND hwndSheet = NULL;
switch( message ) {
case WM_INITDIALOG:
{
DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet::DlgProc -- WM_INITDIALOG\n") ));
assert( lParam != NULL );
LONG_PTR lthis = ((CFaxDeviceSettingsPropSheet *)lParam)->_PropSheet.lParam;
CFaxDeviceSettingsPropSheet * pthis = (CFaxDeviceSettingsPropSheet *)lthis;
assert( pthis != NULL );
SetWindowLongPtr( hwndDlg, DWLP_USER, lthis );
// setup the spinner control
hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS );
SendMessage( hwnd, UDM_SETRANGE32, MIN_RING_COUNT, MAX_RING_COUNT );
SendMessage( hwnd, UDM_SETPOS, 0, (LPARAM) MAKELONG((short) pthis->_pOwnNode->pDeviceInfo->Rings, 0) );
SendMessage( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_RINGS ), EM_SETLIMITTEXT, 2, 0 );
// setup TSID control
SetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID, pthis->_pOwnNode->pDeviceInfo->Tsid );
SendMessage( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID ), EM_SETLIMITTEXT, TSID_LIMIT, 0 );
// setup send checkbox
CheckDlgButton(hwndDlg,IDC_SEND,((pthis->_pOwnNode->pDeviceInfo->Flags & FPF_SEND) == FPF_SEND));
// setup CSID control
SetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID, pthis->_pOwnNode->pDeviceInfo->Csid );
SendMessage( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID ), EM_SETLIMITTEXT, CSID_LIMIT , 0 );
// setup receive checkbox
CheckDlgButton(hwndDlg,IDC_RECEIVE,((pthis->_pOwnNode->pDeviceInfo->Flags & FPF_RECEIVE) == FPF_RECEIVE));
EnableWindow( GetDlgItem( hwndDlg, IDC_STATIC_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
EnableWindow( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
EnableWindow( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
pthis->_pComp->IncPropSheetCount();
fRet = TRUE;
break;
}
case WM_COMMAND:
{
DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet::DlgProc -- WM_COMMAND\n") ));
// activate apply button
WORD wID = LOWORD( wParam );
switch( wID ) {
case IDDI_DEVICE_PROP_EDIT_CSID:
case IDDI_DEVICE_PROP_EDIT_TSID:
case IDDI_DEVICE_PROP_EDIT_RINGS:
if( HIWORD(wParam) == EN_CHANGE ) { // notification code
hwndSheet = GetParent( hwndDlg );
PropSheet_Changed( hwndSheet, hwndDlg );
}
break;
case IDC_RECEIVE:
EnableWindow( GetDlgItem( hwndDlg, IDC_STATIC_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
EnableWindow( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
EnableWindow( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
case IDC_SEND:
if ( HIWORD(wParam) == BN_CLICKED ) { // notification code
hwndSheet = GetParent( hwndDlg );
PropSheet_Changed( hwndSheet, hwndDlg );
}
default:
break;
} // switch
fRet = TRUE;
break;
}
case WM_HELP:
WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle,
FAXCFG_HELP_FILENAME,
HELP_WM_HELP,
(ULONG_PTR) &DeviceGeneralHelpIDs);
fRet = TRUE;
break;
case WM_CONTEXTMENU:
WinHelp((HWND) wParam,
FAXCFG_HELP_FILENAME,
HELP_CONTEXTMENU,
(ULONG_PTR) &DeviceGeneralHelpIDs);
fRet = TRUE;
break;
case WM_NOTIFY:
{
// DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet::DlgProc -- WM_NOTIFY\n") ));
CFaxDeviceSettingsPropSheet * pthis =
(CFaxDeviceSettingsPropSheet *)GetWindowLongPtr( hwndDlg,
DWLP_USER );
switch( ((LPNMHDR) lParam)->code ) {
case PSN_APPLY:
{
// apply changes here!!
if (SUCCEEDED(pthis->ValidateData( hwndDlg) )) {
pthis->UpdateData( hwndDlg );
MMCPropertyChangeNotify( pthis->_hMmcNotify, (LONG_PTR)pthis->_pOwnNode );
// deactivate apply button
hwndSheet = GetParent( hwndDlg );
PropSheet_UnChanged( hwndSheet, hwndDlg );
fRet = TRUE;
} else {
fRet = FALSE;
}
break;
}
} // switch
break;
}
case WM_DESTROY:
{
DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet::DlgProc -- WM_DESTROY\n") ));
CFaxDeviceSettingsPropSheet * pthis =
(CFaxDeviceSettingsPropSheet *)GetWindowLongPtr( hwndDlg,
DWLP_USER );
if( pthis != NULL ) {
pthis->_pComp->DecPropSheetCount();
MMCFreeNotifyHandle( pthis->_hMmcNotify );
}
fRet = TRUE;
break;
}
} // switch
return fRet;
}
// the settings are updated in the property sheet because this
// allows the property sheet to complete even if the snapin or
// owner node has already been destroyed.
HRESULT
CFaxDeviceSettingsPropSheet::UpdateData(
HWND hwndDlg
)
/*++
Routine Description:
Update Data method
Arguments:
hwndDlg - the hwnd of the dialog
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
DebugPrint(( TEXT("Trace: CInternalDevice::UpdateData") ));
assert( hwndDlg != NULL );
HRESULT hr = S_OK;
HANDLE portHandle = NULL;
HWND hwnd;
PFAX_PORT_INFO pDeviceInfo = NULL;
LRESULT lr;
UINT rc;
TCHAR m_Tsid[ TSID_LIMIT+1 ];
TCHAR m_Csid[ CSID_LIMIT+1 ];
ZeroMemory( m_Tsid, sizeof(TCHAR) * (TSID_LIMIT+1) );
ZeroMemory( m_Csid, sizeof(TCHAR) * (CSID_LIMIT+1) );
try {
do {
if( _pCompData->QueryRpcError() ) {
hr = E_UNEXPECTED;
break;
}
// open the port
if( !FaxOpenPort( _hFaxServer, _dwDeviceId, PORT_OPEN_MODIFY, &portHandle ) ) {
if (GetLastError() != ERROR_ACCESS_DENIED) {
_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
}
::GlobalStringTable->SystemErrorMsg( GetLastError() );
hr = E_UNEXPECTED;
break;
}
// get data
if( !FaxGetPort( portHandle, &pDeviceInfo ) ) {
if (GetLastError() != ERROR_ACCESS_DENIED) {
_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
}
::GlobalStringTable->SystemErrorMsg( GetLastError() );
hr = E_UNEXPECTED;
break;
}
// grab the TSID and CSID from the dialog
hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID );
rc = GetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID, m_Tsid, TSID_LIMIT+1 );
if( rc == 0 ) {
assert( FALSE );
hr = E_UNEXPECTED;
break;
}
hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID );
rc = GetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID, m_Csid, CSID_LIMIT+1 );
if( rc == 0 ) {
assert( FALSE );
hr = E_UNEXPECTED;
break;
}
assert( pDeviceInfo != NULL );
pDeviceInfo->Tsid = m_Tsid;
pDeviceInfo->Csid = m_Csid;
// grab the position from the spinner control
hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS );
lr = SendMessage( hwnd, UDM_GETPOS, 0, 0 );
if( HIWORD( lr ) != 0 ) {
assert( FALSE );
hr = E_UNEXPECTED;
break;
}
pDeviceInfo->Rings = LOWORD( lr );
pDeviceInfo->Rings = max(pDeviceInfo->Rings,MIN_RING_COUNT);
pDeviceInfo->Rings = min(pDeviceInfo->Rings,MAX_RING_COUNT);
//grab the send and receive checkbox from the dialog
pDeviceInfo->Flags = (IsDlgButtonChecked(hwndDlg,IDC_RECEIVE) == BST_CHECKED) ?
(pDeviceInfo->Flags | FPF_RECEIVE) :
(pDeviceInfo->Flags & (~FPF_RECEIVE)) ;
pDeviceInfo->Flags = (IsDlgButtonChecked(hwndDlg,IDC_SEND) == BST_CHECKED) ?
(pDeviceInfo->Flags | FPF_SEND) :
(pDeviceInfo->Flags & (~FPF_SEND)) ;
// set new settings
if( !FaxSetPort( portHandle, pDeviceInfo ) ) {
DWORD ec = GetLastError();
if (ec != ERROR_ACCESS_DENIED && ec != ERROR_DEVICE_IN_USE) {
_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
}
if (ec == ERROR_DEVICE_IN_USE)
::GlobalStringTable->PopUpMsg( hwndDlg, IDS_DEVICE_INUSE, TRUE, 0 );
else
::GlobalStringTable->SystemErrorMsg( ec );
hr = E_UNEXPECTED;
break;
}
FaxClose( portHandle );
FaxFreeBuffer( (PVOID) pDeviceInfo );
pDeviceInfo = NULL;
portHandle = NULL;
// See if faxstat is running
HWND hWndFaxStat = FindWindow(FAXSTAT_WINCLASS, NULL);
if (hWndFaxStat) {
if (SendMessage(hWndFaxStat, WM_FAXSTAT_MMC, (WPARAM) _dwDeviceId, 0)) {
::GlobalStringTable->PopUpMsg( hwndDlg, IDS_DEVICE_MANUALANSWER, FALSE, 0 );
}
}
} while( 0 );
} catch( ... ) {
_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
hr = E_UNEXPECTED;
}
if(portHandle != NULL ) {
FaxClose( portHandle );
FaxFreeBuffer( (PVOID) pDeviceInfo );
pDeviceInfo = NULL;
}
return hr;
}
UINT
CALLBACK
CFaxDeviceSettingsPropSheet::PropSheetPageProc(
HWND hwnd,
UINT uMsg,
LPPROPSHEETPAGE ppsp
)
/*++
Routine Description:
Dialog Init and destroy routine
Arguments:
hwndDlg - the hwnd of the dialog - will be NULL
uMsg - the message PSPCB_CREATE or PSPCB_RELEASE
ppsp - pointer to a PROPERTYSHEETPAGE struct
Return Value:
UINT - nonzero to allow, zero to fail
--*/
{
CFaxDeviceSettingsPropSheet * pthis = NULL;
UINT retval = 1;
// release my property sheet
if( uMsg == PSPCB_RELEASE ) {
try {
pthis = (CFaxDeviceSettingsPropSheet * )(ppsp->lParam);
delete pthis;
} catch( ... ) {
assert( FALSE );
retval = 0;
}
}
return retval;
}
BOOL
IsAscii(
LPCWSTR ptszChar
)
{
BOOL fReturnValue = TRUE;
while ( (*ptszChar != (WCHAR) TEXT('\0')) &&
( fReturnValue != (BOOL) FALSE) ) {
if ( (*ptszChar < (WCHAR) 0x0020) || (*ptszChar > (WCHAR) MAXCHAR) ) {
fReturnValue = (BOOL) FALSE;
}
ptszChar = _wcsinc( ptszChar );
}
return fReturnValue;
}
HRESULT
CFaxDeviceSettingsPropSheet::ValidateData(
HWND hwndDlg
)
/*++
Routine Description:
validate Data method
Arguments:
hwndDlg - the hwnd of the dialog
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
DebugPrint(( TEXT("Trace: CInternalDevice::ValidateData") ));
assert( hwndDlg != NULL );
HWND hwnd;
UINT rc;
TCHAR Tsid[ TSID_LIMIT+1 ] = {0};
TCHAR Csid[ CSID_LIMIT+1 ] = {0};
DWORD Rings;
LRESULT lr;
// grab the TSID and CSID from the dialog
hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID );
rc = GetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID, Tsid, TSID_LIMIT+1 );
hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID );
rc = GetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID, Csid, CSID_LIMIT+1 );
// get the ring count
hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS );
lr = SendMessage( hwnd, UDM_GETPOS, 0, 0 );
if( HIWORD( lr ) != 0 ) {
::GlobalStringTable->PopUpMsg( hwndDlg, IDS_ERR_INVALID_RING, TRUE, 0 );
return( E_FAIL);
}
Rings = LOWORD( lr );
//
// make sure the CSID and TSID are both ascii strings
//
if (!*Csid || !*Tsid) {
::GlobalStringTable->PopUpMsg( hwndDlg, IDS_ERR_ID_REQD, TRUE, 0 );
return E_FAIL;
}
if (!IsAscii(Csid) || !IsAscii(Tsid)) {
::GlobalStringTable->PopUpMsg( hwndDlg, IDS_ERR_ASCII_ONLY, TRUE, 0 );
return E_FAIL;
}
if (Rings < MIN_RING_COUNT || Rings > MAX_RING_COUNT) {
::GlobalStringTable->PopUpMsg( hwndDlg, IDS_ERR_INVALID_RING, TRUE, 0 );
return E_FAIL;
}
return S_OK;
}