Source code of Windows XP (NT5)
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.

1042 lines
25 KiB

  1. //==========================================================================;
  2. //
  3. // init.c
  4. //
  5. // Copyright (c) 1991-1999 Microsoft Corporation
  6. //
  7. // Description:
  8. //
  9. //
  10. // History:
  11. // 11/15/92 cjp [curtisp]
  12. //
  13. //==========================================================================;
  14. #include <windows.h>
  15. #include <windowsx.h>
  16. #include <mmsystem.h>
  17. #include <mmddkp.h>
  18. #include <mmreg.h>
  19. #include <msacm.h>
  20. #include <msacmdrv.h>
  21. #ifdef USE_ACMTHUNK
  22. #include "acmthunk.h"
  23. #endif
  24. #include "msacmmap.h"
  25. #include "profile.h"
  26. #include "debug.h"
  27. //
  28. //
  29. //
  30. //
  31. ACMGLOBALINFO acmglobalinfo;
  32. ACMGARB acmgarb;
  33. PACMGARB gpag;
  34. //--------------------------------------------------------------------------;
  35. //
  36. // LRESULT mapWaveGetDevCaps
  37. //
  38. // Description:
  39. //
  40. //
  41. // Arguments:
  42. // BOOL fInput: TRUE if input.
  43. //
  44. // LPWAVEOUTCAPS pwc: Pointer to a WAVEOUTCAPS structure to receive
  45. // the information. Used for both input and output. Output structure
  46. // contains input structure plus extras....
  47. //
  48. // UINT cbSize: Size of the WAVEOUTCAPS structure.
  49. //
  50. // Return (MMRESULT):
  51. //
  52. // History:
  53. // 06/14/93 cjp [curtisp]
  54. //
  55. //--------------------------------------------------------------------------;
  56. MMRESULT FNGLOBAL mapWaveGetDevCaps
  57. (
  58. BOOL fInput,
  59. LPWAVEOUTCAPS pwc,
  60. UINT cbSize
  61. )
  62. {
  63. MMRESULT mmr;
  64. WAVEOUTCAPS woc;
  65. UINT cWaveDevs;
  66. BOOL fFoundOnlyOneMappableDeviceID;
  67. UINT uMappableDeviceID;
  68. UINT i;
  69. if (fInput)
  70. {
  71. cbSize = min(sizeof(WAVEINCAPS), cbSize);
  72. cWaveDevs = gpag->cWaveInDevs;
  73. }
  74. else
  75. {
  76. cbSize = min(sizeof(WAVEOUTCAPS), cbSize);
  77. cWaveDevs = gpag->cWaveOutDevs;
  78. }
  79. //
  80. // Determine if there is only one mappable device ID. If there is only
  81. // one, then set fFoundOnlyOneMappableID=TRUE and put the device ID
  82. // in uMappableDeviceID.
  83. //
  84. fFoundOnlyOneMappableDeviceID = FALSE;
  85. for (i=0; i < cWaveDevs; i++)
  86. {
  87. if (fInput)
  88. {
  89. mmr = (MMRESULT)waveInMessage((HWAVEIN)LongToHandle(i), DRV_QUERYMAPPABLE, 0L, 0L);
  90. }
  91. else
  92. {
  93. mmr = (MMRESULT)waveOutMessage((HWAVEOUT)LongToHandle(i), DRV_QUERYMAPPABLE, 0L, 0L);
  94. }
  95. if (MMSYSERR_NOERROR == mmr)
  96. {
  97. if (fFoundOnlyOneMappableDeviceID)
  98. {
  99. fFoundOnlyOneMappableDeviceID = FALSE;
  100. break;
  101. }
  102. uMappableDeviceID = i;
  103. fFoundOnlyOneMappableDeviceID = TRUE;
  104. }
  105. }
  106. //
  107. // If there is only one mappable device ID, then get the caps from it to
  108. // fill in the dwSupport fields. Otherwise, let's hardcode the dwSupport
  109. // field.
  110. //
  111. if (fFoundOnlyOneMappableDeviceID)
  112. {
  113. if (fInput)
  114. {
  115. mmr = waveInGetDevCaps(uMappableDeviceID, (LPWAVEINCAPS)&woc, cbSize);
  116. }
  117. else
  118. {
  119. mmr = waveOutGetDevCaps(uMappableDeviceID, &woc, cbSize);
  120. }
  121. }
  122. else
  123. {
  124. woc.dwSupport = WAVECAPS_VOLUME | WAVECAPS_LRVOLUME;
  125. mmr = MMSYSERR_NOERROR;
  126. }
  127. //
  128. // Bail on error
  129. //
  130. if (MMSYSERR_NOERROR != mmr)
  131. {
  132. return (mmr);
  133. }
  134. //
  135. //
  136. //
  137. woc.wMid = MM_MICROSOFT;
  138. woc.wPid = MM_WAVE_MAPPER;
  139. woc.vDriverVersion = VERSION_MSACMMAP;
  140. woc.wChannels = 2;
  141. LoadString(gpag->hinst, IDS_ACM_CAPS_DESCRIPTION, woc.szPname, SIZEOF(woc.szPname));
  142. //
  143. //
  144. //
  145. woc.dwFormats = WAVE_FORMAT_1M08 |
  146. WAVE_FORMAT_1S08 |
  147. WAVE_FORMAT_1M16 |
  148. WAVE_FORMAT_1S16 |
  149. WAVE_FORMAT_2M08 |
  150. WAVE_FORMAT_2S08 |
  151. WAVE_FORMAT_2M16 |
  152. WAVE_FORMAT_2S16 |
  153. WAVE_FORMAT_4M08 |
  154. WAVE_FORMAT_4S08 |
  155. WAVE_FORMAT_4M16 |
  156. WAVE_FORMAT_4S16;
  157. _fmemcpy(pwc, &woc, cbSize);
  158. return (MMSYSERR_NOERROR);
  159. } // waveGetDevCaps()
  160. //--------------------------------------------------------------------------;
  161. //
  162. // UINT GetPCMSupportFlags
  163. //
  164. // Description:
  165. //
  166. //
  167. // Arguments:
  168. // PZYZPCMFORMATS pzpf
  169. // UINT iaPCMFormats:
  170. //
  171. // Return (VOID):
  172. //
  173. // History:
  174. // 06/14/93 cjp [curtisp]
  175. // 03/13/94 fdy [frankye]
  176. // Modifed the interface to take pzpf and an index into it.
  177. // Modifed the function to set flags to indicate which wave
  178. // devices support the format in question.
  179. //
  180. //--------------------------------------------------------------------------;
  181. VOID FNLOCAL GetPCMSupportFlags
  182. (
  183. PZYZPCMFORMAT pzpf,
  184. UINT iaPCMFormats
  185. )
  186. {
  187. PCMWAVEFORMAT wfPCM;
  188. UINT uSamplesPerSec;
  189. UINT u, n, i;
  190. #define WFQFLAGS (WAVE_FORMAT_QUERY | WAVE_ALLOWSYNC)
  191. WAIT_FOR_MUTEX(gpag->hMutexSettings);
  192. //
  193. // set all supported formats to 'not supported'
  194. //
  195. for (i = gpag->cWaveInDevs; i; i--)
  196. pzpf[iaPCMFormats].uFlagsInput[i-1] = 0;
  197. for (i = gpag->cWaveOutDevs; i; i--)
  198. pzpf[iaPCMFormats].uFlagsOutput[i-1] = 0;
  199. //
  200. // we need to try 4 different format types:
  201. // Mono 8 Bit
  202. // Stereo 8 Bit
  203. // Mono 16 Bit
  204. // Stereo 16 Bit
  205. //
  206. for (u = 0; u < 4; u++)
  207. {
  208. //
  209. // set the stuff that is constant for all 4 formats
  210. //
  211. uSamplesPerSec = pzpf[iaPCMFormats].uSamplesPerSec;
  212. wfPCM.wf.wFormatTag = WAVE_FORMAT_PCM;
  213. wfPCM.wf.nSamplesPerSec = uSamplesPerSec;
  214. switch (u)
  215. {
  216. case 0:
  217. wfPCM.wf.nChannels = 1;
  218. wfPCM.wf.nAvgBytesPerSec= uSamplesPerSec;
  219. wfPCM.wf.nBlockAlign = 1;
  220. wfPCM.wBitsPerSample = 8;
  221. break;
  222. case 1:
  223. wfPCM.wf.nChannels = 2;
  224. wfPCM.wf.nAvgBytesPerSec= uSamplesPerSec * 2;
  225. wfPCM.wf.nBlockAlign = 2;
  226. wfPCM.wBitsPerSample = 8;
  227. break;
  228. case 2:
  229. wfPCM.wf.nChannels = 1;
  230. wfPCM.wf.nAvgBytesPerSec= uSamplesPerSec * 2;
  231. wfPCM.wf.nBlockAlign = 2;
  232. wfPCM.wBitsPerSample = 16;
  233. break;
  234. case 3:
  235. wfPCM.wf.nChannels = 2;
  236. wfPCM.wf.nAvgBytesPerSec= uSamplesPerSec * 4;
  237. wfPCM.wf.nBlockAlign = 4;
  238. wfPCM.wBitsPerSample = 16;
  239. break;
  240. }
  241. //
  242. // first query ALL ENABLED INPUT devices for the wfPCM format
  243. //
  244. if (gpag->pSettings->fPreferredOnly &&
  245. (gpag->pSettings->uIdPreferredIn != -1))
  246. {
  247. i = gpag->pSettings->uIdPreferredIn;
  248. n = gpag->pSettings->uIdPreferredIn + 1;
  249. }
  250. else
  251. {
  252. i = 0;
  253. n = gpag->cWaveInDevs;
  254. }
  255. for (; i < n; i++)
  256. {
  257. #ifndef _WIN32
  258. if (!waveInOpen(NULL, i, (LPWAVEFORMAT)&wfPCM, 0L, 0L, WFQFLAGS))
  259. #else
  260. if (!waveInOpen(NULL, i, (LPWAVEFORMATEX)&wfPCM, 0L, 0L, WFQFLAGS))
  261. #endif
  262. {
  263. pzpf[iaPCMFormats].uFlagsInput[i] |= (ZYZPCMF_IN_M08 << u);
  264. }
  265. }
  266. //
  267. // now query ALL ENABLED OUTPUT devices for the wfPCM format
  268. //
  269. if (gpag->pSettings->fPreferredOnly &&
  270. (gpag->pSettings->uIdPreferredOut != -1))
  271. {
  272. i = gpag->pSettings->uIdPreferredOut;
  273. n = gpag->pSettings->uIdPreferredOut + 1;
  274. }
  275. else
  276. {
  277. i = 0;
  278. n = gpag->cWaveOutDevs;
  279. }
  280. for (; i < n; i++)
  281. {
  282. #ifndef _WIN32
  283. if (!waveOutOpen(NULL, i, (LPWAVEFORMAT)&wfPCM, 0L, 0L, WFQFLAGS))
  284. #else
  285. if (!waveOutOpen(NULL, i, (LPWAVEFORMATEX)&wfPCM, 0L, 0L, WFQFLAGS))
  286. #endif
  287. {
  288. pzpf[iaPCMFormats].uFlagsOutput[i] |= (ZYZPCMF_OUT_M08 << u);
  289. }
  290. }
  291. }
  292. //
  293. // finally return
  294. //
  295. #if 0 // def DEBUG
  296. DPF(3, "PCM Support: %uHz, In[%d]=%04xh, Out[%d]=%04xh",
  297. pzpf[iaPCMFormats].uSamplesPerSec,
  298. iaPCMFormats,
  299. *pzpf[iaPCMFormats].uFlagsInput,
  300. iaPCMFormats,
  301. *pzpf[iaPCMFormats].uFlagsOutput);
  302. #endif
  303. RELEASE_MUTEX(gpag->hMutexSettings);
  304. return;
  305. } // GetPCMSupportFlags()
  306. //--------------------------------------------------------------------------;
  307. //
  308. // BOOL GetWaveFormats
  309. //
  310. // Description:
  311. //
  312. //
  313. // Arguments:
  314. // PZYZPCMFORMAT pzpf:
  315. //
  316. // Return (BOOL):
  317. //
  318. // History:
  319. // 06/14/93 cjp [curtisp]
  320. // 03/13/94 fdy [frankye]
  321. // Expanded the ZYZPCMFORMAT structure to include flags which
  322. // indicate which wave device supports a given format. This
  323. // function will now set these flags. Note that
  324. // the code that is #if 0'd WILL NOT WORK given these changes, so
  325. // if anybody ever resuscitates that code, you better modify it!
  326. //
  327. //--------------------------------------------------------------------------;
  328. BOOL FNGLOBAL GetWaveFormats
  329. (
  330. PZYZPCMFORMAT pzpf
  331. )
  332. {
  333. UINT u;
  334. #if 0
  335. WAVEOUTCAPS woc;
  336. WAVEINCAPS wic;
  337. UINT n;
  338. DWORD dwInFormats;
  339. DWORD dwOutFormats;
  340. //
  341. // first things first: get all 'standard' supported formats from the
  342. // current selected devices for input and output...
  343. //
  344. dwInFormats = 0L;
  345. if (gpag->fPreferredOnly && (gpag->uIdPreferredIn != -1))
  346. {
  347. if (!waveInGetDevCaps(gpag->uIdPreferredIn, &wic, sizeof(wic)))
  348. dwInFormats = wic.dwFormats;
  349. }
  350. else
  351. {
  352. n = gpag->cWaveInDevs;
  353. for (i = 0; i < n; i++)
  354. {
  355. if (!waveInGetDevCaps(i, &wic, sizeof(wic)))
  356. dwInFormats |= wic.dwFormats;
  357. }
  358. }
  359. dwOutFormats = 0L;
  360. if (gpag->fPreferredOnly && (gpag->uIdPreferredOut != -1))
  361. {
  362. if (!waveOutGetDevCaps(gpag->uIdPreferredOut, &woc, sizeof(woc)))
  363. dwOutFormats = woc.dwFormats;
  364. }
  365. else
  366. {
  367. n = gpag->cWaveOutDevs;
  368. for (i = 0; i < n; i++)
  369. {
  370. if (!waveOutGetDevCaps(i, &woc, sizeof(woc)))
  371. dwOutFormats |= woc.dwFormats;
  372. }
  373. }
  374. #endif
  375. //
  376. // now step through each sample rate in the pzpf structure and set all
  377. // the appropriate bits for whether it is supported, etc..
  378. //
  379. for (u = 0; pzpf[u].uSamplesPerSec; u++)
  380. {
  381. //
  382. // we need to special case a few of the sample rates, etc to get
  383. // this whole thing working--once the grunt work is done here
  384. // (and only once during initialization), then the data is easily
  385. // accessible/used...
  386. //
  387. switch (pzpf[u].uSamplesPerSec)
  388. {
  389. //
  390. // NOTE! it would be nice if we could rely on the caps
  391. // structure being correct on drivers.... but alas, Media Vision
  392. // found a way to mess that up also (on some of their hundreds
  393. // of releases of their drivers). so ALWAYS query for the
  394. // format support.
  395. //
  396. // by the way, the reason they ship their drivers with this
  397. // bug (and possibly other OEM's) is due to Sound Recorder
  398. // (apparently their only test app?!?) only doing queries
  399. // and never looking at the caps bits.
  400. //
  401. #if 0
  402. case 11025:
  403. pzpf[u].uFlags = (WORD)(dwInFormats & WAVE_FORMAT_11k) << 8;
  404. pzpf[u].uFlags |= (WORD)(dwOutFormats & WAVE_FORMAT_11k);
  405. break;
  406. case 22050:
  407. pzpf[u].uFlags =
  408. (WORD)(dwInFormats & WAVE_FORMAT_22k) >> 4 << 8;
  409. pzpf[u].uFlags |= (WORD)(dwOutFormats & WAVE_FORMAT_22k) >> 4;
  410. break;
  411. case 44100:
  412. pzpf[u].uFlags =
  413. (WORD)(dwInFormats & WAVE_FORMAT_44k) >> 8 << 8;
  414. pzpf[u].uFlags |= (WORD)(dwOutFormats & WAVE_FORMAT_44k) >> 8;
  415. break;
  416. #else
  417. case 11025:
  418. case 22050:
  419. case 44100:
  420. #endif
  421. case 5510:
  422. case 6620:
  423. case 8000:
  424. case 9600:
  425. case 16000:
  426. case 18900:
  427. case 27420:
  428. case 32000:
  429. case 33075:
  430. case 37800:
  431. case 48000:
  432. GetPCMSupportFlags(pzpf, u);
  433. break;
  434. }
  435. }
  436. //
  437. // reset these--they are auto determined while the mapper is being
  438. // used...
  439. //
  440. WAIT_FOR_MUTEX(gpag->hMutexSettings);
  441. gpag->pSettings->fSyncOnlyOut = FALSE;
  442. gpag->pSettings->fSyncOnlyIn = FALSE;
  443. RELEASE_MUTEX(gpag->hMutexSettings);
  444. return (TRUE);
  445. } // GetWaveFormats()
  446. //--------------------------------------------------------------------------;
  447. //
  448. // BOOL mapSettingsRestore
  449. //
  450. // Description:
  451. //
  452. //
  453. // Arguments:
  454. // None.
  455. //
  456. // Return (BOOL):
  457. //
  458. // History:
  459. // 06/14/93 cjp [curtisp]
  460. //
  461. //--------------------------------------------------------------------------;
  462. BOOL FNGLOBAL mapSettingsRestore
  463. (
  464. void
  465. )
  466. {
  467. DWORD dwFlags;
  468. UINT ii;
  469. DWORD cbSize;
  470. PUINT pFlags;
  471. DPF(1, "mapSettingsRestore:");
  472. //
  473. //
  474. //
  475. gpag->cWaveOutDevs = waveOutGetNumDevs();
  476. gpag->cWaveInDevs = waveInGetNumDevs();
  477. // Number of devices per sampling rate...
  478. cbSize = gpag->cWaveOutDevs + gpag->cWaveInDevs;
  479. // Number of total flags...
  480. // cbSize *= (sizeof(gaPCMFormats)/sizeof(gaPCMFormats[0]));
  481. cbSize *= 15; // It's fifteen; Trust Me - Fwong.
  482. // Size in bytes...
  483. cbSize *= sizeof(UINT);
  484. pFlags = (PUINT)GlobalAllocPtr(GHND, cbSize);
  485. if (NULL == pFlags)
  486. {
  487. //
  488. // Hmm... How do we cope.
  489. //
  490. return FALSE;
  491. }
  492. ZeroMemory(pFlags, cbSize);
  493. if (NULL != gaPCMFormats[0].uFlagsInput)
  494. {
  495. GlobalFreePtr(gaPCMFormats[0].uFlagsInput);
  496. }
  497. for (ii = 0; ;ii++)
  498. {
  499. if (0 == gaPCMFormats[ii].uSamplesPerSec)
  500. {
  501. break;
  502. }
  503. gaPCMFormats[ii].uFlagsInput = pFlags;
  504. pFlags += gpag->cWaveInDevs;
  505. gaPCMFormats[ii].uFlagsOutput = pFlags;
  506. pFlags += gpag->cWaveOutDevs;
  507. }
  508. WAIT_FOR_MUTEX(gpag->hMutexSettings);
  509. // gpag->fPrestoSyncAsync = (BOOL)IRegReadDwordDefault( hkeyMapper, gszKeyPrestoSyncAsync, 0 );
  510. gpag->fPrestoSyncAsync = FALSE;
  511. //
  512. // find the waveOut device that is selected as preferred
  513. //
  514. if (!waveOutMessage((HWAVEOUT)LongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&gpag->pSettings->uIdPreferredOut, (DWORD_PTR)&dwFlags)) {
  515. gpag->pSettings->fPreferredOnly = (0 != (DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY));
  516. } else {
  517. gpag->pSettings->uIdPreferredOut = (UINT)(-1);
  518. gpag->pSettings->fPreferredOnly = TRUE;
  519. }
  520. //
  521. // find the waveIn device that is selected as preferred
  522. //
  523. if (!waveInMessage((HWAVEIN)LongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&gpag->pSettings->uIdPreferredIn, (DWORD_PTR)&dwFlags)) {
  524. gpag->pSettings->fPreferredOnly = (0 != (DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY));
  525. } else {
  526. gpag->pSettings->uIdPreferredOut = (UINT)(-1);
  527. gpag->pSettings->fPreferredOnly = TRUE;
  528. }
  529. //
  530. // reread/cache all the PCM format info from the devices selected, etc.
  531. //
  532. GetWaveFormats(gaPCMFormats);
  533. RELEASE_MUTEX(gpag->hMutexSettings);
  534. return (TRUE);
  535. } // mapSettingsRestore()
  536. //==========================================================================;
  537. //
  538. //
  539. //
  540. //
  541. //==========================================================================;
  542. //--------------------------------------------------------------------------;
  543. //
  544. // LRESULT mapDriverEnable
  545. //
  546. // Description:
  547. //
  548. //
  549. // Arguments:
  550. // HDRVR hdrvr:
  551. //
  552. // Return (LRESULT):
  553. //
  554. // History:
  555. // 09/18/93 cjp [curtisp]
  556. //
  557. //--------------------------------------------------------------------------;
  558. LRESULT FNGLOBAL mapDriverEnable
  559. (
  560. HDRVR hdrvr
  561. )
  562. {
  563. #ifdef USE_ACMTHUNK
  564. BOOL f;
  565. #endif
  566. DWORD dw;
  567. DPF(1, "mapDriverEnable(hdrvr=%.04Xh)", hdrvr);
  568. #ifdef USE_ACMTHUNK
  569. f = acmThunkInitialize();
  570. if (!f)
  571. {
  572. DPF(0, "!ACM thunk cannot be initialized!");
  573. return (0L);
  574. }
  575. #endif
  576. dw = acmGetVersion();
  577. if (VERSION_MSACMMAP > HIWORD(dw))
  578. {
  579. DPF(0, "!requires version %u.%.02u of the ACM!",
  580. VERSION_MSACMMAP_MAJOR, VERSION_MSACMMAP_MINOR);
  581. #ifdef USE_ACMTHUNK
  582. acmThunkTerminate();
  583. #endif
  584. return (0L);
  585. }
  586. mapSettingsRestore();
  587. gpag->fEnabled = TRUE;
  588. //
  589. // the return value is ignored, but return non-zero anyway
  590. //
  591. return (1L);
  592. } // mapDriverEnable()
  593. //--------------------------------------------------------------------------;
  594. //
  595. // LRESULT mapDriverDisable
  596. //
  597. // Description:
  598. //
  599. //
  600. // Arguments:
  601. // HDRVR hdrvr:
  602. //
  603. // Return (LRESULT):
  604. //
  605. // History:
  606. // 09/18/93 cjp [curtisp]
  607. //
  608. //--------------------------------------------------------------------------;
  609. LRESULT FNGLOBAL mapDriverDisable
  610. (
  611. HDRVR hdrvr
  612. )
  613. {
  614. DPF(1, "mapDriverDisable(hdrvr=%.04Xh)", hdrvr);
  615. if (gpag->fEnabled)
  616. {
  617. gpag->fEnabled = FALSE;
  618. }
  619. #ifdef USE_ACMTHUNK
  620. acmThunkTerminate();
  621. #endif
  622. //
  623. // the return value is ignored, but return non-zero anyway
  624. //
  625. return (1L);
  626. } // mapDriverDisable()
  627. //==========================================================================;
  628. //
  629. //
  630. //
  631. //
  632. //==========================================================================;
  633. //--------------------------------------------------------------------------;
  634. //
  635. // LRESULT mapDriverInstall
  636. //
  637. // Description:
  638. //
  639. //
  640. // Arguments:
  641. // HDRVR hdrvr:
  642. //
  643. // Return (LRESULT):
  644. //
  645. // History:
  646. // 09/25/93 cjp [curtisp]
  647. //
  648. //--------------------------------------------------------------------------;
  649. LRESULT FNGLOBAL mapDriverInstall
  650. (
  651. HDRVR hdrvr
  652. )
  653. {
  654. DPF(1, "mapDriverInstall(hdrvr=%.04Xh)", hdrvr);
  655. //
  656. //
  657. //
  658. return (DRVCNF_RESTART);
  659. } // mapDriverInstall()
  660. //--------------------------------------------------------------------------;
  661. //
  662. // LRESULT mapDriverRemove
  663. //
  664. // Description:
  665. //
  666. //
  667. // Arguments:
  668. // HDRVR hdrvr:
  669. //
  670. // Return (LRESULT):
  671. //
  672. // History:
  673. // 09/25/93 cjp [curtisp]
  674. //
  675. //--------------------------------------------------------------------------;
  676. LRESULT FNGLOBAL mapDriverRemove
  677. (
  678. HDRVR hdrvr
  679. )
  680. {
  681. DPF(1, "mapDriverRemove(hdrvr=%.04Xh)", hdrvr);
  682. //
  683. //
  684. //
  685. return (DRVCNF_RESTART);
  686. } // mapDriverRemove()
  687. //==========================================================================;
  688. //
  689. // WIN 16 SPECIFIC SUPPORT
  690. //
  691. //==========================================================================;
  692. #ifndef WIN32
  693. //--------------------------------------------------------------------------;
  694. //
  695. // int WEP
  696. //
  697. // Description:
  698. // The infamous useless WEP(). Note that this procedure needs to be
  699. // in a FIXED segment under Windows 3.0. Under Windows 3.1 this is
  700. // not necessary.
  701. //
  702. // Arguments:
  703. // WORD wUseless: Should tell whether Windows is exiting or not.
  704. //
  705. // Return (int):
  706. // Always return non-zero.
  707. //
  708. // History:
  709. // 04/29/93 cjp [curtisp]
  710. //
  711. //--------------------------------------------------------------------------;
  712. EXTERN_C int FNEXPORT WEP
  713. (
  714. WORD wUseless
  715. )
  716. {
  717. DPF(1, "WEP(wUseless=%u)", wUseless);
  718. //
  719. // always return non-zero
  720. //
  721. return (1);
  722. } // WEP()
  723. //--------------------------------------------------------------------------;
  724. //
  725. // int LibMain
  726. //
  727. // Description:
  728. // Library initialization code.
  729. //
  730. // This routine must guarantee the following things so CODEC's don't
  731. // have to special case code everywhere:
  732. //
  733. // o will only run in Windows 3.10 or greater (our exehdr is
  734. // marked appropriately).
  735. //
  736. // o will only run on >= 386 processor. only need to check
  737. // on Win 3.1.
  738. //
  739. // Arguments:
  740. // HINSTANCE hinst: Our module instance handle.
  741. //
  742. // WORD wDataSeg: Our data segment selector.
  743. //
  744. // WORD cbHeapSize: The heap size from the .def file.
  745. //
  746. // LPSTR pszCmdLine: The command line.
  747. //
  748. // Return (int):
  749. // Returns non-zero if the initialization was successful and 0 otherwise.
  750. //
  751. // History:
  752. // 11/15/92 cjp [curtisp]
  753. //
  754. //--------------------------------------------------------------------------;
  755. int FNGLOBAL LibMain
  756. (
  757. HINSTANCE hinst,
  758. WORD wDataSeg,
  759. WORD cbHeapSize,
  760. LPSTR pszCmdLine
  761. )
  762. {
  763. //
  764. // we ONLY work on >= 386. if we are on a wimpy processor, scream in
  765. // pain and die a horrible death!
  766. //
  767. // NOTE! do this check first thing and get out if on a 286. we are
  768. // compiling with -G3 and C8's libentry garbage does not check for
  769. // >= 386 processor. the following code does not execute any 386
  770. // instructions (not complex enough)..
  771. //
  772. #if (WINVER < 0x0400)
  773. if (GetWinFlags() & WF_CPU286)
  774. {
  775. return (FALSE);
  776. }
  777. #endif
  778. DbgInitialize(TRUE);
  779. DPF(1, "LibMain(hinst=%.4Xh, wDataSeg=%.4Xh, cbHeapSize=%u, pszCmdLine=%.8lXh)",
  780. hinst, wDataSeg, cbHeapSize, pszCmdLine);
  781. DPF(5, "!*** break for debugging ***");
  782. //
  783. // everything looks good to go in Win 16 land.
  784. //
  785. gpag = &acmgarb;
  786. gpag->hinst = hinst;
  787. // Note: in Win16 there's only one instance of the mapper
  788. gpag->pSettings = &(acmglobalinfo);
  789. return (TRUE);
  790. } // LibMain()
  791. #else // WIN32
  792. //==========================================================================;
  793. //
  794. // WIN 32 SPECIFIC SUPPORT
  795. //
  796. //==========================================================================;
  797. //--------------------------------------------------------------------------;
  798. //
  799. // PACMGLOBALINFO mapAllocateGlobalInfo
  800. //
  801. // Description:
  802. // Either creates the common buffer among all instances of the mapper
  803. // or it finds the common buffer.
  804. //
  805. // Arguments:
  806. // None.
  807. //
  808. // Return (PACMGLOBALINFO):
  809. // Returns a pointer to global info structure.
  810. //
  811. // History:
  812. // 01/21/98 Fwong Adding multi-instance support.
  813. // 01/24/99 FrankYe Back to simple single process support, since
  814. // since winmm has been modified to hold the
  815. // preferred device settings.
  816. //
  817. //--------------------------------------------------------------------------;
  818. PACMGLOBALINFO mapAllocateGlobalInfo
  819. (
  820. void
  821. )
  822. {
  823. // We could actually use a critical section instead of a mutex here.
  824. gpag->hMutexSettings = CreateMutex(NULL, FALSE, NULL);
  825. return &(acmglobalinfo);
  826. } // mapAllocateGlobalInfo()
  827. //--------------------------------------------------------------------------;
  828. //
  829. // void mapFreeGlobalInfo
  830. //
  831. // Description:
  832. // Cleans up the objects associated with the global memory buffer.
  833. //
  834. // Arguments:
  835. // PACMGLOBALINFO pagi: Base buffer for global info.
  836. //
  837. // Return (void):
  838. //
  839. // History:
  840. // 01/21/98 Fwong Adding multi-instance support.
  841. // 01/24/99 FrankYe Back to simple single process support, since
  842. // since winmm has been modified to hold the
  843. // preferred device settings.
  844. //
  845. //--------------------------------------------------------------------------;
  846. void mapFreeGlobalInfo
  847. (
  848. PACMGLOBALINFO pagi
  849. )
  850. {
  851. if(NULL != gpag->hMutexSettings) CloseHandle(gpag->hMutexSettings);
  852. } // mapFreeGlobalInfo()
  853. //--------------------------------------------------------------------------;
  854. //
  855. // BOOL DllEntryPoint
  856. //
  857. // Description:
  858. // This is the standard DLL entry point for Win 32.
  859. //
  860. // Arguments:
  861. // HINSTANCE hinst: Our instance handle.
  862. //
  863. // DWORD dwReason: The reason we've been called--process/thread attach
  864. // and detach.
  865. //
  866. // LPVOID lpReserved: Reserved. Should be NULL--so ignore it.
  867. //
  868. // Return (BOOL):
  869. // Returns non-zero if the initialization was successful and 0 otherwise.
  870. //
  871. // History:
  872. // 11/15/92 cjp [curtisp]
  873. //
  874. //--------------------------------------------------------------------------;
  875. BOOL FNEXPORT DllEntryPoint
  876. (
  877. HINSTANCE hinst,
  878. DWORD dwReason,
  879. LPVOID lpReserved
  880. )
  881. {
  882. switch (dwReason)
  883. {
  884. case DLL_PROCESS_ATTACH:
  885. DbgInitialize(TRUE);
  886. gpag = &acmgarb;
  887. gpag->hinst = hinst;
  888. gpag->pSettings = mapAllocateGlobalInfo();
  889. DisableThreadLibraryCalls(hinst);
  890. DPF(1, "DllEntryPoint(hinst=%.08lXh, DLL_PROCESS_ATTACH)", hinst);
  891. return (TRUE);
  892. case DLL_PROCESS_DETACH:
  893. mapFreeGlobalInfo(gpag->pSettings);
  894. DPF(1, "DllEntryPoint(hinst=%.08lXh, DLL_PROCESS_DETACH)", hinst);
  895. return (TRUE);
  896. }
  897. return (TRUE);
  898. } // DllEntryPoint()
  899. #endif