winmm: Exclude unused headers.
[wine/wine64.git] / dlls / winmm / mmsystem.c
blobac6e537c4b0e0fecadb2a90bd64deb9e53204369
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * MMSYTEM 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 "winemm16.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
48 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16);
49 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCWSTR, LPCWSTR, LPARAM);
50 static LRESULT DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM);
51 static LRESULT DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM);
52 static LRESULT MMIO_Callback16(SEGPTR, LPMMIOINFO, UINT, LPARAM, LPARAM);
54 /* ###################################################
55 * # LIBRARY #
56 * ###################################################
59 /**************************************************************************
60 * DllEntryPoint (MMSYSTEM.4)
62 * MMSYSTEM DLL entry point
65 BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
66 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
68 TRACE("%p 0x%x\n", hinstDLL, fdwReason);
70 switch (fdwReason) {
71 case DLL_PROCESS_ATTACH:
72 /* need to load WinMM in order to:
73 * - initiate correctly shared variables (WINMM_Init())
75 if (!GetModuleHandleA("WINMM.DLL"))
77 ERR("Could not load sibling WinMM.dll\n");
78 return FALSE;
80 WINMM_IData.hWinMM16Instance = hinstDLL;
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 WINMM_IData.hWinMM16Instance = 0;
93 pFnGetMMThread16 = NULL;
94 pFnOpenDriver16 = NULL;
95 pFnCloseDriver16 = NULL;
96 pFnSendMessage16 = NULL;
97 pFnMmioCallback16 = NULL;
98 pFnReleaseThunkLock = NULL;
99 pFnRestoreThunkLock = NULL;
100 /* FIXME: add equivalent for MMDRV_Init16() */
101 break;
102 case DLL_THREAD_ATTACH:
103 case DLL_THREAD_DETACH:
104 break;
106 return TRUE;
109 /**************************************************************************
110 * WEP [MMSYSTEM.1]
112 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
113 WORD cbHeapSize, LPSTR lpCmdLine)
115 TRACE("STUB: Unloading MMSystem DLL ... hInst=%04X\n", hInstance);
116 return TRUE;
119 /* ###################################################
120 * # PlaySound #
121 * ###################################################
124 /**************************************************************************
125 * PlaySound [MMSYSTEM.3]
127 BOOL16 WINAPI PlaySound16(LPCSTR pszSound, HMODULE16 hmod, DWORD fdwSound)
129 BOOL16 retv;
130 DWORD lc;
132 if ((fdwSound & SND_RESOURCE) == SND_RESOURCE)
134 HGLOBAL16 handle;
135 HRSRC16 res;
137 if (!(res = FindResource16( hmod, pszSound, "WAVE" ))) return FALSE;
138 if (!(handle = LoadResource16( hmod, res ))) return FALSE;
139 pszSound = LockResource16(handle);
140 fdwSound = (fdwSound & ~SND_RESOURCE) | SND_MEMORY;
141 /* FIXME: FreeResource16 */
144 ReleaseThunkLock(&lc);
145 retv = PlaySoundA(pszSound, 0, fdwSound);
146 RestoreThunkLock(lc);
148 return retv;
151 /**************************************************************************
152 * sndPlaySound [MMSYSTEM.2]
154 BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags)
156 BOOL16 retv;
157 DWORD lc;
159 ReleaseThunkLock(&lc);
160 retv = sndPlaySoundA(lpszSoundName, uFlags);
161 RestoreThunkLock(lc);
163 return retv;
166 /* ###################################################
167 * # MISC #
168 * ###################################################
171 /**************************************************************************
172 * mmsystemGetVersion [MMSYSTEM.5]
175 UINT16 WINAPI mmsystemGetVersion16(void)
177 return mmsystemGetVersion();
180 /**************************************************************************
181 * DriverCallback [MMSYSTEM.31]
183 BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev,
184 WORD wMsg, DWORD dwUser, DWORD dwParam1,
185 DWORD dwParam2)
187 return DriverCallback(dwCallBack, uFlags, HDRVR_32(hDev), wMsg, dwUser, dwParam1, dwParam2);
190 /**************************************************************************
191 * OutputDebugStr [MMSYSTEM.30]
193 void WINAPI OutputDebugStr16(LPCSTR str)
195 OutputDebugStringA( str );
199 /* ###################################################
200 * # MIXER #
201 * ###################################################
204 /**************************************************************************
205 * Mixer devices. New to Win95
208 /**************************************************************************
209 * mixerGetNumDevs [MMSYSTEM.800]
211 UINT16 WINAPI mixerGetNumDevs16(void)
213 return MMDRV_GetNum(MMDRV_MIXER);
216 /**************************************************************************
217 * mixerGetDevCaps [MMSYSTEM.801]
219 UINT16 WINAPI mixerGetDevCaps16(UINT16 uDeviceID, LPMIXERCAPS16 lpCaps,
220 UINT16 uSize)
222 MIXERCAPSA micA;
223 UINT ret;
225 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
227 ret = mixerGetDevCapsA(uDeviceID, &micA, sizeof(micA));
228 if (ret == MMSYSERR_NOERROR) {
229 MIXERCAPS16 mic16;
230 mic16.wMid = micA.wMid;
231 mic16.wPid = micA.wPid;
232 mic16.vDriverVersion = micA.vDriverVersion;
233 strcpy(mic16.szPname, micA.szPname);
234 mic16.fdwSupport = micA.fdwSupport;
235 mic16.cDestinations = micA.cDestinations;
236 memcpy(lpCaps, &mic16, min(uSize, sizeof(mic16)));
238 return ret;
241 /**************************************************************************
242 * mixerOpen [MMSYSTEM.802]
244 UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix, UINT16 uDeviceID, DWORD dwCallback,
245 DWORD dwInstance, DWORD fdwOpen)
247 HMIXER hmix;
248 UINT ret;
250 ret = MIXER_Open(&hmix, uDeviceID, dwCallback, dwInstance, fdwOpen, FALSE);
251 if (lphmix) *lphmix = HMIXER_16(hmix);
252 return ret;
255 /**************************************************************************
256 * mixerClose [MMSYSTEM.803]
258 UINT16 WINAPI mixerClose16(HMIXER16 hMix)
260 return mixerClose(HMIXER_32(hMix));
263 /**************************************************************************
264 * mixerGetID (MMSYSTEM.806)
266 UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID)
268 UINT xid;
269 UINT ret = mixerGetID(HMIXEROBJ_32(hmix), &xid, fdwID);
271 if (lpid)
272 *lpid = xid;
273 return ret;
276 /**************************************************************************
277 * mixerGetControlDetails [MMSYSTEM.808]
279 UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,
280 LPMIXERCONTROLDETAILS16 lpmcd,
281 DWORD fdwDetails)
283 DWORD ret = MMSYSERR_NOTENABLED;
284 SEGPTR sppaDetails;
286 TRACE("(%04x, %p, %08x)\n", hmix, lpmcd, fdwDetails);
288 if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
289 return MMSYSERR_INVALPARAM;
291 sppaDetails = (SEGPTR)lpmcd->paDetails;
292 lpmcd->paDetails = MapSL(sppaDetails);
293 ret = mixerGetControlDetailsA(HMIXEROBJ_32(hmix),
294 (LPMIXERCONTROLDETAILS)lpmcd, fdwDetails);
295 lpmcd->paDetails = (LPVOID)sppaDetails;
297 return ret;
300 /**************************************************************************
301 * mixerGetLineControls [MMSYSTEM.807]
303 UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,
304 LPMIXERLINECONTROLS16 lpmlc16,
305 DWORD fdwControls)
307 MIXERLINECONTROLSA mlcA;
308 DWORD ret;
309 unsigned int i;
310 LPMIXERCONTROL16 lpmc16;
312 TRACE("(%04x, %p, %08x)\n", hmix, lpmlc16, fdwControls);
314 if (lpmlc16 == NULL || lpmlc16->cbStruct != sizeof(*lpmlc16) ||
315 lpmlc16->cbmxctrl != sizeof(MIXERCONTROL16))
316 return MMSYSERR_INVALPARAM;
318 mlcA.cbStruct = sizeof(mlcA);
319 mlcA.dwLineID = lpmlc16->dwLineID;
320 mlcA.u.dwControlID = lpmlc16->u.dwControlID;
321 mlcA.u.dwControlType = lpmlc16->u.dwControlType;
322 mlcA.cControls = lpmlc16->cControls;
323 mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
324 mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
325 mlcA.cControls * mlcA.cbmxctrl);
327 ret = mixerGetLineControlsA(HMIXEROBJ_32(hmix), &mlcA, fdwControls);
329 if (ret == MMSYSERR_NOERROR) {
330 lpmlc16->dwLineID = mlcA.dwLineID;
331 lpmlc16->u.dwControlID = mlcA.u.dwControlID;
332 lpmlc16->u.dwControlType = mlcA.u.dwControlType;
333 lpmlc16->cControls = mlcA.cControls;
335 lpmc16 = MapSL(lpmlc16->pamxctrl);
337 for (i = 0; i < mlcA.cControls; i++) {
338 lpmc16[i].cbStruct = sizeof(MIXERCONTROL16);
339 lpmc16[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
340 lpmc16[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
341 lpmc16[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
342 lpmc16[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
343 strcpy(lpmc16[i].szShortName, mlcA.pamxctrl[i].szShortName);
344 strcpy(lpmc16[i].szName, mlcA.pamxctrl[i].szName);
345 /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
346 memcpy(&lpmc16[i].Bounds, &mlcA.pamxctrl[i].Bounds,
347 sizeof(mlcA.pamxctrl[i].Bounds));
348 /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
349 memcpy(&lpmc16[i].Metrics, &mlcA.pamxctrl[i].Metrics,
350 sizeof(mlcA.pamxctrl[i].Metrics));
354 HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);
356 return ret;
359 /**************************************************************************
360 * mixerGetLineInfo [MMSYSTEM.805]
362 UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16,
363 DWORD fdwInfo)
365 MIXERLINEA mliA;
366 UINT ret;
368 TRACE("(%04x, %p, %08x)\n", hmix, lpmli16, fdwInfo);
370 if (lpmli16 == NULL || lpmli16->cbStruct != sizeof(*lpmli16))
371 return MMSYSERR_INVALPARAM;
373 mliA.cbStruct = sizeof(mliA);
374 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
375 case MIXER_GETLINEINFOF_COMPONENTTYPE:
376 mliA.dwComponentType = lpmli16->dwComponentType;
377 break;
378 case MIXER_GETLINEINFOF_DESTINATION:
379 mliA.dwDestination = lpmli16->dwDestination;
380 break;
381 case MIXER_GETLINEINFOF_LINEID:
382 mliA.dwLineID = lpmli16->dwLineID;
383 break;
384 case MIXER_GETLINEINFOF_SOURCE:
385 mliA.dwDestination = lpmli16->dwDestination;
386 mliA.dwSource = lpmli16->dwSource;
387 break;
388 case MIXER_GETLINEINFOF_TARGETTYPE:
389 mliA.Target.dwType = lpmli16->Target.dwType;
390 mliA.Target.wMid = lpmli16->Target.wMid;
391 mliA.Target.wPid = lpmli16->Target.wPid;
392 mliA.Target.vDriverVersion = lpmli16->Target.vDriverVersion;
393 strcpy(mliA.Target.szPname, lpmli16->Target.szPname);
394 break;
395 default:
396 FIXME("Unsupported fdwControls=0x%08x\n", fdwInfo);
399 ret = mixerGetLineInfoA(HMIXEROBJ_32(hmix), &mliA, fdwInfo);
401 lpmli16->dwDestination = mliA.dwDestination;
402 lpmli16->dwSource = mliA.dwSource;
403 lpmli16->dwLineID = mliA.dwLineID;
404 lpmli16->fdwLine = mliA.fdwLine;
405 lpmli16->dwUser = mliA.dwUser;
406 lpmli16->dwComponentType = mliA.dwComponentType;
407 lpmli16->cChannels = mliA.cChannels;
408 lpmli16->cConnections = mliA.cConnections;
409 lpmli16->cControls = mliA.cControls;
410 strcpy(lpmli16->szShortName, mliA.szShortName);
411 strcpy(lpmli16->szName, mliA.szName);
412 lpmli16->Target.dwType = mliA.Target.dwType;
413 lpmli16->Target.dwDeviceID = mliA.Target.dwDeviceID;
414 lpmli16->Target.wMid = mliA.Target.wMid;
415 lpmli16->Target.wPid = mliA.Target.wPid;
416 lpmli16->Target.vDriverVersion = mliA.Target.vDriverVersion;
417 strcpy(lpmli16->Target.szPname, mliA.Target.szPname);
419 return ret;
422 /**************************************************************************
423 * mixerSetControlDetails [MMSYSTEM.809]
425 UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,
426 LPMIXERCONTROLDETAILS16 lpmcd,
427 DWORD fdwDetails)
429 TRACE("(%04x, %p, %08x)\n", hmix, lpmcd, fdwDetails);
430 return MMSYSERR_NOTENABLED;
433 /**************************************************************************
434 * mixerMessage [MMSYSTEM.804]
436 DWORD WINAPI mixerMessage16(HMIXER16 hmix, UINT16 uMsg, DWORD dwParam1,
437 DWORD dwParam2)
439 return mixerMessage(HMIXER_32(hmix), uMsg, dwParam1, dwParam2);
442 /**************************************************************************
443 * auxGetNumDevs [MMSYSTEM.350]
445 UINT16 WINAPI auxGetNumDevs16(void)
447 return MMDRV_GetNum(MMDRV_AUX);
450 /* ###################################################
451 * # AUX #
452 * ###################################################
455 /**************************************************************************
456 * auxGetDevCaps [MMSYSTEM.351]
458 UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID, LPAUXCAPS16 lpCaps, UINT16 uSize)
460 AUXCAPSA acA;
461 UINT ret;
463 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
465 ret = auxGetDevCapsA(uDeviceID, &acA, sizeof(acA));
466 if (ret == MMSYSERR_NOERROR) {
467 AUXCAPS16 ac16;
468 ac16.wMid = acA.wMid;
469 ac16.wPid = acA.wPid;
470 ac16.vDriverVersion = acA.vDriverVersion;
471 strcpy(ac16.szPname, acA.szPname);
472 ac16.wTechnology = acA.wTechnology;
473 ac16.dwSupport = acA.dwSupport;
474 memcpy(lpCaps, &ac16, min(uSize, sizeof(ac16)));
476 return ret;
479 /**************************************************************************
480 * auxGetVolume [MMSYSTEM.352]
482 UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, LPDWORD lpdwVolume)
484 LPWINE_MLD wmld;
486 TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
488 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
489 return MMSYSERR_INVALHANDLE;
490 return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L, TRUE);
493 /**************************************************************************
494 * auxSetVolume [MMSYSTEM.353]
496 UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
498 LPWINE_MLD wmld;
500 TRACE("(%04X, %u) !\n", uDeviceID, dwVolume);
502 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
503 return MMSYSERR_INVALHANDLE;
504 return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE);
507 /**************************************************************************
508 * auxOutMessage [MMSYSTEM.354]
510 DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
512 LPWINE_MLD wmld;
514 TRACE("(%04X, %04X, %08X, %08X)\n", uDeviceID, uMessage, dw1, dw2);
516 switch (uMessage) {
517 case AUXDM_GETNUMDEVS:
518 case AUXDM_SETVOLUME:
519 /* no argument conversion needed */
520 break;
521 case AUXDM_GETVOLUME:
522 return auxGetVolume16(uDeviceID, MapSL(dw1));
523 case AUXDM_GETDEVCAPS:
524 return auxGetDevCaps16(uDeviceID, MapSL(dw1), dw2);
525 default:
526 TRACE("(%04x, %04x, %08x, %08x): unhandled message\n",
527 uDeviceID, uMessage, dw1, dw2);
528 break;
530 if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
531 return MMSYSERR_INVALHANDLE;
533 return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE);
536 /* ###################################################
537 * # MCI #
538 * ###################################################
541 /**************************************************************************
542 * mciGetErrorString [MMSYSTEM.706]
544 BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer, UINT16 uLength)
546 return mciGetErrorStringA(wError, lpstrBuffer, uLength);
549 /**************************************************************************
550 * mciDriverNotify [MMSYSTEM.711]
552 BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
554 TRACE("(%04X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
556 return PostMessageA(HWND_32(hWndCallBack), MM_MCINOTIFY, wStatus, wDevID);
559 /**************************************************************************
560 * mciGetDriverData [MMSYSTEM.708]
562 DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID)
564 return mciGetDriverData(uDeviceID);
567 /**************************************************************************
568 * mciSetDriverData [MMSYSTEM.707]
570 BOOL16 WINAPI mciSetDriverData16(UINT16 uDeviceID, DWORD data)
572 return mciSetDriverData(uDeviceID, data);
575 /**************************************************************************
576 * mciSendCommand [MMSYSTEM.701]
578 DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
580 DWORD dwRet;
582 TRACE("(%04X, %s, %08X, %08X)\n",
583 wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
585 dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, FALSE);
586 dwRet = MCI_CleanUp(dwRet, wMsg, (DWORD)MapSL(dwParam2));
587 TRACE("=> %d\n", dwRet);
588 return dwRet;
591 /**************************************************************************
592 * mciGetDeviceID [MMSYSTEM.703]
594 UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
596 TRACE("(\"%s\")\n", lpstrName);
598 return mciGetDeviceIDA(lpstrName);
601 /**************************************************************************
602 * mciSetYieldProc [MMSYSTEM.714]
604 BOOL16 WINAPI mciSetYieldProc16(UINT16 uDeviceID, YIELDPROC16 fpYieldProc, DWORD dwYieldData)
606 LPWINE_MCIDRIVER wmd;
608 TRACE("(%u, %p, %08x)\n", uDeviceID, fpYieldProc, dwYieldData);
610 if (!(wmd = MCI_GetDriver(uDeviceID))) {
611 WARN("Bad uDeviceID\n");
612 return FALSE;
615 wmd->lpfnYieldProc = (YIELDPROC)fpYieldProc;
616 wmd->dwYieldData = dwYieldData;
617 wmd->bIs32 = FALSE;
619 return TRUE;
622 /**************************************************************************
623 * mciGetDeviceIDFromElementID [MMSYSTEM.715]
625 UINT16 WINAPI mciGetDeviceIDFromElementID16(DWORD dwElementID, LPCSTR lpstrType)
627 FIXME("(%u, %s) stub\n", dwElementID, lpstrType);
628 return 0;
631 /**************************************************************************
632 * mciGetYieldProc [MMSYSTEM.716]
634 YIELDPROC16 WINAPI mciGetYieldProc16(UINT16 uDeviceID, DWORD* lpdwYieldData)
636 LPWINE_MCIDRIVER wmd;
638 TRACE("(%u, %p)\n", uDeviceID, lpdwYieldData);
640 if (!(wmd = MCI_GetDriver(uDeviceID))) {
641 WARN("Bad uDeviceID\n");
642 return NULL;
644 if (!wmd->lpfnYieldProc) {
645 WARN("No proc set\n");
646 return NULL;
648 if (wmd->bIs32) {
649 WARN("Proc is 32 bit\n");
650 return NULL;
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 const WAVEFORMATEX *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);
1285 TRACE("(%04X, %08x, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1287 if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM;
1289 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1290 return MMSYSERR_INVALHANDLE;
1292 return MMDRV_Message(wmld, WODM_PREPARE, lpsegWaveOutHdr, uSize, FALSE);
1295 /**************************************************************************
1296 * waveOutUnprepareHeader [MMSYSTEM.407]
1298 UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
1299 SEGPTR lpsegWaveOutHdr, /* [???] */
1300 UINT16 uSize) /* [in] */
1302 LPWINE_MLD wmld;
1303 LPWAVEHDR lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1305 TRACE("(%04X, %08x, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1307 if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
1308 return MMSYSERR_NOERROR;
1311 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1312 return MMSYSERR_INVALHANDLE;
1314 return MMDRV_Message(wmld, WODM_UNPREPARE, lpsegWaveOutHdr, uSize, FALSE);
1317 /**************************************************************************
1318 * waveOutWrite [MMSYSTEM.408]
1320 UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, /* [in] */
1321 LPWAVEHDR lpsegWaveOutHdr, /* [???] NOTE: SEGPTR */
1322 UINT16 uSize) /* [in] */
1324 LPWINE_MLD wmld;
1326 TRACE("(%04X, %p, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1328 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1329 return MMSYSERR_INVALHANDLE;
1331 return MMDRV_Message(wmld, WODM_WRITE, (DWORD_PTR)lpsegWaveOutHdr, uSize, FALSE);
1334 /**************************************************************************
1335 * waveOutBreakLoop [MMSYSTEM.419]
1337 UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut16)
1339 DWORD level;
1340 UINT16 ret;
1342 ReleaseThunkLock(&level);
1343 ret = waveOutBreakLoop(HWAVEOUT_32(hWaveOut16));
1344 RestoreThunkLock(level);
1345 return ret;
1348 /**************************************************************************
1349 * waveOutPause [MMSYSTEM.409]
1351 UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut16)
1353 DWORD level;
1354 UINT16 ret;
1356 ReleaseThunkLock(&level);
1357 ret = waveOutPause(HWAVEOUT_32(hWaveOut16));
1358 RestoreThunkLock(level);
1359 return ret;
1362 /**************************************************************************
1363 * waveOutReset [MMSYSTEM.411]
1365 UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut16)
1367 DWORD level;
1368 UINT16 ret;
1370 ReleaseThunkLock(&level);
1371 ret = waveOutReset(HWAVEOUT_32(hWaveOut16));
1372 RestoreThunkLock(level);
1373 return ret;
1376 /**************************************************************************
1377 * waveOutRestart [MMSYSTEM.410]
1379 UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut16)
1381 DWORD level;
1382 UINT16 ret;
1384 ReleaseThunkLock(&level);
1385 ret = waveOutRestart(HWAVEOUT_32(hWaveOut16));
1386 RestoreThunkLock(level);
1387 return ret;
1390 /**************************************************************************
1391 * waveOutGetPosition [MMSYSTEM.412]
1393 UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut, LPMMTIME16 lpTime,
1394 UINT16 uSize)
1396 UINT ret;
1397 MMTIME mmt;
1399 mmt.wType = lpTime->wType;
1400 ret = waveOutGetPosition(HWAVEOUT_32(hWaveOut), &mmt, sizeof(mmt));
1401 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1402 return ret;
1405 /**************************************************************************
1406 * waveOutGetPitch [MMSYSTEM.413]
1408 UINT16 WINAPI waveOutGetPitch16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
1410 return waveOutGetPitch(HWAVEOUT_32(hWaveOut16), lpdw);
1413 /**************************************************************************
1414 * waveOutSetPitch [MMSYSTEM.414]
1416 UINT16 WINAPI waveOutSetPitch16(HWAVEOUT16 hWaveOut16, DWORD dw)
1418 return waveOutSetPitch(HWAVEOUT_32(hWaveOut16), dw);
1421 /**************************************************************************
1422 * waveOutGetPlaybackRate [MMSYSTEM.417]
1424 UINT16 WINAPI waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
1426 return waveOutGetPlaybackRate(HWAVEOUT_32(hWaveOut16), lpdw);
1429 /**************************************************************************
1430 * waveOutSetPlaybackRate [MMSYSTEM.418]
1432 UINT16 WINAPI waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16, DWORD dw)
1434 return waveOutSetPlaybackRate(HWAVEOUT_32(hWaveOut16), dw);
1437 /**************************************************************************
1438 * waveOutGetVolume [MMSYSTEM.415]
1440 UINT16 WINAPI waveOutGetVolume16(UINT16 devid, LPDWORD lpdw)
1442 return waveOutGetVolume(HWAVEOUT_32(devid), lpdw);
1445 /**************************************************************************
1446 * waveOutSetVolume [MMSYSTEM.416]
1448 UINT16 WINAPI waveOutSetVolume16(UINT16 devid, DWORD dw)
1450 return waveOutSetVolume(HWAVEOUT_32(devid), dw);
1453 /**************************************************************************
1454 * waveOutGetID [MMSYSTEM.420]
1456 UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16* lpuDeviceID)
1458 LPWINE_MLD wmld;
1460 TRACE("(%04X, %p);\n", hWaveOut, lpuDeviceID);
1462 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1464 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1465 return MMSYSERR_INVALHANDLE;
1467 *lpuDeviceID = wmld->uDeviceID;
1468 return 0;
1471 /**************************************************************************
1472 * waveOutMessage [MMSYSTEM.421]
1474 DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage,
1475 DWORD dwParam1, DWORD dwParam2)
1477 LPWINE_MLD wmld;
1479 TRACE("(%04x, %u, %d, %d)\n", hWaveOut, uMessage, dwParam1, dwParam2);
1481 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) {
1482 if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, TRUE)) != NULL) {
1483 if (uMessage == DRV_QUERYDRVENTRY || uMessage == DRV_QUERYDEVNODE)
1484 dwParam1 = (DWORD)MapSL(dwParam1);
1485 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1487 return MMSYSERR_INVALHANDLE;
1490 /* from M$ KB */
1491 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1492 return MMSYSERR_INVALPARAM;
1494 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1497 /**************************************************************************
1498 * waveInGetNumDevs [MMSYSTEM.501]
1500 UINT16 WINAPI waveInGetNumDevs16(void)
1502 return MMDRV_GetNum(MMDRV_WAVEIN);
1505 /**************************************************************************
1506 * waveInGetDevCaps [MMSYSTEM.502]
1508 UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps,
1509 UINT16 uSize)
1511 WAVEINCAPSA wicA;
1512 UINT ret;
1514 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1516 ret = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(wicA));
1517 if (ret == MMSYSERR_NOERROR) {
1518 WAVEINCAPS16 wic16;
1519 wic16.wMid = wicA.wMid;
1520 wic16.wPid = wicA.wPid;
1521 wic16.vDriverVersion = wicA.vDriverVersion;
1522 strcpy(wic16.szPname, wicA.szPname);
1523 wic16.dwFormats = wicA.dwFormats;
1524 wic16.wChannels = wicA.wChannels;
1525 memcpy(lpCaps, &wic16, min(uSize, sizeof(wic16)));
1527 return ret;
1530 /**************************************************************************
1531 * waveInOpen [MMSYSTEM.504]
1533 UINT16 WINAPI waveInOpen16(HWAVEIN16* lphWaveIn, UINT16 uDeviceID,
1534 const WAVEFORMATEX *lpFormat, DWORD dwCallback,
1535 DWORD dwInstance, DWORD dwFlags)
1537 HANDLE hWaveIn;
1538 UINT ret;
1540 /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1541 * call the 32 bit version
1542 * however, we need to promote correctly the wave mapper id
1543 * (0xFFFFFFFF and not 0x0000FFFF)
1545 ret = WAVE_Open(&hWaveIn, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
1546 MMDRV_WAVEIN, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1548 if (lphWaveIn != NULL) *lphWaveIn = HWAVEIN_16(hWaveIn);
1549 return ret;
1552 /**************************************************************************
1553 * waveInClose [MMSYSTEM.505]
1555 UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
1557 DWORD level;
1558 UINT16 ret;
1560 ReleaseThunkLock(&level);
1561 ret = waveInClose(HWAVEIN_32(hWaveIn));
1562 RestoreThunkLock(level);
1563 return ret;
1566 /**************************************************************************
1567 * waveInPrepareHeader [MMSYSTEM.506]
1569 UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1570 SEGPTR lpsegWaveInHdr, /* [???] */
1571 UINT16 uSize) /* [in] */
1573 LPWINE_MLD wmld;
1574 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1575 UINT16 ret;
1577 TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
1579 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1580 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1581 return MMSYSERR_INVALHANDLE;
1583 lpWaveInHdr->dwBytesRecorded = 0;
1585 ret = MMDRV_Message(wmld, WIDM_PREPARE, lpsegWaveInHdr, uSize, FALSE);
1586 return ret;
1589 /**************************************************************************
1590 * waveInUnprepareHeader [MMSYSTEM.507]
1592 UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
1593 SEGPTR lpsegWaveInHdr, /* [???] */
1594 UINT16 uSize) /* [in] */
1596 LPWINE_MLD wmld;
1597 LPWAVEHDR lpWaveInHdr = MapSL(lpsegWaveInHdr);
1599 TRACE("(%04X, %08x, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1601 if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1603 if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) {
1604 return MMSYSERR_NOERROR;
1607 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1608 return MMSYSERR_INVALHANDLE;
1610 return MMDRV_Message(wmld, WIDM_UNPREPARE, lpsegWaveInHdr, uSize, FALSE);
1613 /**************************************************************************
1614 * waveInAddBuffer [MMSYSTEM.508]
1616 UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn, /* [in] */
1617 WAVEHDR* lpsegWaveInHdr, /* [???] NOTE: SEGPTR */
1618 UINT16 uSize) /* [in] */
1620 LPWINE_MLD wmld;
1622 TRACE("(%04X, %p, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1624 if (lpsegWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1625 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1626 return MMSYSERR_INVALHANDLE;
1628 return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD_PTR)lpsegWaveInHdr, uSize, FALSE);
1631 /**************************************************************************
1632 * waveInReset [MMSYSTEM.511]
1634 UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn16)
1636 DWORD level;
1637 UINT16 ret;
1639 ReleaseThunkLock(&level);
1640 ret = waveInReset(HWAVEIN_32(hWaveIn16));
1641 RestoreThunkLock(level);
1642 return ret;
1645 /**************************************************************************
1646 * waveInStart [MMSYSTEM.509]
1648 UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn16)
1650 DWORD level;
1651 UINT16 ret;
1653 ReleaseThunkLock(&level);
1654 ret = waveInStart(HWAVEIN_32(hWaveIn16));
1655 RestoreThunkLock(level);
1656 return ret;
1659 /**************************************************************************
1660 * waveInStop [MMSYSTEM.510]
1662 UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn16)
1664 DWORD level;
1665 UINT16 ret;
1667 ReleaseThunkLock(&level);
1668 ret = waveInStop(HWAVEIN_32(hWaveIn16));
1669 RestoreThunkLock(level);
1670 return ret;
1673 /**************************************************************************
1674 * waveInGetPosition [MMSYSTEM.512]
1676 UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn, LPMMTIME16 lpTime,
1677 UINT16 uSize)
1679 UINT ret;
1680 MMTIME mmt;
1682 mmt.wType = lpTime->wType;
1683 ret = waveInGetPosition(HWAVEIN_32(hWaveIn), &mmt, sizeof(mmt));
1684 MMSYSTEM_MMTIME32to16(lpTime, &mmt);
1685 return ret;
1688 /**************************************************************************
1689 * waveInGetID [MMSYSTEM.513]
1691 UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16* lpuDeviceID)
1693 LPWINE_MLD wmld;
1695 TRACE("(%04X, %p);\n", hWaveIn, lpuDeviceID);
1697 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1699 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1700 return MMSYSERR_INVALHANDLE;
1702 *lpuDeviceID = wmld->uDeviceID;
1703 return MMSYSERR_NOERROR;
1706 /**************************************************************************
1707 * waveInMessage [MMSYSTEM.514]
1709 DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
1710 DWORD dwParam1, DWORD dwParam2)
1712 LPWINE_MLD wmld;
1714 TRACE("(%04x, %u, %d, %d)\n", hWaveIn, uMessage, dwParam1, dwParam2);
1716 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL) {
1717 if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, TRUE)) != NULL) {
1718 if (uMessage == DRV_QUERYDRVENTRY || uMessage == DRV_QUERYDEVNODE)
1719 dwParam1 = (DWORD)MapSL(dwParam1);
1720 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1722 return MMSYSERR_INVALHANDLE;
1725 /* from M$ KB */
1726 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
1727 return MMSYSERR_INVALPARAM;
1729 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1732 /* ###################################################
1733 * # TASK #
1734 * ###################################################
1737 /*#define USE_MM_TSK_WINE*/
1739 /**************************************************************************
1740 * mmTaskCreate [MMSYSTEM.900]
1742 * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be
1743 * called upon creation with dwPmt as parameter.
1745 HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD dwPmt)
1747 HINSTANCE16 ret;
1748 HINSTANCE16 handle;
1749 char cmdline[16];
1750 DWORD showCmd = 0x40002;
1751 LOADPARAMS16 lp;
1753 TRACE("(%08x, %p, %08x);\n", spProc, lphMmTask, dwPmt);
1754 /* This to work requires NE modules to be started with a binary command line
1755 * which is not currently the case. A patch exists but has never been committed.
1756 * A workaround would be to integrate code for mmtask.tsk into Wine, but
1757 * this requires tremendous work (starting with patching tools/build to
1758 * create NE executables (and not only DLLs) for builtins modules.
1759 * EP 99/04/25
1761 FIXME("This is currently broken. It will fail\n");
1763 cmdline[0] = 0x0d;
1764 *(LPDWORD)(cmdline + 1) = (DWORD)spProc;
1765 *(LPDWORD)(cmdline + 5) = dwPmt;
1766 *(LPDWORD)(cmdline + 9) = 0;
1768 lp.hEnvironment = 0;
1769 lp.cmdLine = MapLS(cmdline);
1770 lp.showCmd = MapLS(&showCmd);
1771 lp.reserved = 0;
1773 #ifndef USE_MM_TSK_WINE
1774 handle = LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp);
1775 #else
1776 handle = LoadModule16("mmtask.tsk", &lp);
1777 #endif
1778 if (handle < 32) {
1779 ret = (handle) ? 1 : 2;
1780 handle = 0;
1781 } else {
1782 ret = 0;
1784 if (lphMmTask)
1785 *lphMmTask = handle;
1787 UnMapLS( lp.cmdLine );
1788 UnMapLS( lp.showCmd );
1789 TRACE("=> 0x%04x/%d\n", handle, ret);
1790 return ret;
1793 #ifdef USE_MM_TSK_WINE
1794 /* C equivalent to mmtask.tsk binary content */
1795 void mmTaskEntryPoint16(LPSTR cmdLine, WORD di, WORD si)
1797 int len = cmdLine[0x80];
1799 if (len / 2 == 6) {
1800 void (*fpProc)(DWORD) = MapSL(*((DWORD*)(cmdLine + 1)));
1801 DWORD dwPmt = *((DWORD*)(cmdLine + 5));
1803 #if 0
1804 InitTask16(); /* FIXME: pmts / from context ? */
1805 InitApp(di);
1806 #endif
1807 if (SetMessageQueue16(0x40)) {
1808 WaitEvent16(0);
1809 if (HIWORD(fpProc)) {
1810 OldYield16();
1811 /* EPP StackEnter16(); */
1812 (fpProc)(dwPmt);
1816 OldYield16();
1817 OldYield16();
1818 OldYield16();
1819 ExitProcess(0);
1821 #endif
1823 /**************************************************************************
1824 * mmTaskBlock [MMSYSTEM.902]
1826 void WINAPI mmTaskBlock16(HINSTANCE16 hInst)
1828 MSG msg;
1830 do {
1831 GetMessageA(&msg, 0, 0, 0);
1832 if (msg.hwnd) {
1833 TranslateMessage(&msg);
1834 DispatchMessageA(&msg);
1836 } while (msg.message < 0x3A0);
1839 /**************************************************************************
1840 * mmTaskSignal [MMSYSTEM.903]
1842 LRESULT WINAPI mmTaskSignal16(HTASK16 ht)
1844 TRACE("(%04x);\n", ht);
1845 return PostThreadMessageW( HTASK_32(ht), WM_USER, 0, 0 );
1848 /**************************************************************************
1849 * mmGetCurrentTask [MMSYSTEM.904]
1851 HTASK16 WINAPI mmGetCurrentTask16(void)
1853 return GetCurrentTask();
1856 /**************************************************************************
1857 * mmTaskYield [MMSYSTEM.905]
1859 void WINAPI mmTaskYield16(void)
1861 MSG msg;
1863 if (PeekMessageA(&msg, 0, 0, 0, 0)) {
1864 WOWYield16();
1868 extern DWORD WINAPI GetProcessFlags(DWORD);
1870 /******************************************************************
1871 * WINMM_GetmmThread
1875 static WINE_MMTHREAD* WINMM_GetmmThread(HANDLE16 h)
1877 return (WINE_MMTHREAD*)MapSL( MAKESEGPTR(h, 0) );
1880 DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID);
1882 /**************************************************************************
1883 * mmThreadCreate [MMSYSTEM.1120]
1885 * undocumented
1886 * Creates a MM thread, calling fpThreadAddr(dwPmt).
1887 * dwFlags:
1888 * bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc
1889 * bit.1 set means to open a VxD for this thread (unsupported)
1891 LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags)
1893 HANDLE16 hndl;
1894 LRESULT ret;
1896 TRACE("(%p, %p, %08x, %08x)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags);
1898 hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT);
1900 if (hndl == 0) {
1901 ret = 2;
1902 } else {
1903 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1905 #if 0
1906 /* force mmtask routines even if mmthread is required */
1907 /* this will work only if the patch about binary cmd line and NE tasks
1908 * is committed
1910 dwFlags |= 1;
1911 #endif
1913 lpMMThd->dwSignature = WINE_MMTHREAD_CREATED;
1914 lpMMThd->dwCounter = 0;
1915 lpMMThd->hThread = 0;
1916 lpMMThd->dwThreadID = 0;
1917 lpMMThd->fpThread = (DWORD)fpThreadAddr;
1918 lpMMThd->dwThreadPmt = dwPmt;
1919 lpMMThd->dwSignalCount = 0;
1920 lpMMThd->hEvent = 0;
1921 lpMMThd->hVxD = 0;
1922 lpMMThd->dwStatus = 0;
1923 lpMMThd->dwFlags = dwFlags;
1924 lpMMThd->hTask = 0;
1926 if ((dwFlags & 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) {
1927 lpMMThd->hEvent = CreateEventW(NULL, FALSE, TRUE, NULL);
1929 TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd);
1930 if (lpMMThd->dwFlags & 2) {
1931 /* as long as we don't support MM VxD in wine, we don't need
1932 * to care about this flag
1934 /* FIXME("Don't know how to properly open VxD handles\n"); */
1935 /* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */
1938 lpMMThd->hThread = CreateThread(0, 0, WINE_mmThreadEntryPoint,
1939 (LPVOID)(DWORD_PTR)hndl, CREATE_SUSPENDED, &lpMMThd->dwThreadID);
1940 if (lpMMThd->hThread == 0) {
1941 WARN("Couldn't create thread\n");
1942 /* clean-up(VxDhandle...); devicedirectio... */
1943 if (lpMMThd->hEvent != 0)
1944 CloseHandle(lpMMThd->hEvent);
1945 ret = 2;
1946 } else {
1947 SetThreadPriority(lpMMThd->hThread, THREAD_PRIORITY_TIME_CRITICAL);
1948 TRACE("Got a nice thread hndl=%p id=0x%08x\n", lpMMThd->hThread, lpMMThd->dwThreadID);
1949 ret = 0;
1951 } else {
1952 /* get WINE_mmThreadEntryPoint()
1953 * 2047 is its ordinal in mmsystem.spec
1955 FARPROC16 fp = GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR)2047);
1957 TRACE("farproc seg=0x%p lin=%p\n", fp, MapSL((SEGPTR)fp));
1959 ret = (fp == 0) ? 2 : mmTaskCreate16((DWORD)fp, 0, hndl);
1962 if (ret == 0) {
1963 if (lpMMThd->hThread && !ResumeThread(lpMMThd->hThread))
1964 WARN("Couldn't resume thread\n");
1966 while (lpMMThd->dwStatus != 0x10) { /* test also HIWORD of dwStatus */
1967 UserYield16();
1972 if (ret != 0) {
1973 GlobalFree16(hndl);
1974 hndl = 0;
1977 if (lpHndl)
1978 *lpHndl = hndl;
1980 TRACE("ok => %ld\n", ret);
1981 return ret;
1984 /**************************************************************************
1985 * mmThreadSignal [MMSYSTEM.1121]
1987 void WINAPI mmThreadSignal16(HANDLE16 hndl)
1989 TRACE("(%04x)!\n", hndl);
1991 if (hndl) {
1992 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
1994 lpMMThd->dwCounter++;
1995 if (lpMMThd->hThread != 0) {
1996 InterlockedIncrement(&lpMMThd->dwSignalCount);
1997 SetEvent(lpMMThd->hEvent);
1998 } else {
1999 mmTaskSignal16(lpMMThd->hTask);
2001 lpMMThd->dwCounter--;
2005 static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd)
2007 MSG msg;
2008 DWORD ret;
2010 if (lpMMThd->dwThreadID != GetCurrentThreadId())
2011 ERR("Not called by thread itself\n");
2013 for (;;) {
2014 ResetEvent(lpMMThd->hEvent);
2015 if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0)
2016 break;
2017 InterlockedIncrement(&lpMMThd->dwSignalCount);
2019 TRACE("S1\n");
2021 ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT);
2022 switch (ret) {
2023 case WAIT_OBJECT_0: /* Event */
2024 TRACE("S2.1\n");
2025 break;
2026 case WAIT_OBJECT_0 + 1: /* Msg */
2027 TRACE("S2.2\n");
2028 if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
2029 TranslateMessage(&msg);
2030 DispatchMessageA(&msg);
2032 break;
2033 default:
2034 WARN("S2.x unsupported ret val 0x%08x\n", ret);
2036 TRACE("S3\n");
2040 /**************************************************************************
2041 * mmThreadBlock [MMSYSTEM.1122]
2043 void WINAPI mmThreadBlock16(HANDLE16 hndl)
2045 TRACE("(%04x)!\n", hndl);
2047 if (hndl) {
2048 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2050 if (lpMMThd->hThread != 0) {
2051 DWORD lc;
2053 ReleaseThunkLock(&lc);
2054 MMSYSTEM_ThreadBlock(lpMMThd);
2055 RestoreThunkLock(lc);
2056 } else {
2057 mmTaskBlock16(lpMMThd->hTask);
2060 TRACE("done\n");
2063 /**************************************************************************
2064 * mmThreadIsCurrent [MMSYSTEM.1123]
2066 BOOL16 WINAPI mmThreadIsCurrent16(HANDLE16 hndl)
2068 BOOL16 ret = FALSE;
2070 TRACE("(%04x)!\n", hndl);
2072 if (hndl && mmThreadIsValid16(hndl)) {
2073 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2074 ret = (GetCurrentThreadId() == lpMMThd->dwThreadID);
2076 TRACE("=> %d\n", ret);
2077 return ret;
2080 /**************************************************************************
2081 * mmThreadIsValid [MMSYSTEM.1124]
2083 BOOL16 WINAPI mmThreadIsValid16(HANDLE16 hndl)
2085 BOOL16 ret = FALSE;
2087 TRACE("(%04x)!\n", hndl);
2089 if (hndl) {
2090 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2092 if (!IsBadWritePtr(lpMMThd, sizeof(WINE_MMTHREAD)) &&
2093 lpMMThd->dwSignature == WINE_MMTHREAD_CREATED &&
2094 IsTask16(lpMMThd->hTask)) {
2095 lpMMThd->dwCounter++;
2096 if (lpMMThd->hThread != 0) {
2097 DWORD dwThreadRet;
2098 if (GetExitCodeThread(lpMMThd->hThread, &dwThreadRet) &&
2099 dwThreadRet == STATUS_PENDING) {
2100 ret = TRUE;
2102 } else {
2103 ret = TRUE;
2105 lpMMThd->dwCounter--;
2108 TRACE("=> %d\n", ret);
2109 return ret;
2112 /**************************************************************************
2113 * mmThreadGetTask [MMSYSTEM.1125]
2115 HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl)
2117 HANDLE16 ret = 0;
2119 TRACE("(%04x)\n", hndl);
2121 if (mmThreadIsValid16(hndl)) {
2122 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2123 ret = lpMMThd->hTask;
2125 return ret;
2128 /**************************************************************************
2129 * __wine_mmThreadEntryPoint (MMSYSTEM.2047)
2131 DWORD WINAPI WINE_mmThreadEntryPoint(LPVOID p)
2133 HANDLE16 hndl = (HANDLE16)(DWORD_PTR)p;
2134 WINE_MMTHREAD* lpMMThd = WINMM_GetmmThread(hndl);
2136 TRACE("(%04x %p)\n", hndl, lpMMThd);
2138 lpMMThd->hTask = LOWORD(GetCurrentTask());
2139 TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask);
2140 lpMMThd->dwStatus = 0x10;
2141 MMSYSTEM_ThreadBlock(lpMMThd);
2142 TRACE("[20-%p]\n", lpMMThd->hThread);
2143 lpMMThd->dwStatus = 0x20;
2144 if (lpMMThd->fpThread) {
2145 WOWCallback16(lpMMThd->fpThread, lpMMThd->dwThreadPmt);
2147 lpMMThd->dwStatus = 0x30;
2148 TRACE("[30-%p]\n", lpMMThd->hThread);
2149 while (lpMMThd->dwCounter) {
2150 Sleep(1);
2151 /* WOWYield16();*/
2153 TRACE("[XX-%p]\n", lpMMThd->hThread);
2154 /* paranoia */
2155 lpMMThd->dwSignature = WINE_MMTHREAD_DELETED;
2156 /* close lpMMThread->hVxD directIO */
2157 if (lpMMThd->hEvent)
2158 CloseHandle(lpMMThd->hEvent);
2159 GlobalFree16(hndl);
2160 TRACE("done\n");
2162 return 0;
2165 typedef BOOL16 (WINAPI *MMCPLCALLBACK)(HWND, LPCSTR, LPCSTR, LPCSTR);
2167 /**************************************************************************
2168 * mmShowMMCPLPropertySheet [MMSYSTEM.1150]
2170 BOOL16 WINAPI mmShowMMCPLPropertySheet16(HWND hWnd, LPCSTR lpStrDevice,
2171 LPCSTR lpStrTab, LPCSTR lpStrTitle)
2173 HANDLE hndl;
2174 BOOL16 ret = FALSE;
2176 TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2178 hndl = LoadLibraryA("MMSYS.CPL");
2179 if (hndl != 0) {
2180 MMCPLCALLBACK fp = (MMCPLCALLBACK)GetProcAddress(hndl, "ShowMMCPLPropertySheet");
2181 if (fp != NULL) {
2182 DWORD lc;
2183 ReleaseThunkLock(&lc);
2184 ret = (fp)(hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2185 RestoreThunkLock(lc);
2187 FreeLibrary(hndl);
2190 return ret;
2193 /**************************************************************************
2194 * StackEnter [MMSYSTEM.32]
2196 void WINAPI StackEnter16(void)
2198 #ifdef __i386__
2199 /* mmsystem.dll from Win 95 does only this: so does Wine */
2200 __asm__("stc");
2201 #endif
2204 /**************************************************************************
2205 * StackLeave [MMSYSTEM.33]
2207 void WINAPI StackLeave16(void)
2209 #ifdef __i386__
2210 /* mmsystem.dll from Win 95 does only this: so does Wine */
2211 __asm__("stc");
2212 #endif
2215 /**************************************************************************
2216 * WMMMidiRunOnce [MMSYSTEM.8]
2218 void WINAPI WMMMidiRunOnce16(void)
2220 FIXME("(), stub!\n");
2223 /* ###################################################
2224 * # DRIVER #
2225 * ###################################################
2228 /**************************************************************************
2229 * DRIVER_MapMsg32To16 [internal]
2231 * Map a 32 bit driver message to a 16 bit driver message.
2233 static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, LPARAM *lParam1, LPARAM *lParam2)
2235 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2237 switch (wMsg) {
2238 case DRV_LOAD:
2239 case DRV_ENABLE:
2240 case DRV_DISABLE:
2241 case DRV_FREE:
2242 case DRV_QUERYCONFIGURE:
2243 case DRV_REMOVE:
2244 case DRV_EXITSESSION:
2245 case DRV_EXITAPPLICATION:
2246 case DRV_POWER:
2247 case DRV_CLOSE: /* should be 0/0 */
2248 case DRV_OPEN: /* pass through */
2249 /* lParam1 and lParam2 are not used */
2250 ret = WINMM_MAP_OK;
2251 break;
2252 case DRV_CONFIGURE:
2253 case DRV_INSTALL:
2254 /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
2255 * lParam2 is a pointer to DRVCONFIGINFO
2257 if (*lParam2) {
2258 LPDRVCONFIGINFO16 dci16 = HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16) );
2259 LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
2261 if (dci16) {
2262 LPSTR str1 = NULL,str2;
2263 INT len;
2264 dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
2266 if (dci32->lpszDCISectionName) {
2267 len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, NULL, 0, NULL, NULL );
2268 str1 = HeapAlloc( GetProcessHeap(), 0, len );
2269 if (str1) {
2270 WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCISectionName, -1, str1, len, NULL, NULL );
2271 dci16->lpszDCISectionName = MapLS( str1 );
2272 } else {
2273 HeapFree( GetProcessHeap(), 0, dci16);
2274 return WINMM_MAP_NOMEM;
2276 } else {
2277 dci16->lpszDCISectionName = 0L;
2279 if (dci32->lpszDCIAliasName) {
2280 len = WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, NULL, 0, NULL, NULL );
2281 str2 = HeapAlloc( GetProcessHeap(), 0, len );
2282 if (str2) {
2283 WideCharToMultiByte( CP_ACP, 0, dci32->lpszDCIAliasName, -1, str2, len, NULL, NULL );
2284 dci16->lpszDCIAliasName = MapLS( str2 );
2285 } else {
2286 HeapFree( GetProcessHeap(), 0, str1);
2287 HeapFree( GetProcessHeap(), 0, dci16);
2288 return WINMM_MAP_NOMEM;
2290 } else {
2291 dci16->lpszDCISectionName = 0L;
2293 } else {
2294 return WINMM_MAP_NOMEM;
2296 *lParam2 = MapLS( dci16 );
2297 ret = WINMM_MAP_OKMEM;
2298 } else {
2299 ret = WINMM_MAP_OK;
2301 break;
2302 default:
2303 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2304 FIXME("Unknown message 0x%04x\n", wMsg);
2306 ret = WINMM_MAP_OK;
2308 return ret;
2311 /**************************************************************************
2312 * DRIVER_UnMapMsg32To16 [internal]
2314 * UnMap a 32 bit driver message to a 16 bit driver message.
2316 static WINMM_MapType DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
2318 WINMM_MapType ret = WINMM_MAP_MSGERROR;
2320 switch (wMsg) {
2321 case DRV_LOAD:
2322 case DRV_ENABLE:
2323 case DRV_DISABLE:
2324 case DRV_FREE:
2325 case DRV_QUERYCONFIGURE:
2326 case DRV_REMOVE:
2327 case DRV_EXITSESSION:
2328 case DRV_EXITAPPLICATION:
2329 case DRV_POWER:
2330 case DRV_OPEN:
2331 case DRV_CLOSE:
2332 /* lParam1 and lParam2 are not used */
2333 break;
2334 case DRV_CONFIGURE:
2335 case DRV_INSTALL:
2336 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
2337 if (lParam2) {
2338 LPDRVCONFIGINFO16 dci16 = MapSL(lParam2);
2339 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCISectionName) );
2340 HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCIAliasName) );
2341 UnMapLS( lParam2 );
2342 UnMapLS( dci16->lpszDCISectionName );
2343 UnMapLS( dci16->lpszDCIAliasName );
2344 HeapFree( GetProcessHeap(), 0, dci16 );
2346 ret = WINMM_MAP_OK;
2347 break;
2348 default:
2349 if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
2350 FIXME("Unknown message 0x%04x\n", wMsg);
2352 ret = WINMM_MAP_OK;
2354 return ret;
2357 /**************************************************************************
2358 * DRIVER_TryOpenDriver16 [internal]
2360 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
2362 static LPWINE_DRIVER DRIVER_OpenDriver16(LPCWSTR fn, LPCWSTR sn, LPARAM lParam2)
2364 LPWINE_DRIVER lpDrv = NULL;
2365 LPCSTR cause = NULL;
2366 LPSTR fnA = NULL, snA = NULL;
2367 unsigned len;
2369 TRACE("(%s, %s, %08lX);\n", debugstr_w(fn), debugstr_w(sn), lParam2);
2371 lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
2372 if (lpDrv == NULL) {cause = "OOM"; goto exit;}
2374 if (fn)
2376 len = WideCharToMultiByte( CP_ACP, 0, fn, -1, NULL, 0, NULL, NULL );
2377 fnA = HeapAlloc(GetProcessHeap(), 0, len);
2378 if (fnA == NULL) {cause = "OOM"; goto exit;}
2379 WideCharToMultiByte( CP_ACP, 0, fn, -1, fnA, len, NULL, NULL );
2382 if (sn)
2384 len = WideCharToMultiByte( CP_ACP, 0, sn, -1, NULL, 0, NULL, NULL );
2385 snA = HeapAlloc(GetProcessHeap(), 0, len);
2386 if (snA == NULL) {cause = "OOM"; goto exit;}
2387 WideCharToMultiByte( CP_ACP, 0, sn, -1, snA, len, NULL, NULL );
2390 /* FIXME: shall we do some black magic here on sn ?
2391 * drivers32 => drivers
2392 * mci32 => mci
2393 * ...
2395 lpDrv->d.d16.hDriver16 = OpenDriver16(fnA, snA, lParam2);
2396 if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;}
2397 lpDrv->dwFlags = WINE_GDF_16BIT;
2399 TRACE("=> %p\n", lpDrv);
2400 return lpDrv;
2402 exit:
2403 HeapFree(GetProcessHeap(), 0, lpDrv);
2404 HeapFree(GetProcessHeap(), 0, fnA);
2405 HeapFree(GetProcessHeap(), 0, snA);
2406 TRACE("Unable to load 16 bit module %s[%s]: %s\n",
2407 debugstr_w(fn), debugstr_w(sn), cause);
2408 return NULL;
2411 /******************************************************************
2412 * DRIVER_SendMessage16
2416 static LRESULT DRIVER_SendMessage16(HDRVR16 hDrv16, UINT msg,
2417 LPARAM lParam1, LPARAM lParam2)
2419 LRESULT ret = 0;
2420 WINMM_MapType map;
2422 TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
2423 hDrv16, msg, lParam1, lParam2);
2425 switch (map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) {
2426 case WINMM_MAP_OKMEM:
2427 case WINMM_MAP_OK:
2428 ret = SendDriverMessage16(hDrv16, msg, lParam1, lParam2);
2429 if (map == WINMM_MAP_OKMEM)
2430 DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
2431 default:
2432 break;
2434 return ret;
2437 /******************************************************************
2438 * DRIVER_CloseDriver16
2442 static LRESULT DRIVER_CloseDriver16(HDRVR16 hDrv16, LPARAM lParam1, LPARAM lParam2)
2444 return CloseDriver16(hDrv16, lParam1, lParam2);
2447 /**************************************************************************
2448 * DrvOpen [MMSYSTEM.1100]
2450 HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
2452 return OpenDriver16(lpDriverName, lpSectionName, lParam);
2455 /**************************************************************************
2456 * DrvClose [MMSYSTEM.1101]
2458 LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
2460 return CloseDriver16(hDrv, lParam1, lParam2);
2463 /**************************************************************************
2464 * DrvSendMessage [MMSYSTEM.1102]
2466 LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
2467 LPARAM lParam2)
2469 return SendDriverMessage16(hDrv, msg, lParam1, lParam2);
2472 /**************************************************************************
2473 * DrvGetModuleHandle [MMSYSTEM.1103]
2475 HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
2477 return GetDriverModuleHandle16(hDrv);
2480 /**************************************************************************
2481 * DrvDefDriverProc [MMSYSTEM.1104]
2483 LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg,
2484 DWORD dwParam1, DWORD dwParam2)
2486 return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
2489 /**************************************************************************
2490 * DriverProc [MMSYSTEM.6]
2492 LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
2493 DWORD dwParam1, DWORD dwParam2)
2495 TRACE("dwDevID=%08x hDrv=%04x wMsg=%04x dwParam1=%08x dwParam2=%08x\n",
2496 dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2498 return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
2501 /* ###################################################
2502 * # TIME #
2503 * ###################################################
2506 /******************************************************************
2507 * MMSYSTEM_MMTIME32to16
2511 void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32)
2513 mmt16->wType = mmt32->wType;
2514 /* layout of rest is the same for 32/16,
2515 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2517 memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u));
2520 /******************************************************************
2521 * MMSYSTEM_MMTIME16to32
2525 void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16)
2527 mmt32->wType = mmt16->wType;
2528 /* layout of rest is the same for 32/16,
2529 * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
2531 memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u));
2534 /**************************************************************************
2535 * timeGetSystemTime [MMSYSTEM.601]
2537 MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
2539 if (wSize >= sizeof(*lpTime)) {
2540 lpTime->wType = TIME_MS;
2541 lpTime->u.ms = GetTickCount();
2543 TRACE("=> %u\n", lpTime->u.ms);
2546 return 0;
2549 /**************************************************************************
2550 * timeSetEvent [MMSYSTEM.602]
2552 MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc,
2553 DWORD dwUser, UINT16 wFlags)
2555 if (wFlags & WINE_TIMER_IS32)
2556 WARN("Unknown windows flag... wine internally used.. ooch\n");
2558 return TIME_SetEventInternal(wDelay, wResol, (LPTIMECALLBACK)lpFunc,
2559 dwUser, wFlags & ~WINE_TIMER_IS32);
2562 /**************************************************************************
2563 * timeKillEvent [MMSYSTEM.603]
2565 MMRESULT16 WINAPI timeKillEvent16(UINT16 wID)
2567 return timeKillEvent(wID);
2570 /**************************************************************************
2571 * timeGetDevCaps [MMSYSTEM.604]
2573 MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize)
2575 TIMECAPS caps;
2576 MMRESULT ret;
2577 TRACE("(%p, %u) !\n", lpCaps, wSize);
2579 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2581 ret = timeGetDevCaps(&caps, sizeof(caps));
2582 if (ret == MMSYSERR_NOERROR) {
2583 TIMECAPS16 tc16;
2584 tc16.wPeriodMin = caps.wPeriodMin;
2585 tc16.wPeriodMax = caps.wPeriodMax;
2586 memcpy(lpCaps, &tc16, min(wSize, sizeof(tc16)));
2588 return ret;
2591 /**************************************************************************
2592 * timeBeginPeriod [MMSYSTEM.605]
2594 MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod)
2596 TRACE("(%u) !\n", wPeriod);
2598 return timeBeginPeriod(wPeriod);
2601 /**************************************************************************
2602 * timeEndPeriod [MMSYSTEM.606]
2604 MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod)
2606 TRACE("(%u) !\n", wPeriod);
2608 return timeEndPeriod(wPeriod);
2611 /**************************************************************************
2612 * mciSendString [MMSYSTEM.702]
2614 DWORD WINAPI mciSendString16(LPCSTR lpstrCommand, LPSTR lpstrRet,
2615 UINT16 uRetLen, HWND16 hwndCallback)
2617 return mciSendStringA(lpstrCommand, lpstrRet, uRetLen, HWND_32(hwndCallback));
2620 /**************************************************************************
2621 * mciLoadCommandResource [MMSYSTEM.705]
2623 UINT16 WINAPI mciLoadCommandResource16(HINSTANCE16 hInst, LPCSTR resname, UINT16 type)
2625 HRSRC16 res;
2626 HGLOBAL16 handle;
2627 const BYTE* ptr16;
2628 BYTE* ptr32;
2629 unsigned pos = 0, size = 1024, len;
2630 const char* str;
2631 DWORD flg;
2632 WORD eid;
2633 UINT16 ret = MCIERR_OUT_OF_MEMORY;
2635 if (!(res = FindResource16( hInst, resname, (LPSTR)RT_RCDATA))) return MCI_NO_COMMAND_TABLE;
2636 if (!(handle = LoadResource16( hInst, res ))) return MCI_NO_COMMAND_TABLE;
2637 ptr16 = LockResource16(handle);
2638 /* converting the 16 bit resource table into a 32W one */
2639 if ((ptr32 = HeapAlloc(GetProcessHeap(), 0, size)))
2641 do {
2642 str = (LPCSTR)ptr16;
2643 ptr16 += strlen(str) + 1;
2644 flg = *(const DWORD*)ptr16;
2645 eid = *(const WORD*)(ptr16 + sizeof(DWORD));
2646 ptr16 += sizeof(DWORD) + sizeof(WORD);
2647 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0) * sizeof(WCHAR);
2648 if (pos + len + sizeof(DWORD) + sizeof(WORD) > size)
2650 while (pos + len * sizeof(WCHAR) + sizeof(DWORD) + sizeof(WORD) > size) size += 1024;
2651 ptr32 = HeapReAlloc(GetProcessHeap(), 0, ptr32, size);
2652 if (!ptr32) goto the_end;
2654 MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)(ptr32 + pos), len / sizeof(WCHAR));
2655 *(DWORD*)(ptr32 + pos + len) = flg;
2656 *(WORD*)(ptr32 + pos + len + sizeof(DWORD)) = eid;
2657 pos += len + sizeof(DWORD) + sizeof(WORD);
2658 } while (eid != MCI_END_COMMAND_LIST);
2660 the_end:
2661 FreeResource16( handle );
2662 if (ptr32) ret = MCI_SetCommandTable(ptr32, type);
2663 return ret;
2666 /**************************************************************************
2667 * mciFreeCommandResource [MMSYSTEM.713]
2669 BOOL16 WINAPI mciFreeCommandResource16(UINT16 uTable)
2671 TRACE("(%04x)!\n", uTable);
2673 return MCI_DeleteCommandTable(uTable, TRUE);
2676 /* ###################################################
2677 * # MMIO #
2678 * ###################################################
2681 /****************************************************************
2682 * MMIO_Map32To16 [INTERNAL]
2684 static LRESULT MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2)
2686 switch (wMsg) {
2687 case MMIOM_CLOSE:
2688 case MMIOM_SEEK:
2689 /* nothing to do */
2690 break;
2691 case MMIOM_OPEN:
2692 case MMIOM_READ:
2693 case MMIOM_WRITE:
2694 case MMIOM_WRITEFLUSH:
2695 *lp1 = MapLS( (void *)*lp1 );
2696 break;
2697 case MMIOM_RENAME:
2698 *lp1 = MapLS( (void *)*lp1 );
2699 *lp2 = MapLS( (void *)*lp2 );
2700 break;
2701 default:
2702 if (wMsg < MMIOM_USER)
2703 TRACE("Not a mappable message (%d)\n", wMsg);
2705 return MMSYSERR_NOERROR;
2708 /****************************************************************
2709 * MMIO_UnMap32To16 [INTERNAL]
2711 static LRESULT MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2,
2712 LPARAM lp1, LPARAM lp2)
2714 switch (wMsg) {
2715 case MMIOM_CLOSE:
2716 case MMIOM_SEEK:
2717 /* nothing to do */
2718 break;
2719 case MMIOM_OPEN:
2720 case MMIOM_READ:
2721 case MMIOM_WRITE:
2722 case MMIOM_WRITEFLUSH:
2723 UnMapLS( lp1 );
2724 break;
2725 case MMIOM_RENAME:
2726 UnMapLS( lp1 );
2727 UnMapLS( lp2 );
2728 break;
2729 default:
2730 if (wMsg < MMIOM_USER)
2731 TRACE("Not a mappable message (%d)\n", wMsg);
2733 return MMSYSERR_NOERROR;
2736 /******************************************************************
2737 * MMIO_Callback16
2741 static LRESULT MMIO_Callback16(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage,
2742 LPARAM lParam1, LPARAM lParam2)
2744 DWORD result;
2745 MMIOINFO16 mmioInfo16;
2746 SEGPTR segmmioInfo16;
2747 LPARAM lp1 = lParam1, lp2 = lParam2;
2748 WORD args[7];
2750 memset(&mmioInfo16, 0, sizeof(MMIOINFO16));
2751 mmioInfo16.lDiskOffset = lpmmioinfo->lDiskOffset;
2752 mmioInfo16.adwInfo[0] = lpmmioinfo->adwInfo[0];
2753 mmioInfo16.adwInfo[1] = lpmmioinfo->adwInfo[1];
2754 mmioInfo16.adwInfo[2] = lpmmioinfo->adwInfo[2];
2755 /* map (lParam1, lParam2) into (lp1, lp2) 32=>16 */
2756 if ((result = MMIO_Map32To16(uMessage, &lp1, &lp2)) != MMSYSERR_NOERROR)
2757 return result;
2759 segmmioInfo16 = MapLS(&mmioInfo16);
2760 args[6] = HIWORD(segmmioInfo16);
2761 args[5] = LOWORD(segmmioInfo16);
2762 args[4] = uMessage;
2763 args[3] = HIWORD(lp1);
2764 args[2] = LOWORD(lp1);
2765 args[1] = HIWORD(lp2);
2766 args[0] = LOWORD(lp2);
2767 WOWCallback16Ex( cb16, WCB16_PASCAL, sizeof(args), args, &result );
2768 UnMapLS(segmmioInfo16);
2769 MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2);
2771 lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset;
2772 lpmmioinfo->adwInfo[0] = mmioInfo16.adwInfo[0];
2773 lpmmioinfo->adwInfo[1] = mmioInfo16.adwInfo[1];
2774 lpmmioinfo->adwInfo[2] = mmioInfo16.adwInfo[2];
2776 return result;
2779 /******************************************************************
2780 * MMIO_ResetSegmentedData
2783 static LRESULT MMIO_SetSegmentedBuffer(HMMIO hmmio, SEGPTR ptr, BOOL release)
2785 LPWINE_MMIO wm;
2787 if ((wm = MMIO_Get(hmmio)) == NULL)
2788 return MMSYSERR_INVALHANDLE;
2789 if (release) UnMapLS(wm->segBuffer16);
2790 wm->segBuffer16 = ptr;
2791 return MMSYSERR_NOERROR;
2794 /**************************************************************************
2795 * mmioOpen [MMSYSTEM.1210]
2797 HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16,
2798 DWORD dwOpenFlags)
2800 HMMIO ret;
2802 if (lpmmioinfo16) {
2803 MMIOINFO mmioinfo;
2805 memset(&mmioinfo, 0, sizeof(mmioinfo));
2807 mmioinfo.dwFlags = lpmmioinfo16->dwFlags;
2808 mmioinfo.fccIOProc = lpmmioinfo16->fccIOProc;
2809 mmioinfo.pIOProc = (LPMMIOPROC)lpmmioinfo16->pIOProc;
2810 mmioinfo.cchBuffer = lpmmioinfo16->cchBuffer;
2811 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo16->pchBuffer);
2812 mmioinfo.adwInfo[0] = lpmmioinfo16->adwInfo[0];
2813 /* if we don't have a file name, it's likely a passed open file descriptor */
2814 if (!szFileName)
2815 mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]);
2816 mmioinfo.adwInfo[1] = lpmmioinfo16->adwInfo[1];
2817 mmioinfo.adwInfo[2] = lpmmioinfo16->adwInfo[2];
2819 ret = MMIO_Open(szFileName, &mmioinfo, dwOpenFlags, MMIO_PROC_16);
2820 MMIO_SetSegmentedBuffer(mmioinfo.hmmio, (SEGPTR)lpmmioinfo16->pchBuffer, FALSE);
2822 lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet;
2823 lpmmioinfo16->hmmio = HMMIO_16(mmioinfo.hmmio);
2824 } else {
2825 ret = MMIO_Open(szFileName, NULL, dwOpenFlags, MMIO_PROC_32A);
2827 return HMMIO_16(ret);
2830 /**************************************************************************
2831 * mmioClose [MMSYSTEM.1211]
2833 MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
2835 MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), (SEGPTR)NULL, TRUE);
2836 return mmioClose(HMMIO_32(hmmio), uFlags);
2839 /**************************************************************************
2840 * mmioRead [MMSYSTEM.1212]
2842 LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
2844 return mmioRead(HMMIO_32(hmmio), pch, cch);
2847 /**************************************************************************
2848 * mmioWrite [MMSYSTEM.1213]
2850 LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
2852 return mmioWrite(HMMIO_32(hmmio),pch,cch);
2855 /**************************************************************************
2856 * mmioSeek [MMSYSTEM.1214]
2858 LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
2860 return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin);
2863 /**************************************************************************
2864 * mmioGetInfo [MMSYSTEM.1215]
2866 MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2868 MMIOINFO mmioinfo;
2869 MMRESULT ret;
2870 LPWINE_MMIO wm;
2872 TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags);
2874 if ((wm = MMIO_Get(HMMIO_32(hmmio))) == NULL)
2875 return MMSYSERR_INVALHANDLE;
2877 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
2878 if (ret != MMSYSERR_NOERROR) return ret;
2880 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
2881 lpmmioinfo->fccIOProc = mmioinfo.fccIOProc;
2882 lpmmioinfo->pIOProc = (wm->ioProc->type == MMIO_PROC_16) ?
2883 (LPMMIOPROC16)wm->ioProc->pIOProc : NULL;
2884 lpmmioinfo->wErrorRet = mmioinfo.wErrorRet;
2885 lpmmioinfo->hTask = HTASK_16(mmioinfo.hTask);
2886 lpmmioinfo->cchBuffer = mmioinfo.cchBuffer;
2887 lpmmioinfo->pchBuffer = (void*)wm->segBuffer16;
2888 lpmmioinfo->pchNext = (void*)(wm->segBuffer16 + (mmioinfo.pchNext - mmioinfo.pchBuffer));
2889 lpmmioinfo->pchEndRead = (void*)(wm->segBuffer16 + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
2890 lpmmioinfo->pchEndWrite = (void*)(wm->segBuffer16 + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
2891 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
2892 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
2893 lpmmioinfo->adwInfo[0] = mmioinfo.adwInfo[0];
2894 lpmmioinfo->adwInfo[1] = mmioinfo.adwInfo[1];
2895 lpmmioinfo->adwInfo[2] = mmioinfo.adwInfo[2];
2896 lpmmioinfo->dwReserved1 = 0;
2897 lpmmioinfo->dwReserved2 = 0;
2898 lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio);
2900 return MMSYSERR_NOERROR;
2903 /**************************************************************************
2904 * mmioSetInfo [MMSYSTEM.1216]
2906 MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2908 MMIOINFO mmioinfo;
2909 MMRESULT ret;
2911 TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
2913 ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0);
2914 if (ret != MMSYSERR_NOERROR) return ret;
2916 /* check if seg and lin buffers are the same */
2917 if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer ||
2918 mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer))
2919 return MMSYSERR_INVALPARAM;
2921 /* check pointers coherence */
2922 if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer ||
2923 lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
2924 lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer ||
2925 lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
2926 lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer ||
2927 lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer)
2928 return MMSYSERR_INVALPARAM;
2930 mmioinfo.pchNext = mmioinfo.pchBuffer + (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer);
2931 mmioinfo.pchEndRead = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead - lpmmioinfo->pchBuffer);
2932 mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer);
2934 return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
2937 /**************************************************************************
2938 * mmioSetBuffer [MMSYSTEM.1217]
2940 MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, LPSTR pchBuffer,
2941 LONG cchBuffer, UINT16 uFlags)
2943 MMRESULT ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL((DWORD)pchBuffer),
2944 cchBuffer, uFlags);
2946 if (ret == MMSYSERR_NOERROR)
2947 MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), (DWORD)pchBuffer, TRUE);
2948 else
2949 UnMapLS((DWORD)pchBuffer);
2950 return ret;
2953 /**************************************************************************
2954 * mmioFlush [MMSYSTEM.1218]
2956 MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
2958 return mmioFlush(HMMIO_32(hmmio), uFlags);
2961 /***********************************************************************
2962 * mmioAdvance [MMSYSTEM.1219]
2964 MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
2966 MMIOINFO mmioinfo;
2967 LRESULT ret;
2969 /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which
2970 * fields to init
2972 if (lpmmioinfo)
2974 mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer);
2975 mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext);
2976 mmioinfo.dwFlags = lpmmioinfo->dwFlags;
2977 mmioinfo.lBufOffset = lpmmioinfo->lBufOffset;
2978 ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags);
2980 else
2981 ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags);
2983 if (ret != MMSYSERR_NOERROR) return ret;
2985 if (lpmmioinfo)
2987 lpmmioinfo->dwFlags = mmioinfo.dwFlags;
2988 lpmmioinfo->pchNext = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
2989 lpmmioinfo->pchEndRead = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
2990 lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
2991 lpmmioinfo->lBufOffset = mmioinfo.lBufOffset;
2992 lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
2995 return MMSYSERR_NOERROR;
2998 /**************************************************************************
2999 * mmioStringToFOURCC [MMSYSTEM.1220]
3001 FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
3003 return mmioStringToFOURCCA(sz, uFlags);
3006 /**************************************************************************
3007 * mmioInstallIOProc [MMSYSTEM.1221]
3009 LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc,
3010 DWORD dwFlags)
3012 return (LPMMIOPROC16)MMIO_InstallIOProc(fccIOProc, (LPMMIOPROC)pIOProc,
3013 dwFlags, MMIO_PROC_16);
3016 /**************************************************************************
3017 * mmioSendMessage [MMSYSTEM.1222]
3019 LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage,
3020 LPARAM lParam1, LPARAM lParam2)
3022 return MMIO_SendMessage(HMMIO_32(hmmio), uMessage,
3023 lParam1, lParam2, MMIO_PROC_16);
3026 /**************************************************************************
3027 * mmioDescend [MMSYSTEM.1223]
3029 MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck,
3030 const MMCKINFO* lpckParent, UINT16 uFlags)
3032 return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags);
3035 /**************************************************************************
3036 * mmioAscend [MMSYSTEM.1224]
3038 MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
3040 return mmioAscend(HMMIO_32(hmmio),lpck,uFlags);
3043 /**************************************************************************
3044 * mmioCreateChunk [MMSYSTEM.1225]
3046 MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
3048 return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags);
3051 /**************************************************************************
3052 * mmioRename [MMSYSTEM.1226]
3054 MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName,
3055 MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags)
3057 BOOL inst = FALSE;
3058 MMRESULT ret;
3059 MMIOINFO mmioinfo;
3061 if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL &&
3062 lpmmioinfo->fccIOProc == 0) {
3063 FIXME("Can't handle this case yet\n");
3064 return MMSYSERR_ERROR;
3067 /* this is a bit hacky, but it'll work if we get a fourCC code or nothing.
3068 * but a non installed ioproc without a fourcc won't do
3070 if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) {
3071 MMIO_InstallIOProc(lpmmioinfo->fccIOProc, (LPMMIOPROC)lpmmioinfo->pIOProc,
3072 MMIO_INSTALLPROC, MMIO_PROC_16);
3073 inst = TRUE;
3075 memset(&mmioinfo, 0, sizeof(mmioinfo));
3076 mmioinfo.fccIOProc = lpmmioinfo->fccIOProc;
3077 ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags);
3078 if (inst) {
3079 MMIO_InstallIOProc(lpmmioinfo->fccIOProc, NULL,
3080 MMIO_REMOVEPROC, MMIO_PROC_16);
3082 return ret;
3085 /* ###################################################
3086 * # JOYSTICK #
3087 * ###################################################
3090 /**************************************************************************
3091 * joyGetNumDevs [MMSYSTEM.101]
3093 UINT16 WINAPI joyGetNumDevs16(void)
3095 return joyGetNumDevs();
3098 /**************************************************************************
3099 * joyGetDevCaps [MMSYSTEM.102]
3101 MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize)
3103 JOYCAPSA jca;
3104 MMRESULT ret;
3106 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
3108 ret = joyGetDevCapsA(wID, &jca, sizeof(jca));
3110 if (ret != JOYERR_NOERROR) return ret;
3111 lpCaps->wMid = jca.wMid;
3112 lpCaps->wPid = jca.wPid;
3113 strcpy(lpCaps->szPname, jca.szPname);
3114 lpCaps->wXmin = jca.wXmin;
3115 lpCaps->wXmax = jca.wXmax;
3116 lpCaps->wYmin = jca.wYmin;
3117 lpCaps->wYmax = jca.wYmax;
3118 lpCaps->wZmin = jca.wZmin;
3119 lpCaps->wZmax = jca.wZmax;
3120 lpCaps->wNumButtons = jca.wNumButtons;
3121 lpCaps->wPeriodMin = jca.wPeriodMin;
3122 lpCaps->wPeriodMax = jca.wPeriodMax;
3124 if (wSize >= sizeof(JOYCAPS16)) { /* Win95 extensions ? */
3125 lpCaps->wRmin = jca.wRmin;
3126 lpCaps->wRmax = jca.wRmax;
3127 lpCaps->wUmin = jca.wUmin;
3128 lpCaps->wUmax = jca.wUmax;
3129 lpCaps->wVmin = jca.wVmin;
3130 lpCaps->wVmax = jca.wVmax;
3131 lpCaps->wCaps = jca.wCaps;
3132 lpCaps->wMaxAxes = jca.wMaxAxes;
3133 lpCaps->wNumAxes = jca.wNumAxes;
3134 lpCaps->wMaxButtons = jca.wMaxButtons;
3135 strcpy(lpCaps->szRegKey, jca.szRegKey);
3136 strcpy(lpCaps->szOEMVxD, jca.szOEMVxD);
3139 return ret;
3142 /**************************************************************************
3143 * joyGetPosEx [MMSYSTEM.110]
3145 MMRESULT16 WINAPI joyGetPosEx16(UINT16 wID, LPJOYINFOEX lpInfo)
3147 return joyGetPosEx(wID, lpInfo);
3150 /**************************************************************************
3151 * joyGetPos [MMSYSTEM.103]
3153 MMRESULT16 WINAPI joyGetPos16(UINT16 wID, LPJOYINFO16 lpInfo)
3155 JOYINFO ji;
3156 MMRESULT ret;
3158 TRACE("(%d, %p);\n", wID, lpInfo);
3160 if ((ret = joyGetPos(wID, &ji)) == JOYERR_NOERROR) {
3161 lpInfo->wXpos = ji.wXpos;
3162 lpInfo->wYpos = ji.wYpos;
3163 lpInfo->wZpos = ji.wZpos;
3164 lpInfo->wButtons = ji.wButtons;
3166 return ret;
3169 /**************************************************************************
3170 * joyGetThreshold [MMSYSTEM.104]
3172 MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold)
3174 UINT t;
3175 MMRESULT ret;
3177 ret = joyGetThreshold(wID, &t);
3178 if (ret == JOYERR_NOERROR)
3179 *lpThreshold = t;
3180 return ret;
3183 /**************************************************************************
3184 * joyReleaseCapture [MMSYSTEM.105]
3186 MMRESULT16 WINAPI joyReleaseCapture16(UINT16 wID)
3188 return joyReleaseCapture(wID);
3191 /**************************************************************************
3192 * joySetCapture [MMSYSTEM.106]
3194 MMRESULT16 WINAPI joySetCapture16(HWND16 hWnd, UINT16 wID, UINT16 wPeriod, BOOL16 bChanged)
3196 return joySetCapture16(hWnd, wID, wPeriod, bChanged);
3199 /**************************************************************************
3200 * joySetThreshold [MMSYSTEM.107]
3202 MMRESULT16 WINAPI joySetThreshold16(UINT16 wID, UINT16 wThreshold)
3204 return joySetThreshold16(wID,wThreshold);
3207 /**************************************************************************
3208 * joySetCalibration [MMSYSTEM.109]
3210 MMRESULT16 WINAPI joySetCalibration16(UINT16 wID)
3212 FIXME("(%04X): stub.\n", wID);
3213 return JOYERR_NOCANDO;