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.

3382 lines
106 KiB

  1. /***********************************************************************\
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WMMEDIA2.C
  8. * WOW32 16-bit MultiMedia API support
  9. *
  10. * Contains:
  11. * Midi IN apis
  12. * Midi OUT apis
  13. * Wave IN apis
  14. * Wave OUT apis
  15. *
  16. *
  17. * History:
  18. * Created 21-Jan-1992 by Mike Tricker (MikeTri), after jeffpar
  19. * Changed 15-Jul-1992 by Mike Tricker (MikeTri), fixing GetDevCaps calls
  20. * 26-Jul-1992 by Stephen Estrop (StephenE) thunks for mciSendCommand
  21. * 30-Jul-1992 by Mike Tricker (MikeTri), fixing Wave/Midi/MMIO
  22. * 03-Aug-1992 by Mike Tricker (MikeTri), added proper error handling
  23. * 08-Oct-1992 by StephenE spawned from the original wmmedia.c
  24. *
  25. \***********************************************************************/
  26. //
  27. // We define NO_STRICT so that the compiler doesn't moan and groan when
  28. // I use the FARPROC type for the Multi-Media api loading.
  29. //
  30. #define NO_STRICT
  31. #define OEMRESOURCE
  32. #include "precomp.h"
  33. #pragma hdrstop
  34. #if 0
  35. MODNAME(wmmedia2.c);
  36. // A 32 bit ptr to the 16 bit callback data
  37. extern PCALLBACK_DATA pCallBackData;
  38. extern CRITICAL_SECTION mmCriticalSection;
  39. #if DBG
  40. /*
  41. ** AllocCount maintains a count of the number XXM_DONE messages that
  42. ** we expect to receive before the device is closed. When the device is
  43. ** closed this count should be zero.
  44. **
  45. */
  46. int AllocWaveCount = 0;
  47. int AllocMidiCount = 0;
  48. int mmTraceWave = 0;
  49. int mmTraceMidi = 0;
  50. #endif
  51. /* ---------------------------------------------------------------------
  52. ** MIDI Output API's
  53. ** ---------------------------------------------------------------------
  54. */
  55. /**********************************************************************\
  56. *
  57. * WMM32midiOutGetNumDevs
  58. *
  59. * This function retrieves the number of MIDI output devices present
  60. * in the system.
  61. *
  62. \**********************************************************************/
  63. ULONG FASTCALL WMM32midiOutGetNumDevs(PVDMFRAME pFrame)
  64. {
  65. static FARPROC mmAPI = NULL;
  66. ULONG ul;
  67. UNREFERENCED_PARAMETER(pFrame);
  68. GET_MULTIMEDIA_API( "midiOutGetNumDevs", mmAPI, MMSYSERR_NODRIVER );
  69. trace_midi(( "midiOutGetNumDevs()" ));
  70. ul = GETWORD16((*mmAPI)() );
  71. trace_midi(( "-> %ld\n", ul ));
  72. RETURN(ul);
  73. }
  74. /**********************************************************************\
  75. *
  76. * WMM32midiOutGetDevCaps
  77. *
  78. * This function queries a specified MIDI output device to determine its
  79. * capabilities.
  80. *
  81. *
  82. *
  83. * We will now change things...
  84. *
  85. * Step 1: get the ENTIRE Caps structure, irrespective of the number of bytes
  86. * requested
  87. * (previously I was getting the requested number of bytes via
  88. * parg16->f3 (plus 2 'cos of the WORD -> UINT change for version -
  89. * which was wrong anyway...) )
  90. *
  91. * Step 2: thunk the ENTIRE structure in to a 16 bit local variable
  92. *
  93. * Step 3: RtlCopyMemory the REQUESTED number of bytes from the local copy
  94. * to the "real" structure within the app
  95. *
  96. * Thanks to RCBS for sorting me out once again !
  97. *
  98. *
  99. *
  100. \**********************************************************************/
  101. ULONG FASTCALL WMM32midiOutGetDevCaps(PVDMFRAME pFrame)
  102. {
  103. register PMIDIOUTGETDEVCAPS16 parg16;
  104. static FARPROC mmAPI = NULL;
  105. ULONG ul;
  106. MIDIOUTCAPS midioutcaps;
  107. GET_MULTIMEDIA_API( "midiOutGetDevCapsA", mmAPI, MMSYSERR_NODRIVER );
  108. GETARGPTR(pFrame, sizeof(MIDIOUTGETDEVCAPS16), parg16);
  109. trace_midi(( "midiOutGetDevCaps( %x, %x, %x )", INT32( parg16->f1 ),
  110. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  111. /*
  112. ** If the size parameter was zero return straight away. Note that this
  113. ** is not an error.
  114. */
  115. if ( UINT32( parg16->f3 ) == 0 ) {
  116. ul = MMSYSERR_NOERROR;
  117. }
  118. else {
  119. ul = GETWORD16((*mmAPI)( INT32(parg16->f1), &midioutcaps,
  120. sizeof(MIDIOUTCAPS) ));
  121. /*
  122. ** This must now thunk the ENTIRE structure, then copy parg16->f3
  123. ** bytes onto the "real" structure in the app, but only if the call
  124. ** returned success.
  125. */
  126. if ( ul == MMSYSERR_NOERROR ) {
  127. ul = PUTMIDIOUTCAPS16(parg16->f2, &midioutcaps, UINT32(parg16->f3));
  128. }
  129. }
  130. trace_midi(( "-> %ld\n", ul ));
  131. FREEARGPTR(parg16);
  132. RETURN(ul);
  133. }
  134. /**********************************************************************\
  135. *
  136. * WMM32midiOutGetErrorText
  137. *
  138. * This function retrieves a textual description of the error
  139. * identified by the specified error number.
  140. *
  141. \**********************************************************************/
  142. ULONG FASTCALL WMM32midiOutGetErrorText(PVDMFRAME pFrame)
  143. {
  144. register PMIDIOUTGETERRORTEXT16 parg16;
  145. static FARPROC mmAPI = NULL;
  146. ULONG ul = MMSYSERR_NOERROR;
  147. PSZ pszText;
  148. GET_MULTIMEDIA_API( "midiOutGetErrorTextA", mmAPI, MMSYSERR_NODRIVER );
  149. GETARGPTR(pFrame, sizeof(MIDIOUTGETERRORTEXT16), parg16);
  150. trace_midi(( "midiOutGetErrorText( %x, %x, %x )", UINT32( parg16->f1 ),
  151. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  152. /*
  153. ** Test against a zero length string and a NULL pointer. If 0 is passed
  154. ** as the buffer length then the manual says we should return
  155. ** MMSYSERR_NOERR. MMGETOPTPTR only returns a pointer if parg16->f2 is
  156. ** not NULL.
  157. */
  158. MMGETOPTPTR( parg16->f2, UINT32(parg16->f3), pszText );
  159. if ( pszText != NULL ) {
  160. ul = GETWORD16((*mmAPI)( UINT32(parg16->f1), pszText,
  161. UINT32(parg16->f3) ));
  162. FLUSHVDMPTR(DWORD32(parg16->f2), UINT32(parg16->f3), pszText);
  163. FREEVDMPTR(pszText);
  164. }
  165. trace_midi(( "-> %ld\n", ul ));
  166. FREEARGPTR(parg16);
  167. RETURN(ul);
  168. }
  169. /***********************************************************************\
  170. *
  171. * WMM32midiOutOpen
  172. *
  173. * This function opens a specified MIDI output device for playback.
  174. *
  175. \***********************************************************************/
  176. ULONG FASTCALL WMM32midiOutOpen(PVDMFRAME pFrame)
  177. {
  178. register PMIDIOUTOPEN16 parg16;
  179. static FARPROC mmAPI = NULL;
  180. ULONG ul = MMSYSERR_NOERROR;
  181. UINT uDevID;
  182. PINSTANCEDATA pInstanceData;
  183. LPHMIDIOUT lpHMidiOut; // pointer to handle in 16 bit app space
  184. HMIDIOUT Hand32; // 32bit handle
  185. GET_MULTIMEDIA_API( "midiOutOpen", mmAPI, MMSYSERR_NODRIVER );
  186. GETARGPTR(pFrame, sizeof(MIDIOUTOPEN16), parg16);
  187. trace_midi(( "midiOutOpen( %x, %x, %x, %x, %x )",
  188. DWORD32( parg16->f1 ), INT32 ( parg16->f2 ),
  189. DWORD32( parg16->f3 ), DWORD32( parg16->f4 ),
  190. DWORD32( parg16->f5 ) ));
  191. /*
  192. ** Get the device ID. We use INT32 here not UINT32 to make sure that
  193. ** negative values (such as MIDI_MAPPER (-1)) get thunked correctly.
  194. */
  195. uDevID = (UINT)INT32(parg16->f2);
  196. /*
  197. ** Map the 16 bit pointer is one was specified.
  198. */
  199. MMGETOPTPTR( parg16->f1, sizeof(HMIDIOUT16), lpHMidiOut );
  200. if ( lpHMidiOut ) {
  201. /*
  202. ** Create InstanceData block to be used by our callback routine.
  203. **
  204. ** NOTE: Although we malloc it here we don't free it.
  205. ** This is not a mistake - it must not be freed before the
  206. ** callback routine has used it - so it does the freeing.
  207. **
  208. ** If the malloc fails we bomb down to the bottom,
  209. ** set ul to MMSYSERR_NOMEM and exit gracefully.
  210. **
  211. ** We always have a callback functions. This is to ensure that
  212. ** the MIDIHDR structure keeps getting copied back from
  213. ** 32 bit space to 16 bit, as it contains flags which
  214. ** applications are liable to keep checking.
  215. */
  216. if ( pInstanceData = malloc_w(sizeof(INSTANCEDATA)) ) {
  217. dprintf2(( "WM32midiOutOpen: Allocated instance buffer at %8X",
  218. pInstanceData ));
  219. pInstanceData->dwCallback = DWORD32(parg16->f3);
  220. pInstanceData->dwCallbackInstance = DWORD32(parg16->f4);
  221. pInstanceData->dwFlags = DWORD32(parg16->f5);
  222. ul = GETWORD16((*mmAPI)( &Hand32, uDevID,
  223. (DWORD)W32CommonDeviceOpen,
  224. (DWORD)pInstanceData,
  225. CALLBACK_FUNCTION ));
  226. }
  227. else {
  228. ul = MMSYSERR_NOMEM;
  229. }
  230. /*
  231. ** If the call returns success update the 16 bit handle,
  232. ** otherwise don't, and free the memory we malloc'd earlier, as
  233. ** the callback that would have freed it will never get callled.
  234. */
  235. if ( ul == MMSYSERR_NOERROR ) {
  236. HMIDIOUT16 Hand16 = GETHMIDIOUT16(Hand32);
  237. trace_midi(( "Handle -> %x", Hand16 ));
  238. STOREWORD ( *lpHMidiOut, Hand16 );
  239. FLUSHVDMPTR( DWORD32(parg16->f1), sizeof(HMIDIOUT16),
  240. lpHMidiOut );
  241. }
  242. /*
  243. ** We only free the memory if we actually allocated any
  244. */
  245. else if ( pInstanceData ) {
  246. free_w(pInstanceData);
  247. }
  248. /*
  249. ** Regardless of sucess or failure we need to free the pointer
  250. ** to the 16 bit MidiIn handle.
  251. */
  252. FREEVDMPTR ( lpHMidiOut );
  253. }
  254. else {
  255. ul = MMSYSERR_INVALPARAM;
  256. }
  257. trace_midi(( "-> %ld\n", ul ));
  258. FREEARGPTR(parg16);
  259. RETURN(ul);
  260. }
  261. /**********************************************************************\
  262. *
  263. * WMM32midiOutClose
  264. *
  265. * This function closes the specified MIDI output device.
  266. *
  267. \**********************************************************************/
  268. ULONG FASTCALL WMM32midiOutClose(PVDMFRAME pFrame)
  269. {
  270. register PMIDIOUTCLOSE16 parg16;
  271. static FARPROC mmAPI = NULL;
  272. ULONG ul;
  273. GET_MULTIMEDIA_API( "midiOutClose", mmAPI, MMSYSERR_NODRIVER );
  274. GETARGPTR(pFrame, sizeof(MIDIOUTCLOSE16), parg16);
  275. trace_midi(( "midiOutClose( %x )", WORD32( parg16->f1 ) ));
  276. ul = GETWORD16( (*mmAPI)(HMIDIOUT32(parg16->f1) ));
  277. trace_midi(( "-> %ld\n", ul ));
  278. FREEARGPTR(parg16);
  279. RETURN(ul);
  280. }
  281. /**********************************************************************\
  282. *
  283. * WMM32midiOutPrepareHeader
  284. *
  285. * This function prepares the specified midiform header.
  286. *
  287. \**********************************************************************/
  288. ULONG FASTCALL WMM32midiOutPrepareHeader(PVDMFRAME pFrame)
  289. {
  290. register PMIDIOUTPREPAREHEADER3216 parg16;
  291. static FARPROC mmAPI = NULL;
  292. ULONG ul;
  293. MIDIHDR midihdr;
  294. GET_MULTIMEDIA_API( "midiOutPrepareHeader", mmAPI, MMSYSERR_NODRIVER );
  295. GETARGPTR(pFrame, sizeof(MIDIOUTPREPAREHEADER3216), parg16);
  296. trace_midi(( "midiOutPrepareHeader( %x %x %x)", WORD32( parg16->f1 ),
  297. DWORD32( parg16->f2 ), WORD32( parg16->f3 ) ));
  298. GETMIDIHDR16(parg16->f2, &midihdr);
  299. ul = GETWORD16((*mmAPI)( HMIDIOUT32(parg16->f1),
  300. &midihdr, WORD32(parg16->f3) ) );
  301. /*
  302. ** Only update the 16 bit structure if the call returns success
  303. **
  304. */
  305. if ( !ul ) {
  306. PUTMIDIHDR16(parg16->f2, &midihdr);
  307. }
  308. trace_midi(( "-> %ld\n", ul ));
  309. FREEARGPTR(parg16);
  310. RETURN(ul);
  311. }
  312. /**********************************************************************\
  313. *
  314. * WMM32midiOutUnprepareHeader
  315. *
  316. * This function prepares the specified midiform header.
  317. * This function cleans up the preparation performed by midiOutPrepareHeader.
  318. * The function must be called after the device driver has finished with a
  319. * data block. You must call this function before freeing the data buffer.
  320. *
  321. \**********************************************************************/
  322. ULONG FASTCALL WMM32midiOutUnprepareHeader(PVDMFRAME pFrame)
  323. {
  324. register PMIDIOUTUNPREPAREHEADER3216 parg16;
  325. static FARPROC mmAPI = NULL;
  326. ULONG ul;
  327. MIDIHDR midihdr;
  328. GET_MULTIMEDIA_API( "midiOutUnprepareHeader", mmAPI, MMSYSERR_NODRIVER );
  329. GETARGPTR(pFrame, sizeof(MIDIOUTUNPREPAREHEADER3216), parg16);
  330. trace_midi(( "midiOutUnprepareHeader( %x %x %x)", WORD32( parg16->f1 ),
  331. DWORD32( parg16->f2 ), WORD32( parg16->f3 ) ));
  332. GETMIDIHDR16(parg16->f2, &midihdr);
  333. ul = GETWORD16((*mmAPI)( HMIDIOUT32(parg16->f1),
  334. &midihdr, WORD32(parg16->f3) ) );
  335. /*
  336. ** Only update the 16 bit structure if the call returns success
  337. */
  338. if (!ul) {
  339. PUTMIDIHDR16(parg16->f2, &midihdr);
  340. }
  341. trace_midi(( "-> %ld\n", ul ));
  342. FREEARGPTR(parg16);
  343. RETURN(ul);
  344. }
  345. /**********************************************************************\
  346. *
  347. * WMM32midiOutShortMsg
  348. *
  349. * This function sends a short MIDI message to the specified MIDI output device.
  350. * Use this function to send any MIDI message except for system exclusive
  351. * messages.
  352. *
  353. \**********************************************************************/
  354. ULONG FASTCALL WMM32midiOutShortMsg(PVDMFRAME pFrame)
  355. {
  356. register PMIDIOUTSHORTMSG16 parg16;
  357. static FARPROC mmAPI = NULL;
  358. ULONG ul;
  359. GET_MULTIMEDIA_API( "midiOutShortMsg", mmAPI, MMSYSERR_NODRIVER );
  360. GETARGPTR(pFrame, sizeof(MIDIOUTSHORTMSG16), parg16);
  361. trace_midi(( "midiOutShortMsg( %x, %x )", WORD32( parg16->f1 ),
  362. DWORD32( parg16->f2 ) ));
  363. ul = GETWORD16((*mmAPI)( HMIDIOUT32(parg16->f1), DWORD32(parg16->f2) ));
  364. trace_midi(( "-> %ld\n", ul ));
  365. FREEARGPTR(parg16);
  366. RETURN(ul);
  367. }
  368. /**********************************************************************\
  369. *
  370. * WMM32midiOutLongMsg
  371. *
  372. * This function sends a long MIDI message to the specified MIDI output
  373. * device. Use this function to send system exclusive messages or to
  374. * send a buffer filled with short messages.
  375. *
  376. \**********************************************************************/
  377. ULONG FASTCALL WMM32midiOutLongMsg(PVDMFRAME pFrame)
  378. {
  379. register PMIDIOUTLONGMSG16 parg16;
  380. static FARPROC mmAPI = NULL;
  381. ULONG ul;
  382. PMIDIHDR32 pMidihdr32;
  383. GET_MULTIMEDIA_API( "midiOutLongMsg", mmAPI, MMSYSERR_NODRIVER );
  384. GETARGPTR(pFrame, sizeof(MIDIOUTLONGMSG16), parg16);
  385. trace_midi(( "midiOutLongMsg( %x, %x, %x )", WORD32( parg16->f1 ),
  386. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  387. /*
  388. ** If the given size of the MIDIHDR structure is too small
  389. ** or the lphdr is invalid return an error
  390. **
  391. */
  392. if ( UINT32(parg16->f3) < sizeof(MIDIHDR16)
  393. || HIWORD( DWORD32(parg16->f2) ) == 0 ) {
  394. ul = MMSYSERR_INVALPARAM;
  395. }
  396. else {
  397. if ( pMidihdr32 = malloc_w(sizeof(MIDIHDR32)) ) {
  398. PMIDIHDR lpwhdr;
  399. #if DBG
  400. AllocMidiCount++;
  401. dprintf2(( "M>> %8X (%d)", pMidihdr32, AllocMidiCount ));
  402. #endif
  403. /* Copy across the midi header stuff. Note that lpwhdr (a
  404. ** 32 bit ptr to a 32 bit midi header) is used to make the
  405. ** pointer stuff a bit less hairy.
  406. **
  407. ** pMidihdr32->pMidihdr32 is a 32 bit ptr to a 16 bit midi header
  408. ** pMidihdr32->pMidihdr16 is a 16 bit ptr to a 16 bit midi header
  409. ** pMidihdr32->Midihdr is a 32 bit midi header
  410. */
  411. lpwhdr = &(pMidihdr32->Midihdr);
  412. pMidihdr32->pMidihdr16 = (PMIDIHDR16)DWORD32(parg16->f2);
  413. pMidihdr32->pMidihdr32 = GETMIDIHDR16(DWORD32(parg16->f2), lpwhdr);
  414. /*
  415. ** GETMIDIHDR16 can return NULL, in which case we should set
  416. ** lpwhdr to NULL too and call midiOutLongMessage only to get the
  417. ** correct error code.
  418. */
  419. if ( pMidihdr32->pMidihdr32 == NULL ) {
  420. lpwhdr = NULL;
  421. }
  422. ul = GETWORD16( (*mmAPI)( HMIDIOUT32(parg16->f1), lpwhdr,
  423. UINT32(parg16->f3) ) );
  424. /*
  425. ** If the call fails we need to free the memory we malloc'd
  426. ** above, as the callback that would have freed it will never
  427. ** get called.
  428. **
  429. */
  430. if ( ul == MMSYSERR_NOERROR ) {
  431. /*
  432. ** Make sure we reflect any changes that midiOutLongMessage did
  433. ** to the MIDIHDR back to 16 bit land.
  434. **
  435. ** This is important because some apps poll the
  436. ** MHDR_DONE bit !!
  437. */
  438. COPY_MIDIOUTHDR16_FLAGS( pMidihdr32->pMidihdr32,
  439. pMidihdr32->Midihdr );
  440. }
  441. else {
  442. #if DBG
  443. AllocMidiCount--;
  444. dprintf2(( "M<< \t%8X (%d)", pMidihdr32,
  445. AllocMidiCount ));
  446. #endif
  447. free_w( pMidihdr32 );
  448. }
  449. }
  450. else {
  451. ul = MMSYSERR_NOMEM;
  452. }
  453. }
  454. trace_midi(( "-> %ld\n", ul ));
  455. FREEARGPTR(parg16);
  456. RETURN(ul);
  457. }
  458. /**********************************************************************\
  459. *
  460. * WMM32midiOutReset
  461. *
  462. * This function turns off all notes on al MIDI channels for the specified
  463. * MIDI output deice.
  464. *
  465. \**********************************************************************/
  466. ULONG FASTCALL WMM32midiOutReset(PVDMFRAME pFrame)
  467. {
  468. register PMIDIOUTRESET16 parg16;
  469. static FARPROC mmAPI = NULL;
  470. ULONG ul;
  471. GET_MULTIMEDIA_API( "midiOutReset", mmAPI, MMSYSERR_NODRIVER );
  472. GETARGPTR(pFrame, sizeof(MIDIOUTRESET16), parg16);
  473. trace_midi(( "midiOutReset( %x )", WORD32( parg16->f1 ) ));
  474. ul = GETWORD16((*mmAPI)( HMIDIOUT32(parg16->f1) ));
  475. trace_midi(( "-> %ld\n", ul ));
  476. FREEARGPTR(parg16);
  477. RETURN(ul);
  478. }
  479. /**********************************************************************\
  480. *
  481. * WMM32midiOutGetVolume
  482. *
  483. * This function returns the current volume setting of a MIDI output device.
  484. *
  485. \**********************************************************************/
  486. ULONG FASTCALL WMM32midiOutGetVolume(PVDMFRAME pFrame)
  487. {
  488. register PMIDIOUTGETVOLUME16 parg16;
  489. static FARPROC mmAPI = NULL;
  490. ULONG ul;
  491. LPDWORD lpdwVolume;
  492. DWORD dwVolume;
  493. GET_MULTIMEDIA_API( "midiOutGetVolume", mmAPI, MMSYSERR_NODRIVER );
  494. GETARGPTR(pFrame, sizeof(MIDIOUTGETVOLUME16), parg16);
  495. trace_midi(( "midiOutGetVolume( %x, %x )", INT32( parg16->f1 ),
  496. DWORD32( parg16->f2 ) ));
  497. ul = GETWORD16((*mmAPI)( INT32(parg16->f1), &dwVolume ));
  498. if ( ul == MMSYSERR_NOERROR ) {
  499. MMGETOPTPTR( parg16->f2, sizeof(DWORD), lpdwVolume);
  500. if ( lpdwVolume ) {
  501. STOREDWORD ( *lpdwVolume, dwVolume );
  502. FLUSHVDMPTR( DWORD32(parg16->f2), sizeof(DWORD), lpdwVolume );
  503. FREEVDMPTR ( lpdwVolume );
  504. }
  505. else {
  506. ul = MMSYSERR_INVALPARAM;
  507. }
  508. }
  509. trace_midi(( "-> %ld\n", ul ));
  510. FREEARGPTR(parg16);
  511. RETURN(ul);
  512. }
  513. /**********************************************************************\
  514. *
  515. * WMM32midiOutSetVolume
  516. *
  517. * This function sets the volume of a MIDI output device.
  518. *
  519. \**********************************************************************/
  520. ULONG FASTCALL WMM32midiOutSetVolume(PVDMFRAME pFrame)
  521. {
  522. register PMIDIOUTSETVOLUME16 parg16;
  523. static FARPROC mmAPI = NULL;
  524. ULONG ul;
  525. GET_MULTIMEDIA_API( "midiOutSetVolume", mmAPI, MMSYSERR_NODRIVER );
  526. GETARGPTR(pFrame, sizeof(MIDIOUTSETVOLUME16), parg16);
  527. trace_midi(( "midiOutSetVolume( %x, %x )", WORD32( parg16->f1 ),
  528. DWORD32( parg16->f2 ) ));
  529. ul = GETWORD16((*mmAPI)( INT32(parg16->f1), DWORD32(parg16->f2) ));
  530. trace_midi(( "-> %ld\n", ul ));
  531. FREEARGPTR(parg16);
  532. RETURN(ul);
  533. }
  534. /**********************************************************************\
  535. *
  536. * WMM32midiOutCachePatches
  537. *
  538. * This function requests that an internal MIDI synthesizer device preload a
  539. * specified set of patches. Some synthesizers are not capable of keeping all
  540. * patches loaded simultaneously and must load data from disk when they receive
  541. * MIDI program change messages. Caching patches ensures specified patches are
  542. * immediately available.
  543. *
  544. \**********************************************************************/
  545. ULONG FASTCALL WMM32midiOutCachePatches(PVDMFRAME pFrame)
  546. {
  547. register PMIDIOUTCACHEPATCHES16 parg16;
  548. static FARPROC mmAPI = NULL;
  549. ULONG ul = MMSYSERR_INVALPARAM;
  550. LPPATCHARRAY lppa1;
  551. GET_MULTIMEDIA_API( "midiOutCachePatches", mmAPI, MMSYSERR_NODRIVER );
  552. GETARGPTR(pFrame, sizeof(MIDIOUTCACHEPATCHES16), parg16);
  553. trace_midi(( "midiOutCachePatches( %x, %x, %x, %x )", WORD32( parg16->f1 ),
  554. UINT32( parg16->f2 ), DWORD32( parg16->f3 ),
  555. UINT32( parg16->f4 ) ));
  556. /*
  557. ** GETMISCPTR checks that parg16->f3 is not zero so we need not bother.
  558. */
  559. GETMISCPTR( DWORD32( parg16->f3 ), lppa1 );
  560. if ( lppa1 ) {
  561. ul = GETWORD16((*mmAPI)( HMIDIOUT32(parg16->f1), UINT32(parg16->f2),
  562. lppa1, UINT32(parg16->f4) ));
  563. FREEMISCPTR( lppa1 );
  564. }
  565. else {
  566. dprintf1(( "WMM32midiOutCachePatches passed a NULL pointer" ));
  567. }
  568. trace_midi(( "-> %ld\n", ul ));
  569. FREEARGPTR(parg16);
  570. RETURN(ul);
  571. }
  572. /**********************************************************************\
  573. *
  574. * WMM32midiOutCacheDrumPatches
  575. *
  576. * This function requests that an internal MIDI synthesizer device preload a
  577. * specified set of key-based percussion patches. Some synthesizers are not
  578. * capable of keeping all percussion patches loaded simultaneously. Caching
  579. * patches ensures specified patches are immediately available.
  580. *
  581. \**********************************************************************/
  582. ULONG FASTCALL WMM32midiOutCacheDrumPatches(PVDMFRAME pFrame)
  583. {
  584. register PMIDIOUTCACHEDRUMPATCHES16 parg16;
  585. static FARPROC mmAPI = NULL;
  586. ULONG ul = MMSYSERR_INVALPARAM;
  587. LPKEYARRAY lpka1;
  588. GET_MULTIMEDIA_API( "midiOutCacheDrumPatches", mmAPI, MMSYSERR_NODRIVER );
  589. GETARGPTR(pFrame, sizeof(MIDIOUTCACHEDRUMPATCHES16), parg16);
  590. trace_midi(( "midiOutCacheDrumPatches( %x, %x, %x, %x )",
  591. WORD32( parg16->f1 ), UINT32( parg16->f2 ),
  592. DWORD32( parg16->f3 ), UINT32( parg16->f4 ) ));
  593. GETMISCPTR( DWORD32( parg16->f3 ), lpka1 );
  594. if ( lpka1 ) {
  595. ul = GETWORD16((*mmAPI)( HMIDIOUT32(parg16->f1), UINT32(parg16->f2),
  596. lpka1, UINT32(parg16->f4) ) );
  597. FREEMISCPTR(lpka1);
  598. }
  599. else {
  600. dprintf1(( "WMM32midiOutCacheDrumPatches passed a NULL pointer" ));
  601. }
  602. trace_midi(( "-> %ld\n", ul ));
  603. FREEARGPTR(parg16);
  604. RETURN(ul);
  605. }
  606. /**********************************************************************\
  607. *
  608. * WMM32midiOutGetID
  609. *
  610. * This function gets the device ID for a MIDI output device.
  611. *
  612. \**********************************************************************/
  613. ULONG FASTCALL WMM32midiOutGetID(PVDMFRAME pFrame)
  614. {
  615. register PMIDIOUTGETID16 parg16;
  616. static FARPROC mmAPI = NULL;
  617. ULONG ul;
  618. UINT dwDeviceID32;
  619. LPWORD lpwDeviceID16;
  620. GET_MULTIMEDIA_API( "midiOutGetID", mmAPI, MMSYSERR_NODRIVER );
  621. GETARGPTR(pFrame, sizeof(MIDIOUTGETID16), parg16);
  622. trace_midi(( "midiOutGetID( %x, %x )", WORD32( parg16->f1 ),
  623. DWORD32( parg16->f2 ) ));
  624. ul = GETWORD16((*mmAPI)( (HMIDIOUT)HMIDIOUT32(parg16->f1), &dwDeviceID32 ));
  625. /*
  626. ** Only copy the ID back to 16 bit space if the call was sucessful
  627. **
  628. */
  629. if ( ul == MMSYSERR_NOERROR ) {
  630. MMGETOPTPTR( parg16->f2, sizeof(WORD), lpwDeviceID16 );
  631. if ( lpwDeviceID16 ) {
  632. STOREWORD ( *lpwDeviceID16, dwDeviceID32 );
  633. FLUSHVDMPTR( DWORD32(parg16->f2), sizeof(WORD), lpwDeviceID16 );
  634. FREEVDMPTR ( lpwDeviceID16 );
  635. }
  636. else {
  637. ul = MMSYSERR_INVALPARAM;
  638. }
  639. }
  640. trace_midi(( "-> %ld\n", ul ));
  641. FREEARGPTR(parg16);
  642. RETURN(ul);
  643. }
  644. /**********************************************************************\
  645. *
  646. * WMM32midiOutMessage
  647. *
  648. * This function sends a message to the specified MIDI output device.
  649. *
  650. \**********************************************************************/
  651. ULONG FASTCALL WMM32midiOutMessage(PVDMFRAME pFrame)
  652. {
  653. register PMIDIOUTMESSAGE3216 parg16;
  654. static FARPROC mmAPI = NULL;
  655. ULONG ul;
  656. GET_MULTIMEDIA_API( "midiOutMessage", mmAPI, MMSYSERR_NODRIVER );
  657. GETARGPTR(pFrame, sizeof(MIDIOUTMESSAGE16), parg16);
  658. trace_midi(( "midiOutMessage( %x, %x, %x, %x )",
  659. WORD32( parg16->f1 ), UINT32( parg16->f2 ),
  660. DWORD32( parg16->f3 ), DWORD32( parg16->f4 ) ));
  661. if ( (UINT32(parg16->f2) >= DRV_BUFFER_LOW)
  662. && (UINT32(parg16->f2) <= DRV_BUFFER_HIGH) ) {
  663. LPDWORD lpdwParam1;
  664. GETMISCPTR(parg16->f3, lpdwParam1);
  665. ul = GETDWORD16((*mmAPI)( HMIDIOUT32(parg16->f1), UINT32(parg16->f2),
  666. (DWORD)lpdwParam1, DWORD32(parg16->f4)));
  667. FREEMISCPTR(lpdwParam1);
  668. } else {
  669. ul = GETDWORD16((*mmAPI)( HMIDIOUT32(parg16->f1),
  670. MAKELONG( WORD32(parg16->f2), 0xFFFF ),
  671. DWORD32(parg16->f3), DWORD32(parg16->f4) ));
  672. }
  673. trace_midi(( "-> %ld\n", ul ));
  674. FREEARGPTR(parg16);
  675. RETURN(ul);
  676. }
  677. /* ---------------------------------------------------------------------
  678. ** MIDI Input API's
  679. ** ---------------------------------------------------------------------
  680. */
  681. /**********************************************************************\
  682. *
  683. * WMM32midiInGetNumDevs
  684. *
  685. * This function retrieves the number of MIDI input devices in the system.
  686. *
  687. \**********************************************************************/
  688. ULONG FASTCALL WMM32midiInGetNumDevs(PVDMFRAME pFrame)
  689. {
  690. static FARPROC mmAPI = NULL;
  691. ULONG ul;
  692. GET_MULTIMEDIA_API( "midiInGetNumDevs", mmAPI, MMSYSERR_NODRIVER );
  693. UNREFERENCED_PARAMETER(pFrame);
  694. trace_midi(( "midiInGetNumDevs()" ));
  695. ul = GETWORD16((*mmAPI)() );
  696. trace_midi(( "-> %ld\n", ul ));
  697. RETURN(ul);
  698. }
  699. /**********************************************************************\
  700. *
  701. * WMM32midiInGetDevCaps
  702. *
  703. * This function queries a specified MIDI input device to determine its
  704. * capabilities.
  705. *
  706. \**********************************************************************/
  707. ULONG FASTCALL WMM32midiInGetDevCaps(PVDMFRAME pFrame)
  708. {
  709. ULONG ul;
  710. MIDIINCAPS midiincaps1;
  711. register PMIDIINGETDEVCAPS16 parg16;
  712. static FARPROC mmAPI = NULL;
  713. GET_MULTIMEDIA_API( "midiInGetDevCapsA", mmAPI, MMSYSERR_NODRIVER );
  714. GETARGPTR(pFrame, sizeof(MIDIINGETDEVCAPS16), parg16);
  715. trace_midi(( "midiInGetDevCaps( %x, %x, %x )", INT32( parg16->f1 ),
  716. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  717. if ( UINT32( parg16->f3 ) == 0 ) {
  718. ul = MMSYSERR_NOERROR;
  719. }
  720. else {
  721. ul = GETWORD16((*mmAPI)(INT32(parg16->f1), &midiincaps1,
  722. sizeof(MIDIINCAPS) ) );
  723. /*
  724. ** This must now thunk the ENTIRE structure, then copy parg16->f3
  725. ** bytes onto the "real" structure in the app, but only if the
  726. ** call returned success.
  727. */
  728. if ( ul == MMSYSERR_NOERROR ) {
  729. ul = PUTMIDIINCAPS16( parg16->f2, &midiincaps1, UINT32(parg16->f3) );
  730. }
  731. }
  732. trace_midi(( "-> %ld\n", ul ));
  733. FREEARGPTR(parg16);
  734. RETURN(ul);
  735. }
  736. /**********************************************************************\
  737. *
  738. * WMM32midiInGetErrorText
  739. *
  740. * This function retrieves a textual description of the error identified by the
  741. * specified error number.
  742. *
  743. \**********************************************************************/
  744. ULONG FASTCALL WMM32midiInGetErrorText(PVDMFRAME pFrame)
  745. {
  746. register PMIDIINGETERRORTEXT16 parg16;
  747. ULONG ul = MMSYSERR_NOERROR;
  748. PSZ pszText;
  749. static FARPROC mmAPI = NULL;
  750. GET_MULTIMEDIA_API( "midiInGetErrorTextA", mmAPI, MMSYSERR_NODRIVER );
  751. GETARGPTR( pFrame, sizeof(MIDIINGETERRORTEXT16), parg16 );
  752. trace_midi(( "midiInGetErrorText( %x, %x, %x )", UINT32( parg16->f1 ),
  753. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  754. /*
  755. ** Test against a zero length string and a NULL pointer. If 0 is passed
  756. ** as the buffer length then the manual says we should return
  757. ** MMSYSERR_NOERR.
  758. */
  759. MMGETOPTPTR( parg16->f2, UINT32(parg16->f3), pszText );
  760. if ( pszText != NULL ) {
  761. ul = GETWORD16( (*mmAPI)( UINT32(parg16->f1), pszText,
  762. UINT32(parg16->f3) ) );
  763. FLUSHVDMPTR( DWORD32(parg16->f2), UINT32(parg16->f3), pszText);
  764. FREEVDMPTR( pszText );
  765. }
  766. trace_midi(( "-> %ld\n", ul ));
  767. FREEARGPTR(parg16);
  768. RETURN(ul);
  769. }
  770. /**********************************************************************\
  771. *
  772. * WMM32midiInOpen
  773. *
  774. * This function opens a specified MIDI input device.
  775. *
  776. \***********************************************************************/
  777. ULONG FASTCALL WMM32midiInOpen(PVDMFRAME pFrame)
  778. {
  779. ULONG ul=0;
  780. UINT uDevID;
  781. PINSTANCEDATA pInstanceData;
  782. LPHMIDIIN lpHMidiIn; // pointer to handle in 16 bit app space
  783. HMIDIIN Hand32; // 32bit handle
  784. register PMIDIINOPEN16 parg16;
  785. static FARPROC mmAPI = NULL;
  786. GET_MULTIMEDIA_API( "midiInOpen", mmAPI, MMSYSERR_NODRIVER );
  787. GETARGPTR(pFrame, sizeof(MIDIINOPEN16), parg16);
  788. trace_midi(( "midiInOpen( %x, %x, %x, %x, %x )",
  789. DWORD32( parg16->f1 ), INT32 ( parg16->f2 ),
  790. DWORD32( parg16->f3 ), DWORD32( parg16->f4 ),
  791. DWORD32( parg16->f5 ) ));
  792. /*
  793. ** Get the device ID. We use INT32 here not UINT32 to make sure that
  794. ** negative values (such as MIDI_MAPPER (-1)) get thunked correctly.
  795. */
  796. uDevID = (UINT)INT32(parg16->f2);
  797. /*
  798. ** Map the 16 bit pointer is one was specified.
  799. */
  800. MMGETOPTPTR( parg16->f1, sizeof(HMIDIIN), lpHMidiIn );
  801. if ( lpHMidiIn ) {
  802. /*
  803. ** Create InstanceData block to be used by our callback routine.
  804. **
  805. ** NOTE: Although we malloc it here we don't free it.
  806. ** This is not a mistake - it must not be freed before the
  807. ** callback routine has used it - so it does the freeing.
  808. **
  809. ** If the malloc fails we bomb down to the bottom,
  810. ** set ul to MMSYSERR_NOMEM and exit gracefully.
  811. **
  812. ** We always have a callback functions. This is to ensure that
  813. ** the MIDIHDR structure keeps getting copied back from
  814. ** 32 bit space to 16 bit, as it contains flags which
  815. ** applications are liable to keep checking.
  816. */
  817. if ( pInstanceData = malloc_w(sizeof(INSTANCEDATA) ) ) {
  818. dprintf2(( "WM32midiInOpen: Allocated instance buffer at %8X",
  819. pInstanceData ));
  820. pInstanceData->dwCallback = DWORD32(parg16->f3);
  821. pInstanceData->dwCallbackInstance = DWORD32(parg16->f4);
  822. pInstanceData->dwFlags = DWORD32(parg16->f5);
  823. ul = GETWORD16((*mmAPI)( &Hand32, uDevID,
  824. (DWORD)W32CommonDeviceOpen,
  825. (DWORD)pInstanceData,
  826. CALLBACK_FUNCTION ));
  827. }
  828. else {
  829. ul = (ULONG)MMSYSERR_NOMEM;
  830. }
  831. /*
  832. ** If the call returns success update the 16 bit handle,
  833. ** otherwise don't, and free the memory we malloc'd earlier, as
  834. ** the callback that would have freed it will never get callled.
  835. */
  836. if ( ul == MMSYSERR_NOERROR ) {
  837. HMIDIIN16 Hand16 = GETHMIDIIN16(Hand32);
  838. trace_midi(( "Handle -> %x", Hand16 ));
  839. STOREWORD ( *lpHMidiIn, Hand16 );
  840. FLUSHVDMPTR( DWORD32(parg16->f1), sizeof(HMIDIIN), lpHMidiIn );
  841. }
  842. /*
  843. ** We only free the memory if we actually allocated any and the
  844. ** 32 bit call failed.
  845. */
  846. else if ( pInstanceData ) {
  847. free_w(pInstanceData);
  848. }
  849. /*
  850. ** Regardless of sucess or failure we need to free the pointer
  851. ** to the 16 bit MidiIn handle.
  852. */
  853. FREEVDMPTR ( lpHMidiIn );
  854. }
  855. else {
  856. ul = MMSYSERR_INVALPARAM;
  857. }
  858. trace_midi(( "-> %ld\n", ul ));
  859. FREEARGPTR(parg16);
  860. RETURN(ul);
  861. }
  862. /**********************************************************************\
  863. *
  864. * WMM32midiInClose
  865. *
  866. * This function closes the specified MIDI input device.
  867. *
  868. \**********************************************************************/
  869. ULONG FASTCALL WMM32midiInClose(PVDMFRAME pFrame)
  870. {
  871. ULONG ul;
  872. register PMIDIINCLOSE16 parg16;
  873. static FARPROC mmAPI = NULL;
  874. GET_MULTIMEDIA_API( "midiInClose", mmAPI, MMSYSERR_NODRIVER );
  875. GETARGPTR(pFrame, sizeof(MIDIINCLOSE16), parg16);
  876. trace_midi(( "midiInClose( %x )", WORD32( parg16->f1 ) ));
  877. ul = GETWORD16((*mmAPI)(HMIDIIN32(parg16->f1) ) );
  878. trace_midi(( "-> %ld\n", ul ));
  879. FREEARGPTR(parg16);
  880. RETURN(ul);
  881. }
  882. /**********************************************************************\
  883. *
  884. * WMM32midiInPrepareHeader
  885. *
  886. * This function prepares the specified midiform header.
  887. *
  888. \**********************************************************************/
  889. ULONG FASTCALL WMM32midiInPrepareHeader(PVDMFRAME pFrame)
  890. {
  891. register PMIDIOUTPREPAREHEADER3216 parg16;
  892. static FARPROC mmAPI = NULL;
  893. ULONG ul;
  894. MIDIHDR midihdr;
  895. GET_MULTIMEDIA_API( "midiInPrepareHeader", mmAPI, MMSYSERR_NODRIVER );
  896. GETARGPTR(pFrame, sizeof(MIDIOUTPREPAREHEADER3216), parg16);
  897. trace_midi(( "midiInPrepareHeader( %x %x %x)", WORD32( parg16->f1 ),
  898. DWORD32( parg16->f2 ), WORD32( parg16->f3 ) ));
  899. GETMIDIHDR16(parg16->f2, &midihdr);
  900. ul = GETWORD16((*mmAPI)( HMIDIOUT32(parg16->f1),
  901. &midihdr, WORD32(parg16->f3) ) );
  902. /*
  903. ** Only update the 16 bit structure if the call returns success
  904. **
  905. */
  906. if ( !ul ) {
  907. PUTMIDIHDR16(parg16->f2, &midihdr);
  908. }
  909. trace_midi(( "-> %ld\n", ul ));
  910. FREEARGPTR(parg16);
  911. RETURN(ul);
  912. }
  913. /**********************************************************************\
  914. *
  915. * WMM32midiInUnprepareHeader
  916. *
  917. * This function prepares the specified midiform header.
  918. * This function cleans up the preparation performed by midiInPrepareHeader.
  919. * The function must be called after the device driver has finished with a
  920. * data block. You must call this function before freeing the data buffer.
  921. *
  922. \**********************************************************************/
  923. ULONG FASTCALL WMM32midiInUnprepareHeader(PVDMFRAME pFrame)
  924. {
  925. register PMIDIOUTUNPREPAREHEADER3216 parg16;
  926. static FARPROC mmAPI = NULL;
  927. ULONG ul;
  928. MIDIHDR midihdr;
  929. GET_MULTIMEDIA_API( "midiInUnprepareHeader", mmAPI, MMSYSERR_NODRIVER );
  930. GETARGPTR(pFrame, sizeof(MIDIOUTUNPREPAREHEADER3216), parg16);
  931. trace_midi(( "midiInUnprepareHeader( %x %x %x)", WORD32( parg16->f1 ),
  932. DWORD32( parg16->f2 ), WORD32( parg16->f3 ) ));
  933. GETMIDIHDR16(parg16->f2, &midihdr);
  934. ul = GETWORD16((*mmAPI)( HMIDIOUT32(parg16->f1),
  935. &midihdr, WORD32(parg16->f3) ) );
  936. /*
  937. ** Only update the 16 bit structure if the call returns success
  938. */
  939. if (!ul) {
  940. PUTMIDIHDR16(parg16->f2, &midihdr);
  941. }
  942. trace_midi(( "-> %ld\n", ul ));
  943. FREEARGPTR(parg16);
  944. RETURN(ul);
  945. }
  946. /**********************************************************************\
  947. *
  948. * WMM32midiInAddBuffer
  949. *
  950. * This function sends an input buffer to a specified opened MIDI input device.
  951. * When the buffer is filled, it is sent back to the application. Input buffers
  952. * are used only for system exclusive messages.
  953. *
  954. \**********************************************************************/
  955. ULONG FASTCALL WMM32midiInAddBuffer(PVDMFRAME pFrame)
  956. {
  957. ULONG ul;
  958. PMIDIHDR32 pMidihdr32;
  959. register PMIDIINADDBUFFER16 parg16;
  960. static FARPROC mmAPI = NULL;
  961. GET_MULTIMEDIA_API( "midiInAddBuffer", mmAPI, MMSYSERR_NODRIVER );
  962. GETARGPTR(pFrame, sizeof(MIDIINADDBUFFER16), parg16);
  963. trace_midi(( "midiInAddBuffer( %x, %x, %x )", WORD32( parg16->f1 ),
  964. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  965. /*
  966. ** If the given size of the MIDIHDR structure is too small
  967. ** or the lphdr is invalid return an error
  968. **
  969. */
  970. if ( UINT32(parg16->f3) < sizeof(MIDIHDR16)
  971. || HIWORD( DWORD32(parg16->f2) ) == 0 ) {
  972. ul = (ULONG)MMSYSERR_INVALPARAM;
  973. }
  974. else {
  975. if (pMidihdr32 = malloc_w(sizeof(MIDIHDR32) ) ) {
  976. PMIDIHDR lpwhdr;
  977. #if DBG
  978. AllocMidiCount++;
  979. dprintf2(( "M>> %8X (%d)", pMidihdr32, AllocMidiCount ));
  980. #endif
  981. /* Copy across the midi header stuff. Note that lpwhdr (a
  982. ** 32 bit ptr to a 32 bit midi header) is used to make the
  983. ** pointer stuff a bit less hairy.
  984. **
  985. ** pMidihdr32->Midihdr is a 32 bit midi header
  986. ** pMidihdr32->pMidihdr16 is a 16 bit ptr to a 16 bit midi header
  987. ** pMidihdr32->pMidihdr32 is a 32 bit ptr to a 16 bit midi header
  988. */
  989. lpwhdr = &(pMidihdr32->Midihdr);
  990. pMidihdr32->pMidihdr16 = (PMIDIHDR16)DWORD32(parg16->f2);
  991. pMidihdr32->pMidihdr32 = GETMIDIHDR16(DWORD32(parg16->f2), lpwhdr);
  992. /*
  993. ** GETMIDIHDR16 can return NULL, in which case we should set
  994. ** lpwhdr to NULL too and call midiInAddBuffer only to get the
  995. ** correct error code.
  996. */
  997. if ( pMidihdr32->pMidihdr32 == NULL ) {
  998. lpwhdr = NULL;
  999. }
  1000. ul = GETWORD16((*mmAPI)( HMIDIIN32(parg16->f1), lpwhdr,
  1001. UINT32(parg16->f3) ));
  1002. /*
  1003. ** If the call fails we need to free the memory we malloc'd
  1004. ** above, as the callback that would have freed it will never
  1005. ** get called.
  1006. **
  1007. */
  1008. if ( ul == MMSYSERR_NOERROR ) {
  1009. /*
  1010. ** Make sure we reflect any changes that midiInAddBuffer did
  1011. ** to the MIDIHDR back to 16 bit land.
  1012. **
  1013. ** This is important because some apps poll the
  1014. ** MHDR_DONE bit !!
  1015. */
  1016. COPY_MIDIINHDR16_FLAGS( pMidihdr32->pMidihdr32,
  1017. pMidihdr32->Midihdr );
  1018. }
  1019. else {
  1020. #if DBG
  1021. AllocMidiCount--;
  1022. dprintf2(( "M<< \t%8X (%d)", pMidihdr32,
  1023. AllocMidiCount ));
  1024. #endif
  1025. free_w( pMidihdr32 );
  1026. }
  1027. }
  1028. else {
  1029. ul = (ULONG)MMSYSERR_NOMEM;
  1030. }
  1031. }
  1032. trace_midi(( "-> %ld\n", ul ));
  1033. FREEARGPTR(parg16);
  1034. RETURN(ul);
  1035. }
  1036. /**********************************************************************\
  1037. *
  1038. * WMM32midiInStart
  1039. *
  1040. * This function starts MIDI input on the specified MIDI input device.
  1041. *
  1042. \**********************************************************************/
  1043. ULONG FASTCALL WMM32midiInStart(PVDMFRAME pFrame)
  1044. {
  1045. ULONG ul;
  1046. register PMIDIINSTART16 parg16;
  1047. static FARPROC mmAPI = NULL;
  1048. GET_MULTIMEDIA_API( "midiInStart", mmAPI, MMSYSERR_NODRIVER );
  1049. GETARGPTR(pFrame, sizeof(MIDIINSTART16), parg16);
  1050. trace_midi(( "midiInStart( %x )", WORD32( parg16->f1 ) ));
  1051. ul = GETWORD16((*mmAPI)(HMIDIIN32(parg16->f1) ) );
  1052. trace_midi(( "-> %ld\n", ul ));
  1053. FREEARGPTR(parg16);
  1054. RETURN(ul);
  1055. }
  1056. /**********************************************************************\
  1057. *
  1058. * WMM32midiInStop
  1059. *
  1060. * This function terminates MIDI input on the specified MIDI input device.
  1061. *
  1062. \**********************************************************************/
  1063. ULONG FASTCALL WMM32midiInStop(PVDMFRAME pFrame)
  1064. {
  1065. ULONG ul;
  1066. register PMIDIINSTOP16 parg16;
  1067. static FARPROC mmAPI = NULL;
  1068. GET_MULTIMEDIA_API( "midiInStop", mmAPI, MMSYSERR_NODRIVER );
  1069. GETARGPTR(pFrame, sizeof(MIDIINSTOP16), parg16);
  1070. trace_midi(( "midiInStop( %x )", WORD32( parg16->f1 ) ));
  1071. ul = GETWORD16((*mmAPI)(HMIDIIN32(parg16->f1) ) );
  1072. trace_midi(( "-> %ld\n", ul ));
  1073. FREEARGPTR(parg16);
  1074. RETURN(ul);
  1075. }
  1076. /**********************************************************************\
  1077. *
  1078. * WMM32midiInReset
  1079. *
  1080. * This function stops input on a given MIDI input device and marks all pending
  1081. * input buffers as done.
  1082. *
  1083. \**********************************************************************/
  1084. ULONG FASTCALL WMM32midiInReset(PVDMFRAME pFrame)
  1085. {
  1086. ULONG ul;
  1087. register PMIDIINRESET16 parg16;
  1088. static FARPROC mmAPI = NULL;
  1089. GET_MULTIMEDIA_API( "midiInReset", mmAPI, MMSYSERR_NODRIVER );
  1090. GETARGPTR(pFrame, sizeof(MIDIINRESET16), parg16);
  1091. trace_midi(( "midiInReset( %x )", WORD32( parg16->f1 ) ));
  1092. ul = GETWORD16((*mmAPI)(HMIDIIN32(parg16->f1) ) );
  1093. trace_midi(( "-> %ld\n", ul ));
  1094. FREEARGPTR(parg16);
  1095. RETURN(ul);
  1096. }
  1097. /**********************************************************************\
  1098. *
  1099. * WMM32midiInGetID
  1100. *
  1101. * This function gets the device ID for a MIDI input device.
  1102. *
  1103. \**********************************************************************/
  1104. ULONG FASTCALL WMM32midiInGetID(PVDMFRAME pFrame)
  1105. {
  1106. register PMIDIINGETID16 parg16;
  1107. static FARPROC mmAPI = NULL;
  1108. ULONG ul;
  1109. UINT dwDeviceID32;
  1110. LPWORD lpwDeviceID16;
  1111. GET_MULTIMEDIA_API( "midiInGetID", mmAPI, MMSYSERR_NODRIVER );
  1112. GETARGPTR(pFrame, sizeof(MIDIINGETID16), parg16);
  1113. trace_midi(( "midiInGetID( %x, %x )", WORD32( parg16->f1 ),
  1114. DWORD32( parg16->f2 ) ));
  1115. ul = GETWORD16((*mmAPI)( HMIDIIN32(parg16->f1), &dwDeviceID32 ));
  1116. /*
  1117. ** Only copy the ID back to 16 bit space if the call was sucessful
  1118. **
  1119. */
  1120. if ( ul == MMSYSERR_NOERROR ) {
  1121. MMGETOPTPTR( parg16->f2, sizeof(WORD), lpwDeviceID16 );
  1122. if ( lpwDeviceID16 ) {
  1123. STOREWORD ( *lpwDeviceID16, dwDeviceID32 );
  1124. FLUSHVDMPTR( DWORD32(parg16->f2), sizeof(WORD), lpwDeviceID16 );
  1125. FREEVDMPTR ( lpwDeviceID16 );
  1126. }
  1127. else {
  1128. ul = MMSYSERR_INVALPARAM;
  1129. }
  1130. }
  1131. trace_midi(( "-> %ld\n", ul ));
  1132. FREEARGPTR(parg16);
  1133. RETURN(ul);
  1134. }
  1135. /**********************************************************************\
  1136. *
  1137. * WMM32midiInMessage
  1138. *
  1139. * This function sends a message to the specified MIDI input device.
  1140. *
  1141. \**********************************************************************/
  1142. ULONG FASTCALL WMM32midiInMessage(PVDMFRAME pFrame)
  1143. {
  1144. ULONG ul;
  1145. register PMIDIINMESSAGE3216 parg16;
  1146. static FARPROC mmAPI = NULL;
  1147. GET_MULTIMEDIA_API( "midiInMessage", mmAPI, MMSYSERR_NODRIVER );
  1148. GETARGPTR(pFrame, sizeof(MIDIINMESSAGE16), parg16);
  1149. trace_midi(( "midiInMessage( %x, %x, %x, %x )",
  1150. WORD32( parg16->f1 ), UINT32( parg16->f2 ),
  1151. DWORD32( parg16->f3 ), DWORD32( parg16->f4 ) ));
  1152. if ( (UINT32(parg16->f2) >= DRV_BUFFER_LOW)
  1153. && (UINT32(parg16->f2) <= DRV_BUFFER_HIGH) ) {
  1154. LPDWORD lpdwParam1;
  1155. GETMISCPTR(parg16->f3, lpdwParam1);
  1156. ul = GETDWORD16((*mmAPI)( HMIDIIN32(parg16->f1), UINT32(parg16->f2),
  1157. (DWORD)lpdwParam1, DWORD32(parg16->f4)));
  1158. FREEMISCPTR(lpdwParam1);
  1159. } else {
  1160. ul = GETDWORD16((*mmAPI)( HMIDIIN32(parg16->f1),
  1161. MAKELONG( WORD32(parg16->f2), 0xFFFF ),
  1162. DWORD32(parg16->f3), DWORD32(parg16->f4) ));
  1163. }
  1164. trace_midi(( "-> %ld\n", ul ));
  1165. FREEARGPTR(parg16);
  1166. RETURN(ul);
  1167. }
  1168. /* ---------------------------------------------------------------------
  1169. ** WAVE Output API's
  1170. ** ---------------------------------------------------------------------
  1171. */
  1172. /**********************************************************************\
  1173. *
  1174. * WMM32waveOutGetNumDevs
  1175. *
  1176. * This function retrieves the number of waveform output devices present in the
  1177. * system.
  1178. *
  1179. \**********************************************************************/
  1180. ULONG FASTCALL WMM32waveOutGetNumDevs(PVDMFRAME pFrame)
  1181. {
  1182. static FARPROC mmAPI = NULL;
  1183. ULONG ul;
  1184. GET_MULTIMEDIA_API( "waveOutGetNumDevs", mmAPI, MMSYSERR_NODRIVER );
  1185. trace_wave(( "waveOutGetNumDevs()" ));
  1186. ul = GETWORD16((*mmAPI)() );
  1187. trace_wave(( "-> %ld\n", ul ));
  1188. RETURN(ul);
  1189. UNREFERENCED_PARAMETER(pFrame);
  1190. }
  1191. /**********************************************************************\
  1192. *
  1193. * WMM32waveOutGetDevCaps
  1194. *
  1195. * This function queries a specified waveform device to determine its
  1196. * capabilities.
  1197. *
  1198. \**********************************************************************/
  1199. ULONG FASTCALL WMM32waveOutGetDevCaps(PVDMFRAME pFrame)
  1200. {
  1201. register PWAVEOUTGETDEVCAPS16 parg16;
  1202. static FARPROC mmAPI = NULL;
  1203. ULONG ul;
  1204. WAVEOUTCAPS waveoutcaps;
  1205. GET_MULTIMEDIA_API( "waveOutGetDevCapsA", mmAPI, MMSYSERR_NODRIVER );
  1206. GETARGPTR(pFrame, sizeof(WAVEOUTGETDEVCAPS16), parg16);
  1207. trace_wave(( "waveOutGetDevCaps( %x, %x, %x )", INT32( parg16->f1 ),
  1208. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  1209. /*
  1210. ** If the size parameter was zero return straight away. Note that this
  1211. ** is not an error.
  1212. */
  1213. if ( UINT32( parg16->f3 ) == 0 ) {
  1214. ul = MMSYSERR_NOERROR;
  1215. }
  1216. else {
  1217. ul = GETWORD16((*mmAPI)( INT32(parg16->f1), &waveoutcaps,
  1218. sizeof(WAVEOUTCAPS) ));
  1219. /*
  1220. ** Don't update the 16 bit structure if the call failed
  1221. **
  1222. */
  1223. if ( ul == MMSYSERR_NOERROR ) {
  1224. ul = PUTWAVEOUTCAPS16(parg16->f2, &waveoutcaps, UINT32(parg16->f3));
  1225. }
  1226. }
  1227. trace_wave(( "-> %ld\n", ul ));
  1228. FREEARGPTR(parg16);
  1229. RETURN(ul);
  1230. }
  1231. /**********************************************************************\
  1232. *
  1233. * WMM32waveOutGetErrorText
  1234. *
  1235. * This function retrieves a textual description of the error identified by the
  1236. * specified error number.
  1237. *
  1238. \**********************************************************************/
  1239. ULONG FASTCALL WMM32waveOutGetErrorText(PVDMFRAME pFrame)
  1240. {
  1241. register PWAVEOUTGETERRORTEXT16 parg16;
  1242. static FARPROC mmAPI = NULL;
  1243. ULONG ul = MMSYSERR_NOERROR;
  1244. PSZ pszText;
  1245. GET_MULTIMEDIA_API( "waveOutGetErrorTextA", mmAPI, MMSYSERR_NODRIVER );
  1246. GETARGPTR(pFrame, sizeof(WAVEOUTGETERRORTEXT16), parg16);
  1247. trace_wave(( "waveOutGetErrorText( %x, %x, %x )", UINT32( parg16->f1 ),
  1248. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  1249. /*
  1250. ** Test against a zero length string and a NULL pointer. If 0 is passed
  1251. ** as the buffer length then the manual says we should return
  1252. ** MMSYSERR_NOERR. MMGETOPTPTR only returns a pointer if parg16->f2 is
  1253. ** not NULL.
  1254. */
  1255. MMGETOPTPTR( parg16->f2, UINT32(parg16->f3), pszText );
  1256. if ( pszText != NULL ) {
  1257. ul = GETWORD16( (*mmAPI)( UINT32(parg16->f1), pszText,
  1258. UINT32(parg16->f3) ) );
  1259. FLUSHVDMPTR( DWORD32(parg16->f2), UINT32(parg16->f3), pszText);
  1260. FREEVDMPTR(pszText);
  1261. }
  1262. trace_wave(( "-> %ld\n", ul ));
  1263. FREEARGPTR(parg16);
  1264. RETURN(ul);
  1265. }
  1266. /**********************************************************************\
  1267. *
  1268. * WMM32waveOutOpen
  1269. *
  1270. * This function opens a specified waveform output device for playback.
  1271. *
  1272. * As of November 1992 we map the 16 bit Wave Format data directly to the
  1273. * the 32 bit side, no thunking of the parameters is performed.
  1274. *
  1275. \**********************************************************************/
  1276. ULONG FASTCALL WMM32waveOutOpen(PVDMFRAME pFrame)
  1277. {
  1278. ULONG ul = MMSYSERR_NOERROR;
  1279. UINT uDevID;
  1280. PINSTANCEDATA pInstanceData = NULL;
  1281. DWORD dwFlags;
  1282. PWAVEFORMAT16 lpWaveformData;
  1283. LPHWAVEOUT lphWaveOut = NULL; // pointer to handle in 16 bit app space
  1284. HWAVEOUT Hand32; // 32bit handle
  1285. register PWAVEOUTOPEN16 parg16;
  1286. static FARPROC mmAPI = NULL;
  1287. GET_MULTIMEDIA_API( "waveOutOpen", mmAPI, MMSYSERR_NODRIVER );
  1288. GETARGPTR(pFrame, sizeof(WAVEOUTOPEN16), parg16);
  1289. trace_wave(( "waveOutOpen( %x, %x, %x, %x, %x, %x )",
  1290. DWORD32( parg16->f1 ), INT32 ( parg16->f2 ),
  1291. DWORD32( parg16->f3 ), DWORD32( parg16->f4 ),
  1292. DWORD32( parg16->f5 ), DWORD32( parg16->f6 ) ));
  1293. /*
  1294. ** Get the device ID. We use INT32 here not UINT32 to make sure that
  1295. ** negative values (such as WAVE_MAPPER (-1)) get thunked correctly.
  1296. ** Also, get the flags to be used.
  1297. */
  1298. uDevID = (UINT)INT32(parg16->f2);
  1299. dwFlags = DWORD32(parg16->f6);
  1300. /*
  1301. ** Get a pointer to the WAVEFORMAT structure. Because the format of this
  1302. ** structure is exactly the same in 32 and 16 bit land I will use
  1303. ** GETMISCPTR to get a generic pointer to the data. The stuff being
  1304. ** pointed to could be full of unaligned WORDs, but the 32 bit code
  1305. ** would have to cope with this anyway.
  1306. */
  1307. GETMISCPTR( parg16->f3, lpWaveformData );
  1308. if ( lpWaveformData == (PWAVEFORMAT16)NULL ) {
  1309. ul = (ULONG)MMSYSERR_INVALPARAM;
  1310. goto exit_function;
  1311. }
  1312. /*
  1313. ** We don't need a callback routine when the WAVE_FORMAT_QUERY flag
  1314. ** is specified.
  1315. */
  1316. if ( !(dwFlags & WAVE_FORMAT_QUERY) ) {
  1317. /*
  1318. ** Map the 16 bit pointer is one was specified.
  1319. */
  1320. MMGETOPTPTR( parg16->f1, sizeof(HWAVEOUT), lphWaveOut );
  1321. if ( lphWaveOut == NULL ) {
  1322. ul = MMSYSERR_INVALPARAM;
  1323. }
  1324. /*
  1325. ** Create InstanceData block to be used by our callback routine.
  1326. **
  1327. ** NOTE: Although we malloc it here we don't free it.
  1328. ** This is not a mistake - it must not be freed before the
  1329. ** callback routine has used it - so it does the freeing.
  1330. **
  1331. ** If the malloc fails we bomb down to the bottom,
  1332. ** set ul to MMSYSERR_NOMEM and exit gracefully.
  1333. **
  1334. ** We always have a callback functions. This is to ensure that
  1335. ** the WAVEHDR structure keeps getting copied back from
  1336. ** 32 bit space to 16 bit, as it contains flags which
  1337. ** applications are liable to keep checking.
  1338. */
  1339. else if ( pInstanceData = malloc_w(sizeof(INSTANCEDATA) ) ) {
  1340. DWORD dwNewFlags = CALLBACK_FUNCTION;
  1341. dprintf2(( "WM32waveOutOpen: Allocated instance buffer at %8X",
  1342. pInstanceData ));
  1343. pInstanceData->dwCallback = DWORD32(parg16->f4);;
  1344. pInstanceData->dwCallbackInstance = DWORD32(parg16->f5);
  1345. pInstanceData->dwFlags = dwFlags;
  1346. dwNewFlags |= (dwFlags & WAVE_ALLOWSYNC);
  1347. ul = GETWORD16((*mmAPI)( &Hand32, uDevID,
  1348. (LPWAVEFORMAT)lpWaveformData,
  1349. (DWORD)W32CommonDeviceOpen,
  1350. (DWORD)pInstanceData, dwNewFlags ));
  1351. /*
  1352. ** If the call returns success update the 16 bit handle,
  1353. ** otherwise don't, and free the memory we malloc'd earlier, as
  1354. ** the callback that would have freed it will never get callled.
  1355. */
  1356. if ( ul == MMSYSERR_NOERROR ) {
  1357. HWAVEOUT16 Hand16 = GETHWAVEOUT16(Hand32);
  1358. trace_wave(( "Handle -> %x", Hand16 ));
  1359. STOREWORD ( *lphWaveOut, Hand16);
  1360. FLUSHVDMPTR( DWORD32(parg16->f1), sizeof(HWAVEOUT),
  1361. lphWaveOut );
  1362. }
  1363. else {
  1364. dprintf2(( "WM32waveOutOpen: Freeing instance buffer at %8X",
  1365. pInstanceData ));
  1366. free_w(pInstanceData);
  1367. }
  1368. /*
  1369. ** Regardless of sucess or failure we need to free the pointer
  1370. ** to the 16 bit WaveOut handle.
  1371. */
  1372. FREEVDMPTR ( lphWaveOut );
  1373. }
  1374. else {
  1375. ul = (ULONG)MMSYSERR_NOMEM;
  1376. }
  1377. }
  1378. else {
  1379. ul = GETWORD16((*mmAPI)( NULL, uDevID, (LPWAVEFORMAT)lpWaveformData,
  1380. DWORD32(parg16->f4), DWORD32(parg16->f5),
  1381. dwFlags ));
  1382. }
  1383. /*
  1384. ** Regardless of sucess or failure we need to free the pointer to the
  1385. ** 16 bit WaveFormatData.
  1386. */
  1387. FREEMISCPTR( lpWaveformData );
  1388. exit_function:
  1389. trace_wave(( "-> %ld\n", ul ));
  1390. FREEARGPTR(parg16);
  1391. RETURN(ul);
  1392. }
  1393. /**********************************************************************\
  1394. *
  1395. * WMM32waveOutClose
  1396. *
  1397. * This function closes the specified waveform output device.
  1398. *
  1399. \**********************************************************************/
  1400. ULONG FASTCALL WMM32waveOutClose(PVDMFRAME pFrame)
  1401. {
  1402. register PWAVEOUTCLOSE16 parg16;
  1403. static FARPROC mmAPI = NULL;
  1404. ULONG ul;
  1405. GET_MULTIMEDIA_API( "waveOutClose", mmAPI, MMSYSERR_NODRIVER );
  1406. GETARGPTR(pFrame, sizeof(WAVEOUTCLOSE16), parg16);
  1407. trace_wave(( "waveOutClose( %x )", WORD32( parg16->f1 ) ));
  1408. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1) ));
  1409. trace_wave(( "-> %ld\n", ul ));
  1410. FREEARGPTR(parg16);
  1411. RETURN(ul);
  1412. }
  1413. /**********************************************************************\
  1414. *
  1415. * WMM32waveOutPrepareHeader
  1416. *
  1417. * This function prepares the specified waveform header.
  1418. *
  1419. \**********************************************************************/
  1420. ULONG FASTCALL WMM32waveOutPrepareHeader(PVDMFRAME pFrame)
  1421. {
  1422. register PWAVEOUTPREPAREHEADER3216 parg16;
  1423. static FARPROC mmAPI = NULL;
  1424. ULONG ul;
  1425. WAVEHDR wavehdr;
  1426. GET_MULTIMEDIA_API( "waveOutPrepareHeader", mmAPI, MMSYSERR_NODRIVER );
  1427. GETARGPTR(pFrame, sizeof(WAVEOUTPREPAREHEADER3216), parg16);
  1428. trace_wave(( "waveOutPrepareHeader( %x %x %x)", WORD32( parg16->f1 ),
  1429. DWORD32( parg16->f2 ), WORD32( parg16->f3 ) ));
  1430. GETWAVEHDR16(parg16->f2, &wavehdr);
  1431. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1),
  1432. &wavehdr, WORD32(parg16->f3) ) );
  1433. /*
  1434. ** Only update the 16 bit structure if the call returns success
  1435. **
  1436. */
  1437. if ( !ul ) {
  1438. PUTWAVEHDR16(parg16->f2, &wavehdr);
  1439. }
  1440. trace_wave(( "-> %ld\n", ul ));
  1441. FREEARGPTR(parg16);
  1442. RETURN(ul);
  1443. }
  1444. /**********************************************************************\
  1445. *
  1446. * WMM32waveOutUnprepareHeader
  1447. *
  1448. * This function prepares the specified waveform header.
  1449. * This function cleans up the preparation performed by waveOutPrepareHeader.
  1450. * The function must be called after the device driver has finished with a
  1451. * data block. You must call this function before freeing the data buffer.
  1452. *
  1453. \**********************************************************************/
  1454. ULONG FASTCALL WMM32waveOutUnprepareHeader(PVDMFRAME pFrame)
  1455. {
  1456. register PWAVEOUTUNPREPAREHEADER3216 parg16;
  1457. static FARPROC mmAPI = NULL;
  1458. ULONG ul;
  1459. WAVEHDR wavehdr;
  1460. GET_MULTIMEDIA_API( "waveOutUnprepareHeader", mmAPI, MMSYSERR_NODRIVER );
  1461. GETARGPTR(pFrame, sizeof(WAVEOUTUNPREPAREHEADER3216), parg16);
  1462. trace_wave(( "waveOutUnprepareHeader( %x %x %x)", WORD32( parg16->f1 ),
  1463. DWORD32( parg16->f2 ), WORD32( parg16->f3 ) ));
  1464. GETWAVEHDR16(parg16->f2, &wavehdr);
  1465. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1),
  1466. &wavehdr, WORD32(parg16->f3) ) );
  1467. /*
  1468. ** Only update the 16 bit structure if the call returns success
  1469. */
  1470. if (!ul) {
  1471. PUTWAVEHDR16(parg16->f2, &wavehdr);
  1472. }
  1473. trace_wave(( "-> %ld\n", ul ));
  1474. FREEARGPTR(parg16);
  1475. RETURN(ul);
  1476. }
  1477. /**********************************************************************\
  1478. *
  1479. * WMM32waveOutWrite
  1480. *
  1481. * This function sends a data block to the specified waveform output device.
  1482. *
  1483. \**********************************************************************/
  1484. ULONG FASTCALL WMM32waveOutWrite(PVDMFRAME pFrame)
  1485. {
  1486. register PWAVEOUTWRITE16 parg16;
  1487. static FARPROC mmAPI = NULL;
  1488. ULONG ul;
  1489. PWAVEHDR32 pWavehdr32;
  1490. GET_MULTIMEDIA_API( "waveOutWrite", mmAPI, MMSYSERR_NODRIVER );
  1491. GETARGPTR(pFrame, sizeof(WAVEOUTWRITE16), parg16);
  1492. trace_wave(( "waveOutWrite( %x, %x, %x)", WORD32( parg16->f1 ),
  1493. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  1494. /*
  1495. ** If the given size of the WAVEHDR structure is too small
  1496. ** or the lphdr is invalid return an error
  1497. **
  1498. */
  1499. if ( UINT32(parg16->f3) < sizeof(WAVEHDR16)
  1500. || HIWORD( DWORD32(parg16->f2) ) == 0 ) {
  1501. ul = (ULONG)MMSYSERR_INVALPARAM;
  1502. }
  1503. else {
  1504. if ( pWavehdr32 = malloc_w( sizeof(WAVEHDR32) ) ) {
  1505. PWAVEHDR lpwhdr; /* used to simplify ptr stuff later on */
  1506. #if DBG
  1507. AllocWaveCount++;
  1508. dprintf2(( "W>> %8X (%d)", pWavehdr32, AllocWaveCount ));
  1509. #endif
  1510. /* Copy across the wave header stuff. Note that lpwhdr (a
  1511. ** 32 bit ptr to a 32 bit wave header) is used to make the
  1512. ** pointer stuff a bit less hairy.
  1513. **
  1514. ** pWavehdr32->Wavehdr is a 32 bit wave header
  1515. ** pWavehdr32->pWavehdr16 is a 16 bit ptr to a 16 bit wave header
  1516. ** pWavehdr32->pWavehdr32 is a 32 bit ptr to a 16 bit wave header
  1517. */
  1518. lpwhdr = &(pWavehdr32->Wavehdr);
  1519. pWavehdr32->pWavehdr16 = (PWAVEHDR16)DWORD32(parg16->f2);
  1520. pWavehdr32->pWavehdr32 = GETWAVEHDR16(DWORD32(parg16->f2), lpwhdr);
  1521. /*
  1522. ** GETWAVEHDR16 can return NULL, in which case we should set
  1523. ** lpwhdr to NULL too and call waveOutWrite only to get the
  1524. ** correct error code.
  1525. */
  1526. if ( pWavehdr32->pWavehdr32 == NULL ) {
  1527. lpwhdr = NULL;
  1528. }
  1529. ul = GETWORD16( (*mmAPI)( HWAVEOUT32(parg16->f1),
  1530. lpwhdr, UINT32(parg16->f3) ) );
  1531. /* If the call fails we need to free the memory we malloc'd
  1532. ** above, as the callback that would have freed it will never
  1533. ** get called.
  1534. */
  1535. if ( ul == MMSYSERR_NOERROR ) {
  1536. /* Make sure we reflect any changes that waveOutWrite did
  1537. ** to the WAVEHDR back to 16 bit land.
  1538. **
  1539. ** This is important because some apps (waveedit) poll the
  1540. ** WHDR_DONE bit !!
  1541. */
  1542. COPY_WAVEOUTHDR16_FLAGS( pWavehdr32->pWavehdr32,
  1543. pWavehdr32->Wavehdr );
  1544. }
  1545. else {
  1546. #if DBG
  1547. AllocWaveCount--;
  1548. dprintf2(( "W<< \t%8X (%d)", pWavehdr32,
  1549. AllocWaveCount ));
  1550. #endif
  1551. free_w( pWavehdr32 );
  1552. }
  1553. }
  1554. else {
  1555. ul = (ULONG)MMSYSERR_NOMEM;
  1556. }
  1557. }
  1558. trace_wave(( "-> %ld\n", ul ));
  1559. FREEARGPTR(parg16);
  1560. RETURN(ul);
  1561. }
  1562. /**********************************************************************\
  1563. *
  1564. * WMM32waveOutPause
  1565. *
  1566. * This function pauses playback on a specified waveform output device. The
  1567. * current playback position is saved. Use wavOutRestart to resume playback from
  1568. * the current playback position.
  1569. *
  1570. \**********************************************************************/
  1571. ULONG FASTCALL WMM32waveOutPause(PVDMFRAME pFrame)
  1572. {
  1573. ULONG ul;
  1574. register PWAVEOUTPAUSE16 parg16;
  1575. static FARPROC mmAPI = NULL;
  1576. GET_MULTIMEDIA_API( "waveOutPause", mmAPI, MMSYSERR_NODRIVER );
  1577. GETARGPTR(pFrame, sizeof(WAVEOUTPAUSE16), parg16);
  1578. trace_wave(( "waveOutGetPause( %x )", WORD32( parg16->f1 ) ));
  1579. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1) ));
  1580. trace_wave(( "-> %ld\n", ul ));
  1581. FREEARGPTR(parg16);
  1582. RETURN(ul);
  1583. }
  1584. /**********************************************************************\
  1585. *
  1586. * WMM32waveOutRestart
  1587. *
  1588. * This function restarts a paused waveform output device.
  1589. *
  1590. \**********************************************************************/
  1591. ULONG FASTCALL WMM32waveOutRestart(PVDMFRAME pFrame)
  1592. {
  1593. ULONG ul;
  1594. register PWAVEOUTRESTART16 parg16;
  1595. static FARPROC mmAPI = NULL;
  1596. GET_MULTIMEDIA_API( "waveOutRestart", mmAPI, MMSYSERR_NODRIVER );
  1597. GETARGPTR(pFrame, sizeof(WAVEOUTRESTART16), parg16);
  1598. trace_wave(( "waveOutRestart( %x )", WORD32( parg16->f1 ) ));
  1599. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1) ));
  1600. trace_wave(( "-> %ld\n", ul ));
  1601. FREEARGPTR(parg16);
  1602. RETURN(ul);
  1603. }
  1604. /**********************************************************************\
  1605. *
  1606. * WMM32waveOutReset
  1607. *
  1608. * This function stops playback on a given waveform output device and resets the
  1609. * current position to 0. All pending playback buffers are marked as done and
  1610. * returned to the application.
  1611. *
  1612. \**********************************************************************/
  1613. ULONG FASTCALL WMM32waveOutReset(PVDMFRAME pFrame)
  1614. {
  1615. ULONG ul;
  1616. register PWAVEOUTRESET16 parg16;
  1617. static FARPROC mmAPI = NULL;
  1618. GET_MULTIMEDIA_API( "waveOutReset", mmAPI, MMSYSERR_NODRIVER );
  1619. GETARGPTR(pFrame, sizeof(WAVEOUTRESET16), parg16);
  1620. trace_wave(( "waveOutReset( %x )", WORD32( parg16->f1 ) ));
  1621. ul = GETWORD16( (*mmAPI)( HWAVEOUT32(parg16->f1) ));
  1622. trace_wave(( "-> %ld\n", ul ));
  1623. FREEARGPTR(parg16);
  1624. RETURN(ul);
  1625. }
  1626. /**********************************************************************\
  1627. *
  1628. * WMM32waveOutGetPosition
  1629. *
  1630. * This function retrieves the current palyback position of the specified
  1631. * waveform output device.
  1632. *
  1633. \**********************************************************************/
  1634. ULONG FASTCALL WMM32waveOutGetPosition(PVDMFRAME pFrame)
  1635. {
  1636. register PWAVEOUTGETPOSITION16 parg16;
  1637. static FARPROC mmAPI = NULL;
  1638. MMTIME mmtime;
  1639. ULONG ul = MMSYSERR_INVALPARAM;
  1640. GET_MULTIMEDIA_API( "waveOutGetPosition", mmAPI, MMSYSERR_NODRIVER );
  1641. GETARGPTR(pFrame, sizeof(WAVEOUTGETPOSITION16), parg16);
  1642. trace_wave(( "waveOutGetPosition( %x, %x, %x )", WORD32( parg16->f1 ),
  1643. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  1644. /*
  1645. ** If the given size of the MMTIME structure is too small return an error
  1646. **
  1647. ** There is a problem here on MIPS. For some reason the MIPS
  1648. ** compiler thinks a MMTIME16 structure is 10 bytes big. We
  1649. ** have a pragma in wowmmed.h to align this structure on byte
  1650. ** boundaries therefore I guess this is a compiler bug!
  1651. **
  1652. ** If the input structure is not large enough we return immediately
  1653. */
  1654. #ifdef MIPS_COMPILER_PACKING_BUG
  1655. if ( UINT32(parg16->f3) >= 8 ) {
  1656. #else
  1657. if ( UINT32(parg16->f3) >= sizeof(MMTIME16) ) {
  1658. #endif
  1659. ul = GETMMTIME16( parg16->f2, &mmtime);
  1660. if ( ul == MMSYSERR_NOERROR ) {
  1661. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1),
  1662. &mmtime, sizeof(MMTIME) ));
  1663. /*
  1664. ** Only update the 16 bit structure if the call returns success
  1665. **
  1666. */
  1667. if ( ul == MMSYSERR_NOERROR ) {
  1668. ul = PUTMMTIME16( parg16->f2, &mmtime);
  1669. }
  1670. }
  1671. }
  1672. trace_wave(( "-> %ld\n", ul ));
  1673. FREEARGPTR(parg16);
  1674. RETURN(ul);
  1675. }
  1676. /**********************************************************************\
  1677. *
  1678. * WMM32waveOutGetPitch
  1679. *
  1680. * This function queries the current pitch setting of a waveform output device.
  1681. *
  1682. \**********************************************************************/
  1683. ULONG FASTCALL WMM32waveOutGetPitch(PVDMFRAME pFrame)
  1684. {
  1685. register PWAVEOUTGETPITCH16 parg16;
  1686. static FARPROC mmAPI = NULL;
  1687. ULONG ul = MMSYSERR_INVALPARAM;
  1688. LPDWORD lpdwPitch;
  1689. DWORD dwPitch;
  1690. GET_MULTIMEDIA_API( "waveOutGetPitch", mmAPI, MMSYSERR_NODRIVER );
  1691. GETARGPTR(pFrame, sizeof(WAVEOUTGETPITCH16), parg16);
  1692. trace_wave(( "waveOutGetPitch( %x, %x )", WORD32( parg16->f1 ),
  1693. DWORD32( parg16->f2 ) ));
  1694. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1), &dwPitch ));
  1695. if ( ul == MMSYSERR_NOERROR ) {
  1696. MMGETOPTPTR( parg16->f2, sizeof(DWORD), lpdwPitch);
  1697. if ( lpdwPitch ) {
  1698. STOREDWORD ( *lpdwPitch, dwPitch );
  1699. FLUSHVDMPTR( DWORD32(parg16->f2), sizeof(DWORD), lpdwPitch );
  1700. FREEVDMPTR ( lpdwPitch );
  1701. }
  1702. else {
  1703. ul = MMSYSERR_INVALPARAM;
  1704. }
  1705. }
  1706. trace_wave(( "-> %ld\n", ul ));
  1707. FREEARGPTR(parg16);
  1708. RETURN(ul);
  1709. }
  1710. /**********************************************************************\
  1711. *
  1712. * WMM32waveOutSetPitch
  1713. *
  1714. * This function sets the pitch of a waveform output device.
  1715. *
  1716. \**********************************************************************/
  1717. ULONG FASTCALL WMM32waveOutSetPitch(PVDMFRAME pFrame)
  1718. {
  1719. register PWAVEOUTSETPITCH16 parg16;
  1720. static FARPROC mmAPI = NULL;
  1721. ULONG ul;
  1722. GET_MULTIMEDIA_API( "waveOutSetPitch", mmAPI, MMSYSERR_NODRIVER );
  1723. GETARGPTR(pFrame, sizeof(WAVEOUTSETPITCH16), parg16);
  1724. trace_wave(( "waveOutSetPitch( %x, %x )", WORD32( parg16->f1 ),
  1725. DWORD32( parg16->f2 ) ));
  1726. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1), DWORD32(parg16->f2) ));
  1727. trace_wave(( "-> %ld\n", ul ));
  1728. FREEARGPTR(parg16);
  1729. RETURN(ul);
  1730. }
  1731. /**********************************************************************\
  1732. *
  1733. * WMM32waveOutGetVolume
  1734. *
  1735. * This function queries the current volume setting of a waveform output device.
  1736. *
  1737. \**********************************************************************/
  1738. ULONG FASTCALL WMM32waveOutGetVolume(PVDMFRAME pFrame)
  1739. {
  1740. register PWAVEOUTGETVOLUME16 parg16;
  1741. static FARPROC mmAPI = NULL;
  1742. ULONG ul;
  1743. LPDWORD lpdwVolume;
  1744. DWORD dwVolume;
  1745. GET_MULTIMEDIA_API( "waveOutGetVolume", mmAPI, MMSYSERR_NODRIVER );
  1746. GETARGPTR(pFrame, sizeof(WAVEOUTGETVOLUME16), parg16);
  1747. trace_wave(( "waveOutGetVolume( %x, %x )", INT32( parg16->f1 ),
  1748. DWORD32( parg16->f2 ) ));
  1749. ul = GETWORD16((*mmAPI)( INT32(parg16->f1), &dwVolume ));
  1750. if ( ul == MMSYSERR_NOERROR ) {
  1751. MMGETOPTPTR( parg16->f2, sizeof(DWORD), lpdwVolume);
  1752. if ( lpdwVolume ) {
  1753. STOREDWORD ( *lpdwVolume, dwVolume );
  1754. FLUSHVDMPTR( DWORD32(parg16->f2), sizeof(DWORD), lpdwVolume );
  1755. FREEVDMPTR ( lpdwVolume );
  1756. }
  1757. else {
  1758. ul = MMSYSERR_INVALPARAM;
  1759. }
  1760. }
  1761. trace_wave(( "-> %ld\n", ul ));
  1762. FREEARGPTR(parg16);
  1763. RETURN(ul);
  1764. }
  1765. /**********************************************************************\
  1766. *
  1767. * WMM32waveOutSetVolume
  1768. *
  1769. * This function sets the volume of a waveform output device.
  1770. *
  1771. \**********************************************************************/
  1772. ULONG FASTCALL WMM32waveOutSetVolume(PVDMFRAME pFrame)
  1773. {
  1774. ULONG ul;
  1775. register PWAVEOUTSETVOLUME16 parg16;
  1776. static FARPROC mmAPI = NULL;
  1777. GET_MULTIMEDIA_API( "waveOutSetVolume", mmAPI, MMSYSERR_NODRIVER );
  1778. GETARGPTR(pFrame, sizeof(WAVEOUTSETVOLUME16), parg16);
  1779. trace_wave(( "waveOutSetVolume( %x, %x )", INT32( parg16->f1 ),
  1780. DWORD32( parg16->f2 ) ));
  1781. ul = GETWORD16((*mmAPI)( INT32(parg16->f1), DWORD32(parg16->f2) ));
  1782. trace_wave(( "-> %ld\n", ul ));
  1783. FREEARGPTR(parg16);
  1784. RETURN(ul);
  1785. }
  1786. /**********************************************************************\
  1787. *
  1788. * WMM32waveOutGetPlaybackRate
  1789. *
  1790. * This function queries the current playback rate setting of a waveform output
  1791. * device.
  1792. *
  1793. \**********************************************************************/
  1794. ULONG FASTCALL WMM32waveOutGetPlaybackRate(PVDMFRAME pFrame)
  1795. {
  1796. register PWAVEOUTGETPLAYBACKRATE16 parg16;
  1797. static FARPROC mmAPI = NULL;
  1798. ULONG ul;
  1799. LPDWORD lpdwRate;
  1800. DWORD dwRate;
  1801. GET_MULTIMEDIA_API( "waveOutGetPlaybackRate", mmAPI, MMSYSERR_NODRIVER );
  1802. GETARGPTR(pFrame, sizeof(WAVEOUTGETPLAYBACKRATE16), parg16);
  1803. trace_wave(( "waveOutGetPlaybackRate( %x, %x )", WORD32( parg16->f1 ),
  1804. DWORD32( parg16->f2 ) ));
  1805. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1), &dwRate ));
  1806. if ( ul == MMSYSERR_NOERROR ) {
  1807. MMGETOPTPTR( parg16->f2, sizeof(DWORD), lpdwRate );
  1808. if ( lpdwRate ) {
  1809. STOREDWORD ( *lpdwRate, dwRate );
  1810. FLUSHVDMPTR( DWORD32(parg16->f2), sizeof(DWORD), lpdwRate );
  1811. FREEVDMPTR ( lpdwRate );
  1812. }
  1813. }
  1814. trace_wave(( "-> %ld\n", ul ));
  1815. FREEARGPTR(parg16);
  1816. RETURN(ul);
  1817. }
  1818. /**********************************************************************\
  1819. *
  1820. * WMM32waveOutSetPlaybackRate
  1821. *
  1822. * This function sets the playback rate of a waveform output device.
  1823. *
  1824. \**********************************************************************/
  1825. ULONG FASTCALL WMM32waveOutSetPlaybackRate(PVDMFRAME pFrame)
  1826. {
  1827. ULONG ul;
  1828. register PWAVEOUTSETPLAYBACKRATE16 parg16;
  1829. static FARPROC mmAPI = NULL;
  1830. GET_MULTIMEDIA_API( "waveOutSetPlaybackRate", mmAPI, MMSYSERR_NODRIVER );
  1831. GETARGPTR(pFrame, sizeof(WAVEOUTSETPLAYBACKRATE16), parg16);
  1832. trace_wave(( "waveOutSetPlaybackRate( %x, %x )", WORD32( parg16->f1 ),
  1833. DWORD32( parg16->f2 ) ));
  1834. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1), DWORD32(parg16->f2) ));
  1835. trace_wave(( "-> %ld\n", ul ));
  1836. FREEARGPTR(parg16);
  1837. RETURN(ul);
  1838. }
  1839. /**********************************************************************\
  1840. *
  1841. * WMM32waveOutBreakLoop
  1842. *
  1843. * This function breaks a loop on a given waveform output device and allows
  1844. * playback to continue with the next block in the driver list.
  1845. *
  1846. \**********************************************************************/
  1847. ULONG FASTCALL WMM32waveOutBreakLoop(PVDMFRAME pFrame)
  1848. {
  1849. ULONG ul;
  1850. register PWAVEOUTBREAKLOOP16 parg16;
  1851. static FARPROC mmAPI = NULL;
  1852. GET_MULTIMEDIA_API( "waveOutBreakLoop", mmAPI, MMSYSERR_NODRIVER );
  1853. GETARGPTR(pFrame, sizeof(WAVEOUTBREAKLOOP16), parg16);
  1854. trace_wave(( "waveOutBreakLoop( %x )", WORD32( parg16->f1 ) ));
  1855. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1) ));
  1856. trace_wave(( "-> %ld\n", ul ));
  1857. FREEARGPTR(parg16);
  1858. RETURN(ul);
  1859. }
  1860. /**********************************************************************\
  1861. *
  1862. * WMM32waveOutGetID
  1863. *
  1864. * This function gets the device ID for a waveform output device.
  1865. *
  1866. \**********************************************************************/
  1867. ULONG FASTCALL WMM32waveOutGetID(PVDMFRAME pFrame)
  1868. {
  1869. register PWAVEOUTGETID16 parg16;
  1870. static FARPROC mmAPI = NULL;
  1871. ULONG ul;
  1872. UINT dwDeviceID32;
  1873. LPWORD lpwDeviceID16;
  1874. GET_MULTIMEDIA_API( "waveOutGetID", mmAPI, MMSYSERR_NODRIVER );
  1875. GETARGPTR(pFrame, sizeof(WAVEOUTGETID16), parg16);
  1876. trace_wave(( "waveOutGetID( %x, %x )", WORD32( parg16->f1 ),
  1877. DWORD32( parg16->f2 ) ));
  1878. ul = GETWORD16((*mmAPI)( HWAVEOUT32(parg16->f1), &dwDeviceID32 ));
  1879. /*
  1880. ** Only copy the ID back to 16 bit space if the call was sucessful
  1881. **
  1882. */
  1883. if ( ul == MMSYSERR_NOERROR ) {
  1884. MMGETOPTPTR( parg16->f2, sizeof(WORD), lpwDeviceID16 );
  1885. if ( lpwDeviceID16 ) {
  1886. STOREWORD ( *lpwDeviceID16, dwDeviceID32 );
  1887. FLUSHVDMPTR( DWORD32(parg16->f2), sizeof(WORD), lpwDeviceID16 );
  1888. FREEVDMPTR ( lpwDeviceID16 );
  1889. }
  1890. else {
  1891. ul = MMSYSERR_INVALPARAM;
  1892. }
  1893. }
  1894. trace_wave(( "-> %ld\n", ul ));
  1895. FREEARGPTR(parg16);
  1896. RETURN(ul);
  1897. }
  1898. /**********************************************************************\
  1899. *
  1900. * WMM32waveOutMessage
  1901. *
  1902. * This function send a message to a waveform output device.
  1903. *
  1904. \**********************************************************************/
  1905. ULONG FASTCALL WMM32waveOutMessage(PVDMFRAME pFrame)
  1906. {
  1907. ULONG ul;
  1908. register PWAVEOUTMESSAGE3216 parg16;
  1909. static FARPROC mmAPI = NULL;
  1910. GET_MULTIMEDIA_API( "waveOutMessage", mmAPI, MMSYSERR_NODRIVER );
  1911. GETARGPTR(pFrame, sizeof(WAVEOUTMESSAGE16), parg16);
  1912. trace_wave(( "waveOutMessage( %x, %x, %x, %x )",
  1913. WORD32( parg16->f1 ), UINT32( parg16->f2 ),
  1914. DWORD32( parg16->f3 ), DWORD32( parg16->f4 ) ));
  1915. if ( (UINT32(parg16->f2) >= DRV_BUFFER_LOW)
  1916. && (UINT32(parg16->f2) <= DRV_BUFFER_HIGH) ) {
  1917. LPDWORD lpdwParam1;
  1918. GETMISCPTR(parg16->f3, lpdwParam1);
  1919. ul = GETDWORD16((*mmAPI)( HWAVEOUT32(parg16->f1), UINT32(parg16->f2),
  1920. (DWORD)lpdwParam1, DWORD32(parg16->f4) ));
  1921. FREEMISCPTR(lpdwParam1);
  1922. } else {
  1923. ul = GETDWORD16((*mmAPI)( HWAVEOUT32(parg16->f1),
  1924. MAKELONG( WORD32(parg16->f2), 0xFFFF ),
  1925. DWORD32(parg16->f3), DWORD32(parg16->f4) ));
  1926. }
  1927. trace_wave(( "-> %ld\n", ul ));
  1928. FREEARGPTR(parg16);
  1929. RETURN(ul);
  1930. }
  1931. /* ---------------------------------------------------------------------
  1932. ** WAVE Input API's
  1933. ** ---------------------------------------------------------------------
  1934. */
  1935. /**********************************************************************\
  1936. *
  1937. * WMM32waveInGetNumDevs
  1938. *
  1939. * This function returns the number of waveform input devices.
  1940. *
  1941. \**********************************************************************/
  1942. ULONG FASTCALL WMM32waveInGetNumDevs(PVDMFRAME pFrame)
  1943. {
  1944. ULONG ul;
  1945. static FARPROC mmAPI = NULL;
  1946. GET_MULTIMEDIA_API( "waveInGetNumDevs", mmAPI, MMSYSERR_NODRIVER );
  1947. UNREFERENCED_PARAMETER(pFrame);
  1948. trace_wave(( "waveInGetNumDevs()" ));
  1949. ul = GETWORD16((*mmAPI)() );
  1950. trace_wave(( "-> %ld\n", ul ));
  1951. RETURN(ul);
  1952. }
  1953. /**********************************************************************\
  1954. *
  1955. * WMM32waveInGetDevCaps
  1956. *
  1957. * This function queries a specified waveform input device to determine its
  1958. * capabilities.
  1959. *
  1960. \**********************************************************************/
  1961. ULONG FASTCALL WMM32waveInGetDevCaps(PVDMFRAME pFrame)
  1962. {
  1963. ULONG ul;
  1964. WAVEINCAPS waveincaps1;
  1965. register PWAVEINGETDEVCAPS16 parg16;
  1966. static FARPROC mmAPI = NULL;
  1967. GET_MULTIMEDIA_API( "waveInGetDevCapsA", mmAPI, MMSYSERR_NODRIVER );
  1968. GETARGPTR(pFrame, sizeof(WAVEINGETDEVCAPS16), parg16);
  1969. trace_wave(( "waveInGetDevCaps( %x, %x, %x )", WORD32( parg16->f1 ),
  1970. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  1971. /*
  1972. ** If the size parameter was zero return straight away. Note that this
  1973. ** is not an error.
  1974. */
  1975. if ( UINT32( parg16->f3 ) == 0 ) {
  1976. ul = MMSYSERR_NOERROR;
  1977. }
  1978. else {
  1979. ul = GETWORD16((*mmAPI)(INT32(parg16->f1), &waveincaps1,
  1980. sizeof(WAVEINCAPS) ) );
  1981. /*
  1982. ** Don't update the 16 bit structure if the call failed
  1983. **
  1984. */
  1985. if ( ul == MMSYSERR_NOERROR ) {
  1986. ul = PUTWAVEINCAPS16(parg16->f2, &waveincaps1, UINT32(parg16->f3));
  1987. }
  1988. }
  1989. trace_wave(( "-> %ld\n", ul ));
  1990. FREEARGPTR(parg16);
  1991. RETURN(ul);
  1992. }
  1993. /**********************************************************************\
  1994. *
  1995. * WMM32waveInGetErrorText
  1996. *
  1997. * This function retrieves a textual description of the error identified by the
  1998. * specified error number.
  1999. *
  2000. \**********************************************************************/
  2001. ULONG FASTCALL WMM32waveInGetErrorText(PVDMFRAME pFrame)
  2002. {
  2003. ULONG ul = MMSYSERR_NOERROR;
  2004. PSZ pszText;
  2005. register PWAVEINGETERRORTEXT16 parg16;
  2006. static FARPROC mmAPI = NULL;
  2007. GET_MULTIMEDIA_API( "waveInGetErrorTextA", mmAPI, MMSYSERR_NODRIVER );
  2008. GETARGPTR(pFrame, sizeof(WAVEINGETERRORTEXT16), parg16);
  2009. trace_wave(( "waveInGetErrorText( %x, %x, %x )", UINT32( parg16->f1 ),
  2010. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  2011. /*
  2012. ** Test against a zero length string and a NULL pointer. If 0 is passed
  2013. ** as the buffer length then the manual says we should return
  2014. ** MMSYSERR_NOERR. MMGETOPTPTR only returns a pointer if parg16->f2 is
  2015. ** not NULL.
  2016. */
  2017. MMGETOPTPTR( parg16->f2, UINT32(parg16->f3), pszText );
  2018. if ( pszText != NULL ) {
  2019. ul = GETWORD16((*mmAPI)( UINT32(parg16->f1), pszText,
  2020. UINT32(parg16->f3) ));
  2021. FLUSHVDMPTR( DWORD32(parg16->f2), UINT32(parg16->f3), pszText);
  2022. FREEVDMPTR(pszText);
  2023. }
  2024. trace_wave(( "-> %ld\n", ul ));
  2025. FREEARGPTR(parg16);
  2026. RETURN(ul);
  2027. }
  2028. /**********************************************************************\
  2029. *
  2030. * WMM32waveInOpen
  2031. *
  2032. * This function opens a specified waveform input device for recording.
  2033. *
  2034. * As of November 1992 we map the 16 bit Wave Format data directly to the
  2035. * the 32 bit side, no thunking of the parameters is performed.
  2036. *
  2037. *
  2038. \**********************************************************************/
  2039. ULONG FASTCALL WMM32waveInOpen(PVDMFRAME pFrame)
  2040. {
  2041. ULONG ul=0;
  2042. UINT uDevID;
  2043. PINSTANCEDATA pInstanceData = NULL;
  2044. DWORD dwFlags;
  2045. PWAVEFORMAT16 lpWaveformData;
  2046. LPHWAVEIN lphWaveIn; // pointer to handle in 16 bit app space
  2047. HWAVEIN Hand32; // 32bit handle
  2048. register PWAVEINOPEN16 parg16;
  2049. static FARPROC mmAPI = NULL;
  2050. GET_MULTIMEDIA_API( "waveInOpen", mmAPI, MMSYSERR_NODRIVER );
  2051. GETARGPTR(pFrame, sizeof(WAVEINOPEN16), parg16);
  2052. trace_wave(( "waveInOpen( %x, %x, %x, %x, %x, %x )",
  2053. DWORD32( parg16->f1 ), INT32 ( parg16->f2 ),
  2054. DWORD32( parg16->f3 ), DWORD32( parg16->f4 ),
  2055. DWORD32( parg16->f5 ), DWORD32( parg16->f6 ) ));
  2056. /*
  2057. ** Get the device ID. We use INT32 here not UINT32 to make sure that
  2058. ** negative values (such as WAVE_MAPPER (-1)) get thunked correctly.
  2059. */
  2060. uDevID = (UINT)INT32(parg16->f2);
  2061. /*
  2062. ** Get the flags to be used.
  2063. */
  2064. dwFlags = DWORD32(parg16->f6);
  2065. /*
  2066. ** Get a pointer to the WAVEFORMAT structure. Because the format of this
  2067. ** structure is exactly the same in 32 and 16 bit land I will use
  2068. ** GETMISCPTR to get a generic pointer to the data. The stuff being
  2069. ** pointed to could be full of unaligned WORDs, but the 32 bit code
  2070. ** would have to cope with this anyway.
  2071. */
  2072. GETMISCPTR( DWORD32(parg16->f3), lpWaveformData );
  2073. if ( lpWaveformData == (PWAVEFORMAT16)NULL ) {
  2074. ul = (ULONG)MMSYSERR_INVALPARAM;
  2075. goto exit_function;
  2076. }
  2077. /*
  2078. ** We don't need a callback routine when the WAVE_FORMAT_QUERY flag
  2079. ** is specified.
  2080. */
  2081. if ( !( dwFlags & WAVE_FORMAT_QUERY ) ) {
  2082. /*
  2083. ** Map the 16 bit pointer is one was specified.
  2084. */
  2085. MMGETOPTPTR( parg16->f1, sizeof(HWAVEIN), lphWaveIn );
  2086. if ( lphWaveIn == NULL ) {
  2087. ul = MMSYSERR_INVALPARAM;
  2088. }
  2089. /*
  2090. ** Create InstanceData block to be used by our callback routine.
  2091. **
  2092. ** NOTE: Although we malloc it here we don't free it.
  2093. ** This is not a mistake - it must not be freed before the
  2094. ** callback routine has used it - so it does the freeing.
  2095. **
  2096. ** If the malloc fails we bomb down to the bottom,
  2097. ** set ul to MMSYSERR_NOMEM and exit gracefully.
  2098. **
  2099. ** We always have a callback functions. This is to ensure that
  2100. ** the WAVEHDR structure keeps getting copied back from
  2101. ** 32 bit space to 16 bit, as it contains flags which
  2102. ** applications are liable to keep checking.
  2103. */
  2104. else if ( pInstanceData = malloc_w(sizeof(INSTANCEDATA) ) ) {
  2105. DWORD dwNewFlags = CALLBACK_FUNCTION;
  2106. dprintf2(( "WM32waveInOpen: Allocated instance buffer at %8X",
  2107. pInstanceData ));
  2108. pInstanceData->dwCallback = DWORD32(parg16->f4);;
  2109. pInstanceData->dwCallbackInstance = DWORD32(parg16->f5);
  2110. pInstanceData->dwFlags = dwFlags;
  2111. dwNewFlags |= (dwFlags & WAVE_ALLOWSYNC);
  2112. ul = GETWORD16( (*mmAPI)( &Hand32, uDevID,
  2113. (LPWAVEFORMAT)lpWaveformData,
  2114. (DWORD)W32CommonDeviceOpen,
  2115. (DWORD)pInstanceData, dwNewFlags ) );
  2116. /*
  2117. ** If the call returns success update the 16 bit handle,
  2118. ** otherwise don't, and free the memory we malloc'd earlier, as
  2119. ** the callback that would have freed it will never get callled.
  2120. */
  2121. if ( ul == MMSYSERR_NOERROR ) {
  2122. HWAVEIN16 Hand16 = GETHWAVEIN16(Hand32);
  2123. trace_wave(( "Handle -> %x", Hand16 ));
  2124. STOREWORD ( *lphWaveIn, Hand16 );
  2125. FLUSHVDMPTR( DWORD32(parg16->f1), sizeof(HWAVEIN), lphWaveIn );
  2126. }
  2127. else {
  2128. free_w(pInstanceData);
  2129. }
  2130. /*
  2131. ** Regardless of sucess or failure we need to free the pointer
  2132. ** to the 16 bit WaveIn handle.
  2133. */
  2134. FREEVDMPTR ( lphWaveIn );
  2135. }
  2136. else {
  2137. ul = (ULONG)MMSYSERR_NOMEM;
  2138. }
  2139. }
  2140. else {
  2141. ul = GETWORD16( (*mmAPI)( NULL, uDevID, (LPWAVEFORMAT)lpWaveformData,
  2142. DWORD32(parg16->f4),
  2143. DWORD32(parg16->f5), dwFlags) );
  2144. }
  2145. /*
  2146. ** Regardless of sucess or failure we need to free the pointer to the
  2147. ** 16 bit WaveFormatData.
  2148. */
  2149. FREEMISCPTR( lpWaveformData );
  2150. exit_function:
  2151. trace_wave(( "-> %ld\n", ul ));
  2152. FREEARGPTR(parg16);
  2153. RETURN(ul);
  2154. }
  2155. /**********************************************************************\
  2156. *
  2157. * WMM32waveInClose
  2158. *
  2159. * This function closes the specified waveform input device.
  2160. *
  2161. \**********************************************************************/
  2162. ULONG FASTCALL WMM32waveInClose(PVDMFRAME pFrame)
  2163. {
  2164. ULONG ul;
  2165. register PWAVEINCLOSE16 parg16;
  2166. static FARPROC mmAPI = NULL;
  2167. GET_MULTIMEDIA_API( "waveInClose", mmAPI, MMSYSERR_NODRIVER );
  2168. GETARGPTR(pFrame, sizeof(WAVEINCLOSE16), parg16);
  2169. trace_wave(( "waveInClose( %x )", WORD32( parg16->f1 ) ));
  2170. ul = GETWORD16((*mmAPI)( HWAVEIN32(parg16->f1) ));
  2171. trace_wave(( "-> %ld\n", ul ));
  2172. FREEARGPTR(parg16);
  2173. RETURN(ul);
  2174. }
  2175. /**********************************************************************\
  2176. *
  2177. * WMM32waveInPrepareHeader
  2178. *
  2179. * This function prepares the specified waveform header.
  2180. *
  2181. \**********************************************************************/
  2182. ULONG FASTCALL WMM32waveInPrepareHeader(PVDMFRAME pFrame)
  2183. {
  2184. register PWAVEINPREPAREHEADER3216 parg16;
  2185. static FARPROC mmAPI = NULL;
  2186. ULONG ul;
  2187. WAVEHDR wavehdr;
  2188. GET_MULTIMEDIA_API( "waveInPrepareHeader", mmAPI, MMSYSERR_NODRIVER );
  2189. GETARGPTR(pFrame, sizeof(WAVEINPREPAREHEADER3216), parg16);
  2190. trace_wave(( "waveInPrepareHeader( %x %x %x)", WORD32( parg16->f1 ),
  2191. DWORD32( parg16->f2 ), WORD32( parg16->f3 ) ));
  2192. GETWAVEHDR16(parg16->f2, &wavehdr);
  2193. ul = GETWORD16((*mmAPI)( HWAVEIN32(parg16->f1),
  2194. &wavehdr, WORD32(parg16->f3) ) );
  2195. /*
  2196. ** Only update the 16 bit structure if the call returns success
  2197. **
  2198. */
  2199. if ( !ul ) {
  2200. PUTWAVEHDR16(parg16->f2, &wavehdr);
  2201. }
  2202. trace_wave(( "-> %ld\n", ul ));
  2203. FREEARGPTR(parg16);
  2204. RETURN(ul);
  2205. }
  2206. /**********************************************************************\
  2207. *
  2208. * WMM32waveInUnprepareHeader
  2209. *
  2210. * This function prepares the specified waveform header.
  2211. * This function cleans up the preparation performed by waveInPrepareHeader.
  2212. * The function must be called after the device driver has finished with a
  2213. * data block. You must call this function before freeing the data buffer.
  2214. *
  2215. \**********************************************************************/
  2216. ULONG FASTCALL WMM32waveInUnprepareHeader(PVDMFRAME pFrame)
  2217. {
  2218. register PWAVEINUNPREPAREHEADER3216 parg16;
  2219. static FARPROC mmAPI = NULL;
  2220. ULONG ul;
  2221. WAVEHDR wavehdr;
  2222. GET_MULTIMEDIA_API( "waveInUnprepareHeader", mmAPI, MMSYSERR_NODRIVER );
  2223. GETARGPTR(pFrame, sizeof(WAVEINUNPREPAREHEADER3216), parg16);
  2224. trace_wave(( "waveInUnprepareHeader( %x %x %x)", WORD32( parg16->f1 ),
  2225. DWORD32( parg16->f2 ), WORD32( parg16->f3 ) ));
  2226. GETWAVEHDR16(parg16->f2, &wavehdr);
  2227. ul = GETWORD16((*mmAPI)( HWAVEIN32(parg16->f1),
  2228. &wavehdr, WORD32(parg16->f3) ) );
  2229. /*
  2230. ** Only update the 16 bit structure if the call returns success
  2231. */
  2232. if (!ul) {
  2233. PUTWAVEHDR16(parg16->f2, &wavehdr);
  2234. }
  2235. trace_wave(( "-> %ld\n", ul ));
  2236. FREEARGPTR(parg16);
  2237. RETURN(ul);
  2238. }
  2239. /**********************************************************************\
  2240. *
  2241. * WMM32waveInAddBuffer
  2242. *
  2243. * This function sends an input buffer to a waveform input device.
  2244. * When the buffer is filled it is sent back to the application.
  2245. *
  2246. \**********************************************************************/
  2247. ULONG FASTCALL WMM32waveInAddBuffer(PVDMFRAME pFrame)
  2248. {
  2249. ULONG ul;
  2250. PWAVEHDR32 pWavehdr32;
  2251. register PWAVEINADDBUFFER16 parg16;
  2252. static FARPROC mmAPI = NULL;
  2253. GET_MULTIMEDIA_API( "waveInAddBuffer", mmAPI, MMSYSERR_NODRIVER );
  2254. GETARGPTR(pFrame, sizeof(WAVEINADDBUFFER16), parg16);
  2255. trace_wave(( "waveInAddBuffer( %x, %x, %x)", WORD32( parg16->f1 ),
  2256. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  2257. /*
  2258. ** If the given size of the WAVEHDR structure is too small
  2259. ** or the lphdr is invalid return an error
  2260. **
  2261. */
  2262. if ( UINT32(parg16->f3) < sizeof(WAVEHDR16)
  2263. || HIWORD( DWORD32(parg16->f2) ) == 0 ) {
  2264. ul = (ULONG)MMSYSERR_INVALPARAM;
  2265. }
  2266. else {
  2267. if (pWavehdr32 = malloc_w(sizeof(WAVEHDR32) ) ) {
  2268. PWAVEHDR lpwhdr; /* used to simplify ptr stuff later on */
  2269. #if DBG
  2270. AllocWaveCount++;
  2271. dprintf2(( "W>> %8X (%d)", pWavehdr32, AllocWaveCount ));
  2272. #endif
  2273. /* Copy across the wave header stuff. Note that lpwhdr (a
  2274. ** 32 bit ptr to a 32 bit wave header) is used to make the
  2275. ** pointer stuff a bit less hairy.
  2276. **
  2277. ** pWavehdr32->Wavehdr is a 32 bit wave header
  2278. ** pWavehdr32->pWavehdr16 is a 16 bit ptr to a 16 bit wave header
  2279. ** pWavehdr32->pWavehdr32 is a 32 bit ptr to a 16 bit wave header
  2280. */
  2281. lpwhdr = &(pWavehdr32->Wavehdr);
  2282. pWavehdr32->pWavehdr16 = (PWAVEHDR16)DWORD32(parg16->f2);
  2283. pWavehdr32->pWavehdr32 = GETWAVEHDR16(DWORD32(parg16->f2), lpwhdr);
  2284. /*
  2285. ** GETWAVEHDR16 can return NULL, in which case we should set
  2286. ** lpwhdr to NULL too and call waveInAddBuffer only to get the
  2287. ** correct error code.
  2288. */
  2289. if ( pWavehdr32->pWavehdr32 == NULL ) {
  2290. lpwhdr = NULL;
  2291. }
  2292. ul = GETWORD16( (*mmAPI)( HWAVEIN32(parg16->f1),
  2293. lpwhdr, UINT32(parg16->f3) ) );
  2294. /*
  2295. ** If the call fails we need to free the memory we malloc'd
  2296. ** above, as the callback that would have freed it will never
  2297. ** get called.
  2298. **
  2299. */
  2300. if ( ul == MMSYSERR_NOERROR ) {
  2301. /*
  2302. ** Make sure we reflect any changes that waveInAddBuffer did
  2303. ** to the WAVEHDR back to 16 bit land.
  2304. **
  2305. ** This is important because some apps (waveedit) poll the
  2306. ** WHDR_DONE bit !!
  2307. */
  2308. COPY_WAVEINHDR16_FLAGS( pWavehdr32->pWavehdr32,
  2309. pWavehdr32->Wavehdr );
  2310. }
  2311. else {
  2312. #if DBG
  2313. AllocWaveCount--;
  2314. dprintf2(( "W<< \t%8X (%d)", pWavehdr32,
  2315. AllocWaveCount ));
  2316. #endif
  2317. free_w( pWavehdr32 );
  2318. }
  2319. }
  2320. else {
  2321. ul = (ULONG)MMSYSERR_NOMEM;
  2322. }
  2323. }
  2324. trace_wave(( "-> %ld\n", ul ));
  2325. FREEARGPTR(parg16);
  2326. RETURN(ul);
  2327. }
  2328. /**********************************************************************\
  2329. *
  2330. * WMM32waveInStart
  2331. *
  2332. * This function starts input on the specified waveform input device.
  2333. *
  2334. \**********************************************************************/
  2335. ULONG FASTCALL WMM32waveInStart(PVDMFRAME pFrame)
  2336. {
  2337. ULONG ul;
  2338. register PWAVEINSTART16 parg16;
  2339. static FARPROC mmAPI = NULL;
  2340. GET_MULTIMEDIA_API( "waveInStart", mmAPI, MMSYSERR_NODRIVER );
  2341. GETARGPTR(pFrame, sizeof(WAVEINSTART16), parg16);
  2342. trace_wave(( "waveInStart( %x )", WORD32( parg16->f1 ) ));
  2343. ul = GETWORD16((*mmAPI)( HWAVEIN32(parg16->f1) ));
  2344. trace_wave(( "-> %ld\n", ul ));
  2345. FREEARGPTR(parg16);
  2346. RETURN(ul);
  2347. }
  2348. /**********************************************************************\
  2349. *
  2350. * WMM32waveInStop
  2351. *
  2352. * This function stops waveform input.
  2353. *
  2354. \**********************************************************************/
  2355. ULONG FASTCALL WMM32waveInStop(PVDMFRAME pFrame)
  2356. {
  2357. ULONG ul;
  2358. register PWAVEINSTOP16 parg16;
  2359. static FARPROC mmAPI = NULL;
  2360. GET_MULTIMEDIA_API( "waveInStop", mmAPI, MMSYSERR_NODRIVER );
  2361. GETARGPTR(pFrame, sizeof(WAVEINSTOP16), parg16);
  2362. trace_wave(( "waveInStop( %x )", WORD32( parg16->f1 ) ));
  2363. ul = GETWORD16((*mmAPI)( HWAVEIN32(parg16->f1) ));
  2364. trace_wave(( "-> %ld\n", ul ));
  2365. FREEARGPTR(parg16);
  2366. RETURN(ul);
  2367. }
  2368. /**********************************************************************\
  2369. *
  2370. * WMM32waveInReset
  2371. *
  2372. * This function stops input on a given waveform input device and resets the
  2373. * current position to 0. All pending buffers are marked as done and returned
  2374. * to the application.
  2375. *
  2376. \**********************************************************************/
  2377. ULONG FASTCALL WMM32waveInReset(PVDMFRAME pFrame)
  2378. {
  2379. ULONG ul;
  2380. register PWAVEINRESET16 parg16;
  2381. static FARPROC mmAPI = NULL;
  2382. GET_MULTIMEDIA_API( "waveInReset", mmAPI, MMSYSERR_NODRIVER );
  2383. GETARGPTR(pFrame, sizeof(WAVEINRESET16), parg16);
  2384. trace_wave(( "waveInReset( %x )", WORD32( parg16->f1 ) ));
  2385. ul = GETWORD16((*mmAPI)( HWAVEIN32(parg16->f1) ));
  2386. trace_wave(( "-> %ld\n", ul ));
  2387. FREEARGPTR(parg16);
  2388. RETURN(ul);
  2389. }
  2390. /**********************************************************************\
  2391. *
  2392. * WMM32waveInGetPosition
  2393. *
  2394. * This function retrieves the current input position of the specified waveform
  2395. * input device.
  2396. *
  2397. \**********************************************************************/
  2398. ULONG FASTCALL WMM32waveInGetPosition(PVDMFRAME pFrame)
  2399. {
  2400. register PWAVEINGETPOSITION16 parg16;
  2401. MMTIME mmtime;
  2402. ULONG ul = MMSYSERR_INVALPARAM;
  2403. static FARPROC mmAPI = NULL;
  2404. GET_MULTIMEDIA_API( "waveInGetPosition", mmAPI, MMSYSERR_NODRIVER );
  2405. GETARGPTR(pFrame, sizeof(WAVEINGETPOSITION16), parg16);
  2406. trace_wave(( "waveInGetPosition( %x, %x, %x )", WORD32( parg16->f1 ),
  2407. DWORD32( parg16->f2 ), UINT32( parg16->f3 ) ));
  2408. /*
  2409. ** If the given size of the MMTIME structure is too small return an error
  2410. **
  2411. ** There is a problem here on MIPS. For some reason the MIPS
  2412. ** compiler thinks a MMTIME16 structure is 10 bytes big. We
  2413. ** have a pragma in wowmmed.h to align this structure on byte
  2414. ** boundaries therefore I guess this is a compiler bug!
  2415. **
  2416. ** If the input structure is not large enough we return immediately
  2417. */
  2418. #ifdef MIPS_COMPILER_PACKING_BUG
  2419. if ( UINT32(parg16->f3) >= 8 ) {
  2420. #else
  2421. if ( UINT32(parg16->f3) >= sizeof(MMTIME16) ) {
  2422. #endif
  2423. ul = GETMMTIME16( parg16->f2, &mmtime );
  2424. if ( ul == MMSYSERR_NOERROR ) {
  2425. ul = GETWORD16((*mmAPI)( HWAVEIN32(parg16->f1),
  2426. &mmtime, sizeof(MMTIME) ));
  2427. /*
  2428. ** Only update the 16 bit structure if the call returns success
  2429. **
  2430. */
  2431. if ( ul == MMSYSERR_NOERROR ) {
  2432. ul = PUTMMTIME16( parg16->f2, &mmtime );
  2433. }
  2434. }
  2435. }
  2436. trace_wave(( "-> %ld\n", ul ));
  2437. FREEARGPTR(parg16);
  2438. RETURN(ul);
  2439. }
  2440. /**********************************************************************\
  2441. *
  2442. * WMM32waveInGetID
  2443. *
  2444. * This function gets the device ID for a waveform input device.
  2445. *
  2446. \**********************************************************************/
  2447. ULONG FASTCALL WMM32waveInGetID(PVDMFRAME pFrame)
  2448. {
  2449. register PWAVEINGETID16 parg16;
  2450. ULONG ul;
  2451. UINT dwDeviceID32;
  2452. LPWORD lpwDeviceID16;
  2453. static FARPROC mmAPI = NULL;
  2454. GET_MULTIMEDIA_API( "waveInGetID", mmAPI, MMSYSERR_NODRIVER );
  2455. GETARGPTR(pFrame, sizeof(WAVEINGETID16), parg16);
  2456. trace_wave(( "waveInGetID( %x, %x )", WORD32( parg16->f1 ),
  2457. DWORD32( parg16->f2 ) ));
  2458. ul = GETWORD16((*mmAPI)( HWAVEIN32(parg16->f1), &dwDeviceID32 ));
  2459. /*
  2460. ** Only copy the ID back to 16 bit space if the call was sucessful
  2461. **
  2462. */
  2463. if ( ul == MMSYSERR_NOERROR ) {
  2464. MMGETOPTPTR( parg16->f2, sizeof(WORD), lpwDeviceID16 );
  2465. if ( lpwDeviceID16 ) {
  2466. STOREWORD ( *lpwDeviceID16, dwDeviceID32 );
  2467. FLUSHVDMPTR( DWORD32(parg16->f2), sizeof(WORD), lpwDeviceID16 );
  2468. FREEVDMPTR ( lpwDeviceID16 );
  2469. }
  2470. else {
  2471. ul = MMSYSERR_INVALPARAM;
  2472. }
  2473. }
  2474. trace_wave(( "-> %ld\n", ul ));
  2475. FREEARGPTR(parg16);
  2476. RETURN(ul);
  2477. }
  2478. /**********************************************************************\
  2479. *
  2480. * WMM32waveInMessage
  2481. *
  2482. * This function sends a message to a waveform input device.
  2483. *
  2484. \**********************************************************************/
  2485. ULONG FASTCALL WMM32waveInMessage(PVDMFRAME pFrame)
  2486. {
  2487. ULONG ul;
  2488. register PWAVEINMESSAGE3216 parg16;
  2489. static FARPROC mmAPI = NULL;
  2490. GET_MULTIMEDIA_API( "waveInMessage", mmAPI, MMSYSERR_NODRIVER );
  2491. GETARGPTR(pFrame, sizeof(WAVEINMESSAGE16), parg16);
  2492. trace_wave(( "waveInMessage( %x, %x, %x, %x )", WORD32( parg16->f1 ),
  2493. UINT32( parg16->f2 ), DWORD32( parg16->f3 ),
  2494. DWORD32( parg16->f4 ) ));
  2495. if ( (UINT32(parg16->f2) >= DRV_BUFFER_LOW)
  2496. && (UINT32(parg16->f2) <= DRV_BUFFER_HIGH) ) {
  2497. LPDWORD lpdwParam1;
  2498. GETMISCPTR(parg16->f3, lpdwParam1);
  2499. ul = GETDWORD16((*mmAPI)( HWAVEIN32(parg16->f1), UINT32(parg16->f2),
  2500. (DWORD)lpdwParam1, DWORD32(parg16->f4) ));
  2501. FREEMISCPTR(lpdwParam1);
  2502. } else {
  2503. ul = GETDWORD16((*mmAPI)( HWAVEIN32(parg16->f1),
  2504. MAKELONG( WORD32(parg16->f2), 0xFFFF ),
  2505. DWORD32(parg16->f3), DWORD32(parg16->f4) ));
  2506. }
  2507. trace_wave(( "-> %ld\n", ul ));
  2508. FREEARGPTR(parg16);
  2509. RETURN(ul);
  2510. }
  2511. /**********************************************************************\
  2512. *
  2513. * W32CommonDeviceOpen
  2514. *
  2515. * This routine is the callback which is ALWAYS called by wave and midi
  2516. * functions. This is done to ensure that the XXXXHDR structure keeps
  2517. * getting copied back from 32 bit space to 16 bit, as it contains flags
  2518. * which the application is liable to keep checking.
  2519. *
  2520. * The way this whole business works is that the wave/midi data stays in 16
  2521. * bit space, but the XXXXHDR is copied to the 32 bit side, with the
  2522. * address of the data thunked accordingly so that Robin's device driver
  2523. * can still get at the data but we don't have the performance penalty of
  2524. * copying it back and forth all the time, not least because it is liable
  2525. * to be rather large...
  2526. *
  2527. * It also handles the tidying up of memory which is reserved to store
  2528. * the XXXXHDR, and the instance data (HWND/Callback address; instance
  2529. * data; flags) which the xxxxOpen calls pass to this routine, enabling
  2530. * it to forward messages or call callback as required.
  2531. *
  2532. * This routine handles all the messages that get sent from Robin's
  2533. * driver, and in fact thunks them back to the correct 16 bit form. In
  2534. * theory there should be no MM_ format messages from the 16 bit side, so
  2535. * I can zap 'em out of WMSG16. However the 32 bit side should thunk the
  2536. * mesages correctly and forward them to the 16 bit side and thence to
  2537. * the app.
  2538. *
  2539. * However... I discover that somewhere in the system the wParam Msg
  2540. * parameter (which is 32 bits in Win32 and 16 bits in Win16) is having
  2541. * the top 16 bits trashed (zeroed actually). As I pass a 32 bit handle
  2542. * in it, to be thunked in WMDISP32 back to a 16 bit handle, the loss of
  2543. * the top 16 bits is not conducive to correct thunking. Soooo, no more
  2544. * thunking in WMDISP32 - I do it all here and Post the correct 16 bit
  2545. * message.
  2546. *
  2547. * Hence WMTBL32 (the 32 bit message switch table) contains the
  2548. * NoThunking entry for all the MM_ messages - I'll do 'em myself thank
  2549. * you.
  2550. *
  2551. *
  2552. * For the MM_WIM_DATA and MM_WOM_DONE message dwParam1 points to the
  2553. * following data struture.
  2554. *
  2555. * P32HDR is a 32 bit pointer to the original 16 bit header
  2556. * P16HDR is a 16 bit far pointer to the original 16 bit header
  2557. *
  2558. * If we need to refernece the original header we must do via the
  2559. * P32HDR pointer.
  2560. *
  2561. * +---------+
  2562. * | P32HDR +----->+---------+
  2563. * +---------+ | 16 bit |
  2564. * | P16HDR +----->| | This is the original
  2565. * dwParam1 ----->+---------+ | Wave | wave header passed to
  2566. * | 32 bit | | Header | us by the Win 16 app.
  2567. * This is the 32 | | | |
  2568. * bit wave | Wave | +---------+
  2569. * header that we | Header |
  2570. * thunked at | |
  2571. * earlier. +---------+
  2572. *
  2573. *
  2574. * We must ensure that the 32 bit structure is completely hidden from the
  2575. * 16 bit application, ie. the 16 bit app only see's the wave header that it
  2576. * passed to us earlier.
  2577. *
  2578. *
  2579. * NOTE: dwParam2 is junk
  2580. *
  2581. *
  2582. \**********************************************************************/
  2583. VOID W32CommonDeviceOpen( HANDLE handle, UINT uMsg, DWORD dwInstance,
  2584. DWORD dwParam1, DWORD dwParam2 )
  2585. {
  2586. PWAVEHDR32 pWavehdr32;
  2587. PMIDIHDR32 pMidihdr32;
  2588. PINSTANCEDATA pInstanceData;
  2589. WORD Handle;
  2590. switch (uMsg) {
  2591. /* ------------------------------------------------------------
  2592. ** MIDI INPUT MESSAGES
  2593. ** ------------------------------------------------------------
  2594. */
  2595. case MM_MIM_LONGDATA:
  2596. /*
  2597. ** This message is sent to a window when an input buffer has been
  2598. ** filled with MIDI system-exclusive data and is being returned to
  2599. ** the application.
  2600. */
  2601. case MM_MIM_LONGERROR:
  2602. /*
  2603. ** This message is sent to a window when an invalid MIDI
  2604. ** system-exclusive message is received.
  2605. */
  2606. pMidihdr32 = (PMIDIHDR32)( (PBYTE)dwParam1 - (sizeof(PMIDIHDR16) * 2) );
  2607. WOW32ASSERT( pMidihdr32 );
  2608. COPY_MIDIINHDR16_FLAGS( pMidihdr32->pMidihdr32, pMidihdr32->Midihdr );
  2609. dwParam1 = (DWORD)pMidihdr32->pMidihdr16;
  2610. case MM_MIM_DATA:
  2611. /*
  2612. ** This message is sent to a window when a MIDI message is
  2613. ** received by a MIDI input device.
  2614. */
  2615. case MM_MIM_ERROR:
  2616. /*
  2617. ** This message is sent to a window when an invalid MIDI message
  2618. ** is received.
  2619. */
  2620. case MM_MIM_OPEN:
  2621. /*
  2622. ** This message is sent to a window when a MIDI input device is opened.
  2623. ** We process this message the same way as MM_MIM_CLOSE (see below)
  2624. */
  2625. case MM_MIM_CLOSE:
  2626. /*
  2627. ** This message is sent to a window when a MIDI input device is
  2628. ** closed. The device handle is no longer valid once this message
  2629. ** has been sent.
  2630. */
  2631. Handle = GETHMIDIIN16(handle);
  2632. break;
  2633. /* ------------------------------------------------------------
  2634. ** MIDI OUTPUT MESSAGES
  2635. ** ------------------------------------------------------------
  2636. */
  2637. case MM_MOM_DONE:
  2638. /*
  2639. ** This message is sent to a window when the specified
  2640. ** system-exclusive buffer has been played and is being returned to
  2641. ** the application.
  2642. */
  2643. pMidihdr32 = (PMIDIHDR32)( (PBYTE)dwParam1 - (sizeof(PMIDIHDR16) * 2) );
  2644. WOW32ASSERT( pMidihdr32 );
  2645. COPY_MIDIOUTHDR16_FLAGS( pMidihdr32->pMidihdr32, pMidihdr32->Midihdr );
  2646. dwParam1 = (DWORD)pMidihdr32->pMidihdr16;
  2647. case MM_MOM_OPEN:
  2648. /*
  2649. ** This message is sent to a window when a MIDI output device is opened.
  2650. ** We process this message the same way as MM_MOM_CLOSE (see below)
  2651. */
  2652. case MM_MOM_CLOSE:
  2653. /*
  2654. ** This message is sent to a window when a MIDI output device is
  2655. ** closed. The device handle is no longer valid once this message
  2656. ** has been sent.
  2657. */
  2658. Handle = GETHMIDIOUT16(handle);
  2659. break;
  2660. /* ------------------------------------------------------------
  2661. ** WAVE INPUT MESSAGES
  2662. ** ------------------------------------------------------------
  2663. */
  2664. case MM_WIM_DATA:
  2665. /*
  2666. ** This message is sent to a window when waveform data is present
  2667. ** in the input buffer and the buffer is being returned to the
  2668. ** application. The message can be sent either when the buffer
  2669. ** is full, or after the waveInReset function is called.
  2670. */
  2671. pWavehdr32 = (PWAVEHDR32)( (PBYTE)dwParam1 - (sizeof(PWAVEHDR16) * 2));
  2672. WOW32ASSERT( pWavehdr32 );
  2673. COPY_WAVEINHDR16_FLAGS( pWavehdr32->pWavehdr32, pWavehdr32->Wavehdr );
  2674. dwParam1 = (DWORD)pWavehdr32->pWavehdr16;
  2675. case MM_WIM_OPEN:
  2676. /*
  2677. ** This message is sent to a window when a waveform input
  2678. ** device is opened.
  2679. **
  2680. ** We process this message the same way as MM_WIM_CLOSE (see below)
  2681. */
  2682. case MM_WIM_CLOSE:
  2683. /*
  2684. ** This message is sent to a window when a waveform input device is
  2685. ** closed. The device handle is no longer valid once the message has
  2686. ** been sent.
  2687. */
  2688. Handle = GETHWAVEIN16(handle);
  2689. break;
  2690. /* ------------------------------------------------------------
  2691. ** WAVE OUTPUT MESSAGES
  2692. ** ------------------------------------------------------------
  2693. */
  2694. case MM_WOM_DONE:
  2695. /*
  2696. ** This message is sent to a window when the specified output
  2697. ** buffer is being returned to the application. Buffers are returned
  2698. ** to the application when they have been played, or as the result of
  2699. ** a call to waveOutReset.
  2700. */
  2701. pWavehdr32 = (PWAVEHDR32)( (PBYTE)dwParam1 - (sizeof(PWAVEHDR16) * 2));
  2702. WOW32ASSERT( pWavehdr32 );
  2703. COPY_WAVEOUTHDR16_FLAGS( pWavehdr32->pWavehdr32, pWavehdr32->Wavehdr );
  2704. dwParam1 = (DWORD)pWavehdr32->pWavehdr16;
  2705. case MM_WOM_OPEN:
  2706. /*
  2707. ** This message is sent to a window when a waveform output device
  2708. ** is opened.
  2709. **
  2710. ** We process this message the same way as MM_WOM_CLOSE (see below)
  2711. */
  2712. case MM_WOM_CLOSE:
  2713. /*
  2714. ** This message is sent to a window when a waveform output device
  2715. ** is closed. The device handle is no longer valid once the
  2716. ** message has been sent.
  2717. */
  2718. Handle = GETHWAVEOUT16(handle);
  2719. break;
  2720. #if DBG
  2721. default:
  2722. dprintf(( "Unknown message received in CallBack function " ));
  2723. dprintf(( "best call StephenE or MikeTri" ));
  2724. return;
  2725. #endif
  2726. }
  2727. /*
  2728. ** Now make the CallBack, or PostMessage call depending
  2729. ** on the flags passed to original (wave|midi)(In|Out)Open call.
  2730. */
  2731. pInstanceData = (PINSTANCEDATA)dwInstance;
  2732. WOW32ASSERT( pInstanceData );
  2733. switch (pInstanceData->dwFlags & CALLBACK_TYPEMASK) {
  2734. case CALLBACK_WINDOW:
  2735. dprintf2(( "WINDOW callback identified" ));
  2736. PostMessage( HWND32( LOWORD(pInstanceData->dwCallback) ),
  2737. uMsg, Handle, dwParam1 );
  2738. break;
  2739. case CALLBACK_TASK:
  2740. case CALLBACK_FUNCTION: {
  2741. DWORD dwFlags;
  2742. if ( (pInstanceData->dwFlags & CALLBACK_TYPEMASK) == CALLBACK_TASK ) {
  2743. dprintf2(( "TASK callback identified" ));
  2744. dwFlags = DCB_TASK;
  2745. }
  2746. else {
  2747. dprintf2(( "FUNCTION callback identified" ));
  2748. dwFlags = DCB_FUNCTION;
  2749. }
  2750. WOW32DriverCallback( pInstanceData->dwCallback,
  2751. dwFlags,
  2752. Handle,
  2753. LOWORD( uMsg ),
  2754. pInstanceData->dwCallbackInstance,
  2755. dwParam1,
  2756. dwParam2 );
  2757. }
  2758. break;
  2759. }
  2760. /*
  2761. ** Now, free up any storage that was allocated during the waveOutOpen
  2762. ** and waveInOpen. This should only be freed during the MM_WOM_CLOSE or
  2763. ** MM_WIM_CLOSE message.
  2764. **
  2765. ** Also, free up any storage that was allocated during the waveOutWrite
  2766. ** and waveInAddBuffer call. This should only be freed during the
  2767. ** MM_WOM_DONE or MM_WIM_DATA message.
  2768. */
  2769. switch (uMsg) {
  2770. case MM_MIM_CLOSE:
  2771. case MM_MOM_CLOSE:
  2772. case MM_WIM_CLOSE:
  2773. case MM_WOM_CLOSE:
  2774. dprintf2(( "W32CommonDeviceOpen: Freeing device open buffer at %X",
  2775. pInstanceData ));
  2776. dprintf2(( "Alloc Midi count = %d", AllocMidiCount ));
  2777. dprintf2(( "Alloc Wave count = %d", AllocWaveCount ));
  2778. free_w( pInstanceData );
  2779. FREEHWAVEIN16( Handle );
  2780. break;
  2781. case MM_WIM_DATA:
  2782. case MM_WOM_DONE:
  2783. # if DBG
  2784. AllocWaveCount--;
  2785. dprintf2(( "W<< \t%8X (%d)", pWavehdr32, AllocWaveCount ));
  2786. # endif
  2787. free_w( pWavehdr32 );
  2788. break;
  2789. case MM_MIM_LONGDATA:
  2790. case MM_MIM_LONGERROR:
  2791. case MM_MOM_DONE:
  2792. # if DBG
  2793. AllocMidiCount--;
  2794. dprintf2(( "M<< \t%8X (%d)", pMidihdr32, AllocMidiCount ));
  2795. # endif
  2796. free_w( pMidihdr32 );
  2797. break;
  2798. }
  2799. }
  2800. #endif