winmm: Remove direct inclusion of winemm.h in winemm16.h.
[wine/hacks.git] / dlls / winmm / mmsystem.c
blob669d16187a7a20a1118697269bff77ba06cd482b
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * MMSYSTEM functions
6 * Copyright 1993 Martin Ayotte
7 * 1998-2003 Eric Pouech
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 * Eric POUECH :
26 * 99/4 added mmTask and mmThread functions support
29 #include <stdarg.h>
30 #include <string.h>
32 #define NONAMELESSUNION
33 #define NONAMELESSSTRUCT
34 #include "windef.h"
35 #include "winbase.h"
36 #include "mmsystem.h"
37 #include "winternl.h"
38 #include "wownt32.h"
39 #include "winnls.h"
41 #include "wine/winuser16.h"
42 #include "winemm.h"
43 #include "winemm16.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
49 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16);
50 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCWSTR, LPCWSTR, LPARAM);
51 static LRESULT DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM);
52 static LRESULT DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM);
53 static LRESULT MMIO_Callback16(SEGPTR, LPMMIOINFO, UINT, LPARAM, LPARAM);
55 /* ###################################################
56 * # LIBRARY #
57 * ###################################################
60 /**************************************************************************
61 * DllEntryPoint (MMSYSTEM.4)
63 * MMSYSTEM DLL entry point
66 BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
67 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
69 TRACE("%p 0x%x\n", hinstDLL, fdwReason);
71 switch (fdwReason) {
72 case DLL_PROCESS_ATTACH:
73 /* need to load WinMM in order to:
74 * - initiate correctly shared variables (WINMM_Init())
76 if (!GetModuleHandleA("WINMM.DLL"))
78 ERR("Could not load sibling WinMM.dll\n");
79 return FALSE;
81 /* hook in our 16 bit function pointers */
82 pFnGetMMThread16 = WINMM_GetmmThread;
83 pFnOpenDriver16 = DRIVER_OpenDriver16;
84 pFnCloseDriver16 = DRIVER_CloseDriver16;
85 pFnSendMessage16 = DRIVER_SendMessage16;
86 pFnMmioCallback16 = MMIO_Callback16;
87 pFnReleaseThunkLock = ReleaseThunkLock;
88 pFnRestoreThunkLock = RestoreThunkLock;
89 MMDRV_Init16();
90 break;
91 case DLL_PROCESS_DETACH:
92 pFnGetMMThread16 = NULL;
93 pFnOpenDriver16 = NULL;
94 pFnCloseDriver16 = NULL;
95 pFnSendMessage16 = NULL;
96 pFnMmioCallback16 = NULL;
97 pFnReleaseThunkLock = NULL;
98 pFnRestoreThunkLock = NULL;
99 /* FIXME: add equivalent for MMDRV_Init16() */
100 break;
101 case DLL_THREAD_ATTACH:
102 case DLL_THREAD_DETACH:
103 break;
105 return TRUE;
108 /**************************************************************************
109 * WEP [MMSYSTEM.1]
111 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
112 WORD cbHeapSize, LPSTR lpCmdLine)
114 TRACE("STUB: Unloading MMSystem DLL ... hInst=%04X\n", hInstance);
115 return TRUE;
118 /* ###################################################
119 * # PlaySound #
120 * ###################################################
123 /**************************************************************************
124 * PlaySound [MMSYSTEM.3]
126 BOOL16 WINAPI PlaySound16(LPCSTR pszSound, HMODULE16 hmod, DWORD fdwSound)
128 BOOL16 retv;
129 DWORD lc;
131 if ((fdwSound & SND_RESOURCE) == SND_RESOURCE)
133 HGLOBAL16 handle;
134 HRSRC16 res;
136 if (!(res = FindResource16( hmod, pszSound, "WAVE" ))) return FALSE;
137 if (!(handle = LoadResource16( hmod, res ))) return FALSE;
138 pszSound = LockResource16(handle);
139 fdwSound = (fdwSound & ~SND_RESOURCE) | SND_MEMORY;
140 /* FIXME: FreeResource16 */
143 ReleaseThunkLock(&lc);
144 retv = PlaySoundA(pszSound, 0, fdwSound);
145 RestoreThunkLock(lc);
147 return retv;
150 /**************************************************************************
151 * sndPlaySound [MMSYSTEM.2]
153 BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags)
155 BOOL16 retv;
156 DWORD lc;
158 ReleaseThunkLock(&lc);
159 retv = sndPlaySoundA(lpszSoundName, uFlags);
160 RestoreThunkLock(lc);
162 return retv;
165 /* ###################################################
166 * # MISC #
167 * ###################################################
170 /**************************************************************************
171 * mmsystemGetVersion [MMSYSTEM.5]
174 UINT16 WINAPI mmsystemGetVersion16(void)
176 return mmsystemGetVersion();
179 /**************************************************************************
180 * DriverCallback [MMSYSTEM.31]
182 BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev,
183 WORD wMsg, DWORD dwUser, DWORD dwParam1,
184 DWORD dwParam2)
186 return DriverCallback(dwCallBack, uFlags, HDRVR_32(hDev), wMsg, dwUser, dwParam1, dwParam2);
189 /**************************************************************************
190 * OutputDebugStr [MMSYSTEM.30]
192 void WINAPI OutputDebugStr16(LPCSTR str)
194 OutputDebugStringA( str );
198 /* ###################################################
199 * # MIXER #
200 * ###################################################
203 /**************************************************************************
204 * Mixer devices. New to Win95
207 /**************************************************************************
208 * mixerGetNumDevs [MMSYSTEM.800]
210 UINT16 WINAPI mixerGetNumDevs16(void)
212 return MMDRV_GetNum(MMDRV_MIXER);
215 /**************************************************************************
216 * mixerGetDevCaps [MMSYSTEM.801]
218 UINT16 WINAPI mixerGetDevCaps16(UINT16 uDeviceID, LPMIXERCAPS16 lpCaps,
219 UINT16 uSize)
221 MIXERCAPSA micA;
222 UINT ret;
224 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
226 ret = mixerGetDevCapsA(uDeviceID, &micA, sizeof(micA));
227 if (ret == MMSYSERR_NOERROR) {
228 MIXERCAPS16 mic16;
229 mic16.wMid = micA.wMid;
230 mic16.wPid = micA.wPid;
231 mic16.vDriverVersion = micA.vDriverVersion;
232 strcpy(mic16.szPname, micA.szPname);
233 mic16.fdwSupport = micA.fdwSupport;
234 mic16.cDestinations = micA.cDestinations;
235 memcpy(lpCaps, &mic16, min(uSize, sizeof(mic16)));
237 return ret;
240 /**************************************************************************
241 * mixerOpen [MMSYSTEM.802]
243 UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix, UINT16 uDeviceID, DWORD dwCallback,
244 DWORD dwInstance, DWORD fdwOpen)
246 HMIXER hmix;
247 UINT ret;
249 ret = MIXER_Open(&hmix, uDeviceID, dwCallback, dwInstance, fdwOpen, FALSE);
250 if (lphmix) *lphmix = HMIXER_16(hmix);
251 return ret;
254 /**************************************************************************
255 * mixerClose [MMSYSTEM.803]
257 UINT16 WINAPI mixerClose16(HMIXER16 hMix)
259 return mixerClose(HMIXER_32(hMix));
262 /**************************************************************************
263 * mixerGetID (MMSYSTEM.806)
265 UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID)
267 UINT xid;
268 UINT ret = mixerGetID(HMIXEROBJ_32(hmix), &xid, fdwID);
270 if (lpid)
271 *lpid = xid;
272 return ret;
275 /**************************************************************************
276 * mixerGetControlDetails [MMSYSTEM.808]
278 UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,
279 LPMIXERCONTROLDETAILS16 lpmcd,
280 DWORD fdwDetails)
282 DWORD ret = MMSYSERR_NOTENABLED;
283 SEGPTR sppaDetails;
285 TRACE("(%04x, %p, %08x)\n", hmix, lpmcd, fdwDetails);
287 if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
288 return MMSYSERR_INVALPARAM;
290 sppaDetails = (SEGPTR)lpmcd->paDetails;
291 lpmcd->paDetails = MapSL(sppaDetails);
292 ret = mixerGetControlDetailsA(HMIXEROBJ_32(hmix),
293 (LPMIXERCONTROLDETAILS)lpmcd, fdwDetails);
294 lpmcd->paDetails = (LPVOID)sppaDetails;
296 return ret;
299 /**************************************************************************
300 * mixerGetLineControls [MMSYSTEM.807]
302 UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,
303 LPMIXERLINECONTROLS16 lpmlc16,
304 DWORD fdwControls)
306 MIXERLINECONTROLSA mlcA;
307 DWORD ret;
308 unsigned int i;
309 LPMIXERCONTROL16 lpmc16;
311 TRACE("(%04x, %p, %08x)\n", hmix, lpmlc16, fdwControls);
313 if (lpmlc16 == NULL || lpmlc16->cbStruct != sizeof(*lpmlc16) ||
314 lpmlc16->cbmxctrl != sizeof(MIXERCONTROL16))
315 return MMSYSERR_INVALPARAM;
317 mlcA.cbStruct = sizeof(mlcA);
318 mlcA.dwLineID = lpmlc16->dwLineID;
319 mlcA.u.dwControlID = lpmlc16->u.dwControlID;
320 mlcA.u.dwControlType = lpmlc16->u.dwControlType;
321 mlcA.cControls = lpmlc16->cControls;
322 mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
323 mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
324 mlcA.cControls * mlcA.cbmxctrl);
326 ret = mixerGetLineControlsA(HMIXEROBJ_32(hmix), &mlcA, fdwControls);
328 if (ret == MMSYSERR_NOERROR) {
329 lpmlc16->dwLineID = mlcA.dwLineID;
330 lpmlc16->u.dwControlID = mlcA.u.dwControlID;
331 lpmlc16->u.dwControlType = mlcA.u.dwControlType;
332 lpmlc16->cControls = mlcA.cControls;
334 lpmc16 = MapSL(lpmlc16->pamxctrl);
336 for (i = 0; i < mlcA.cControls; i++) {
337 lpmc16[i].cbStruct = sizeof(MIXERCONTROL16);
338 lpmc16[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
339 lpmc16[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
340 lpmc16[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
341 lpmc16[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
342 strcpy(lpmc16[i].szShortName, mlcA.pamxctrl[i].szShortName);
343 strcpy(lpmc16[i].szName, mlcA.pamxctrl[i].szName);
344 /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
345 memcpy(&lpmc16[i].Bounds, &mlcA.pamxctrl[i].Bounds,
346 sizeof(mlcA.pamxctrl[i].Bounds));
347 /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
348 memcpy(&lpmc16[i].Metrics, &mlcA.pamxctrl[i].Metrics,
349 sizeof(mlcA.pamxctrl[i].Metrics));
353 HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);
355 return ret;
358 /**************************************************************************
359 * mixerGetLineInfo [MMSYSTEM.805]
361 UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16,
362 DWORD fdwInfo)
364 MIXERLINEA mliA;
365 UINT ret;
367 TRACE("(%04x, %p, %08x)\n", hmix, lpmli16, fdwInfo);
369 if (lpmli16 == NULL || lpmli16->cbStruct != sizeof(*lpmli16))
370 return MMSYSERR_INVALPARAM;
372 mliA.cbStruct = sizeof(mliA);
373 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
374 case MIXER_GETLINEINFOF_COMPONENTTYPE:
375 mliA.dwComponentType = lpmli16->dwComponentType;
376 break;
377 case MIXER_GETLINEINFOF_DESTINATION:
378 mliA.dwDestination = lpmli16->dwDestination;
379 break;
380 case MIXER_GETLINEINFOF_LINEID:
381 mliA.dwLineID = lpmli16->dwLineID;
382 break;
383 case MIXER_GETLINEINFOF_SOURCE:
384 mliA.dwDestination = lpmli16->dwDestination;
385 mliA.dwSource = lpmli16->dwSource;
386 break;
387 case MIXER_GETLINEINFOF_TARGETTYPE:
388 mliA.Target.dwType = lpmli16->Target.dwType;
389 mliA.Target.wMid = lpmli16->Target.wMid;
390 mliA.Target.wPid = lpmli16->Target.wPid;
391 mliA.Target.vDriverVersion = lpmli16->Target.vDriverVersion;
392 strcpy(mliA.Target.szPname, lpmli16->Target.szPname);
393 break;
394 default:
395 FIXME("Unsupported fdwControls=0x%08x\n", fdwInfo);
398 ret = mixerGetLineInfoA(HMIXEROBJ_32(hmix), &mliA, fdwInfo);
400 lpmli16->dwDestination = mliA.dwDestination;
401 lpmli16->dwSource = mliA.dwSource;
402 lpmli16->dwLineID = mliA.dwLineID;
403 lpmli16->fdwLine = mliA.fdwLine;
404 lpmli16->dwUser = mliA.dwUser;
405 lpmli16->dwComponentType = mliA.dwComponentType;
406 lpmli16->cChannels = mliA.cChannels;
407 lpmli16->cConnections = mliA.cConnections;
408 lpmli16->cControls = mliA.cControls;
409 strcpy(lpmli16->szShortName, mliA.szShortName);
410 strcpy(lpmli16->szName, mliA.szName);
411 lpmli16->Target.dwType = mliA.Target.dwType;
412 lpmli16->Target.dwDeviceID = mliA.Target.dwDeviceID;
413 lpmli16->Target.wMid = mliA.Target.wMid;
414 lpmli16->Target.wPid = mliA.Target.wPid;
415 lpmli16->Target.vDriverVersion = mliA.Target.vDriverVersion;
416 strcpy(lpmli16->Target.szPname, mliA.Target.szPname);
418 return ret;
421 /**************************************************************************
422 * mixerSetControlDetails [MMSYSTEM.809]
424 UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,
425 LPMIXERCONTROLDETAILS16 lpmcd,
426 DWORD fdwDetails)
428 TRACE("(%04x, %p, %08x)\n", hmix, lpmcd, fdwDetails);
429 return MMSYSERR_NOTENABLED;
432 /**************************************************************************
433 * mixerMessage [MMSYSTEM.804]
435 DWORD WINAPI mixerMessage16(HMIXER16 hmix, UINT16 uMsg, DWORD dwParam1,
436 DWORD dwParam2)
438 return mixerMessage(HMIXER_32(hmix), uMsg, dwParam1, dwParam2);
441 /**************************************************************************
442 * auxGetNumDevs [MMSYSTEM.350]
444 UINT16 WINAPI auxGetNumDevs16(void)
446 return MMDRV_GetNum(MMDRV_AUX);
449 /* ###################################################
450 * # AUX #
451 * ###################################################
454 /**************************************************************************
455 * auxGetDevCaps [MMSYSTEM.351]
457 UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID, LPAUXCAPS16 lpCaps, UINT16 uSize)
459 AUXCAPSA acA;
460 UINT ret;
462 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
464 ret = auxGetDevCapsA(uDeviceID, &acA, sizeof(acA));
465 if (ret == MMSYSERR_NOERROR) {
466 AUXCAPS16 ac16;
467 ac16.wMid = acA.wMid;
468 ac16.wPid = acA.wPid;
469 ac16.vDriverVersion = acA.vDriverVersion;
470 strcpy(ac16.szPname, acA.szPname);
471 ac16.wTechnology = acA.wTechnology;
472 ac16.dwSupport = acA.dwSupport;
473 memcpy(lpCaps, &ac16, min(uSize, sizeof(ac16)));
475 return ret;
478 /**************************************************************************
479 * auxGetVolume [MMSYSTEM.352]
481 UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, LPDWORD lpdwVolume)
483 LPWINE_MLD wmld;
485 TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
487 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
488 return MMSYSERR_INVALHANDLE;
489 return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L, TRUE);
492 /**************************************************************************
493 * auxSetVolume [MMSYSTEM.353]
495 UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
497 LPWINE_MLD wmld;
499 TRACE("(%04X, %u) !\n", uDeviceID, dwVolume);
501 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
502 return MMSYSERR_INVALHANDLE;
503 return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE);
506 /**************************************************************************
507 * auxOutMessage [MMSYSTEM.354]
509 DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
511 LPWINE_MLD wmld;
513 TRACE("(%04X, %04X, %08X, %08X)\n", uDeviceID, uMessage, dw1, dw2);
515 switch (uMessage) {
516 case AUXDM_GETNUMDEVS:
517 case AUXDM_SETVOLUME:
518 /* no argument conversion needed */
519 break;
520 case AUXDM_GETVOLUME:
521 return auxGetVolume16(uDeviceID, MapSL(dw1));
522 case AUXDM_GETDEVCAPS:
523 return auxGetDevCaps16(uDeviceID, MapSL(dw1), dw2);
524 default:
525 TRACE("(%04x, %04x, %08x, %08x): unhandled message\n",
526 uDeviceID, uMessage, dw1, dw2);
527 break;
529 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
530 return MMSYSERR_INVALHANDLE;
532 return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE);
535 /* ###################################################
536 * # MCI #
537 * ###################################################
540 /**************************************************************************
541 * mciGetErrorString [MMSYSTEM.706]
543 BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer, UINT16 uLength)
545 return mciGetErrorStringA(wError, lpstrBuffer, uLength);
548 /**************************************************************************
549 * mciDriverNotify [MMSYSTEM.711]
551 BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
553 TRACE("(%04X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
555 return PostMessageA(HWND_32(hWndCallBack), MM_MCINOTIFY, wStatus, wDevID);
558 /**************************************************************************
559 * mciGetDriverData [MMSYSTEM.708]
561 DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID)
563 return mciGetDriverData(uDeviceID);
566 /**************************************************************************
567 * mciSetDriverData [MMSYSTEM.707]
569 BOOL16 WINAPI mciSetDriverData16(UINT16 uDeviceID, DWORD data)
571 return mciSetDriverData(uDeviceID, data);
574 /**************************************************************************
575 * mciSendCommand [MMSYSTEM.701]
577 DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
579 DWORD dwRet;
581 TRACE("(%04X, %s, %08X, %08X)\n",
582 wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
584 dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, FALSE);
585 dwRet = MCI_CleanUp(dwRet, wMsg, (DWORD)MapSL(dwParam2));
586 TRACE("=> %d\n", dwRet);
587 return dwRet;
590 /**************************************************************************
591 * mciGetDeviceID [MMSYSTEM.703]
593 UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
595 TRACE("(\"%s\")\n", lpstrName);
597 return mciGetDeviceIDA(lpstrName);
600 /**************************************************************************
601 * mciSetYieldProc [MMSYSTEM.714]
603 BOOL16 WINAPI mciSetYieldProc16(UINT16 uDeviceID, YIELDPROC16 fpYieldProc, DWORD dwYieldData)
605 LPWINE_MCIDRIVER wmd;
607 TRACE("(%u, %p, %08x)\n", uDeviceID, fpYieldProc, dwYieldData);
609 if (!(wmd = MCI_GetDriver(uDeviceID))) {
610 WARN("Bad uDeviceID\n");
611 return FALSE;
614 wmd->lpfnYieldProc = (YIELDPROC)fpYieldProc;
615 wmd->dwYieldData = dwYieldData;
616 wmd->bIs32 = FALSE;
618 return TRUE;
621 /**************************************************************************
622 * mciGetDeviceIDFromElementID [MMSYSTEM.715]
624 UINT16 WINAPI mciGetDeviceIDFromElementID16(DWORD dwElementID, LPCSTR lpstrType)
626 FIXME("(%u, %s) stub\n", dwElementID, lpstrType);
627 return 0;
630 /**************************************************************************
631 * mciGetYieldProc [MMSYSTEM.716]
633 YIELDPROC16 WINAPI mciGetYieldProc16(UINT16 uDeviceID, DWORD* lpdwYieldData)
635 LPWINE_MCIDRIVER wmd;
637 TRACE("(%u, %p)\n", uDeviceID, lpdwYieldData);
639 if (!(wmd = MCI_GetDriver(uDeviceID))) {
640 WARN("Bad uDeviceID\n");
641 return NULL;
643 if (!wmd->lpfnYieldProc) {
644 WARN("No proc set\n");
645 return NULL;
647 if (wmd->bIs32) {
648 WARN("Proc is 32 bit\n");
649 return NULL;
651 if (lpdwYieldData) *lpdwYieldData = wmd->dwYieldData;
652 return (YIELDPROC16)wmd->lpfnYieldProc;
655 /**************************************************************************
656 * mciGetCreatorTask [MMSYSTEM.717]
658 HTASK16 WINAPI mciGetCreatorTask16(UINT16 uDeviceID)
660 LPWINE_MCIDRIVER wmd;
661 HTASK16 ret = 0;
663 if ((wmd = MCI_GetDriver(uDeviceID)))
664 ret = HTASK_16(wmd->CreatorThread);
666 TRACE("(%u) => %04x\n", uDeviceID, ret);
667 return ret;
670 /**************************************************************************
671 * mciDriverYield [MMSYSTEM.710]
673 UINT16 WINAPI mciDriverYield16(UINT16 uDeviceID)
675 LPWINE_MCIDRIVER wmd;
676 UINT16 ret = 0;
678 /* TRACE("(%04x)\n", uDeviceID); */
680 if (!(wmd = MCI_GetDriver(uDeviceID)) || !wmd->lpfnYieldProc || wmd->bIs32) {
681 UserYield16();
682 } else {
683 ret = wmd->lpfnYieldProc(uDeviceID, wmd->dwYieldData);
686 return ret;
689 /* ###################################################
690 * # MIDI #
691 * ###################################################
694 /**************************************************************************
695 * midiOutGetNumDevs [MMSYSTEM.201]
697 UINT16 WINAPI midiOutGetNumDevs16(void)
699 return MMDRV_GetNum(MMDRV_MIDIOUT);
702 /**************************************************************************
703 * midiOutGetDevCaps [MMSYSTEM.202]
705 UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID, LPMIDIOUTCAPS16 lpCaps,
706 UINT16 uSize)
708 MIDIOUTCAPSA mocA;
709 UINT ret;
711 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
713 ret = midiOutGetDevCapsA(uDeviceID, &mocA, sizeof(mocA));
714 if (ret == MMSYSERR_NOERROR) {
715 MIDIOUTCAPS16 moc16;
716 moc16.wMid = mocA.wMid;
717 moc16.wPid = mocA.wPid;
718 moc16.vDriverVersion = mocA.vDriverVersion;
719 strcpy(moc16.szPname, mocA.szPname);
720 moc16.wTechnology = mocA.wTechnology;
721 moc16.wVoices = mocA.wVoices;
722 moc16.wNotes = mocA.wNotes;
723 moc16.wChannelMask = mocA.wChannelMask;
724 moc16.dwSupport = mocA.dwSupport;
725 memcpy(lpCaps, &moc16, min(uSize, sizeof(moc16)));
727 return ret;
730 /**************************************************************************
731 * midiOutGetErrorText [MMSYSTEM.203]
732 * midiInGetErrorText [MMSYSTEM.303]
734 UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
736 return midiOutGetErrorTextA(uError, lpText, uSize);
739 /**************************************************************************
740 * midiOutOpen [MMSYSTEM.204]
742 UINT16 WINAPI midiOutOpen16(HMIDIOUT16* lphMidiOut, UINT16 uDeviceID,
743 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
745 HMIDIOUT hmo;
746 UINT ret;
748 ret = MIDI_OutOpen(&hmo, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
750 if (lphMidiOut != NULL) *lphMidiOut = HMIDIOUT_16(hmo);
751 return ret;
754 /**************************************************************************
755 * midiOutClose [MMSYSTEM.205]
757 UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
759 return midiOutClose(HMIDIOUT_32(hMidiOut));
762 /**************************************************************************
763 * midiOutPrepareHeader [MMSYSTEM.206]
765 UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
766 SEGPTR lpsegMidiOutHdr, /* [???] */
767 UINT16 uSize) /* [in] */
769 LPWINE_MLD wmld;
771 TRACE("(%04X, %08x, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
773 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
774 return MMSYSERR_INVALHANDLE;
776 return MMDRV_Message(wmld, MODM_PREPARE, lpsegMidiOutHdr, uSize, FALSE);
779 /**************************************************************************
780 * midiOutUnprepareHeader [MMSYSTEM.207]
782 UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
783 SEGPTR lpsegMidiOutHdr, /* [???] */
784 UINT16 uSize) /* [in] */
786 LPWINE_MLD wmld;
787 LPMIDIHDR16 lpMidiOutHdr = MapSL(lpsegMidiOutHdr);
789 TRACE("(%04X, %08x, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
791 if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
792 return MMSYSERR_NOERROR;
795 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
796 return MMSYSERR_INVALHANDLE;
798 return MMDRV_Message(wmld, MODM_UNPREPARE, lpsegMidiOutHdr, uSize, FALSE);
801 /**************************************************************************
802 * midiOutShortMsg [MMSYSTEM.208]
804 UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
806 return midiOutShortMsg(HMIDIOUT_32(hMidiOut), dwMsg);
809 /**************************************************************************
810 * midiOutLongMsg [MMSYSTEM.209]
812 UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut, /* [in] */
813 LPMIDIHDR16 lpsegMidiOutHdr, /* [???] NOTE: SEGPTR */
814 UINT16 uSize) /* [in] */
816 LPWINE_MLD wmld;
818 TRACE("(%04X, %p, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
820 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
821 return MMSYSERR_INVALHANDLE;
823 return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpsegMidiOutHdr, uSize, FALSE);
826 /**************************************************************************
827 * midiOutReset [MMSYSTEM.210]
829 UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
831 return midiOutReset(HMIDIOUT_32(hMidiOut));
834 /**************************************************************************
835 * midiOutGetVolume [MMSYSTEM.211]
837 UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD* lpdwVolume)
839 return midiOutGetVolume(HMIDIOUT_32(uDeviceID), lpdwVolume);
842 /**************************************************************************
843 * midiOutSetVolume [MMSYSTEM.212]
845 UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
847 return midiOutSetVolume(HMIDIOUT_32(uDeviceID), dwVolume);
850 /**************************************************************************
851 * midiOutCachePatches [MMSYSTEM.213]
853 UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
854 WORD* lpwPatchArray, UINT16 uFlags)
856 return midiOutCachePatches(HMIDIOUT_32(hMidiOut), uBank, lpwPatchArray,
857 uFlags);
860 /**************************************************************************
861 * midiOutCacheDrumPatches [MMSYSTEM.214]
863 UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
864 WORD* lpwKeyArray, UINT16 uFlags)
866 return midiOutCacheDrumPatches(HMIDIOUT_32(hMidiOut), uPatch, lpwKeyArray, uFlags);
869 /**************************************************************************
870 * midiOutGetID [MMSYSTEM.215]
872 UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16* lpuDeviceID)
874 LPWINE_MLD wmld;
876 TRACE("(%04X, %p)\n", hMidiOut, lpuDeviceID);
878 if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
879 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
880 return MMSYSERR_INVALHANDLE;
882 *lpuDeviceID = wmld->uDeviceID;
883 return MMSYSERR_NOERROR;
886 /**************************************************************************
887 * midiOutMessage [MMSYSTEM.216]
889 DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage,
890 DWORD dwParam1, DWORD dwParam2)
892 LPWINE_MLD wmld;
894 TRACE("(%04X, %04X, %08X, %08X)\n", hMidiOut, uMessage, dwParam1, dwParam2);
896 if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
897 return MMSYSERR_INVALHANDLE;
899 switch (uMessage) {
900 case MODM_OPEN:
901 case MODM_CLOSE:
902 FIXME("can't handle OPEN or CLOSE message!\n");
903 return MMSYSERR_NOTSUPPORTED;
905 case MODM_GETVOLUME:
906 return midiOutGetVolume16(hMidiOut, MapSL(dwParam1));
907 case MODM_LONGDATA:
908 return midiOutLongMsg16(hMidiOut, MapSL(dwParam1), dwParam2);
909 case MODM_PREPARE:
910 /* lpMidiOutHdr is still a segmented pointer for this function */
911 return midiOutPrepareHeader16(hMidiOut, dwParam1, dwParam2);
912 case MODM_UNPREPARE:
913 return midiOutUnprepareHeader16(hMidiOut, dwParam1, dwParam2);
915 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
918 /**************************************************************************
919 * midiInGetNumDevs [MMSYSTEM.301]
921 UINT16 WINAPI midiInGetNumDevs16(void)
923 return MMDRV_GetNum(MMDRV_MIDIIN);
926 /**************************************************************************
927 * midiInGetDevCaps [MMSYSTEM.302]
929 UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID, LPMIDIINCAPS16 lpCaps,
930 UINT16 uSize)
932 MIDIINCAPSA micA;
933 UINT ret;
935 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
937 ret = midiInGetDevCapsA(uDeviceID, &micA, uSize);
938 if (ret == MMSYSERR_NOERROR) {
939 MIDIINCAPS16 mic16;
940 mic16.wMid = micA.wMid;
941 mic16.wPid = micA.wPid;
942 mic16.vDriverVersion = micA.vDriverVersion;
943 strcpy(mic16.szPname, micA.szPname);
944 mic16.dwSupport = micA.dwSupport;
945 memcpy(lpCaps, &mic16, min(uSize, sizeof(mic16)));
947 return ret;
950 /**************************************************************************
951 * midiInOpen [MMSYSTEM.304]
953 UINT16 WINAPI midiInOpen16(HMIDIIN16* lphMidiIn, UINT16 uDeviceID,
954 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
956 HMIDIIN xhmid;
957 UINT ret;
959 ret = MIDI_InOpen(&xhmid, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
961 if (lphMidiIn) *lphMidiIn = HMIDIIN_16(xhmid);
962 return ret;
965 /**************************************************************************
966 * midiInClose [MMSYSTEM.305]
968 UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
970 return midiInClose(HMIDIIN_32(hMidiIn));
973 /**************************************************************************
974 * midiInPrepareHeader [MMSYSTEM.306]
976 UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
977 SEGPTR lpsegMidiInHdr, /* [???] */
978 UINT16 uSize) /* [in] */
980 LPWINE_MLD wmld;
982 TRACE("(%04X, %08x, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
984 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
985 return MMSYSERR_INVALHANDLE;
987 return MMDRV_Message(wmld, MIDM_PREPARE, lpsegMidiInHdr, uSize, FALSE);
990 /**************************************************************************
991 * midiInUnprepareHeader [MMSYSTEM.307]
993 UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
994 SEGPTR lpsegMidiInHdr, /* [???] */
995 UINT16 uSize) /* [in] */
997 LPWINE_MLD wmld;
998 LPMIDIHDR16 lpMidiInHdr = MapSL(lpsegMidiInHdr);
1000 TRACE("(%04X, %08x, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
1002 if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
1003 return MMSYSERR_NOERROR;
1006 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
1007 return MMSYSERR_INVALHANDLE;
1009 return MMDRV_Message(wmld, MIDM_UNPREPARE, lpsegMidiInHdr, uSize, FALSE);
1012 /**************************************************************************
1013 * midiInAddBuffer [MMSYSTEM.308]
1015 UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn, /* [in] */
1016 MIDIHDR16* lpsegMidiInHdr, /* [???] NOTE: SEGPTR */
1017 UINT16 uSize) /* [in] */
1019 LPWINE_MLD wmld;
1021 TRACE("(%04X, %p, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
1023 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
1024 return MMSYSERR_INVALHANDLE;
1026 return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD_PTR)lpsegMidiInHdr, uSize, FALSE);
1029 /**************************************************************************
1030 * midiInStart [MMSYSTEM.309]
1032 UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
1034 return midiInStart(HMIDIIN_32(hMidiIn));
1037 /**************************************************************************
1038 * midiInStop [MMSYSTEM.310]
1040 UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
1042 return midiInStop(HMIDIIN_32(hMidiIn));
1045 /**************************************************************************
1046 * midiInReset [MMSYSTEM.311]
1048 UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
1050 return midiInReset(HMIDIIN_32(hMidiIn));
1053 /**************************************************************************
1054 * midiInGetID [MMSYSTEM.312]
1056 UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
1058 LPWINE_MLD wmld;
1060 TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID);
1062 if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1064 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, TRUE)) == NULL)
1065 return MMSYSERR_INVALHANDLE;
1067 *lpuDeviceID = wmld->uDeviceID;
1069 return MMSYSERR_NOERROR;
1072 /**************************************************************************
1073 * midiInMessage [MMSYSTEM.313]
1075 DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage,
1076 DWORD dwParam1, DWORD dwParam2)
1078 LPWINE_MLD wmld;
1080 TRACE("(%04X, %04X, %08X, %08X)\n", hMidiIn, uMessage, dwParam1, dwParam2);
1082 switch (uMessage) {
1083 case MIDM_OPEN:
1084 case MIDM_CLOSE:
1085 FIXME("can't handle OPEN or CLOSE message!\n");
1086 return MMSYSERR_NOTSUPPORTED;
1088 case MIDM_GETDEVCAPS:
1089 return midiInGetDevCaps16(hMidiIn, MapSL(dwParam1), dwParam2);
1090 case MIDM_PREPARE:
1091 return midiInPrepareHeader16(hMidiIn, dwParam1, dwParam2);
1092 case MIDM_UNPREPARE:
1093 return midiInUnprepareHeader16(hMidiIn, dwParam1, dwParam2);
1094 case MIDM_ADDBUFFER:
1095 return midiInAddBuffer16(hMidiIn, MapSL(dwParam1), dwParam2);
1098 if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
1099 return MMSYSERR_INVALHANDLE;
1101 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1104 /**************************************************************************
1105 * midiStreamClose [MMSYSTEM.252]
1107 MMRESULT16 WINAPI midiStreamClose16(HMIDISTRM16 hMidiStrm)
1109 return midiStreamClose(HMIDISTRM_32(hMidiStrm));
1112 /**************************************************************************
1113 * midiStreamOpen [MMSYSTEM.251]
1115 MMRESULT16 WINAPI midiStreamOpen16(HMIDISTRM16* phMidiStrm, LPUINT16 devid,
1116 DWORD cMidi, DWORD dwCallback,
1117 DWORD dwInstance, DWORD fdwOpen)
1119 HMIDISTRM hMidiStrm32;
1120 MMRESULT ret;
1121 UINT devid32;
1123 if (!phMidiStrm || !devid)
1124 return MMSYSERR_INVALPARAM;
1125 devid32 = *devid;
1126 ret = MIDI_StreamOpen(&hMidiStrm32, &devid32, cMidi, dwCallback,
1127 dwInstance, fdwOpen, FALSE);
1128 *phMidiStrm = HMIDISTRM_16(hMidiStrm32);
1129 *devid = devid32;
1130 return ret;
1133 /**************************************************************************
1134 * midiStreamOut [MMSYSTEM.254]
1136 MMRESULT16 WINAPI midiStreamOut16(HMIDISTRM16 hMidiStrm, LPMIDIHDR16 lpMidiHdr, UINT16 cbMidiHdr)
1138 return midiStreamOut(HMIDISTRM_32(hMidiStrm), (LPMIDIHDR)lpMidiHdr,
1139 cbMidiHdr);
1142 /**************************************************************************
1143 * midiStreamPause [MMSYSTEM.255]
1145 MMRESULT16 WINAPI midiStreamPause16(HMIDISTRM16 hMidiStrm)
1147 return midiStreamPause(HMIDISTRM_32(hMidiStrm));
1150 /**************************************************************************
1151 * midiStreamPosition [MMSYSTEM.253]
1153 MMRESULT16 WINAPI midiStreamPosition16(HMIDISTRM16 hMidiStrm, LPMMTIME16 lpmmt16, UINT16 cbmmt)
1155 MMTIME mmt32;
1156 MMRESULT ret;
1158 if (!lpmmt16)
1159 return MMSYSERR_INVALPARAM;
1160 MMSYSTEM_MMTIME16to32(&mmt32, lpmmt16);
1161 ret = midiStreamPosition(HMIDISTRM_32(hMidiStrm), &mmt32, sizeof(MMTIME));
1162 MMSYSTEM_MMTIME32to16(lpmmt16, &mmt32);
1163 return ret;
1166 /**************************************************************************
1167 * midiStreamProperty [MMSYSTEM.250]
1169 MMRESULT16 WINAPI midiStreamProperty16(HMIDISTRM16 hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
1171 return midiStreamProperty(HMIDISTRM_32(hMidiStrm), lpPropData, dwProperty);
1174 /**************************************************************************
1175 * midiStreamRestart [MMSYSTEM.256]
1177 MMRESULT16 WINAPI midiStreamRestart16(HMIDISTRM16 hMidiStrm)
1179 return midiStreamRestart(HMIDISTRM_32(hMidiStrm));
1182 /**************************************************************************
1183 * midiStreamStop [MMSYSTEM.257]
1185 MMRESULT16 WINAPI midiStreamStop16(HMIDISTRM16 hMidiStrm)
1187 return midiStreamStop(HMIDISTRM_32(hMidiStrm));
1190 /* ###################################################
1191 * # WAVE #
1192 * ###################################################
1195 /**************************************************************************
1196 * waveOutGetNumDevs [MMSYSTEM.401]
1198 UINT16 WINAPI waveOutGetNumDevs16(void)
1200 return MMDRV_GetNum(MMDRV_WAVEOUT);
1203 /**************************************************************************
1204 * waveOutGetDevCaps [MMSYSTEM.402]
1206 UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID,
1207 LPWAVEOUTCAPS16 lpCaps, UINT16 uSize)
1209 WAVEOUTCAPSA wocA;
1210 UINT ret;
1211 TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
1213 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1215 ret = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(wocA));
1216 if (ret == MMSYSERR_NOERROR) {
1217 WAVEOUTCAPS16 woc16;
1218 woc16.wMid = wocA.wMid;
1219 woc16.wPid = wocA.wPid;
1220 woc16.vDriverVersion = wocA.vDriverVersion;
1221 strcpy(woc16.szPname, wocA.szPname);
1222 woc16.dwFormats = wocA.dwFormats;
1223 woc16.wChannels = wocA.wChannels;
1224 woc16.dwSupport = wocA.dwSupport;
1225 memcpy(lpCaps, &woc16, min(uSize, sizeof(woc16)));
1227 return ret;
1230 /**************************************************************************
1231 * waveOutGetErrorText [MMSYSTEM.403]
1232 * waveInGetErrorText [MMSYSTEM.503]
1234 UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
1236 return waveOutGetErrorTextA(uError, lpText, uSize);
1239 /**************************************************************************
1240 * waveOutOpen [MMSYSTEM.404]
1242 UINT16 WINAPI waveOutOpen16(HWAVEOUT16* lphWaveOut, UINT16 uDeviceID,
1243 LPCWAVEFORMATEX lpFormat, DWORD dwCallback,
1244 DWORD dwInstance, DWORD dwFlags)
1246 HANDLE hWaveOut;
1247 UINT ret;
1249 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1250 * call the 32 bit version
1251 * however, we need to promote correctly the wave mapper id
1252 * (0xFFFFFFFF and not 0x0000FFFF)
1254 ret = WAVE_Open(&hWaveOut, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1255 MMDRV_WAVEOUT, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1257 if (lphWaveOut != NULL) *lphWaveOut = HWAVEOUT_16(hWaveOut);
1258 return ret;
1261 /**************************************************************************
1262 * waveOutClose [MMSYSTEM.405]
1264 UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
1266 DWORD level;
1267 UINT16 ret;
1269 ReleaseThunkLock(&level);
1270 ret = waveOutClose(HWAVEOUT_32(hWaveOut));
1271 RestoreThunkLock(level);
1272 return ret;
1275 /**************************************************************************
1276 * waveOutPrepareHeader [MMSYSTEM.406]
1278 UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
1279 SEGPTR lpsegWaveOutHdr, /* [???] */
1280 UINT16 uSize) /* [in] */
1282 LPWINE_MLD wmld;
1283 LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1284 UINT16 result;
1286 TRACE("(%04X, %08x, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1288 if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM;
1290 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1291 return MMSYSERR_INVALHANDLE;
1293 if ((result = MMDRV_Message(wmld, WODM_PREPARE, lpsegWaveOutHdr,
1294 uSize, FALSE)) != MMSYSERR_NOTSUPPORTED)
1295 return result;
1297 if (lpWaveOutHdr->dwFlags & WHDR_INQUEUE)
1298 return WAVERR_STILLPLAYING;
1300 lpWaveOutHdr->dwFlags |= WHDR_PREPARED;
1301 lpWaveOutHdr->dwFlags &= ~WHDR_DONE;
1303 return MMSYSERR_NOERROR;
1306 /**************************************************************************
1307 * waveOutUnprepareHeader [MMSYSTEM.407]
1309 UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
1310 SEGPTR lpsegWaveOutHdr, /* [???] */
1311 UINT16 uSize) /* [in] */
1313 LPWINE_MLD wmld;
1314 LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1316 TRACE("(%04X, %08x, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1318 if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
1319 return MMSYSERR_NOERROR;
1322 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1323 return MMSYSERR_INVALHANDLE;
1325 return MMDRV_Message(wmld, WODM_UNPREPARE, lpsegWaveOutHdr, uSize, FALSE);
1328 /**************************************************************************
1329 * waveOutWrite [MMSYSTEM.408]
1331 UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, /* [in] */
1332 LPWAVEHDR lpsegWaveOutHdr, /* [???] NOTE: SEGPTR */
1333 UINT16 uSize) /* [in] */
1335 LPWINE_MLD wmld;
1337 TRACE("(%04X, %p, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1339 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1340 return MMSYSERR_INVALHANDLE;
1342 return MMDRV_Message(wmld, WODM_WRITE, (DWORD_PTR)lpsegWaveOutHdr, uSize, FALSE);
1345 /**************************************************************************
1346 * waveOutBreakLoop [MMSYSTEM.419]
1348 UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut16)
1350 DWORD level;
1351 UINT16 ret;
1353 ReleaseThunkLock(&level);
1354 ret = waveOutBreakLoop(HWAVEOUT_32(hWaveOut16));
1355 RestoreThunkLock(level);
1356 return ret;
1359 /**************************************************************************
1360 * waveOutPause [MMSYSTEM.409]
1362 UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut16)
1364 DWORD level;
1365 UINT16 ret;
1367 ReleaseThunkLock(&level);
1368 ret = waveOutPause(HWAVEOUT_32(hWaveOut16));
1369 RestoreThunkLock(level);
1370 return ret;
1373 /**************************************************************************
1374 * waveOutReset [MMSYSTEM.411]
1376 UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut16)
1378 DWORD level;
1379 UINT16 ret;
1381 ReleaseThunkLock(&level);
1382 ret = waveOutReset(HWAVEOUT_32(hWaveOut16));
1383 RestoreThunkLock(level);
1384 return ret;
1387 /**************************************************************************
1388 * waveOutRestart [MMSYSTEM.410]
1390 UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut16)
1392 DWORD level;
1393 UINT16 ret;
1395 ReleaseThunkLock(&level);
1396 ret = waveOutRestart(HWAVEOUT_32(hWaveOut16));
1397 RestoreThunkLock(level);
1398 return ret;
1401 /**************************************************************************
1402 * waveOutGetPosition [MMSYSTEM.412]
1404 UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut, LPMMTIME16 lpTime,
1405 UINT16 uSize)
1407 UINT ret;
1408 MMTIME mmt;
1410 mmt.wType = lpTime->wType;
1411 ret = waveOutGetPosition(HWAVEOUT_32(hWaveOut), &mmt, sizeof(mmt));
1412 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1413 return ret;
1416 /**************************************************************************
1417 * waveOutGetPitch [MMSYSTEM.413]
1419 UINT16 WINAPI waveOutGetPitch16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
1421 return waveOutGetPitch(HWAVEOUT_32(hWaveOut16), lpdw);
1424 /**************************************************************************
1425 * waveOutSetPitch [MMSYSTEM.414]
1427 UINT16 WINAPI waveOutSetPitch16(HWAVEOUT16 hWaveOut16, DWORD dw)
1429 return waveOutSetPitch(HWAVEOUT_32(hWaveOut16), dw);
1432 /**************************************************************************
1433 * waveOutGetPlaybackRate [MMSYSTEM.417]
1435 UINT16 WINAPI waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
1437 return waveOutGetPlaybackRate(HWAVEOUT_32(hWaveOut16), lpdw);
1440 /**************************************************************************
1441 * waveOutSetPlaybackRate [MMSYSTEM.418]
1443 UINT16 WINAPI waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16, DWORD dw)
1445 return waveOutSetPlaybackRate(HWAVEOUT_32(hWaveOut16), dw);
1448 /**************************************************************************
1449 * waveOutGetVolume [MMSYSTEM.415]
1451 UINT16 WINAPI waveOutGetVolume16(UINT16 devid, LPDWORD lpdw)
1453 return waveOutGetVolume(HWAVEOUT_32(devid), lpdw);
1456 /**************************************************************************
1457 * waveOutSetVolume [MMSYSTEM.416]
1459 UINT16 WINAPI waveOutSetVolume16(UINT16 devid, DWORD dw)
1461 return waveOutSetVolume(HWAVEOUT_32(devid), dw);
1464 /**************************************************************************
1465 * waveOutGetID [MMSYSTEM.420]
1467 UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16* lpuDeviceID)
1469 LPWINE_MLD wmld;
1471 TRACE("(%04X, %p);\n", hWaveOut, lpuDeviceID);
1473 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1475 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1476 return MMSYSERR_INVALHANDLE;
1478 *lpuDeviceID = wmld->uDeviceID;
1479 return 0;
1482 /**************************************************************************
1483 * waveOutMessage [MMSYSTEM.421]
1485 DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage,
1486 DWORD dwParam1, DWORD dwParam2)
1488 LPWINE_MLD wmld;
1490 TRACE("(%04x, %u, %d, %d)\n", hWaveOut, uMessage, dwParam1, dwParam2);
1492 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) {
1493 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, TRUE)) != NULL) {
1494 if (uMessage == DRV_QUERYDRVENTRY || uMessage == DRV_QUERYDEVNODE)
1495 dwParam1 = (DWORD)MapSL(dwParam1);
1496 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1498 return MMSYSERR_INVALHANDLE;
1501 /* from M$ KB */
1502 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1503 return MMSYSERR_INVALPARAM;
1505 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1508 /**************************************************************************
1509 * waveInGetNumDevs [MMSYSTEM.501]
1511 UINT16 WINAPI waveInGetNumDevs16(void)
1513 return MMDRV_GetNum(MMDRV_WAVEIN);
1516 /**************************************************************************
1517 * waveInGetDevCaps [MMSYSTEM.502]
1519 UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps,
1520 UINT16 uSize)
1522 WAVEINCAPSA wicA;
1523 UINT ret;
1525 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1527 ret = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(wicA));
1528 if (ret == MMSYSERR_NOERROR) {
1529 WAVEINCAPS16 wic16;
1530 wic16.wMid = wicA.wMid;
1531 wic16.wPid = wicA.wPid;
1532 wic16.vDriverVersion = wicA.vDriverVersion;
1533 strcpy(wic16.szPname, wicA.szPname);
1534 wic16.dwFormats = wicA.dwFormats;
1535 wic16.wChannels = wicA.wChannels;
1536 memcpy(lpCaps, &wic16, min(uSize, sizeof(wic16)));
1538 return ret;
1541 /**************************************************************************
1542 * waveInOpen [MMSYSTEM.504]
1544 UINT16 WINAPI waveInOpen16(HWAVEIN16* lphWaveIn, UINT16 uDeviceID,
1545 LPCWAVEFORMATEX lpFormat, DWORD dwCallback,
1546 DWORD dwInstance, DWORD dwFlags)
1548 HANDLE hWaveIn;
1549 UINT ret;
1551 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1552 * call the 32 bit version
1553 * however, we need to promote correctly the wave mapper id
1554 * (0xFFFFFFFF and not 0x0000FFFF)
1556 ret = WAVE_Open(&hWaveIn, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1557 MMDRV_WAVEIN, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1559 if (lphWaveIn != NULL) *lphWaveIn = HWAVEIN_16(hWaveIn);
1560 return ret;
1563 /**************************************************************************
1564 * waveInClose [MMSYSTEM.505]
1566 UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
1568 DWORD level;
1569 UINT16 ret;
1571 ReleaseThunkLock(&level);
1572 ret = waveInClose(HWAVEIN_32(hWaveIn));
1573 RestoreThunkLock(level);
1574 return ret;
1577 /**************************************************************************
1578 * waveInPrepareHeader [MMSYSTEM.506]
1580 UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1581 SEGPTR lpsegWaveInHdr, /* [???] */
1582 UINT16 uSize) /* [in] */
1584 LPWINE_MLD wmld;
1585 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1586 UINT16 ret;
1588 TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
1590 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1591 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1592 return MMSYSERR_INVALHANDLE;
1594 lpWaveInHdr->dwBytesRecorded = 0;
1596 ret = MMDRV_Message(wmld, WIDM_PREPARE, lpsegWaveInHdr, uSize, FALSE);
1597 return ret;
1600 /**************************************************************************
1601 * waveInUnprepareHeader [MMSYSTEM.507]
1603 UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1604 SEGPTR lpsegWaveInHdr, /* [???] */
1605 UINT16 uSize) /* [in] */
1607 LPWINE_MLD wmld;
1608 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1610 TRACE("(%04X, %08x, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1612 if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1614 if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) {
1615 return MMSYSERR_NOERROR;
1618 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1619 return MMSYSERR_INVALHANDLE;
1621 return MMDRV_Message(wmld, WIDM_UNPREPARE, lpsegWaveInHdr, uSize, FALSE);
1624 /**************************************************************************
1625 * waveInAddBuffer [MMSYSTEM.508]
1627 UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn, /* [in] */
1628 WAVEHDR* lpsegWaveInHdr, /* [???] NOTE: SEGPTR */
1629 UINT16 uSize) /* [in] */
1631 LPWINE_MLD wmld;
1633 TRACE("(%04X, %p, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1635 if (lpsegWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1636 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1637 return MMSYSERR_INVALHANDLE;
1639 return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD_PTR)lpsegWaveInHdr, uSize, FALSE);
1642 /**************************************************************************
1643 * waveInReset [MMSYSTEM.511]
1645 UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn16)
1647 DWORD level;
1648 UINT16 ret;
1650 ReleaseThunkLock(&level);
1651 ret = waveInReset(HWAVEIN_32(hWaveIn16));
1652 RestoreThunkLock(level);
1653 return ret;
1656 /**************************************************************************
1657 * waveInStart [MMSYSTEM.509]
1659 UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn16)
1661 DWORD level;
1662 UINT16 ret;
1664 ReleaseThunkLock(&level);
1665 ret = waveInStart(HWAVEIN_32(hWaveIn16));
1666 RestoreThunkLock(level);
1667 return ret;
1670 /**************************************************************************
1671 * waveInStop [MMSYSTEM.510]
1673 UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn16)
1675 DWORD level;
1676 UINT16 ret;
1678 ReleaseThunkLock(&level);
1679 ret = waveInStop(HWAVEIN_32(hWaveIn16));
1680 RestoreThunkLock(level);
1681 return ret;
1684 /**************************************************************************
1685 * waveInGetPosition [MMSYSTEM.512]
1687 UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn, LPMMTIME16 lpTime,
1688 UINT16 uSize)
1690 UINT ret;
1691 MMTIME mmt;
1693 mmt.wType = lpTime->wType;
1694 ret = waveInGetPosition(HWAVEIN_32(hWaveIn), &mmt, sizeof(mmt));
1695 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1696 return ret;
1699 /**************************************************************************
1700 * waveInGetID [MMSYSTEM.513]
1702 UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16* lpuDeviceID)
1704 LPWINE_MLD wmld;
1706 TRACE("(%04X, %p);\n", hWaveIn, lpuDeviceID);
1708 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1710 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1711 return MMSYSERR_INVALHANDLE;
1713 *lpuDeviceID = wmld->uDeviceID;
1714 return MMSYSERR_NOERROR;
1717 /**************************************************************************
1718 * waveInMessage [MMSYSTEM.514]
1720 DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
1721 DWORD dwParam1, DWORD dwParam2)
1723 LPWINE_MLD wmld;
1725 TRACE("(%04x, %u, %d, %d)\n", hWaveIn, uMessage, dwParam1, dwParam2);
1727 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL) {
1728 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, TRUE)) != NULL) {
1729 if (uMessage == DRV_QUERYDRVENTRY || uMessage == DRV_QUERYDEVNODE)
1730 dwParam1 = (DWORD)MapSL(dwParam1);
1731 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1733 return MMSYSERR_INVALHANDLE;
1736 /* from M$ KB */
1737 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1738 return MMSYSERR_INVALPARAM;
1740 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1743 /* ###################################################
1744 * # TASK #
1745 * ###################################################
1748 /*#define USE_MM_TSK_WINE*/
1750 /**************************************************************************
1751 * mmTaskCreate [MMSYSTEM.900]
1753 * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be
1754 * called upon creation with dwPmt as parameter.
1756 HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD dwPmt)
1758 HINSTANCE16 ret;
1759 HINSTANCE16 handle;
1760 char cmdline[16];
1761 DWORD showCmd = 0x40002;
1762 LOADPARAMS16 lp;
1764 TRACE("(%08x, %p, %08x);\n", spProc, lphMmTask, dwPmt);
1765 /* This to work requires NE modules to be started with a binary command line
1766 * which is not currently the case. A patch exists but has never been committed.
1767 * A workaround would be to integrate code for mmtask.tsk into Wine, but
1768 * this requires tremendous work (starting with patching tools/build to
1769 * create NE executables (and not only DLLs) for builtins modules.
1770 * EP 99/04/25
1772 FIXME("This is currently broken. It will fail\n");
1774 cmdline[0] = 0x0d;
1775 *(LPDWORD)(cmdline + 1) = (DWORD)spProc;
1776 *(LPDWORD)(cmdline + 5) = dwPmt;
1777 *(LPDWORD)(cmdline + 9) = 0;
1779 lp.hEnvironment = 0;
1780 lp.cmdLine = MapLS(cmdline);
1781 lp.showCmd = MapLS(&showCmd);
1782 lp.reserved = 0;
1784 #ifndef USE_MM_TSK_WINE
1785 handle = LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp);
1786 #else
1787 handle = LoadModule16("mmtask.tsk", &lp);
1788 #endif
1789 if (handle < 32) {
1790 ret = (handle) ? 1 : 2;
1791 handle = 0;
1792 } else {
1793 ret = 0;
1795 if (lphMmTask)
1796 *lphMmTask = handle;
1798 UnMapLS( lp.cmdLine );
1799 UnMapLS( lp.showCmd );
1800 TRACE("=> 0x%04x/%d\n", handle, ret);
1801 return ret;
1804 #ifdef USE_MM_TSK_WINE
1805 /* C equivalent to mmtask.tsk binary content */
1806 void mmTaskEntryPoint16(LPSTR cmdLine, WORD di, WORD si)
1808 int len = cmdLine[0x80];
1810 if (len / 2 == 6) {
1811 void (*fpProc)(DWORD) = MapSL(*((DWORD*)(cmdLine + 1)));
1812 DWORD dwPmt = *((DWORD*)(cmdLine + 5));
1814 #if 0
1815 InitTask16(); /* FIXME: pmts / from context ? */
1816 InitApp(di);
1817 #endif
1818 if (SetMessageQueue16(0x40)) {
1819 WaitEvent16(0);
1820 if (HIWORD(fpProc)) {
1821 OldYield16();
1822 /* EPP StackEnter16(); */
1823 (fpProc)(dwPmt);
1827 OldYield16();
1828 OldYield16();
1829 OldYield16();
1830 ExitProcess(0);
1832 #endif
1834 /**************************************************************************
1835 * mmTaskBlock [MMSYSTEM.902]
1837 void WINAPI mmTaskBlock16(HINSTANCE16 hInst)
1839 MSG msg;
1841 do {
1842 GetMessageA(&msg, 0, 0, 0);
1843 if (msg.hwnd) {
1844 TranslateMessage(&msg);
1845 DispatchMessageA(&msg);
1847 } while (msg.message < 0x3A0);
1850 /**************************************************************************
1851 * mmTaskSignal [MMSYSTEM.903]
1853 LRESULT WINAPI mmTaskSignal16(HTASK16 ht)
1855 TRACE("(%04x);\n", ht);
1856 return PostThreadMessageW( HTASK_32(ht), WM_USER, 0, 0 );
1859 /**************************************************************************
1860 * mmGetCurrentTask [MMSYSTEM.904]
1862 HTASK16 WINAPI mmGetCurrentTask16(void)
1864 return GetCurrentTask();
1867 /**************************************************************************
1868 * mmTaskYield [MMSYSTEM.905]
1870 void WINAPI mmTaskYield16(void)
1872 MSG msg;
1874 if (PeekMessageA(&msg, 0, 0, 0, 0)) {
1875 WOWYield16();
1879 extern DWORD WINAPI GetProcessFlags(DWORD);
1881 /******************************************************************
1882 * WINMM_GetmmThread
1886 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16 h)
1888 return MapSL(MAKESEGPTR(h, 0));
1891 DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID);
1893 /**************************************************************************
1894 * mmThreadCreate [MMSYSTEM.1120]
1896 * undocumented
1897 * Creates a MM thread, calling fpThreadAddr(dwPmt).
1898 * dwFlags:
1899 * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc
1900 * bit.1 set means to open a VxD for this thread (unsupported)
1902 LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags)
1904 HANDLE16 hndl;
1905 LRESULT ret;
1907 TRACE("(%p, %p, %08x, %08x)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags);
1909 hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT);
1911 if (hndl == 0) {
1912 ret = 2;
1913 } else {
1914 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1916 #if 0
1917 /* force mmtask routines even if mmthread is required */
1918 /* this will work only if the patch about binary cmd line and NE tasks
1919 * is committed
1921 dwFlags |= 1;
1922 #endif
1924 lpMMThd->dwSignature = WINE_MMTHREAD_CREATED;
1925 lpMMThd->dwCounter = 0;
1926 lpMMThd->hThread = 0;
1927 lpMMThd->dwThreadID = 0;
1928 lpMMThd->fpThread = (DWORD)fpThreadAddr;
1929 lpMMThd->dwThreadPmt = dwPmt;
1930 lpMMThd->dwSignalCount = 0;
1931 lpMMThd->hEvent = 0;
1932 lpMMThd->hVxD = 0;
1933 lpMMThd->dwStatus = 0;
1934 lpMMThd->dwFlags = dwFlags;
1935 lpMMThd->hTask = 0;
1937 if ((dwFlags & 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) {
1938 lpMMThd->hEvent = CreateEventW(NULL, FALSE, TRUE, NULL);
1940 TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd);
1941 if (lpMMThd->dwFlags & 2) {
1942 /* as long as we don't support MM VxD in wine, we don't need
1943 * to care about this flag
1945 /* FIXME("Don't know how to properly open VxD handles\n"); */
1946 /* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */
1949 lpMMThd->hThread = CreateThread(0, 0, WINE_mmThreadEntryPoint,
1950 (LPVOID)(DWORD_PTR)hndl, CREATE_SUSPENDED, &lpMMThd->dwThreadID);
1951 if (lpMMThd->hThread == 0) {
1952 WARN("Couldn't create thread\n");
1953 /* clean-up(VxDhandle...); devicedirectio... */
1954 if (lpMMThd->hEvent != 0)
1955 CloseHandle(lpMMThd->hEvent);
1956 ret = 2;
1957 } else {
1958 SetThreadPriority(lpMMThd->hThread, THREAD_PRIORITY_TIME_CRITICAL);
1959 TRACE("Got a nice thread hndl=%p id=0x%08x\n", lpMMThd->hThread, lpMMThd->dwThreadID);
1960 ret = 0;
1962 } else {
1963 /* get WINE_mmThreadEntryPoint()
1964 * 2047 is its ordinal in mmsystem.spec
1966 FARPROC16 fp = GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR)2047);
1968 TRACE("farproc seg=0x%p lin=%p\n", fp, MapSL((SEGPTR)fp));
1970 ret = (fp == 0) ? 2 : mmTaskCreate16((DWORD)fp, 0, hndl);
1973 if (ret == 0) {
1974 if (lpMMThd->hThread && !ResumeThread(lpMMThd->hThread))
1975 WARN("Couldn't resume thread\n");
1977 while (lpMMThd->dwStatus != 0x10) { /* test also HIWORD of dwStatus */
1978 UserYield16();
1983 if (ret != 0) {
1984 GlobalFree16(hndl);
1985 hndl = 0;
1988 if (lpHndl)
1989 *lpHndl = hndl;
1991 TRACE("ok => %ld\n", ret);
1992 return ret;
1995 /**************************************************************************
1996 * mmThreadSignal [MMSYSTEM.1121]
1998 void WINAPI mmThreadSignal16(HANDLE16 hndl)
2000 TRACE("(%04x)!\n", hndl);
2002 if (hndl) {
2003 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2005 lpMMThd->dwCounter++;
2006 if (lpMMThd->hThread != 0) {
2007 InterlockedIncrement(&lpMMThd->dwSignalCount);
2008 SetEvent(lpMMThd->hEvent);
2009 } else {
2010 mmTaskSignal16(lpMMThd->hTask);
2012 lpMMThd->dwCounter--;
2016 static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd)
2018 MSG msg;
2019 DWORD ret;
2021 if (lpMMThd->dwThreadID != GetCurrentThreadId())
2022 ERR("Not called by thread itself\n");
2024 for (;;) {
2025 ResetEvent(lpMMThd->hEvent);
2026 if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0)
2027 break;
2028 InterlockedIncrement(&lpMMThd->dwSignalCount);
2030 TRACE("S1\n");
2032 ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT);
2033 switch (ret) {
2034 case WAIT_OBJECT_0: /* Event */
2035 TRACE("S2.1\n");
2036 break;
2037 case WAIT_OBJECT_0 + 1: /* Msg */
2038 TRACE("S2.2\n");
2039 if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
2040 TranslateMessage(&msg);
2041 DispatchMessageA(&msg);
2043 break;
2044 default:
2045 WARN("S2.x unsupported ret val 0x%08x\n", ret);
2047 TRACE("S3\n");
2051 /**************************************************************************
2052 * mmThreadBlock [MMSYSTEM.1122]
2054 void WINAPI mmThreadBlock16(HANDLE16 hndl)
2056 TRACE("(%04x)!\n", hndl);
2058 if (hndl) {
2059 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2061 if (lpMMThd->hThread != 0) {
2062 DWORD lc;
2064 ReleaseThunkLock(&lc);
2065 MMSYSTEM_ThreadBlock(lpMMThd);
2066 RestoreThunkLock(lc);
2067 } else {
2068 mmTaskBlock16(lpMMThd->hTask);
2071 TRACE("done\n");
2074 /**************************************************************************
2075 * mmThreadIsCurrent [MMSYSTEM.1123]
2077 BOOL16 WINAPI mmThreadIsCurrent16(HANDLE16 hndl)
2079 BOOL16 ret = FALSE;
2081 TRACE("(%04x)!\n", hndl);
2083 if (hndl && mmThreadIsValid16(hndl)) {
2084 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2085 ret = (GetCurrentThreadId() == lpMMThd->dwThreadID);
2087 TRACE("=> %d\n", ret);
2088 return ret;
2091 /**************************************************************************
2092 * mmThreadIsValid [MMSYSTEM.1124]
2094 BOOL16 WINAPI mmThreadIsValid16(HANDLE16 hndl)
2096 BOOL16 ret = FALSE;
2098 TRACE("(%04x)!\n", hndl);
2100 if (hndl) {
2101 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2103 if (!IsBadWritePtr(lpMMThd, sizeof(WINE_MMTHREAD)) &&
2104 lpMMThd->dwSignature == WINE_MMTHREAD_CREATED &&
2105 IsTask16(lpMMThd->hTask)) {
2106 lpMMThd->dwCounter++;
2107 if (lpMMThd->hThread != 0) {
2108 DWORD dwThreadRet;
2109 if (GetExitCodeThread(lpMMThd->hThread, &dwThreadRet) &&
2110 dwThreadRet == STATUS_PENDING) {
2111 ret = TRUE;
2113 } else {
2114 ret = TRUE;
2116 lpMMThd->dwCounter--;
2119 TRACE("=> %d\n", ret);
2120 return ret;
2123 /**************************************************************************
2124 * mmThreadGetTask [MMSYSTEM.1125]
2126 HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl)
2128 HANDLE16 ret = 0;
2130 TRACE("(%04x)\n", hndl);
2132 if (mmThreadIsValid16(hndl)) {
2133 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2134 ret = lpMMThd->hTask;
2136 return ret;
2139 /**************************************************************************
2140 * __wine_mmThreadEntryPoint (MMSYSTEM.2047)
2142 DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID p)
2144 HANDLE16 hndl = (HANDLE16)(DWORD_PTR)p;
2145 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2147 TRACE("(%04x %p)\n", hndl, lpMMThd);
2149 lpMMThd->hTask = LOWORD(GetCurrentTask());
2150 TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask);
2151 lpMMThd->dwStatus = 0x10;
2152 MMSYSTEM_ThreadBlock(lpMMThd);
2153 TRACE("[20-%p]\n", lpMMThd->hThread);
2154 lpMMThd->dwStatus = 0x20;
2155 if (lpMMThd->fpThread) {
2156 WOWCallback16(lpMMThd->fpThread, lpMMThd->dwThreadPmt);
2158 lpMMThd->dwStatus = 0x30;
2159 TRACE("[30-%p]\n", lpMMThd->hThread);
2160 while (lpMMThd->dwCounter) {
2161 Sleep(1);
2162 /* WOWYield16();*/
2164 TRACE("[XX-%p]\n", lpMMThd->hThread);
2165 /* paranoia */
2166 lpMMThd->dwSignature = WINE_MMTHREAD_DELETED;
2167 /* close lpMMThread->hVxD directIO */
2168 if (lpMMThd->hEvent)
2169 CloseHandle(lpMMThd->hEvent);
2170 GlobalFree16(hndl);
2171 TRACE("done\n");
2173 return 0;
2176 typedef BOOL16 (WINAPI *MMCPLCALLBACK)(HWND, LPCSTR, LPCSTR, LPCSTR);
2178 /**************************************************************************
2179 * mmShowMMCPLPropertySheet [MMSYSTEM.1150]
2181 BOOL16 WINAPI mmShowMMCPLPropertySheet16(HWND hWnd, LPCSTR lpStrDevice,
2182 LPCSTR lpStrTab, LPCSTR lpStrTitle)
2184 HANDLE hndl;
2185 BOOL16 ret = FALSE;
2187 TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2189 hndl = LoadLibraryA("MMSYS.CPL");
2190 if (hndl != 0) {
2191 MMCPLCALLBACK fp = (MMCPLCALLBACK)GetProcAddress(hndl, "ShowMMCPLPropertySheet");
2192 if (fp != NULL) {
2193 DWORD lc;
2194 ReleaseThunkLock(&lc);
2195 ret = (fp)(hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2196 RestoreThunkLock(lc);
2198 FreeLibrary(hndl);
2201 return ret;
2204 /**************************************************************************
2205 * StackEnter [MMSYSTEM.32]
2207 void WINAPI StackEnter16(void)
2209 #ifdef __i386__
2210 /* mmsystem.dll from Win 95 does only this: so does Wine */
2211 __asm__("stc");
2212 #endif
2215 /**************************************************************************
2216 * StackLeave [MMSYSTEM.33]
2218 void WINAPI StackLeave16(void)
2220 #ifdef __i386__
2221 /* mmsystem.dll from Win 95 does only this: so does Wine */
2222 __asm__("stc");
2223 #endif
2226 /**************************************************************************
2227 * WMMMidiRunOnce [MMSYSTEM.8]
2229 void WINAPI WMMMidiRunOnce16(void)
2231 FIXME("(), stub!\n");
2234 /* ###################################################
2235 * # DRIVER #
2236 * ###################################################
2239 /**************************************************************************
2240 * DRIVER_MapMsg32To16 [internal]
2242 * Map a 32 bit driver message to a 16 bit driver message.
2244 static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, LPARAM *lParam1, LPARAM *lParam2)
2246 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2248 switch (wMsg) {
2249 case DRV_LOAD:
2250 case DRV_ENABLE:
2251 case DRV_DISABLE:
2252 case DRV_FREE:
2253 case DRV_QUERYCONFIGURE:
2254 case DRV_REMOVE:
2255 case DRV_EXITSESSION:
2256 case DRV_EXITAPPLICATION:
2257 case DRV_POWER:
2258 case DRV_CLOSE: /* should be 0/0 */
2259 case DRV_OPEN: /* pass through */
2260 /* lParam1 and lParam2 are not used */
2261 ret = WINMM_MAP_OK;
2262 break;
2263 case DRV_CONFIGURE:
2264 case DRV_INSTALL:
2265 /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
2266 * lParam2 is a pointer to DRVCONFIGINFO
2268 if (*lParam2) {
2269 LPDRVCONFIGINFO16 dci16 = HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16) );
2270 LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
2272 if (dci16) {
2273 LPSTR str1 = NULL,str2;
2274 INT len;
2275 dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
2277 if (dci32->lpszDCISectionName) {
2278 len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, NULL, 0, NULL, NULL );
2279 str1 = HeapAlloc( GetProcessHeap(), 0, len );
2280 if (str1) {
2281 WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, str1, len, NULL, NULL );
2282 dci16->lpszDCISectionName = MapLS( str1 );
2283 } else {
2284 HeapFree( GetProcessHeap(), 0, dci16);
2285 return WINMM_MAP_NOMEM;
2287 } else {
2288 dci16->lpszDCISectionName = 0L;
2290 if (dci32->lpszDCIAliasName) {
2291 len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, NULL, 0, NULL, NULL );
2292 str2 = HeapAlloc( GetProcessHeap(), 0, len );
2293 if (str2) {
2294 WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, str2, len, NULL, NULL );
2295 dci16->lpszDCIAliasName = MapLS( str2 );
2296 } else {
2297 HeapFree( GetProcessHeap(), 0, str1);
2298 HeapFree( GetProcessHeap(), 0, dci16);
2299 return WINMM_MAP_NOMEM;
2301 } else {
2302 dci16->lpszDCISectionName = 0L;
2304 } else {
2305 return WINMM_MAP_NOMEM;
2307 *lParam2 = MapLS( dci16 );
2308 ret = WINMM_MAP_OKMEM;
2309 } else {
2310 ret = WINMM_MAP_OK;
2312 break;
2313 default:
2314 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2315 FIXME("Unknown message 0x%04x\n", wMsg);
2317 ret = WINMM_MAP_OK;
2319 return ret;
2322 /**************************************************************************
2323 * DRIVER_UnMapMsg32To16 [internal]
2325 * UnMap a 32 bit driver message to a 16 bit driver message.
2327 static WINMM_MapType DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
2329 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2331 switch (wMsg) {
2332 case DRV_LOAD:
2333 case DRV_ENABLE:
2334 case DRV_DISABLE:
2335 case DRV_FREE:
2336 case DRV_QUERYCONFIGURE:
2337 case DRV_REMOVE:
2338 case DRV_EXITSESSION:
2339 case DRV_EXITAPPLICATION:
2340 case DRV_POWER:
2341 case DRV_OPEN:
2342 case DRV_CLOSE:
2343 /* lParam1 and lParam2 are not used */
2344 break;
2345 case DRV_CONFIGURE:
2346 case DRV_INSTALL:
2347 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
2348 if (lParam2) {
2349 LPDRVCONFIGINFO16 dci16 = MapSL(lParam2);
2350 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCISectionName) );
2351 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCIAliasName) );
2352 UnMapLS( lParam2 );
2353 UnMapLS( dci16->lpszDCISectionName );
2354 UnMapLS( dci16->lpszDCIAliasName );
2355 HeapFree( GetProcessHeap(), 0, dci16 );
2357 ret = WINMM_MAP_OK;
2358 break;
2359 default:
2360 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2361 FIXME("Unknown message 0x%04x\n", wMsg);
2363 ret = WINMM_MAP_OK;
2365 return ret;
2368 /**************************************************************************
2369 * DRIVER_TryOpenDriver16 [internal]
2371 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
2373 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCWSTR fn, LPCWSTR sn, LPARAM lParam2)
2375 LPWINE_DRIVER lpDrv = NULL;
2376 LPCSTR cause = NULL;
2377 LPSTR fnA = NULL, snA = NULL;
2378 unsigned len;
2380 TRACE("(%s, %s, %08lX);\n", debugstr_w(fn), debugstr_w(sn), lParam2);
2382 lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
2383 if (lpDrv == NULL) {cause = "OOM"; goto exit;}
2385 if (fn)
2387 len = WideCharToMultiByte( CP_ACP, 0, fn, -1, NULL, 0, NULL, NULL );
2388 fnA = HeapAlloc(GetProcessHeap(), 0, len);
2389 if (fnA == NULL) {cause = "OOM"; goto exit;}
2390 WideCharToMultiByte( CP_ACP, 0, fn, -1, fnA, len, NULL, NULL );
2393 if (sn)
2395 len = WideCharToMultiByte( CP_ACP, 0, sn, -1, NULL, 0, NULL, NULL );
2396 snA = HeapAlloc(GetProcessHeap(), 0, len);
2397 if (snA == NULL) {cause = "OOM"; goto exit;}
2398 WideCharToMultiByte( CP_ACP, 0, sn, -1, snA, len, NULL, NULL );
2401 /* FIXME: shall we do some black magic here on sn ?
2402 * drivers32 => drivers
2403 * mci32 => mci
2404 * ...
2406 lpDrv->d.d16.hDriver16 = OpenDriver16(fnA, snA, lParam2);
2407 if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;}
2408 lpDrv->dwFlags = WINE_GDF_16BIT;
2410 exit:
2411 HeapFree(GetProcessHeap(), 0, fnA);
2412 HeapFree(GetProcessHeap(), 0, snA);
2414 if (cause)
2416 TRACE("Unable to load 16 bit module %s[%s]: %s\n",
2417 debugstr_w(fn), debugstr_w(sn), cause);
2418 HeapFree(GetProcessHeap(), 0, lpDrv);
2419 return NULL;
2422 TRACE("=> %p\n", lpDrv);
2423 return lpDrv;
2426 /******************************************************************
2427 * DRIVER_SendMessage16
2431 static LRESULT DRIVER_SendMessage16(HDRVR16 hDrv16, UINT msg,
2432 LPARAM lParam1, LPARAM lParam2)
2434 LRESULT ret = 0;
2435 WINMM_MapType map;
2437 TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
2438 hDrv16, msg, lParam1, lParam2);
2440 switch (map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) {
2441 case WINMM_MAP_OKMEM:
2442 case WINMM_MAP_OK:
2443 ret = SendDriverMessage16(hDrv16, msg, lParam1, lParam2);
2444 if (map == WINMM_MAP_OKMEM)
2445 DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
2446 default:
2447 break;
2449 return ret;
2452 /******************************************************************
2453 * DRIVER_CloseDriver16
2457 static LRESULT DRIVER_CloseDriver16(HDRVR16 hDrv16, LPARAM lParam1, LPARAM lParam2)
2459 return CloseDriver16(hDrv16, lParam1, lParam2);
2462 /**************************************************************************
2463 * DrvOpen [MMSYSTEM.1100]
2465 HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
2467 return OpenDriver16(lpDriverName, lpSectionName, lParam);
2470 /**************************************************************************
2471 * DrvClose [MMSYSTEM.1101]
2473 LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
2475 return CloseDriver16(hDrv, lParam1, lParam2);
2478 /**************************************************************************
2479 * DrvSendMessage [MMSYSTEM.1102]
2481 LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
2482 LPARAM lParam2)
2484 return SendDriverMessage16(hDrv, msg, lParam1, lParam2);
2487 /**************************************************************************
2488 * DrvGetModuleHandle [MMSYSTEM.1103]
2490 HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
2492 return GetDriverModuleHandle16(hDrv);
2495 /**************************************************************************
2496 * DrvDefDriverProc [MMSYSTEM.1104]
2498 LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg,
2499 DWORD dwParam1, DWORD dwParam2)
2501 return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
2504 /**************************************************************************
2505 * DriverProc [MMSYSTEM.6]
2507 LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
2508 DWORD dwParam1, DWORD dwParam2)
2510 TRACE("dwDevID=%08x hDrv=%04x wMsg=%04x dwParam1=%08x dwParam2=%08x\n",
2511 dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2513 return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2516 /* ###################################################
2517 * # TIME #
2518 * ###################################################
2521 /******************************************************************
2522 * MMSYSTEM_MMTIME32to16
2526 void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32)
2528 mmt16->wType = mmt32->wType;
2529 /* layout of rest is the same for 32/16,
2530 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2532 memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u));
2535 /******************************************************************
2536 * MMSYSTEM_MMTIME16to32
2540 void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16)
2542 mmt32->wType = mmt16->wType;
2543 /* layout of rest is the same for 32/16,
2544 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2546 memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u));
2549 /**************************************************************************
2550 * timeGetSystemTime [MMSYSTEM.601]
2552 MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
2554 if (wSize >= sizeof(*lpTime)) {
2555 lpTime->wType = TIME_MS;
2556 lpTime->u.ms = GetTickCount();
2558 TRACE("=> %u\n", lpTime->u.ms);
2561 return 0;
2564 /**************************************************************************
2565 * timeSetEvent [MMSYSTEM.602]
2567 MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc,
2568 DWORD dwUser, UINT16 wFlags)
2570 if (wFlags & WINE_TIMER_IS32)
2571 WARN("Unknown windows flag... wine internally used.. ooch\n");
2573 return TIME_SetEventInternal(wDelay, wResol, (LPTIMECALLBACK)lpFunc,
2574 dwUser, wFlags & ~WINE_TIMER_IS32);
2577 /**************************************************************************
2578 * timeKillEvent [MMSYSTEM.603]
2580 MMRESULT16 WINAPI timeKillEvent16(UINT16 wID)
2582 return timeKillEvent(wID);
2585 /**************************************************************************
2586 * timeGetDevCaps [MMSYSTEM.604]
2588 MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize)
2590 TIMECAPS caps;
2591 MMRESULT ret;
2592 TRACE("(%p, %u) !\n", lpCaps, wSize);
2594 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2596 ret = timeGetDevCaps(&caps, sizeof(caps));
2597 if (ret == MMSYSERR_NOERROR) {
2598 TIMECAPS16 tc16;
2599 tc16.wPeriodMin = caps.wPeriodMin;
2600 tc16.wPeriodMax = caps.wPeriodMax;
2601 memcpy(lpCaps, &tc16, min(wSize, sizeof(tc16)));
2603 return ret;
2606 /**************************************************************************
2607 * timeBeginPeriod [MMSYSTEM.605]
2609 MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod)
2611 TRACE("(%u) !\n", wPeriod);
2613 return timeBeginPeriod(wPeriod);
2616 /**************************************************************************
2617 * timeEndPeriod [MMSYSTEM.606]
2619 MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod)
2621 TRACE("(%u) !\n", wPeriod);
2623 return timeEndPeriod(wPeriod);
2626 /**************************************************************************
2627 * mciSendString [MMSYSTEM.702]
2629 DWORD WINAPI mciSendString16(LPCSTR lpstrCommand, LPSTR lpstrRet,
2630 UINT16 uRetLen, HWND16 hwndCallback)
2632 return mciSendStringA(lpstrCommand, lpstrRet, uRetLen, HWND_32(hwndCallback));
2635 /**************************************************************************
2636 * mciLoadCommandResource [MMSYSTEM.705]
2638 UINT16 WINAPI mciLoadCommandResource16(HINSTANCE16 hInst, LPCSTR resname, UINT16 type)
2640 HRSRC16 res;
2641 HGLOBAL16 handle;
2642 const BYTE* ptr16;
2643 BYTE* ptr32;
2644 unsigned pos = 0, size = 1024, len;
2645 const char* str;
2646 DWORD flg;
2647 WORD eid;
2648 UINT16 ret = MCIERR_OUT_OF_MEMORY;
2650 if (!(res = FindResource16( hInst, resname, (LPSTR)RT_RCDATA))) return MCI_NO_COMMAND_TABLE;
2651 if (!(handle = LoadResource16( hInst, res ))) return MCI_NO_COMMAND_TABLE;
2652 ptr16 = LockResource16(handle);
2653 /* converting the 16 bit resource table into a 32W one */
2654 if ((ptr32 = HeapAlloc(GetProcessHeap(), 0, size)))
2656 do {
2657 str = (LPCSTR)ptr16;
2658 ptr16 += strlen(str) + 1;
2659 flg = *(const DWORD*)ptr16;
2660 eid = *(const WORD*)(ptr16 + sizeof(DWORD));
2661 ptr16 += sizeof(DWORD) + sizeof(WORD);
2662 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0) * sizeof(WCHAR);
2663 if (pos + len + sizeof(DWORD) + sizeof(WORD) > size)
2665 while (pos + len * sizeof(WCHAR) + sizeof(DWORD) + sizeof(WORD) > size) size += 1024;
2666 ptr32 = HeapReAlloc(GetProcessHeap(), 0, ptr32, size);
2667 if (!ptr32) goto the_end;
2669 MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)(ptr32 + pos), len / sizeof(WCHAR));
2670 *(DWORD*)(ptr32 + pos + len) = flg;
2671 *(WORD*)(ptr32 + pos + len + sizeof(DWORD)) = eid;
2672 pos += len + sizeof(DWORD) + sizeof(WORD);
2673 } while (eid != MCI_END_COMMAND_LIST);
2675 the_end:
2676 FreeResource16( handle );
2677 if (ptr32) ret = MCI_SetCommandTable(ptr32, type);
2678 return ret;
2681 /**************************************************************************
2682 * mciFreeCommandResource [MMSYSTEM.713]
2684 BOOL16 WINAPI mciFreeCommandResource16(UINT16 uTable)
2686 TRACE("(%04x)!\n", uTable);
2688 return MCI_DeleteCommandTable(uTable, TRUE);
2691 /* ###################################################
2692 * # MMIO #
2693 * ###################################################
2696 /****************************************************************
2697 * MMIO_Map32To16 [INTERNAL]
2699 static LRESULT MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2)
2701 switch (wMsg) {
2702 case MMIOM_CLOSE:
2703 case MMIOM_SEEK:
2704 /* nothing to do */
2705 break;
2706 case MMIOM_OPEN:
2707 case MMIOM_READ:
2708 case MMIOM_WRITE:
2709 case MMIOM_WRITEFLUSH:
2710 *lp1 = MapLS( (void *)*lp1 );
2711 break;
2712 case MMIOM_RENAME:
2713 *lp1 = MapLS( (void *)*lp1 );
2714 *lp2 = MapLS( (void *)*lp2 );
2715 break;
2716 default:
2717 if (wMsg < MMIOM_USER)
2718 TRACE("Not a mappable message (%d)\n", wMsg);
2720 return MMSYSERR_NOERROR;
2723 /****************************************************************
2724 * MMIO_UnMap32To16 [INTERNAL]
2726 static LRESULT MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2,
2727 LPARAM lp1, LPARAM lp2)
2729 switch (wMsg) {
2730 case MMIOM_CLOSE:
2731 case MMIOM_SEEK:
2732 /* nothing to do */
2733 break;
2734 case MMIOM_OPEN:
2735 case MMIOM_READ:
2736 case MMIOM_WRITE:
2737 case MMIOM_WRITEFLUSH:
2738 UnMapLS( lp1 );
2739 break;
2740 case MMIOM_RENAME:
2741 UnMapLS( lp1 );
2742 UnMapLS( lp2 );
2743 break;
2744 default:
2745 if (wMsg < MMIOM_USER)
2746 TRACE("Not a mappable message (%d)\n", wMsg);
2748 return MMSYSERR_NOERROR;
2751 /******************************************************************
2752 * MMIO_Callback16
2756 static LRESULT MMIO_Callback16(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage,
2757 LPARAM lParam1, LPARAM lParam2)
2759 DWORD result;
2760 MMIOINFO16 mmioInfo16;
2761 SEGPTR segmmioInfo16;
2762 LPARAM lp1 = lParam1, lp2 = lParam2;
2763 WORD args[7];
2765 memset(&mmioInfo16, 0, sizeof(MMIOINFO16));
2766 mmioInfo16.lDiskOffset = lpmmioinfo->lDiskOffset;
2767 mmioInfo16.adwInfo[0] = lpmmioinfo->adwInfo[0];
2768 mmioInfo16.adwInfo[1] = lpmmioinfo->adwInfo[1];
2769 mmioInfo16.adwInfo[2] = lpmmioinfo->adwInfo[2];
2770 /* map (lParam1, lParam2) into (lp1, lp2) 32=>16 */
2771 if ((result = MMIO_Map32To16(uMessage, &lp1, &lp2)) != MMSYSERR_NOERROR)
2772 return result;
2774 segmmioInfo16 = MapLS(&mmioInfo16);
2775 args[6] = HIWORD(segmmioInfo16);
2776 args[5] = LOWORD(segmmioInfo16);
2777 args[4] = uMessage;
2778 args[3] = HIWORD(lp1);
2779 args[2] = LOWORD(lp1);
2780 args[1] = HIWORD(lp2);
2781 args[0] = LOWORD(lp2);
2782 WOWCallback16Ex( cb16, WCB16_PASCAL, sizeof(args), args, &result );
2783 UnMapLS(segmmioInfo16);
2784 MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2);
2786 lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset;
2787 lpmmioinfo->adwInfo[0] = mmioInfo16.adwInfo[0];
2788 lpmmioinfo->adwInfo[1] = mmioInfo16.adwInfo[1];
2789 lpmmioinfo->adwInfo[2] = mmioInfo16.adwInfo[2];
2791 return result;
2794 /******************************************************************
2795 * MMIO_ResetSegmentedData
2798 static LRESULT MMIO_SetSegmentedBuffer(HMMIO hmmio, SEGPTR ptr, BOOL release)
2800 LPWINE_MMIO wm;
2802 if ((wm = MMIO_Get(hmmio)) == NULL)
2803 return MMSYSERR_INVALHANDLE;
2804 if (release) UnMapLS(wm->segBuffer16);
2805 wm->segBuffer16 = ptr;
2806 return MMSYSERR_NOERROR;
2809 /**************************************************************************
2810 * mmioOpen [MMSYSTEM.1210]
2812 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16,
2813 DWORD dwOpenFlags)
2815 HMMIO ret;
2817 if (lpmmioinfo16) {
2818 MMIOINFO mmioinfo;
2820 memset(&mmioinfo, 0, sizeof(mmioinfo));
2822 mmioinfo.dwFlags = lpmmioinfo16->dwFlags;
2823 mmioinfo.fccIOProc = lpmmioinfo16->fccIOProc;
2824 mmioinfo.pIOProc = (LPMMIOPROC)lpmmioinfo16->pIOProc;
2825 mmioinfo.cchBuffer = lpmmioinfo16->cchBuffer;
2826 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo16->pchBuffer);
2827 mmioinfo.adwInfo[0] = lpmmioinfo16->adwInfo[0];
2828 /* if we don't have a file name, it's likely a passed open file descriptor */
2829 if (!szFileName)
2830 mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]);
2831 mmioinfo.adwInfo[1] = lpmmioinfo16->adwInfo[1];
2832 mmioinfo.adwInfo[2] = lpmmioinfo16->adwInfo[2];
2834 ret = MMIO_Open(szFileName, &mmioinfo, dwOpenFlags, MMIO_PROC_16);
2835 MMIO_SetSegmentedBuffer(mmioinfo.hmmio, (SEGPTR)lpmmioinfo16->pchBuffer, FALSE);
2837 lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet;
2838 lpmmioinfo16->hmmio = HMMIO_16(mmioinfo.hmmio);
2839 } else {
2840 ret = MMIO_Open(szFileName, NULL, dwOpenFlags, MMIO_PROC_32A);
2842 return HMMIO_16(ret);
2845 /**************************************************************************
2846 * mmioClose [MMSYSTEM.1211]
2848 MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
2850 MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), 0, TRUE);
2851 return mmioClose(HMMIO_32(hmmio), uFlags);
2854 /**************************************************************************
2855 * mmioRead [MMSYSTEM.1212]
2857 LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
2859 return mmioRead(HMMIO_32(hmmio), pch, cch);
2862 /**************************************************************************
2863 * mmioWrite [MMSYSTEM.1213]
2865 LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
2867 return mmioWrite(HMMIO_32(hmmio),pch,cch);
2870 /**************************************************************************
2871 * mmioSeek [MMSYSTEM.1214]
2873 LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
2875 return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin);
2878 /**************************************************************************
2879 * mmioGetInfo [MMSYSTEM.1215]
2881 MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2883 MMIOINFO mmioinfo;
2884 MMRESULT ret;
2885 LPWINE_MMIO wm;
2887 TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags);
2889 if ((wm = MMIO_Get(HMMIO_32(hmmio))) == NULL)
2890 return MMSYSERR_INVALHANDLE;
2892 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
2893 if (ret != MMSYSERR_NOERROR) return ret;
2895 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
2896 lpmmioinfo->fccIOProc = mmioinfo.fccIOProc;
2897 lpmmioinfo->pIOProc = (wm->ioProc->type == MMIO_PROC_16) ?
2898 (LPMMIOPROC16)wm->ioProc->pIOProc : NULL;
2899 lpmmioinfo->wErrorRet = mmioinfo.wErrorRet;
2900 lpmmioinfo->hTask = HTASK_16(mmioinfo.hTask);
2901 lpmmioinfo->cchBuffer = mmioinfo.cchBuffer;
2902 lpmmioinfo->pchBuffer = (void*)wm->segBuffer16;
2903 lpmmioinfo->pchNext = (void*)(wm->segBuffer16 + (mmioinfo.pchNext - mmioinfo.pchBuffer));
2904 lpmmioinfo->pchEndRead = (void*)(wm->segBuffer16 + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
2905 lpmmioinfo->pchEndWrite = (void*)(wm->segBuffer16 + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
2906 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
2907 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
2908 lpmmioinfo->adwInfo[0] = mmioinfo.adwInfo[0];
2909 lpmmioinfo->adwInfo[1] = mmioinfo.adwInfo[1];
2910 lpmmioinfo->adwInfo[2] = mmioinfo.adwInfo[2];
2911 lpmmioinfo->dwReserved1 = 0;
2912 lpmmioinfo->dwReserved2 = 0;
2913 lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio);
2915 return MMSYSERR_NOERROR;
2918 /**************************************************************************
2919 * mmioSetInfo [MMSYSTEM.1216]
2921 MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2923 MMIOINFO mmioinfo;
2924 MMRESULT ret;
2926 TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
2928 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0);
2929 if (ret != MMSYSERR_NOERROR) return ret;
2931 /* check if seg and lin buffers are the same */
2932 if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer ||
2933 mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer))
2934 return MMSYSERR_INVALPARAM;
2936 /* check pointers coherence */
2937 if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer ||
2938 lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
2939 lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer ||
2940 lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
2941 lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer ||
2942 lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer)
2943 return MMSYSERR_INVALPARAM;
2945 mmioinfo.pchNext = mmioinfo.pchBuffer + (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer);
2946 mmioinfo.pchEndRead = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead - lpmmioinfo->pchBuffer);
2947 mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer);
2949 return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
2952 /**************************************************************************
2953 * mmioSetBuffer [MMSYSTEM.1217]
2955 MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, LPSTR pchBuffer,
2956 LONG cchBuffer, UINT16 uFlags)
2958 MMRESULT ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL((DWORD)pchBuffer),
2959 cchBuffer, uFlags);
2961 if (ret == MMSYSERR_NOERROR)
2962 MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), (DWORD)pchBuffer, TRUE);
2963 else
2964 UnMapLS((DWORD)pchBuffer);
2965 return ret;
2968 /**************************************************************************
2969 * mmioFlush [MMSYSTEM.1218]
2971 MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
2973 return mmioFlush(HMMIO_32(hmmio), uFlags);
2976 /***********************************************************************
2977 * mmioAdvance [MMSYSTEM.1219]
2979 MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2981 MMIOINFO mmioinfo;
2982 LRESULT ret;
2984 /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which
2985 * fields to init
2987 if (lpmmioinfo)
2989 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer);
2990 mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext);
2991 mmioinfo.dwFlags = lpmmioinfo->dwFlags;
2992 mmioinfo.lBufOffset = lpmmioinfo->lBufOffset;
2993 ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags);
2995 else
2996 ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags);
2998 if (ret != MMSYSERR_NOERROR) return ret;
3000 if (lpmmioinfo)
3002 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
3003 lpmmioinfo->pchNext = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
3004 lpmmioinfo->pchEndRead = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
3005 lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
3006 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
3007 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
3010 return MMSYSERR_NOERROR;
3013 /**************************************************************************
3014 * mmioStringToFOURCC [MMSYSTEM.1220]
3016 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
3018 return mmioStringToFOURCCA(sz, uFlags);
3021 /**************************************************************************
3022 * mmioInstallIOProc [MMSYSTEM.1221]
3024 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc,
3025 DWORD dwFlags)
3027 return (LPMMIOPROC16)MMIO_InstallIOProc(fccIOProc, (LPMMIOPROC)pIOProc,
3028 dwFlags, MMIO_PROC_16);
3031 /**************************************************************************
3032 * mmioSendMessage [MMSYSTEM.1222]
3034 LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage,
3035 LPARAM lParam1, LPARAM lParam2)
3037 return MMIO_SendMessage(HMMIO_32(hmmio), uMessage,
3038 lParam1, lParam2, MMIO_PROC_16);
3041 /**************************************************************************
3042 * mmioDescend [MMSYSTEM.1223]
3044 MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck,
3045 const MMCKINFO* lpckParent, UINT16 uFlags)
3047 return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags);
3050 /**************************************************************************
3051 * mmioAscend [MMSYSTEM.1224]
3053 MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
3055 return mmioAscend(HMMIO_32(hmmio),lpck,uFlags);
3058 /**************************************************************************
3059 * mmioCreateChunk [MMSYSTEM.1225]
3061 MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
3063 return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags);
3066 /**************************************************************************
3067 * mmioRename [MMSYSTEM.1226]
3069 MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName,
3070 MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags)
3072 BOOL inst = FALSE;
3073 MMRESULT ret;
3074 MMIOINFO mmioinfo;
3076 if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL &&
3077 lpmmioinfo->fccIOProc == 0) {
3078 FIXME("Can't handle this case yet\n");
3079 return MMSYSERR_ERROR;
3082 /* this is a bit hacky, but it'll work if we get a fourCC code or nothing.
3083 * but a non installed ioproc without a fourcc won't do
3085 if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) {
3086 MMIO_InstallIOProc(lpmmioinfo->fccIOProc, (LPMMIOPROC)lpmmioinfo->pIOProc,
3087 MMIO_INSTALLPROC, MMIO_PROC_16);
3088 inst = TRUE;
3090 memset(&mmioinfo, 0, sizeof(mmioinfo));
3091 mmioinfo.fccIOProc = lpmmioinfo->fccIOProc;
3092 ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags);
3093 if (inst) {
3094 MMIO_InstallIOProc(lpmmioinfo->fccIOProc, NULL,
3095 MMIO_REMOVEPROC, MMIO_PROC_16);
3097 return ret;
3100 /* ###################################################
3101 * # JOYSTICK #
3102 * ###################################################
3105 /**************************************************************************
3106 * joyGetNumDevs [MMSYSTEM.101]
3108 UINT16 WINAPI joyGetNumDevs16(void)
3110 return joyGetNumDevs();
3113 /**************************************************************************
3114 * joyGetDevCaps [MMSYSTEM.102]
3116 MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize)
3118 JOYCAPSA jca;
3119 MMRESULT ret;
3121 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
3123 ret = joyGetDevCapsA(wID, &jca, sizeof(jca));
3125 if (ret != JOYERR_NOERROR) return ret;
3126 lpCaps->wMid = jca.wMid;
3127 lpCaps->wPid = jca.wPid;
3128 strcpy(lpCaps->szPname, jca.szPname);
3129 lpCaps->wXmin = jca.wXmin;
3130 lpCaps->wXmax = jca.wXmax;
3131 lpCaps->wYmin = jca.wYmin;
3132 lpCaps->wYmax = jca.wYmax;
3133 lpCaps->wZmin = jca.wZmin;
3134 lpCaps->wZmax = jca.wZmax;
3135 lpCaps->wNumButtons = jca.wNumButtons;
3136 lpCaps->wPeriodMin = jca.wPeriodMin;
3137 lpCaps->wPeriodMax = jca.wPeriodMax;
3139 if (wSize >= sizeof(JOYCAPS16)) { /* Win95 extensions ? */
3140 lpCaps->wRmin = jca.wRmin;
3141 lpCaps->wRmax = jca.wRmax;
3142 lpCaps->wUmin = jca.wUmin;
3143 lpCaps->wUmax = jca.wUmax;
3144 lpCaps->wVmin = jca.wVmin;
3145 lpCaps->wVmax = jca.wVmax;
3146 lpCaps->wCaps = jca.wCaps;
3147 lpCaps->wMaxAxes = jca.wMaxAxes;
3148 lpCaps->wNumAxes = jca.wNumAxes;
3149 lpCaps->wMaxButtons = jca.wMaxButtons;
3150 strcpy(lpCaps->szRegKey, jca.szRegKey);
3151 strcpy(lpCaps->szOEMVxD, jca.szOEMVxD);
3154 return ret;
3157 /**************************************************************************
3158 * joyGetPosEx [MMSYSTEM.110]
3160 MMRESULT16 WINAPI joyGetPosEx16(UINT16 wID, LPJOYINFOEX lpInfo)
3162 return joyGetPosEx(wID, lpInfo);
3165 /**************************************************************************
3166 * joyGetPos [MMSYSTEM.103]
3168 MMRESULT16 WINAPI joyGetPos16(UINT16 wID, LPJOYINFO16 lpInfo)
3170 JOYINFO ji;
3171 MMRESULT ret;
3173 TRACE("(%d, %p);\n", wID, lpInfo);
3175 if ((ret = joyGetPos(wID, &ji)) == JOYERR_NOERROR) {
3176 lpInfo->wXpos = ji.wXpos;
3177 lpInfo->wYpos = ji.wYpos;
3178 lpInfo->wZpos = ji.wZpos;
3179 lpInfo->wButtons = ji.wButtons;
3181 return ret;
3184 /**************************************************************************
3185 * joyGetThreshold [MMSYSTEM.104]
3187 MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold)
3189 UINT t;
3190 MMRESULT ret;
3192 ret = joyGetThreshold(wID, &t);
3193 if (ret == JOYERR_NOERROR)
3194 *lpThreshold = t;
3195 return ret;
3198 /**************************************************************************
3199 * joyReleaseCapture [MMSYSTEM.105]
3201 MMRESULT16 WINAPI joyReleaseCapture16(UINT16 wID)
3203 return joyReleaseCapture(wID);
3206 /**************************************************************************
3207 * joySetCapture [MMSYSTEM.106]
3209 MMRESULT16 WINAPI joySetCapture16(HWND16 hWnd, UINT16 wID, UINT16 wPeriod, BOOL16 bChanged)
3211 return joySetCapture(HWND_32(hWnd), wID, wPeriod, bChanged);
3214 /**************************************************************************
3215 * joySetThreshold [MMSYSTEM.107]
3217 MMRESULT16 WINAPI joySetThreshold16(UINT16 wID, UINT16 wThreshold)
3219 return joySetThreshold(wID,wThreshold);
3222 /**************************************************************************
3223 * joySetCalibration [MMSYSTEM.109]
3225 MMRESULT16 WINAPI joySetCalibration16(UINT16 wID)
3227 FIXME("(%04X): stub.\n", wID);
3228 return JOYERR_NOCANDO;