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/winuser16.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(mmsys
);
49 static WINE_MMTHREAD
* WINMM_GetmmThread(HANDLE16
);
50 static LPWINE_DRIVER
DRIVER_OpenDriver16(LPCWSTR
, LPCWSTR
, LPARAM
);
51 static LRESULT
DRIVER_CloseDriver16(HDRVR16
, LPARAM
, LPARAM
);
52 static LRESULT
DRIVER_SendMessage16(HDRVR16
, UINT
, LPARAM
, LPARAM
);
54 /* ###################################################
56 * ###################################################
59 /**************************************************************************
60 * DllEntryPoint (MMSYSTEM.4)
62 * MMSYSTEM DLL entry point
65 BOOL WINAPI
MMSYSTEM_LibMain(DWORD fdwReason
, HINSTANCE hinstDLL
, WORD ds
,
66 WORD wHeapSize
, DWORD dwReserved1
, WORD wReserved2
)
68 TRACE("%p 0x%x\n", hinstDLL
, fdwReason
);
71 case DLL_PROCESS_ATTACH
:
72 /* need to load WinMM in order to:
73 * - initiate correctly shared variables (WINMM_Init())
75 if (!GetModuleHandleA("WINMM.DLL"))
77 ERR("Could not load sibling WinMM.dll\n");
80 /* hook in our 16 bit function pointers */
81 pFnGetMMThread16
= WINMM_GetmmThread
;
82 pFnOpenDriver16
= DRIVER_OpenDriver16
;
83 pFnCloseDriver16
= DRIVER_CloseDriver16
;
84 pFnSendMessage16
= DRIVER_SendMessage16
;
85 pFnReleaseThunkLock
= ReleaseThunkLock
;
86 pFnRestoreThunkLock
= RestoreThunkLock
;
89 case DLL_PROCESS_DETACH
:
90 pFnGetMMThread16
= NULL
;
91 pFnOpenDriver16
= NULL
;
92 pFnCloseDriver16
= NULL
;
93 pFnSendMessage16
= NULL
;
94 pFnReleaseThunkLock
= NULL
;
95 pFnRestoreThunkLock
= NULL
;
96 /* FIXME: add equivalent for MMDRV_Init16() */
98 case DLL_THREAD_ATTACH
:
99 case DLL_THREAD_DETACH
:
105 /**************************************************************************
108 int WINAPI
MMSYSTEM_WEP(HINSTANCE16 hInstance
, WORD wDataSeg
,
109 WORD cbHeapSize
, LPSTR lpCmdLine
)
111 TRACE("STUB: Unloading MMSystem DLL ... hInst=%04X\n", hInstance
);
115 /* ###################################################
117 * ###################################################
120 /**************************************************************************
121 * PlaySound [MMSYSTEM.3]
123 BOOL16 WINAPI
PlaySound16(LPCSTR pszSound
, HMODULE16 hmod
, DWORD fdwSound
)
128 if ((fdwSound
& SND_RESOURCE
) == SND_RESOURCE
)
133 if (!(res
= FindResource16( hmod
, pszSound
, "WAVE" ))) return FALSE
;
134 if (!(handle
= LoadResource16( hmod
, res
))) return FALSE
;
135 pszSound
= LockResource16(handle
);
136 fdwSound
= (fdwSound
& ~SND_RESOURCE
) | SND_MEMORY
;
137 /* FIXME: FreeResource16 */
140 ReleaseThunkLock(&lc
);
141 retv
= PlaySoundA(pszSound
, 0, fdwSound
);
142 RestoreThunkLock(lc
);
147 /**************************************************************************
148 * sndPlaySound [MMSYSTEM.2]
150 BOOL16 WINAPI
sndPlaySound16(LPCSTR lpszSoundName
, UINT16 uFlags
)
155 ReleaseThunkLock(&lc
);
156 retv
= sndPlaySoundA(lpszSoundName
, uFlags
);
157 RestoreThunkLock(lc
);
162 /* ###################################################
164 * ###################################################
167 /**************************************************************************
168 * mmsystemGetVersion [MMSYSTEM.5]
171 UINT16 WINAPI
mmsystemGetVersion16(void)
173 return mmsystemGetVersion();
176 /**************************************************************************
177 * DriverCallback [MMSYSTEM.31]
179 BOOL16 WINAPI
DriverCallback16(DWORD dwCallBack
, UINT16 uFlags
, HDRVR16 hDev
,
180 WORD wMsg
, DWORD dwUser
, DWORD dwParam1
,
183 return DriverCallback(dwCallBack
, uFlags
, HDRVR_32(hDev
), wMsg
, dwUser
, dwParam1
, dwParam2
);
186 /**************************************************************************
187 * OutputDebugStr [MMSYSTEM.30]
189 void WINAPI
OutputDebugStr16(LPCSTR str
)
191 OutputDebugStringA( str
);
195 /* ###################################################
197 * ###################################################
200 /**************************************************************************
201 * Mixer devices. New to Win95
204 /**************************************************************************
205 * mixerGetNumDevs [MMSYSTEM.800]
207 UINT16 WINAPI
mixerGetNumDevs16(void)
209 return mixerGetNumDevs();
212 /**************************************************************************
213 * mixerGetDevCaps [MMSYSTEM.801]
215 UINT16 WINAPI
mixerGetDevCaps16(UINT16 uDeviceID
, LPMIXERCAPS16 lpCaps
,
221 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
223 ret
= mixerGetDevCapsA(uDeviceID
, &micA
, sizeof(micA
));
224 if (ret
== MMSYSERR_NOERROR
) {
226 mic16
.wMid
= micA
.wMid
;
227 mic16
.wPid
= micA
.wPid
;
228 mic16
.vDriverVersion
= micA
.vDriverVersion
;
229 strcpy(mic16
.szPname
, micA
.szPname
);
230 mic16
.fdwSupport
= micA
.fdwSupport
;
231 mic16
.cDestinations
= micA
.cDestinations
;
232 memcpy(lpCaps
, &mic16
, min(uSize
, sizeof(mic16
)));
237 /**************************************************************************
238 * mixerOpen [MMSYSTEM.802]
240 UINT16 WINAPI
mixerOpen16(LPHMIXER16 lphmix
, UINT16 uDeviceID
, DWORD dwCallback
,
241 DWORD dwInstance
, DWORD fdwOpen
)
246 ret
= MIXER_Open(&hmix
, uDeviceID
, dwCallback
, dwInstance
, fdwOpen
, FALSE
);
247 if (lphmix
) *lphmix
= HMIXER_16(hmix
);
251 /**************************************************************************
252 * mixerClose [MMSYSTEM.803]
254 UINT16 WINAPI
mixerClose16(HMIXER16 hMix
)
256 return mixerClose(HMIXER_32(hMix
));
259 /**************************************************************************
260 * mixerGetID (MMSYSTEM.806)
262 UINT16 WINAPI
mixerGetID16(HMIXEROBJ16 hmix
, LPUINT16 lpid
, DWORD fdwID
)
265 UINT ret
= mixerGetID(HMIXEROBJ_32(hmix
), &xid
, fdwID
);
272 /**************************************************************************
273 * mixerGetControlDetails [MMSYSTEM.808]
275 UINT16 WINAPI
mixerGetControlDetails16(HMIXEROBJ16 hmix
,
276 LPMIXERCONTROLDETAILS16 lpmcd
,
279 DWORD ret
= MMSYSERR_NOTENABLED
;
282 TRACE("(%04x, %p, %08x)\n", hmix
, lpmcd
, fdwDetails
);
284 if (lpmcd
== NULL
|| lpmcd
->cbStruct
!= sizeof(*lpmcd
))
285 return MMSYSERR_INVALPARAM
;
287 sppaDetails
= (SEGPTR
)lpmcd
->paDetails
;
288 lpmcd
->paDetails
= MapSL(sppaDetails
);
289 ret
= mixerGetControlDetailsA(HMIXEROBJ_32(hmix
),
290 (LPMIXERCONTROLDETAILS
)lpmcd
, fdwDetails
);
291 lpmcd
->paDetails
= (LPVOID
)sppaDetails
;
296 /**************************************************************************
297 * mixerGetLineControls [MMSYSTEM.807]
299 UINT16 WINAPI
mixerGetLineControls16(HMIXEROBJ16 hmix
,
300 LPMIXERLINECONTROLS16 lpmlc16
,
303 MIXERLINECONTROLSA mlcA
;
306 LPMIXERCONTROL16 lpmc16
;
308 TRACE("(%04x, %p, %08x)\n", hmix
, lpmlc16
, fdwControls
);
310 if (lpmlc16
== NULL
|| lpmlc16
->cbStruct
!= sizeof(*lpmlc16
) ||
311 lpmlc16
->cbmxctrl
!= sizeof(MIXERCONTROL16
))
312 return MMSYSERR_INVALPARAM
;
314 mlcA
.cbStruct
= sizeof(mlcA
);
315 mlcA
.dwLineID
= lpmlc16
->dwLineID
;
316 mlcA
.u
.dwControlID
= lpmlc16
->u
.dwControlID
;
317 mlcA
.u
.dwControlType
= lpmlc16
->u
.dwControlType
;
318 mlcA
.cControls
= lpmlc16
->cControls
;
319 mlcA
.cbmxctrl
= sizeof(MIXERCONTROLA
);
320 mlcA
.pamxctrl
= HeapAlloc(GetProcessHeap(), 0,
321 mlcA
.cControls
* mlcA
.cbmxctrl
);
323 ret
= mixerGetLineControlsA(HMIXEROBJ_32(hmix
), &mlcA
, fdwControls
);
325 if (ret
== MMSYSERR_NOERROR
) {
326 lpmlc16
->dwLineID
= mlcA
.dwLineID
;
327 lpmlc16
->u
.dwControlID
= mlcA
.u
.dwControlID
;
328 lpmlc16
->u
.dwControlType
= mlcA
.u
.dwControlType
;
329 lpmlc16
->cControls
= mlcA
.cControls
;
331 lpmc16
= MapSL(lpmlc16
->pamxctrl
);
333 for (i
= 0; i
< mlcA
.cControls
; i
++) {
334 lpmc16
[i
].cbStruct
= sizeof(MIXERCONTROL16
);
335 lpmc16
[i
].dwControlID
= mlcA
.pamxctrl
[i
].dwControlID
;
336 lpmc16
[i
].dwControlType
= mlcA
.pamxctrl
[i
].dwControlType
;
337 lpmc16
[i
].fdwControl
= mlcA
.pamxctrl
[i
].fdwControl
;
338 lpmc16
[i
].cMultipleItems
= mlcA
.pamxctrl
[i
].cMultipleItems
;
339 strcpy(lpmc16
[i
].szShortName
, mlcA
.pamxctrl
[i
].szShortName
);
340 strcpy(lpmc16
[i
].szName
, mlcA
.pamxctrl
[i
].szName
);
341 /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
342 memcpy(&lpmc16
[i
].Bounds
, &mlcA
.pamxctrl
[i
].Bounds
,
343 sizeof(mlcA
.pamxctrl
[i
].Bounds
));
344 /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
345 memcpy(&lpmc16
[i
].Metrics
, &mlcA
.pamxctrl
[i
].Metrics
,
346 sizeof(mlcA
.pamxctrl
[i
].Metrics
));
350 HeapFree(GetProcessHeap(), 0, mlcA
.pamxctrl
);
355 /**************************************************************************
356 * mixerGetLineInfo [MMSYSTEM.805]
358 UINT16 WINAPI
mixerGetLineInfo16(HMIXEROBJ16 hmix
, LPMIXERLINE16 lpmli16
,
364 TRACE("(%04x, %p, %08x)\n", hmix
, lpmli16
, fdwInfo
);
366 if (lpmli16
== NULL
|| lpmli16
->cbStruct
!= sizeof(*lpmli16
))
367 return MMSYSERR_INVALPARAM
;
369 mliA
.cbStruct
= sizeof(mliA
);
370 switch (fdwInfo
& MIXER_GETLINEINFOF_QUERYMASK
) {
371 case MIXER_GETLINEINFOF_COMPONENTTYPE
:
372 mliA
.dwComponentType
= lpmli16
->dwComponentType
;
374 case MIXER_GETLINEINFOF_DESTINATION
:
375 mliA
.dwDestination
= lpmli16
->dwDestination
;
377 case MIXER_GETLINEINFOF_LINEID
:
378 mliA
.dwLineID
= lpmli16
->dwLineID
;
380 case MIXER_GETLINEINFOF_SOURCE
:
381 mliA
.dwDestination
= lpmli16
->dwDestination
;
382 mliA
.dwSource
= lpmli16
->dwSource
;
384 case MIXER_GETLINEINFOF_TARGETTYPE
:
385 mliA
.Target
.dwType
= lpmli16
->Target
.dwType
;
386 mliA
.Target
.wMid
= lpmli16
->Target
.wMid
;
387 mliA
.Target
.wPid
= lpmli16
->Target
.wPid
;
388 mliA
.Target
.vDriverVersion
= lpmli16
->Target
.vDriverVersion
;
389 strcpy(mliA
.Target
.szPname
, lpmli16
->Target
.szPname
);
392 FIXME("Unsupported fdwControls=0x%08x\n", fdwInfo
);
395 ret
= mixerGetLineInfoA(HMIXEROBJ_32(hmix
), &mliA
, fdwInfo
);
397 lpmli16
->dwDestination
= mliA
.dwDestination
;
398 lpmli16
->dwSource
= mliA
.dwSource
;
399 lpmli16
->dwLineID
= mliA
.dwLineID
;
400 lpmli16
->fdwLine
= mliA
.fdwLine
;
401 lpmli16
->dwUser
= mliA
.dwUser
;
402 lpmli16
->dwComponentType
= mliA
.dwComponentType
;
403 lpmli16
->cChannels
= mliA
.cChannels
;
404 lpmli16
->cConnections
= mliA
.cConnections
;
405 lpmli16
->cControls
= mliA
.cControls
;
406 strcpy(lpmli16
->szShortName
, mliA
.szShortName
);
407 strcpy(lpmli16
->szName
, mliA
.szName
);
408 lpmli16
->Target
.dwType
= mliA
.Target
.dwType
;
409 lpmli16
->Target
.dwDeviceID
= mliA
.Target
.dwDeviceID
;
410 lpmli16
->Target
.wMid
= mliA
.Target
.wMid
;
411 lpmli16
->Target
.wPid
= mliA
.Target
.wPid
;
412 lpmli16
->Target
.vDriverVersion
= mliA
.Target
.vDriverVersion
;
413 strcpy(lpmli16
->Target
.szPname
, mliA
.Target
.szPname
);
418 /**************************************************************************
419 * mixerSetControlDetails [MMSYSTEM.809]
421 UINT16 WINAPI
mixerSetControlDetails16(HMIXEROBJ16 hmix
,
422 LPMIXERCONTROLDETAILS16 lpmcd
,
425 TRACE("(%04x, %p, %08x)\n", hmix
, lpmcd
, fdwDetails
);
426 return MMSYSERR_NOTENABLED
;
429 /**************************************************************************
430 * mixerMessage [MMSYSTEM.804]
432 DWORD WINAPI
mixerMessage16(HMIXER16 hmix
, UINT16 uMsg
, DWORD dwParam1
,
435 return mixerMessage(HMIXER_32(hmix
), uMsg
, dwParam1
, dwParam2
);
438 /**************************************************************************
439 * auxGetNumDevs [MMSYSTEM.350]
441 UINT16 WINAPI
auxGetNumDevs16(void)
443 return auxGetNumDevs();
446 /* ###################################################
448 * ###################################################
451 /**************************************************************************
452 * auxGetDevCaps [MMSYSTEM.351]
454 UINT16 WINAPI
auxGetDevCaps16(UINT16 uDeviceID
, LPAUXCAPS16 lpCaps
, UINT16 uSize
)
459 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
461 ret
= auxGetDevCapsA(uDeviceID
, &acA
, sizeof(acA
));
462 if (ret
== MMSYSERR_NOERROR
) {
464 ac16
.wMid
= acA
.wMid
;
465 ac16
.wPid
= acA
.wPid
;
466 ac16
.vDriverVersion
= acA
.vDriverVersion
;
467 strcpy(ac16
.szPname
, acA
.szPname
);
468 ac16
.wTechnology
= acA
.wTechnology
;
469 ac16
.dwSupport
= acA
.dwSupport
;
470 memcpy(lpCaps
, &ac16
, min(uSize
, sizeof(ac16
)));
475 /**************************************************************************
476 * auxGetVolume [MMSYSTEM.352]
478 UINT16 WINAPI
auxGetVolume16(UINT16 uDeviceID
, LPDWORD lpdwVolume
)
480 return auxGetVolume(uDeviceID
, lpdwVolume
);
483 /**************************************************************************
484 * auxSetVolume [MMSYSTEM.353]
486 UINT16 WINAPI
auxSetVolume16(UINT16 uDeviceID
, DWORD dwVolume
)
488 return auxSetVolume(uDeviceID
, dwVolume
);
491 /**************************************************************************
492 * auxOutMessage [MMSYSTEM.354]
494 DWORD WINAPI
auxOutMessage16(UINT16 uDeviceID
, UINT16 uMessage
, DWORD dw1
, DWORD dw2
)
496 TRACE("(%04X, %04X, %08X, %08X)\n", uDeviceID
, uMessage
, dw1
, dw2
);
499 case AUXDM_GETNUMDEVS
:
500 case AUXDM_SETVOLUME
:
501 /* no argument conversion needed */
503 case AUXDM_GETVOLUME
:
504 return auxGetVolume16(uDeviceID
, MapSL(dw1
));
505 case AUXDM_GETDEVCAPS
:
506 return auxGetDevCaps16(uDeviceID
, MapSL(dw1
), dw2
);
508 TRACE("(%04x, %04x, %08x, %08x): unhandled message\n",
509 uDeviceID
, uMessage
, dw1
, dw2
);
512 return auxOutMessage(uDeviceID
, uMessage
, dw1
, dw2
);
515 /* ###################################################
517 * ###################################################
520 /**************************************************************************
521 * mciGetErrorString [MMSYSTEM.706]
523 BOOL16 WINAPI
mciGetErrorString16(DWORD wError
, LPSTR lpstrBuffer
, UINT16 uLength
)
525 return mciGetErrorStringA(wError
, lpstrBuffer
, uLength
);
528 /**************************************************************************
529 * mciDriverNotify [MMSYSTEM.711]
531 BOOL16 WINAPI
mciDriverNotify16(HWND16 hWndCallBack
, UINT16 wDevID
, UINT16 wStatus
)
533 TRACE("(%04X, %04x, %04X)\n", hWndCallBack
, wDevID
, wStatus
);
535 return PostMessageA(HWND_32(hWndCallBack
), MM_MCINOTIFY
, wStatus
, wDevID
);
538 /**************************************************************************
539 * mciGetDriverData [MMSYSTEM.708]
541 DWORD WINAPI
mciGetDriverData16(UINT16 uDeviceID
)
543 return mciGetDriverData(uDeviceID
);
546 /**************************************************************************
547 * mciSetDriverData [MMSYSTEM.707]
549 BOOL16 WINAPI
mciSetDriverData16(UINT16 uDeviceID
, DWORD data
)
551 return mciSetDriverData(uDeviceID
, data
);
554 /**************************************************************************
555 * mciSendCommand [MMSYSTEM.701]
557 DWORD WINAPI
mciSendCommand16(UINT16 wDevID
, UINT16 wMsg
, DWORD dwParam1
, DWORD dwParam2
)
561 TRACE("(%04X, %s, %08X, %08X)\n",
562 wDevID
, MCI_MessageToString(wMsg
), dwParam1
, dwParam2
);
564 dwRet
= MCI_SendCommand(wDevID
, wMsg
, dwParam1
, dwParam2
, FALSE
);
565 dwRet
= MCI_CleanUp(dwRet
, wMsg
, (DWORD
)MapSL(dwParam2
));
566 TRACE("=> %d\n", dwRet
);
570 /**************************************************************************
571 * mciGetDeviceID [MMSYSTEM.703]
573 UINT16 WINAPI
mciGetDeviceID16(LPCSTR lpstrName
)
575 TRACE("(\"%s\")\n", lpstrName
);
577 return mciGetDeviceIDA(lpstrName
);
580 /**************************************************************************
581 * mciSetYieldProc [MMSYSTEM.714]
583 BOOL16 WINAPI
mciSetYieldProc16(UINT16 uDeviceID
, YIELDPROC16 fpYieldProc
, DWORD dwYieldData
)
585 LPWINE_MCIDRIVER wmd
;
587 TRACE("(%u, %p, %08x)\n", uDeviceID
, fpYieldProc
, dwYieldData
);
589 if (!(wmd
= MCI_GetDriver(uDeviceID
))) {
590 WARN("Bad uDeviceID\n");
594 wmd
->lpfnYieldProc
= (YIELDPROC
)fpYieldProc
;
595 wmd
->dwYieldData
= dwYieldData
;
601 /**************************************************************************
602 * mciGetDeviceIDFromElementID [MMSYSTEM.715]
604 UINT16 WINAPI
mciGetDeviceIDFromElementID16(DWORD dwElementID
, LPCSTR lpstrType
)
606 FIXME("(%u, %s) stub\n", dwElementID
, lpstrType
);
610 /**************************************************************************
611 * mciGetYieldProc [MMSYSTEM.716]
613 YIELDPROC16 WINAPI
mciGetYieldProc16(UINT16 uDeviceID
, DWORD
* lpdwYieldData
)
615 LPWINE_MCIDRIVER wmd
;
617 TRACE("(%u, %p)\n", uDeviceID
, lpdwYieldData
);
619 if (!(wmd
= MCI_GetDriver(uDeviceID
))) {
620 WARN("Bad uDeviceID\n");
623 if (!wmd
->lpfnYieldProc
) {
624 WARN("No proc set\n");
628 WARN("Proc is 32 bit\n");
631 if (lpdwYieldData
) *lpdwYieldData
= wmd
->dwYieldData
;
632 return (YIELDPROC16
)wmd
->lpfnYieldProc
;
635 /**************************************************************************
636 * mciGetCreatorTask [MMSYSTEM.717]
638 HTASK16 WINAPI
mciGetCreatorTask16(UINT16 uDeviceID
)
640 return HTASK_16(mciGetCreatorTask(uDeviceID
));
643 /**************************************************************************
644 * mciDriverYield [MMSYSTEM.710]
646 UINT16 WINAPI
mciDriverYield16(UINT16 uDeviceID
)
648 LPWINE_MCIDRIVER wmd
;
651 /* TRACE("(%04x)\n", uDeviceID); */
653 if (!(wmd
= MCI_GetDriver(uDeviceID
)) || !wmd
->lpfnYieldProc
|| wmd
->bIs32
) {
656 ret
= wmd
->lpfnYieldProc(uDeviceID
, wmd
->dwYieldData
);
662 /* ###################################################
664 * ###################################################
667 /**************************************************************************
668 * midiOutGetNumDevs [MMSYSTEM.201]
670 UINT16 WINAPI
midiOutGetNumDevs16(void)
672 return midiOutGetNumDevs();
675 /**************************************************************************
676 * midiOutGetDevCaps [MMSYSTEM.202]
678 UINT16 WINAPI
midiOutGetDevCaps16(UINT16 uDeviceID
, LPMIDIOUTCAPS16 lpCaps
,
684 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
686 ret
= midiOutGetDevCapsA(uDeviceID
, &mocA
, sizeof(mocA
));
687 if (ret
== MMSYSERR_NOERROR
) {
689 moc16
.wMid
= mocA
.wMid
;
690 moc16
.wPid
= mocA
.wPid
;
691 moc16
.vDriverVersion
= mocA
.vDriverVersion
;
692 strcpy(moc16
.szPname
, mocA
.szPname
);
693 moc16
.wTechnology
= mocA
.wTechnology
;
694 moc16
.wVoices
= mocA
.wVoices
;
695 moc16
.wNotes
= mocA
.wNotes
;
696 moc16
.wChannelMask
= mocA
.wChannelMask
;
697 moc16
.dwSupport
= mocA
.dwSupport
;
698 memcpy(lpCaps
, &moc16
, min(uSize
, sizeof(moc16
)));
703 /**************************************************************************
704 * midiOutGetErrorText [MMSYSTEM.203]
705 * midiInGetErrorText [MMSYSTEM.303]
707 UINT16 WINAPI
midiOutGetErrorText16(UINT16 uError
, LPSTR lpText
, UINT16 uSize
)
709 return midiOutGetErrorTextA(uError
, lpText
, uSize
);
712 /**************************************************************************
713 * midiOutOpen [MMSYSTEM.204]
715 UINT16 WINAPI
midiOutOpen16(HMIDIOUT16
* lphMidiOut
, UINT16 uDeviceID
,
716 DWORD dwCallback
, DWORD dwInstance
, DWORD dwFlags
)
721 ret
= MIDI_OutOpen(&hmo
, uDeviceID
, dwCallback
, dwInstance
, dwFlags
, FALSE
);
723 if (lphMidiOut
!= NULL
) *lphMidiOut
= HMIDIOUT_16(hmo
);
727 /**************************************************************************
728 * midiOutClose [MMSYSTEM.205]
730 UINT16 WINAPI
midiOutClose16(HMIDIOUT16 hMidiOut
)
732 return midiOutClose(HMIDIOUT_32(hMidiOut
));
735 /**************************************************************************
736 * midiOutPrepareHeader [MMSYSTEM.206]
738 UINT16 WINAPI
midiOutPrepareHeader16(HMIDIOUT16 hMidiOut
, /* [in] */
739 SEGPTR lpsegMidiOutHdr
, /* [???] */
740 UINT16 uSize
) /* [in] */
744 TRACE("(%04X, %08x, %d)\n", hMidiOut
, lpsegMidiOutHdr
, uSize
);
746 if ((wmld
= MMDRV_Get(HMIDIOUT_32(hMidiOut
), MMDRV_MIDIOUT
, FALSE
)) == NULL
)
747 return MMSYSERR_INVALHANDLE
;
749 return MMDRV_Message(wmld
, MODM_PREPARE
, lpsegMidiOutHdr
, uSize
, FALSE
);
752 /**************************************************************************
753 * midiOutUnprepareHeader [MMSYSTEM.207]
755 UINT16 WINAPI
midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut
, /* [in] */
756 SEGPTR lpsegMidiOutHdr
, /* [???] */
757 UINT16 uSize
) /* [in] */
760 LPMIDIHDR16 lpMidiOutHdr
= MapSL(lpsegMidiOutHdr
);
762 TRACE("(%04X, %08x, %d)\n", hMidiOut
, lpsegMidiOutHdr
, uSize
);
764 if (!(lpMidiOutHdr
->dwFlags
& MHDR_PREPARED
)) {
765 return MMSYSERR_NOERROR
;
768 if ((wmld
= MMDRV_Get(HMIDIOUT_32(hMidiOut
), MMDRV_MIDIOUT
, FALSE
)) == NULL
)
769 return MMSYSERR_INVALHANDLE
;
771 return MMDRV_Message(wmld
, MODM_UNPREPARE
, lpsegMidiOutHdr
, uSize
, FALSE
);
774 /**************************************************************************
775 * midiOutShortMsg [MMSYSTEM.208]
777 UINT16 WINAPI
midiOutShortMsg16(HMIDIOUT16 hMidiOut
, DWORD dwMsg
)
779 return midiOutShortMsg(HMIDIOUT_32(hMidiOut
), dwMsg
);
782 /**************************************************************************
783 * midiOutLongMsg [MMSYSTEM.209]
785 UINT16 WINAPI
midiOutLongMsg16(HMIDIOUT16 hMidiOut
, /* [in] */
786 LPMIDIHDR16 lpsegMidiOutHdr
, /* [???] NOTE: SEGPTR */
787 UINT16 uSize
) /* [in] */
791 TRACE("(%04X, %p, %d)\n", hMidiOut
, lpsegMidiOutHdr
, uSize
);
793 if ((wmld
= MMDRV_Get(HMIDIOUT_32(hMidiOut
), MMDRV_MIDIOUT
, FALSE
)) == NULL
)
794 return MMSYSERR_INVALHANDLE
;
796 return MMDRV_Message(wmld
, MODM_LONGDATA
, (DWORD_PTR
)lpsegMidiOutHdr
, uSize
, FALSE
);
799 /**************************************************************************
800 * midiOutReset [MMSYSTEM.210]
802 UINT16 WINAPI
midiOutReset16(HMIDIOUT16 hMidiOut
)
804 return midiOutReset(HMIDIOUT_32(hMidiOut
));
807 /**************************************************************************
808 * midiOutGetVolume [MMSYSTEM.211]
810 UINT16 WINAPI
midiOutGetVolume16(UINT16 uDeviceID
, DWORD
* lpdwVolume
)
812 return midiOutGetVolume(HMIDIOUT_32(uDeviceID
), lpdwVolume
);
815 /**************************************************************************
816 * midiOutSetVolume [MMSYSTEM.212]
818 UINT16 WINAPI
midiOutSetVolume16(UINT16 uDeviceID
, DWORD dwVolume
)
820 return midiOutSetVolume(HMIDIOUT_32(uDeviceID
), dwVolume
);
823 /**************************************************************************
824 * midiOutCachePatches [MMSYSTEM.213]
826 UINT16 WINAPI
midiOutCachePatches16(HMIDIOUT16 hMidiOut
, UINT16 uBank
,
827 WORD
* lpwPatchArray
, UINT16 uFlags
)
829 return midiOutCachePatches(HMIDIOUT_32(hMidiOut
), uBank
, lpwPatchArray
,
833 /**************************************************************************
834 * midiOutCacheDrumPatches [MMSYSTEM.214]
836 UINT16 WINAPI
midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut
, UINT16 uPatch
,
837 WORD
* lpwKeyArray
, UINT16 uFlags
)
839 return midiOutCacheDrumPatches(HMIDIOUT_32(hMidiOut
), uPatch
, lpwKeyArray
, uFlags
);
842 /**************************************************************************
843 * midiOutGetID [MMSYSTEM.215]
845 UINT16 WINAPI
midiOutGetID16(HMIDIOUT16 hMidiOut
, UINT16
* lpuDeviceID
)
850 ret
= midiOutGetID(HMIDIOUT_32(hMidiOut
), &devid
);
851 if (ret
!= MMSYSERR_NOERROR
) return ret
;
852 *lpuDeviceID
= devid
;
856 /**************************************************************************
857 * midiOutMessage [MMSYSTEM.216]
859 DWORD WINAPI
midiOutMessage16(HMIDIOUT16 hMidiOut
, UINT16 uMessage
,
860 DWORD dwParam1
, DWORD dwParam2
)
864 TRACE("(%04X, %04X, %08X, %08X)\n", hMidiOut
, uMessage
, dwParam1
, dwParam2
);
866 if ((wmld
= MMDRV_Get(HMIDIOUT_32(hMidiOut
), MMDRV_MIDIOUT
, FALSE
)) == NULL
)
867 return MMSYSERR_INVALHANDLE
;
872 FIXME("can't handle OPEN or CLOSE message!\n");
873 return MMSYSERR_NOTSUPPORTED
;
876 return midiOutGetVolume16(hMidiOut
, MapSL(dwParam1
));
878 return midiOutLongMsg16(hMidiOut
, MapSL(dwParam1
), dwParam2
);
880 /* lpMidiOutHdr is still a segmented pointer for this function */
881 return midiOutPrepareHeader16(hMidiOut
, dwParam1
, dwParam2
);
883 return midiOutUnprepareHeader16(hMidiOut
, dwParam1
, dwParam2
);
885 return MMDRV_Message(wmld
, uMessage
, dwParam1
, dwParam2
, TRUE
);
888 /**************************************************************************
889 * midiInGetNumDevs [MMSYSTEM.301]
891 UINT16 WINAPI
midiInGetNumDevs16(void)
893 return midiInGetNumDevs();
896 /**************************************************************************
897 * midiInGetDevCaps [MMSYSTEM.302]
899 UINT16 WINAPI
midiInGetDevCaps16(UINT16 uDeviceID
, LPMIDIINCAPS16 lpCaps
,
905 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
907 ret
= midiInGetDevCapsA(uDeviceID
, &micA
, uSize
);
908 if (ret
== MMSYSERR_NOERROR
) {
910 mic16
.wMid
= micA
.wMid
;
911 mic16
.wPid
= micA
.wPid
;
912 mic16
.vDriverVersion
= micA
.vDriverVersion
;
913 strcpy(mic16
.szPname
, micA
.szPname
);
914 mic16
.dwSupport
= micA
.dwSupport
;
915 memcpy(lpCaps
, &mic16
, min(uSize
, sizeof(mic16
)));
920 /**************************************************************************
921 * midiInOpen [MMSYSTEM.304]
923 UINT16 WINAPI
midiInOpen16(HMIDIIN16
* lphMidiIn
, UINT16 uDeviceID
,
924 DWORD dwCallback
, DWORD dwInstance
, DWORD dwFlags
)
929 ret
= MIDI_InOpen(&xhmid
, uDeviceID
, dwCallback
, dwInstance
, dwFlags
, FALSE
);
931 if (lphMidiIn
) *lphMidiIn
= HMIDIIN_16(xhmid
);
935 /**************************************************************************
936 * midiInClose [MMSYSTEM.305]
938 UINT16 WINAPI
midiInClose16(HMIDIIN16 hMidiIn
)
940 return midiInClose(HMIDIIN_32(hMidiIn
));
943 /**************************************************************************
944 * midiInPrepareHeader [MMSYSTEM.306]
946 UINT16 WINAPI
midiInPrepareHeader16(HMIDIIN16 hMidiIn
, /* [in] */
947 SEGPTR lpsegMidiInHdr
, /* [???] */
948 UINT16 uSize
) /* [in] */
952 TRACE("(%04X, %08x, %d)\n", hMidiIn
, lpsegMidiInHdr
, uSize
);
954 if ((wmld
= MMDRV_Get(HMIDIIN_32(hMidiIn
), MMDRV_MIDIIN
, FALSE
)) == NULL
)
955 return MMSYSERR_INVALHANDLE
;
957 return MMDRV_Message(wmld
, MIDM_PREPARE
, lpsegMidiInHdr
, uSize
, FALSE
);
960 /**************************************************************************
961 * midiInUnprepareHeader [MMSYSTEM.307]
963 UINT16 WINAPI
midiInUnprepareHeader16(HMIDIIN16 hMidiIn
, /* [in] */
964 SEGPTR lpsegMidiInHdr
, /* [???] */
965 UINT16 uSize
) /* [in] */
968 LPMIDIHDR16 lpMidiInHdr
= MapSL(lpsegMidiInHdr
);
970 TRACE("(%04X, %08x, %d)\n", hMidiIn
, lpsegMidiInHdr
, uSize
);
972 if (!(lpMidiInHdr
->dwFlags
& MHDR_PREPARED
)) {
973 return MMSYSERR_NOERROR
;
976 if ((wmld
= MMDRV_Get(HMIDIIN_32(hMidiIn
), MMDRV_MIDIIN
, FALSE
)) == NULL
)
977 return MMSYSERR_INVALHANDLE
;
979 return MMDRV_Message(wmld
, MIDM_UNPREPARE
, lpsegMidiInHdr
, uSize
, FALSE
);
982 /**************************************************************************
983 * midiInAddBuffer [MMSYSTEM.308]
985 UINT16 WINAPI
midiInAddBuffer16(HMIDIIN16 hMidiIn
, /* [in] */
986 MIDIHDR16
* lpsegMidiInHdr
, /* [???] NOTE: SEGPTR */
987 UINT16 uSize
) /* [in] */
991 TRACE("(%04X, %p, %d)\n", hMidiIn
, lpsegMidiInHdr
, uSize
);
993 if ((wmld
= MMDRV_Get(HMIDIIN_32(hMidiIn
), MMDRV_MIDIIN
, FALSE
)) == NULL
)
994 return MMSYSERR_INVALHANDLE
;
996 return MMDRV_Message(wmld
, MIDM_ADDBUFFER
, (DWORD_PTR
)lpsegMidiInHdr
, uSize
, FALSE
);
999 /**************************************************************************
1000 * midiInStart [MMSYSTEM.309]
1002 UINT16 WINAPI
midiInStart16(HMIDIIN16 hMidiIn
)
1004 return midiInStart(HMIDIIN_32(hMidiIn
));
1007 /**************************************************************************
1008 * midiInStop [MMSYSTEM.310]
1010 UINT16 WINAPI
midiInStop16(HMIDIIN16 hMidiIn
)
1012 return midiInStop(HMIDIIN_32(hMidiIn
));
1015 /**************************************************************************
1016 * midiInReset [MMSYSTEM.311]
1018 UINT16 WINAPI
midiInReset16(HMIDIIN16 hMidiIn
)
1020 return midiInReset(HMIDIIN_32(hMidiIn
));
1023 /**************************************************************************
1024 * midiInGetID [MMSYSTEM.312]
1026 UINT16 WINAPI
midiInGetID16(HMIDIIN16 hMidiIn
, UINT16
* lpuDeviceID
)
1031 ret
= midiInGetID(HMIDIIN_32(hMidiIn
), &devid
);
1032 if (ret
!= MMSYSERR_NOERROR
) return ret
;
1033 *lpuDeviceID
= devid
;
1037 /**************************************************************************
1038 * midiInMessage [MMSYSTEM.313]
1040 DWORD WINAPI
midiInMessage16(HMIDIIN16 hMidiIn
, UINT16 uMessage
,
1041 DWORD dwParam1
, DWORD dwParam2
)
1045 TRACE("(%04X, %04X, %08X, %08X)\n", hMidiIn
, uMessage
, dwParam1
, dwParam2
);
1050 FIXME("can't handle OPEN or CLOSE message!\n");
1051 return MMSYSERR_NOTSUPPORTED
;
1053 case MIDM_GETDEVCAPS
:
1054 return midiInGetDevCaps16(hMidiIn
, MapSL(dwParam1
), dwParam2
);
1056 return midiInPrepareHeader16(hMidiIn
, dwParam1
, dwParam2
);
1057 case MIDM_UNPREPARE
:
1058 return midiInUnprepareHeader16(hMidiIn
, dwParam1
, dwParam2
);
1059 case MIDM_ADDBUFFER
:
1060 return midiInAddBuffer16(hMidiIn
, MapSL(dwParam1
), dwParam2
);
1063 if ((wmld
= MMDRV_Get(HMIDIIN_32(hMidiIn
), MMDRV_MIDIIN
, FALSE
)) == NULL
)
1064 return MMSYSERR_INVALHANDLE
;
1066 return MMDRV_Message(wmld
, uMessage
, dwParam1
, dwParam2
, FALSE
);
1069 /**************************************************************************
1070 * midiStreamClose [MMSYSTEM.252]
1072 MMRESULT16 WINAPI
midiStreamClose16(HMIDISTRM16 hMidiStrm
)
1074 return midiStreamClose(HMIDISTRM_32(hMidiStrm
));
1077 /**************************************************************************
1078 * midiStreamOpen [MMSYSTEM.251]
1080 MMRESULT16 WINAPI
midiStreamOpen16(HMIDISTRM16
* phMidiStrm
, LPUINT16 devid
,
1081 DWORD cMidi
, DWORD dwCallback
,
1082 DWORD dwInstance
, DWORD fdwOpen
)
1084 HMIDISTRM hMidiStrm32
;
1088 if (!phMidiStrm
|| !devid
)
1089 return MMSYSERR_INVALPARAM
;
1091 ret
= MIDI_StreamOpen(&hMidiStrm32
, &devid32
, cMidi
, dwCallback
,
1092 dwInstance
, fdwOpen
, FALSE
);
1093 *phMidiStrm
= HMIDISTRM_16(hMidiStrm32
);
1098 /**************************************************************************
1099 * midiStreamOut [MMSYSTEM.254]
1101 MMRESULT16 WINAPI
midiStreamOut16(HMIDISTRM16 hMidiStrm
, LPMIDIHDR16 lpMidiHdr
, UINT16 cbMidiHdr
)
1103 return midiStreamOut(HMIDISTRM_32(hMidiStrm
), (LPMIDIHDR
)lpMidiHdr
,
1107 /**************************************************************************
1108 * midiStreamPause [MMSYSTEM.255]
1110 MMRESULT16 WINAPI
midiStreamPause16(HMIDISTRM16 hMidiStrm
)
1112 return midiStreamPause(HMIDISTRM_32(hMidiStrm
));
1115 /**************************************************************************
1116 * midiStreamPosition [MMSYSTEM.253]
1118 MMRESULT16 WINAPI
midiStreamPosition16(HMIDISTRM16 hMidiStrm
, LPMMTIME16 lpmmt16
, UINT16 cbmmt
)
1124 return MMSYSERR_INVALPARAM
;
1125 MMSYSTEM_MMTIME16to32(&mmt32
, lpmmt16
);
1126 ret
= midiStreamPosition(HMIDISTRM_32(hMidiStrm
), &mmt32
, sizeof(MMTIME
));
1127 MMSYSTEM_MMTIME32to16(lpmmt16
, &mmt32
);
1131 /**************************************************************************
1132 * midiStreamProperty [MMSYSTEM.250]
1134 MMRESULT16 WINAPI
midiStreamProperty16(HMIDISTRM16 hMidiStrm
, LPBYTE lpPropData
, DWORD dwProperty
)
1136 return midiStreamProperty(HMIDISTRM_32(hMidiStrm
), lpPropData
, dwProperty
);
1139 /**************************************************************************
1140 * midiStreamRestart [MMSYSTEM.256]
1142 MMRESULT16 WINAPI
midiStreamRestart16(HMIDISTRM16 hMidiStrm
)
1144 return midiStreamRestart(HMIDISTRM_32(hMidiStrm
));
1147 /**************************************************************************
1148 * midiStreamStop [MMSYSTEM.257]
1150 MMRESULT16 WINAPI
midiStreamStop16(HMIDISTRM16 hMidiStrm
)
1152 return midiStreamStop(HMIDISTRM_32(hMidiStrm
));
1155 /* ###################################################
1157 * ###################################################
1160 /**************************************************************************
1161 * waveOutGetNumDevs [MMSYSTEM.401]
1163 UINT16 WINAPI
waveOutGetNumDevs16(void)
1165 return waveOutGetNumDevs();
1168 /**************************************************************************
1169 * waveOutGetDevCaps [MMSYSTEM.402]
1171 UINT16 WINAPI
waveOutGetDevCaps16(UINT16 uDeviceID
,
1172 LPWAVEOUTCAPS16 lpCaps
, UINT16 uSize
)
1176 TRACE("(%u %p %u)!\n", uDeviceID
, lpCaps
, uSize
);
1178 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
1180 ret
= waveOutGetDevCapsA(uDeviceID
, &wocA
, sizeof(wocA
));
1181 if (ret
== MMSYSERR_NOERROR
) {
1182 WAVEOUTCAPS16 woc16
;
1183 woc16
.wMid
= wocA
.wMid
;
1184 woc16
.wPid
= wocA
.wPid
;
1185 woc16
.vDriverVersion
= wocA
.vDriverVersion
;
1186 strcpy(woc16
.szPname
, wocA
.szPname
);
1187 woc16
.dwFormats
= wocA
.dwFormats
;
1188 woc16
.wChannels
= wocA
.wChannels
;
1189 woc16
.dwSupport
= wocA
.dwSupport
;
1190 memcpy(lpCaps
, &woc16
, min(uSize
, sizeof(woc16
)));
1195 /**************************************************************************
1196 * waveOutGetErrorText [MMSYSTEM.403]
1197 * waveInGetErrorText [MMSYSTEM.503]
1199 UINT16 WINAPI
waveOutGetErrorText16(UINT16 uError
, LPSTR lpText
, UINT16 uSize
)
1201 return waveOutGetErrorTextA(uError
, lpText
, uSize
);
1204 /**************************************************************************
1205 * waveOutOpen [MMSYSTEM.404]
1207 UINT16 WINAPI
waveOutOpen16(HWAVEOUT16
* lphWaveOut
, UINT16 uDeviceID
,
1208 LPCWAVEFORMATEX lpFormat
, DWORD dwCallback
,
1209 DWORD dwInstance
, DWORD dwFlags
)
1214 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1215 * call the 32 bit version
1216 * however, we need to promote correctly the wave mapper id
1217 * (0xFFFFFFFF and not 0x0000FFFF)
1219 ret
= WAVE_Open(&hWaveOut
, (uDeviceID
== (UINT16
)-1) ? (UINT
)-1 : uDeviceID
,
1220 MMDRV_WAVEOUT
, lpFormat
, dwCallback
, dwInstance
, dwFlags
, FALSE
);
1222 if (lphWaveOut
!= NULL
) *lphWaveOut
= HWAVEOUT_16(hWaveOut
);
1226 /**************************************************************************
1227 * waveOutClose [MMSYSTEM.405]
1229 UINT16 WINAPI
waveOutClose16(HWAVEOUT16 hWaveOut
)
1234 ReleaseThunkLock(&level
);
1235 ret
= waveOutClose(HWAVEOUT_32(hWaveOut
));
1236 RestoreThunkLock(level
);
1240 /**************************************************************************
1241 * waveOutPrepareHeader [MMSYSTEM.406]
1243 UINT16 WINAPI
waveOutPrepareHeader16(HWAVEOUT16 hWaveOut
, /* [in] */
1244 SEGPTR lpsegWaveOutHdr
, /* [???] */
1245 UINT16 uSize
) /* [in] */
1248 LPWAVEHDR lpWaveOutHdr
= MapSL(lpsegWaveOutHdr
);
1251 TRACE("(%04X, %08x, %u);\n", hWaveOut
, lpsegWaveOutHdr
, uSize
);
1253 if (lpWaveOutHdr
== NULL
) return MMSYSERR_INVALPARAM
;
1255 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, FALSE
)) == NULL
)
1256 return MMSYSERR_INVALHANDLE
;
1258 if ((result
= MMDRV_Message(wmld
, WODM_PREPARE
, lpsegWaveOutHdr
,
1259 uSize
, FALSE
)) != MMSYSERR_NOTSUPPORTED
)
1262 if (lpWaveOutHdr
->dwFlags
& WHDR_INQUEUE
)
1263 return WAVERR_STILLPLAYING
;
1265 lpWaveOutHdr
->dwFlags
|= WHDR_PREPARED
;
1266 lpWaveOutHdr
->dwFlags
&= ~WHDR_DONE
;
1268 return MMSYSERR_NOERROR
;
1271 /**************************************************************************
1272 * waveOutUnprepareHeader [MMSYSTEM.407]
1274 UINT16 WINAPI
waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut
, /* [in] */
1275 SEGPTR lpsegWaveOutHdr
, /* [???] */
1276 UINT16 uSize
) /* [in] */
1279 LPWAVEHDR lpWaveOutHdr
= MapSL(lpsegWaveOutHdr
);
1281 TRACE("(%04X, %08x, %u);\n", hWaveOut
, lpsegWaveOutHdr
, uSize
);
1283 if (!(lpWaveOutHdr
->dwFlags
& WHDR_PREPARED
)) {
1284 return MMSYSERR_NOERROR
;
1287 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, FALSE
)) == NULL
)
1288 return MMSYSERR_INVALHANDLE
;
1290 return MMDRV_Message(wmld
, WODM_UNPREPARE
, lpsegWaveOutHdr
, uSize
, FALSE
);
1293 /**************************************************************************
1294 * waveOutWrite [MMSYSTEM.408]
1296 UINT16 WINAPI
waveOutWrite16(HWAVEOUT16 hWaveOut
, /* [in] */
1297 LPWAVEHDR lpsegWaveOutHdr
, /* [???] NOTE: SEGPTR */
1298 UINT16 uSize
) /* [in] */
1302 TRACE("(%04X, %p, %u);\n", hWaveOut
, lpsegWaveOutHdr
, uSize
);
1304 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, FALSE
)) == NULL
)
1305 return MMSYSERR_INVALHANDLE
;
1307 return MMDRV_Message(wmld
, WODM_WRITE
, (DWORD_PTR
)lpsegWaveOutHdr
, uSize
, FALSE
);
1310 /**************************************************************************
1311 * waveOutBreakLoop [MMSYSTEM.419]
1313 UINT16 WINAPI
waveOutBreakLoop16(HWAVEOUT16 hWaveOut16
)
1318 ReleaseThunkLock(&level
);
1319 ret
= waveOutBreakLoop(HWAVEOUT_32(hWaveOut16
));
1320 RestoreThunkLock(level
);
1324 /**************************************************************************
1325 * waveOutPause [MMSYSTEM.409]
1327 UINT16 WINAPI
waveOutPause16(HWAVEOUT16 hWaveOut16
)
1332 ReleaseThunkLock(&level
);
1333 ret
= waveOutPause(HWAVEOUT_32(hWaveOut16
));
1334 RestoreThunkLock(level
);
1338 /**************************************************************************
1339 * waveOutReset [MMSYSTEM.411]
1341 UINT16 WINAPI
waveOutReset16(HWAVEOUT16 hWaveOut16
)
1346 ReleaseThunkLock(&level
);
1347 ret
= waveOutReset(HWAVEOUT_32(hWaveOut16
));
1348 RestoreThunkLock(level
);
1352 /**************************************************************************
1353 * waveOutRestart [MMSYSTEM.410]
1355 UINT16 WINAPI
waveOutRestart16(HWAVEOUT16 hWaveOut16
)
1360 ReleaseThunkLock(&level
);
1361 ret
= waveOutRestart(HWAVEOUT_32(hWaveOut16
));
1362 RestoreThunkLock(level
);
1366 /**************************************************************************
1367 * waveOutGetPosition [MMSYSTEM.412]
1369 UINT16 WINAPI
waveOutGetPosition16(HWAVEOUT16 hWaveOut
, LPMMTIME16 lpTime
,
1375 mmt
.wType
= lpTime
->wType
;
1376 ret
= waveOutGetPosition(HWAVEOUT_32(hWaveOut
), &mmt
, sizeof(mmt
));
1377 MMSYSTEM_MMTIME32to16(lpTime
, &mmt
);
1381 /**************************************************************************
1382 * waveOutGetPitch [MMSYSTEM.413]
1384 UINT16 WINAPI
waveOutGetPitch16(HWAVEOUT16 hWaveOut16
, LPDWORD lpdw
)
1386 return waveOutGetPitch(HWAVEOUT_32(hWaveOut16
), lpdw
);
1389 /**************************************************************************
1390 * waveOutSetPitch [MMSYSTEM.414]
1392 UINT16 WINAPI
waveOutSetPitch16(HWAVEOUT16 hWaveOut16
, DWORD dw
)
1394 return waveOutSetPitch(HWAVEOUT_32(hWaveOut16
), dw
);
1397 /**************************************************************************
1398 * waveOutGetPlaybackRate [MMSYSTEM.417]
1400 UINT16 WINAPI
waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16
, LPDWORD lpdw
)
1402 return waveOutGetPlaybackRate(HWAVEOUT_32(hWaveOut16
), lpdw
);
1405 /**************************************************************************
1406 * waveOutSetPlaybackRate [MMSYSTEM.418]
1408 UINT16 WINAPI
waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16
, DWORD dw
)
1410 return waveOutSetPlaybackRate(HWAVEOUT_32(hWaveOut16
), dw
);
1413 /**************************************************************************
1414 * waveOutGetVolume [MMSYSTEM.415]
1416 UINT16 WINAPI
waveOutGetVolume16(UINT16 devid
, LPDWORD lpdw
)
1418 return waveOutGetVolume(HWAVEOUT_32(devid
), lpdw
);
1421 /**************************************************************************
1422 * waveOutSetVolume [MMSYSTEM.416]
1424 UINT16 WINAPI
waveOutSetVolume16(UINT16 devid
, DWORD dw
)
1426 return waveOutSetVolume(HWAVEOUT_32(devid
), dw
);
1429 /**************************************************************************
1430 * waveOutGetID [MMSYSTEM.420]
1432 UINT16 WINAPI
waveOutGetID16(HWAVEOUT16 hWaveOut
, UINT16
* lpuDeviceID
)
1437 ret
= waveOutGetID(HWAVEOUT_32(hWaveOut
), &devid
);
1438 if (ret
!= MMSYSERR_NOERROR
) return ret
;
1439 *lpuDeviceID
= devid
;
1443 /**************************************************************************
1444 * waveOutMessage [MMSYSTEM.421]
1446 DWORD WINAPI
waveOutMessage16(HWAVEOUT16 hWaveOut
, UINT16 uMessage
,
1447 DWORD dwParam1
, DWORD dwParam2
)
1451 TRACE("(%04x, %u, %d, %d)\n", hWaveOut
, uMessage
, dwParam1
, dwParam2
);
1453 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, FALSE
)) == NULL
) {
1454 if ((wmld
= MMDRV_Get(HWAVEOUT_32(hWaveOut
), MMDRV_WAVEOUT
, TRUE
)) != NULL
) {
1455 if (uMessage
== DRV_QUERYDRVENTRY
|| uMessage
== DRV_QUERYDEVNODE
)
1456 dwParam1
= (DWORD
)MapSL(dwParam1
);
1457 return MMDRV_PhysicalFeatures(wmld
, uMessage
, dwParam1
, dwParam2
);
1459 return MMSYSERR_INVALHANDLE
;
1463 if (uMessage
< DRVM_IOCTL
|| (uMessage
>= DRVM_IOCTL_LAST
&& uMessage
< DRVM_MAPPER
))
1464 return MMSYSERR_INVALPARAM
;
1466 return MMDRV_Message(wmld
, uMessage
, dwParam1
, dwParam2
, FALSE
);
1469 /**************************************************************************
1470 * waveInGetNumDevs [MMSYSTEM.501]
1472 UINT16 WINAPI
waveInGetNumDevs16(void)
1474 return waveInGetNumDevs();
1477 /**************************************************************************
1478 * waveInGetDevCaps [MMSYSTEM.502]
1480 UINT16 WINAPI
waveInGetDevCaps16(UINT16 uDeviceID
, LPWAVEINCAPS16 lpCaps
,
1486 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
1488 ret
= waveInGetDevCapsA(uDeviceID
, &wicA
, sizeof(wicA
));
1489 if (ret
== MMSYSERR_NOERROR
) {
1491 wic16
.wMid
= wicA
.wMid
;
1492 wic16
.wPid
= wicA
.wPid
;
1493 wic16
.vDriverVersion
= wicA
.vDriverVersion
;
1494 strcpy(wic16
.szPname
, wicA
.szPname
);
1495 wic16
.dwFormats
= wicA
.dwFormats
;
1496 wic16
.wChannels
= wicA
.wChannels
;
1497 memcpy(lpCaps
, &wic16
, min(uSize
, sizeof(wic16
)));
1502 /**************************************************************************
1503 * waveInOpen [MMSYSTEM.504]
1505 UINT16 WINAPI
waveInOpen16(HWAVEIN16
* lphWaveIn
, UINT16 uDeviceID
,
1506 LPCWAVEFORMATEX lpFormat
, DWORD dwCallback
,
1507 DWORD dwInstance
, DWORD dwFlags
)
1512 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1513 * call the 32 bit version
1514 * however, we need to promote correctly the wave mapper id
1515 * (0xFFFFFFFF and not 0x0000FFFF)
1517 ret
= WAVE_Open(&hWaveIn
, (uDeviceID
== (UINT16
)-1) ? (UINT
)-1 : uDeviceID
,
1518 MMDRV_WAVEIN
, lpFormat
, dwCallback
, dwInstance
, dwFlags
, FALSE
);
1520 if (lphWaveIn
!= NULL
) *lphWaveIn
= HWAVEIN_16(hWaveIn
);
1524 /**************************************************************************
1525 * waveInClose [MMSYSTEM.505]
1527 UINT16 WINAPI
waveInClose16(HWAVEIN16 hWaveIn
)
1532 ReleaseThunkLock(&level
);
1533 ret
= waveInClose(HWAVEIN_32(hWaveIn
));
1534 RestoreThunkLock(level
);
1538 /**************************************************************************
1539 * waveInPrepareHeader [MMSYSTEM.506]
1541 UINT16 WINAPI
waveInPrepareHeader16(HWAVEIN16 hWaveIn
, /* [in] */
1542 SEGPTR lpsegWaveInHdr
, /* [???] */
1543 UINT16 uSize
) /* [in] */
1546 LPWAVEHDR lpWaveInHdr
= MapSL(lpsegWaveInHdr
);
1549 TRACE("(%04X, %p, %u);\n", hWaveIn
, lpWaveInHdr
, uSize
);
1551 if (lpWaveInHdr
== NULL
) return MMSYSERR_INVALHANDLE
;
1552 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, FALSE
)) == NULL
)
1553 return MMSYSERR_INVALHANDLE
;
1555 lpWaveInHdr
->dwBytesRecorded
= 0;
1557 ret
= MMDRV_Message(wmld
, WIDM_PREPARE
, lpsegWaveInHdr
, uSize
, FALSE
);
1561 /**************************************************************************
1562 * waveInUnprepareHeader [MMSYSTEM.507]
1564 UINT16 WINAPI
waveInUnprepareHeader16(HWAVEIN16 hWaveIn
, /* [in] */
1565 SEGPTR lpsegWaveInHdr
, /* [???] */
1566 UINT16 uSize
) /* [in] */
1569 LPWAVEHDR lpWaveInHdr
= MapSL(lpsegWaveInHdr
);
1571 TRACE("(%04X, %08x, %u);\n", hWaveIn
, lpsegWaveInHdr
, uSize
);
1573 if (lpWaveInHdr
== NULL
) return MMSYSERR_INVALPARAM
;
1575 if (!(lpWaveInHdr
->dwFlags
& WHDR_PREPARED
)) {
1576 return MMSYSERR_NOERROR
;
1579 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, FALSE
)) == NULL
)
1580 return MMSYSERR_INVALHANDLE
;
1582 return MMDRV_Message(wmld
, WIDM_UNPREPARE
, lpsegWaveInHdr
, uSize
, FALSE
);
1585 /**************************************************************************
1586 * waveInAddBuffer [MMSYSTEM.508]
1588 UINT16 WINAPI
waveInAddBuffer16(HWAVEIN16 hWaveIn
, /* [in] */
1589 WAVEHDR
* lpsegWaveInHdr
, /* [???] NOTE: SEGPTR */
1590 UINT16 uSize
) /* [in] */
1594 TRACE("(%04X, %p, %u);\n", hWaveIn
, lpsegWaveInHdr
, uSize
);
1596 if (lpsegWaveInHdr
== NULL
) return MMSYSERR_INVALPARAM
;
1597 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, FALSE
)) == NULL
)
1598 return MMSYSERR_INVALHANDLE
;
1600 return MMDRV_Message(wmld
, WIDM_ADDBUFFER
, (DWORD_PTR
)lpsegWaveInHdr
, uSize
, FALSE
);
1603 /**************************************************************************
1604 * waveInReset [MMSYSTEM.511]
1606 UINT16 WINAPI
waveInReset16(HWAVEIN16 hWaveIn16
)
1611 ReleaseThunkLock(&level
);
1612 ret
= waveInReset(HWAVEIN_32(hWaveIn16
));
1613 RestoreThunkLock(level
);
1617 /**************************************************************************
1618 * waveInStart [MMSYSTEM.509]
1620 UINT16 WINAPI
waveInStart16(HWAVEIN16 hWaveIn16
)
1625 ReleaseThunkLock(&level
);
1626 ret
= waveInStart(HWAVEIN_32(hWaveIn16
));
1627 RestoreThunkLock(level
);
1631 /**************************************************************************
1632 * waveInStop [MMSYSTEM.510]
1634 UINT16 WINAPI
waveInStop16(HWAVEIN16 hWaveIn16
)
1639 ReleaseThunkLock(&level
);
1640 ret
= waveInStop(HWAVEIN_32(hWaveIn16
));
1641 RestoreThunkLock(level
);
1645 /**************************************************************************
1646 * waveInGetPosition [MMSYSTEM.512]
1648 UINT16 WINAPI
waveInGetPosition16(HWAVEIN16 hWaveIn
, LPMMTIME16 lpTime
,
1654 mmt
.wType
= lpTime
->wType
;
1655 ret
= waveInGetPosition(HWAVEIN_32(hWaveIn
), &mmt
, sizeof(mmt
));
1656 MMSYSTEM_MMTIME32to16(lpTime
, &mmt
);
1660 /**************************************************************************
1661 * waveInGetID [MMSYSTEM.513]
1663 UINT16 WINAPI
waveInGetID16(HWAVEIN16 hWaveIn
, UINT16
* lpuDeviceID
)
1668 ret
= waveInGetID(HWAVEIN_32(hWaveIn
), &devid
);
1669 if (ret
!= MMSYSERR_NOERROR
) return ret
;
1670 *lpuDeviceID
= devid
;
1674 /**************************************************************************
1675 * waveInMessage [MMSYSTEM.514]
1677 DWORD WINAPI
waveInMessage16(HWAVEIN16 hWaveIn
, UINT16 uMessage
,
1678 DWORD dwParam1
, DWORD dwParam2
)
1682 TRACE("(%04x, %u, %d, %d)\n", hWaveIn
, uMessage
, dwParam1
, dwParam2
);
1684 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, FALSE
)) == NULL
) {
1685 if ((wmld
= MMDRV_Get(HWAVEIN_32(hWaveIn
), MMDRV_WAVEIN
, TRUE
)) != NULL
) {
1686 if (uMessage
== DRV_QUERYDRVENTRY
|| uMessage
== DRV_QUERYDEVNODE
)
1687 dwParam1
= (DWORD
)MapSL(dwParam1
);
1688 return MMDRV_PhysicalFeatures(wmld
, uMessage
, dwParam1
, dwParam2
);
1690 return MMSYSERR_INVALHANDLE
;
1694 if (uMessage
< DRVM_IOCTL
|| (uMessage
>= DRVM_IOCTL_LAST
&& uMessage
< DRVM_MAPPER
))
1695 return MMSYSERR_INVALPARAM
;
1697 return MMDRV_Message(wmld
, uMessage
, dwParam1
, dwParam2
, FALSE
);
1700 /* ###################################################
1702 * ###################################################
1705 /*#define USE_MM_TSK_WINE*/
1707 /**************************************************************************
1708 * mmTaskCreate [MMSYSTEM.900]
1710 * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be
1711 * called upon creation with dwPmt as parameter.
1713 HINSTANCE16 WINAPI
mmTaskCreate16(SEGPTR spProc
, HINSTANCE16
*lphMmTask
, DWORD dwPmt
)
1718 DWORD showCmd
= 0x40002;
1721 TRACE("(%08x, %p, %08x);\n", spProc
, lphMmTask
, dwPmt
);
1722 /* This to work requires NE modules to be started with a binary command line
1723 * which is not currently the case. A patch exists but has never been committed.
1724 * A workaround would be to integrate code for mmtask.tsk into Wine, but
1725 * this requires tremendous work (starting with patching tools/build to
1726 * create NE executables (and not only DLLs) for builtins modules.
1729 FIXME("This is currently broken. It will fail\n");
1732 *(LPDWORD
)(cmdline
+ 1) = (DWORD
)spProc
;
1733 *(LPDWORD
)(cmdline
+ 5) = dwPmt
;
1734 *(LPDWORD
)(cmdline
+ 9) = 0;
1736 lp
.hEnvironment
= 0;
1737 lp
.cmdLine
= MapLS(cmdline
);
1738 lp
.showCmd
= MapLS(&showCmd
);
1741 #ifndef USE_MM_TSK_WINE
1742 handle
= LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp
);
1744 handle
= LoadModule16("mmtask.tsk", &lp
);
1747 ret
= (handle
) ? 1 : 2;
1753 *lphMmTask
= handle
;
1755 UnMapLS( lp
.cmdLine
);
1756 UnMapLS( lp
.showCmd
);
1757 TRACE("=> 0x%04x/%d\n", handle
, ret
);
1761 #ifdef USE_MM_TSK_WINE
1762 /* C equivalent to mmtask.tsk binary content */
1763 void mmTaskEntryPoint16(LPSTR cmdLine
, WORD di
, WORD si
)
1765 int len
= cmdLine
[0x80];
1768 void (*fpProc
)(DWORD
) = MapSL(*((DWORD
*)(cmdLine
+ 1)));
1769 DWORD dwPmt
= *((DWORD
*)(cmdLine
+ 5));
1772 InitTask16(); /* FIXME: pmts / from context ? */
1775 if (SetMessageQueue16(0x40)) {
1777 if (HIWORD(fpProc
)) {
1779 /* EPP StackEnter16(); */
1791 /**************************************************************************
1792 * mmTaskBlock [MMSYSTEM.902]
1794 void WINAPI
mmTaskBlock16(HINSTANCE16 hInst
)
1799 GetMessageA(&msg
, 0, 0, 0);
1801 TranslateMessage(&msg
);
1802 DispatchMessageA(&msg
);
1804 } while (msg
.message
< 0x3A0);
1807 /**************************************************************************
1808 * mmTaskSignal [MMSYSTEM.903]
1810 LRESULT WINAPI
mmTaskSignal16(HTASK16 ht
)
1812 TRACE("(%04x);\n", ht
);
1813 return PostThreadMessageW( HTASK_32(ht
), WM_USER
, 0, 0 );
1816 /**************************************************************************
1817 * mmGetCurrentTask [MMSYSTEM.904]
1819 HTASK16 WINAPI
mmGetCurrentTask16(void)
1821 return GetCurrentTask();
1824 /**************************************************************************
1825 * mmTaskYield [MMSYSTEM.905]
1827 void WINAPI
mmTaskYield16(void)
1831 if (PeekMessageA(&msg
, 0, 0, 0, 0)) {
1836 extern DWORD WINAPI
GetProcessFlags(DWORD
);
1838 /******************************************************************
1843 static WINE_MMTHREAD
* WINMM_GetmmThread(HANDLE16 h
)
1845 return MapSL(MAKESEGPTR(h
, 0));
1848 DWORD WINAPI
WINE_mmThreadEntryPoint(LPVOID
);
1850 /**************************************************************************
1851 * mmThreadCreate [MMSYSTEM.1120]
1854 * Creates a MM thread, calling fpThreadAddr(dwPmt).
1856 * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc
1857 * bit.1 set means to open a VxD for this thread (unsupported)
1859 LRESULT WINAPI
mmThreadCreate16(FARPROC16 fpThreadAddr
, LPHANDLE16 lpHndl
, DWORD dwPmt
, DWORD dwFlags
)
1864 TRACE("(%p, %p, %08x, %08x)!\n", fpThreadAddr
, lpHndl
, dwPmt
, dwFlags
);
1866 hndl
= GlobalAlloc16(sizeof(WINE_MMTHREAD
), GMEM_SHARE
|GMEM_ZEROINIT
);
1871 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1874 /* force mmtask routines even if mmthread is required */
1875 /* this will work only if the patch about binary cmd line and NE tasks
1881 lpMMThd
->dwSignature
= WINE_MMTHREAD_CREATED
;
1882 lpMMThd
->dwCounter
= 0;
1883 lpMMThd
->hThread
= 0;
1884 lpMMThd
->dwThreadID
= 0;
1885 lpMMThd
->fpThread
= (DWORD
)fpThreadAddr
;
1886 lpMMThd
->dwThreadPmt
= dwPmt
;
1887 lpMMThd
->dwSignalCount
= 0;
1888 lpMMThd
->hEvent
= 0;
1890 lpMMThd
->dwStatus
= 0;
1891 lpMMThd
->dwFlags
= dwFlags
;
1894 if ((dwFlags
& 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) {
1895 lpMMThd
->hEvent
= CreateEventW(NULL
, FALSE
, TRUE
, NULL
);
1897 TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd
);
1898 if (lpMMThd
->dwFlags
& 2) {
1899 /* as long as we don't support MM VxD in wine, we don't need
1900 * to care about this flag
1902 /* FIXME("Don't know how to properly open VxD handles\n"); */
1903 /* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */
1906 lpMMThd
->hThread
= CreateThread(0, 0, WINE_mmThreadEntryPoint
,
1907 (LPVOID
)(DWORD_PTR
)hndl
, CREATE_SUSPENDED
, &lpMMThd
->dwThreadID
);
1908 if (lpMMThd
->hThread
== 0) {
1909 WARN("Couldn't create thread\n");
1910 /* clean-up(VxDhandle...); devicedirectio... */
1911 if (lpMMThd
->hEvent
!= 0)
1912 CloseHandle(lpMMThd
->hEvent
);
1915 SetThreadPriority(lpMMThd
->hThread
, THREAD_PRIORITY_TIME_CRITICAL
);
1916 TRACE("Got a nice thread hndl=%p id=0x%08x\n", lpMMThd
->hThread
, lpMMThd
->dwThreadID
);
1920 /* get WINE_mmThreadEntryPoint()
1921 * 2047 is its ordinal in mmsystem.spec
1923 FARPROC16 fp
= GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR
)2047);
1925 TRACE("farproc seg=0x%p lin=%p\n", fp
, MapSL((SEGPTR
)fp
));
1927 ret
= (fp
== 0) ? 2 : mmTaskCreate16((DWORD
)fp
, 0, hndl
);
1931 if (lpMMThd
->hThread
&& !ResumeThread(lpMMThd
->hThread
))
1932 WARN("Couldn't resume thread\n");
1934 while (lpMMThd
->dwStatus
!= 0x10) { /* test also HIWORD of dwStatus */
1948 TRACE("ok => %ld\n", ret
);
1952 /**************************************************************************
1953 * mmThreadSignal [MMSYSTEM.1121]
1955 void WINAPI
mmThreadSignal16(HANDLE16 hndl
)
1957 TRACE("(%04x)!\n", hndl
);
1960 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
1962 lpMMThd
->dwCounter
++;
1963 if (lpMMThd
->hThread
!= 0) {
1964 InterlockedIncrement(&lpMMThd
->dwSignalCount
);
1965 SetEvent(lpMMThd
->hEvent
);
1967 mmTaskSignal16(lpMMThd
->hTask
);
1969 lpMMThd
->dwCounter
--;
1973 static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD
* lpMMThd
)
1978 if (lpMMThd
->dwThreadID
!= GetCurrentThreadId())
1979 ERR("Not called by thread itself\n");
1982 ResetEvent(lpMMThd
->hEvent
);
1983 if (InterlockedDecrement(&lpMMThd
->dwSignalCount
) >= 0)
1985 InterlockedIncrement(&lpMMThd
->dwSignalCount
);
1989 ret
= MsgWaitForMultipleObjects(1, &lpMMThd
->hEvent
, FALSE
, INFINITE
, QS_ALLINPUT
);
1991 case WAIT_OBJECT_0
: /* Event */
1994 case WAIT_OBJECT_0
+ 1: /* Msg */
1996 if (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
)) {
1997 TranslateMessage(&msg
);
1998 DispatchMessageA(&msg
);
2002 WARN("S2.x unsupported ret val 0x%08x\n", ret
);
2008 /**************************************************************************
2009 * mmThreadBlock [MMSYSTEM.1122]
2011 void WINAPI
mmThreadBlock16(HANDLE16 hndl
)
2013 TRACE("(%04x)!\n", hndl
);
2016 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
2018 if (lpMMThd
->hThread
!= 0) {
2021 ReleaseThunkLock(&lc
);
2022 MMSYSTEM_ThreadBlock(lpMMThd
);
2023 RestoreThunkLock(lc
);
2025 mmTaskBlock16(lpMMThd
->hTask
);
2031 /**************************************************************************
2032 * mmThreadIsCurrent [MMSYSTEM.1123]
2034 BOOL16 WINAPI
mmThreadIsCurrent16(HANDLE16 hndl
)
2038 TRACE("(%04x)!\n", hndl
);
2040 if (hndl
&& mmThreadIsValid16(hndl
)) {
2041 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
2042 ret
= (GetCurrentThreadId() == lpMMThd
->dwThreadID
);
2044 TRACE("=> %d\n", ret
);
2048 /**************************************************************************
2049 * mmThreadIsValid [MMSYSTEM.1124]
2051 BOOL16 WINAPI
mmThreadIsValid16(HANDLE16 hndl
)
2055 TRACE("(%04x)!\n", hndl
);
2058 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
2060 if (!IsBadWritePtr(lpMMThd
, sizeof(WINE_MMTHREAD
)) &&
2061 lpMMThd
->dwSignature
== WINE_MMTHREAD_CREATED
&&
2062 IsTask16(lpMMThd
->hTask
)) {
2063 lpMMThd
->dwCounter
++;
2064 if (lpMMThd
->hThread
!= 0) {
2066 if (GetExitCodeThread(lpMMThd
->hThread
, &dwThreadRet
) &&
2067 dwThreadRet
== STATUS_PENDING
) {
2073 lpMMThd
->dwCounter
--;
2076 TRACE("=> %d\n", ret
);
2080 /**************************************************************************
2081 * mmThreadGetTask [MMSYSTEM.1125]
2083 HANDLE16 WINAPI
mmThreadGetTask16(HANDLE16 hndl
)
2087 TRACE("(%04x)\n", hndl
);
2089 if (mmThreadIsValid16(hndl
)) {
2090 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
2091 ret
= lpMMThd
->hTask
;
2096 /**************************************************************************
2097 * __wine_mmThreadEntryPoint (MMSYSTEM.2047)
2099 DWORD WINAPI
WINE_mmThreadEntryPoint(LPVOID p
)
2101 HANDLE16 hndl
= (HANDLE16
)(DWORD_PTR
)p
;
2102 WINE_MMTHREAD
* lpMMThd
= WINMM_GetmmThread(hndl
);
2104 TRACE("(%04x %p)\n", hndl
, lpMMThd
);
2106 lpMMThd
->hTask
= LOWORD(GetCurrentTask());
2107 TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd
->hThread
, lpMMThd
->hTask
);
2108 lpMMThd
->dwStatus
= 0x10;
2109 MMSYSTEM_ThreadBlock(lpMMThd
);
2110 TRACE("[20-%p]\n", lpMMThd
->hThread
);
2111 lpMMThd
->dwStatus
= 0x20;
2112 if (lpMMThd
->fpThread
) {
2113 WOWCallback16(lpMMThd
->fpThread
, lpMMThd
->dwThreadPmt
);
2115 lpMMThd
->dwStatus
= 0x30;
2116 TRACE("[30-%p]\n", lpMMThd
->hThread
);
2117 while (lpMMThd
->dwCounter
) {
2121 TRACE("[XX-%p]\n", lpMMThd
->hThread
);
2123 lpMMThd
->dwSignature
= WINE_MMTHREAD_DELETED
;
2124 /* close lpMMThread->hVxD directIO */
2125 if (lpMMThd
->hEvent
)
2126 CloseHandle(lpMMThd
->hEvent
);
2133 typedef BOOL16 (WINAPI
*MMCPLCALLBACK
)(HWND
, LPCSTR
, LPCSTR
, LPCSTR
);
2135 /**************************************************************************
2136 * mmShowMMCPLPropertySheet [MMSYSTEM.1150]
2138 BOOL16 WINAPI
mmShowMMCPLPropertySheet16(HWND hWnd
, LPCSTR lpStrDevice
,
2139 LPCSTR lpStrTab
, LPCSTR lpStrTitle
)
2144 TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd
, lpStrDevice
, lpStrTab
, lpStrTitle
);
2146 hndl
= LoadLibraryA("MMSYS.CPL");
2148 MMCPLCALLBACK fp
= (MMCPLCALLBACK
)GetProcAddress(hndl
, "ShowMMCPLPropertySheet");
2151 ReleaseThunkLock(&lc
);
2152 ret
= (fp
)(hWnd
, lpStrDevice
, lpStrTab
, lpStrTitle
);
2153 RestoreThunkLock(lc
);
2161 /**************************************************************************
2162 * StackEnter [MMSYSTEM.32]
2164 void WINAPI
StackEnter16(void)
2167 /* mmsystem.dll from Win 95 does only this: so does Wine */
2172 /**************************************************************************
2173 * StackLeave [MMSYSTEM.33]
2175 void WINAPI
StackLeave16(void)
2178 /* mmsystem.dll from Win 95 does only this: so does Wine */
2183 /**************************************************************************
2184 * WMMMidiRunOnce [MMSYSTEM.8]
2186 void WINAPI
WMMMidiRunOnce16(void)
2188 FIXME("(), stub!\n");
2191 /* ###################################################
2193 * ###################################################
2196 /**************************************************************************
2197 * DRIVER_MapMsg32To16 [internal]
2199 * Map a 32 bit driver message to a 16 bit driver message.
2201 static WINMM_MapType
DRIVER_MapMsg32To16(WORD wMsg
, LPARAM
*lParam1
, LPARAM
*lParam2
)
2203 WINMM_MapType ret
= WINMM_MAP_MSGERROR
;
2210 case DRV_QUERYCONFIGURE
:
2212 case DRV_EXITSESSION
:
2213 case DRV_EXITAPPLICATION
:
2215 case DRV_CLOSE
: /* should be 0/0 */
2216 case DRV_OPEN
: /* pass through */
2217 /* lParam1 and lParam2 are not used */
2222 /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
2223 * lParam2 is a pointer to DRVCONFIGINFO
2226 LPDRVCONFIGINFO16 dci16
= HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16
) );
2227 LPDRVCONFIGINFO dci32
= (LPDRVCONFIGINFO
)(*lParam2
);
2230 LPSTR str1
= NULL
,str2
;
2232 dci16
->dwDCISize
= sizeof(DRVCONFIGINFO16
);
2234 if (dci32
->lpszDCISectionName
) {
2235 len
= WideCharToMultiByte( CP_ACP
, 0, dci32
->lpszDCISectionName
, -1, NULL
, 0, NULL
, NULL
);
2236 str1
= HeapAlloc( GetProcessHeap(), 0, len
);
2238 WideCharToMultiByte( CP_ACP
, 0, dci32
->lpszDCISectionName
, -1, str1
, len
, NULL
, NULL
);
2239 dci16
->lpszDCISectionName
= MapLS( str1
);
2241 HeapFree( GetProcessHeap(), 0, dci16
);
2242 return WINMM_MAP_NOMEM
;
2245 dci16
->lpszDCISectionName
= 0L;
2247 if (dci32
->lpszDCIAliasName
) {
2248 len
= WideCharToMultiByte( CP_ACP
, 0, dci32
->lpszDCIAliasName
, -1, NULL
, 0, NULL
, NULL
);
2249 str2
= HeapAlloc( GetProcessHeap(), 0, len
);
2251 WideCharToMultiByte( CP_ACP
, 0, dci32
->lpszDCIAliasName
, -1, str2
, len
, NULL
, NULL
);
2252 dci16
->lpszDCIAliasName
= MapLS( str2
);
2254 HeapFree( GetProcessHeap(), 0, str1
);
2255 HeapFree( GetProcessHeap(), 0, dci16
);
2256 return WINMM_MAP_NOMEM
;
2259 dci16
->lpszDCISectionName
= 0L;
2262 return WINMM_MAP_NOMEM
;
2264 *lParam2
= MapLS( dci16
);
2265 ret
= WINMM_MAP_OKMEM
;
2271 if (!((wMsg
>= 0x800 && wMsg
< 0x900) || (wMsg
>= 0x4000 && wMsg
< 0x4100))) {
2272 FIXME("Unknown message 0x%04x\n", wMsg
);
2279 /**************************************************************************
2280 * DRIVER_UnMapMsg32To16 [internal]
2282 * UnMap a 32 bit driver message to a 16 bit driver message.
2284 static WINMM_MapType
DRIVER_UnMapMsg32To16(WORD wMsg
, DWORD lParam1
, DWORD lParam2
)
2286 WINMM_MapType ret
= WINMM_MAP_MSGERROR
;
2293 case DRV_QUERYCONFIGURE
:
2295 case DRV_EXITSESSION
:
2296 case DRV_EXITAPPLICATION
:
2300 /* lParam1 and lParam2 are not used */
2304 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
2306 LPDRVCONFIGINFO16 dci16
= MapSL(lParam2
);
2307 HeapFree( GetProcessHeap(), 0, MapSL(dci16
->lpszDCISectionName
) );
2308 HeapFree( GetProcessHeap(), 0, MapSL(dci16
->lpszDCIAliasName
) );
2310 UnMapLS( dci16
->lpszDCISectionName
);
2311 UnMapLS( dci16
->lpszDCIAliasName
);
2312 HeapFree( GetProcessHeap(), 0, dci16
);
2317 if (!((wMsg
>= 0x800 && wMsg
< 0x900) || (wMsg
>= 0x4000 && wMsg
< 0x4100))) {
2318 FIXME("Unknown message 0x%04x\n", wMsg
);
2325 /**************************************************************************
2326 * DRIVER_TryOpenDriver16 [internal]
2328 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
2330 static LPWINE_DRIVER
DRIVER_OpenDriver16(LPCWSTR fn
, LPCWSTR sn
, LPARAM lParam2
)
2332 LPWINE_DRIVER lpDrv
= NULL
;
2333 LPCSTR cause
= NULL
;
2334 LPSTR fnA
= NULL
, snA
= NULL
;
2337 TRACE("(%s, %s, %08lX);\n", debugstr_w(fn
), debugstr_w(sn
), lParam2
);
2339 lpDrv
= HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER
));
2340 if (lpDrv
== NULL
) {cause
= "OOM"; goto exit
;}
2344 len
= WideCharToMultiByte( CP_ACP
, 0, fn
, -1, NULL
, 0, NULL
, NULL
);
2345 fnA
= HeapAlloc(GetProcessHeap(), 0, len
);
2346 if (fnA
== NULL
) {cause
= "OOM"; goto exit
;}
2347 WideCharToMultiByte( CP_ACP
, 0, fn
, -1, fnA
, len
, NULL
, NULL
);
2352 len
= WideCharToMultiByte( CP_ACP
, 0, sn
, -1, NULL
, 0, NULL
, NULL
);
2353 snA
= HeapAlloc(GetProcessHeap(), 0, len
);
2354 if (snA
== NULL
) {cause
= "OOM"; goto exit
;}
2355 WideCharToMultiByte( CP_ACP
, 0, sn
, -1, snA
, len
, NULL
, NULL
);
2358 /* FIXME: shall we do some black magic here on sn ?
2359 * drivers32 => drivers
2363 lpDrv
->d
.d16
.hDriver16
= OpenDriver16(fnA
, snA
, lParam2
);
2364 if (lpDrv
->d
.d16
.hDriver16
== 0) {cause
= "Not a 16 bit driver"; goto exit
;}
2365 lpDrv
->dwFlags
= WINE_GDF_16BIT
;
2368 HeapFree(GetProcessHeap(), 0, fnA
);
2369 HeapFree(GetProcessHeap(), 0, snA
);
2373 TRACE("Unable to load 16 bit module %s[%s]: %s\n",
2374 debugstr_w(fn
), debugstr_w(sn
), cause
);
2375 HeapFree(GetProcessHeap(), 0, lpDrv
);
2379 TRACE("=> %p\n", lpDrv
);
2383 /******************************************************************
2384 * DRIVER_SendMessage16
2388 static LRESULT
DRIVER_SendMessage16(HDRVR16 hDrv16
, UINT msg
,
2389 LPARAM lParam1
, LPARAM lParam2
)
2394 TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
2395 hDrv16
, msg
, lParam1
, lParam2
);
2397 switch (map
= DRIVER_MapMsg32To16(msg
, &lParam1
, &lParam2
)) {
2398 case WINMM_MAP_OKMEM
:
2400 ret
= SendDriverMessage16(hDrv16
, msg
, lParam1
, lParam2
);
2401 if (map
== WINMM_MAP_OKMEM
)
2402 DRIVER_UnMapMsg32To16(msg
, lParam1
, lParam2
);
2409 /******************************************************************
2410 * DRIVER_CloseDriver16
2414 static LRESULT
DRIVER_CloseDriver16(HDRVR16 hDrv16
, LPARAM lParam1
, LPARAM lParam2
)
2416 return CloseDriver16(hDrv16
, lParam1
, lParam2
);
2419 /**************************************************************************
2420 * DrvOpen [MMSYSTEM.1100]
2422 HDRVR16 WINAPI
DrvOpen16(LPSTR lpDriverName
, LPSTR lpSectionName
, LPARAM lParam
)
2424 return OpenDriver16(lpDriverName
, lpSectionName
, lParam
);
2427 /**************************************************************************
2428 * DrvClose [MMSYSTEM.1101]
2430 LRESULT WINAPI
DrvClose16(HDRVR16 hDrv
, LPARAM lParam1
, LPARAM lParam2
)
2432 return CloseDriver16(hDrv
, lParam1
, lParam2
);
2435 /**************************************************************************
2436 * DrvSendMessage [MMSYSTEM.1102]
2438 LRESULT WINAPI
DrvSendMessage16(HDRVR16 hDrv
, WORD msg
, LPARAM lParam1
,
2441 return SendDriverMessage16(hDrv
, msg
, lParam1
, lParam2
);
2444 /**************************************************************************
2445 * DrvGetModuleHandle [MMSYSTEM.1103]
2447 HANDLE16 WINAPI
DrvGetModuleHandle16(HDRVR16 hDrv
)
2449 return GetDriverModuleHandle16(hDrv
);
2452 /**************************************************************************
2453 * DrvDefDriverProc [MMSYSTEM.1104]
2455 LRESULT WINAPI
DrvDefDriverProc16(DWORD dwDriverID
, HDRVR16 hDrv
, WORD wMsg
,
2456 DWORD dwParam1
, DWORD dwParam2
)
2458 return DefDriverProc16(dwDriverID
, hDrv
, wMsg
, dwParam1
, dwParam2
);
2461 /**************************************************************************
2462 * DriverProc [MMSYSTEM.6]
2464 LRESULT WINAPI
DriverProc16(DWORD dwDevID
, HDRVR16 hDrv
, WORD wMsg
,
2465 DWORD dwParam1
, DWORD dwParam2
)
2467 TRACE("dwDevID=%08x hDrv=%04x wMsg=%04x dwParam1=%08x dwParam2=%08x\n",
2468 dwDevID
, hDrv
, wMsg
, dwParam1
, dwParam2
);
2470 return DrvDefDriverProc16(dwDevID
, hDrv
, wMsg
, dwParam1
, dwParam2
);
2473 /* ###################################################
2475 * ###################################################
2478 /******************************************************************
2479 * MMSYSTEM_MMTIME32to16
2483 void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16
, const MMTIME
* mmt32
)
2485 mmt16
->wType
= mmt32
->wType
;
2486 /* layout of rest is the same for 32/16,
2487 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2489 memcpy(&(mmt16
->u
), &(mmt32
->u
), sizeof(mmt16
->u
));
2492 /******************************************************************
2493 * MMSYSTEM_MMTIME16to32
2497 void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32
, const MMTIME16
* mmt16
)
2499 mmt32
->wType
= mmt16
->wType
;
2500 /* layout of rest is the same for 32/16,
2501 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2503 memcpy(&(mmt32
->u
), &(mmt16
->u
), sizeof(mmt16
->u
));
2506 /**************************************************************************
2507 * timeGetSystemTime [MMSYSTEM.601]
2509 MMRESULT16 WINAPI
timeGetSystemTime16(LPMMTIME16 lpTime
, UINT16 wSize
)
2511 if (wSize
>= sizeof(*lpTime
)) {
2512 lpTime
->wType
= TIME_MS
;
2513 lpTime
->u
.ms
= GetTickCount();
2515 TRACE("=> %u\n", lpTime
->u
.ms
);
2521 /**************************************************************************
2522 * timeSetEvent [MMSYSTEM.602]
2524 MMRESULT16 WINAPI
timeSetEvent16(UINT16 wDelay
, UINT16 wResol
, LPTIMECALLBACK16 lpFunc
,
2525 DWORD dwUser
, UINT16 wFlags
)
2527 if (wFlags
& WINE_TIMER_IS32
)
2528 WARN("Unknown windows flag... wine internally used.. ooch\n");
2530 return TIME_SetEventInternal(wDelay
, wResol
, (LPTIMECALLBACK
)lpFunc
,
2531 dwUser
, wFlags
& ~WINE_TIMER_IS32
);
2534 /**************************************************************************
2535 * timeKillEvent [MMSYSTEM.603]
2537 MMRESULT16 WINAPI
timeKillEvent16(UINT16 wID
)
2539 return timeKillEvent(wID
);
2542 /**************************************************************************
2543 * timeGetDevCaps [MMSYSTEM.604]
2545 MMRESULT16 WINAPI
timeGetDevCaps16(LPTIMECAPS16 lpCaps
, UINT16 wSize
)
2549 TRACE("(%p, %u) !\n", lpCaps
, wSize
);
2551 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
2553 ret
= timeGetDevCaps(&caps
, sizeof(caps
));
2554 if (ret
== MMSYSERR_NOERROR
) {
2556 tc16
.wPeriodMin
= caps
.wPeriodMin
;
2557 tc16
.wPeriodMax
= caps
.wPeriodMax
;
2558 memcpy(lpCaps
, &tc16
, min(wSize
, sizeof(tc16
)));
2563 /**************************************************************************
2564 * timeBeginPeriod [MMSYSTEM.605]
2566 MMRESULT16 WINAPI
timeBeginPeriod16(UINT16 wPeriod
)
2568 TRACE("(%u) !\n", wPeriod
);
2570 return timeBeginPeriod(wPeriod
);
2573 /**************************************************************************
2574 * timeEndPeriod [MMSYSTEM.606]
2576 MMRESULT16 WINAPI
timeEndPeriod16(UINT16 wPeriod
)
2578 TRACE("(%u) !\n", wPeriod
);
2580 return timeEndPeriod(wPeriod
);
2583 /**************************************************************************
2584 * mciSendString [MMSYSTEM.702]
2586 DWORD WINAPI
mciSendString16(LPCSTR lpstrCommand
, LPSTR lpstrRet
,
2587 UINT16 uRetLen
, HWND16 hwndCallback
)
2589 return mciSendStringA(lpstrCommand
, lpstrRet
, uRetLen
, HWND_32(hwndCallback
));
2592 /**************************************************************************
2593 * mciLoadCommandResource [MMSYSTEM.705]
2595 UINT16 WINAPI
mciLoadCommandResource16(HINSTANCE16 hInst
, LPCSTR resname
, UINT16 type
)
2601 unsigned pos
= 0, size
= 1024, len
;
2605 UINT16 ret
= MCIERR_OUT_OF_MEMORY
;
2607 if (!(res
= FindResource16( hInst
, resname
, (LPSTR
)RT_RCDATA
))) return MCI_NO_COMMAND_TABLE
;
2608 if (!(handle
= LoadResource16( hInst
, res
))) return MCI_NO_COMMAND_TABLE
;
2609 ptr16
= LockResource16(handle
);
2610 /* converting the 16 bit resource table into a 32W one */
2611 if ((ptr32
= HeapAlloc(GetProcessHeap(), 0, size
)))
2614 str
= (LPCSTR
)ptr16
;
2615 ptr16
+= strlen(str
) + 1;
2616 flg
= *(const DWORD
*)ptr16
;
2617 eid
= *(const WORD
*)(ptr16
+ sizeof(DWORD
));
2618 ptr16
+= sizeof(DWORD
) + sizeof(WORD
);
2619 len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0) * sizeof(WCHAR
);
2620 if (pos
+ len
+ sizeof(DWORD
) + sizeof(WORD
) > size
)
2622 while (pos
+ len
* sizeof(WCHAR
) + sizeof(DWORD
) + sizeof(WORD
) > size
) size
+= 1024;
2623 ptr32
= HeapReAlloc(GetProcessHeap(), 0, ptr32
, size
);
2624 if (!ptr32
) goto the_end
;
2626 MultiByteToWideChar(CP_ACP
, 0, str
, -1, (LPWSTR
)(ptr32
+ pos
), len
/ sizeof(WCHAR
));
2627 *(DWORD
*)(ptr32
+ pos
+ len
) = flg
;
2628 *(WORD
*)(ptr32
+ pos
+ len
+ sizeof(DWORD
)) = eid
;
2629 pos
+= len
+ sizeof(DWORD
) + sizeof(WORD
);
2630 } while (eid
!= MCI_END_COMMAND_LIST
);
2633 FreeResource16( handle
);
2634 if (ptr32
) ret
= MCI_SetCommandTable(ptr32
, type
);
2638 /**************************************************************************
2639 * mciFreeCommandResource [MMSYSTEM.713]
2641 BOOL16 WINAPI
mciFreeCommandResource16(UINT16 uTable
)
2643 TRACE("(%04x)!\n", uTable
);
2645 return MCI_DeleteCommandTable(uTable
, TRUE
);
2648 /* ###################################################
2650 * ###################################################
2653 /**************************************************************************
2654 * joyGetNumDevs [MMSYSTEM.101]
2656 UINT16 WINAPI
joyGetNumDevs16(void)
2658 return joyGetNumDevs();
2661 /**************************************************************************
2662 * joyGetDevCaps [MMSYSTEM.102]
2664 MMRESULT16 WINAPI
joyGetDevCaps16(UINT16 wID
, LPJOYCAPS16 lpCaps
, UINT16 wSize
)
2669 if (lpCaps
== NULL
) return MMSYSERR_INVALPARAM
;
2671 ret
= joyGetDevCapsA(wID
, &jca
, sizeof(jca
));
2673 if (ret
!= JOYERR_NOERROR
) return ret
;
2674 lpCaps
->wMid
= jca
.wMid
;
2675 lpCaps
->wPid
= jca
.wPid
;
2676 strcpy(lpCaps
->szPname
, jca
.szPname
);
2677 lpCaps
->wXmin
= jca
.wXmin
;
2678 lpCaps
->wXmax
= jca
.wXmax
;
2679 lpCaps
->wYmin
= jca
.wYmin
;
2680 lpCaps
->wYmax
= jca
.wYmax
;
2681 lpCaps
->wZmin
= jca
.wZmin
;
2682 lpCaps
->wZmax
= jca
.wZmax
;
2683 lpCaps
->wNumButtons
= jca
.wNumButtons
;
2684 lpCaps
->wPeriodMin
= jca
.wPeriodMin
;
2685 lpCaps
->wPeriodMax
= jca
.wPeriodMax
;
2687 if (wSize
>= sizeof(JOYCAPS16
)) { /* Win95 extensions ? */
2688 lpCaps
->wRmin
= jca
.wRmin
;
2689 lpCaps
->wRmax
= jca
.wRmax
;
2690 lpCaps
->wUmin
= jca
.wUmin
;
2691 lpCaps
->wUmax
= jca
.wUmax
;
2692 lpCaps
->wVmin
= jca
.wVmin
;
2693 lpCaps
->wVmax
= jca
.wVmax
;
2694 lpCaps
->wCaps
= jca
.wCaps
;
2695 lpCaps
->wMaxAxes
= jca
.wMaxAxes
;
2696 lpCaps
->wNumAxes
= jca
.wNumAxes
;
2697 lpCaps
->wMaxButtons
= jca
.wMaxButtons
;
2698 strcpy(lpCaps
->szRegKey
, jca
.szRegKey
);
2699 strcpy(lpCaps
->szOEMVxD
, jca
.szOEMVxD
);
2705 /**************************************************************************
2706 * joyGetPosEx [MMSYSTEM.110]
2708 MMRESULT16 WINAPI
joyGetPosEx16(UINT16 wID
, LPJOYINFOEX lpInfo
)
2710 return joyGetPosEx(wID
, lpInfo
);
2713 /**************************************************************************
2714 * joyGetPos [MMSYSTEM.103]
2716 MMRESULT16 WINAPI
joyGetPos16(UINT16 wID
, LPJOYINFO16 lpInfo
)
2721 TRACE("(%d, %p);\n", wID
, lpInfo
);
2723 if ((ret
= joyGetPos(wID
, &ji
)) == JOYERR_NOERROR
) {
2724 lpInfo
->wXpos
= ji
.wXpos
;
2725 lpInfo
->wYpos
= ji
.wYpos
;
2726 lpInfo
->wZpos
= ji
.wZpos
;
2727 lpInfo
->wButtons
= ji
.wButtons
;
2732 /**************************************************************************
2733 * joyGetThreshold [MMSYSTEM.104]
2735 MMRESULT16 WINAPI
joyGetThreshold16(UINT16 wID
, LPUINT16 lpThreshold
)
2740 ret
= joyGetThreshold(wID
, &t
);
2741 if (ret
== JOYERR_NOERROR
)
2746 /**************************************************************************
2747 * joyReleaseCapture [MMSYSTEM.105]
2749 MMRESULT16 WINAPI
joyReleaseCapture16(UINT16 wID
)
2751 return joyReleaseCapture(wID
);
2754 /**************************************************************************
2755 * joySetCapture [MMSYSTEM.106]
2757 MMRESULT16 WINAPI
joySetCapture16(HWND16 hWnd
, UINT16 wID
, UINT16 wPeriod
, BOOL16 bChanged
)
2759 return joySetCapture(HWND_32(hWnd
), wID
, wPeriod
, bChanged
);
2762 /**************************************************************************
2763 * joySetThreshold [MMSYSTEM.107]
2765 MMRESULT16 WINAPI
joySetThreshold16(UINT16 wID
, UINT16 wThreshold
)
2767 return joySetThreshold(wID
,wThreshold
);
2770 /**************************************************************************
2771 * joySetCalibration [MMSYSTEM.109]
2773 MMRESULT16 WINAPI
joySetCalibration16(UINT16 wID
)
2775 FIXME("(%04X): stub.\n", wID
);
2776 return JOYERR_NOCANDO
;