Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1141 lines
31 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Copyright (c) Microsoft Corporation 1993-1996
  4. //
  5. // File: port.c
  6. //
  7. // This files contains the dialog code for the Port Settings property page.
  8. //
  9. // History:
  10. // 2-09-94 ScottH Created
  11. // 11-06-95 ScottH Ported to NT
  12. //
  13. //---------------------------------------------------------------------------
  14. #include "proj.h"
  15. // This is the structure that is used to fill the
  16. // max speed listbox
  17. typedef struct _Bauds
  18. {
  19. DWORD dwDTERate;
  20. int ids;
  21. } Bauds;
  22. static Bauds g_rgbauds[] = {
  23. { 110L, IDS_BAUD_110 },
  24. { 300L, IDS_BAUD_300 },
  25. { 1200L, IDS_BAUD_1200 },
  26. { 2400L, IDS_BAUD_2400 },
  27. { 4800L, IDS_BAUD_4800 },
  28. { 9600L, IDS_BAUD_9600 },
  29. { 19200, IDS_BAUD_19200 },
  30. { 38400, IDS_BAUD_38400 },
  31. { 57600, IDS_BAUD_57600 },
  32. { 115200, IDS_BAUD_115200 },
  33. { 230400, IDS_BAUD_230400 },
  34. { 460800, IDS_BAUD_460800 },
  35. { 921600, IDS_BAUD_921600 },
  36. };
  37. // Command IDs for the parity listbox
  38. #define CMD_PARITY_EVEN 1
  39. #define CMD_PARITY_ODD 2
  40. #define CMD_PARITY_NONE 3
  41. #define CMD_PARITY_MARK 4
  42. #define CMD_PARITY_SPACE 5
  43. // Command IDs for the flow control listbox
  44. #define CMD_FLOWCTL_XONXOFF 1
  45. #define CMD_FLOWCTL_HARDWARE 2
  46. #define CMD_FLOWCTL_NONE 3
  47. // This table is the generic port settings table
  48. // that is used to fill the various listboxes
  49. typedef struct _PortValues
  50. {
  51. union {
  52. BYTE bytesize;
  53. BYTE cmd;
  54. BYTE stopbits;
  55. };
  56. int ids;
  57. } PortValues, FAR * LPPORTVALUES;
  58. #pragma data_seg(DATASEG_READONLY)
  59. // This is the structure that is used to fill the data bits listbox
  60. static PortValues s_rgbytesize[] = {
  61. { 5, IDS_BYTESIZE_5 },
  62. { 6, IDS_BYTESIZE_6 },
  63. { 7, IDS_BYTESIZE_7 },
  64. { 8, IDS_BYTESIZE_8 },
  65. };
  66. // This is the structure that is used to fill the parity listbox
  67. static PortValues s_rgparity[] = {
  68. { CMD_PARITY_EVEN, IDS_PARITY_EVEN },
  69. { CMD_PARITY_ODD, IDS_PARITY_ODD },
  70. { CMD_PARITY_NONE, IDS_PARITY_NONE },
  71. { CMD_PARITY_MARK, IDS_PARITY_MARK },
  72. { CMD_PARITY_SPACE, IDS_PARITY_SPACE },
  73. };
  74. // This is the structure that is used to fill the stopbits listbox
  75. static PortValues s_rgstopbits[] = {
  76. { ONESTOPBIT, IDS_STOPBITS_1 },
  77. { ONE5STOPBITS, IDS_STOPBITS_1_5 },
  78. { TWOSTOPBITS, IDS_STOPBITS_2 },
  79. };
  80. // This is the structure that is used to fill the flow control listbox
  81. static PortValues s_rgflowctl[] = {
  82. { CMD_FLOWCTL_XONXOFF, IDS_FLOWCTL_XONXOFF },
  83. { CMD_FLOWCTL_HARDWARE, IDS_FLOWCTL_HARDWARE },
  84. { CMD_FLOWCTL_NONE, IDS_FLOWCTL_NONE },
  85. };
  86. #pragma data_seg()
  87. typedef struct tagPORT
  88. {
  89. HWND hdlg; // dialog handle
  90. HWND hwndBaudRate;
  91. HWND hwndDataBits;
  92. HWND hwndParity;
  93. HWND hwndStopBits;
  94. HWND hwndFlowCtl;
  95. LPPORTINFO pportinfo; // pointer to shared working buffer
  96. } PORT, FAR * PPORT;
  97. // This structure contains the default settings for the dialog
  98. static struct _DefPortSettings
  99. {
  100. int iSelBaud;
  101. int iSelDataBits;
  102. int iSelParity;
  103. int iSelStopBits;
  104. int iSelFlowCtl;
  105. } s_defportsettings;
  106. // These are default settings
  107. #define DEFAULT_BAUDRATE 9600L
  108. #define DEFAULT_BYTESIZE 8
  109. #define DEFAULT_PARITY CMD_PARITY_NONE
  110. #define DEFAULT_STOPBITS ONESTOPBIT
  111. #define DEFAULT_FLOWCTL CMD_FLOWCTL_NONE
  112. #define Port_GetPtr(hwnd) (PPORT)GetWindowLongPtr(hwnd, DWLP_USER)
  113. #define Port_SetPtr(hwnd, lp) (PPORT)SetWindowLongPtr(hwnd, DWLP_USER, (ULONG_PTR)(lp))
  114. UINT WINAPI FeFiFoFum(HWND hwndOwner, LPCTSTR pszPortName);
  115. /*----------------------------------------------------------
  116. Purpose: Fills the baud rate combobox with the possible baud
  117. rates that Windows supports.
  118. Returns: --
  119. Cond: --
  120. */
  121. void PRIVATE Port_FillBaud(
  122. PPORT this)
  123. {
  124. HWND hwndCB = this->hwndBaudRate;
  125. WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
  126. int i;
  127. int n;
  128. int iMatch = -1;
  129. int iDef = -1;
  130. int iSel;
  131. TCHAR sz[MAXMEDLEN];
  132. // Fill the listbox
  133. for (i = 0; i < ARRAYSIZE(g_rgbauds); i++)
  134. {
  135. n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, g_rgbauds[i].ids, sz, SIZECHARS(sz)));
  136. ComboBox_SetItemData(hwndCB, n, g_rgbauds[i].dwDTERate);
  137. // Keep our eyes peeled for important values
  138. if (DEFAULT_BAUDRATE == g_rgbauds[i].dwDTERate)
  139. {
  140. iDef = n;
  141. }
  142. if (pdcb->BaudRate == g_rgbauds[i].dwDTERate)
  143. {
  144. iMatch = n;
  145. }
  146. }
  147. ASSERT(-1 != iDef);
  148. s_defportsettings.iSelBaud = iDef;
  149. // Does the DCB baudrate exist in our list of baud rates?
  150. if (-1 == iMatch)
  151. {
  152. // No; choose the default
  153. iSel = iDef;
  154. }
  155. else
  156. {
  157. // Yes; choose the matched value
  158. ASSERT(-1 != iMatch);
  159. iSel = iMatch;
  160. }
  161. ComboBox_SetCurSel(hwndCB, iSel);
  162. }
  163. /*----------------------------------------------------------
  164. Purpose: Fills the bytesize combobox with the possible byte sizes.
  165. Returns: --
  166. Cond: --
  167. */
  168. void PRIVATE Port_FillDataBits(
  169. PPORT this)
  170. {
  171. HWND hwndCB = this->hwndDataBits;
  172. WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
  173. int i;
  174. int iSel;
  175. int n;
  176. int iMatch = -1;
  177. int iDef = -1;
  178. TCHAR sz[MAXMEDLEN];
  179. // Fill the listbox
  180. for (i = 0; i < ARRAYSIZE(s_rgbytesize); i++)
  181. {
  182. n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgbytesize[i].ids, sz, SIZECHARS(sz)));
  183. ComboBox_SetItemData(hwndCB, n, s_rgbytesize[i].bytesize);
  184. // Keep our eyes peeled for important values
  185. if (DEFAULT_BYTESIZE == s_rgbytesize[i].bytesize)
  186. {
  187. iDef = n;
  188. }
  189. if (pdcb->ByteSize == s_rgbytesize[i].bytesize)
  190. {
  191. iMatch = n;
  192. }
  193. }
  194. ASSERT(-1 != iDef);
  195. s_defportsettings.iSelDataBits = iDef;
  196. // Does the DCB value exist in our list?
  197. if (-1 == iMatch)
  198. {
  199. // No; choose the default
  200. iSel = iDef;
  201. }
  202. else
  203. {
  204. // Yes; choose the matched value
  205. ASSERT(-1 != iMatch);
  206. iSel = iMatch;
  207. }
  208. ComboBox_SetCurSel(hwndCB, iSel);
  209. }
  210. /*----------------------------------------------------------
  211. Purpose: Fills the parity combobox with the possible settings.
  212. Returns: --
  213. Cond: --
  214. */
  215. void PRIVATE Port_FillParity(
  216. PPORT this)
  217. {
  218. HWND hwndCB = this->hwndParity;
  219. WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
  220. int i;
  221. int iSel;
  222. int n;
  223. int iMatch = -1;
  224. int iDef = -1;
  225. TCHAR sz[MAXMEDLEN];
  226. // Fill the listbox
  227. for (i = 0; i < ARRAYSIZE(s_rgparity); i++)
  228. {
  229. n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgparity[i].ids, sz, SIZECHARS(sz)));
  230. ComboBox_SetItemData(hwndCB, n, s_rgparity[i].cmd);
  231. // Keep our eyes peeled for important values
  232. if (DEFAULT_PARITY == s_rgparity[i].cmd)
  233. {
  234. iDef = n;
  235. }
  236. switch (s_rgparity[i].cmd)
  237. {
  238. case CMD_PARITY_EVEN:
  239. if (EVENPARITY == pdcb->Parity)
  240. iMatch = n;
  241. break;
  242. case CMD_PARITY_ODD:
  243. if (ODDPARITY == pdcb->Parity)
  244. iMatch = n;
  245. break;
  246. case CMD_PARITY_NONE:
  247. if (NOPARITY == pdcb->Parity)
  248. iMatch = n;
  249. break;
  250. case CMD_PARITY_MARK:
  251. if (MARKPARITY == pdcb->Parity)
  252. iMatch = n;
  253. break;
  254. case CMD_PARITY_SPACE:
  255. if (SPACEPARITY == pdcb->Parity)
  256. iMatch = n;
  257. break;
  258. default:
  259. ASSERT(0);
  260. break;
  261. }
  262. }
  263. ASSERT(-1 != iDef);
  264. s_defportsettings.iSelParity = iDef;
  265. // Does the DCB value exist in our list?
  266. if (-1 == iMatch)
  267. {
  268. // No; choose the default
  269. iSel = iDef;
  270. }
  271. else
  272. {
  273. // Yes; choose the matched value
  274. ASSERT(-1 != iMatch);
  275. iSel = iMatch;
  276. }
  277. ComboBox_SetCurSel(hwndCB, iSel);
  278. }
  279. /*----------------------------------------------------------
  280. Purpose: Fills the stopbits combobox with the possible settings.
  281. Returns: --
  282. Cond: --
  283. */
  284. void PRIVATE Port_FillStopBits(
  285. PPORT this)
  286. {
  287. HWND hwndCB = this->hwndStopBits;
  288. WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
  289. int i;
  290. int iSel;
  291. int n;
  292. int iMatch = -1;
  293. int iDef = -1;
  294. TCHAR sz[MAXMEDLEN];
  295. // Fill the listbox
  296. for (i = 0; i < ARRAYSIZE(s_rgstopbits); i++)
  297. {
  298. n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgstopbits[i].ids, sz, SIZECHARS(sz)));
  299. ComboBox_SetItemData(hwndCB, n, s_rgstopbits[i].stopbits);
  300. // Keep our eyes peeled for important values
  301. if (DEFAULT_STOPBITS == s_rgstopbits[i].stopbits)
  302. {
  303. iDef = n;
  304. }
  305. if (pdcb->StopBits == s_rgstopbits[i].stopbits)
  306. {
  307. iMatch = n;
  308. }
  309. }
  310. ASSERT(-1 != iDef);
  311. s_defportsettings.iSelStopBits = iDef;
  312. // Does the DCB value exist in our list?
  313. if (-1 == iMatch)
  314. {
  315. // No; choose the default
  316. iSel = iDef;
  317. }
  318. else
  319. {
  320. // Yes; choose the matched value
  321. ASSERT(-1 != iMatch);
  322. iSel = iMatch;
  323. }
  324. ComboBox_SetCurSel(hwndCB, iSel);
  325. }
  326. /*----------------------------------------------------------
  327. Purpose: Fills the flow control combobox with the possible settings.
  328. Returns: --
  329. Cond: --
  330. */
  331. void PRIVATE Port_FillFlowCtl(
  332. PPORT this)
  333. {
  334. HWND hwndCB = this->hwndFlowCtl;
  335. WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
  336. int i;
  337. int iSel;
  338. int n;
  339. int iMatch = -1;
  340. int iDef = -1;
  341. TCHAR sz[MAXMEDLEN];
  342. // Fill the listbox
  343. for (i = 0; i < ARRAYSIZE(s_rgflowctl); i++)
  344. {
  345. n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgflowctl[i].ids, sz, SIZECHARS(sz)));
  346. ComboBox_SetItemData(hwndCB, n, s_rgflowctl[i].cmd);
  347. // Keep our eyes peeled for important values
  348. if (DEFAULT_FLOWCTL == s_rgflowctl[i].cmd)
  349. {
  350. iDef = n;
  351. }
  352. switch (s_rgflowctl[i].cmd)
  353. {
  354. case CMD_FLOWCTL_XONXOFF:
  355. if (TRUE == pdcb->fOutX && FALSE == pdcb->fOutxCtsFlow)
  356. iMatch = n;
  357. break;
  358. case CMD_FLOWCTL_HARDWARE:
  359. if (FALSE == pdcb->fOutX && TRUE == pdcb->fOutxCtsFlow)
  360. iMatch = n;
  361. break;
  362. case CMD_FLOWCTL_NONE:
  363. if (FALSE == pdcb->fOutX && FALSE == pdcb->fOutxCtsFlow)
  364. iMatch = n;
  365. break;
  366. default:
  367. ASSERT(0);
  368. break;
  369. }
  370. }
  371. ASSERT(-1 != iDef);
  372. s_defportsettings.iSelFlowCtl = iDef;
  373. // Does the DCB value exist in our list?
  374. if (-1 == iMatch)
  375. {
  376. // No; choose the default
  377. iSel = iDef;
  378. }
  379. else
  380. {
  381. // Yes; choose the matched value
  382. ASSERT(-1 != iMatch);
  383. iSel = iMatch;
  384. }
  385. ComboBox_SetCurSel(hwndCB, iSel);
  386. }
  387. /*----------------------------------------------------------
  388. Purpose: WM_INITDIALOG Handler
  389. Returns: FALSE when we assign the control focus
  390. Cond: --
  391. */
  392. BOOL PRIVATE Port_OnInitDialog(
  393. PPORT this,
  394. HWND hwndFocus,
  395. LPARAM lParam) // expected to be PROPSHEETINFO
  396. {
  397. LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  398. HWND hwnd = this->hdlg;
  399. ASSERT((LPTSTR)lppsp->lParam);
  400. this->pportinfo = (LPPORTINFO)lppsp->lParam;
  401. // Save away the window handles
  402. this->hwndBaudRate = GetDlgItem(hwnd, IDC_PS_BAUDRATE);
  403. this->hwndDataBits = GetDlgItem(hwnd, IDC_PS_DATABITS);
  404. this->hwndParity = GetDlgItem(hwnd, IDC_PS_PARITY);
  405. this->hwndStopBits = GetDlgItem(hwnd, IDC_PS_STOPBITS);
  406. this->hwndFlowCtl = GetDlgItem(hwnd, IDC_PS_FLOWCTL);
  407. Port_FillBaud(this);
  408. Port_FillDataBits(this);
  409. Port_FillParity(this);
  410. Port_FillStopBits(this);
  411. Port_FillFlowCtl(this);
  412. #if !defined(SUPPORT_FIFO)
  413. // Hide and disable the Advanced button
  414. ShowWindow(GetDlgItem(hwnd, IDC_PS_ADVANCED), FALSE);
  415. EnableWindow(GetDlgItem(hwnd, IDC_PS_ADVANCED), FALSE);
  416. #endif
  417. return TRUE; // allow USER to set the initial focus
  418. }
  419. /*----------------------------------------------------------
  420. Purpose: WM_COMMAND Handler
  421. Returns: --
  422. Cond: --
  423. */
  424. void PRIVATE Port_OnCommand(
  425. PPORT this,
  426. int id,
  427. HWND hwndCtl,
  428. UINT uNotifyCode)
  429. {
  430. HWND hwnd = this->hdlg;
  431. switch (id)
  432. {
  433. case IDC_PS_PB_RESTORE:
  434. // Set the values to the default settings
  435. ComboBox_SetCurSel(this->hwndBaudRate, s_defportsettings.iSelBaud);
  436. ComboBox_SetCurSel(this->hwndDataBits, s_defportsettings.iSelDataBits);
  437. ComboBox_SetCurSel(this->hwndParity, s_defportsettings.iSelParity);
  438. ComboBox_SetCurSel(this->hwndStopBits, s_defportsettings.iSelStopBits);
  439. ComboBox_SetCurSel(this->hwndFlowCtl, s_defportsettings.iSelFlowCtl);
  440. break;
  441. #ifdef SUPPORT_FIFO
  442. case IDC_PS_ADVANCED:
  443. FeFiFoFum(this->hdlg, this->pportinfo->szFriendlyName);
  444. break;
  445. #endif
  446. default:
  447. switch (uNotifyCode) {
  448. case CBN_SELCHANGE:
  449. PropSheet_Changed(GetParent(hwnd), hwnd);
  450. break;
  451. }
  452. break;
  453. }
  454. }
  455. /*----------------------------------------------------------
  456. Purpose: PSN_APPLY handler
  457. Returns: --
  458. Cond: --
  459. */
  460. void PRIVATE Port_OnApply(
  461. PPORT this)
  462. {
  463. int iSel;
  464. BYTE cmd;
  465. WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
  466. // Determine new speed settings
  467. iSel = ComboBox_GetCurSel(this->hwndBaudRate);
  468. pdcb->BaudRate = (DWORD)ComboBox_GetItemData(this->hwndBaudRate, iSel);
  469. // Determine new byte size
  470. iSel = ComboBox_GetCurSel(this->hwndDataBits);
  471. pdcb->ByteSize = (BYTE)ComboBox_GetItemData(this->hwndDataBits, iSel);
  472. // Determine new parity settings
  473. iSel = ComboBox_GetCurSel(this->hwndParity);
  474. cmd = (BYTE)ComboBox_GetItemData(this->hwndParity, iSel);
  475. switch (cmd)
  476. {
  477. case CMD_PARITY_EVEN:
  478. pdcb->fParity = TRUE;
  479. pdcb->Parity = EVENPARITY;
  480. break;
  481. case CMD_PARITY_ODD:
  482. pdcb->fParity = TRUE;
  483. pdcb->Parity = ODDPARITY;
  484. break;
  485. case CMD_PARITY_NONE:
  486. pdcb->fParity = FALSE;
  487. pdcb->Parity = NOPARITY;
  488. break;
  489. case CMD_PARITY_MARK:
  490. pdcb->fParity = TRUE;
  491. pdcb->Parity = MARKPARITY;
  492. break;
  493. case CMD_PARITY_SPACE:
  494. pdcb->fParity = TRUE;
  495. pdcb->Parity = SPACEPARITY;
  496. break;
  497. default:
  498. ASSERT(0);
  499. break;
  500. }
  501. // Determine new stopbits setting
  502. iSel = ComboBox_GetCurSel(this->hwndStopBits);
  503. pdcb->StopBits = (BYTE)ComboBox_GetItemData(this->hwndStopBits, iSel);
  504. // Determine new flow control settings
  505. iSel = ComboBox_GetCurSel(this->hwndFlowCtl);
  506. cmd = (BYTE)ComboBox_GetItemData(this->hwndFlowCtl, iSel);
  507. switch (cmd)
  508. {
  509. case CMD_FLOWCTL_XONXOFF:
  510. pdcb->fOutX = TRUE;
  511. pdcb->fInX = TRUE;
  512. pdcb->fOutxCtsFlow = FALSE;
  513. pdcb->fRtsControl = RTS_CONTROL_DISABLE;
  514. break;
  515. case CMD_FLOWCTL_HARDWARE:
  516. pdcb->fOutX = FALSE;
  517. pdcb->fInX = FALSE;
  518. pdcb->fOutxCtsFlow = TRUE;
  519. pdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
  520. break;
  521. case CMD_FLOWCTL_NONE:
  522. pdcb->fOutX = FALSE;
  523. pdcb->fInX = FALSE;
  524. pdcb->fOutxCtsFlow = FALSE;
  525. pdcb->fRtsControl = RTS_CONTROL_DISABLE;
  526. break;
  527. default:
  528. ASSERT(0); // should never be here
  529. break;
  530. }
  531. this->pportinfo->idRet = IDOK;
  532. }
  533. /*----------------------------------------------------------
  534. Purpose: WM_NOTIFY handler
  535. Returns: varies
  536. Cond: --
  537. */
  538. LRESULT PRIVATE Port_OnNotify(
  539. PPORT this,
  540. int idFrom,
  541. NMHDR FAR * lpnmhdr)
  542. {
  543. LRESULT lRet = 0;
  544. switch (lpnmhdr->code)
  545. {
  546. case PSN_SETACTIVE:
  547. break;
  548. case PSN_KILLACTIVE:
  549. // N.b. This message is not sent if user clicks Cancel!
  550. // N.b. This message is sent prior to PSN_APPLY
  551. //
  552. break;
  553. case PSN_APPLY:
  554. Port_OnApply(this);
  555. break;
  556. default:
  557. break;
  558. }
  559. return lRet;
  560. }
  561. ///////////////////////////////////////////////////// EXPORTED FUNCTIONS
  562. static BOOL s_bPortRecurse = FALSE;
  563. LRESULT INLINE Port_DefProc(
  564. HWND hDlg,
  565. UINT msg,
  566. WPARAM wParam,
  567. LPARAM lParam)
  568. {
  569. ENTER_X()
  570. {
  571. s_bPortRecurse = TRUE;
  572. }
  573. LEAVE_X()
  574. return DefDlgProc(hDlg, msg, wParam, lParam);
  575. }
  576. // Context help header file and arrays for devmgr ports tab
  577. // Created 2/21/98 by WGruber NTUA and DoronH NTDEV
  578. //
  579. // "Port Settings" Dialog Box
  580. //
  581. #define IDH_NOHELP ((DWORD)-1)
  582. #define IDH_DEVMGR_PORTSET_ADVANCED 15840 // "&Advanced" (Button)
  583. #define IDH_DEVMGR_PORTSET_BPS 15841 // "" (ComboBox)
  584. #define IDH_DEVMGR_PORTSET_DATABITS 15842 // "" (ComboBox)
  585. #define IDH_DEVMGR_PORTSET_PARITY 15843 // "" (ComboBox)
  586. #define IDH_DEVMGR_PORTSET_STOPBITS 15844 // "" (ComboBox)
  587. #define IDH_DEVMGR_PORTSET_FLOW 15845 // "" (ComboBox)
  588. #define IDH_DEVMGR_PORTSET_DEFAULTS 15892 // "&Restore Defaults" (Button)
  589. #pragma data_seg(DATASEG_READONLY)
  590. const static DWORD rgHelpIDs[] = { // old winhelp IDs
  591. IDC_STATIC, IDH_NOHELP,
  592. IDC_PS_PORT, IDH_NOHELP,
  593. IDC_PS_LBL_BAUDRATE, IDH_DEVMGR_PORTSET_BPS, // IDH_PORT_BAUD,
  594. IDC_PS_BAUDRATE, IDH_DEVMGR_PORTSET_BPS, // IDH_PORT_BAUD,
  595. IDC_PS_LBL_DATABITS, IDH_DEVMGR_PORTSET_DATABITS, // IDH_PORT_DATA,
  596. IDC_PS_DATABITS, IDH_DEVMGR_PORTSET_DATABITS, // IDH_PORT_DATA,
  597. IDC_PS_LBL_PARITY, IDH_DEVMGR_PORTSET_PARITY, // IDH_PORT_PARITY,
  598. IDC_PS_PARITY, IDH_DEVMGR_PORTSET_PARITY, // IDH_PORT_PARITY,
  599. IDC_PS_LBL_STOPBITS, IDH_DEVMGR_PORTSET_STOPBITS, // IDH_PORT_STOPBITS,
  600. IDC_PS_STOPBITS, IDH_DEVMGR_PORTSET_STOPBITS, // IDH_PORT_STOPBITS,
  601. IDC_PS_LBL_FLOWCTL, IDH_DEVMGR_PORTSET_FLOW, // IDH_PORT_FLOW,
  602. IDC_PS_FLOWCTL, IDH_DEVMGR_PORTSET_FLOW, // IDH_PORT_FLOW,
  603. IDC_PS_PB_RESTORE, IDH_DEVMGR_PORTSET_DEFAULTS, // IDH_PORT_RESTORE,
  604. IDC_PS_ADVANCED, IDH_DEVMGR_PORTSET_ADVANCED,
  605. 0, 0 };
  606. #pragma data_seg()
  607. /*----------------------------------------------------------
  608. Purpose: Real dialog proc
  609. Returns: varies
  610. Cond: --
  611. */
  612. LRESULT Port_DlgProc(
  613. PPORT this,
  614. UINT message,
  615. WPARAM wParam,
  616. LPARAM lParam)
  617. {
  618. switch (message)
  619. {
  620. HANDLE_MSG(this, WM_INITDIALOG, Port_OnInitDialog);
  621. HANDLE_MSG(this, WM_COMMAND, Port_OnCommand);
  622. HANDLE_MSG(this, WM_NOTIFY, Port_OnNotify);
  623. case WM_HELP:
  624. WinHelp(((LPHELPINFO)lParam)->hItemHandle, c_szWinHelpFile, HELP_WM_HELP, (ULONG_PTR)(LPVOID)rgHelpIDs);
  625. return 0;
  626. case WM_CONTEXTMENU:
  627. WinHelp((HWND)wParam, c_szWinHelpFile, HELP_CONTEXTMENU, (ULONG_PTR)(LPVOID)rgHelpIDs);
  628. return 0;
  629. default:
  630. return Port_DefProc(this->hdlg, message, wParam, lParam);
  631. }
  632. }
  633. /*----------------------------------------------------------
  634. Purpose: Dialog Wrapper
  635. Returns: varies
  636. Cond: --
  637. */
  638. INT_PTR CALLBACK Port_WrapperProc(
  639. HWND hDlg, // std params
  640. UINT message,
  641. WPARAM wParam,
  642. LPARAM lParam)
  643. {
  644. PPORT this;
  645. // Cool windowsx.h dialog technique. For full explanation, see
  646. // WINDOWSX.TXT. This supports multiple-instancing of dialogs.
  647. //
  648. ENTER_X()
  649. {
  650. if (s_bPortRecurse)
  651. {
  652. s_bPortRecurse = FALSE;
  653. LEAVE_X()
  654. return FALSE;
  655. }
  656. }
  657. LEAVE_X()
  658. this = Port_GetPtr(hDlg);
  659. if (this == NULL)
  660. {
  661. if (message == WM_INITDIALOG)
  662. {
  663. this = (PPORT)LocalAlloc(LPTR, sizeof(PORT));
  664. if (!this)
  665. {
  666. MsgBox(g_hinst,
  667. hDlg,
  668. MAKEINTRESOURCE(IDS_OOM_PORT),
  669. MAKEINTRESOURCE(IDS_CAP_PORT),
  670. NULL,
  671. MB_ERROR);
  672. EndDialog(hDlg, IDCANCEL);
  673. return (BOOL)Port_DefProc(hDlg, message, wParam, lParam);
  674. }
  675. this->hdlg = hDlg;
  676. Port_SetPtr(hDlg, this);
  677. }
  678. else
  679. {
  680. return (BOOL)Port_DefProc(hDlg, message, wParam, lParam);
  681. }
  682. }
  683. if (message == WM_DESTROY)
  684. {
  685. Port_DlgProc(this, message, wParam, lParam);
  686. LocalFree((HLOCAL)OFFSETOF(this));
  687. Port_SetPtr(hDlg, NULL);
  688. return 0;
  689. }
  690. return SetDlgMsgResult(hDlg, message, Port_DlgProc(this, message, wParam, lParam));
  691. }
  692. #ifdef SUPPORT_FIFO
  693. //
  694. // Advanced Port Settings
  695. //
  696. #pragma data_seg(DATASEG_READONLY)
  697. // Fifo related strings
  698. TCHAR const FAR c_szSettings[] = TEXT("Settings");
  699. TCHAR const FAR c_szComxFifo[] = TEXT("Fifo");
  700. TCHAR const FAR c_szEnh[] = TEXT("386Enh");
  701. TCHAR const FAR c_szSystem[] = TEXT("system.ini");
  702. //
  703. // "Advanced Communications Port Properties" Dialog Box
  704. //
  705. #define IDH_DEVMGR_PORTSET_ADV_USEFIFO 16885 // "&Use FIFO buffers (requires 16550 compatible UART)" (Button)
  706. #define IDH_DEVMGR_PORTSET_ADV_TRANS 16842 // "" (msctls_trackbar32)
  707. // #define IDH_DEVMGR_PORTSET_ADV_DEVICES 161027 // "" (ComboBox)
  708. #define IDH_DEVMGR_PORTSET_ADV_RECV 16821 // "" (msctls_trackbar32)
  709. // #define IDH_DEVMGR_PORTSET_ADV_NUMBER 16846 // "" (ComboBox)
  710. #define IDH_DEVMGR_PORTSET_ADV_DEFAULTS 16844
  711. const DWORD rgAdvHelpIDs[] =
  712. {
  713. IDC_STATIC IDW_NOHELP,
  714. IDC_FIFO_USAGE, IDH_DEVMGR_PORTSET_ADV_USEFIFO, // "Use FIFO buffers (requires 16550 compatible UART)" (Button)
  715. IDC_LBL_RXFIFO, IDH_NOHELP, // "&Receive Buffer:" (Static)
  716. IDC_RXFIFO_USAGE, IDH_DEVMGR_PORTSET_ADV_RECV, // "" (msctls_trackbar32)
  717. IDC_LBL_RXFIFO_LO, IDH_NOHELP, // "Low (%d)" (Static)
  718. IDC_LBL_RXFIFO_HI, IDH_NOHELP, // "High (%d)" (Static)
  719. IDC_LBL_TXFIFO, IDH_NOHELP, // "&Transmit Buffer:" (Static)
  720. IDC_TXFIFO_USAGE, IDH_DEVMGR_PORTSET_ADV_TRANS, // "" (msctls_trackbar32)
  721. IDC_LBL_TXFIFO_LO, IDH_NOHELP, // "Low (%d)" (Static)
  722. IDC_LBL_TXFIFO_HI, IDH_NOHELP, // "High (%d)" (Static)
  723. IDC_DEFAULTS, IDH_DEVMGR_PORTSET_ADV_DEFAULTS,// "&Restore Defaults" (Button)
  724. 0, 0
  725. };
  726. #pragma data_seg()
  727. /*----------------------------------------------------------
  728. Purpose: Set the dialog controls
  729. Returns: --
  730. Cond: --
  731. */
  732. void DisplayAdvSettings(
  733. HWND hDlg,
  734. BYTE RxTrigger,
  735. BYTE TxTrigger,
  736. BOOL bUseFifo)
  737. {
  738. SendDlgItemMessage(hDlg, IDC_RXFIFO_USAGE, TBM_SETRANGE, 0, 0x30000);
  739. SendDlgItemMessage(hDlg, IDC_TXFIFO_USAGE, TBM_SETRANGE, 0, 0x30000);
  740. // Use FIFO?
  741. if ( !bUseFifo )
  742. {
  743. // No
  744. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), FALSE);
  745. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), FALSE);
  746. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), FALSE);
  747. EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), FALSE);
  748. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), FALSE);
  749. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), FALSE);
  750. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), FALSE);
  751. EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), FALSE);
  752. CheckDlgButton(hDlg, IDC_FIFO_USAGE, FALSE);
  753. }
  754. else
  755. {
  756. CheckDlgButton(hDlg, IDC_FIFO_USAGE, TRUE);
  757. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), TRUE);
  758. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), TRUE);
  759. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), TRUE);
  760. EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), TRUE);
  761. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), TRUE);
  762. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), TRUE);
  763. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), TRUE);
  764. EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), TRUE);
  765. SendDlgItemMessage(hDlg, IDC_RXFIFO_USAGE, TBM_SETPOS,
  766. TRUE, RxTrigger);
  767. SendDlgItemMessage(hDlg, IDC_TXFIFO_USAGE, TBM_SETPOS,
  768. TRUE, TxTrigger/4);
  769. }
  770. }
  771. typedef struct tagSETTINGS
  772. {
  773. BYTE fifoon;
  774. BYTE txfifosize;
  775. BYTE dsron;
  776. BYTE rxtriggersize;
  777. } SETTINGS;
  778. typedef enum
  779. {
  780. ACT_GET,
  781. ACT_SET
  782. } ACTION;
  783. BYTE RxTriggerValues[4]={0,0x40,0x80,0xC0};
  784. /*----------------------------------------------------------
  785. Purpose: Gets or sets the advanced settings of the port
  786. Returns: --
  787. Cond: --
  788. */
  789. void GetSetAdvSettings(
  790. LPCTSTR pszPortName,
  791. BYTE FAR *RxTrigger,
  792. BYTE FAR *TxTrigger,
  793. BOOL FAR * pbUseFifo,
  794. ACTION action)
  795. {
  796. LPFINDDEV pfd;
  797. DWORD cbData;
  798. SETTINGS settings;
  799. TCHAR szFifo[256];
  800. TCHAR OnStr[2] = TEXT("0");
  801. ASSERT(pszPortName);
  802. // In Win95, the FIFO settings were (wrongfully) stored in the
  803. // device key. I've changed this to look in the driver key.
  804. // (scotth)
  805. if (FindDev_Create(&pfd, c_pguidPort, c_szFriendlyName, pszPortName) ||
  806. FindDev_Create(&pfd, c_pguidPort, c_szPortName, pszPortName) ||
  807. FindDev_Create(&pfd, c_pguidModem, c_szPortName, pszPortName))
  808. {
  809. switch (action)
  810. {
  811. case ACT_GET:
  812. ASSERT(4 == sizeof(SETTINGS));
  813. cbData = sizeof(SETTINGS);
  814. if (ERROR_SUCCESS != RegQueryValueEx(pfd->hkeyDrv, c_szSettings, NULL,
  815. NULL, (LPBYTE)&settings, &cbData))
  816. {
  817. // Default settings if not in registry
  818. settings.fifoon = 0x02;
  819. settings.dsron = 0;
  820. settings.txfifosize = 16;
  821. settings.rxtriggersize = 0x80;
  822. }
  823. if (!settings.fifoon)
  824. *pbUseFifo = FALSE;
  825. else
  826. *pbUseFifo = TRUE;
  827. settings.rxtriggersize = settings.rxtriggersize % 0xC1;
  828. *RxTrigger = settings.rxtriggersize/0x40;
  829. *TxTrigger = settings.txfifosize % 17;
  830. break;
  831. case ACT_SET:
  832. if (FALSE == *pbUseFifo)
  833. settings.fifoon = 0;
  834. else
  835. settings.fifoon = 2;
  836. settings.rxtriggersize = RxTriggerValues[*RxTrigger];
  837. settings.dsron = 0;
  838. settings.txfifosize = (*TxTrigger)*5+1;
  839. RegSetValueEx(pfd->hkeyDrv, c_szSettings, 0, REG_BINARY,
  840. (LPBYTE)&settings, sizeof(SETTINGS));
  841. break;
  842. default:
  843. ASSERT(0);
  844. break;
  845. }
  846. cbData = sizeof(szFifo) - 6; // leave room for "fifo" on the end
  847. RegQueryValueEx(pfd->hkeyDrv, c_szPortName, NULL, NULL, (LPBYTE)szFifo,
  848. &cbData);
  849. FindDev_Destroy(pfd);
  850. lstrcat(szFifo, c_szComxFifo);
  851. if (*pbUseFifo)
  852. WritePrivateProfileString(c_szEnh, szFifo, NULL, c_szSystem);
  853. else
  854. WritePrivateProfileString(c_szEnh, szFifo, OnStr, c_szSystem);
  855. }
  856. }
  857. /*----------------------------------------------------------
  858. Purpose: Dialog proc for advanced port settings
  859. Returns: standard
  860. Cond: --
  861. */
  862. BOOL CALLBACK AdvPort_DlgProc(
  863. HWND hDlg,
  864. UINT uMsg,
  865. WPARAM wParam,
  866. LPARAM lParam)
  867. {
  868. BOOL bRet = FALSE;
  869. BYTE rxtrigger, txtrigger;
  870. BOOL bUseFifo;
  871. LPCTSTR pszPortName;
  872. switch (uMsg)
  873. {
  874. case WM_INITDIALOG:
  875. pszPortName = (LPCTSTR)lParam;
  876. SetWindowLongPtr(hDlg, DWLP_USER, (ULONG_PTR)pszPortName);
  877. GetSetAdvSettings(pszPortName, &rxtrigger, &txtrigger, &bUseFifo, ACT_GET);
  878. DisplayAdvSettings(hDlg, rxtrigger, txtrigger, bUseFifo);
  879. break;
  880. case WM_COMMAND:
  881. pszPortName = (LPCTSTR)GetWindowLongPtr(hDlg, DWLP_USER);
  882. if (!pszPortName)
  883. {
  884. ASSERT(0);
  885. break;
  886. }
  887. switch (wParam)
  888. {
  889. case IDOK:
  890. if (IsDlgButtonChecked(hDlg, IDC_FIFO_USAGE))
  891. bUseFifo = TRUE;
  892. else
  893. bUseFifo = FALSE;
  894. rxtrigger = (BYTE)SendDlgItemMessage(hDlg,
  895. IDC_RXFIFO_USAGE, TBM_GETPOS, 0, 0);
  896. txtrigger = (BYTE)SendDlgItemMessage(hDlg,
  897. IDC_TXFIFO_USAGE, TBM_GETPOS, 0, 0);
  898. GetSetAdvSettings(pszPortName, &rxtrigger, &txtrigger, &bUseFifo, ACT_SET);
  899. // Fall thru
  900. // | |
  901. // v v
  902. case IDCANCEL:
  903. EndDialog(hDlg, IDOK == wParam);
  904. break;
  905. case IDC_FIFO_USAGE:
  906. if (!IsDlgButtonChecked(hDlg, IDC_FIFO_USAGE))
  907. DisplayAdvSettings(hDlg, 0, 0, FALSE);
  908. else
  909. {
  910. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), TRUE);
  911. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), TRUE);
  912. EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), TRUE);
  913. EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), TRUE);
  914. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), TRUE);
  915. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), TRUE);
  916. EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), TRUE);
  917. EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), TRUE);
  918. }
  919. break;
  920. case IDC_DEFAULTS:
  921. DisplayAdvSettings(hDlg, 2, 12, TRUE);
  922. break;
  923. }
  924. break;
  925. case WM_HELP:
  926. WinHelp(((LPHELPINFO)lParam)->hItemHandle, c_szWinHelpFile, HELP_WM_HELP, (DWORD)(LPVOID)rgAdvHelpIDs);
  927. return 0;
  928. case WM_CONTEXTMENU:
  929. WinHelp((HWND)wParam, c_szWinHelpFile, HELP_CONTEXTMENU, (DWORD)(LPVOID)rgAdvHelpIDs);
  930. return 0;
  931. default:
  932. break;
  933. }
  934. return bRet;
  935. }
  936. /*----------------------------------------------------------
  937. Purpose: Private entry point to show the Advanced Fifo dialog
  938. Returns: IDOK or IDCANCEL
  939. Cond: --
  940. */
  941. UINT WINAPI FeFiFoFum(
  942. HWND hwndOwner,
  943. LPCTSTR pszPortName)
  944. {
  945. UINT uRet = (UINT)-1;
  946. // Invoke the advanced dialog
  947. if (pszPortName)
  948. {
  949. uRet = DialogBoxParam(g_hinst, MAKEINTRESOURCE(IDD_ADV_PORT),
  950. hwndOwner, AdvPort_DlgProc, (LPARAM)pszPortName);
  951. }
  952. return uRet;
  953. }
  954. #endif // SUPPORT_FIFO