Leaked source code of windows server 2003
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.

4671 lines
128 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. #include "stdafx.h"
  3. #include <winsta.h>
  4. #include "resource.h"
  5. #include "asyncdlg.h"
  6. #include <utildll.h>
  7. //Most of the code for this has been borrowed from tscfg.
  8. extern void ErrMessage( HWND hwndOwner , INT_PTR iResourceID );
  9. static int LedIds[NUM_LEDS] =
  10. {
  11. IDC_ATDLG_DTR,
  12. IDC_ATDLG_RTS,
  13. IDC_ATDLG_CTS,
  14. IDC_ATDLG_DSR,
  15. IDC_ATDLG_DCD,
  16. IDC_ATDLG_RI
  17. };
  18. INT_PTR CBInsertInstancedName( LPCTSTR pName , HWND hCombo );
  19. void ParseRootAndInstance( LPCTSTR pString, LPTSTR pRoot, long *pInstance );
  20. //---------------------------------------------------------------------------------------------------
  21. CAsyncDlg::CAsyncDlg( )
  22. {
  23. m_hDlg = NULL;
  24. m_pCfgcomp = NULL;
  25. m_nHexBase = 0;
  26. m_szWinstation[ 0 ] = 0;
  27. m_szWDName[ 0 ] = 0;
  28. ZeroMemory( &m_ac , sizeof( ASYNCCONFIG ) );
  29. ZeroMemory( &m_uc , sizeof( USERCONFIG ) );
  30. ZeroMemory( &m_oldAC , sizeof( ASYNCCONFIG ) );
  31. m_nOldAsyncDeviceNameSelection = ( INT )-1;
  32. m_nOldAsyncConnectType = ( INT )-1;
  33. m_nOldBaudRate = ( INT )-1;
  34. m_nOldModemCallBack = ( INT )-1;
  35. }
  36. //---------------------------------------------------------------------------------------------------
  37. BOOL CAsyncDlg::OnInitDialog( HWND hDlg , LPTSTR szWDName , LPTSTR szWinstationName , ICfgComp *pCfgcomp )
  38. {
  39. TCHAR tchName[ 80 ];
  40. TCHAR tchErrTitle[ 80 ];
  41. TCHAR tchErrMsg[ 256 ];
  42. TCHAR szDecoratedName[ DEVICENAME_LENGTH + MODEMNAME_LENGTH + 1 ];
  43. ASSERT( pCfgcomp != NULL );
  44. if( m_pCfgcomp == NULL )
  45. {
  46. m_pCfgcomp = pCfgcomp;
  47. m_pCfgcomp->AddRef( );
  48. }
  49. m_hDlg = hDlg;
  50. m_oldAC = m_ac;
  51. if( szWinstationName != NULL )
  52. {
  53. lstrcpyn( m_szWinstation , szWinstationName , SIZE_OF_BUFFER( m_szWinstation ) - sizeof( TCHAR ) );
  54. }
  55. if( szWDName != NULL )
  56. {
  57. lstrcpyn( m_szWDName , szWDName , SIZE_OF_BUFFER( m_szWDName ) - sizeof( TCHAR ) );
  58. }
  59. // initialize controls
  60. int idx = 0;
  61. HRESULT hr;
  62. SendMessage( GetDlgItem( hDlg , IDC_ASYNC_CONNECT ) , CB_RESETCONTENT , 0 , 0 );
  63. while( SUCCEEDED( ( hr = pCfgcomp->GetConnTypeName( idx , tchName ) ) ) )
  64. {
  65. if( hr == S_FALSE )
  66. {
  67. break;
  68. }
  69. SendMessage( GetDlgItem( hDlg , IDC_ASYNC_CONNECT ) , CB_ADDSTRING , 0 , ( LPARAM )tchName );
  70. idx++;
  71. }
  72. idx = 0;
  73. SendMessage( GetDlgItem( hDlg , IDC_ASYNC_MODEMCALLBACK ) , CB_RESETCONTENT , 0 , 0 );
  74. while( SUCCEEDED( ( hr = pCfgcomp->GetModemCallbackString( idx , tchName ) ) ) )
  75. {
  76. if( hr == S_FALSE )
  77. {
  78. break;
  79. }
  80. SendMessage( GetDlgItem( hDlg , IDC_ASYNC_MODEMCALLBACK ) , CB_ADDSTRING , 0 , ( LPARAM )tchName );
  81. idx++;
  82. }
  83. // fill in device list
  84. ULONG ulItems = 0;
  85. LPBYTE pBuffer = NULL;
  86. HWND hCombo = GetDlgItem( hDlg , IDC_ASYNC_DEVICENAME );
  87. SendMessage( hCombo , CB_RESETCONTENT , 0 , 0 );
  88. // szWDname is used for creating a new connection
  89. // szWinstaionName is used if we're editing an existing connection
  90. TCHAR *pszName = NULL;
  91. NameType type = WdName;
  92. if( szWDName == NULL )
  93. {
  94. pszName = szWinstationName;
  95. type = WsName;
  96. }
  97. else
  98. {
  99. pszName = szWDName;
  100. }
  101. ASSERT( pszName != NULL );
  102. hr = pCfgcomp->GetDeviceList( pszName , type , &ulItems , &pBuffer );
  103. if( SUCCEEDED( hr ) )
  104. {
  105. PPDPARAMS pPdParams = NULL;
  106. DBGMSG( L"TSCC : GetDeviceList returned %d devices that are available\n" , ulItems );
  107. for( idx = 0 , pPdParams = ( PPDPARAMS )pBuffer; idx < ( int )ulItems ; idx++, pPdParams++ )
  108. {
  109. // Form decorated name.
  110. #ifdef DBG
  111. TCHAR temsg[ 128 ];
  112. wsprintf( temsg , L"TSCC : %d ) %s is a device\n" , idx , pPdParams->Async.DeviceName );
  113. ODS( temsg );
  114. #endif
  115. FormDecoratedAsyncDeviceName( szDecoratedName, &( pPdParams->Async ) );
  116. if( pCfgcomp->IsAsyncDeviceAvailable( pPdParams->Async.DeviceName ) )
  117. {
  118. CBInsertInstancedName( szDecoratedName , hCombo );
  119. }
  120. #if 0 // this block was taken from tscfg and to this date it still does not make any sense
  121. /*
  122. Don't add this device to the list if it is already in use by a
  123. WinStation other than the current one.
  124. */
  125. if (FALSE == pCfgcomp->IsAsyncDeviceAvailable(pPdParams->Async.DeviceName))
  126. continue;
  127. // Insert the name into the combo-box if it's not a TAPI modem
  128. // or it is a TAPI modem that's not being used by RAS and it's
  129. // port is currently available.
  130. INT_PTR nRet = SendMessage( hCombo , CB_FINDSTRINGEXACT , ( WPARAM )-1 , ( LPARAM )pPdParams->Async.DeviceName );
  131. if( !*( pPdParams->Async.ModemName ) || ( /*!pPdParams->Async.Parity &&*/ ( nRet != ( INT_PTR )CB_ERR ) ) )
  132. {
  133. CBInsertInstancedName( szDecoratedName , hCombo );
  134. }
  135. #endif
  136. // If this device is a modem, make sure that the raw port this
  137. // device is configured on is not present in the list. This will
  138. // also take care of removing the raw port for TAPI modems that are
  139. // configured for use by RAS, in which case neither the configured.
  140. // TAPI modem(s) or raw port will be present in the list.
  141. INT_PTR nRet = SendMessage( hCombo , CB_FINDSTRINGEXACT , ( WPARAM )-1 , ( LPARAM )pPdParams->Async.DeviceName );
  142. if( *( pPdParams->Async.ModemName ) && ( nRet != CB_ERR ) )
  143. {
  144. ODS(L"Deleting item\n");
  145. SendMessage( hCombo , CB_DELETESTRING , ( WPARAM )nRet , 0 );
  146. }
  147. }
  148. LocalFree( pBuffer );
  149. }
  150. // Always make sure that the currently configured device is in
  151. if( m_ac.DeviceName[0] != 0 )
  152. {
  153. FormDecoratedAsyncDeviceName( szDecoratedName , &m_ac );
  154. INT_PTR nRet = SendMessage( hCombo , CB_FINDSTRINGEXACT , ( WPARAM )-1 , ( LPARAM )szDecoratedName );
  155. if( nRet == CB_ERR )
  156. {
  157. nRet = CBInsertInstancedName( szDecoratedName , hCombo );
  158. }
  159. SendMessage( hCombo , CB_SETCURSEL , ( WPARAM )nRet , 0 );
  160. m_nOldAsyncDeviceNameSelection = (int)nRet;
  161. }
  162. else
  163. {
  164. SendMessage( hCombo , CB_SETCURSEL , ( WPARAM )0, 0 );
  165. m_nOldAsyncDeviceNameSelection = 0;
  166. }
  167. INT_PTR iitem = SendMessage( hCombo , CB_GETCOUNT , ( WPARAM )0 , ( LPARAM )0);
  168. if(0 == iitem || CB_ERR == iitem)
  169. {
  170. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) );
  171. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_NODEVICES , tchErrMsg , SIZE_OF_BUFFER( tchErrMsg ) );
  172. MessageBox( hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );
  173. return FALSE;
  174. }
  175. // Set the BAUDRATE combo-box selection (in it's edit field) and limit the
  176. // edit field text.
  177. TCHAR string[ULONG_DIGIT_MAX];
  178. wsprintf( string, TEXT("%lu"), m_ac.BaudRate );
  179. m_nOldBaudRate = ( INT )m_ac.BaudRate;
  180. HWND hBaud = GetDlgItem( hDlg , IDC_ASYNC_BAUDRATE );
  181. SendMessage( hBaud , CB_RESETCONTENT , 0 , 0 );
  182. SetDlgItemText( hDlg , IDC_ASYNC_BAUDRATE , string );
  183. SendMessage(hBaud , CB_LIMITTEXT , ULONG_DIGIT_MAX - 1 , 0 );
  184. //The Baud rate field should contain only numbers
  185. HWND hEdit = GetWindow(hBaud,GW_CHILD);
  186. if(hEdit)
  187. {
  188. LONG Style = GetWindowLong(hEdit, GWL_STYLE);
  189. SetWindowLong(hEdit,GWL_STYLE, Style | ES_NUMBER);
  190. }
  191. TCHAR TempString[100]; // Number enough to hold the baud rate values
  192. //Add the default strings to the BaudRate Field
  193. lstrcpy(TempString, L"9600");
  194. SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
  195. lstrcpy(TempString, L"19200");
  196. SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
  197. lstrcpy(TempString, L"38400");
  198. SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
  199. lstrcpy(TempString, L"57600");
  200. SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
  201. lstrcpy(TempString, L"115200");
  202. SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
  203. lstrcpy(TempString, L"230400");
  204. SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
  205. // Set the CONNECT combo-box selection.
  206. SendMessage( GetDlgItem( hDlg , IDC_ASYNC_CONNECT ) , CB_SETCURSEL , m_ac.Connect.Type , 0 );
  207. m_nOldAsyncConnectType = ( INT )m_ac.Connect.Type;
  208. // CoTaskMemFree( pac );
  209. HWND hCbxModemCallback = GetDlgItem( hDlg , IDC_ASYNC_MODEMCALLBACK );
  210. // Set the MODEMCALLBACK combo-box selection, phone number, and 'inherit'
  211. // checkboxes, based on the current UserConfig settings.
  212. SendMessage( hCbxModemCallback , CB_SETCURSEL , ( WPARAM )m_uc.Callback , 0 );
  213. m_nOldModemCallBack = ( INT )m_uc.Callback;
  214. SetDlgItemText( hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER , m_uc.CallbackNumber );
  215. CheckDlgButton( hDlg , IDC_ASYNC_MODEMCALLBACK_INHERIT , m_uc.fInheritCallback );
  216. CheckDlgButton( hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT , m_uc.fInheritCallbackNumber );
  217. OnSelchangeAsyncDevicename( );
  218. return TRUE;
  219. }
  220. //---------------------------------------------------------------------------------------------------
  221. BOOL CAsyncDlg::OnSelchangeAsyncModemcallback()
  222. {
  223. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK);
  224. /*
  225. * Ignore this notification if the combo box is in a dropped-down
  226. * state.
  227. */
  228. if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) )
  229. {
  230. return FALSE;
  231. }
  232. /*
  233. * Fetch current callback selection.
  234. */
  235. INT index = (INT)SendMessage(hCbx,CB_GETCURSEL,0,0);
  236. if( index != m_nOldModemCallBack )
  237. {
  238. m_uc.Callback = (CALLBACKCLASS)index;
  239. m_nOldModemCallBack = index;
  240. if( index == 0 ) // disabled
  241. {
  242. EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , FALSE );
  243. //EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , FALSE );
  244. }
  245. else
  246. {
  247. // inusre that these controls are in the proper state
  248. OnClickedAsyncModemcallbackPhonenumberInherit();
  249. }
  250. return TRUE;
  251. }
  252. return FALSE;
  253. } // end OnSelchangeAsyncModemcallback
  254. //---------------------------------------------------------------------------------------------------
  255. void CAsyncDlg::OnSelchangeAsyncModemcallbackPhoneNumber()
  256. {
  257. GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER);
  258. /*
  259. * Fetch current callback Phone number.
  260. */
  261. GetDlgItemText(m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER, m_uc.CallbackNumber,SIZE_OF_BUFFER(m_uc.CallbackNumber));
  262. return;
  263. } // end OnSelchangeAsyncModemcallback
  264. //---------------------------------------------------------------------------------------------------
  265. BOOL CAsyncDlg::OnSelchangeAsyncConnect()
  266. {
  267. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_CONNECT );
  268. /*
  269. * Ignore this notification if the combo box is in a dropped-down
  270. * state.
  271. */
  272. if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) )
  273. {
  274. return FALSE;
  275. }
  276. INT index = ( INT )SendMessage(hCbx,CB_GETCURSEL,0,0);
  277. if( index != m_nOldAsyncConnectType )
  278. {
  279. m_ac.Connect.Type = (ASYNCCONNECTCLASS)index;
  280. m_nOldAsyncConnectType = index;
  281. return TRUE;
  282. }
  283. return FALSE;
  284. } // end CAsyncDlg::OnSelchangeAsyncConnect
  285. //---------------------------------------------------------------------------------------------------
  286. BOOL CAsyncDlg::OnSelchangeAsyncBaudrate()
  287. {
  288. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_BAUDRATE );
  289. ODS( L"TSCC : OnSelchangeAsyncBaudrate\n" );
  290. TCHAR string[ULONG_DIGIT_MAX], *endptr = NULL;
  291. /*
  292. * Ignore this notification if the combo box is in a dropped-down
  293. * state.
  294. */
  295. if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) )
  296. {
  297. return FALSE;
  298. }
  299. //GetDlgItemText(m_hDlg, IDC_ASYNC_BAUDRATE, string,ULONG_DIGIT_MAX);
  300. int idx = ( int )SendMessage( hCbx , CB_GETCURSEL , 0 , 0 );
  301. SendMessage( hCbx , CB_GETLBTEXT , ( WPARAM )idx , ( LPARAM )&string[ 0 ] );
  302. INT nBaudRate = ( INT )wcstoul(string, &endptr, 10);
  303. if( m_nOldBaudRate != nBaudRate )
  304. {
  305. m_ac.BaudRate = nBaudRate;
  306. m_nOldBaudRate = nBaudRate;
  307. return TRUE;
  308. }
  309. return FALSE;
  310. } // end CAsyncDlg::OnSelchangeAsyncBaudrate
  311. //---------------------------------------------------------------------------------------------------
  312. void CAsyncDlg::OnClickedModemProperties()
  313. {
  314. if ( !ConfigureModem( m_ac.ModemName, m_hDlg) )
  315. {
  316. ErrMessage(m_hDlg,IDP_ERROR_MODEM_PROPERTIES_NOT_AVAILABLE);
  317. }
  318. return;
  319. }
  320. //---------------------------------------------------------------------------------------------------
  321. BOOL CAsyncDlg::OnSelchangeAsyncDevicename( )
  322. {
  323. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_DEVICENAME );
  324. BOOL bModemEnableFlag, bDirectEnableFlag;
  325. INT_PTR index;
  326. int nModemCmdShow, nDirectCmdShow;
  327. // Ignore this notification if the combo box is in a dropped-down state.
  328. if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) )
  329. {
  330. return TRUE;
  331. }
  332. if( ( index = SendMessage( hCbx , CB_GETCURSEL , 0 , 0 ) ) != CB_ERR )
  333. {
  334. if( m_nOldAsyncDeviceNameSelection != index )
  335. {
  336. TCHAR szDeviceName[DEVICENAME_LENGTH+MODEMNAME_LENGTH+1];
  337. // Fetch current selection and parse into device and modem names.
  338. TCHAR tchErrMsg[ 512 ];
  339. TCHAR tchbuf[ 356 ];
  340. TCHAR tchErrTitle[ 80 ];
  341. LONG lCount = 0;
  342. if( m_pCfgcomp != NULL )
  343. {
  344. m_pCfgcomp->QueryLoggedOnCount( m_szWinstation , &lCount );
  345. if( lCount > 0 )
  346. {
  347. if( *m_ac.ModemName != 0 )
  348. {
  349. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_CHANGE_ASYNC , tchbuf , SIZE_OF_BUFFER( tchbuf ) ) );
  350. }
  351. else
  352. {
  353. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_CHANGE_MODEM , tchbuf , SIZE_OF_BUFFER( tchbuf ) ) );
  354. }
  355. wsprintf( tchErrMsg , tchbuf , m_szWinstation );
  356. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) ) );
  357. if( MessageBox( m_hDlg , tchErrMsg , tchErrTitle , MB_YESNO | MB_ICONEXCLAMATION ) == IDNO )
  358. {
  359. SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_nOldAsyncDeviceNameSelection , 0 );
  360. return FALSE;
  361. }
  362. }
  363. }
  364. SendMessage( hCbx , CB_GETLBTEXT , ( WPARAM )index , ( LPARAM )&szDeviceName[0] );
  365. ParseDecoratedAsyncDeviceName( szDeviceName , &m_ac );
  366. m_nOldAsyncDeviceNameSelection = (INT)index;
  367. }
  368. else
  369. {
  370. return FALSE;
  371. }
  372. }
  373. /*
  374. * The SetDefaults, Advanced, and Test buttons and Device Connect
  375. * and Baud fields are enabled if the configuration is non-modem.
  376. * Otherwise, the Configure Modem button and modem callback fields
  377. * are enabled. (The Install Modems buttons is always enabled).
  378. */
  379. if( ( *m_ac.ModemName != 0 ) )
  380. {
  381. bModemEnableFlag = TRUE;
  382. nModemCmdShow = SW_SHOW;
  383. bDirectEnableFlag = FALSE;
  384. nDirectCmdShow = SW_HIDE;
  385. } else {
  386. bModemEnableFlag = FALSE;
  387. nModemCmdShow = SW_HIDE;
  388. bDirectEnableFlag = TRUE;
  389. nDirectCmdShow = SW_SHOW;
  390. }
  391. ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK) , nModemCmdShow );
  392. EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK ) , bModemEnableFlag );
  393. ShowWindow( GetDlgItem( m_hDlg, IDC_MODEM_PROP_PROP) , nModemCmdShow );
  394. EnableWindow( GetDlgItem( m_hDlg, IDC_MODEM_PROP_PROP ) , bModemEnableFlag );
  395. ShowWindow( GetDlgItem( m_hDlg, IDC_MODEM_PROP_WIZ) , nModemCmdShow );
  396. EnableWindow( GetDlgItem( m_hDlg, IDC_MODEM_PROP_WIZ ) , bModemEnableFlag );
  397. ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK1 ) , nModemCmdShow );
  398. EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK1 ) , bModemEnableFlag );
  399. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK ) , nModemCmdShow );
  400. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK ) , bModemEnableFlag );
  401. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_INHERIT ) , nModemCmdShow );
  402. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_INHERIT ) , bModemEnableFlag );
  403. ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK_PHONENUMBER ) , nModemCmdShow );
  404. EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK_PHONENUMBER ) , bModemEnableFlag );
  405. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , nModemCmdShow );
  406. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , bModemEnableFlag );
  407. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , nModemCmdShow );
  408. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , bModemEnableFlag );
  409. ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_CONNECT ) , nDirectCmdShow );
  410. EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_CONNECT ) , bDirectEnableFlag );
  411. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_CONNECT ) , nDirectCmdShow );
  412. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_CONNECT ) , bDirectEnableFlag );
  413. ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_BAUDRATE ) , nDirectCmdShow );
  414. EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_BAUDRATE ) , bDirectEnableFlag );
  415. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_BAUDRATE ) , nDirectCmdShow );
  416. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_BAUDRATE ) , bDirectEnableFlag );
  417. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_DEFAULTS ) , nDirectCmdShow );
  418. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_DEFAULTS ) , bDirectEnableFlag );
  419. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_ADVANCED ) , nDirectCmdShow );
  420. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_ADVANCED ) , bDirectEnableFlag );
  421. ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_TEST ) , nDirectCmdShow );
  422. EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_TEST ) , bDirectEnableFlag );
  423. // If this is a modem device, properly set the callback fields.
  424. if( ( *m_ac.ModemName != 0 ) )
  425. {
  426. OnClickedAsyncModemcallbackInherit( );
  427. OnClickedAsyncModemcallbackPhonenumberInherit( );
  428. }
  429. return TRUE;
  430. }
  431. //---------------------------------------------------------------------------------------------------
  432. void CAsyncDlg::OnClickedAsyncModemcallbackInherit( )
  433. {
  434. BOOL bChecked = ( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_INHERIT ) , BM_GETCHECK , 0 , 0 );
  435. BOOL bEnable = !bChecked;
  436. m_uc.fInheritCallback = bChecked;
  437. EnableWindow( GetDlgItem( m_hDlg , IDL_ASYNC_MODEMCALLBACK1 ) , bEnable );
  438. EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK ) , bEnable );
  439. // now check to see if we need to enable the modem callback number
  440. if( bChecked )
  441. {
  442. if( SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK) , CB_GETCURSEL , 0 , 0 ) == 0 )
  443. {
  444. if( !( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , BM_GETCHECK , 0 , 0 ) )
  445. {
  446. EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , TRUE );
  447. // EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , TRUE );
  448. }
  449. }
  450. }
  451. else
  452. {
  453. if( (INT)SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK) , CB_GETCURSEL , 0 , 0 ) == 0 )
  454. {
  455. if( !( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , BM_GETCHECK , 0 , 0 ) )
  456. {
  457. EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , FALSE );
  458. // EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , FALSE );
  459. }
  460. }
  461. }
  462. return;
  463. }
  464. //---------------------------------------------------------------------------------------------------
  465. void CAsyncDlg::OnClickedAsyncModemcallbackPhonenumberInherit( )
  466. {
  467. BOOL bChecked = ( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , BM_GETCHECK , 0 , 0 );
  468. BOOL bEnable = !bChecked;
  469. m_uc.fInheritCallbackNumber = bChecked;
  470. if( !bChecked )
  471. {
  472. if( !( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_INHERIT ) , BM_GETCHECK , 0 , 0 ) )
  473. {
  474. if( SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK) , CB_GETCURSEL , 0 , 0 ) == 0 )
  475. {
  476. EnableWindow( GetDlgItem( m_hDlg , IDL_ASYNC_MODEMCALLBACK_PHONENUMBER ) , FALSE );
  477. EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , FALSE );
  478. return;
  479. }
  480. }
  481. }
  482. EnableWindow( GetDlgItem( m_hDlg , IDL_ASYNC_MODEMCALLBACK_PHONENUMBER ) , bEnable );
  483. EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , bEnable );
  484. return;
  485. }
  486. //---------------------------------------------------------------------------------------------------
  487. BOOL CAsyncDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl , PBOOL pfPersisted )
  488. {
  489. UNREFERENCED_PARAMETER( hwndCtrl );
  490. if( wNotifyCode == BN_CLICKED )
  491. {
  492. if( wID == IDC_ASYNC_DEFAULTS )
  493. {
  494. if( SetDefaults( ) == S_OK )
  495. {
  496. *pfPersisted = FALSE;
  497. }
  498. }
  499. else if( wID == IDC_ASYNC_ADVANCED )
  500. {
  501. if( DoAsyncAdvance( ) == S_OK )
  502. {
  503. *pfPersisted = FALSE;
  504. }
  505. }
  506. else if( wID == IDC_ASYNC_TEST )
  507. {
  508. DoAsyncTest( );
  509. }
  510. else if( wID == IDC_ASYNC_MODEMCALLBACK_INHERIT )
  511. {
  512. OnClickedAsyncModemcallbackInherit();
  513. *pfPersisted = FALSE;
  514. }
  515. else if( wID == IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT )
  516. {
  517. OnClickedAsyncModemcallbackPhonenumberInherit();
  518. *pfPersisted = FALSE;
  519. }
  520. else if(wID == IDC_MODEM_PROP_PROP || wID == IDC_MODEM_PROP_WIZ)
  521. {
  522. OnClickedModemProperties();
  523. }
  524. }
  525. else if( wNotifyCode == CBN_SELCHANGE )
  526. {
  527. if(wID == IDC_ASYNC_DEVICENAME)
  528. {
  529. if( OnSelchangeAsyncDevicename( ) )
  530. {
  531. *pfPersisted = FALSE;
  532. }
  533. }
  534. else if(wID == IDC_ASYNC_CONNECT)
  535. {
  536. if( OnSelchangeAsyncConnect() )
  537. {
  538. *pfPersisted = FALSE;
  539. }
  540. }
  541. else if(wID == IDC_ASYNC_BAUDRATE)
  542. {
  543. if( OnSelchangeAsyncBaudrate() )
  544. {
  545. *pfPersisted = FALSE;
  546. }
  547. }
  548. else if(wID == IDC_ASYNC_MODEMCALLBACK)
  549. {
  550. if( OnSelchangeAsyncModemcallback() )
  551. {
  552. *pfPersisted = FALSE;
  553. }
  554. }
  555. }
  556. /*else if( wNotifyCode == CBN_KILLFOCUS)
  557. {
  558. if(wID == IDC_ASYNC_BAUDRATE)
  559. {
  560. OnSelchangeAsyncBaudrate();
  561. }
  562. }*/
  563. else if(wNotifyCode == EN_CHANGE )
  564. {
  565. if(wID == IDC_ASYNC_MODEMCALLBACK_PHONENUMBER)
  566. {
  567. OnSelchangeAsyncModemcallbackPhoneNumber();
  568. *pfPersisted = FALSE;
  569. }
  570. }
  571. return TRUE;
  572. }
  573. //---------------------------------------------------------------------------------------------------
  574. BOOL CAsyncDlg::AsyncRelease( )
  575. {
  576. if( m_pCfgcomp != NULL )
  577. {
  578. m_pCfgcomp->Release( );
  579. }
  580. return TRUE;
  581. }
  582. //---------------------------------------------------------------------------------------------------
  583. HRESULT CAsyncDlg::SetAsyncFields(ASYNCCONFIG& AsyncConfig , PUSERCONFIG pUc)
  584. {
  585. HRESULT hres = S_OK;
  586. if( pUc == NULL )
  587. {
  588. return E_INVALIDARG;
  589. }
  590. // check for variation
  591. lstrcpy( AsyncConfig.DeviceName , m_ac.DeviceName );
  592. if( memcmp( ( PVOID )&AsyncConfig , ( PVOID )&m_ac , sizeof( ASYNCCONFIG ) ) == 0 )
  593. {
  594. if( memcmp( pUc->CallbackNumber , m_uc.CallbackNumber , sizeof( m_uc.CallbackNumber ) ) == 0 &&
  595. pUc->fInheritCallback == m_uc.fInheritCallback &&
  596. pUc->fInheritCallbackNumber == m_uc.fInheritCallbackNumber )
  597. {
  598. return S_FALSE;
  599. }
  600. }
  601. BOOL bSelectDefault = !( *AsyncConfig.DeviceName);
  602. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_DEVICENAME );
  603. HWND hCbxCallback = GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK );
  604. TCHAR szDeviceName[DEVICENAME_LENGTH+MODEMNAME_LENGTH+1];
  605. /*
  606. * Set the DEVICE combo-box selection from the current selection.
  607. */
  608. FormDecoratedAsyncDeviceName( szDeviceName, &AsyncConfig );
  609. if( SendMessage( hCbx , CB_SELECTSTRING , ( WPARAM )-1 , ( LPARAM )szDeviceName ) == CB_ERR )
  610. {
  611. /*
  612. * Can't select current async DeviceName in combo-box. If this is
  613. * because we're supposed to select a default device name, select
  614. * the first device in the list.
  615. */
  616. if( bSelectDefault )
  617. {
  618. SendMessage( hCbx , CB_SETCURSEL , 0 , 0 );
  619. }
  620. else
  621. {
  622. hres = E_FAIL;
  623. }
  624. }
  625. /*
  626. * Set the MODEMCALLBACK combo-box selection, phone number, and 'inherit'
  627. * checkboxes, based on the current UserConfig settings.
  628. */
  629. SendMessage( hCbxCallback , CB_SETCURSEL , m_uc.Callback , 0 );
  630. SetDlgItemText( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER, m_uc.CallbackNumber );
  631. CheckDlgButton( m_hDlg , IDC_ASYNC_MODEMCALLBACK_INHERIT , m_uc.fInheritCallback );
  632. CheckDlgButton( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT , m_uc.fInheritCallbackNumber );
  633. /*
  634. * Set the BAUDRATE combo-box selection (in it's edit field) and limit the
  635. * edit field text.
  636. */
  637. TCHAR string[ULONG_DIGIT_MAX];
  638. wsprintf( string, TEXT("%lu"), AsyncConfig.BaudRate );
  639. SetDlgItemText( m_hDlg , IDC_ASYNC_BAUDRATE, string );
  640. SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_BAUDRATE ) , CB_LIMITTEXT , ULONG_DIGIT_MAX-1 , 0);
  641. HWND hEdit = GetWindow(GetDlgItem( m_hDlg , IDC_ASYNC_BAUDRATE ),GW_CHILD);
  642. if(hEdit)
  643. {
  644. LONG Style = GetWindowLong(hEdit, GWL_STYLE);
  645. SetWindowLong(hEdit,GWL_STYLE, Style | ES_NUMBER);
  646. }
  647. /*
  648. * Set the CONNECT combo-box selection.
  649. */
  650. SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_CONNECT) , CB_SETCURSEL , AsyncConfig.Connect.Type , 0 );
  651. // copy over default values
  652. CopyMemory( ( PVOID )&m_ac , ( PVOID )&AsyncConfig , sizeof( ASYNCCONFIGW ) );
  653. return hres;
  654. }
  655. //---------------------------------------------------------------------------------------------------
  656. BOOL CAsyncDlg::GetAsyncFields(ASYNCCONFIG& AsyncConfig, USERCONFIG UsrCfg)
  657. {
  658. /*
  659. * Fetch the currently selected DEVICENAME string.
  660. */
  661. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_DEVICENAME );
  662. ASSERT( hCbx != NULL );
  663. if( !SendMessage( hCbx , CB_GETCOUNT , 0 , 0 ) || SendMessage( hCbx , CB_GETCURSEL , 0 , 0 ) == CB_ERR )
  664. {
  665. ErrMessage( m_hDlg , IDS_INVALID_DEVICE );
  666. return FALSE;
  667. }
  668. /*
  669. * Get the MODEMCALLBACK phone number (callback state and 'user specified'
  670. * flags are already gotten).
  671. */
  672. GetDlgItemText(m_hDlg,IDC_ASYNC_MODEMCALLBACK_PHONENUMBER,
  673. UsrCfg.CallbackNumber,
  674. SIZE_OF_BUFFER(UsrCfg.CallbackNumber) );
  675. /*
  676. * Fetch and convert the BAUDRATE combo-box selection (in it's edit field).
  677. */
  678. {
  679. TCHAR string[ULONG_DIGIT_MAX], *endptr;
  680. ULONG ul;
  681. GetDlgItemText(m_hDlg,IDC_ASYNC_BAUDRATE, string, ULONG_DIGIT_MAX);
  682. ul = wcstoul( string, &endptr, 10 );
  683. if ( *endptr != TEXT('\0') )
  684. {
  685. /*
  686. * Invalid character in Baud Rate field.
  687. */
  688. ErrMessage( m_hDlg , IDS_INVALID_DEVICE );
  689. return FALSE;
  690. }
  691. else
  692. {
  693. AsyncConfig.BaudRate = ul;
  694. }
  695. }
  696. /*
  697. * Fetch the CONNECT combo-box selection and set/reset the break
  698. * disconnect flag.
  699. */
  700. AsyncConfig.Connect.Type = (ASYNCCONNECTCLASS)SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_CONNECT ) , CB_GETCURSEL , 0 , 0 );
  701. if(AsyncConfig.Connect.Type == Connect_FirstChar)
  702. {
  703. AsyncConfig.Connect.fEnableBreakDisconnect = 1;
  704. }
  705. else
  706. {
  707. AsyncConfig.Connect.fEnableBreakDisconnect = 0;
  708. }
  709. return(TRUE);
  710. } // end CAsyncDlg::GetAsyncFields
  711. //---------------------------------------------------------------------------------------------------
  712. // returns E_FAIL for general error
  713. // S_OK for default values saved
  714. // S_FALSE for default values have not been changed
  715. //---------------------------------------------------------------------------------------------------
  716. HRESULT CAsyncDlg::SetDefaults()
  717. {
  718. ASYNCCONFIG AsyncConfig;
  719. PUSERCONFIG pUserConfig = NULL;
  720. HRESULT hResult;
  721. hResult = m_pCfgcomp->GetAsyncConfig(m_szWDName,WdName,&AsyncConfig);
  722. if( SUCCEEDED( hResult ) )
  723. {
  724. LONG lsz;
  725. hResult = m_pCfgcomp->GetUserConfig( m_szWinstation , &lsz , &pUserConfig, TRUE );
  726. }
  727. if( SUCCEEDED( hResult ) )
  728. {
  729. hResult = SetAsyncFields( AsyncConfig , pUserConfig );
  730. }
  731. if( pUserConfig != NULL )
  732. {
  733. CoTaskMemFree( pUserConfig );
  734. }
  735. return hResult;
  736. }
  737. //---------------------------------------------------------------------------------------------------
  738. HRESULT CAsyncDlg::DoAsyncAdvance( )
  739. {
  740. CAdvancedAsyncDlg AADlg;
  741. //Initialize the dialog's member variables.
  742. AADlg.m_Async = m_ac;
  743. AADlg.m_bReadOnly = FALSE;
  744. AADlg.m_bModem = FALSE;
  745. AADlg.m_nHexBase = m_nHexBase;
  746. PWS pWs = NULL;
  747. LONG lSize = 0;
  748. if( m_szWDName[ 0 ] != 0 )
  749. {
  750. ODS( L"CAsyncDlg::DoAsyncAdvance m_pCfgcomp->GetWdType\n" );
  751. VERIFY_S( S_OK , m_pCfgcomp->GetWdType( m_szWDName , ( ULONG *)&AADlg.m_nWdFlag ) );
  752. }
  753. else if( SUCCEEDED( m_pCfgcomp->GetWSInfo( m_szWinstation , &lSize , &pWs ) ) )
  754. {
  755. ODS( L"CAsyncDlg::DoAsyncAdvance with m_szWinstation -- m_pCfgcomp->GetWdType\n" );
  756. VERIFY_S( S_OK , m_pCfgcomp->GetWdType( pWs->wdName , ( ULONG *)&AADlg.m_nWdFlag ) ) ;
  757. CoTaskMemFree( pWs );
  758. }
  759. AADlg.m_pCfgcomp = m_pCfgcomp; // addref here
  760. // Invoke dialog
  761. INT_PTR nRet = ::DialogBoxParam( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDD_ASYNC_ADVANCED ) , m_hDlg , CAdvancedAsyncDlg::DlgProc , ( LPARAM )&AADlg );
  762. if( nRet == IDOK )
  763. {
  764. // Fetch the dialog's member variables.
  765. if( memcmp( ( PVOID )&m_ac ,( PVOID )&AADlg.m_Async , sizeof( ASYNCCONFIG ) ) != 0 )
  766. {
  767. m_ac = AADlg.m_Async;
  768. m_nHexBase = AADlg.m_nHexBase;
  769. return S_OK;
  770. }
  771. }
  772. return S_FALSE;
  773. }
  774. //---------------------------------------------------------------------------------------------------
  775. BOOL CAsyncDlg::DoAsyncTest( )
  776. {
  777. CAsyncTestDlg ATDlg( m_pCfgcomp );
  778. // WINSTATIONCONFIG2W wsconfig;
  779. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_DEVICENAME );
  780. ASSERT( hCbx != NULL );
  781. if( !SendMessage( hCbx , CB_GETCOUNT , 0 , 0 ) || SendMessage( hCbx , CB_GETCURSEL , 0 , 0 ) == CB_ERR )
  782. {
  783. ErrMessage( m_hDlg , IDS_INVALID_DEVICE );
  784. return FALSE;
  785. }
  786. ATDlg.m_ac = m_ac;
  787. ATDlg.m_pWSName = m_szWinstation;
  788. // Invoke the dialog.
  789. INT_PTR nRet = ::DialogBoxParam( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDD_ASYNC_TEST ) , m_hDlg , CAsyncTestDlg::DlgProc , ( LPARAM )&ATDlg);
  790. if( nRet == IDOK )
  791. {
  792. m_ac = ATDlg.m_ac;
  793. }
  794. return TRUE;
  795. }
  796. //*******************************************************************************
  797. //
  798. // Help functions from Citrix
  799. //
  800. /*******************************************************************************
  801. *
  802. * CBInsertInstancedName - helper function
  803. *
  804. * Insert the specified 'instanced' name into the specified combo box,
  805. * using a special sort based on the 'root' name and 'instance' count.
  806. *
  807. * ENTRY:
  808. * pName (input)
  809. * Pointer to name string to insert.
  810. * pComboBox (input)
  811. * Pointer to CComboBox object to insert name string into.
  812. *
  813. * EXIT:
  814. * (int) Combo box list index of name after insertion, or error code.
  815. *
  816. ******************************************************************************/
  817. INT_PTR CBInsertInstancedName( LPCTSTR pName, HWND hCombo )
  818. {
  819. INT_PTR i, count, result;
  820. TCHAR NameRoot[64], ListRoot[64];
  821. if( pName == NULL || *pName == 0 )
  822. {
  823. ODS( L"TSCC: Invalid Arg @ CBInsertInstancedName\n" );
  824. return -1;
  825. }
  826. LPTSTR ListString = NULL;
  827. long NameInstance, ListInstance;
  828. /*
  829. * Form the root and instance for this name
  830. */
  831. ParseRootAndInstance( pName, NameRoot, &NameInstance );
  832. /*
  833. * Traverse combo box to perform insert.
  834. */
  835. for ( i = 0, count = SendMessage( hCombo , CB_GETCOUNT , 0 , 0 ); i < count; i++ ) {
  836. /*
  837. * Fetch current combo (list) box string.
  838. */
  839. if( ListString != NULL )
  840. {
  841. SendMessage( hCombo , CB_GETLBTEXT , ( WPARAM )i , ( LPARAM )ListString );
  842. }
  843. /*
  844. * Parse the root and instance of the list box string.
  845. */
  846. ParseRootAndInstance( ListString, ListRoot, &ListInstance );
  847. /*
  848. * If the list box string's root is greater than the our name string's
  849. * root, or the root strings are the same but the list instance is
  850. * greater than the name string's instance, or the root strings are
  851. * the same and the instances are the same but the entire list string
  852. * is greater than the entire name string, the name string belongs
  853. * at the current list position: insert it there.
  854. */
  855. if ( ((result = lstrcmpi( ListRoot, NameRoot )) > 0) ||
  856. ((result == 0) &&
  857. (ListInstance > NameInstance)) ||
  858. ((result == 0) &&
  859. (ListInstance == NameInstance) &&
  860. ( ListString != NULL && lstrcmpi(ListString, pName) > 0) ) )
  861. {
  862. return SendMessage( hCombo , CB_INSERTSTRING , ( WPARAM )i , ( LPARAM )pName );
  863. }
  864. }
  865. /*
  866. * Insert this name at the end of the list.
  867. */
  868. return SendMessage( hCombo , CB_INSERTSTRING , ( WPARAM )-1 , ( LPARAM )pName );
  869. } // end CBInsertInstancedName
  870. /*******************************************************************************
  871. *
  872. * ParseRootAndInstance - helper function
  873. *
  874. * Parse the 'root' string and instance count for a specified string.
  875. *
  876. * ENTRY:
  877. * pString (input)
  878. * Points to the string to parse.
  879. * pRoot (output)
  880. * Points to the buffer to store the parsed 'root' string.
  881. * pInstance (output)
  882. * Points to the int variable to store the parsed instance count.
  883. *
  884. * EXIT:
  885. * ParseRootAndInstance will parse only up to the first blank character
  886. * of the string (if a blank exists).
  887. * If the string contains no 'instance' count (no trailing digits), the
  888. * pInstance variable will contain -1. If the string consists entirely
  889. * of digits, the pInstance variable will contain the conversion of those
  890. * digits and pRoot will contain a null string.
  891. *
  892. ******************************************************************************/
  893. void
  894. ParseRootAndInstance( LPCTSTR pString,
  895. LPTSTR pRoot,
  896. long *pInstance )
  897. {
  898. LPCTSTR end, p;
  899. TCHAR szString[256];
  900. if( pString == NULL || pString[ 0 ] == 0 )
  901. {
  902. ODS( L"TSCC: Invalid arg @ ParseRootAndInstance\n" );
  903. return;
  904. }
  905. /*
  906. * Make a copy of the string and terminate at first blank (if present).
  907. */
  908. lstrcpyn(szString, pString, SIZE_OF_BUFFER( szString ) );
  909. // szString[ lstrlen(szString) - 1 ] = TEXT('\0');
  910. TCHAR *pTemp = szString;
  911. while( *pTemp && *pTemp != L' ' )
  912. {
  913. pTemp++;
  914. }
  915. p = &(pTemp[lstrlen(pTemp)-1]);
  916. /*
  917. * Parse the instance portion of the string.
  918. */
  919. end = p;
  920. while( (p >= pTemp) && !IsCharAlpha(*p) )
  921. p--;
  922. if ( p == end ) {
  923. /*
  924. * No trailing digits: indicate no 'instance' and make the 'root'
  925. * the whole string.
  926. */
  927. *pInstance = -1;
  928. lstrcpy( pRoot, pTemp );
  929. } else {
  930. /*
  931. * Trailing digits found (or entire string was digits): calculate
  932. * 'instance' and copy the 'root' string (null if all digits).
  933. */
  934. end = p;
  935. *pInstance = (int)_tcstol( p+1, NULL, 10 );
  936. /*
  937. * Copy 'root' string.
  938. */
  939. for ( p = szString; p <= end; pRoot++, p++ )
  940. *pRoot = *p;
  941. /*
  942. * Terminate 'root' string.
  943. */
  944. *pRoot = TEXT('\0');
  945. }
  946. } // end ParseRootAndInstance
  947. ////////////////////////////////////////////////////////////////////////////////
  948. CAdvancedAsyncDlg::CAdvancedAsyncDlg()
  949. {
  950. m_hDlg = NULL;
  951. } // end CAdvancedAsyncDlg::CAdvancedAsyncDlg
  952. //---------------------------------------------------------------------------------------------------
  953. BOOL CAdvancedAsyncDlg::HandleEnterEscKey(int nID)
  954. {
  955. /*
  956. * Check HW Flow Receive and Transmit combo boxes.
  957. */
  958. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWRX );
  959. ASSERT( hCbx != NULL );
  960. if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) )
  961. {
  962. if( nID == IDCANCEL )
  963. {
  964. // select original selection
  965. SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_Async.FlowControl.HardwareReceive , 0 );
  966. }
  967. SendMessage( hCbx , CB_SHOWDROPDOWN , ( WPARAM )FALSE , 0 );
  968. return FALSE;
  969. }
  970. hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWTX );
  971. ASSERT( hCbx != NULL );
  972. if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) )
  973. {
  974. if( nID == IDCANCEL )
  975. {
  976. // select original selection
  977. SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_Async.FlowControl.HardwareTransmit , 0 );
  978. }
  979. SendMessage( hCbx , CB_SHOWDROPDOWN , ( WPARAM )FALSE , 0 );
  980. return FALSE;
  981. }
  982. /*
  983. * No combo boxes are down; process Enter/Esc.
  984. */
  985. return TRUE;
  986. } // end CAdvancedAsyncDlg::HandleEnterEscKey
  987. //---------------------------------------------------------------------------------------------------
  988. void CAdvancedAsyncDlg::SetFields()
  989. {
  990. int nId = 0;
  991. /*
  992. * Set the FLOWCONTROL radio buttons.
  993. */
  994. switch( m_Async.FlowControl.Type ) {
  995. case FlowControl_None:
  996. nId = IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE;
  997. break;
  998. case FlowControl_Hardware:
  999. nId = IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE;
  1000. break;
  1001. case FlowControl_Software:
  1002. nId = IDC_ASYNC_ADVANCED_FLOWCONTROL_SOFTWARE;
  1003. break;
  1004. }
  1005. CheckRadioButton( m_hDlg ,
  1006. IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE,
  1007. IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE,
  1008. nId );
  1009. /*
  1010. * Set the text of the Hardware flowcontrol button.
  1011. */
  1012. SetHWFlowText();
  1013. /*
  1014. * If a modem is defined, disable the Flow Control fields, since they cannot
  1015. * be modified (must match modem's flow control established in Modem dialog).
  1016. */
  1017. if( m_bModem )
  1018. {
  1019. for ( nId = IDL_ASYNC_ADVANCED_FLOWCONTROL; nId <= IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE; nId++ )
  1020. {
  1021. EnableWindow( GetDlgItem( m_hDlg , nId ) , FALSE);
  1022. }
  1023. }
  1024. /*
  1025. * Call member functions to set the Global, Hardware, and Software fields.
  1026. */
  1027. SetGlobalFields();
  1028. SetHWFields();
  1029. SetSWFields();
  1030. } // end CAdvancedAsyncDlg::SetFields
  1031. //---------------------------------------------------------------------------------------------------
  1032. void CAdvancedAsyncDlg::SetHWFlowText( )
  1033. {
  1034. TCHAR tchStr[ 256 ];
  1035. LoadString( _Module.GetResourceInstance( ) , IDS_HARDWARE , tchStr , SIZE_OF_BUFFER( tchStr ) );
  1036. switch ( m_Async.FlowControl.HardwareReceive )
  1037. {
  1038. case ReceiveFlowControl_None:
  1039. lstrcat( tchStr , TEXT(" (.../") );
  1040. break;
  1041. case ReceiveFlowControl_RTS:
  1042. lstrcat( tchStr , TEXT(" (RTS/") );
  1043. break;
  1044. case ReceiveFlowControl_DTR:
  1045. lstrcat( tchStr , TEXT(" (DTR/") ) ;
  1046. break;
  1047. }
  1048. switch ( m_Async.FlowControl.HardwareTransmit )
  1049. {
  1050. case TransmitFlowControl_None:
  1051. lstrcat( tchStr , TEXT("...)" ) );
  1052. break;
  1053. case TransmitFlowControl_CTS:
  1054. lstrcat( tchStr , TEXT("CTS)") );
  1055. break;
  1056. case TransmitFlowControl_DSR:
  1057. lstrcat( tchStr , TEXT("DSR)") );
  1058. break;
  1059. }
  1060. SetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE , tchStr );
  1061. } // end CAdvancedAsyncDlg::SetHWFlowText
  1062. //---------------------------------------------------------------------------------------------------
  1063. void CAdvancedAsyncDlg::SetGlobalFields()
  1064. {
  1065. /*
  1066. * Select proper DTR radio button.
  1067. */
  1068. CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_DTROFF, IDC_ASYNC_ADVANCED_DTRON,
  1069. IDC_ASYNC_ADVANCED_DTROFF +
  1070. (int)m_Async.FlowControl.fEnableDTR );
  1071. /*
  1072. * Select proper RTS radio button.
  1073. */
  1074. CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_RTSOFF, IDC_ASYNC_ADVANCED_RTSON,
  1075. IDC_ASYNC_ADVANCED_RTSOFF +
  1076. (int)m_Async.FlowControl.fEnableRTS );
  1077. /*
  1078. * Set the PARITY radio buttons.
  1079. */
  1080. CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_PARITY_NONE,
  1081. IDC_ASYNC_ADVANCED_PARITY_SPACE,
  1082. IDC_ASYNC_ADVANCED_PARITY_NONE +
  1083. (int)m_Async.Parity );
  1084. /*
  1085. * Set the STOPBITS radio buttons.
  1086. */
  1087. CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_STOPBITS_1,
  1088. IDC_ASYNC_ADVANCED_STOPBITS_2,
  1089. IDC_ASYNC_ADVANCED_STOPBITS_1 +
  1090. (int)m_Async.StopBits );
  1091. /*
  1092. * Set the BYTESIZE radio buttons.
  1093. *
  1094. * NOTE: the constant '7' that is subtracted from the stored ByteSize
  1095. * must track the lowest allowed byte size / BYTESIZE radio button.
  1096. */
  1097. CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_BYTESIZE_7,
  1098. IDC_ASYNC_ADVANCED_BYTESIZE_8,
  1099. IDC_ASYNC_ADVANCED_BYTESIZE_7 +
  1100. ((int)m_Async.ByteSize - 7) );
  1101. /*
  1102. * If the currently selected Wd is an ICA type, disable the BYTESIZE
  1103. * group box and buttons - user can't change from default.
  1104. */
  1105. if ( m_nWdFlag & WDF_ICA )
  1106. {
  1107. int i;
  1108. for( i = IDL_ASYNC_ADVANCED_BYTESIZE ; i <= IDC_ASYNC_ADVANCED_BYTESIZE_8; i++ )
  1109. {
  1110. EnableWindow( GetDlgItem( m_hDlg , i ) , FALSE );
  1111. }
  1112. }
  1113. } // end CAdvancedAsyncDlg::SetGlobalFields
  1114. //---------------------------------------------------------------------------------------------------
  1115. void CAdvancedAsyncDlg::SetHWFields()
  1116. {
  1117. int i;
  1118. /*
  1119. * Initialize HW Receive class combo-box
  1120. */
  1121. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWRX );
  1122. ASSERT( hCbx != NULL );
  1123. SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_Async.FlowControl.HardwareReceive , 0 );
  1124. /*
  1125. * If HW flow control is selected AND the HW Receive class is set to
  1126. * ReceiveFlowControl_DTR, disable the DTR controls & labels.
  1127. * Otherwise, enable the DTR control & labels.
  1128. */
  1129. for( i = IDL_ASYNC_ADVANCED_DTRSTATE ; i <= IDC_ASYNC_ADVANCED_DTRON ; i++ )
  1130. {
  1131. EnableWindow( GetDlgItem( m_hDlg , i ) , ( ( m_Async.FlowControl.Type == FlowControl_Hardware) &&
  1132. (m_Async.FlowControl.HardwareReceive == ReceiveFlowControl_DTR) ) ? FALSE : TRUE );
  1133. }
  1134. /*
  1135. * Initialize HW Transmit class combo-box.
  1136. */
  1137. hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWTX);
  1138. SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_Async.FlowControl.HardwareTransmit , 0 );
  1139. /*
  1140. * If HW flow control is selected AND the HW Receive class is set to
  1141. * ReceiveFlowControl_RTS, disable the RTS controls & labels.
  1142. * Otherwise, enable the RTS control & labels.
  1143. */
  1144. for( i = IDL_ASYNC_ADVANCED_RTSSTATE ; i <= IDC_ASYNC_ADVANCED_RTSON ; i++ )
  1145. {
  1146. EnableWindow( GetDlgItem( m_hDlg , i ) , ( ( m_Async.FlowControl.Type == FlowControl_Hardware) &&
  1147. ( m_Async.FlowControl.HardwareReceive == ReceiveFlowControl_RTS ) ) ? FALSE : TRUE );
  1148. }
  1149. /*
  1150. * Enable or disable all HW fields.
  1151. */
  1152. for( i = IDL_ASYNC_ADVANCED_HARDWARE ; i <= IDC_ASYNC_ADVANCED_HWTX ; i++ )
  1153. {
  1154. EnableWindow( GetDlgItem( m_hDlg , i ) , m_Async.FlowControl.Type == FlowControl_Hardware );
  1155. }
  1156. } // end CAdvancedAsyncDlg::SetHWFields
  1157. //---------------------------------------------------------------------------------------------------
  1158. void CAdvancedAsyncDlg::SetSWFields()
  1159. {
  1160. TCHAR string[UCHAR_DIGIT_MAX];
  1161. /*
  1162. * Initialize Xon character edit control.
  1163. */
  1164. wsprintf( string, ( m_nHexBase ? TEXT("0x%02X") : TEXT("%d")) , (UCHAR)m_Async.FlowControl.XonChar );
  1165. SetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_XON , string );
  1166. SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XON ) , EM_SETMODIFY , ( WPARAM )FALSE , 0 );
  1167. SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XON ) , EM_LIMITTEXT , ( WPARAM )UCHAR_DIGIT_MAX-1 , 0 );
  1168. /*
  1169. * Initialize Xoff character edit control.
  1170. */
  1171. wsprintf( string, ( m_nHexBase ? TEXT( "0x%02X" ) : TEXT( "%d" ) ) , ( UCHAR )m_Async.FlowControl.XoffChar );
  1172. SetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_XOFF, string );
  1173. SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XOFF ) , EM_SETMODIFY , ( WPARAM )FALSE , 0 );
  1174. SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XOFF ) , EM_LIMITTEXT , ( WPARAM )UCHAR_DIGIT_MAX-1 , 0 );
  1175. /*
  1176. * Initialize the Xon/Xoff base control.
  1177. */
  1178. CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_BASEDEC, IDC_ASYNC_ADVANCED_BASEHEX,
  1179. ( int )( IDC_ASYNC_ADVANCED_BASEDEC + m_nHexBase ) );
  1180. /*
  1181. * Enable or disable all SW fields.
  1182. */
  1183. for( int i = IDL_ASYNC_ADVANCED_SOFTWARE ; i <= IDC_ASYNC_ADVANCED_BASEHEX ; i++ )
  1184. {
  1185. EnableWindow( GetDlgItem( m_hDlg , i ) , m_Async.FlowControl.Type == FlowControl_Software );
  1186. }
  1187. } // end CAdvancedAsyncDlg::SetSWFields
  1188. //---------------------------------------------------------------------------------------------------
  1189. BOOL CAdvancedAsyncDlg::GetFields()
  1190. {
  1191. /*
  1192. * Call member functions to get the Flow Control, Global, Hardware, and
  1193. * Software fields.
  1194. */
  1195. GetFlowControlFields();
  1196. if ( !GetGlobalFields() )
  1197. return(FALSE);
  1198. if ( !GetHWFields() )
  1199. return(FALSE);
  1200. if ( !GetSWFields(TRUE) )
  1201. return(FALSE);
  1202. return(TRUE);
  1203. } // end CAdvancedAsyncDlg::GetFields
  1204. //---------------------------------------------------------------------------------------------------
  1205. void CAdvancedAsyncDlg::GetFlowControlFields()
  1206. {
  1207. switch( GetCheckedRadioButton( IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE , IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE ) )
  1208. {
  1209. case IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE:
  1210. m_Async.FlowControl.Type = FlowControl_None;
  1211. break;
  1212. case IDC_ASYNC_ADVANCED_FLOWCONTROL_SOFTWARE:
  1213. m_Async.FlowControl.Type = FlowControl_Software;
  1214. break;
  1215. case IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE:
  1216. m_Async.FlowControl.Type = FlowControl_Hardware;
  1217. break;
  1218. }
  1219. } // end CAdvancedAsyncDlg::GetFlowControlFields
  1220. //---------------------------------------------------------------------------------------------------
  1221. BOOL CAdvancedAsyncDlg::GetGlobalFields()
  1222. {
  1223. /*
  1224. * Fetch DTR state.
  1225. */
  1226. m_Async.FlowControl.fEnableDTR =
  1227. (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_DTROFF,
  1228. IDC_ASYNC_ADVANCED_DTRON )
  1229. - IDC_ASYNC_ADVANCED_DTROFF);
  1230. /*
  1231. * Fetch RTS state.
  1232. */
  1233. m_Async.FlowControl.fEnableRTS =
  1234. (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_RTSOFF,
  1235. IDC_ASYNC_ADVANCED_RTSON )
  1236. - IDC_ASYNC_ADVANCED_RTSOFF);
  1237. /*
  1238. * Fetch the selected PARITY.
  1239. */
  1240. m_Async.Parity = (ULONG)
  1241. (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_PARITY_NONE,
  1242. IDC_ASYNC_ADVANCED_PARITY_SPACE )
  1243. - IDC_ASYNC_ADVANCED_PARITY_NONE);
  1244. /*
  1245. * Fetch the selected STOPBITS.
  1246. */
  1247. m_Async.StopBits = (ULONG)
  1248. (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_STOPBITS_1,
  1249. IDC_ASYNC_ADVANCED_STOPBITS_2 )
  1250. - IDC_ASYNC_ADVANCED_STOPBITS_1);
  1251. /*
  1252. * Fetch the selected BYTESIZE.
  1253. *
  1254. * NOTE: the constant '7' that is added to the stored ByteSize
  1255. * must track the lowest allowed byte size / BYTESIZE radio button.
  1256. */
  1257. m_Async.ByteSize = (ULONG)
  1258. (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_BYTESIZE_7,
  1259. IDC_ASYNC_ADVANCED_BYTESIZE_8 )
  1260. - IDC_ASYNC_ADVANCED_BYTESIZE_7 + 7);
  1261. return(TRUE);
  1262. } // end CAdvancedAsyncDlg::GetGlobalFields
  1263. //---------------------------------------------------------------------------------------------------
  1264. BOOL CAdvancedAsyncDlg::GetHWFields()
  1265. {
  1266. /*
  1267. * Fetch the HW receive flow class.
  1268. */
  1269. m_Async.FlowControl.HardwareReceive = ( RECEIVEFLOWCONTROLCLASS )
  1270. SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWRX ) , CB_GETCURSEL , 0 , 0 );
  1271. /*
  1272. * Fetch the HW transmit flow class.
  1273. */
  1274. m_Async.FlowControl.HardwareTransmit = ( TRANSMITFLOWCONTROLCLASS )
  1275. SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWTX ) , CB_GETCURSEL , 0 , 0 );
  1276. return TRUE;
  1277. } // end CAdvancedAsyncDlg::GetHWFields
  1278. //---------------------------------------------------------------------------------------------------
  1279. BOOL CAdvancedAsyncDlg::GetSWFields( BOOL bValidate )
  1280. {
  1281. TCHAR string[UCHAR_DIGIT_MAX], *endptr;
  1282. ULONG ul;
  1283. INT_PTR nNewHexBase, base;
  1284. /*
  1285. * Determine the current state of the base controls and save.
  1286. */
  1287. nNewHexBase = (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_BASEDEC,
  1288. IDC_ASYNC_ADVANCED_BASEHEX )
  1289. - IDC_ASYNC_ADVANCED_BASEDEC);
  1290. /*
  1291. * Fetch and convert XON character.
  1292. */
  1293. GetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_XON , string , SIZE_OF_BUFFER( string ) );
  1294. /*
  1295. * If the edit box is modified, use the 'new' base for conversion.
  1296. */
  1297. base = SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XON ) , EM_GETMODIFY , 0 , 0 ) ? nNewHexBase : m_nHexBase ;
  1298. ul = _tcstoul( string, &endptr, (base ? 16 : 10) );
  1299. /*
  1300. * If validation is requested and there is a problem with the input,
  1301. * complain and allow user to fix.
  1302. */
  1303. if( bValidate && ( (*endptr != TEXT('\0') ) || ( ul > 255 ) ) )
  1304. {
  1305. /*
  1306. * Invalid character in field or invalid value.
  1307. */
  1308. // ERROR_MESSAGE((IDP_INVALID_XONXOFF))
  1309. /*
  1310. * Set focus to the control so that it can be fixed.
  1311. */
  1312. SetFocus( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XON ) );
  1313. return FALSE;
  1314. }
  1315. /*
  1316. * Save the Xon character.
  1317. */
  1318. m_Async.FlowControl.XonChar = (UCHAR)ul;
  1319. /*
  1320. * Fetch and convert XOFF character.
  1321. */
  1322. GetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_XOFF , string , SIZE_OF_BUFFER( string ) );
  1323. /*
  1324. * If the edit box is modified, use the 'new' base for conversion.
  1325. */
  1326. base = SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XOFF ) , EM_GETMODIFY , 0 , 0 ) ? nNewHexBase : m_nHexBase ;
  1327. ul = _tcstoul( string, &endptr, (base ? 16 : 10) );
  1328. /*
  1329. * If validation is requested and there is a problem with the input,
  1330. * complain and allow user to fix.
  1331. */
  1332. if( bValidate && ( (*endptr != TEXT('\0' )) || ( ul > 255 ) ) )
  1333. {
  1334. /*
  1335. * Invalid character in field or invalid value.
  1336. */
  1337. // ERROR_MESSAGE((IDP_INVALID_XONXOFF))
  1338. /*
  1339. * Set focus to the control so that it can be fixed.
  1340. */
  1341. SetFocus( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XOFF ) );
  1342. return FALSE;
  1343. }
  1344. /*
  1345. * Save the Xoff character.
  1346. */
  1347. m_Async.FlowControl.XoffChar = (UCHAR)ul;
  1348. /*
  1349. * Save the current base state.
  1350. */
  1351. m_nHexBase = nNewHexBase;
  1352. return TRUE;
  1353. } // end CAdvancedAsyncDlg::GetSWFields
  1354. ////////////////////////////////////////////////////////////////////////////////
  1355. // CAdvancedAsyncDlg message map
  1356. BOOL CAdvancedAsyncDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  1357. {
  1358. switch( wNotifyCode )
  1359. {
  1360. case BN_CLICKED:
  1361. if( wID == IDC_ASYNC_ADVANCED_BASEDEC )
  1362. {
  1363. OnClickedAsyncAdvancedBasedec( );
  1364. }
  1365. else if( wID == IDC_ASYNC_ADVANCED_BASEHEX )
  1366. {
  1367. OnClickedAsyncAdvancedBasehex( );
  1368. }
  1369. else if( wID == IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE )
  1370. {
  1371. OnClickedAsyncAdvancedFlowcontrolHardware( );
  1372. }
  1373. else if( wID == IDC_ASYNC_ADVANCED_FLOWCONTROL_SOFTWARE )
  1374. {
  1375. OnClickedAsyncAdvancedFlowcontrolSoftware( );
  1376. }
  1377. else if( wID == IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE )
  1378. {
  1379. OnClickedAsyncAdvancedFlowcontrolNone( );
  1380. }
  1381. else if( wID == IDOK )
  1382. {
  1383. OnOK( );
  1384. return EndDialog( m_hDlg , IDOK );
  1385. }
  1386. else if( wID == IDCANCEL )
  1387. {
  1388. OnCancel( );
  1389. return EndDialog( m_hDlg , IDCANCEL );
  1390. }
  1391. else if( wID == ID_HELP )
  1392. {
  1393. TCHAR tchHelpFile[ MAX_PATH ];
  1394. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ASYNC_HELPFILE , tchHelpFile , SIZE_OF_BUFFER( tchHelpFile ) ) );
  1395. WinHelp( GetParent( hwndCtrl ) , tchHelpFile , HELP_CONTEXT , HID_ASYNCADVANCE );
  1396. }
  1397. break;
  1398. case CBN_CLOSEUP:
  1399. if( wID == IDC_ASYNC_ADVANCED_HWRX )
  1400. {
  1401. OnCloseupAsyncAdvancedHwrx( );
  1402. }
  1403. else if( wID == IDC_ASYNC_ADVANCED_HWTX )
  1404. {
  1405. OnCloseupAsyncAdvancedHwtx( );
  1406. }
  1407. break;
  1408. case CBN_SELCHANGE:
  1409. if( wID == IDC_ASYNC_ADVANCED_HWRX )
  1410. {
  1411. OnSelchangeAsyncAdvancedHwrx( );
  1412. }
  1413. else if( wID == IDC_ASYNC_ADVANCED_HWTX )
  1414. {
  1415. OnSelchangeAsyncAdvancedHwtx( );
  1416. }
  1417. break;
  1418. }
  1419. return TRUE;
  1420. }
  1421. ////////////////////////////////////////////////////////////////////////////////
  1422. // CAdvancedAsyncDlg commands
  1423. //---------------------------------------------------------------------------------------------------
  1424. BOOL CAdvancedAsyncDlg::OnInitDialog( HWND hDlg , WPARAM wp , LPARAM lp )
  1425. {
  1426. UNREFERENCED_PARAMETER( wp );
  1427. UNREFERENCED_PARAMETER( lp );
  1428. // int i;
  1429. TCHAR tchString[ 80 ];
  1430. HWND hCbx = GetDlgItem( hDlg , IDC_ASYNC_ADVANCED_HWRX );
  1431. ASSERT( hCbx != NULL );
  1432. // Load up combo boxes with strings.
  1433. m_hDlg = hDlg;
  1434. int idx = 0;
  1435. HRESULT hr;
  1436. while( SUCCEEDED( ( hr = m_pCfgcomp->GetHWReceiveName( idx , tchString ) ) ) )
  1437. {
  1438. if( hr == S_FALSE )
  1439. {
  1440. break;
  1441. }
  1442. SendMessage( hCbx , CB_ADDSTRING , 0 , ( LPARAM )tchString );
  1443. idx++;
  1444. }
  1445. hCbx = GetDlgItem( hDlg , IDC_ASYNC_ADVANCED_HWTX);
  1446. ASSERT( hCbx != NULL );
  1447. idx = 0;
  1448. while( SUCCEEDED( ( hr = m_pCfgcomp->GetHWTransmitName( idx , tchString ) ) ) )
  1449. {
  1450. if( hr == S_FALSE )
  1451. {
  1452. break;
  1453. }
  1454. SendMessage( hCbx , CB_ADDSTRING , 0 , ( LPARAM )tchString );
  1455. idx++;
  1456. }
  1457. // Initalize all dialog fields.
  1458. SetFields();
  1459. /*
  1460. if ( m_bReadOnly ) {
  1461. /*
  1462. * Document is 'read-only': disable all dialog controls and labels
  1463. * except for CANCEL & HELP buttons.
  1464. for ( i=IDL_ASYNC_ADVANCED_FLOWCONTROL;
  1465. i <=IDC_ASYNC_ADVANCED_BYTESIZE_8; i++ )
  1466. GetDlgItem(i)->EnableWindow(FALSE);
  1467. GetDlgItem(IDOK)->EnableWindow(FALSE);
  1468. }
  1469. */
  1470. return(TRUE);
  1471. } // end CAdvancedAsyncDlg::OnInitDialog
  1472. //---------------------------------------------------------------------------------------------------
  1473. void CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolHardware()
  1474. {
  1475. GetFlowControlFields();
  1476. SetFields();
  1477. } // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolHardware
  1478. //---------------------------------------------------------------------------------------------------
  1479. void CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolSoftware()
  1480. {
  1481. GetFlowControlFields();
  1482. SetFields();
  1483. } // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolSoftware
  1484. //---------------------------------------------------------------------------------------------------
  1485. void CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolNone()
  1486. {
  1487. GetFlowControlFields();
  1488. SetFields();
  1489. } // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolNone
  1490. //---------------------------------------------------------------------------------------------------
  1491. void CAdvancedAsyncDlg::OnCloseupAsyncAdvancedHwrx()
  1492. {
  1493. OnSelchangeAsyncAdvancedHwrx();
  1494. } // end CAdvancedAsyncDlg::OnCloseupAsyncAdvancedHwrx
  1495. //---------------------------------------------------------------------------------------------------
  1496. void CAdvancedAsyncDlg::OnSelchangeAsyncAdvancedHwrx()
  1497. {
  1498. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWRX );
  1499. ASSERT( hCbx != NULL );
  1500. /*
  1501. * Ignore this notification if the combo box is in a dropped-down
  1502. * state.
  1503. */
  1504. if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) )
  1505. {
  1506. return;
  1507. }
  1508. /*
  1509. * Fetch and Set the Hardware fields to update.
  1510. */
  1511. GetHWFields();
  1512. SetHWFields();
  1513. SetHWFlowText();
  1514. } // end CAdvancedAsyncDlg::OnSelchangeAsyncAdvancedHwrx
  1515. //---------------------------------------------------------------------------------------------------
  1516. void CAdvancedAsyncDlg::OnCloseupAsyncAdvancedHwtx()
  1517. {
  1518. OnSelchangeAsyncAdvancedHwtx();
  1519. } // end CAdvancedAsyncDlg::OnCloseupAsyncAdvancedHwtx
  1520. //---------------------------------------------------------------------------------------------------
  1521. void CAdvancedAsyncDlg::OnSelchangeAsyncAdvancedHwtx()
  1522. {
  1523. HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWTX );
  1524. ASSERT( hCbx != NULL );
  1525. /*
  1526. * Ignore this notification if the combo box is in a dropped-down
  1527. * state.
  1528. */
  1529. if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) )
  1530. {
  1531. return;
  1532. }
  1533. /*
  1534. * Fetch and Set the Hardware fields to update.
  1535. */
  1536. GetHWFields();
  1537. SetHWFields();
  1538. SetHWFlowText();
  1539. } // end CAdvancedAsyncDlg::OnSelchangeAsyncAdvancedHwtx
  1540. //---------------------------------------------------------------------------------------------------
  1541. void CAdvancedAsyncDlg::OnClickedAsyncAdvancedBasedec()
  1542. {
  1543. /*
  1544. * Get/Set the SW fields to display in decimal base.
  1545. */
  1546. GetSWFields(FALSE);
  1547. SetSWFields();
  1548. } // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedBasedec
  1549. //---------------------------------------------------------------------------------------------------
  1550. void CAdvancedAsyncDlg::OnClickedAsyncAdvancedBasehex()
  1551. {
  1552. /*
  1553. * Get/Set the SW fields to display in hexadecimal base.
  1554. */
  1555. GetSWFields(FALSE);
  1556. SetSWFields();
  1557. } // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedBasehex
  1558. //---------------------------------------------------------------------------------------------------
  1559. void CAdvancedAsyncDlg::OnOK()
  1560. {
  1561. /*
  1562. * If the Enter key was pressed while a combo box was dropped down, ignore
  1563. * it (treat as combo list selection only).
  1564. */
  1565. if ( !HandleEnterEscKey(IDOK) )
  1566. return;
  1567. /*
  1568. * Fetch the field contents. Return (don't close dialog) if a problem
  1569. * was found.
  1570. */
  1571. GetFields();
  1572. } // end CAdvancedAsyncDlg::OnOK
  1573. //---------------------------------------------------------------------------------------------------
  1574. void CAdvancedAsyncDlg::OnCancel()
  1575. {
  1576. /*
  1577. * If the Esc key was pressed while a combo box was dropped down, ignore
  1578. * it (treat as combo close-up and cancel only).
  1579. */
  1580. HandleEnterEscKey( IDCANCEL );
  1581. } // end CAdvancedAsyncDlg::OnCancel
  1582. //---------------------------------------------------------------------------------------------------
  1583. int CAdvancedAsyncDlg::GetCheckedRadioButton( int nIDFirstButton, int nIDLastButton )
  1584. {
  1585. for (int nID = nIDFirstButton; nID <= nIDLastButton; nID++)
  1586. {
  1587. if( IsDlgButtonChecked( m_hDlg , nID ) )
  1588. {
  1589. return nID; // id that matched
  1590. }
  1591. }
  1592. return 0; // invalid ID
  1593. }
  1594. //---------------------------------------------------------------------------------------------------
  1595. INT_PTR CALLBACK CAdvancedAsyncDlg::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  1596. {
  1597. CAdvancedAsyncDlg *pDlg;
  1598. if( msg == WM_INITDIALOG )
  1599. {
  1600. CAdvancedAsyncDlg *pDlg = ( CAdvancedAsyncDlg * )lp;
  1601. SetWindowLongPtr( hwnd , DWLP_USER, ( LONG_PTR )pDlg );
  1602. if( !IsBadReadPtr( pDlg , sizeof( CAdvancedAsyncDlg ) ) )
  1603. {
  1604. pDlg->OnInitDialog( hwnd , wp , lp );
  1605. }
  1606. return 0;
  1607. }
  1608. else
  1609. {
  1610. pDlg = ( CAdvancedAsyncDlg * )GetWindowLongPtr( hwnd , DWLP_USER);
  1611. if( IsBadReadPtr( pDlg , sizeof( CAdvancedAsyncDlg ) ) )
  1612. {
  1613. return 0;
  1614. }
  1615. }
  1616. switch( msg )
  1617. {
  1618. /*case WM_DESTROY:
  1619. pDlg->OnDestroy( );
  1620. break;*/
  1621. case WM_COMMAND:
  1622. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  1623. break;
  1624. case WM_CONTEXTMENU:
  1625. {
  1626. POINT pt;
  1627. pt.x = LOWORD( lp );
  1628. pt.y = HIWORD( lp );
  1629. // pDlg->OnContextMenu( ( HWND )wp , pt );
  1630. }
  1631. break;
  1632. case WM_HELP:
  1633. // pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
  1634. break;
  1635. /*case WM_NOTIFY:
  1636. return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );*/
  1637. }
  1638. return 0;
  1639. }
  1640. /***********************************************************************************************************/
  1641. //---------------------------------------------------------------------------------------------------
  1642. void CEchoEditControl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  1643. {
  1644. UNREFERENCED_PARAMETER( nRepCnt );
  1645. UNREFERENCED_PARAMETER( nFlags );
  1646. /*
  1647. * Tell dialog to write the character to the device unless we're
  1648. * currently processing edit control output. This flag check is needed
  1649. * because the CEdit::Cut() member function will generate an OnChar()
  1650. * event, which we need to ignore ('\b' processing).
  1651. */
  1652. if( !m_bProcessingOutput )
  1653. {
  1654. ODS( L"CEchoEditControl::OnChar -- WM_ASYNCTESTWRITECHAR( S )\n" );
  1655. ::SendMessage( m_hDlg , WM_ASYNCTESTWRITECHAR, nChar, 0 );
  1656. }
  1657. /*
  1658. * Pass character on to the edit control. This will do nothing if
  1659. * the edit control is 'read only'. To cause a 'local echo' effect,
  1660. * set the edit control to 'read/write'.
  1661. */
  1662. }
  1663. //---------------------------------------------------------------------------------------------------
  1664. void CEchoEditControl::SubclassDlgItem( HWND hDlg , int nRes )
  1665. {
  1666. HWND hCtrl = GetDlgItem( hDlg , nRes );
  1667. ASSERT( hCtrl != NULL );
  1668. m_oldproc = ( WNDPROC )SetWindowLongPtr( hCtrl , GWLP_WNDPROC , ( LONG_PTR )CEchoEditControl::WndProc );
  1669. SetWindowLongPtr( hCtrl , GWLP_USERDATA , ( LONG_PTR )this );
  1670. }
  1671. //---------------------------------------------------------------------------------------------------
  1672. LRESULT CALLBACK CEchoEditControl::WndProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  1673. {
  1674. CEchoEditControl *pEdit = ( CEchoEditControl * )GetWindowLongPtr( hwnd , GWLP_USERDATA );
  1675. if( pEdit == NULL )
  1676. {
  1677. ODS( L"CEchoEditControl static object not set\n" );
  1678. return 0;
  1679. }
  1680. switch( msg )
  1681. {
  1682. case WM_CHAR:
  1683. pEdit->OnChar( ( TCHAR )wp , LOWORD( lp ) , HIWORD( lp ) );
  1684. break;
  1685. }
  1686. if( pEdit->m_oldproc != NULL )
  1687. {
  1688. return ::CallWindowProc( pEdit->m_oldproc , hwnd , msg ,wp , lp ) ;
  1689. }
  1690. return DefWindowProc( hwnd , msg ,wp , lp );
  1691. }
  1692. //---------------------------------------------------------------------------------------------------
  1693. CLed::CLed( HBRUSH hBrush )
  1694. {
  1695. m_hBrush = hBrush;
  1696. m_bOn = FALSE;
  1697. }
  1698. //---------------------------------------------------------------------------------------------------
  1699. void CLed::Subclass( HWND hDlg , int nRes )
  1700. {
  1701. HWND hCtrl = GetDlgItem( hDlg , nRes );
  1702. ASSERT( hCtrl != NULL );
  1703. m_hWnd = hCtrl;
  1704. m_oldproc = ( WNDPROC )SetWindowLongPtr( hCtrl , GWLP_WNDPROC , ( LONG_PTR )CLed::WndProc );
  1705. SetWindowLongPtr( hCtrl , GWLP_USERDATA , ( LONG_PTR )this );
  1706. }
  1707. //---------------------------------------------------------------------------------------------------
  1708. void CLed::Update(int nOn)
  1709. {
  1710. m_bOn = nOn ? TRUE : FALSE;
  1711. InvalidateRect( m_hWnd , NULL , FALSE );
  1712. UpdateWindow( m_hWnd );
  1713. }
  1714. //---------------------------------------------------------------------------------------------------
  1715. void CLed::Toggle()
  1716. {
  1717. ODS(L"CLed::Toggle\n");
  1718. m_bOn = !m_bOn;
  1719. InvalidateRect( m_hWnd , NULL , FALSE );
  1720. // UpdateWindow( m_hWnd );
  1721. }
  1722. void CLed::OnPaint( HWND hwnd )
  1723. {
  1724. RECT rect;
  1725. PAINTSTRUCT ps;
  1726. ODS(L"CLed::OnPaint\n");
  1727. HDC dc = BeginPaint( hwnd , &ps );
  1728. HBRUSH brush;
  1729. GetClientRect( hwnd , &rect );
  1730. #ifdef USING_3DCONTROLS
  1731. (rect.right)--;
  1732. (rect.bottom)--;
  1733. brush = ( HBRUSH )GetStockObject( GRAY_BRUSH );
  1734. FrameRect( dc , &rect, brush );
  1735. (rect.top)++;
  1736. (rect.left)++;
  1737. (rect.right)++;
  1738. (rect.bottom)++;
  1739. brush = ( HBRUSH )GetStockObject( WHITE_BRUSH );
  1740. FrameRect( dc , &rect, brush );
  1741. (rect.top)++;
  1742. (rect.left)++;
  1743. (rect.right) -= 2;
  1744. (rect.bottom) -= 2;
  1745. #else
  1746. brush = ( HBRUSH )GetStockObject( BLACK_BRUSH );
  1747. FrameRect( dc , &rect , brush );
  1748. (rect.top)++;
  1749. (rect.left)++;
  1750. (rect.right)--;
  1751. (rect.bottom)--;
  1752. #endif
  1753. DBGMSG( L"led should be %s\n" , m_bOn ? L"red" : L"grey" );
  1754. brush = m_bOn ? m_hBrush : ( HBRUSH )GetStockObject( LTGRAY_BRUSH );
  1755. FillRect( dc , &rect , brush );
  1756. EndPaint( hwnd , &ps );
  1757. }
  1758. //---------------------------------------------------------------------------------------------------
  1759. LRESULT CALLBACK CLed::WndProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  1760. {
  1761. CLed *pWnd = ( CLed * )GetWindowLongPtr( hwnd , GWLP_USERDATA );
  1762. if( pWnd == NULL )
  1763. {
  1764. ODS( L"CLed is not available\n" );
  1765. return 0;
  1766. }
  1767. switch( msg )
  1768. {
  1769. case WM_PAINT:
  1770. pWnd->OnPaint( hwnd );
  1771. break;
  1772. }
  1773. if( pWnd->m_oldproc != NULL )
  1774. {
  1775. return ::CallWindowProc( pWnd->m_oldproc , hwnd , msg ,wp , lp ) ;
  1776. }
  1777. return DefWindowProc( hwnd , msg ,wp , lp );
  1778. }
  1779. //---------------------------------------------------------------------------------------------------
  1780. ////////////////////////////////////////////////////////////////////////////////
  1781. // CThread class construction / destruction, implementation
  1782. /*******************************************************************************
  1783. *
  1784. * CThread - CThread constructor
  1785. *
  1786. * ENTRY:
  1787. * EXIT:
  1788. *
  1789. ******************************************************************************/
  1790. CThread::CThread()
  1791. {
  1792. m_hThread = NULL;
  1793. m_dwThreadID = 0;
  1794. } // end CThread::CThread
  1795. /*******************************************************************************
  1796. *
  1797. * ~CThread - CThread destructor
  1798. *
  1799. * ENTRY:
  1800. * EXIT:
  1801. *
  1802. ******************************************************************************/
  1803. CThread::~CThread()
  1804. {
  1805. } // end CThread::~CThread
  1806. ////////////////////////////////////////////////////////////////////////////////
  1807. // CThread operations: primary thread
  1808. /*******************************************************************************
  1809. *
  1810. * CreateThread - CThread implementation function
  1811. *
  1812. * Class wrapper for the Win32 CreateThread API.
  1813. *
  1814. * ENTRY:
  1815. * EXIT:
  1816. *
  1817. ******************************************************************************/
  1818. HANDLE CThread::CreateThread( DWORD cbStack , DWORD fdwCreate )
  1819. {
  1820. /*
  1821. * Simple wrapper for Win32 CreateThread API.
  1822. */
  1823. return( m_hThread = ::CreateThread( NULL, cbStack, ThreadEntryPoint , ( LPVOID ) this, fdwCreate, &m_dwThreadID ) );
  1824. } // end CThread::CreateThread
  1825. ////////////////////////////////////////////////////////////////////////////////
  1826. // CThread operations: secondary thread
  1827. /*******************************************************************************
  1828. *
  1829. * ThreadEntryPoint - CThread implementation function
  1830. * (SECONDARY THREAD)
  1831. *
  1832. * ENTRY:
  1833. * EXIT:
  1834. *
  1835. ******************************************************************************/
  1836. DWORD __stdcall CThread::ThreadEntryPoint( LPVOID lpParam )
  1837. {
  1838. CThread *pThread;
  1839. DWORD dwResult = ( DWORD )-1;
  1840. /*
  1841. * (lpParam is actually the 'this' pointer)
  1842. */
  1843. pThread = (CThread*)lpParam;
  1844. /*
  1845. * Run the thread.
  1846. */
  1847. if( pThread != NULL )
  1848. {
  1849. dwResult = pThread->RunThread();
  1850. }
  1851. /*
  1852. * Return the result.
  1853. */
  1854. return(dwResult);
  1855. } // end CThread::ThreadEntryPoint
  1856. ////////////////////////////////////////////////////////////////////////////////
  1857. ////////////////////////////////////////////////////////////////////////////////
  1858. // CATDlgInputThread class construction / destruction, implementation
  1859. /*******************************************************************************
  1860. *
  1861. * CATDlgInputThread - CATDlgInputThread constructor
  1862. *
  1863. * ENTRY:
  1864. * EXIT:
  1865. *
  1866. ******************************************************************************/
  1867. CATDlgInputThread::CATDlgInputThread()
  1868. {
  1869. /*
  1870. * Initialize member variables.
  1871. */
  1872. m_bExit = FALSE;
  1873. m_ErrorStatus = ERROR_SUCCESS;
  1874. m_hConsumed = NULL;
  1875. ZeroMemory( &m_OverlapSignal , sizeof( OVERLAPPED ) );
  1876. ZeroMemory( &m_OverlapRead , sizeof( OVERLAPPED ) );
  1877. //m_OverlapSignal.hEvent = NULL;
  1878. //m_OverlapRead.hEvent = NULL;
  1879. m_BufferBytes = 0;
  1880. } // end CATDlgInputThread::CATDlgInputThread
  1881. /*******************************************************************************
  1882. *
  1883. * ~CATDlgInputThread - CATDlgInputThread destructor
  1884. *
  1885. * ENTRY:
  1886. * EXIT:
  1887. *
  1888. ******************************************************************************/
  1889. CATDlgInputThread::~CATDlgInputThread()
  1890. {
  1891. /*
  1892. * Close the semaphore and events when the CATDlgInputThread
  1893. * object is destroyed.
  1894. */
  1895. if ( m_hConsumed )
  1896. CloseHandle(m_hConsumed);
  1897. if ( m_OverlapRead.hEvent )
  1898. CloseHandle(m_OverlapRead.hEvent);
  1899. if ( m_OverlapSignal.hEvent )
  1900. CloseHandle(m_OverlapSignal.hEvent);
  1901. } // end CATDlgInputThread::~CATDlgInputThread
  1902. /*******************************************************************************
  1903. *
  1904. * RunThread - CATDlgInputThread secondary thread main function loop
  1905. * (SECONDARY THREAD)
  1906. *
  1907. * ENTRY:
  1908. * EXIT:
  1909. * (DWORD) exit status for the secondary thread.
  1910. *
  1911. ******************************************************************************/
  1912. DWORD
  1913. CATDlgInputThread::RunThread()
  1914. {
  1915. HANDLE hWait[2];
  1916. DWORD Status;
  1917. int iStat;
  1918. /*
  1919. * Initialize for overlapped status and read input.
  1920. */
  1921. m_hConsumed = CreateSemaphore( NULL , 0 , MAX_STATUS_SEMAPHORE_COUNT , NULL );
  1922. m_OverlapRead.hEvent = CreateEvent( NULL , TRUE , FALSE , NULL );
  1923. m_OverlapSignal.hEvent = CreateEvent( NULL , TRUE , FALSE , NULL );
  1924. if ( m_hConsumed == NULL || m_OverlapRead.hEvent == NULL || m_OverlapSignal.hEvent == NULL ||
  1925. !SetCommMask( m_hDevice , EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_BREAK ) )
  1926. {
  1927. NotifyAbort(IDP_ERROR_CANT_INITIALIZE_INPUT_THREAD);
  1928. return(1);
  1929. }
  1930. /*
  1931. * Query initial comm status to initialize dialog with (return if error).
  1932. */
  1933. if ( (iStat = CommStatusAndNotify()) != -1 )
  1934. return(iStat);
  1935. /*
  1936. * Post Read for input data.
  1937. */
  1938. if ( (iStat = PostInputRead()) != -1 )
  1939. return(iStat);
  1940. /*
  1941. * Post Read for status.
  1942. */
  1943. if ( (iStat = PostStatusRead()) != -1 )
  1944. return(iStat);
  1945. /*
  1946. * Loop till exit requested.
  1947. */
  1948. for ( ; ; ) {
  1949. /*
  1950. * Wait for either input data or an comm status event.
  1951. */
  1952. hWait[0] = m_OverlapRead.hEvent;
  1953. hWait[1] = m_OverlapSignal.hEvent;
  1954. ODS( L"CATDlgInputThread::RunThread waiting on either event to be signaled\n");
  1955. Status = WaitForMultipleObjects(2, hWait, FALSE, INFINITE);
  1956. /*
  1957. * Check for exit.
  1958. */
  1959. if ( m_bExit )
  1960. {
  1961. ODS( L"CATDlgInputThread::RunThread exiting\n" );
  1962. return(0);
  1963. }
  1964. if ( Status == WAIT_OBJECT_0 ) {
  1965. /*
  1966. * Read event:
  1967. * Get result of overlapped read.
  1968. */
  1969. ODS(L"CATDlgInputThread::RunThread Read event signaled\n" );
  1970. if ( !GetOverlappedResult( m_hDevice,
  1971. &m_OverlapRead,
  1972. &m_BufferBytes,
  1973. TRUE ) ) {
  1974. NotifyAbort(IDP_ERROR_GET_OVERLAPPED_RESULT_READ);
  1975. return(1);
  1976. }
  1977. /*
  1978. * Notify dialog.
  1979. */
  1980. if ( (iStat = CommInputNotify()) != -1 )
  1981. return(iStat);
  1982. /*
  1983. * Post Read for input data.
  1984. */
  1985. if ( (iStat = PostInputRead()) != -1 )
  1986. return(iStat);
  1987. } else if ( Status == WAIT_OBJECT_0+1 ) {
  1988. ODS(L"CATDlgInputThread::RunThread Signal event signaled\n" );
  1989. /*
  1990. * Comm status event:
  1991. * Query comm status and notify dialog.
  1992. */
  1993. if ( (iStat = CommStatusAndNotify()) != -1 )
  1994. return(iStat);
  1995. /*
  1996. * Post Read for status.
  1997. */
  1998. if ( (iStat = PostStatusRead()) != -1 )
  1999. return(iStat);
  2000. } else {
  2001. /*
  2002. * Unknown event: Abort.
  2003. */
  2004. NotifyAbort(IDP_ERROR_WAIT_FOR_MULTIPLE_OBJECTS);
  2005. return(1);
  2006. }
  2007. }
  2008. } // end CATDlgInputThread::RunThread
  2009. ////////////////////////////////////////////////////////////////////////////////
  2010. // CATDlgInputThread operations: primary thread
  2011. /*******************************************************************************
  2012. *
  2013. * SignalConsumed - CATDlgInputThread member function: public operation
  2014. *
  2015. * Release the m_hConsumed semaphore to allow secondary thread to continue
  2016. * running.
  2017. *
  2018. * ENTRY:
  2019. * EXIT:
  2020. *
  2021. ******************************************************************************/
  2022. void
  2023. CATDlgInputThread::SignalConsumed()
  2024. {
  2025. ReleaseSemaphore( m_hConsumed, 1, NULL );
  2026. } // end CATDlgInputThread::SignalConsumed
  2027. /*******************************************************************************
  2028. *
  2029. * ExitThread - CATDlgInputThread member function: public operation
  2030. *
  2031. * Tell the secondary thread to exit and cleanup after.
  2032. *
  2033. * ENTRY:
  2034. * EXIT:
  2035. *
  2036. ******************************************************************************/
  2037. void
  2038. CATDlgInputThread::ExitThread()
  2039. {
  2040. DWORD dwReturnCode;
  2041. int i;
  2042. // CWaitCursor wait;
  2043. /*
  2044. * If the thread was not created properly, just delete object and return.
  2045. */
  2046. if ( !m_hThread ) {
  2047. delete this;
  2048. return;
  2049. }
  2050. /*
  2051. * Set the m_bExit flag to TRUE, wake up the run thread's WaitCommEvent() by
  2052. * resetting device's Comm mask, and bump the consumed semaphore to assure exit.
  2053. */
  2054. m_bExit = TRUE;
  2055. SetCommMask(m_hDevice, 0);
  2056. SignalConsumed();
  2057. /*
  2058. * Purge the recieve buffer and any pending read.
  2059. */
  2060. PurgeComm(m_hDevice, PURGE_RXABORT | PURGE_RXCLEAR);
  2061. /*
  2062. * Wait a while for the thread to exit.
  2063. */
  2064. for ( i = 0, GetExitCodeThread( m_hThread, &dwReturnCode );
  2065. (i < MAX_SLEEP_COUNT) && (dwReturnCode == STILL_ACTIVE); i++ ) {
  2066. Sleep(100);
  2067. GetExitCodeThread( m_hThread, &dwReturnCode );
  2068. }
  2069. /*
  2070. * If the thread has still not exited, terminate it.
  2071. */
  2072. if( dwReturnCode == STILL_ACTIVE )
  2073. {
  2074. TerminateThread( m_hThread, 1 );
  2075. ODS( L"Thread terminated irregularly\n" );
  2076. }
  2077. /*
  2078. * Close the thread handle and delete this CATDlgInputThread object
  2079. */
  2080. CloseHandle( m_hThread );
  2081. delete this;
  2082. } // end CATDlgInputThread::ExitThread
  2083. ////////////////////////////////////////////////////////////////////////////////
  2084. // CATDlgInputThread operations: secondary thread
  2085. /*******************************************************************************
  2086. *
  2087. * NotifyAbort - CATDlgInputThread member function: private operation
  2088. * (SECONDARY THREAD)
  2089. *
  2090. * Notify the dialog of thread abort and reason.
  2091. *
  2092. * ENTRY:
  2093. * idError (input)
  2094. * Resource id for error message.
  2095. * EXIT:
  2096. *
  2097. ******************************************************************************/
  2098. void
  2099. CATDlgInputThread::NotifyAbort(UINT idError )
  2100. {
  2101. TCHAR tchErrTitle[ 80 ];
  2102. TCHAR tchErrMsg[ 256 ];
  2103. //::PostMessage(m_hDlg, WM_ASYNCTESTABORT, idError, GetLastError());
  2104. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) );
  2105. LoadString( _Module.GetResourceInstance( ) , idError , tchErrMsg , SIZE_OF_BUFFER( tchErrMsg ) );
  2106. MessageBox( m_hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );
  2107. } // end CATDlgInputThread::NotifyAbort
  2108. /*******************************************************************************
  2109. *
  2110. * CommInputNotify - CATDlgInputThread member function: private operation
  2111. * (SECONDARY THREAD)
  2112. *
  2113. * Notify the dialog of comm input.
  2114. *
  2115. * ENTRY:
  2116. * EXIT:
  2117. * -1 no error and continue thread
  2118. * 0 if ExitThread was requested by parent
  2119. *
  2120. ******************************************************************************/
  2121. int
  2122. CATDlgInputThread::CommInputNotify()
  2123. {
  2124. /*
  2125. * Tell the dialog that we've got some new input.
  2126. */
  2127. ::PostMessage(m_hDlg, WM_ASYNCTESTINPUTREADY, 0, 0);
  2128. ODS( L"TSCC:CATDlgInputThread::CommInputNotify WM_ASYNCTESTINPUTREADY (P)\n" );
  2129. ODS( L"TSCC:CATDlgInputThread::CommInputNotify waiting on semaphore\n" );
  2130. WaitForSingleObject(m_hConsumed, INFINITE);
  2131. ODS( L"TSCC:CATDlgInputThread::CommInputNotify semaphore signaled\n" );
  2132. /*
  2133. * Check for thread exit request.
  2134. */
  2135. if ( m_bExit )
  2136. return(0);
  2137. else
  2138. return(-1);
  2139. } // end CATDlgInputThread::CommInputNotify
  2140. /*******************************************************************************
  2141. *
  2142. * CommStatusAndNotify - CATDlgInputThread member function: private operation
  2143. * (SECONDARY THREAD)
  2144. *
  2145. * Read the comm port status and notify dialog.
  2146. *
  2147. * ENTRY:
  2148. * EXIT:
  2149. * -1 no error and continue thread
  2150. * 0 if ExitThread was requested by parent
  2151. * 1 error condition
  2152. *
  2153. ******************************************************************************/
  2154. int
  2155. CATDlgInputThread::CommStatusAndNotify()
  2156. {
  2157. PFLOWCONTROLCONFIG pFlow = NULL;
  2158. DWORD ModemStatus = 0;
  2159. DWORD Error = 0;
  2160. if ( !GetCommModemStatus(m_hDevice, &ModemStatus) ) {
  2161. /*
  2162. * We can't query the comm information; tell the primary thread
  2163. * that we've aborted, and return error (will exit thread).
  2164. */
  2165. NotifyAbort(IDP_ERROR_GET_COMM_MODEM_STATUS);
  2166. return(1);
  2167. }
  2168. /*
  2169. * Update modem status
  2170. */
  2171. m_Status.AsyncSignal = ModemStatus;
  2172. /*
  2173. * Or in status of DTR and RTS
  2174. */
  2175. // pFlow = &m_PdConfig.Params.Async.FlowControl;
  2176. pFlow = &m_ac.FlowControl;
  2177. if ( pFlow->fEnableDTR )
  2178. m_Status.AsyncSignal |= MS_DTR_ON;
  2179. if ( pFlow->fEnableRTS )
  2180. m_Status.AsyncSignal |= MS_RTS_ON;
  2181. /*
  2182. * OR in new event mask
  2183. */
  2184. m_Status.AsyncSignalMask |= m_EventMask;
  2185. /*
  2186. * Update async error counters
  2187. */
  2188. if ( m_EventMask & EV_ERR ) {
  2189. (VOID) ClearCommError( m_hDevice, &Error, NULL );
  2190. if ( Error & CE_OVERRUN )
  2191. m_Status.Output.AsyncOverrunError++;
  2192. if ( Error & CE_FRAME )
  2193. m_Status.Input.AsyncFramingError++;
  2194. if ( Error & CE_RXOVER )
  2195. m_Status.Input.AsyncOverflowError++;
  2196. if ( Error & CE_RXPARITY )
  2197. m_Status.Input.AsyncParityError++;
  2198. }
  2199. /*
  2200. * Tell the dialog that we've got some new status information.
  2201. */
  2202. ::PostMessage(m_hDlg, WM_ASYNCTESTSTATUSREADY, 0, 0);
  2203. ODS( L"TSCC:CATDlgInputThread::CommStatusAndNotify WM_ASYNCTESTSTATUSREADY( P )\n");
  2204. ODS( L"TSCC:CATDlgInputThread::CommStatusAndNotify waiting on semaphore\n" );
  2205. WaitForSingleObject(m_hConsumed, INFINITE);
  2206. ODS( L"TSCC:CATDlgInputThread::CommStatusAndNotify semaphore signaled\n" );
  2207. /*
  2208. * Check for thread exit request.
  2209. */
  2210. if ( m_bExit )
  2211. return(0);
  2212. else
  2213. return(-1);
  2214. } // end CATDlgInputThread::CommStatusAndNotify
  2215. /*******************************************************************************
  2216. *
  2217. * PostInputRead - CATDlgInputThread member function: private operation
  2218. * (SECONDARY THREAD)
  2219. *
  2220. * Post a ReadFile operation for the device, processing as long as data
  2221. * is present.
  2222. *
  2223. * ENTRY:
  2224. * EXIT:
  2225. * -1 if read operation posted sucessfully
  2226. * 0 if ExitThread was requested by parent
  2227. * 1 if error condition
  2228. *
  2229. ******************************************************************************/
  2230. int
  2231. CATDlgInputThread::PostInputRead()
  2232. {
  2233. int iStat;
  2234. // TCHAR tchErrTitle[ 80 ];
  2235. // TCHAR tchErrMsg[ 256 ];
  2236. ODS(L"TSCC:CATDlgInputThread::PostInputRead\n");
  2237. /*
  2238. * Post read for input data, processing immediataly if not 'pending'.
  2239. */
  2240. while ( ReadFile( m_hDevice, m_Buffer, MAX_COMMAND_LEN,
  2241. &m_BufferBytes, &m_OverlapRead ) )
  2242. {
  2243. DBGMSG( L"Buffer received %s\n",m_Buffer );
  2244. if ( (iStat = CommInputNotify()) != -1 )
  2245. return(iStat);
  2246. }
  2247. /*
  2248. * Make sure read is pending (not some other error).
  2249. */
  2250. if ( GetLastError() != ERROR_IO_PENDING )
  2251. {
  2252. DBGMSG( L"ReadFile returned 0x%x\n" , GetLastError() );
  2253. NotifyAbort(IDP_ERROR_READ_FILE);
  2254. /* LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , sizeof( tchErrTitle ) );
  2255. LoadString( _Module.GetResourceInstance( ) , IDP_ERROR_READ_FILE , tchErrMsg , sizeof( tchErrMsg ) );
  2256. MessageBox( m_hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );*/
  2257. EndDialog(m_hDlg, IDCANCEL);
  2258. return(1);
  2259. }
  2260. /*
  2261. * Return 'posted sucessfully' status.
  2262. */
  2263. return(-1);
  2264. } // end CATDlgInputThread::PostInputRead
  2265. /*******************************************************************************
  2266. *
  2267. * PostStatusRead - CATDlgInputThread member function: private operation
  2268. * (SECONDARY THREAD)
  2269. *
  2270. * Post a WaitCommStatus operation for the device.
  2271. *
  2272. * ENTRY:
  2273. * EXIT:
  2274. * -1 if status operation posted sucessfully
  2275. * 1 if error condition
  2276. *
  2277. ******************************************************************************/
  2278. int
  2279. CATDlgInputThread::PostStatusRead()
  2280. {
  2281. /*
  2282. * Post read for comm status.
  2283. */
  2284. ODS( L"CATDlgInputThread::PostStatusRead\n");
  2285. if ( !WaitCommEvent(m_hDevice, &m_EventMask, &m_OverlapSignal) ) {
  2286. /*
  2287. * Make sure comm status read is pending (not some other error).
  2288. */
  2289. if ( GetLastError() != ERROR_IO_PENDING ) {
  2290. NotifyAbort(IDP_ERROR_WAIT_COMM_EVENT);
  2291. return(1);
  2292. }
  2293. }
  2294. /*
  2295. * Return 'posted sucessfully' status.
  2296. */
  2297. return(-1);
  2298. } // end CATDlgInputThread::PostStatusRead
  2299. ////////////////////////////////////////////////////////////////////////////////
  2300. ///////////////////////////////////////////////////////////////////////////////
  2301. // CAsyncTestDlg class construction / destruction, implementation
  2302. /*******************************************************************************
  2303. *
  2304. * CAsyncTestDlg - CAsyncTestDlg constructor
  2305. *
  2306. * ENTRY:
  2307. * EXIT:
  2308. * (Refer to MFC CDialog::CDialog documentation)
  2309. *
  2310. ******************************************************************************/
  2311. CAsyncTestDlg::CAsyncTestDlg(ICfgComp * pCfgComp) :
  2312. m_hDevice(INVALID_HANDLE_VALUE),
  2313. m_hRedBrush(NULL),
  2314. m_LEDToggleTimer(0),
  2315. m_pATDlgInputThread(NULL),
  2316. m_CurrentPos(0),
  2317. m_hModem(NULL),
  2318. m_bDeletedWinStation(FALSE)
  2319. {
  2320. /*
  2321. * Create a solid RED brush for painting the 'LED's when 'on'.
  2322. */
  2323. m_hRedBrush = CreateSolidBrush( RGB( 255 , 0 , 0 ) );
  2324. /*
  2325. * Initialize member variables.
  2326. */
  2327. FillMemory( &m_Status , sizeof( PROTOCOLSTATUS ) , 0 );
  2328. FillMemory( &m_OverlapWrite , sizeof( OVERLAPPED ) , 0 );
  2329. /*
  2330. * Create the led objects.
  2331. */
  2332. for( int i = 0 ; i < NUM_LEDS ; i++ )
  2333. {
  2334. m_pLeds[i] = new CLed(m_hRedBrush);
  2335. }
  2336. m_pCfgComp = pCfgComp;
  2337. if( pCfgComp != NULL )
  2338. {
  2339. m_pCfgComp->AddRef();
  2340. }
  2341. } // end CAsyncTestDlg::CAsyncTestDlg
  2342. /*******************************************************************************
  2343. *
  2344. * ~CAsyncTestDlg - CAsyncTestDlg destructor
  2345. *
  2346. * ENTRY:
  2347. * EXIT:
  2348. * (Refer to MFC CDialog::~CDialog documentation)
  2349. *
  2350. ******************************************************************************/
  2351. CAsyncTestDlg::~CAsyncTestDlg()
  2352. {
  2353. /*
  2354. * Zap our led objects.
  2355. */
  2356. for( int i = 0; i < NUM_LEDS; i++ )
  2357. {
  2358. if( m_pLeds[i] != NULL )
  2359. {
  2360. delete m_pLeds[i];
  2361. }
  2362. }
  2363. if(m_pCfgComp != NULL )
  2364. {
  2365. m_pCfgComp->Release();
  2366. }
  2367. } // end CAsyncTestDlg::~CAsyncTestDlg
  2368. ////////////////////////////////////////////////////////////////////////////////
  2369. // CAsyncTestDlg operations
  2370. /*******************************************************************************
  2371. *
  2372. * NotifyAbort - CAsyncTestDlg member function: private operation
  2373. *
  2374. * Post a WM_ASYNCTESTABORT message to notify the dialog of
  2375. * abort and reason.
  2376. *
  2377. * ENTRY:
  2378. * idError (input)
  2379. * Resource id for error message.
  2380. * EXIT:
  2381. *
  2382. ******************************************************************************/
  2383. void CAsyncTestDlg::NotifyAbort( UINT idError )
  2384. {
  2385. TCHAR tchErrTitle[ 80 ];
  2386. TCHAR tchErrMsg[ 256 ];
  2387. LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) );
  2388. LoadString( _Module.GetResourceInstance( ) , idError , tchErrMsg , SIZE_OF_BUFFER( tchErrMsg ) );
  2389. MessageBox( m_hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );
  2390. } // end CAsyncTestDlg::NotifyAbort
  2391. /*******************************************************************************
  2392. *
  2393. * DeviceSetParams - CAsyncTestDlg member function: private operation
  2394. *
  2395. * Set device parameters for opened device.
  2396. *
  2397. * ENTRY:
  2398. * EXIT:
  2399. * TRUE - no error; FALSE error.
  2400. *
  2401. ******************************************************************************/
  2402. BOOL CAsyncTestDlg::DeviceSetParams()
  2403. {
  2404. PASYNCCONFIG pAsync;
  2405. PFLOWCONTROLCONFIG pFlow;
  2406. DCB Dcb;
  2407. /*
  2408. * Get pointer to async parameters
  2409. */
  2410. // pAsync = &m_PdConfig0.Params.Async;
  2411. pAsync = &m_ac;
  2412. /*
  2413. * Get current DCB
  2414. */
  2415. if( !GetCommState( m_hDevice, &Dcb ) )
  2416. {
  2417. return(FALSE);
  2418. }
  2419. /*
  2420. * Set defaults
  2421. */
  2422. Dcb.fOutxCtsFlow = FALSE;
  2423. Dcb.fOutxDsrFlow = FALSE;
  2424. Dcb.fTXContinueOnXoff = TRUE;
  2425. Dcb.fOutX = FALSE;
  2426. Dcb.fInX = FALSE;
  2427. Dcb.fErrorChar = FALSE;
  2428. Dcb.fNull = FALSE;
  2429. Dcb.fAbortOnError = FALSE;
  2430. /*
  2431. * Set Communication parameters
  2432. */
  2433. Dcb.BaudRate = pAsync->BaudRate;
  2434. Dcb.Parity = (BYTE) pAsync->Parity;
  2435. Dcb.StopBits = (BYTE) pAsync->StopBits;
  2436. Dcb.ByteSize = (BYTE) pAsync->ByteSize;
  2437. Dcb.fDsrSensitivity = pAsync->fEnableDsrSensitivity;
  2438. pFlow = &pAsync->FlowControl;
  2439. /*
  2440. * Initialize default DTR state
  2441. */
  2442. if ( pFlow->fEnableDTR )
  2443. Dcb.fDtrControl = DTR_CONTROL_ENABLE;
  2444. else
  2445. Dcb.fDtrControl = DTR_CONTROL_DISABLE;
  2446. /*
  2447. * Initialize default RTS state
  2448. */
  2449. if ( pFlow->fEnableRTS )
  2450. Dcb.fRtsControl = RTS_CONTROL_ENABLE;
  2451. else
  2452. Dcb.fRtsControl = RTS_CONTROL_DISABLE;
  2453. /*
  2454. * Initialize flow control
  2455. */
  2456. switch ( pFlow->Type ) {
  2457. /*
  2458. * Initialize hardware flow control
  2459. */
  2460. case FlowControl_Hardware :
  2461. switch ( pFlow->HardwareReceive ) {
  2462. case ReceiveFlowControl_RTS :
  2463. Dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  2464. break;
  2465. case ReceiveFlowControl_DTR :
  2466. Dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
  2467. break;
  2468. }
  2469. switch ( pFlow->HardwareTransmit ) {
  2470. case TransmitFlowControl_CTS :
  2471. Dcb.fOutxCtsFlow = TRUE;
  2472. break;
  2473. case TransmitFlowControl_DSR :
  2474. Dcb.fOutxDsrFlow = TRUE;
  2475. break;
  2476. }
  2477. break;
  2478. /*
  2479. * Initialize software flow control
  2480. */
  2481. case FlowControl_Software :
  2482. Dcb.fOutX = pFlow->fEnableSoftwareTx;
  2483. Dcb.fInX = pFlow->fEnableSoftwareRx;
  2484. Dcb.XonChar = (char) pFlow->XonChar;
  2485. Dcb.XoffChar = (char) pFlow->XoffChar;
  2486. break;
  2487. case FlowControl_None :
  2488. break;
  2489. }
  2490. /*
  2491. * Set new DCB
  2492. */
  2493. if ( !SetCommState( m_hDevice, &Dcb ) )
  2494. return(FALSE);
  2495. return( TRUE );
  2496. } // end CAsyncTestDlg::DeviceSetParams
  2497. /*******************************************************************************
  2498. *
  2499. * DeviceWrite - CAsyncTestDlg member function: private operation
  2500. *
  2501. * Write out m_Buffer contents (m_BufferBytes length) to the m_hDevice.
  2502. *
  2503. * ENTRY:
  2504. * EXIT:
  2505. * TRUE - no error; FALSE error.
  2506. *
  2507. ******************************************************************************/
  2508. BOOL CAsyncTestDlg::DeviceWrite()
  2509. {
  2510. DWORD Error, BytesWritten;
  2511. /*
  2512. * Write data
  2513. */
  2514. ODS( L"TSCC:CAsyncTestDlg::DeviceWrite Writing out to buffer\n" );
  2515. if ( !WriteFile( m_hDevice, m_Buffer, m_BufferBytes,
  2516. &BytesWritten, &m_OverlapWrite ) )
  2517. {
  2518. DBGMSG( L"TSCC:CAsyncTestDlg::DeviceWrite WriteFile returned 0x%x\n" , GetLastError() );
  2519. if ( (Error = GetLastError()) == ERROR_IO_PENDING )
  2520. {
  2521. /*
  2522. * Wait for write to complete (this may block till timeout)
  2523. */
  2524. if ( !GetOverlappedResult( m_hDevice, &m_OverlapWrite,
  2525. &BytesWritten, TRUE ) )
  2526. {
  2527. CancelIo( m_hDevice );
  2528. NotifyAbort(IDP_ERROR_GET_OVERLAPPED_RESULT_WRITE);
  2529. return(FALSE);
  2530. }
  2531. } else {
  2532. NotifyAbort(IDP_ERROR_WRITE_FILE);
  2533. return(FALSE);
  2534. }
  2535. }
  2536. return(TRUE);
  2537. } // end CAsyncTestDlg::DeviceWrite
  2538. //---------------------------------------------------------------------
  2539. cwnd * CAsyncTestDlg::GetDlgItem( int nRes )
  2540. {
  2541. HWND hCtrl = ::GetDlgItem( m_hDlg , nRes );
  2542. for( int i = 0; i < NUM_LEDS; i++ )
  2543. {
  2544. if( m_pLeds[ i ] != NULL )
  2545. {
  2546. if( m_pLeds[ i ]->m_hWnd == hCtrl )
  2547. {
  2548. return m_pLeds[ i ];
  2549. }
  2550. }
  2551. }
  2552. return 0;
  2553. }
  2554. /*******************************************************************************
  2555. *
  2556. * SetInfoFields - CAsyncTestDlg member function: private operation
  2557. *
  2558. * Update the fields in the dialog with new data, if necessary.
  2559. *
  2560. * ENTRY:
  2561. * pCurrent (input)
  2562. * points to COMMINFO structure containing the current Comm Input data.
  2563. * pNew (input)
  2564. * points to COMMINFO structure containing the new Comm Input data.
  2565. *
  2566. * EXIT:
  2567. *
  2568. ******************************************************************************/
  2569. void CAsyncTestDlg::SetInfoFields( PPROTOCOLSTATUS pCurrent , PPROTOCOLSTATUS pNew )
  2570. {
  2571. BOOL bSetTimer = FALSE;
  2572. /*
  2573. * Set new LED states if state change, or set up for quick toggle if
  2574. * no state changed, but change(s) were detected since last query.
  2575. */
  2576. if( ( pCurrent->AsyncSignal & MS_DTR_ON ) != ( pNew->AsyncSignal & MS_DTR_ON ) )
  2577. {
  2578. pNew->AsyncSignalMask &= ~EV_DTR;
  2579. ((CLed *)GetDlgItem(IDC_ATDLG_DTR))->Update(pNew->AsyncSignal & MS_DTR_ON);
  2580. } else if ( pNew->AsyncSignalMask & EV_DTR ) {
  2581. pCurrent->AsyncSignal ^= MS_DTR_ON;
  2582. ((CLed *)GetDlgItem(IDC_ATDLG_DTR))->Toggle();
  2583. bSetTimer = TRUE;
  2584. }
  2585. if ( (pCurrent->AsyncSignal & MS_RTS_ON) !=
  2586. (pNew->AsyncSignal & MS_RTS_ON) ) {
  2587. pNew->AsyncSignalMask &= ~EV_RTS;
  2588. ((CLed *)GetDlgItem(IDC_ATDLG_RTS))->
  2589. Update(pNew->AsyncSignal & MS_RTS_ON);
  2590. } else if ( pNew->AsyncSignalMask & EV_RTS ) {
  2591. pCurrent->AsyncSignal ^= MS_RTS_ON;
  2592. ((CLed *)GetDlgItem(IDC_ATDLG_RTS))->Toggle();
  2593. bSetTimer = TRUE;
  2594. }
  2595. if ( (pCurrent->AsyncSignal & MS_CTS_ON) !=
  2596. (pNew->AsyncSignal & MS_CTS_ON) ) {
  2597. pNew->AsyncSignalMask &= ~EV_CTS;
  2598. ((CLed *)GetDlgItem(IDC_ATDLG_CTS))->
  2599. Update(pNew->AsyncSignal & MS_CTS_ON);
  2600. } else if ( pNew->AsyncSignalMask & EV_CTS ) {
  2601. pCurrent->AsyncSignal ^= MS_CTS_ON;
  2602. ((CLed *)GetDlgItem(IDC_ATDLG_CTS))->Toggle();
  2603. bSetTimer = TRUE;
  2604. }
  2605. if ( (pCurrent->AsyncSignal & MS_RLSD_ON) !=
  2606. (pNew->AsyncSignal & MS_RLSD_ON) ) {
  2607. pNew->AsyncSignalMask &= ~EV_RLSD;
  2608. ((CLed *)GetDlgItem(IDC_ATDLG_DCD))->
  2609. Update(pNew->AsyncSignal & MS_RLSD_ON);
  2610. } else if ( pNew->AsyncSignalMask & EV_RLSD ) {
  2611. pCurrent->AsyncSignal ^= MS_RLSD_ON;
  2612. ((CLed *)GetDlgItem(IDC_ATDLG_DCD))->Toggle();
  2613. bSetTimer = TRUE;
  2614. }
  2615. if ( (pCurrent->AsyncSignal & MS_DSR_ON) !=
  2616. (pNew->AsyncSignal & MS_DSR_ON) ) {
  2617. pNew->AsyncSignalMask &= ~EV_DSR;
  2618. ((CLed *)GetDlgItem(IDC_ATDLG_DSR))->
  2619. Update(pNew->AsyncSignal & MS_DSR_ON);
  2620. } else if ( pNew->AsyncSignalMask & EV_DSR ) {
  2621. pCurrent->AsyncSignal ^= MS_DSR_ON;
  2622. ((CLed *)GetDlgItem(IDC_ATDLG_DSR))->Toggle();
  2623. bSetTimer = TRUE;
  2624. }
  2625. if ( (pCurrent->AsyncSignal & MS_RING_ON) !=
  2626. (pNew->AsyncSignal & MS_RING_ON) ) {
  2627. pNew->AsyncSignalMask &= ~EV_RING;
  2628. ((CLed *)GetDlgItem(IDC_ATDLG_RI))->
  2629. Update(pNew->AsyncSignal & MS_RING_ON);
  2630. } else if ( pNew->AsyncSignalMask & EV_RING ) {
  2631. pCurrent->AsyncSignal ^= MS_RING_ON;
  2632. ((CLed *)GetDlgItem(IDC_ATDLG_RI))->Toggle();
  2633. bSetTimer = TRUE;
  2634. }
  2635. /*
  2636. * Create our led toggle timer if needed.
  2637. */
  2638. if ( bSetTimer && !m_LEDToggleTimer )
  2639. {
  2640. m_LEDToggleTimer = SetTimer( m_hDlg , IDD_ASYNC_TEST , ASYNC_LED_TOGGLE_MSEC, NULL );
  2641. }
  2642. } // end CAsyncTestDlg::SetInfoFields
  2643. ////////////////////////////////////////////////////////////////////////////////
  2644. // CAsyncTestDlg message map
  2645. BOOL CAsyncTestDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl )
  2646. {
  2647. if( wNotifyCode == BN_CLICKED )
  2648. {
  2649. if( wID == IDC_ATDLG_MODEM_DIAL )
  2650. {
  2651. OnClickedAtdlgModemDial( );
  2652. }
  2653. else if( wID == IDC_ATDLG_MODEM_INIT )
  2654. {
  2655. OnClickedAtdlgModemInit( );
  2656. }
  2657. else if( wID == IDC_ATDLG_MODEM_LISTEN )
  2658. {
  2659. OnClickedAtdlgModemListen( );
  2660. }
  2661. else if( wID == IDOK )
  2662. {
  2663. EndDialog( m_hDlg , IDOK );
  2664. }
  2665. else if( wID == IDCANCEL )
  2666. {
  2667. EndDialog( m_hDlg , IDCANCEL );
  2668. }
  2669. else if( wID == ID_HELP )
  2670. {
  2671. TCHAR tchHelpFile[ MAX_PATH ];
  2672. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ASYNC_HELPFILE , tchHelpFile , SIZE_OF_BUFFER( tchHelpFile ) ) );
  2673. WinHelp( GetParent( hwndCtrl ) , tchHelpFile , HELP_CONTEXT , HID_ASYNCTEST );
  2674. }
  2675. }
  2676. return TRUE;
  2677. }
  2678. ////////////////////////////////////////////////////////////////////////////////
  2679. // CAsyncTestDlg commands
  2680. /*******************************************************************************
  2681. *
  2682. * OnInitDialog - CAsyncTestDlg member function: command (override)
  2683. *
  2684. * Performs the dialog intialization.
  2685. *
  2686. * ENTRY:
  2687. * EXIT:
  2688. * (Refer to CDialog::OnInitDialog documentation)
  2689. * WM_ASYNCTESTABORT message(s) will have been posted on error.
  2690. *
  2691. ******************************************************************************/
  2692. BOOL CAsyncTestDlg::OnInitDialog( HWND hDlg , WPARAM wp , LPARAM lp )
  2693. {
  2694. UNREFERENCED_PARAMETER( wp );
  2695. UNREFERENCED_PARAMETER( lp );
  2696. int i;
  2697. DEVICENAME DeviceName;
  2698. COMMTIMEOUTS CommTimeouts;
  2699. TCHAR tchErrTitle[ 80 ];
  2700. TCHAR tchErrMsg[ 256 ];
  2701. m_hDlg = hDlg;
  2702. //#ifdef WINSTA
  2703. ULONG LogonId;
  2704. //#endif // WINSTA
  2705. /*
  2706. * Fill in the device and baud fields.
  2707. */
  2708. SetDlgItemText( hDlg , IDL_ATDLG_DEVICE , m_ac.DeviceName );
  2709. SetDlgItemInt( hDlg , IDL_ATDLG_BAUD , m_ac.BaudRate , FALSE );
  2710. /*
  2711. * If a WinStation memory object is currently present, reset it.
  2712. */
  2713. //#ifdef WINSTA
  2714. if ( m_pWSName != NULL ) //&& LogonIdFromWinStationName( SERVERNAME_CURRENT , m_pWSName , &LogonId ) )
  2715. {
  2716. LONG Status;
  2717. ULONG Length;
  2718. LONG lCount = 0;
  2719. TCHAR tchbuf[ 256 ];
  2720. if( m_pCfgComp != NULL )
  2721. {
  2722. ODS( L"TSCC : Testing for live connections\n" );
  2723. m_pCfgComp->QueryLoggedOnCount( m_pWSName,&lCount);
  2724. if( lCount )
  2725. {
  2726. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WRN_TSTCON , tchbuf , SIZE_OF_BUFFER( tchbuf ) ) );
  2727. wsprintf( tchErrMsg , tchbuf , m_pWSName);
  2728. VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) ) );
  2729. if( MessageBox( hDlg , tchbuf , tchErrTitle , MB_YESNO | MB_ICONEXCLAMATION ) == IDNO )
  2730. {
  2731. PostMessage( hDlg , WM_COMMAND , MAKEWPARAM( IDOK, BN_CLICKED ) , (LPARAM)(::GetDlgItem( hDlg , IDOK ) ) );
  2732. return(TRUE); // exit dialog via posted 'OK' click
  2733. }
  2734. }
  2735. }
  2736. Status = RegWinStationQuery( SERVERNAME_CURRENT,
  2737. m_pWSName,
  2738. &m_WSConfig,
  2739. sizeof(WINSTATIONCONFIG2),
  2740. &Length );
  2741. if(Status)
  2742. {
  2743. NotifyAbort(IDP_ERROR_DISABLE);
  2744. return(TRUE);
  2745. }
  2746. m_WSConfig.Create.fEnableWinStation = FALSE;
  2747. Status = RegWinStationCreate( SERVERNAME_CURRENT,
  2748. m_pWSName,
  2749. FALSE,
  2750. &m_WSConfig,
  2751. sizeof(WINSTATIONCONFIG2 ) ) ;
  2752. if(Status)
  2753. {
  2754. NotifyAbort(IDP_ERROR_DISABLE);
  2755. return(TRUE);
  2756. }
  2757. /*
  2758. * Do the reset. If, for some reason, the reset was unsucessful,
  2759. * the device open will fail (below).
  2760. */
  2761. // CWaitCursor wait;
  2762. if( LogonIdFromWinStationName( SERVERNAME_CURRENT , m_pWSName , &LogonId ) )
  2763. {
  2764. BOOL b = ( BOOL )WinStationReset(SERVERNAME_CURRENT, LogonId, TRUE);
  2765. DBGMSG( L"TSCC:CAsyncTestDlg::OnInitDialog WinStationReset returned %s\n", b ? L"TRUE" : L"FALSE" );
  2766. //m_bDeletedWinStation = TRUE;
  2767. }
  2768. m_bDeletedWinStation = TRUE;
  2769. }
  2770. //#endif // WINSTA
  2771. /*
  2772. * Open the specified device.
  2773. */
  2774. lstrcpy( DeviceName, TEXT("\\\\.\\") );
  2775. // lstrcat( DeviceName, m_PdConfig0.Params.Async.DeviceName );
  2776. lstrcat( DeviceName, m_ac.DeviceName );
  2777. if( ( m_hDevice = CreateFile( DeviceName,
  2778. GENERIC_READ | GENERIC_WRITE,
  2779. 0, // exclusive access
  2780. NULL, // no security attr
  2781. OPEN_EXISTING, // must exist
  2782. FILE_FLAG_OVERLAPPED,
  2783. NULL // no template
  2784. ) ) == INVALID_HANDLE_VALUE )
  2785. {
  2786. NotifyAbort(IDP_ERROR_CANT_OPEN_DEVICE);
  2787. /* LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , sizeof( tchErrTitle ) );
  2788. LoadString( _Module.GetResourceInstance( ) , IDP_ERROR_CANT_OPEN_DEVICE , tchErrMsg , sizeof( tchErrMsg ) );
  2789. MessageBox( hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );*/
  2790. return(FALSE);
  2791. }
  2792. /*
  2793. * Set device timeouts & communication parameters and create an event
  2794. * for overlapped writes.
  2795. */
  2796. FillMemory( &CommTimeouts , sizeof( COMMTIMEOUTS ) , 0 );
  2797. CommTimeouts.ReadIntervalTimeout = 1; // 1 msec
  2798. CommTimeouts.WriteTotalTimeoutConstant = 1000; // 1 second
  2799. m_OverlapWrite.hEvent = CreateEvent( NULL , TRUE , FALSE, NULL );
  2800. if( !SetCommTimeouts(m_hDevice, &CommTimeouts) || !DeviceSetParams() || m_OverlapWrite.hEvent == NULL )
  2801. {
  2802. NotifyAbort(IDP_ERROR_CANT_INITIALIZE_DEVICE);
  2803. ODS( L"IDP_ERROR_CANT_INITIALIZE_DEVICE\n" );
  2804. /* LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , sizeof( tchErrTitle ) );
  2805. LoadString( _Module.GetResourceInstance( ) , IDP_ERROR_CANT_INITIALIZE_DEVICE , tchErrMsg , sizeof( tchErrMsg ) );
  2806. MessageBox( hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );*/
  2807. return(TRUE);
  2808. }
  2809. /*
  2810. * Create the input thread object and initialize it's member variables.
  2811. */
  2812. m_pATDlgInputThread = new CATDlgInputThread;
  2813. m_pATDlgInputThread->m_hDlg = m_hDlg;
  2814. m_pATDlgInputThread->m_hDevice = m_hDevice;
  2815. // m_pATDlgInputThread->m_PdConfig = m_PdConfig0;
  2816. m_pATDlgInputThread->m_ac = m_ac;
  2817. if( !m_pATDlgInputThread->CreateThread() )
  2818. {
  2819. NotifyAbort(IDP_ERROR_CANT_CREATE_INPUT_THREAD);
  2820. ODS( L"IDP_ERROR_CANT_CREATE_INPUT_THREAD\n" );
  2821. return(TRUE);
  2822. }
  2823. /*
  2824. * Hide the modem string buttons if a modem is not configured, or disable
  2825. * buttons that are not valid.
  2826. */
  2827. for( int id = IDC_ATDLG_MODEM_INIT ; id <= IDC_ATDLG_PHONE_NUMBER ; id++ )
  2828. {
  2829. EnableWindow( ::GetDlgItem( hDlg , id) , FALSE);
  2830. ShowWindow( ::GetDlgItem( hDlg , id) , SW_HIDE);
  2831. }
  2832. /*
  2833. * Subclass the edit field to pass messages to dialog first.
  2834. */
  2835. m_EditControl.m_hDlg = m_hDlg;
  2836. m_EditControl.m_bProcessingOutput = FALSE;
  2837. m_EditControl.SubclassDlgItem( hDlg , IDC_ATDLG_EDIT );
  2838. /*
  2839. * Determine the edit control's font and format offset metrics.
  2840. */
  2841. TEXTMETRIC tm;
  2842. RECT Rect;
  2843. HDC dc;
  2844. HFONT hFont , hOldFont;
  2845. dc = GetDC( m_EditControl.m_hWnd );
  2846. hFont = ( HFONT )SendMessage( m_EditControl.m_hWnd , WM_GETFONT , 0 , 0 );
  2847. hOldFont = ( HFONT )SelectObject( dc , hFont);
  2848. GetTextMetrics( dc , &tm );
  2849. SelectObject( dc , hOldFont);
  2850. ReleaseDC( m_EditControl.m_hWnd , dc );
  2851. m_EditControl.m_FontHeight = tm.tmHeight;
  2852. m_EditControl.m_FontWidth = tm.tmMaxCharWidth;
  2853. SendMessage( m_EditControl.m_hWnd , EM_GETRECT , 0 , ( LPARAM )&Rect );
  2854. m_EditControl.m_FormatOffsetY = Rect.top;
  2855. m_EditControl.m_FormatOffsetX = Rect.left;
  2856. /*
  2857. * Subclass the led controls and default to 'off'.
  2858. */
  2859. for( i = 0; i < NUM_LEDS; i++ )
  2860. {
  2861. m_pLeds[i]->Subclass( hDlg , LedIds[i] );
  2862. m_pLeds[i]->Update(0);
  2863. }
  2864. return ( TRUE );
  2865. } // end CAsyncTestDlg::OnInitDialog
  2866. /*******************************************************************************
  2867. *
  2868. * OnTimer - CAsyncTestDlg member function: command (override)
  2869. *
  2870. * Used for quick 'LED toggle'.
  2871. *
  2872. * ENTRY:
  2873. * EXIT:
  2874. * (Refer to CWnd::OnTimer documentation)
  2875. *
  2876. ******************************************************************************/
  2877. void CAsyncTestDlg::OnTimer(UINT nIDEvent)
  2878. {
  2879. /*
  2880. * Process this timer event if it it our 'LED toggle' event.
  2881. */
  2882. ODS( L"TSCC:CAsyncTestDlg::OnTimer \n" );
  2883. if( nIDEvent == m_LEDToggleTimer )
  2884. {
  2885. ODS( L"TSCC:CAsyncTestDlg::OnTimer hit event\n" );
  2886. /*
  2887. * Toggle each LED that is flagged as 'changed'.
  2888. */
  2889. ODS( L"TSCC:led toggle " );
  2890. if( m_Status.AsyncSignalMask & EV_DTR )
  2891. {
  2892. ODS( L"dtr\n");
  2893. ( ( CLed * )GetDlgItem( IDC_ATDLG_DTR ) )->Toggle();
  2894. }
  2895. if( m_Status.AsyncSignalMask & EV_RTS )
  2896. {
  2897. ODS(L"rts\n");
  2898. ( ( CLed * )GetDlgItem( IDC_ATDLG_RTS ) )->Toggle();
  2899. }
  2900. if( m_Status.AsyncSignalMask & EV_CTS )
  2901. {
  2902. ODS(L"cts\n");
  2903. ( ( CLed * )GetDlgItem( IDC_ATDLG_CTS ) )->Toggle();
  2904. }
  2905. if( m_Status.AsyncSignalMask & EV_RLSD )
  2906. {
  2907. ODS(L"rlsd\n");
  2908. ( ( CLed * )GetDlgItem( IDC_ATDLG_DCD ) )->Toggle();
  2909. }
  2910. if( m_Status.AsyncSignalMask & EV_DSR )
  2911. {
  2912. ODS(L"dsr\n");
  2913. ( ( CLed * )GetDlgItem( IDC_ATDLG_DSR ) )->Toggle();
  2914. }
  2915. if( m_Status.AsyncSignalMask & EV_RING )
  2916. {
  2917. ODS(L"ring\n" );
  2918. ( ( CLed * )GetDlgItem( IDC_ATDLG_RI ) )->Toggle();
  2919. }
  2920. /*
  2921. * Kill this timer event and indicate so.
  2922. */
  2923. KillTimer( m_hDlg , m_LEDToggleTimer );
  2924. m_LEDToggleTimer = 0;
  2925. }
  2926. } // end CAsyncTestDlg::OnTimer
  2927. /*******************************************************************************
  2928. *
  2929. * OnAsyncTestError - CAsyncTestDlg member function: command
  2930. *
  2931. * Handle the Async Test Dialog error conditions.
  2932. *
  2933. * ENTRY:
  2934. * wParam (input)
  2935. * Contains message ID for error.
  2936. * wLparam (input)
  2937. * Contains error code (GetLastError or API-specific return code)
  2938. * EXIT:
  2939. * (LRESULT) always returns 0 to indicate error handling complete.
  2940. *
  2941. ******************************************************************************/
  2942. /*#define STANDARD_ERROR_MESSAGE(x) { if ( 1 ) StandardErrorMessage x ; }
  2943. LRESULT
  2944. CAsyncTestDlg::OnAsyncTestError( WPARAM wParam, LPARAM lParam )
  2945. {
  2946. /*
  2947. * Handle special and default errors.
  2948. */
  2949. /*switch ( wParam )
  2950. {
  2951. case IDP_ERROR_MODEM_SET_INFO:
  2952. case IDP_ERROR_MODEM_GET_DIAL:
  2953. case IDP_ERROR_MODEM_GET_INIT:
  2954. case IDP_ERROR_MODEM_GET_LISTEN:
  2955. break;
  2956. case IDP_ERROR_DISABLE:
  2957. StandardErrorMessage( L"Test", (HWND)LOGONID_NONE, (HINSTANCE)lParam,
  2958. wParam, (UINT)m_pWSName,0 );
  2959. break;
  2960. default:
  2961. StandardErrorMessage( L"Test",(HWND) LOGONID_NONE, (HINSTANCE)lParam, (UINT)wParam, lParam,0);
  2962. break;
  2963. }
  2964. return(0);
  2965. } // end CAsyncTestDlg::OnAsyncTestError*/
  2966. /*******************************************************************************
  2967. *
  2968. * OnAsyncTestAbort - CAsyncTestDlg member function: command
  2969. *
  2970. * Handle the Async Test Dialog abort conditions.
  2971. *
  2972. * ENTRY:
  2973. * wParam (input)
  2974. * Contains message ID for error.
  2975. * wLparam (input)
  2976. * Contains error code (GetLastError)
  2977. * EXIT:
  2978. * (LRESULT) always returns 0 to indicate error handling complete. Will
  2979. * have posted an 'Ok' (Exit) button click to cause exit.
  2980. *
  2981. ******************************************************************************/
  2982. LRESULT CAsyncTestDlg::OnAsyncTestAbort( WPARAM wParam, LPARAM lParam )
  2983. {
  2984. UNREFERENCED_PARAMETER( lParam );
  2985. /*
  2986. * Call OnAsyncTestError() to output message.
  2987. */
  2988. //OnAsyncTestError(wParam, lParam);
  2989. NotifyAbort((UINT)wParam);
  2990. /*
  2991. * Post a click for 'OK' (Exit) button to exit dialog.
  2992. */
  2993. PostMessage( m_hDlg , WM_COMMAND , MAKEWPARAM( IDOK, BN_CLICKED ) , (LPARAM)::GetDlgItem( m_hDlg , IDOK ) );
  2994. return(0);
  2995. } // end CAsyncTestDlg::OnAsyncTestAbort
  2996. /*******************************************************************************
  2997. *
  2998. * OnAsyncTestStatusReady - CAsyncTestDlg member function: command
  2999. *
  3000. * Update dialog with comm status information.
  3001. *
  3002. * ENTRY:
  3003. * wParam (input)
  3004. * not used (0)
  3005. * wLparam (input)
  3006. * not used (0)
  3007. * EXIT:
  3008. * (LRESULT) always returns 0.
  3009. *
  3010. ******************************************************************************/
  3011. LRESULT
  3012. CAsyncTestDlg::OnAsyncTestStatusReady( WPARAM wParam, LPARAM lParam )
  3013. {
  3014. UNREFERENCED_PARAMETER( wParam );
  3015. UNREFERENCED_PARAMETER( lParam );
  3016. /*
  3017. * Update dialog fields with information from the input thread's
  3018. * PROTOCOLSTATUS structure.
  3019. */
  3020. SetInfoFields( &m_Status, &(m_pATDlgInputThread->m_Status) );
  3021. /*
  3022. * Set our working PROTOCOLSTATUS structure to the new one and signal
  3023. * the thread that we're done.
  3024. */
  3025. m_Status = m_pATDlgInputThread->m_Status;
  3026. m_pATDlgInputThread->SignalConsumed();
  3027. return(0);
  3028. } // end CAsyncTestDlg::OnAsyncTestStatusReady
  3029. /*******************************************************************************
  3030. *
  3031. * OnAsyncTestInputReady - CAsyncTestDlg member function: command
  3032. *
  3033. * Update dialog with comm input data.
  3034. *
  3035. * ENTRY:
  3036. * wParam (input)
  3037. * not used (0)
  3038. * wLparam (input)
  3039. * not used (0)
  3040. * EXIT:
  3041. * (LRESULT) always returns 0.
  3042. *
  3043. ******************************************************************************/
  3044. LRESULT
  3045. CAsyncTestDlg::OnAsyncTestInputReady( WPARAM wParam, LPARAM lParam )
  3046. {
  3047. UNREFERENCED_PARAMETER( wParam );
  3048. UNREFERENCED_PARAMETER( lParam );
  3049. BYTE OutBuf[MAX_COMMAND_LEN+2];
  3050. int i, j;
  3051. /*
  3052. * Copy the thread's buffer and count locally.
  3053. */
  3054. m_BufferBytes = m_pATDlgInputThread->m_BufferBytes;
  3055. CopyMemory( m_Buffer , m_pATDlgInputThread->m_Buffer , m_BufferBytes );
  3056. /*
  3057. * Always return caret to the current position before processing, and set
  3058. * edit control to 'read/write' so that character overwrites can occur
  3059. * properly. Finally, flag control for no redraw until all updates are completed,
  3060. * and flag 'processing output' to avoid OnChar() recursion during '\b' processing.
  3061. */
  3062. SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos , m_CurrentPos );
  3063. SendMessage( m_EditControl.m_hWnd , EM_SETREADONLY , ( WPARAM )FALSE , 0 );
  3064. SendMessage( m_EditControl.m_hWnd , WM_SETREDRAW , ( WPARAM )FALSE , 0 );
  3065. /*
  3066. * Loop to traverse the buffer, with special processing for certain
  3067. * control characters.
  3068. */
  3069. for ( i = 0, j = 0; m_BufferBytes; i++, m_BufferBytes-- )
  3070. {
  3071. switch( m_Buffer[i] )
  3072. {
  3073. case '\b':
  3074. /*
  3075. * If there is data in the output buffer, write it now.
  3076. */
  3077. if( j )
  3078. {
  3079. OutputToEditControl(OutBuf, &j);
  3080. }
  3081. /*
  3082. * Output the '\b' (will actually cut current character from buffer)
  3083. */
  3084. OutBuf[j++] = '\b';
  3085. OutputToEditControl(OutBuf, &j);
  3086. continue;
  3087. case '\r':
  3088. /*
  3089. * If there is data in the output buffer, write it now.
  3090. */
  3091. if( j )
  3092. {
  3093. OutputToEditControl(OutBuf, &j);
  3094. }
  3095. /*
  3096. * Output the '\r' (will not actually output, but will special case
  3097. * for caret positioning and screen update).
  3098. */
  3099. OutBuf[j++] = '\r';
  3100. OutputToEditControl(OutBuf, &j);
  3101. continue;
  3102. case '\n':
  3103. /*
  3104. * If there is data in the output buffer, write it now.
  3105. */
  3106. if( j )
  3107. {
  3108. OutputToEditControl(OutBuf, &j);
  3109. }
  3110. /*
  3111. * Output the '\n' (will actually quietly output the '\r' and take
  3112. * care of scolling).
  3113. */
  3114. OutBuf[j++] = '\n';
  3115. OutputToEditControl(OutBuf, &j);
  3116. continue;
  3117. }
  3118. /*
  3119. * Add this character to the output buffer.
  3120. */
  3121. OutBuf[j++] = m_Buffer[i];
  3122. }
  3123. /*
  3124. * If there is anything remaining in the output buffer, output it now.
  3125. */
  3126. if( j )
  3127. {
  3128. OutputToEditControl(OutBuf, &j);
  3129. }
  3130. /*
  3131. * Place edit control back in 'read only' mode, flag 'not processing output',
  3132. * set redraw flag for control, and validate the entire control (updates have
  3133. * already taken place).
  3134. */
  3135. SendMessage( m_EditControl.m_hWnd , EM_SETREADONLY , ( WPARAM )TRUE , 0 );
  3136. SendMessage( m_EditControl.m_hWnd , WM_SETREDRAW , ( WPARAM )TRUE , 0 );
  3137. ValidateRect( m_EditControl.m_hWnd , NULL );
  3138. /*
  3139. * Signal thread that we're done with input so that it can continue.
  3140. * NOTE: we don't do this at the beginning of the routine even though
  3141. * we could (for more parallelism), since a constantly chatty async
  3142. * line would cause WM_ASYNCTESTINPUTREADY messages to always be posted
  3143. * to our message queue, effectively blocking any other message processing
  3144. * (like telling the dialog to exit!).
  3145. */
  3146. m_pATDlgInputThread->SignalConsumed();
  3147. return(0);
  3148. } // end CAsyncTestDlg::OnAsyncTestInputReady
  3149. /*******************************************************************************/
  3150. void CAsyncTestDlg::OutputToEditControl( BYTE *pBuffer, int *pIndex )
  3151. {
  3152. RECT Rect, ClientRect;
  3153. BOOL bScroll = FALSE;
  3154. INT_PTR CurrentLine = SendMessage( m_EditControl.m_hWnd , EM_LINEFROMCHAR , ( WPARAM )m_CurrentPos , 0 );
  3155. INT_PTR FirstVisibleLine = SendMessage( m_EditControl.m_hWnd , EM_GETFIRSTVISIBLELINE , 0 , 0 );
  3156. INT_PTR CurrentLineIndex = SendMessage( m_EditControl.m_hWnd , EM_LINEINDEX , ( WPARAM )CurrentLine , 0 );
  3157. /*
  3158. * Calculate clip rectangle.
  3159. */
  3160. Rect.top = ( ( int )( CurrentLine - FirstVisibleLine ) * m_EditControl.m_FontHeight )
  3161. + m_EditControl.m_FormatOffsetY;
  3162. Rect.bottom = Rect.top + m_EditControl.m_FontHeight;
  3163. Rect.left = m_EditControl.m_FormatOffsetX +( ( int )( m_CurrentPos - CurrentLineIndex ) * m_EditControl.m_FontWidth );
  3164. Rect.right = Rect.left + (*pIndex * m_EditControl.m_FontWidth);
  3165. /*
  3166. * Handle special cases.
  3167. */
  3168. if ( pBuffer[0] == '\b' ) {
  3169. /*
  3170. * If we're already at the beginning of the line, clear buffer index
  3171. * and return (don't do anything).
  3172. */
  3173. if ( m_CurrentPos == CurrentLineIndex ) {
  3174. *pIndex = 0;
  3175. return;
  3176. }
  3177. /*
  3178. * Position the caret back one character and select through current character.
  3179. */
  3180. SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos - 1 , m_CurrentPos );
  3181. /*
  3182. * Cut the character out of the edit buffer.
  3183. */
  3184. m_EditControl.m_bProcessingOutput = TRUE;
  3185. SendMessage( m_EditControl.m_hWnd , WM_CUT , 0 , 0 );
  3186. m_EditControl.m_bProcessingOutput = FALSE;
  3187. /*
  3188. * Decrement current position and zero index to suppress further output. Also,
  3189. * widen the clipping rectangle back one character.
  3190. */
  3191. Rect.left -= m_EditControl.m_FontWidth;
  3192. m_CurrentPos--;
  3193. *pIndex = 0;
  3194. }
  3195. else if( pBuffer[0] == '\r' )
  3196. {
  3197. /*
  3198. * Position the caret at the beginning of the current line.
  3199. */
  3200. m_CurrentPos = CurrentLineIndex;
  3201. SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos, m_CurrentPos );
  3202. /*
  3203. * Zero index to keep from actually outputing to edit buffer.
  3204. */
  3205. *pIndex = 0;
  3206. }
  3207. else if( pBuffer[0] == '\n' )
  3208. {
  3209. /*
  3210. * Position selection point at end of the current edit buffer.
  3211. */
  3212. m_CurrentPos = GetWindowTextLength( m_EditControl.m_hWnd );
  3213. SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos , -1 );
  3214. /*
  3215. * Cause '\r' '\n' pair to be output to edit buffer.
  3216. */
  3217. pBuffer[0] = '\r';
  3218. pBuffer[1] = '\n';
  3219. *pIndex = 2;
  3220. /*
  3221. * See if scrolling needed.
  3222. */
  3223. GetClientRect( m_EditControl.m_hWnd , &ClientRect );
  3224. if ( (Rect.bottom + m_EditControl.m_FontHeight) > ClientRect.bottom )
  3225. bScroll = TRUE;
  3226. }
  3227. else
  3228. {
  3229. /*
  3230. * Set selection from current position through *pIndex characters. This
  3231. * will perform desired 'overwrite' function if current position is not at
  3232. * the end of the edit buffer.
  3233. */
  3234. SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos , m_CurrentPos + *pIndex );
  3235. }
  3236. /*
  3237. * If necessary, update the dialog's edit box with the buffer data.
  3238. */
  3239. if( *pIndex )
  3240. {
  3241. #ifdef UNICODE
  3242. TCHAR OutBuffer[MAX_COMMAND_LEN+1];
  3243. mbstowcs(OutBuffer, (PCHAR)pBuffer, *pIndex);
  3244. OutBuffer[*pIndex] = TEXT('\0');
  3245. SendMessage( m_EditControl.m_hWnd , EM_REPLACESEL , ( WPARAM )FALSE , ( LPARAM )OutBuffer );
  3246. #else
  3247. pBuffer[*pIndex] = BYTE('\0');
  3248. SendMessage( m_EditControl.m_hWnd , EM_REPLACESEL , ( WPARAM )FALSE , ( LPARAM )pBuffer );
  3249. #endif // UNICODE
  3250. }
  3251. /*
  3252. * Update the current line.
  3253. */
  3254. SendMessage( m_EditControl.m_hWnd , WM_SETREDRAW , ( WPARAM )TRUE , 0 );
  3255. ValidateRect( m_EditControl.m_hWnd , NULL );
  3256. InvalidateRect( m_EditControl.m_hWnd , &Rect , FALSE );
  3257. UpdateWindow( m_EditControl.m_hWnd );
  3258. /*
  3259. * If scrolling is required to see the new line, do so.
  3260. */
  3261. if( bScroll )
  3262. {
  3263. SendMessage( m_EditControl.m_hWnd , EM_LINESCROLL , 0 , 1 );
  3264. }
  3265. SendMessage( m_EditControl.m_hWnd , WM_SETREDRAW , ( WPARAM )FALSE , 0 );
  3266. /*
  3267. * Update current position and clear buffer index.
  3268. */
  3269. m_CurrentPos += *pIndex;
  3270. *pIndex = 0;
  3271. } // end CAsyncTestDlg::OutputToEditControl
  3272. /*******************************************************************************
  3273. *
  3274. * OnAsyncTestWriteChar - CAsyncTestDlg member function: command
  3275. *
  3276. * Place the specified character in m_Buffer, set m_BufferBytes to 1,
  3277. * and call DeviceWrite() to output the character to the device.
  3278. *
  3279. * ENTRY:
  3280. * wParam (input)
  3281. * Character to write.
  3282. * lParam (input)
  3283. * not used (0)
  3284. * EXIT:
  3285. * (LRESULT) always returns 0.
  3286. *
  3287. ******************************************************************************/
  3288. LRESULT CAsyncTestDlg::OnAsyncTestWriteChar( WPARAM wParam, LPARAM lParam )
  3289. {
  3290. UNREFERENCED_PARAMETER( wParam );
  3291. UNREFERENCED_PARAMETER( lParam );
  3292. /*
  3293. * Write the byte to the device.
  3294. */
  3295. m_Buffer[0] = (BYTE)wParam;
  3296. m_BufferBytes = 1;
  3297. DeviceWrite();
  3298. return(0);
  3299. } // end CAsyncTestDlg::OnAsyncTestWriteChar
  3300. /*******************************************************************************
  3301. *
  3302. * OnClickedAtdlgModemDial - CAsyncTestDlg member function: command
  3303. *
  3304. * Send the modem dial string.
  3305. *
  3306. * ENTRY:
  3307. * EXIT:
  3308. *
  3309. ******************************************************************************/
  3310. void CAsyncTestDlg::OnClickedAtdlgModemDial()
  3311. {
  3312. } // end CAsyncTestDlg::OnClickedAtdlgModemDial
  3313. /*******************************************************************************
  3314. *
  3315. * OnClickedAtdlgModemInit - CAsyncTestDlg member function: command
  3316. *
  3317. * Send the modem init string.
  3318. *
  3319. * ENTRY:
  3320. * EXIT:
  3321. *
  3322. ******************************************************************************/
  3323. void CAsyncTestDlg::OnClickedAtdlgModemInit()
  3324. {
  3325. } // end CAsyncTestDlg::OnClickedAtdlgModemInit
  3326. /*******************************************************************************
  3327. *
  3328. * OnClickedAtdlgModemListen - CAsyncTestDlg member function: command
  3329. *
  3330. * Send the modem listen string.
  3331. *
  3332. * ENTRY:
  3333. * EXIT:
  3334. *
  3335. ******************************************************************************/
  3336. void CAsyncTestDlg::OnClickedAtdlgModemListen()
  3337. {
  3338. lstrcpy((TCHAR *)m_Buffer, m_szModemListen);
  3339. m_BufferBytes = lstrlen((TCHAR *)m_Buffer);
  3340. DeviceWrite();
  3341. } // end CAsyncTestDlg::OnClickedAtdlgModemListen
  3342. /*******************************************************************************
  3343. *
  3344. * OnNcDestroy - CAsyncTestDlg member function: command
  3345. *
  3346. * Clean up before deleting dialog object.
  3347. *
  3348. * ENTRY:
  3349. * EXIT:
  3350. * (Refer to CWnd::OnNcDestroy documentation)
  3351. *
  3352. ******************************************************************************/
  3353. void
  3354. CAsyncTestDlg::OnNcDestroy()
  3355. {
  3356. if( m_LEDToggleTimer )
  3357. {
  3358. KillTimer( m_hDlg , m_LEDToggleTimer );
  3359. }
  3360. if( m_pATDlgInputThread )
  3361. {
  3362. m_pATDlgInputThread->ExitThread();
  3363. }
  3364. if( m_hDevice != INVALID_HANDLE_VALUE )
  3365. {
  3366. PurgeComm(m_hDevice, PURGE_TXABORT | PURGE_TXCLEAR);
  3367. }
  3368. if( m_OverlapWrite.hEvent != NULL )
  3369. {
  3370. CloseHandle(m_OverlapWrite.hEvent);
  3371. }
  3372. if( m_hDevice != INVALID_HANDLE_VALUE )
  3373. {
  3374. CloseHandle(m_hDevice);
  3375. }
  3376. if( m_bDeletedWinStation && m_pWSName )
  3377. {
  3378. m_WSConfig.Create.fEnableWinStation = TRUE;
  3379. if( RegWinStationCreate( SERVERNAME_CURRENT , m_pWSName , FALSE , &m_WSConfig , sizeof(WINSTATIONCONFIG2) ) != ERROR_SUCCESS )
  3380. {
  3381. _WinStationReadRegistry(SERVERNAME_CURRENT);
  3382. }
  3383. }
  3384. DeleteObject(m_hRedBrush);
  3385. } // end CAsyncTestDlg::OnNcDestroy
  3386. ////////////////////////////////////////////////////////////////////////////////
  3387. INT_PTR CALLBACK CAsyncTestDlg::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp )
  3388. {
  3389. CAsyncTestDlg *pDlg;
  3390. if( msg == WM_INITDIALOG )
  3391. {
  3392. CAsyncTestDlg *pDlg = ( CAsyncTestDlg * )lp;
  3393. SetWindowLongPtr( hwnd , DWLP_USER, ( LONG_PTR )pDlg );
  3394. if( !IsBadReadPtr( pDlg , sizeof( CAsyncTestDlg ) ) )
  3395. {
  3396. if(FALSE == pDlg->OnInitDialog( hwnd , wp , lp ))
  3397. PostMessage(hwnd,WM_CLOSE,0,0);
  3398. }
  3399. return 0;
  3400. }
  3401. else
  3402. {
  3403. pDlg = ( CAsyncTestDlg * )GetWindowLongPtr( hwnd , DWLP_USER);
  3404. if( IsBadReadPtr( pDlg , sizeof( CAsyncTestDlg ) ) )
  3405. {
  3406. return 0;
  3407. }
  3408. }
  3409. switch( msg )
  3410. {
  3411. case WM_NCDESTROY:
  3412. pDlg->OnNcDestroy( );
  3413. break;
  3414. case WM_COMMAND:
  3415. pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
  3416. break;
  3417. case WM_TIMER:
  3418. pDlg->OnTimer( ( UINT )wp );
  3419. break;
  3420. case WM_ASYNCTESTERROR:
  3421. ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTERROR (R)\n" );
  3422. pDlg->NotifyAbort((UINT)wp);
  3423. break;
  3424. case WM_ASYNCTESTABORT:
  3425. ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTABORT (R)\n" );
  3426. pDlg->OnAsyncTestAbort( wp , lp );
  3427. break;
  3428. case WM_ASYNCTESTSTATUSREADY:
  3429. ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTSTATUSREADY (R)\n" );
  3430. pDlg->OnAsyncTestStatusReady( wp , lp );
  3431. break;
  3432. case WM_ASYNCTESTINPUTREADY:
  3433. ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTINPUTREADY (R)\n" );
  3434. pDlg->OnAsyncTestInputReady( wp , lp );
  3435. break;
  3436. case WM_ASYNCTESTWRITECHAR:
  3437. ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTWRITECHAR (R)\n" );
  3438. pDlg->OnAsyncTestWriteChar( wp , lp );
  3439. break;
  3440. }
  3441. return 0;
  3442. }