1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1993 Martin Ayotte
7 * 1998-2002 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * 99/4 added mmTask and mmThread functions support
29 /* FIXME: I think there are some segmented vs. linear pointer weirdnesses
30 * and long term pointers to 16 bit space in here
35 #define NONAMELESSUNION
36 #define NONAMELESSSTRUCT
40 #include "wine/winuser16.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
48 /* ### start build ### */
49 extern LONG CALLBACK MMSYSTEM_CallTo16_long_l (FARPROC16,LONG);
50 extern LONG CALLBACK MMSYSTEM_CallTo16_long_lwll (LPMMIOPROC16,LONG,WORD,LONG,LONG);
51 /* ### stop build ### */
53 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16);
54 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCSTR, LPCSTR, LPARAM);
55 static LRESULT DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM);
56 static LRESULT DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM);
57 static LRESULT MMIO_Callback16(SEGPTR, LPMMIOINFO, UINT, LPARAM, LPARAM);
59 #define HMODULE_32(h16) ((HMODULE)(ULONG_PTR)(h16))
60 #define HINSTANCE_32(h16) ((HMODULE)(ULONG_PTR)(h16))
62 /* ###################################################
64 * ###################################################
67 /**************************************************************************
68 * DllEntryPoint (MMSYSTEM.2046)
70 * MMSYSTEM DLL entry point
73 BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
74 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
76 TRACE("%p 0x%lx\n", hinstDLL, fdwReason);
79 case DLL_PROCESS_ATTACH:
80 /* need to load WinMM in order to:
81 * - initiate correctly shared variables (WINMM_Init())
83 if (!GetModuleHandleA("WINMM.DLL") && !LoadLibraryA("WINMM.DLL"))
85 ERR("Could not load sibling WinMM.dll\n");
88 WINMM_IData->hWinMM16Instance = hinstDLL;
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 pFnMmioCallback16 = MMIO_Callback16;
97 case DLL_PROCESS_DETACH:
98 WINMM_IData->hWinMM16Instance = 0;
99 pFnGetMMThread16 = NULL;
100 pFnOpenDriver16 = NULL;
101 pFnCloseDriver16 = NULL;
102 pFnSendMessage16 = NULL;
103 pFnMmioCallback16 = NULL;
104 /* FIXME: add equivalent for MMDRV_Init16() */
106 case DLL_THREAD_ATTACH:
107 case DLL_THREAD_DETACH:
113 /**************************************************************************
114 * MMSYSTEM_WEP [MMSYSTEM.1]
116 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
117 WORD cbHeapSize, LPSTR lpCmdLine)
119 FIXME("STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
123 /* ###################################################
125 * ###################################################
128 /**************************************************************************
129 * PlaySound [MMSYSTEM.3]
131 BOOL16 WINAPI PlaySound16(LPCSTR pszSound, HMODULE16 hmod, DWORD fdwSound)
136 ReleaseThunkLock(&lc);
137 retv = PlaySoundA(pszSound, HMODULE_32(hmod), fdwSound);
138 RestoreThunkLock(lc);
143 /**************************************************************************
144 * sndPlaySound [MMSYSTEM.2]
146 BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags)
151 ReleaseThunkLock(&lc);
152 retv = sndPlaySoundA(lpszSoundName, uFlags);
153 RestoreThunkLock(lc);
158 /* ###################################################
160 * ###################################################
163 /**************************************************************************
164 * mmsystemGetVersion [MMSYSTEM.5]
167 UINT16 WINAPI mmsystemGetVersion16(void)
169 return mmsystemGetVersion();
172 /**************************************************************************
173 * DriverCallback [MMSYSTEM.31]
175 BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev,
176 WORD wMsg, DWORD dwUser, DWORD dwParam1,
179 return DriverCallback(dwCallBack, uFlags, HDRVR_32(hDev), wMsg, dwUser, dwParam1, dwParam2);
182 /**************************************************************************
183 * OutputDebugStr [MMSYSTEM.30]
185 void WINAPI OutputDebugStr16(LPCSTR str)
187 OutputDebugStringA( str );
191 /* ###################################################
193 * ###################################################
196 /**************************************************************************
197 * Mixer devices. New to Win95
200 /**************************************************************************
201 * mixerGetNumDevs [MMSYSTEM.800]
203 UINT16 WINAPI mixerGetNumDevs16(void)
205 return MMDRV_GetNum(MMDRV_MIXER);
208 /**************************************************************************
209 * mixerGetDevCaps [MMSYSTEM.801]
211 UINT16 WINAPI mixerGetDevCaps16(UINT16 devid, LPMIXERCAPS16 mixcaps,
215 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
217 if (ret == MMSYSERR_NOERROR) {
218 mixcaps->wMid = micA.wMid;
219 mixcaps->wPid = micA.wPid;
220 mixcaps->vDriverVersion = micA.vDriverVersion;
221 strcpy(mixcaps->szPname, micA.szPname);
222 mixcaps->fdwSupport = micA.fdwSupport;
223 mixcaps->cDestinations = micA.cDestinations;
228 /**************************************************************************
229 * mixerOpen [MMSYSTEM.802]
231 UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix, UINT16 uDeviceID, DWORD dwCallback,
232 DWORD dwInstance, DWORD fdwOpen)
237 ret = MIXER_Open(&hmix, uDeviceID, dwCallback, dwInstance, fdwOpen, FALSE);
238 if (lphmix) *lphmix = HMIXER_16(hmix);
242 /**************************************************************************
243 * mixerClose [MMSYSTEM.803]
245 UINT16 WINAPI mixerClose16(HMIXER16 hMix)
247 return mixerClose(HMIXER_32(hMix));
250 /**************************************************************************
251 * mixerGetID (MMSYSTEM.806)
253 UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID)
256 UINT ret = mixerGetID(HMIXEROBJ_32(hmix), &xid, fdwID);
263 /**************************************************************************
264 * mixerGetControlDetails [MMSYSTEM.808]
266 UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,
267 LPMIXERCONTROLDETAILS16 lpmcd,
270 DWORD ret = MMSYSERR_NOTENABLED;
273 TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);
275 if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
276 return MMSYSERR_INVALPARAM;
278 sppaDetails = (SEGPTR)lpmcd->paDetails;
279 lpmcd->paDetails = MapSL(sppaDetails);
280 ret = mixerGetControlDetailsA(HMIXEROBJ_32(hmix),
281 (LPMIXERCONTROLDETAILS)lpmcd, fdwDetails);
282 lpmcd->paDetails = (LPVOID)sppaDetails;
287 /**************************************************************************
288 * mixerGetLineControls [MMSYSTEM.807]
290 UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,
291 LPMIXERLINECONTROLS16 lpmlc16,
294 MIXERLINECONTROLSA mlcA;
297 LPMIXERCONTROL16 lpmc16;
299 TRACE("(%04x, %p, %08lx)\n", hmix, lpmlc16, fdwControls);
301 if (lpmlc16 == NULL || lpmlc16->cbStruct != sizeof(*lpmlc16) ||
302 lpmlc16->cbmxctrl != sizeof(MIXERCONTROL16))
303 return MMSYSERR_INVALPARAM;
305 mlcA.cbStruct = sizeof(mlcA);
306 mlcA.dwLineID = lpmlc16->dwLineID;
307 mlcA.u.dwControlID = lpmlc16->u.dwControlID;
308 mlcA.u.dwControlType = lpmlc16->u.dwControlType;
309 mlcA.cControls = lpmlc16->cControls;
310 mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
311 mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
312 mlcA.cControls * mlcA.cbmxctrl);
314 ret = mixerGetLineControlsA(HMIXEROBJ_32(hmix), &mlcA, fdwControls);
316 if (ret == MMSYSERR_NOERROR) {
317 lpmlc16->dwLineID = mlcA.dwLineID;
318 lpmlc16->u.dwControlID = mlcA.u.dwControlID;
319 lpmlc16->u.dwControlType = mlcA.u.dwControlType;
320 lpmlc16->cControls = mlcA.cControls;
322 lpmc16 = MapSL(lpmlc16->pamxctrl);
324 for (i = 0; i < mlcA.cControls; i++) {
325 lpmc16[i].cbStruct = sizeof(MIXERCONTROL16);
326 lpmc16[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
327 lpmc16[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
328 lpmc16[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
329 lpmc16[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
330 strcpy(lpmc16[i].szShortName, mlcA.pamxctrl[i].szShortName);
331 strcpy(lpmc16[i].szName, mlcA.pamxctrl[i].szName);
332 /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
333 memcpy(&lpmc16[i].Bounds, &mlcA.pamxctrl[i].Bounds,
334 sizeof(mlcA.pamxctrl[i].Bounds));
335 /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
336 memcpy(&lpmc16[i].Metrics, &mlcA.pamxctrl[i].Metrics,
337 sizeof(mlcA.pamxctrl[i].Metrics));
341 HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);
346 /**************************************************************************
347 * mixerGetLineInfo [MMSYSTEM.805]
349 UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16,
355 TRACE("(%04x, %p, %08lx)\n", hmix, lpmli16, fdwInfo);
357 if (lpmli16 == NULL || lpmli16->cbStruct != sizeof(*lpmli16))
358 return MMSYSERR_INVALPARAM;
360 mliA.cbStruct = sizeof(mliA);
361 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
362 case MIXER_GETLINEINFOF_COMPONENTTYPE:
363 mliA.dwComponentType = lpmli16->dwComponentType;
365 case MIXER_GETLINEINFOF_DESTINATION:
366 mliA.dwDestination = lpmli16->dwDestination;
368 case MIXER_GETLINEINFOF_LINEID:
369 mliA.dwLineID = lpmli16->dwLineID;
371 case MIXER_GETLINEINFOF_SOURCE:
372 mliA.dwDestination = lpmli16->dwDestination;
373 mliA.dwSource = lpmli16->dwSource;
375 case MIXER_GETLINEINFOF_TARGETTYPE:
376 mliA.Target.dwType = lpmli16->Target.dwType;
377 mliA.Target.wMid = lpmli16->Target.wMid;
378 mliA.Target.wPid = lpmli16->Target.wPid;
379 mliA.Target.vDriverVersion = lpmli16->Target.vDriverVersion;
380 strcpy(mliA.Target.szPname, lpmli16->Target.szPname);
383 FIXME("Unsupported fdwControls=0x%08lx\n", fdwInfo);
386 ret = mixerGetLineInfoA(HMIXEROBJ_32(hmix), &mliA, fdwInfo);
388 lpmli16->dwDestination = mliA.dwDestination;
389 lpmli16->dwSource = mliA.dwSource;
390 lpmli16->dwLineID = mliA.dwLineID;
391 lpmli16->fdwLine = mliA.fdwLine;
392 lpmli16->dwUser = mliA.dwUser;
393 lpmli16->dwComponentType = mliA.dwComponentType;
394 lpmli16->cChannels = mliA.cChannels;
395 lpmli16->cConnections = mliA.cConnections;
396 lpmli16->cControls = mliA.cControls;
397 strcpy(lpmli16->szShortName, mliA.szShortName);
398 strcpy(lpmli16->szName, mliA.szName);
399 lpmli16->Target.dwType = mliA.Target.dwType;
400 lpmli16->Target.dwDeviceID = mliA.Target.dwDeviceID;
401 lpmli16->Target.wMid = mliA.Target.wMid;
402 lpmli16->Target.wPid = mliA.Target.wPid;
403 lpmli16->Target.vDriverVersion = mliA.Target.vDriverVersion;
404 strcpy(lpmli16->Target.szPname, mliA.Target.szPname);
409 /**************************************************************************
410 * mixerSetControlDetails [MMSYSTEM.809]
412 UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,
413 LPMIXERCONTROLDETAILS16 lpmcd,
416 TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);
417 return MMSYSERR_NOTENABLED;
420 /**************************************************************************
421 * mixerMessage [MMSYSTEM.804]
423 DWORD WINAPI mixerMessage16(HMIXER16 hmix, UINT16 uMsg, DWORD dwParam1,
426 return mixerMessage(HMIXER_32(hmix), uMsg, dwParam1, dwParam2);
429 /**************************************************************************
430 * auxGetNumDevs [MMSYSTEM.350]
432 UINT16 WINAPI auxGetNumDevs16(void)
434 return MMDRV_GetNum(MMDRV_AUX);
437 /* ###################################################
439 * ###################################################
442 /**************************************************************************
443 * auxGetDevCaps [MMSYSTEM.351]
445 UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID, LPAUXCAPS16 lpCaps, UINT16 uSize)
449 TRACE("(%04X, %p, %d) !\n", uDeviceID, lpCaps, uSize);
451 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
452 return MMSYSERR_INVALHANDLE;
453 return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
456 /**************************************************************************
457 * auxGetVolume [MMSYSTEM.352]
459 UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, LPDWORD lpdwVolume)
463 TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
465 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
466 return MMSYSERR_INVALHANDLE;
467 return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE);
470 /**************************************************************************
471 * auxSetVolume [MMSYSTEM.353]
473 UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
477 TRACE("(%04X, %lu) !\n", uDeviceID, dwVolume);
479 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
480 return MMSYSERR_INVALHANDLE;
481 return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE);
484 /**************************************************************************
485 * auxOutMessage [MMSYSTEM.354]
487 DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
491 TRACE("(%04X, %04X, %08lX, %08lX)\n", uDeviceID, uMessage, dw1, dw2);
494 case AUXDM_GETNUMDEVS:
495 case AUXDM_SETVOLUME:
496 /* no argument conversion needed */
498 case AUXDM_GETVOLUME:
499 return auxGetVolume16(uDeviceID, MapSL(dw1));
500 case AUXDM_GETDEVCAPS:
501 return auxGetDevCaps16(uDeviceID, MapSL(dw1), dw2);
503 TRACE("(%04x, %04x, %08lx, %08lx): unhandled message\n",
504 uDeviceID, uMessage, dw1, dw2);
507 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
508 return MMSYSERR_INVALHANDLE;
510 return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE);
513 /* ###################################################
515 * ###################################################
518 /**************************************************************************
519 * mciGetErrorString [MMSYSTEM.706]
521 BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer, UINT16 uLength)
523 return mciGetErrorStringA(wError, lpstrBuffer, uLength);
526 /**************************************************************************
527 * mciDriverNotify [MMSYSTEM.711]
529 BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
531 TRACE("(%04X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
533 return PostMessageA(HWND_32(hWndCallBack), MM_MCINOTIFY, wStatus, wDevID);
536 /**************************************************************************
537 * mciGetDriverData [MMSYSTEM.708]
539 DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID)
541 return mciGetDriverData(uDeviceID);
544 /**************************************************************************
545 * mciSetDriverData [MMSYSTEM.707]
547 BOOL16 WINAPI mciSetDriverData16(UINT16 uDeviceID, DWORD data)
549 return mciSetDriverData(uDeviceID, data);
552 /**************************************************************************
553 * mciSendCommand [MMSYSTEM.701]
555 DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
559 TRACE("(%04X, %s, %08lX, %08lX)\n",
560 wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
562 dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, FALSE);
563 dwRet = MCI_CleanUp(dwRet, wMsg, (DWORD)MapSL(dwParam2));
564 TRACE("=> %ld\n", dwRet);
568 /**************************************************************************
569 * mciGetDeviceID [MMSYSTEM.703]
571 UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
573 TRACE("(\"%s\")\n", lpstrName);
575 return MCI_GetDriverFromString(lpstrName);
578 /**************************************************************************
579 * mciSetYieldProc [MMSYSTEM.714]
581 BOOL16 WINAPI mciSetYieldProc16(UINT16 uDeviceID, YIELDPROC16 fpYieldProc, DWORD dwYieldData)
583 LPWINE_MCIDRIVER wmd;
585 TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData);
587 if (!(wmd = MCI_GetDriver(uDeviceID))) {
588 WARN("Bad uDeviceID\n");
592 wmd->lpfnYieldProc = (YIELDPROC)fpYieldProc;
593 wmd->dwYieldData = dwYieldData;
599 /**************************************************************************
600 * mciGetDeviceIDFromElementID [MMSYSTEM.715]
602 UINT16 WINAPI mciGetDeviceIDFromElementID16(DWORD dwElementID, LPCSTR lpstrType)
604 FIXME("(%lu, %s) stub\n", dwElementID, lpstrType);
608 /**************************************************************************
609 * mciGetYieldProc [MMSYSTEM.716]
611 YIELDPROC16 WINAPI mciGetYieldProc16(UINT16 uDeviceID, DWORD* lpdwYieldData)
613 LPWINE_MCIDRIVER wmd;
615 TRACE("(%u, %p)\n", uDeviceID, lpdwYieldData);
617 if (!(wmd = MCI_GetDriver(uDeviceID))) {
618 WARN("Bad uDeviceID\n");
621 if (!wmd->lpfnYieldProc) {
622 WARN("No proc set\n");
626 WARN("Proc is 32 bit\n");
629 return (YIELDPROC16)wmd->lpfnYieldProc;
632 /**************************************************************************
633 * mciGetCreatorTask [MMSYSTEM.717]
635 HTASK16 WINAPI mciGetCreatorTask16(UINT16 uDeviceID)
637 LPWINE_MCIDRIVER wmd;
640 if ((wmd = MCI_GetDriver(uDeviceID)))
641 ret = HTASK_16(wmd->CreatorThread);
643 TRACE("(%u) => %04x\n", uDeviceID, ret);
647 /**************************************************************************
648 * mciDriverYield [MMSYSTEM.710]
650 UINT16 WINAPI mciDriverYield16(UINT16 uDeviceID)
652 LPWINE_MCIDRIVER wmd;
655 /* TRACE("(%04x)\n", uDeviceID); */
657 if (!(wmd = MCI_GetDriver(uDeviceID)) || !wmd->lpfnYieldProc || wmd->bIs32) {
660 ret = wmd->lpfnYieldProc(uDeviceID, wmd->dwYieldData);
666 /* ###################################################
668 * ###################################################
671 /**************************************************************************
672 * midiOutGetNumDevs [MMSYSTEM.201]
674 UINT16 WINAPI midiOutGetNumDevs16(void)
676 return MMDRV_GetNum(MMDRV_MIDIOUT);
679 /**************************************************************************
680 * midiOutGetDevCaps [MMSYSTEM.202]
682 UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID, LPMIDIOUTCAPS16 lpCaps,
688 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
690 dwRet = midiOutGetDevCapsA(uDeviceID, &capsA, sizeof(capsA));
691 if (dwRet == MMSYSERR_NOERROR) {
692 lpCaps->wMid = capsA.wMid;
693 lpCaps->wPid = capsA.wPid;
694 lpCaps->vDriverVersion = capsA.vDriverVersion;
695 strcpy(lpCaps->szPname, capsA.szPname);
696 lpCaps->wTechnology = capsA.wTechnology;
697 lpCaps->wVoices = capsA.wVoices;
698 lpCaps->wNotes = capsA.wNotes;
699 lpCaps->wChannelMask = capsA.wChannelMask;
700 lpCaps->dwSupport = capsA.dwSupport;
705 /**************************************************************************
706 * midiOutGetErrorText [MMSYSTEM.203]
708 UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
710 return midiOutGetErrorTextA(uError, lpText, uSize);
713 /**************************************************************************
714 * midiOutOpen [MMSYSTEM.204]
716 UINT16 WINAPI midiOutOpen16(HMIDIOUT16* lphMidiOut, UINT16 uDeviceID,
717 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
722 ret = MIDI_OutOpen(&hmo, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
724 if (lphMidiOut != NULL) *lphMidiOut = HMIDIOUT_16(hmo);
728 /**************************************************************************
729 * midiOutClose [MMSYSTEM.205]
731 UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
733 return midiOutClose(HMIDIOUT_32(hMidiOut));
736 /**************************************************************************
737 * midiOutPrepareHeader [MMSYSTEM.206]
739 UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
740 SEGPTR lpsegMidiOutHdr, /* [???] */
741 UINT16 uSize) /* [in] */
745 TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
747 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
748 return MMSYSERR_INVALHANDLE;
750 return MMDRV_Message(wmld, MODM_PREPARE, lpsegMidiOutHdr, uSize, FALSE);
753 /**************************************************************************
754 * midiOutUnprepareHeader [MMSYSTEM.207]
756 UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
757 SEGPTR lpsegMidiOutHdr, /* [???] */
758 UINT16 uSize) /* [in] */
761 LPMIDIHDR16 lpMidiOutHdr = MapSL(lpsegMidiOutHdr);
763 TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
765 if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
766 return MMSYSERR_NOERROR;
769 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
770 return MMSYSERR_INVALHANDLE;
772 return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpsegMidiOutHdr, uSize, FALSE);
775 /**************************************************************************
776 * midiOutShortMsg [MMSYSTEM.208]
778 UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
780 return midiOutShortMsg(HMIDIOUT_32(hMidiOut), dwMsg);
783 /**************************************************************************
784 * midiOutLongMsg [MMSYSTEM.209]
786 UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut, /* [in] */
787 LPMIDIHDR16 lpsegMidiOutHdr, /* [???] NOTE: SEGPTR */
788 UINT16 uSize) /* [in] */
792 TRACE("(%04X, %p, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
794 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
795 return MMSYSERR_INVALHANDLE;
797 return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD)lpsegMidiOutHdr, uSize, FALSE);
800 /**************************************************************************
801 * midiOutReset [MMSYSTEM.210]
803 UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
805 return midiOutReset(HMIDIOUT_32(hMidiOut));
808 /**************************************************************************
809 * midiOutGetVolume [MMSYSTEM.211]
811 UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD* lpdwVolume)
813 return midiOutGetVolume(HMIDIOUT_32(uDeviceID), lpdwVolume);
816 /**************************************************************************
817 * midiOutSetVolume [MMSYSTEM.212]
819 UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
821 return midiOutSetVolume(HMIDIOUT_32(uDeviceID), dwVolume);
824 /**************************************************************************
825 * midiOutCachePatches [MMSYSTEM.213]
827 UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
828 WORD* lpwPatchArray, UINT16 uFlags)
830 return midiOutCachePatches(HMIDIOUT_32(hMidiOut), uBank, lpwPatchArray,
834 /**************************************************************************
835 * midiOutCacheDrumPatches [MMSYSTEM.214]
837 UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
838 WORD* lpwKeyArray, UINT16 uFlags)
840 return midiOutCacheDrumPatches(HMIDIOUT_32(hMidiOut), uPatch, lpwKeyArray, uFlags);
843 /**************************************************************************
844 * midiOutGetID [MMSYSTEM.215]
846 UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16* lpuDeviceID)
850 TRACE("(%04X, %p)\n", hMidiOut, lpuDeviceID);
852 if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
853 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
854 return MMSYSERR_INVALHANDLE;
856 *lpuDeviceID = wmld->uDeviceID;
857 return MMSYSERR_NOERROR;
860 /**************************************************************************
861 * midiOutMessage [MMSYSTEM.216]
863 DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage,
864 DWORD dwParam1, DWORD dwParam2)
868 TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiOut, uMessage, dwParam1, dwParam2);
870 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
871 return MMSYSERR_INVALHANDLE;
876 FIXME("can't handle OPEN or CLOSE message!\n");
877 return MMSYSERR_NOTSUPPORTED;
880 return midiOutGetVolume16(hMidiOut, MapSL(dwParam1));
882 return midiOutLongMsg16(hMidiOut, MapSL(dwParam1), dwParam2);
884 /* lpMidiOutHdr is still a segmented pointer for this function */
885 return midiOutPrepareHeader16(hMidiOut, dwParam1, dwParam2);
887 return midiOutUnprepareHeader16(hMidiOut, dwParam1, dwParam2);
889 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
892 /**************************************************************************
893 * midiInGetNumDevs [MMSYSTEM.301]
895 UINT16 WINAPI midiInGetNumDevs16(void)
897 return MMDRV_GetNum(MMDRV_MIDIIN);
900 /**************************************************************************
901 * midiInGetDevCaps [MMSYSTEM.302]
903 UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID, LPMIDIINCAPS16 lpCaps,
907 UINT ret = midiInGetDevCapsA(uDeviceID, &micA, uSize);
909 if (ret == MMSYSERR_NOERROR) {
910 lpCaps->wMid = micA.wMid;
911 lpCaps->wPid = micA.wPid;
912 lpCaps->vDriverVersion = micA.vDriverVersion;
913 strcpy(lpCaps->szPname, micA.szPname);
914 lpCaps->dwSupport = micA.dwSupport;
920 /**************************************************************************
921 * midiInGetErrorText [MMSYSTEM.303]
923 UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
925 return midiInGetErrorTextA(uError, lpText, uSize);
928 /**************************************************************************
929 * midiInOpen [MMSYSTEM.304]
931 UINT16 WINAPI midiInOpen16(HMIDIIN16* lphMidiIn, UINT16 uDeviceID,
932 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
937 ret = MIDI_InOpen(&xhmid, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
939 if (lphMidiIn) *lphMidiIn = HMIDIIN_16(xhmid);
943 /**************************************************************************
944 * midiInClose [MMSYSTEM.305]
946 UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
948 return midiInClose(HMIDIIN_32(hMidiIn));
951 /**************************************************************************
952 * midiInPrepareHeader [MMSYSTEM.306]
954 UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
955 SEGPTR lpsegMidiInHdr, /* [???] */
956 UINT16 uSize) /* [in] */
960 TRACE("(%04X, %08lx, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
962 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
963 return MMSYSERR_INVALHANDLE;
965 return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD)lpsegMidiInHdr, uSize, FALSE);
968 /**************************************************************************
969 * midiInUnprepareHeader [MMSYSTEM.307]
971 UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
972 SEGPTR lpsegMidiInHdr, /* [???] */
973 UINT16 uSize) /* [in] */
976 LPMIDIHDR16 lpMidiInHdr = MapSL(lpsegMidiInHdr);
978 TRACE("(%04X, %08lx, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
980 if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
981 return MMSYSERR_NOERROR;
984 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
985 return MMSYSERR_INVALHANDLE;
987 return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpsegMidiInHdr, uSize, FALSE);
990 /**************************************************************************
991 * midiInAddBuffer [MMSYSTEM.308]
993 UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn, /* [in] */
994 MIDIHDR16* lpsegMidiInHdr, /* [???] NOTE: SEGPTR */
995 UINT16 uSize) /* [in] */
999 TRACE("(%04X, %p, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
1001 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
1002 return MMSYSERR_INVALHANDLE;
1004 return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD)lpsegMidiInHdr, uSize, FALSE);
1007 /**************************************************************************
1008 * midiInStart [MMSYSTEM.309]
1010 UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
1012 return midiInStart(HMIDIIN_32(hMidiIn));
1015 /**************************************************************************
1016 * midiInStop [MMSYSTEM.310]
1018 UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
1020 return midiInStop(HMIDIIN_32(hMidiIn));
1023 /**************************************************************************
1024 * midiInReset [MMSYSTEM.311]
1026 UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
1028 return midiInReset(HMIDIIN_32(hMidiIn));
1031 /**************************************************************************
1032 * midiInGetID [MMSYSTEM.312]
1034 UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
1038 TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID);
1040 if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1042 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, TRUE)) == NULL)
1043 return MMSYSERR_INVALHANDLE;
1045 *lpuDeviceID = wmld->uDeviceID;
1047 return MMSYSERR_NOERROR;
1050 /**************************************************************************
1051 * midiInMessage [MMSYSTEM.313]
1053 DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage,
1054 DWORD dwParam1, DWORD dwParam2)
1058 TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
1063 FIXME("can't handle OPEN or CLOSE message!\n");
1064 return MMSYSERR_NOTSUPPORTED;
1066 case MIDM_GETDEVCAPS:
1067 return midiInGetDevCaps16(hMidiIn, MapSL(dwParam1), dwParam2);
1069 return midiInPrepareHeader16(hMidiIn, dwParam1, dwParam2);
1070 case MIDM_UNPREPARE:
1071 return midiInUnprepareHeader16(hMidiIn, dwParam1, dwParam2);
1072 case MIDM_ADDBUFFER:
1073 return midiInAddBuffer16(hMidiIn, MapSL(dwParam1), dwParam2);
1076 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
1077 return MMSYSERR_INVALHANDLE;
1079 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1082 /**************************************************************************
1083 * midiStreamClose [MMSYSTEM.252]
1085 MMRESULT16 WINAPI midiStreamClose16(HMIDISTRM16 hMidiStrm)
1087 return midiStreamClose(HMIDISTRM_32(hMidiStrm));
1090 /**************************************************************************
1091 * midiStreamOpen [MMSYSTEM.251]
1093 MMRESULT16 WINAPI midiStreamOpen16(HMIDISTRM16* phMidiStrm, LPUINT16 devid,
1094 DWORD cMidi, DWORD dwCallback,
1095 DWORD dwInstance, DWORD fdwOpen)
1097 HMIDISTRM hMidiStrm32;
1101 if (!phMidiStrm || !devid)
1102 return MMSYSERR_INVALPARAM;
1104 ret = MIDI_StreamOpen(&hMidiStrm32, &devid32, cMidi, dwCallback,
1105 dwInstance, fdwOpen, FALSE);
1106 *phMidiStrm = HMIDISTRM_16(hMidiStrm32);
1111 /**************************************************************************
1112 * midiStreamOut [MMSYSTEM.254]
1114 MMRESULT16 WINAPI midiStreamOut16(HMIDISTRM16 hMidiStrm, LPMIDIHDR16 lpMidiHdr, UINT16 cbMidiHdr)
1116 return midiStreamOut(HMIDISTRM_32(hMidiStrm), (LPMIDIHDR)lpMidiHdr,
1120 /**************************************************************************
1121 * midiStreamPause [MMSYSTEM.255]
1123 MMRESULT16 WINAPI midiStreamPause16(HMIDISTRM16 hMidiStrm)
1125 return midiStreamPause(HMIDISTRM_32(hMidiStrm));
1128 /**************************************************************************
1129 * midiStreamPosition [MMSYSTEM.253]
1131 MMRESULT16 WINAPI midiStreamPosition16(HMIDISTRM16 hMidiStrm, LPMMTIME16 lpmmt16, UINT16 cbmmt)
1137 return MMSYSERR_INVALPARAM;
1138 MMSYSTEM_MMTIME16to32(&mmt32, lpmmt16);
1139 ret = midiStreamPosition(HMIDISTRM_32(hMidiStrm), &mmt32, sizeof(MMTIME));
1140 MMSYSTEM_MMTIME32to16(lpmmt16, &mmt32);
1144 /**************************************************************************
1145 * midiStreamProperty [MMSYSTEM.250]
1147 MMRESULT16 WINAPI midiStreamProperty16(HMIDISTRM16 hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
1149 return midiStreamProperty(HMIDISTRM_32(hMidiStrm), lpPropData, dwProperty);
1152 /**************************************************************************
1153 * midiStreamRestart [MMSYSTEM.256]
1155 MMRESULT16 WINAPI midiStreamRestart16(HMIDISTRM16 hMidiStrm)
1157 return midiStreamRestart(HMIDISTRM_32(hMidiStrm));
1160 /**************************************************************************
1161 * midiStreamStop [MMSYSTEM.257]
1163 MMRESULT16 WINAPI midiStreamStop16(HMIDISTRM16 hMidiStrm)
1165 return midiStreamStop(HMIDISTRM_32(hMidiStrm));
1168 /* ###################################################
1170 * ###################################################
1173 /**************************************************************************
1174 * waveOutGetNumDevs [MMSYSTEM.401]
1176 UINT16 WINAPI waveOutGetNumDevs16(void)
1178 return MMDRV_GetNum(MMDRV_WAVEOUT);
1181 /**************************************************************************
1182 * waveOutGetDevCaps [MMSYSTEM.402]
1184 UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID,
1185 LPWAVEOUTCAPS16 lpCaps, UINT16 uSize)
1190 TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
1191 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1193 ret = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(wocA));
1195 if (ret == MMSYSERR_NOERROR) {
1196 lpCaps->wMid = wocA.wMid;
1197 lpCaps->wPid = wocA.wPid;
1198 lpCaps->vDriverVersion = wocA.vDriverVersion;
1199 strcpy(lpCaps->szPname, wocA.szPname);
1200 lpCaps->dwFormats = wocA.dwFormats;
1201 lpCaps->wChannels = wocA.wChannels;
1202 lpCaps->dwSupport = wocA.dwSupport;
1207 /**************************************************************************
1208 * waveOutGetErrorText [MMSYSTEM.403]
1210 UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
1212 return waveOutGetErrorTextA(uError, lpText, uSize);
1215 /**************************************************************************
1216 * waveOutOpen [MMSYSTEM.404]
1218 UINT16 WINAPI waveOutOpen16(HWAVEOUT16* lphWaveOut, UINT16 uDeviceID,
1219 const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
1220 DWORD dwInstance, DWORD dwFlags)
1225 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1226 * call the 32 bit version
1227 * however, we need to promote correctly the wave mapper id
1228 * (0xFFFFFFFF and not 0x0000FFFF)
1230 ret = WAVE_Open(&hWaveOut, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1231 MMDRV_WAVEOUT, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1233 if (lphWaveOut != NULL) *lphWaveOut = HWAVEOUT_16(hWaveOut);
1237 /**************************************************************************
1238 * waveOutClose [MMSYSTEM.405]
1240 UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
1245 ReleaseThunkLock(&level);
1246 ret = waveOutClose(HWAVEOUT_32(hWaveOut));
1247 RestoreThunkLock(level);
1251 /**************************************************************************
1252 * waveOutPrepareHeader [MMSYSTEM.406]
1254 UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
1255 SEGPTR lpsegWaveOutHdr, /* [???] */
1256 UINT16 uSize) /* [in] */
1259 LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1261 TRACE("(%04X, %08lx, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1263 if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM;
1265 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1266 return MMSYSERR_INVALHANDLE;
1268 return MMDRV_Message(wmld, WODM_PREPARE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
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, %08lx, %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, (DWORD)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)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)
1436 TRACE("(%04X, %p);\n", hWaveOut, lpuDeviceID);
1438 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1440 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1441 return MMSYSERR_INVALHANDLE;
1443 *lpuDeviceID = wmld->uDeviceID;
1447 /**************************************************************************
1448 * waveOutMessage [MMSYSTEM.421]
1450 DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage,
1451 DWORD dwParam1, DWORD dwParam2)
1455 TRACE("(%04x, %u, %ld, %ld)\n", hWaveOut, uMessage, dwParam1, dwParam2);
1457 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) {
1458 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, TRUE)) != NULL) {
1459 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1461 return MMSYSERR_INVALHANDLE;
1465 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1466 return MMSYSERR_INVALPARAM;
1468 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1471 /**************************************************************************
1472 * waveInGetNumDevs [MMSYSTEM.501]
1474 UINT16 WINAPI waveInGetNumDevs16(void)
1476 return MMDRV_GetNum(MMDRV_WAVEIN);
1479 /**************************************************************************
1480 * waveInGetDevCaps [MMSYSTEM.502]
1482 UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps,
1486 UINT ret = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(wicA));
1488 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1490 if (ret == MMSYSERR_NOERROR) {
1491 lpCaps->wMid = wicA.wMid;
1492 lpCaps->wPid = wicA.wPid;
1493 lpCaps->vDriverVersion = wicA.vDriverVersion;
1494 strcpy(lpCaps->szPname, wicA.szPname);
1495 lpCaps->dwFormats = wicA.dwFormats;
1496 lpCaps->wChannels = wicA.wChannels;
1501 /**************************************************************************
1502 * waveInGetErrorText [MMSYSTEM.503]
1504 UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
1506 return waveInGetErrorTextA(uError, lpText, uSize);
1509 /**************************************************************************
1510 * waveInOpen [MMSYSTEM.504]
1512 UINT16 WINAPI waveInOpen16(HWAVEIN16* lphWaveIn, UINT16 uDeviceID,
1513 const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
1514 DWORD dwInstance, DWORD dwFlags)
1519 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1520 * call the 32 bit version
1521 * however, we need to promote correctly the wave mapper id
1522 * (0xFFFFFFFF and not 0x0000FFFF)
1524 ret = WAVE_Open(&hWaveIn, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1525 MMDRV_WAVEIN, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1527 if (lphWaveIn != NULL) *lphWaveIn = HWAVEIN_16(hWaveIn);
1531 /**************************************************************************
1532 * waveInClose [MMSYSTEM.505]
1534 UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
1539 ReleaseThunkLock(&level);
1540 ret = waveInClose(HWAVEIN_32(hWaveIn));
1541 RestoreThunkLock(level);
1545 /**************************************************************************
1546 * waveInPrepareHeader [MMSYSTEM.506]
1548 UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1549 SEGPTR lpsegWaveInHdr, /* [???] */
1550 UINT16 uSize) /* [in] */
1553 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1556 TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
1558 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1559 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1560 return MMSYSERR_INVALHANDLE;
1562 lpWaveInHdr->dwBytesRecorded = 0;
1564 ret = MMDRV_Message(wmld, WIDM_PREPARE, (DWORD)lpsegWaveInHdr, uSize, FALSE);
1568 /**************************************************************************
1569 * waveInUnprepareHeader [MMSYSTEM.507]
1571 UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1572 SEGPTR lpsegWaveInHdr, /* [???] */
1573 UINT16 uSize) /* [in] */
1576 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1578 TRACE("(%04X, %08lx, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1580 if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1582 if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) {
1583 return MMSYSERR_NOERROR;
1586 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1587 return MMSYSERR_INVALHANDLE;
1589 return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpsegWaveInHdr, uSize, FALSE);
1592 /**************************************************************************
1593 * waveInAddBuffer [MMSYSTEM.508]
1595 UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn, /* [in] */
1596 WAVEHDR* lpsegWaveInHdr, /* [???] NOTE: SEGPTR */
1597 UINT16 uSize) /* [in] */
1601 TRACE("(%04X, %p, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1603 if (lpsegWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1604 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1605 return MMSYSERR_INVALHANDLE;
1607 return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD)lpsegWaveInHdr, uSize, FALSE);
1610 /**************************************************************************
1611 * waveInReset [MMSYSTEM.511]
1613 UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn16)
1618 ReleaseThunkLock(&level);
1619 ret = waveInReset(HWAVEIN_32(hWaveIn16));
1620 RestoreThunkLock(level);
1624 /**************************************************************************
1625 * waveInStart [MMSYSTEM.509]
1627 UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn16)
1632 ReleaseThunkLock(&level);
1633 ret = waveInStart(HWAVEIN_32(hWaveIn16));
1634 RestoreThunkLock(level);
1638 /**************************************************************************
1639 * waveInStop [MMSYSTEM.510]
1641 UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn16)
1646 ReleaseThunkLock(&level);
1647 ret = waveInStop(HWAVEIN_32(hWaveIn16));
1648 RestoreThunkLock(level);
1652 /**************************************************************************
1653 * waveInGetPosition [MMSYSTEM.512]
1655 UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn, LPMMTIME16 lpTime,
1661 mmt.wType = lpTime->wType;
1662 ret = waveInGetPosition(HWAVEIN_32(hWaveIn), &mmt, sizeof(mmt));
1663 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1667 /**************************************************************************
1668 * waveInGetID [MMSYSTEM.513]
1670 UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16* lpuDeviceID)
1674 TRACE("(%04X, %p);\n", hWaveIn, lpuDeviceID);
1676 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1678 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1679 return MMSYSERR_INVALHANDLE;
1681 *lpuDeviceID = wmld->uDeviceID;
1682 return MMSYSERR_NOERROR;
1685 /**************************************************************************
1686 * waveInMessage [MMSYSTEM.514]
1688 DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
1689 DWORD dwParam1, DWORD dwParam2)
1693 TRACE("(%04x, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2);
1696 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1697 return MMSYSERR_INVALPARAM;
1699 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1700 return MMSYSERR_INVALHANDLE;
1702 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
1705 /* ###################################################
1707 * ###################################################
1710 /*#define USE_MM_TSK_WINE*/
1712 /**************************************************************************
1713 * mmTaskCreate [MMSYSTEM.900]
1715 * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be
1716 * called upon creation with dwPmt as parameter.
1718 HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD dwPmt)
1723 DWORD showCmd = 0x40002;
1726 TRACE("(%08lx, %p, %08lx);\n", spProc, lphMmTask, dwPmt);
1727 /* This to work requires NE modules to be started with a binary command line
1728 * which is not currently the case. A patch exists but has never been committed.
1729 * A workaround would be to integrate code for mmtask.tsk into Wine, but
1730 * this requires tremendous work (starting with patching tools/build to
1731 * create NE executables (and not only DLLs) for builtins modules.
1734 FIXME("This is currently broken. It will fail\n");
1737 *(LPDWORD)(cmdline + 1) = (DWORD)spProc;
1738 *(LPDWORD)(cmdline + 5) = dwPmt;
1739 *(LPDWORD)(cmdline + 9) = 0;
1741 lp.hEnvironment = 0;
1742 lp.cmdLine = MapLS(cmdline);
1743 lp.showCmd = MapLS(&showCmd);
1746 #ifndef USE_MM_TSK_WINE
1747 handle = LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp);
1749 handle = LoadModule16("mmtask.tsk", &lp);
1752 ret = (handle) ? 1 : 2;
1758 *lphMmTask = handle;
1760 UnMapLS( lp.cmdLine );
1761 UnMapLS( lp.showCmd );
1762 TRACE("=> 0x%04x/%d\n", handle, ret);
1766 #ifdef USE_MM_TSK_WINE
1767 /* C equivalent to mmtask.tsk binary content */
1768 void mmTaskEntryPoint16(LPSTR cmdLine, WORD di, WORD si)
1770 int len = cmdLine[0x80];
1773 void (*fpProc)(DWORD) = MapSL(*((DWORD*)(cmdLine + 1)));
1774 DWORD dwPmt = *((DWORD*)(cmdLine + 5));
1777 InitTask16(); /* FIXME: pmts / from context ? */
1780 if (SetMessageQueue16(0x40)) {
1782 if (HIWORD(fpProc)) {
1784 /* EPP StackEnter16(); */
1796 /**************************************************************************
1797 * mmTaskBlock [MMSYSTEM.902]
1799 void WINAPI mmTaskBlock16(HINSTANCE16 WINE_UNUSED hInst)
1804 GetMessageA(&msg, 0, 0, 0);
1806 TranslateMessage(&msg);
1807 DispatchMessageA(&msg);
1809 } while (msg.message < 0x3A0);
1812 /**************************************************************************
1813 * mmTaskSignal [MMSYSTEM.903]
1815 LRESULT WINAPI mmTaskSignal16(HTASK16 ht)
1817 TRACE("(%04x);\n", ht);
1818 return PostThreadMessageW( HTASK_32(ht), WM_USER, 0, 0 );
1821 /**************************************************************************
1822 * mmGetCurrentTask [MMSYSTEM.904]
1824 HTASK16 WINAPI mmGetCurrentTask16(void)
1826 return GetCurrentTask();
1829 /**************************************************************************
1830 * mmTaskYield [MMSYSTEM.905]
1832 void WINAPI mmTaskYield16(void)
1836 if (PeekMessageA(&msg, 0, 0, 0, 0)) {
1841 extern DWORD WINAPI GetProcessFlags(DWORD);
1843 /******************************************************************
1848 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16 h)
1850 return (WINE_MMTHREAD*)MapSL( MAKESEGPTR(h, 0) );
1853 void WINAPI WINE_mmThreadEntryPoint(DWORD);
1855 /**************************************************************************
1856 * mmThreadCreate [MMSYSTEM.1120]
1859 * Creates a MM thread, calling fpThreadAddr(dwPmt).
1861 * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc
1862 * bit.1 set means to open a VxD for this thread (unsupported)
1864 LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags)
1869 TRACE("(%p, %p, %08lx, %08lx)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags);
1871 hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT);
1876 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1879 /* force mmtask routines even if mmthread is required */
1880 /* this will work only if the patch about binary cmd line and NE tasks
1886 lpMMThd->dwSignature = WINE_MMTHREAD_CREATED;
1887 lpMMThd->dwCounter = 0;
1888 lpMMThd->hThread = 0;
1889 lpMMThd->dwThreadID = 0;
1890 lpMMThd->fpThread = fpThreadAddr;
1891 lpMMThd->dwThreadPmt = dwPmt;
1892 lpMMThd->dwSignalCount = 0;
1893 lpMMThd->hEvent = 0;
1895 lpMMThd->dwStatus = 0;
1896 lpMMThd->dwFlags = dwFlags;
1899 if ((dwFlags & 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) {
1900 lpMMThd->hEvent = CreateEventA(0, 0, 1, 0);
1902 TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd);
1903 if (lpMMThd->dwFlags & 2) {
1904 /* as long as we don't support MM VxD in wine, we don't need
1905 * to care about this flag
1907 /* FIXME("Don't know how to properly open VxD handles\n"); */
1908 /* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */
1911 lpMMThd->hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)WINE_mmThreadEntryPoint,
1912 (LPVOID)(DWORD)hndl, CREATE_SUSPENDED, &lpMMThd->dwThreadID);
1913 if (lpMMThd->hThread == 0) {
1914 WARN("Couldn't create thread\n");
1915 /* clean-up(VxDhandle...); devicedirectio... */
1916 if (lpMMThd->hEvent != 0)
1917 CloseHandle(lpMMThd->hEvent);
1920 TRACE("Got a nice thread hndl=%p id=0x%08lx\n", lpMMThd->hThread, lpMMThd->dwThreadID);
1924 /* get WINE_mmThreadEntryPoint()
1925 * 2047 is its ordinal in mmsystem.spec
1927 FARPROC16 fp = GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR)2047);
1929 TRACE("farproc seg=0x%08lx lin=%p\n", (DWORD)fp, MapSL((SEGPTR)fp));
1931 ret = (fp == 0) ? 2 : mmTaskCreate16((DWORD)fp, 0, hndl);
1935 if (lpMMThd->hThread && !ResumeThread(lpMMThd->hThread))
1936 WARN("Couldn't resume thread\n");
1938 while (lpMMThd->dwStatus != 0x10) { /* test also HIWORD of dwStatus */
1952 TRACE("ok => %ld\n", ret);
1956 /**************************************************************************
1957 * mmThreadSignal [MMSYSTEM.1121]
1959 void WINAPI mmThreadSignal16(HANDLE16 hndl)
1961 TRACE("(%04x)!\n", hndl);
1964 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1966 lpMMThd->dwCounter++;
1967 if (lpMMThd->hThread != 0) {
1968 InterlockedIncrement(&lpMMThd->dwSignalCount);
1969 SetEvent(lpMMThd->hEvent);
1971 mmTaskSignal16(lpMMThd->hTask);
1973 lpMMThd->dwCounter--;
1977 static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd)
1982 if (lpMMThd->dwThreadID != GetCurrentThreadId())
1983 ERR("Not called by thread itself\n");
1986 ResetEvent(lpMMThd->hEvent);
1987 if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0)
1989 InterlockedIncrement(&lpMMThd->dwSignalCount);
1993 ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT);
1995 case WAIT_OBJECT_0: /* Event */
1998 case WAIT_OBJECT_0 + 1: /* Msg */
2000 if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
2001 TranslateMessage(&msg);
2002 DispatchMessageA(&msg);
2006 WARN("S2.x unsupported ret val 0x%08lx\n", ret);
2012 /**************************************************************************
2013 * mmThreadBlock [MMSYSTEM.1122]
2015 void WINAPI mmThreadBlock16(HANDLE16 hndl)
2017 TRACE("(%04x)!\n", hndl);
2020 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2022 if (lpMMThd->hThread != 0) {
2025 ReleaseThunkLock(&lc);
2026 MMSYSTEM_ThreadBlock(lpMMThd);
2027 RestoreThunkLock(lc);
2029 mmTaskBlock16(lpMMThd->hTask);
2035 /**************************************************************************
2036 * mmThreadIsCurrent [MMSYSTEM.1123]
2038 BOOL16 WINAPI mmThreadIsCurrent16(HANDLE16 hndl)
2042 TRACE("(%04x)!\n", hndl);
2044 if (hndl && mmThreadIsValid16(hndl)) {
2045 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2046 ret = (GetCurrentThreadId() == lpMMThd->dwThreadID);
2048 TRACE("=> %d\n", ret);
2052 /**************************************************************************
2053 * mmThreadIsValid [MMSYSTEM.1124]
2055 BOOL16 WINAPI mmThreadIsValid16(HANDLE16 hndl)
2059 TRACE("(%04x)!\n", hndl);
2062 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2064 if (!IsBadWritePtr(lpMMThd, sizeof(WINE_MMTHREAD)) &&
2065 lpMMThd->dwSignature == WINE_MMTHREAD_CREATED &&
2066 IsTask16(lpMMThd->hTask)) {
2067 lpMMThd->dwCounter++;
2068 if (lpMMThd->hThread != 0) {
2070 if (GetExitCodeThread(lpMMThd->hThread, &dwThreadRet) &&
2071 dwThreadRet == STATUS_PENDING) {
2077 lpMMThd->dwCounter--;
2080 TRACE("=> %d\n", ret);
2084 /**************************************************************************
2085 * mmThreadGetTask [MMSYSTEM.1125]
2087 HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl)
2091 TRACE("(%04x)\n", hndl);
2093 if (mmThreadIsValid16(hndl)) {
2094 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2095 ret = lpMMThd->hTask;
2100 /**************************************************************************
2101 * __wine_mmThreadEntryPoint (MMSYSTEM.2047)
2103 void WINAPI WINE_mmThreadEntryPoint(DWORD _pmt)
2105 HANDLE16 hndl = (HANDLE16)_pmt;
2106 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2108 TRACE("(%04x %p)\n", hndl, lpMMThd);
2110 lpMMThd->hTask = LOWORD(GetCurrentTask());
2111 TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask);
2112 lpMMThd->dwStatus = 0x10;
2113 MMSYSTEM_ThreadBlock(lpMMThd);
2114 TRACE("[20-%p]\n", lpMMThd->hThread);
2115 lpMMThd->dwStatus = 0x20;
2116 if (lpMMThd->fpThread) {
2117 MMSYSTEM_CallTo16_long_l(lpMMThd->fpThread, lpMMThd->dwThreadPmt);
2119 lpMMThd->dwStatus = 0x30;
2120 TRACE("[30-%p]\n", lpMMThd->hThread);
2121 while (lpMMThd->dwCounter) {
2123 /* K32WOWYield16();*/
2125 TRACE("[XX-%p]\n", lpMMThd->hThread);
2127 lpMMThd->dwSignature = WINE_MMTHREAD_DELETED;
2128 /* close lpMMThread->hVxD directIO */
2129 if (lpMMThd->hEvent)
2130 CloseHandle(lpMMThd->hEvent);
2135 typedef BOOL16 (WINAPI *MMCPLCALLBACK)(HWND, LPCSTR, LPCSTR, LPCSTR);
2137 /**************************************************************************
2138 * mmShowMMCPLPropertySheet [MMSYSTEM.1150]
2140 BOOL16 WINAPI mmShowMMCPLPropertySheet16(HWND hWnd, LPCSTR lpStrDevice,
2141 LPCSTR lpStrTab, LPCSTR lpStrTitle)
2146 TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2148 hndl = LoadLibraryA("MMSYS.CPL");
2150 MMCPLCALLBACK fp = (MMCPLCALLBACK)GetProcAddress(hndl, "ShowMMCPLPropertySheet");
2153 ReleaseThunkLock(&lc);
2154 ret = (fp)(hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2155 RestoreThunkLock(lc);
2163 /**************************************************************************
2164 * StackEnter [MMSYSTEM.32]
2166 void WINAPI StackEnter16(void)
2169 /* mmsystem.dll from Win 95 does only this: so does Wine */
2174 /**************************************************************************
2175 * StackLeave [MMSYSTEM.33]
2177 void WINAPI StackLeave16(void)
2180 /* mmsystem.dll from Win 95 does only this: so does Wine */
2185 /**************************************************************************
2186 * WMMMidiRunOnce [MMSYSTEM.8]
2188 void WINAPI WMMMidiRunOnce16(void)
2190 FIXME("(), stub!\n");
2193 /* ###################################################
2195 * ###################################################
2198 /**************************************************************************
2199 * DRIVER_MapMsg32To16 [internal]
2201 * Map a 32 bit driver message to a 16 bit driver message.
2203 static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
2205 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2212 case DRV_QUERYCONFIGURE:
2214 case DRV_EXITSESSION:
2215 case DRV_EXITAPPLICATION:
2217 case DRV_CLOSE: /* should be 0/0 */
2218 case DRV_OPEN: /* pass through */
2219 /* lParam1 and lParam2 are not used */
2224 /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
2225 * lParam2 is a pointer to DRVCONFIGINFO
2228 LPDRVCONFIGINFO16 dci16 = HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16) );
2229 LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
2234 dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
2236 if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCISectionName)) != NULL)
2238 dci16->lpszDCISectionName = MapLS( str1 );
2240 return WINMM_MAP_NOMEM;
2242 if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCIAliasName)) != NULL)
2244 dci16->lpszDCIAliasName = MapLS( str1 );
2246 return WINMM_MAP_NOMEM;
2249 return WINMM_MAP_NOMEM;
2251 *lParam2 = MapLS( dci16 );
2252 ret = WINMM_MAP_OKMEM;
2258 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2259 FIXME("Unknown message 0x%04x\n", wMsg);
2266 /**************************************************************************
2267 * DRIVER_UnMapMsg32To16 [internal]
2269 * UnMap a 32 bit driver message to a 16 bit driver message.
2271 static WINMM_MapType DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
2273 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2280 case DRV_QUERYCONFIGURE:
2282 case DRV_EXITSESSION:
2283 case DRV_EXITAPPLICATION:
2287 /* lParam1 and lParam2 are not used */
2291 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
2293 LPDRVCONFIGINFO16 dci16 = MapSL(lParam2);
2294 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCISectionName) );
2295 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCIAliasName) );
2297 UnMapLS( dci16->lpszDCISectionName );
2298 UnMapLS( dci16->lpszDCIAliasName );
2299 HeapFree( GetProcessHeap(), 0, dci16 );
2304 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2305 FIXME("Unknown message 0x%04x\n", wMsg);
2312 /**************************************************************************
2313 * DRIVER_TryOpenDriver16 [internal]
2315 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
2317 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCSTR fn, LPCSTR sn, LPARAM lParam2)
2319 LPWINE_DRIVER lpDrv = NULL;
2322 TRACE("(%s, %08lX);\n", debugstr_a(sn), lParam2);
2324 lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
2325 if (lpDrv == NULL) {cause = "OOM"; goto exit;}
2327 /* FIXME: shall we do some black magic here on sn ?
2328 * drivers32 => drivers
2332 lpDrv->d.d16.hDriver16 = OpenDriver16(fn, sn, lParam2);
2333 if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;}
2334 lpDrv->dwFlags = WINE_GDF_16BIT;
2336 TRACE("=> %p\n", lpDrv);
2339 HeapFree(GetProcessHeap(), 0, lpDrv);
2340 TRACE("Unable to load 16 bit module %s: %s\n", debugstr_a(fn), cause);
2344 /******************************************************************
2345 * DRIVER_SendMessage16
2349 static LRESULT DRIVER_SendMessage16(HDRVR16 hDrv16, UINT msg,
2350 LPARAM lParam1, LPARAM lParam2)
2355 TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
2356 hDrv16, msg, lParam1, lParam2);
2358 switch (map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) {
2359 case WINMM_MAP_OKMEM:
2361 ret = SendDriverMessage16(hDrv16, msg, lParam1, lParam2);
2362 if (map == WINMM_MAP_OKMEM)
2363 DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
2370 /******************************************************************
2371 * DRIVER_CloseDriver16
2375 static LRESULT DRIVER_CloseDriver16(HDRVR16 hDrv16, LPARAM lParam1, LPARAM lParam2)
2377 return CloseDriver16(hDrv16, lParam1, lParam2);
2380 /**************************************************************************
2381 * DrvOpen [MMSYSTEM.1100]
2383 HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
2385 return OpenDriver16(lpDriverName, lpSectionName, lParam);
2388 /**************************************************************************
2389 * DrvClose [MMSYSTEM.1101]
2391 LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
2393 return CloseDriver16(hDrv, lParam1, lParam2);
2396 /**************************************************************************
2397 * DrvSendMessage [MMSYSTEM.1102]
2399 LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
2402 return SendDriverMessage16(hDrv, msg, lParam1, lParam2);
2405 /**************************************************************************
2406 * DrvGetModuleHandle [MMSYSTEM.1103]
2408 HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
2410 return GetDriverModuleHandle16(hDrv);
2413 /**************************************************************************
2414 * DrvDefDriverProc [MMSYSTEM.1104]
2416 LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg,
2417 DWORD dwParam1, DWORD dwParam2)
2419 return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
2422 /**************************************************************************
2423 * DriverProc [MMSYSTEM.6]
2425 LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
2426 DWORD dwParam1, DWORD dwParam2)
2428 TRACE("dwDevID=%08lx hDrv=%04x wMsg=%04x dwParam1=%08lx dwParam2=%08lx\n",
2429 dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2431 return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2434 /* ###################################################
2436 * ###################################################
2439 /******************************************************************
2440 * MMSYSTEM_MMTIME32to16
2444 void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32)
2446 mmt16->wType = mmt32->wType;
2447 /* layout of rest is the same for 32/16,
2448 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2450 memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u));
2453 /******************************************************************
2454 * MMSYSTEM_MMTIME16to32
2458 void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16)
2460 mmt32->wType = mmt16->wType;
2461 /* layout of rest is the same for 32/16,
2462 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2464 memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u));
2467 /**************************************************************************
2468 * timeGetSystemTime [MMSYSTEM.601]
2470 MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
2472 TRACE("(%p, %u);\n", lpTime, wSize);
2474 if (wSize >= sizeof(*lpTime)) {
2475 lpTime->wType = TIME_MS;
2477 lpTime->u.ms = WINMM_IData->mmSysTimeMS;
2479 TRACE("=> %lu\n", lpTime->u.ms);
2485 /**************************************************************************
2486 * timeSetEvent [MMSYSTEM.602]
2488 MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc,
2489 DWORD dwUser, UINT16 wFlags)
2491 if (wFlags & WINE_TIMER_IS32)
2492 WARN("Unknown windows flag... wine internally used.. ooch\n");
2494 return TIME_SetEventInternal(wDelay, wResol, (FARPROC16)lpFunc,
2495 dwUser, wFlags & ~WINE_TIMER_IS32);
2498 /**************************************************************************
2499 * timeKillEvent [MMSYSTEM.603]
2501 MMRESULT16 WINAPI timeKillEvent16(UINT16 wID)
2503 return timeKillEvent(wID);
2506 /**************************************************************************
2507 * timeGetDevCaps [MMSYSTEM.604]
2509 MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize)
2514 TRACE("(%p, %u) !\n", lpCaps, wSize);
2516 ret = timeGetDevCaps(&caps, sizeof(caps));
2517 lpCaps->wPeriodMin = caps.wPeriodMin;
2518 lpCaps->wPeriodMax = caps.wPeriodMax;
2522 /**************************************************************************
2523 * timeBeginPeriod [MMSYSTEM.605]
2525 MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod)
2527 TRACE("(%u) !\n", wPeriod);
2529 return timeBeginPeriod(wPeriod);
2532 /**************************************************************************
2533 * timeEndPeriod [MMSYSTEM.606]
2535 MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod)
2537 TRACE("(%u) !\n", wPeriod);
2539 return timeEndPeriod(wPeriod);
2542 /**************************************************************************
2543 * mciSendString [MMSYSTEM.702]
2545 DWORD WINAPI mciSendString16(LPCSTR lpstrCommand, LPSTR lpstrRet,
2546 UINT16 uRetLen, HWND16 hwndCallback)
2548 return mciSendStringA(lpstrCommand, lpstrRet, uRetLen, HWND_32(hwndCallback));
2551 /**************************************************************************
2552 * mciLoadCommandResource [MMSYSTEM.705]
2554 UINT16 WINAPI mciLoadCommandResource16(HINSTANCE16 hInst, LPCSTR resname, UINT16 type)
2556 LPCWSTR ptr = HEAP_strdupAtoW(GetProcessHeap(), 0, resname);
2557 UINT ret = mciLoadCommandResource(HINSTANCE_32(hInst), ptr, type);
2558 HeapFree(GetProcessHeap(), 0, (LPWSTR)ptr);
2562 /**************************************************************************
2563 * mciFreeCommandResource [MMSYSTEM.713]
2565 BOOL16 WINAPI mciFreeCommandResource16(UINT16 uTable)
2567 TRACE("(%04x)!\n", uTable);
2569 return mciFreeCommandResource(uTable);
2572 /* ###################################################
2574 * ###################################################
2577 /****************************************************************
2578 * MMIO_Map32To16 [INTERNAL]
2580 static LRESULT MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2)
2590 case MMIOM_WRITEFLUSH:
2591 *lp1 = MapLS( (void *)*lp1 );
2594 *lp1 = MapLS( (void *)*lp1 );
2595 *lp2 = MapLS( (void *)*lp2 );
2598 if (wMsg < MMIOM_USER)
2599 TRACE("Not a mappable message (%ld)\n", wMsg);
2601 return MMSYSERR_NOERROR;
2604 /****************************************************************
2605 * MMIO_UnMap32To16 [INTERNAL]
2607 static LRESULT MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2,
2608 LPARAM lp1, LPARAM lp2)
2618 case MMIOM_WRITEFLUSH:
2626 if (wMsg < MMIOM_USER)
2627 TRACE("Not a mappable message (%ld)\n", wMsg);
2629 return MMSYSERR_NOERROR;
2632 /******************************************************************
2637 static LRESULT MMIO_Callback16(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage,
2638 LPARAM lParam1, LPARAM lParam2)
2641 MMIOINFO16 mmioInfo16;
2642 SEGPTR segmmioInfo16;
2643 LPARAM lp1 = lParam1, lp2 = lParam2;
2645 memset(&mmioInfo16, 0, sizeof(MMIOINFO16));
2646 mmioInfo16.lDiskOffset = lpmmioinfo->lDiskOffset;
2647 mmioInfo16.adwInfo[0] = lpmmioinfo->adwInfo[0];
2648 mmioInfo16.adwInfo[1] = lpmmioinfo->adwInfo[1];
2649 mmioInfo16.adwInfo[2] = lpmmioinfo->adwInfo[2];
2650 mmioInfo16.adwInfo[3] = lpmmioinfo->adwInfo[3];
2651 /* map (lParam1, lParam2) into (lp1, lp2) 32=>16 */
2652 if ((result = MMIO_Map32To16(uMessage, &lp1, &lp2)) != MMSYSERR_NOERROR)
2655 segmmioInfo16 = MapLS(&mmioInfo16);
2657 result = MMSYSTEM_CallTo16_long_lwll((LPMMIOPROC16)cb16, segmmioInfo16, uMessage, lp1, lp2);
2658 UnMapLS(segmmioInfo16);
2659 MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2);
2661 lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset;
2662 lpmmioinfo->adwInfo[0] = mmioInfo16.adwInfo[0];
2663 lpmmioinfo->adwInfo[1] = mmioInfo16.adwInfo[1];
2664 lpmmioinfo->adwInfo[2] = mmioInfo16.adwInfo[2];
2665 lpmmioinfo->adwInfo[3] = mmioInfo16.adwInfo[3];
2670 /******************************************************************
2671 * MMIO_ResetSegmentedData
2674 static LRESULT MMIO_SetSegmentedBuffer(HMMIO hmmio, SEGPTR ptr)
2678 if ((wm = MMIO_Get(hmmio)) == NULL)
2679 return MMSYSERR_INVALHANDLE;
2680 wm->segBuffer16 = ptr;
2681 return MMSYSERR_NOERROR;
2684 /**************************************************************************
2685 * mmioOpen [MMSYSTEM.1210]
2687 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16,
2695 memset(&mmioinfo, 0, sizeof(mmioinfo));
2697 mmioinfo.dwFlags = lpmmioinfo16->dwFlags;
2698 mmioinfo.fccIOProc = lpmmioinfo16->fccIOProc;
2699 mmioinfo.pIOProc = (LPMMIOPROC)lpmmioinfo16->pIOProc;
2700 mmioinfo.cchBuffer = lpmmioinfo16->cchBuffer;
2701 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo16->pchBuffer);
2702 mmioinfo.adwInfo[0] = lpmmioinfo16->adwInfo[0];
2703 /* if we don't have a file name, it's likely a passed open file descriptor */
2705 mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]);
2706 mmioinfo.adwInfo[1] = lpmmioinfo16->adwInfo[1];
2707 mmioinfo.adwInfo[2] = lpmmioinfo16->adwInfo[2];
2708 mmioinfo.adwInfo[3] = lpmmioinfo16->adwInfo[3];
2710 ret = MMIO_Open(szFileName, &mmioinfo, dwOpenFlags, MMIO_PROC_16);
2711 MMIO_SetSegmentedBuffer(mmioinfo.hmmio, (SEGPTR)lpmmioinfo16->pchBuffer);
2713 lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet;
2714 lpmmioinfo16->hmmio = HMMIO_16(mmioinfo.hmmio);
2716 ret = MMIO_Open(szFileName, NULL, dwOpenFlags, MMIO_PROC_32A);
2718 return HMMIO_16(ret);
2721 /**************************************************************************
2722 * mmioClose [MMSYSTEM.1211]
2724 MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
2726 return mmioClose(HMMIO_32(hmmio), uFlags);
2729 /**************************************************************************
2730 * mmioRead [MMSYSTEM.1212]
2732 LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
2734 return mmioRead(HMMIO_32(hmmio), pch, cch);
2737 /**************************************************************************
2738 * mmioWrite [MMSYSTEM.1213]
2740 LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
2742 return mmioWrite(HMMIO_32(hmmio),pch,cch);
2745 /**************************************************************************
2746 * mmioSeek [MMSYSTEM.1214]
2748 LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
2750 return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin);
2753 /**************************************************************************
2754 * mmioGetInfo [MMSYSTEM.1215]
2756 MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2762 TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags);
2764 if ((wm = MMIO_Get(HMMIO_32(hmmio))) == NULL)
2765 return MMSYSERR_INVALHANDLE;
2767 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
2768 if (ret != MMSYSERR_NOERROR) return ret;
2770 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
2771 lpmmioinfo->fccIOProc = mmioinfo.fccIOProc;
2772 lpmmioinfo->pIOProc = (wm->ioProc->type == MMIO_PROC_16) ?
2773 (LPMMIOPROC16)wm->ioProc->pIOProc : NULL;
2774 lpmmioinfo->wErrorRet = mmioinfo.wErrorRet;
2775 lpmmioinfo->hTask = HTASK_16(mmioinfo.hTask);
2776 lpmmioinfo->cchBuffer = mmioinfo.cchBuffer;
2777 lpmmioinfo->pchBuffer = (void*)wm->segBuffer16;
2778 lpmmioinfo->pchNext = (void*)(wm->segBuffer16 + (mmioinfo.pchNext - mmioinfo.pchBuffer));
2779 lpmmioinfo->pchEndRead = (void*)(wm->segBuffer16 + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
2780 lpmmioinfo->pchEndWrite = (void*)(wm->segBuffer16 + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
2781 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
2782 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
2783 lpmmioinfo->adwInfo[0] = mmioinfo.adwInfo[0];
2784 lpmmioinfo->adwInfo[1] = mmioinfo.adwInfo[1];
2785 lpmmioinfo->adwInfo[2] = mmioinfo.adwInfo[2];
2786 lpmmioinfo->adwInfo[3] = mmioinfo.adwInfo[3];
2787 lpmmioinfo->dwReserved1 = 0;
2788 lpmmioinfo->dwReserved2 = 0;
2789 lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio);
2791 return MMSYSERR_NOERROR;
2794 /**************************************************************************
2795 * mmioSetInfo [MMSYSTEM.1216]
2797 MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2802 TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
2804 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0);
2805 if (ret != MMSYSERR_NOERROR) return ret;
2807 /* check if seg and lin buffers are the same */
2808 if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer ||
2809 mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer))
2810 return MMSYSERR_INVALPARAM;
2812 /* check pointers coherence */
2813 if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer ||
2814 lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
2815 lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer ||
2816 lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
2817 lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer ||
2818 lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer)
2819 return MMSYSERR_INVALPARAM;
2821 mmioinfo.pchNext = mmioinfo.pchBuffer + (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer);
2822 mmioinfo.pchEndRead = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead - lpmmioinfo->pchBuffer);
2823 mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer);
2825 return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
2828 /**************************************************************************
2829 * mmioSetBuffer [MMSYSTEM.1217]
2831 MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, LPSTR pchBuffer,
2832 LONG cchBuffer, UINT16 uFlags)
2834 MMRESULT ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL((DWORD)pchBuffer),
2837 if (ret == MMSYSERR_NOERROR)
2838 MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), (DWORD)pchBuffer);
2842 /**************************************************************************
2843 * mmioFlush [MMSYSTEM.1218]
2845 MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
2847 return mmioFlush(HMMIO_32(hmmio), uFlags);
2850 /***********************************************************************
2851 * mmioAdvance [MMSYSTEM.1219]
2853 MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2858 /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which
2863 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer);
2864 mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext);
2865 mmioinfo.dwFlags = lpmmioinfo->dwFlags;
2866 mmioinfo.lBufOffset = lpmmioinfo->lBufOffset;
2867 ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags);
2870 ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags);
2872 if (ret != MMSYSERR_NOERROR) return ret;
2876 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
2877 lpmmioinfo->pchNext = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
2878 lpmmioinfo->pchEndRead = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
2879 lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
2880 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
2881 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
2884 return MMSYSERR_NOERROR;
2887 /**************************************************************************
2888 * mmioStringToFOURCC [MMSYSTEM.1220]
2890 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
2892 return mmioStringToFOURCCA(sz, uFlags);
2895 /**************************************************************************
2896 * mmioInstallIOProc [MMSYSTEM.1221]
2898 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc,
2901 return (LPMMIOPROC16)MMIO_InstallIOProc(fccIOProc, (LPMMIOPROC)pIOProc,
2902 dwFlags, MMIO_PROC_16);
2905 /**************************************************************************
2906 * mmioSendMessage [MMSYSTEM.1222]
2908 LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage,
2909 LPARAM lParam1, LPARAM lParam2)
2911 return MMIO_SendMessage(HMMIO_32(hmmio), uMessage,
2912 lParam1, lParam2, MMIO_PROC_16);
2915 /**************************************************************************
2916 * mmioDescend [MMSYSTEM.1223]
2918 MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck,
2919 const MMCKINFO* lpckParent, UINT16 uFlags)
2921 return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags);
2924 /**************************************************************************
2925 * mmioAscend [MMSYSTEM.1224]
2927 MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
2929 return mmioAscend(HMMIO_32(hmmio),lpck,uFlags);
2932 /**************************************************************************
2933 * mmioCreateChunk [MMSYSTEM.1225]
2935 MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
2937 return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags);
2940 /**************************************************************************
2941 * mmioRename [MMSYSTEM.1226]
2943 MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName,
2944 MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags)
2950 if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL &&
2951 lpmmioinfo->fccIOProc == 0) {
2952 FIXME("Can't handle this case yet\n");
2953 return MMSYSERR_ERROR;
2956 /* this is a bit hacky, but it'll work if we get a fourCC code or nothing.
2957 * but a non installed ioproc without a fourcc won't do
2959 if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) {
2960 MMIO_InstallIOProc(lpmmioinfo->fccIOProc, (LPMMIOPROC)lpmmioinfo->pIOProc,
2961 MMIO_INSTALLPROC, MMIO_PROC_16);
2964 memset(&mmioinfo, 0, sizeof(mmioinfo));
2965 mmioinfo.fccIOProc = lpmmioinfo->fccIOProc;
2966 ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags);
2968 MMIO_InstallIOProc(lpmmioinfo->fccIOProc, NULL,
2969 MMIO_REMOVEPROC, MMIO_PROC_16);
2974 /* ###################################################
2976 * ###################################################
2979 /**************************************************************************
2980 * joyGetNumDevs [MMSYSTEM.101]
2982 UINT16 WINAPI joyGetNumDevs16(void)
2984 return joyGetNumDevs();
2987 /**************************************************************************
2988 * joyGetDevCaps [MMSYSTEM.102]
2990 MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize)
2993 MMRESULT ret = joyGetDevCapsA(wID, &jca, sizeof(jca));
2995 if (ret != JOYERR_NOERROR) return ret;
2996 lpCaps->wMid = jca.wMid;
2997 lpCaps->wPid = jca.wPid;
2998 strcpy(lpCaps->szPname, jca.szPname);
2999 lpCaps->wXmin = jca.wXmin;
3000 lpCaps->wXmax = jca.wXmax;
3001 lpCaps->wYmin = jca.wYmin;
3002 lpCaps->wYmax = jca.wYmax;
3003 lpCaps->wZmin = jca.wZmin;
3004 lpCaps->wZmax = jca.wZmax;
3005 lpCaps->wNumButtons = jca.wNumButtons;
3006 lpCaps->wPeriodMin = jca.wPeriodMin;
3007 lpCaps->wPeriodMax = jca.wPeriodMax;
3009 if (wSize >= sizeof(JOYCAPS16)) { /* Win95 extensions ? */
3010 lpCaps->wRmin = jca.wRmin;
3011 lpCaps->wRmax = jca.wRmax;
3012 lpCaps->wUmin = jca.wUmin;
3013 lpCaps->wUmax = jca.wUmax;
3014 lpCaps->wVmin = jca.wVmin;
3015 lpCaps->wVmax = jca.wVmax;
3016 lpCaps->wCaps = jca.wCaps;
3017 lpCaps->wMaxAxes = jca.wMaxAxes;
3018 lpCaps->wNumAxes = jca.wNumAxes;
3019 lpCaps->wMaxButtons = jca.wMaxButtons;
3020 strcpy(lpCaps->szRegKey, jca.szRegKey);
3021 strcpy(lpCaps->szOEMVxD, jca.szOEMVxD);
3027 /**************************************************************************
3028 * joyGetPosEx [MMSYSTEM.110]
3030 MMRESULT16 WINAPI joyGetPosEx16(UINT16 wID, LPJOYINFOEX lpInfo)
3032 return joyGetPosEx(wID, lpInfo);
3035 /**************************************************************************
3036 * joyGetPos [MMSYSTEM.103]
3038 MMRESULT16 WINAPI joyGetPos16(UINT16 wID, LPJOYINFO16 lpInfo)
3043 TRACE("(%d, %p);\n", wID, lpInfo);
3045 if ((ret = joyGetPos(wID, &ji)) == JOYERR_NOERROR) {
3046 lpInfo->wXpos = ji.wXpos;
3047 lpInfo->wYpos = ji.wYpos;
3048 lpInfo->wZpos = ji.wZpos;
3049 lpInfo->wButtons = ji.wButtons;
3054 /**************************************************************************
3055 * joyGetThreshold [MMSYSTEM.104]
3057 MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold)
3062 ret = joyGetThreshold(wID, &t);
3063 if (ret == JOYERR_NOERROR)
3068 /**************************************************************************
3069 * joyReleaseCapture [MMSYSTEM.105]
3071 MMRESULT16 WINAPI joyReleaseCapture16(UINT16 wID)
3073 return joyReleaseCapture(wID);
3076 /**************************************************************************
3077 * joySetCapture [MMSYSTEM.106]
3079 MMRESULT16 WINAPI joySetCapture16(HWND16 hWnd, UINT16 wID, UINT16 wPeriod, BOOL16 bChanged)
3081 return joySetCapture16(hWnd, wID, wPeriod, bChanged);
3084 /**************************************************************************
3085 * joySetThreshold [MMSYSTEM.107]
3087 MMRESULT16 WINAPI joySetThreshold16(UINT16 wID, UINT16 wThreshold)
3089 return joySetThreshold16(wID,wThreshold);
3092 /**************************************************************************
3093 * joySetCalibration [MMSYSTEM.109]
3095 MMRESULT16 WINAPI joySetCalibration16(UINT16 wID)
3097 FIXME("(%04X): stub.\n", wID);
3098 return JOYERR_NOCANDO;