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.

762 lines
23 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WMMSTRUC.C
  8. *
  9. *
  10. * MultiMedia Structure copying functions (modelled after WSTRUC.C by jeffpar)
  11. *
  12. * For input structures, there are GETxxxx16 macros; for output structures
  13. * there are PUTxxxx16 macros. Most or all of these macros will simply call
  14. * the corresponding function below.
  15. *
  16. *
  17. * WOW32 16-bit MultiMedia structure conversion support
  18. *
  19. * History:
  20. * Created 13-Feb-1992 by Mike Tricker (miketri)
  21. * Changed 16-Jul-1992 by Mike Tricker (miketri) Sorted out the Caps structure copies
  22. * Changed 08-Oct-1992 by StephenE Made the thunks safe on MIPS
  23. *
  24. * Basically doing a GETVDMPTR of a null pointer is bad on MIPS, so is
  25. * trying to get a pointer to zero bytes. On Intel these GETXXX macros
  26. * don't really do anything.
  27. *
  28. --*/
  29. #include "precomp.h"
  30. #pragma hdrstop
  31. #if 0
  32. MODNAME(wmmstruc.c);
  33. /**********************************************************************\
  34. * getmmtime16
  35. *
  36. * Thunks an MMTIME structure from 16 bit to 32 bit space.
  37. *
  38. * Used by:
  39. * waveOutGetPosition
  40. * waveInGetPosition
  41. * timeGetSystemTime
  42. *
  43. \**********************************************************************/
  44. ULONG getmmtime16 (VPMMTIME16 vpmmt, LPMMTIME lpmmt)
  45. {
  46. register PMMTIME16 pmmt16;
  47. #ifdef MIPS_COMPILER_PACKING_BUG
  48. MMGETOPTPTR(vpmmt, 8, pmmt16);
  49. #else
  50. MMGETOPTPTR(vpmmt, sizeof(MMTIME16), pmmt16);
  51. #endif
  52. if ( pmmt16 == NULL ) {
  53. dprintf1(( "getmmtime16 MMGETOPTPTR returned a NULL pointer" ));
  54. return MMSYSERR_INVALPARAM;
  55. }
  56. lpmmt->wType = (UINT)FETCHWORD(pmmt16->wType);
  57. switch ( lpmmt->wType ) {
  58. case TIME_MS:
  59. lpmmt->u.ms = FETCHDWORD(pmmt16->u.ms);
  60. break;
  61. case TIME_SAMPLES:
  62. lpmmt->u.sample = FETCHDWORD(pmmt16->u.sample);
  63. break;
  64. case TIME_BYTES:
  65. lpmmt->u.cb = FETCHDWORD(pmmt16->u.cb);
  66. break;
  67. case TIME_SMPTE:
  68. lpmmt->u.smpte.hour = pmmt16->u.smpte.hour;
  69. lpmmt->u.smpte.min = pmmt16->u.smpte.min;
  70. lpmmt->u.smpte.sec = pmmt16->u.smpte.sec;
  71. lpmmt->u.smpte.frame = pmmt16->u.smpte.frame;
  72. lpmmt->u.smpte.fps = pmmt16->u.smpte.fps;
  73. lpmmt->u.smpte.dummy = pmmt16->u.smpte.dummy;
  74. break;
  75. case TIME_MIDI:
  76. lpmmt->u.midi.songptrpos = FETCHDWORD(pmmt16->u.midi.songptrpos);
  77. break;
  78. }
  79. FREEVDMPTR(pmmt16);
  80. return MMSYSERR_NOERROR;
  81. }
  82. /**********************************************************************\
  83. * Thunks an MMTIME structure from 32 bit back to 16 bit space.
  84. *
  85. * Used by:
  86. * waveOutGetPosition
  87. * waveInGetPosition
  88. * timeGetSystemTime
  89. \**********************************************************************/
  90. ULONG putmmtime16 (VPMMTIME16 vpmmt, LPMMTIME lpmmt)
  91. {
  92. register PMMTIME16 pmmt16;
  93. #ifdef MIPS_COMPILER_PACKING_BUG
  94. MMGETOPTPTR(vpmmt, 8, pmmt16);
  95. #else
  96. MMGETOPTPTR(vpmmt, sizeof(MMTIME16), pmmt16);
  97. #endif
  98. if ( pmmt16 == NULL ) {
  99. dprintf1(( "putmmtime16 MMGETOPTPTR returned a NULL pointer" ));
  100. return MMSYSERR_INVALPARAM;
  101. }
  102. STOREWORD(pmmt16->wType, (WORD)lpmmt->wType);
  103. switch ( pmmt16->wType ) {
  104. case TIME_MS:
  105. STOREDWORD(pmmt16->u.ms, lpmmt->u.ms);
  106. dprintf2(( "Time in MS is %x", lpmmt->u.ms ));
  107. break;
  108. case TIME_SAMPLES:
  109. STOREDWORD(pmmt16->u.sample, lpmmt->u.sample);
  110. dprintf2(( "Time in samples is %x", lpmmt->u.sample ));
  111. break;
  112. case TIME_BYTES:
  113. STOREDWORD(pmmt16->u.cb, lpmmt->u.cb);
  114. dprintf2(( "Time in bytes is %x", lpmmt->u.cb ));
  115. break;
  116. case TIME_SMPTE:
  117. pmmt16->u.smpte.hour = lpmmt->u.smpte.hour;
  118. pmmt16->u.smpte.min = lpmmt->u.smpte.min;
  119. pmmt16->u.smpte.sec = lpmmt->u.smpte.sec;
  120. pmmt16->u.smpte.frame = lpmmt->u.smpte.frame;
  121. pmmt16->u.smpte.fps = lpmmt->u.smpte.fps;
  122. pmmt16->u.smpte.dummy = lpmmt->u.smpte.dummy;
  123. break;
  124. case TIME_MIDI:
  125. STOREDWORD(pmmt16->u.midi.songptrpos, lpmmt->u.midi.songptrpos);
  126. dprintf2(( "Time in midi is %x", lpmmt->u.midi.songptrpos ));
  127. break;
  128. }
  129. #ifdef MIPS_COMPILER_PACKING_BUG
  130. FLUSHVDMPTR(vpmmt, 8, pmmt16);
  131. #else
  132. FLUSHVDMPTR(vpmmt, sizeof(MMTIME16), pmmt16);
  133. #endif
  134. FREEVDMPTR(pmmt16);
  135. return MMSYSERR_NOERROR;
  136. }
  137. /**********************************************************************\
  138. * Thunks a WAVEHDR structure from 16 bit to 32 bit space.
  139. *
  140. * Used by:
  141. * waveOutPrepareHeader
  142. * waveOutUnprepareHeader
  143. * waveOutWrite
  144. * waveInPrepareHeader
  145. * waveInUnprepareHeader
  146. * waveInAddBuffer
  147. *
  148. * Returns a 32 bit pointer to the 16 bit wave header. This wave header
  149. * should have been locked down by wave(In|Out)PrepareHeader. Therefore,
  150. * it is to store this pointer for use during the WOM_DONE callback message.
  151. *
  152. * With the WAVEHDR and MIDIHDR structs I am assured by Robin that the ->lpNext
  153. * field is only used by the driver, and is therefore in 32 bit space. It
  154. * therefore doesn't matter what gets passed back and forth (I hope !).
  155. *
  156. \**********************************************************************/
  157. PWAVEHDR16 getwavehdr16( VPWAVEHDR16 vpwhdr, LPWAVEHDR lpwhdr )
  158. {
  159. register PWAVEHDR16 pwhdr16;
  160. MMGETOPTPTR(vpwhdr, sizeof(WAVEHDR16), pwhdr16);
  161. if ( pwhdr16 == NULL ) {
  162. dprintf1(( "getwavehdr16 MMGETOPTPTR returned an invalid pointer" ));
  163. return NULL;
  164. }
  165. if ( HIWORD(FETCHDWORD( pwhdr16->lpData )) != 0 ) {
  166. GETMISCPTR(pwhdr16->lpData, lpwhdr->lpData);
  167. }
  168. else {
  169. dprintf1(( "getwavehdr16 passed an invalid pointer to data" ));
  170. lpwhdr->lpData = (VPSTR)NULL;
  171. }
  172. lpwhdr->dwBufferLength = FETCHDWORD(pwhdr16->dwBufferLength);
  173. dprintf4(( "getwavehdr16: buffer length = %X", lpwhdr->dwBufferLength ));
  174. lpwhdr->dwBytesRecorded = FETCHDWORD(pwhdr16->dwBytesRecorded);
  175. lpwhdr->dwUser = FETCHDWORD(pwhdr16->dwUser);
  176. lpwhdr->dwFlags = FETCHDWORD(pwhdr16->dwFlags);
  177. lpwhdr->dwLoops = FETCHDWORD(pwhdr16->dwLoops);
  178. lpwhdr->lpNext = (PWAVEHDR)FETCHDWORD(pwhdr16->lpNext);
  179. lpwhdr->reserved = FETCHDWORD(pwhdr16->reserved);
  180. return pwhdr16;
  181. }
  182. /**********************************************************************\
  183. * Thunks a WAVEHDR structure from 32 bit back to 16 bit space.
  184. *
  185. * Used by:
  186. * waveOutPrepareHeader
  187. * waveOutUnprepareHeader
  188. * waveOutWrite
  189. * waveInPrepareHeader
  190. * waveInUnprepareHeader
  191. * waveInAddBuffer
  192. *
  193. *
  194. * With the WAVEHDR and MIDIHDR structs I am assured by Robin that the ->lpNext
  195. * field is only used by the driver, and is therefore in 32 bit space. It
  196. * therefore doesn't matter what gets passed back and forth (I hope !).
  197. *
  198. \**********************************************************************/
  199. VOID putwavehdr16 (VPWAVEHDR16 vpwhdr, LPWAVEHDR lpwhdr)
  200. {
  201. register PWAVEHDR16 pwhdr16;
  202. MMGETOPTPTR(vpwhdr, sizeof(WAVEHDR16), pwhdr16);
  203. if ( pwhdr16 == NULL ) {
  204. dprintf1(( "getwavehdr16 MMGETOPTPTR returned a NULL pointer" ));
  205. return;
  206. }
  207. STOREDWORD(pwhdr16->dwBufferLength, lpwhdr->dwBufferLength);
  208. STOREDWORD(pwhdr16->dwBytesRecorded, lpwhdr->dwBytesRecorded);
  209. STOREDWORD(pwhdr16->dwUser, lpwhdr->dwUser);
  210. STOREDWORD(pwhdr16->dwFlags, lpwhdr->dwFlags);
  211. STOREDWORD(pwhdr16->dwLoops, lpwhdr->dwLoops);
  212. STOREDWORD(pwhdr16->lpNext, lpwhdr->lpNext);
  213. STOREDWORD(pwhdr16->reserved, lpwhdr->reserved);
  214. FLUSHVDMPTR(vpwhdr, sizeof(WAVEHDR16), pwhdr16);
  215. FREEVDMPTR(pwhdr16);
  216. }
  217. /**********************************************************************\
  218. * Thunks a WAVEOUTCAPS structure from 32 bit back to 16 bit space.
  219. *
  220. * Used by:
  221. * waveOutGetDevCaps
  222. *
  223. * Remember that the ->vDriverVersion is a WORD in 16bit land and a UINT in
  224. * 32 bit. This applies to WAVEIN/OUTCAPS, MIDIIN/OUTCAPS and AUXCAPS.
  225. *
  226. \**********************************************************************/
  227. ULONG putwaveoutcaps16 (VPWAVEOUTCAPS16 vpwoc, LPWAVEOUTCAPS lpwoc, UINT uSize)
  228. {
  229. INT i;
  230. WAVEOUTCAPS16 Temp;
  231. PWAVEOUTCAPS16 pwoc16;
  232. /*
  233. ** Just in case the app specified a NULL pointer. We have already
  234. ** validated that uSize is not zero.
  235. */
  236. MMGETOPTPTR( vpwoc, min(uSize, sizeof(WAVEOUTCAPS16)), pwoc16 );
  237. if ( pwoc16 == NULL ) {
  238. dprintf1(( "putwaveoutcaps16 MMGETOPTPTR returned a NULL pointer" ));
  239. return MMSYSERR_INVALPARAM;
  240. }
  241. STOREWORD(Temp.wMid, lpwoc->wMid);
  242. STOREWORD(Temp.wPid, lpwoc->wPid);
  243. STOREWORD(Temp.vDriverVersion, (WORD)lpwoc->vDriverVersion);
  244. /*
  245. ** The product name string should be null terminated, but we want
  246. ** the whole string anyway, so copy the whole MAXPNAMELEN bytes.
  247. */
  248. i = 0;
  249. while (i < MAXPNAMELEN) {
  250. Temp.szPname[i] = lpwoc->szPname[i++];
  251. }
  252. STOREDWORD(Temp.dwFormats, lpwoc->dwFormats);
  253. STOREWORD(Temp.wChannels, lpwoc->wChannels);
  254. STOREDWORD(Temp.dwSupport, lpwoc->dwSupport);
  255. RtlCopyMemory( (LPVOID)pwoc16, &Temp, min(uSize, sizeof(WAVEOUTCAPS16)) );
  256. FLUSHVDMPTR(vpwoc, min(uSize, sizeof(WAVEOUTCAPS16)), pwoc16);
  257. FREEVDMPTR(pwoc16);
  258. return MMSYSERR_NOERROR;
  259. }
  260. /**********************************************************************\
  261. * Thunks a WAVEINCAPS structure from 32 bit back to 16 bit space.
  262. *
  263. * Used by:
  264. * waveInGetDevCaps
  265. *
  266. * Remember that the ->vDriverVersion is a WORD in 16bit land and a UINT in
  267. * 32 bit. This applies to WAVEIN/OUTCAPS, MIDIIN/OUTCAPS and AUXCAPS.
  268. *
  269. \**********************************************************************/
  270. ULONG putwaveincaps16 (VPWAVEINCAPS16 vpwic, LPWAVEINCAPS lpwic, UINT uSize)
  271. {
  272. INT i;
  273. WAVEINCAPS16 Temp;
  274. PWAVEINCAPS16 pwic16;
  275. /*
  276. ** Just in case the app specified a NULL pointer. We have already
  277. ** validated that uSize is not zero.
  278. */
  279. MMGETOPTPTR(vpwic, min(uSize, sizeof(WAVEINCAPS16)), pwic16);
  280. if ( pwic16 == NULL ) {
  281. dprintf1(( "putwaveincaps16 MMGETOPTPTR returned a NULL pointer" ));
  282. return MMSYSERR_INVALPARAM;
  283. }
  284. STOREWORD(Temp.wMid, lpwic->wMid);
  285. STOREWORD(Temp.wPid, lpwic->wPid);
  286. STOREWORD(Temp.vDriverVersion, (WORD)lpwic->vDriverVersion);
  287. /*
  288. ** The product name string should be null terminated,
  289. ** but we want the whole string anyway, so copy the whole
  290. ** MAXPNAMELEN bytes.
  291. */
  292. i = 0;
  293. while (i < MAXPNAMELEN) {
  294. Temp.szPname[i] = lpwic->szPname[i++];
  295. }
  296. STOREDWORD(Temp.dwFormats, lpwic->dwFormats);
  297. STOREWORD(Temp.wChannels, lpwic->wChannels);
  298. RtlCopyMemory( (LPVOID)pwic16, &Temp, min(uSize, sizeof(WAVEINCAPS16)) );
  299. FLUSHVDMPTR(vpwic, min(uSize, sizeof(WAVEINCAPS16)), pwic16);
  300. FREEVDMPTR(pwic16);
  301. return MMSYSERR_NOERROR;
  302. }
  303. /**********************************************************************\
  304. * Thunks a MIDIHDR structure from 16 bit to 32 bit space.
  305. *
  306. * Used by:
  307. * midiOutLongMsg
  308. * midiInAddBuffer
  309. * midiOutPrepareHdr
  310. * midiOutUnprepareHdr
  311. * midiInPrepareHdr
  312. * midiInUnprepareHdr
  313. *
  314. \**********************************************************************/
  315. PMIDIHDR16 getmidihdr16 (VPMIDIHDR16 vpmhdr, LPMIDIHDR lpmhdr)
  316. {
  317. PMIDIHDR16 pmhdr16;
  318. MMGETOPTPTR(vpmhdr, sizeof(MIDIHDR16), pmhdr16);
  319. if ( pmhdr16 == NULL ) {
  320. dprintf1(( "getmidihdr MMGETOPTPTR returned a NULL pointer" ));
  321. return NULL;
  322. }
  323. if ( HIWORD(FETCHDWORD( pmhdr16->lpData )) != 0 ) {
  324. GETMISCPTR(pmhdr16->lpData, lpmhdr->lpData);
  325. }
  326. else {
  327. dprintf1(( "getmidihdr16 passed a NULL pointer to data" ));
  328. lpmhdr->lpData = (VPSTR)NULL;
  329. }
  330. lpmhdr->dwBufferLength = FETCHDWORD(pmhdr16->dwBufferLength);
  331. dprintf4(( "getmidihdr16: buffer length = %X", lpmhdr->dwBufferLength ));
  332. lpmhdr->dwBytesRecorded = FETCHDWORD(pmhdr16->dwBytesRecorded);
  333. lpmhdr->dwUser = FETCHDWORD(pmhdr16->dwUser);
  334. lpmhdr->dwFlags = FETCHDWORD(pmhdr16->dwFlags);
  335. lpmhdr->lpNext = (PMIDIHDR)FETCHDWORD(pmhdr16->lpNext);
  336. lpmhdr->reserved = FETCHDWORD(pmhdr16->reserved);
  337. return pmhdr16;
  338. }
  339. /**********************************************************************\
  340. * Thunks a MIDIHDR structure from 32 bit to 16 bit space.
  341. *
  342. * Used by:
  343. * midiOutLongMsg
  344. * midiInAddBuffer
  345. * midiOutPrepareHdr
  346. * midiOutUnprepareHdr
  347. * midiInPrepareHdr
  348. * midiInUnprepareHdr
  349. *
  350. \**********************************************************************/
  351. VOID putmidihdr16 (VPMIDIHDR16 vpmhdr, LPMIDIHDR lpmhdr)
  352. {
  353. register PMIDIHDR16 pmhdr16;
  354. MMGETOPTPTR(vpmhdr, sizeof(MIDIHDR16), pmhdr16);
  355. if ( pmhdr16 == NULL ) {
  356. dprintf1(( "putmidihdr MMGETOPTPTR returned a NULL pointer" ));
  357. return;
  358. }
  359. STOREDWORD(pmhdr16->dwBufferLength, lpmhdr->dwBufferLength);
  360. STOREDWORD(pmhdr16->dwBytesRecorded, lpmhdr->dwBytesRecorded);
  361. STOREDWORD(pmhdr16->dwUser, lpmhdr->dwUser);
  362. STOREDWORD(pmhdr16->dwFlags, lpmhdr->dwFlags);
  363. STOREDWORD(pmhdr16->lpNext, lpmhdr->lpNext);
  364. STOREDWORD(pmhdr16->reserved, lpmhdr->reserved);
  365. FLUSHVDMPTR(vpmhdr, sizeof(MIDIHDR16), pmhdr16);
  366. FREEVDMPTR(pmhdr16);
  367. }
  368. /**********************************************************************\
  369. * Thunks an AUXCAPS structure from 32 bit back to 16 bit space.
  370. *
  371. * Used by:
  372. * auxGetDevCaps
  373. *
  374. * Remember that the ->vDriverVersion is a WORD in 16bit land and a UINT in
  375. * 32 bit. This applies to WAVEIN/OUTCAPS, MIDIIN/OUTCAPS and AUXCAPS.
  376. *
  377. \**********************************************************************/
  378. ULONG putauxcaps16 (VPAUXCAPS16 vpauxc, LPAUXCAPS lpauxc, UINT uSize)
  379. {
  380. INT i;
  381. AUXCAPS16 Temp;
  382. PAUXCAPS16 pauxc16;
  383. /*
  384. ** Just in case the app specified a NULL pointer. We have already
  385. ** validated that uSize is not zero.
  386. */
  387. MMGETOPTPTR(vpauxc, min(uSize, sizeof(AUXCAPS16)), pauxc16);
  388. if ( pauxc16 == NULL ) {
  389. dprintf1(( "putauxcaps16 MMGETOPTPTR returned a NULL pointer" ));
  390. return MMSYSERR_INVALPARAM;
  391. }
  392. STOREWORD(Temp.wMid, lpauxc->wMid);
  393. STOREWORD(Temp.wPid, lpauxc->wPid);
  394. STOREWORD(Temp.vDriverVersion, (WORD)lpauxc->vDriverVersion);
  395. /*
  396. ** The product name string should be null terminated,
  397. ** but we want the whole string anyway, so copy the whole
  398. ** MAXPNAMELEN bytes.
  399. */
  400. i = 0;
  401. while (i < MAXPNAMELEN) {
  402. Temp.szPname[i] = lpauxc->szPname[i++];
  403. }
  404. STOREWORD(Temp.wTechnology, lpauxc->wTechnology);
  405. STOREDWORD(Temp.dwSupport, lpauxc->dwSupport);
  406. RtlCopyMemory( (LPVOID)pauxc16, &Temp, min(uSize, sizeof(AUXCAPS16)) );
  407. FLUSHVDMPTR(vpauxc, min(uSize, sizeof(AUXCAPS16)), pauxc16);
  408. FREEVDMPTR(pauxc16);
  409. return MMSYSERR_NOERROR;
  410. }
  411. /**********************************************************************\
  412. * Thunks a TIMECAPS structure from 32 bit back to 16 bit space.
  413. *
  414. * Used by:
  415. * timeGetDevCaps
  416. *
  417. \**********************************************************************/
  418. ULONG puttimecaps16(VPTIMECAPS16 vptimec, LPTIMECAPS lptimec, UINT uSize)
  419. {
  420. PTIMECAPS16 ptimec16;
  421. TIMECAPS16 Temp;
  422. /*
  423. ** Just in case the app specified a NULL pointer. We have already
  424. ** validated that uSize is not zero.
  425. */
  426. MMGETOPTPTR(vptimec, min(uSize, sizeof(TIMECAPS16)), ptimec16);
  427. if ( ptimec16 == NULL ) {
  428. dprintf1(( "puttimecaps16 MMGETOPTPTR returned a NULL pointer" ));
  429. return MMSYSERR_INVALPARAM;
  430. }
  431. //
  432. // Under NT, the minimum time period is about 15ms. But Win3.1 on a 386
  433. // always returns 1ms. Encarta doesn't even bother testing the
  434. // CD-ROM's speed if the minimum period is > 2ms, it just assumes
  435. // it is too slow. So here we lie to WOW apps and always tell
  436. // them 1ms just like Win3.1.
  437. // John Vert (jvert) 17-Jun-1993
  438. //
  439. STOREWORD( Temp.wPeriodMin, 1 );
  440. /*
  441. ** In windows 3.1 the wPeriodMax value is 0xFFFF which is the
  442. ** max value you can store in a word. In windows NT the
  443. ** wPeriodMax is 0xF4240 (1000 seconds).
  444. **
  445. ** If we just cast the 32 bit value down to a 16bit value we
  446. ** end up with 0x4240 which very small compared to real 32 bit
  447. ** value.
  448. **
  449. ** Therefore I will take the minimum of wPeriodMax and 0xFFFF
  450. ** that way will should remain consistant with Win 3.1 if
  451. ** wPeriodMax is greater than 0xFFFF.
  452. */
  453. STOREWORD(Temp.wPeriodMax, (WORD)min( 0xFFFF, lptimec->wPeriodMax) );
  454. RtlCopyMemory( (LPVOID)ptimec16, &Temp, min(uSize, sizeof(TIMECAPS16)) );
  455. FLUSHVDMPTR(vptimec, min(uSize, sizeof(TIMECAPS16)), ptimec16);
  456. FREEVDMPTR(ptimec16);
  457. return MMSYSERR_NOERROR;
  458. }
  459. /**********************************************************************\
  460. * Thunks a MIDIINCAPS structure from 32 bit back to 16 bit space.
  461. *
  462. * Used by:
  463. * midiInGetDevCaps
  464. *
  465. * OK - heres the scoop:
  466. *
  467. * Robin observed that it is valid (in theory) to copy back more bytes than
  468. * JUST those contained in the MIDIINCAPS16 structure...
  469. * Unfortunately that would probably blow this lot clean out of the water, so
  470. * we aren't going to worry about that possibility for now.
  471. * We will thunk the ENTIRE structure (not least 'cos we ALWAYS request it in
  472. * the 32 bit call), then copy the required number, <= sizeof(MIDIINCAPS16)
  473. * back to the 16 bit app.
  474. *
  475. * pTemp is the pointer to our local copy of the complete MIDIOUTCAPS16
  476. \**********************************************************************/
  477. ULONG putmidiincaps16 (VPMIDIINCAPS16 vpmic, LPMIDIINCAPS lpmic, UINT uSize)
  478. {
  479. INT i;
  480. MIDIINCAPS16 Temp;
  481. PMIDIINCAPS16 pmic16;
  482. /*
  483. ** Just in case the app specified a NULL pointer. We have already
  484. ** validated that uSize is not zero.
  485. */
  486. MMGETOPTPTR(vpmic, min(uSize, sizeof(MIDIINCAPS16)), pmic16);
  487. if ( pmic16 == NULL ) {
  488. dprintf1(( "putmidiincaps16 MMGETOPTPTR returned a NULL pointer" ));
  489. return MMSYSERR_INVALPARAM;
  490. }
  491. STOREWORD(Temp.wMid, lpmic->wMid);
  492. STOREWORD(Temp.wPid, lpmic->wPid);
  493. STOREWORD(Temp.vDriverVersion, (WORD)lpmic->vDriverVersion);
  494. /*
  495. ** The product name string should be null terminated, but we want the whole
  496. ** string anyway, so copy the whole MAXPNAMELEN bytes.
  497. */
  498. i = 0;
  499. while (i < MAXPNAMELEN) {
  500. Temp.szPname[i] = lpmic->szPname[i++];
  501. }
  502. RtlCopyMemory( (LPVOID)pmic16, &Temp, min(uSize, sizeof(MIDIINCAPS16)) );
  503. FLUSHVDMPTR(vpmic, min(uSize, sizeof(MIDIINCAPS16)), pmic16);
  504. FREEVDMPTR(pmic16);
  505. return MMSYSERR_NOERROR;
  506. }
  507. /**********************************************************************\
  508. * Thunks a MIDIOUTCAPS structure from 32 bit back to 16 bit space.
  509. *
  510. *
  511. * OK - heres the scoop:
  512. *
  513. * Robin observed that it is valid (in theory) to copy back more bytes than
  514. * JUST those contained in the MIDIOUTCAPS16 structure...
  515. * Unfortunately that would probably blow this lot clean out of the water, so
  516. * we aren't going to worry about that possibility for now.
  517. * We will thunk the ENTIRE structure (not least 'cos we ALWAYS request it in
  518. * the 32 bit call), then copy the required number, <= sizeof(MIDIOUTCAPS16)
  519. * back to the 16 bit app.
  520. *
  521. * pTemp is the pointer to our local copy of the complete MIDIOUTCAPS16
  522. *
  523. * Used by:
  524. * midiOutGetDevCaps
  525. *
  526. \**********************************************************************/
  527. ULONG putmidioutcaps16 (VPMIDIOUTCAPS16 vpmoc, LPMIDIOUTCAPS lpmoc, UINT uSize)
  528. {
  529. INT i;
  530. MIDIOUTCAPS16 Temp;
  531. PMIDIOUTCAPS16 pmoc16;
  532. /*
  533. ** Just in case the app specified a NULL pointer. We have already
  534. ** validated that uSize is not zero.
  535. */
  536. MMGETOPTPTR(vpmoc, min(uSize, sizeof(MIDIINCAPS16)), pmoc16);
  537. if ( pmoc16 == NULL ) {
  538. dprintf1(( "putmidioutcaps16 MMGETOPTPTR returned a NULL pointer" ));
  539. return MMSYSERR_INVALPARAM;
  540. }
  541. STOREWORD(Temp.wMid, lpmoc->wMid);
  542. STOREWORD(Temp.wPid, lpmoc->wPid);
  543. STOREWORD(Temp.vDriverVersion, (WORD)lpmoc->vDriverVersion);
  544. /*
  545. ** The product name string should be null terminated, but we want the whole
  546. ** string anyway, so copy the whole MAXPNAMELEN bytes.
  547. */
  548. i = 0;
  549. while (i < MAXPNAMELEN) {
  550. Temp.szPname[i] = lpmoc->szPname[i++];
  551. }
  552. STOREWORD(Temp.wTechnology, lpmoc->wTechnology);
  553. STOREWORD(Temp.wVoices, lpmoc->wVoices);
  554. STOREWORD(Temp.wNotes, lpmoc->wNotes);
  555. STOREWORD(Temp.wChannelMask, lpmoc->wChannelMask);
  556. STOREDWORD(Temp.dwSupport, lpmoc->dwSupport);
  557. RtlCopyMemory( (LPVOID)pmoc16, &Temp, min(uSize, sizeof(MIDIOUTCAPS16)) );
  558. FLUSHVDMPTR(vpmoc, min(uSize, sizeof(MIDIOUTCAPS16)), pmoc16);
  559. FREEVDMPTR(pmoc16);
  560. return MMSYSERR_NOERROR;
  561. }
  562. /**********************************************************************\
  563. * Thunks a JOYCAPS structure from 32 bit back to 16 bit space.
  564. *
  565. * Used by:
  566. * joyGetDevCaps
  567. *
  568. \**********************************************************************/
  569. ULONG putjoycaps16 (VPJOYCAPS16 vpjoyc, LPJOYCAPS lpjoyc, UINT uSize)
  570. {
  571. INT i;
  572. JOYCAPS16 Temp;
  573. PJOYCAPS16 pjoyc16;
  574. /*
  575. ** Just in case the app specified a NULL pointer. We have already
  576. ** validated that uSize is not zero.
  577. */
  578. MMGETOPTPTR(vpjoyc, min(uSize, sizeof(JOYCAPS16)), pjoyc16);
  579. if ( pjoyc16 == NULL ) {
  580. dprintf1(( "putjoycaps16 MMGETOPTPTR returned a NULL pointer" ));
  581. return JOYERR_PARMS;
  582. }
  583. STOREWORD(Temp.wMid, lpjoyc->wMid);
  584. STOREWORD(Temp.wPid, lpjoyc->wPid);
  585. /*
  586. ** The product name string should be null terminated,
  587. ** but we want the whole string anyway, so copy the
  588. ** whole MAXPNAMELEN bytes.
  589. */
  590. i = 0;
  591. while (i < MAXPNAMELEN) {
  592. Temp.szPname[i] = lpjoyc->szPname[i++];
  593. }
  594. STOREWORD(Temp.wXmin, lpjoyc->wXmin);
  595. STOREWORD(Temp.wXmax, lpjoyc->wXmax);
  596. STOREWORD(Temp.wYmin, lpjoyc->wYmin);
  597. STOREWORD(Temp.wYmax, lpjoyc->wYmax);
  598. STOREWORD(Temp.wZmin, lpjoyc->wZmin);
  599. STOREWORD(Temp.wZmax, lpjoyc->wZmax);
  600. STOREWORD(Temp.wNumButtons, lpjoyc->wNumButtons);
  601. STOREWORD(Temp.wPeriodMin, lpjoyc->wPeriodMin);
  602. STOREWORD(Temp.wPeriodMax, lpjoyc->wPeriodMax);
  603. RtlCopyMemory( (LPVOID)pjoyc16, &Temp, min(uSize, sizeof(JOYCAPS16)) );
  604. FLUSHVDMPTR(vpjoyc, min(uSize, sizeof(JOYCAPS16) ), pjoyc16);
  605. FREEVDMPTR(pjoyc16);
  606. return JOYERR_NOERROR;
  607. }
  608. /**********************************************************************\
  609. * Thunks a JOYINFO structure from 32 bit back to 16 bit space.
  610. *
  611. * Used by:
  612. * joyGetPos
  613. *
  614. \**********************************************************************/
  615. ULONG putjoyinfo16 (VPJOYINFO16 vpjoyi, LPJOYINFO lpjoyi)
  616. {
  617. PJOYINFO16 pjoyi16;
  618. /*
  619. ** Protect against NULL pointers
  620. */
  621. MMGETOPTPTR(vpjoyi, sizeof(JOYINFO16), pjoyi16);
  622. if ( pjoyi16 == NULL ) {
  623. dprintf1(( "putjoyinfo16 MMGETOPTPTR returned a NULL pointer" ));
  624. return JOYERR_PARMS;
  625. }
  626. STOREWORD(pjoyi16->wXpos, lpjoyi->wXpos);
  627. STOREWORD(pjoyi16->wYpos, lpjoyi->wYpos);
  628. STOREWORD(pjoyi16->wZpos, lpjoyi->wZpos);
  629. STOREWORD(pjoyi16->wButtons, lpjoyi->wButtons);
  630. FLUSHVDMPTR(vpjoyi, sizeof(JOYINFO16), pjoyi16);
  631. FREEVDMPTR(pjoyi16);
  632. return JOYERR_NOERROR;
  633. }
  634. #endif