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.

1456 lines
42 KiB

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