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.

1442 lines
40 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*******************************************************************************
  3. *
  4. * atdlg.cpp
  5. *
  6. * implementation of WINCFG CAsyncTestDlg, CEchoEditControl, and CLed classes
  7. *
  8. * copyright notice: Copyright 1995, Citrix Systems Inc.
  9. *
  10. * $Author: butchd $ Butch Davis
  11. *
  12. * $Log: M:\nt\private\utils\citrix\winutils\wincfg\VCS\atdlg.cpp $
  13. *
  14. * Rev 1.18 12 Sep 1997 16:22:28 butchd
  15. * better async test auto-disable/enable
  16. *
  17. * Rev 1.17 19 Jun 1997 19:21:14 kurtp
  18. * update
  19. *
  20. * Rev 1.16 30 Sep 1996 12:11:22 butchd
  21. * update
  22. *
  23. * Rev 1.15 20 Sep 1996 20:36:56 butchd
  24. * update
  25. *
  26. * Rev 1.14 19 Sep 1996 15:57:56 butchd
  27. * update
  28. *
  29. * Rev 1.13 12 Sep 1996 16:15:56 butchd
  30. * update
  31. *
  32. *******************************************************************************/
  33. /*
  34. * include files
  35. */
  36. #include "stdafx.h"
  37. #include "wincfg.h"
  38. #include "atdlg.h"
  39. #ifdef _DEBUG
  40. #undef THIS_FILE
  41. static char BASED_CODE THIS_FILE[] = __FILE__;
  42. #endif
  43. extern CWincfgApp *pApp;
  44. extern "C" LPCTSTR WinUtilsAppName;
  45. extern "C" HWND WinUtilsAppWindow;
  46. extern "C" HINSTANCE WinUtilsAppInstance;
  47. static int LedIds[NUM_LEDS] = {
  48. IDC_ATDLG_DTR,
  49. IDC_ATDLG_RTS,
  50. IDC_ATDLG_CTS,
  51. IDC_ATDLG_DSR,
  52. IDC_ATDLG_DCD,
  53. IDC_ATDLG_RI };
  54. ///////////////////////////////////////////////////////////////////////////////
  55. // CEchoEditControl class construction / destruction, implementation
  56. ////////////////////////////////////////////////////////////////////////////////
  57. // CEchoEditControl message map
  58. BEGIN_MESSAGE_MAP(CEchoEditControl, CEdit)
  59. //{{AFX_MSG_MAP(CEchoEditControl)
  60. ON_WM_CHAR()
  61. //}}AFX_MSG_MAP
  62. END_MESSAGE_MAP()
  63. ////////////////////////////////////////////////////////////////////////////////
  64. // CEchoEditControl commands
  65. void
  66. CEchoEditControl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  67. {
  68. /*
  69. * Tell dialog to write the character to the device unless we're
  70. * currently processing edit control output. This flag check is needed
  71. * because the CEdit::Cut() member function will generate an OnChar()
  72. * event, which we need to ignore ('\b' processing).
  73. */
  74. if ( !m_bProcessingOutput )
  75. ::SendMessage(m_hDlg, WM_ASYNCTESTWRITECHAR, nChar, 0);
  76. /*
  77. * Pass character on to the edit control. This will do nothing if
  78. * the edit control is 'read only'. To cause a 'local echo' effect,
  79. * set the edit control to 'read/write'.
  80. */
  81. CEdit::OnChar(nChar, nRepCnt, nFlags);
  82. } // end CEchoEditControl::OnChar
  83. ////////////////////////////////////////////////////////////////////////////////
  84. ///////////////////////////////////////////////////////////////////////////////
  85. // CAsyncTestDlg class construction / destruction, implementation
  86. /*******************************************************************************
  87. *
  88. * CAsyncTestDlg - CAsyncTestDlg constructor
  89. *
  90. * ENTRY:
  91. * EXIT:
  92. * (Refer to MFC CDialog::CDialog documentation)
  93. *
  94. ******************************************************************************/
  95. CAsyncTestDlg::CAsyncTestDlg()
  96. : CBaseDialog(CAsyncTestDlg::IDD),
  97. m_hDevice(INVALID_HANDLE_VALUE),
  98. m_hRedBrush(NULL),
  99. m_LEDToggleTimer(0),
  100. m_pATDlgInputThread(NULL),
  101. m_CurrentPos(0),
  102. m_hModem(NULL),
  103. m_bDeletedWinStation(FALSE)
  104. {
  105. //{{AFX_DATA_INIT(CAsyncTestDlg)
  106. //}}AFX_DATA_INIT
  107. int i;
  108. /*
  109. * Create a solid RED brush for painting the 'LED's when 'on'.
  110. */
  111. VERIFY( m_hRedBrush = CreateSolidBrush(RGB(255,0,0)) );
  112. /*
  113. * Initialize member variables.
  114. */
  115. memset(&m_Status, 0, sizeof(PROTOCOLSTATUS));
  116. memset(&m_OverlapWrite, 0, sizeof(OVERLAPPED));
  117. /*
  118. * Create the led objects.
  119. */
  120. for ( i = 0; i < NUM_LEDS; i++ )
  121. m_pLeds[i] = new CLed(m_hRedBrush);
  122. } // end CAsyncTestDlg::CAsyncTestDlg
  123. /*******************************************************************************
  124. *
  125. * ~CAsyncTestDlg - CAsyncTestDlg destructor
  126. *
  127. * ENTRY:
  128. * EXIT:
  129. * (Refer to MFC CDialog::~CDialog documentation)
  130. *
  131. ******************************************************************************/
  132. CAsyncTestDlg::~CAsyncTestDlg()
  133. {
  134. int i;
  135. /*
  136. * Zap our led objects.
  137. */
  138. for ( i = 0; i < NUM_LEDS; i++ )
  139. if ( m_pLeds[i] )
  140. delete m_pLeds[i];
  141. } // end CAsyncTestDlg::~CAsyncTestDlg
  142. ////////////////////////////////////////////////////////////////////////////////
  143. // CAsyncTestDlg operations
  144. /*******************************************************************************
  145. *
  146. * NotifyAbort - CAsyncTestDlg member function: private operation
  147. *
  148. * Post a WM_ASYNCTESTABORT message to notify the dialog of
  149. * abort and reason.
  150. *
  151. * ENTRY:
  152. * idError (input)
  153. * Resource id for error message.
  154. * EXIT:
  155. *
  156. ******************************************************************************/
  157. void
  158. CAsyncTestDlg::NotifyAbort( UINT idError )
  159. {
  160. PostMessage(WM_ASYNCTESTABORT, idError, GetLastError());
  161. } // end CAsyncTestDlg::NotifyAbort
  162. /*******************************************************************************
  163. *
  164. * DeviceSetParams - CAsyncTestDlg member function: private operation
  165. *
  166. * Set device parameters for opened device.
  167. *
  168. * ENTRY:
  169. * EXIT:
  170. * TRUE - no error; FALSE error.
  171. *
  172. ******************************************************************************/
  173. BOOL
  174. CAsyncTestDlg::DeviceSetParams()
  175. {
  176. PASYNCCONFIG pAsync;
  177. PFLOWCONTROLCONFIG pFlow;
  178. DCB Dcb;
  179. /*
  180. * Get pointer to async parameters
  181. */
  182. pAsync = &m_PdConfig0.Params.Async;
  183. /*
  184. * Get current DCB
  185. */
  186. if ( !GetCommState( m_hDevice, &Dcb ) )
  187. return(FALSE);
  188. /*
  189. * Set defaults
  190. */
  191. Dcb.fOutxCtsFlow = FALSE;
  192. Dcb.fOutxDsrFlow = FALSE;
  193. Dcb.fTXContinueOnXoff = TRUE;
  194. Dcb.fOutX = FALSE;
  195. Dcb.fInX = FALSE;
  196. Dcb.fErrorChar = FALSE;
  197. Dcb.fNull = FALSE;
  198. Dcb.fAbortOnError = FALSE;
  199. /*
  200. * Set Communication parameters
  201. */
  202. Dcb.BaudRate = pAsync->BaudRate;
  203. Dcb.Parity = (BYTE) pAsync->Parity;
  204. Dcb.StopBits = (BYTE) pAsync->StopBits;
  205. Dcb.ByteSize = (BYTE) pAsync->ByteSize;
  206. Dcb.fDsrSensitivity = pAsync->fEnableDsrSensitivity;
  207. pFlow = &pAsync->FlowControl;
  208. /*
  209. * Initialize default DTR state
  210. */
  211. if ( pFlow->fEnableDTR )
  212. Dcb.fDtrControl = DTR_CONTROL_ENABLE;
  213. else
  214. Dcb.fDtrControl = DTR_CONTROL_DISABLE;
  215. /*
  216. * Initialize default RTS state
  217. */
  218. if ( pFlow->fEnableRTS )
  219. Dcb.fRtsControl = RTS_CONTROL_ENABLE;
  220. else
  221. Dcb.fRtsControl = RTS_CONTROL_DISABLE;
  222. /*
  223. * Initialize flow control
  224. */
  225. switch ( pFlow->Type ) {
  226. /*
  227. * Initialize hardware flow control
  228. */
  229. case FlowControl_Hardware :
  230. switch ( pFlow->HardwareReceive ) {
  231. case ReceiveFlowControl_RTS :
  232. Dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  233. break;
  234. case ReceiveFlowControl_DTR :
  235. Dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
  236. break;
  237. }
  238. switch ( pFlow->HardwareTransmit ) {
  239. case TransmitFlowControl_CTS :
  240. Dcb.fOutxCtsFlow = TRUE;
  241. break;
  242. case TransmitFlowControl_DSR :
  243. Dcb.fOutxDsrFlow = TRUE;
  244. break;
  245. }
  246. break;
  247. /*
  248. * Initialize software flow control
  249. */
  250. case FlowControl_Software :
  251. Dcb.fOutX = pFlow->fEnableSoftwareTx;
  252. Dcb.fInX = pFlow->fEnableSoftwareRx;
  253. Dcb.XonChar = (char) pFlow->XonChar;
  254. Dcb.XoffChar = (char) pFlow->XoffChar;
  255. break;
  256. case FlowControl_None :
  257. break;
  258. default :
  259. ASSERT( FALSE );
  260. break;
  261. }
  262. /*
  263. * Set new DCB
  264. */
  265. if ( !SetCommState( m_hDevice, &Dcb ) )
  266. return(FALSE);
  267. return( TRUE );
  268. } // end CAsyncTestDlg::DeviceSetParams
  269. /*******************************************************************************
  270. *
  271. * DeviceWrite - CAsyncTestDlg member function: private operation
  272. *
  273. * Write out m_Buffer contents (m_BufferBytes length) to the m_hDevice.
  274. *
  275. * ENTRY:
  276. * EXIT:
  277. * TRUE - no error; FALSE error.
  278. *
  279. ******************************************************************************/
  280. BOOL
  281. CAsyncTestDlg::DeviceWrite()
  282. {
  283. DWORD Error, BytesWritten;
  284. /*
  285. * Write data
  286. */
  287. if ( !WriteFile( m_hDevice, m_Buffer, m_BufferBytes,
  288. &BytesWritten, &m_OverlapWrite ) ) {
  289. if ( (Error = GetLastError()) == ERROR_IO_PENDING ) {
  290. /*
  291. * Wait for write to complete (this may block till timeout)
  292. */
  293. if ( !GetOverlappedResult( m_hDevice, &m_OverlapWrite,
  294. &BytesWritten, TRUE ) ) {
  295. OnAsyncTestError(IDP_ERROR_GET_OVERLAPPED_RESULT_WRITE, Error);
  296. return(FALSE);
  297. }
  298. } else {
  299. OnAsyncTestError(IDP_ERROR_WRITE_FILE, Error);
  300. return(FALSE);
  301. }
  302. }
  303. return(TRUE);
  304. } // end CAsyncTestDlg::DeviceWrite
  305. /*******************************************************************************
  306. *
  307. * SetInfoFields - CAsyncTestDlg member function: private operation
  308. *
  309. * Update the fields in the dialog with new data, if necessary.
  310. *
  311. * ENTRY:
  312. * pCurrent (input)
  313. * points to COMMINFO structure containing the current Comm Input data.
  314. * pNew (input)
  315. * points to COMMINFO structure containing the new Comm Input data.
  316. *
  317. * EXIT:
  318. *
  319. ******************************************************************************/
  320. void
  321. CAsyncTestDlg::SetInfoFields( PPROTOCOLSTATUS pCurrent,
  322. PPROTOCOLSTATUS pNew )
  323. {
  324. BOOL bSetTimer = FALSE;
  325. /*
  326. * Set new LED states if state change, or set up for quick toggle if
  327. * no state changed, but change(s) were detected since last query.
  328. */
  329. if ( (pCurrent->AsyncSignal & MS_DTR_ON) !=
  330. (pNew->AsyncSignal & MS_DTR_ON) ) {
  331. pNew->AsyncSignalMask &= ~EV_DTR;
  332. ((CLed *)GetDlgItem(IDC_ATDLG_DTR))->
  333. Update(pNew->AsyncSignal & MS_DTR_ON);
  334. } else if ( pNew->AsyncSignalMask & EV_DTR ) {
  335. pCurrent->AsyncSignal ^= MS_DTR_ON;
  336. ((CLed *)GetDlgItem(IDC_ATDLG_DTR))->Toggle();
  337. bSetTimer = TRUE;
  338. }
  339. if ( (pCurrent->AsyncSignal & MS_RTS_ON) !=
  340. (pNew->AsyncSignal & MS_RTS_ON) ) {
  341. pNew->AsyncSignalMask &= ~EV_RTS;
  342. ((CLed *)GetDlgItem(IDC_ATDLG_RTS))->
  343. Update(pNew->AsyncSignal & MS_RTS_ON);
  344. } else if ( pNew->AsyncSignalMask & EV_RTS ) {
  345. pCurrent->AsyncSignal ^= MS_RTS_ON;
  346. ((CLed *)GetDlgItem(IDC_ATDLG_RTS))->Toggle();
  347. bSetTimer = TRUE;
  348. }
  349. if ( (pCurrent->AsyncSignal & MS_CTS_ON) !=
  350. (pNew->AsyncSignal & MS_CTS_ON) ) {
  351. pNew->AsyncSignalMask &= ~EV_CTS;
  352. ((CLed *)GetDlgItem(IDC_ATDLG_CTS))->
  353. Update(pNew->AsyncSignal & MS_CTS_ON);
  354. } else if ( pNew->AsyncSignalMask & EV_CTS ) {
  355. pCurrent->AsyncSignal ^= MS_CTS_ON;
  356. ((CLed *)GetDlgItem(IDC_ATDLG_CTS))->Toggle();
  357. bSetTimer = TRUE;
  358. }
  359. if ( (pCurrent->AsyncSignal & MS_RLSD_ON) !=
  360. (pNew->AsyncSignal & MS_RLSD_ON) ) {
  361. pNew->AsyncSignalMask &= ~EV_RLSD;
  362. ((CLed *)GetDlgItem(IDC_ATDLG_DCD))->
  363. Update(pNew->AsyncSignal & MS_RLSD_ON);
  364. } else if ( pNew->AsyncSignalMask & EV_RLSD ) {
  365. pCurrent->AsyncSignal ^= MS_RLSD_ON;
  366. ((CLed *)GetDlgItem(IDC_ATDLG_DCD))->Toggle();
  367. bSetTimer = TRUE;
  368. }
  369. if ( (pCurrent->AsyncSignal & MS_DSR_ON) !=
  370. (pNew->AsyncSignal & MS_DSR_ON) ) {
  371. pNew->AsyncSignalMask &= ~EV_DSR;
  372. ((CLed *)GetDlgItem(IDC_ATDLG_DSR))->
  373. Update(pNew->AsyncSignal & MS_DSR_ON);
  374. } else if ( pNew->AsyncSignalMask & EV_DSR ) {
  375. pCurrent->AsyncSignal ^= MS_DSR_ON;
  376. ((CLed *)GetDlgItem(IDC_ATDLG_DSR))->Toggle();
  377. bSetTimer = TRUE;
  378. }
  379. if ( (pCurrent->AsyncSignal & MS_RING_ON) !=
  380. (pNew->AsyncSignal & MS_RING_ON) ) {
  381. pNew->AsyncSignalMask &= ~EV_RING;
  382. ((CLed *)GetDlgItem(IDC_ATDLG_RI))->
  383. Update(pNew->AsyncSignal & MS_RING_ON);
  384. } else if ( pNew->AsyncSignalMask & EV_RING ) {
  385. pCurrent->AsyncSignal ^= MS_RING_ON;
  386. ((CLed *)GetDlgItem(IDC_ATDLG_RI))->Toggle();
  387. bSetTimer = TRUE;
  388. }
  389. /*
  390. * Create our led toggle timer if needed.
  391. */
  392. if ( bSetTimer && !m_LEDToggleTimer )
  393. m_LEDToggleTimer = SetTimer( IDD_ASYNC_TEST,
  394. ASYNC_LED_TOGGLE_MSEC, NULL );
  395. } // end CAsyncTestDlg::SetInfoFields
  396. ////////////////////////////////////////////////////////////////////////////////
  397. // CAsyncTestDlg message map
  398. BEGIN_MESSAGE_MAP(CAsyncTestDlg, CBaseDialog)
  399. //{{AFX_MSG_MAP(CAsyncTestDlg)
  400. ON_WM_TIMER()
  401. ON_MESSAGE(WM_ASYNCTESTERROR, OnAsyncTestError)
  402. ON_MESSAGE(WM_ASYNCTESTABORT, OnAsyncTestAbort)
  403. ON_MESSAGE(WM_ASYNCTESTSTATUSREADY, OnAsyncTestStatusReady)
  404. ON_MESSAGE(WM_ASYNCTESTINPUTREADY, OnAsyncTestInputReady)
  405. ON_MESSAGE(WM_ASYNCTESTWRITECHAR, OnAsyncTestWriteChar)
  406. ON_BN_CLICKED(IDC_ATDLG_MODEM_DIAL, OnClickedAtdlgModemDial)
  407. ON_BN_CLICKED(IDC_ATDLG_MODEM_INIT, OnClickedAtdlgModemInit)
  408. ON_BN_CLICKED(IDC_ATDLG_MODEM_LISTEN, OnClickedAtdlgModemListen)
  409. ON_WM_NCDESTROY()
  410. //}}AFX_MSG_MAP
  411. END_MESSAGE_MAP()
  412. ////////////////////////////////////////////////////////////////////////////////
  413. // CAsyncTestDlg commands
  414. /*******************************************************************************
  415. *
  416. * OnInitDialog - CAsyncTestDlg member function: command (override)
  417. *
  418. * Performs the dialog intialization.
  419. *
  420. * ENTRY:
  421. * EXIT:
  422. * (Refer to CDialog::OnInitDialog documentation)
  423. * WM_ASYNCTESTABORT message(s) will have been posted on error.
  424. *
  425. ******************************************************************************/
  426. BOOL CAsyncTestDlg::OnInitDialog()
  427. {
  428. int i;
  429. DEVICENAME DeviceName;
  430. COMMTIMEOUTS CommTimeouts;
  431. BOOL bModemInit = TRUE;
  432. BOOL bModemDial = TRUE;
  433. BOOL bModemListen = TRUE;
  434. #ifdef WINSTA
  435. ULONG LogonId;
  436. #endif // WINSTA
  437. /*
  438. * Call the parent classes' OnInitDialog to perform default dialog
  439. * initialization.
  440. */
  441. CBaseDialog::OnInitDialog();
  442. /*
  443. * Fill in the device and baud fields.
  444. */
  445. SetDlgItemText( IDL_ATDLG_DEVICE,
  446. m_PdConfig0.Params.Async.DeviceName );
  447. SetDlgItemInt( IDL_ATDLG_BAUD,
  448. m_PdConfig0.Params.Async.BaudRate,
  449. FALSE );
  450. /*
  451. * If a WinStation memory object is currently present, reset it.
  452. */
  453. #ifdef WINSTA
  454. if ( m_pWSName &&
  455. LogonIdFromWinStationName(SERVERNAME_CURRENT, m_pWSName, &LogonId) ) {
  456. LONG Status;
  457. ULONG Length;
  458. if ( QueryLoggedOnCount(m_pWSName) ) {
  459. if ( QuestionMessage( MB_YESNO | MB_ICONEXCLAMATION,
  460. IDP_CONFIRM_ASYNCTESTDISABLE,
  461. m_pWSName ) == IDNO ) {
  462. PostMessage( WM_COMMAND, MAKEWPARAM( IDOK, BN_CLICKED ),
  463. (LPARAM)(GetDlgItem(IDOK)->m_hWnd) );
  464. return(TRUE); // exit dialog via posted 'OK' click
  465. }
  466. }
  467. if ( (Status = RegWinStationQuery( SERVERNAME_CURRENT,
  468. m_pWSName,
  469. &m_WSConfig,
  470. sizeof(WINSTATIONCONFIG2),
  471. &Length )) ) {
  472. NotifyAbort(IDP_ERROR_DISABLE);
  473. return(TRUE);
  474. }
  475. m_WSConfig.Create.fEnableWinStation = FALSE;
  476. if ( (Status = RegWinStationCreate( SERVERNAME_CURRENT,
  477. m_pWSName,
  478. FALSE,
  479. &m_WSConfig,
  480. sizeof(WINSTATIONCONFIG2) )) ) {
  481. NotifyAbort(IDP_ERROR_DISABLE);
  482. return(TRUE);
  483. }
  484. /*
  485. * Do the reset. If, for some reason, the reset was unsucessful,
  486. * the device open will fail (below).
  487. */
  488. CWaitCursor wait;
  489. WinStationReset(SERVERNAME_CURRENT, LogonId, TRUE);
  490. m_bDeletedWinStation = TRUE;
  491. }
  492. #endif // WINSTA
  493. /*
  494. * Open the specified device.
  495. */
  496. lstrcpy( DeviceName, TEXT("\\\\.\\") );
  497. lstrcat( DeviceName, m_PdConfig0.Params.Async.DeviceName );
  498. if ( (m_hDevice = CreateFile( DeviceName,
  499. GENERIC_READ | GENERIC_WRITE,
  500. 0, // exclusive access
  501. NULL, // no security attr
  502. OPEN_EXISTING, // must exist
  503. FILE_FLAG_OVERLAPPED,
  504. NULL // no template
  505. )) == INVALID_HANDLE_VALUE ) {
  506. NotifyAbort(IDP_ERROR_CANT_OPEN_DEVICE);
  507. return(TRUE);
  508. }
  509. /*
  510. * Set device timeouts & communication parameters and create an event
  511. * for overlapped writes.
  512. */
  513. memset(&CommTimeouts, 0, sizeof(COMMTIMEOUTS));
  514. CommTimeouts.ReadIntervalTimeout = 1; // 1 msec
  515. CommTimeouts.WriteTotalTimeoutConstant = 1000; // 1 second
  516. if ( !SetCommTimeouts(m_hDevice, &CommTimeouts) ||
  517. !DeviceSetParams() ||
  518. !(m_OverlapWrite.hEvent = CreateEvent( NULL, TRUE,
  519. FALSE, NULL )) ) {
  520. NotifyAbort(IDP_ERROR_CANT_INITIALIZE_DEVICE);
  521. return(TRUE);
  522. }
  523. /*
  524. * Create the input thread object and initialize it's member variables.
  525. */
  526. m_pATDlgInputThread = new CATDlgInputThread;
  527. m_pATDlgInputThread->m_hDlg = m_hWnd;
  528. m_pATDlgInputThread->m_hDevice = m_hDevice;
  529. m_pATDlgInputThread->m_PdConfig = m_PdConfig0;
  530. if ( !m_pATDlgInputThread->CreateThread() ) {
  531. NotifyAbort(IDP_ERROR_CANT_CREATE_INPUT_THREAD);
  532. return(TRUE);
  533. }
  534. #ifdef WF1x
  535. /*
  536. * If a modem is configured, get command strings for current configuration.
  537. */
  538. if ( m_PdConfig1.Create.SdClass == PdModem ) {
  539. ULONG dRC, fCapability, cbCommand;
  540. if ( (dRC = ModemOpen( &m_hModem,
  541. (BYTE *)m_PdConfig1.Params.Modem.ModemName,
  542. &fCapability )) != ERROR_SUCCESS ) {
  543. OnAsyncTestError(IDP_ERROR_MODEMOPEN_CONFIG, dRC);
  544. bModemInit = bModemDial = bModemListen = FALSE;
  545. m_hModem = NULL;
  546. }
  547. if ( m_hModem ) {
  548. /*
  549. * Set configured capability.
  550. */
  551. fCapability = 0 ;
  552. fCapability |= m_PdConfig1.Params.Modem.fHwFlowControl ?
  553. MODEM_CAPABILITY_HW_FLOWCONTROL_ON :
  554. MODEM_CAPABILITY_HW_FLOWCONTROL_OFF;
  555. fCapability |= m_PdConfig1.Params.Modem.fProtocol ?
  556. MODEM_CAPABILITY_ERROR_CORRECTION_ON :
  557. MODEM_CAPABILITY_ERROR_CORRECTION_OFF;
  558. fCapability |= m_PdConfig1.Params.Modem.fCompression ?
  559. MODEM_CAPABILITY_COMPRESSION_ON :
  560. MODEM_CAPABILITY_COMPRESSION_OFF;
  561. fCapability |= m_PdConfig1.Params.Modem.fSpeaker ?
  562. MODEM_CAPABILITY_SPEAKER_ON :
  563. MODEM_CAPABILITY_SPEAKER_OFF;
  564. fCapability |= m_PdConfig1.Params.Modem.fAutoBaud ?
  565. MODEM_CAPABILITY_AUTOBAUD_ON :
  566. MODEM_CAPABILITY_AUTOBAUD_OFF;
  567. if ( (dRC = ModemSetInfo(m_hModem, &fCapability)) != ERROR_SUCCESS ) {
  568. OnAsyncTestError(IDP_ERROR_MODEM_SET_INFO, dRC);
  569. bModemInit = bModemDial = bModemListen = FALSE;
  570. ModemClose(m_hModem);
  571. m_hModem = NULL;
  572. }
  573. }
  574. cbCommand = MAX_COMMAND_LEN;
  575. if ( (dRC == ERROR_SUCCESS) &&
  576. ((dRC = ModemGetCommand( m_hModem, CT_LISTEN, FALSE,
  577. (BYTE *)m_szModemListen,
  578. &cbCommand)) != ERROR_SUCCESS) ) {
  579. OnAsyncTestError(IDP_ERROR_MODEM_GET_LISTEN, dRC);
  580. bModemListen = FALSE;
  581. cbCommand = 0;
  582. }
  583. m_szModemListen[cbCommand] = TCHAR('\0');
  584. }
  585. #endif // WF1x
  586. /*
  587. * Hide the modem string buttons if a modem is not configured, or disable
  588. * buttons that are not valid.
  589. */
  590. #ifdef WF1x
  591. if ( m_PdConfig1.Create.SdClass != PdModem ) {
  592. #endif // WF1x
  593. int id;
  594. for ( id=IDC_ATDLG_MODEM_INIT; id <= IDC_ATDLG_PHONE_NUMBER; id++ ) {
  595. GetDlgItem(id)->EnableWindow(FALSE);
  596. GetDlgItem(id)->ShowWindow(SW_HIDE);
  597. }
  598. #ifdef WF1x
  599. } else {
  600. if ( !bModemInit )
  601. GetDlgItem(IDC_ATDLG_MODEM_INIT)->EnableWindow(FALSE);
  602. if ( !bModemListen )
  603. GetDlgItem(IDC_ATDLG_MODEM_LISTEN)->EnableWindow(FALSE);
  604. }
  605. #endif // WF1x
  606. /*
  607. * Subclass the edit field to pass messages to dialog first.
  608. */
  609. m_EditControl.m_hDlg = m_hWnd;
  610. m_EditControl.m_bProcessingOutput = FALSE;
  611. m_EditControl.SubclassDlgItem(IDC_ATDLG_EDIT, this);
  612. /*
  613. * Determine the edit control's font and format offset metrics.
  614. */
  615. {
  616. TEXTMETRIC tm;
  617. RECT Rect;
  618. CDC *pDC;
  619. CFont *pFont, *pOldFont;
  620. pDC = m_EditControl.GetDC();
  621. pFont = m_EditControl.GetFont();
  622. pOldFont = pDC->SelectObject(pFont);
  623. pDC->GetTextMetrics(&tm);
  624. pDC->SelectObject(pOldFont);
  625. m_EditControl.ReleaseDC(pDC);
  626. m_EditControl.m_FontHeight = tm.tmHeight;
  627. m_EditControl.m_FontWidth = tm.tmMaxCharWidth;
  628. m_EditControl.GetRect(&Rect);
  629. m_EditControl.m_FormatOffsetY = Rect.top;
  630. m_EditControl.m_FormatOffsetX = Rect.left;
  631. }
  632. /*
  633. * Subclass the led controls and default to 'off'.
  634. */
  635. for ( i = 0; i < NUM_LEDS; i++ ) {
  636. m_pLeds[i]->Subclass( (CStatic *)GetDlgItem(LedIds[i]) );
  637. m_pLeds[i]->Update(0);
  638. }
  639. return ( TRUE );
  640. } // end CAsyncTestDlg::OnInitDialog
  641. /*******************************************************************************
  642. *
  643. * OnTimer - CAsyncTestDlg member function: command (override)
  644. *
  645. * Used for quick 'LED toggle'.
  646. *
  647. * ENTRY:
  648. * EXIT:
  649. * (Refer to CWnd::OnTimer documentation)
  650. *
  651. ******************************************************************************/
  652. void
  653. CAsyncTestDlg::OnTimer(UINT nIDEvent)
  654. {
  655. /*
  656. * Process this timer event if it it our 'LED toggle' event.
  657. */
  658. if ( nIDEvent == m_LEDToggleTimer ) {
  659. /*
  660. * Toggle each LED that is flagged as 'changed'.
  661. */
  662. if ( m_Status.AsyncSignalMask & EV_DTR )
  663. ((CLed *)GetDlgItem(IDC_ATDLG_DTR))->Toggle();
  664. if ( m_Status.AsyncSignalMask & EV_RTS )
  665. ((CLed *)GetDlgItem(IDC_ATDLG_RTS))->Toggle();
  666. if ( m_Status.AsyncSignalMask & EV_CTS )
  667. ((CLed *)GetDlgItem(IDC_ATDLG_CTS))->Toggle();
  668. if ( m_Status.AsyncSignalMask & EV_RLSD )
  669. ((CLed *)GetDlgItem(IDC_ATDLG_DCD))->Toggle();
  670. if ( m_Status.AsyncSignalMask & EV_DSR )
  671. ((CLed *)GetDlgItem(IDC_ATDLG_DSR))->Toggle();
  672. if ( m_Status.AsyncSignalMask & EV_RING )
  673. ((CLed *)GetDlgItem(IDC_ATDLG_RI))->Toggle();
  674. /*
  675. * Kill this timer event and indicate so.
  676. */
  677. KillTimer(m_LEDToggleTimer);
  678. m_LEDToggleTimer = 0;
  679. } else
  680. CBaseDialog::OnTimer(nIDEvent);
  681. } // end CAsyncTestDlg::OnTimer
  682. /*******************************************************************************
  683. *
  684. * OnAsyncTestError - CAsyncTestDlg member function: command
  685. *
  686. * Handle the Async Test Dialog error conditions.
  687. *
  688. * ENTRY:
  689. * wParam (input)
  690. * Contains message ID for error.
  691. * wLparam (input)
  692. * Contains error code (GetLastError or API-specific return code)
  693. * EXIT:
  694. * (LRESULT) always returns 0 to indicate error handling complete.
  695. *
  696. ******************************************************************************/
  697. LRESULT
  698. CAsyncTestDlg::OnAsyncTestError( WPARAM wParam, LPARAM lParam )
  699. {
  700. /*
  701. * Handle special and default errors.
  702. */
  703. switch ( wParam ) {
  704. #ifdef WF1x
  705. case IDP_ERROR_MODEMOPEN_CONFIG:
  706. #endif // WF1x
  707. case IDP_ERROR_MODEM_SET_INFO:
  708. case IDP_ERROR_MODEM_GET_DIAL:
  709. case IDP_ERROR_MODEM_GET_INIT:
  710. case IDP_ERROR_MODEM_GET_LISTEN:
  711. #ifdef WF1x
  712. STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, lParam,
  713. wParam, m_PdConfig1.Params.Modem.ModemName ))
  714. #endif // WF1x
  715. break;
  716. case IDP_ERROR_DISABLE:
  717. STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, lParam,
  718. wParam, m_pWSName ))
  719. break;
  720. default:
  721. STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, lParam, wParam, lParam ))
  722. break;
  723. }
  724. return(0);
  725. } // end CAsyncTestDlg::OnAsyncTestError
  726. /*******************************************************************************
  727. *
  728. * OnAsyncTestAbort - CAsyncTestDlg member function: command
  729. *
  730. * Handle the Async Test Dialog abort conditions.
  731. *
  732. * ENTRY:
  733. * wParam (input)
  734. * Contains message ID for error.
  735. * wLparam (input)
  736. * Contains error code (GetLastError)
  737. * EXIT:
  738. * (LRESULT) always returns 0 to indicate error handling complete. Will
  739. * have posted an 'Ok' (Exit) button click to cause exit.
  740. *
  741. ******************************************************************************/
  742. LRESULT
  743. CAsyncTestDlg::OnAsyncTestAbort( WPARAM wParam, LPARAM lParam )
  744. {
  745. /*
  746. * Call OnAsyncTestError() to output message.
  747. */
  748. OnAsyncTestError(wParam, lParam);
  749. /*
  750. * Post a click for 'OK' (Exit) button to exit dialog.
  751. */
  752. PostMessage( WM_COMMAND, MAKEWPARAM( IDOK, BN_CLICKED ),
  753. (LPARAM)(GetDlgItem(IDOK)->m_hWnd) );
  754. return(0);
  755. } // end CAsyncTestDlg::OnAsyncTestAbort
  756. /*******************************************************************************
  757. *
  758. * OnAsyncTestStatusReady - CAsyncTestDlg member function: command
  759. *
  760. * Update dialog with comm status information.
  761. *
  762. * ENTRY:
  763. * wParam (input)
  764. * not used (0)
  765. * wLparam (input)
  766. * not used (0)
  767. * EXIT:
  768. * (LRESULT) always returns 0.
  769. *
  770. ******************************************************************************/
  771. LRESULT
  772. CAsyncTestDlg::OnAsyncTestStatusReady( WPARAM wParam, LPARAM lParam )
  773. {
  774. /*
  775. * Update dialog fields with information from the input thread's
  776. * PROTOCOLSTATUS structure.
  777. */
  778. SetInfoFields( &m_Status, &(m_pATDlgInputThread->m_Status) );
  779. /*
  780. * Set our working PROTOCOLSTATUS structure to the new one and signal
  781. * the thread that we're done.
  782. */
  783. m_Status = m_pATDlgInputThread->m_Status;
  784. m_pATDlgInputThread->SignalConsumed();
  785. return(0);
  786. } // end CAsyncTestDlg::OnAsyncTestStatusReady
  787. /*******************************************************************************
  788. *
  789. * OnAsyncTestInputReady - CAsyncTestDlg member function: command
  790. *
  791. * Update dialog with comm input data.
  792. *
  793. * ENTRY:
  794. * wParam (input)
  795. * not used (0)
  796. * wLparam (input)
  797. * not used (0)
  798. * EXIT:
  799. * (LRESULT) always returns 0.
  800. *
  801. ******************************************************************************/
  802. LRESULT
  803. CAsyncTestDlg::OnAsyncTestInputReady( WPARAM wParam, LPARAM lParam )
  804. {
  805. BYTE OutBuf[MAX_COMMAND_LEN+2];
  806. int i, j;
  807. /*
  808. * Copy the thread's buffer and count locally.
  809. */
  810. m_BufferBytes = m_pATDlgInputThread->m_BufferBytes;
  811. memcpy(m_Buffer, m_pATDlgInputThread->m_Buffer, m_BufferBytes);
  812. /*
  813. * Always return caret to the current position before processing, and set
  814. * edit control to 'read/write' so that character overwrites can occur
  815. * properly. Finally, flag control for no redraw until all updates are completed,
  816. * and flag 'processing output' to avoid OnChar() recursion during '\b' processing.
  817. */
  818. m_EditControl.SetSel(m_CurrentPos, m_CurrentPos);
  819. m_EditControl.SetReadOnly(FALSE);
  820. m_EditControl.SetRedraw(FALSE);
  821. /*
  822. * Loop to traverse the buffer, with special processing for certain
  823. * control characters.
  824. */
  825. for ( i = 0, j = 0; m_BufferBytes; i++, m_BufferBytes-- ) {
  826. switch ( m_Buffer[i] ) {
  827. case '\b':
  828. /*
  829. * If there is data in the output buffer, write it now.
  830. */
  831. if ( j )
  832. OutputToEditControl(OutBuf, &j);
  833. /*
  834. * Output the '\b' (will actually cut current character from buffer)
  835. */
  836. OutBuf[j++] = '\b';
  837. OutputToEditControl(OutBuf, &j);
  838. continue;
  839. case '\r':
  840. /*
  841. * If there is data in the output buffer, write it now.
  842. */
  843. if ( j )
  844. OutputToEditControl(OutBuf, &j);
  845. /*
  846. * Output the '\r' (will not actually output, but will special case
  847. * for caret positioning and screen update).
  848. */
  849. OutBuf[j++] = '\r';
  850. OutputToEditControl(OutBuf, &j);
  851. continue;
  852. case '\n':
  853. /*
  854. * If there is data in the output buffer, write it now.
  855. */
  856. if ( j )
  857. OutputToEditControl(OutBuf, &j);
  858. /*
  859. * Output the '\n' (will actually quietly output the '\r' and take
  860. * care of scolling).
  861. */
  862. OutBuf[j++] = '\n';
  863. OutputToEditControl(OutBuf, &j);
  864. continue;
  865. default:
  866. break;
  867. }
  868. /*
  869. * Add this character to the output buffer.
  870. */
  871. OutBuf[j++] = m_Buffer[i];
  872. }
  873. /*
  874. * If there is anything remaining in the output buffer, output it now.
  875. */
  876. if ( j )
  877. OutputToEditControl(OutBuf, &j);
  878. /*
  879. * Place edit control back in 'read only' mode, flag 'not processing output',
  880. * set redraw flag for control, and validate the entire control (updates have
  881. * already taken place).
  882. */
  883. m_EditControl.SetReadOnly(TRUE);
  884. m_EditControl.SetRedraw(TRUE);
  885. m_EditControl.ValidateRect(NULL);
  886. /*
  887. * Signal thread that we're done with input so that it can continue.
  888. * NOTE: we don't do this at the beginning of the routine even though
  889. * we could (for more parallelism), since a constantly chatty async
  890. * line would cause WM_ASYNCTESTINPUTREADY messages to always be posted
  891. * to our message queue, effectively blocking any other message processing
  892. * (like telling the dialog to exit!).
  893. */
  894. m_pATDlgInputThread->SignalConsumed();
  895. return(0);
  896. } // end CAsyncTestDlg::OnAsyncTestInputReady
  897. void
  898. CAsyncTestDlg::OutputToEditControl( BYTE *pBuffer, int *pIndex )
  899. {
  900. RECT Rect, ClientRect;
  901. BOOL bScroll = FALSE;
  902. int CurrentLine = m_EditControl.LineFromChar(m_CurrentPos);
  903. int FirstVisibleLine = m_EditControl.GetFirstVisibleLine();
  904. int CurrentLineIndex = m_EditControl.LineIndex(CurrentLine);
  905. /*
  906. * Calculate clip rectangle.
  907. */
  908. Rect.top = ((CurrentLine - FirstVisibleLine) * m_EditControl.m_FontHeight)
  909. + m_EditControl.m_FormatOffsetY;
  910. Rect.bottom = Rect.top + m_EditControl.m_FontHeight;
  911. Rect.left = m_EditControl.m_FormatOffsetX +
  912. ((m_CurrentPos - CurrentLineIndex) * m_EditControl.m_FontWidth);
  913. Rect.right = Rect.left + (*pIndex * m_EditControl.m_FontWidth);
  914. /*
  915. * Handle special cases.
  916. */
  917. if ( pBuffer[0] == '\b' ) {
  918. /*
  919. * If we're already at the beginning of the line, clear buffer index
  920. * and return (don't do anything).
  921. */
  922. if ( m_CurrentPos == CurrentLineIndex ) {
  923. *pIndex = 0;
  924. return;
  925. }
  926. /*
  927. * Position the caret back one character and select through current character.
  928. */
  929. m_EditControl.SetSel(m_CurrentPos - 1, m_CurrentPos);
  930. /*
  931. * Cut the character out of the edit buffer.
  932. */
  933. m_EditControl.m_bProcessingOutput = TRUE;
  934. m_EditControl.Cut();
  935. m_EditControl.m_bProcessingOutput = FALSE;
  936. /*
  937. * Decrement current position and zero index to suppress further output. Also,
  938. * widen the clipping rectangle back one character.
  939. */
  940. Rect.left -= m_EditControl.m_FontWidth;
  941. m_CurrentPos--;
  942. *pIndex = 0;
  943. } else if ( pBuffer[0] == '\r' ) {
  944. /*
  945. * Position the caret at the beginning of the current line.
  946. */
  947. m_CurrentPos = CurrentLineIndex;
  948. m_EditControl.SetSel(m_CurrentPos, m_CurrentPos);
  949. /*
  950. * Zero index to keep from actually outputing to edit buffer.
  951. */
  952. *pIndex = 0;
  953. } else if ( pBuffer[0] == '\n' ) {
  954. /*
  955. * Position selection point at end of the current edit buffer.
  956. */
  957. m_EditControl.SetSel(m_CurrentPos = m_EditControl.GetWindowTextLength(), -1 );
  958. /*
  959. * Cause '\r' '\n' pair to be output to edit buffer.
  960. */
  961. pBuffer[0] = '\r';
  962. pBuffer[1] = '\n';
  963. *pIndex = 2;
  964. /*
  965. * See if scrolling needed.
  966. */
  967. m_EditControl.GetClientRect(&ClientRect);
  968. if ( (Rect.bottom + m_EditControl.m_FontHeight) > ClientRect.bottom )
  969. bScroll = TRUE;
  970. } else {
  971. /*
  972. * Set selection from current position through *pIndex characters. This
  973. * will perform desired 'overwrite' function if current position is not at
  974. * the end of the edit buffer.
  975. */
  976. m_EditControl.SetSel(m_CurrentPos, m_CurrentPos + *pIndex);
  977. }
  978. /*
  979. * If necessary, update the dialog's edit box with the buffer data.
  980. */
  981. if ( *pIndex ) {
  982. #ifdef UNICODE
  983. TCHAR OutBuffer[MAX_COMMAND_LEN+1];
  984. mbstowcs(OutBuffer, (PCHAR)pBuffer, *pIndex);
  985. OutBuffer[*pIndex] = TEXT('\0');
  986. m_EditControl.ReplaceSel(OutBuffer);
  987. #else
  988. pBuffer[*pIndex] = BYTE('\0');
  989. m_EditControl.ReplaceSel((LPCSTR)pBuffer);
  990. #endif // UNICODE
  991. }
  992. /*
  993. * Update the current line.
  994. */
  995. m_EditControl.SetRedraw(TRUE);
  996. m_EditControl.ValidateRect(NULL);
  997. m_EditControl.InvalidateRect(&Rect, FALSE);
  998. m_EditControl.UpdateWindow();
  999. /*
  1000. * If scrolling is required to see the new line, do so.
  1001. */
  1002. if ( bScroll )
  1003. m_EditControl.LineScroll(1);
  1004. m_EditControl.SetRedraw(FALSE);
  1005. /*
  1006. * Update current position and clear buffer index.
  1007. */
  1008. m_CurrentPos += *pIndex;
  1009. *pIndex = 0;
  1010. } // end CAsyncTestDlg::OutputToEditControl
  1011. /*******************************************************************************
  1012. *
  1013. * OnAsyncTestWriteChar - CAsyncTestDlg member function: command
  1014. *
  1015. * Place the specified character in m_Buffer, set m_BufferBytes to 1,
  1016. * and call DeviceWrite() to output the character to the device.
  1017. *
  1018. * ENTRY:
  1019. * wParam (input)
  1020. * Character to write.
  1021. * lParam (input)
  1022. * not used (0)
  1023. * EXIT:
  1024. * (LRESULT) always returns 0.
  1025. *
  1026. ******************************************************************************/
  1027. LRESULT
  1028. CAsyncTestDlg::OnAsyncTestWriteChar( WPARAM wParam, LPARAM lParam )
  1029. {
  1030. /*
  1031. * Write the byte to the device.
  1032. */
  1033. m_Buffer[0] = (BYTE)wParam;
  1034. m_BufferBytes = 1;
  1035. DeviceWrite();
  1036. return(0);
  1037. } // end CAsyncTestDlg::OnAsyncTestWriteChar
  1038. /*******************************************************************************
  1039. *
  1040. * OnClickedAtdlgModemDial - CAsyncTestDlg member function: command
  1041. *
  1042. * Send the modem dial string.
  1043. *
  1044. * ENTRY:
  1045. * EXIT:
  1046. *
  1047. ******************************************************************************/
  1048. void
  1049. CAsyncTestDlg::OnClickedAtdlgModemDial()
  1050. {
  1051. #ifdef WF1x
  1052. TCHAR PhoneNumber[CALLBACK_LENGTH + 1];
  1053. ULONG dRC, cbCommand;
  1054. GetDlgItemText(IDC_ATDLG_PHONE_NUMBER, PhoneNumber, lengthof(PhoneNumber));
  1055. if ( (dRC = ModemSetCallback(m_hModem, (BYTE *)PhoneNumber)) != ERROR_SUCCESS ) {
  1056. OnAsyncTestError(IDP_ERROR_MODEM_SET_INFO, dRC);
  1057. return;
  1058. }
  1059. cbCommand = MAX_COMMAND_LEN;
  1060. if ( ((dRC = ModemGetCommand( m_hModem, CT_DIAL, TRUE,
  1061. (BYTE *)m_szModemDial,
  1062. &cbCommand)) != ERROR_SUCCESS) ) {
  1063. OnAsyncTestError(IDP_ERROR_MODEM_GET_DIAL, dRC);
  1064. return;
  1065. }
  1066. m_szModemDial[cbCommand] = TCHAR('\0');
  1067. lstrcpy((TCHAR *)m_Buffer, m_szModemDial);
  1068. m_BufferBytes = lstrlen((TCHAR *)m_Buffer);
  1069. DeviceWrite();
  1070. #endif // WF1x
  1071. } // end CAsyncTestDlg::OnClickedAtdlgModemDial
  1072. /*******************************************************************************
  1073. *
  1074. * OnClickedAtdlgModemInit - CAsyncTestDlg member function: command
  1075. *
  1076. * Send the modem init string.
  1077. *
  1078. * ENTRY:
  1079. * EXIT:
  1080. *
  1081. ******************************************************************************/
  1082. void
  1083. CAsyncTestDlg::OnClickedAtdlgModemInit()
  1084. {
  1085. #ifdef WF1x
  1086. ULONG cbCommand;
  1087. ULONG fFirst = TRUE;
  1088. CWaitCursor Wait;
  1089. for ( ;; ) {
  1090. cbCommand = MAX_COMMAND_LEN;
  1091. if ( !m_hModem || (ModemGetCommand( m_hModem, CT_INIT, fFirst,
  1092. (BYTE *)m_szModemInit,
  1093. &cbCommand) != ERROR_SUCCESS) ) {
  1094. return;
  1095. }
  1096. fFirst = FALSE;
  1097. m_szModemInit[cbCommand] = TCHAR('\0');
  1098. lstrcpy((TCHAR *)m_Buffer, m_szModemInit);
  1099. m_BufferBytes = lstrlen((TCHAR *)m_Buffer);
  1100. DeviceWrite();
  1101. Sleep( 2000 );
  1102. }
  1103. #endif // WF1x
  1104. } // end CAsyncTestDlg::OnClickedAtdlgModemInit
  1105. /*******************************************************************************
  1106. *
  1107. * OnClickedAtdlgModemListen - CAsyncTestDlg member function: command
  1108. *
  1109. * Send the modem listen string.
  1110. *
  1111. * ENTRY:
  1112. * EXIT:
  1113. *
  1114. ******************************************************************************/
  1115. void
  1116. CAsyncTestDlg::OnClickedAtdlgModemListen()
  1117. {
  1118. lstrcpy((TCHAR *)m_Buffer, m_szModemListen);
  1119. m_BufferBytes = lstrlen((TCHAR *)m_Buffer);
  1120. DeviceWrite();
  1121. } // end CAsyncTestDlg::OnClickedAtdlgModemListen
  1122. /*******************************************************************************
  1123. *
  1124. * OnNcDestroy - CAsyncTestDlg member function: command
  1125. *
  1126. * Clean up before deleting dialog object.
  1127. *
  1128. * ENTRY:
  1129. * EXIT:
  1130. * (Refer to CWnd::OnNcDestroy documentation)
  1131. *
  1132. ******************************************************************************/
  1133. void
  1134. CAsyncTestDlg::OnNcDestroy()
  1135. {
  1136. if ( m_LEDToggleTimer )
  1137. KillTimer(m_LEDToggleTimer);
  1138. #ifdef WF1x
  1139. if ( m_hModem )
  1140. ModemClose(m_hModem);
  1141. #endif // WF1x
  1142. if ( m_pATDlgInputThread )
  1143. m_pATDlgInputThread->ExitThread();
  1144. if ( m_hDevice != INVALID_HANDLE_VALUE )
  1145. PurgeComm(m_hDevice, PURGE_TXABORT | PURGE_TXCLEAR);
  1146. if ( m_OverlapWrite.hEvent )
  1147. CloseHandle(m_OverlapWrite.hEvent);
  1148. if ( m_hDevice != INVALID_HANDLE_VALUE )
  1149. CloseHandle(m_hDevice);
  1150. if ( m_bDeletedWinStation && m_pWSName ) {
  1151. LONG Status;
  1152. m_WSConfig.Create.fEnableWinStation = TRUE;
  1153. if ( !(Status = RegWinStationCreate( SERVERNAME_CURRENT,
  1154. m_pWSName,
  1155. FALSE,
  1156. &m_WSConfig,
  1157. sizeof(WINSTATIONCONFIG2) )) ) {
  1158. #ifdef WINSTA
  1159. _WinStationReadRegistry(SERVERNAME_CURRENT);
  1160. #endif // WINSTA
  1161. }
  1162. }
  1163. DeleteObject(m_hRedBrush);
  1164. /*
  1165. * Call parent after we've cleaned up.
  1166. */
  1167. CBaseDialog::OnNcDestroy();
  1168. } // end CAsyncTestDlg::OnNcDestroy
  1169. ////////////////////////////////////////////////////////////////////////////////