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.

1258 lines
29 KiB

  1. /*----------------------------------------------------------------------
  2. file: pp.c - property page
  3. @@BEGIN_DDKSPLIT
  4. ToDo_NT50
  5. {
  6. * Bug?: DIF_MOVEDEVICE in class installer opens reg key as READ access
  7. to perform a write.(ports.c)
  8. }
  9. * History:
  10. 7-29-97 - Add this module for NT5.0, kpb
  11. @@END_DDKSPLIT
  12. ----------------------------------------------------------------------*/
  13. #include "ports.h"
  14. #include "pp.h"
  15. // @@BEGIN_DDKSPLIT
  16. BOOL
  17. IsUserAdmin(
  18. VOID
  19. )
  20. /*++
  21. Routine Description:
  22. This routine returns TRUE if the caller's process is a
  23. member of the Administrators local group.
  24. Caller is NOT expected to be impersonating anyone and IS
  25. expected to be able to open their own process and process
  26. token.
  27. Arguments:
  28. None.
  29. Return Value:
  30. TRUE - Caller has Administrators local group.
  31. FALSE - Caller does not have Administrators local group.
  32. --*/
  33. {
  34. HANDLE Token;
  35. DWORD BytesRequired;
  36. PTOKEN_GROUPS Groups;
  37. BOOL b;
  38. DWORD i;
  39. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  40. PSID AdministratorsGroup;
  41. //
  42. // Open the process token.
  43. //
  44. if(!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&Token)) {
  45. return(FALSE);
  46. }
  47. b = FALSE;
  48. Groups = NULL;
  49. //
  50. // Get group information.
  51. //
  52. if(!GetTokenInformation(Token,TokenGroups,NULL,0,&BytesRequired)
  53. && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  54. && (Groups = (PTOKEN_GROUPS)LocalAlloc(LMEM_FIXED,BytesRequired))
  55. && GetTokenInformation(Token,TokenGroups,Groups,BytesRequired,&BytesRequired)) {
  56. b = AllocateAndInitializeSid(
  57. &NtAuthority,
  58. 2,
  59. SECURITY_BUILTIN_DOMAIN_RID,
  60. DOMAIN_ALIAS_RID_ADMINS,
  61. 0, 0, 0, 0, 0, 0,
  62. &AdministratorsGroup
  63. );
  64. if(b) {
  65. //
  66. // See if the user has the administrator group.
  67. //
  68. b = FALSE;
  69. for(i=0; i<Groups->GroupCount; i++) {
  70. if(EqualSid(Groups->Groups[i].Sid,AdministratorsGroup)) {
  71. b = TRUE;
  72. break;
  73. }
  74. }
  75. FreeSid(AdministratorsGroup);
  76. }
  77. }
  78. //
  79. // Clean up and return.
  80. //
  81. if(Groups) {
  82. LocalFree(Groups);
  83. }
  84. CloseHandle(Token);
  85. return(b);
  86. }
  87. // @@END_DDKSPLIT
  88. TCHAR m_szDevMgrHelp[] = _T("devmgr.hlp");
  89. const DWORD HelpIDs[]=
  90. {
  91. IDC_STATIC, IDH_NOHELP,
  92. IDC_ADVANCED, IDH_DEVMGR_PORTSET_ADVANCED, // "&Advanced" (Button)
  93. PP_PORT_BAUDRATE, IDH_DEVMGR_PORTSET_BPS, // "" (ComboBox)
  94. PP_PORT_DATABITS, IDH_DEVMGR_PORTSET_DATABITS, // "" (ComboBox)
  95. PP_PORT_PARITY, IDH_DEVMGR_PORTSET_PARITY, // "" (ComboBox)
  96. PP_PORT_STOPBITS, IDH_DEVMGR_PORTSET_STOPBITS, // "" (ComboBox)
  97. PP_PORT_FLOWCTL, IDH_DEVMGR_PORTSET_FLOW, // "" (ComboBox)
  98. IDC_RESTORE_PORT, IDH_DEVMGR_PORTSET_DEFAULTS, // "&Restore Defaults" (Button)
  99. 0, 0
  100. };
  101. void InitPortParams(
  102. IN OUT PPORT_PARAMS Params,
  103. IN HDEVINFO DeviceInfoSet,
  104. IN PSP_DEVINFO_DATA DeviceInfoData
  105. )
  106. {
  107. BOOL showAdvanced = TRUE;
  108. SP_DEVINFO_LIST_DETAIL_DATA detailData;
  109. ZeroMemory(Params, sizeof(PORT_PARAMS));
  110. Params->DeviceInfoSet = DeviceInfoSet;
  111. Params->DeviceInfoData = DeviceInfoData;
  112. Params->ChangesEnabled = TRUE;
  113. //
  114. // Now we know how big our structure is, so we can allocate memory
  115. //
  116. Params->pAdvancedData =
  117. (PADVANCED_DATA) LocalAlloc(LPTR, sizeof(ADVANCED_DATA));
  118. if (Params->pAdvancedData == NULL) {
  119. //
  120. // Not enough memory
  121. //
  122. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  123. showAdvanced = FALSE;
  124. }
  125. else
  126. {
  127. Params->pAdvancedData->HidePolling = FALSE;
  128. }
  129. //
  130. // See if we are being invoked locally or over the network. If over the net,
  131. // then disable all possible changes.
  132. //
  133. detailData.cbSize = sizeof(SP_DEVINFO_LIST_DETAIL_DATA);
  134. if (SetupDiGetDeviceInfoListDetail(DeviceInfoSet, &detailData) &&
  135. detailData.RemoteMachineHandle != NULL) {
  136. showAdvanced = FALSE;
  137. Params->ChangesEnabled = FALSE;
  138. }
  139. // @@BEGIN_DDKSPLIT
  140. //
  141. // The user can still change the buadrate etc b/c it is written to some
  142. // magic place in the registry, not into the devnode
  143. //
  144. if (!IsUserAdmin()) {
  145. showAdvanced = FALSE;
  146. }
  147. // @@END_DDKSPLIT
  148. if (Params->pAdvancedData)
  149. {
  150. Params->pAdvancedData->DeviceInfoSet = DeviceInfoSet;
  151. Params->pAdvancedData->DeviceInfoData = DeviceInfoData;
  152. }
  153. Params->ShowAdvanced = showAdvanced;
  154. }
  155. HPROPSHEETPAGE InitSettingsPage(PROPSHEETPAGE * psp,
  156. OUT PPORT_PARAMS Params)
  157. {
  158. //
  159. // Add the Port Settings property page
  160. //
  161. psp->dwSize = sizeof(PROPSHEETPAGE);
  162. psp->dwFlags = PSP_USECALLBACK; // | PSP_HASHELP;
  163. psp->hInstance = g_hInst;
  164. psp->pszTemplate = MAKEINTRESOURCE(DLG_PP_PORTSETTINGS);
  165. //
  166. // following points to the dlg window proc
  167. //
  168. psp->pfnDlgProc = PortSettingsDlgProc;
  169. psp->lParam = (LPARAM) Params;
  170. //
  171. // following points to some control callback of the dlg window proc
  172. //
  173. psp->pfnCallback = PortSettingsDlgCallback;
  174. //
  175. // allocate our "Ports Setting" sheet
  176. //
  177. return CreatePropertySheetPage(psp);
  178. }
  179. /*++
  180. Routine Description: SerialPortPropPageProvider
  181. Entry-point for adding additional device manager property
  182. sheet pages. Registry specifies this routine under
  183. Control\Class\PortNode::EnumPropPage32="msports.dll,thisproc"
  184. entry. This entry-point gets called only when the Device
  185. Manager asks for additional property pages.
  186. Arguments:
  187. Info - points to PROPSHEETPAGE_REQUEST, see setupapi.h
  188. AddFunc - function ptr to call to add sheet.
  189. Lparam - add sheet functions private data handle.
  190. Return Value:
  191. BOOL: FALSE if pages could not be added, TRUE on success
  192. --*/
  193. BOOL APIENTRY SerialPortPropPageProvider(LPVOID Info,
  194. LPFNADDPROPSHEETPAGE AddFunc,
  195. LPARAM Lparam
  196. )
  197. {
  198. PSP_PROPSHEETPAGE_REQUEST pprPropPageRequest;
  199. PROPSHEETPAGE psp;
  200. HPROPSHEETPAGE hpsp;
  201. PPORT_PARAMS params = NULL;
  202. pprPropPageRequest = (PSP_PROPSHEETPAGE_REQUEST) Info;
  203. if (PortTypeSerial !=
  204. GetPortType(pprPropPageRequest->DeviceInfoSet,
  205. pprPropPageRequest->DeviceInfoData,
  206. FALSE)) {
  207. return FALSE;
  208. }
  209. //
  210. // Allocate and zero out memory for the struct that will contain
  211. // page specific data
  212. //
  213. params = (PPORT_PARAMS) LocalAlloc(LPTR, sizeof(PORT_PARAMS));
  214. if (!params) {
  215. ErrMemDlg(GetFocus());
  216. return FALSE;
  217. }
  218. if (pprPropPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) {
  219. InitPortParams(params,
  220. pprPropPageRequest->DeviceInfoSet,
  221. pprPropPageRequest->DeviceInfoData);
  222. hpsp = InitSettingsPage(&psp, params);
  223. if (!hpsp) {
  224. return FALSE;
  225. }
  226. if (!(*AddFunc)(hpsp, Lparam)) {
  227. DestroyPropertySheetPage(hpsp);
  228. return FALSE;
  229. }
  230. }
  231. return TRUE;
  232. } /* SerialPortPropPageProvider */
  233. UINT CALLBACK
  234. PortSettingsDlgCallback(HWND hwnd,
  235. UINT uMsg,
  236. LPPROPSHEETPAGE ppsp)
  237. {
  238. PPORT_PARAMS params;
  239. switch (uMsg) {
  240. case PSPCB_CREATE:
  241. return TRUE; // return TRUE to continue with creation of page
  242. case PSPCB_RELEASE:
  243. params = (PPORT_PARAMS) ppsp->lParam;
  244. if (params->pAdvancedData) {
  245. LocalFree(params->pAdvancedData);
  246. }
  247. LocalFree(params);
  248. return 0; // return value ignored
  249. default:
  250. break;
  251. }
  252. return TRUE;
  253. }
  254. void
  255. Port_OnCommand(
  256. HWND DialogHwnd,
  257. int ControlId,
  258. HWND ControlHwnd,
  259. UINT NotifyCode
  260. );
  261. BOOL
  262. Port_OnContextMenu(
  263. HWND HwndControl,
  264. WORD Xpos,
  265. WORD Ypos
  266. );
  267. void
  268. Port_OnHelp(
  269. HWND DialogHwnd,
  270. LPHELPINFO HelpInfo
  271. );
  272. BOOL
  273. Port_OnInitDialog(
  274. HWND DialogHwnd,
  275. HWND FocusHwnd,
  276. LPARAM Lparam
  277. );
  278. BOOL
  279. Port_OnNotify(
  280. HWND DialogHwnd,
  281. LPNMHDR NmHdr
  282. );
  283. /*++
  284. Routine Description: PortSettingsDlgProc
  285. The windows control function for the Port Settings properties window
  286. Arguments:
  287. hDlg, uMessage, wParam, lParam: standard windows DlgProc parameters
  288. Return Value:
  289. BOOL: FALSE if function fails, TRUE if function passes
  290. --*/
  291. INT_PTR APIENTRY
  292. PortSettingsDlgProc(IN HWND hDlg,
  293. IN UINT uMessage,
  294. IN WPARAM wParam,
  295. IN LPARAM lParam)
  296. {
  297. switch(uMessage) {
  298. case WM_COMMAND:
  299. Port_OnCommand(hDlg, (int) LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam));
  300. break;
  301. case WM_CONTEXTMENU:
  302. return Port_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  303. case WM_HELP:
  304. Port_OnHelp(hDlg, (LPHELPINFO) lParam);
  305. break;
  306. case WM_INITDIALOG:
  307. return Port_OnInitDialog(hDlg, (HWND)wParam, lParam);
  308. case WM_NOTIFY:
  309. return Port_OnNotify(hDlg, (NMHDR *)lParam);
  310. }
  311. return FALSE;
  312. } /* PortSettingsDialogProc */
  313. void
  314. Port_OnAdvancedClicked(
  315. HWND DialogHwnd,
  316. PPORT_PARAMS Params
  317. )
  318. {
  319. //
  320. // Initialize the new COM name with the current COM name
  321. //
  322. lstrcpy(Params->pAdvancedData->szNewComName,
  323. Params->PortSettings.szComName);
  324. if (DisplayAdvancedDialog(DialogHwnd, Params->pAdvancedData)) {
  325. //
  326. // Only update if there is a change
  327. //
  328. if (_tcscmp(Params->pAdvancedData->szNewComName,
  329. Params->PortSettings.szComName) != 0) {
  330. lstrcpy(Params->PortSettings.szComName,
  331. Params->pAdvancedData->szNewComName);
  332. }
  333. }
  334. }
  335. void
  336. Port_OnRestorePortClicked(
  337. HWND DialogHwnd,
  338. PPORT_PARAMS Params
  339. )
  340. {
  341. RestorePortSettings(DialogHwnd, Params);
  342. PropSheet_Changed(GetParent(DialogHwnd), DialogHwnd);
  343. }
  344. void
  345. Port_OnCommand(
  346. HWND DialogHwnd,
  347. int ControlId,
  348. HWND ControlHwnd,
  349. UINT NotifyCode
  350. )
  351. {
  352. PPORT_PARAMS params = (PPORT_PARAMS)GetWindowLongPtr(DialogHwnd, DWLP_USER);
  353. if (NotifyCode == CBN_SELCHANGE) {
  354. PropSheet_Changed(GetParent(DialogHwnd), DialogHwnd);
  355. }
  356. else {
  357. switch (ControlId) {
  358. case IDC_ADVANCED:
  359. Port_OnAdvancedClicked(DialogHwnd, params);
  360. break;
  361. case IDC_RESTORE_PORT:
  362. Port_OnRestorePortClicked(DialogHwnd, params);
  363. break;
  364. //
  365. // Because this is a prop sheet, we should never get this.
  366. // All notifications for ctrols outside of the sheet come through
  367. // WM_NOTIFY
  368. //
  369. case IDCANCEL:
  370. EndDialog(DialogHwnd, 0);
  371. return;
  372. }
  373. }
  374. }
  375. BOOL
  376. Port_OnContextMenu(
  377. HWND HwndControl,
  378. WORD Xpos,
  379. WORD Ypos
  380. )
  381. {
  382. WinHelp(HwndControl,
  383. m_szDevMgrHelp,
  384. HELP_CONTEXTMENU,
  385. (ULONG_PTR) HelpIDs);
  386. return FALSE;
  387. }
  388. void
  389. Port_OnHelp(
  390. HWND DialogHwnd,
  391. LPHELPINFO HelpInfo
  392. )
  393. {
  394. if (HelpInfo->iContextType == HELPINFO_WINDOW) {
  395. WinHelp((HWND) HelpInfo->hItemHandle,
  396. m_szDevMgrHelp,
  397. HELP_WM_HELP,
  398. (ULONG_PTR) HelpIDs);
  399. }
  400. }
  401. BOOL
  402. Port_OnInitDialog(
  403. HWND DialogHwnd,
  404. HWND FocusHwnd,
  405. LPARAM Lparam
  406. )
  407. {
  408. PPORT_PARAMS params;
  409. //
  410. // on WM_INITDIALOG call, lParam points to the property
  411. // sheet page.
  412. //
  413. // The lParam field in the property sheet page struct is set by the
  414. // caller. When I created the property sheet, I passed in a pointer
  415. // to a struct containing information about the device. Save this in
  416. // the user window long so I can access it on later messages.
  417. //
  418. params = (PPORT_PARAMS) ((LPPROPSHEETPAGE)Lparam)->lParam;
  419. SetWindowLongPtr(DialogHwnd, DWLP_USER, (ULONG_PTR) params);
  420. //
  421. // Set up the combo boxes with choices
  422. //
  423. FillCommDlg(DialogHwnd);
  424. //
  425. // Read current settings
  426. //
  427. FillPortSettingsDlg(DialogHwnd, params);
  428. EnableWindow(GetDlgItem(DialogHwnd, IDC_ADVANCED),
  429. params->ShowAdvanced);
  430. EnableWindow(GetDlgItem(DialogHwnd, IDC_RESTORE_PORT),
  431. params->ChangesEnabled);
  432. return TRUE; // No need for us to set the focus.
  433. }
  434. BOOL
  435. Port_OnNotify(
  436. HWND DialogHwnd,
  437. LPNMHDR NmHdr
  438. )
  439. {
  440. PPORT_PARAMS params = (PPORT_PARAMS)GetWindowLongPtr(DialogHwnd, DWLP_USER);
  441. switch (NmHdr->code) {
  442. //
  443. // Sent when the user clicks on Apply OR OK !!
  444. //
  445. case PSN_APPLY:
  446. //
  447. // Write out the com port options to the registry
  448. //
  449. SavePortSettingsDlg(DialogHwnd, params);
  450. SetWindowLongPtr(DialogHwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
  451. return TRUE;
  452. default:
  453. return FALSE;
  454. }
  455. }
  456. VOID
  457. SetCBFromRes(
  458. HWND HwndCB,
  459. DWORD ResId,
  460. DWORD Default,
  461. BOOL CheckDecimal)
  462. {
  463. TCHAR szTemp[258], szDecSep[2], cSep;
  464. LPTSTR pThis, pThat, pDecSep;
  465. int iRV;
  466. if (CheckDecimal) {
  467. iRV = GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SDECIMAL,szDecSep,2);
  468. if (iRV == 0) {
  469. //
  470. // following code can take only one char for decimal separator,
  471. // better leave the point as separator
  472. //
  473. CheckDecimal = FALSE;
  474. }
  475. }
  476. if (!LoadString(g_hInst, ResId, szTemp, CharSizeOf(szTemp)))
  477. return;
  478. for (pThis = szTemp, cSep = *pThis++; pThis; pThis = pThat) {
  479. if (pThat = _tcschr( pThis, cSep))
  480. *pThat++ = TEXT('\0');
  481. if(CheckDecimal) {
  482. //
  483. // Assume dec separator in resource is '.', comment was put to this
  484. // effect
  485. //
  486. pDecSep = _tcschr(pThis,TEXT('.'));
  487. if (pDecSep) {
  488. //
  489. // assume decimal sep width == 1
  490. //
  491. *pDecSep = *szDecSep;
  492. }
  493. }
  494. SendMessage(HwndCB, CB_ADDSTRING, 0, (LPARAM) pThis);
  495. }
  496. SendMessage(HwndCB, CB_SETCURSEL, Default, 0L);
  497. }
  498. /*++
  499. Routine Description: FillCommDlg
  500. Fill in baud rate, parity, etc in port dialog box
  501. Arguments:
  502. hDlg: the window address
  503. Return Value:
  504. BOOL: FALSE if function fails, TRUE if function passes
  505. --*/
  506. BOOL
  507. FillCommDlg(
  508. HWND DialogHwnd
  509. )
  510. {
  511. SHORT shIndex;
  512. TCHAR szTemp[81];
  513. //
  514. // just list all of the baud rates
  515. //
  516. for(shIndex = 0; m_nBaudRates[shIndex]; shIndex++) {
  517. MyItoa(m_nBaudRates[shIndex], szTemp, 10);
  518. SendDlgItemMessage(DialogHwnd,
  519. PP_PORT_BAUDRATE,
  520. CB_ADDSTRING,
  521. 0,
  522. (LPARAM)szTemp);
  523. }
  524. //
  525. // Set 9600 as default baud selection
  526. //
  527. shIndex = (USHORT) SendDlgItemMessage(DialogHwnd,
  528. PP_PORT_BAUDRATE,
  529. CB_FINDSTRING,
  530. (WPARAM)-1,
  531. (LPARAM)m_sz9600);
  532. shIndex = (shIndex == CB_ERR) ? 0 : shIndex;
  533. SendDlgItemMessage(DialogHwnd,
  534. PP_PORT_BAUDRATE,
  535. CB_SETCURSEL,
  536. shIndex,
  537. 0L);
  538. for(shIndex = 0; m_nDataBits[shIndex]; shIndex++) {
  539. MyItoa(m_nDataBits[shIndex], szTemp, 10);
  540. SendDlgItemMessage(DialogHwnd,
  541. PP_PORT_DATABITS,
  542. CB_ADDSTRING,
  543. 0,
  544. (LPARAM)szTemp);
  545. }
  546. SendDlgItemMessage(DialogHwnd,
  547. PP_PORT_DATABITS,
  548. CB_SETCURSEL,
  549. DEF_WORD,
  550. 0L);
  551. SetCBFromRes(GetDlgItem(DialogHwnd, PP_PORT_PARITY),
  552. IDS_PARITY,
  553. DEF_PARITY,
  554. FALSE);
  555. SetCBFromRes(GetDlgItem(DialogHwnd, PP_PORT_STOPBITS),
  556. IDS_BITS,
  557. DEF_STOP,
  558. TRUE);
  559. SetCBFromRes(GetDlgItem(DialogHwnd, PP_PORT_FLOWCTL),
  560. IDS_FLOWCONTROL,
  561. DEF_SHAKE,
  562. FALSE);
  563. return 0;
  564. } /* FillCommDlg */
  565. /*++
  566. Routine Description: FillPortSettingsDlg
  567. fill in the port settings dlg sheet
  568. Arguments:
  569. params: the data to fill in
  570. hDlg: address of the window
  571. Return Value:
  572. ULONG: returns error messages
  573. --*/
  574. ULONG
  575. FillPortSettingsDlg(
  576. IN HWND DialogHwnd,
  577. IN PPORT_PARAMS Params
  578. )
  579. {
  580. HKEY hDeviceKey;
  581. DWORD dwPortNameSize, dwError;
  582. TCHAR szCharBuffer[81];
  583. //
  584. // Open the device key for the source device instance, and retrieve its
  585. // "PortName" value.
  586. //
  587. hDeviceKey = SetupDiOpenDevRegKey(Params->DeviceInfoSet,
  588. Params->DeviceInfoData,
  589. DICS_FLAG_GLOBAL,
  590. 0,
  591. DIREG_DEV,
  592. KEY_READ);
  593. if (INVALID_HANDLE_VALUE == hDeviceKey) {
  594. goto RetGetLastError;
  595. }
  596. dwPortNameSize = sizeof(Params->PortSettings.szComName);
  597. dwError = RegQueryValueEx(hDeviceKey,
  598. m_szPortName, // "PortName"
  599. NULL,
  600. NULL,
  601. (PBYTE)Params->PortSettings.szComName,
  602. &dwPortNameSize);
  603. RegCloseKey(hDeviceKey);
  604. if(ERROR_SUCCESS != dwError) {
  605. goto RetERROR;
  606. }
  607. //
  608. // create "com#:"
  609. //
  610. lstrcpy(szCharBuffer, Params->PortSettings.szComName);
  611. lstrcat(szCharBuffer, m_szColon);
  612. //
  613. // get values from system, fills in baudrate, parity, etc.
  614. //
  615. GetPortSettings(DialogHwnd, szCharBuffer, Params);
  616. if (!Params->ChangesEnabled) {
  617. EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_BAUDRATE), FALSE);
  618. EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_PARITY), FALSE);
  619. EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_DATABITS), FALSE);
  620. EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_STOPBITS), FALSE);
  621. EnableWindow(GetDlgItem(DialogHwnd, PP_PORT_FLOWCTL), FALSE);
  622. }
  623. return 0;
  624. RetERROR:
  625. return dwError;
  626. RetGetLastError:
  627. return GetLastError();
  628. } /* FillPortSettingsDlg */
  629. /*++
  630. Routine Description: GetPortSettings
  631. Read in port settings from the system
  632. Arguments:
  633. DialogHwnd: address of the window
  634. ComName: the port we're dealing with
  635. Params: where to put the information we're getting
  636. Return Value:
  637. ULONG: returns error messages
  638. --*/
  639. void
  640. GetPortSettings(
  641. IN HWND DialogHwnd,
  642. IN PTCHAR ComName,
  643. IN PPORT_PARAMS Params
  644. )
  645. {
  646. TCHAR szParms[81];
  647. PTCHAR szCur, szNext;
  648. int nIndex;
  649. int nBaud;
  650. //
  651. // read settings in from system
  652. //
  653. GetProfileString(m_szPorts,
  654. ComName,
  655. g_szNull,
  656. szParms,
  657. 81);
  658. StripBlanks(szParms);
  659. if (lstrlen(szParms) == 0) {
  660. lstrcpy(szParms, m_szDefParams);
  661. WriteProfileString(m_szPorts, ComName, szParms);
  662. }
  663. szCur = szParms;
  664. //
  665. // baud rate
  666. //
  667. szNext = strscan(szCur, m_szComma);
  668. if (*szNext) {
  669. //
  670. // If we found a comma, terminate
  671. //
  672. *szNext++ = 0;
  673. }
  674. //
  675. // current Baud Rate selection
  676. //
  677. if (*szCur) {
  678. Params->PortSettings.BaudRate = myatoi(szCur);
  679. }
  680. else {
  681. //
  682. // must not have been written, use default
  683. //
  684. Params->PortSettings.BaudRate = m_nBaudRates[DEF_BAUD];
  685. }
  686. //
  687. // set the current value in the dialog sheet
  688. //
  689. nIndex = (int)SendDlgItemMessage(DialogHwnd,
  690. PP_PORT_BAUDRATE,
  691. CB_FINDSTRING,
  692. (WPARAM)-1,
  693. (LPARAM)szCur);
  694. nIndex = (nIndex == CB_ERR) ? 0 : nIndex;
  695. SendDlgItemMessage(DialogHwnd,
  696. PP_PORT_BAUDRATE,
  697. CB_SETCURSEL,
  698. nIndex,
  699. 0L);
  700. szCur = szNext;
  701. //
  702. // parity
  703. //
  704. szNext = strscan(szCur, m_szComma);
  705. if (*szNext) {
  706. *szNext++ = 0;
  707. }
  708. StripBlanks(szCur);
  709. switch(*szCur) {
  710. case TEXT('o'):
  711. nIndex = PAR_ODD;
  712. break;
  713. case TEXT('e'):
  714. nIndex = PAR_EVEN;
  715. break;
  716. case TEXT('n'):
  717. nIndex = PAR_NONE;
  718. break;
  719. case TEXT('m'):
  720. nIndex = PAR_MARK;
  721. break;
  722. case TEXT('s'):
  723. nIndex = PAR_SPACE;
  724. break;
  725. default:
  726. nIndex = DEF_PARITY;
  727. break;
  728. }
  729. Params->PortSettings.Parity = nIndex;
  730. SendDlgItemMessage(DialogHwnd,
  731. PP_PORT_PARITY,
  732. CB_SETCURSEL,
  733. nIndex,
  734. 0L);
  735. szCur = szNext;
  736. //
  737. // word length: 4 - 8
  738. //
  739. szNext = strscan(szCur, m_szComma);
  740. if (*szNext) {
  741. *szNext++ = 0;
  742. }
  743. StripBlanks(szCur);
  744. nIndex = *szCur - TEXT('4');
  745. if (nIndex < 0 || nIndex > 4) {
  746. nIndex = DEF_WORD;
  747. }
  748. Params->PortSettings.DataBits = nIndex;
  749. SendDlgItemMessage(DialogHwnd,
  750. PP_PORT_DATABITS,
  751. CB_SETCURSEL,
  752. nIndex,
  753. 0L);
  754. szCur = szNext;
  755. //
  756. // stop bits
  757. //
  758. szNext = strscan(szCur, m_szComma);
  759. if (*szNext) {
  760. *szNext++ = 0;
  761. }
  762. StripBlanks(szCur);
  763. if (!lstrcmp(szCur, TEXT("1"))) {
  764. nIndex = STOP_1;
  765. }
  766. else if(!lstrcmp(szCur, TEXT("1.5"))) {
  767. nIndex = STOP_15;
  768. }
  769. else if(!lstrcmp(szCur, TEXT("2"))) {
  770. nIndex = STOP_2;
  771. }
  772. else {
  773. nIndex = DEF_STOP;
  774. }
  775. SendDlgItemMessage(DialogHwnd,
  776. PP_PORT_STOPBITS,
  777. CB_SETCURSEL,
  778. nIndex,
  779. 0L);
  780. Params->PortSettings.StopBits = nIndex;
  781. szCur = szNext;
  782. //
  783. // handshaking: Hardware, xon/xoff, or none
  784. //
  785. szNext = strscan(szCur, m_szComma);
  786. if (*szNext) {
  787. *szNext++ = 0;
  788. }
  789. StripBlanks(szCur);
  790. if (*szCur == TEXT('p')) {
  791. nIndex = FLOW_HARD;
  792. }
  793. else if (*szCur == TEXT('x')) {
  794. nIndex = FLOW_XON;
  795. }
  796. else {
  797. nIndex = FLOW_NONE;
  798. }
  799. SendDlgItemMessage(DialogHwnd,
  800. PP_PORT_FLOWCTL,
  801. CB_SETCURSEL,
  802. nIndex,
  803. 0L);
  804. Params->PortSettings.FlowControl = nIndex;
  805. } /* GetPortSettings */
  806. void
  807. RestorePortSettings(
  808. HWND DialogHwnd,
  809. PPORT_PARAMS Params
  810. )
  811. {
  812. UINT nIndex;
  813. //
  814. // baud rate
  815. //
  816. nIndex = (UINT)SendDlgItemMessage(DialogHwnd,
  817. PP_PORT_BAUDRATE,
  818. CB_FINDSTRING,
  819. (WPARAM)-1,
  820. (LPARAM)TEXT("9600"));
  821. nIndex = (nIndex == CB_ERR) ? 0 : nIndex;
  822. SendDlgItemMessage(DialogHwnd,
  823. PP_PORT_BAUDRATE,
  824. CB_SETCURSEL,
  825. nIndex,
  826. 0L);
  827. //
  828. // parity
  829. //
  830. SendDlgItemMessage(DialogHwnd,
  831. PP_PORT_PARITY,
  832. CB_SETCURSEL,
  833. PAR_NONE,
  834. 0L);
  835. //
  836. // word length: 4 - 8
  837. //
  838. SendDlgItemMessage(DialogHwnd,
  839. PP_PORT_DATABITS,
  840. CB_SETCURSEL,
  841. 4, // the 4th index is 8, what we want
  842. 0L);
  843. //
  844. // stop bits
  845. //
  846. SendDlgItemMessage(DialogHwnd,
  847. PP_PORT_STOPBITS,
  848. CB_SETCURSEL,
  849. STOP_1,
  850. 0L);
  851. //
  852. // handshaking: Hardware, xon/xoff, or none
  853. //
  854. SendDlgItemMessage(DialogHwnd,
  855. PP_PORT_FLOWCTL,
  856. CB_SETCURSEL,
  857. FLOW_NONE,
  858. 0L);
  859. // nIndex = FLOW_HARD;
  860. // nIndex = FLOW_XON;
  861. // nIndex = FLOW_NONE;
  862. }
  863. /*++
  864. Routine Description: SavePortSettingsDlg
  865. save changes in the Ports Settings dlg sheet
  866. Arguments:
  867. Params: where to save the data to
  868. ParentHwnd: address of the window
  869. Return Value:
  870. ULONG: returns error messages
  871. --*/
  872. ULONG
  873. SavePortSettingsDlg(
  874. IN HWND DialogHwnd,
  875. IN PPORT_PARAMS Params
  876. )
  877. {
  878. TCHAR szCharBuffer[81];
  879. DWORD dwPortnum, dwOldPortnum;
  880. DWORD dwPortNameSize, dwError;
  881. TCHAR szNewComName[21];
  882. TCHAR szSerialKey[41];
  883. TCHAR szTitle[81];
  884. TCHAR szTitleFormat[81];
  885. HKEY hDeviceKey, hKey;
  886. //
  887. // create "com#:"
  888. //
  889. // lstrcpy(szCharBuffer, Params->pAdvancedData->szNewComName);
  890. lstrcpy(szCharBuffer, Params->PortSettings.szComName);
  891. lstrcat(szCharBuffer, m_szColon);
  892. //
  893. // store changes to win.ini; broadcast changes to apps
  894. //
  895. SavePortSettings(DialogHwnd, szCharBuffer, Params);
  896. return 0;
  897. } /* SavePortSettingsDlg */
  898. /*++
  899. Routine Description: SavePortSettings
  900. Read the dlg screen selections for baudrate, parity, etc.
  901. If changed from what we started with, then save them
  902. Arguments:
  903. hDlg: address of the window
  904. szComName: which comport we're dealing with
  905. Params: contains, baudrate, parity, etc
  906. Return Value:
  907. ULONG: returns error messages
  908. --*/
  909. void
  910. SavePortSettings(
  911. IN HWND DialogHwnd,
  912. IN PTCHAR ComName,
  913. IN PPORT_PARAMS Params
  914. )
  915. {
  916. TCHAR szBuild[PATHMAX];
  917. ULONG i;
  918. PP_PORTSETTINGS pppNewPortSettings;
  919. //
  920. // Get the baud rate
  921. //
  922. i = (ULONG)SendDlgItemMessage(DialogHwnd,
  923. PP_PORT_BAUDRATE,
  924. WM_GETTEXT,
  925. 18,
  926. (LPARAM)szBuild);
  927. if (!i) {
  928. goto Return;
  929. }
  930. pppNewPortSettings.BaudRate = myatoi(szBuild);
  931. //
  932. // Get the parity setting
  933. //
  934. i = (ULONG)SendDlgItemMessage(DialogHwnd,
  935. PP_PORT_PARITY,
  936. CB_GETCURSEL,
  937. 0,
  938. 0L);
  939. if (i == CB_ERR || i == CB_ERRSPACE) {
  940. goto Return;
  941. }
  942. pppNewPortSettings.Parity = i;
  943. lstrcat(szBuild, m_pszParitySuf[i]);
  944. //
  945. // Get the word length
  946. //
  947. i = (ULONG)SendDlgItemMessage(DialogHwnd,
  948. PP_PORT_DATABITS,
  949. CB_GETCURSEL,
  950. 0,
  951. 0L);
  952. if (i == CB_ERR || i == CB_ERRSPACE) {
  953. goto Return;
  954. }
  955. pppNewPortSettings.DataBits = i;
  956. lstrcat(szBuild, m_pszLenSuf[i]);
  957. //
  958. // Get the stop bits
  959. //
  960. i = (ULONG)SendDlgItemMessage(DialogHwnd,
  961. PP_PORT_STOPBITS,
  962. CB_GETCURSEL,
  963. 0,
  964. 0L);
  965. if (i == CB_ERR || i == CB_ERRSPACE) {
  966. goto Return;
  967. }
  968. pppNewPortSettings.StopBits = i;
  969. lstrcat(szBuild, m_pszStopSuf[i]);
  970. //
  971. // Get the flow control
  972. //
  973. i = (ULONG)SendDlgItemMessage(DialogHwnd,
  974. PP_PORT_FLOWCTL,
  975. CB_GETCURSEL,
  976. 0,
  977. 0L);
  978. if (i == CB_ERR || i == CB_ERRSPACE) {
  979. goto Return;
  980. }
  981. pppNewPortSettings.FlowControl = i;
  982. lstrcat(szBuild, m_pszFlowSuf[i]);
  983. //
  984. // if any of the values changed, then save it off
  985. //
  986. if (Params->PortSettings.BaudRate != pppNewPortSettings.BaudRate ||
  987. Params->PortSettings.Parity != pppNewPortSettings.Parity ||
  988. Params->PortSettings.DataBits != pppNewPortSettings.DataBits ||
  989. Params->PortSettings.StopBits != pppNewPortSettings.StopBits ||
  990. Params->PortSettings.FlowControl != pppNewPortSettings.FlowControl) {
  991. //
  992. // Write settings string to [ports] section in win.ini
  993. // NT translates this if a translate key is set in registry
  994. // and it winds up getting written to
  995. // HKLM\Software\Microsoft\Windows NT\CurrentVersion\Ports
  996. //
  997. WriteProfileString(m_szPorts, ComName, szBuild);
  998. //
  999. // Send global notification message to all windows
  1000. //
  1001. SendWinIniChange((LPTSTR)m_szPorts);
  1002. if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
  1003. Params->DeviceInfoSet,
  1004. Params->DeviceInfoData)) {
  1005. //
  1006. // Possibly do something here
  1007. //
  1008. }
  1009. }
  1010. Return:
  1011. return;
  1012. } /* SavePortSettings */