Windows NT 4.0 source code leak
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.

511 lines
15 KiB

4 years ago
  1. /****************************************************************************
  2. *
  3. * config.c
  4. *
  5. * Copyright (c) 1991-1992 Microsoft Corporation. All Rights Reserved.
  6. *
  7. ***************************************************************************/
  8. #include <windows.h>
  9. #include <mmsystem.h>
  10. #include "registry.h"
  11. #include "sndblst.h"
  12. /*****************************************************************************
  13. internal function prototypes
  14. ****************************************************************************/
  15. void Configure(HWND hDlg);
  16. static int PortToId(DWORD wPort)
  17. {
  18. switch(wPort) {
  19. case 0x210: return IDC_210;
  20. case 0x220: return IDC_220;
  21. case 0x230: return IDC_230;
  22. case 0x240: return IDC_240;
  23. case 0x250: return IDC_250;
  24. case 0x260: return IDC_260;
  25. default: return -1;
  26. }
  27. }
  28. static DWORD IdToPort(int id)
  29. {
  30. switch(id) {
  31. case IDC_210: return 0x210;
  32. case IDC_220: return 0x220;
  33. case IDC_230: return 0x230;
  34. case IDC_240: return 0x240;
  35. case IDC_250: return 0x250;
  36. case IDC_260: return 0x260;
  37. default: return (DWORD)-1;
  38. }
  39. }
  40. static int IntToId(DWORD Int)
  41. {
  42. switch(Int) {
  43. case 2: return IDC_2;
  44. case 9: return IDC_2;
  45. case 3: return IDC_3;
  46. case 5: return IDC_5;
  47. case 7: return IDC_7;
  48. case 10: return IDC_10;
  49. default: return (DWORD)-1;
  50. }
  51. }
  52. static DWORD IdToInt(int id)
  53. {
  54. switch(id) {
  55. case IDC_2: return 9;
  56. case IDC_3: return 3;
  57. case IDC_5: return 5;
  58. case IDC_7: return 7;
  59. case IDC_10: return 10;
  60. default: return (DWORD)-1;
  61. }
  62. }
  63. /***************************************************************************/
  64. void ConfigErrorMsgBox(HWND hDlg, UINT StringId)
  65. {
  66. WCHAR szErrorBuffer[MAX_ERR_STRING]; /* buffer for error messages */
  67. LoadString(ghModule, StringId, szErrorBuffer, sizeof(szErrorBuffer));
  68. MessageBox(hDlg, szErrorBuffer, STR_PRODUCTNAME, MB_OK|MB_ICONEXCLAMATION);
  69. }
  70. /***************************************************************************/
  71. LRESULT ConfigRemove(HWND hDlg)
  72. {
  73. LRESULT rc;
  74. //
  75. // Remove the soundblaster driver entry from the registry
  76. //
  77. rc = DrvRemoveDriver(&RegAccess);
  78. if (rc == DRVCNF_CANCEL) {
  79. /*
  80. * Tell the user there's a problem
  81. */
  82. ConfigErrorMsgBox(hDlg, IDS_FAILREMOVE);
  83. }
  84. return rc;
  85. }
  86. /****************************************************************************
  87. * @doc INTERNAL
  88. *
  89. * @api int | Config | This puts up the configuration dialog box.
  90. *
  91. * @parm HWND | hWnd | Our Window handle.
  92. *
  93. * @parm HANDLE | hInstance | Our instance handle.
  94. *
  95. * @rdesc Returns whatever was returned from the dialog box procedure.
  96. ***************************************************************************/
  97. int Config(HWND hWnd, HANDLE hInstance)
  98. {
  99. return DialogBox(hInstance,
  100. MAKEINTATOM(DLG_CONFIG),
  101. hWnd,
  102. (DLGPROC)ConfigDlgProc);
  103. }
  104. /****************************************************************************
  105. * @doc INTERNAL
  106. *
  107. * @api BOOL | SetDriverConfig | Callback to set config info in the registry
  108. * does not write uninitialized values (-1)
  109. *
  110. * @parm PVOID | Context | Our context.
  111. *
  112. * @rdesc Returns TRUE if success, FALSE otherwise.
  113. ***************************************************************************/
  114. BOOL SetDriverConfig(PVOID Context)
  115. {
  116. SB_CONFIG *Config;
  117. Config = (SB_CONFIG *)Context;
  118. /* We set the IO port and interrupt values */
  119. /* and set the returned version to 0 */
  120. /* */
  121. /* If any of these calls fail then give up */
  122. if (Config->Port != (DWORD)-1 &&
  123. DrvSetDeviceParameter(
  124. &RegAccess,
  125. SOUND_REG_PORT,
  126. Config->Port) != ERROR_SUCCESS ||
  127. Config->Int != (DWORD)-1 &&
  128. DrvSetDeviceParameter(
  129. &RegAccess,
  130. SOUND_REG_INTERRUPT,
  131. Config->Int) != ERROR_SUCCESS ||
  132. DrvSetDeviceParameter(
  133. &RegAccess,
  134. TEXT("DSP Version"),
  135. 0) != ERROR_SUCCESS) {
  136. return FALSE;
  137. } else {
  138. return TRUE;
  139. }
  140. }
  141. /****************************************************************************
  142. * @doc INTERNAL
  143. *
  144. * @api void | GetPortAndInt | Determines which port and interrupt settings
  145. * the user has chosen in the configuration dialog box.
  146. *
  147. * @parm HWND | hDlg | Handle to the configuration dialog box.
  148. *
  149. * @rdesc Structure containing new port and interrupt
  150. ***************************************************************************/
  151. SB_CONFIG GetPortAndInt(HWND hDlg)
  152. {
  153. SB_CONFIG NewConfig;
  154. int id;
  155. NewConfig.Port = (DWORD)-1;
  156. NewConfig.Int = (DWORD)-1;
  157. for (id = IDC_FIRSTPORT; id <= IDC_LASTPORT; id++)
  158. if (IsDlgButtonChecked(hDlg, id)) {
  159. NewConfig.Port = IdToPort(id);
  160. break;
  161. }
  162. for (id = IDC_FIRSTINT; id <= IDC_LASTINT; id++)
  163. if (IsDlgButtonChecked(hDlg, id)) {
  164. NewConfig.Int = IdToInt(id);
  165. break;
  166. }
  167. return NewConfig;
  168. }
  169. /****************************************************************************
  170. * @doc INTERNAL
  171. *
  172. * @api int | ConfigDlgProc | Dialog proc for the configuration dialog box.
  173. *
  174. * @parm HWND | hDlg | Handle to the configuration dialog box.
  175. *
  176. * @parm WORD | msg | Message sent to the dialog box.
  177. *
  178. * @parm WORD | wParam | Message dependent parameter.
  179. *
  180. * @parm LONG | lParam | Message dependent parameter.
  181. *
  182. * @rdesc Returns DRV_RESTART if the user has changed settings, which will
  183. * cause the drivers applet which launched this to give the user a
  184. * message about having to restart Windows for the changes to take
  185. * effect. If the user clicks on "Cancel" or if no settings have changed,
  186. * DRV_CANCEL is returned.
  187. ***************************************************************************/
  188. int ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  189. {
  190. int id;
  191. static SB_CONFIG StartConfig; /* Initial port */
  192. switch (msg) {
  193. case WM_INITDIALOG:
  194. StartConfig.Int = ConfigGetIRQ();
  195. StartConfig.Port = ConfigGetPortBase();
  196. if ((id = PortToId(StartConfig.Port)) != -1)
  197. CheckRadioButton(hDlg, IDC_FIRSTPORT, IDC_LASTPORT, id);
  198. if ((id = IntToId(StartConfig.Int)) != -1)
  199. CheckRadioButton(hDlg, IDC_FIRSTINT, IDC_LASTINT, id);
  200. break;
  201. case WM_COMMAND:
  202. switch (LOWORD(wParam)) {
  203. case IDOK:
  204. Configure(hDlg);
  205. break;
  206. case IDCANCEL:
  207. /*
  208. * Restore to state on entry to dialog if we
  209. * possibly can
  210. */
  211. if (bInstall) {
  212. DrvRemoveDriver(&RegAccess);
  213. } else {
  214. DrvConfigureDriver(&RegAccess,
  215. STR_DRIVERNAME,
  216. SoundDriverTypeNormal,
  217. SetDriverConfig,
  218. &StartConfig);
  219. }
  220. EndDialog(hDlg, DRVCNF_CANCEL);
  221. break;
  222. case IDC_210:
  223. case IDC_220:
  224. case IDC_230:
  225. case IDC_240:
  226. case IDC_250:
  227. case IDC_260:
  228. CheckRadioButton(hDlg, IDC_FIRSTPORT, IDC_LASTPORT, wParam);
  229. break;
  230. case IDC_2:
  231. case IDC_3:
  232. case IDC_5:
  233. case IDC_7:
  234. case IDC_10:
  235. CheckRadioButton(hDlg, IDC_FIRSTINT, IDC_LASTINT, wParam);
  236. break;
  237. default:
  238. break;
  239. }
  240. break;
  241. default:
  242. return FALSE;
  243. }
  244. return TRUE;
  245. }
  246. /**************************************************************************
  247. *
  248. * Function : Configure
  249. *
  250. * Arguments :
  251. *
  252. * NewPort
  253. * NewInterrupt
  254. * NewChannel
  255. *
  256. * Description
  257. *
  258. * The user has selected a (new) configuration. There are a number
  259. * of (binary) state varibles to consider :
  260. *
  261. * 1) Is this a new install?
  262. *
  263. * 2) Was the driver previously loaded?
  264. *
  265. * 3) Has the configuration changed?
  266. *
  267. * 4) If the driver was previously loaded could it be unloaded?
  268. *
  269. * 5) Could the driver be loaded ?
  270. *
  271. * Possible actions are :
  272. *
  273. * a. Try unload
  274. *
  275. * b. Try reload
  276. *
  277. * c. Warn user parameters are not accepted by driver
  278. *
  279. * d. Put up reboot menu
  280. *
  281. * e. Update registry with new config data
  282. *
  283. * f. Check version and issue necessary warnings
  284. *
  285. * Notes :
  286. * A - 1 & 2 should not happen
  287. *
  288. * B - ~2 => 4 irrelevant
  289. *
  290. * C - configuration change irrelevant for new install
  291. *
  292. * There's never and point in unloading !
  293. *
  294. * If the configuration changes we have to put it in the registry to
  295. * test it.
  296. *
  297. * We must correctly detect the 'not loaded' state via SC manager
  298. *
  299. * Don't warn them about the version if it's not an install (how
  300. * do we know ?)
  301. *
  302. *
  303. * The logic is :
  304. *
  305. * 1 2 3 4 5 | a b c d e f Comments
  306. * ----------|-------------------------------------------------------------
  307. * 0 0 0 0 0 | Config not changed, not new so don't load
  308. * 0 0 0 0 1 | Config not changed, not new so don't load
  309. * 0 0 0 1 0 | B
  310. * 0 0 0 1 1 | B
  311. * 0 0 1 0 0 | X X X Assume load failed due to config failure
  312. * 0 0 1 0 1 | X X Was not loaded, config changed, now loaded OK
  313. * 0 0 1 1 0 | B
  314. * 0 0 1 1 1 | B
  315. * 0 1 0 0 0 | Config not changed, driver loaded so OK
  316. * 0 1 0 0 1 | Config not changed, driver loaded so OK
  317. * 0 1 0 1 0 | Config not changed, driver loaded so OK
  318. * 0 1 0 1 1 | Config not changed, driver loaded so OK
  319. * 0 1 1 0 0 | X X Driver was running OK with old config
  320. * 0 1 1 0 1 | X X Driver was running OK with old config
  321. * 0 1 1 1 0 | X X Driver was running OK with old config
  322. * 0 1 1 1 1 | X X Driver was running OK with old config
  323. * 1 0 0 0 0 | X X X Assume load failed due to config failure
  324. * 1 0 0 0 1 | X X X Good install and load
  325. * 1 0 0 1 0 | B
  326. * 1 0 0 1 1 | B
  327. * 1 0 1 0 0 | C
  328. * 1 0 1 0 1 | C
  329. * 1 0 1 1 0 | B
  330. * 1 0 1 1 1 | B
  331. * 1 1 0 0 0 | A
  332. * 1 1 0 0 1 | A
  333. * 1 1 0 1 0 | A
  334. * 1 1 0 1 1 | A
  335. * 1 1 1 0 0 | A
  336. * 1 1 1 0 1 | A
  337. * 1 1 1 1 0 | A
  338. * 1 1 1 1 1 | A
  339. *
  340. **************************************************************************/
  341. void Configure(HWND hDlg)
  342. {
  343. DWORD DspVersion;
  344. SB_CONFIG NewConfig; /* New port and int chosen in config box */
  345. BOOL Success;
  346. /*
  347. * Get the new configuration which the user entered
  348. */
  349. NewConfig = GetPortAndInt(hDlg);
  350. /*
  351. * NOTE - even if the configuration has not changed the driver
  352. * may now load in some cases - so even in this case try it.
  353. *
  354. * Put the new config in the registry
  355. *
  356. * unload the driver if needed (note this may fail but we've
  357. * no way of telling whether it was loaded in the first place).
  358. *
  359. * if the driver is not loaded
  360. *
  361. * try loading the driver
  362. *
  363. * if the load failed put up a message
  364. *
  365. * if the load succeeded put up a warning if we don't like
  366. * the version
  367. *
  368. * if the driver is already loaded ask them if they would like
  369. * to reboot (ie return DRVCNF_RESTART (note that if the driver
  370. * is currently loaded then changing the config will stop it
  371. * working !).
  372. *
  373. */
  374. /*
  375. * We have a new config - Configure the driver for this configuration
  376. */
  377. Success = DrvConfigureDriver(&RegAccess,
  378. STR_DRIVERNAME,
  379. SoundDriverTypeNormal,
  380. SetDriverConfig,
  381. &NewConfig);
  382. /*
  383. * Find out what we got back
  384. */
  385. //
  386. // get the version from the registry if the driver put it there
  387. //
  388. if (DrvQueryDeviceParameter(&RegAccess,
  389. TEXT("DSP Version"),
  390. &DspVersion)
  391. != ERROR_SUCCESS) {
  392. DspVersion = 0;
  393. }
  394. /*
  395. * See if we succeeded and interpret the 'version number'
  396. * accordingly.
  397. */
  398. if (!Success) {
  399. /*
  400. * Private interface to kernel driver.
  401. * Flag 0x8000 set says it's a thunderboard
  402. * Flag 0x4000 set says wrong port
  403. * Flag 0x2000 set says wrong interrupt
  404. * Flag 0x1000 set says interrupt is in use by someone else
  405. */
  406. ConfigErrorMsgBox(hDlg,
  407. DspVersion & 0x4000 ? IDS_ERRBADPORT :
  408. DspVersion & 0x2000 ? IDS_ERRBADINT :
  409. DspVersion & 0x1000 ? IDS_ERRINTINUSE :
  410. IDS_ERRBADCONFIG);
  411. } else {
  412. /*
  413. * If we're an install then check out the version
  414. */
  415. if (bInstall) {
  416. /* Advise upgrade if on <= 1.00 DSP */
  417. if (DspVersion <= DSP_VERSION_REQD) {
  418. /* display error and DON'T write INI settings - */
  419. /* this way the driver will never enable */
  420. ConfigErrorMsgBox(hDlg, IDS_ERRBADVERSION);
  421. }
  422. /* high bit set if Thunder Board - warn them */
  423. /* but continue installing */
  424. if (DspVersion & 0x8000)
  425. ConfigErrorMsgBox(hDlg, IDS_WARNTHUNDER);
  426. /* if installing on a Pro spectrum card, warn them */
  427. /* but continue installing */
  428. else if (DspVersion & 0x800)
  429. ConfigErrorMsgBox(hDlg, IDS_WARNPROSPEC);
  430. /* if installing on a Pro card, warn them */
  431. /* but continue installing */
  432. else if (DspVersion >= DSP_VERSION_PRO)
  433. ConfigErrorMsgBox(hDlg, IDS_WARNPROCARD);
  434. bInstall = FALSE;
  435. }
  436. EndDialog(hDlg, DRVCNF_RESTART);
  437. return;
  438. }
  439. }