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_DEBUG mmdrv_critsect_debug
=
58 { &mmdrv_critsect_debug
.ProcessLocksList
, &mmdrv_critsect_debug
.ProcessLocksList
},
59 0, 0, { (DWORD_PTR
)(__FILE__
": mmsystem_mmdrv_cs") }
61 CRITICAL_SECTION mmdrv_cs
= { &mmdrv_critsect_debug
, -1, 0, 0, 0, 0 };
63 /* ###################################################
65 * ###################################################
68 /**************************************************************************
69 * DllEntryPoint (MMSYSTEM.4)
71 * MMSYSTEM DLL entry point
74 BOOL WINAPI
MMSYSTEM_LibMain(DWORD fdwReason
, HINSTANCE hinstDLL
, WORD ds
,
75 WORD wHeapSize
, DWORD dwReserved1
, WORD wReserved2
)
77 TRACE("%p 0x%x\n", hinstDLL
, fdwReason
);
80 case DLL_PROCESS_ATTACH
:
81 /* need to load WinMM in order to:
82 * - initiate correctly shared variables (WINMM_Init())
84 if (!GetModuleHandleA("WINMM.DLL"))
86 ERR("Could not load sibling WinMM.dll\n");
89 /* hook in our 16 bit function pointers */
90 pFnGetMMThread16
= WINMM_GetmmThread
;
91 pFnOpenDriver16
= DRIVER_OpenDriver16
;
92 pFnCloseDriver16
= DRIVER_CloseDriver16
;
93 pFnSendMessage16
= DRIVER_SendMessage16
;
94 pFnReleaseThunkLock
= ReleaseThunkLock
;
95 pFnRestoreThunkLock
= RestoreThunkLock
;
98 case DLL_PROCESS_DETACH
:
99 pFnGetMMThread16
= NULL
;
100 pFnOpenDriver16
= NULL
;
101 pFnCloseDriver16
= NULL
;
102 pFnSendMessage16
= NULL
;
103 pFnReleaseThunkLock
= NULL
;
104 pFnRestoreThunkLock
= NULL
;
105 /* FIXME: add equivalent for MMDRV_Init16() */
107 case DLL_THREAD_ATTACH
:
108 case DLL_THREAD_DETACH
:
114 /**************************************************************************
117 int WINAPI
MMSYSTEM_WEP(HINSTANCE16 hInstance
, WORD wDataSeg
,
118 WORD cbHeapSize
, LPSTR lpCmdLine
)
120 TRACE("STUB: Unloading MMSystem DLL ... hInst=%04X\n", hInstance
);
124 /* ###################################################
126 * ###################################################
129 /**************************************************************************
130 * PlaySound [MMSYSTEM.3]
132 BOOL16 WINAPI
PlaySound16(LPCSTR pszSound
, HMODULE16 hmod
, DWORD fdwSound
)
137 if ((fdwSound
& SND_RESOURCE
) == SND_RESOURCE
)
142 if (!(res
= FindResource16( hmod
, pszSound
, "WAVE" ))) return FALSE
;
143 if (!(handle
= LoadResource16( hmod
, res
))) return FALSE
;
144 pszSound
= LockResource16(handle
);
145 fdwSound
= (fdwSound
& ~SND_RESOURCE
) | SND_MEMORY
;
146 /* FIXME: FreeResource16 */
149 ReleaseThunkLock(&lc
);
150 retv
= PlaySoundA(pszSound
, 0, fdwSound
);
151 RestoreThunkLock(lc
);
156 /**************************************************************************
157 * sndPlaySound [MMSYSTEM.2]
159 BOOL16 WINAPI
sndPlaySound16(LPCSTR lpszSoundName
, UINT16 uFlags
)
164 ReleaseThunkLock(&lc
);
165 retv
= sndPlaySoundA(lpszSoundName
, uFlags
);
166 RestoreThunkLock(lc
);
171 /* ###################################################
173 * ###################################################
176 /**************************************************************************
177 * mmsystemGetVersion [MMSYSTEM.5]
180 UINT16 WINAPI
mmsystemGetVersion16(void)
182 return mmsystemGetVersion();
185 /**************************************************************************
186 * DriverCallback [MMSYSTEM.31]
188 BOOL16 WINAPI
DriverCallback16(DWORD dwCallBack
, UINT16 uFlags
, HDRVR16 hDev
,
189 WORD wMsg
, DWORD dwUser
, DWORD dwParam1
,
192 return DriverCallback(dwCallBack
, uFlags
, HDRVR_32(hDev
), wMsg
, dwUser
, dwParam1
, dwParam2
);
195 /**************************************************************************
196 * OutputDebugStr [MMSYSTEM.30]
198 void WINAPI
OutputDebugStr16(LPCSTR str
)
200 OutputDebugStringA( str
);
203 /* ###################################################
205 * ###################################################
208 /**************************************************************************
209 * Mixer devices. New to Win95
212 /**************************************************************************
213 * mixerGetNumDevs [MMSYSTEM.800]
215 UINT16 WINAPI
mixerGetNumDevs16(void)
217 return mixerGetNumDevs();
220 /**************************************************************************
221 * mixerGetDevCaps [MMSYSTEM.801]
223 UINT16 WINAPI
mixerGetDevCaps16(UINT16 uDeviceID
, LPMIXERCAPS16 lpCaps
,
229 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
231 ret
= mixerGetDevCapsA(uDeviceID
, &micA
, sizeof(micA
));
232 if (ret
== MMSYSERR_NOERROR
) {
234 mic16
.wMid
= micA
.wMid
;
235 mic16
.wPid
= micA
.wPid
;
236 mic16
.vDriverVersion
= micA
.vDriverVersion
;
237 strcpy(mic16
.szPname
, micA
.szPname
);
238 mic16
.fdwSupport
= micA
.fdwSupport
;
239 mic16
.cDestinations
= micA
.cDestinations
;
240 memcpy(lpCaps
, &mic16
, min(uSize
, sizeof(mic16
)));
245 /**************************************************************************
246 * mixerOpen [MMSYSTEM.802]
248 UINT16 WINAPI
mixerOpen16(LPHMIXER16 lphmix
, UINT16 uDeviceID
, DWORD dwCallback
,
249 DWORD dwInstance
, DWORD fdwOpen
)
254 ret
= MIXER_Open(&hmix
, uDeviceID
, dwCallback
, dwInstance
, fdwOpen
, FALSE
);
255 if (lphmix
) *lphmix
= HMIXER_16(hmix
);
259 /**************************************************************************
260 * mixerClose [MMSYSTEM.803]
262 UINT16 WINAPI
mixerClose16(HMIXER16 hMix
)
264 return mixerClose(HMIXER_32(hMix
));
267 /**************************************************************************
268 * mixerGetID (MMSYSTEM.806)
270 UINT16 WINAPI
mixerGetID16(HMIXEROBJ16 hmix
, LPUINT16 lpid
, DWORD fdwID
)
273 UINT ret
= mixerGetID(HMIXEROBJ_32(hmix
), &xid
, fdwID
);
280 /**************************************************************************
281 * mixerGetControlDetails [MMSYSTEM.808]
283 UINT16 WINAPI
mixerGetControlDetails16(HMIXEROBJ16 hmix
,
284 LPMIXERCONTROLDETAILS16 lpmcd
,
287 DWORD ret
= MMSYSERR_NOTENABLED
;
290 TRACE("(%04x, %p, %08x)\n", hmix
, lpmcd
, fdwDetails
);
292 if (lpmcd
== NULL
|| lpmcd
->cbStruct
!= sizeof(*lpmcd
))
293 return MMSYSERR_INVALPARAM
;
295 sppaDetails
= (SEGPTR
)lpmcd
->paDetails
;
296 lpmcd
->paDetails
= MapSL(sppaDetails
);
297 ret
= mixerGetControlDetailsA(HMIXEROBJ_32(hmix
),
298 (LPMIXERCONTROLDETAILS
)lpmcd
, fdwDetails
);
299 lpmcd
->paDetails
= (LPVOID
)sppaDetails
;
304 /**************************************************************************
305 * mixerGetLineControls [MMSYSTEM.807]
307 UINT16 WINAPI
mixerGetLineControls16(HMIXEROBJ16 hmix
,
308 LPMIXERLINECONTROLS16 lpmlc16
,
311 MIXERLINECONTROLSA mlcA
;
314 LPMIXERCONTROL16 lpmc16
;
316 TRACE("(%04x, %p, %08x)\n", hmix
, lpmlc16
, fdwControls
);
318 if (lpmlc16
== NULL
|| lpmlc16
->cbStruct
!= sizeof(*lpmlc16
) ||
319 lpmlc16
->cbmxctrl
!= sizeof(MIXERCONTROL16
))
320 return MMSYSERR_INVALPARAM
;
322 mlcA
.cbStruct
= sizeof(mlcA
);
323 mlcA
.dwLineID
= lpmlc16
->dwLineID
;
324 mlcA
.u
.dwControlID
= lpmlc16
->u
.dwControlID
;
325 mlcA
.u
.dwControlType
= lpmlc16
->u
.dwControlType
;
326 mlcA
.cControls
= lpmlc16
->cControls
;
327 mlcA
.cbmxctrl
= sizeof(MIXERCONTROLA
);
328 mlcA
.pamxctrl
= HeapAlloc(GetProcessHeap(), 0,
329 mlcA
.cControls
* mlcA
.cbmxctrl
);
331 ret
= mixerGetLineControlsA(HMIXEROBJ_32(hmix
), &mlcA
, fdwControls
);
333 if (ret
== MMSYSERR_NOERROR
) {
334 lpmlc16
->dwLineID
= mlcA
.dwLineID
;
335 lpmlc16
->u
.dwControlID
= mlcA
.u
.dwControlID
;
336 lpmlc16
->u
.dwControlType
= mlcA
.u
.dwControlType
;
337 lpmlc16
->cControls
= mlcA
.cControls
;
339 lpmc16
= MapSL(lpmlc16
->pamxctrl
);
341 for (i
= 0; i
< mlcA
.cControls
; i
++) {
342 lpmc16
[i
].cbStruct
= sizeof(MIXERCONTROL16
);
343 lpmc16
[i
].dwControlID
= mlcA
.pamxctrl
[i
].dwControlID
;
344 lpmc16
[i
].dwControlType
= mlcA
.pamxctrl
[i
].dwControlType
;
345 lpmc16
[i
].fdwControl
= mlcA
.pamxctrl
[i
].fdwControl
;
346 lpmc16
[i
].cMultipleItems
= mlcA
.pamxctrl
[i
].cMultipleItems
;
347 strcpy(lpmc16
[i
].szShortName
, mlcA
.pamxctrl
[i
].szShortName
);
348 strcpy(lpmc16
[i
].szName
, mlcA
.pamxctrl
[i
].szName
);
349 /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
350 memcpy(&lpmc16
[i
].Bounds
, &mlcA
.pamxctrl
[i
].Bounds
,
351 sizeof(mlcA
.pamxctrl
[i
].Bounds
));
352 /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
353 memcpy(&lpmc16
[i
].Metrics
, &mlcA
.pamxctrl
[i
].Metrics
,
354 sizeof(mlcA
.pamxctrl
[i
].Metrics
));
358 HeapFree(GetProcessHeap(), 0, mlcA
.pamxctrl
);
363 /**************************************************************************
364 * mixerGetLineInfo [MMSYSTEM.805]
366 UINT16 WINAPI
mixerGetLineInfo16(HMIXEROBJ16 hmix
, LPMIXERLINE16 lpmli16
,
372 TRACE("(%04x, %p, %08x)\n", hmix
, lpmli16
, fdwInfo
);
374 if (lpmli16
== NULL
|| lpmli16
->cbStruct
!= sizeof(*lpmli16
))
375 return MMSYSERR_INVALPARAM
;
377 mliA
.cbStruct
= sizeof(mliA
);
378 switch (fdwInfo
& MIXER_GETLINEINFOF_QUERYMASK
) {
379 case MIXER_GETLINEINFOF_COMPONENTTYPE
:
380 mliA
.dwComponentType
= lpmli16
->dwComponentType
;
382 case MIXER_GETLINEINFOF_DESTINATION
:
383 mliA
.dwDestination
= lpmli16
->dwDestination
;
385 case MIXER_GETLINEINFOF_LINEID
:
386 mliA
.dwLineID
= lpmli16
->dwLineID
;
388 case MIXER_GETLINEINFOF_SOURCE
:
389 mliA
.dwDestination
= lpmli16
->dwDestination
;
390 mliA
.dwSource
= lpmli16
->dwSource
;
392 case MIXER_GETLINEINFOF_TARGETTYPE
:
393 mliA
.Target
.dwType
= lpmli16
->Target
.dwType
;
394 mliA
.Target
.wMid
= lpmli16
->Target
.wMid
;
395 mliA
.Target
.wPid
= lpmli16
->Target
.wPid
;
396 mliA
.Target
.vDriverVersion
= lpmli16
->Target
.vDriverVersion
;
397 strcpy(mliA
.Target
.szPname
, lpmli16
->Target
.szPname
);
400 FIXME("Unsupported fdwControls=0x%08x\n", fdwInfo
);
403 ret
= mixerGetLineInfoA(HMIXEROBJ_32(hmix
), &mliA
, fdwInfo
);
405 lpmli16
->dwDestination
= mliA
.dwDestination
;
406 lpmli16
->dwSource
= mliA
.dwSource
;
407 lpmli16
->dwLineID
= mliA
.dwLineID
;
408 lpmli16
->fdwLine
= mliA
.fdwLine
;
409 lpmli16
->dwUser
= mliA
.dwUser
;
410 lpmli16
->dwComponentType
= mliA
.dwComponentType
;
411 lpmli16
->cChannels
= mliA
.cChannels
;
412 lpmli16
->cConnections
= mliA
.cConnections
;
413 lpmli16
->cControls
= mliA
.cControls
;
414 strcpy(lpmli16
->szShortName
, mliA
.szShortName
);
415 strcpy(lpmli16
->szName
, mliA
.szName
);
416 lpmli16
->Target
.dwType
= mliA
.Target
.dwType
;
417 lpmli16
->Target
.dwDeviceID
= mliA
.Target
.dwDeviceID
;
418 lpmli16
->Target
.wMid
= mliA
.Target
.wMid
;
419 lpmli16
->Target
.wPid
= mliA
.Target
.wPid
;
420 lpmli16
->Target
.vDriverVersion
= mliA
.Target
.vDriverVersion
;
421 strcpy(lpmli16
->Target
.szPname
, mliA
.Target
.szPname
);
426 /**************************************************************************
427 * mixerSetControlDetails [MMSYSTEM.809]
429 UINT16 WINAPI
mixerSetControlDetails16(HMIXEROBJ16 hmix
,
430 LPMIXERCONTROLDETAILS16 lpmcd
,
433 TRACE("(%04x, %p, %08x)\n", hmix
, lpmcd
, fdwDetails
);
434 return MMSYSERR_NOTENABLED
;
437 /**************************************************************************
438 * mixerMessage [MMSYSTEM.804]
440 DWORD WINAPI
mixerMessage16(HMIXER16 hmix
, UINT16 uMsg
, DWORD dwParam1
,
443 return mixerMessage(HMIXER_32(hmix
), uMsg
, dwParam1
, dwParam2
);
446 /* ###################################################
448 * ###################################################
451 /**************************************************************************
452 * auxGetNumDevs [MMSYSTEM.350]
454 UINT16 WINAPI
auxGetNumDevs16(void)
456 return auxGetNumDevs();
459 /**************************************************************************
460 * auxGetDevCaps [MMSYSTEM.351]
462 UINT16 WINAPI
auxGetDevCaps16(UINT16 uDeviceID
, LPAUXCAPS16 lpCaps
, UINT16 uSize
)
467 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
469 ret
= auxGetDevCapsA(uDeviceID
, &acA
, sizeof(acA
));
470 if (ret
== MMSYSERR_NOERROR
) {
472 ac16
.wMid
= acA
.wMid
;
473 ac16
.wPid
= acA
.wPid
;
474 ac16
.vDriverVersion
= acA
.vDriverVersion
;
475 strcpy(ac16
.szPname
, acA
.szPname
);
476 ac16
.wTechnology
= acA
.wTechnology
;
477 ac16
.dwSupport
= acA
.dwSupport
;
478 memcpy(lpCaps
, &ac16
, min(uSize
, sizeof(ac16
)));
483 /**************************************************************************
484 * auxGetVolume [MMSYSTEM.352]
486 UINT16 WINAPI
auxGetVolume16(UINT16 uDeviceID
, LPDWORD lpdwVolume
)
488 return auxGetVolume(uDeviceID
, lpdwVolume
);
491 /**************************************************************************
492 * auxSetVolume [MMSYSTEM.353]
494 UINT16 WINAPI
auxSetVolume16(UINT16 uDeviceID
, DWORD dwVolume
)
496 return auxSetVolume(uDeviceID
, dwVolume
);
499 /**************************************************************************
500 * auxOutMessage [MMSYSTEM.354]
502 DWORD WINAPI
auxOutMessage16(UINT16 uDeviceID
, UINT16 uMessage
, DWORD dw1
, DWORD dw2
)
504 TRACE("(%04X, %04X, %08X, %08X)\n", uDeviceID
, uMessage
, dw1
, dw2
);
507 case AUXDM_GETNUMDEVS
:
508 case AUXDM_SETVOLUME
:
509 /* no argument conversion needed */
511 case AUXDM_GETVOLUME
:
512 return auxGetVolume(uDeviceID
, MapSL(dw1
));
513 case AUXDM_GETDEVCAPS
:
514 return auxGetDevCaps16(uDeviceID
, MapSL(dw1
), dw2
);
516 TRACE("(%04x, %04x, %08x, %08x): unhandled message\n",
517 uDeviceID
, uMessage
, dw1
, dw2
);
520 return auxOutMessage(uDeviceID
, uMessage
, dw1
, dw2
);
523 /* ###################################################
525 * ###################################################
528 /**************************************************************************
529 * midiOutGetNumDevs [MMSYSTEM.201]
531 UINT16 WINAPI
midiOutGetNumDevs16(void)
533 return midiOutGetNumDevs();
536 /**************************************************************************
537 * midiOutGetDevCaps [MMSYSTEM.202]
539 UINT16 WINAPI
midiOutGetDevCaps16(UINT16 uDeviceID
, LPMIDIOUTCAPS16 lpCaps
,
545 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
547 ret
= midiOutGetDevCapsA(uDeviceID
, &mocA
, sizeof(mocA
));
548 if (ret
== MMSYSERR_NOERROR
) {
550 moc16
.wMid
= mocA
.wMid
;
551 moc16
.wPid
= mocA
.wPid
;
552 moc16
.vDriverVersion
= mocA
.vDriverVersion
;
553 strcpy(moc16
.szPname
, mocA
.szPname
);
554 moc16
.wTechnology
= mocA
.wTechnology
;
555 moc16
.wVoices
= mocA
.wVoices
;
556 moc16
.wNotes
= mocA
.wNotes
;
557 moc16
.wChannelMask
= mocA
.wChannelMask
;
558 moc16
.dwSupport
= mocA
.dwSupport
;
559 memcpy(lpCaps
, &moc16
, min(uSize
, sizeof(moc16
)));
564 /**************************************************************************
565 * midiOutGetErrorText [MMSYSTEM.203]
566 * midiInGetErrorText [MMSYSTEM.303]
568 UINT16 WINAPI
midiOutGetErrorText16(UINT16 uError
, LPSTR lpText
, UINT16 uSize
)
570 return midiOutGetErrorTextA(uError
, lpText
, uSize
);
573 /**************************************************************************
574 * midiOutOpen [MMSYSTEM.204]
576 UINT16 WINAPI
midiOutOpen16(HMIDIOUT16
* lphMidiOut
, UINT16 uDeviceID
,
577 DWORD dwCallback
, DWORD dwInstance
, DWORD dwFlags
)
582 ret
= MIDI_OutOpen(&hmo
, uDeviceID
, dwCallback
, dwInstance
, dwFlags
, FALSE
);
584 if (lphMidiOut
!= NULL
) *lphMidiOut
= HMIDIOUT_16(hmo
);
588 /**************************************************************************
589 * midiOutClose [MMSYSTEM.205]
591 UINT16 WINAPI
midiOutClose16(HMIDIOUT16 hMidiOut
)
593 return midiOutClose(HMIDIOUT_32(hMidiOut
));
596 /**************************************************************************
597 * midiOutPrepareHeader [MMSYSTEM.206]
599 UINT16 WINAPI
midiOutPrepareHeader16(HMIDIOUT16 hMidiOut
, /* [in] */
600 SEGPTR lpsegMidiOutHdr
, /* [???] */
601 UINT16 uSize
) /* [in] */
605 TRACE("(%04X, %08x, %d)\n", hMidiOut
, lpsegMidiOutHdr
, uSize
);
607 if ((wmld
= MMDRV_Get(HMIDIOUT_32(hMidiOut
), MMDRV_MIDIOUT
, FALSE
)) == NULL
)
608 return MMSYSERR_INVALHANDLE
;
610 return MMDRV_Message(wmld
, MODM_PREPARE
, lpsegMidiOutHdr
, uSize
, FALSE
);
613 /**************************************************************************
614 * midiOutUnprepareHeader [MMSYSTEM.207]
616 UINT16 WINAPI
midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut
, /* [in] */
617 SEGPTR lpsegMidiOutHdr
, /* [???] */
618 UINT16 uSize
) /* [in] */
621 LPMIDIHDR16 lpMidiOutHdr
= MapSL(lpsegMidiOutHdr
);
623 TRACE("(%04X, %08x, %d)\n", hMidiOut
, lpsegMidiOutHdr
, uSize
);
625 if (!(lpMidiOutHdr
->dwFlags
& MHDR_PREPARED
)) {
626 return MMSYSERR_NOERROR
;
629 if ((wmld
= MMDRV_Get(HMIDIOUT_32(hMidiOut
), MMDRV_MIDIOUT
, FALSE
)) == NULL
)
630 return MMSYSERR_INVALHANDLE
;
632 return MMDRV_Message(wmld
, MODM_UNPREPARE
, lpsegMidiOutHdr
, uSize
, FALSE
);
635 /**************************************************************************
636 * midiOutShortMsg [MMSYSTEM.208]
638 UINT16 WINAPI
midiOutShortMsg16(HMIDIOUT16 hMidiOut
, DWORD dwMsg
)
640 return midiOutShortMsg(HMIDIOUT_32(hMidiOut
), dwMsg
);
643 /**************************************************************************
644 * midiOutLongMsg [MMSYSTEM.209]
646 UINT16 WINAPI
midiOutLongMsg16(HMIDIOUT16 hMidiOut
, /* [in] */
647 LPMIDIHDR16 lpsegMidiOutHdr
, /* [???] NOTE: SEGPTR */
648 UINT16 uSize
) /* [in] */
652 TRACE("(%04X, %p, %d)\n", hMidiOut
, lpsegMidiOutHdr
, uSize
);
654 if ((wmld
= MMDRV_Get(HMIDIOUT_32(hMidiOut
), MMDRV_MIDIOUT
, FALSE
)) == NULL
)
655 return MMSYSERR_INVALHANDLE
;
657 return MMDRV_Message(wmld
, MODM_LONGDATA
, (DWORD_PTR
)lpsegMidiOutHdr
, uSize
, FALSE
);
660 /**************************************************************************
661 * midiOutReset [MMSYSTEM.210]
663 UINT16 WINAPI
midiOutReset16(HMIDIOUT16 hMidiOut
)
665 return midiOutReset(HMIDIOUT_32(hMidiOut
));
668 /**************************************************************************
669 * midiOutGetVolume [MMSYSTEM.211]
671 UINT16 WINAPI
midiOutGetVolume16(UINT16 uDeviceID
, DWORD
* lpdwVolume
)
673 return midiOutGetVolume(HMIDIOUT_32(uDeviceID
), lpdwVolume
);
676 /**************************************************************************
677 * midiOutSetVolume [MMSYSTEM.212]
679 UINT16 WINAPI
midiOutSetVolume16(UINT16 uDeviceID
, DWORD dwVolume
)
681 return midiOutSetVolume(HMIDIOUT_32(uDeviceID
), dwVolume
);
684 /**************************************************************************
685 * midiOutCachePatches [MMSYSTEM.213]
687 UINT16 WINAPI
midiOutCachePatches16(HMIDIOUT16 hMidiOut
, UINT16 uBank
,
688 WORD
* lpwPatchArray
, UINT16 uFlags
)
690 return midiOutCachePatches(HMIDIOUT_32(hMidiOut
), uBank
, lpwPatchArray
,
694 /**************************************************************************
695 * midiOutCacheDrumPatches [MMSYSTEM.214]
697 UINT16 WINAPI
midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut
, UINT16 uPatch
,
698 WORD
* lpwKeyArray
, UINT16 uFlags
)
700 return midiOutCacheDrumPatches(HMIDIOUT_32(hMidiOut
), uPatch
, lpwKeyArray
, uFlags
);
703 /**************************************************************************
704 * midiOutGetID [MMSYSTEM.215]
706 UINT16 WINAPI
midiOutGetID16(HMIDIOUT16 hMidiOut
, UINT16
* lpuDeviceID
)
711 ret
= midiOutGetID(HMIDIOUT_32(hMidiOut
), &devid
);
712 if (ret
!= MMSYSERR_NOERROR
) return ret
;
713 *lpuDeviceID
= devid
;
717 /**************************************************************************
718 * midiOutMessage [MMSYSTEM.216]
720 DWORD WINAPI
midiOutMessage16(HMIDIOUT16 hMidiOut
, UINT16 uMessage
,
721 DWORD dwParam1
, DWORD dwParam2
)
725 TRACE("(%04X, %04X, %08X, %08X)\n", hMidiOut
, uMessage
, dwParam1
, dwParam2
);
727 if ((wmld
= MMDRV_Get(HMIDIOUT_32(hMidiOut
), MMDRV_MIDIOUT
, FALSE
)) == NULL
)
728 return MMSYSERR_INVALHANDLE
;
733 FIXME("can't handle OPEN or CLOSE message!\n");
734 return MMSYSERR_NOTSUPPORTED
;
737 return midiOutGetVolume16(hMidiOut
, MapSL(dwParam1
));
739 return midiOutLongMsg16(hMidiOut
, MapSL(dwParam1
), dwParam2
);
741 /* lpMidiOutHdr is still a segmented pointer for this function */
742 return midiOutPrepareHeader16(hMidiOut
, dwParam1
, dwParam2
);
744 return midiOutUnprepareHeader16(hMidiOut
, dwParam1
, dwParam2
);
746 return MMDRV_Message(wmld
, uMessage
, dwParam1
, dwParam2
, TRUE
);
749 /**************************************************************************
750 * midiInGetNumDevs [MMSYSTEM.301]
752 UINT16 WINAPI
midiInGetNumDevs16(void)
754 return midiInGetNumDevs();
757 /**************************************************************************
758 * midiInGetDevCaps [MMSYSTEM.302]
760 UINT16 WINAPI
midiInGetDevCaps16(UINT16 uDeviceID
, LPMIDIINCAPS16 lpCaps
,
766 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
768 ret
= midiInGetDevCapsA(uDeviceID
, &micA
, uSize
);
769 if (ret
== MMSYSERR_NOERROR
) {
771 mic16
.wMid
= micA
.wMid
;
772 mic16
.wPid
= micA
.wPid
;
773 mic16
.vDriverVersion
= micA
.vDriverVersion
;
774 strcpy(mic16
.szPname
, micA
.szPname
);
775 mic16
.dwSupport
= micA
.dwSupport
;
776 memcpy(lpCaps
, &mic16
, min(uSize
, sizeof(mic16
)));
781 /**************************************************************************
782 * midiInOpen [MMSYSTEM.304]
784 UINT16 WINAPI
midiInOpen16(HMIDIIN16
* lphMidiIn
, UINT16 uDeviceID
,
785 DWORD dwCallback
, DWORD dwInstance
, DWORD dwFlags
)
790 ret
= MIDI_InOpen(&xhmid
, uDeviceID
, dwCallback
, dwInstance
, dwFlags
, FALSE
);
792 if (lphMidiIn
) *lphMidiIn
= HMIDIIN_16(xhmid
);
796 /**************************************************************************
797 * midiInClose [MMSYSTEM.305]
799 UINT16 WINAPI
midiInClose16(HMIDIIN16 hMidiIn
)
801 return midiInClose(HMIDIIN_32(hMidiIn
));
804 /**************************************************************************
805 * midiInPrepareHeader [MMSYSTEM.306]
807 UINT16 WINAPI
midiInPrepareHeader16(HMIDIIN16 hMidiIn
, /* [in] */
808 SEGPTR lpsegMidiInHdr
, /* [???] */
809 UINT16 uSize
) /* [in] */
813 TRACE("(%04X, %08x, %d)\n", hMidiIn
, lpsegMidiInHdr
, uSize
);
815 if ((wmld
= MMDRV_Get(HMIDIIN_32(hMidiIn
), MMDRV_MIDIIN
, FALSE
)) == NULL
)
816 return MMSYSERR_INVALHANDLE
;
818 return MMDRV_Message(wmld
, MIDM_PREPARE
, lpsegMidiInHdr
, uSize
, FALSE
);
821 /**************************************************************************
822 * midiInUnprepareHeader [MMSYSTEM.307]
824 UINT16 WINAPI
midiInUnprepareHeader16(HMIDIIN16 hMidiIn
, /* [in] */
825 SEGPTR lpsegMidiInHdr
, /* [???] */
826 UINT16 uSize
) /* [in] */
829 LPMIDIHDR16 lpMidiInHdr
= MapSL(lpsegMidiInHdr
);
831 TRACE("(%04X, %08x, %d)\n", hMidiIn
, lpsegMidiInHdr
, uSize
);
833 if (!(lpMidiInHdr
->dwFlags
& MHDR_PREPARED
)) {
834 return MMSYSERR_NOERROR
;
837 if ((wmld
= MMDRV_Get(HMIDIIN_32(hMidiIn
), MMDRV_MIDIIN
, FALSE
)) == NULL
)
838 return MMSYSERR_INVALHANDLE
;
840 return MMDRV_Message(wmld
, MIDM_UNPREPARE
, lpsegMidiInHdr
, uSize
, FALSE
);
843 /**************************************************************************
844 * midiInAddBuffer [MMSYSTEM.308]
846 UINT16 WINAPI
midiInAddBuffer16(HMIDIIN16 hMidiIn
, /* [in] */
847 MIDIHDR16
* lpsegMidiInHdr
, /* [???] NOTE: SEGPTR */
848 UINT16 uSize
) /* [in] */
852 TRACE("(%04X, %p, %d)\n", hMidiIn
, lpsegMidiInHdr
, uSize
);
854 if ((wmld
= MMDRV_Get(HMIDIIN_32(hMidiIn
), MMDRV_MIDIIN
, FALSE
)) == NULL
)
855 return MMSYSERR_INVALHANDLE
;
857 return MMDRV_Message(wmld
, MIDM_ADDBUFFER
, (DWORD_PTR
)lpsegMidiInHdr
, uSize
, FALSE
);
860 /**************************************************************************
861 * midiInStart [MMSYSTEM.309]
863 UINT16 WINAPI
midiInStart16(HMIDIIN16 hMidiIn
)
865 return midiInStart(HMIDIIN_32(hMidiIn
));
868 /**************************************************************************
869 * midiInStop [MMSYSTEM.310]
871 UINT16 WINAPI
midiInStop16(HMIDIIN16 hMidiIn
)
873 return midiInStop(HMIDIIN_32(hMidiIn
));
876 /**************************************************************************
877 * midiInReset [MMSYSTEM.311]
879 UINT16 WINAPI
midiInReset16(HMIDIIN16 hMidiIn
)
881 return midiInReset(HMIDIIN_32(hMidiIn
));
884 /**************************************************************************
885 * midiInGetID [MMSYSTEM.312]
887 UINT16 WINAPI
midiInGetID16(HMIDIIN16 hMidiIn
, UINT16
* lpuDeviceID
)
892 ret
= midiInGetID(HMIDIIN_32(hMidiIn
), &devid
);
893 if (ret
!= MMSYSERR_NOERROR
) return ret
;
894 *lpuDeviceID
= devid
;
898 /**************************************************************************
899 * midiInMessage [MMSYSTEM.313]
901 DWORD WINAPI
midiInMessage16(HMIDIIN16 hMidiIn
, UINT16 uMessage
,
902 DWORD dwParam1
, DWORD dwParam2
)
906 TRACE("(%04X, %04X, %08X, %08X)\n", hMidiIn
, uMessage
, dwParam1
, dwParam2
);
911 FIXME("can't handle OPEN or CLOSE message!\n");
912 return MMSYSERR_NOTSUPPORTED
;
914 case MIDM_GETDEVCAPS
:
915 return midiInGetDevCaps16(hMidiIn
, MapSL(dwParam1
), dwParam2
);
917 return midiInPrepareHeader16(hMidiIn
, dwParam1
, dwParam2
);
919 return midiInUnprepareHeader16(hMidiIn
, dwParam1
, dwParam2
);
921 return midiInAddBuffer16(hMidiIn
, MapSL(dwParam1
), dwParam2
);
924 if ((wmld
= MMDRV_Get(HMIDIIN_32(hMidiIn
), MMDRV_MIDIIN
, FALSE
)) == NULL
)
925 return MMSYSERR_INVALHANDLE
;
927 return MMDRV_Message(wmld
, uMessage
, dwParam1
, dwParam2
, FALSE
);
930 /**************************************************************************
931 * midiStreamClose [MMSYSTEM.252]
933 MMRESULT16 WINAPI
midiStreamClose16(HMIDISTRM16 hMidiStrm
)
935 return midiStreamClose(HMIDISTRM_32(hMidiStrm
));
938 /**************************************************************************
939 * midiStreamOpen [MMSYSTEM.251]
941 MMRESULT16 WINAPI
midiStreamOpen16(HMIDISTRM16
* phMidiStrm
, LPUINT16 devid
,
942 DWORD cMidi
, DWORD dwCallback
,
943 DWORD dwInstance
, DWORD fdwOpen
)
945 HMIDISTRM hMidiStrm32
;
949 if (!phMidiStrm
|| !devid
)
950 return MMSYSERR_INVALPARAM
;
952 ret
= MIDI_StreamOpen(&hMidiStrm32
, &devid32
, cMidi
, dwCallback
,
953 dwInstance
, fdwOpen
, FALSE
);
954 *phMidiStrm
= HMIDISTRM_16(hMidiStrm32
);
959 /**************************************************************************
960 * midiStreamOut [MMSYSTEM.254]
962 MMRESULT16 WINAPI
midiStreamOut16(HMIDISTRM16 hMidiStrm
, LPMIDIHDR16 lpMidiHdr
, UINT16 cbMidiHdr
)
964 return midiStreamOut(HMIDISTRM_32(hMidiStrm
), (LPMIDIHDR
)lpMidiHdr
,
968 /**************************************************************************
969 * midiStreamPause [MMSYSTEM.255]
971 MMRESULT16 WINAPI
midiStreamPause16(HMIDISTRM16 hMidiStrm
)
973 return midiStreamPause(HMIDISTRM_32(hMidiStrm
));
976 /**************************************************************************
977 * midiStreamPosition [MMSYSTEM.253]
979 MMRESULT16 WINAPI
midiStreamPosition16(HMIDISTRM16 hMidiStrm
, LPMMTIME16 lpmmt16
, UINT16 cbmmt
)
985 return MMSYSERR_INVALPARAM
;
986 MMSYSTEM_MMTIME16to32(&mmt32
, lpmmt16
);
987 ret
= midiStreamPosition(HMIDISTRM_32(hMidiStrm
), &mmt32
, sizeof(MMTIME
));
988 MMSYSTEM_MMTIME32to16(lpmmt16
, &mmt32
);
992 /**************************************************************************
993 * midiStreamProperty [MMSYSTEM.250]
995 MMRESULT16 WINAPI
midiStreamProperty16(HMIDISTRM16 hMidiStrm
, LPBYTE lpPropData
, DWORD dwProperty
)
997 return midiStreamProperty(HMIDISTRM_32(hMidiStrm
), lpPropData
, dwProperty
);
1000 /**************************************************************************
1001 * midiStreamRestart [MMSYSTEM.256]
1003 MMRESULT16 WINAPI
midiStreamRestart16(HMIDISTRM16 hMidiStrm
)
1005 return midiStreamRestart(HMIDISTRM_32(hMidiStrm
));
1008 /**************************************************************************
1009 * midiStreamStop [MMSYSTEM.257]
1011 MMRESULT16 WINAPI
midiStreamStop16(HMIDISTRM16 hMidiStrm
)
1013 return midiStreamStop(HMIDISTRM_32(hMidiStrm
));
1016 /* ###################################################
1018 * ###################################################
1021 /**************************************************************************
1022 * waveOutGetNumDevs [MMSYSTEM.401]
1024 UINT16 WINAPI
waveOutGetNumDevs16(void)
1026 return waveOutGetNumDevs();
1029 /**************************************************************************
1030 * waveOutGetDevCaps [MMSYSTEM.402]
1032 UINT16 WINAPI
waveOutGetDevCaps16(UINT16 uDeviceID
,
1033 LPWAVEOUTCAPS16 lpCaps
, UINT16 uSize
)
1037 TRACE("(%u %p %u)!\n", uDeviceID
, lpCaps
, uSize
);
1039 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
1041 ret
= waveOutGetDevCapsA(uDeviceID
, &wocA
, sizeof(wocA
));
1042 if (ret
== MMSYSERR_NOERROR
) {
1043 WAVEOUTCAPS16 woc16
;
1044 woc16
.wMid
= wocA
.wMid
;
1045 woc16
.wPid
= wocA
.wPid
;
1046 woc16
.vDriverVersion
= wocA
.vDriverVersion
;
1047 strcpy(woc16
.szPname
, wocA
.szPname
);
1048 woc16
.dwFormats
= wocA
.dwFormats
;
1049 woc16
.wChannels
= wocA
.wChannels
;
1050 woc16
.dwSupport
= wocA
.dwSupport
;
1051 memcpy(lpCaps
, &woc16
, min(uSize
, sizeof(woc16
)));
1056 /**************************************************************************
1057 * waveOutGetErrorText [MMSYSTEM.403]
1058 * waveInGetErrorText [MMSYSTEM.503]
1060 UINT16 WINAPI
waveOutGetErrorText16(UINT16 uError
, LPSTR lpText
, UINT16 uSize
)
1062 return waveOutGetErrorTextA(uError
, lpText
, uSize
);
1065 /**************************************************************************
1066 * waveOutOpen [MMSYSTEM.404]
1068 UINT16 WINAPI
waveOutOpen16(HWAVEOUT16
* lphWaveOut
, UINT16 uDeviceID
,
1069 LPCWAVEFORMATEX lpFormat
, DWORD dwCallback
,
1070 DWORD dwInstance
, DWORD dwFlags
)
1075 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1076 * call the 32 bit version
1077 * however, we need to promote correctly the wave mapper id
1078 * (0xFFFFFFFF and not 0x0000FFFF)
1080 ret
= WAVE_Open(&hWaveOut
, (uDeviceID
== (UINT16
)-1) ? (UINT
)-1 : uDeviceID
,
1081 MMDRV_WAVEOUT
, lpFormat
, dwCallback
, dwInstance
, dwFlags
, FALSE
);
1083 if (lphWaveOut
!= NULL
) *lphWaveOut
= HWAVEOUT_16(hWaveOut
);
1087 /**************************************************************************
1088 * waveOutClose [MMSYSTEM.405]
1090 UINT16 WINAPI
waveOutClose16(HWAVEOUT16 hWaveOut
)
1095 ReleaseThunkLock(&level
);
1096 ret
= waveOutClose(HWAVEOUT_32(hWaveOut
));
1097 RestoreThunkLock(level
);
1101 /**************************************************************************
1102 * waveOutPrepareHeader [MMSYSTEM.406]
1104 UINT16 WINAPI
waveOutPrepareHeader16(HWAVEOUT16 hWaveOut
, /* [in] */
1105 SEGPTR lpsegWaveOutHdr
, /* [???] */
1106 UINT16 uSize
) /* [in] */
1109 LPWAVEHDR lpWaveOutHdr
= MapSL(lpsegWaveOutHdr
);
1112 TRACE("(%04X, %08x, %u);\n", hWaveOut
, lpsegWaveOutHdr
, uSize
);
1114 if (lpWaveOutHdr
== NULL
) return MMSYSERR_INVALPARAM
;
1116 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, FALSE
)) == NULL
)
1117 return MMSYSERR_INVALHANDLE
;
1119 if ((result
= MMDRV_Message(wmld
, WODM_PREPARE
, lpsegWaveOutHdr
,
1120 uSize
, FALSE
)) != MMSYSERR_NOTSUPPORTED
)
1123 if (lpWaveOutHdr
->dwFlags
& WHDR_INQUEUE
)
1124 return WAVERR_STILLPLAYING
;
1126 lpWaveOutHdr
->dwFlags
|= WHDR_PREPARED
;
1127 lpWaveOutHdr
->dwFlags
&= ~WHDR_DONE
;
1129 return MMSYSERR_NOERROR
;
1132 /**************************************************************************
1133 * waveOutUnprepareHeader [MMSYSTEM.407]
1135 UINT16 WINAPI
waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut
, /* [in] */
1136 SEGPTR lpsegWaveOutHdr
, /* [???] */
1137 UINT16 uSize
) /* [in] */
1140 LPWAVEHDR lpWaveOutHdr
= MapSL(lpsegWaveOutHdr
);
1142 TRACE("(%04X, %08x, %u);\n", hWaveOut
, lpsegWaveOutHdr
, uSize
);
1144 if (!(lpWaveOutHdr
->dwFlags
& WHDR_PREPARED
)) {
1145 return MMSYSERR_NOERROR
;
1148 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, FALSE
)) == NULL
)
1149 return MMSYSERR_INVALHANDLE
;
1151 return MMDRV_Message(wmld
, WODM_UNPREPARE
, lpsegWaveOutHdr
, uSize
, FALSE
);
1154 /**************************************************************************
1155 * waveOutWrite [MMSYSTEM.408]
1157 UINT16 WINAPI
waveOutWrite16(HWAVEOUT16 hWaveOut
, /* [in] */
1158 LPWAVEHDR lpsegWaveOutHdr
, /* [???] NOTE: SEGPTR */
1159 UINT16 uSize
) /* [in] */
1163 TRACE("(%04X, %p, %u);\n", hWaveOut
, lpsegWaveOutHdr
, uSize
);
1165 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, FALSE
)) == NULL
)
1166 return MMSYSERR_INVALHANDLE
;
1168 return MMDRV_Message(wmld
, WODM_WRITE
, (DWORD_PTR
)lpsegWaveOutHdr
, uSize
, FALSE
);
1171 /**************************************************************************
1172 * waveOutBreakLoop [MMSYSTEM.419]
1174 UINT16 WINAPI
waveOutBreakLoop16(HWAVEOUT16 hWaveOut16
)
1179 ReleaseThunkLock(&level
);
1180 ret
= waveOutBreakLoop(HWAVEOUT_32(hWaveOut16
));
1181 RestoreThunkLock(level
);
1185 /**************************************************************************
1186 * waveOutPause [MMSYSTEM.409]
1188 UINT16 WINAPI
waveOutPause16(HWAVEOUT16 hWaveOut16
)
1193 ReleaseThunkLock(&level
);
1194 ret
= waveOutPause(HWAVEOUT_32(hWaveOut16
));
1195 RestoreThunkLock(level
);
1199 /**************************************************************************
1200 * waveOutReset [MMSYSTEM.411]
1202 UINT16 WINAPI
waveOutReset16(HWAVEOUT16 hWaveOut16
)
1207 ReleaseThunkLock(&level
);
1208 ret
= waveOutReset(HWAVEOUT_32(hWaveOut16
));
1209 RestoreThunkLock(level
);
1213 /**************************************************************************
1214 * waveOutRestart [MMSYSTEM.410]
1216 UINT16 WINAPI
waveOutRestart16(HWAVEOUT16 hWaveOut16
)
1221 ReleaseThunkLock(&level
);
1222 ret
= waveOutRestart(HWAVEOUT_32(hWaveOut16
));
1223 RestoreThunkLock(level
);
1227 /**************************************************************************
1228 * waveOutGetPosition [MMSYSTEM.412]
1230 UINT16 WINAPI
waveOutGetPosition16(HWAVEOUT16 hWaveOut
, LPMMTIME16 lpTime
,
1236 mmt
.wType
= lpTime
->wType
;
1237 ret
= waveOutGetPosition(HWAVEOUT_32(hWaveOut
), &mmt
, sizeof(mmt
));
1238 MMSYSTEM_MMTIME32to16(lpTime
, &mmt
);
1242 /**************************************************************************
1243 * waveOutGetPitch [MMSYSTEM.413]
1245 UINT16 WINAPI
waveOutGetPitch16(HWAVEOUT16 hWaveOut16
, LPDWORD lpdw
)
1247 return waveOutGetPitch(HWAVEOUT_32(hWaveOut16
), lpdw
);
1250 /**************************************************************************
1251 * waveOutSetPitch [MMSYSTEM.414]
1253 UINT16 WINAPI
waveOutSetPitch16(HWAVEOUT16 hWaveOut16
, DWORD dw
)
1255 return waveOutSetPitch(HWAVEOUT_32(hWaveOut16
), dw
);
1258 /**************************************************************************
1259 * waveOutGetPlaybackRate [MMSYSTEM.417]
1261 UINT16 WINAPI
waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16
, LPDWORD lpdw
)
1263 return waveOutGetPlaybackRate(HWAVEOUT_32(hWaveOut16
), lpdw
);
1266 /**************************************************************************
1267 * waveOutSetPlaybackRate [MMSYSTEM.418]
1269 UINT16 WINAPI
waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16
, DWORD dw
)
1271 return waveOutSetPlaybackRate(HWAVEOUT_32(hWaveOut16
), dw
);
1274 /**************************************************************************
1275 * waveOutGetVolume [MMSYSTEM.415]
1277 UINT16 WINAPI
waveOutGetVolume16(UINT16 devid
, LPDWORD lpdw
)
1279 return waveOutGetVolume(HWAVEOUT_32(devid
), lpdw
);
1282 /**************************************************************************
1283 * waveOutSetVolume [MMSYSTEM.416]
1285 UINT16 WINAPI
waveOutSetVolume16(UINT16 devid
, DWORD dw
)
1287 return waveOutSetVolume(HWAVEOUT_32(devid
), dw
);
1290 /**************************************************************************
1291 * waveOutGetID [MMSYSTEM.420]
1293 UINT16 WINAPI
waveOutGetID16(HWAVEOUT16 hWaveOut
, UINT16
* lpuDeviceID
)
1298 ret
= waveOutGetID(HWAVEOUT_32(hWaveOut
), &devid
);
1299 if (ret
!= MMSYSERR_NOERROR
) return ret
;
1300 *lpuDeviceID
= devid
;
1304 /**************************************************************************
1305 * waveOutMessage [MMSYSTEM.421]
1307 DWORD WINAPI
waveOutMessage16(HWAVEOUT16 hWaveOut
, UINT16 uMessage
,
1308 DWORD dwParam1
, DWORD dwParam2
)
1312 TRACE("(%04x, %u, %d, %d)\n", hWaveOut
, uMessage
, dwParam1
, dwParam2
);
1314 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, FALSE
)) == NULL
) {
1315 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, TRUE
)) != NULL
) {
1316 if (uMessage
== DRV_QUERYDRVENTRY
|| uMessage
== DRV_QUERYDEVNODE
)
1317 dwParam1
= (DWORD
)MapSL(dwParam1
);
1318 return MMDRV_PhysicalFeatures(wmld
, uMessage
, dwParam1
, dwParam2
);
1320 return MMSYSERR_INVALHANDLE
;
1324 if (uMessage
< DRVM_IOCTL
|| (uMessage
>= DRVM_IOCTL_LAST
&& uMessage
< DRVM_MAPPER
))
1325 return MMSYSERR_INVALPARAM
;
1327 return MMDRV_Message(wmld
, uMessage
, dwParam1
, dwParam2
, FALSE
);
1330 /**************************************************************************
1331 * waveInGetNumDevs [MMSYSTEM.501]
1333 UINT16 WINAPI
waveInGetNumDevs16(void)
1335 return waveInGetNumDevs();
1338 /**************************************************************************
1339 * waveInGetDevCaps [MMSYSTEM.502]
1341 UINT16 WINAPI
waveInGetDevCaps16(UINT16 uDeviceID
, LPWAVEINCAPS16 lpCaps
,
1347 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
1349 ret
= waveInGetDevCapsA(uDeviceID
, &wicA
, sizeof(wicA
));
1350 if (ret
== MMSYSERR_NOERROR
) {
1352 wic16
.wMid
= wicA
.wMid
;
1353 wic16
.wPid
= wicA
.wPid
;
1354 wic16
.vDriverVersion
= wicA
.vDriverVersion
;
1355 strcpy(wic16
.szPname
, wicA
.szPname
);
1356 wic16
.dwFormats
= wicA
.dwFormats
;
1357 wic16
.wChannels
= wicA
.wChannels
;
1358 memcpy(lpCaps
, &wic16
, min(uSize
, sizeof(wic16
)));
1363 /**************************************************************************
1364 * waveInOpen [MMSYSTEM.504]
1366 UINT16 WINAPI
waveInOpen16(HWAVEIN16
* lphWaveIn
, UINT16 uDeviceID
,
1367 LPCWAVEFORMATEX lpFormat
, DWORD dwCallback
,
1368 DWORD dwInstance
, DWORD dwFlags
)
1373 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1374 * call the 32 bit version
1375 * however, we need to promote correctly the wave mapper id
1376 * (0xFFFFFFFF and not 0x0000FFFF)
1378 ret
= WAVE_Open(&hWaveIn
, (uDeviceID
== (UINT16
)-1) ? (UINT
)-1 : uDeviceID
,
1379 MMDRV_WAVEIN
, lpFormat
, dwCallback
, dwInstance
, dwFlags
, FALSE
);
1381 if (lphWaveIn
!= NULL
) *lphWaveIn
= HWAVEIN_16(hWaveIn
);
1385 /**************************************************************************
1386 * waveInClose [MMSYSTEM.505]
1388 UINT16 WINAPI
waveInClose16(HWAVEIN16 hWaveIn
)
1393 ReleaseThunkLock(&level
);
1394 ret
= waveInClose(HWAVEIN_32(hWaveIn
));
1395 RestoreThunkLock(level
);
1399 /**************************************************************************
1400 * waveInPrepareHeader [MMSYSTEM.506]
1402 UINT16 WINAPI
waveInPrepareHeader16(HWAVEIN16 hWaveIn
, /* [in] */
1403 SEGPTR lpsegWaveInHdr
, /* [???] */
1404 UINT16 uSize
) /* [in] */
1407 LPWAVEHDR lpWaveInHdr
= MapSL(lpsegWaveInHdr
);
1410 TRACE("(%04X, %p, %u);\n", hWaveIn
, lpWaveInHdr
, uSize
);
1412 if (lpWaveInHdr
== NULL
) return MMSYSERR_INVALHANDLE
;
1413 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, FALSE
)) == NULL
)
1414 return MMSYSERR_INVALHANDLE
;
1416 lpWaveInHdr
->dwBytesRecorded
= 0;
1418 ret
= MMDRV_Message(wmld
, WIDM_PREPARE
, lpsegWaveInHdr
, uSize
, FALSE
);
1422 /**************************************************************************
1423 * waveInUnprepareHeader [MMSYSTEM.507]
1425 UINT16 WINAPI
waveInUnprepareHeader16(HWAVEIN16 hWaveIn
, /* [in] */
1426 SEGPTR lpsegWaveInHdr
, /* [???] */
1427 UINT16 uSize
) /* [in] */
1430 LPWAVEHDR lpWaveInHdr
= MapSL(lpsegWaveInHdr
);
1432 TRACE("(%04X, %08x, %u);\n", hWaveIn
, lpsegWaveInHdr
, uSize
);
1434 if (lpWaveInHdr
== NULL
) return MMSYSERR_INVALPARAM
;
1436 if (!(lpWaveInHdr
->dwFlags
& WHDR_PREPARED
)) {
1437 return MMSYSERR_NOERROR
;
1440 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, FALSE
)) == NULL
)
1441 return MMSYSERR_INVALHANDLE
;
1443 return MMDRV_Message(wmld
, WIDM_UNPREPARE
, lpsegWaveInHdr
, uSize
, FALSE
);
1446 /**************************************************************************
1447 * waveInAddBuffer [MMSYSTEM.508]
1449 UINT16 WINAPI
waveInAddBuffer16(HWAVEIN16 hWaveIn
, /* [in] */
1450 WAVEHDR
* lpsegWaveInHdr
, /* [???] NOTE: SEGPTR */
1451 UINT16 uSize
) /* [in] */
1455 TRACE("(%04X, %p, %u);\n", hWaveIn
, lpsegWaveInHdr
, uSize
);
1457 if (lpsegWaveInHdr
== NULL
) return MMSYSERR_INVALPARAM
;
1458 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, FALSE
)) == NULL
)
1459 return MMSYSERR_INVALHANDLE
;
1461 return MMDRV_Message(wmld
, WIDM_ADDBUFFER
, (DWORD_PTR
)lpsegWaveInHdr
, uSize
, FALSE
);
1464 /**************************************************************************
1465 * waveInReset [MMSYSTEM.511]
1467 UINT16 WINAPI
waveInReset16(HWAVEIN16 hWaveIn16
)
1472 ReleaseThunkLock(&level
);
1473 ret
= waveInReset(HWAVEIN_32(hWaveIn16
));
1474 RestoreThunkLock(level
);
1478 /**************************************************************************
1479 * waveInStart [MMSYSTEM.509]
1481 UINT16 WINAPI
waveInStart16(HWAVEIN16 hWaveIn16
)
1486 ReleaseThunkLock(&level
);
1487 ret
= waveInStart(HWAVEIN_32(hWaveIn16
));
1488 RestoreThunkLock(level
);
1492 /**************************************************************************
1493 * waveInStop [MMSYSTEM.510]
1495 UINT16 WINAPI
waveInStop16(HWAVEIN16 hWaveIn16
)
1500 ReleaseThunkLock(&level
);
1501 ret
= waveInStop(HWAVEIN_32(hWaveIn16
));
1502 RestoreThunkLock(level
);
1506 /**************************************************************************
1507 * waveInGetPosition [MMSYSTEM.512]
1509 UINT16 WINAPI
waveInGetPosition16(HWAVEIN16 hWaveIn
, LPMMTIME16 lpTime
,
1515 mmt
.wType
= lpTime
->wType
;
1516 ret
= waveInGetPosition(HWAVEIN_32(hWaveIn
), &mmt
, sizeof(mmt
));
1517 MMSYSTEM_MMTIME32to16(lpTime
, &mmt
);
1521 /**************************************************************************
1522 * waveInGetID [MMSYSTEM.513]
1524 UINT16 WINAPI
waveInGetID16(HWAVEIN16 hWaveIn
, UINT16
* lpuDeviceID
)
1529 ret
= waveInGetID(HWAVEIN_32(hWaveIn
), &devid
);
1530 if (ret
!= MMSYSERR_NOERROR
) return ret
;
1531 *lpuDeviceID
= devid
;
1535 /**************************************************************************
1536 * waveInMessage [MMSYSTEM.514]
1538 DWORD WINAPI
waveInMessage16(HWAVEIN16 hWaveIn
, UINT16 uMessage
,
1539 DWORD dwParam1
, DWORD dwParam2
)
1543 TRACE("(%04x, %u, %d, %d)\n", hWaveIn
, uMessage
, dwParam1
, dwParam2
);
1545 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, FALSE
)) == NULL
) {
1546 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, TRUE
)) != NULL
) {
1547 if (uMessage
== DRV_QUERYDRVENTRY
|| uMessage
== DRV_QUERYDEVNODE
)
1548 dwParam1
= (DWORD
)MapSL(dwParam1
);
1549 return MMDRV_PhysicalFeatures(wmld
, uMessage
, dwParam1
, dwParam2
);
1551 return MMSYSERR_INVALHANDLE
;
1555 if (uMessage
< DRVM_IOCTL
|| (uMessage
>= DRVM_IOCTL_LAST
&& uMessage
< DRVM_MAPPER
))
1556 return MMSYSERR_INVALPARAM
;
1558 return MMDRV_Message(wmld
, uMessage
, dwParam1
, dwParam2
, FALSE
);
1561 /* ###################################################
1563 * ###################################################
1566 /*#define USE_MM_TSK_WINE*/
1568 /**************************************************************************
1569 * mmTaskCreate [MMSYSTEM.900]
1571 * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be
1572 * called upon creation with dwPmt as parameter.
1574 HINSTANCE16 WINAPI
mmTaskCreate16(SEGPTR spProc
, HINSTANCE16
*lphMmTask
, DWORD dwPmt
)
1579 DWORD showCmd
= 0x40002;
1582 TRACE("(%08x, %p, %08x);\n", spProc
, lphMmTask
, dwPmt
);
1583 /* This to work requires NE modules to be started with a binary command line
1584 * which is not currently the case. A patch exists but has never been committed.
1585 * A workaround would be to integrate code for mmtask.tsk into Wine, but
1586 * this requires tremendous work (starting with patching tools/build to
1587 * create NE executables (and not only DLLs) for builtins modules.
1590 FIXME("This is currently broken. It will fail\n");
1593 *(LPDWORD
)(cmdline
+ 1) = (DWORD
)spProc
;
1594 *(LPDWORD
)(cmdline
+ 5) = dwPmt
;
1595 *(LPDWORD
)(cmdline
+ 9) = 0;
1597 lp
.hEnvironment
= 0;
1598 lp
.cmdLine
= MapLS(cmdline
);
1599 lp
.showCmd
= MapLS(&showCmd
);
1602 #ifndef USE_MM_TSK_WINE
1603 handle
= LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp
);
1605 handle
= LoadModule16("mmtask.tsk", &lp
);
1608 ret
= (handle
) ? 1 : 2;
1614 *lphMmTask
= handle
;
1616 UnMapLS( lp
.cmdLine
);
1617 UnMapLS( lp
.showCmd
);
1618 TRACE("=> 0x%04x/%d\n", handle
, ret
);
1622 #ifdef USE_MM_TSK_WINE
1623 /* C equivalent to mmtask.tsk binary content */
1624 void mmTaskEntryPoint16(LPSTR cmdLine
, WORD di
, WORD si
)
1626 int len
= cmdLine
[0x80];
1629 void (*fpProc
)(DWORD
) = MapSL(*((DWORD
*)(cmdLine
+ 1)));
1630 DWORD dwPmt
= *((DWORD
*)(cmdLine
+ 5));
1633 InitTask16(); /* FIXME: pmts / from context ? */
1636 if (SetMessageQueue16(0x40)) {
1638 if (HIWORD(fpProc
)) {
1640 /* EPP StackEnter16(); */
1652 /**************************************************************************
1653 * mmTaskBlock [MMSYSTEM.902]
1655 void WINAPI
mmTaskBlock16(HINSTANCE16 hInst
)
1660 GetMessageA(&msg
, 0, 0, 0);
1662 TranslateMessage(&msg
);
1663 DispatchMessageA(&msg
);
1665 } while (msg
.message
< 0x3A0);
1668 /**************************************************************************
1669 * mmTaskSignal [MMSYSTEM.903]
1671 LRESULT WINAPI
mmTaskSignal16(HTASK16 ht
)
1673 TRACE("(%04x);\n", ht
);
1674 return PostThreadMessageW( HTASK_32(ht
), WM_USER
, 0, 0 );
1677 /**************************************************************************
1678 * mmGetCurrentTask [MMSYSTEM.904]
1680 HTASK16 WINAPI
mmGetCurrentTask16(void)
1682 return GetCurrentTask();
1685 /**************************************************************************
1686 * mmTaskYield [MMSYSTEM.905]
1688 void WINAPI
mmTaskYield16(void)
1692 if (PeekMessageA(&msg
, 0, 0, 0, 0)) {
1697 extern DWORD WINAPI
GetProcessFlags(DWORD
);
1699 /******************************************************************
1704 static WINE_MMTHREAD
* WINMM_GetmmThread(HANDLE16 h
)
1706 return MapSL(MAKESEGPTR(h
, 0));
1709 DWORD WINAPI
WINE_mmThreadEntryPoint(LPVOID
);
1711 /**************************************************************************
1712 * mmThreadCreate [MMSYSTEM.1120]
1715 * Creates a MM thread, calling fpThreadAddr(dwPmt).
1717 * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc
1718 * bit.1 set means to open a VxD for this thread (unsupported)
1720 LRESULT WINAPI
mmThreadCreate16(FARPROC16 fpThreadAddr
, LPHANDLE16 lpHndl
, DWORD dwPmt
, DWORD dwFlags
)
1725 TRACE("(%p, %p, %08x, %08x)!\n", fpThreadAddr
, lpHndl
, dwPmt
, dwFlags
);
1727 hndl
= GlobalAlloc16(sizeof(WINE_MMTHREAD
), GMEM_SHARE
|GMEM_ZEROINIT
);
1732 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1735 /* force mmtask routines even if mmthread is required */
1736 /* this will work only if the patch about binary cmd line and NE tasks
1742 lpMMThd
->dwSignature
= WINE_MMTHREAD_CREATED
;
1743 lpMMThd
->dwCounter
= 0;
1744 lpMMThd
->hThread
= 0;
1745 lpMMThd
->dwThreadID
= 0;
1746 lpMMThd
->fpThread
= (DWORD
)fpThreadAddr
;
1747 lpMMThd
->dwThreadPmt
= dwPmt
;
1748 lpMMThd
->dwSignalCount
= 0;
1749 lpMMThd
->hEvent
= 0;
1751 lpMMThd
->dwStatus
= 0;
1752 lpMMThd
->dwFlags
= dwFlags
;
1755 if ((dwFlags
& 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) {
1756 lpMMThd
->hEvent
= CreateEventW(NULL
, FALSE
, TRUE
, NULL
);
1758 TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd
);
1759 if (lpMMThd
->dwFlags
& 2) {
1760 /* as long as we don't support MM VxD in wine, we don't need
1761 * to care about this flag
1763 /* FIXME("Don't know how to properly open VxD handles\n"); */
1764 /* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */
1767 lpMMThd
->hThread
= CreateThread(0, 0, WINE_mmThreadEntryPoint
,
1768 (LPVOID
)(DWORD_PTR
)hndl
, CREATE_SUSPENDED
, &lpMMThd
->dwThreadID
);
1769 if (lpMMThd
->hThread
== 0) {
1770 WARN("Couldn't create thread\n");
1771 /* clean-up(VxDhandle...); devicedirectio... */
1772 if (lpMMThd
->hEvent
!= 0)
1773 CloseHandle(lpMMThd
->hEvent
);
1776 SetThreadPriority(lpMMThd
->hThread
, THREAD_PRIORITY_TIME_CRITICAL
);
1777 TRACE("Got a nice thread hndl=%p id=0x%08x\n", lpMMThd
->hThread
, lpMMThd
->dwThreadID
);
1781 /* get WINE_mmThreadEntryPoint()
1782 * 2047 is its ordinal in mmsystem.spec
1784 FARPROC16 fp
= GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR
)2047);
1786 TRACE("farproc seg=0x%p lin=%p\n", fp
, MapSL((SEGPTR
)fp
));
1788 ret
= (fp
== 0) ? 2 : mmTaskCreate16((DWORD
)fp
, 0, hndl
);
1792 if (lpMMThd
->hThread
&& !ResumeThread(lpMMThd
->hThread
))
1793 WARN("Couldn't resume thread\n");
1795 while (lpMMThd
->dwStatus
!= 0x10) { /* test also HIWORD of dwStatus */
1809 TRACE("ok => %ld\n", ret
);
1813 /**************************************************************************
1814 * mmThreadSignal [MMSYSTEM.1121]
1816 void WINAPI
mmThreadSignal16(HANDLE16 hndl
)
1818 TRACE("(%04x)!\n", hndl
);
1821 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1823 lpMMThd
->dwCounter
++;
1824 if (lpMMThd
->hThread
!= 0) {
1825 InterlockedIncrement(&lpMMThd
->dwSignalCount
);
1826 SetEvent(lpMMThd
->hEvent
);
1828 mmTaskSignal16(lpMMThd
->hTask
);
1830 lpMMThd
->dwCounter
--;
1834 static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD
* lpMMThd
)
1839 if (lpMMThd
->dwThreadID
!= GetCurrentThreadId())
1840 ERR("Not called by thread itself\n");
1843 ResetEvent(lpMMThd
->hEvent
);
1844 if (InterlockedDecrement(&lpMMThd
->dwSignalCount
) >= 0)
1846 InterlockedIncrement(&lpMMThd
->dwSignalCount
);
1850 ret
= MsgWaitForMultipleObjects(1, &lpMMThd
->hEvent
, FALSE
, INFINITE
, QS_ALLINPUT
);
1852 case WAIT_OBJECT_0
: /* Event */
1855 case WAIT_OBJECT_0
+ 1: /* Msg */
1857 if (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
)) {
1858 TranslateMessage(&msg
);
1859 DispatchMessageA(&msg
);
1863 WARN("S2.x unsupported ret val 0x%08x\n", ret
);
1869 /**************************************************************************
1870 * mmThreadBlock [MMSYSTEM.1122]
1872 void WINAPI
mmThreadBlock16(HANDLE16 hndl
)
1874 TRACE("(%04x)!\n", hndl
);
1877 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1879 if (lpMMThd
->hThread
!= 0) {
1882 ReleaseThunkLock(&lc
);
1883 MMSYSTEM_ThreadBlock(lpMMThd
);
1884 RestoreThunkLock(lc
);
1886 mmTaskBlock16(lpMMThd
->hTask
);
1892 /**************************************************************************
1893 * mmThreadIsCurrent [MMSYSTEM.1123]
1895 BOOL16 WINAPI
mmThreadIsCurrent16(HANDLE16 hndl
)
1899 TRACE("(%04x)!\n", hndl
);
1901 if (hndl
&& mmThreadIsValid16(hndl
)) {
1902 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1903 ret
= (GetCurrentThreadId() == lpMMThd
->dwThreadID
);
1905 TRACE("=> %d\n", ret
);
1909 /**************************************************************************
1910 * mmThreadIsValid [MMSYSTEM.1124]
1912 BOOL16 WINAPI
mmThreadIsValid16(HANDLE16 hndl
)
1916 TRACE("(%04x)!\n", hndl
);
1919 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1921 if (!IsBadWritePtr(lpMMThd
, sizeof(WINE_MMTHREAD
)) &&
1922 lpMMThd
->dwSignature
== WINE_MMTHREAD_CREATED
&&
1923 IsTask16(lpMMThd
->hTask
)) {
1924 lpMMThd
->dwCounter
++;
1925 if (lpMMThd
->hThread
!= 0) {
1927 if (GetExitCodeThread(lpMMThd
->hThread
, &dwThreadRet
) &&
1928 dwThreadRet
== STATUS_PENDING
) {
1934 lpMMThd
->dwCounter
--;
1937 TRACE("=> %d\n", ret
);
1941 /**************************************************************************
1942 * mmThreadGetTask [MMSYSTEM.1125]
1944 HANDLE16 WINAPI
mmThreadGetTask16(HANDLE16 hndl
)
1948 TRACE("(%04x)\n", hndl
);
1950 if (mmThreadIsValid16(hndl
)) {
1951 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1952 ret
= lpMMThd
->hTask
;
1957 /**************************************************************************
1958 * __wine_mmThreadEntryPoint (MMSYSTEM.2047)
1960 DWORD WINAPI
WINE_mmThreadEntryPoint(LPVOID p
)
1962 HANDLE16 hndl
= (HANDLE16
)(DWORD_PTR
)p
;
1963 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1965 TRACE("(%04x %p)\n", hndl
, lpMMThd
);
1967 lpMMThd
->hTask
= LOWORD(GetCurrentTask());
1968 TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd
->hThread
, lpMMThd
->hTask
);
1969 lpMMThd
->dwStatus
= 0x10;
1970 MMSYSTEM_ThreadBlock(lpMMThd
);
1971 TRACE("[20-%p]\n", lpMMThd
->hThread
);
1972 lpMMThd
->dwStatus
= 0x20;
1973 if (lpMMThd
->fpThread
) {
1974 WOWCallback16(lpMMThd
->fpThread
, lpMMThd
->dwThreadPmt
);
1976 lpMMThd
->dwStatus
= 0x30;
1977 TRACE("[30-%p]\n", lpMMThd
->hThread
);
1978 while (lpMMThd
->dwCounter
) {
1982 TRACE("[XX-%p]\n", lpMMThd
->hThread
);
1984 lpMMThd
->dwSignature
= WINE_MMTHREAD_DELETED
;
1985 /* close lpMMThread->hVxD directIO */
1986 if (lpMMThd
->hEvent
)
1987 CloseHandle(lpMMThd
->hEvent
);
1994 typedef BOOL16 (WINAPI
*MMCPLCALLBACK
)(HWND
, LPCSTR
, LPCSTR
, LPCSTR
);
1996 /**************************************************************************
1997 * mmShowMMCPLPropertySheet [MMSYSTEM.1150]
1999 BOOL16 WINAPI
mmShowMMCPLPropertySheet16(HWND hWnd
, LPCSTR lpStrDevice
,
2000 LPCSTR lpStrTab
, LPCSTR lpStrTitle
)
2005 TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd
, lpStrDevice
, lpStrTab
, lpStrTitle
);
2007 hndl
= LoadLibraryA("MMSYS.CPL");
2009 MMCPLCALLBACK fp
= (MMCPLCALLBACK
)GetProcAddress(hndl
, "ShowMMCPLPropertySheet");
2012 ReleaseThunkLock(&lc
);
2013 ret
= (fp
)(hWnd
, lpStrDevice
, lpStrTab
, lpStrTitle
);
2014 RestoreThunkLock(lc
);
2022 /**************************************************************************
2023 * StackEnter [MMSYSTEM.32]
2025 void WINAPI
StackEnter16(void)
2028 /* mmsystem.dll from Win 95 does only this: so does Wine */
2033 /**************************************************************************
2034 * StackLeave [MMSYSTEM.33]
2036 void WINAPI
StackLeave16(void)
2039 /* mmsystem.dll from Win 95 does only this: so does Wine */
2044 /**************************************************************************
2045 * WMMMidiRunOnce [MMSYSTEM.8]
2047 void WINAPI
WMMMidiRunOnce16(void)
2049 FIXME("(), stub!\n");
2052 /* ###################################################
2054 * ###################################################
2057 /**************************************************************************
2058 * DRIVER_MapMsg32To16 [internal]
2060 * Map a 32 bit driver message to a 16 bit driver message.
2062 static WINMM_MapType
DRIVER_MapMsg32To16(WORD wMsg
, LPARAM
*lParam1
, LPARAM
*lParam2
)
2064 WINMM_MapType ret
= WINMM_MAP_MSGERROR
;
2071 case DRV_QUERYCONFIGURE
:
2073 case DRV_EXITSESSION
:
2074 case DRV_EXITAPPLICATION
:
2076 case DRV_CLOSE
: /* should be 0/0 */
2077 case DRV_OPEN
: /* pass through */
2078 /* lParam1 and lParam2 are not used */
2083 /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
2084 * lParam2 is a pointer to DRVCONFIGINFO
2087 LPDRVCONFIGINFO16 dci16
= HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16
) );
2088 LPDRVCONFIGINFO dci32
= (LPDRVCONFIGINFO
)(*lParam2
);
2091 LPSTR str1
= NULL
,str2
;
2093 dci16
->dwDCISize
= sizeof(DRVCONFIGINFO16
);
2095 if (dci32
->lpszDCISectionName
) {
2096 len
= WideCharToMultiByte( CP_ACP
, 0, dci32
->lpszDCISectionName
, -1, NULL
, 0, NULL
, NULL
);
2097 str1
= HeapAlloc( GetProcessHeap(), 0, len
);
2099 WideCharToMultiByte( CP_ACP
, 0, dci32
->lpszDCISectionName
, -1, str1
, len
, NULL
, NULL
);
2100 dci16
->lpszDCISectionName
= MapLS( str1
);
2102 HeapFree( GetProcessHeap(), 0, dci16
);
2103 return WINMM_MAP_NOMEM
;
2106 dci16
->lpszDCISectionName
= 0L;
2108 if (dci32
->lpszDCIAliasName
) {
2109 len
= WideCharToMultiByte( CP_ACP
, 0, dci32
->lpszDCIAliasName
, -1, NULL
, 0, NULL
, NULL
);
2110 str2
= HeapAlloc( GetProcessHeap(), 0, len
);
2112 WideCharToMultiByte( CP_ACP
, 0, dci32
->lpszDCIAliasName
, -1, str2
, len
, NULL
, NULL
);
2113 dci16
->lpszDCIAliasName
= MapLS( str2
);
2115 HeapFree( GetProcessHeap(), 0, str1
);
2116 HeapFree( GetProcessHeap(), 0, dci16
);
2117 return WINMM_MAP_NOMEM
;
2120 dci16
->lpszDCISectionName
= 0L;
2123 return WINMM_MAP_NOMEM
;
2125 *lParam2
= MapLS( dci16
);
2126 ret
= WINMM_MAP_OKMEM
;
2132 if (!((wMsg
>= 0x800 && wMsg
< 0x900) || (wMsg
>= 0x4000 && wMsg
< 0x4100))) {
2133 FIXME("Unknown message 0x%04x\n", wMsg
);
2140 /**************************************************************************
2141 * DRIVER_UnMapMsg32To16 [internal]
2143 * UnMap a 32 bit driver message to a 16 bit driver message.
2145 static WINMM_MapType
DRIVER_UnMapMsg32To16(WORD wMsg
, DWORD lParam1
, DWORD lParam2
)
2147 WINMM_MapType ret
= WINMM_MAP_MSGERROR
;
2154 case DRV_QUERYCONFIGURE
:
2156 case DRV_EXITSESSION
:
2157 case DRV_EXITAPPLICATION
:
2161 /* lParam1 and lParam2 are not used */
2165 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
2167 LPDRVCONFIGINFO16 dci16
= MapSL(lParam2
);
2168 HeapFree( GetProcessHeap(), 0, MapSL(dci16
->lpszDCISectionName
) );
2169 HeapFree( GetProcessHeap(), 0, MapSL(dci16
->lpszDCIAliasName
) );
2171 UnMapLS( dci16
->lpszDCISectionName
);
2172 UnMapLS( dci16
->lpszDCIAliasName
);
2173 HeapFree( GetProcessHeap(), 0, dci16
);
2178 if (!((wMsg
>= 0x800 && wMsg
< 0x900) || (wMsg
>= 0x4000 && wMsg
< 0x4100))) {
2179 FIXME("Unknown message 0x%04x\n", wMsg
);
2186 /**************************************************************************
2187 * DRIVER_TryOpenDriver16 [internal]
2189 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
2191 static LPWINE_DRIVER
DRIVER_OpenDriver16(LPCWSTR fn
, LPCWSTR sn
, LPARAM lParam2
)
2193 LPWINE_DRIVER lpDrv
= NULL
;
2194 LPCSTR cause
= NULL
;
2195 LPSTR fnA
= NULL
, snA
= NULL
;
2198 TRACE("(%s, %s, %08lX);\n", debugstr_w(fn
), debugstr_w(sn
), lParam2
);
2200 lpDrv
= HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER
));
2201 if (lpDrv
== NULL
) {cause
= "OOM"; goto exit
;}
2205 len
= WideCharToMultiByte( CP_ACP
, 0, fn
, -1, NULL
, 0, NULL
, NULL
);
2206 fnA
= HeapAlloc(GetProcessHeap(), 0, len
);
2207 if (fnA
== NULL
) {cause
= "OOM"; goto exit
;}
2208 WideCharToMultiByte( CP_ACP
, 0, fn
, -1, fnA
, len
, NULL
, NULL
);
2213 len
= WideCharToMultiByte( CP_ACP
, 0, sn
, -1, NULL
, 0, NULL
, NULL
);
2214 snA
= HeapAlloc(GetProcessHeap(), 0, len
);
2215 if (snA
== NULL
) {cause
= "OOM"; goto exit
;}
2216 WideCharToMultiByte( CP_ACP
, 0, sn
, -1, snA
, len
, NULL
, NULL
);
2219 /* FIXME: shall we do some black magic here on sn ?
2220 * drivers32 => drivers
2224 lpDrv
->d
.d16
.hDriver16
= OpenDriver16(fnA
, snA
, lParam2
);
2225 if (lpDrv
->d
.d16
.hDriver16
== 0) {cause
= "Not a 16 bit driver"; goto exit
;}
2226 lpDrv
->dwFlags
= WINE_GDF_16BIT
;
2229 HeapFree(GetProcessHeap(), 0, fnA
);
2230 HeapFree(GetProcessHeap(), 0, snA
);
2234 TRACE("Unable to load 16 bit module %s[%s]: %s\n",
2235 debugstr_w(fn
), debugstr_w(sn
), cause
);
2236 HeapFree(GetProcessHeap(), 0, lpDrv
);
2240 TRACE("=> %p\n", lpDrv
);
2244 /******************************************************************
2245 * DRIVER_SendMessage16
2249 static LRESULT
DRIVER_SendMessage16(HDRVR16 hDrv16
, UINT msg
,
2250 LPARAM lParam1
, LPARAM lParam2
)
2255 TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
2256 hDrv16
, msg
, lParam1
, lParam2
);
2258 switch (map
= DRIVER_MapMsg32To16(msg
, &lParam1
, &lParam2
)) {
2259 case WINMM_MAP_OKMEM
:
2261 ret
= SendDriverMessage16(hDrv16
, msg
, lParam1
, lParam2
);
2262 if (map
== WINMM_MAP_OKMEM
)
2263 DRIVER_UnMapMsg32To16(msg
, lParam1
, lParam2
);
2270 /******************************************************************
2271 * DRIVER_CloseDriver16
2275 static LRESULT
DRIVER_CloseDriver16(HDRVR16 hDrv16
, LPARAM lParam1
, LPARAM lParam2
)
2277 return CloseDriver16(hDrv16
, lParam1
, lParam2
);
2280 /**************************************************************************
2281 * DrvOpen [MMSYSTEM.1100]
2283 HDRVR16 WINAPI
DrvOpen16(LPSTR lpDriverName
, LPSTR lpSectionName
, LPARAM lParam
)
2285 return OpenDriver16(lpDriverName
, lpSectionName
, lParam
);
2288 /**************************************************************************
2289 * DrvClose [MMSYSTEM.1101]
2291 LRESULT WINAPI
DrvClose16(HDRVR16 hDrv
, LPARAM lParam1
, LPARAM lParam2
)
2293 return CloseDriver16(hDrv
, lParam1
, lParam2
);
2296 /**************************************************************************
2297 * DrvSendMessage [MMSYSTEM.1102]
2299 LRESULT WINAPI
DrvSendMessage16(HDRVR16 hDrv
, WORD msg
, LPARAM lParam1
,
2302 return SendDriverMessage16(hDrv
, msg
, lParam1
, lParam2
);
2305 /**************************************************************************
2306 * DrvGetModuleHandle [MMSYSTEM.1103]
2308 HANDLE16 WINAPI
DrvGetModuleHandle16(HDRVR16 hDrv
)
2310 return GetDriverModuleHandle16(hDrv
);
2313 /**************************************************************************
2314 * DrvDefDriverProc [MMSYSTEM.1104]
2316 LRESULT WINAPI
DrvDefDriverProc16(DWORD dwDriverID
, HDRVR16 hDrv
, WORD wMsg
,
2317 DWORD dwParam1
, DWORD dwParam2
)
2319 return DefDriverProc16(dwDriverID
, hDrv
, wMsg
, dwParam1
, dwParam2
);
2322 /**************************************************************************
2323 * DriverProc [MMSYSTEM.6]
2325 LRESULT WINAPI
DriverProc16(DWORD dwDevID
, HDRVR16 hDrv
, WORD wMsg
,
2326 DWORD dwParam1
, DWORD dwParam2
)
2328 TRACE("dwDevID=%08x hDrv=%04x wMsg=%04x dwParam1=%08x dwParam2=%08x\n",
2329 dwDevID
, hDrv
, wMsg
, dwParam1
, dwParam2
);
2331 return DrvDefDriverProc16(dwDevID
, hDrv
, wMsg
, dwParam1
, dwParam2
);
2334 /* ###################################################
2336 * ###################################################
2339 /******************************************************************
2340 * MMSYSTEM_MMTIME32to16
2344 void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16
, const MMTIME
* mmt32
)
2346 mmt16
->wType
= mmt32
->wType
;
2347 /* layout of rest is the same for 32/16,
2348 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2350 memcpy(&(mmt16
->u
), &(mmt32
->u
), sizeof(mmt16
->u
));
2353 /******************************************************************
2354 * MMSYSTEM_MMTIME16to32
2358 void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32
, const MMTIME16
* mmt16
)
2360 mmt32
->wType
= mmt16
->wType
;
2361 /* layout of rest is the same for 32/16,
2362 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2364 memcpy(&(mmt32
->u
), &(mmt16
->u
), sizeof(mmt16
->u
));
2367 /**************************************************************************
2368 * timeGetSystemTime [MMSYSTEM.601]
2370 MMRESULT16 WINAPI
timeGetSystemTime16(LPMMTIME16 lpTime
, UINT16 wSize
)
2372 if (wSize
>= sizeof(*lpTime
)) {
2373 lpTime
->wType
= TIME_MS
;
2374 lpTime
->u
.ms
= GetTickCount();
2376 TRACE("=> %u\n", lpTime
->u
.ms
);
2382 struct timer_entry
{
2385 LPTIMECALLBACK16 func16
;
2389 static struct list timer_list
= LIST_INIT(timer_list
);
2391 static void CALLBACK
timeCB3216(UINT id
, UINT uMsg
, DWORD_PTR user
, DWORD_PTR dw1
, DWORD_PTR dw2
)
2393 struct timer_entry
* te
= (void*)user
;
2397 args
[7] = LOWORD(id
);
2398 args
[6] = LOWORD(uMsg
);
2399 args
[5] = HIWORD(te
->user
);
2400 args
[4] = LOWORD(te
->user
);
2401 args
[3] = HIWORD(dw1
);
2402 args
[2] = LOWORD(dw2
);
2403 args
[1] = HIWORD(dw2
);
2404 args
[0] = LOWORD(dw2
);
2405 WOWCallback16Ex((DWORD
)te
->func16
, WCB16_PASCAL
, sizeof(args
), args
, &ret
);
2408 /**************************************************************************
2409 * timeSetEvent [MMSYSTEM.602]
2411 MMRESULT16 WINAPI
timeSetEvent16(UINT16 wDelay
, UINT16 wResol
, LPTIMECALLBACK16 lpFunc
,
2412 DWORD dwUser
, UINT16 wFlags
)
2415 struct timer_entry
* te
;
2417 switch (wFlags
& (TIME_CALLBACK_EVENT_SET
|TIME_CALLBACK_EVENT_PULSE
))
2419 case TIME_CALLBACK_EVENT_SET
:
2420 case TIME_CALLBACK_EVENT_PULSE
:
2421 id
= timeSetEvent(wDelay
, wResol
, (LPTIMECALLBACK
)lpFunc
, dwUser
, wFlags
);
2423 case TIME_CALLBACK_FUNCTION
:
2424 te
= HeapAlloc(GetProcessHeap(), 0, sizeof(*te
));
2426 te
->func16
= lpFunc
;
2428 id
= te
->id
= timeSetEvent(wDelay
, wResol
, timeCB3216
, (DWORD_PTR
)te
, wFlags
);
2431 EnterCriticalSection(&mmdrv_cs
);
2432 list_add_tail(&timer_list
, &te
->entry
);
2433 LeaveCriticalSection(&mmdrv_cs
);
2435 else HeapFree(GetProcessHeap(), 0, te
);
2444 /**************************************************************************
2445 * timeKillEvent [MMSYSTEM.603]
2447 MMRESULT16 WINAPI
timeKillEvent16(UINT16 wID
)
2449 MMRESULT16 ret
= timeKillEvent(wID
);
2450 struct timer_entry
* te
;
2452 if (ret
== TIMERR_NOERROR
)
2454 EnterCriticalSection(&mmdrv_cs
);
2455 LIST_FOR_EACH_ENTRY(te
, &timer_list
, struct timer_entry
, entry
)
2459 list_remove(&te
->entry
);
2460 HeapFree(GetProcessHeap(), 0, te
);
2464 LeaveCriticalSection(&mmdrv_cs
);
2469 /**************************************************************************
2470 * timeGetDevCaps [MMSYSTEM.604]
2472 MMRESULT16 WINAPI
timeGetDevCaps16(LPTIMECAPS16 lpCaps
, UINT16 wSize
)
2476 TRACE("(%p, %u) !\n", lpCaps
, wSize
);
2478 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
2480 ret
= timeGetDevCaps(&caps
, sizeof(caps
));
2481 if (ret
== MMSYSERR_NOERROR
) {
2483 tc16
.wPeriodMin
= caps
.wPeriodMin
;
2484 tc16
.wPeriodMax
= caps
.wPeriodMax
;
2485 memcpy(lpCaps
, &tc16
, min(wSize
, sizeof(tc16
)));
2490 /**************************************************************************
2491 * timeBeginPeriod [MMSYSTEM.605]
2493 MMRESULT16 WINAPI
timeBeginPeriod16(UINT16 wPeriod
)
2495 TRACE("(%u) !\n", wPeriod
);
2497 return timeBeginPeriod(wPeriod
);
2500 /**************************************************************************
2501 * timeEndPeriod [MMSYSTEM.606]
2503 MMRESULT16 WINAPI
timeEndPeriod16(UINT16 wPeriod
)
2505 TRACE("(%u) !\n", wPeriod
);
2507 return timeEndPeriod(wPeriod
);
2510 /**************************************************************************
2511 * timeGetTime [MMSYSTEM.607]
2513 DWORD WINAPI
timeGetTime16(void)
2515 return timeGetTime();
2518 /* ###################################################
2520 * ###################################################
2523 /**************************************************************************
2524 * joyGetNumDevs [MMSYSTEM.101]
2526 UINT16 WINAPI
joyGetNumDevs16(void)
2528 return joyGetNumDevs();
2531 /**************************************************************************
2532 * joyGetDevCaps [MMSYSTEM.102]
2534 MMRESULT16 WINAPI
joyGetDevCaps16(UINT16 wID
, LPJOYCAPS16 lpCaps
, UINT16 wSize
)
2539 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
2541 ret
= joyGetDevCapsA(wID
, &jca
, sizeof(jca
));
2543 if (ret
!= JOYERR_NOERROR
) return ret
;
2544 lpCaps
->wMid
= jca
.wMid
;
2545 lpCaps
->wPid
= jca
.wPid
;
2546 strcpy(lpCaps
->szPname
, jca
.szPname
);
2547 lpCaps
->wXmin
= jca
.wXmin
;
2548 lpCaps
->wXmax
= jca
.wXmax
;
2549 lpCaps
->wYmin
= jca
.wYmin
;
2550 lpCaps
->wYmax
= jca
.wYmax
;
2551 lpCaps
->wZmin
= jca
.wZmin
;
2552 lpCaps
->wZmax
= jca
.wZmax
;
2553 lpCaps
->wNumButtons
= jca
.wNumButtons
;
2554 lpCaps
->wPeriodMin
= jca
.wPeriodMin
;
2555 lpCaps
->wPeriodMax
= jca
.wPeriodMax
;
2557 if (wSize
>= sizeof(JOYCAPS16
)) { /* Win95 extensions ? */
2558 lpCaps
->wRmin
= jca
.wRmin
;
2559 lpCaps
->wRmax
= jca
.wRmax
;
2560 lpCaps
->wUmin
= jca
.wUmin
;
2561 lpCaps
->wUmax
= jca
.wUmax
;
2562 lpCaps
->wVmin
= jca
.wVmin
;
2563 lpCaps
->wVmax
= jca
.wVmax
;
2564 lpCaps
->wCaps
= jca
.wCaps
;
2565 lpCaps
->wMaxAxes
= jca
.wMaxAxes
;
2566 lpCaps
->wNumAxes
= jca
.wNumAxes
;
2567 lpCaps
->wMaxButtons
= jca
.wMaxButtons
;
2568 strcpy(lpCaps
->szRegKey
, jca
.szRegKey
);
2569 strcpy(lpCaps
->szOEMVxD
, jca
.szOEMVxD
);
2575 /**************************************************************************
2576 * joyGetPosEx [MMSYSTEM.110]
2578 MMRESULT16 WINAPI
joyGetPosEx16(UINT16 wID
, LPJOYINFOEX lpInfo
)
2580 return joyGetPosEx(wID
, lpInfo
);
2583 /**************************************************************************
2584 * joyGetPos [MMSYSTEM.103]
2586 MMRESULT16 WINAPI
joyGetPos16(UINT16 wID
, LPJOYINFO16 lpInfo
)
2591 TRACE("(%d, %p);\n", wID
, lpInfo
);
2593 if ((ret
= joyGetPos(wID
, &ji
)) == JOYERR_NOERROR
) {
2594 lpInfo
->wXpos
= ji
.wXpos
;
2595 lpInfo
->wYpos
= ji
.wYpos
;
2596 lpInfo
->wZpos
= ji
.wZpos
;
2597 lpInfo
->wButtons
= ji
.wButtons
;
2602 /**************************************************************************
2603 * joyGetThreshold [MMSYSTEM.104]
2605 MMRESULT16 WINAPI
joyGetThreshold16(UINT16 wID
, LPUINT16 lpThreshold
)
2610 ret
= joyGetThreshold(wID
, &t
);
2611 if (ret
== JOYERR_NOERROR
)
2616 /**************************************************************************
2617 * joyReleaseCapture [MMSYSTEM.105]
2619 MMRESULT16 WINAPI
joyReleaseCapture16(UINT16 wID
)
2621 return joyReleaseCapture(wID
);
2624 /**************************************************************************
2625 * joySetCapture [MMSYSTEM.106]
2627 MMRESULT16 WINAPI
joySetCapture16(HWND16 hWnd
, UINT16 wID
, UINT16 wPeriod
, BOOL16 bChanged
)
2629 return joySetCapture(HWND_32(hWnd
), wID
, wPeriod
, bChanged
);
2632 /**************************************************************************
2633 * joySetThreshold [MMSYSTEM.107]
2635 MMRESULT16 WINAPI
joySetThreshold16(UINT16 wID
, UINT16 wThreshold
)
2637 return joySetThreshold(wID
,wThreshold
);
2640 /**************************************************************************
2641 * joySetCalibration [MMSYSTEM.109]
2643 MMRESULT16 WINAPI
joySetCalibration16(UINT16 wID
)
2645 FIXME("(%04X): stub.\n", wID
);
2646 return JOYERR_NOCANDO
;