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.

1899 lines
51 KiB

  1. ///////////////////////////////////////////////////////////////////////////
  2. // Advanced Dialog Functions
  3. ///////////////////////////////////////////////////////////////////////////
  4. #include "ports.h"
  5. #include "pp.h"
  6. #include <windowsx.h>
  7. #define COBJMACROS 1
  8. #include <ole2.h>
  9. #include <initguid.h>
  10. #include <oleacc.h>
  11. #include <winable.h>
  12. //
  13. // write out values in tenths of a sec
  14. //
  15. #define SECONDS_CONVERSION_FACTOR (10)
  16. #define NUM_POLLING_PERIODS 7
  17. DWORD PollingPeriods[NUM_POLLING_PERIODS] = {
  18. -1,
  19. 0,
  20. 1 * SECONDS_CONVERSION_FACTOR,
  21. 5 * SECONDS_CONVERSION_FACTOR,
  22. 10 * SECONDS_CONVERSION_FACTOR,
  23. 30 * SECONDS_CONVERSION_FACTOR,
  24. 60 * SECONDS_CONVERSION_FACTOR
  25. };
  26. TCHAR PeriodDescription[NUM_POLLING_PERIODS+1][40] = {
  27. { _T("Disabled") },
  28. { _T("Manually") },
  29. { _T("Every second") },
  30. { _T("Every 5 seconds") },
  31. { _T("Every 10 seconds") },
  32. { _T("Every 30 seconds") },
  33. { _T("Every minute") },
  34. { _T("Other (every %d sec)") }
  35. };
  36. ULONG RxValues[4] = { 1, 4, 8, 14};
  37. WCHAR RxValuesStringMap[] = L"A:0:1:1:2:4:3:8:4:14:";
  38. WCHAR TxValuesStringMap[] = L"use_raw";
  39. TCHAR m_szRxFIFO[] = _T("RxFIFO");
  40. TCHAR m_szTxFIFO[] = _T("TxFIFO");
  41. TCHAR m_szFifoRxMax[] = _T("FifoRxMax");
  42. TCHAR m_szFifoTxMax[] = _T("FifoTxMax");
  43. const DWORD AdvanHelpIDs[] =
  44. {
  45. IDC_DESC_1, IDH_NOHELP,
  46. IDC_DESC_2, IDH_NOHELP,
  47. IDC_FIFO, IDH_DEVMGR_PORTSET_ADV_USEFIFO, // "Use FIFO buffers (requires 16550 compatible UART)" (Button)
  48. IDC_RECEIVE_TEXT, IDH_NOHELP, // "&Receive Buffer:" (Static)
  49. IDC_RECEIVE_SLIDER, IDH_DEVMGR_PORTSET_ADV_RECV, // "" (msctls_trackbar32)
  50. IDC_RECEIVE_LOW, IDH_NOHELP, // "Low (%d)" (Static)
  51. IDC_RECEIVE_HIGH, IDH_NOHELP, // "High (%d)" (Static)
  52. IDC_RXVALUE, IDH_NOHELP,
  53. IDC_TRANSMIT_TEXT, IDH_NOHELP, // "&Transmit Buffer:" (Static)
  54. IDC_TRANSMIT_SLIDER, IDH_DEVMGR_PORTSET_ADV_TRANS, // "" (msctls_trackbar32)
  55. IDC_TRANSMIT_LOW, IDH_NOHELP, // "Low (%d)" (Static)
  56. IDC_TRANSMIT_HIGH, IDH_NOHELP, // "High (%d)" (Static)
  57. IDC_TXVALUE, IDH_NOHELP,
  58. IDC_POLL_DESC, IDH_NOHELP,
  59. IDC_POLL_PERIOD, IDH_DEVMGR_PORTSET_ADV_DEVICES, // "" (ComboBox)
  60. PP_PORT_NUMBER, IDH_DEVMGR_PORTSET_ADV_NUMBER, // "" (ComboBox)
  61. IDC_COMNUMTEXT, IDH_NOHELP, // "COM &Port Number:" (Static)
  62. IDC_RESTORE, IDH_DEVMGR_PORTSET_ADV_DEFAULTS,// "&Restore Defaults" (Button)
  63. 0, 0
  64. };
  65. #define Trackbar_SetPos(hwndTb, Redraw, Position)\
  66. (VOID) SendMessage(hwndTb, TBM_SETPOS, (WPARAM) Redraw, (LPARAM) Position)
  67. #define Trackbar_SetRange(hwndTb, Redraw, MinVal, MaxVal)\
  68. (VOID) SendMessage(hwndTb, TBM_SETRANGE, (WPARAM) Redraw, (LPARAM) MAKELONG(MinVal, MaxVal))
  69. #define Trackbar_SetTic(hwndTb, Tic)\
  70. (VOID) SendMessage(hwndTb, TBM_SETTIC, (WPARAM) 0, (LPARAM) Tic)
  71. #define Trackbar_GetPos(hwndTb)\
  72. (DWORD) SendMessage(hwndTb, TBM_GETPOS, (WPARAM) 0, (LPARAM) 0)
  73. BOOL
  74. Advanced_OnCommand(
  75. HWND ParentHwnd,
  76. int ControlId,
  77. HWND ControlHwnd,
  78. UINT NotifyCode
  79. );
  80. BOOL
  81. Advanced_OnContextMenu(
  82. HWND HwndControl,
  83. WORD Xpos,
  84. WORD Ypos
  85. );
  86. void
  87. Advanced_OnHelp(
  88. HWND ParentHwnd,
  89. LPHELPINFO HelpInfo
  90. );
  91. BOOL
  92. Advanced_OnInitDialog(
  93. HWND ParentHwnd,
  94. HWND FocusHwnd,
  95. LPARAM Lparam
  96. );
  97. /*++
  98. Routine Description: AdvancedPortsDlgProc
  99. The windows proc for the Advanced properties window
  100. Arguments:
  101. hDlg, uMessage, wParam, lParam: standard windows DlgProc parameters
  102. Return Value:
  103. BOOL: FALSE if the page could not be created
  104. --*/
  105. INT_PTR APIENTRY
  106. AdvancedPortsDlgProc(
  107. IN HWND hDlg,
  108. IN UINT uMessage,
  109. IN WPARAM wParam,
  110. IN LPARAM lParam
  111. )
  112. {
  113. switch(uMessage) {
  114. case WM_COMMAND:
  115. return Advanced_OnCommand(hDlg,
  116. (int) LOWORD(wParam),
  117. (HWND)lParam,
  118. (UINT) HIWORD(wParam));
  119. case WM_CONTEXTMENU:
  120. return Advanced_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  121. case WM_HELP:
  122. Advanced_OnHelp(hDlg, (LPHELPINFO) lParam);
  123. break;
  124. case WM_HSCROLL:
  125. HandleTrackbarChange(hDlg, (HWND) lParam);
  126. return TRUE;
  127. case WM_INITDIALOG:
  128. return Advanced_OnInitDialog(hDlg, (HWND) wParam, lParam);
  129. }
  130. return FALSE;
  131. } /* AdvancedPortsDlgProc */
  132. BOOL
  133. Advanced_OnCommand(
  134. HWND ParentHwnd,
  135. int ControlId,
  136. HWND ControlHwnd,
  137. UINT NotifyCode
  138. )
  139. {
  140. PADVANCED_DATA advancedData =
  141. (PADVANCED_DATA) GetWindowLongPtr(ParentHwnd, DWLP_USER);
  142. switch(ControlId) {
  143. case IDC_FIFO:
  144. //
  145. // Disable or enable the sliders
  146. //
  147. EnableFifoControls(ParentHwnd, IsDlgButtonChecked(ParentHwnd, IDC_FIFO));
  148. return TRUE;
  149. case IDOK:
  150. SaveAdvancedSettings(ParentHwnd, advancedData);
  151. // fall through
  152. case IDCANCEL:
  153. EndDialog(ParentHwnd, ControlId);
  154. return TRUE;
  155. case IDC_RESTORE:
  156. RestoreAdvancedDefaultState(ParentHwnd, advancedData);
  157. return TRUE;
  158. }
  159. return FALSE;
  160. }
  161. BOOL
  162. Advanced_OnContextMenu(
  163. HWND HwndControl,
  164. WORD Xpos,
  165. WORD Ypos
  166. )
  167. {
  168. WinHelp(HwndControl,
  169. m_szDevMgrHelp,
  170. HELP_CONTEXTMENU,
  171. (ULONG_PTR) AdvanHelpIDs);
  172. return FALSE;
  173. }
  174. void
  175. Advanced_OnHelp(
  176. HWND ParentHwnd,
  177. LPHELPINFO HelpInfo
  178. )
  179. {
  180. if (HelpInfo->iContextType == HELPINFO_WINDOW) {
  181. WinHelp((HWND) HelpInfo->hItemHandle,
  182. m_szDevMgrHelp,
  183. HELP_WM_HELP,
  184. (ULONG_PTR) AdvanHelpIDs);
  185. }
  186. }
  187. BOOL
  188. Advanced_OnInitDialog(
  189. HWND ParentHwnd,
  190. HWND FocusHwnd,
  191. LPARAM Lparam
  192. )
  193. {
  194. PADVANCED_DATA advancedData;
  195. TCHAR szFormat[200];
  196. TCHAR szBuffer[200];
  197. advancedData = (PADVANCED_DATA) Lparam;
  198. //
  199. // Initialize the dialog box parameters
  200. //
  201. FillAdvancedDlg(ParentHwnd, advancedData);
  202. SetWindowLongPtr(ParentHwnd, DWLP_USER, (ULONG_PTR) advancedData);
  203. //
  204. // Set up the dialog box with these initialized parameters
  205. //
  206. InitializeControls(ParentHwnd, advancedData);
  207. LoadString(g_hInst, IDS_ADVANCED_SETTINGS_FOR, szFormat, CharSizeOf(szFormat));
  208. wsprintf(szBuffer, szFormat, advancedData->szComName);
  209. SetWindowText(ParentHwnd, szBuffer);
  210. return TRUE;
  211. }
  212. // @@BEGIN_DDKSPLIT
  213. LONG
  214. SerialDisplayAdvancedSettings(
  215. IN HWND ParentHwnd,
  216. IN HDEVINFO DeviceInfoSet,
  217. IN PSP_DEVINFO_DATA DeviceInfoData
  218. )
  219. {
  220. ADVANCED_DATA advancedData;
  221. HKEY hDeviceKey;
  222. DWORD dwPortNameSize;
  223. if (!DeviceInfoSet) {
  224. return ERROR_INVALID_PARAMETER;
  225. }
  226. advancedData.HidePolling = TRUE;
  227. advancedData.DeviceInfoSet = DeviceInfoSet;
  228. advancedData.DeviceInfoData = DeviceInfoData;
  229. //
  230. // Open the device key for the source device instance, and retrieve its
  231. // "PortName" value.
  232. //
  233. hDeviceKey = SetupDiOpenDevRegKey(DeviceInfoSet,
  234. DeviceInfoData,
  235. DICS_FLAG_GLOBAL,
  236. 0,
  237. DIREG_DEV,
  238. KEY_READ);
  239. if (INVALID_HANDLE_VALUE == hDeviceKey)
  240. return ERROR_ACCESS_DENIED;
  241. dwPortNameSize = sizeof(advancedData.szComName);
  242. if (RegQueryValueEx(hDeviceKey,
  243. m_szPortName,
  244. NULL,
  245. NULL,
  246. (PBYTE) advancedData.szComName,
  247. &dwPortNameSize) != ERROR_SUCCESS) {
  248. RegCloseKey(hDeviceKey);
  249. return ERROR_INVALID_DATA;
  250. }
  251. RegCloseKey(hDeviceKey);
  252. return DisplayAdvancedDialog(ParentHwnd, &advancedData) ? ERROR_SUCCESS
  253. : ERROR_ACCESS_DENIED;
  254. }
  255. // @@END_DDKSPLIT
  256. BOOL InternalAdvancedDialog(
  257. IN HWND ParentHwnd,
  258. IN OUT PADVANCED_DATA AdvancedData
  259. )
  260. {
  261. AdvancedData->hComDB = HCOMDB_INVALID_HANDLE_VALUE;
  262. ComDBOpen(&AdvancedData->hComDB);
  263. DialogBoxParam(g_hInst,
  264. MAKEINTRESOURCE(DLG_PP_ADVPORTS),
  265. ParentHwnd,
  266. AdvancedPortsDlgProc,
  267. (DWORD_PTR) AdvancedData);
  268. ComDBClose(AdvancedData->hComDB);
  269. AdvancedData->hComDB = HCOMDB_INVALID_HANDLE_VALUE;
  270. return TRUE;
  271. }
  272. // @@BEGIN_DDKSPLIT
  273. BOOL
  274. FindAdvancedDialogOverride(
  275. IN HDEVINFO DeviceInfoSet,
  276. IN PSP_DEVINFO_DATA DeviceInfoData,
  277. IN PTCHAR Value
  278. )
  279. /*++
  280. Routine Description:
  281. Checks the driver key in the devnode for the override value.
  282. Arguments:
  283. DeviceInfoSet - Supplies a handle to the device information
  284. DeviceInfoData - Supplies the address of the device information element
  285. Value - Value read in from the registry
  286. Return Value:
  287. If found TRUE, otherwise FALSE
  288. --*/
  289. {
  290. HKEY hKey;
  291. TCHAR szLine[LINE_LEN];
  292. DWORD dwDataType, dwSize;
  293. TCHAR szOverrideName[] = _T("EnumAdvancedDialog");
  294. //
  295. // Open up the driver key for this device so we can run our INF registry mods
  296. // against it.
  297. //
  298. hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
  299. DeviceInfoData,
  300. DICS_FLAG_GLOBAL,
  301. 0,
  302. DIREG_DRV,
  303. KEY_READ);
  304. dwSize = sizeof(szLine);
  305. if (RegQueryValueEx(hKey,
  306. szOverrideName,
  307. NULL,
  308. &dwDataType,
  309. (PBYTE) &szLine,
  310. &dwSize) != ERROR_SUCCESS ||
  311. dwDataType != REG_SZ) {
  312. RegCloseKey(hKey);
  313. return FALSE;
  314. }
  315. lstrcpy(Value, szLine);
  316. RegCloseKey(hKey);
  317. return TRUE;
  318. }
  319. BOOL
  320. CallAdvancedDialogOverride(
  321. IN HWND ParentHwnd,
  322. IN PADVANCED_DATA AdvancedData,
  323. PTCHAR Override,
  324. PBOOL Success
  325. )
  326. {
  327. PTCHAR szProc = NULL;
  328. HINSTANCE hInst = NULL;
  329. PPORT_ADVANCED_DIALOG pfnAdvanced = NULL;
  330. TCHAR szNewComName[50];
  331. HKEY hDeviceKey;
  332. DWORD dwSize;
  333. TCHAR szMfg[LINE_LEN];
  334. #ifdef UNICODE
  335. CHAR szFunction[LINE_LEN];
  336. #endif
  337. szProc = _tcschr(Override, _T(','));
  338. if (!szProc) {
  339. return FALSE;
  340. }
  341. *szProc = _T('\0');
  342. szProc++;
  343. hInst = LoadLibrary(Override);
  344. if (!hInst) {
  345. return FALSE;
  346. }
  347. #ifdef UNICODE
  348. WideCharToMultiByte(CP_ACP,
  349. 0,
  350. szProc,
  351. lstrlen(szProc) + 1,
  352. szFunction,
  353. sizeof(szFunction),
  354. NULL,
  355. NULL);
  356. pfnAdvanced = (PPORT_ADVANCED_DIALOG) GetProcAddress(hInst, szFunction);
  357. #else
  358. pfnAdvanced = (PPORT_ADVANCED_DIALOG) GetProcAddress(hInst, szProc);
  359. #endif
  360. if (!pfnAdvanced) {
  361. FreeLibrary(hInst);
  362. return FALSE;
  363. }
  364. _try
  365. {
  366. *Success = (*pfnAdvanced) (ParentHwnd,
  367. AdvancedData->HidePolling,
  368. AdvancedData->DeviceInfoSet,
  369. AdvancedData->DeviceInfoData,
  370. NULL);
  371. }
  372. _except(UnhandledExceptionFilter(GetExceptionInformation()))
  373. {
  374. *Success = FALSE;
  375. }
  376. //
  377. // Make sure the new com name is zero terminated in case of error
  378. //
  379. AdvancedData->szComName[0] = TEXT('\0');
  380. //
  381. // Open the device key for the source device instance, and retrieve its
  382. // "PortName" value in case the override dialog changed it.
  383. //
  384. hDeviceKey = SetupDiOpenDevRegKey(AdvancedData->DeviceInfoSet,
  385. AdvancedData->DeviceInfoData,
  386. DICS_FLAG_GLOBAL,
  387. 0,
  388. DIREG_DEV,
  389. KEY_READ);
  390. if (INVALID_HANDLE_VALUE != hDeviceKey) {
  391. dwSize = sizeof(szNewComName);
  392. if (RegQueryValueEx(hDeviceKey,
  393. m_szPortName,
  394. NULL,
  395. NULL,
  396. (PBYTE) szNewComName,
  397. &dwSize) == ERROR_SUCCESS) {
  398. lstrcpy(AdvancedData->szComName, szNewComName);
  399. }
  400. RegCloseKey(hDeviceKey);
  401. }
  402. FreeLibrary(hInst);
  403. return TRUE;
  404. }
  405. // @@END_DDKSPLIT
  406. /*++
  407. Routine Description: DisplayAdvancedDialog
  408. Opens the devices instance and checks to see if it is valid. If so, then the advanced
  409. dialog is displayed. Otherwise a message is displayed to the user stating that the user
  410. does not have write access to this particular key.
  411. Arguments:
  412. ParentHwnd - Handle to the parent dialog (Port Settings Property Sheet)
  413. AdvancedData - hDeviceKey will be set with the device's key in the registry upon success,
  414. INVALID_HANDLE_VALUE upon error
  415. Return Value:
  416. None
  417. --*/
  418. BOOL DisplayAdvancedDialog(
  419. IN HWND ParentHwnd,
  420. IN OUT PADVANCED_DATA AdvancedData
  421. )
  422. {
  423. AdvancedData->hDeviceKey =
  424. SetupDiOpenDevRegKey(AdvancedData->DeviceInfoSet,
  425. AdvancedData->DeviceInfoData,
  426. DICS_FLAG_GLOBAL,
  427. 0,
  428. DIREG_DEV,
  429. KEY_ALL_ACCESS);
  430. if (AdvancedData->hDeviceKey == INVALID_HANDLE_VALUE) {
  431. MyMessageBox(ParentHwnd,
  432. IDS_NO_WRITE_PRVILEGE,
  433. IDS_NAME_PROPERTIES,
  434. MB_OK | MB_ICONINFORMATION);
  435. return FALSE;
  436. }
  437. else {
  438. // @@BEGIN_DDKSPLIT
  439. TCHAR szOverride[LINE_LEN];
  440. BOOL success = FALSE;
  441. if (FindAdvancedDialogOverride(AdvancedData->DeviceInfoSet,
  442. AdvancedData->DeviceInfoData,
  443. szOverride) &&
  444. CallAdvancedDialogOverride(ParentHwnd,
  445. AdvancedData,
  446. szOverride,
  447. &success)) {
  448. RegCloseKey(AdvancedData->hDeviceKey);
  449. return success;
  450. }
  451. else {
  452. // @@END_DDKSPLIT
  453. return InternalAdvancedDialog(ParentHwnd, AdvancedData);
  454. // @@BEGIN_DDKSPLIT
  455. }
  456. // @@END_DDKSPLIT
  457. }
  458. }
  459. /*++
  460. Routine Description: EnableFifoControls
  461. Enables/Disables all of the controls bounded by the rectangle with the Use Fifo
  462. checkbox.
  463. Arguments:
  464. hDlg - Handle to the dialog
  465. enabled - flag to either enable/disable the controls
  466. Return Value:
  467. None
  468. --*/
  469. void EnableFifoControls(IN HWND hDlg,
  470. IN BOOL enabled)
  471. {
  472. // The actual trackbar/slider
  473. EnableWindow(GetDlgItem(hDlg, IDC_RECEIVE_SLIDER), enabled);
  474. // "Low (xxx)" (Receive)
  475. EnableWindow(GetDlgItem(hDlg, IDC_RECEIVE_LOW), enabled);
  476. // "High (xxx)" (Receive)
  477. EnableWindow(GetDlgItem(hDlg, IDC_RECEIVE_HIGH), enabled);
  478. // "Receive Buffer: "
  479. EnableWindow(GetDlgItem(hDlg, IDC_RECEIVE_TEXT), enabled);
  480. // "(xxx)" (Actual value of trackbar, Receive)
  481. EnableWindow(GetDlgItem(hDlg, IDC_RXVALUE), enabled);
  482. // The actual trackbar/slider
  483. EnableWindow(GetDlgItem(hDlg, IDC_TRANSMIT_SLIDER), enabled);
  484. // "Low (xxx)" (Transmit)
  485. EnableWindow(GetDlgItem(hDlg, IDC_TRANSMIT_LOW), enabled);
  486. // "High (xxx)" (Transmit)
  487. EnableWindow(GetDlgItem(hDlg, IDC_TRANSMIT_HIGH), enabled);
  488. // "Transmit Buffer" (Transmit)
  489. EnableWindow(GetDlgItem(hDlg, IDC_TRANSMIT_TEXT), enabled);
  490. // "(xxx)" (Actual value of trackbar, Trasmist)
  491. EnableWindow(GetDlgItem(hDlg, IDC_TXVALUE), enabled);
  492. }
  493. /*++
  494. Routine Description: HandleTrackbarChange
  495. Whenever the user changes the trackbar thumb position, update the control
  496. to its right which displays its actual numeric value
  497. Arguments:
  498. hDlg - Handle to the parent dialog
  499. hTrackbar - Handle to the trackbar whose thumb has changed
  500. Return Value:
  501. None
  502. --*/
  503. void HandleTrackbarChange(IN HWND hDlg,
  504. IN HWND hTrackbar
  505. )
  506. {
  507. DWORD ctrlID;
  508. TCHAR szCurrentValue[10];
  509. ULONG position;
  510. position = Trackbar_GetPos(hTrackbar);
  511. if (GetDlgCtrlID(hTrackbar) == IDC_RECEIVE_SLIDER) {
  512. //
  513. // Rx we need to translate the tick position from index to value
  514. //
  515. wsprintf(szCurrentValue, TEXT("(%d)"), RxValues[position-1]);
  516. ctrlID = IDC_RXVALUE;
  517. }
  518. else {
  519. //
  520. // Tx is just a straight translation between value and index
  521. //
  522. wsprintf(szCurrentValue, TEXT("(%d)"), position);
  523. ctrlID = IDC_TXVALUE;
  524. }
  525. SetDlgItemText(hDlg, ctrlID, szCurrentValue);
  526. }
  527. DWORD
  528. RxValueToTrackbarPosition(IN OUT PDWORD RxValue
  529. )
  530. {
  531. switch (*RxValue) {
  532. case 1: return 1;
  533. case 4: return 2;
  534. case 8: return 3;
  535. case 14: return 4;
  536. }
  537. //
  538. // busted value
  539. //
  540. *RxValue = 14;
  541. return 4;
  542. }
  543. /*++
  544. Routine Description: SetTxTrackbarTicks
  545. Creates a tick at 1/4, half, and 3/4 across the span of the trackbar
  546. Arguments:
  547. hTrackbar - handle to the trackbar that will receive the ticks
  548. minVal, maxVal - Range on the trackbar
  549. Return Value:
  550. None
  551. --*/
  552. void
  553. SetTxTrackbarTics(
  554. IN HWND TrackbarHwnd
  555. )
  556. {
  557. Trackbar_SetTic(TrackbarHwnd, 6);
  558. Trackbar_SetTic(TrackbarHwnd, 11);
  559. }
  560. /*++
  561. Routine Description: SetLabelText
  562. Sets the label's to the string identified by resID concated with the passed
  563. in value and closing paren.
  564. The final string is [resID string][value])
  565. Arguments:
  566. hLabel - handle to the control whose text is going to change
  567. resID - resource ID for the beginning of the string that will become the
  568. label's text
  569. value - number to be concated into the string
  570. Return Value:
  571. None
  572. --*/
  573. void
  574. SetLabelText(
  575. IN HWND LabelHwnd,
  576. IN DWORD ResId,
  577. IN ULONG Value
  578. )
  579. {
  580. TCHAR szTemp[258], txt[258];
  581. if (LoadString(g_hInst, ResId, szTemp, CharSizeOf(szTemp))) {
  582. lstrcpy(txt, szTemp);
  583. wsprintf(szTemp, _T("%d)"), Value);
  584. lstrcat(txt, szTemp);
  585. }
  586. else {
  587. lstrcpy(txt, _T("Low"));
  588. }
  589. SetWindowText(LabelHwnd, txt);
  590. }
  591. /*++
  592. Routine Description: InitializeControls
  593. Initializes all of the controls that represent Fifo
  594. Arguments:
  595. ParentHwnd - handle to the dialog
  596. AdvancedData - Contains all of the initial values
  597. Return Value:
  598. None
  599. --*/
  600. void InitializeControls(
  601. IN HWND ParentHwnd,
  602. IN PADVANCED_DATA AdvancedData
  603. )
  604. {
  605. TCHAR szCurrentValue[40];
  606. HWND hwnd;
  607. int i, periodIdx;
  608. //
  609. // Set up the Fifo buffers checkbox
  610. //
  611. if (!AdvancedData->UseFifoBuffersControl) {
  612. //
  613. // Something went wrong with the Fifo buffers control. Disable
  614. // the checkbox
  615. //
  616. CheckDlgButton(ParentHwnd, IDC_FIFO, BST_UNCHECKED);
  617. EnableWindow(GetDlgItem(ParentHwnd, IDC_FIFO), FALSE);
  618. EnableFifoControls(ParentHwnd, FALSE);
  619. }
  620. else {
  621. EnableWindow(GetDlgItem(ParentHwnd, IDC_FIFO), TRUE);
  622. if (!AdvancedData->UseFifoBuffers) {
  623. EnableFifoControls(ParentHwnd, FALSE);
  624. CheckDlgButton(ParentHwnd, IDC_FIFO, BST_UNCHECKED);
  625. }
  626. else {
  627. EnableFifoControls(ParentHwnd, TRUE);
  628. CheckDlgButton(ParentHwnd, IDC_FIFO, BST_CHECKED);
  629. }
  630. }
  631. //
  632. // Set up the sliders
  633. //
  634. if (!AdvancedData->UseRxFIFOControl ||
  635. !AdvancedData->UseTxFIFOControl) {
  636. //
  637. // Something went wrong with the sliders.
  638. // Disable them
  639. //
  640. CheckDlgButton(ParentHwnd, IDC_FIFO, BST_UNCHECKED);
  641. EnableWindow(GetDlgItem(ParentHwnd, IDC_FIFO), FALSE);
  642. EnableFifoControls(ParentHwnd, FALSE);
  643. }
  644. else {
  645. IAccPropServices * pAccPropServices = NULL;
  646. HRESULT hr;
  647. //
  648. // Set up Rx Slider
  649. //
  650. hwnd = GetDlgItem(ParentHwnd, IDC_RECEIVE_SLIDER);
  651. Trackbar_SetRange(hwnd, TRUE, RX_MIN, 4);
  652. Trackbar_SetPos(hwnd,
  653. TRUE,
  654. RxValueToTrackbarPosition(&AdvancedData->RxFIFO));
  655. SetLabelText(GetDlgItem(ParentHwnd, IDC_RECEIVE_LOW),
  656. IDS_LOW,
  657. RX_MIN);
  658. SetLabelText(GetDlgItem(ParentHwnd, IDC_RECEIVE_HIGH),
  659. IDS_HIGH,
  660. AdvancedData->FifoRxMax);
  661. wsprintf(szCurrentValue, TEXT("(%d)"), AdvancedData->RxFIFO);
  662. SetDlgItemText(ParentHwnd, IDC_RXVALUE, szCurrentValue);
  663. //
  664. // Create the mapping for this slider for accessibility
  665. //
  666. hr = CoCreateInstance(&CLSID_AccPropServices,
  667. NULL,
  668. CLSCTX_INPROC_SERVER,
  669. &IID_IAccPropServices,
  670. (PVOID *) &pAccPropServices);
  671. if (SUCCEEDED(hr) && pAccPropServices != NULL) {
  672. IAccPropServices_SetHwndPropStr(pAccPropServices,
  673. hwnd,
  674. OBJID_CLIENT,
  675. CHILDID_SELF,
  676. PROPID_ACC_VALUEMAP,
  677. RxValuesStringMap);
  678. IAccPropServices_Release(pAccPropServices);
  679. }
  680. //
  681. // Set up the Tx slider
  682. //
  683. hwnd = GetDlgItem(ParentHwnd, IDC_TRANSMIT_SLIDER);
  684. Trackbar_SetRange(hwnd, TRUE, TX_MIN, AdvancedData->FifoTxMax);
  685. Trackbar_SetPos(hwnd, TRUE, AdvancedData->TxFIFO);
  686. SetTxTrackbarTics(hwnd);
  687. SetLabelText(GetDlgItem(ParentHwnd, IDC_TRANSMIT_LOW),
  688. IDS_LOW,
  689. TX_MIN);
  690. SetLabelText(GetDlgItem(ParentHwnd, IDC_TRANSMIT_HIGH),
  691. IDS_HIGH,
  692. AdvancedData->FifoTxMax);
  693. wsprintf(szCurrentValue, TEXT("(%d)"), AdvancedData->TxFIFO);
  694. SetDlgItemText(ParentHwnd, IDC_TXVALUE, szCurrentValue);
  695. //
  696. // Create the mapping for this slider for accessibility
  697. //
  698. hr = CoCreateInstance(&CLSID_AccPropServices,
  699. NULL,
  700. CLSCTX_INPROC_SERVER,
  701. &IID_IAccPropServices,
  702. (PVOID *) &pAccPropServices);
  703. if (SUCCEEDED(hr) && pAccPropServices != NULL) {
  704. IAccPropServices_SetHwndPropStr(pAccPropServices,
  705. hwnd,
  706. OBJID_CLIENT,
  707. CHILDID_SELF,
  708. PROPID_ACC_VALUEMAP,
  709. TxValuesStringMap);
  710. IAccPropServices_Release(pAccPropServices);
  711. }
  712. }
  713. FillPortNameCb(ParentHwnd, AdvancedData);
  714. if (!AdvancedData->HidePolling) {
  715. //
  716. // Add the descriptions for each polling period and select the current
  717. // setting
  718. //
  719. hwnd = GetDlgItem(ParentHwnd, IDC_POLL_PERIOD);
  720. periodIdx = NUM_POLLING_PERIODS;
  721. for (i = 0; i < NUM_POLLING_PERIODS; i++) {
  722. ComboBox_AddString(hwnd, PeriodDescription[i]);
  723. if (PollingPeriods[i] == AdvancedData->PollingPeriod) {
  724. periodIdx = i;
  725. }
  726. }
  727. if (periodIdx == NUM_POLLING_PERIODS) {
  728. wsprintf(szCurrentValue,
  729. PeriodDescription[NUM_POLLING_PERIODS],
  730. AdvancedData->PollingPeriod / SECONDS_CONVERSION_FACTOR);
  731. ComboBox_AddString(hwnd, szCurrentValue);
  732. }
  733. ComboBox_SetCurSel(hwnd, periodIdx);
  734. }
  735. else {
  736. ShowWindow(GetDlgItem(ParentHwnd, IDC_POLL_PERIOD), SW_HIDE);
  737. ShowWindow(GetDlgItem(ParentHwnd, IDC_POLL_DESC), SW_HIDE);
  738. }
  739. } /* InitializeControls */
  740. /*++
  741. Routine Description: RestoreAdvancedDefaultState
  742. Restores all values and UI to their default state, specifically:
  743. o All Fifo related child controls are enabled
  744. o The Rx trackbar is set to its max value
  745. o The Tx trackbar is set to its max value
  746. o The number of the comport is reset to its original value
  747. Return Value:
  748. None
  749. --*/
  750. void RestoreAdvancedDefaultState(
  751. IN HWND ParentHwnd,
  752. IN PADVANCED_DATA AdvancedData
  753. )
  754. {
  755. USHORT ushIndex;
  756. TCHAR szCurrentValue[10];
  757. int i;
  758. //
  759. // Set up the Fifo buffers checkbox
  760. //
  761. EnableWindow(GetDlgItem(ParentHwnd, IDC_FIFO), TRUE);
  762. EnableFifoControls(ParentHwnd, TRUE);
  763. CheckDlgButton(ParentHwnd, IDC_FIFO, BST_CHECKED);
  764. //
  765. // Set up the sliders and the static control that show their numberic value
  766. //
  767. Trackbar_SetPos(GetDlgItem(ParentHwnd, IDC_RECEIVE_SLIDER),
  768. TRUE,
  769. RxValueToTrackbarPosition(&AdvancedData->FifoRxMax));
  770. wsprintf(szCurrentValue, TEXT("(%d)"), AdvancedData->FifoRxMax);
  771. SetDlgItemText(ParentHwnd, IDC_RXVALUE, szCurrentValue);
  772. Trackbar_SetPos(GetDlgItem(ParentHwnd, IDC_TRANSMIT_SLIDER), TRUE, AdvancedData->FifoTxMax);
  773. wsprintf(szCurrentValue, TEXT("(%d)"), AdvancedData->FifoTxMax);
  774. SetDlgItemText(ParentHwnd, IDC_TXVALUE, szCurrentValue);
  775. //
  776. // Set the COM name to whatever it is currently set to in the registry
  777. //
  778. ushIndex =
  779. (USHORT) ComboBox_FindString(GetDlgItem(ParentHwnd, PP_PORT_NUMBER),
  780. -1,
  781. AdvancedData->szComName);
  782. ushIndex = (ushIndex == CB_ERR) ? 0 : ushIndex;
  783. ComboBox_SetCurSel(GetDlgItem(ParentHwnd, PP_PORT_NUMBER), ushIndex);
  784. ComboBox_SetCurSel(GetDlgItem(ParentHwnd, IDC_POLL_PERIOD), POLL_PERIOD_DEFAULT_IDX);
  785. } /* RestoreAdvancedDefaultStates */
  786. /*++
  787. Routine Description: FillPortNameCb
  788. fill in the Port Name combo box selection with a list
  789. of possible un-used portnames
  790. Arguments:
  791. poppOurPropParams: where to save the data to
  792. hDlg: address of the window
  793. Return Value:
  794. ULONG: returns error messages
  795. --*/
  796. ULONG
  797. FillPortNameCb(
  798. HWND ParentHwnd,
  799. PADVANCED_DATA AdvancedData
  800. )
  801. {
  802. BYTE portUsage[MAX_COM_PORT/8];
  803. DWORD tmp, portsReported;
  804. int i, j, nEntries;
  805. int nCurPortNum;
  806. TCHAR szCom[40];
  807. TCHAR szInUse[40];
  808. char mask, *current;
  809. HWND portHwnd;
  810. portHwnd = GetDlgItem(ParentHwnd, PP_PORT_NUMBER);
  811. //
  812. // Check if our ComName is blank. If it is, disable the com port selector
  813. //
  814. if (_tcscmp(AdvancedData->szComName, TEXT("")) == 0) {
  815. EnableWindow(portHwnd, FALSE);
  816. EnableWindow(GetDlgItem(ParentHwnd, IDC_COMNUMTEXT), FALSE);
  817. return 0;
  818. }
  819. //
  820. // assumes szComPort filled in...
  821. //
  822. nCurPortNum = myatoi(&AdvancedData->szComName[3]);
  823. if (!LoadString(g_hInst, IDS_IN_USE, szInUse, CharSizeOf(szInUse))) {
  824. wcscpy(szInUse, _T(" (in use)"));
  825. }
  826. //
  827. // first tally up which ports NOT to offer in list box
  828. //
  829. ZeroMemory(portUsage, MAX_COM_PORT/8);
  830. if (AdvancedData->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
  831. ComDBGetCurrentPortUsage(AdvancedData->hComDB,
  832. portUsage,
  833. MAX_COM_PORT / 8,
  834. CDB_REPORT_BITS,
  835. &portsReported);
  836. }
  837. //
  838. // tag the current port as not in use so it shows up in the CB
  839. //
  840. current = portUsage + (nCurPortNum-1) / 8;
  841. if ((i = nCurPortNum % 8))
  842. *current &= ~(1 << (i-1));
  843. else
  844. *current &= ~(0x80);
  845. current = portUsage;
  846. mask = 0x1;
  847. for(nEntries = j = 0, i = MIN_COM-1; i < MAX_COM_PORT; i++) {
  848. wsprintf(szCom, TEXT("COM%d"), i+1);
  849. if (*current & mask) {
  850. wcscat(szCom, szInUse);
  851. }
  852. if (mask == (char) 0x80) {
  853. mask = 0x01;
  854. current++;
  855. }
  856. else {
  857. mask <<= 1;
  858. }
  859. ComboBox_AddString(portHwnd, szCom);
  860. }
  861. ComboBox_SetCurSel(portHwnd, nCurPortNum-1);
  862. return 0;
  863. } /* FillPortNamesCb */
  864. /*++
  865. Routine Description: FillAdvancedDlg
  866. fill in the advanced dialog window
  867. Arguments:
  868. poppOurPropParams: the data to fill in
  869. ParentHwnd: address of the window
  870. Return Value:
  871. ULONG: returns error messages
  872. --*/
  873. ULONG
  874. FillAdvancedDlg(
  875. IN HWND ParentHwnd,
  876. IN PADVANCED_DATA AdvancedData
  877. )
  878. {
  879. PSP_DEVINFO_DATA DeviceInfoData = AdvancedData->DeviceInfoData;
  880. HKEY hDeviceKey;
  881. DWORD dwSize, dwData, dwFifo, dwError = ERROR_SUCCESS;
  882. //
  883. // Open the device key for the source device instance
  884. //
  885. hDeviceKey = AdvancedData->hDeviceKey;
  886. //
  887. // Get COM Name
  888. //
  889. dwSize = sizeof(AdvancedData->szComName);
  890. dwError = RegQueryValueEx(hDeviceKey,
  891. m_szPortName,
  892. NULL,
  893. NULL,
  894. (PBYTE)AdvancedData->szComName,
  895. &dwSize);
  896. if (dwError != ERROR_SUCCESS) {
  897. wsprintf(AdvancedData->szComName, TEXT("COMX"));
  898. }
  899. //
  900. // Get ForceFifoEnable information
  901. //
  902. AdvancedData->UseFifoBuffersControl = TRUE;
  903. dwSize = sizeof(dwFifo);
  904. dwError = RegQueryValueEx(hDeviceKey,
  905. m_szFIFO,
  906. NULL,
  907. NULL,
  908. (LPBYTE)(&dwFifo),
  909. &dwSize);
  910. if (dwError == ERROR_SUCCESS) {
  911. //
  912. // Save this initial value
  913. //
  914. AdvancedData->UseFifoBuffersControl = TRUE;
  915. if (dwFifo == 0) {
  916. AdvancedData->UseFifoBuffers = FALSE;
  917. }
  918. else {
  919. AdvancedData->UseFifoBuffers = TRUE;
  920. }
  921. }
  922. else {
  923. //
  924. // value does not exist. Create our own
  925. //
  926. dwData = 1;
  927. dwSize = sizeof(dwSize);
  928. dwError = RegSetValueEx(hDeviceKey,
  929. m_szFIFO,
  930. 0,
  931. REG_DWORD,
  932. (CONST BYTE *)(&dwData),
  933. dwSize);
  934. if (dwError == ERROR_SUCCESS) {
  935. AdvancedData->UseFifoBuffers = TRUE;
  936. }
  937. else {
  938. AdvancedData->UseFifoBuffers = FALSE;
  939. AdvancedData->UseFifoBuffersControl = FALSE;
  940. }
  941. }
  942. //
  943. // Get FifoRxMax information
  944. //
  945. dwSize = sizeof(dwFifo);
  946. dwError = RegQueryValueEx(hDeviceKey,
  947. m_szFifoRxMax,
  948. NULL,
  949. NULL,
  950. (LPBYTE)(&dwFifo),
  951. &dwFifo);
  952. if (dwError == ERROR_SUCCESS) {
  953. //
  954. // Save this initial value
  955. //
  956. AdvancedData->FifoRxMax = dwFifo;
  957. if (AdvancedData->FifoRxMax > RX_MAX) {
  958. AdvancedData->FifoRxMax = RX_MAX;
  959. }
  960. }
  961. else {
  962. //
  963. // value does not exist. Create our own
  964. //
  965. AdvancedData->FifoRxMax = RX_MAX;
  966. }
  967. //
  968. // Get RxFIFO information
  969. //
  970. dwSize = sizeof(dwFifo);
  971. dwError = RegQueryValueEx(hDeviceKey,
  972. m_szFifoTxMax,
  973. NULL,
  974. NULL,
  975. (LPBYTE)(&dwFifo),
  976. &dwSize);
  977. if (dwError == ERROR_SUCCESS) {
  978. //
  979. // Save this initial value
  980. //
  981. AdvancedData->FifoTxMax = dwFifo;
  982. if (AdvancedData->FifoTxMax > TX_MAX) {
  983. AdvancedData->FifoTxMax = TX_MAX;
  984. }
  985. }
  986. else {
  987. //
  988. // value does not exist. Create our own
  989. //
  990. AdvancedData->FifoTxMax = TX_MAX;
  991. }
  992. //
  993. // Get RxFIFO information
  994. //
  995. AdvancedData->UseRxFIFOControl = TRUE;
  996. dwSize = sizeof(dwFifo);
  997. dwError = RegQueryValueEx(hDeviceKey,
  998. m_szRxFIFO,
  999. NULL,
  1000. NULL,
  1001. (LPBYTE)(&dwFifo),
  1002. &dwSize);
  1003. if (dwError == ERROR_SUCCESS) {
  1004. //
  1005. // Save this initial value
  1006. //
  1007. AdvancedData->RxFIFO = dwFifo;
  1008. if (AdvancedData->RxFIFO > RX_MAX) {
  1009. goto SetRxFIFO;
  1010. }
  1011. }
  1012. else {
  1013. SetRxFIFO:
  1014. //
  1015. // value does not exist. Create our own
  1016. //
  1017. dwData = AdvancedData->FifoRxMax;
  1018. dwSize = sizeof(dwData);
  1019. dwError = RegSetValueEx(hDeviceKey,
  1020. m_szRxFIFO,
  1021. 0,
  1022. REG_DWORD,
  1023. (CONST BYTE *)(&dwData),
  1024. dwSize);
  1025. if (dwError == ERROR_SUCCESS) {
  1026. AdvancedData->RxFIFO = AdvancedData->FifoRxMax;
  1027. }
  1028. else {
  1029. AdvancedData->RxFIFO = 0;
  1030. AdvancedData->UseRxFIFOControl = FALSE;
  1031. }
  1032. }
  1033. //
  1034. // Get TxFIFO information
  1035. //
  1036. AdvancedData->UseTxFIFOControl = TRUE;
  1037. dwSize = sizeof(dwFifo);
  1038. dwError = RegQueryValueEx(hDeviceKey,
  1039. m_szTxFIFO,
  1040. NULL,
  1041. NULL,
  1042. (LPBYTE)(&dwFifo),
  1043. &dwSize);
  1044. if (dwError == ERROR_SUCCESS) {
  1045. //
  1046. // Save this initial value
  1047. //
  1048. AdvancedData->TxFIFO = dwFifo;
  1049. if (AdvancedData->TxFIFO > TX_MAX) {
  1050. goto SetTxFIFO;
  1051. }
  1052. }
  1053. else {
  1054. SetTxFIFO:
  1055. //
  1056. // value does not exist. Create our own
  1057. //
  1058. dwData = AdvancedData->FifoTxMax;
  1059. dwSize = sizeof(dwData);
  1060. dwError = RegSetValueEx(hDeviceKey,
  1061. m_szTxFIFO,
  1062. 0,
  1063. REG_DWORD,
  1064. (LPBYTE)(&dwData),
  1065. dwSize);
  1066. if (dwError == ERROR_SUCCESS) {
  1067. AdvancedData->TxFIFO = AdvancedData->FifoTxMax;
  1068. }
  1069. else {
  1070. AdvancedData->TxFIFO = 0;
  1071. AdvancedData->UseTxFIFOControl = FALSE;
  1072. }
  1073. }
  1074. //
  1075. // Get Polling Period information
  1076. //
  1077. AdvancedData->PollingPeriod = PollingPeriods[POLL_PERIOD_DEFAULT_IDX];
  1078. dwSize = sizeof(dwFifo);
  1079. dwError = RegQueryValueEx(hDeviceKey,
  1080. m_szPollingPeriod,
  1081. NULL,
  1082. NULL,
  1083. (LPBYTE)(&dwFifo),
  1084. &dwSize);
  1085. if (dwError == ERROR_SUCCESS) {
  1086. //
  1087. // Save this initial value
  1088. //
  1089. AdvancedData->PollingPeriod = dwFifo;
  1090. }
  1091. else {
  1092. //
  1093. // value does not exist. Create our own
  1094. //
  1095. dwData = AdvancedData->PollingPeriod;
  1096. dwSize = sizeof(dwData);
  1097. dwError = RegSetValueEx(hDeviceKey,
  1098. m_szPollingPeriod,
  1099. 0,
  1100. REG_DWORD,
  1101. (LPBYTE)(&dwData),
  1102. dwSize);
  1103. }
  1104. RegCloseKey(hDeviceKey);
  1105. if (ERROR_SUCCESS != dwError) {
  1106. return dwError;
  1107. }
  1108. else {
  1109. return ERROR_SUCCESS;
  1110. }
  1111. } /* FillAdvancedDlg*/
  1112. void
  1113. ChangeParentTitle(
  1114. IN HWND Hwnd,
  1115. IN LPCTSTR OldComName,
  1116. IN LPCTSTR NewComName
  1117. )
  1118. {
  1119. INT textLength, offset, newNameLen, oldNameLen;
  1120. PTCHAR oldTitle = NULL, newTitle = NULL;
  1121. PTCHAR oldLocation;
  1122. textLength = GetWindowTextLength(Hwnd);
  1123. if (textLength == 0) {
  1124. return;
  1125. }
  1126. //
  1127. // Account for null char and unicode
  1128. //
  1129. textLength++;
  1130. oldTitle = (PTCHAR) LocalAlloc(LPTR, textLength * sizeof(TCHAR));
  1131. if (!oldTitle) {
  1132. return;
  1133. }
  1134. if (!GetWindowText(Hwnd, oldTitle, textLength)) {
  1135. goto exit;
  1136. }
  1137. oldLocation = wcsstr(oldTitle, OldComName);
  1138. if (!oldLocation) {
  1139. goto exit;
  1140. }
  1141. newNameLen = lstrlen(NewComName);
  1142. oldNameLen = lstrlen(OldComName);
  1143. offset = newNameLen - oldNameLen;
  1144. if (offset > 0) {
  1145. textLength += offset;
  1146. }
  1147. newTitle = (PTCHAR) LocalAlloc(LPTR, textLength * sizeof(TCHAR));
  1148. if (!newTitle) {
  1149. goto exit;
  1150. }
  1151. //
  1152. // Find the OldComName in the title and do the following
  1153. // 1) up to that location in the string
  1154. // 2) copy the new name
  1155. // 3) copy the remainder of the string after OldComName
  1156. //
  1157. offset = (INT)(oldLocation - oldTitle);
  1158. CopyMemory(newTitle, oldTitle, offset * sizeof(TCHAR)); // 1
  1159. CopyMemory(newTitle + offset, NewComName, newNameLen * sizeof(TCHAR)); // 2
  1160. lstrcpy(newTitle + offset + newNameLen, oldLocation + oldNameLen); // 3
  1161. SetWindowText(Hwnd, newTitle);
  1162. exit:
  1163. if (oldTitle) {
  1164. LocalFree(oldTitle);
  1165. }
  1166. if (newTitle) {
  1167. LocalFree(newTitle);
  1168. }
  1169. }
  1170. void
  1171. MigratePortSettings(
  1172. LPCTSTR OldComName,
  1173. LPCTSTR NewComName
  1174. )
  1175. {
  1176. TCHAR settings[BUFFER_SIZE];
  1177. TCHAR szNew[20], szOld[20];
  1178. lstrcpy(szOld, OldComName);
  1179. wcscat(szOld, m_szColon);
  1180. lstrcpy(szNew, NewComName);
  1181. wcscat(szNew, m_szColon);
  1182. settings[0] = TEXT('\0');
  1183. GetProfileString(m_szPorts,
  1184. szOld,
  1185. TEXT(""),
  1186. settings,
  1187. sizeof(settings) / sizeof(TCHAR) );
  1188. //
  1189. // Insert the new key based on the old one
  1190. //
  1191. if (settings[0] == TEXT('\0')) {
  1192. WriteProfileString(m_szPorts, szNew, m_szDefParams);
  1193. }
  1194. else {
  1195. WriteProfileString(m_szPorts, szNew, settings);
  1196. }
  1197. //
  1198. // Notify everybody of the changes and blow away the old key
  1199. //
  1200. SendWinIniChange((LPTSTR)m_szPorts);
  1201. WriteProfileString(m_szPorts, szOld, NULL);
  1202. }
  1203. void
  1204. EnactComNameChanges(
  1205. IN HWND ParentHwnd,
  1206. IN PADVANCED_DATA AdvancedData,
  1207. IN HKEY hDeviceKey,
  1208. IN UINT NewComNum)
  1209. {
  1210. DWORD dwNewComNameLen;
  1211. TCHAR buffer[BUFFER_SIZE];
  1212. TCHAR szFriendlyNameFormat[LINE_LEN];
  1213. TCHAR szDeviceDesc[LINE_LEN];
  1214. PTCHAR szNewComName;
  1215. UINT i;
  1216. UINT curComNum;
  1217. BOOLEAN updateMapping = TRUE;
  1218. SP_DEVINSTALL_PARAMS spDevInstall;
  1219. curComNum = myatoi(AdvancedData->szComName + wcslen(m_szCOM));
  1220. if (AdvancedData->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
  1221. BYTE portUsage[MAX_COM_PORT/8];
  1222. DWORD portsReported;
  1223. char mask;
  1224. //
  1225. // Check to see if the desired new COM number has been claimed in the
  1226. // com name database. If so, ask the user if they are *really* sure
  1227. //
  1228. ComDBGetCurrentPortUsage(AdvancedData->hComDB,
  1229. portUsage,
  1230. MAX_COM_PORT / 8,
  1231. CDB_REPORT_BITS,
  1232. &portsReported);
  1233. if ((i = NewComNum % 8))
  1234. mask = 1 << (i-1);
  1235. else
  1236. mask = (char) 0x80;
  1237. if ((portUsage[(NewComNum-1)/8] & mask) &&
  1238. MyMessageBox(ParentHwnd, IDS_PORT_IN_USE, IDS_NAME_PROPERTIES,
  1239. MB_YESNO | MB_ICONINFORMATION) == IDNO) {
  1240. //
  1241. // Port has been previously claimed and user doesn't want to override
  1242. //
  1243. return;
  1244. }
  1245. }
  1246. if (!QueryDosDevice(AdvancedData->szComName, buffer, BUFFER_SIZE-1)) {
  1247. //
  1248. // The old com name does not exist in the mapping. Basically, the symbolic
  1249. // link from COMX => \Device\SerialY has been broken. Just change the
  1250. // value in the registry and the friendly name for the device; don't
  1251. // change the dos symbolic name b/c one does not exist
  1252. //
  1253. updateMapping = FALSE;
  1254. }
  1255. else {
  1256. TCHAR szComFileName[20]; // more than enough for "\\.\COMXxxx"
  1257. HANDLE hCom;
  1258. lstrcpy(szComFileName, L"\\\\.\\");
  1259. lstrcat(szComFileName, AdvancedData->szComName);
  1260. //
  1261. // Make sure that the port has not been opened by another application
  1262. //
  1263. hCom = CreateFile(szComFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  1264. FILE_ATTRIBUTE_NORMAL, NULL);
  1265. //
  1266. // If the file handle is invalid, then the com port is open, warn the user
  1267. //
  1268. if (hCom == INVALID_HANDLE_VALUE &&
  1269. MyMessageBox(ParentHwnd, IDS_PORT_OPEN, IDS_NAME_PROPERTIES,
  1270. MB_YESNO | MB_ICONERROR) == IDNO) {
  1271. return;
  1272. }
  1273. if (hCom != INVALID_HANDLE_VALUE) {
  1274. CloseHandle(hCom);
  1275. }
  1276. }
  1277. szNewComName = AdvancedData->szNewComName;
  1278. wsprintf(szNewComName, _T("COM%d"), NewComNum);
  1279. dwNewComNameLen = ByteCountOf(wcslen(szNewComName) + 1);
  1280. //
  1281. // Change the name in the symbolic namespace.
  1282. // First try to get what device the old com name mapped to
  1283. // (ie something like \Device\Serial0). Then remove the mapping. If
  1284. // the user isn't an admin, then this will fail and the dialog will popup.
  1285. // Finally, map the new name to the old device retrieved from the
  1286. // QueryDosDevice
  1287. //
  1288. if (updateMapping) {
  1289. BOOL removed;
  1290. HKEY hSerialMap;
  1291. if (!QueryDosDevice(AdvancedData->szComName, buffer, BUFFER_SIZE-1)) {
  1292. //
  1293. // This shouldn't happen because the previous QueryDosDevice call
  1294. // succeeded
  1295. //
  1296. MyMessageBox(ParentHwnd, IDS_PORT_RENAME_ERROR, IDS_NAME_PROPERTIES,
  1297. MB_ICONERROR);
  1298. return;
  1299. }
  1300. //
  1301. // If this fails, then the following define will just replace the current
  1302. // mapping.
  1303. //
  1304. removed = DefineDosDevice(DDD_REMOVE_DEFINITION, AdvancedData->szComName, NULL);
  1305. if (!DefineDosDevice(DDD_RAW_TARGET_PATH, szNewComName, buffer)) {
  1306. //
  1307. // error, first fix up the remove definition and restore the old
  1308. // mapping
  1309. //
  1310. if (removed) {
  1311. DefineDosDevice(DDD_RAW_TARGET_PATH, AdvancedData->szComName, buffer);
  1312. }
  1313. MyMessageBox(ParentHwnd, IDS_PORT_RENAME_ERROR, IDS_NAME_PROPERTIES,
  1314. MB_ICONERROR);
  1315. return;
  1316. }
  1317. //
  1318. // Set the \\HARDWARE\DEVICEMAP\SERIALCOMM field
  1319. //
  1320. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1321. m_szRegSerialMap,
  1322. 0,
  1323. KEY_ALL_ACCESS,
  1324. &hSerialMap) == ERROR_SUCCESS) {
  1325. TCHAR szSerial[BUFFER_SIZE];
  1326. DWORD dwSerialSize, dwEnum, dwType, dwComSize;
  1327. TCHAR szCom[BUFFER_SIZE];
  1328. i = 0;
  1329. do {
  1330. dwSerialSize = CharSizeOf(szSerial);
  1331. dwComSize = sizeof(szCom);
  1332. dwEnum = RegEnumValue(hSerialMap,
  1333. i++,
  1334. szSerial,
  1335. &dwSerialSize,
  1336. NULL,
  1337. &dwType,
  1338. (LPBYTE)szCom,
  1339. &dwComSize);
  1340. if (dwEnum == ERROR_SUCCESS) {
  1341. if(dwType != REG_SZ)
  1342. continue;
  1343. if (wcscmp(szCom, AdvancedData->szComName) == 0) {
  1344. RegSetValueEx(hSerialMap,
  1345. szSerial,
  1346. 0,
  1347. REG_SZ,
  1348. (PBYTE) szNewComName,
  1349. dwNewComNameLen);
  1350. break;
  1351. }
  1352. }
  1353. } while (dwEnum == ERROR_SUCCESS);
  1354. }
  1355. RegCloseKey(hSerialMap);
  1356. }
  1357. //
  1358. // Update the com db
  1359. //
  1360. if (AdvancedData->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
  1361. ComDBReleasePort(AdvancedData->hComDB, (DWORD) curComNum);
  1362. ComDBClaimPort(AdvancedData->hComDB, (DWORD) NewComNum, TRUE, NULL);
  1363. }
  1364. //
  1365. // Set the friendly name in the form of DeviceDesc (COM#)
  1366. //
  1367. if (LoadString(g_hInst,
  1368. IDS_FRIENDLY_FORMAT,
  1369. szFriendlyNameFormat,
  1370. CharSizeOf(szFriendlyNameFormat)) &&
  1371. SetupDiGetDeviceRegistryProperty(AdvancedData->DeviceInfoSet,
  1372. AdvancedData->DeviceInfoData,
  1373. SPDRP_DEVICEDESC,
  1374. NULL,
  1375. (PBYTE) szDeviceDesc,
  1376. sizeof(szDeviceDesc),
  1377. NULL)) {
  1378. wsprintf(buffer, szFriendlyNameFormat, szDeviceDesc, szNewComName);
  1379. }
  1380. else {
  1381. //
  1382. // Use the COM port name straight out
  1383. //
  1384. lstrcpy(buffer, szNewComName);
  1385. }
  1386. SetupDiSetDeviceRegistryProperty(AdvancedData->DeviceInfoSet,
  1387. AdvancedData->DeviceInfoData,
  1388. SPDRP_FRIENDLYNAME,
  1389. (PBYTE) buffer,
  1390. ByteCountOf(wcslen(buffer)+1));
  1391. //
  1392. // Set the parent dialog's title to reflect the change in the com port's name
  1393. //
  1394. ChangeParentTitle(GetParent(ParentHwnd), AdvancedData->szComName, szNewComName);
  1395. MigratePortSettings(AdvancedData->szComName, szNewComName);
  1396. //
  1397. // Update the PortName value in the devnode
  1398. //
  1399. RegSetValueEx(hDeviceKey,
  1400. m_szPortName,
  1401. 0,
  1402. REG_SZ,
  1403. (PBYTE)szNewComName,
  1404. dwNewComNameLen);
  1405. //
  1406. // Now broadcast this change to the device manager
  1407. //
  1408. ZeroMemory(&spDevInstall, sizeof(SP_DEVINSTALL_PARAMS));
  1409. spDevInstall.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  1410. if (SetupDiGetDeviceInstallParams(AdvancedData->DeviceInfoSet,
  1411. AdvancedData->DeviceInfoData,
  1412. &spDevInstall)) {
  1413. spDevInstall.Flags |= DI_PROPERTIES_CHANGE;
  1414. SetupDiSetDeviceInstallParams(AdvancedData->DeviceInfoSet,
  1415. AdvancedData->DeviceInfoData,
  1416. &spDevInstall);
  1417. }
  1418. }
  1419. /*++
  1420. Routine Description: SaveAdvancedSettings
  1421. saves the advanced box settings back to the registry, if any were
  1422. changed
  1423. Arguments:
  1424. AdvancedData: holds the current settings and the location of of
  1425. the device in the registry
  1426. ParentHwnd: address of the window
  1427. Return Value:
  1428. ULONG: returns error messages
  1429. --*/
  1430. ULONG
  1431. SaveAdvancedSettings(
  1432. IN HWND ParentHwnd,
  1433. IN PADVANCED_DATA AdvancedData
  1434. )
  1435. {
  1436. HKEY hDeviceKey;
  1437. DWORD dwSize, dwData;
  1438. UINT i = CB_ERR, curComNum, newComNum = CB_ERR;
  1439. UINT uiDlgButtonChecked;
  1440. DWORD dwRxPosition, dwTxPosition, dwPollingPeriod;
  1441. SP_DEVINSTALL_PARAMS spDevInstall;
  1442. //
  1443. // Grab all of the new settings
  1444. //
  1445. uiDlgButtonChecked = IsDlgButtonChecked(ParentHwnd, IDC_FIFO);
  1446. dwTxPosition = Trackbar_GetPos(GetDlgItem(ParentHwnd, IDC_TRANSMIT_SLIDER));
  1447. dwRxPosition = Trackbar_GetPos(GetDlgItem(ParentHwnd, IDC_RECEIVE_SLIDER));
  1448. //
  1449. // Index is actually into the array of values
  1450. //
  1451. dwRxPosition = RxValues[dwRxPosition-1];
  1452. curComNum = myatoi(AdvancedData->szComName + wcslen(m_szCOM));
  1453. newComNum = ComboBox_GetCurSel(GetDlgItem(ParentHwnd, PP_PORT_NUMBER));
  1454. if (newComNum == CB_ERR) {
  1455. newComNum = curComNum;
  1456. }
  1457. else {
  1458. newComNum++;
  1459. }
  1460. i = ComboBox_GetCurSel(GetDlgItem(ParentHwnd, IDC_POLL_PERIOD));
  1461. if (i == CB_ERR || i >= NUM_POLLING_PERIODS) {
  1462. dwPollingPeriod = AdvancedData->PollingPeriod;
  1463. }
  1464. else {
  1465. dwPollingPeriod = PollingPeriods[i];
  1466. }
  1467. //
  1468. // See if they changed anything
  1469. //
  1470. if (((AdvancedData->UseFifoBuffers && uiDlgButtonChecked == BST_CHECKED) ||
  1471. (!AdvancedData->UseFifoBuffers && uiDlgButtonChecked == BST_UNCHECKED)) &&
  1472. AdvancedData->RxFIFO == dwRxPosition &&
  1473. AdvancedData->TxFIFO == dwTxPosition &&
  1474. AdvancedData->PollingPeriod == dwPollingPeriod &&
  1475. newComNum == curComNum) {
  1476. //
  1477. // They didn't change anything. Just exit.
  1478. //
  1479. return ERROR_SUCCESS;
  1480. }
  1481. //
  1482. // Open the device key for the source device instance
  1483. //
  1484. hDeviceKey = SetupDiOpenDevRegKey(AdvancedData->DeviceInfoSet,
  1485. AdvancedData->DeviceInfoData,
  1486. DICS_FLAG_GLOBAL,
  1487. 0,
  1488. DIREG_DEV,
  1489. KEY_ALL_ACCESS);
  1490. if (INVALID_HANDLE_VALUE == hDeviceKey) {
  1491. //
  1492. // Not much we can do without a valid key, exit gracefully
  1493. //
  1494. return ERROR_SUCCESS;
  1495. }
  1496. //
  1497. // Check to see if the user changed the COM port name
  1498. //
  1499. if (newComNum != curComNum) {
  1500. EnactComNameChanges(ParentHwnd,
  1501. AdvancedData,
  1502. hDeviceKey,
  1503. newComNum);
  1504. }
  1505. if ((AdvancedData->UseFifoBuffers && uiDlgButtonChecked == BST_UNCHECKED) ||
  1506. (!AdvancedData->UseFifoBuffers && uiDlgButtonChecked == BST_CHECKED)) {
  1507. //
  1508. // They changed the Use Fifo checkbox.
  1509. //
  1510. dwData = (uiDlgButtonChecked == BST_CHECKED) ? 1 : 0;
  1511. dwSize = sizeof(dwData);
  1512. RegSetValueEx(hDeviceKey,
  1513. m_szFIFO,
  1514. 0,
  1515. REG_DWORD,
  1516. (CONST BYTE *)(&dwData),
  1517. dwSize);
  1518. }
  1519. if (AdvancedData->RxFIFO != dwRxPosition) {
  1520. //
  1521. // They changed the RxFIFO setting
  1522. //
  1523. dwData = dwRxPosition;
  1524. dwSize = sizeof(dwData);
  1525. RegSetValueEx(hDeviceKey,
  1526. m_szRxFIFO,
  1527. 0,
  1528. REG_DWORD,
  1529. (CONST BYTE *)(&dwData),
  1530. dwSize);
  1531. }
  1532. if (AdvancedData->TxFIFO != dwTxPosition) {
  1533. //
  1534. // They changed the TxFIFO setting
  1535. //
  1536. dwData = dwTxPosition;
  1537. dwSize = sizeof(dwData);
  1538. RegSetValueEx(hDeviceKey,
  1539. m_szTxFIFO,
  1540. 0,
  1541. REG_DWORD,
  1542. (CONST BYTE *)(&dwData),
  1543. dwSize);
  1544. }
  1545. if (AdvancedData->PollingPeriod != dwPollingPeriod) {
  1546. //
  1547. // They changed the polling period
  1548. //
  1549. dwData = dwPollingPeriod;
  1550. dwSize = sizeof(dwData);
  1551. RegSetValueEx(hDeviceKey,
  1552. m_szPollingPeriod,
  1553. 0,
  1554. REG_DWORD,
  1555. (CONST BYTE *)(&dwData),
  1556. dwSize);
  1557. //
  1558. // Don't really care if this fails, nothing else we can do
  1559. //
  1560. CM_Reenumerate_DevNode(AdvancedData->DeviceInfoData->DevInst,
  1561. CM_REENUMERATE_NORMAL);
  1562. }
  1563. RegCloseKey(hDeviceKey);
  1564. SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
  1565. AdvancedData->DeviceInfoSet,
  1566. AdvancedData->DeviceInfoData);
  1567. return ERROR_SUCCESS;
  1568. } /* SaveAdvancedSettings*/