Source code of Windows XP (NT5)
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.

606 lines
19 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. dcomputer.cpp
  5. Abstract:
  6. This file contains implementation of
  7. the computer selection dialog.
  8. Environment:
  9. WIN32 User Mode
  10. Author:
  11. Darwin Ouyang (t-darouy) 30-Sept-1997
  12. --*/
  13. #include "stdafx.h"
  14. #include "faxcompd.h"
  15. #include "faxcomp.h"
  16. #include "ddevmain.h"
  17. #include "inode.h"
  18. #include "idevice.h"
  19. #include "adminhlp.h"
  20. #include "faxreg.h"
  21. #pragma hdrstop
  22. ////////////////////////////////////////////////////////////////////////////////////////////////////
  23. ////////////////////////////////////////////////////////////////////////////////////////////////////
  24. ////////////////////////////////////////////////////////////////////////////////////////////////////
  25. ////////////////////////////////////////////////////////////////////////////////////////////////////
  26. //
  27. //
  28. // Constructor and destructor
  29. //
  30. //
  31. CFaxDeviceSettingsPropSheet::CFaxDeviceSettingsPropSheet(
  32. IN HINSTANCE hInstance,
  33. IN LONG_PTR hMmcNotify,
  34. IN CInternalDevice * NodePtr,
  35. IN CFaxComponent * pComp
  36. )
  37. : _hMmcNotify( hMmcNotify ),
  38. _dwDeviceId( 0 ),
  39. _hFaxServer( 0 ),
  40. _pOwnNode( NodePtr ),
  41. _pCompData( NULL ),
  42. _pComp( pComp )
  43. /*++
  44. Routine Description:
  45. Constructor
  46. Arguments:
  47. hInstance - the instance pointer
  48. hMmcNotify - the MMC notify handle
  49. NodePtr - a pointer to the owning node
  50. Return Value:
  51. None.
  52. --*/
  53. {
  54. INITCOMMONCONTROLSEX icex;
  55. icex.dwSize = sizeof(icex);
  56. icex.dwICC = ICC_DATE_CLASSES;
  57. InitCommonControlsEx(&icex);
  58. DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet Created") ));
  59. _PropSheet.dwSize = sizeof( *this );
  60. _PropSheet.dwFlags = PSP_USETITLE | PSP_USECALLBACK;
  61. _PropSheet.hInstance = hInstance;
  62. _PropSheet.pszTemplate = MAKEINTRESOURCE(IDP_DEVICE_PROP_PAGE_1);
  63. _PropSheet.pszTitle = MAKEINTRESOURCE(IDP_DEVICE_PROP_PAGE_1_TITLE);
  64. _PropSheet.pfnDlgProc = CFaxDeviceSettingsPropSheet::DlgProc;
  65. _PropSheet.lParam = (LONG_PTR)this;
  66. _PropSheet.pfnCallback = &PropSheetPageProc;
  67. _hPropSheet = NULL;
  68. _hPropSheet = CreatePropertySheetPage( &_PropSheet );
  69. assert(_hPropSheet != NULL );
  70. assert( NodePtr != NULL );
  71. assert( NodePtr->pDeviceInfo != NULL );
  72. _hFaxServer = NodePtr->hFaxServer;
  73. _dwDeviceId = NodePtr->pDeviceInfo->DeviceId;
  74. _pCompData = NodePtr->m_pCompData;
  75. }
  76. CFaxDeviceSettingsPropSheet::~CFaxDeviceSettingsPropSheet()
  77. /*++
  78. Routine Description:
  79. Destructor
  80. Arguments:
  81. None.
  82. Return Value:
  83. None.
  84. --*/
  85. {
  86. DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet Destroyed") ));
  87. }
  88. ////////////////////////////////////////////////////////////////////////////////////////////////////
  89. ////////////////////////////////////////////////////////////////////////////////////////////////////
  90. ////////////////////////////////////////////////////////////////////////////////////////////////////
  91. ////////////////////////////////////////////////////////////////////////////////////////////////////
  92. //
  93. //
  94. // Dialog Proc
  95. //
  96. //
  97. INT_PTR
  98. APIENTRY
  99. CFaxDeviceSettingsPropSheet::DlgProc(
  100. IN HWND hwndDlg,
  101. IN UINT message,
  102. IN WPARAM wParam,
  103. IN LPARAM lParam
  104. )
  105. /*++
  106. Routine Description:
  107. Dialog Procedure
  108. Arguments:
  109. hwndDlg - the hwnd of the dialog
  110. message - the message
  111. wParam, lParam - the window message parameters
  112. Return Value:
  113. BOOL
  114. --*/
  115. {
  116. // DebugPrint(( TEXT("Trace: CFaxDeviceSettingsPropSheet::DlgProc") ));
  117. BOOL fRet = FALSE;
  118. HWND hwnd = NULL;
  119. HWND hwndSheet = NULL;
  120. switch( message ) {
  121. case WM_INITDIALOG:
  122. {
  123. DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet::DlgProc -- WM_INITDIALOG\n") ));
  124. assert( lParam != NULL );
  125. LONG_PTR lthis = ((CFaxDeviceSettingsPropSheet *)lParam)->_PropSheet.lParam;
  126. CFaxDeviceSettingsPropSheet * pthis = (CFaxDeviceSettingsPropSheet *)lthis;
  127. assert( pthis != NULL );
  128. SetWindowLongPtr( hwndDlg, DWLP_USER, lthis );
  129. // setup the spinner control
  130. hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS );
  131. SendMessage( hwnd, UDM_SETRANGE32, MIN_RING_COUNT, MAX_RING_COUNT );
  132. SendMessage( hwnd, UDM_SETPOS, 0, (LPARAM) MAKELONG((short) pthis->_pOwnNode->pDeviceInfo->Rings, 0) );
  133. SendMessage( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_RINGS ), EM_SETLIMITTEXT, 2, 0 );
  134. // setup TSID control
  135. SetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID, pthis->_pOwnNode->pDeviceInfo->Tsid );
  136. SendMessage( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID ), EM_SETLIMITTEXT, TSID_LIMIT, 0 );
  137. // setup send checkbox
  138. CheckDlgButton(hwndDlg,IDC_SEND,((pthis->_pOwnNode->pDeviceInfo->Flags & FPF_SEND) == FPF_SEND));
  139. // setup CSID control
  140. SetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID, pthis->_pOwnNode->pDeviceInfo->Csid );
  141. SendMessage( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID ), EM_SETLIMITTEXT, CSID_LIMIT , 0 );
  142. // setup receive checkbox
  143. CheckDlgButton(hwndDlg,IDC_RECEIVE,((pthis->_pOwnNode->pDeviceInfo->Flags & FPF_RECEIVE) == FPF_RECEIVE));
  144. EnableWindow( GetDlgItem( hwndDlg, IDC_STATIC_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
  145. EnableWindow( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
  146. EnableWindow( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
  147. pthis->_pComp->IncPropSheetCount();
  148. fRet = TRUE;
  149. break;
  150. }
  151. case WM_COMMAND:
  152. {
  153. DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet::DlgProc -- WM_COMMAND\n") ));
  154. // activate apply button
  155. WORD wID = LOWORD( wParam );
  156. switch( wID ) {
  157. case IDDI_DEVICE_PROP_EDIT_CSID:
  158. case IDDI_DEVICE_PROP_EDIT_TSID:
  159. case IDDI_DEVICE_PROP_EDIT_RINGS:
  160. if( HIWORD(wParam) == EN_CHANGE ) { // notification code
  161. hwndSheet = GetParent( hwndDlg );
  162. PropSheet_Changed( hwndSheet, hwndDlg );
  163. }
  164. break;
  165. case IDC_RECEIVE:
  166. EnableWindow( GetDlgItem( hwndDlg, IDC_STATIC_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
  167. EnableWindow( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
  168. EnableWindow( GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS ), IsDlgButtonChecked( hwndDlg,IDC_RECEIVE ) );
  169. case IDC_SEND:
  170. if ( HIWORD(wParam) == BN_CLICKED ) { // notification code
  171. hwndSheet = GetParent( hwndDlg );
  172. PropSheet_Changed( hwndSheet, hwndDlg );
  173. }
  174. default:
  175. break;
  176. } // switch
  177. fRet = TRUE;
  178. break;
  179. }
  180. case WM_HELP:
  181. WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle,
  182. FAXCFG_HELP_FILENAME,
  183. HELP_WM_HELP,
  184. (ULONG_PTR) &DeviceGeneralHelpIDs);
  185. fRet = TRUE;
  186. break;
  187. case WM_CONTEXTMENU:
  188. WinHelp((HWND) wParam,
  189. FAXCFG_HELP_FILENAME,
  190. HELP_CONTEXTMENU,
  191. (ULONG_PTR) &DeviceGeneralHelpIDs);
  192. fRet = TRUE;
  193. break;
  194. case WM_NOTIFY:
  195. {
  196. // DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet::DlgProc -- WM_NOTIFY\n") ));
  197. CFaxDeviceSettingsPropSheet * pthis =
  198. (CFaxDeviceSettingsPropSheet *)GetWindowLongPtr( hwndDlg,
  199. DWLP_USER );
  200. switch( ((LPNMHDR) lParam)->code ) {
  201. case PSN_APPLY:
  202. {
  203. // apply changes here!!
  204. if (SUCCEEDED(pthis->ValidateData( hwndDlg) )) {
  205. pthis->UpdateData( hwndDlg );
  206. MMCPropertyChangeNotify( pthis->_hMmcNotify, (LONG_PTR)pthis->_pOwnNode );
  207. // deactivate apply button
  208. hwndSheet = GetParent( hwndDlg );
  209. PropSheet_UnChanged( hwndSheet, hwndDlg );
  210. fRet = TRUE;
  211. } else {
  212. fRet = FALSE;
  213. }
  214. break;
  215. }
  216. } // switch
  217. break;
  218. }
  219. case WM_DESTROY:
  220. {
  221. DebugPrint(( TEXT("CFaxDeviceSettingsPropSheet::DlgProc -- WM_DESTROY\n") ));
  222. CFaxDeviceSettingsPropSheet * pthis =
  223. (CFaxDeviceSettingsPropSheet *)GetWindowLongPtr( hwndDlg,
  224. DWLP_USER );
  225. if( pthis != NULL ) {
  226. pthis->_pComp->DecPropSheetCount();
  227. MMCFreeNotifyHandle( pthis->_hMmcNotify );
  228. }
  229. fRet = TRUE;
  230. break;
  231. }
  232. } // switch
  233. return fRet;
  234. }
  235. // the settings are updated in the property sheet because this
  236. // allows the property sheet to complete even if the snapin or
  237. // owner node has already been destroyed.
  238. HRESULT
  239. CFaxDeviceSettingsPropSheet::UpdateData(
  240. HWND hwndDlg
  241. )
  242. /*++
  243. Routine Description:
  244. Update Data method
  245. Arguments:
  246. hwndDlg - the hwnd of the dialog
  247. Return Value:
  248. HRESULT indicating SUCCEEDED() or FAILED()
  249. --*/
  250. {
  251. DebugPrint(( TEXT("Trace: CInternalDevice::UpdateData") ));
  252. assert( hwndDlg != NULL );
  253. HRESULT hr = S_OK;
  254. HANDLE portHandle = NULL;
  255. HWND hwnd;
  256. PFAX_PORT_INFO pDeviceInfo = NULL;
  257. LRESULT lr;
  258. UINT rc;
  259. TCHAR m_Tsid[ TSID_LIMIT+1 ];
  260. TCHAR m_Csid[ CSID_LIMIT+1 ];
  261. ZeroMemory( m_Tsid, sizeof(TCHAR) * (TSID_LIMIT+1) );
  262. ZeroMemory( m_Csid, sizeof(TCHAR) * (CSID_LIMIT+1) );
  263. try {
  264. do {
  265. if( _pCompData->QueryRpcError() ) {
  266. hr = E_UNEXPECTED;
  267. break;
  268. }
  269. // open the port
  270. if( !FaxOpenPort( _hFaxServer, _dwDeviceId, PORT_OPEN_MODIFY, &portHandle ) ) {
  271. if (GetLastError() != ERROR_ACCESS_DENIED) {
  272. _pCompData->NotifyRpcError( TRUE );
  273. assert(FALSE);
  274. }
  275. ::GlobalStringTable->SystemErrorMsg( GetLastError() );
  276. hr = E_UNEXPECTED;
  277. break;
  278. }
  279. // get data
  280. if( !FaxGetPort( portHandle, &pDeviceInfo ) ) {
  281. if (GetLastError() != ERROR_ACCESS_DENIED) {
  282. _pCompData->NotifyRpcError( TRUE );
  283. assert(FALSE);
  284. }
  285. ::GlobalStringTable->SystemErrorMsg( GetLastError() );
  286. hr = E_UNEXPECTED;
  287. break;
  288. }
  289. // grab the TSID and CSID from the dialog
  290. hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID );
  291. rc = GetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID, m_Tsid, TSID_LIMIT+1 );
  292. if( rc == 0 ) {
  293. assert( FALSE );
  294. hr = E_UNEXPECTED;
  295. break;
  296. }
  297. hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID );
  298. rc = GetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID, m_Csid, CSID_LIMIT+1 );
  299. if( rc == 0 ) {
  300. assert( FALSE );
  301. hr = E_UNEXPECTED;
  302. break;
  303. }
  304. assert( pDeviceInfo != NULL );
  305. pDeviceInfo->Tsid = m_Tsid;
  306. pDeviceInfo->Csid = m_Csid;
  307. // grab the position from the spinner control
  308. hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS );
  309. lr = SendMessage( hwnd, UDM_GETPOS, 0, 0 );
  310. if( HIWORD( lr ) != 0 ) {
  311. assert( FALSE );
  312. hr = E_UNEXPECTED;
  313. break;
  314. }
  315. pDeviceInfo->Rings = LOWORD( lr );
  316. pDeviceInfo->Rings = max(pDeviceInfo->Rings,MIN_RING_COUNT);
  317. pDeviceInfo->Rings = min(pDeviceInfo->Rings,MAX_RING_COUNT);
  318. //grab the send and receive checkbox from the dialog
  319. pDeviceInfo->Flags = (IsDlgButtonChecked(hwndDlg,IDC_RECEIVE) == BST_CHECKED) ?
  320. (pDeviceInfo->Flags | FPF_RECEIVE) :
  321. (pDeviceInfo->Flags & (~FPF_RECEIVE)) ;
  322. pDeviceInfo->Flags = (IsDlgButtonChecked(hwndDlg,IDC_SEND) == BST_CHECKED) ?
  323. (pDeviceInfo->Flags | FPF_SEND) :
  324. (pDeviceInfo->Flags & (~FPF_SEND)) ;
  325. // set new settings
  326. if( !FaxSetPort( portHandle, pDeviceInfo ) ) {
  327. DWORD ec = GetLastError();
  328. if (ec != ERROR_ACCESS_DENIED && ec != ERROR_DEVICE_IN_USE) {
  329. _pCompData->NotifyRpcError( TRUE );
  330. assert(FALSE);
  331. }
  332. if (ec == ERROR_DEVICE_IN_USE)
  333. ::GlobalStringTable->PopUpMsg( hwndDlg, IDS_DEVICE_INUSE, TRUE, 0 );
  334. else
  335. ::GlobalStringTable->SystemErrorMsg( ec );
  336. hr = E_UNEXPECTED;
  337. break;
  338. }
  339. FaxClose( portHandle );
  340. FaxFreeBuffer( (PVOID) pDeviceInfo );
  341. pDeviceInfo = NULL;
  342. portHandle = NULL;
  343. // See if faxstat is running
  344. HWND hWndFaxStat = FindWindow(FAXSTAT_WINCLASS, NULL);
  345. if (hWndFaxStat) {
  346. if (SendMessage(hWndFaxStat, WM_FAXSTAT_MMC, (WPARAM) _dwDeviceId, 0)) {
  347. ::GlobalStringTable->PopUpMsg( hwndDlg, IDS_DEVICE_MANUALANSWER, FALSE, 0 );
  348. }
  349. }
  350. } while( 0 );
  351. } catch( ... ) {
  352. _pCompData->NotifyRpcError( TRUE );
  353. assert(FALSE);
  354. hr = E_UNEXPECTED;
  355. }
  356. if(portHandle != NULL ) {
  357. FaxClose( portHandle );
  358. FaxFreeBuffer( (PVOID) pDeviceInfo );
  359. pDeviceInfo = NULL;
  360. }
  361. return hr;
  362. }
  363. UINT
  364. CALLBACK
  365. CFaxDeviceSettingsPropSheet::PropSheetPageProc(
  366. HWND hwnd,
  367. UINT uMsg,
  368. LPPROPSHEETPAGE ppsp
  369. )
  370. /*++
  371. Routine Description:
  372. Dialog Init and destroy routine
  373. Arguments:
  374. hwndDlg - the hwnd of the dialog - will be NULL
  375. uMsg - the message PSPCB_CREATE or PSPCB_RELEASE
  376. ppsp - pointer to a PROPERTYSHEETPAGE struct
  377. Return Value:
  378. UINT - nonzero to allow, zero to fail
  379. --*/
  380. {
  381. CFaxDeviceSettingsPropSheet * pthis = NULL;
  382. UINT retval = 1;
  383. // release my property sheet
  384. if( uMsg == PSPCB_RELEASE ) {
  385. try {
  386. pthis = (CFaxDeviceSettingsPropSheet * )(ppsp->lParam);
  387. delete pthis;
  388. } catch( ... ) {
  389. assert( FALSE );
  390. retval = 0;
  391. }
  392. }
  393. return retval;
  394. }
  395. BOOL
  396. IsAscii(
  397. LPCWSTR ptszChar
  398. )
  399. {
  400. BOOL fReturnValue = TRUE;
  401. while ( (*ptszChar != (WCHAR) TEXT('\0')) &&
  402. ( fReturnValue != (BOOL) FALSE) ) {
  403. if ( (*ptszChar < (WCHAR) 0x0020) || (*ptszChar > (WCHAR) MAXCHAR) ) {
  404. fReturnValue = (BOOL) FALSE;
  405. }
  406. ptszChar = _wcsinc( ptszChar );
  407. }
  408. return fReturnValue;
  409. }
  410. HRESULT
  411. CFaxDeviceSettingsPropSheet::ValidateData(
  412. HWND hwndDlg
  413. )
  414. /*++
  415. Routine Description:
  416. validate Data method
  417. Arguments:
  418. hwndDlg - the hwnd of the dialog
  419. Return Value:
  420. HRESULT indicating SUCCEEDED() or FAILED()
  421. --*/
  422. {
  423. DebugPrint(( TEXT("Trace: CInternalDevice::ValidateData") ));
  424. assert( hwndDlg != NULL );
  425. HWND hwnd;
  426. UINT rc;
  427. TCHAR Tsid[ TSID_LIMIT+1 ] = {0};
  428. TCHAR Csid[ CSID_LIMIT+1 ] = {0};
  429. DWORD Rings;
  430. LRESULT lr;
  431. // grab the TSID and CSID from the dialog
  432. hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID );
  433. rc = GetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_TSID, Tsid, TSID_LIMIT+1 );
  434. hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID );
  435. rc = GetDlgItemText( hwndDlg, IDDI_DEVICE_PROP_EDIT_CSID, Csid, CSID_LIMIT+1 );
  436. // get the ring count
  437. hwnd = GetDlgItem( hwndDlg, IDDI_DEVICE_PROP_SPIN_RINGS );
  438. lr = SendMessage( hwnd, UDM_GETPOS, 0, 0 );
  439. if( HIWORD( lr ) != 0 ) {
  440. ::GlobalStringTable->PopUpMsg( hwndDlg, IDS_ERR_INVALID_RING, TRUE, 0 );
  441. return( E_FAIL);
  442. }
  443. Rings = LOWORD( lr );
  444. //
  445. // make sure the CSID and TSID are both ascii strings
  446. //
  447. if (!*Csid || !*Tsid) {
  448. ::GlobalStringTable->PopUpMsg( hwndDlg, IDS_ERR_ID_REQD, TRUE, 0 );
  449. return E_FAIL;
  450. }
  451. if (!IsAscii(Csid) || !IsAscii(Tsid)) {
  452. ::GlobalStringTable->PopUpMsg( hwndDlg, IDS_ERR_ASCII_ONLY, TRUE, 0 );
  453. return E_FAIL;
  454. }
  455. if (Rings < MIN_RING_COUNT || Rings > MAX_RING_COUNT) {
  456. ::GlobalStringTable->PopUpMsg( hwndDlg, IDS_ERR_INVALID_RING, TRUE, 0 );
  457. return E_FAIL;
  458. }
  459. return S_OK;
  460. }