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.

2154 lines
63 KiB

  1. /*-----------------------------------------------------------------------
  2. | setup.c - VSLinkA/RocketPort Windows Install Program.
  3. 12-11-98 - use szAppTitle(.rc str) instead of aptitle for prop sheet title.
  4. 11-24-98 - zero out psh struct to ensure deterministic propsheet behavior. kpb
  5. 10-23-98 - in send_to_driver, fix ioctl_close() when inappropriate,
  6. caused crash on setup exit.
  7. 9-25-98 - on nt4 uninstall, rename setup.exe to setupold.exe since
  8. we can't delete it. This fixes backward compatibility problem.
  9. Copyright 1998. Comtrol(TM) Corporation.
  10. |-----------------------------------------------------------------------*/
  11. #include "precomp.h"
  12. #define D_Level 0x100
  13. static int option_changed(char *value_str,
  14. int *ret_chg_flag,
  15. int *ret_unknown_flag,
  16. Our_Options *option,
  17. int device_index,
  18. int port_index);
  19. static int send_option(char *str_value,
  20. Our_Options *option,
  21. int device_index,
  22. int port_index,
  23. char *ioctl_buf,
  24. IoctlSetup *ioctl_setup);
  25. static int auto_install(void);
  26. int our_ioctl_call(IoctlSetup *ioctl_setup);
  27. static int remove_old_infs(void);
  28. int debug_flags = 1;
  29. int prompting_off = 0; // turn our_message() prompting off for auto-install
  30. /*----------------------- local vars ---------------------------------*/
  31. static char *szSlash = {"\\"};
  32. static char szInstallGroup[60];
  33. static char szModemInfEntry[60];
  34. #if DBG
  35. static TCHAR *dbg_label = TEXT("DBG_VERSION");
  36. #endif
  37. char szAppTitle[60];
  38. #ifdef S_VS
  39. //----------- VSLinkA Specific Strings and variables
  40. //char *aptitle = {"Comtrol Hardware Setup, Comtrol Corporation"};
  41. char *szAppName = {"VS1000/VS2000/RocketPort Serial Hub"};
  42. char *OurServiceName = {"VSLinka"};
  43. char *OurDriverName = {"VSLinka.sys"};
  44. char *OurAppDir = {"VSLink"};
  45. #ifdef NT50
  46. char *szSetup_hlp = {"vssetup.hlp"};
  47. #else
  48. char *szSetup_hlp = {"setup.hlp"};
  49. #endif
  50. char *progman_list_nt[] = {
  51. szInstallGroup, // "Comtrol VS Link", // group Description
  52. "vslink.grp", // group file name
  53. #ifndef NT50
  54. "Comtrol Hardware Setup", // item 1
  55. "setup.exe", // file 1
  56. #endif
  57. "Test Terminal", // item 2
  58. "wcom32.exe", // file 2
  59. "Port Monitor", // item 3
  60. "portmon.exe", // file 3
  61. NULL};
  62. #else
  63. //----------- RocketPort Specific Strings and variables
  64. //char *aptitle = {"RocketPort Setup, Comtrol Corporation"};
  65. char *szAppName = {"RocketPort"};
  66. char *OurServiceName = {"RocketPort"};
  67. char *OurDriverName = {"rocket.sys"};
  68. char *OurAppDir = {"Rocket"};
  69. #ifdef NT50
  70. char *szSetup_hlp = {"ctmasetp.chm"};
  71. #else
  72. char *szSetup_hlp = {"setup.hlp"};
  73. #endif
  74. char *progman_list_nt[] = {
  75. szInstallGroup, // "Comtrol RocketPort RocketModem", // group Description
  76. "rocket.grp", // group file name
  77. #ifndef NT50
  78. "RocketPort Setup", // item 1
  79. "setup.exe", // file 1
  80. #endif
  81. "Test Terminal", // item 2
  82. "wcom32.exe", // file 2
  83. "Port Monitor", // item 3
  84. "portmon.exe", // file 3
  85. NULL};
  86. #endif
  87. // WinHelp array. commented out values are defined, but unused.
  88. // in alphabetical order...
  89. //
  90. const DWORD help_ids[] = {
  91. IDB_ADD, IDB_ADD,
  92. IDB_DEF, IDB_DEF,
  93. // IDB_DONE,IDB_DONE,
  94. // IDB_HELP,IDB_HELP,
  95. // IDB_INSTALL,IDB_INSTALL,
  96. IDB_PROPERTIES, IDB_PROPERTIES,
  97. IDB_REFRESH, IDB_REFRESH,
  98. IDB_REMOVE, IDB_REMOVE,
  99. IDB_RESET, IDB_RESET,
  100. IDB_STAT_RESET, IDB_STAT_RESET,
  101. IDC_BACKUP_SERVER, IDC_BACKUP_SERVER,
  102. IDC_BACKUP_TIMER, IDC_BACKUP_TIMER,
  103. IDC_CBOX_IOADDR, IDC_CBOX_IOADDR,
  104. // IDC_CBOX_IRQ,IDC_CBOX_IRQ,
  105. IDC_CBOX_MACADDR, IDC_CBOX_MACADDR,
  106. // IDC_CBOX_MAPBAUD,IDC_CBOX_MAPBAUD,
  107. IDC_CBOX_NUMPORTS, IDC_CBOX_NUMPORTS,
  108. IDC_CBOX_SC, IDC_CBOX_SC,
  109. IDC_CBOX_SCAN_RATE,IDC_CBOX_SCAN_RATE,
  110. // IDC_CBOX_TYPE,IDC_CBOX_TYPE,
  111. IDC_CLONE, IDC_CLONE,
  112. // IDC_CONF,IDC_CONF,
  113. IDC_EB_NAME, IDC_EB_NAME,
  114. IDC_GROUP, IDC_GROUP,
  115. IDC_LBL_SUMMARY1, IDC_LBL_SUMMARY1,
  116. IDC_LBL_SUMMARY2, IDC_LBL_SUMMARY2,
  117. IDC_LBOX_DEVICE, IDC_LBOX_DEVICE,
  118. IDC_MAP_2TO1, IDC_MAP_2TO1,
  119. IDC_MAP_CDTODSR, IDC_MAP_CDTODSR,
  120. IDC_RING_EMULATE, IDC_RING_EMULATE,
  121. // IDC_PN0,IDC_PN0,
  122. // IDC_PN1,IDC_PN1,
  123. // IDC_PN2,IDC_PN2,
  124. // IDC_PN3,IDC_PN3,
  125. IDC_PNP_PORTS, IDC_PNP_PORTS,
  126. IDC_PORT_LOCKBAUD, IDC_PORT_LOCKBAUD,
  127. IDC_PORT_RS485_LOCK,IDC_PORT_RS485_LOCK,
  128. IDC_PORT_RS485_TLOW,IDC_PORT_RS485_TLOW,
  129. IDC_PORT_WAIT_ON_CLOSE, IDC_PORT_WAIT_ON_CLOSE,
  130. IDC_PORT_WONTX, IDC_PORT_WONTX,
  131. IDC_PS_PORT, IDC_PS_PORT,
  132. IDC_ST_NIC_DVC_NAME,IDC_ST_NIC_DVC_NAME,
  133. IDC_ST_NIC_MAC, IDC_ST_NIC_MAC,
  134. IDC_ST_NIC_PKT_RCVD_NOT_OURS, IDC_ST_NIC_PKT_RCVD_NOT_OURS,
  135. IDC_ST_NIC_PKT_RCVD_OURS, IDC_ST_NIC_PKT_RCVD_OURS,
  136. IDC_ST_NIC_PKT_SENT, IDC_ST_NIC_PKT_SENT,
  137. IDC_ST_PM_LOADS, IDC_ST_PM_LOADS,
  138. IDC_ST_STATE, IDC_ST_STATE,
  139. IDC_ST_VSL_DETECTED, IDC_ST_VSL_DETECTED,
  140. IDC_ST_VSL_IFRAMES_OUTOFSEQ, IDC_ST_VSL_IFRAMES_OUTOFSEQ,
  141. IDC_ST_VSL_IFRAMES_RCVD, IDC_ST_VSL_IFRAMES_RCVD,
  142. IDC_ST_VSL_IFRAMES_RESENT, IDC_ST_VSL_IFRAMES_RESENT,
  143. IDC_ST_VSL_IFRAMES_SENT, IDC_ST_VSL_IFRAMES_SENT,
  144. IDC_ST_VSL_MAC, IDC_ST_VSL_MAC,
  145. IDC_ST_VSL_STATE, IDC_ST_VSL_STATE,
  146. // IDC_USE_IRQ,IDC_USE_IRQ,
  147. IDC_VERBOSE, IDC_VERBOSE,
  148. IDC_VERSION, IDC_VERSION,
  149. // IDC_WIZ1_ISA,IDC_WIZ1_ISA,
  150. // IDC_WIZ1_ISA2,IDC_WIZ1_ISA2,
  151. IDC_WIZ_BOARD_SELECT, IDC_WIZ_BOARD_SELECT,
  152. IDC_WIZ_CBOX_COUNTRY, IDC_WIZ_CBOX_COUNTRY,
  153. IDC_WIZ_CBOX_IOADDR, IDC_WIZ_CBOX_IOADDR,
  154. IDC_WIZ_CBOX_NUMPORTS, IDC_WIZ_CBOX_NUMPORTS,
  155. IDC_WIZ_CBOX_MAC, IDC_WIZ_CBOX_MAC,
  156. IDC_WIZ_ISA, IDC_WIZ_ISA,
  157. IDC_WIZ_PCI, IDC_WIZ_PCI,
  158. // IDC_ADD_WIZ1,IDC_ADD_WIZ1,
  159. // IDC_ADD_WIZ2,IDC_ADD_WIZ2,
  160. // IDC_ADD_WIZ3,IDC_ADD_WIZ3,
  161. IDD_ADD_WIZ_BASEIO, IDD_ADD_WIZ_BASEIO,
  162. IDD_ADD_WIZ_BOARD, IDD_ADD_WIZ_BOARD,
  163. IDD_ADD_WIZ_BUSTYPE, IDD_ADD_WIZ_BUSTYPE,
  164. IDD_ADD_WIZ_COUNTRY, IDD_ADD_WIZ_COUNTRY,
  165. IDD_ADD_WIZ_DONE, IDD_ADD_WIZ_DONE,
  166. IDD_ADD_WIZ_INTRO, IDD_ADD_WIZ_INTRO,
  167. IDD_ADD_WIZ_NUMPORTS,IDD_ADD_WIZ_NUMPORTS,
  168. IDD_ADD_WIZ_DEVICE, IDD_ADD_WIZ_DEVICE,
  169. IDD_ADD_WIZ_MAC, IDD_ADD_WIZ_MAC,
  170. IDD_ADD_WIZ_BACKUP, IDD_ADD_WIZ_BACKUP,
  171. IDD_DEVICE_SETUP, IDD_DEVICE_SETUP,
  172. IDD_DIALOG1, IDD_DIALOG1,
  173. IDD_DRIVER_OPTIONS, IDD_DRIVER_OPTIONS,
  174. IDD_DRIVER_OPTIONS_NT50, IDD_DRIVER_OPTIONS_NT50,
  175. IDD_MAIN_DLG, IDD_MAIN_DLG,
  176. IDD_PORT_485_OPTIONS,IDD_PORT_485_OPTIONS,
  177. IDD_PORT_MODEM_OPTIONS, IDD_PORT_MODEM_OPTIONS,
  178. IDD_PORT_OPTIONS, IDD_PORT_OPTIONS,
  179. // IDD_PORTLIST_PICK, IDD_PORTLIST_PICK,
  180. // IDD_PROPPAGE_MEDIUM,IDD_PROPPAGE_MEDIUM,
  181. IDD_STATUS,IDD_STATUS, IDD_STATUS,IDD_STATUS,
  182. IDD_VS_DEVICE_SETUP, IDD_VS_DEVICE_SETUP,
  183. IDM_ADVANCED, IDM_ADVANCED,
  184. IDM_ADVANCED_MODEM_INF, IDM_ADVANCED_MODEM_INF,
  185. IDM_ADVANCED_NAMES, IDM_ADVANCED_NAMES,
  186. IDC_GLOBAL485, IDC_GLOBAL485,
  187. // IDM_CLOSE,IDM_CLOSE,
  188. // IDM_EDIT_README,IDM_EDIT_README,
  189. IDM_EXIT, IDM_EXIT,
  190. // IDM_F1,IDM_F1,
  191. // IDM_HELP,IDM_HELP,
  192. // IDM_HELPABOUT,IDM_HELPABOUT,
  193. // IDM_OPTIONS,IDM_OPTIONS,
  194. // IDM_PM,IDM_PM,
  195. // IDM_STATS,IDM_STATS,
  196. 0xffffffff, 0,
  197. 0, 0};
  198. /*-------------------------- Global Variables ---------------------*/
  199. TCHAR m_szRegSerialMap[] = TEXT( "Hardware\\DeviceMap\\SerialComm" );
  200. unsigned char broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
  201. unsigned char mac_zero_addr[6] = {0,0,0,0,0,0};
  202. HWND glob_hwnd = NULL;
  203. HINSTANCE glob_hinst = 0; // current instance
  204. char gtmpstr[250];
  205. HWND glob_hDlg = 0;
  206. OUR_INFO *glob_info = NULL; // global context handles and general baggage to carry.
  207. AddWiz_Config *glob_add_wiz; // transfer buffer from Add Device wizard
  208. Driver_Config *wi; // current info
  209. Driver_Config *org_wi; // original info, use to detect changes
  210. /*------------------------------------------------------------------------
  211. | FillDriverPropertySheets - Setup pages for driver level property sheets.
  212. |------------------------------------------------------------------------*/
  213. int FillDriverPropertySheets(PROPSHEETPAGE *psp, LPARAM our_params)
  214. {
  215. INT pi;
  216. static TCHAR mainsetstr[40], optstr[40];
  217. memset(psp, 0, sizeof(*psp) * NUM_DRIVER_SHEETS);
  218. pi = 0;
  219. psp[pi].dwSize = sizeof(PROPSHEETPAGE);
  220. psp[pi].dwFlags = PSP_USETITLE | PSP_HASHELP | PSH_NOAPPLYNOW;
  221. psp[pi].hInstance = glob_hinst;
  222. psp[pi].pszTemplate = MAKEINTRESOURCE(IDD_MAIN_DLG);
  223. psp[pi].pfnDlgProc = DevicePickSheet;
  224. load_str( glob_hinst, (TITLESTR+7), mainsetstr, CharSizeOf(mainsetstr) );
  225. psp[pi].pszTitle = mainsetstr;
  226. psp[pi].lParam = (LPARAM)our_params;
  227. psp[pi].pfnCallback = NULL;
  228. ++pi;
  229. psp[pi].dwSize = sizeof(PROPSHEETPAGE);
  230. psp[pi].dwFlags = PSP_USETITLE | PSP_HASHELP | PSH_NOAPPLYNOW;
  231. psp[pi].hInstance = glob_hinst;
  232. #ifdef NT50
  233. psp[pi].pszTemplate = MAKEINTRESOURCE(IDD_DRIVER_OPTIONS_NT50);
  234. #else
  235. psp[pi].pszTemplate = MAKEINTRESOURCE(IDD_DRIVER_OPTIONS);
  236. #endif
  237. psp[pi].pfnDlgProc = AdvDriverSheet;
  238. load_str( glob_hinst, (TITLESTR+8), optstr, CharSizeOf(optstr) );
  239. psp[pi].pszTitle = optstr;
  240. psp[pi].lParam = (LPARAM)our_params;
  241. psp[pi].pfnCallback = NULL;
  242. return 0;
  243. }
  244. /*------------------------------------------------------------------------
  245. | setup_init - Instantiate and setup our main structures. Also, allocate
  246. space for a original config struct(org_wi) for later detection
  247. of changes made to master config copy(wi).
  248. |------------------------------------------------------------------------*/
  249. int setup_init(void)
  250. {
  251. int size,i;
  252. //---- allocate global baggage struct
  253. glob_info = (OUR_INFO *) calloc(1,sizeof(OUR_INFO));
  254. //---- allocate global add wizard transfer buffer
  255. glob_add_wiz = (AddWiz_Config *) calloc(1, sizeof(AddWiz_Config));
  256. //---- allocate driver struct
  257. size = sizeof(Driver_Config);
  258. wi = (Driver_Config *) calloc(1,size);
  259. memset(wi, 0, size); // clear our structure
  260. org_wi = (Driver_Config *) calloc(1,size);
  261. memset(wi, 0, size); // clear our structure
  262. //---- allocate device structs
  263. size = sizeof(Device_Config) * MAX_NUM_DEVICES;
  264. wi->dev = (Device_Config *) calloc(1,size);
  265. memset(wi->dev, 0, size); // clear our structure
  266. org_wi->dev = (Device_Config *) calloc(1,size);
  267. memset(org_wi->dev, 0, size); // clear our structure
  268. //---- allocate port structs
  269. for (i=0; i<MAX_NUM_DEVICES; i++)
  270. {
  271. size = sizeof(Port_Config) * MAX_NUM_PORTS_PER_DEVICE;
  272. wi->dev[i].ports = (Port_Config *) calloc(1,size);
  273. memset(wi->dev[i].ports, 0, size); // clear our structure
  274. org_wi->dev[i].ports = (Port_Config *) calloc(1,size);
  275. memset(org_wi->dev[i].ports, 0, size); // clear our structure
  276. }
  277. wi->install_style = INS_NETWORK_INF; // default to original nt4.0 style
  278. #if defined(S_VS)
  279. if (load_str(glob_hinst, IDS_VS_INSTALL_GROUP, szInstallGroup, CharSizeOf(szInstallGroup)))
  280. {
  281. MessageBox(GetFocus(), "Error String Load", OurServiceName, MB_OK);
  282. return 1;
  283. }
  284. load_str(glob_hinst, IDS_VS_AP_TITLE, szAppTitle, CharSizeOf(szAppTitle));
  285. load_str(glob_hinst, IDS_VS_MODEM_INF_ENTRY, szModemInfEntry, CharSizeOf(szModemInfEntry));
  286. #else
  287. if (load_str(glob_hinst, IDS_INSTALL_GROUP, szInstallGroup, CharSizeOf(szInstallGroup)))
  288. {
  289. MessageBox(GetFocus(), "Error String Load", OurServiceName, MB_OK);
  290. return 1;
  291. }
  292. load_str(glob_hinst, IDS_AP_TITLE, szAppTitle, CharSizeOf(szAppTitle));
  293. load_str(glob_hinst, IDS_MODEM_INF_ENTRY, szModemInfEntry, CharSizeOf(szModemInfEntry));
  294. #endif
  295. // fill in InstallPaths structure : system info, directory names, etc.
  296. setup_install_info(&wi->ip, // our InstallPaths structure to fill out.
  297. glob_hinst, // stuff to fill it out with...
  298. OurServiceName,
  299. OurDriverName,
  300. szAppTitle,
  301. OurAppDir);
  302. return 0; // ok
  303. }
  304. /*------------------------------------------------------------------------
  305. | copy_setup_init - Make a copy of our original config to detect changes
  306. in our master copy later. This is a bit wasteful of memory, especially
  307. since we just create space for max. num devices and ports, but memory
  308. is cheap.
  309. Should call this after setup_init() allocates these config structs,
  310. and after we input/read the initial configuration from the registry.
  311. |------------------------------------------------------------------------*/
  312. int copy_setup_init(void)
  313. {
  314. int i;
  315. int size;
  316. Device_Config *save_dev;
  317. Port_Config *save_port;
  318. //--- copy the driver configuration
  319. save_dev = org_wi->dev; // retain, don't overwrite this with memcpy!
  320. memcpy(org_wi, wi, sizeof(*wi)); // save copy of original
  321. org_wi->dev = save_dev; // restore our ptr to our device array
  322. for (i=0; i<MAX_NUM_DEVICES; i++)
  323. {
  324. //--- copy the device configuration array
  325. save_port = org_wi->dev[i].ports; // retain, don't overwrite this with memcpy!
  326. memcpy(&org_wi->dev[i], &wi->dev[i], sizeof(Device_Config)); // save copy of original
  327. org_wi->dev[i].ports = save_port; // restore our ptr to our device array
  328. size = sizeof(Port_Config) * MAX_NUM_PORTS_PER_DEVICE;
  329. //--- copy the port configuration array
  330. memcpy(org_wi->dev[i].ports, wi->dev[i].ports, size); // save copy of original
  331. }
  332. return 0; // ok
  333. }
  334. /*------------------------------------------------------------------------
  335. | DoDriverPropPages - Main driver level property sheet for NT4.0
  336. |------------------------------------------------------------------------*/
  337. int DoDriverPropPages(HWND hwndOwner)
  338. {
  339. PROPSHEETPAGE psp[NUM_DRIVER_SHEETS];
  340. PROPSHEETHEADER psh;
  341. OUR_INFO * our_params;
  342. INT stat;
  343. //Fill out the PROPSHEETPAGE data structure for the Background Color
  344. //sheet
  345. our_params = glob_info; // temporary kludge, unless we don't need re-entrantancy
  346. //Fill out the PROPSHEETPAGE data structure for the Client Area Shape
  347. //sheet
  348. FillDriverPropertySheets(&psp[0], (LPARAM)our_params);
  349. //Fill out the PROPSHEETHEADER
  350. memset(&psh, 0, sizeof(PROPSHEETHEADER)); // add fix 11-24-98
  351. psh.dwSize = sizeof(PROPSHEETHEADER);
  352. //psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE;
  353. psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
  354. psh.hwndParent = hwndOwner;
  355. psh.hInstance = glob_hinst;
  356. psh.pszIcon = "";
  357. //psh.pszCaption = (LPSTR) aptitle; //"Driver Properties";
  358. psh.pszCaption = (LPSTR) szAppTitle; //"Driver Properties";
  359. psh.nPages = NUM_DRIVER_SHEETS;
  360. psh.ppsp = (LPCPROPSHEETPAGE) &psp;
  361. //And finally display the dialog with the two property sheets.
  362. DbgPrintf(D_Init, ("Init 8\n"))
  363. stat = PropertySheet(&psh);
  364. return 0;
  365. }
  366. /*---------------------------------------------------------------------------
  367. our_context_help -
  368. |---------------------------------------------------------------------------*/
  369. void our_context_help(LPARAM lParam)
  370. {
  371. LPHELPINFO lphi;
  372. HWND helpWin;
  373. lphi = (LPHELPINFO) lParam;
  374. if ((lphi->iContextType == HELPINFO_MENUITEM) ||
  375. (lphi->iContextType == HELPINFO_WINDOW))
  376. {
  377. //wsprintf(gtmpstr, "id:%d", lphi->iCtrlId);
  378. //our_message(gtmpstr,MB_OK);
  379. //strcpy(gtmpstr, wi->ip.src_dir);
  380. //strcat(gtmpstr,szSlash);
  381. //strcat(gtmpstr,szSetup_hlp);
  382. // strcpy(gtmpstr, szSetup_hlp);
  383. wsprintf(gtmpstr, "%s\\%s", wi->ip.src_dir, szSetup_hlp);
  384. #ifdef NT50
  385. strcat(gtmpstr, "::/");
  386. strcat(gtmpstr, "resource.txt");
  387. helpWin = HtmlHelp((HWND) lphi->hItemHandle, gtmpstr,
  388. HH_TP_HELP_WM_HELP, (DWORD)help_ids);
  389. if (!helpWin) {
  390. DbgPrintf(D_Level, ("Failed to open WhatsThis help window\n"));
  391. }
  392. #else
  393. WinHelp((HWND) lphi->hItemHandle, gtmpstr,
  394. HELP_WM_HELP, (DWORD)help_ids);
  395. #endif
  396. //WinHelp((HWND) lphi->hItemHandle, szSetup_hlp,
  397. // HELP_WM_HELP, (DWORD) help_ids);
  398. //WinHelp(GetFocus(),szSetup_hlp, HELP_CONTEXT, lphi->iCtrlId);
  399. }
  400. #ifdef COMMENT_OUT
  401. if (lphi->iContextType == HELPINFO_MENUITEM)
  402. {
  403. wsprintf(gtmpstr, "id:%d", lphi->iCtrlId);
  404. our_message(gtmpstr,MB_OK);
  405. i = 0;
  406. while ((help_ids[i*2] != lphi->iCtrlId) &&
  407. (help_ids[i*2] != 0xffffffff))
  408. ++i;
  409. if (help_ids[i*2] != 0xffffffff)
  410. WinHelp(GetFocus(),szSetup_hlp, HELP_CONTEXT, help_ids[i*2+1]);
  411. else WinHelp(GetFocus(),szSetup_hlp, HELP_CONTEXT, WIN_NT);
  412. }
  413. if (lphi->iContextType == HELPINFO_WINDOW)
  414. {
  415. wsprintf(gtmpstr, "id:%d", lphi->iCtrlId);
  416. our_message(gtmpstr,MB_OK);
  417. i = 0;
  418. while ((help_ids[i*2] != lphi->iCtrlId) &&
  419. (help_ids[i*2] != 0xffffffff))
  420. ++i;
  421. if (help_ids[i*2] != 0xffffffff)
  422. WinHelp(GetFocus(),szSetup_hlp, HELP_CONTEXTPOPUP, help_ids[i*2+1]);
  423. else WinHelp(GetFocus(),szSetup_hlp, HELP_CONTEXT, WIN_NT);
  424. //WinHelp(GetFocus(),szSetup_hlp, HELP_CONTEXT, lphi->dwContextId);
  425. //WinHelp((HWND) lphi->hItemHandle, szSetup_hlp,
  426. // HELP_WM_HELP, (DWORD) help_ids);
  427. }
  428. #endif
  429. }
  430. /*---------------------------------------------------------------------------
  431. remove_old_infs - A new common Comtrol modem inf file is called mdmctm1.inf,
  432. and replaces older individual ones called: mdmrckt.inf & mdmvsa1.inf.
  433. We must remove the older ones on install to clear out the older entries.
  434. |---------------------------------------------------------------------------*/
  435. static int remove_old_infs(void)
  436. {
  437. static TCHAR *sz_inf = TEXT("\\inf\\");
  438. // delete the old inf\mdmrckt.inf file
  439. GetWindowsDirectory(wi->ip.dest_str,144);
  440. strcat(wi->ip.dest_str, sz_inf);
  441. strcat(wi->ip.dest_str, "mdmrckt.inf");
  442. DeleteFile(wi->ip.dest_str);
  443. // delete the old inf\mdmvsa1.inf file
  444. GetWindowsDirectory(wi->ip.dest_str,144);
  445. strcat(wi->ip.dest_str, sz_inf);
  446. strcat(wi->ip.dest_str, "mdmvsa1.inf");
  447. DeleteFile(wi->ip.dest_str);
  448. return 0; // ok
  449. }
  450. /*---------------------------------------------------------------------------
  451. remove_driver - clear out the driver from the system as much as possible.
  452. |---------------------------------------------------------------------------*/
  453. int remove_driver(int all)
  454. {
  455. int stat,i;
  456. static char *delete_list[] = {
  457. "peer.exe",
  458. "peer.hlp",
  459. "portmon.exe",
  460. "portmon.hlp",
  461. "wcom32.exe",
  462. "wcom.hlp",
  463. //"setup.exe", // since setup is running, a sharing violation prevents this
  464. "readme.txt",
  465. "history.txt",
  466. #ifdef S_VS
  467. "vssetup.hlp",
  468. "vssetup.gid",
  469. #else
  470. "rksetup.hlp",
  471. "rksetup.gid",
  472. "ctmmdmld.rm",
  473. "ctmmdmfw.rm",
  474. #endif
  475. "wcom.gid",
  476. "portmon.gid",
  477. "calcs.dat",
  478. "ctmmdm35.inf",
  479. "portmon.vew",
  480. NULL};
  481. // delete the drivers\rocket.sys driver file
  482. GetSystemDirectory(wi->ip.dest_str,144);
  483. strcat(wi->ip.dest_str, "\\drivers\\");
  484. strcat(wi->ip.dest_str, wi->ip.szDriverName);
  485. DeleteFile(wi->ip.dest_str);
  486. #ifdef S_VS
  487. // form "vslinka.bin", and delete the file from drivers dir
  488. // cut off .sys as "vslink."
  489. wi->ip.dest_str[strlen(wi->ip.dest_str) - 3] = 0;
  490. strcat(wi->ip.dest_str, "bin");
  491. DeleteFile(wi->ip.dest_str);
  492. #endif
  493. if (all)
  494. {
  495. // had some problems implementing, so the "all" is for
  496. // test right now.
  497. // delete most of the files in system32\ROCKET directory
  498. i = 0;
  499. while (delete_list[i] != NULL)
  500. {
  501. //wsprintf(tmpstr, "
  502. //MessageBox(0, s, "Debug", MB_OK);
  503. GetSystemDirectory(wi->ip.dest_str,144);
  504. strcat(wi->ip.dest_str, szSlash);
  505. strcat(wi->ip.dest_str, wi->ip.szAppDir);
  506. strcat(wi->ip.dest_str, szSlash);
  507. strcat(wi->ip.dest_str, delete_list[i]);
  508. DeleteFile(wi->ip.dest_str);
  509. ++i;
  510. }
  511. #ifndef NT50
  512. // we can't just delete ourselves, so we rename ourselves
  513. // and that is good enough.
  514. GetSystemDirectory(wi->ip.dest_str,144);
  515. strcat(wi->ip.dest_str, szSlash);
  516. strcat(wi->ip.dest_str, wi->ip.szAppDir);
  517. strcat(wi->ip.dest_str, szSlash);
  518. strcpy(wi->ip.src_str, wi->ip.dest_str);
  519. strcat(wi->ip.dest_str, "setupold.exe");
  520. strcat(wi->ip.src_str, "setup.exe");
  521. stat = MoveFileEx(wi->ip.src_str, wi->ip.dest_str, MOVEFILE_REPLACE_EXISTING);
  522. #endif
  523. }
  524. // kill our program manager
  525. stat = delete_progman_group(progman_list_nt, wi->ip.dest_dir);
  526. // remove some registry entries
  527. stat = remove_driver_reg_entries(wi->ip.szServiceName);
  528. setup_service(OUR_REMOVE, OUR_SERVICE); // do a remove on the service
  529. return 0;
  530. }
  531. /*-----------------------------------------------------------------------------
  532. | allow_exit - Performs 3 tasks:
  533. 1.) If cancel selected: check to see if we allow the user to cancel
  534. out of the setup program. If its an initial install, then force
  535. them to save it off with an OK selection.
  536. 2.) If cancel selected: Handle prompting to ask the user if they
  537. really want to cancel without saving.
  538. 3.) If saving, make sure a valid save set is resident. If not,
  539. do various things.
  540. RETURNS: true if we are allowing a cancel, false if we don't allow it.
  541. |-----------------------------------------------------------------------------*/
  542. int allow_exit(int want_to_cancel)
  543. {
  544. int allow_it = 0;
  545. int stat;
  546. if (!wi->ChangesMade)
  547. send_to_driver(0); // evaluate if anything changed(sets ChangesMade if true)
  548. if (want_to_cancel) // they want to cancel out of the setup program
  549. {
  550. if ((do_progman_add) // if initial add, don't let them decline
  551. && (wi->install_style == INS_NETWORK_INF))
  552. {
  553. our_message(&wi->ip,RcStr((MSGSTR+5)),MB_OK);
  554. }
  555. else
  556. {
  557. #ifndef NT50
  558. // only prompt for nt40, I don't want the prompt for nt50...
  559. if (wi->ChangesMade)
  560. {
  561. stat = our_message(&wi->ip,"Quit without making changes?",MB_YESNO);
  562. if (stat == IDYES)
  563. {
  564. allow_it = 1;
  565. }
  566. }
  567. else
  568. #endif
  569. allow_it = 1;
  570. }
  571. }
  572. else // they pressed OK
  573. {
  574. if (wi->NumDevices == 0) // all devices removed, hmmm...
  575. {
  576. if ((wi->nt_reg_flags & 2) || // missing linkage thing(did not install via network inf)
  577. (wi->install_style == INS_SIMPLE))
  578. {
  579. stat = our_message(&wi->ip,RcStr((MSGSTR+6)),MB_YESNO);
  580. if (stat == IDYES)
  581. {
  582. remove_driver(1);
  583. //PostQuitMessage(0); // end the setup program.
  584. allow_it = 1;
  585. }
  586. }
  587. else
  588. {
  589. #ifdef NT50
  590. our_message(&wi->ip,RcStr((MSGSTR+20)),MB_OK);
  591. #else
  592. our_message(&wi->ip,RcStr((MSGSTR+7)),MB_OK);
  593. #endif
  594. }
  595. }
  596. else
  597. {
  598. #ifndef NT50
  599. // only prompt for nt40, I don't want the prompt for nt50...
  600. // maybe we should yank it out for 40 too.
  601. if (wi->ChangesMade)
  602. {
  603. stat = our_message(&wi->ip, "Save configuration changes and exit?", MB_YESNO);
  604. if (stat == IDYES)
  605. {
  606. allow_it = 1;
  607. }
  608. }
  609. else
  610. #endif
  611. allow_it = 1;
  612. }
  613. }
  614. return allow_it;
  615. }
  616. /*-----------------------------------------------------------------------------
  617. | our_exit - save/do install on exit if required.
  618. |-----------------------------------------------------------------------------*/
  619. void our_exit(void)
  620. {
  621. int stat;
  622. static int did_exit = 0;
  623. // prop pages have independent action which under nt5.0 cause multiple
  624. // exit points, this did_exit thing prevents prompting and saving twice..
  625. if (did_exit)
  626. return;
  627. {
  628. if (wi->NumDevices > 0)
  629. {
  630. #ifndef NT50
  631. // only setup service for NT4.0 for now..
  632. stat = do_install();
  633. setup_service(OUR_RESTART, OUR_SERVICE); // restart the service
  634. #endif
  635. if (wi->NeedReset)
  636. our_message(&wi->ip,RcStr((MSGSTR+8)),MB_OK);
  637. }
  638. #ifndef NT50
  639. else
  640. setup_service(OUR_REMOVE, OUR_SERVICE); // do a remove on the service
  641. #endif
  642. }
  643. }
  644. /*-----------------------------------------------------------------------------
  645. | do_install -
  646. |-----------------------------------------------------------------------------*/
  647. int do_install(void)
  648. {
  649. int stat = 0;
  650. int do_remove = 0;
  651. int do_modem_inf = 0;
  652. static int in_here = 0;
  653. if (in_here) // problem hitting OK button twice(sets off two of these)
  654. return 2;
  655. in_here = 1;
  656. #ifndef NT50
  657. if (do_progman_add)
  658. {
  659. if (wi->ip.major_ver == 3) // for NT3.51
  660. do_modem_inf = 1; // only do on initial install
  661. }
  662. if (do_progman_add)
  663. {
  664. // if no inf file, then copy over the files ourselves if initial
  665. // install.
  666. if (wi->install_style == INS_SIMPLE)
  667. {
  668. SetCursor(LoadCursor(NULL, IDC_WAIT)); // load hourglass cursor
  669. stat = copy_files_nt(&wi->ip);
  670. SetCursor(LoadCursor(NULL, IDC_ARROW)); // load arrow
  671. if (stat != 0)
  672. our_message(&wi->ip, "Error while copying files", MB_OK);
  673. }
  674. stat = setup_make_progman_group(0); // no prompt
  675. remove_old_infs(); // kill any old modem infs
  676. }
  677. #endif
  678. in_here = 0;
  679. #ifndef NT50
  680. if (do_modem_inf)
  681. update_modem_inf(0);
  682. if (!do_progman_add) // if initial add, don't let them decline
  683. {
  684. if (!wi->ChangesMade)
  685. send_to_driver(0); // evaluate if anything changed
  686. // i'm getting tire of all these prompts(kb, 8-16-98)...
  687. #if 0
  688. if (wi->ChangesMade)
  689. {
  690. strcpy(gtmpstr, "Setup will now save the new configuration.");
  691. if (our_message(&wi->ip, gtmpstr, MB_OKCANCEL) != IDOK)
  692. return 1; // error
  693. }
  694. #endif
  695. }
  696. if (do_progman_add)
  697. {
  698. if (wi->install_style == INS_SIMPLE)
  699. {
  700. strcpy(gtmpstr, "System32\\Drivers\\");
  701. strcat(gtmpstr, OurDriverName);
  702. stat = service_man(OurServiceName, OurDriverName, CHORE_INSTALL);
  703. //sprintf(gtmpstr, "Install service, result=%x", stat);
  704. //our_message(&wi->ip, gtmpstr, MB_OK);
  705. }
  706. }
  707. #endif
  708. stat = send_to_driver(1);
  709. stat = set_nt_config(wi);
  710. // new, fire the thing up right away after saving options
  711. if (do_progman_add)
  712. {
  713. // try to start the service
  714. // setup_service(OUR_RESTART, OUR_DRIVER); // restart the service
  715. }
  716. if (stat)
  717. return 1; // error
  718. return 0; // ok
  719. }
  720. /*-----------------------------------------------------------------------------
  721. | setup_service - setup our service. The service reads the scanrates of
  722. VS & RocketPort drivers on startup, and adjusts NT's tick based then.
  723. So we need to restart this service.
  724. flags: 1H = stop & remove, 2 = restart it, 4 = install & start
  725. which_service: 0=ctmservi common service task. 1=vs or rk driver.
  726. |-----------------------------------------------------------------------------*/
  727. int setup_service(int flags, int which_service)
  728. {
  729. static char *Ctmservi_OurUserServiceName = {"ctmservi"};
  730. char OurUserServiceName[60];
  731. char OurUserServicePath[60];
  732. //#define DEBUG_SERVICE_FUNC
  733. int installed = 0;
  734. int stat;
  735. if (which_service == 0) // our common service
  736. {
  737. strcpy(OurUserServiceName, Ctmservi_OurUserServiceName);
  738. strcpy(OurUserServicePath, Ctmservi_OurUserServiceName);
  739. strcat(OurUserServicePath, ".exe");
  740. }
  741. else if (which_service == 1) // rk or vs driver service
  742. {
  743. strcpy(OurUserServiceName, OurServiceName); // driver
  744. strcpy(OurUserServicePath, OurDriverName);
  745. }
  746. DbgPrintf(D_Test, ("Service %s Flags:%xH\n", OurUserServiceName, flags))
  747. if (service_man(OurUserServiceName, OurUserServicePath,
  748. CHORE_IS_INSTALLED) == 0) // it's installed
  749. {
  750. installed = 1;
  751. DbgPrintf(D_Test, (" Installed\n"))
  752. }
  753. else
  754. {
  755. DbgPrintf(D_Test, (" Not Installed\n"))
  756. }
  757. if (flags & 1) // remove
  758. {
  759. DbgPrintf(D_Test, (" srv remove\n"))
  760. if (installed)
  761. {
  762. DbgPrintf(D_Test, (" srv remove a\n"))
  763. stat = service_man(OurUserServiceName, OurUserServicePath, CHORE_STOP);
  764. if (stat != 0)
  765. {
  766. DbgPrintf(D_Error, ("Error %d stopping service\n", stat))
  767. }
  768. DbgPrintf(D_Test, (" srv remove b\n"))
  769. stat = service_man(OurUserServiceName, OurUserServicePath, CHORE_REMOVE);
  770. if (stat != 0)
  771. {
  772. DbgPrintf(D_Error, ("Error %d removing service\n", stat))
  773. }
  774. installed = 0;
  775. }
  776. }
  777. if (flags & 2) // restart it
  778. {
  779. DbgPrintf(D_Test, (" srv restart\n"))
  780. if (!installed)
  781. {
  782. DbgPrintf(D_Test, (" srv restart a\n"))
  783. flags |= 4; // install & start it
  784. }
  785. else
  786. {
  787. DbgPrintf(D_Test, (" srv restart b\n"))
  788. stat = service_man(OurUserServiceName, OurUserServicePath, CHORE_STOP);
  789. if (stat != 0)
  790. {
  791. DbgPrintf(D_Error, ("Error %d stopping service\n", stat))
  792. }
  793. // the start was failing with a 1056 error(instance already running)
  794. Sleep(100L);
  795. stat = service_man(OurUserServiceName, OurUserServicePath, CHORE_START);
  796. if (stat != 0)
  797. {
  798. DbgPrintf(D_Error, ("Error %d starting service\n", stat))
  799. }
  800. }
  801. }
  802. if (flags & 4) // install & start it
  803. {
  804. DbgPrintf(D_Test, (" srv install & start\n"))
  805. if (!installed)
  806. {
  807. DbgPrintf(D_Test, (" srv install & start a\n"))
  808. stat = service_man(OurUserServiceName, OurUserServicePath,
  809. CHORE_INSTALL_SERVICE);
  810. if (stat != 0)
  811. {
  812. DbgPrintf(D_Error, ("Error %d installing service\n", stat))
  813. }
  814. stat = service_man(OurUserServiceName, OurUserServicePath, CHORE_START);
  815. if (stat != 0)
  816. {
  817. DbgPrintf(D_Error, ("Error %d starting service\n", stat))
  818. }
  819. }
  820. }
  821. return 0;
  822. }
  823. /*-----------------------------------------------------------------------------
  824. | setup_utils_exist - tells if utils like wcom32.exe, portmon.exe, rksetup.exe
  825. exist. For NT5.0, embedded in OS we may not have utils.
  826. |-----------------------------------------------------------------------------*/
  827. int setup_utils_exist(void)
  828. {
  829. ULONG dstat;
  830. strcpy(gtmpstr, wi->ip.dest_dir);
  831. // first installed file in list
  832. strcat(gtmpstr,"\\");
  833. strcat(gtmpstr,progman_list_nt[3]);
  834. dstat = GetFileAttributes(gtmpstr);
  835. if (dstat != 0xffffffff) // it must exist
  836. return 1; // exists
  837. return 0; // does not exist
  838. }
  839. /*-----------------------------------------------------------------------------
  840. | setup_make_progman_group -
  841. |-----------------------------------------------------------------------------*/
  842. int setup_make_progman_group(int prompt)
  843. {
  844. int stat;
  845. if (prompt)
  846. {
  847. if (our_message(&wi->ip, RcStr((MSGSTR+9)), MB_YESNO) != IDYES)
  848. return 0;
  849. }
  850. stat = make_progman_group(progman_list_nt, wi->ip.dest_dir);
  851. if (stat)
  852. {
  853. our_message(&wi->ip,RcStr((MSGSTR+10)),MB_OK);
  854. }
  855. return stat;
  856. }
  857. /*-----------------------------------------------------------------------------
  858. | update_modem_inf - query and update modem.inf file for rocketmodem entries.
  859. |-----------------------------------------------------------------------------*/
  860. int update_modem_inf(int ok_prompt)
  861. {
  862. int stat;
  863. int do_it = 1;
  864. if (ok_prompt)
  865. {
  866. do_it = 0;
  867. #ifdef S_VS
  868. strcpy(gtmpstr, RcStr((MSGSTR+11)));
  869. #else
  870. strcpy(gtmpstr, RcStr((MSGSTR+12)));
  871. #endif
  872. if (our_message(&wi->ip, gtmpstr, MB_OKCANCEL) == IDOK)
  873. do_it = 1;
  874. }
  875. if (do_it)
  876. {
  877. #ifdef S_VS
  878. stat = modem_inf_change(&wi->ip, "VsLink\\ctmmdm35.inf", szModemInfEntry);
  879. #else
  880. stat = modem_inf_change(&wi->ip, "Rocket\\ctmmdm35.inf", szModemInfEntry);
  881. #endif
  882. if (stat)
  883. {
  884. our_message(&wi->ip,RcStr((MSGSTR+13)),MB_OK);
  885. return 1; // error
  886. }
  887. else
  888. {
  889. if (ok_prompt)
  890. our_message(&wi->ip,RcStr((MSGSTR+14)),MB_OK);
  891. return 1; // error
  892. }
  893. }
  894. return 0; // ok
  895. }
  896. #ifdef S_VS
  897. /*-----------------------------------------------------------------------------
  898. | get_mac_list - get mac address list from driver which polls network for
  899. boxes and returns us a list of mac-addresses(with 2-extra bytes of
  900. misc. bits of information.)
  901. |-----------------------------------------------------------------------------*/
  902. int get_mac_list(char *buf, int in_buf_size, int *ret_buf_size)
  903. {
  904. IoctlSetup ioctl_setup;
  905. int product_id = NT_VS1000;
  906. int stat;
  907. memset(&ioctl_setup, 0 , sizeof(ioctl_setup));
  908. stat = ioctl_open(&ioctl_setup, product_id); // just ensure we can open
  909. if (stat != 0) // error from ioctl
  910. {
  911. *ret_buf_size = 0;
  912. // could not talk to driver
  913. return 1;
  914. }
  915. ioctl_setup.buf_size = in_buf_size - sizeof(*ioctl_setup.pm_base);
  916. ioctl_setup.pm_base = (PortMonBase *) buf;
  917. ioctl_setup.pm_base->struct_type = IOCTL_MACLIST; // get mac-address list
  918. stat = ioctl_call(&ioctl_setup); // get names, number of ports
  919. if (stat)
  920. {
  921. ioctl_close(&ioctl_setup);
  922. *ret_buf_size = 0;
  923. return 0x100; // failed ioctl call
  924. }
  925. ioctl_close(&ioctl_setup);
  926. *ret_buf_size = ioctl_setup.ret_bytes - sizeof(ioctl_setup.pm_base[0]);
  927. return 0; // ok
  928. }
  929. /*------------------------------------------------------------------------
  930. our_get_ping_list - cause the driver to do a broadcast ping on
  931. all devices, and obtain a list of returned mac-addresses and misc.
  932. query flag settings in an array. We allocated buffer space and
  933. just leave it for program/os to clean up.
  934. |------------------------------------------------------------------------*/
  935. BYTE *our_get_ping_list(int *ret_stat, int *ret_bytes)
  936. {
  937. static char *ioctl_buf = NULL; // we alloc this once, then it remains
  938. BYTE *macbuf;
  939. //BYTE *mac;
  940. int found, nbytes, stat;
  941. if (ioctl_buf == NULL)
  942. {
  943. // alloc 8byte mac-address fields(2 times as many as could be configured)
  944. ioctl_buf = calloc(1, (MAX_NUM_DEVICES*8)*2);
  945. }
  946. memset(ioctl_buf, 0, (MAX_NUM_DEVICES*8)*2);
  947. found = 0;
  948. nbytes = 0;
  949. macbuf = &ioctl_buf[sizeof(PortMonBase)]; // ptr past header
  950. // call to get mac-address list of boxes on network
  951. SetCursor(LoadCursor(NULL, IDC_WAIT)); // load hourglass cursor
  952. stat = get_mac_list(ioctl_buf, (MAX_NUM_DEVICES*8)*2, &nbytes);
  953. SetCursor(LoadCursor(NULL, IDC_ARROW)); // load arrow
  954. *ret_stat = stat;
  955. *ret_bytes = nbytes;
  956. return macbuf;
  957. }
  958. #endif
  959. /*-----------------------------------------------------------------------------
  960. | send_to_driver -
  961. send_to_driver - if set, then send it to driver.
  962. if not set, then just determine if changes were made
  963. |-----------------------------------------------------------------------------*/
  964. int send_to_driver(int send_it)
  965. {
  966. char ioctl_buffer[200];
  967. char value_str[100];
  968. char *ioctl_buf;
  969. IoctlSetup ioctl_setup;
  970. Our_Options *options;
  971. int dev_i, stat;
  972. int op_i;
  973. int chg_flag;
  974. int unknown_value;
  975. int pi;
  976. int changes_found=0;
  977. int changes_need_reboot=0;
  978. Device_Config *dev;
  979. // for ioctl calls into driver
  980. #ifdef S_VS
  981. int product_id = NT_VS1000;
  982. #else
  983. int product_id = NT_ROCKET;
  984. #endif
  985. if (send_it)
  986. {
  987. DbgPrintf(D_Level,(TEXT("send_to_driver\n")));
  988. memset(&ioctl_setup, 0 , sizeof(ioctl_setup));
  989. memset(&ioctl_buffer, 0 , sizeof(ioctl_buffer));
  990. stat = ioctl_open(&ioctl_setup, product_id); // just ensure we can open
  991. if (stat != 0) // error from ioctl
  992. {
  993. // could not talk to driver
  994. DbgPrintf(D_Level,(TEXT("Driver Not Present\n")));
  995. wi->NeedReset = 1;
  996. return 1;
  997. }
  998. ioctl_setup.buf_size = sizeof(ioctl_buffer) - sizeof(*ioctl_setup.pm_base);
  999. ioctl_setup.pm_base = (PortMonBase *)ioctl_buffer;
  1000. ioctl_setup.pm_base->struct_type = IOCTL_OPTION; // set options
  1001. ioctl_buf = (char *) &ioctl_setup.pm_base[1]; // ptr to past header(about 16 bytes)
  1002. }
  1003. options = driver_options;
  1004. op_i = 0;
  1005. while (options[op_i].name != NULL)
  1006. {
  1007. option_changed(value_str, &chg_flag, &unknown_value, &options[op_i],
  1008. 0,0);
  1009. if (chg_flag)
  1010. {
  1011. changes_found = 1;
  1012. if (send_it)
  1013. {
  1014. stat = send_option(value_str,
  1015. &options[op_i],
  1016. 0,
  1017. 0,ioctl_buf, &ioctl_setup);
  1018. if (stat != 0)
  1019. changes_need_reboot = 1;
  1020. } // send_it
  1021. }
  1022. ++op_i;
  1023. }
  1024. DbgPrintf(D_Level,(TEXT("send_to_driver 1\n")));
  1025. for(dev_i=0; dev_i<wi->NumDevices; dev_i++) // Loop through all possible boards
  1026. {
  1027. dev = &wi->dev[dev_i];
  1028. op_i = 0;
  1029. options = device_options;
  1030. while (options[op_i].name != NULL)
  1031. {
  1032. option_changed(value_str, &chg_flag, &unknown_value, &options[op_i],
  1033. dev_i,0);
  1034. if (chg_flag)
  1035. {
  1036. changes_found = 1;
  1037. if (send_it)
  1038. {
  1039. stat = send_option(value_str,
  1040. &options[op_i],
  1041. dev_i,
  1042. 0,ioctl_buf, &ioctl_setup);
  1043. if (stat != 0)
  1044. changes_need_reboot = 1;
  1045. } // send_it
  1046. } // chg_flag
  1047. ++op_i;
  1048. } // device strings
  1049. for(pi=0; pi<dev->NumPorts; pi++) // Loop through all possible boards
  1050. {
  1051. op_i = 0;
  1052. options = port_options;
  1053. while (options[op_i].name != NULL)
  1054. {
  1055. option_changed(value_str, &chg_flag, &unknown_value, &options[op_i],
  1056. dev_i, pi);
  1057. if (chg_flag)
  1058. {
  1059. changes_found = 1;
  1060. if (send_it)
  1061. {
  1062. stat = send_option(value_str,
  1063. &options[op_i],
  1064. dev_i,
  1065. pi, ioctl_buf, &ioctl_setup);
  1066. if (stat != 0)
  1067. changes_need_reboot = 1;
  1068. } // send_it
  1069. } // chg_flag
  1070. ++op_i;
  1071. } // port strings
  1072. } // for pi=0; ..ports
  1073. } // for dev_i = num_devices
  1074. if (changes_need_reboot)
  1075. wi->NeedReset = 1;
  1076. if (changes_found)
  1077. wi->ChangesMade = 1;
  1078. if (send_it)
  1079. {
  1080. ioctl_close(&ioctl_setup);
  1081. }
  1082. return 0;
  1083. }
  1084. /*-----------------------------------------------------------------------------
  1085. | send_option - send option over to driver.
  1086. |-----------------------------------------------------------------------------*/
  1087. static int send_option(char *value_str,
  1088. Our_Options *option,
  1089. int device_index,
  1090. int port_index,
  1091. char *ioctl_buf,
  1092. IoctlSetup *ioctl_setup)
  1093. {
  1094. char dev_name[80];
  1095. int stat;
  1096. #if (defined(NT50))
  1097. strcpy(dev_name, wi->ip.szNt50DevObjName);
  1098. #else
  1099. wsprintf(dev_name, "%d", device_index);
  1100. #endif
  1101. if (option->id & 0x100) // its a driver option
  1102. {
  1103. wsprintf(ioctl_buf, "%s=%s", option->name, value_str);
  1104. }
  1105. else if (option->id & 0x200) // its a device option
  1106. {
  1107. wsprintf(ioctl_buf, "device[%s].%s=%s",
  1108. dev_name, option->name, value_str);
  1109. }
  1110. else if (option->id & 0x400) // its a port option
  1111. {
  1112. wsprintf(ioctl_buf, "device[%s].port[%d].%s=%s",
  1113. dev_name, port_index,
  1114. option->name, value_str);
  1115. }
  1116. stat = our_ioctl_call(ioctl_setup);
  1117. if (stat == 52)
  1118. {
  1119. //special return code indicating driver doesn't care or know about
  1120. // this option(its setup only option.)
  1121. stat = 0; // change to ok.
  1122. }
  1123. return stat;
  1124. //if (stat != 0)
  1125. // changes_need_reboot = 1;
  1126. }
  1127. /*-----------------------------------------------------------------------------
  1128. | option_changed - detect if an option changed, and format a new value
  1129. |-----------------------------------------------------------------------------*/
  1130. static int option_changed(char *value_str,
  1131. int *ret_chg_flag,
  1132. int *ret_unknown_flag,
  1133. Our_Options *option,
  1134. int device_index,
  1135. int port_index)
  1136. {
  1137. int chg_flag = 0;
  1138. int value = 0;
  1139. int org_value = 0;
  1140. int unknown_value = 0;
  1141. Port_Config *port, *org_port;
  1142. Device_Config *org_dev, *dev;
  1143. dev = &wi->dev[device_index];
  1144. org_dev = &org_wi->dev[device_index];
  1145. port = &dev->ports[port_index];
  1146. org_port = &org_dev->ports[port_index];
  1147. if (option->id & 0x300) // port level option
  1148. {
  1149. }
  1150. else if (option->id & 0x200) // device level option
  1151. {
  1152. }
  1153. else if (option->id & 0x100) // driver level option
  1154. {
  1155. }
  1156. *value_str = 0;
  1157. switch(option->id)
  1158. {
  1159. //------ Driver Options ------
  1160. case OP_VerboseLog:
  1161. value = wi->VerboseLog; org_value = org_wi->VerboseLog;
  1162. break;
  1163. case OP_NumDevices:
  1164. value = wi->NumDevices; org_value = org_wi->NumDevices;
  1165. break;
  1166. #ifdef NT50
  1167. case OP_NoPnpPorts:
  1168. value = wi->NoPnpPorts; org_value = org_wi->NoPnpPorts;
  1169. break;
  1170. #endif
  1171. case OP_ScanRate:
  1172. value = wi->ScanRate; org_value = org_wi->ScanRate;
  1173. break;
  1174. case OP_ModemCountry:
  1175. value = wi->ModemCountry; org_value = org_wi->ModemCountry;
  1176. break;
  1177. case OP_GlobalRS485:
  1178. value = wi->GlobalRS485; org_value = org_wi->GlobalRS485;
  1179. break;
  1180. //------ Device Options ------
  1181. #if 0 // don't send this to driver, make it go away
  1182. case OP_StartComIndex :
  1183. value = dev->StartComIndex; org_value = org_dev->StartComIndex;
  1184. break;
  1185. #endif
  1186. case OP_NumPorts :
  1187. value = dev->NumPorts; org_value = org_dev->NumPorts;
  1188. break;
  1189. case OP_MacAddr :
  1190. if (!mac_match(dev->MacAddr, org_dev->MacAddr))
  1191. {
  1192. chg_flag = 1;
  1193. wsprintf(value_str, "%x %x %x %x %x %x",
  1194. dev->MacAddr[0], dev->MacAddr[1], dev->MacAddr[2],
  1195. dev->MacAddr[3], dev->MacAddr[4], dev->MacAddr[5]);
  1196. }
  1197. break;
  1198. #ifdef S_VS
  1199. case OP_BackupServer:
  1200. value = dev->BackupServer; org_value = org_dev->BackupServer;
  1201. break;
  1202. case OP_BackupTimer:
  1203. value = dev->BackupTimer; org_value = org_dev->BackupTimer;
  1204. break;
  1205. #endif
  1206. case OP_Name:
  1207. if (strcmp(dev->Name, org_dev->Name) != 0)
  1208. {
  1209. chg_flag = 1;
  1210. strcpy(value_str, dev->Name);
  1211. }
  1212. break;
  1213. case OP_ModelName:
  1214. if (strcmp(dev->ModelName, org_dev->ModelName) != 0)
  1215. {
  1216. chg_flag = 1;
  1217. strcpy(value_str, dev->ModelName);
  1218. }
  1219. break;
  1220. #ifdef S_RK
  1221. case OP_IoAddress:
  1222. value = dev->IoAddress; org_value = org_dev->IoAddress;
  1223. break;
  1224. #endif
  1225. case OP_ModemDevice:
  1226. value = dev->ModemDevice; org_value = org_dev->ModemDevice;
  1227. break;
  1228. case OP_HubDevice:
  1229. value = dev->HubDevice; org_value = org_dev->HubDevice;
  1230. break;
  1231. //------ Port Options ------
  1232. case OP_WaitOnTx :
  1233. value = port->WaitOnTx;
  1234. org_value = org_port->WaitOnTx;
  1235. break;
  1236. case OP_RS485Override :
  1237. value = port->RS485Override;
  1238. org_value = org_port->RS485Override;
  1239. break;
  1240. case OP_RS485Low :
  1241. value = port->RS485Low;
  1242. org_value = org_port->RS485Low;
  1243. break;
  1244. case OP_TxCloseTime :
  1245. value = port->TxCloseTime; org_value = org_port->TxCloseTime;
  1246. break;
  1247. case OP_LockBaud :
  1248. value = port->LockBaud; org_value = org_port->LockBaud;
  1249. break;
  1250. case OP_Map2StopsTo1 :
  1251. value = port->Map2StopsTo1;
  1252. org_value = org_port->Map2StopsTo1;
  1253. break;
  1254. case OP_MapCdToDsr :
  1255. value = port->MapCdToDsr;
  1256. org_value = org_port->MapCdToDsr;
  1257. break;
  1258. case OP_RingEmulate :
  1259. value = port->RingEmulate;
  1260. org_value = org_port->RingEmulate;
  1261. break;
  1262. case OP_PortName :
  1263. if (strcmp(port->Name, org_port->Name) != 0)
  1264. {
  1265. DbgPrintf(D_Test, ("chg port name:%s to %s\n",
  1266. org_port->Name, port->Name))
  1267. chg_flag = 1;
  1268. strcpy(value_str, port->Name);
  1269. }
  1270. break;
  1271. default:
  1272. DbgPrintf(D_Error,(TEXT("Unknown Option %s ID:%x\n"),
  1273. option->name,
  1274. option->id));
  1275. unknown_value = 1;
  1276. break;
  1277. }
  1278. if ( (!unknown_value) &&
  1279. (!(option->var_type == OP_T_STRING)) )
  1280. {
  1281. if (value != org_value)
  1282. {
  1283. chg_flag = 1;
  1284. wsprintf(value_str, "%d", value);
  1285. }
  1286. }
  1287. if (chg_flag)
  1288. {
  1289. DbgPrintf(D_Level,(TEXT("changed:%s\n"),option->name));
  1290. }
  1291. if (unknown_value)
  1292. {
  1293. DbgPrintf(D_Level,(TEXT("Unknown value:%s\n"),option->name));
  1294. }
  1295. *ret_chg_flag = chg_flag;
  1296. *ret_unknown_flag = unknown_value;
  1297. return 0;
  1298. }
  1299. /*-----------------------------------------------------------------------------
  1300. | our_ioctl_call - send our ascii option data to driver. Driver will
  1301. return 0 if successful, other values assume error, value of 52 if the
  1302. driver does not known what the option is.
  1303. |-----------------------------------------------------------------------------*/
  1304. int our_ioctl_call(IoctlSetup *ioctl_setup)
  1305. {
  1306. int stat;
  1307. char *pstr;
  1308. stat = ioctl_call(ioctl_setup);
  1309. if (stat)
  1310. {
  1311. return 0x100; // failed ioctl call
  1312. }
  1313. //otherwise, driver returns "Option stat:#" with a decimal return code.
  1314. pstr = (char *)&ioctl_setup->pm_base[1]; // find the return status value from the driver
  1315. while ((*pstr != 0) && (*pstr != ':'))
  1316. ++pstr;
  1317. if (*pstr == ':')
  1318. {
  1319. ++pstr;
  1320. stat = getint(pstr, NULL); // atoi(), return driver code
  1321. if (stat == 0)
  1322. {
  1323. //DbgPrintf(D_Level, (TEXT("ok ioctl\n")));
  1324. }
  1325. else
  1326. {
  1327. //DbgPrintf(D_Level, (TEXT("bad ioctl\n")));
  1328. }
  1329. }
  1330. else
  1331. {
  1332. //DbgPrintf(D_Level, (TEXT("err ret on ioctl\n")));
  1333. stat = 0x101; // no return status given
  1334. }
  1335. return stat;
  1336. }
  1337. /*-----------------------------------------------------------------------------
  1338. | our_help -
  1339. |-----------------------------------------------------------------------------*/
  1340. int our_help(InstallPaths *ip, int index)
  1341. {
  1342. strcpy(ip->tmpstr, ip->src_dir);
  1343. strcat(ip->tmpstr,szSlash);
  1344. strcat(ip->tmpstr,szSetup_hlp);
  1345. #ifdef NT50
  1346. HtmlHelp(GetFocus(),ip->tmpstr, HH_HELP_CONTEXT, index);
  1347. #else
  1348. WinHelp(GetFocus(),ip->tmpstr, HELP_CONTEXT, index);
  1349. #endif
  1350. return 0;
  1351. }
  1352. /*-----------------------------------------------------------------
  1353. validate_config -
  1354. |------------------------------------------------------------------*/
  1355. int validate_config(int auto_correct)
  1356. {
  1357. int di, stat;
  1358. Device_Config *dev;
  1359. int invalid = 0;
  1360. DbgPrintf(D_Level, ("validate_config\n"))
  1361. for (di=0; di<wi->NumDevices; di++)
  1362. {
  1363. dev = &wi->dev[di];
  1364. stat = validate_device(dev, 1);
  1365. if (stat)
  1366. invalid = 1;
  1367. }
  1368. return invalid;
  1369. }
  1370. /*-----------------------------------------------------------------------------
  1371. validate_device -
  1372. |-----------------------------------------------------------------------------*/
  1373. int validate_device(Device_Config *dev, int auto_correct)
  1374. {
  1375. int invalid = 0;
  1376. Port_Config *ps;
  1377. int pi,stat;
  1378. DbgPrintf(D_Level, ("validate_dev\n"))
  1379. //----- verify the name is not blank
  1380. if (dev->Name[0] == 0)
  1381. {
  1382. invalid = 1;
  1383. if (auto_correct)
  1384. {
  1385. #ifdef S_VS
  1386. wsprintf(dev->Name, "VS #%d", wi->NumDevices+1); // user designated name
  1387. #else
  1388. wsprintf(dev->Name, "RK #%d", wi->NumDevices+1); // user designated name
  1389. #endif
  1390. }
  1391. }
  1392. //----- verify the number of ports is non-zero
  1393. if (dev->NumPorts == 0)
  1394. {
  1395. invalid = 1;
  1396. if (auto_correct)
  1397. {
  1398. dev->NumPorts = 8; // 8 is common for rocketport
  1399. }
  1400. }
  1401. #ifdef S_RK
  1402. //----- verify the number of ports is non-zero
  1403. if (dev->IoAddress == 0)
  1404. {
  1405. invalid = 1;
  1406. if (auto_correct)
  1407. {
  1408. if (dev->IoAddress == 0)
  1409. dev->IoAddress = 1; // setup for a pci-board
  1410. }
  1411. }
  1412. #endif
  1413. if (wi->ModemCountry == 0) // not valid
  1414. wi->ModemCountry = mcNA; // North America
  1415. #ifdef S_VS
  1416. if (dev->BackupTimer < 2) dev->BackupTimer = 2; // 2 minute, no less
  1417. #endif
  1418. for (pi=0; pi<dev->NumPorts; pi++)
  1419. {
  1420. ps = &dev->ports[pi];
  1421. stat = validate_port(ps, auto_correct);
  1422. if (stat)
  1423. invalid = 1;
  1424. }
  1425. if (invalid)
  1426. {
  1427. DbgPrintf(D_Error, ("validate_dev:invalid config\n"))
  1428. }
  1429. return invalid;
  1430. }
  1431. /*-----------------------------------------------------------------------------
  1432. validate_port -
  1433. |-----------------------------------------------------------------------------*/
  1434. int validate_port(Port_Config *ps, int auto_correct)
  1435. {
  1436. int invalid = 0;
  1437. //DbgPrintf(D_Level, ("validate_port\n"))
  1438. invalid = validate_port_name(ps, auto_correct);
  1439. return invalid;
  1440. }
  1441. /*-----------------------------------------------------------------------------
  1442. validate_port_name -
  1443. |-----------------------------------------------------------------------------*/
  1444. int validate_port_name(Port_Config *ps, int auto_correct)
  1445. {
  1446. int stat;
  1447. int bad = 0;
  1448. char oldname[26];
  1449. int invalid = 0;
  1450. //DbgPrintf(D_Level, ("validate_port_name 0\n"))
  1451. stat = 0;
  1452. //----- verify the name is unique
  1453. if (ps->Name[0] == 0) {
  1454. bad = 1; // error, need a new name
  1455. }
  1456. #if 0
  1457. // take out due to tech. difficulties in the artificial intelligence area
  1458. //DbgPrintf(D_Level, ("validate_port_name 1\n"))
  1459. if (bad == 0)
  1460. {
  1461. stat = IsPortNameInSetupUse(ps->Name);
  1462. if (stat > 1)
  1463. bad = 2; // error, more than one defined in our config
  1464. }
  1465. if (bad == 0) // its ok, not in use
  1466. {
  1467. stat = IsPortNameInRegUse(ps->Name);
  1468. if (stat == 2) // in use, but by our driver, so ok
  1469. stat = 0;
  1470. if (stat != 0)
  1471. bad = 3; // error, more than one defined in our config
  1472. }
  1473. #endif
  1474. //DbgPrintf(D_Level, ("validate_port_name 2\n"))
  1475. strcpy(oldname, ps->Name);
  1476. if (bad != 0) // need a new name, this one won't work
  1477. {
  1478. invalid = 1;
  1479. if (auto_correct)
  1480. {
  1481. ps->Name[0] = 0; // need this for newname func to work
  1482. FormANewComPortName(ps->Name, NULL);
  1483. }
  1484. DbgPrintf(D_Level, (" New Name:%s Old:%s Code:%d\n", ps->Name, oldname, bad))
  1485. }
  1486. return invalid;
  1487. }
  1488. #if 0
  1489. /*-----------------------------------------------------------------------------
  1490. rename_ascending - rename the rest of the ports on the board in
  1491. ascending order.
  1492. |-----------------------------------------------------------------------------*/
  1493. void rename_ascending(int device_selected,
  1494. int port_selected)
  1495. {
  1496. Device_Config *dev;
  1497. Port_Config *ps;
  1498. int i;
  1499. char name[20];
  1500. dev = &wi->dev[device_selected];
  1501. ps = &dev->ports[port_selected];
  1502. for (i=port_selected+1; i<dev->NumPorts; i++)
  1503. {
  1504. ps = &dev->ports[i];
  1505. FormANewComPortName(name, dev->ports[port_selected-1].Name);
  1506. strcpy(ps->Name, name);
  1507. //validate_port_name(ps, 1);
  1508. }
  1509. }
  1510. #endif
  1511. /*-----------------------------------------------------------------------------
  1512. FormANewComPortName -
  1513. |-----------------------------------------------------------------------------*/
  1514. int FormANewComPortName(IN OUT TCHAR *szComName, IN TCHAR *szDefName)
  1515. {
  1516. char try_name[25];
  1517. int stat;
  1518. char base_name[20];
  1519. int num;
  1520. //DbgPrintf(D_Level, ("Form a new name\n"))
  1521. base_name[0] = 0;
  1522. if (szDefName != NULL)
  1523. strcpy(base_name, szDefName);
  1524. else
  1525. GetLastValidName(base_name);
  1526. //DbgPrintf(D_Level, ("Base name:%s\n", base_name))
  1527. num = ExtractNameNum(base_name); // num = 3 if "COM3"
  1528. if (num == 0)
  1529. num = 3;
  1530. else ++num;
  1531. StripNameNum(base_name);
  1532. if (base_name[0] == 0)
  1533. {
  1534. strcat(base_name, "COM");
  1535. }
  1536. stat = 2;
  1537. while (stat != 0)
  1538. {
  1539. wsprintf(try_name, TEXT("%s%d"), base_name, num);
  1540. //DbgPrintf(D_Level, ("try:%s\n", try_name))
  1541. if (IsPortNameInSetupUse(try_name) != 0)
  1542. {
  1543. DbgPrintf(D_Level, (" SetupUse\n"))
  1544. stat = 2; // port in use by us
  1545. }
  1546. else
  1547. {
  1548. stat = IsPortNameInRegUse(try_name);
  1549. if (stat)
  1550. {
  1551. if ( stat == 2 ) {
  1552. stat = 0;
  1553. } else {
  1554. DbgPrintf(D_Level, (" InRegUse\n"))
  1555. }
  1556. }
  1557. }
  1558. if (stat == 0)
  1559. {
  1560. strcpy(szComName, try_name);
  1561. }
  1562. ++num;
  1563. }
  1564. //DbgPrintf(D_Level, ("End FormANewComPortName\n"))
  1565. return 0;
  1566. }
  1567. /*-----------------------------------------------------------------------------
  1568. GetLastValidName - Get a com-port name which makes sense to start naming
  1569. things at. So if our last com-port name is "COM45", then return this.
  1570. Pick the Com-port with the highest number.
  1571. |-----------------------------------------------------------------------------*/
  1572. int GetLastValidName(IN OUT TCHAR *szComName)
  1573. {
  1574. int di, pi;
  1575. int last_di, last_pi;
  1576. char tmpName[20];
  1577. int num=0;
  1578. for (di=0; di<wi->NumDevices; di++)
  1579. {
  1580. for (pi=0; pi<wi->dev[di].NumPorts; pi++)
  1581. {
  1582. strcpy(tmpName, wi->dev[di].ports[pi].Name);
  1583. if (ExtractNameNum(tmpName) > num)
  1584. {
  1585. num = ExtractNameNum(tmpName);
  1586. strcpy(szComName, wi->dev[di].ports[pi].Name);
  1587. last_di = di;
  1588. last_pi = pi;
  1589. }
  1590. }
  1591. }
  1592. if (num == 0)
  1593. szComName[0] = 0;
  1594. //DbgPrintf(D_Level, ("LastValidName:%s [%d.%d]\n", szComName, last_di, last_pi))
  1595. return 0;
  1596. }
  1597. /*-----------------------------------------------------------------------------
  1598. BumpPortName - Add 1 to the number of the comport name, so change "COM23"
  1599. to "COM24".
  1600. |-----------------------------------------------------------------------------*/
  1601. int BumpPortName(IN OUT TCHAR *szComName)
  1602. {
  1603. char tmpstr[25];
  1604. int i;
  1605. strcpy(tmpstr, szComName);
  1606. i = ExtractNameNum(szComName);
  1607. if (i< 1)
  1608. i = 1;
  1609. ++i;
  1610. StripNameNum(tmpstr);
  1611. wsprintf(szComName, "%s%d", tmpstr, i);
  1612. return 0;
  1613. }
  1614. /*-----------------------------------------------------------------------------
  1615. StripNameNum -
  1616. |-----------------------------------------------------------------------------*/
  1617. int StripNameNum(IN OUT TCHAR *szComName)
  1618. {
  1619. char *pstr;
  1620. pstr = szComName;
  1621. while ((!isdigit(*pstr)) && (*pstr != 0))
  1622. {
  1623. pstr++;
  1624. }
  1625. *pstr = 0; // null terminate at digit
  1626. return 0;
  1627. }
  1628. /*-----------------------------------------------------------------------------
  1629. ExtractNameNum -
  1630. |-----------------------------------------------------------------------------*/
  1631. int ExtractNameNum(IN TCHAR *szComName)
  1632. {
  1633. int num;
  1634. char *pstr;
  1635. pstr = szComName;
  1636. while ((!isdigit(*pstr)) && (*pstr != 0))
  1637. {
  1638. pstr++;
  1639. }
  1640. if (*pstr == 0)
  1641. num = 0;
  1642. else
  1643. num = atoi(pstr);
  1644. return num;
  1645. }
  1646. /*-----------------------------------------------------------------------------
  1647. IsPortNameInSetupUse - Checks our setup info to see if com-port name is
  1648. unique.
  1649. |-----------------------------------------------------------------------------*/
  1650. int IsPortNameInSetupUse(IN TCHAR *szComName)
  1651. {
  1652. int di, pi;
  1653. int times_in_use = 0;
  1654. for (di=0; di<wi->NumDevices; di++)
  1655. {
  1656. for (pi=0; pi<wi->dev[di].NumPorts; pi++)
  1657. {
  1658. if (_tcsicmp(szComName, wi->dev[di].ports[pi].Name) == 0)
  1659. {
  1660. ++times_in_use;
  1661. #if DBG
  1662. //if (times_in_use > 1)
  1663. // DbgPrintf(D_Level, (" %s InSetupUs:%d, [%d %d]\n",
  1664. // szComName, times_in_use, di, pi))
  1665. #endif
  1666. }
  1667. }
  1668. }
  1669. return times_in_use;
  1670. }
  1671. /*------------------------------------------------------------------------
  1672. IsPortNameInRegUse - Checks registry area where com-ports typically export
  1673. com-port names under NT.
  1674. return 0=not in use, 1=in use by other driver, 2=in use by our driver.
  1675. |------------------------------------------------------------------------*/
  1676. int IsPortNameInRegUse(IN TCHAR *szComName)
  1677. {
  1678. HKEY hkey;
  1679. int i, nEntries;
  1680. ULONG dwSize, dwBufz;
  1681. ULONG dwType;
  1682. TCHAR szSerial[ 40 ];
  1683. TCHAR szCom[ 40 ];
  1684. TCHAR szDriver[8];
  1685. _tcsncpy(szDriver, OurDriverName, 6); // something to match to "vslink" or "rocket"
  1686. szDriver[6] = 0;
  1687. _tcsupr(szDriver);
  1688. // "Hardware\\DeviceMap\\SerialComm"
  1689. if( !RegOpenKeyEx( HKEY_LOCAL_MACHINE, m_szRegSerialMap,
  1690. 0L, KEY_READ, &hkey ) )
  1691. {
  1692. dwBufz = sizeof( szSerial );
  1693. dwSize = sizeof( szCom );
  1694. nEntries = i = 0;
  1695. while( !RegEnumValue( hkey, i++, szSerial, &dwBufz,
  1696. NULL, &dwType, (LPBYTE) szCom, &dwSize ) )
  1697. {
  1698. if (dwType != REG_SZ)
  1699. continue;
  1700. _tcsupr(szCom);
  1701. _tcsupr(szSerial);
  1702. if (_tcsicmp(szComName, szCom) == 0)
  1703. {
  1704. // compare 5 characters of the key name to our driver name
  1705. if (_tcsstr(szSerial, szDriver) != NULL)
  1706. {
  1707. //DbgPrintf(D_Level, (" %s InRegUseUsOurs [%s,%s]\n", szComName,
  1708. // szSerial, szDriver))
  1709. return 2; // in use, but probably ours
  1710. }
  1711. else
  1712. {
  1713. //DbgPrintf(D_Level, (" %s InRegUseUsNotOurs [%s,%s]\n", szComName,
  1714. // szSerial, szDriver))
  1715. return 1; // it's in use, someone elses driver
  1716. }
  1717. }
  1718. ++nEntries;
  1719. dwSize = sizeof( szCom );
  1720. dwBufz = sizeof( szSerial );
  1721. }
  1722. RegCloseKey( hkey );
  1723. }
  1724. return 0; // not in use
  1725. }
  1726. #ifdef LOG_MESS
  1727. /*------------------------------------------------------------------------
  1728. | log_mess -
  1729. |------------------------------------------------------------------------*/
  1730. void log_mess(char *str, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  1731. {
  1732. FILE *fp;
  1733. int i;
  1734. static struct {
  1735. WORD value;
  1736. char *string;
  1737. }
  1738. ddd[200] =
  1739. {
  1740. {WM_COMPACTING, "WM_COMPACTING"},
  1741. {WM_WININICHANGE, "WM_WININICHANGE"},
  1742. {WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE"},
  1743. {WM_QUERYNEWPALETTE, "WM_QUERYNEWPALETTE"},
  1744. {WM_PALETTEISCHANGING, "WM_PALETTEISCHANGING"},
  1745. {WM_PALETTECHANGED, "WM_PALETTECHANGED"},
  1746. {WM_FONTCHANGE, "WM_FONTCHANGE"},
  1747. {WM_SPOOLERSTATUS, "WM_SPOOLERSTATUS"},
  1748. {WM_DEVMODECHANGE, "WM_DEVMODECHANGE"},
  1749. {WM_TIMECHANGE, "WM_TIMECHANGE"},
  1750. {WM_NULL, "WM_NULL"},
  1751. {WM_USER, "WM_USER"},
  1752. {WM_PENWINFIRST, "WM_PENWINFIRST"},
  1753. {WM_PENWINLAST, "WM_PENWINLAST"},
  1754. #ifdef WIN16
  1755. {WM_COALESCE_FIRST, "WM_COALESCE_FIRST"},
  1756. {WM_COALESCE_LAST, "WM_COALESCE_LAST"},
  1757. #endif
  1758. {WM_POWER, "WM_POWER"},
  1759. {WM_QUERYENDSESSION, "WM_QUERYENDSESSION"},
  1760. {WM_ENDSESSION, "WM_ENDSESSION"},
  1761. {WM_QUIT, "WM_QUIT"},
  1762. #ifdef WIN16
  1763. {WM_SYSTEMERROR, "WM_SYSTEMERROR"},
  1764. #endif
  1765. {WM_CREATE, "WM_CREATE"},
  1766. {WM_NCCREATE, "WM_NCCREATE"},
  1767. {WM_DESTROY, "WM_DESTROY"},
  1768. {WM_NCDESTROY, "WM_NCDESTROY"},
  1769. {WM_SHOWWINDOW, "WM_SHOWWINDOW"},
  1770. {WM_SETREDRAW, "WM_SETREDRAW"},
  1771. {WM_ENABLE, "WM_ENABLE"},
  1772. {WM_SETTEXT, "WM_SETTEXT"},
  1773. {WM_GETTEXT, "WM_GETTEXT"},
  1774. {WM_GETTEXTLENGTH, "WM_GETTEXTLENGTH"},
  1775. {WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING"},
  1776. {WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED"},
  1777. {WM_MOVE, "WM_MOVE"},
  1778. {WM_SIZE, "WM_SIZE"},
  1779. {WM_QUERYOPEN, "WM_QUERYOPEN"},
  1780. {WM_CLOSE, "WM_CLOSE"},
  1781. {WM_GETMINMAXINFO, "WM_GETMINMAXINFO"},
  1782. {WM_PAINT, "WM_PAINT"},
  1783. {WM_ERASEBKGND, "WM_ERASEBKGND"},
  1784. {WM_ICONERASEBKGND, "WM_ICONERASEBKGND"},
  1785. {WM_NCPAINT, "WM_NCPAINT"},
  1786. {WM_NCCALCSIZE, "WM_NCCALCSIZE"},
  1787. {WM_NCHITTEST, "WM_NCHITTEST"},
  1788. {WM_QUERYDRAGICON, "WM_QUERYDRAGICON"},
  1789. {WM_DROPFILES, "WM_DROPFILES"},
  1790. {WM_ACTIVATE, "WM_ACTIVATE"},
  1791. {WM_ACTIVATEAPP, "WM_ACTIVATEAPP"},
  1792. {WM_NCACTIVATE, "WM_NCACTIVATE"},
  1793. {WM_SETFOCUS, "WM_SETFOCUS"},
  1794. {WM_KILLFOCUS, "WM_KILLFOCUS"},
  1795. {WM_KEYDOWN, "WM_KEYDOWN"},
  1796. {WM_KEYUP, "WM_KEYUP"},
  1797. {WM_CHAR, "WM_CHAR"},
  1798. {WM_DEADCHAR, "WM_DEADCHAR"},
  1799. {WM_SYSKEYDOWN, "WM_SYSKEYDOWN"},
  1800. {WM_SYSKEYUP, "WM_SYSKEYUP"},
  1801. {WM_SYSCHAR, "WM_SYSCHAR"},
  1802. {WM_SYSDEADCHAR, "WM_SYSDEADCHAR"},
  1803. {WM_KEYFIRST, "WM_KEYFIRST"},
  1804. {WM_KEYLAST, "WM_KEYLAST"},
  1805. {WM_MOUSEMOVE, "WM_MOUSEMOVE"},
  1806. {WM_LBUTTONDOWN, "WM_LBUTTONDOWN"},
  1807. {WM_LBUTTONUP, "WM_LBUTTONUP"},
  1808. {WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK"},
  1809. {WM_RBUTTONDOWN, "WM_RBUTTONDOWN"},
  1810. {WM_RBUTTONUP, "WM_RBUTTONUP"},
  1811. {WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK"},
  1812. {WM_MBUTTONDOWN, "WM_MBUTTONDOWN"},
  1813. {WM_MBUTTONUP, "WM_MBUTTONUP"},
  1814. {WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK"},
  1815. {WM_MOUSEFIRST, "WM_MOUSEFIRST"},
  1816. {WM_MOUSELAST, "WM_MOUSELAST"},
  1817. {WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE"},
  1818. {WM_NCLBUTTONDOWN, "WM_NCLBUTTONDOWN"},
  1819. {WM_NCLBUTTONUP, "WM_NCLBUTTONUP"},
  1820. {WM_NCLBUTTONDBLCLK, "WM_NCLBUTTONDBLCLK"},
  1821. {WM_NCRBUTTONDOWN, "WM_NCRBUTTONDOWN"},
  1822. {WM_NCRBUTTONUP, "WM_NCRBUTTONUP"},
  1823. {WM_NCRBUTTONDBLCLK, "WM_NCRBUTTONDBLCLK"},
  1824. {WM_NCMBUTTONDOWN, "WM_NCMBUTTONDOWN"},
  1825. {WM_NCMBUTTONUP, "WM_NCMBUTTONUP"},
  1826. {WM_NCMBUTTONDBLCLK, "WM_NCMBUTTONDBLCLK"},
  1827. {WM_MOUSEACTIVATE, "WM_MOUSEACTIVATE"},
  1828. {WM_CANCELMODE, "WM_CANCELMODE"},
  1829. {WM_TIMER, "WM_TIMER"},
  1830. {WM_INITMENU, "WM_INITMENU"},
  1831. {WM_INITMENUPOPUP, "WM_INITMENUPOPUP"},
  1832. {WM_MENUSELECT, "WM_MENUSELECT"},
  1833. {WM_MENUCHAR, "WM_MENUCHAR"},
  1834. {WM_COMMAND, "WM_COMMAND"},
  1835. {WM_HSCROLL, "WM_HSCROLL"},
  1836. {WM_VSCROLL, "WM_VSCROLL"},
  1837. {WM_CUT, "WM_CUT"},
  1838. {WM_COPY, "WM_COPY"},
  1839. {WM_PASTE, "WM_PASTE"},
  1840. {WM_CLEAR, "WM_CLEAR"},
  1841. {WM_UNDO, "WM_UNDO"},
  1842. {WM_RENDERFORMAT, "WM_RENDERFORMAT"},
  1843. {WM_RENDERALLFORMATS, "WM_RENDERALLFORMATS"},
  1844. {WM_DESTROYCLIPBOARD, "WM_DESTROYCLIPBOARD"},
  1845. {WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD"},
  1846. {WM_PAINTCLIPBOARD, "WM_PAINTCLIPBOARD"},
  1847. {WM_SIZECLIPBOARD, "WM_SIZECLIPBOARD"},
  1848. {WM_VSCROLLCLIPBOARD, "WM_VSCROLLCLIPBOARD"},
  1849. {WM_HSCROLLCLIPBOARD, "WM_HSCROLLCLIPBOARD"},
  1850. {WM_ASKCBFORMATNAME, "WM_ASKCBFORMATNAME"},
  1851. {WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN"},
  1852. {WM_SETCURSOR, "WM_SETCURSOR"},
  1853. {WM_SYSCOMMAND, "WM_SYSCOMMAND"},
  1854. {WM_MDICREATE, "WM_MDICREATE"},
  1855. {WM_MDIDESTROY, "WM_MDIDESTROY"},
  1856. {WM_MDIACTIVATE, "WM_MDIACTIVATE"},
  1857. {WM_MDIRESTORE, "WM_MDIRESTORE"},
  1858. {WM_MDINEXT, "WM_MDINEXT"},
  1859. {WM_MDIMAXIMIZE, "WM_MDIMAXIMIZE"},
  1860. {WM_MDITILE, "WM_MDITILE"},
  1861. {WM_MDICASCADE, "WM_MDICASCADE"},
  1862. {WM_MDIICONARRANGE, "WM_MDIICONARRANGE"},
  1863. {WM_MDIGETACTIVE, "WM_MDIGETACTIVE"},
  1864. {WM_MDISETMENU, "WM_MDISETMENU"},
  1865. {WM_CHILDACTIVATE, "WM_CHILDACTIVATE"},
  1866. {WM_INITDIALOG, "WM_INITDIALOG"},
  1867. {WM_NEXTDLGCTL, "WM_NEXTDLGCTL"},
  1868. {WM_PARENTNOTIFY, "WM_PARENTNOTIFY"},
  1869. {WM_ENTERIDLE, "WM_ENTERIDLE"},
  1870. {WM_GETDLGCODE, "WM_GETDLGCODE"},
  1871. #ifdef WIN16
  1872. {WM_CTLCOLOR, "WM_CTLCOLOR"},
  1873. #endif
  1874. {WM_CTLCOLORMSGBOX, "WM_CTLCOLORMSGBOX"},
  1875. {WM_CTLCOLOREDIT, "WM_CTLCOLOREDIT"},
  1876. {WM_CTLCOLORLISTBOX, "WM_CTLCOLORLISTBOX"},
  1877. {WM_CTLCOLORBTN, "WM_CTLCOLORBTN"},
  1878. {WM_CTLCOLORDLG, "WM_CTLCOLORDLG"},
  1879. {WM_CTLCOLORSCROLLBAR, "WM_CTLCOLORSCROLLBAR"},
  1880. {WM_CTLCOLORSTATIC, "WM_CTLCOLORSTATIC"},
  1881. {WM_SETFONT, "WM_SETFONT"},
  1882. {WM_GETFONT, "WM_GETFONT"},
  1883. {WM_DRAWITEM, "WM_DRAWITEM"},
  1884. {WM_MEASUREITEM, "WM_MEASUREITEM"},
  1885. {WM_DELETEITEM, "WM_DELETEITEM"},
  1886. {0xfff0, "WM_?"}
  1887. };
  1888. fp = fopen("log.tmp", "a");
  1889. if (fp == NULL) return;
  1890. i = 0;
  1891. while (ddd[i].value != 0xfff0)
  1892. {
  1893. if (message == ddd[i].value) break;
  1894. ++i;
  1895. }
  1896. if (ddd[i].value == 0xfff0) /* not found */
  1897. {
  1898. if ((message >= WM_USER) && (message <= (WM_USER+0x100)))
  1899. fprintf(fp, "%s,WM_USER+%x> ", str, message-WM_USER);
  1900. else
  1901. fprintf(fp, "%s,%s %x> ", str, ddd[i].string, message);
  1902. }
  1903. else
  1904. fprintf(fp, "%s,%s> ", str, ddd[i].string);
  1905. fprintf(fp, "h:%x, m:%x, w:%x, lh:%x ll:%x\n", hwnd, message, wParam,
  1906. HIWORD(lParam), LOWORD(lParam));
  1907. fclose(fp);
  1908. }
  1909. #endif
  1910. #ifndef S_VS
  1911. #ifndef S_RK
  1912. ERROR, makefile should define S_VS or S_RK
  1913. #endif
  1914. #endif
  1915. #ifdef S_VS
  1916. #ifdef S_RK
  1917. ERROR, makefile should define S_VS or S_RK
  1918. #endif
  1919. #endif