/*++ 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; }