1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1993 Martin Ayotte
7 * 1998-2003 Eric Pouech
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 * 99/4 added mmTask and mmThread functions support
32 #define NONAMELESSUNION
33 #define NONAMELESSSTRUCT
41 #include "wine/list.h"
42 #include "wine/winuser16.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
50 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16);
51 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCWSTR, LPCWSTR, LPARAM);
52 static LRESULT DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM);
53 static LRESULT DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM);
55 static CRITICAL_SECTION mmdrv_cs;
56 static CRITICAL_SECTION_DEBUG mmdrv_critsect_debug =
59 { &mmdrv_critsect_debug.ProcessLocksList, &mmdrv_critsect_debug.ProcessLocksList },
60 0, 0, { (DWORD_PTR)(__FILE__ ": mmsystem_mmdrv_cs") }
62 static CRITICAL_SECTION mmdrv_cs = { &mmdrv_critsect_debug, -1, 0, 0, 0, 0 };
64 /* ###################################################
66 * ###################################################
69 /**************************************************************************
70 * DllEntryPoint (MMSYSTEM.4)
72 * MMSYSTEM DLL entry point
75 BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
76 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
78 TRACE("%p 0x%x\n", hinstDLL, fdwReason);
81 case DLL_PROCESS_ATTACH:
82 /* need to load WinMM in order to:
83 * - initiate correctly shared variables (WINMM_Init())
85 if (!GetModuleHandleA("WINMM.DLL"))
87 ERR("Could not load sibling WinMM.dll\n");
90 /* hook in our 16 bit function pointers */
91 pFnGetMMThread16 = WINMM_GetmmThread;
92 pFnOpenDriver16 = DRIVER_OpenDriver16;
93 pFnCloseDriver16 = DRIVER_CloseDriver16;
94 pFnSendMessage16 = DRIVER_SendMessage16;
95 pFnReleaseThunkLock = ReleaseThunkLock;
96 pFnRestoreThunkLock = RestoreThunkLock;
99 case DLL_PROCESS_DETACH:
100 pFnGetMMThread16 = NULL;
101 pFnOpenDriver16 = NULL;
102 pFnCloseDriver16 = NULL;
103 pFnSendMessage16 = NULL;
104 pFnReleaseThunkLock = NULL;
105 pFnRestoreThunkLock = NULL;
106 /* FIXME: add equivalent for MMDRV_Init16() */
108 case DLL_THREAD_ATTACH:
109 case DLL_THREAD_DETACH:
115 /**************************************************************************
118 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
119 WORD cbHeapSize, LPSTR lpCmdLine)
121 TRACE("STUB: Unloading MMSystem DLL ... hInst=%04X\n", hInstance);
125 /* ###################################################
127 * ###################################################
130 /**************************************************************************
131 * PlaySound [MMSYSTEM.3]
133 BOOL16 WINAPI PlaySound16(LPCSTR pszSound, HMODULE16 hmod, DWORD fdwSound)
138 if ((fdwSound & SND_RESOURCE) == SND_RESOURCE)
143 if (!(res = FindResource16( hmod, pszSound, "WAVE" ))) return FALSE;
144 if (!(handle = LoadResource16( hmod, res ))) return FALSE;
145 pszSound = LockResource16(handle);
146 fdwSound = (fdwSound & ~SND_RESOURCE) | SND_MEMORY;
147 /* FIXME: FreeResource16 */
150 ReleaseThunkLock(&lc);
151 retv = PlaySoundA(pszSound, 0, fdwSound);
152 RestoreThunkLock(lc);
157 /**************************************************************************
158 * sndPlaySound [MMSYSTEM.2]
160 BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags)
165 ReleaseThunkLock(&lc);
166 retv = sndPlaySoundA(lpszSoundName, uFlags);
167 RestoreThunkLock(lc);
172 /* ###################################################
174 * ###################################################
177 /**************************************************************************
178 * mmsystemGetVersion [MMSYSTEM.5]
181 UINT16 WINAPI mmsystemGetVersion16(void)
183 return mmsystemGetVersion();
186 /**************************************************************************
187 * DriverCallback [MMSYSTEM.31]
189 BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev,
190 WORD wMsg, DWORD dwUser, DWORD dwParam1,
193 return DriverCallback(dwCallBack, uFlags, HDRVR_32(hDev), wMsg, dwUser, dwParam1, dwParam2);
196 /**************************************************************************
197 * OutputDebugStr [MMSYSTEM.30]
199 void WINAPI OutputDebugStr16(LPCSTR str)
201 OutputDebugStringA( str );
205 /* ###################################################
207 * ###################################################
210 /**************************************************************************
211 * Mixer devices. New to Win95
214 /**************************************************************************
215 * mixerGetNumDevs [MMSYSTEM.800]
217 UINT16 WINAPI mixerGetNumDevs16(void)
219 return mixerGetNumDevs();
222 /**************************************************************************
223 * mixerGetDevCaps [MMSYSTEM.801]
225 UINT16 WINAPI mixerGetDevCaps16(UINT16 uDeviceID, LPMIXERCAPS16 lpCaps,
231 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
233 ret = mixerGetDevCapsA(uDeviceID, &micA, sizeof(micA));
234 if (ret == MMSYSERR_NOERROR) {
236 mic16.wMid = micA.wMid;
237 mic16.wPid = micA.wPid;
238 mic16.vDriverVersion = micA.vDriverVersion;
239 strcpy(mic16.szPname, micA.szPname);
240 mic16.fdwSupport = micA.fdwSupport;
241 mic16.cDestinations = micA.cDestinations;
242 memcpy(lpCaps, &mic16, min(uSize, sizeof(mic16)));
247 /**************************************************************************
248 * mixerOpen [MMSYSTEM.802]
250 UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix, UINT16 uDeviceID, DWORD dwCallback,
251 DWORD dwInstance, DWORD fdwOpen)
256 ret = MIXER_Open(&hmix, uDeviceID, dwCallback, dwInstance, fdwOpen, FALSE);
257 if (lphmix) *lphmix = HMIXER_16(hmix);
261 /**************************************************************************
262 * mixerClose [MMSYSTEM.803]
264 UINT16 WINAPI mixerClose16(HMIXER16 hMix)
266 return mixerClose(HMIXER_32(hMix));
269 /**************************************************************************
270 * mixerGetID (MMSYSTEM.806)
272 UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID)
275 UINT ret = mixerGetID(HMIXEROBJ_32(hmix), &xid, fdwID);
282 /**************************************************************************
283 * mixerGetControlDetails [MMSYSTEM.808]
285 UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,
286 LPMIXERCONTROLDETAILS16 lpmcd,
289 DWORD ret = MMSYSERR_NOTENABLED;
292 TRACE("(%04x, %p, %08x)\n", hmix, lpmcd, fdwDetails);
294 if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
295 return MMSYSERR_INVALPARAM;
297 sppaDetails = (SEGPTR)lpmcd->paDetails;
298 lpmcd->paDetails = MapSL(sppaDetails);
299 ret = mixerGetControlDetailsA(HMIXEROBJ_32(hmix),
300 (LPMIXERCONTROLDETAILS)lpmcd, fdwDetails);
301 lpmcd->paDetails = (LPVOID)sppaDetails;
306 /**************************************************************************
307 * mixerGetLineControls [MMSYSTEM.807]
309 UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,
310 LPMIXERLINECONTROLS16 lpmlc16,
313 MIXERLINECONTROLSA mlcA;
316 LPMIXERCONTROL16 lpmc16;
318 TRACE("(%04x, %p, %08x)\n", hmix, lpmlc16, fdwControls);
320 if (lpmlc16 == NULL || lpmlc16->cbStruct != sizeof(*lpmlc16) ||
321 lpmlc16->cbmxctrl != sizeof(MIXERCONTROL16))
322 return MMSYSERR_INVALPARAM;
324 mlcA.cbStruct = sizeof(mlcA);
325 mlcA.dwLineID = lpmlc16->dwLineID;
326 mlcA.u.dwControlID = lpmlc16->u.dwControlID;
327 mlcA.u.dwControlType = lpmlc16->u.dwControlType;
328 mlcA.cControls = lpmlc16->cControls;
329 mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
330 mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
331 mlcA.cControls * mlcA.cbmxctrl);
333 ret = mixerGetLineControlsA(HMIXEROBJ_32(hmix), &mlcA, fdwControls);
335 if (ret == MMSYSERR_NOERROR) {
336 lpmlc16->dwLineID = mlcA.dwLineID;
337 lpmlc16->u.dwControlID = mlcA.u.dwControlID;
338 lpmlc16->u.dwControlType = mlcA.u.dwControlType;
339 lpmlc16->cControls = mlcA.cControls;
341 lpmc16 = MapSL(lpmlc16->pamxctrl);
343 for (i = 0; i < mlcA.cControls; i++) {
344 lpmc16[i].cbStruct = sizeof(MIXERCONTROL16);
345 lpmc16[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
346 lpmc16[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
347 lpmc16[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
348 lpmc16[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
349 strcpy(lpmc16[i].szShortName, mlcA.pamxctrl[i].szShortName);
350 strcpy(lpmc16[i].szName, mlcA.pamxctrl[i].szName);
351 /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
352 memcpy(&lpmc16[i].Bounds, &mlcA.pamxctrl[i].Bounds,
353 sizeof(mlcA.pamxctrl[i].Bounds));
354 /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
355 memcpy(&lpmc16[i].Metrics, &mlcA.pamxctrl[i].Metrics,
356 sizeof(mlcA.pamxctrl[i].Metrics));
360 HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);
365 /**************************************************************************
366 * mixerGetLineInfo [MMSYSTEM.805]
368 UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16,
374 TRACE("(%04x, %p, %08x)\n", hmix, lpmli16, fdwInfo);
376 if (lpmli16 == NULL || lpmli16->cbStruct != sizeof(*lpmli16))
377 return MMSYSERR_INVALPARAM;
379 mliA.cbStruct = sizeof(mliA);
380 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
381 case MIXER_GETLINEINFOF_COMPONENTTYPE:
382 mliA.dwComponentType = lpmli16->dwComponentType;
384 case MIXER_GETLINEINFOF_DESTINATION:
385 mliA.dwDestination = lpmli16->dwDestination;
387 case MIXER_GETLINEINFOF_LINEID:
388 mliA.dwLineID = lpmli16->dwLineID;
390 case MIXER_GETLINEINFOF_SOURCE:
391 mliA.dwDestination = lpmli16->dwDestination;
392 mliA.dwSource = lpmli16->dwSource;
394 case MIXER_GETLINEINFOF_TARGETTYPE:
395 mliA.Target.dwType = lpmli16->Target.dwType;
396 mliA.Target.wMid = lpmli16->Target.wMid;
397 mliA.Target.wPid = lpmli16->Target.wPid;
398 mliA.Target.vDriverVersion = lpmli16->Target.vDriverVersion;
399 strcpy(mliA.Target.szPname, lpmli16->Target.szPname);
402 FIXME("Unsupported fdwControls=0x%08x\n", fdwInfo);
405 ret = mixerGetLineInfoA(HMIXEROBJ_32(hmix), &mliA, fdwInfo);
407 lpmli16->dwDestination = mliA.dwDestination;
408 lpmli16->dwSource = mliA.dwSource;
409 lpmli16->dwLineID = mliA.dwLineID;
410 lpmli16->fdwLine = mliA.fdwLine;
411 lpmli16->dwUser = mliA.dwUser;
412 lpmli16->dwComponentType = mliA.dwComponentType;
413 lpmli16->cChannels = mliA.cChannels;
414 lpmli16->cConnections = mliA.cConnections;
415 lpmli16->cControls = mliA.cControls;
416 strcpy(lpmli16->szShortName, mliA.szShortName);
417 strcpy(lpmli16->szName, mliA.szName);
418 lpmli16->Target.dwType = mliA.Target.dwType;
419 lpmli16->Target.dwDeviceID = mliA.Target.dwDeviceID;
420 lpmli16->Target.wMid = mliA.Target.wMid;
421 lpmli16->Target.wPid = mliA.Target.wPid;
422 lpmli16->Target.vDriverVersion = mliA.Target.vDriverVersion;
423 strcpy(lpmli16->Target.szPname, mliA.Target.szPname);
428 /**************************************************************************
429 * mixerSetControlDetails [MMSYSTEM.809]
431 UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,
432 LPMIXERCONTROLDETAILS16 lpmcd,
435 TRACE("(%04x, %p, %08x)\n", hmix, lpmcd, fdwDetails);
436 return MMSYSERR_NOTENABLED;
439 /**************************************************************************
440 * mixerMessage [MMSYSTEM.804]
442 DWORD WINAPI mixerMessage16(HMIXER16 hmix, UINT16 uMsg, DWORD dwParam1,
445 return mixerMessage(HMIXER_32(hmix), uMsg, dwParam1, dwParam2);
448 /**************************************************************************
449 * auxGetNumDevs [MMSYSTEM.350]
451 UINT16 WINAPI auxGetNumDevs16(void)
453 return auxGetNumDevs();
456 /* ###################################################
458 * ###################################################
461 /**************************************************************************
462 * auxGetDevCaps [MMSYSTEM.351]
464 UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID, LPAUXCAPS16 lpCaps, UINT16 uSize)
469 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
471 ret = auxGetDevCapsA(uDeviceID, &acA, sizeof(acA));
472 if (ret == MMSYSERR_NOERROR) {
474 ac16.wMid = acA.wMid;
475 ac16.wPid = acA.wPid;
476 ac16.vDriverVersion = acA.vDriverVersion;
477 strcpy(ac16.szPname, acA.szPname);
478 ac16.wTechnology = acA.wTechnology;
479 ac16.dwSupport = acA.dwSupport;
480 memcpy(lpCaps, &ac16, min(uSize, sizeof(ac16)));
485 /**************************************************************************
486 * auxGetVolume [MMSYSTEM.352]
488 UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, LPDWORD lpdwVolume)
490 return auxGetVolume(uDeviceID, lpdwVolume);
493 /**************************************************************************
494 * auxSetVolume [MMSYSTEM.353]
496 UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
498 return auxSetVolume(uDeviceID, dwVolume);
501 /**************************************************************************
502 * auxOutMessage [MMSYSTEM.354]
504 DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
506 TRACE("(%04X, %04X, %08X, %08X)\n", uDeviceID, uMessage, dw1, dw2);
509 case AUXDM_GETNUMDEVS:
510 case AUXDM_SETVOLUME:
511 /* no argument conversion needed */
513 case AUXDM_GETVOLUME:
514 return auxGetVolume16(uDeviceID, MapSL(dw1));
515 case AUXDM_GETDEVCAPS:
516 return auxGetDevCaps16(uDeviceID, MapSL(dw1), dw2);
518 TRACE("(%04x, %04x, %08x, %08x): unhandled message\n",
519 uDeviceID, uMessage, dw1, dw2);
522 return auxOutMessage(uDeviceID, uMessage, dw1, dw2);
525 /* ###################################################
527 * ###################################################
530 /**************************************************************************
531 * midiOutGetNumDevs [MMSYSTEM.201]
533 UINT16 WINAPI midiOutGetNumDevs16(void)
535 return midiOutGetNumDevs();
538 /**************************************************************************
539 * midiOutGetDevCaps [MMSYSTEM.202]
541 UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID, LPMIDIOUTCAPS16 lpCaps,
547 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
549 ret = midiOutGetDevCapsA(uDeviceID, &mocA, sizeof(mocA));
550 if (ret == MMSYSERR_NOERROR) {
552 moc16.wMid = mocA.wMid;
553 moc16.wPid = mocA.wPid;
554 moc16.vDriverVersion = mocA.vDriverVersion;
555 strcpy(moc16.szPname, mocA.szPname);
556 moc16.wTechnology = mocA.wTechnology;
557 moc16.wVoices = mocA.wVoices;
558 moc16.wNotes = mocA.wNotes;
559 moc16.wChannelMask = mocA.wChannelMask;
560 moc16.dwSupport = mocA.dwSupport;
561 memcpy(lpCaps, &moc16, min(uSize, sizeof(moc16)));
566 /**************************************************************************
567 * midiOutGetErrorText [MMSYSTEM.203]
568 * midiInGetErrorText [MMSYSTEM.303]
570 UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
572 return midiOutGetErrorTextA(uError, lpText, uSize);
575 /**************************************************************************
576 * midiOutOpen [MMSYSTEM.204]
578 UINT16 WINAPI midiOutOpen16(HMIDIOUT16* lphMidiOut, UINT16 uDeviceID,
579 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
584 ret = MIDI_OutOpen(&hmo, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
586 if (lphMidiOut != NULL) *lphMidiOut = HMIDIOUT_16(hmo);
590 /**************************************************************************
591 * midiOutClose [MMSYSTEM.205]
593 UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
595 return midiOutClose(HMIDIOUT_32(hMidiOut));
598 /**************************************************************************
599 * midiOutPrepareHeader [MMSYSTEM.206]
601 UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
602 SEGPTR lpsegMidiOutHdr, /* [???] */
603 UINT16 uSize) /* [in] */
607 TRACE("(%04X, %08x, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
609 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
610 return MMSYSERR_INVALHANDLE;
612 return MMDRV_Message(wmld, MODM_PREPARE, lpsegMidiOutHdr, uSize, FALSE);
615 /**************************************************************************
616 * midiOutUnprepareHeader [MMSYSTEM.207]
618 UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
619 SEGPTR lpsegMidiOutHdr, /* [???] */
620 UINT16 uSize) /* [in] */
623 LPMIDIHDR16 lpMidiOutHdr = MapSL(lpsegMidiOutHdr);
625 TRACE("(%04X, %08x, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
627 if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
628 return MMSYSERR_NOERROR;
631 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
632 return MMSYSERR_INVALHANDLE;
634 return MMDRV_Message(wmld, MODM_UNPREPARE, lpsegMidiOutHdr, uSize, FALSE);
637 /**************************************************************************
638 * midiOutShortMsg [MMSYSTEM.208]
640 UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
642 return midiOutShortMsg(HMIDIOUT_32(hMidiOut), dwMsg);
645 /**************************************************************************
646 * midiOutLongMsg [MMSYSTEM.209]
648 UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut, /* [in] */
649 LPMIDIHDR16 lpsegMidiOutHdr, /* [???] NOTE: SEGPTR */
650 UINT16 uSize) /* [in] */
654 TRACE("(%04X, %p, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
656 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
657 return MMSYSERR_INVALHANDLE;
659 return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpsegMidiOutHdr, uSize, FALSE);
662 /**************************************************************************
663 * midiOutReset [MMSYSTEM.210]
665 UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
667 return midiOutReset(HMIDIOUT_32(hMidiOut));
670 /**************************************************************************
671 * midiOutGetVolume [MMSYSTEM.211]
673 UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD* lpdwVolume)
675 return midiOutGetVolume(HMIDIOUT_32(uDeviceID), lpdwVolume);
678 /**************************************************************************
679 * midiOutSetVolume [MMSYSTEM.212]
681 UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
683 return midiOutSetVolume(HMIDIOUT_32(uDeviceID), dwVolume);
686 /**************************************************************************
687 * midiOutCachePatches [MMSYSTEM.213]
689 UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
690 WORD* lpwPatchArray, UINT16 uFlags)
692 return midiOutCachePatches(HMIDIOUT_32(hMidiOut), uBank, lpwPatchArray,
696 /**************************************************************************
697 * midiOutCacheDrumPatches [MMSYSTEM.214]
699 UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
700 WORD* lpwKeyArray, UINT16 uFlags)
702 return midiOutCacheDrumPatches(HMIDIOUT_32(hMidiOut), uPatch, lpwKeyArray, uFlags);
705 /**************************************************************************
706 * midiOutGetID [MMSYSTEM.215]
708 UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16* lpuDeviceID)
713 ret = midiOutGetID(HMIDIOUT_32(hMidiOut), &devid);
714 if (ret != MMSYSERR_NOERROR) return ret;
715 *lpuDeviceID = devid;
719 /**************************************************************************
720 * midiOutMessage [MMSYSTEM.216]
722 DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage,
723 DWORD dwParam1, DWORD dwParam2)
727 TRACE("(%04X, %04X, %08X, %08X)\n", hMidiOut, uMessage, dwParam1, dwParam2);
729 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
730 return MMSYSERR_INVALHANDLE;
735 FIXME("can't handle OPEN or CLOSE message!\n");
736 return MMSYSERR_NOTSUPPORTED;
739 return midiOutGetVolume16(hMidiOut, MapSL(dwParam1));
741 return midiOutLongMsg16(hMidiOut, MapSL(dwParam1), dwParam2);
743 /* lpMidiOutHdr is still a segmented pointer for this function */
744 return midiOutPrepareHeader16(hMidiOut, dwParam1, dwParam2);
746 return midiOutUnprepareHeader16(hMidiOut, dwParam1, dwParam2);
748 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
751 /**************************************************************************
752 * midiInGetNumDevs [MMSYSTEM.301]
754 UINT16 WINAPI midiInGetNumDevs16(void)
756 return midiInGetNumDevs();
759 /**************************************************************************
760 * midiInGetDevCaps [MMSYSTEM.302]
762 UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID, LPMIDIINCAPS16 lpCaps,
768 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
770 ret = midiInGetDevCapsA(uDeviceID, &micA, uSize);
771 if (ret == MMSYSERR_NOERROR) {
773 mic16.wMid = micA.wMid;
774 mic16.wPid = micA.wPid;
775 mic16.vDriverVersion = micA.vDriverVersion;
776 strcpy(mic16.szPname, micA.szPname);
777 mic16.dwSupport = micA.dwSupport;
778 memcpy(lpCaps, &mic16, min(uSize, sizeof(mic16)));
783 /**************************************************************************
784 * midiInOpen [MMSYSTEM.304]
786 UINT16 WINAPI midiInOpen16(HMIDIIN16* lphMidiIn, UINT16 uDeviceID,
787 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
792 ret = MIDI_InOpen(&xhmid, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
794 if (lphMidiIn) *lphMidiIn = HMIDIIN_16(xhmid);
798 /**************************************************************************
799 * midiInClose [MMSYSTEM.305]
801 UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
803 return midiInClose(HMIDIIN_32(hMidiIn));
806 /**************************************************************************
807 * midiInPrepareHeader [MMSYSTEM.306]
809 UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
810 SEGPTR lpsegMidiInHdr, /* [???] */
811 UINT16 uSize) /* [in] */
815 TRACE("(%04X, %08x, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
817 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
818 return MMSYSERR_INVALHANDLE;
820 return MMDRV_Message(wmld, MIDM_PREPARE, lpsegMidiInHdr, uSize, FALSE);
823 /**************************************************************************
824 * midiInUnprepareHeader [MMSYSTEM.307]
826 UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
827 SEGPTR lpsegMidiInHdr, /* [???] */
828 UINT16 uSize) /* [in] */
831 LPMIDIHDR16 lpMidiInHdr = MapSL(lpsegMidiInHdr);
833 TRACE("(%04X, %08x, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
835 if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
836 return MMSYSERR_NOERROR;
839 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
840 return MMSYSERR_INVALHANDLE;
842 return MMDRV_Message(wmld, MIDM_UNPREPARE, lpsegMidiInHdr, uSize, FALSE);
845 /**************************************************************************
846 * midiInAddBuffer [MMSYSTEM.308]
848 UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn, /* [in] */
849 MIDIHDR16* lpsegMidiInHdr, /* [???] NOTE: SEGPTR */
850 UINT16 uSize) /* [in] */
854 TRACE("(%04X, %p, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
856 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
857 return MMSYSERR_INVALHANDLE;
859 return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD_PTR)lpsegMidiInHdr, uSize, FALSE);
862 /**************************************************************************
863 * midiInStart [MMSYSTEM.309]
865 UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
867 return midiInStart(HMIDIIN_32(hMidiIn));
870 /**************************************************************************
871 * midiInStop [MMSYSTEM.310]
873 UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
875 return midiInStop(HMIDIIN_32(hMidiIn));
878 /**************************************************************************
879 * midiInReset [MMSYSTEM.311]
881 UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
883 return midiInReset(HMIDIIN_32(hMidiIn));
886 /**************************************************************************
887 * midiInGetID [MMSYSTEM.312]
889 UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
894 ret = midiInGetID(HMIDIIN_32(hMidiIn), &devid);
895 if (ret != MMSYSERR_NOERROR) return ret;
896 *lpuDeviceID = devid;
900 /**************************************************************************
901 * midiInMessage [MMSYSTEM.313]
903 DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage,
904 DWORD dwParam1, DWORD dwParam2)
908 TRACE("(%04X, %04X, %08X, %08X)\n", hMidiIn, uMessage, dwParam1, dwParam2);
913 FIXME("can't handle OPEN or CLOSE message!\n");
914 return MMSYSERR_NOTSUPPORTED;
916 case MIDM_GETDEVCAPS:
917 return midiInGetDevCaps16(hMidiIn, MapSL(dwParam1), dwParam2);
919 return midiInPrepareHeader16(hMidiIn, dwParam1, dwParam2);
921 return midiInUnprepareHeader16(hMidiIn, dwParam1, dwParam2);
923 return midiInAddBuffer16(hMidiIn, MapSL(dwParam1), dwParam2);
926 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
927 return MMSYSERR_INVALHANDLE;
929 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
932 /**************************************************************************
933 * midiStreamClose [MMSYSTEM.252]
935 MMRESULT16 WINAPI midiStreamClose16(HMIDISTRM16 hMidiStrm)
937 return midiStreamClose(HMIDISTRM_32(hMidiStrm));
940 /**************************************************************************
941 * midiStreamOpen [MMSYSTEM.251]
943 MMRESULT16 WINAPI midiStreamOpen16(HMIDISTRM16* phMidiStrm, LPUINT16 devid,
944 DWORD cMidi, DWORD dwCallback,
945 DWORD dwInstance, DWORD fdwOpen)
947 HMIDISTRM hMidiStrm32;
951 if (!phMidiStrm || !devid)
952 return MMSYSERR_INVALPARAM;
954 ret = MIDI_StreamOpen(&hMidiStrm32, &devid32, cMidi, dwCallback,
955 dwInstance, fdwOpen, FALSE);
956 *phMidiStrm = HMIDISTRM_16(hMidiStrm32);
961 /**************************************************************************
962 * midiStreamOut [MMSYSTEM.254]
964 MMRESULT16 WINAPI midiStreamOut16(HMIDISTRM16 hMidiStrm, LPMIDIHDR16 lpMidiHdr, UINT16 cbMidiHdr)
966 return midiStreamOut(HMIDISTRM_32(hMidiStrm), (LPMIDIHDR)lpMidiHdr,
970 /**************************************************************************
971 * midiStreamPause [MMSYSTEM.255]
973 MMRESULT16 WINAPI midiStreamPause16(HMIDISTRM16 hMidiStrm)
975 return midiStreamPause(HMIDISTRM_32(hMidiStrm));
978 /**************************************************************************
979 * midiStreamPosition [MMSYSTEM.253]
981 MMRESULT16 WINAPI midiStreamPosition16(HMIDISTRM16 hMidiStrm, LPMMTIME16 lpmmt16, UINT16 cbmmt)
987 return MMSYSERR_INVALPARAM;
988 MMSYSTEM_MMTIME16to32(&mmt32, lpmmt16);
989 ret = midiStreamPosition(HMIDISTRM_32(hMidiStrm), &mmt32, sizeof(MMTIME));
990 MMSYSTEM_MMTIME32to16(lpmmt16, &mmt32);
994 /**************************************************************************
995 * midiStreamProperty [MMSYSTEM.250]
997 MMRESULT16 WINAPI midiStreamProperty16(HMIDISTRM16 hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
999 return midiStreamProperty(HMIDISTRM_32(hMidiStrm), lpPropData, dwProperty);
1002 /**************************************************************************
1003 * midiStreamRestart [MMSYSTEM.256]
1005 MMRESULT16 WINAPI midiStreamRestart16(HMIDISTRM16 hMidiStrm)
1007 return midiStreamRestart(HMIDISTRM_32(hMidiStrm));
1010 /**************************************************************************
1011 * midiStreamStop [MMSYSTEM.257]
1013 MMRESULT16 WINAPI midiStreamStop16(HMIDISTRM16 hMidiStrm)
1015 return midiStreamStop(HMIDISTRM_32(hMidiStrm));
1018 /* ###################################################
1020 * ###################################################
1023 /**************************************************************************
1024 * waveOutGetNumDevs [MMSYSTEM.401]
1026 UINT16 WINAPI waveOutGetNumDevs16(void)
1028 return waveOutGetNumDevs();
1031 /**************************************************************************
1032 * waveOutGetDevCaps [MMSYSTEM.402]
1034 UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID,
1035 LPWAVEOUTCAPS16 lpCaps, UINT16 uSize)
1039 TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
1041 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1043 ret = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(wocA));
1044 if (ret == MMSYSERR_NOERROR) {
1045 WAVEOUTCAPS16 woc16;
1046 woc16.wMid = wocA.wMid;
1047 woc16.wPid = wocA.wPid;
1048 woc16.vDriverVersion = wocA.vDriverVersion;
1049 strcpy(woc16.szPname, wocA.szPname);
1050 woc16.dwFormats = wocA.dwFormats;
1051 woc16.wChannels = wocA.wChannels;
1052 woc16.dwSupport = wocA.dwSupport;
1053 memcpy(lpCaps, &woc16, min(uSize, sizeof(woc16)));
1058 /**************************************************************************
1059 * waveOutGetErrorText [MMSYSTEM.403]
1060 * waveInGetErrorText [MMSYSTEM.503]
1062 UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
1064 return waveOutGetErrorTextA(uError, lpText, uSize);
1067 /**************************************************************************
1068 * waveOutOpen [MMSYSTEM.404]
1070 UINT16 WINAPI waveOutOpen16(HWAVEOUT16* lphWaveOut, UINT16 uDeviceID,
1071 LPCWAVEFORMATEX lpFormat, DWORD dwCallback,
1072 DWORD dwInstance, DWORD dwFlags)
1077 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1078 * call the 32 bit version
1079 * however, we need to promote correctly the wave mapper id
1080 * (0xFFFFFFFF and not 0x0000FFFF)
1082 ret = WAVE_Open(&hWaveOut, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1083 MMDRV_WAVEOUT, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1085 if (lphWaveOut != NULL) *lphWaveOut = HWAVEOUT_16(hWaveOut);
1089 /**************************************************************************
1090 * waveOutClose [MMSYSTEM.405]
1092 UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
1097 ReleaseThunkLock(&level);
1098 ret = waveOutClose(HWAVEOUT_32(hWaveOut));
1099 RestoreThunkLock(level);
1103 /**************************************************************************
1104 * waveOutPrepareHeader [MMSYSTEM.406]
1106 UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
1107 SEGPTR lpsegWaveOutHdr, /* [???] */
1108 UINT16 uSize) /* [in] */
1111 LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1114 TRACE("(%04X, %08x, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1116 if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM;
1118 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1119 return MMSYSERR_INVALHANDLE;
1121 if ((result = MMDRV_Message(wmld, WODM_PREPARE, lpsegWaveOutHdr,
1122 uSize, FALSE)) != MMSYSERR_NOTSUPPORTED)
1125 if (lpWaveOutHdr->dwFlags & WHDR_INQUEUE)
1126 return WAVERR_STILLPLAYING;
1128 lpWaveOutHdr->dwFlags |= WHDR_PREPARED;
1129 lpWaveOutHdr->dwFlags &= ~WHDR_DONE;
1131 return MMSYSERR_NOERROR;
1134 /**************************************************************************
1135 * waveOutUnprepareHeader [MMSYSTEM.407]
1137 UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
1138 SEGPTR lpsegWaveOutHdr, /* [???] */
1139 UINT16 uSize) /* [in] */
1142 LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1144 TRACE("(%04X, %08x, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1146 if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
1147 return MMSYSERR_NOERROR;
1150 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1151 return MMSYSERR_INVALHANDLE;
1153 return MMDRV_Message(wmld, WODM_UNPREPARE, lpsegWaveOutHdr, uSize, FALSE);
1156 /**************************************************************************
1157 * waveOutWrite [MMSYSTEM.408]
1159 UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, /* [in] */
1160 LPWAVEHDR lpsegWaveOutHdr, /* [???] NOTE: SEGPTR */
1161 UINT16 uSize) /* [in] */
1165 TRACE("(%04X, %p, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1167 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1168 return MMSYSERR_INVALHANDLE;
1170 return MMDRV_Message(wmld, WODM_WRITE, (DWORD_PTR)lpsegWaveOutHdr, uSize, FALSE);
1173 /**************************************************************************
1174 * waveOutBreakLoop [MMSYSTEM.419]
1176 UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut16)
1181 ReleaseThunkLock(&level);
1182 ret = waveOutBreakLoop(HWAVEOUT_32(hWaveOut16));
1183 RestoreThunkLock(level);
1187 /**************************************************************************
1188 * waveOutPause [MMSYSTEM.409]
1190 UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut16)
1195 ReleaseThunkLock(&level);
1196 ret = waveOutPause(HWAVEOUT_32(hWaveOut16));
1197 RestoreThunkLock(level);
1201 /**************************************************************************
1202 * waveOutReset [MMSYSTEM.411]
1204 UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut16)
1209 ReleaseThunkLock(&level);
1210 ret = waveOutReset(HWAVEOUT_32(hWaveOut16));
1211 RestoreThunkLock(level);
1215 /**************************************************************************
1216 * waveOutRestart [MMSYSTEM.410]
1218 UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut16)
1223 ReleaseThunkLock(&level);
1224 ret = waveOutRestart(HWAVEOUT_32(hWaveOut16));
1225 RestoreThunkLock(level);
1229 /**************************************************************************
1230 * waveOutGetPosition [MMSYSTEM.412]
1232 UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut, LPMMTIME16 lpTime,
1238 mmt.wType = lpTime->wType;
1239 ret = waveOutGetPosition(HWAVEOUT_32(hWaveOut), &mmt, sizeof(mmt));
1240 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1244 /**************************************************************************
1245 * waveOutGetPitch [MMSYSTEM.413]
1247 UINT16 WINAPI waveOutGetPitch16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
1249 return waveOutGetPitch(HWAVEOUT_32(hWaveOut16), lpdw);
1252 /**************************************************************************
1253 * waveOutSetPitch [MMSYSTEM.414]
1255 UINT16 WINAPI waveOutSetPitch16(HWAVEOUT16 hWaveOut16, DWORD dw)
1257 return waveOutSetPitch(HWAVEOUT_32(hWaveOut16), dw);
1260 /**************************************************************************
1261 * waveOutGetPlaybackRate [MMSYSTEM.417]
1263 UINT16 WINAPI waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
1265 return waveOutGetPlaybackRate(HWAVEOUT_32(hWaveOut16), lpdw);
1268 /**************************************************************************
1269 * waveOutSetPlaybackRate [MMSYSTEM.418]
1271 UINT16 WINAPI waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16, DWORD dw)
1273 return waveOutSetPlaybackRate(HWAVEOUT_32(hWaveOut16), dw);
1276 /**************************************************************************
1277 * waveOutGetVolume [MMSYSTEM.415]
1279 UINT16 WINAPI waveOutGetVolume16(UINT16 devid, LPDWORD lpdw)
1281 return waveOutGetVolume(HWAVEOUT_32(devid), lpdw);
1284 /**************************************************************************
1285 * waveOutSetVolume [MMSYSTEM.416]
1287 UINT16 WINAPI waveOutSetVolume16(UINT16 devid, DWORD dw)
1289 return waveOutSetVolume(HWAVEOUT_32(devid), dw);
1292 /**************************************************************************
1293 * waveOutGetID [MMSYSTEM.420]
1295 UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16* lpuDeviceID)
1300 ret = waveOutGetID(HWAVEOUT_32(hWaveOut), &devid);
1301 if (ret != MMSYSERR_NOERROR) return ret;
1302 *lpuDeviceID = devid;
1306 /**************************************************************************
1307 * waveOutMessage [MMSYSTEM.421]
1309 DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage,
1310 DWORD dwParam1, DWORD dwParam2)
1314 TRACE("(%04x, %u, %d, %d)\n", hWaveOut, uMessage, dwParam1, dwParam2);
1316 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) {
1317 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, TRUE)) != NULL) {
1318 if (uMessage == DRV_QUERYDRVENTRY || uMessage == DRV_QUERYDEVNODE)
1319 dwParam1 = (DWORD)MapSL(dwParam1);
1320 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1322 return MMSYSERR_INVALHANDLE;
1326 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1327 return MMSYSERR_INVALPARAM;
1329 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1332 /**************************************************************************
1333 * waveInGetNumDevs [MMSYSTEM.501]
1335 UINT16 WINAPI waveInGetNumDevs16(void)
1337 return waveInGetNumDevs();
1340 /**************************************************************************
1341 * waveInGetDevCaps [MMSYSTEM.502]
1343 UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps,
1349 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1351 ret = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(wicA));
1352 if (ret == MMSYSERR_NOERROR) {
1354 wic16.wMid = wicA.wMid;
1355 wic16.wPid = wicA.wPid;
1356 wic16.vDriverVersion = wicA.vDriverVersion;
1357 strcpy(wic16.szPname, wicA.szPname);
1358 wic16.dwFormats = wicA.dwFormats;
1359 wic16.wChannels = wicA.wChannels;
1360 memcpy(lpCaps, &wic16, min(uSize, sizeof(wic16)));
1365 /**************************************************************************
1366 * waveInOpen [MMSYSTEM.504]
1368 UINT16 WINAPI waveInOpen16(HWAVEIN16* lphWaveIn, UINT16 uDeviceID,
1369 LPCWAVEFORMATEX lpFormat, DWORD dwCallback,
1370 DWORD dwInstance, DWORD dwFlags)
1375 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1376 * call the 32 bit version
1377 * however, we need to promote correctly the wave mapper id
1378 * (0xFFFFFFFF and not 0x0000FFFF)
1380 ret = WAVE_Open(&hWaveIn, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1381 MMDRV_WAVEIN, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1383 if (lphWaveIn != NULL) *lphWaveIn = HWAVEIN_16(hWaveIn);
1387 /**************************************************************************
1388 * waveInClose [MMSYSTEM.505]
1390 UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
1395 ReleaseThunkLock(&level);
1396 ret = waveInClose(HWAVEIN_32(hWaveIn));
1397 RestoreThunkLock(level);
1401 /**************************************************************************
1402 * waveInPrepareHeader [MMSYSTEM.506]
1404 UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1405 SEGPTR lpsegWaveInHdr, /* [???] */
1406 UINT16 uSize) /* [in] */
1409 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1412 TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
1414 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1415 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1416 return MMSYSERR_INVALHANDLE;
1418 lpWaveInHdr->dwBytesRecorded = 0;
1420 ret = MMDRV_Message(wmld, WIDM_PREPARE, lpsegWaveInHdr, uSize, FALSE);
1424 /**************************************************************************
1425 * waveInUnprepareHeader [MMSYSTEM.507]
1427 UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1428 SEGPTR lpsegWaveInHdr, /* [???] */
1429 UINT16 uSize) /* [in] */
1432 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1434 TRACE("(%04X, %08x, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1436 if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1438 if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) {
1439 return MMSYSERR_NOERROR;
1442 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1443 return MMSYSERR_INVALHANDLE;
1445 return MMDRV_Message(wmld, WIDM_UNPREPARE, lpsegWaveInHdr, uSize, FALSE);
1448 /**************************************************************************
1449 * waveInAddBuffer [MMSYSTEM.508]
1451 UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn, /* [in] */
1452 WAVEHDR* lpsegWaveInHdr, /* [???] NOTE: SEGPTR */
1453 UINT16 uSize) /* [in] */
1457 TRACE("(%04X, %p, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1459 if (lpsegWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1460 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1461 return MMSYSERR_INVALHANDLE;
1463 return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD_PTR)lpsegWaveInHdr, uSize, FALSE);
1466 /**************************************************************************
1467 * waveInReset [MMSYSTEM.511]
1469 UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn16)
1474 ReleaseThunkLock(&level);
1475 ret = waveInReset(HWAVEIN_32(hWaveIn16));
1476 RestoreThunkLock(level);
1480 /**************************************************************************
1481 * waveInStart [MMSYSTEM.509]
1483 UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn16)
1488 ReleaseThunkLock(&level);
1489 ret = waveInStart(HWAVEIN_32(hWaveIn16));
1490 RestoreThunkLock(level);
1494 /**************************************************************************
1495 * waveInStop [MMSYSTEM.510]
1497 UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn16)
1502 ReleaseThunkLock(&level);
1503 ret = waveInStop(HWAVEIN_32(hWaveIn16));
1504 RestoreThunkLock(level);
1508 /**************************************************************************
1509 * waveInGetPosition [MMSYSTEM.512]
1511 UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn, LPMMTIME16 lpTime,
1517 mmt.wType = lpTime->wType;
1518 ret = waveInGetPosition(HWAVEIN_32(hWaveIn), &mmt, sizeof(mmt));
1519 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1523 /**************************************************************************
1524 * waveInGetID [MMSYSTEM.513]
1526 UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16* lpuDeviceID)
1531 ret = waveInGetID(HWAVEIN_32(hWaveIn), &devid);
1532 if (ret != MMSYSERR_NOERROR) return ret;
1533 *lpuDeviceID = devid;
1537 /**************************************************************************
1538 * waveInMessage [MMSYSTEM.514]
1540 DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
1541 DWORD dwParam1, DWORD dwParam2)
1545 TRACE("(%04x, %u, %d, %d)\n", hWaveIn, uMessage, dwParam1, dwParam2);
1547 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL) {
1548 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, TRUE)) != NULL) {
1549 if (uMessage == DRV_QUERYDRVENTRY || uMessage == DRV_QUERYDEVNODE)
1550 dwParam1 = (DWORD)MapSL(dwParam1);
1551 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1553 return MMSYSERR_INVALHANDLE;
1557 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1558 return MMSYSERR_INVALPARAM;
1560 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1563 /* ###################################################
1565 * ###################################################
1568 /*#define USE_MM_TSK_WINE*/
1570 /**************************************************************************
1571 * mmTaskCreate [MMSYSTEM.900]
1573 * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be
1574 * called upon creation with dwPmt as parameter.
1576 HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD dwPmt)
1581 DWORD showCmd = 0x40002;
1584 TRACE("(%08x, %p, %08x);\n", spProc, lphMmTask, dwPmt);
1585 /* This to work requires NE modules to be started with a binary command line
1586 * which is not currently the case. A patch exists but has never been committed.
1587 * A workaround would be to integrate code for mmtask.tsk into Wine, but
1588 * this requires tremendous work (starting with patching tools/build to
1589 * create NE executables (and not only DLLs) for builtins modules.
1592 FIXME("This is currently broken. It will fail\n");
1595 *(LPDWORD)(cmdline + 1) = (DWORD)spProc;
1596 *(LPDWORD)(cmdline + 5) = dwPmt;
1597 *(LPDWORD)(cmdline + 9) = 0;
1599 lp.hEnvironment = 0;
1600 lp.cmdLine = MapLS(cmdline);
1601 lp.showCmd = MapLS(&showCmd);
1604 #ifndef USE_MM_TSK_WINE
1605 handle = LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp);
1607 handle = LoadModule16("mmtask.tsk", &lp);
1610 ret = (handle) ? 1 : 2;
1616 *lphMmTask = handle;
1618 UnMapLS( lp.cmdLine );
1619 UnMapLS( lp.showCmd );
1620 TRACE("=> 0x%04x/%d\n", handle, ret);
1624 #ifdef USE_MM_TSK_WINE
1625 /* C equivalent to mmtask.tsk binary content */
1626 void mmTaskEntryPoint16(LPSTR cmdLine, WORD di, WORD si)
1628 int len = cmdLine[0x80];
1631 void (*fpProc)(DWORD) = MapSL(*((DWORD*)(cmdLine + 1)));
1632 DWORD dwPmt = *((DWORD*)(cmdLine + 5));
1635 InitTask16(); /* FIXME: pmts / from context ? */
1638 if (SetMessageQueue16(0x40)) {
1640 if (HIWORD(fpProc)) {
1642 /* EPP StackEnter16(); */
1654 /**************************************************************************
1655 * mmTaskBlock [MMSYSTEM.902]
1657 void WINAPI mmTaskBlock16(HINSTANCE16 hInst)
1662 GetMessageA(&msg, 0, 0, 0);
1664 TranslateMessage(&msg);
1665 DispatchMessageA(&msg);
1667 } while (msg.message < 0x3A0);
1670 /**************************************************************************
1671 * mmTaskSignal [MMSYSTEM.903]
1673 LRESULT WINAPI mmTaskSignal16(HTASK16 ht)
1675 TRACE("(%04x);\n", ht);
1676 return PostThreadMessageW( HTASK_32(ht), WM_USER, 0, 0 );
1679 /**************************************************************************
1680 * mmGetCurrentTask [MMSYSTEM.904]
1682 HTASK16 WINAPI mmGetCurrentTask16(void)
1684 return GetCurrentTask();
1687 /**************************************************************************
1688 * mmTaskYield [MMSYSTEM.905]
1690 void WINAPI mmTaskYield16(void)
1694 if (PeekMessageA(&msg, 0, 0, 0, 0)) {
1699 extern DWORD WINAPI GetProcessFlags(DWORD);
1701 /******************************************************************
1706 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16 h)
1708 return MapSL(MAKESEGPTR(h, 0));
1711 DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID);
1713 /**************************************************************************
1714 * mmThreadCreate [MMSYSTEM.1120]
1717 * Creates a MM thread, calling fpThreadAddr(dwPmt).
1719 * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc
1720 * bit.1 set means to open a VxD for this thread (unsupported)
1722 LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags)
1727 TRACE("(%p, %p, %08x, %08x)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags);
1729 hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT);
1734 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1737 /* force mmtask routines even if mmthread is required */
1738 /* this will work only if the patch about binary cmd line and NE tasks
1744 lpMMThd->dwSignature = WINE_MMTHREAD_CREATED;
1745 lpMMThd->dwCounter = 0;
1746 lpMMThd->hThread = 0;
1747 lpMMThd->dwThreadID = 0;
1748 lpMMThd->fpThread = (DWORD)fpThreadAddr;
1749 lpMMThd->dwThreadPmt = dwPmt;
1750 lpMMThd->dwSignalCount = 0;
1751 lpMMThd->hEvent = 0;
1753 lpMMThd->dwStatus = 0;
1754 lpMMThd->dwFlags = dwFlags;
1757 if ((dwFlags & 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) {
1758 lpMMThd->hEvent = CreateEventW(NULL, FALSE, TRUE, NULL);
1760 TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd);
1761 if (lpMMThd->dwFlags & 2) {
1762 /* as long as we don't support MM VxD in wine, we don't need
1763 * to care about this flag
1765 /* FIXME("Don't know how to properly open VxD handles\n"); */
1766 /* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */
1769 lpMMThd->hThread = CreateThread(0, 0, WINE_mmThreadEntryPoint,
1770 (LPVOID)(DWORD_PTR)hndl, CREATE_SUSPENDED, &lpMMThd->dwThreadID);
1771 if (lpMMThd->hThread == 0) {
1772 WARN("Couldn't create thread\n");
1773 /* clean-up(VxDhandle...); devicedirectio... */
1774 if (lpMMThd->hEvent != 0)
1775 CloseHandle(lpMMThd->hEvent);
1778 SetThreadPriority(lpMMThd->hThread, THREAD_PRIORITY_TIME_CRITICAL);
1779 TRACE("Got a nice thread hndl=%p id=0x%08x\n", lpMMThd->hThread, lpMMThd->dwThreadID);
1783 /* get WINE_mmThreadEntryPoint()
1784 * 2047 is its ordinal in mmsystem.spec
1786 FARPROC16 fp = GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR)2047);
1788 TRACE("farproc seg=0x%p lin=%p\n", fp, MapSL((SEGPTR)fp));
1790 ret = (fp == 0) ? 2 : mmTaskCreate16((DWORD)fp, 0, hndl);
1794 if (lpMMThd->hThread && !ResumeThread(lpMMThd->hThread))
1795 WARN("Couldn't resume thread\n");
1797 while (lpMMThd->dwStatus != 0x10) { /* test also HIWORD of dwStatus */
1811 TRACE("ok => %ld\n", ret);
1815 /**************************************************************************
1816 * mmThreadSignal [MMSYSTEM.1121]
1818 void WINAPI mmThreadSignal16(HANDLE16 hndl)
1820 TRACE("(%04x)!\n", hndl);
1823 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1825 lpMMThd->dwCounter++;
1826 if (lpMMThd->hThread != 0) {
1827 InterlockedIncrement(&lpMMThd->dwSignalCount);
1828 SetEvent(lpMMThd->hEvent);
1830 mmTaskSignal16(lpMMThd->hTask);
1832 lpMMThd->dwCounter--;
1836 static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd)
1841 if (lpMMThd->dwThreadID != GetCurrentThreadId())
1842 ERR("Not called by thread itself\n");
1845 ResetEvent(lpMMThd->hEvent);
1846 if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0)
1848 InterlockedIncrement(&lpMMThd->dwSignalCount);
1852 ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT);
1854 case WAIT_OBJECT_0: /* Event */
1857 case WAIT_OBJECT_0 + 1: /* Msg */
1859 if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
1860 TranslateMessage(&msg);
1861 DispatchMessageA(&msg);
1865 WARN("S2.x unsupported ret val 0x%08x\n", ret);
1871 /**************************************************************************
1872 * mmThreadBlock [MMSYSTEM.1122]
1874 void WINAPI mmThreadBlock16(HANDLE16 hndl)
1876 TRACE("(%04x)!\n", hndl);
1879 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1881 if (lpMMThd->hThread != 0) {
1884 ReleaseThunkLock(&lc);
1885 MMSYSTEM_ThreadBlock(lpMMThd);
1886 RestoreThunkLock(lc);
1888 mmTaskBlock16(lpMMThd->hTask);
1894 /**************************************************************************
1895 * mmThreadIsCurrent [MMSYSTEM.1123]
1897 BOOL16 WINAPI mmThreadIsCurrent16(HANDLE16 hndl)
1901 TRACE("(%04x)!\n", hndl);
1903 if (hndl && mmThreadIsValid16(hndl)) {
1904 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1905 ret = (GetCurrentThreadId() == lpMMThd->dwThreadID);
1907 TRACE("=> %d\n", ret);
1911 /**************************************************************************
1912 * mmThreadIsValid [MMSYSTEM.1124]
1914 BOOL16 WINAPI mmThreadIsValid16(HANDLE16 hndl)
1918 TRACE("(%04x)!\n", hndl);
1921 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1923 if (!IsBadWritePtr(lpMMThd, sizeof(WINE_MMTHREAD)) &&
1924 lpMMThd->dwSignature == WINE_MMTHREAD_CREATED &&
1925 IsTask16(lpMMThd->hTask)) {
1926 lpMMThd->dwCounter++;
1927 if (lpMMThd->hThread != 0) {
1929 if (GetExitCodeThread(lpMMThd->hThread, &dwThreadRet) &&
1930 dwThreadRet == STATUS_PENDING) {
1936 lpMMThd->dwCounter--;
1939 TRACE("=> %d\n", ret);
1943 /**************************************************************************
1944 * mmThreadGetTask [MMSYSTEM.1125]
1946 HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl)
1950 TRACE("(%04x)\n", hndl);
1952 if (mmThreadIsValid16(hndl)) {
1953 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1954 ret = lpMMThd->hTask;
1959 /**************************************************************************
1960 * __wine_mmThreadEntryPoint (MMSYSTEM.2047)
1962 DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID p)
1964 HANDLE16 hndl = (HANDLE16)(DWORD_PTR)p;
1965 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1967 TRACE("(%04x %p)\n", hndl, lpMMThd);
1969 lpMMThd->hTask = LOWORD(GetCurrentTask());
1970 TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask);
1971 lpMMThd->dwStatus = 0x10;
1972 MMSYSTEM_ThreadBlock(lpMMThd);
1973 TRACE("[20-%p]\n", lpMMThd->hThread);
1974 lpMMThd->dwStatus = 0x20;
1975 if (lpMMThd->fpThread) {
1976 WOWCallback16(lpMMThd->fpThread, lpMMThd->dwThreadPmt);
1978 lpMMThd->dwStatus = 0x30;
1979 TRACE("[30-%p]\n", lpMMThd->hThread);
1980 while (lpMMThd->dwCounter) {
1984 TRACE("[XX-%p]\n", lpMMThd->hThread);
1986 lpMMThd->dwSignature = WINE_MMTHREAD_DELETED;
1987 /* close lpMMThread->hVxD directIO */
1988 if (lpMMThd->hEvent)
1989 CloseHandle(lpMMThd->hEvent);
1996 typedef BOOL16 (WINAPI *MMCPLCALLBACK)(HWND, LPCSTR, LPCSTR, LPCSTR);
1998 /**************************************************************************
1999 * mmShowMMCPLPropertySheet [MMSYSTEM.1150]
2001 BOOL16 WINAPI mmShowMMCPLPropertySheet16(HWND hWnd, LPCSTR lpStrDevice,
2002 LPCSTR lpStrTab, LPCSTR lpStrTitle)
2007 TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2009 hndl = LoadLibraryA("MMSYS.CPL");
2011 MMCPLCALLBACK fp = (MMCPLCALLBACK)GetProcAddress(hndl, "ShowMMCPLPropertySheet");
2014 ReleaseThunkLock(&lc);
2015 ret = (fp)(hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2016 RestoreThunkLock(lc);
2024 /**************************************************************************
2025 * StackEnter [MMSYSTEM.32]
2027 void WINAPI StackEnter16(void)
2030 /* mmsystem.dll from Win 95 does only this: so does Wine */
2035 /**************************************************************************
2036 * StackLeave [MMSYSTEM.33]
2038 void WINAPI StackLeave16(void)
2041 /* mmsystem.dll from Win 95 does only this: so does Wine */
2046 /**************************************************************************
2047 * WMMMidiRunOnce [MMSYSTEM.8]
2049 void WINAPI WMMMidiRunOnce16(void)
2051 FIXME("(), stub!\n");
2054 /* ###################################################
2056 * ###################################################
2059 /**************************************************************************
2060 * DRIVER_MapMsg32To16 [internal]
2062 * Map a 32 bit driver message to a 16 bit driver message.
2064 static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, LPARAM *lParam1, LPARAM *lParam2)
2066 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2073 case DRV_QUERYCONFIGURE:
2075 case DRV_EXITSESSION:
2076 case DRV_EXITAPPLICATION:
2078 case DRV_CLOSE: /* should be 0/0 */
2079 case DRV_OPEN: /* pass through */
2080 /* lParam1 and lParam2 are not used */
2085 /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
2086 * lParam2 is a pointer to DRVCONFIGINFO
2089 LPDRVCONFIGINFO16 dci16 = HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16) );
2090 LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
2093 LPSTR str1 = NULL,str2;
2095 dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
2097 if (dci32->lpszDCISectionName) {
2098 len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, NULL, 0, NULL, NULL );
2099 str1 = HeapAlloc( GetProcessHeap(), 0, len );
2101 WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, str1, len, NULL, NULL );
2102 dci16->lpszDCISectionName = MapLS( str1 );
2104 HeapFree( GetProcessHeap(), 0, dci16);
2105 return WINMM_MAP_NOMEM;
2108 dci16->lpszDCISectionName = 0L;
2110 if (dci32->lpszDCIAliasName) {
2111 len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, NULL, 0, NULL, NULL );
2112 str2 = HeapAlloc( GetProcessHeap(), 0, len );
2114 WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, str2, len, NULL, NULL );
2115 dci16->lpszDCIAliasName = MapLS( str2 );
2117 HeapFree( GetProcessHeap(), 0, str1);
2118 HeapFree( GetProcessHeap(), 0, dci16);
2119 return WINMM_MAP_NOMEM;
2122 dci16->lpszDCISectionName = 0L;
2125 return WINMM_MAP_NOMEM;
2127 *lParam2 = MapLS( dci16 );
2128 ret = WINMM_MAP_OKMEM;
2134 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2135 FIXME("Unknown message 0x%04x\n", wMsg);
2142 /**************************************************************************
2143 * DRIVER_UnMapMsg32To16 [internal]
2145 * UnMap a 32 bit driver message to a 16 bit driver message.
2147 static WINMM_MapType DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
2149 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2156 case DRV_QUERYCONFIGURE:
2158 case DRV_EXITSESSION:
2159 case DRV_EXITAPPLICATION:
2163 /* lParam1 and lParam2 are not used */
2167 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
2169 LPDRVCONFIGINFO16 dci16 = MapSL(lParam2);
2170 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCISectionName) );
2171 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCIAliasName) );
2173 UnMapLS( dci16->lpszDCISectionName );
2174 UnMapLS( dci16->lpszDCIAliasName );
2175 HeapFree( GetProcessHeap(), 0, dci16 );
2180 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2181 FIXME("Unknown message 0x%04x\n", wMsg);
2188 /**************************************************************************
2189 * DRIVER_TryOpenDriver16 [internal]
2191 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
2193 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCWSTR fn, LPCWSTR sn, LPARAM lParam2)
2195 LPWINE_DRIVER lpDrv = NULL;
2196 LPCSTR cause = NULL;
2197 LPSTR fnA = NULL, snA = NULL;
2200 TRACE("(%s, %s, %08lX);\n", debugstr_w(fn), debugstr_w(sn), lParam2);
2202 lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
2203 if (lpDrv == NULL) {cause = "OOM"; goto exit;}
2207 len = WideCharToMultiByte( CP_ACP, 0, fn, -1, NULL, 0, NULL, NULL );
2208 fnA = HeapAlloc(GetProcessHeap(), 0, len);
2209 if (fnA == NULL) {cause = "OOM"; goto exit;}
2210 WideCharToMultiByte( CP_ACP, 0, fn, -1, fnA, len, NULL, NULL );
2215 len = WideCharToMultiByte( CP_ACP, 0, sn, -1, NULL, 0, NULL, NULL );
2216 snA = HeapAlloc(GetProcessHeap(), 0, len);
2217 if (snA == NULL) {cause = "OOM"; goto exit;}
2218 WideCharToMultiByte( CP_ACP, 0, sn, -1, snA, len, NULL, NULL );
2221 /* FIXME: shall we do some black magic here on sn ?
2222 * drivers32 => drivers
2226 lpDrv->d.d16.hDriver16 = OpenDriver16(fnA, snA, lParam2);
2227 if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;}
2228 lpDrv->dwFlags = WINE_GDF_16BIT;
2231 HeapFree(GetProcessHeap(), 0, fnA);
2232 HeapFree(GetProcessHeap(), 0, snA);
2236 TRACE("Unable to load 16 bit module %s[%s]: %s\n",
2237 debugstr_w(fn), debugstr_w(sn), cause);
2238 HeapFree(GetProcessHeap(), 0, lpDrv);
2242 TRACE("=> %p\n", lpDrv);
2246 /******************************************************************
2247 * DRIVER_SendMessage16
2251 static LRESULT DRIVER_SendMessage16(HDRVR16 hDrv16, UINT msg,
2252 LPARAM lParam1, LPARAM lParam2)
2257 TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
2258 hDrv16, msg, lParam1, lParam2);
2260 switch (map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) {
2261 case WINMM_MAP_OKMEM:
2263 ret = SendDriverMessage16(hDrv16, msg, lParam1, lParam2);
2264 if (map == WINMM_MAP_OKMEM)
2265 DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
2272 /******************************************************************
2273 * DRIVER_CloseDriver16
2277 static LRESULT DRIVER_CloseDriver16(HDRVR16 hDrv16, LPARAM lParam1, LPARAM lParam2)
2279 return CloseDriver16(hDrv16, lParam1, lParam2);
2282 /**************************************************************************
2283 * DrvOpen [MMSYSTEM.1100]
2285 HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
2287 return OpenDriver16(lpDriverName, lpSectionName, lParam);
2290 /**************************************************************************
2291 * DrvClose [MMSYSTEM.1101]
2293 LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
2295 return CloseDriver16(hDrv, lParam1, lParam2);
2298 /**************************************************************************
2299 * DrvSendMessage [MMSYSTEM.1102]
2301 LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
2304 return SendDriverMessage16(hDrv, msg, lParam1, lParam2);
2307 /**************************************************************************
2308 * DrvGetModuleHandle [MMSYSTEM.1103]
2310 HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
2312 return GetDriverModuleHandle16(hDrv);
2315 /**************************************************************************
2316 * DrvDefDriverProc [MMSYSTEM.1104]
2318 LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg,
2319 DWORD dwParam1, DWORD dwParam2)
2321 return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
2324 /**************************************************************************
2325 * DriverProc [MMSYSTEM.6]
2327 LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
2328 DWORD dwParam1, DWORD dwParam2)
2330 TRACE("dwDevID=%08x hDrv=%04x wMsg=%04x dwParam1=%08x dwParam2=%08x\n",
2331 dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2333 return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2336 /* ###################################################
2338 * ###################################################
2341 /******************************************************************
2342 * MMSYSTEM_MMTIME32to16
2346 void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32)
2348 mmt16->wType = mmt32->wType;
2349 /* layout of rest is the same for 32/16,
2350 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2352 memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u));
2355 /******************************************************************
2356 * MMSYSTEM_MMTIME16to32
2360 void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16)
2362 mmt32->wType = mmt16->wType;
2363 /* layout of rest is the same for 32/16,
2364 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2366 memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u));
2369 /**************************************************************************
2370 * timeGetSystemTime [MMSYSTEM.601]
2372 MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
2374 if (wSize >= sizeof(*lpTime)) {
2375 lpTime->wType = TIME_MS;
2376 lpTime->u.ms = GetTickCount();
2378 TRACE("=> %u\n", lpTime->u.ms);
2384 struct timer_entry {
2387 LPTIMECALLBACK16 func16;
2391 static struct list timer_list = LIST_INIT(timer_list);
2393 static void CALLBACK timeCB3216(UINT id, UINT uMsg, DWORD_PTR user, DWORD_PTR dw1, DWORD_PTR dw2)
2395 struct timer_entry* te = (void*)user;
2399 args[7] = LOWORD(id);
2400 args[6] = LOWORD(uMsg);
2401 args[5] = HIWORD(te->user);
2402 args[4] = LOWORD(te->user);
2403 args[3] = HIWORD(dw1);
2404 args[2] = LOWORD(dw2);
2405 args[1] = HIWORD(dw2);
2406 args[0] = LOWORD(dw2);
2407 WOWCallback16Ex((DWORD)te->func16, WCB16_PASCAL, sizeof(args), args, &ret);
2410 /**************************************************************************
2411 * timeSetEvent [MMSYSTEM.602]
2413 MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc,
2414 DWORD dwUser, UINT16 wFlags)
2417 struct timer_entry* te;
2419 switch (wFlags & (TIME_CALLBACK_EVENT_SET|TIME_CALLBACK_EVENT_PULSE))
2421 case TIME_CALLBACK_EVENT_SET:
2422 case TIME_CALLBACK_EVENT_PULSE:
2423 id = timeSetEvent(wDelay, wResol, (LPTIMECALLBACK)lpFunc, dwUser, wFlags);
2425 case TIME_CALLBACK_FUNCTION:
2426 te = HeapAlloc(GetProcessHeap(), 0, sizeof(*te));
2428 te->func16 = lpFunc;
2430 id = te->id = timeSetEvent(wDelay, wResol, timeCB3216, (DWORD_PTR)te, wFlags);
2433 EnterCriticalSection(&mmdrv_cs);
2434 list_add_tail(&timer_list, &te->entry);
2435 LeaveCriticalSection(&mmdrv_cs);
2437 else HeapFree(GetProcessHeap(), 0, te);
2446 /**************************************************************************
2447 * timeKillEvent [MMSYSTEM.603]
2449 MMRESULT16 WINAPI timeKillEvent16(UINT16 wID)
2451 MMRESULT16 ret = timeKillEvent(wID);
2452 struct timer_entry* te;
2454 if (ret == TIMERR_NOERROR)
2456 EnterCriticalSection(&mmdrv_cs);
2457 LIST_FOR_EACH_ENTRY(te, &timer_list, struct timer_entry, entry)
2461 list_remove(&te->entry);
2462 HeapFree(GetProcessHeap(), 0, te);
2466 LeaveCriticalSection(&mmdrv_cs);
2471 /**************************************************************************
2472 * timeGetDevCaps [MMSYSTEM.604]
2474 MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize)
2478 TRACE("(%p, %u) !\n", lpCaps, wSize);
2480 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2482 ret = timeGetDevCaps(&caps, sizeof(caps));
2483 if (ret == MMSYSERR_NOERROR) {
2485 tc16.wPeriodMin = caps.wPeriodMin;
2486 tc16.wPeriodMax = caps.wPeriodMax;
2487 memcpy(lpCaps, &tc16, min(wSize, sizeof(tc16)));
2492 /**************************************************************************
2493 * timeBeginPeriod [MMSYSTEM.605]
2495 MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod)
2497 TRACE("(%u) !\n", wPeriod);
2499 return timeBeginPeriod(wPeriod);
2502 /**************************************************************************
2503 * timeEndPeriod [MMSYSTEM.606]
2505 MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod)
2507 TRACE("(%u) !\n", wPeriod);
2509 return timeEndPeriod(wPeriod);
2512 /**************************************************************************
2513 * mciLoadCommandResource [MMSYSTEM.705]
2515 UINT16 WINAPI mciLoadCommandResource16(HINSTANCE16 hInst, LPCSTR resname, UINT16 type)
2521 unsigned pos = 0, size = 1024, len;
2525 UINT16 ret = MCIERR_OUT_OF_MEMORY;
2527 if (!(res = FindResource16( hInst, resname, (LPSTR)RT_RCDATA))) return MCI_NO_COMMAND_TABLE;
2528 if (!(handle = LoadResource16( hInst, res ))) return MCI_NO_COMMAND_TABLE;
2529 ptr16 = LockResource16(handle);
2530 /* converting the 16 bit resource table into a 32W one */
2531 if ((ptr32 = HeapAlloc(GetProcessHeap(), 0, size)))
2534 str = (LPCSTR)ptr16;
2535 ptr16 += strlen(str) + 1;
2536 flg = *(const DWORD*)ptr16;
2537 eid = *(const WORD*)(ptr16 + sizeof(DWORD));
2538 ptr16 += sizeof(DWORD) + sizeof(WORD);
2539 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0) * sizeof(WCHAR);
2540 if (pos + len + sizeof(DWORD) + sizeof(WORD) > size)
2542 while (pos + len * sizeof(WCHAR) + sizeof(DWORD) + sizeof(WORD) > size) size += 1024;
2543 ptr32 = HeapReAlloc(GetProcessHeap(), 0, ptr32, size);
2544 if (!ptr32) goto the_end;
2546 MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)(ptr32 + pos), len / sizeof(WCHAR));
2547 *(DWORD*)(ptr32 + pos + len) = flg;
2548 *(WORD*)(ptr32 + pos + len + sizeof(DWORD)) = eid;
2549 pos += len + sizeof(DWORD) + sizeof(WORD);
2550 } while (eid != MCI_END_COMMAND_LIST);
2553 FreeResource16( handle );
2554 if (ptr32) ret = MCI_SetCommandTable(ptr32, type);
2558 /**************************************************************************
2559 * mciFreeCommandResource [MMSYSTEM.713]
2561 BOOL16 WINAPI mciFreeCommandResource16(UINT16 uTable)
2563 TRACE("(%04x)!\n", uTable);
2565 return MCI_DeleteCommandTable(uTable, TRUE);
2568 /* ###################################################
2570 * ###################################################
2573 /**************************************************************************
2574 * joyGetNumDevs [MMSYSTEM.101]
2576 UINT16 WINAPI joyGetNumDevs16(void)
2578 return joyGetNumDevs();
2581 /**************************************************************************
2582 * joyGetDevCaps [MMSYSTEM.102]
2584 MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize)
2589 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2591 ret = joyGetDevCapsA(wID, &jca, sizeof(jca));
2593 if (ret != JOYERR_NOERROR) return ret;
2594 lpCaps->wMid = jca.wMid;
2595 lpCaps->wPid = jca.wPid;
2596 strcpy(lpCaps->szPname, jca.szPname);
2597 lpCaps->wXmin = jca.wXmin;
2598 lpCaps->wXmax = jca.wXmax;
2599 lpCaps->wYmin = jca.wYmin;
2600 lpCaps->wYmax = jca.wYmax;
2601 lpCaps->wZmin = jca.wZmin;
2602 lpCaps->wZmax = jca.wZmax;
2603 lpCaps->wNumButtons = jca.wNumButtons;
2604 lpCaps->wPeriodMin = jca.wPeriodMin;
2605 lpCaps->wPeriodMax = jca.wPeriodMax;
2607 if (wSize >= sizeof(JOYCAPS16)) { /* Win95 extensions ? */
2608 lpCaps->wRmin = jca.wRmin;
2609 lpCaps->wRmax = jca.wRmax;
2610 lpCaps->wUmin = jca.wUmin;
2611 lpCaps->wUmax = jca.wUmax;
2612 lpCaps->wVmin = jca.wVmin;
2613 lpCaps->wVmax = jca.wVmax;
2614 lpCaps->wCaps = jca.wCaps;
2615 lpCaps->wMaxAxes = jca.wMaxAxes;
2616 lpCaps->wNumAxes = jca.wNumAxes;
2617 lpCaps->wMaxButtons = jca.wMaxButtons;
2618 strcpy(lpCaps->szRegKey, jca.szRegKey);
2619 strcpy(lpCaps->szOEMVxD, jca.szOEMVxD);
2625 /**************************************************************************
2626 * joyGetPosEx [MMSYSTEM.110]
2628 MMRESULT16 WINAPI joyGetPosEx16(UINT16 wID, LPJOYINFOEX lpInfo)
2630 return joyGetPosEx(wID, lpInfo);
2633 /**************************************************************************
2634 * joyGetPos [MMSYSTEM.103]
2636 MMRESULT16 WINAPI joyGetPos16(UINT16 wID, LPJOYINFO16 lpInfo)
2641 TRACE("(%d, %p);\n", wID, lpInfo);
2643 if ((ret = joyGetPos(wID, &ji)) == JOYERR_NOERROR) {
2644 lpInfo->wXpos = ji.wXpos;
2645 lpInfo->wYpos = ji.wYpos;
2646 lpInfo->wZpos = ji.wZpos;
2647 lpInfo->wButtons = ji.wButtons;
2652 /**************************************************************************
2653 * joyGetThreshold [MMSYSTEM.104]
2655 MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold)
2660 ret = joyGetThreshold(wID, &t);
2661 if (ret == JOYERR_NOERROR)
2666 /**************************************************************************
2667 * joyReleaseCapture [MMSYSTEM.105]
2669 MMRESULT16 WINAPI joyReleaseCapture16(UINT16 wID)
2671 return joyReleaseCapture(wID);
2674 /**************************************************************************
2675 * joySetCapture [MMSYSTEM.106]
2677 MMRESULT16 WINAPI joySetCapture16(HWND16 hWnd, UINT16 wID, UINT16 wPeriod, BOOL16 bChanged)
2679 return joySetCapture(HWND_32(hWnd), wID, wPeriod, bChanged);
2682 /**************************************************************************
2683 * joySetThreshold [MMSYSTEM.107]
2685 MMRESULT16 WINAPI joySetThreshold16(UINT16 wID, UINT16 wThreshold)
2687 return joySetThreshold(wID,wThreshold);
2690 /**************************************************************************
2691 * joySetCalibration [MMSYSTEM.109]
2693 MMRESULT16 WINAPI joySetCalibration16(UINT16 wID)
2695 FIXME("(%04X): stub.\n", wID);
2696 return JOYERR_NOCANDO;