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
42 #include "wine/winuser16.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
50 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16);
51 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCSTR, LPCSTR, LPARAM);
52 static LRESULT DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM);
53 static LRESULT DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM);
54 static LRESULT MMIO_Callback16(SEGPTR, LPMMIOINFO, UINT, LPARAM, LPARAM);
56 #define HMODULE_32(h16) ((HMODULE)(ULONG_PTR)(h16))
57 #define HINSTANCE_32(h16) ((HMODULE)(ULONG_PTR)(h16))
59 /* ###################################################
61 * ###################################################
64 /**************************************************************************
65 * DllEntryPoint (MMSYSTEM.2046)
67 * MMSYSTEM DLL entry point
70 BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
71 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
73 TRACE("%p 0x%lx\n", hinstDLL, fdwReason);
76 case DLL_PROCESS_ATTACH:
77 /* need to load WinMM in order to:
78 * - initiate correctly shared variables (WINMM_Init())
80 if (!GetModuleHandleA("WINMM.DLL") && !LoadLibraryA("WINMM.DLL"))
82 ERR("Could not load sibling WinMM.dll\n");
85 WINMM_IData->hWinMM16Instance = hinstDLL;
86 /* hook in our 16 bit function pointers */
87 pFnGetMMThread16 = WINMM_GetmmThread;
88 pFnOpenDriver16 = DRIVER_OpenDriver16;
89 pFnCloseDriver16 = DRIVER_CloseDriver16;
90 pFnSendMessage16 = DRIVER_SendMessage16;
91 pFnMmioCallback16 = MMIO_Callback16;
94 case DLL_PROCESS_DETACH:
95 WINMM_IData->hWinMM16Instance = 0;
96 pFnGetMMThread16 = NULL;
97 pFnOpenDriver16 = NULL;
98 pFnCloseDriver16 = NULL;
99 pFnSendMessage16 = NULL;
100 pFnMmioCallback16 = NULL;
101 /* FIXME: add equivalent for MMDRV_Init16() */
103 case DLL_THREAD_ATTACH:
104 case DLL_THREAD_DETACH:
110 /**************************************************************************
111 * MMSYSTEM_WEP [MMSYSTEM.1]
113 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
114 WORD cbHeapSize, LPSTR lpCmdLine)
116 FIXME("STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
120 /* ###################################################
122 * ###################################################
125 /**************************************************************************
126 * PlaySound [MMSYSTEM.3]
128 BOOL16 WINAPI PlaySound16(LPCSTR pszSound, HMODULE16 hmod, DWORD fdwSound)
133 ReleaseThunkLock(&lc);
134 retv = PlaySoundA(pszSound, HMODULE_32(hmod), fdwSound);
135 RestoreThunkLock(lc);
140 /**************************************************************************
141 * sndPlaySound [MMSYSTEM.2]
143 BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags)
148 ReleaseThunkLock(&lc);
149 retv = sndPlaySoundA(lpszSoundName, uFlags);
150 RestoreThunkLock(lc);
155 /* ###################################################
157 * ###################################################
160 /**************************************************************************
161 * mmsystemGetVersion [MMSYSTEM.5]
164 UINT16 WINAPI mmsystemGetVersion16(void)
166 return mmsystemGetVersion();
169 /**************************************************************************
170 * DriverCallback [MMSYSTEM.31]
172 BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev,
173 WORD wMsg, DWORD dwUser, DWORD dwParam1,
176 return DriverCallback(dwCallBack, uFlags, HDRVR_32(hDev), wMsg, dwUser, dwParam1, dwParam2);
179 /**************************************************************************
180 * OutputDebugStr [MMSYSTEM.30]
182 void WINAPI OutputDebugStr16(LPCSTR str)
184 OutputDebugStringA( str );
188 /* ###################################################
190 * ###################################################
193 /**************************************************************************
194 * Mixer devices. New to Win95
197 /**************************************************************************
198 * mixerGetNumDevs [MMSYSTEM.800]
200 UINT16 WINAPI mixerGetNumDevs16(void)
202 return MMDRV_GetNum(MMDRV_MIXER);
205 /**************************************************************************
206 * mixerGetDevCaps [MMSYSTEM.801]
208 UINT16 WINAPI mixerGetDevCaps16(UINT16 devid, LPMIXERCAPS16 mixcaps,
212 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
214 if (ret == MMSYSERR_NOERROR) {
215 mixcaps->wMid = micA.wMid;
216 mixcaps->wPid = micA.wPid;
217 mixcaps->vDriverVersion = micA.vDriverVersion;
218 strcpy(mixcaps->szPname, micA.szPname);
219 mixcaps->fdwSupport = micA.fdwSupport;
220 mixcaps->cDestinations = micA.cDestinations;
225 /**************************************************************************
226 * mixerOpen [MMSYSTEM.802]
228 UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix, UINT16 uDeviceID, DWORD dwCallback,
229 DWORD dwInstance, DWORD fdwOpen)
234 ret = MIXER_Open(&hmix, uDeviceID, dwCallback, dwInstance, fdwOpen, FALSE);
235 if (lphmix) *lphmix = HMIXER_16(hmix);
239 /**************************************************************************
240 * mixerClose [MMSYSTEM.803]
242 UINT16 WINAPI mixerClose16(HMIXER16 hMix)
244 return mixerClose(HMIXER_32(hMix));
247 /**************************************************************************
248 * mixerGetID (MMSYSTEM.806)
250 UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID)
253 UINT ret = mixerGetID(HMIXEROBJ_32(hmix), &xid, fdwID);
260 /**************************************************************************
261 * mixerGetControlDetails [MMSYSTEM.808]
263 UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,
264 LPMIXERCONTROLDETAILS16 lpmcd,
267 DWORD ret = MMSYSERR_NOTENABLED;
270 TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);
272 if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
273 return MMSYSERR_INVALPARAM;
275 sppaDetails = (SEGPTR)lpmcd->paDetails;
276 lpmcd->paDetails = MapSL(sppaDetails);
277 ret = mixerGetControlDetailsA(HMIXEROBJ_32(hmix),
278 (LPMIXERCONTROLDETAILS)lpmcd, fdwDetails);
279 lpmcd->paDetails = (LPVOID)sppaDetails;
284 /**************************************************************************
285 * mixerGetLineControls [MMSYSTEM.807]
287 UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,
288 LPMIXERLINECONTROLS16 lpmlc16,
291 MIXERLINECONTROLSA mlcA;
294 LPMIXERCONTROL16 lpmc16;
296 TRACE("(%04x, %p, %08lx)\n", hmix, lpmlc16, fdwControls);
298 if (lpmlc16 == NULL || lpmlc16->cbStruct != sizeof(*lpmlc16) ||
299 lpmlc16->cbmxctrl != sizeof(MIXERCONTROL16))
300 return MMSYSERR_INVALPARAM;
302 mlcA.cbStruct = sizeof(mlcA);
303 mlcA.dwLineID = lpmlc16->dwLineID;
304 mlcA.u.dwControlID = lpmlc16->u.dwControlID;
305 mlcA.u.dwControlType = lpmlc16->u.dwControlType;
306 mlcA.cControls = lpmlc16->cControls;
307 mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
308 mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
309 mlcA.cControls * mlcA.cbmxctrl);
311 ret = mixerGetLineControlsA(HMIXEROBJ_32(hmix), &mlcA, fdwControls);
313 if (ret == MMSYSERR_NOERROR) {
314 lpmlc16->dwLineID = mlcA.dwLineID;
315 lpmlc16->u.dwControlID = mlcA.u.dwControlID;
316 lpmlc16->u.dwControlType = mlcA.u.dwControlType;
317 lpmlc16->cControls = mlcA.cControls;
319 lpmc16 = MapSL(lpmlc16->pamxctrl);
321 for (i = 0; i < mlcA.cControls; i++) {
322 lpmc16[i].cbStruct = sizeof(MIXERCONTROL16);
323 lpmc16[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
324 lpmc16[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
325 lpmc16[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
326 lpmc16[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
327 strcpy(lpmc16[i].szShortName, mlcA.pamxctrl[i].szShortName);
328 strcpy(lpmc16[i].szName, mlcA.pamxctrl[i].szName);
329 /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
330 memcpy(&lpmc16[i].Bounds, &mlcA.pamxctrl[i].Bounds,
331 sizeof(mlcA.pamxctrl[i].Bounds));
332 /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
333 memcpy(&lpmc16[i].Metrics, &mlcA.pamxctrl[i].Metrics,
334 sizeof(mlcA.pamxctrl[i].Metrics));
338 HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);
343 /**************************************************************************
344 * mixerGetLineInfo [MMSYSTEM.805]
346 UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16,
352 TRACE("(%04x, %p, %08lx)\n", hmix, lpmli16, fdwInfo);
354 if (lpmli16 == NULL || lpmli16->cbStruct != sizeof(*lpmli16))
355 return MMSYSERR_INVALPARAM;
357 mliA.cbStruct = sizeof(mliA);
358 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
359 case MIXER_GETLINEINFOF_COMPONENTTYPE:
360 mliA.dwComponentType = lpmli16->dwComponentType;
362 case MIXER_GETLINEINFOF_DESTINATION:
363 mliA.dwDestination = lpmli16->dwDestination;
365 case MIXER_GETLINEINFOF_LINEID:
366 mliA.dwLineID = lpmli16->dwLineID;
368 case MIXER_GETLINEINFOF_SOURCE:
369 mliA.dwDestination = lpmli16->dwDestination;
370 mliA.dwSource = lpmli16->dwSource;
372 case MIXER_GETLINEINFOF_TARGETTYPE:
373 mliA.Target.dwType = lpmli16->Target.dwType;
374 mliA.Target.wMid = lpmli16->Target.wMid;
375 mliA.Target.wPid = lpmli16->Target.wPid;
376 mliA.Target.vDriverVersion = lpmli16->Target.vDriverVersion;
377 strcpy(mliA.Target.szPname, lpmli16->Target.szPname);
380 FIXME("Unsupported fdwControls=0x%08lx\n", fdwInfo);
383 ret = mixerGetLineInfoA(HMIXEROBJ_32(hmix), &mliA, fdwInfo);
385 lpmli16->dwDestination = mliA.dwDestination;
386 lpmli16->dwSource = mliA.dwSource;
387 lpmli16->dwLineID = mliA.dwLineID;
388 lpmli16->fdwLine = mliA.fdwLine;
389 lpmli16->dwUser = mliA.dwUser;
390 lpmli16->dwComponentType = mliA.dwComponentType;
391 lpmli16->cChannels = mliA.cChannels;
392 lpmli16->cConnections = mliA.cConnections;
393 lpmli16->cControls = mliA.cControls;
394 strcpy(lpmli16->szShortName, mliA.szShortName);
395 strcpy(lpmli16->szName, mliA.szName);
396 lpmli16->Target.dwType = mliA.Target.dwType;
397 lpmli16->Target.dwDeviceID = mliA.Target.dwDeviceID;
398 lpmli16->Target.wMid = mliA.Target.wMid;
399 lpmli16->Target.wPid = mliA.Target.wPid;
400 lpmli16->Target.vDriverVersion = mliA.Target.vDriverVersion;
401 strcpy(lpmli16->Target.szPname, mliA.Target.szPname);
406 /**************************************************************************
407 * mixerSetControlDetails [MMSYSTEM.809]
409 UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,
410 LPMIXERCONTROLDETAILS16 lpmcd,
413 TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);
414 return MMSYSERR_NOTENABLED;
417 /**************************************************************************
418 * mixerMessage [MMSYSTEM.804]
420 DWORD WINAPI mixerMessage16(HMIXER16 hmix, UINT16 uMsg, DWORD dwParam1,
423 return mixerMessage(HMIXER_32(hmix), uMsg, dwParam1, dwParam2);
426 /**************************************************************************
427 * auxGetNumDevs [MMSYSTEM.350]
429 UINT16 WINAPI auxGetNumDevs16(void)
431 return MMDRV_GetNum(MMDRV_AUX);
434 /* ###################################################
436 * ###################################################
439 /**************************************************************************
440 * auxGetDevCaps [MMSYSTEM.351]
442 UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID, LPAUXCAPS16 lpCaps, UINT16 uSize)
446 TRACE("(%04X, %p, %d) !\n", uDeviceID, lpCaps, uSize);
448 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
449 return MMSYSERR_INVALHANDLE;
450 return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
453 /**************************************************************************
454 * auxGetVolume [MMSYSTEM.352]
456 UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, LPDWORD lpdwVolume)
460 TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
462 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
463 return MMSYSERR_INVALHANDLE;
464 return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE);
467 /**************************************************************************
468 * auxSetVolume [MMSYSTEM.353]
470 UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
474 TRACE("(%04X, %lu) !\n", uDeviceID, dwVolume);
476 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
477 return MMSYSERR_INVALHANDLE;
478 return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE);
481 /**************************************************************************
482 * auxOutMessage [MMSYSTEM.354]
484 DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
488 TRACE("(%04X, %04X, %08lX, %08lX)\n", uDeviceID, uMessage, dw1, dw2);
491 case AUXDM_GETNUMDEVS:
492 case AUXDM_SETVOLUME:
493 /* no argument conversion needed */
495 case AUXDM_GETVOLUME:
496 return auxGetVolume16(uDeviceID, MapSL(dw1));
497 case AUXDM_GETDEVCAPS:
498 return auxGetDevCaps16(uDeviceID, MapSL(dw1), dw2);
500 TRACE("(%04x, %04x, %08lx, %08lx): unhandled message\n",
501 uDeviceID, uMessage, dw1, dw2);
504 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
505 return MMSYSERR_INVALHANDLE;
507 return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE);
510 /* ###################################################
512 * ###################################################
515 /**************************************************************************
516 * mciGetErrorString [MMSYSTEM.706]
518 BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer, UINT16 uLength)
520 return mciGetErrorStringA(wError, lpstrBuffer, uLength);
523 /**************************************************************************
524 * mciDriverNotify [MMSYSTEM.711]
526 BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
528 TRACE("(%04X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
530 return PostMessageA(HWND_32(hWndCallBack), MM_MCINOTIFY, wStatus, wDevID);
533 /**************************************************************************
534 * mciGetDriverData [MMSYSTEM.708]
536 DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID)
538 return mciGetDriverData(uDeviceID);
541 /**************************************************************************
542 * mciSetDriverData [MMSYSTEM.707]
544 BOOL16 WINAPI mciSetDriverData16(UINT16 uDeviceID, DWORD data)
546 return mciSetDriverData(uDeviceID, data);
549 /**************************************************************************
550 * mciSendCommand [MMSYSTEM.701]
552 DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
556 TRACE("(%04X, %s, %08lX, %08lX)\n",
557 wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
559 dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, FALSE);
560 dwRet = MCI_CleanUp(dwRet, wMsg, (DWORD)MapSL(dwParam2));
561 TRACE("=> %ld\n", dwRet);
565 /**************************************************************************
566 * mciGetDeviceID [MMSYSTEM.703]
568 UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
570 TRACE("(\"%s\")\n", lpstrName);
572 return MCI_GetDriverFromString(lpstrName);
575 /**************************************************************************
576 * mciSetYieldProc [MMSYSTEM.714]
578 BOOL16 WINAPI mciSetYieldProc16(UINT16 uDeviceID, YIELDPROC16 fpYieldProc, DWORD dwYieldData)
580 LPWINE_MCIDRIVER wmd;
582 TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData);
584 if (!(wmd = MCI_GetDriver(uDeviceID))) {
585 WARN("Bad uDeviceID\n");
589 wmd->lpfnYieldProc = (YIELDPROC)fpYieldProc;
590 wmd->dwYieldData = dwYieldData;
596 /**************************************************************************
597 * mciGetDeviceIDFromElementID [MMSYSTEM.715]
599 UINT16 WINAPI mciGetDeviceIDFromElementID16(DWORD dwElementID, LPCSTR lpstrType)
601 FIXME("(%lu, %s) stub\n", dwElementID, lpstrType);
605 /**************************************************************************
606 * mciGetYieldProc [MMSYSTEM.716]
608 YIELDPROC16 WINAPI mciGetYieldProc16(UINT16 uDeviceID, DWORD* lpdwYieldData)
610 LPWINE_MCIDRIVER wmd;
612 TRACE("(%u, %p)\n", uDeviceID, lpdwYieldData);
614 if (!(wmd = MCI_GetDriver(uDeviceID))) {
615 WARN("Bad uDeviceID\n");
618 if (!wmd->lpfnYieldProc) {
619 WARN("No proc set\n");
623 WARN("Proc is 32 bit\n");
626 return (YIELDPROC16)wmd->lpfnYieldProc;
629 /**************************************************************************
630 * mciGetCreatorTask [MMSYSTEM.717]
632 HTASK16 WINAPI mciGetCreatorTask16(UINT16 uDeviceID)
634 LPWINE_MCIDRIVER wmd;
637 if ((wmd = MCI_GetDriver(uDeviceID)))
638 ret = HTASK_16(wmd->CreatorThread);
640 TRACE("(%u) => %04x\n", uDeviceID, ret);
644 /**************************************************************************
645 * mciDriverYield [MMSYSTEM.710]
647 UINT16 WINAPI mciDriverYield16(UINT16 uDeviceID)
649 LPWINE_MCIDRIVER wmd;
652 /* TRACE("(%04x)\n", uDeviceID); */
654 if (!(wmd = MCI_GetDriver(uDeviceID)) || !wmd->lpfnYieldProc || wmd->bIs32) {
657 ret = wmd->lpfnYieldProc(uDeviceID, wmd->dwYieldData);
663 /* ###################################################
665 * ###################################################
668 /**************************************************************************
669 * midiOutGetNumDevs [MMSYSTEM.201]
671 UINT16 WINAPI midiOutGetNumDevs16(void)
673 return MMDRV_GetNum(MMDRV_MIDIOUT);
676 /**************************************************************************
677 * midiOutGetDevCaps [MMSYSTEM.202]
679 UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID, LPMIDIOUTCAPS16 lpCaps,
685 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
687 dwRet = midiOutGetDevCapsA(uDeviceID, &capsA, sizeof(capsA));
688 if (dwRet == MMSYSERR_NOERROR) {
689 lpCaps->wMid = capsA.wMid;
690 lpCaps->wPid = capsA.wPid;
691 lpCaps->vDriverVersion = capsA.vDriverVersion;
692 strcpy(lpCaps->szPname, capsA.szPname);
693 lpCaps->wTechnology = capsA.wTechnology;
694 lpCaps->wVoices = capsA.wVoices;
695 lpCaps->wNotes = capsA.wNotes;
696 lpCaps->wChannelMask = capsA.wChannelMask;
697 lpCaps->dwSupport = capsA.dwSupport;
702 /**************************************************************************
703 * midiOutGetErrorText [MMSYSTEM.203]
705 UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
707 return midiOutGetErrorTextA(uError, lpText, uSize);
710 /**************************************************************************
711 * midiOutOpen [MMSYSTEM.204]
713 UINT16 WINAPI midiOutOpen16(HMIDIOUT16* lphMidiOut, UINT16 uDeviceID,
714 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
719 ret = MIDI_OutOpen(&hmo, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
721 if (lphMidiOut != NULL) *lphMidiOut = HMIDIOUT_16(hmo);
725 /**************************************************************************
726 * midiOutClose [MMSYSTEM.205]
728 UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
730 return midiOutClose(HMIDIOUT_32(hMidiOut));
733 /**************************************************************************
734 * midiOutPrepareHeader [MMSYSTEM.206]
736 UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
737 SEGPTR lpsegMidiOutHdr, /* [???] */
738 UINT16 uSize) /* [in] */
742 TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
744 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
745 return MMSYSERR_INVALHANDLE;
747 return MMDRV_Message(wmld, MODM_PREPARE, lpsegMidiOutHdr, uSize, FALSE);
750 /**************************************************************************
751 * midiOutUnprepareHeader [MMSYSTEM.207]
753 UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
754 SEGPTR lpsegMidiOutHdr, /* [???] */
755 UINT16 uSize) /* [in] */
758 LPMIDIHDR16 lpMidiOutHdr = MapSL(lpsegMidiOutHdr);
760 TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
762 if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
763 return MMSYSERR_NOERROR;
766 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
767 return MMSYSERR_INVALHANDLE;
769 return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpsegMidiOutHdr, uSize, FALSE);
772 /**************************************************************************
773 * midiOutShortMsg [MMSYSTEM.208]
775 UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
777 return midiOutShortMsg(HMIDIOUT_32(hMidiOut), dwMsg);
780 /**************************************************************************
781 * midiOutLongMsg [MMSYSTEM.209]
783 UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut, /* [in] */
784 LPMIDIHDR16 lpsegMidiOutHdr, /* [???] NOTE: SEGPTR */
785 UINT16 uSize) /* [in] */
789 TRACE("(%04X, %p, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
791 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
792 return MMSYSERR_INVALHANDLE;
794 return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD)lpsegMidiOutHdr, uSize, FALSE);
797 /**************************************************************************
798 * midiOutReset [MMSYSTEM.210]
800 UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
802 return midiOutReset(HMIDIOUT_32(hMidiOut));
805 /**************************************************************************
806 * midiOutGetVolume [MMSYSTEM.211]
808 UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD* lpdwVolume)
810 return midiOutGetVolume(HMIDIOUT_32(uDeviceID), lpdwVolume);
813 /**************************************************************************
814 * midiOutSetVolume [MMSYSTEM.212]
816 UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
818 return midiOutSetVolume(HMIDIOUT_32(uDeviceID), dwVolume);
821 /**************************************************************************
822 * midiOutCachePatches [MMSYSTEM.213]
824 UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
825 WORD* lpwPatchArray, UINT16 uFlags)
827 return midiOutCachePatches(HMIDIOUT_32(hMidiOut), uBank, lpwPatchArray,
831 /**************************************************************************
832 * midiOutCacheDrumPatches [MMSYSTEM.214]
834 UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
835 WORD* lpwKeyArray, UINT16 uFlags)
837 return midiOutCacheDrumPatches(HMIDIOUT_32(hMidiOut), uPatch, lpwKeyArray, uFlags);
840 /**************************************************************************
841 * midiOutGetID [MMSYSTEM.215]
843 UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16* lpuDeviceID)
847 TRACE("(%04X, %p)\n", hMidiOut, lpuDeviceID);
849 if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
850 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
851 return MMSYSERR_INVALHANDLE;
853 *lpuDeviceID = wmld->uDeviceID;
854 return MMSYSERR_NOERROR;
857 /**************************************************************************
858 * midiOutMessage [MMSYSTEM.216]
860 DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage,
861 DWORD dwParam1, DWORD dwParam2)
865 TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiOut, uMessage, dwParam1, dwParam2);
867 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
868 return MMSYSERR_INVALHANDLE;
873 FIXME("can't handle OPEN or CLOSE message!\n");
874 return MMSYSERR_NOTSUPPORTED;
877 return midiOutGetVolume16(hMidiOut, MapSL(dwParam1));
879 return midiOutLongMsg16(hMidiOut, MapSL(dwParam1), dwParam2);
881 /* lpMidiOutHdr is still a segmented pointer for this function */
882 return midiOutPrepareHeader16(hMidiOut, dwParam1, dwParam2);
884 return midiOutUnprepareHeader16(hMidiOut, dwParam1, dwParam2);
886 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
889 /**************************************************************************
890 * midiInGetNumDevs [MMSYSTEM.301]
892 UINT16 WINAPI midiInGetNumDevs16(void)
894 return MMDRV_GetNum(MMDRV_MIDIIN);
897 /**************************************************************************
898 * midiInGetDevCaps [MMSYSTEM.302]
900 UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID, LPMIDIINCAPS16 lpCaps,
904 UINT ret = midiInGetDevCapsA(uDeviceID, &micA, uSize);
906 if (ret == MMSYSERR_NOERROR) {
907 lpCaps->wMid = micA.wMid;
908 lpCaps->wPid = micA.wPid;
909 lpCaps->vDriverVersion = micA.vDriverVersion;
910 strcpy(lpCaps->szPname, micA.szPname);
911 lpCaps->dwSupport = micA.dwSupport;
917 /**************************************************************************
918 * midiInGetErrorText [MMSYSTEM.303]
920 UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
922 return midiInGetErrorTextA(uError, lpText, uSize);
925 /**************************************************************************
926 * midiInOpen [MMSYSTEM.304]
928 UINT16 WINAPI midiInOpen16(HMIDIIN16* lphMidiIn, UINT16 uDeviceID,
929 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
934 ret = MIDI_InOpen(&xhmid, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
936 if (lphMidiIn) *lphMidiIn = HMIDIIN_16(xhmid);
940 /**************************************************************************
941 * midiInClose [MMSYSTEM.305]
943 UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
945 return midiInClose(HMIDIIN_32(hMidiIn));
948 /**************************************************************************
949 * midiInPrepareHeader [MMSYSTEM.306]
951 UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
952 SEGPTR lpsegMidiInHdr, /* [???] */
953 UINT16 uSize) /* [in] */
957 TRACE("(%04X, %08lx, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
959 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
960 return MMSYSERR_INVALHANDLE;
962 return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD)lpsegMidiInHdr, uSize, FALSE);
965 /**************************************************************************
966 * midiInUnprepareHeader [MMSYSTEM.307]
968 UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
969 SEGPTR lpsegMidiInHdr, /* [???] */
970 UINT16 uSize) /* [in] */
973 LPMIDIHDR16 lpMidiInHdr = MapSL(lpsegMidiInHdr);
975 TRACE("(%04X, %08lx, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
977 if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
978 return MMSYSERR_NOERROR;
981 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
982 return MMSYSERR_INVALHANDLE;
984 return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpsegMidiInHdr, uSize, FALSE);
987 /**************************************************************************
988 * midiInAddBuffer [MMSYSTEM.308]
990 UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn, /* [in] */
991 MIDIHDR16* lpsegMidiInHdr, /* [???] NOTE: SEGPTR */
992 UINT16 uSize) /* [in] */
996 TRACE("(%04X, %p, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
998 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
999 return MMSYSERR_INVALHANDLE;
1001 return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD)lpsegMidiInHdr, uSize, FALSE);
1004 /**************************************************************************
1005 * midiInStart [MMSYSTEM.309]
1007 UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
1009 return midiInStart(HMIDIIN_32(hMidiIn));
1012 /**************************************************************************
1013 * midiInStop [MMSYSTEM.310]
1015 UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
1017 return midiInStop(HMIDIIN_32(hMidiIn));
1020 /**************************************************************************
1021 * midiInReset [MMSYSTEM.311]
1023 UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
1025 return midiInReset(HMIDIIN_32(hMidiIn));
1028 /**************************************************************************
1029 * midiInGetID [MMSYSTEM.312]
1031 UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
1035 TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID);
1037 if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1039 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, TRUE)) == NULL)
1040 return MMSYSERR_INVALHANDLE;
1042 *lpuDeviceID = wmld->uDeviceID;
1044 return MMSYSERR_NOERROR;
1047 /**************************************************************************
1048 * midiInMessage [MMSYSTEM.313]
1050 DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage,
1051 DWORD dwParam1, DWORD dwParam2)
1055 TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
1060 FIXME("can't handle OPEN or CLOSE message!\n");
1061 return MMSYSERR_NOTSUPPORTED;
1063 case MIDM_GETDEVCAPS:
1064 return midiInGetDevCaps16(hMidiIn, MapSL(dwParam1), dwParam2);
1066 return midiInPrepareHeader16(hMidiIn, dwParam1, dwParam2);
1067 case MIDM_UNPREPARE:
1068 return midiInUnprepareHeader16(hMidiIn, dwParam1, dwParam2);
1069 case MIDM_ADDBUFFER:
1070 return midiInAddBuffer16(hMidiIn, MapSL(dwParam1), dwParam2);
1073 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
1074 return MMSYSERR_INVALHANDLE;
1076 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1079 /**************************************************************************
1080 * midiStreamClose [MMSYSTEM.252]
1082 MMRESULT16 WINAPI midiStreamClose16(HMIDISTRM16 hMidiStrm)
1084 return midiStreamClose(HMIDISTRM_32(hMidiStrm));
1087 /**************************************************************************
1088 * midiStreamOpen [MMSYSTEM.251]
1090 MMRESULT16 WINAPI midiStreamOpen16(HMIDISTRM16* phMidiStrm, LPUINT16 devid,
1091 DWORD cMidi, DWORD dwCallback,
1092 DWORD dwInstance, DWORD fdwOpen)
1094 HMIDISTRM hMidiStrm32;
1098 if (!phMidiStrm || !devid)
1099 return MMSYSERR_INVALPARAM;
1101 ret = MIDI_StreamOpen(&hMidiStrm32, &devid32, cMidi, dwCallback,
1102 dwInstance, fdwOpen, FALSE);
1103 *phMidiStrm = HMIDISTRM_16(hMidiStrm32);
1108 /**************************************************************************
1109 * midiStreamOut [MMSYSTEM.254]
1111 MMRESULT16 WINAPI midiStreamOut16(HMIDISTRM16 hMidiStrm, LPMIDIHDR16 lpMidiHdr, UINT16 cbMidiHdr)
1113 return midiStreamOut(HMIDISTRM_32(hMidiStrm), (LPMIDIHDR)lpMidiHdr,
1117 /**************************************************************************
1118 * midiStreamPause [MMSYSTEM.255]
1120 MMRESULT16 WINAPI midiStreamPause16(HMIDISTRM16 hMidiStrm)
1122 return midiStreamPause(HMIDISTRM_32(hMidiStrm));
1125 /**************************************************************************
1126 * midiStreamPosition [MMSYSTEM.253]
1128 MMRESULT16 WINAPI midiStreamPosition16(HMIDISTRM16 hMidiStrm, LPMMTIME16 lpmmt16, UINT16 cbmmt)
1134 return MMSYSERR_INVALPARAM;
1135 MMSYSTEM_MMTIME16to32(&mmt32, lpmmt16);
1136 ret = midiStreamPosition(HMIDISTRM_32(hMidiStrm), &mmt32, sizeof(MMTIME));
1137 MMSYSTEM_MMTIME32to16(lpmmt16, &mmt32);
1141 /**************************************************************************
1142 * midiStreamProperty [MMSYSTEM.250]
1144 MMRESULT16 WINAPI midiStreamProperty16(HMIDISTRM16 hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
1146 return midiStreamProperty(HMIDISTRM_32(hMidiStrm), lpPropData, dwProperty);
1149 /**************************************************************************
1150 * midiStreamRestart [MMSYSTEM.256]
1152 MMRESULT16 WINAPI midiStreamRestart16(HMIDISTRM16 hMidiStrm)
1154 return midiStreamRestart(HMIDISTRM_32(hMidiStrm));
1157 /**************************************************************************
1158 * midiStreamStop [MMSYSTEM.257]
1160 MMRESULT16 WINAPI midiStreamStop16(HMIDISTRM16 hMidiStrm)
1162 return midiStreamStop(HMIDISTRM_32(hMidiStrm));
1165 /* ###################################################
1167 * ###################################################
1170 /**************************************************************************
1171 * waveOutGetNumDevs [MMSYSTEM.401]
1173 UINT16 WINAPI waveOutGetNumDevs16(void)
1175 return MMDRV_GetNum(MMDRV_WAVEOUT);
1178 /**************************************************************************
1179 * waveOutGetDevCaps [MMSYSTEM.402]
1181 UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID,
1182 LPWAVEOUTCAPS16 lpCaps, UINT16 uSize)
1187 TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
1188 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1190 ret = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(wocA));
1192 if (ret == MMSYSERR_NOERROR) {
1193 lpCaps->wMid = wocA.wMid;
1194 lpCaps->wPid = wocA.wPid;
1195 lpCaps->vDriverVersion = wocA.vDriverVersion;
1196 strcpy(lpCaps->szPname, wocA.szPname);
1197 lpCaps->dwFormats = wocA.dwFormats;
1198 lpCaps->wChannels = wocA.wChannels;
1199 lpCaps->dwSupport = wocA.dwSupport;
1204 /**************************************************************************
1205 * waveOutGetErrorText [MMSYSTEM.403]
1207 UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
1209 return waveOutGetErrorTextA(uError, lpText, uSize);
1212 /**************************************************************************
1213 * waveOutOpen [MMSYSTEM.404]
1215 UINT16 WINAPI waveOutOpen16(HWAVEOUT16* lphWaveOut, UINT16 uDeviceID,
1216 const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
1217 DWORD dwInstance, DWORD dwFlags)
1222 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1223 * call the 32 bit version
1224 * however, we need to promote correctly the wave mapper id
1225 * (0xFFFFFFFF and not 0x0000FFFF)
1227 ret = WAVE_Open(&hWaveOut, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1228 MMDRV_WAVEOUT, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1230 if (lphWaveOut != NULL) *lphWaveOut = HWAVEOUT_16(hWaveOut);
1234 /**************************************************************************
1235 * waveOutClose [MMSYSTEM.405]
1237 UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
1242 ReleaseThunkLock(&level);
1243 ret = waveOutClose(HWAVEOUT_32(hWaveOut));
1244 RestoreThunkLock(level);
1248 /**************************************************************************
1249 * waveOutPrepareHeader [MMSYSTEM.406]
1251 UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
1252 SEGPTR lpsegWaveOutHdr, /* [???] */
1253 UINT16 uSize) /* [in] */
1256 LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1258 TRACE("(%04X, %08lx, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1260 if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM;
1262 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1263 return MMSYSERR_INVALHANDLE;
1265 return MMDRV_Message(wmld, WODM_PREPARE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
1268 /**************************************************************************
1269 * waveOutUnprepareHeader [MMSYSTEM.407]
1271 UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
1272 SEGPTR lpsegWaveOutHdr, /* [???] */
1273 UINT16 uSize) /* [in] */
1276 LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1278 TRACE("(%04X, %08lx, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1280 if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
1281 return MMSYSERR_NOERROR;
1284 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1285 return MMSYSERR_INVALHANDLE;
1287 return MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
1290 /**************************************************************************
1291 * waveOutWrite [MMSYSTEM.408]
1293 UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, /* [in] */
1294 LPWAVEHDR lpsegWaveOutHdr, /* [???] NOTE: SEGPTR */
1295 UINT16 uSize) /* [in] */
1299 TRACE("(%04X, %p, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1301 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1302 return MMSYSERR_INVALHANDLE;
1304 return MMDRV_Message(wmld, WODM_WRITE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
1307 /**************************************************************************
1308 * waveOutBreakLoop [MMSYSTEM.419]
1310 UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut16)
1315 ReleaseThunkLock(&level);
1316 ret = waveOutBreakLoop(HWAVEOUT_32(hWaveOut16));
1317 RestoreThunkLock(level);
1321 /**************************************************************************
1322 * waveOutPause [MMSYSTEM.409]
1324 UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut16)
1329 ReleaseThunkLock(&level);
1330 ret = waveOutPause(HWAVEOUT_32(hWaveOut16));
1331 RestoreThunkLock(level);
1335 /**************************************************************************
1336 * waveOutReset [MMSYSTEM.411]
1338 UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut16)
1343 ReleaseThunkLock(&level);
1344 ret = waveOutReset(HWAVEOUT_32(hWaveOut16));
1345 RestoreThunkLock(level);
1349 /**************************************************************************
1350 * waveOutRestart [MMSYSTEM.410]
1352 UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut16)
1357 ReleaseThunkLock(&level);
1358 ret = waveOutRestart(HWAVEOUT_32(hWaveOut16));
1359 RestoreThunkLock(level);
1363 /**************************************************************************
1364 * waveOutGetPosition [MMSYSTEM.412]
1366 UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut, LPMMTIME16 lpTime,
1372 mmt.wType = lpTime->wType;
1373 ret = waveOutGetPosition(HWAVEOUT_32(hWaveOut), &mmt, sizeof(mmt));
1374 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1378 /**************************************************************************
1379 * waveOutGetPitch [MMSYSTEM.413]
1381 UINT16 WINAPI waveOutGetPitch16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
1383 return waveOutGetPitch(HWAVEOUT_32(hWaveOut16), lpdw);
1386 /**************************************************************************
1387 * waveOutSetPitch [MMSYSTEM.414]
1389 UINT16 WINAPI waveOutSetPitch16(HWAVEOUT16 hWaveOut16, DWORD dw)
1391 return waveOutSetPitch(HWAVEOUT_32(hWaveOut16), dw);
1394 /**************************************************************************
1395 * waveOutGetPlaybackRate [MMSYSTEM.417]
1397 UINT16 WINAPI waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
1399 return waveOutGetPlaybackRate(HWAVEOUT_32(hWaveOut16), lpdw);
1402 /**************************************************************************
1403 * waveOutSetPlaybackRate [MMSYSTEM.418]
1405 UINT16 WINAPI waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16, DWORD dw)
1407 return waveOutSetPlaybackRate(HWAVEOUT_32(hWaveOut16), dw);
1410 /**************************************************************************
1411 * waveOutGetVolume [MMSYSTEM.415]
1413 UINT16 WINAPI waveOutGetVolume16(UINT16 devid, LPDWORD lpdw)
1415 return waveOutGetVolume(HWAVEOUT_32(devid), lpdw);
1418 /**************************************************************************
1419 * waveOutSetVolume [MMSYSTEM.416]
1421 UINT16 WINAPI waveOutSetVolume16(UINT16 devid, DWORD dw)
1423 return waveOutSetVolume(HWAVEOUT_32(devid), dw);
1426 /**************************************************************************
1427 * waveOutGetID [MMSYSTEM.420]
1429 UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16* lpuDeviceID)
1433 TRACE("(%04X, %p);\n", hWaveOut, lpuDeviceID);
1435 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1437 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1438 return MMSYSERR_INVALHANDLE;
1440 *lpuDeviceID = wmld->uDeviceID;
1444 /**************************************************************************
1445 * waveOutMessage [MMSYSTEM.421]
1447 DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage,
1448 DWORD dwParam1, DWORD dwParam2)
1452 TRACE("(%04x, %u, %ld, %ld)\n", hWaveOut, uMessage, dwParam1, dwParam2);
1454 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) {
1455 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, TRUE)) != NULL) {
1456 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1458 return MMSYSERR_INVALHANDLE;
1462 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1463 return MMSYSERR_INVALPARAM;
1465 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1468 /**************************************************************************
1469 * waveInGetNumDevs [MMSYSTEM.501]
1471 UINT16 WINAPI waveInGetNumDevs16(void)
1473 return MMDRV_GetNum(MMDRV_WAVEIN);
1476 /**************************************************************************
1477 * waveInGetDevCaps [MMSYSTEM.502]
1479 UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps,
1483 UINT ret = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(wicA));
1485 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1487 if (ret == MMSYSERR_NOERROR) {
1488 lpCaps->wMid = wicA.wMid;
1489 lpCaps->wPid = wicA.wPid;
1490 lpCaps->vDriverVersion = wicA.vDriverVersion;
1491 strcpy(lpCaps->szPname, wicA.szPname);
1492 lpCaps->dwFormats = wicA.dwFormats;
1493 lpCaps->wChannels = wicA.wChannels;
1498 /**************************************************************************
1499 * waveInGetErrorText [MMSYSTEM.503]
1501 UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
1503 return waveInGetErrorTextA(uError, lpText, uSize);
1506 /**************************************************************************
1507 * waveInOpen [MMSYSTEM.504]
1509 UINT16 WINAPI waveInOpen16(HWAVEIN16* lphWaveIn, UINT16 uDeviceID,
1510 const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
1511 DWORD dwInstance, DWORD dwFlags)
1516 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1517 * call the 32 bit version
1518 * however, we need to promote correctly the wave mapper id
1519 * (0xFFFFFFFF and not 0x0000FFFF)
1521 ret = WAVE_Open(&hWaveIn, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1522 MMDRV_WAVEIN, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1524 if (lphWaveIn != NULL) *lphWaveIn = HWAVEIN_16(hWaveIn);
1528 /**************************************************************************
1529 * waveInClose [MMSYSTEM.505]
1531 UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
1536 ReleaseThunkLock(&level);
1537 ret = waveInClose(HWAVEIN_32(hWaveIn));
1538 RestoreThunkLock(level);
1542 /**************************************************************************
1543 * waveInPrepareHeader [MMSYSTEM.506]
1545 UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1546 SEGPTR lpsegWaveInHdr, /* [???] */
1547 UINT16 uSize) /* [in] */
1550 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1553 TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
1555 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1556 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1557 return MMSYSERR_INVALHANDLE;
1559 lpWaveInHdr->dwBytesRecorded = 0;
1561 ret = MMDRV_Message(wmld, WIDM_PREPARE, (DWORD)lpsegWaveInHdr, uSize, FALSE);
1565 /**************************************************************************
1566 * waveInUnprepareHeader [MMSYSTEM.507]
1568 UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1569 SEGPTR lpsegWaveInHdr, /* [???] */
1570 UINT16 uSize) /* [in] */
1573 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1575 TRACE("(%04X, %08lx, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1577 if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1579 if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) {
1580 return MMSYSERR_NOERROR;
1583 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1584 return MMSYSERR_INVALHANDLE;
1586 return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpsegWaveInHdr, uSize, FALSE);
1589 /**************************************************************************
1590 * waveInAddBuffer [MMSYSTEM.508]
1592 UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn, /* [in] */
1593 WAVEHDR* lpsegWaveInHdr, /* [???] NOTE: SEGPTR */
1594 UINT16 uSize) /* [in] */
1598 TRACE("(%04X, %p, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1600 if (lpsegWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1601 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1602 return MMSYSERR_INVALHANDLE;
1604 return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD)lpsegWaveInHdr, uSize, FALSE);
1607 /**************************************************************************
1608 * waveInReset [MMSYSTEM.511]
1610 UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn16)
1615 ReleaseThunkLock(&level);
1616 ret = waveInReset(HWAVEIN_32(hWaveIn16));
1617 RestoreThunkLock(level);
1621 /**************************************************************************
1622 * waveInStart [MMSYSTEM.509]
1624 UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn16)
1629 ReleaseThunkLock(&level);
1630 ret = waveInStart(HWAVEIN_32(hWaveIn16));
1631 RestoreThunkLock(level);
1635 /**************************************************************************
1636 * waveInStop [MMSYSTEM.510]
1638 UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn16)
1643 ReleaseThunkLock(&level);
1644 ret = waveInStop(HWAVEIN_32(hWaveIn16));
1645 RestoreThunkLock(level);
1649 /**************************************************************************
1650 * waveInGetPosition [MMSYSTEM.512]
1652 UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn, LPMMTIME16 lpTime,
1658 mmt.wType = lpTime->wType;
1659 ret = waveInGetPosition(HWAVEIN_32(hWaveIn), &mmt, sizeof(mmt));
1660 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1664 /**************************************************************************
1665 * waveInGetID [MMSYSTEM.513]
1667 UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16* lpuDeviceID)
1671 TRACE("(%04X, %p);\n", hWaveIn, lpuDeviceID);
1673 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1675 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1676 return MMSYSERR_INVALHANDLE;
1678 *lpuDeviceID = wmld->uDeviceID;
1679 return MMSYSERR_NOERROR;
1682 /**************************************************************************
1683 * waveInMessage [MMSYSTEM.514]
1685 DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
1686 DWORD dwParam1, DWORD dwParam2)
1690 TRACE("(%04x, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2);
1693 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1694 return MMSYSERR_INVALPARAM;
1696 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1697 return MMSYSERR_INVALHANDLE;
1699 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
1702 /* ###################################################
1704 * ###################################################
1707 /*#define USE_MM_TSK_WINE*/
1709 /**************************************************************************
1710 * mmTaskCreate [MMSYSTEM.900]
1712 * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be
1713 * called upon creation with dwPmt as parameter.
1715 HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD dwPmt)
1720 DWORD showCmd = 0x40002;
1723 TRACE("(%08lx, %p, %08lx);\n", spProc, lphMmTask, dwPmt);
1724 /* This to work requires NE modules to be started with a binary command line
1725 * which is not currently the case. A patch exists but has never been committed.
1726 * A workaround would be to integrate code for mmtask.tsk into Wine, but
1727 * this requires tremendous work (starting with patching tools/build to
1728 * create NE executables (and not only DLLs) for builtins modules.
1731 FIXME("This is currently broken. It will fail\n");
1734 *(LPDWORD)(cmdline + 1) = (DWORD)spProc;
1735 *(LPDWORD)(cmdline + 5) = dwPmt;
1736 *(LPDWORD)(cmdline + 9) = 0;
1738 lp.hEnvironment = 0;
1739 lp.cmdLine = MapLS(cmdline);
1740 lp.showCmd = MapLS(&showCmd);
1743 #ifndef USE_MM_TSK_WINE
1744 handle = LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp);
1746 handle = LoadModule16("mmtask.tsk", &lp);
1749 ret = (handle) ? 1 : 2;
1755 *lphMmTask = handle;
1757 UnMapLS( lp.cmdLine );
1758 UnMapLS( lp.showCmd );
1759 TRACE("=> 0x%04x/%d\n", handle, ret);
1763 #ifdef USE_MM_TSK_WINE
1764 /* C equivalent to mmtask.tsk binary content */
1765 void mmTaskEntryPoint16(LPSTR cmdLine, WORD di, WORD si)
1767 int len = cmdLine[0x80];
1770 void (*fpProc)(DWORD) = MapSL(*((DWORD*)(cmdLine + 1)));
1771 DWORD dwPmt = *((DWORD*)(cmdLine + 5));
1774 InitTask16(); /* FIXME: pmts / from context ? */
1777 if (SetMessageQueue16(0x40)) {
1779 if (HIWORD(fpProc)) {
1781 /* EPP StackEnter16(); */
1793 /**************************************************************************
1794 * mmTaskBlock [MMSYSTEM.902]
1796 void WINAPI mmTaskBlock16(HINSTANCE16 WINE_UNUSED hInst)
1801 GetMessageA(&msg, 0, 0, 0);
1803 TranslateMessage(&msg);
1804 DispatchMessageA(&msg);
1806 } while (msg.message < 0x3A0);
1809 /**************************************************************************
1810 * mmTaskSignal [MMSYSTEM.903]
1812 LRESULT WINAPI mmTaskSignal16(HTASK16 ht)
1814 TRACE("(%04x);\n", ht);
1815 return PostThreadMessageW( HTASK_32(ht), WM_USER, 0, 0 );
1818 /**************************************************************************
1819 * mmGetCurrentTask [MMSYSTEM.904]
1821 HTASK16 WINAPI mmGetCurrentTask16(void)
1823 return GetCurrentTask();
1826 /**************************************************************************
1827 * mmTaskYield [MMSYSTEM.905]
1829 void WINAPI mmTaskYield16(void)
1833 if (PeekMessageA(&msg, 0, 0, 0, 0)) {
1838 extern DWORD WINAPI GetProcessFlags(DWORD);
1840 /******************************************************************
1845 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16 h)
1847 return (WINE_MMTHREAD*)MapSL( MAKESEGPTR(h, 0) );
1850 void WINAPI WINE_mmThreadEntryPoint(DWORD);
1852 /**************************************************************************
1853 * mmThreadCreate [MMSYSTEM.1120]
1856 * Creates a MM thread, calling fpThreadAddr(dwPmt).
1858 * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc
1859 * bit.1 set means to open a VxD for this thread (unsupported)
1861 LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags)
1866 TRACE("(%p, %p, %08lx, %08lx)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags);
1868 hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT);
1873 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1876 /* force mmtask routines even if mmthread is required */
1877 /* this will work only if the patch about binary cmd line and NE tasks
1883 lpMMThd->dwSignature = WINE_MMTHREAD_CREATED;
1884 lpMMThd->dwCounter = 0;
1885 lpMMThd->hThread = 0;
1886 lpMMThd->dwThreadID = 0;
1887 lpMMThd->fpThread = fpThreadAddr;
1888 lpMMThd->dwThreadPmt = dwPmt;
1889 lpMMThd->dwSignalCount = 0;
1890 lpMMThd->hEvent = 0;
1892 lpMMThd->dwStatus = 0;
1893 lpMMThd->dwFlags = dwFlags;
1896 if ((dwFlags & 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) {
1897 lpMMThd->hEvent = CreateEventA(0, 0, 1, 0);
1899 TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd);
1900 if (lpMMThd->dwFlags & 2) {
1901 /* as long as we don't support MM VxD in wine, we don't need
1902 * to care about this flag
1904 /* FIXME("Don't know how to properly open VxD handles\n"); */
1905 /* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */
1908 lpMMThd->hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)WINE_mmThreadEntryPoint,
1909 (LPVOID)(DWORD)hndl, CREATE_SUSPENDED, &lpMMThd->dwThreadID);
1910 if (lpMMThd->hThread == 0) {
1911 WARN("Couldn't create thread\n");
1912 /* clean-up(VxDhandle...); devicedirectio... */
1913 if (lpMMThd->hEvent != 0)
1914 CloseHandle(lpMMThd->hEvent);
1917 TRACE("Got a nice thread hndl=%p id=0x%08lx\n", lpMMThd->hThread, lpMMThd->dwThreadID);
1921 /* get WINE_mmThreadEntryPoint()
1922 * 2047 is its ordinal in mmsystem.spec
1924 FARPROC16 fp = GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR)2047);
1926 TRACE("farproc seg=0x%08lx lin=%p\n", (DWORD)fp, MapSL((SEGPTR)fp));
1928 ret = (fp == 0) ? 2 : mmTaskCreate16((DWORD)fp, 0, hndl);
1932 if (lpMMThd->hThread && !ResumeThread(lpMMThd->hThread))
1933 WARN("Couldn't resume thread\n");
1935 while (lpMMThd->dwStatus != 0x10) { /* test also HIWORD of dwStatus */
1949 TRACE("ok => %ld\n", ret);
1953 /**************************************************************************
1954 * mmThreadSignal [MMSYSTEM.1121]
1956 void WINAPI mmThreadSignal16(HANDLE16 hndl)
1958 TRACE("(%04x)!\n", hndl);
1961 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1963 lpMMThd->dwCounter++;
1964 if (lpMMThd->hThread != 0) {
1965 InterlockedIncrement(&lpMMThd->dwSignalCount);
1966 SetEvent(lpMMThd->hEvent);
1968 mmTaskSignal16(lpMMThd->hTask);
1970 lpMMThd->dwCounter--;
1974 static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd)
1979 if (lpMMThd->dwThreadID != GetCurrentThreadId())
1980 ERR("Not called by thread itself\n");
1983 ResetEvent(lpMMThd->hEvent);
1984 if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0)
1986 InterlockedIncrement(&lpMMThd->dwSignalCount);
1990 ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT);
1992 case WAIT_OBJECT_0: /* Event */
1995 case WAIT_OBJECT_0 + 1: /* Msg */
1997 if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
1998 TranslateMessage(&msg);
1999 DispatchMessageA(&msg);
2003 WARN("S2.x unsupported ret val 0x%08lx\n", ret);
2009 /**************************************************************************
2010 * mmThreadBlock [MMSYSTEM.1122]
2012 void WINAPI mmThreadBlock16(HANDLE16 hndl)
2014 TRACE("(%04x)!\n", hndl);
2017 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2019 if (lpMMThd->hThread != 0) {
2022 ReleaseThunkLock(&lc);
2023 MMSYSTEM_ThreadBlock(lpMMThd);
2024 RestoreThunkLock(lc);
2026 mmTaskBlock16(lpMMThd->hTask);
2032 /**************************************************************************
2033 * mmThreadIsCurrent [MMSYSTEM.1123]
2035 BOOL16 WINAPI mmThreadIsCurrent16(HANDLE16 hndl)
2039 TRACE("(%04x)!\n", hndl);
2041 if (hndl && mmThreadIsValid16(hndl)) {
2042 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2043 ret = (GetCurrentThreadId() == lpMMThd->dwThreadID);
2045 TRACE("=> %d\n", ret);
2049 /**************************************************************************
2050 * mmThreadIsValid [MMSYSTEM.1124]
2052 BOOL16 WINAPI mmThreadIsValid16(HANDLE16 hndl)
2056 TRACE("(%04x)!\n", hndl);
2059 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2061 if (!IsBadWritePtr(lpMMThd, sizeof(WINE_MMTHREAD)) &&
2062 lpMMThd->dwSignature == WINE_MMTHREAD_CREATED &&
2063 IsTask16(lpMMThd->hTask)) {
2064 lpMMThd->dwCounter++;
2065 if (lpMMThd->hThread != 0) {
2067 if (GetExitCodeThread(lpMMThd->hThread, &dwThreadRet) &&
2068 dwThreadRet == STATUS_PENDING) {
2074 lpMMThd->dwCounter--;
2077 TRACE("=> %d\n", ret);
2081 /**************************************************************************
2082 * mmThreadGetTask [MMSYSTEM.1125]
2084 HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl)
2088 TRACE("(%04x)\n", hndl);
2090 if (mmThreadIsValid16(hndl)) {
2091 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2092 ret = lpMMThd->hTask;
2097 /**************************************************************************
2098 * __wine_mmThreadEntryPoint (MMSYSTEM.2047)
2100 void WINAPI WINE_mmThreadEntryPoint(DWORD _pmt)
2102 HANDLE16 hndl = (HANDLE16)_pmt;
2103 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2105 TRACE("(%04x %p)\n", hndl, lpMMThd);
2107 lpMMThd->hTask = LOWORD(GetCurrentTask());
2108 TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask);
2109 lpMMThd->dwStatus = 0x10;
2110 MMSYSTEM_ThreadBlock(lpMMThd);
2111 TRACE("[20-%p]\n", lpMMThd->hThread);
2112 lpMMThd->dwStatus = 0x20;
2113 if (lpMMThd->fpThread) {
2114 WOWCallback16((DWORD)lpMMThd->fpThread, lpMMThd->dwThreadPmt);
2116 lpMMThd->dwStatus = 0x30;
2117 TRACE("[30-%p]\n", lpMMThd->hThread);
2118 while (lpMMThd->dwCounter) {
2120 /* K32WOWYield16();*/
2122 TRACE("[XX-%p]\n", lpMMThd->hThread);
2124 lpMMThd->dwSignature = WINE_MMTHREAD_DELETED;
2125 /* close lpMMThread->hVxD directIO */
2126 if (lpMMThd->hEvent)
2127 CloseHandle(lpMMThd->hEvent);
2132 typedef BOOL16 (WINAPI *MMCPLCALLBACK)(HWND, LPCSTR, LPCSTR, LPCSTR);
2134 /**************************************************************************
2135 * mmShowMMCPLPropertySheet [MMSYSTEM.1150]
2137 BOOL16 WINAPI mmShowMMCPLPropertySheet16(HWND hWnd, LPCSTR lpStrDevice,
2138 LPCSTR lpStrTab, LPCSTR lpStrTitle)
2143 TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2145 hndl = LoadLibraryA("MMSYS.CPL");
2147 MMCPLCALLBACK fp = (MMCPLCALLBACK)GetProcAddress(hndl, "ShowMMCPLPropertySheet");
2150 ReleaseThunkLock(&lc);
2151 ret = (fp)(hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2152 RestoreThunkLock(lc);
2160 /**************************************************************************
2161 * StackEnter [MMSYSTEM.32]
2163 void WINAPI StackEnter16(void)
2166 /* mmsystem.dll from Win 95 does only this: so does Wine */
2171 /**************************************************************************
2172 * StackLeave [MMSYSTEM.33]
2174 void WINAPI StackLeave16(void)
2177 /* mmsystem.dll from Win 95 does only this: so does Wine */
2182 /**************************************************************************
2183 * WMMMidiRunOnce [MMSYSTEM.8]
2185 void WINAPI WMMMidiRunOnce16(void)
2187 FIXME("(), stub!\n");
2190 /* ###################################################
2192 * ###################################################
2195 /**************************************************************************
2196 * DRIVER_MapMsg32To16 [internal]
2198 * Map a 32 bit driver message to a 16 bit driver message.
2200 static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
2202 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2209 case DRV_QUERYCONFIGURE:
2211 case DRV_EXITSESSION:
2212 case DRV_EXITAPPLICATION:
2214 case DRV_CLOSE: /* should be 0/0 */
2215 case DRV_OPEN: /* pass through */
2216 /* lParam1 and lParam2 are not used */
2221 /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
2222 * lParam2 is a pointer to DRVCONFIGINFO
2225 LPDRVCONFIGINFO16 dci16 = HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16) );
2226 LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
2231 dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
2233 if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCISectionName)) != NULL)
2235 dci16->lpszDCISectionName = MapLS( str1 );
2237 return WINMM_MAP_NOMEM;
2239 if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCIAliasName)) != NULL)
2241 dci16->lpszDCIAliasName = MapLS( str1 );
2243 return WINMM_MAP_NOMEM;
2246 return WINMM_MAP_NOMEM;
2248 *lParam2 = MapLS( dci16 );
2249 ret = WINMM_MAP_OKMEM;
2255 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2256 FIXME("Unknown message 0x%04x\n", wMsg);
2263 /**************************************************************************
2264 * DRIVER_UnMapMsg32To16 [internal]
2266 * UnMap a 32 bit driver message to a 16 bit driver message.
2268 static WINMM_MapType DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
2270 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2277 case DRV_QUERYCONFIGURE:
2279 case DRV_EXITSESSION:
2280 case DRV_EXITAPPLICATION:
2284 /* lParam1 and lParam2 are not used */
2288 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
2290 LPDRVCONFIGINFO16 dci16 = MapSL(lParam2);
2291 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCISectionName) );
2292 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCIAliasName) );
2294 UnMapLS( dci16->lpszDCISectionName );
2295 UnMapLS( dci16->lpszDCIAliasName );
2296 HeapFree( GetProcessHeap(), 0, dci16 );
2301 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2302 FIXME("Unknown message 0x%04x\n", wMsg);
2309 /**************************************************************************
2310 * DRIVER_TryOpenDriver16 [internal]
2312 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
2314 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCSTR fn, LPCSTR sn, LPARAM lParam2)
2316 LPWINE_DRIVER lpDrv = NULL;
2319 TRACE("(%s, %08lX);\n", debugstr_a(sn), lParam2);
2321 lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
2322 if (lpDrv == NULL) {cause = "OOM"; goto exit;}
2324 /* FIXME: shall we do some black magic here on sn ?
2325 * drivers32 => drivers
2329 lpDrv->d.d16.hDriver16 = OpenDriver16(fn, sn, lParam2);
2330 if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;}
2331 lpDrv->dwFlags = WINE_GDF_16BIT;
2333 TRACE("=> %p\n", lpDrv);
2336 HeapFree(GetProcessHeap(), 0, lpDrv);
2337 TRACE("Unable to load 16 bit module %s: %s\n", debugstr_a(fn), cause);
2341 /******************************************************************
2342 * DRIVER_SendMessage16
2346 static LRESULT DRIVER_SendMessage16(HDRVR16 hDrv16, UINT msg,
2347 LPARAM lParam1, LPARAM lParam2)
2352 TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
2353 hDrv16, msg, lParam1, lParam2);
2355 switch (map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) {
2356 case WINMM_MAP_OKMEM:
2358 ret = SendDriverMessage16(hDrv16, msg, lParam1, lParam2);
2359 if (map == WINMM_MAP_OKMEM)
2360 DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
2367 /******************************************************************
2368 * DRIVER_CloseDriver16
2372 static LRESULT DRIVER_CloseDriver16(HDRVR16 hDrv16, LPARAM lParam1, LPARAM lParam2)
2374 return CloseDriver16(hDrv16, lParam1, lParam2);
2377 /**************************************************************************
2378 * DrvOpen [MMSYSTEM.1100]
2380 HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
2382 return OpenDriver16(lpDriverName, lpSectionName, lParam);
2385 /**************************************************************************
2386 * DrvClose [MMSYSTEM.1101]
2388 LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
2390 return CloseDriver16(hDrv, lParam1, lParam2);
2393 /**************************************************************************
2394 * DrvSendMessage [MMSYSTEM.1102]
2396 LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
2399 return SendDriverMessage16(hDrv, msg, lParam1, lParam2);
2402 /**************************************************************************
2403 * DrvGetModuleHandle [MMSYSTEM.1103]
2405 HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
2407 return GetDriverModuleHandle16(hDrv);
2410 /**************************************************************************
2411 * DrvDefDriverProc [MMSYSTEM.1104]
2413 LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg,
2414 DWORD dwParam1, DWORD dwParam2)
2416 return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
2419 /**************************************************************************
2420 * DriverProc [MMSYSTEM.6]
2422 LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
2423 DWORD dwParam1, DWORD dwParam2)
2425 TRACE("dwDevID=%08lx hDrv=%04x wMsg=%04x dwParam1=%08lx dwParam2=%08lx\n",
2426 dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2428 return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2431 /* ###################################################
2433 * ###################################################
2436 /******************************************************************
2437 * MMSYSTEM_MMTIME32to16
2441 void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32)
2443 mmt16->wType = mmt32->wType;
2444 /* layout of rest is the same for 32/16,
2445 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2447 memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u));
2450 /******************************************************************
2451 * MMSYSTEM_MMTIME16to32
2455 void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16)
2457 mmt32->wType = mmt16->wType;
2458 /* layout of rest is the same for 32/16,
2459 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2461 memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u));
2464 /**************************************************************************
2465 * timeGetSystemTime [MMSYSTEM.601]
2467 MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
2469 TRACE("(%p, %u);\n", lpTime, wSize);
2471 if (wSize >= sizeof(*lpTime)) {
2472 lpTime->wType = TIME_MS;
2474 lpTime->u.ms = WINMM_IData->mmSysTimeMS;
2476 TRACE("=> %lu\n", lpTime->u.ms);
2482 /**************************************************************************
2483 * timeSetEvent [MMSYSTEM.602]
2485 MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc,
2486 DWORD dwUser, UINT16 wFlags)
2488 if (wFlags & WINE_TIMER_IS32)
2489 WARN("Unknown windows flag... wine internally used.. ooch\n");
2491 return TIME_SetEventInternal(wDelay, wResol, (FARPROC16)lpFunc,
2492 dwUser, wFlags & ~WINE_TIMER_IS32);
2495 /**************************************************************************
2496 * timeKillEvent [MMSYSTEM.603]
2498 MMRESULT16 WINAPI timeKillEvent16(UINT16 wID)
2500 return timeKillEvent(wID);
2503 /**************************************************************************
2504 * timeGetDevCaps [MMSYSTEM.604]
2506 MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize)
2511 TRACE("(%p, %u) !\n", lpCaps, wSize);
2513 ret = timeGetDevCaps(&caps, sizeof(caps));
2514 lpCaps->wPeriodMin = caps.wPeriodMin;
2515 lpCaps->wPeriodMax = caps.wPeriodMax;
2519 /**************************************************************************
2520 * timeBeginPeriod [MMSYSTEM.605]
2522 MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod)
2524 TRACE("(%u) !\n", wPeriod);
2526 return timeBeginPeriod(wPeriod);
2529 /**************************************************************************
2530 * timeEndPeriod [MMSYSTEM.606]
2532 MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod)
2534 TRACE("(%u) !\n", wPeriod);
2536 return timeEndPeriod(wPeriod);
2539 /**************************************************************************
2540 * mciSendString [MMSYSTEM.702]
2542 DWORD WINAPI mciSendString16(LPCSTR lpstrCommand, LPSTR lpstrRet,
2543 UINT16 uRetLen, HWND16 hwndCallback)
2545 return mciSendStringA(lpstrCommand, lpstrRet, uRetLen, HWND_32(hwndCallback));
2548 /**************************************************************************
2549 * mciLoadCommandResource [MMSYSTEM.705]
2551 UINT16 WINAPI mciLoadCommandResource16(HINSTANCE16 hInst, LPCSTR resname, UINT16 type)
2555 RtlCreateUnicodeStringFromAsciiz(&ptr, resname);
2556 ret = mciLoadCommandResource(HINSTANCE_32(hInst), ptr.Buffer, type);
2557 RtlFreeUnicodeString(&ptr);
2561 /**************************************************************************
2562 * mciFreeCommandResource [MMSYSTEM.713]
2564 BOOL16 WINAPI mciFreeCommandResource16(UINT16 uTable)
2566 TRACE("(%04x)!\n", uTable);
2568 return mciFreeCommandResource(uTable);
2571 /* ###################################################
2573 * ###################################################
2576 /****************************************************************
2577 * MMIO_Map32To16 [INTERNAL]
2579 static LRESULT MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2)
2589 case MMIOM_WRITEFLUSH:
2590 *lp1 = MapLS( (void *)*lp1 );
2593 *lp1 = MapLS( (void *)*lp1 );
2594 *lp2 = MapLS( (void *)*lp2 );
2597 if (wMsg < MMIOM_USER)
2598 TRACE("Not a mappable message (%ld)\n", wMsg);
2600 return MMSYSERR_NOERROR;
2603 /****************************************************************
2604 * MMIO_UnMap32To16 [INTERNAL]
2606 static LRESULT MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2,
2607 LPARAM lp1, LPARAM lp2)
2617 case MMIOM_WRITEFLUSH:
2625 if (wMsg < MMIOM_USER)
2626 TRACE("Not a mappable message (%ld)\n", wMsg);
2628 return MMSYSERR_NOERROR;
2631 /******************************************************************
2636 static LRESULT MMIO_Callback16(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage,
2637 LPARAM lParam1, LPARAM lParam2)
2640 MMIOINFO16 mmioInfo16;
2641 SEGPTR segmmioInfo16;
2642 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);
2656 args[6] = HIWORD(segmmioInfo16);
2657 args[5] = LOWORD(segmmioInfo16);
2659 args[3] = HIWORD(lp1);
2660 args[2] = LOWORD(lp1);
2661 args[1] = HIWORD(lp2);
2662 args[0] = LOWORD(lp2);
2663 WOWCallback16Ex( cb16, WCB16_PASCAL, sizeof(args), args, &result );
2664 UnMapLS(segmmioInfo16);
2665 MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2);
2667 lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset;
2668 lpmmioinfo->adwInfo[0] = mmioInfo16.adwInfo[0];
2669 lpmmioinfo->adwInfo[1] = mmioInfo16.adwInfo[1];
2670 lpmmioinfo->adwInfo[2] = mmioInfo16.adwInfo[2];
2671 lpmmioinfo->adwInfo[3] = mmioInfo16.adwInfo[3];
2676 /******************************************************************
2677 * MMIO_ResetSegmentedData
2680 static LRESULT MMIO_SetSegmentedBuffer(HMMIO hmmio, SEGPTR ptr)
2684 if ((wm = MMIO_Get(hmmio)) == NULL)
2685 return MMSYSERR_INVALHANDLE;
2686 wm->segBuffer16 = ptr;
2687 return MMSYSERR_NOERROR;
2690 /**************************************************************************
2691 * mmioOpen [MMSYSTEM.1210]
2693 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16,
2701 memset(&mmioinfo, 0, sizeof(mmioinfo));
2703 mmioinfo.dwFlags = lpmmioinfo16->dwFlags;
2704 mmioinfo.fccIOProc = lpmmioinfo16->fccIOProc;
2705 mmioinfo.pIOProc = (LPMMIOPROC)lpmmioinfo16->pIOProc;
2706 mmioinfo.cchBuffer = lpmmioinfo16->cchBuffer;
2707 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo16->pchBuffer);
2708 mmioinfo.adwInfo[0] = lpmmioinfo16->adwInfo[0];
2709 /* if we don't have a file name, it's likely a passed open file descriptor */
2711 mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]);
2712 mmioinfo.adwInfo[1] = lpmmioinfo16->adwInfo[1];
2713 mmioinfo.adwInfo[2] = lpmmioinfo16->adwInfo[2];
2714 mmioinfo.adwInfo[3] = lpmmioinfo16->adwInfo[3];
2716 ret = MMIO_Open(szFileName, &mmioinfo, dwOpenFlags, MMIO_PROC_16);
2717 MMIO_SetSegmentedBuffer(mmioinfo.hmmio, (SEGPTR)lpmmioinfo16->pchBuffer);
2719 lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet;
2720 lpmmioinfo16->hmmio = HMMIO_16(mmioinfo.hmmio);
2722 ret = MMIO_Open(szFileName, NULL, dwOpenFlags, MMIO_PROC_32A);
2724 return HMMIO_16(ret);
2727 /**************************************************************************
2728 * mmioClose [MMSYSTEM.1211]
2730 MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
2732 return mmioClose(HMMIO_32(hmmio), uFlags);
2735 /**************************************************************************
2736 * mmioRead [MMSYSTEM.1212]
2738 LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
2740 return mmioRead(HMMIO_32(hmmio), pch, cch);
2743 /**************************************************************************
2744 * mmioWrite [MMSYSTEM.1213]
2746 LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
2748 return mmioWrite(HMMIO_32(hmmio),pch,cch);
2751 /**************************************************************************
2752 * mmioSeek [MMSYSTEM.1214]
2754 LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
2756 return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin);
2759 /**************************************************************************
2760 * mmioGetInfo [MMSYSTEM.1215]
2762 MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2768 TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags);
2770 if ((wm = MMIO_Get(HMMIO_32(hmmio))) == NULL)
2771 return MMSYSERR_INVALHANDLE;
2773 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
2774 if (ret != MMSYSERR_NOERROR) return ret;
2776 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
2777 lpmmioinfo->fccIOProc = mmioinfo.fccIOProc;
2778 lpmmioinfo->pIOProc = (wm->ioProc->type == MMIO_PROC_16) ?
2779 (LPMMIOPROC16)wm->ioProc->pIOProc : NULL;
2780 lpmmioinfo->wErrorRet = mmioinfo.wErrorRet;
2781 lpmmioinfo->hTask = HTASK_16(mmioinfo.hTask);
2782 lpmmioinfo->cchBuffer = mmioinfo.cchBuffer;
2783 lpmmioinfo->pchBuffer = (void*)wm->segBuffer16;
2784 lpmmioinfo->pchNext = (void*)(wm->segBuffer16 + (mmioinfo.pchNext - mmioinfo.pchBuffer));
2785 lpmmioinfo->pchEndRead = (void*)(wm->segBuffer16 + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
2786 lpmmioinfo->pchEndWrite = (void*)(wm->segBuffer16 + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
2787 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
2788 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
2789 lpmmioinfo->adwInfo[0] = mmioinfo.adwInfo[0];
2790 lpmmioinfo->adwInfo[1] = mmioinfo.adwInfo[1];
2791 lpmmioinfo->adwInfo[2] = mmioinfo.adwInfo[2];
2792 lpmmioinfo->adwInfo[3] = mmioinfo.adwInfo[3];
2793 lpmmioinfo->dwReserved1 = 0;
2794 lpmmioinfo->dwReserved2 = 0;
2795 lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio);
2797 return MMSYSERR_NOERROR;
2800 /**************************************************************************
2801 * mmioSetInfo [MMSYSTEM.1216]
2803 MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2808 TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
2810 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0);
2811 if (ret != MMSYSERR_NOERROR) return ret;
2813 /* check if seg and lin buffers are the same */
2814 if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer ||
2815 mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer))
2816 return MMSYSERR_INVALPARAM;
2818 /* check pointers coherence */
2819 if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer ||
2820 lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
2821 lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer ||
2822 lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
2823 lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer ||
2824 lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer)
2825 return MMSYSERR_INVALPARAM;
2827 mmioinfo.pchNext = mmioinfo.pchBuffer + (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer);
2828 mmioinfo.pchEndRead = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead - lpmmioinfo->pchBuffer);
2829 mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer);
2831 return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
2834 /**************************************************************************
2835 * mmioSetBuffer [MMSYSTEM.1217]
2837 MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, LPSTR pchBuffer,
2838 LONG cchBuffer, UINT16 uFlags)
2840 MMRESULT ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL((DWORD)pchBuffer),
2843 if (ret == MMSYSERR_NOERROR)
2844 MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), (DWORD)pchBuffer);
2848 /**************************************************************************
2849 * mmioFlush [MMSYSTEM.1218]
2851 MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
2853 return mmioFlush(HMMIO_32(hmmio), uFlags);
2856 /***********************************************************************
2857 * mmioAdvance [MMSYSTEM.1219]
2859 MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2864 /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which
2869 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer);
2870 mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext);
2871 mmioinfo.dwFlags = lpmmioinfo->dwFlags;
2872 mmioinfo.lBufOffset = lpmmioinfo->lBufOffset;
2873 ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags);
2876 ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags);
2878 if (ret != MMSYSERR_NOERROR) return ret;
2882 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
2883 lpmmioinfo->pchNext = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
2884 lpmmioinfo->pchEndRead = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
2885 lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
2886 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
2887 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
2890 return MMSYSERR_NOERROR;
2893 /**************************************************************************
2894 * mmioStringToFOURCC [MMSYSTEM.1220]
2896 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
2898 return mmioStringToFOURCCA(sz, uFlags);
2901 /**************************************************************************
2902 * mmioInstallIOProc [MMSYSTEM.1221]
2904 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc,
2907 return (LPMMIOPROC16)MMIO_InstallIOProc(fccIOProc, (LPMMIOPROC)pIOProc,
2908 dwFlags, MMIO_PROC_16);
2911 /**************************************************************************
2912 * mmioSendMessage [MMSYSTEM.1222]
2914 LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage,
2915 LPARAM lParam1, LPARAM lParam2)
2917 return MMIO_SendMessage(HMMIO_32(hmmio), uMessage,
2918 lParam1, lParam2, MMIO_PROC_16);
2921 /**************************************************************************
2922 * mmioDescend [MMSYSTEM.1223]
2924 MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck,
2925 const MMCKINFO* lpckParent, UINT16 uFlags)
2927 return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags);
2930 /**************************************************************************
2931 * mmioAscend [MMSYSTEM.1224]
2933 MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
2935 return mmioAscend(HMMIO_32(hmmio),lpck,uFlags);
2938 /**************************************************************************
2939 * mmioCreateChunk [MMSYSTEM.1225]
2941 MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
2943 return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags);
2946 /**************************************************************************
2947 * mmioRename [MMSYSTEM.1226]
2949 MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName,
2950 MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags)
2956 if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL &&
2957 lpmmioinfo->fccIOProc == 0) {
2958 FIXME("Can't handle this case yet\n");
2959 return MMSYSERR_ERROR;
2962 /* this is a bit hacky, but it'll work if we get a fourCC code or nothing.
2963 * but a non installed ioproc without a fourcc won't do
2965 if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) {
2966 MMIO_InstallIOProc(lpmmioinfo->fccIOProc, (LPMMIOPROC)lpmmioinfo->pIOProc,
2967 MMIO_INSTALLPROC, MMIO_PROC_16);
2970 memset(&mmioinfo, 0, sizeof(mmioinfo));
2971 mmioinfo.fccIOProc = lpmmioinfo->fccIOProc;
2972 ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags);
2974 MMIO_InstallIOProc(lpmmioinfo->fccIOProc, NULL,
2975 MMIO_REMOVEPROC, MMIO_PROC_16);
2980 /* ###################################################
2982 * ###################################################
2985 /**************************************************************************
2986 * joyGetNumDevs [MMSYSTEM.101]
2988 UINT16 WINAPI joyGetNumDevs16(void)
2990 return joyGetNumDevs();
2993 /**************************************************************************
2994 * joyGetDevCaps [MMSYSTEM.102]
2996 MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize)
2999 MMRESULT ret = joyGetDevCapsA(wID, &jca, sizeof(jca));
3001 if (ret != JOYERR_NOERROR) return ret;
3002 lpCaps->wMid = jca.wMid;
3003 lpCaps->wPid = jca.wPid;
3004 strcpy(lpCaps->szPname, jca.szPname);
3005 lpCaps->wXmin = jca.wXmin;
3006 lpCaps->wXmax = jca.wXmax;
3007 lpCaps->wYmin = jca.wYmin;
3008 lpCaps->wYmax = jca.wYmax;
3009 lpCaps->wZmin = jca.wZmin;
3010 lpCaps->wZmax = jca.wZmax;
3011 lpCaps->wNumButtons = jca.wNumButtons;
3012 lpCaps->wPeriodMin = jca.wPeriodMin;
3013 lpCaps->wPeriodMax = jca.wPeriodMax;
3015 if (wSize >= sizeof(JOYCAPS16)) { /* Win95 extensions ? */
3016 lpCaps->wRmin = jca.wRmin;
3017 lpCaps->wRmax = jca.wRmax;
3018 lpCaps->wUmin = jca.wUmin;
3019 lpCaps->wUmax = jca.wUmax;
3020 lpCaps->wVmin = jca.wVmin;
3021 lpCaps->wVmax = jca.wVmax;
3022 lpCaps->wCaps = jca.wCaps;
3023 lpCaps->wMaxAxes = jca.wMaxAxes;
3024 lpCaps->wNumAxes = jca.wNumAxes;
3025 lpCaps->wMaxButtons = jca.wMaxButtons;
3026 strcpy(lpCaps->szRegKey, jca.szRegKey);
3027 strcpy(lpCaps->szOEMVxD, jca.szOEMVxD);
3033 /**************************************************************************
3034 * joyGetPosEx [MMSYSTEM.110]
3036 MMRESULT16 WINAPI joyGetPosEx16(UINT16 wID, LPJOYINFOEX lpInfo)
3038 return joyGetPosEx(wID, lpInfo);
3041 /**************************************************************************
3042 * joyGetPos [MMSYSTEM.103]
3044 MMRESULT16 WINAPI joyGetPos16(UINT16 wID, LPJOYINFO16 lpInfo)
3049 TRACE("(%d, %p);\n", wID, lpInfo);
3051 if ((ret = joyGetPos(wID, &ji)) == JOYERR_NOERROR) {
3052 lpInfo->wXpos = ji.wXpos;
3053 lpInfo->wYpos = ji.wYpos;
3054 lpInfo->wZpos = ji.wZpos;
3055 lpInfo->wButtons = ji.wButtons;
3060 /**************************************************************************
3061 * joyGetThreshold [MMSYSTEM.104]
3063 MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold)
3068 ret = joyGetThreshold(wID, &t);
3069 if (ret == JOYERR_NOERROR)
3074 /**************************************************************************
3075 * joyReleaseCapture [MMSYSTEM.105]
3077 MMRESULT16 WINAPI joyReleaseCapture16(UINT16 wID)
3079 return joyReleaseCapture(wID);
3082 /**************************************************************************
3083 * joySetCapture [MMSYSTEM.106]
3085 MMRESULT16 WINAPI joySetCapture16(HWND16 hWnd, UINT16 wID, UINT16 wPeriod, BOOL16 bChanged)
3087 return joySetCapture16(hWnd, wID, wPeriod, bChanged);
3090 /**************************************************************************
3091 * joySetThreshold [MMSYSTEM.107]
3093 MMRESULT16 WINAPI joySetThreshold16(UINT16 wID, UINT16 wThreshold)
3095 return joySetThreshold16(wID,wThreshold);
3098 /**************************************************************************
3099 * joySetCalibration [MMSYSTEM.109]
3101 MMRESULT16 WINAPI joySetCalibration16(UINT16 wID)
3103 FIXME("(%04X): stub.\n", wID);
3104 return JOYERR_NOCANDO;