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.

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