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.

1252 lines
30 KiB

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