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.

1589 lines
47 KiB

  1. /*----------------------------------------------------------------------
  2. file: pp.c - property page
  3. ----------------------------------------------------------------------*/
  4. #include "cyyports.h"
  5. #include "pp.h"
  6. #include <htmlhelp.h>
  7. #include <windowsx.h>
  8. //TCHAR m_szDevMgrHelp[] = _T("devmgr.hlp");
  9. TCHAR m_szCyycoinsHelp[] = _T("cyycoins.chm");
  10. TCHAR y_szNumOfPorts[] = TEXT("NumOfPorts");
  11. const DWORD HelpIDs[]=
  12. {
  13. IDC_STATIC, IDH_CYYCOINS_NOHELP,
  14. IDC_STATIC_BOARD_DETAILS, IDH_CYYCOINS_NOHELP,
  15. IDC_STATIC_SETTINGS, IDH_CYYCOINS_NOHELP,
  16. IDC_NUM_PORTS, IDH_CYYCOINS_NUM_PORTS,
  17. PP_NUM_PORTS, IDH_CYYCOINS_NUM_PORTS,
  18. IDC_START_COM, IDH_CYYCOINS_START_COM,
  19. PP_START_COM, IDH_CYYCOINS_START_COM,
  20. IDC_RESTORE_DEFAULTS, IDH_CYYCOINS_RESTORE_DEFAULTS,
  21. IDC_BUS_TYPE, IDH_CYYCOINS_BUS_TYPE,
  22. PP_BUS_TYPE, IDH_CYYCOINS_BUS_TYPE,
  23. IDC_CONFIGURATION, IDH_CYYCOINS_CONFIGURATION,
  24. PP_CONFIGURATION, IDH_CYYCOINS_CONFIGURATION,
  25. IDC_MODEL, IDH_CYYCOINS_MODEL,
  26. PP_MODEL, IDH_CYYCOINS_MODEL,
  27. 0, 0
  28. };
  29. void InitPortParams(
  30. IN OUT PPORT_PARAMS Params,
  31. IN HDEVINFO DeviceInfoSet,
  32. IN PSP_DEVINFO_DATA DeviceInfoData
  33. )
  34. {
  35. SP_DEVINFO_LIST_DETAIL_DATA detailData;
  36. HCOMDB hComDB;
  37. DWORD maxPortsReported;
  38. //DbgOut(TEXT("InitPortParams\n"));
  39. ZeroMemory(Params, sizeof(PORT_PARAMS));
  40. Params->DeviceInfoSet = DeviceInfoSet;
  41. Params->DeviceInfoData = DeviceInfoData;
  42. // Allocate and initialize PortUsage matrix
  43. ComDBOpen(&hComDB);
  44. if (hComDB != INVALID_HANDLE_VALUE) {
  45. ComDBGetCurrentPortUsage(hComDB,
  46. NULL,
  47. 0,
  48. CDB_REPORT_BYTES,
  49. &maxPortsReported);
  50. //#if DBG
  51. //{
  52. // TCHAR buf[500];
  53. // wsprintf(buf, TEXT("maxPortsReported %d\n"),maxPortsReported);
  54. // DbgOut(buf);
  55. //}
  56. //#endif
  57. if (maxPortsReported != 0) {
  58. Params->ShowStartCom = TRUE;
  59. //Params->PortUsage = (PBYTE) LocalAlloc(LPTR,maxPortsReported/8);
  60. if (maxPortsReported > MAX_COM_PORT) {
  61. Params->PortUsageSize = maxPortsReported;
  62. } else {
  63. Params->PortUsageSize = MAX_COM_PORT;
  64. }
  65. Params->PortUsage = (PBYTE) LocalAlloc(LPTR,Params->PortUsageSize/8);
  66. if (Params->PortUsage != NULL) {
  67. Params->PortUsageSize = maxPortsReported/8;
  68. ComDBGetCurrentPortUsage(hComDB,
  69. Params->PortUsage,
  70. Params->PortUsageSize,
  71. CDB_REPORT_BITS,
  72. &maxPortsReported
  73. );
  74. }
  75. }
  76. ComDBClose(hComDB);
  77. } else {
  78. // This happens if we don't have sufficient security privileges.
  79. // GetLastError returns 0 here!!! Some bug in ComDBOpen.
  80. DbgOut(TEXT("cyycoins ComDBOpen failed.\n"));
  81. }
  82. //
  83. // See if we are being invoked locally or over the network. If over the net,
  84. // then disable all possible changes.
  85. //
  86. detailData.cbSize = sizeof(SP_DEVINFO_LIST_DETAIL_DATA);
  87. if (SetupDiGetDeviceInfoListDetail(DeviceInfoSet, &detailData) &&
  88. detailData.RemoteMachineHandle != NULL) {
  89. Params->ShowStartCom = FALSE;
  90. }
  91. }
  92. HPROPSHEETPAGE InitSettingsPage(PROPSHEETPAGE * psp,
  93. OUT PPORT_PARAMS Params)
  94. {
  95. //
  96. // Add the Port Settings property page
  97. //
  98. psp->dwSize = sizeof(PROPSHEETPAGE);
  99. psp->dwFlags = PSP_USECALLBACK; // | PSP_HASHELP;
  100. psp->hInstance = g_hInst;
  101. psp->pszTemplate = MAKEINTRESOURCE(DLG_PP_PORTSETTINGS);
  102. //
  103. // following points to the dlg window proc
  104. //
  105. psp->pfnDlgProc = PortSettingsDlgProc;
  106. psp->lParam = (LPARAM) Params;
  107. //
  108. // following points to some control callback of the dlg window proc
  109. //
  110. psp->pfnCallback = PortSettingsDlgCallback;
  111. //
  112. // allocate our "Ports Setting" sheet
  113. //
  114. return CreatePropertySheetPage(psp);
  115. }
  116. /*++
  117. Routine Description: CyclomyPropPageProvider
  118. Entry-point for adding additional device manager property
  119. sheet pages. Registry specifies this routine under
  120. Control\Class\PortNode::EnumPropPage32="msports.dll,thisproc"
  121. entry. This entry-point gets called only when the Device
  122. Manager asks for additional property pages.
  123. Arguments:
  124. Info - points to PROPSHEETPAGE_REQUEST, see setupapi.h
  125. AddFunc - function ptr to call to add sheet.
  126. Lparam - add sheet functions private data handle.
  127. Return Value:
  128. BOOL: FALSE if pages could not be added, TRUE on success
  129. --*/
  130. BOOL APIENTRY CyclomyPropPageProvider(LPVOID Info,
  131. LPFNADDPROPSHEETPAGE AddFunc,
  132. LPARAM Lparam
  133. )
  134. {
  135. PSP_PROPSHEETPAGE_REQUEST pprPropPageRequest;
  136. PROPSHEETPAGE psp;
  137. HPROPSHEETPAGE hpsp;
  138. PPORT_PARAMS params = NULL;
  139. //DbgOut(TEXT("cyycoins CyclomyPropPageProvider entry\n"));
  140. pprPropPageRequest = (PSP_PROPSHEETPAGE_REQUEST) Info;
  141. //
  142. // Allocate and zero out memory for the struct that will contain
  143. // page specific data
  144. //
  145. params = (PPORT_PARAMS) LocalAlloc(LPTR, sizeof(PORT_PARAMS));
  146. //******************************************************************
  147. // TEST ERROR
  148. // if (params)
  149. // LocalFree(params);
  150. // params = NULL;
  151. //
  152. //******************************************************************
  153. if (!params) {
  154. ErrMemDlg(GetFocus());
  155. return FALSE;
  156. }
  157. if (pprPropPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) {
  158. InitPortParams(params,
  159. pprPropPageRequest->DeviceInfoSet,
  160. pprPropPageRequest->DeviceInfoData);
  161. hpsp = InitSettingsPage(&psp, params);
  162. if (!hpsp) {
  163. return FALSE;
  164. }
  165. if (!(*AddFunc)(hpsp, Lparam)) {
  166. DestroyPropertySheetPage(hpsp);
  167. return FALSE;
  168. }
  169. }
  170. return TRUE;
  171. } /* CyclomyPropPageProvider */
  172. UINT CALLBACK
  173. PortSettingsDlgCallback(HWND hwnd,
  174. UINT uMsg,
  175. LPPROPSHEETPAGE ppsp)
  176. {
  177. PPORT_PARAMS params;
  178. switch (uMsg) {
  179. case PSPCB_CREATE:
  180. return TRUE; // return TRUE to continue with creation of page
  181. case PSPCB_RELEASE:
  182. //DbgOut(TEXT("PortSettingsDlgCallBack PSPCB_RELEASE\n"));
  183. params = (PPORT_PARAMS) ppsp->lParam;
  184. if (params->PortUsage) {
  185. LocalFree(params->PortUsage);
  186. }
  187. LocalFree(params);
  188. return 0; // return value ignored
  189. default:
  190. break;
  191. }
  192. return TRUE;
  193. }
  194. void
  195. Port_OnCommand(
  196. HWND DialogHwnd,
  197. int ControlId,
  198. HWND ControlHwnd,
  199. UINT NotifyCode
  200. );
  201. BOOL
  202. Port_OnContextMenu(
  203. HWND HwndControl,
  204. WORD Xpos,
  205. WORD Ypos
  206. );
  207. void
  208. Port_OnHelp(
  209. HWND DialogHwnd,
  210. LPHELPINFO HelpInfo
  211. );
  212. BOOL
  213. Port_OnInitDialog(
  214. HWND DialogHwnd,
  215. HWND FocusHwnd,
  216. LPARAM Lparam
  217. );
  218. BOOL
  219. Port_OnNotify(
  220. HWND DialogHwnd,
  221. LPNMHDR NmHdr
  222. );
  223. /*++
  224. Routine Description: PortSettingsDlgProc
  225. The windows control function for the Port Settings properties window
  226. Arguments:
  227. hDlg, uMessage, wParam, lParam: standard windows DlgProc parameters
  228. Return Value:
  229. BOOL: FALSE if function fails, TRUE if function passes
  230. --*/
  231. INT_PTR APIENTRY
  232. PortSettingsDlgProc(IN HWND hDlg,
  233. IN UINT uMessage,
  234. IN WPARAM wParam,
  235. IN LPARAM lParam)
  236. {
  237. switch(uMessage) {
  238. case WM_COMMAND:
  239. Port_OnCommand(hDlg, (int) LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam));
  240. break;
  241. case WM_CONTEXTMENU:
  242. return Port_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  243. case WM_HELP:
  244. Port_OnHelp(hDlg, (LPHELPINFO) lParam);
  245. break;
  246. case WM_INITDIALOG:
  247. return Port_OnInitDialog(hDlg, (HWND)wParam, lParam);
  248. case WM_NOTIFY:
  249. return Port_OnNotify(hDlg, (NMHDR *)lParam);
  250. }
  251. return FALSE;
  252. } /* PortSettingsDialogProc */
  253. void
  254. Port_OnRestoreDefaultsClicked(
  255. HWND DialogHwnd,
  256. PPORT_PARAMS Params
  257. )
  258. {
  259. RestoreDefaults(DialogHwnd, Params);
  260. PropSheet_Changed(GetParent(DialogHwnd), DialogHwnd);
  261. }
  262. void
  263. Port_OnCommand(
  264. HWND DialogHwnd,
  265. int ControlId,
  266. HWND ControlHwnd,
  267. UINT NotifyCode
  268. )
  269. {
  270. PPORT_PARAMS params = (PPORT_PARAMS)GetWindowLongPtr(DialogHwnd, DWLP_USER);
  271. if (NotifyCode == CBN_SELCHANGE) {
  272. PropSheet_Changed(GetParent(DialogHwnd), DialogHwnd);
  273. }
  274. else {
  275. switch (ControlId) {
  276. //case IDC_ADVANCED:
  277. // Port_OnAdvancedClicked(DialogHwnd, params);
  278. // break;
  279. //
  280. case IDC_RESTORE_DEFAULTS:
  281. Port_OnRestoreDefaultsClicked(DialogHwnd, params);
  282. break;
  283. //
  284. // Because this is a prop sheet, we should never get this.
  285. // All notifications for ctrols outside of the sheet come through
  286. // WM_NOTIFY
  287. //
  288. case IDCANCEL:
  289. EndDialog(DialogHwnd, 0);
  290. return;
  291. }
  292. }
  293. }
  294. BOOL
  295. Port_OnContextMenu(
  296. HWND HwndControl,
  297. WORD Xpos,
  298. WORD Ypos
  299. )
  300. {
  301. // WinHelp(HwndControl,
  302. // m_szCyycoinsHelp, //m_szDevMgrHelp,
  303. // HELP_CONTEXTMENU,
  304. // (ULONG_PTR) HelpIDs);
  305. HtmlHelp(HwndControl,
  306. m_szCyycoinsHelp,
  307. HH_TP_HELP_CONTEXTMENU,
  308. (ULONG_PTR) HelpIDs);
  309. return FALSE;
  310. }
  311. void
  312. Port_OnHelp(
  313. HWND DialogHwnd,
  314. LPHELPINFO HelpInfo
  315. )
  316. {
  317. if (HelpInfo->iContextType == HELPINFO_WINDOW) {
  318. // WinHelp((HWND) HelpInfo->hItemHandle,
  319. // m_szCyycoinsHelp, //m_szDevMgrHelp,
  320. // HELP_WM_HELP,
  321. // (ULONG_PTR) HelpIDs);
  322. HtmlHelp((HWND) HelpInfo->hItemHandle,
  323. m_szCyycoinsHelp,
  324. HH_TP_HELP_WM_HELP,
  325. (ULONG_PTR) HelpIDs);
  326. }
  327. }
  328. BOOL
  329. Port_OnInitDialog(
  330. HWND DialogHwnd,
  331. HWND FocusHwnd,
  332. LPARAM Lparam
  333. )
  334. {
  335. PPORT_PARAMS params;
  336. DWORD dwError;
  337. //DbgOut(TEXT("Port_OnInitDialog\n"));
  338. //
  339. // on WM_INITDIALOG call, lParam points to the property
  340. // sheet page.
  341. //
  342. // The lParam field in the property sheet page struct is set by the
  343. // caller. When I created the property sheet, I passed in a pointer
  344. // to a struct containing information about the device. Save this in
  345. // the user window long so I can access it on later messages.
  346. //
  347. params = (PPORT_PARAMS) ((LPPROPSHEETPAGE)Lparam)->lParam;
  348. SetWindowLongPtr(DialogHwnd, DWLP_USER, (ULONG_PTR) params);
  349. // Display board details
  350. FillNumberOfPortsText(DialogHwnd,params);
  351. FillModelAndBusTypeText(DialogHwnd,params);
  352. //
  353. // Set up the combo box with choices
  354. //
  355. if (params->ShowStartCom) {
  356. ComDBOpen(&params->hComDB);
  357. params->ShowStartCom = FillStartComCb(DialogHwnd, params);
  358. if (params->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
  359. ComDBClose(params->hComDB);
  360. }
  361. } else {
  362. EnableWindow(GetDlgItem(DialogHwnd, PP_START_COM), FALSE);
  363. EnableWindow(GetDlgItem(DialogHwnd, IDC_START_COM), FALSE);
  364. }
  365. return TRUE; // No need for us to set the focus.
  366. }
  367. BOOL
  368. Port_OnNotify(
  369. HWND DialogHwnd,
  370. LPNMHDR NmHdr
  371. )
  372. {
  373. PPORT_PARAMS params = (PPORT_PARAMS)GetWindowLongPtr(DialogHwnd, DWLP_USER);
  374. switch (NmHdr->code) {
  375. //
  376. // Sent when the user clicks on Apply OR OK !!
  377. //
  378. case PSN_APPLY:
  379. //DbgOut(TEXT("Port_OnNotify PSN_APPLY\n"));
  380. //
  381. // Write out the com port options to the registry
  382. //
  383. if (SavePortSettingsDlg(DialogHwnd, params)) {
  384. SetWindowLongPtr(DialogHwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
  385. } else {
  386. SetWindowLongPtr(DialogHwnd, DWLP_MSGRESULT, PSNRET_INVALID);
  387. }
  388. return TRUE;
  389. default:
  390. //DbgOut(TEXT("Port_OnNotify default\n"));
  391. return FALSE;
  392. }
  393. }
  394. ULONG
  395. FillModelAndBusTypeText(
  396. IN HWND DialogHwnd,
  397. IN PPORT_PARAMS Params
  398. )
  399. {
  400. TCHAR szHardwareId[LINE_LEN];
  401. PTCHAR szCharPtr;
  402. HWND detailHwnd;
  403. TCHAR szBusType[10];
  404. TCHAR szConfiguration[10];
  405. TCHAR szModel[10];
  406. DWORD dataType;
  407. ZeroMemory(szBusType,sizeof(szBusType));
  408. ZeroMemory(szConfiguration,sizeof(szConfiguration));
  409. ZeroMemory(szModel,sizeof(szModel));
  410. if (SetupDiGetDeviceRegistryProperty(Params->DeviceInfoSet,
  411. Params->DeviceInfoData,
  412. SPDRP_HARDWAREID,
  413. &dataType,
  414. (PBYTE) szHardwareId,
  415. sizeof(szHardwareId),
  416. NULL)) {
  417. szCharPtr = szHardwareId;
  418. while (*szCharPtr) {
  419. if (_tcsnicmp(szCharPtr,
  420. TEXT("PCI\\VEN_120E&DEV_0100&SUBSYS_0100120E"),
  421. _tcslen(TEXT("PCI\\VEN_120E&DEV_0100&SUBSYS_0100120E")))
  422. == 0) {
  423. wsprintf(szBusType, TEXT("PCI"));
  424. wsprintf(szConfiguration, TEXT("Below 1MB"));
  425. wsprintf(szModel, TEXT("YeP"));
  426. break;
  427. } else if (_tcsnicmp(szCharPtr,
  428. TEXT("PCI\\VEN_120E&DEV_0101&SUBSYS_0100120E"),
  429. _tcslen(TEXT("PCI\\VEN_120E&DEV_0101&SUBSYS_0100120E")))
  430. == 0) {
  431. wsprintf(szBusType, TEXT("PCI"));
  432. wsprintf(szConfiguration, TEXT("Above 1MB"));
  433. wsprintf(szModel, TEXT("YeP"));
  434. break;
  435. } else if (_tcsnicmp(szCharPtr,
  436. TEXT("PCI\\VEN_120E&DEV_0100"),
  437. _tcslen(TEXT("PCI\\VEN_120E&DEV_0100")))
  438. == 0) {
  439. wsprintf(szBusType, TEXT("PCI"));
  440. wsprintf(szConfiguration, TEXT("Below 1MB"));
  441. break;
  442. } else if (_tcsnicmp(szCharPtr,
  443. TEXT("PCI\\VEN_120E&DEV_0101"),
  444. _tcslen(TEXT("PCI\\VEN_120E&DEV_0101")))
  445. == 0) {
  446. wsprintf(szBusType, TEXT("PCI"));
  447. wsprintf(szConfiguration, TEXT("Above 1MB"));
  448. break;
  449. } else if (_tcsnicmp(szCharPtr,
  450. TEXT("PCI\\VEN_120E&DEV_0102"),
  451. _tcslen(TEXT("PCI\\VEN_120E&DEV_0102")))
  452. == 0) {
  453. wsprintf(szBusType, TEXT("PCI"));
  454. wsprintf(szConfiguration, TEXT("Below 1MB"));
  455. wsprintf(szModel, TEXT("4YP"));
  456. break;
  457. } else if (_tcsnicmp(szCharPtr,
  458. TEXT("PCI\\VEN_120E&DEV_0103"),
  459. _tcslen(TEXT("PCI\\VEN_120E&DEV_0103")))
  460. == 0) {
  461. wsprintf(szBusType, TEXT("PCI"));
  462. wsprintf(szConfiguration, TEXT("Above 1MB"));
  463. wsprintf(szModel, TEXT("4YP"));
  464. break;
  465. } else if (_tcsnicmp(szCharPtr,
  466. TEXT("PCI\\VEN_120E&DEV_0104"),
  467. _tcslen(TEXT("PCI\\VEN_120E&DEV_0104")))
  468. == 0) {
  469. wsprintf(szBusType, TEXT("PCI"));
  470. wsprintf(szConfiguration, TEXT("Below 1MB"));
  471. wsprintf(szModel, TEXT("8YP"));
  472. break;
  473. } else if (_tcsnicmp(szCharPtr,
  474. TEXT("PCI\\VEN_120E&DEV_0105"),
  475. _tcslen(TEXT("PCI\\VEN_120E&DEV_0105")))
  476. == 0) {
  477. wsprintf(szBusType, TEXT("PCI"));
  478. wsprintf(szConfiguration, TEXT("Above 1MB"));
  479. wsprintf(szModel, TEXT("8YP"));
  480. break;
  481. } else if (_tcsnicmp(szCharPtr,
  482. TEXT("YISA"),
  483. _tcslen(TEXT("YISA")))
  484. == 0) {
  485. wsprintf(szBusType, TEXT("ISA"));
  486. } break;
  487. szCharPtr = szCharPtr + _tcslen(szCharPtr) + 1;
  488. }
  489. if (*szBusType) {
  490. detailHwnd = GetDlgItem(DialogHwnd, PP_BUS_TYPE);
  491. SetWindowText(detailHwnd,szBusType);
  492. }
  493. if (*szConfiguration) {
  494. detailHwnd = GetDlgItem(DialogHwnd, IDC_CONFIGURATION);
  495. SetWindowText(detailHwnd,TEXT("Configuration:"));
  496. detailHwnd = GetDlgItem(DialogHwnd, PP_CONFIGURATION);
  497. SetWindowText(detailHwnd,szConfiguration);
  498. }
  499. if (*szModel) {
  500. detailHwnd = GetDlgItem(DialogHwnd, IDC_MODEL);
  501. SetWindowText(detailHwnd,TEXT("Model:"));
  502. detailHwnd = GetDlgItem(DialogHwnd, PP_MODEL);
  503. SetWindowText(detailHwnd,szModel);
  504. }
  505. }
  506. return ERROR_SUCCESS;
  507. }
  508. ULONG
  509. FillNumberOfPortsText(
  510. IN HWND DialogHwnd,
  511. IN PPORT_PARAMS Params
  512. )
  513. {
  514. HKEY hDeviceKey;
  515. DWORD err,numOfPortsSize,numOfPorts;
  516. HWND numportHwnd;
  517. TCHAR szText[10];
  518. err = ERROR_SUCCESS;
  519. if((hDeviceKey = SetupDiOpenDevRegKey(Params->DeviceInfoSet,
  520. Params->DeviceInfoData,
  521. DICS_FLAG_GLOBAL,
  522. 0,
  523. DIREG_DEV,
  524. KEY_READ)) == INVALID_HANDLE_VALUE) {
  525. err = GetLastError();
  526. goto FillNPortsExit;
  527. }
  528. numOfPortsSize = sizeof(numOfPorts);
  529. err = RegQueryValueEx(hDeviceKey,
  530. y_szNumOfPorts,
  531. NULL,
  532. NULL,
  533. (PBYTE)&numOfPorts,
  534. &numOfPortsSize
  535. );
  536. //********************************************************
  537. // TEST ERROR
  538. // err=ERROR_REGISTRY_CORRUPT;
  539. //********************************************************
  540. RegCloseKey(hDeviceKey);
  541. if(err != ERROR_SUCCESS) {
  542. goto FillNPortsExit;
  543. }
  544. numportHwnd = GetDlgItem(DialogHwnd, PP_NUM_PORTS);
  545. wsprintf(szText, TEXT("%d"),numOfPorts);
  546. SetWindowText(numportHwnd,szText);
  547. FillNPortsExit:
  548. //if (err != ERROR_SUCCESS) {
  549. // MyMessageBoxWithErr(DialogHwnd,IDS_NUM_PORTS_DISABLED,IDS_CYCLOMY,MB_ICONWARNING,err);
  550. //}
  551. return err;
  552. }
  553. /*++
  554. Routine Description: FillStartComCb
  555. fill in the Port Name combo box selection with a list
  556. of possible un-used portnames
  557. Arguments:
  558. poppOurPropParams: where to save the data to
  559. hDlg: address of the window
  560. Return Value:
  561. BOOL: TRUE if StartCom CB displayed with no errors
  562. --*/
  563. BOOL
  564. FillStartComCb(
  565. HWND ParentHwnd,
  566. PPORT_PARAMS Params
  567. )
  568. {
  569. int i, j, nEntries;
  570. DWORD nCurPortNum = 0;
  571. DWORD nCom; // Changed from int to DWORD (Fanny)
  572. DWORD dwError;
  573. TCHAR szCom[40];
  574. TCHAR szInUse[40];
  575. char mask, *current;
  576. HWND portHwnd;
  577. DEVINST devInst,newInst;
  578. //DbgOut(TEXT("FillStartComCb\n"));
  579. portHwnd = GetDlgItem(ParentHwnd, PP_START_COM);
  580. if (Params->hComDB == HCOMDB_INVALID_HANDLE_VALUE) {
  581. // This happens if we don't have sufficient security privileges.
  582. EnableWindow(portHwnd, FALSE);
  583. EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
  584. return 0;
  585. }
  586. if (Params->PortUsage == NULL || Params->PortUsageSize == 0) {
  587. MyMessageBox(ParentHwnd,
  588. IDS_MEM_ALLOC_WRN,
  589. IDS_CYCLOMY,
  590. MB_ICONWARNING);
  591. EnableWindow(portHwnd, FALSE);
  592. EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
  593. return 0;
  594. }
  595. if (!LoadString(g_hInst, IDS_IN_USE, szInUse, CharSizeOf(szInUse))) {
  596. wcscpy(szInUse, _T(" (in use)"));
  597. }
  598. //
  599. // first tally up which ports NOT to offer in list box, ie,
  600. // my ports should not appear as In Use.
  601. //
  602. if (CM_Get_Child(&devInst,(Params->DeviceInfoData)->DevInst,0) == CR_SUCCESS) {
  603. if ((dwError=GetPortName(devInst,Params->szComName,sizeof(Params->szComName))) != ERROR_SUCCESS) {
  604. MyMessageBoxWithErr(ParentHwnd,IDS_START_COM_DISABLED,IDS_CYCLOMY,MB_ICONWARNING,dwError);
  605. EnableWindow(portHwnd, FALSE);
  606. EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
  607. return 0;
  608. }
  609. nCurPortNum = myatoi(&Params->szComName[3]);
  610. //nCom = myatoi(&szCom[3]);
  611. if ((dwError=CheckComRange(ParentHwnd,Params,nCurPortNum)) != COM_RANGE_OK) {
  612. if (dwError == COM_RANGE_TOO_BIG) {
  613. MyMessageBox(ParentHwnd,IDS_COM_TOO_BIG_WRN,IDS_CYCLOMY,MB_ICONWARNING);
  614. } else {
  615. MyMessageBox(ParentHwnd,IDS_MEM_ALLOC_WRN,IDS_CYCLOMY,MB_ICONWARNING);
  616. }
  617. EnableWindow(portHwnd, FALSE);
  618. EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
  619. return 0;
  620. }
  621. current = Params->PortUsage + (nCurPortNum-1) / 8;
  622. if ((i = nCurPortNum % 8))
  623. *current &= ~(1 << (i-1));
  624. else
  625. *current &= ~(0x80);
  626. Params->NumChildren = 1;
  627. while (CM_Get_Sibling(&newInst,devInst,0) == CR_SUCCESS) {
  628. if ((dwError=GetPortName(newInst,szCom,sizeof(szCom))) != ERROR_SUCCESS) {
  629. MyMessageBoxWithErr(ParentHwnd,IDS_START_COM_DISABLED,IDS_CYCLOMY,MB_ICONWARNING,dwError);
  630. EnableWindow(portHwnd, FALSE);
  631. EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
  632. return 0;
  633. }
  634. nCom = myatoi(&szCom[3]);
  635. if ((dwError=CheckComRange(ParentHwnd,Params,nCom)) != COM_RANGE_OK) {
  636. if (dwError == COM_RANGE_TOO_BIG) {
  637. MyMessageBox(ParentHwnd,IDS_COM_TOO_BIG_WRN,IDS_CYCLOMY,MB_ICONWARNING);
  638. } else {
  639. MyMessageBox(ParentHwnd,IDS_MEM_ALLOC_WRN,IDS_CYCLOMY,MB_ICONWARNING);
  640. }
  641. EnableWindow(portHwnd, FALSE);
  642. EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
  643. return 0;
  644. }
  645. current = Params->PortUsage + (nCom-1) / 8;
  646. if ((i = nCom % 8))
  647. *current &= ~(1 << (i-1));
  648. else
  649. *current &= ~(0x80);
  650. Params->NumChildren++;
  651. devInst = newInst;
  652. }
  653. }
  654. // Fill Start COM Combo Box
  655. current = Params->PortUsage;
  656. mask = 0x1;
  657. for(nEntries = j = 0, i = MIN_COM-1; i < MAX_COM_PORT; i++) {
  658. wsprintf(szCom, TEXT("COM%d"), i+1);
  659. if (*current & mask) {
  660. wcscat(szCom, szInUse);
  661. }
  662. if (mask == (char) 0x80) {
  663. mask = 0x01;
  664. current++;
  665. }
  666. else {
  667. mask <<= 1;
  668. }
  669. ComboBox_AddString(portHwnd, szCom);
  670. }
  671. ComboBox_SetCurSel(portHwnd, nCurPortNum-1);
  672. return 1;
  673. } /* FillStartComCb */
  674. /*++
  675. Routine Description: SavePortSettingsDlg
  676. save changes in the Cyclom-Y Settings dlg sheet
  677. Arguments:
  678. Params: where to save the data to
  679. ParentHwnd: address of the window
  680. Return Value:
  681. BOOL: FALSE if function fails, TRUE if function passes
  682. --*/
  683. BOOL
  684. SavePortSettingsDlg(
  685. IN HWND DialogHwnd,
  686. IN PPORT_PARAMS Params
  687. )
  688. {
  689. BOOL retValue = TRUE;
  690. //
  691. // store changes to win.ini; broadcast changes to apps
  692. //
  693. if (Params->ShowStartCom) {
  694. ComDBOpen(&Params->hComDB);
  695. retValue = SavePortSettings(DialogHwnd, Params);
  696. if (Params->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
  697. ComDBClose(Params->hComDB);
  698. }
  699. }
  700. return retValue;
  701. } /* SavePortSettingsDlg */
  702. /*++
  703. Routine Description: SavePortSettings
  704. Read the dlg screen selections for baudrate, parity, etc.
  705. If changed from what we started with, then save them
  706. Arguments:
  707. hDlg: address of the window
  708. szComName: which comport we're dealing with
  709. Params: contains, baudrate, parity, etc
  710. Return Value:
  711. BOOL: FALSE if function fails, TRUE if function passes
  712. --*/
  713. BOOL
  714. SavePortSettings(
  715. IN HWND DialogHwnd,
  716. IN PPORT_PARAMS Params
  717. )
  718. {
  719. UINT startComNum, curComNum, newComNum = CB_ERR;
  720. DEVINST devInst,newInst;
  721. TCHAR buffer[BUFFER_SIZE];
  722. PCHILD_DATA ChildPtr,VarChildPtr;
  723. DWORD numChild=0;
  724. DWORD i;
  725. DWORD dwError = ERROR_SUCCESS;
  726. BOOL retValue = FALSE; // FALSE = failure
  727. //DbgOut(TEXT("SavePortSettings\n"));
  728. curComNum = myatoi(Params->szComName + wcslen(m_szCOM));
  729. newComNum = ComboBox_GetCurSel(GetDlgItem(DialogHwnd, PP_START_COM));
  730. if (newComNum == CB_ERR) {
  731. newComNum = curComNum;
  732. }
  733. else {
  734. newComNum++;
  735. }
  736. if (newComNum == curComNum) {
  737. return TRUE; // No change, so just accept it.
  738. }
  739. startComNum = newComNum;
  740. if (Params->hComDB == HCOMDB_INVALID_HANDLE_VALUE) {
  741. MyMessageBox(DialogHwnd,IDS_INVALID_HCOMDB,IDS_CYCLOMY,MB_ICONERROR);
  742. return retValue;
  743. }
  744. ChildPtr = (PCHILD_DATA) LocalAlloc(LPTR,Params->NumChildren * sizeof(CHILD_DATA));
  745. if (ChildPtr == NULL) {
  746. MyMessageBox(DialogHwnd, IDS_MEM_ALLOC_ERR, IDS_CYCLOMY, MB_ICONERROR);
  747. return retValue;
  748. }
  749. VarChildPtr = ChildPtr;
  750. if (CM_Get_Child(&devInst,(Params->DeviceInfoData)->DevInst,0) == CR_SUCCESS) {
  751. if ((dwError = GetPortData(devInst,VarChildPtr)) != ERROR_SUCCESS) {
  752. MyMessageBoxWithErr(DialogHwnd,IDS_START_COM_NOT_CHANGED,IDS_CYCLOMY,
  753. MB_ICONERROR,dwError);
  754. //ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
  755. goto Return;
  756. }
  757. numChild++;
  758. if (!QueryDosDevice(VarChildPtr->szComName, buffer, BUFFER_SIZE-1)) {
  759. dwError = GetLastError();
  760. MyMessageBoxWithErr(DialogHwnd, IDS_START_COM_NOT_CHANGED, IDS_CYCLOMY,
  761. MB_ICONERROR,dwError);
  762. //ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
  763. goto Return;
  764. }
  765. //#if DBG
  766. //{
  767. //TCHAR buf[500];
  768. //wsprintf(buf, TEXT("QueryDosDevice(%s,buffer,%d) returned %s\n"),VarChildPtr->szComName,BUFFER_SIZE-1,buffer);
  769. //DbgOut(buf);
  770. //}
  771. //#endif
  772. if (TryToOpen(VarChildPtr->szComName) == FALSE) {
  773. dwError = GetLastError();
  774. MyMessageBox(DialogHwnd, IDS_PORT_OPEN_ERROR,IDS_CYCLOMY,MB_ICONERROR,
  775. VarChildPtr->szComName);
  776. //ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
  777. goto Return;
  778. }
  779. if ((dwError = CheckComRange(DialogHwnd,Params,newComNum)) != COM_RANGE_OK) {
  780. if (dwError == COM_RANGE_TOO_BIG) {
  781. MyMessageBox(DialogHwnd, IDS_COM_TOO_BIG_ERR,IDS_CYCLOMY,MB_ICONERROR);
  782. } else {
  783. MyMessageBox(DialogHwnd, IDS_MEM_ALLOC_ERR,IDS_CYCLOMY,MB_ICONERROR);
  784. }
  785. //ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
  786. goto Return;
  787. }
  788. if (!NewComAvailable(Params,newComNum)) {
  789. MyMessageBox(DialogHwnd, IDS_PORT_IN_USE_ERROR, IDS_CYCLOMY,MB_ICONERROR);
  790. //ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
  791. goto Return;
  792. }
  793. VarChildPtr->NewComNum = newComNum;
  794. while (CM_Get_Sibling(&newInst,devInst,0) == CR_SUCCESS) {
  795. if (numChild >= Params->NumChildren) {
  796. // We should never reach here.
  797. DbgOut(TEXT("cyycoins Somehow I'm getting different number of children this time!\n"));
  798. break;
  799. }
  800. VarChildPtr++;
  801. if ((dwError=GetPortData(newInst,VarChildPtr)) != ERROR_SUCCESS) {
  802. MyMessageBoxWithErr(DialogHwnd, IDS_START_COM_NOT_CHANGED, IDS_CYCLOMY,
  803. MB_ICONERROR,dwError);
  804. goto Return;
  805. }
  806. numChild++;
  807. if (!QueryDosDevice(VarChildPtr->szComName, buffer, BUFFER_SIZE-1)) {
  808. dwError = GetLastError();
  809. MyMessageBoxWithErr(DialogHwnd, IDS_START_COM_NOT_CHANGED, IDS_CYCLOMY,
  810. MB_ICONERROR,dwError);
  811. goto Return;
  812. }
  813. if (TryToOpen(VarChildPtr->szComName) == FALSE) {
  814. dwError = GetLastError();
  815. MyMessageBox(DialogHwnd, IDS_PORT_OPEN_ERROR,IDS_CYCLOMY,
  816. MB_ICONERROR,VarChildPtr->szComName);
  817. goto Return;
  818. }
  819. while (1) {
  820. newComNum++;
  821. if ((dwError=CheckComRange(DialogHwnd,Params,newComNum)) != COM_RANGE_OK) {
  822. if (dwError == COM_RANGE_TOO_BIG) {
  823. MyMessageBox(DialogHwnd, IDS_COM_TOO_BIG_ERR,IDS_CYCLOMY,MB_ICONERROR);
  824. } else {
  825. MyMessageBox(DialogHwnd, IDS_MEM_ALLOC_ERR,IDS_CYCLOMY,MB_ICONERROR);
  826. }
  827. //ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
  828. goto Return;
  829. }
  830. if (NewComAvailable(Params,newComNum)) {
  831. break;
  832. }
  833. }
  834. VarChildPtr->NewComNum = newComNum;
  835. devInst = newInst;
  836. }
  837. }
  838. if (startComNum < curComNum) {
  839. VarChildPtr = ChildPtr;
  840. }
  841. for (i=0; i<numChild; i++) {
  842. EnactComNameChanges(DialogHwnd,Params,VarChildPtr);
  843. if (startComNum < curComNum) {
  844. VarChildPtr++;
  845. } else {
  846. VarChildPtr--;
  847. }
  848. }
  849. retValue = TRUE; // TRUE = SUCCESS
  850. Return:
  851. if (ChildPtr) {
  852. VarChildPtr = ChildPtr;
  853. for (i=0; i<numChild; i++) {
  854. ClosePortData(VarChildPtr);
  855. VarChildPtr++;
  856. }
  857. LocalFree(ChildPtr);
  858. }
  859. return retValue;
  860. } /* SavePortSettings */
  861. void
  862. RestoreDefaults(
  863. HWND DialogHwnd,
  864. PPORT_PARAMS Params
  865. )
  866. {
  867. USHORT ushIndex;
  868. ushIndex =
  869. (USHORT) ComboBox_FindString(GetDlgItem(DialogHwnd, PP_START_COM),
  870. -1,
  871. Params->szComName);
  872. ushIndex = (ushIndex == CB_ERR) ? 0 : ushIndex;
  873. ComboBox_SetCurSel(GetDlgItem(DialogHwnd, PP_START_COM), ushIndex);
  874. }
  875. void
  876. MigratePortSettings(
  877. LPCTSTR OldComName,
  878. LPCTSTR NewComName
  879. )
  880. {
  881. TCHAR settings[BUFFER_SIZE];
  882. TCHAR szNew[20], szOld[20];
  883. lstrcpy(szOld, OldComName);
  884. wcscat(szOld, m_szColon);
  885. lstrcpy(szNew, NewComName);
  886. wcscat(szNew, m_szColon);
  887. settings[0] = TEXT('\0');
  888. GetProfileString(m_szPorts,
  889. szOld,
  890. TEXT(""),
  891. settings,
  892. sizeof(settings) / sizeof(TCHAR) );
  893. //
  894. // Insert the new key based on the old one
  895. //
  896. if (settings[0] == TEXT('\0')) {
  897. WriteProfileString(m_szPorts, szNew, m_szDefParams);
  898. }
  899. else {
  900. WriteProfileString(m_szPorts, szNew, settings);
  901. }
  902. //
  903. // Notify everybody of the changes and blow away the old key
  904. //
  905. SendWinIniChange((LPTSTR)m_szPorts);
  906. WriteProfileString(m_szPorts, szOld, NULL);
  907. }
  908. void
  909. EnactComNameChanges(
  910. IN HWND ParentHwnd,
  911. IN PPORT_PARAMS Params,
  912. IN PCHILD_DATA ChildPtr)
  913. {
  914. DWORD dwNewComNameLen;
  915. TCHAR buffer[BUFFER_SIZE];
  916. TCHAR szFriendlyNameFormat[LINE_LEN];
  917. TCHAR szDeviceDesc[LINE_LEN];
  918. TCHAR szNewComName[20];
  919. UINT i;
  920. UINT curComNum,NewComNum;
  921. SP_DEVINSTALL_PARAMS spDevInstall;
  922. //DbgOut(TEXT("EnactComNameChanges\n"));
  923. NewComNum = ChildPtr->NewComNum;
  924. curComNum = myatoi(ChildPtr->szComName + wcslen(m_szCOM));
  925. wsprintf(szNewComName, _T("COM%d"), NewComNum);
  926. dwNewComNameLen = ByteCountOf(wcslen(szNewComName) + 1);
  927. //
  928. // Change the name in the symbolic namespace.
  929. // First try to get what device the old com name mapped to
  930. // (ie something like \Device\Serial0). Then remove the mapping. If
  931. // the user isn't an admin, then this will fail and the dialog will popup.
  932. // Finally, map the new name to the old device retrieved from the
  933. // QueryDosDevice
  934. //
  935. //if (updateMapping)
  936. {
  937. BOOL removed;
  938. HKEY hSerialMap;
  939. if (!QueryDosDevice(ChildPtr->szComName, buffer, BUFFER_SIZE-1)) {
  940. //
  941. // This shouldn't happen because the previous QueryDosDevice call
  942. // succeeded
  943. //
  944. MyMessageBox(ParentHwnd, IDS_PORT_RENAME_ERROR, IDS_CYCLOMY,
  945. MB_ICONERROR, curComNum);
  946. return;
  947. }
  948. //
  949. // If this fails, then the following define will just replace the current
  950. // mapping.
  951. //
  952. removed = DefineDosDevice(DDD_REMOVE_DEFINITION, ChildPtr->szComName, NULL);
  953. if (!DefineDosDevice(DDD_RAW_TARGET_PATH, szNewComName, buffer)) {
  954. //
  955. // error, first fix up the remove definition and restore the old
  956. // mapping
  957. //
  958. if (removed) {
  959. DefineDosDevice(DDD_RAW_TARGET_PATH, ChildPtr->szComName, buffer);
  960. }
  961. MyMessageBox(ParentHwnd, IDS_PORT_RENAME_ERROR, IDS_CYCLOMY,
  962. MB_ICONERROR, curComNum);
  963. return;
  964. }
  965. //
  966. // Set the \\HARDWARE\DEVICEMAP\SERIALCOMM field
  967. //
  968. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  969. m_szRegSerialMap,
  970. 0,
  971. KEY_ALL_ACCESS,
  972. &hSerialMap) == ERROR_SUCCESS) {
  973. TCHAR szSerial[BUFFER_SIZE];
  974. DWORD dwSerialSize, dwEnum, dwType, dwComSize;
  975. TCHAR szCom[BUFFER_SIZE];
  976. i = 0;
  977. do {
  978. dwSerialSize = CharSizeOf(szSerial);
  979. dwComSize = sizeof(szCom);
  980. dwEnum = RegEnumValue(hSerialMap,
  981. i++,
  982. szSerial,
  983. &dwSerialSize,
  984. NULL,
  985. &dwType,
  986. (LPBYTE)szCom,
  987. &dwComSize);
  988. if (dwEnum == ERROR_SUCCESS) {
  989. if(dwType != REG_SZ)
  990. continue;
  991. if (wcscmp(szCom, ChildPtr->szComName) == 0) {
  992. RegSetValueEx(hSerialMap,
  993. szSerial,
  994. 0,
  995. REG_SZ,
  996. (PBYTE) szNewComName,
  997. dwNewComNameLen);
  998. break;
  999. }
  1000. }
  1001. } while (dwEnum == ERROR_SUCCESS);
  1002. }
  1003. RegCloseKey(hSerialMap);
  1004. }
  1005. //
  1006. // Update the com db
  1007. //
  1008. if (Params->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
  1009. ComDBReleasePort(Params->hComDB, (DWORD) curComNum);
  1010. ComDBClaimPort(Params->hComDB, (DWORD) NewComNum, TRUE, NULL);
  1011. }
  1012. //
  1013. // Set the friendly name in the form of DeviceDesc (COM#)
  1014. //
  1015. if (ReplaceFriendlyName(ChildPtr->DeviceInfoSet,
  1016. &ChildPtr->DeviceInfoData,
  1017. szNewComName) == FALSE) {
  1018. // ReplaceFriendlyName failed. Use original code.
  1019. if (LoadString(g_hInst,
  1020. IDS_FRIENDLY_FORMAT,
  1021. szFriendlyNameFormat,
  1022. CharSizeOf(szFriendlyNameFormat)) &&
  1023. SetupDiGetDeviceRegistryProperty(ChildPtr->DeviceInfoSet,
  1024. &ChildPtr->DeviceInfoData,
  1025. SPDRP_DEVICEDESC,
  1026. NULL,
  1027. (PBYTE) szDeviceDesc,
  1028. sizeof(szDeviceDesc),
  1029. NULL)) {
  1030. wsprintf(buffer, szFriendlyNameFormat, szDeviceDesc, szNewComName);
  1031. }
  1032. else {
  1033. //
  1034. // Use the COM port name straight out
  1035. //
  1036. lstrcpy(buffer, szNewComName);
  1037. }
  1038. SetupDiSetDeviceRegistryProperty(ChildPtr->DeviceInfoSet,
  1039. &ChildPtr->DeviceInfoData,
  1040. SPDRP_FRIENDLYNAME,
  1041. (PBYTE) buffer,
  1042. ByteCountOf(wcslen(buffer)+1));
  1043. }
  1044. //
  1045. // Set the parent dialog's title to reflect the change in the com port's name
  1046. //
  1047. //ChangeParentTitle(GetParent(ParentHwnd), AdvancedData->szComName, szNewComName);
  1048. MigratePortSettings(ChildPtr->szComName, szNewComName);
  1049. //
  1050. // Update the PortName value in the devnode
  1051. //
  1052. RegSetValueEx(ChildPtr->hDeviceKey,
  1053. m_szPortName,
  1054. 0,
  1055. REG_SZ,
  1056. (PBYTE)szNewComName,
  1057. dwNewComNameLen);
  1058. //
  1059. // Now broadcast this change to the device manager
  1060. //
  1061. ZeroMemory(&spDevInstall, sizeof(SP_DEVINSTALL_PARAMS));
  1062. spDevInstall.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  1063. if (SetupDiGetDeviceInstallParams(Params->DeviceInfoSet,
  1064. Params->DeviceInfoData,
  1065. &spDevInstall)) {
  1066. spDevInstall.Flags |= DI_PROPERTIES_CHANGE;
  1067. SetupDiSetDeviceInstallParams(Params->DeviceInfoSet,
  1068. Params->DeviceInfoData,
  1069. &spDevInstall);
  1070. }
  1071. }
  1072. BOOL
  1073. NewComAvailable(
  1074. IN PPORT_PARAMS Params,
  1075. IN DWORD NewComNum
  1076. )
  1077. {
  1078. DWORD i;
  1079. UCHAR mask;
  1080. if ((i = NewComNum % 8))
  1081. mask = 1 << (i-1);
  1082. else
  1083. mask = (char) 0x80;
  1084. if (Params->PortUsage[(NewComNum-1)/8] & mask) {
  1085. //
  1086. // Port has been previously claimed
  1087. //
  1088. return FALSE;
  1089. }
  1090. return TRUE;
  1091. }
  1092. BOOL
  1093. TryToOpen(
  1094. IN PTCHAR szCom
  1095. )
  1096. {
  1097. TCHAR szComFileName[20]; // more than enough for "\\.\COMXxxx"
  1098. HANDLE hCom;
  1099. lstrcpy(szComFileName, L"\\\\.\\");
  1100. lstrcat(szComFileName, szCom);
  1101. //
  1102. // Make sure that the port has not been opened by another application
  1103. //
  1104. hCom = CreateFile(szComFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  1105. FILE_ATTRIBUTE_NORMAL, NULL);
  1106. //
  1107. // If the file handle is invalid, then the com port is open, warn the user
  1108. //
  1109. if (hCom == INVALID_HANDLE_VALUE) {
  1110. return FALSE;
  1111. }
  1112. CloseHandle(hCom);
  1113. return TRUE;
  1114. }
  1115. ULONG
  1116. GetPortName(
  1117. IN DEVINST PortInst,
  1118. IN OUT TCHAR *ComName,
  1119. IN ULONG ComNameSize
  1120. )
  1121. {
  1122. HDEVINFO portInfo;
  1123. SP_DEVINFO_DATA portData;
  1124. TCHAR portId[MAX_DEVICE_ID_LEN];
  1125. DWORD dwPortNameSize, dwError;
  1126. HKEY hDeviceKey;
  1127. dwError = ERROR_SUCCESS;
  1128. if (CM_Get_Device_ID(PortInst,portId,CharSizeOf(portId),0) == CR_SUCCESS) {
  1129. portInfo = SetupDiCreateDeviceInfoList(NULL,NULL);
  1130. if (portInfo != INVALID_HANDLE_VALUE) {
  1131. portData.cbSize = sizeof(SP_DEVINFO_DATA);
  1132. if (SetupDiOpenDeviceInfo(portInfo,portId,NULL,0,&portData)) {
  1133. hDeviceKey = SetupDiOpenDevRegKey(portInfo,&portData,
  1134. DICS_FLAG_GLOBAL,0,
  1135. DIREG_DEV,KEY_READ);
  1136. if (hDeviceKey == INVALID_HANDLE_VALUE) {
  1137. dwError = GetLastError();
  1138. }
  1139. dwPortNameSize = ComNameSize;
  1140. dwError = RegQueryValueEx(hDeviceKey,
  1141. m_szPortName, // "PortName"
  1142. NULL,
  1143. NULL,
  1144. (PBYTE)ComName,
  1145. &dwPortNameSize);
  1146. if (dwError == ERROR_SUCCESS) {
  1147. // #if DBG
  1148. // {
  1149. // TCHAR buf[500];
  1150. // wsprintf(buf, TEXT("cyycoins PortName %s\n"),ComName);
  1151. // DbgOut(buf);
  1152. // }
  1153. // #endif
  1154. }
  1155. RegCloseKey(hDeviceKey);
  1156. } else {
  1157. dwError = GetLastError();
  1158. }
  1159. SetupDiDestroyDeviceInfoList(portInfo);
  1160. } else {
  1161. dwError = GetLastError();
  1162. }
  1163. }
  1164. return dwError;
  1165. }
  1166. ULONG
  1167. GetPortData(
  1168. IN DEVINST PortInst,
  1169. OUT PCHILD_DATA ChildPtr
  1170. )
  1171. {
  1172. HDEVINFO portInfo;
  1173. HKEY hDeviceKey;
  1174. TCHAR portId[MAX_DEVICE_ID_LEN];
  1175. DWORD dwPortNameSize,dwError;
  1176. dwError = ERROR_SUCCESS;
  1177. portInfo = INVALID_HANDLE_VALUE;
  1178. hDeviceKey = INVALID_HANDLE_VALUE;
  1179. if (CM_Get_Device_ID(PortInst,portId,CharSizeOf(portId),0) == CR_SUCCESS) {
  1180. portInfo = SetupDiCreateDeviceInfoList(NULL,NULL);
  1181. if (portInfo != INVALID_HANDLE_VALUE) {
  1182. ChildPtr->DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  1183. if (SetupDiOpenDeviceInfo(portInfo,
  1184. portId,
  1185. NULL,
  1186. 0,
  1187. &ChildPtr->DeviceInfoData)) {
  1188. hDeviceKey = SetupDiOpenDevRegKey(portInfo,&ChildPtr->DeviceInfoData,
  1189. DICS_FLAG_GLOBAL,0,
  1190. DIREG_DEV,KEY_ALL_ACCESS);
  1191. if (hDeviceKey == INVALID_HANDLE_VALUE) {
  1192. dwError = GetLastError();
  1193. } else {
  1194. dwPortNameSize = sizeof(ChildPtr->szComName);
  1195. dwError = RegQueryValueEx(hDeviceKey,
  1196. m_szPortName, // "PortName"
  1197. NULL,
  1198. NULL,
  1199. (PBYTE)ChildPtr->szComName,
  1200. &dwPortNameSize);
  1201. if (dwError != ERROR_SUCCESS) {
  1202. RegCloseKey(hDeviceKey);
  1203. hDeviceKey = INVALID_HANDLE_VALUE;
  1204. }
  1205. }
  1206. } else {
  1207. dwError = GetLastError();
  1208. }
  1209. if (dwError != ERROR_SUCCESS) {
  1210. SetupDiDestroyDeviceInfoList(portInfo);
  1211. portInfo = INVALID_HANDLE_VALUE;
  1212. }
  1213. } else {
  1214. dwError = GetLastError();
  1215. }
  1216. }
  1217. ChildPtr->DeviceInfoSet = portInfo;
  1218. ChildPtr->hDeviceKey = hDeviceKey;
  1219. return dwError;
  1220. }
  1221. void
  1222. ClosePortData(
  1223. IN PCHILD_DATA ChildPtr
  1224. )
  1225. {
  1226. if (ChildPtr->hDeviceKey != INVALID_HANDLE_VALUE) {
  1227. RegCloseKey(ChildPtr->hDeviceKey);
  1228. }
  1229. if (ChildPtr->DeviceInfoSet != INVALID_HANDLE_VALUE) {
  1230. SetupDiDestroyDeviceInfoList(ChildPtr->DeviceInfoSet);
  1231. }
  1232. }
  1233. /*++
  1234. Routine Description: CheckComRange
  1235. Returns TRUE if Com port is in the PortUsage range.
  1236. Arguments:
  1237. ParentHwnd: address of the window
  1238. Params: where to save the data to
  1239. ComPort: com port to be checked
  1240. Return Value:
  1241. COM_RANGE_OK
  1242. COM_RANGE_TOO_BIG
  1243. COM_RANGE_MEM_ERR
  1244. --*/
  1245. DWORD
  1246. CheckComRange(
  1247. HWND ParentHwnd,
  1248. PPORT_PARAMS Params,
  1249. DWORD nCom
  1250. )
  1251. {
  1252. PBYTE newPortUsage;
  1253. DWORD portsReported;
  1254. HCOMDB hComDB;
  1255. DWORD comUsageSize = Params->PortUsageSize*8;
  1256. if (nCom > MAX_COM_PORT) {
  1257. return COM_RANGE_TOO_BIG;
  1258. }
  1259. if (nCom > comUsageSize) {
  1260. if (comUsageSize < 256) {
  1261. comUsageSize = 256;
  1262. } else if (comUsageSize < 1024) {
  1263. comUsageSize = 1024;
  1264. } else if (comUsageSize < 2048) {
  1265. comUsageSize = 2048;
  1266. } else {
  1267. return COM_RANGE_TOO_BIG;
  1268. }
  1269. // Re-alloc to COMDB_MAX_PORTS_ARBITRATED
  1270. newPortUsage = (PBYTE) LocalAlloc(LPTR,comUsageSize/8);
  1271. if (newPortUsage == NULL) {
  1272. return COM_RANGE_MEM_ERR;
  1273. } else {
  1274. //DbgOut(TEXT("Params->PortUsage replaced\n"));
  1275. LocalFree(Params->PortUsage);
  1276. Params->PortUsage = newPortUsage;
  1277. Params->PortUsageSize = comUsageSize/8;
  1278. ComDBGetCurrentPortUsage(Params->hComDB,
  1279. NULL,
  1280. 0,
  1281. 0,
  1282. &portsReported
  1283. );
  1284. if (comUsageSize > portsReported) {
  1285. if (ComDBResizeDatabase(Params->hComDB, comUsageSize) != ERROR_SUCCESS){
  1286. //return COM_RANGE_TOO_BIG; // TODO: Replace by a better message.
  1287. }
  1288. }
  1289. ComDBGetCurrentPortUsage(Params->hComDB,
  1290. Params->PortUsage,
  1291. Params->PortUsageSize,
  1292. CDB_REPORT_BITS,
  1293. &portsReported
  1294. );
  1295. }
  1296. }
  1297. return COM_RANGE_OK;
  1298. }