mmsystem.c 91.3 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2
/* -*- tab-width: 8; c-basic-offset: 4 -*- */

Alexandre Julliard's avatar
Alexandre Julliard committed
3 4 5
/*
 * MMSYTEM functions
 *
6 7
 * Copyright 1993      Martin Ayotte
 *           1998-2002 Eric Pouech
8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Alexandre Julliard's avatar
Alexandre Julliard committed
22
 */
23

24 25
/*
 * Eric POUECH :
26
 *  	99/4	added mmTask and mmThread functions support
27 28
 */

29
/* FIXME: I think there are some segmented vs. linear pointer weirdnesses
Alexandre Julliard's avatar
Alexandre Julliard committed
30 31
 *        and long term pointers to 16 bit space in here
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
32

Alexandre Julliard's avatar
Alexandre Julliard committed
33
#include <string.h>
34

35
#include "mmsystem.h"
36
#include "winbase.h"
37

38
#include "wine/winuser16.h"
39
#include "winemm.h"
40
#include "heap.h"
41

42
#include "wine/debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
43

44
WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
45

46 47 48 49 50
/* ### start build ### */
extern LONG CALLBACK MMSYSTEM_CallTo16_long_l    (FARPROC16,LONG);
extern LONG CALLBACK MMSYSTEM_CallTo16_long_lwll (LPMMIOPROC16,LONG,WORD,LONG,LONG);
/* ### stop build ### */

51
static WINE_MMTHREAD*   WINMM_GetmmThread(HANDLE16);
52 53 54
static LPWINE_DRIVER    DRIVER_OpenDriver16(LPCSTR, LPCSTR, LPARAM);
static LRESULT          DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM);
static LRESULT          DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM);
Eric Pouech's avatar
Eric Pouech committed
55
static LRESULT          MMIO_Callback16(SEGPTR, LPMMIOINFO, UINT, LPARAM, LPARAM);
56

57 58 59
#define HMODULE_32(h16) ((HMODULE)(ULONG_PTR)(h16))
#define HINSTANCE_32(h16) ((HMODULE)(ULONG_PTR)(h16))

60 61 62 63 64
/* ###################################################
 * #                  LIBRARY                        #
 * ###################################################
 */

65
/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
66
 * 			DllEntryPoint (MMSYSTEM.2046)
67 68 69 70
 *
 * MMSYSTEM DLL entry point
 *
 */
71
BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
72 73
			     WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
{
74
    TRACE("%p 0x%lx\n", hinstDLL, fdwReason);
75 76 77

    switch (fdwReason) {
    case DLL_PROCESS_ATTACH:
78
	/* need to load WinMM in order to:
79
	 * - initiate correctly shared variables (WINMM_Init())
80
	 */
81 82 83 84
        if (!GetModuleHandleA("WINMM.DLL") && !LoadLibraryA("WINMM.DLL"))
        {
            ERR("Could not load sibling WinMM.dll\n");
            return FALSE;
85
	}
86
	WINMM_IData->hWinMM16Instance = hinstDLL;
Eric Pouech's avatar
Eric Pouech committed
87
        /* hook in our 16 bit function pointers */
88
        pFnGetMMThread16  = WINMM_GetmmThread;
89 90 91
        pFnOpenDriver16   = DRIVER_OpenDriver16;
        pFnCloseDriver16  = DRIVER_CloseDriver16;
        pFnSendMessage16  = DRIVER_SendMessage16;
92
        pFnMmioCallback16 = MMIO_Callback16;
93
        MMDRV_Init16();
94 95
	break;
    case DLL_PROCESS_DETACH:
96
	WINMM_IData->hWinMM16Instance = 0;
97
        pFnGetMMThread16  = NULL;
98 99 100
        pFnOpenDriver16   = NULL;
        pFnCloseDriver16  = NULL;
        pFnSendMessage16  = NULL;
101
        pFnMmioCallback16 = NULL;
102
        /* FIXME: add equivalent for MMDRV_Init16() */
103 104 105 106 107 108 109 110
	break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
	break;
    }
    return TRUE;
}

Alexandre Julliard's avatar
Alexandre Julliard committed
111
/**************************************************************************
112
 * 				MMSYSTEM_WEP			[MMSYSTEM.1]
Alexandre Julliard's avatar
Alexandre Julliard committed
113
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
114 115
int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
                        WORD cbHeapSize, LPSTR lpCmdLine)
Alexandre Julliard's avatar
Alexandre Julliard committed
116
{
117
    FIXME("STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
118
    return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
119 120
}

121 122 123 124 125
/* ###################################################
 * #                  PlaySound                      #
 * ###################################################
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
126
/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
127
 * 				PlaySound		[MMSYSTEM.3]
128
 */
129 130
BOOL16 WINAPI PlaySound16(LPCSTR pszSound, HMODULE16 hmod, DWORD fdwSound)
{
131 132
    BOOL16	retv;
    DWORD	lc;
133

134
    ReleaseThunkLock(&lc);
135
    retv = PlaySoundA(pszSound, HMODULE_32(hmod), fdwSound);
136
    RestoreThunkLock(lc);
137 138 139 140 141

    return retv;
}

/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
142
 * 				sndPlaySound		[MMSYSTEM.2]
143 144 145
 */
BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags)
{
146 147
    BOOL16	retv;
    DWORD	lc;
148

149
    ReleaseThunkLock(&lc);
150
    retv = sndPlaySoundA(lpszSoundName, uFlags);
151
    RestoreThunkLock(lc);
152 153 154 155

    return retv;
}

156 157 158 159 160
/* ###################################################
 * #                    MISC                         #
 * ###################################################
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
161
/**************************************************************************
162
 * 				mmsystemGetVersion	[MMSYSTEM.5]
163
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
164
 */
165
UINT16 WINAPI mmsystemGetVersion16(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
166
{
167
    return mmsystemGetVersion();
Alexandre Julliard's avatar
Alexandre Julliard committed
168 169
}

170 171 172
/**************************************************************************
 * 				DriverCallback			[MMSYSTEM.31]
 */
173 174
BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev,
			       WORD wMsg, DWORD dwUser, DWORD dwParam1,
175 176
			       DWORD dwParam2)
{
177
    return DriverCallback(dwCallBack, uFlags, HDRVR_32(hDev), wMsg, dwUser, dwParam1, dwParam2);
178 179
}

180 181 182 183 184 185 186 187 188 189 190 191 192 193
/**************************************************************************
 * 			OutputDebugStr	 	[MMSYSTEM.30]
 */
void WINAPI OutputDebugStr16(LPCSTR str)
{
    OutputDebugStringA( str );
}


/* ###################################################
 * #                    MIXER                        #
 * ###################################################
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
194
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
195 196
 * 	Mixer devices. New to Win95
 */
197

Alexandre Julliard's avatar
Alexandre Julliard committed
198
/**************************************************************************
199
 * 				mixerGetNumDevs			[MMSYSTEM.800]
Alexandre Julliard's avatar
Alexandre Julliard committed
200
 */
201
UINT16 WINAPI mixerGetNumDevs16(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
202
{
203
    return MMDRV_GetNum(MMDRV_MIXER);
Alexandre Julliard's avatar
Alexandre Julliard committed
204 205 206
}

/**************************************************************************
207
 * 				mixerGetDevCaps			[MMSYSTEM.801]
Alexandre Julliard's avatar
Alexandre Julliard committed
208
 */
209 210
UINT16 WINAPI mixerGetDevCaps16(UINT16 devid, LPMIXERCAPS16 mixcaps,
				UINT16 size)
Alexandre Julliard's avatar
Alexandre Julliard committed
211
{
212 213
    MIXERCAPSA  micA;
    UINT        ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
214

215
    if (ret == MMSYSERR_NOERROR) {
216 217 218 219 220 221
        mixcaps->wMid           = micA.wMid;
        mixcaps->wPid           = micA.wPid;
        mixcaps->vDriverVersion = micA.vDriverVersion;
        strcpy(mixcaps->szPname, micA.szPname);
        mixcaps->fdwSupport     = micA.fdwSupport;
        mixcaps->cDestinations  = micA.cDestinations;
222 223
    }
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
224 225 226
}

/**************************************************************************
227
 * 				mixerOpen			[MMSYSTEM.802]
Alexandre Julliard's avatar
Alexandre Julliard committed
228
 */
229
UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix, UINT16 uDeviceID, DWORD dwCallback,
230
			  DWORD dwInstance, DWORD fdwOpen)
Alexandre Julliard's avatar
Alexandre Julliard committed
231
{
232 233
    HMIXER	hmix;
    UINT	ret;
234

235
    ret = MIXER_Open(&hmix, uDeviceID, dwCallback, dwInstance, fdwOpen, FALSE);
236
    if (lphmix) *lphmix = HMIXER_16(hmix);
237
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
238 239 240
}

/**************************************************************************
241
 * 				mixerClose			[MMSYSTEM.803]
Alexandre Julliard's avatar
Alexandre Julliard committed
242
 */
243
UINT16 WINAPI mixerClose16(HMIXER16 hMix)
Alexandre Julliard's avatar
Alexandre Julliard committed
244
{
245
    return mixerClose(HMIXER_32(hMix));
Alexandre Julliard's avatar
Alexandre Julliard committed
246 247 248
}

/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
249
 * 				mixerGetID (MMSYSTEM.806)
Alexandre Julliard's avatar
Alexandre Julliard committed
250
 */
251
UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID)
Alexandre Julliard's avatar
Alexandre Julliard committed
252
{
253
    UINT	xid;
254
    UINT	ret = mixerGetID(HMIXEROBJ_32(hmix), &xid, fdwID);
255

256
    if (lpid)
257 258
	*lpid = xid;
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
259 260 261 262 263
}

/**************************************************************************
 * 				mixerGetControlDetails	[MMSYSTEM.808]
 */
264 265 266
UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,
				       LPMIXERCONTROLDETAILS16 lpmcd,
				       DWORD fdwDetails)
Alexandre Julliard's avatar
Alexandre Julliard committed
267
{
268 269 270 271 272 273 274 275 276
    DWORD	ret = MMSYSERR_NOTENABLED;
    SEGPTR	sppaDetails;

    TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);

    if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
	return MMSYSERR_INVALPARAM;

    sppaDetails = (SEGPTR)lpmcd->paDetails;
277
    lpmcd->paDetails = MapSL(sppaDetails);
278 279
    ret = mixerGetControlDetailsA(HMIXEROBJ_32(hmix),
			         (LPMIXERCONTROLDETAILS)lpmcd, fdwDetails);
280 281 282
    lpmcd->paDetails = (LPVOID)sppaDetails;

    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
283 284 285
}

/**************************************************************************
286
 * 				mixerGetLineControls		[MMSYSTEM.807]
Alexandre Julliard's avatar
Alexandre Julliard committed
287
 */
288 289 290
UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,
				     LPMIXERLINECONTROLS16 lpmlc16,
				     DWORD fdwControls)
Alexandre Julliard's avatar
Alexandre Julliard committed
291
{
292 293 294 295 296 297 298
    MIXERLINECONTROLSA	mlcA;
    DWORD		ret;
    int			i;
    LPMIXERCONTROL16	lpmc16;

    TRACE("(%04x, %p, %08lx)\n", hmix, lpmlc16, fdwControls);

299
    if (lpmlc16 == NULL || lpmlc16->cbStruct != sizeof(*lpmlc16) ||
300
	lpmlc16->cbmxctrl != sizeof(MIXERCONTROL16))
301 302 303 304 305 306 307 308
	return MMSYSERR_INVALPARAM;

    mlcA.cbStruct = sizeof(mlcA);
    mlcA.dwLineID = lpmlc16->dwLineID;
    mlcA.u.dwControlID = lpmlc16->u.dwControlID;
    mlcA.u.dwControlType = lpmlc16->u.dwControlType;
    mlcA.cControls = lpmlc16->cControls;
    mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
309
    mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
310
			      mlcA.cControls * mlcA.cbmxctrl);
311

312
    ret = mixerGetLineControlsA(HMIXEROBJ_32(hmix), &mlcA, fdwControls);
313 314 315 316 317 318

    if (ret == MMSYSERR_NOERROR) {
	lpmlc16->dwLineID = mlcA.dwLineID;
	lpmlc16->u.dwControlID = mlcA.u.dwControlID;
	lpmlc16->u.dwControlType = mlcA.u.dwControlType;
	lpmlc16->cControls = mlcA.cControls;
319

320
	lpmc16 = MapSL(lpmlc16->pamxctrl);
321

322 323 324 325 326 327 328 329 330
	for (i = 0; i < mlcA.cControls; i++) {
	    lpmc16[i].cbStruct = sizeof(MIXERCONTROL16);
	    lpmc16[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
	    lpmc16[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
	    lpmc16[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
	    lpmc16[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
	    strcpy(lpmc16[i].szShortName, mlcA.pamxctrl[i].szShortName);
	    strcpy(lpmc16[i].szName, mlcA.pamxctrl[i].szName);
	    /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
331
	    memcpy(&lpmc16[i].Bounds, &mlcA.pamxctrl[i].Bounds,
332
		   sizeof(mlcA.pamxctrl[i].Bounds));
333
	    /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
334
	    memcpy(&lpmc16[i].Metrics, &mlcA.pamxctrl[i].Metrics,
335
		   sizeof(mlcA.pamxctrl[i].Metrics));
336 337 338 339 340 341
	}
    }

    HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);

    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
342 343 344 345 346
}

/**************************************************************************
 * 				mixerGetLineInfo	[MMSYSTEM.805]
 */
347 348
UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16,
				 DWORD fdwInfo)
Alexandre Julliard's avatar
Alexandre Julliard committed
349
{
350
    MIXERLINEA		mliA;
351
    UINT		ret;
352

353
    TRACE("(%04x, %p, %08lx)\n", hmix, lpmli16, fdwInfo);
354

355
    if (lpmli16 == NULL || lpmli16->cbStruct != sizeof(*lpmli16))
356 357
	return MMSYSERR_INVALPARAM;

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
    mliA.cbStruct = sizeof(mliA);
    switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
    case MIXER_GETLINEINFOF_COMPONENTTYPE:
	mliA.dwComponentType = lpmli16->dwComponentType;
	break;
    case MIXER_GETLINEINFOF_DESTINATION:
	mliA.dwDestination = lpmli16->dwDestination;
	break;
    case MIXER_GETLINEINFOF_LINEID:
	mliA.dwLineID = lpmli16->dwLineID;
	break;
    case MIXER_GETLINEINFOF_SOURCE:
	mliA.dwDestination = lpmli16->dwDestination;
	mliA.dwSource = lpmli16->dwSource;
	break;
    case MIXER_GETLINEINFOF_TARGETTYPE:
	mliA.Target.dwType = lpmli16->Target.dwType;
	mliA.Target.wMid = lpmli16->Target.wMid;
	mliA.Target.wPid = lpmli16->Target.wPid;
	mliA.Target.vDriverVersion = lpmli16->Target.vDriverVersion;
	strcpy(mliA.Target.szPname, lpmli16->Target.szPname);
	break;
    default:
	FIXME("Unsupported fdwControls=0x%08lx\n", fdwInfo);
    }

384
    ret = mixerGetLineInfoA(HMIXEROBJ_32(hmix), &mliA, fdwInfo);
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403

    lpmli16->dwDestination     	= mliA.dwDestination;
    lpmli16->dwSource          	= mliA.dwSource;
    lpmli16->dwLineID          	= mliA.dwLineID;
    lpmli16->fdwLine           	= mliA.fdwLine;
    lpmli16->dwUser            	= mliA.dwUser;
    lpmli16->dwComponentType   	= mliA.dwComponentType;
    lpmli16->cChannels         	= mliA.cChannels;
    lpmli16->cConnections      	= mliA.cConnections;
    lpmli16->cControls         	= mliA.cControls;
    strcpy(lpmli16->szShortName, mliA.szShortName);
    strcpy(lpmli16->szName, mliA.szName);
    lpmli16->Target.dwType     	= mliA.Target.dwType;
    lpmli16->Target.dwDeviceID 	= mliA.Target.dwDeviceID;
    lpmli16->Target.wMid       	= mliA.Target.wMid;
    lpmli16->Target.wPid        = mliA.Target.wPid;
    lpmli16->Target.vDriverVersion = mliA.Target.vDriverVersion;
    strcpy(lpmli16->Target.szPname, mliA.Target.szPname);

404
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
405 406 407 408 409
}

/**************************************************************************
 * 				mixerSetControlDetails	[MMSYSTEM.809]
 */
410 411 412
UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,
				       LPMIXERCONTROLDETAILS16 lpmcd,
				       DWORD fdwDetails)
Alexandre Julliard's avatar
Alexandre Julliard committed
413
{
414
    TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);
Alexandre Julliard's avatar
Alexandre Julliard committed
415
    return MMSYSERR_NOTENABLED;
Alexandre Julliard's avatar
Alexandre Julliard committed
416 417 418 419 420
}

/**************************************************************************
 * 				mixerMessage		[MMSYSTEM.804]
 */
421 422
DWORD WINAPI mixerMessage16(HMIXER16 hmix, UINT16 uMsg, DWORD dwParam1,
			     DWORD dwParam2)
Alexandre Julliard's avatar
Alexandre Julliard committed
423
{
424
    return mixerMessage(HMIXER_32(hmix), uMsg, dwParam1, dwParam2);
Alexandre Julliard's avatar
Alexandre Julliard committed
425 426 427 428 429
}

/**************************************************************************
 * 				auxGetNumDevs		[MMSYSTEM.350]
 */
Eric Pouech's avatar
Eric Pouech committed
430
UINT16 WINAPI auxGetNumDevs16(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
431
{
432
    return MMDRV_GetNum(MMDRV_AUX);
Alexandre Julliard's avatar
Alexandre Julliard committed
433 434
}

435 436 437 438 439
/* ###################################################
 * #                     AUX                         #
 * ###################################################
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
440 441 442
/**************************************************************************
 * 				auxGetDevCaps		[MMSYSTEM.351]
 */
443
UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID, LPAUXCAPS16 lpCaps, UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
444
{
445 446
    LPWINE_MLD		wmld;

447
    TRACE("(%04X, %p, %d) !\n", uDeviceID, lpCaps, uSize);
448

449
    if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
450 451
	return MMSYSERR_INVALHANDLE;
    return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
Alexandre Julliard's avatar
Alexandre Julliard committed
452 453
}

Alexandre Julliard's avatar
Alexandre Julliard committed
454 455 456
/**************************************************************************
 * 				auxGetVolume		[MMSYSTEM.352]
 */
457
UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, LPDWORD lpdwVolume)
Alexandre Julliard's avatar
Alexandre Julliard committed
458
{
459 460
    LPWINE_MLD		wmld;

461
    TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
462

463
    if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
464 465
	return MMSYSERR_INVALHANDLE;
    return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE);
Alexandre Julliard's avatar
Alexandre Julliard committed
466 467
}

Alexandre Julliard's avatar
Alexandre Julliard committed
468 469 470 471
/**************************************************************************
 * 				auxSetVolume		[MMSYSTEM.353]
 */
UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
Alexandre Julliard's avatar
Alexandre Julliard committed
472
{
473 474 475
    LPWINE_MLD		wmld;

    TRACE("(%04X, %lu) !\n", uDeviceID, dwVolume);
476

477
    if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
478 479
	return MMSYSERR_INVALHANDLE;
    return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE);
Alexandre Julliard's avatar
Alexandre Julliard committed
480 481
}

Alexandre Julliard's avatar
Alexandre Julliard committed
482 483 484 485
/**************************************************************************
 * 				auxOutMessage		[MMSYSTEM.354]
 */
DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
Alexandre Julliard's avatar
Alexandre Julliard committed
486
{
487 488
    LPWINE_MLD		wmld;

489
    TRACE("(%04X, %04X, %08lX, %08lX)\n", uDeviceID, uMessage, dw1, dw2);
490

Alexandre Julliard's avatar
Alexandre Julliard committed
491 492 493 494 495 496
    switch (uMessage) {
    case AUXDM_GETNUMDEVS:
    case AUXDM_SETVOLUME:
	/* no argument conversion needed */
	break;
    case AUXDM_GETVOLUME:
497
	return auxGetVolume16(uDeviceID, MapSL(dw1));
Alexandre Julliard's avatar
Alexandre Julliard committed
498
    case AUXDM_GETDEVCAPS:
499
	return auxGetDevCaps16(uDeviceID, MapSL(dw1), dw2);
Alexandre Julliard's avatar
Alexandre Julliard committed
500
    default:
501 502
	TRACE("(%04x, %04x, %08lx, %08lx): unhandled message\n",
	      uDeviceID, uMessage, dw1, dw2);
Alexandre Julliard's avatar
Alexandre Julliard committed
503 504
	break;
    }
505
    if ((wmld = MMDRV_Get((HANDLE)(ULONG_PTR)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
506 507 508
	return MMSYSERR_INVALHANDLE;

    return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE);
Alexandre Julliard's avatar
Alexandre Julliard committed
509 510
}

511 512 513 514 515
/* ###################################################
 * #                     MCI                         #
 * ###################################################
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
516
/**************************************************************************
517
 * 				mciGetErrorString		[MMSYSTEM.706]
Alexandre Julliard's avatar
Alexandre Julliard committed
518
 */
519
BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer, UINT16 uLength)
Alexandre Julliard's avatar
Alexandre Julliard committed
520
{
521
    return mciGetErrorStringA(wError, lpstrBuffer, uLength);
Alexandre Julliard's avatar
Alexandre Julliard committed
522 523
}

Alexandre Julliard's avatar
Alexandre Julliard committed
524
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
525 526
 * 				mciDriverNotify			[MMSYSTEM.711]
 */
527
BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
Alexandre Julliard's avatar
Alexandre Julliard committed
528
{
529
    TRACE("(%04X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
530

531
    return PostMessageA(HWND_32(hWndCallBack), MM_MCINOTIFY, wStatus, wDevID);
Alexandre Julliard's avatar
Alexandre Julliard committed
532 533
}

Alexandre Julliard's avatar
Alexandre Julliard committed
534 535 536
/**************************************************************************
 * 			mciGetDriverData			[MMSYSTEM.708]
 */
537
DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID)
Alexandre Julliard's avatar
Alexandre Julliard committed
538
{
539
    return mciGetDriverData(uDeviceID);
Alexandre Julliard's avatar
Alexandre Julliard committed
540
}
Alexandre Julliard's avatar
Alexandre Julliard committed
541

Alexandre Julliard's avatar
Alexandre Julliard committed
542
/**************************************************************************
543
 * 			mciSetDriverData			[MMSYSTEM.707]
Alexandre Julliard's avatar
Alexandre Julliard committed
544
 */
545
BOOL16 WINAPI mciSetDriverData16(UINT16 uDeviceID, DWORD data)
Alexandre Julliard's avatar
Alexandre Julliard committed
546
{
547
    return mciSetDriverData(uDeviceID, data);
Alexandre Julliard's avatar
Alexandre Julliard committed
548 549
}

Alexandre Julliard's avatar
Alexandre Julliard committed
550
/**************************************************************************
551
 * 				mciSendCommand			[MMSYSTEM.701]
Alexandre Julliard's avatar
Alexandre Julliard committed
552
 */
553
DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
Alexandre Julliard's avatar
Alexandre Julliard committed
554
{
555
    DWORD		dwRet;
Eric Pouech's avatar
Eric Pouech committed
556

557 558
    TRACE("(%04X, %s, %08lX, %08lX)\n",
	  wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
Eric Pouech's avatar
Eric Pouech committed
559

560
    dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, FALSE);
561
    dwRet = MCI_CleanUp(dwRet, wMsg, (DWORD)MapSL(dwParam2));
562 563 564
    TRACE("=> %ld\n", dwRet);
    return dwRet;
}
565

566 567 568 569 570
/**************************************************************************
 * 				mciGetDeviceID		       	[MMSYSTEM.703]
 */
UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
{
571
    TRACE("(\"%s\")\n", lpstrName);
572

Eric Pouech's avatar
Eric Pouech committed
573
    return MCI_GetDriverFromString(lpstrName);
574
}
575 576 577 578

/**************************************************************************
 * 				mciSetYieldProc			[MMSYSTEM.714]
 */
579
BOOL16 WINAPI mciSetYieldProc16(UINT16 uDeviceID, YIELDPROC16 fpYieldProc, DWORD dwYieldData)
580
{
Eric Pouech's avatar
Eric Pouech committed
581 582
    LPWINE_MCIDRIVER	wmd;

583
    TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData);
584

Eric Pouech's avatar
Eric Pouech committed
585
    if (!(wmd = MCI_GetDriver(uDeviceID))) {
586
	WARN("Bad uDeviceID\n");
587 588
	return FALSE;
    }
589

590
    wmd->lpfnYieldProc = (YIELDPROC)fpYieldProc;
Eric Pouech's avatar
Eric Pouech committed
591 592
    wmd->dwYieldData   = dwYieldData;
    wmd->bIs32         = FALSE;
593 594

    return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
595 596
}

597 598 599 600 601
/**************************************************************************
 * 				mciGetDeviceIDFromElementID	[MMSYSTEM.715]
 */
UINT16 WINAPI mciGetDeviceIDFromElementID16(DWORD dwElementID, LPCSTR lpstrType)
{
602
    FIXME("(%lu, %s) stub\n", dwElementID, lpstrType);
603
    return 0;
604
}
605

606 607 608
/**************************************************************************
 * 				mciGetYieldProc			[MMSYSTEM.716]
 */
609
YIELDPROC16 WINAPI mciGetYieldProc16(UINT16 uDeviceID, DWORD* lpdwYieldData)
610
{
Eric Pouech's avatar
Eric Pouech committed
611 612
    LPWINE_MCIDRIVER	wmd;

613
    TRACE("(%u, %p)\n", uDeviceID, lpdwYieldData);
614

Eric Pouech's avatar
Eric Pouech committed
615
    if (!(wmd = MCI_GetDriver(uDeviceID))) {
616
	WARN("Bad uDeviceID\n");
617 618
	return NULL;
    }
Eric Pouech's avatar
Eric Pouech committed
619
    if (!wmd->lpfnYieldProc) {
620
	WARN("No proc set\n");
621 622
	return NULL;
    }
Eric Pouech's avatar
Eric Pouech committed
623
    if (wmd->bIs32) {
624
	WARN("Proc is 32 bit\n");
625 626
	return NULL;
    }
627
    return (YIELDPROC16)wmd->lpfnYieldProc;
628
}
629

Alexandre Julliard's avatar
Alexandre Julliard committed
630
/**************************************************************************
631
 * 				mciGetCreatorTask		[MMSYSTEM.717]
Alexandre Julliard's avatar
Alexandre Julliard committed
632
 */
633
HTASK16 WINAPI mciGetCreatorTask16(UINT16 uDeviceID)
Alexandre Julliard's avatar
Alexandre Julliard committed
634
{
635 636 637
    LPWINE_MCIDRIVER wmd;
    HTASK16 ret = 0;

638 639
    if ((wmd = MCI_GetDriver(uDeviceID))) 
        ret = HTASK_16(wmd->CreatorThread);
640 641 642

    TRACE("(%u) => %04x\n", uDeviceID, ret);
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
643 644
}

Alexandre Julliard's avatar
Alexandre Julliard committed
645
/**************************************************************************
646
 * 				mciDriverYield			[MMSYSTEM.710]
Alexandre Julliard's avatar
Alexandre Julliard committed
647
 */
648
UINT16 WINAPI mciDriverYield16(UINT16 uDeviceID)
Alexandre Julliard's avatar
Alexandre Julliard committed
649
{
Eric Pouech's avatar
Eric Pouech committed
650 651
    LPWINE_MCIDRIVER	wmd;
    UINT16		ret = 0;
652

653
    /*    TRACE("(%04x)\n", uDeviceID); */
654

655
    if (!(wmd = MCI_GetDriver(uDeviceID)) || !wmd->lpfnYieldProc || wmd->bIs32) {
656
	UserYield16();
657
    } else {
Eric Pouech's avatar
Eric Pouech committed
658
	ret = wmd->lpfnYieldProc(uDeviceID, wmd->dwYieldData);
659 660 661
    }

    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
662 663
}

664 665 666 667 668
/* ###################################################
 * #                     MIDI                        #
 * ###################################################
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
669 670 671 672
/**************************************************************************
 * 				midiOutGetNumDevs	[MMSYSTEM.201]
 */
UINT16 WINAPI midiOutGetNumDevs16(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
673
{
674
    return MMDRV_GetNum(MMDRV_MIDIOUT);
Alexandre Julliard's avatar
Alexandre Julliard committed
675 676
}

Alexandre Julliard's avatar
Alexandre Julliard committed
677 678 679
/**************************************************************************
 * 				midiOutGetDevCaps	[MMSYSTEM.202]
 */
680
UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID, LPMIDIOUTCAPS16 lpCaps,
681
				  UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
682
{
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
    MIDIOUTCAPSA	capsA;
    UINT		dwRet;

    if (lpCaps == NULL)	return MMSYSERR_INVALPARAM;

    dwRet = midiOutGetDevCapsA(uDeviceID, &capsA, sizeof(capsA));
    if (dwRet == MMSYSERR_NOERROR) {
	lpCaps->wMid            = capsA.wMid;
	lpCaps->wPid            = capsA.wPid;
	lpCaps->vDriverVersion  = capsA.vDriverVersion;
	strcpy(lpCaps->szPname, capsA.szPname);
	lpCaps->wTechnology 	= capsA.wTechnology;
	lpCaps->wVoices         = capsA.wVoices;
	lpCaps->wNotes          = capsA.wNotes;
	lpCaps->wChannelMask    = capsA.wChannelMask;
	lpCaps->dwSupport	= capsA.dwSupport;
    }
    return dwRet;
 }
Alexandre Julliard's avatar
Alexandre Julliard committed
702

Alexandre Julliard's avatar
Alexandre Julliard committed
703 704 705 706 707
/**************************************************************************
 * 				midiOutGetErrorText 	[MMSYSTEM.203]
 */
UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
{
708
    return midiOutGetErrorTextA(uError, lpText, uSize);
Alexandre Julliard's avatar
Alexandre Julliard committed
709
}
Alexandre Julliard's avatar
Alexandre Julliard committed
710

Alexandre Julliard's avatar
Alexandre Julliard committed
711 712 713
/**************************************************************************
 * 				midiOutOpen    		[MMSYSTEM.204]
 */
714
UINT16 WINAPI midiOutOpen16(HMIDIOUT16* lphMidiOut, UINT16 uDeviceID,
Alexandre Julliard's avatar
Alexandre Julliard committed
715
                            DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
716
{
717 718
    HMIDIOUT	hmo;
    UINT	ret;
719

720
    ret = MIDI_OutOpen(&hmo, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
721

722
    if (lphMidiOut != NULL) *lphMidiOut = HMIDIOUT_16(hmo);
723
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
724 725
}

Alexandre Julliard's avatar
Alexandre Julliard committed
726 727 728 729
/**************************************************************************
 * 				midiOutClose		[MMSYSTEM.205]
 */
UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
Alexandre Julliard's avatar
Alexandre Julliard committed
730
{
731
    return midiOutClose(HMIDIOUT_32(hMidiOut));
Alexandre Julliard's avatar
Alexandre Julliard committed
732 733
}

Alexandre Julliard's avatar
Alexandre Julliard committed
734 735 736
/**************************************************************************
 * 				midiOutPrepareHeader	[MMSYSTEM.206]
 */
737
UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut,         /* [in] */
738
                                     SEGPTR lpsegMidiOutHdr,      /* [???] */
739
				     UINT16 uSize)                /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
740
{
741
    LPWINE_MLD		wmld;
742

743
    TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
744

745
    if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
746
	return MMSYSERR_INVALHANDLE;
747

748
    return MMDRV_Message(wmld, MODM_PREPARE, lpsegMidiOutHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
749 750
}

Alexandre Julliard's avatar
Alexandre Julliard committed
751 752 753
/**************************************************************************
 * 				midiOutUnprepareHeader	[MMSYSTEM.207]
 */
754
UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut,         /* [in] */
755
				       SEGPTR lpsegMidiOutHdr,      /* [???] */
756
				       UINT16 uSize)                /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
757
{
758
    LPWINE_MLD		wmld;
759
    LPMIDIHDR16		lpMidiOutHdr = MapSL(lpsegMidiOutHdr);
760

761
    TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
762

763 764 765
    if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
	return MMSYSERR_NOERROR;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
766

767
    if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
768 769
	return MMSYSERR_INVALHANDLE;

770
    return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpsegMidiOutHdr, uSize, FALSE);
771 772
}

Alexandre Julliard's avatar
Alexandre Julliard committed
773 774 775 776
/**************************************************************************
 * 				midiOutShortMsg		[MMSYSTEM.208]
 */
UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
Alexandre Julliard's avatar
Alexandre Julliard committed
777
{
778
    return midiOutShortMsg(HMIDIOUT_32(hMidiOut), dwMsg);
Alexandre Julliard's avatar
Alexandre Julliard committed
779 780
}

Alexandre Julliard's avatar
Alexandre Julliard committed
781
/**************************************************************************
782
 * 				midiOutLongMsg		[MMSYSTEM.209]
Alexandre Julliard's avatar
Alexandre Julliard committed
783
 */
784 785 786
UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut,          /* [in] */
                               LPMIDIHDR16 lpsegMidiOutHdr,  /* [???] NOTE: SEGPTR */
			       UINT16 uSize)                 /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
787
{
788 789
    LPWINE_MLD		wmld;

790
    TRACE("(%04X, %p, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
791

792
    if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
793 794
	return MMSYSERR_INVALHANDLE;

795
    return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD)lpsegMidiOutHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
796 797 798 799 800 801
}

/**************************************************************************
 * 				midiOutReset		[MMSYSTEM.210]
 */
UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
Alexandre Julliard's avatar
Alexandre Julliard committed
802
{
803
    return midiOutReset(HMIDIOUT_32(hMidiOut));
Alexandre Julliard's avatar
Alexandre Julliard committed
804 805
}

Alexandre Julliard's avatar
Alexandre Julliard committed
806 807 808
/**************************************************************************
 * 				midiOutGetVolume	[MMSYSTEM.211]
 */
809
UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD* lpdwVolume)
Alexandre Julliard's avatar
Alexandre Julliard committed
810
{
811
    return midiOutGetVolume(uDeviceID, lpdwVolume);
Alexandre Julliard's avatar
Alexandre Julliard committed
812 813
}

Alexandre Julliard's avatar
Alexandre Julliard committed
814 815 816 817
/**************************************************************************
 * 				midiOutSetVolume	[MMSYSTEM.212]
 */
UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
Alexandre Julliard's avatar
Alexandre Julliard committed
818
{
819
    return midiOutSetVolume(uDeviceID, dwVolume);
Alexandre Julliard's avatar
Alexandre Julliard committed
820
}
Alexandre Julliard's avatar
Alexandre Julliard committed
821

Alexandre Julliard's avatar
Alexandre Julliard committed
822 823 824 825
/**************************************************************************
 * 				midiOutCachePatches		[MMSYSTEM.213]
 */
UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
826
                                    WORD* lpwPatchArray, UINT16 uFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
827
{
828 829
    return midiOutCachePatches(HMIDIOUT_32(hMidiOut), uBank, lpwPatchArray,
			       uFlags);
Alexandre Julliard's avatar
Alexandre Julliard committed
830 831
}

Alexandre Julliard's avatar
Alexandre Julliard committed
832 833 834 835
/**************************************************************************
 * 				midiOutCacheDrumPatches	[MMSYSTEM.214]
 */
UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
836
                                        WORD* lpwKeyArray, UINT16 uFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
837
{
838
    return midiOutCacheDrumPatches(HMIDIOUT_32(hMidiOut), uPatch, lpwKeyArray, uFlags);
Alexandre Julliard's avatar
Alexandre Julliard committed
839 840
}

Alexandre Julliard's avatar
Alexandre Julliard committed
841 842 843
/**************************************************************************
 * 				midiOutGetID		[MMSYSTEM.215]
 */
844
UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16* lpuDeviceID)
Alexandre Julliard's avatar
Alexandre Julliard committed
845
{
846 847 848 849 850
    LPWINE_MLD		wmld;

    TRACE("(%04X, %p)\n", hMidiOut, lpuDeviceID);

    if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
851
    if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
852 853 854 855
	return MMSYSERR_INVALHANDLE;

    *lpuDeviceID = wmld->uDeviceID;
    return MMSYSERR_NOERROR;
Alexandre Julliard's avatar
Alexandre Julliard committed
856 857
}

Alexandre Julliard's avatar
Alexandre Julliard committed
858
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
859 860
 * 				midiOutMessage		[MMSYSTEM.216]
 */
861
DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage,
Alexandre Julliard's avatar
Alexandre Julliard committed
862 863
                              DWORD dwParam1, DWORD dwParam2)
{
864 865 866 867
    LPWINE_MLD		wmld;

    TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiOut, uMessage, dwParam1, dwParam2);

868
    if ((wmld = MMDRV_Get(HMIDIOUT_32(hMidiOut), MMDRV_MIDIOUT, FALSE)) == NULL)
869 870
	return MMSYSERR_INVALHANDLE;

Alexandre Julliard's avatar
Alexandre Julliard committed
871 872 873
    switch (uMessage) {
    case MODM_OPEN:
    case MODM_CLOSE:
874 875 876
	FIXME("can't handle OPEN or CLOSE message!\n");
	return MMSYSERR_NOTSUPPORTED;

Alexandre Julliard's avatar
Alexandre Julliard committed
877
    case MODM_GETVOLUME:
878
        return midiOutGetVolume16(hMidiOut, MapSL(dwParam1));
Alexandre Julliard's avatar
Alexandre Julliard committed
879
    case MODM_LONGDATA:
880
        return midiOutLongMsg16(hMidiOut, MapSL(dwParam1), dwParam2);
Alexandre Julliard's avatar
Alexandre Julliard committed
881
    case MODM_PREPARE:
882
        /* lpMidiOutHdr is still a segmented pointer for this function */
883
        return midiOutPrepareHeader16(hMidiOut, dwParam1, dwParam2);
Alexandre Julliard's avatar
Alexandre Julliard committed
884
    case MODM_UNPREPARE:
885
        return midiOutUnprepareHeader16(hMidiOut, dwParam1, dwParam2);
Alexandre Julliard's avatar
Alexandre Julliard committed
886
    }
887
    return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
Alexandre Julliard's avatar
Alexandre Julliard committed
888 889 890 891 892 893
}

/**************************************************************************
 * 				midiInGetNumDevs	[MMSYSTEM.301]
 */
UINT16 WINAPI midiInGetNumDevs16(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
894
{
895
    return MMDRV_GetNum(MMDRV_MIDIIN);
Alexandre Julliard's avatar
Alexandre Julliard committed
896 897
}

Alexandre Julliard's avatar
Alexandre Julliard committed
898 899 900
/**************************************************************************
 * 				midiInGetDevCaps	[MMSYSTEM.302]
 */
901
UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID, LPMIDIINCAPS16 lpCaps,
902
				 UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
903
{
904 905
    MIDIINCAPSA		micA;
    UINT		ret = midiInGetDevCapsA(uDeviceID, &micA, uSize);
906

907 908 909 910 911 912 913
    if (ret == MMSYSERR_NOERROR) {
	lpCaps->wMid = micA.wMid;
	lpCaps->wPid = micA.wPid;
	lpCaps->vDriverVersion = micA.vDriverVersion;
	strcpy(lpCaps->szPname, micA.szPname);
	lpCaps->dwSupport = micA.dwSupport;
    }
914

915
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
916 917
}

Alexandre Julliard's avatar
Alexandre Julliard committed
918 919 920 921
/**************************************************************************
 * 				midiInGetErrorText 		[MMSYSTEM.303]
 */
UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
922
{
923
    return midiInGetErrorTextA(uError, lpText, uSize);
Alexandre Julliard's avatar
Alexandre Julliard committed
924 925 926 927 928
}

/**************************************************************************
 * 				midiInOpen		[MMSYSTEM.304]
 */
929
UINT16 WINAPI midiInOpen16(HMIDIIN16* lphMidiIn, UINT16 uDeviceID,
930
			   DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
931
{
932 933
    HMIDIIN	xhmid;
    UINT 	ret;
934

935
    ret = MIDI_InOpen(&xhmid, uDeviceID, dwCallback, dwInstance, dwFlags, FALSE);
936

937
    if (lphMidiIn) *lphMidiIn = HMIDIIN_16(xhmid);
938
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
939 940
}

Alexandre Julliard's avatar
Alexandre Julliard committed
941 942 943 944
/**************************************************************************
 * 				midiInClose		[MMSYSTEM.305]
 */
UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
Alexandre Julliard's avatar
Alexandre Julliard committed
945
{
946
    return midiInClose(HMIDIIN_32(hMidiIn));
Alexandre Julliard's avatar
Alexandre Julliard committed
947 948
}

Alexandre Julliard's avatar
Alexandre Julliard committed
949 950 951
/**************************************************************************
 * 				midiInPrepareHeader	[MMSYSTEM.306]
 */
952
UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn,         /* [in] */
953
                                    SEGPTR lpsegMidiInHdr,     /* [???] */
954
				    UINT16 uSize)              /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
955
{
956
    LPWINE_MLD		wmld;
957

958
    TRACE("(%04X, %08lx, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
959

960
    if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
961
	return MMSYSERR_INVALHANDLE;
962

963
    return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD)lpsegMidiInHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
964 965
}

Alexandre Julliard's avatar
Alexandre Julliard committed
966 967 968
/**************************************************************************
 * 				midiInUnprepareHeader	[MMSYSTEM.307]
 */
969
UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn,         /* [in] */
970
                                      SEGPTR lpsegMidiInHdr,     /* [???] */
971
				      UINT16 uSize)              /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
972
{
973
    LPWINE_MLD		wmld;
974
    LPMIDIHDR16		lpMidiInHdr = MapSL(lpsegMidiInHdr);
975

976
    TRACE("(%04X, %08lx, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);
977 978 979 980

    if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
	return MMSYSERR_NOERROR;
    }
981

982
    if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
983
	return MMSYSERR_INVALHANDLE;
984 985

    return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpsegMidiInHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
986 987
}

Alexandre Julliard's avatar
Alexandre Julliard committed
988 989 990
/**************************************************************************
 * 				midiInAddBuffer		[MMSYSTEM.308]
 */
991 992 993
UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn,         /* [in] */
                                MIDIHDR16* lpsegMidiInHdr, /* [???] NOTE: SEGPTR */
				UINT16 uSize)              /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
994
{
995 996 997 998
    LPWINE_MLD		wmld;

    TRACE("(%04X, %p, %d)\n", hMidiIn, lpsegMidiInHdr, uSize);

999
    if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
1000 1001
	return MMSYSERR_INVALHANDLE;

1002
    return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD)lpsegMidiInHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1003 1004
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1005 1006
/**************************************************************************
 * 				midiInStart			[MMSYSTEM.309]
1007 1008 1009 1010
 */
UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
{
    return midiInStart(HMIDIIN_32(hMidiIn));
1011 1012 1013
}

/**************************************************************************
1014
 * 				midiInStop			[MMSYSTEM.310]
1015
 */
1016
UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
1017
{
1018
    return midiInStop(HMIDIIN_32(hMidiIn));
1019 1020 1021
}

/**************************************************************************
1022
 * 				midiInReset			[MMSYSTEM.311]
1023
 */
1024
UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
1025
{
1026
    return midiInReset(HMIDIIN_32(hMidiIn));
1027 1028
}

1029
/**************************************************************************
1030
 * 				midiInGetID			[MMSYSTEM.312]
1031
 */
1032
UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
1033
{
1034
    LPWINE_MLD		wmld;
1035

1036
    TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID);
1037

1038
    if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1039

1040 1041 1042 1043 1044 1045
    if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, TRUE)) == NULL)
	return MMSYSERR_INVALHANDLE;

    *lpuDeviceID = wmld->uDeviceID;

    return MMSYSERR_NOERROR;
1046 1047 1048
}

/**************************************************************************
1049
 * 				midiInMessage		[MMSYSTEM.313]
1050
 */
1051 1052
DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage,
                             DWORD dwParam1, DWORD dwParam2)
1053
{
1054
    LPWINE_MLD		wmld;
1055

1056
    TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
1057

1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
    switch (uMessage) {
    case MIDM_OPEN:
    case MIDM_CLOSE:
	FIXME("can't handle OPEN or CLOSE message!\n");
	return MMSYSERR_NOTSUPPORTED;

    case MIDM_GETDEVCAPS:
        return midiInGetDevCaps16(hMidiIn, MapSL(dwParam1), dwParam2);
    case MIDM_PREPARE:
        return midiInPrepareHeader16(hMidiIn, dwParam1, dwParam2);
    case MIDM_UNPREPARE:
        return midiInUnprepareHeader16(hMidiIn, dwParam1, dwParam2);
    case MIDM_ADDBUFFER:
        return midiInAddBuffer16(hMidiIn, MapSL(dwParam1), dwParam2);
1072
    }
1073 1074 1075 1076 1077

    if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
	return MMSYSERR_INVALHANDLE;

    return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
1078 1079
}

1080 1081 1082
/**************************************************************************
 * 				midiStreamClose			[MMSYSTEM.252]
 */
1083
MMRESULT16 WINAPI midiStreamClose16(HMIDISTRM16 hMidiStrm)
1084
{
1085
    return midiStreamClose(HMIDISTRM_32(hMidiStrm));
1086 1087 1088 1089 1090
}

/**************************************************************************
 * 				midiStreamOpen			[MMSYSTEM.251]
 */
1091 1092 1093
MMRESULT16 WINAPI midiStreamOpen16(HMIDISTRM16* phMidiStrm, LPUINT16 devid,
				   DWORD cMidi, DWORD dwCallback,
				   DWORD dwInstance, DWORD fdwOpen)
1094
{
1095
    HMIDISTRM	hMidiStrm32;
1096 1097
    MMRESULT 	ret;
    UINT	devid32;
1098

1099
    if (!phMidiStrm || !devid)
1100 1101
	return MMSYSERR_INVALPARAM;
    devid32 = *devid;
1102 1103
    ret = MIDI_StreamOpen(&hMidiStrm32, &devid32, cMidi, dwCallback,
                          dwInstance, fdwOpen, FALSE);
1104
    *phMidiStrm = HMIDISTRM_16(hMidiStrm32);
1105 1106 1107 1108 1109 1110 1111
    *devid = devid32;
    return ret;
}

/**************************************************************************
 * 				midiStreamOut			[MMSYSTEM.254]
 */
1112
MMRESULT16 WINAPI midiStreamOut16(HMIDISTRM16 hMidiStrm, LPMIDIHDR16 lpMidiHdr, UINT16 cbMidiHdr)
1113
{
1114 1115
    return midiStreamOut(HMIDISTRM_32(hMidiStrm), (LPMIDIHDR)lpMidiHdr,
		         cbMidiHdr);
1116 1117 1118 1119 1120
}

/**************************************************************************
 * 				midiStreamPause			[MMSYSTEM.255]
 */
1121
MMRESULT16 WINAPI midiStreamPause16(HMIDISTRM16 hMidiStrm)
1122
{
1123
    return midiStreamPause(HMIDISTRM_32(hMidiStrm));
1124 1125 1126 1127 1128
}

/**************************************************************************
 * 				midiStreamPosition		[MMSYSTEM.253]
 */
1129
MMRESULT16 WINAPI midiStreamPosition16(HMIDISTRM16 hMidiStrm, LPMMTIME16 lpmmt16, UINT16 cbmmt)
1130
{
1131 1132
    MMTIME	mmt32;
    MMRESULT	ret;
1133

1134
    if (!lpmmt16)
1135
	return MMSYSERR_INVALPARAM;
1136
    MMSYSTEM_MMTIME16to32(&mmt32, lpmmt16);
1137
    ret = midiStreamPosition(HMIDISTRM_32(hMidiStrm), &mmt32, sizeof(MMTIME));
1138
    MMSYSTEM_MMTIME32to16(lpmmt16, &mmt32);
1139 1140 1141 1142 1143 1144
    return ret;
}

/**************************************************************************
 * 				midiStreamProperty		[MMSYSTEM.250]
 */
1145
MMRESULT16 WINAPI midiStreamProperty16(HMIDISTRM16 hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
1146
{
1147
    return midiStreamProperty(HMIDISTRM_32(hMidiStrm), lpPropData, dwProperty);
1148 1149 1150 1151 1152
}

/**************************************************************************
 * 				midiStreamRestart		[MMSYSTEM.256]
 */
1153
MMRESULT16 WINAPI midiStreamRestart16(HMIDISTRM16 hMidiStrm)
1154
{
1155
    return midiStreamRestart(HMIDISTRM_32(hMidiStrm));
1156 1157 1158 1159 1160
}

/**************************************************************************
 * 				midiStreamStop			[MMSYSTEM.257]
 */
1161
MMRESULT16 WINAPI midiStreamStop16(HMIDISTRM16 hMidiStrm)
1162
{
1163
    return midiStreamStop(HMIDISTRM_32(hMidiStrm));
1164
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1165

1166 1167 1168 1169 1170
/* ###################################################
 * #                     WAVE                        #
 * ###################################################
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
1171
/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1172
 * 				waveOutGetNumDevs		[MMSYSTEM.401]
Alexandre Julliard's avatar
Alexandre Julliard committed
1173
 */
Eric Pouech's avatar
Eric Pouech committed
1174
UINT16 WINAPI waveOutGetNumDevs16(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
1175
{
1176
    return MMDRV_GetNum(MMDRV_WAVEOUT);
Alexandre Julliard's avatar
Alexandre Julliard committed
1177
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1178

Alexandre Julliard's avatar
Alexandre Julliard committed
1179
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1180 1181
 * 				waveOutGetDevCaps		[MMSYSTEM.402]
 */
1182
UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID,
1183
				  LPWAVEOUTCAPS16 lpCaps, UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
1184
{
1185 1186
    WAVEOUTCAPSA	wocA;
    UINT 		ret;
1187

1188 1189
    TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
    if (lpCaps == NULL)	return MMSYSERR_INVALPARAM;
1190

1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
    ret = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(wocA));

    if (ret == MMSYSERR_NOERROR) {
	lpCaps->wMid = wocA.wMid;
	lpCaps->wPid = wocA.wPid;
	lpCaps->vDriverVersion = wocA.vDriverVersion;
	strcpy(lpCaps->szPname, wocA.szPname);
	lpCaps->dwFormats = wocA.dwFormats;
	lpCaps->wChannels = wocA.wChannels;
	lpCaps->dwSupport = wocA.dwSupport;
    }
    return ret;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1204

Alexandre Julliard's avatar
Alexandre Julliard committed
1205
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1206 1207 1208 1209
 * 				waveOutGetErrorText 	[MMSYSTEM.403]
 */
UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
{
1210
    return waveOutGetErrorTextA(uError, lpText, uSize);
Alexandre Julliard's avatar
Alexandre Julliard committed
1211
}
1212

Alexandre Julliard's avatar
Alexandre Julliard committed
1213 1214 1215
/**************************************************************************
 *			waveOutOpen			[MMSYSTEM.404]
 */
1216
UINT16 WINAPI waveOutOpen16(HWAVEOUT16* lphWaveOut, UINT16 uDeviceID,
Alexandre Julliard's avatar
Alexandre Julliard committed
1217
                            const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
1218
			    DWORD dwInstance, DWORD dwFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
1219
{
1220
    HANDLE		hWaveOut;
1221 1222
    UINT		ret;

Andreas Mohr's avatar
Andreas Mohr committed
1223
    /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1224
     * call the 32 bit version
1225
     * however, we need to promote correctly the wave mapper id
1226
     * (0xFFFFFFFF and not 0x0000FFFF)
1227
     */
1228 1229
    ret = WAVE_Open(&hWaveOut, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
                    MMDRV_WAVEOUT, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1230

1231
    if (lphWaveOut != NULL) *lphWaveOut = HWAVEOUT_16(hWaveOut);
1232
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
1233 1234
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1235 1236 1237 1238
/**************************************************************************
 * 				waveOutClose		[MMSYSTEM.405]
 */
UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
Alexandre Julliard's avatar
Alexandre Julliard committed
1239
{
1240 1241 1242 1243
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1244
    ret = waveOutClose(HWAVEOUT_32(hWaveOut));
1245 1246
    RestoreThunkLock(level);
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
1247 1248
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1249 1250 1251
/**************************************************************************
 * 				waveOutPrepareHeader	[MMSYSTEM.406]
 */
1252
UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut,      /* [in] */
1253
                                     SEGPTR lpsegWaveOutHdr,   /* [???] */
1254
				     UINT16 uSize)             /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
1255
{
1256
    LPWINE_MLD		wmld;
1257
    LPWAVEHDR		lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1258

1259
    TRACE("(%04X, %08lx, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1260

1261 1262
    if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM;

1263
    if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1264
	return MMSYSERR_INVALHANDLE;
1265 1266

    return MMDRV_Message(wmld, WODM_PREPARE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1267 1268
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1269 1270 1271
/**************************************************************************
 * 				waveOutUnprepareHeader	[MMSYSTEM.407]
 */
1272
UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut,       /* [in] */
1273
				       SEGPTR lpsegWaveOutHdr,    /* [???] */
1274
				       UINT16 uSize)              /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
1275
{
1276
    LPWINE_MLD		wmld;
1277
    LPWAVEHDR		lpWaveOutHdr = MapSL(lpsegWaveOutHdr);
1278

1279
    TRACE("(%04X, %08lx, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1280

1281 1282 1283 1284
    if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
	return MMSYSERR_NOERROR;
    }

1285
    if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1286
	return MMSYSERR_INVALHANDLE;
1287 1288

    return MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1289 1290
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1291 1292 1293
/**************************************************************************
 * 				waveOutWrite		[MMSYSTEM.408]
 */
1294 1295 1296
UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut,       /* [in] */
			     LPWAVEHDR lpsegWaveOutHdr, /* [???] NOTE: SEGPTR */
			     UINT16 uSize)              /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
1297
{
1298
    LPWINE_MLD		wmld;
1299

1300
    TRACE("(%04X, %p, %u);\n", hWaveOut, lpsegWaveOutHdr, uSize);
1301

1302
    if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1303
	return MMSYSERR_INVALHANDLE;
Alexandre Julliard's avatar
Alexandre Julliard committed
1304

1305
    return MMDRV_Message(wmld, WODM_WRITE, (DWORD)lpsegWaveOutHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1306 1307
}

1308
/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1309
 * 				waveOutBreakLoop	[MMSYSTEM.419]
1310 1311 1312 1313 1314 1315 1316
 */
UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut16)
{
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1317
    ret = waveOutBreakLoop(HWAVEOUT_32(hWaveOut16));
1318 1319 1320 1321 1322
    RestoreThunkLock(level);
    return ret;
}

/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1323
 * 				waveOutPause		[MMSYSTEM.409]
1324 1325 1326 1327 1328 1329 1330
 */
UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut16)
{
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1331
    ret = waveOutPause(HWAVEOUT_32(hWaveOut16));
1332 1333 1334 1335 1336
    RestoreThunkLock(level);
    return ret;
}

/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1337
 * 				waveOutReset		[MMSYSTEM.411]
1338 1339 1340 1341 1342 1343 1344
 */
UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut16)
{
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1345
    ret = waveOutReset(HWAVEOUT_32(hWaveOut16));
1346 1347 1348 1349 1350
    RestoreThunkLock(level);
    return ret;
}

/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1351
 * 				waveOutRestart	[MMSYSTEM.410]
1352 1353 1354 1355 1356 1357 1358
 */
UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut16)
{
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1359
    ret = waveOutRestart(HWAVEOUT_32(hWaveOut16));
1360 1361 1362
    RestoreThunkLock(level);
    return ret;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1363

Alexandre Julliard's avatar
Alexandre Julliard committed
1364 1365 1366
/**************************************************************************
 * 				waveOutGetPosition	[MMSYSTEM.412]
 */
1367
UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut, LPMMTIME16 lpTime,
Alexandre Julliard's avatar
Alexandre Julliard committed
1368
                                   UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
1369
{
1370 1371 1372
    UINT	ret;
    MMTIME	mmt;

1373 1374 1375 1376
    mmt.wType = lpTime->wType;
    ret = waveOutGetPosition(HWAVEOUT_32(hWaveOut), &mmt, sizeof(mmt));
    MMSYSTEM_MMTIME32to16(lpTime, &mmt);
    return ret;
1377 1378 1379 1380 1381 1382 1383
}

/**************************************************************************
 * 				waveOutGetPitch		[MMSYSTEM.413]
 */
UINT16 WINAPI waveOutGetPitch16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
{
1384
    return waveOutGetPitch(HWAVEOUT_32(hWaveOut16), lpdw);
1385 1386 1387 1388 1389 1390 1391
}

/**************************************************************************
 * 				waveOutSetPitch		[MMSYSTEM.414]
 */
UINT16 WINAPI waveOutSetPitch16(HWAVEOUT16 hWaveOut16, DWORD dw)
{
1392
    return waveOutSetPitch(HWAVEOUT_32(hWaveOut16), dw);
1393 1394 1395 1396 1397 1398 1399
}

/**************************************************************************
 * 				waveOutGetPlaybackRate	[MMSYSTEM.417]
 */
UINT16 WINAPI waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
{
1400
    return waveOutGetPlaybackRate(HWAVEOUT_32(hWaveOut16), lpdw);
1401 1402 1403 1404 1405 1406 1407
}

/**************************************************************************
 * 				waveOutSetPlaybackRate	[MMSYSTEM.418]
 */
UINT16 WINAPI waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16, DWORD dw)
{
1408
    return waveOutSetPlaybackRate(HWAVEOUT_32(hWaveOut16), dw);
1409 1410 1411 1412 1413 1414 1415 1416 1417
}

/**************************************************************************
 * 				waveOutGetVolume	[MMSYSTEM.415]
 */
UINT16 WINAPI waveOutGetVolume16(UINT16 devid, LPDWORD lpdw)
{
    return waveOutGetVolume(devid, lpdw);
}
1418

1419 1420 1421 1422 1423 1424 1425
/**************************************************************************
 * 				waveOutSetVolume	[MMSYSTEM.416]
 */
UINT16 WINAPI waveOutSetVolume16(UINT16 devid, DWORD dw)
{
    return waveOutSetVolume(devid, dw);
}
1426

Alexandre Julliard's avatar
Alexandre Julliard committed
1427
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1428 1429
 * 				waveOutGetID	 	[MMSYSTEM.420]
 */
1430
UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16* lpuDeviceID)
Alexandre Julliard's avatar
Alexandre Julliard committed
1431
{
1432
    LPWINE_MLD		wmld;
1433

1434
    TRACE("(%04X, %p);\n", hWaveOut, lpuDeviceID);
1435

Alexandre Julliard's avatar
Alexandre Julliard committed
1436
    if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1437

1438
    if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL)
1439 1440 1441
	return MMSYSERR_INVALHANDLE;

    *lpuDeviceID = wmld->uDeviceID;
Alexandre Julliard's avatar
Alexandre Julliard committed
1442
    return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1443 1444
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1445
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1446 1447
 * 				waveOutMessage 		[MMSYSTEM.421]
 */
1448
DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage,
Alexandre Julliard's avatar
Alexandre Julliard committed
1449
                              DWORD dwParam1, DWORD dwParam2)
Alexandre Julliard's avatar
Alexandre Julliard committed
1450
{
1451
    LPWINE_MLD		wmld;
1452

1453 1454
    TRACE("(%04x, %u, %ld, %ld)\n", hWaveOut, uMessage, dwParam1, dwParam2);

1455 1456
    if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, FALSE)) == NULL) {
	if ((wmld = MMDRV_Get(HWAVEOUT_32(hWaveOut), MMDRV_WAVEOUT, TRUE)) != NULL) {
1457 1458 1459
	    return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
	}
	return MMSYSERR_INVALHANDLE;
Alexandre Julliard's avatar
Alexandre Julliard committed
1460
    }
1461 1462 1463 1464 1465 1466

    /* from M$ KB */
    if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
	return MMSYSERR_INVALPARAM;

    return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1467
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1468

Alexandre Julliard's avatar
Alexandre Julliard committed
1469 1470 1471
/**************************************************************************
 * 				waveInGetNumDevs 		[MMSYSTEM.501]
 */
Eric Pouech's avatar
Eric Pouech committed
1472
UINT16 WINAPI waveInGetNumDevs16(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
1473
{
1474
    return MMDRV_GetNum(MMDRV_WAVEIN);
Alexandre Julliard's avatar
Alexandre Julliard committed
1475 1476
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1477 1478 1479
/**************************************************************************
 * 				waveInGetDevCaps 		[MMSYSTEM.502]
 */
1480
UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps,
1481
				 UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
1482
{
1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496
    WAVEINCAPSA	wicA;
    UINT	ret = waveInGetDevCapsA(uDeviceID, &wicA, sizeof(wicA));

    if (lpCaps == NULL)	return MMSYSERR_INVALPARAM;

    if (ret == MMSYSERR_NOERROR) {
	lpCaps->wMid = wicA.wMid;
	lpCaps->wPid = wicA.wPid;
	lpCaps->vDriverVersion = wicA.vDriverVersion;
	strcpy(lpCaps->szPname, wicA.szPname);
	lpCaps->dwFormats = wicA.dwFormats;
	lpCaps->wChannels = wicA.wChannels;
    }
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
1497 1498
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1499
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1500 1501 1502
 * 				waveInGetErrorText 	[MMSYSTEM.503]
 */
UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
1503
{
1504
    return waveInGetErrorTextA(uError, lpText, uSize);
Alexandre Julliard's avatar
Alexandre Julliard committed
1505 1506 1507 1508 1509
}

/**************************************************************************
 * 				waveInOpen			[MMSYSTEM.504]
 */
1510
UINT16 WINAPI waveInOpen16(HWAVEIN16* lphWaveIn, UINT16 uDeviceID,
1511
                           const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
Alexandre Julliard's avatar
Alexandre Julliard committed
1512
                           DWORD dwInstance, DWORD dwFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
1513
{
1514
    HANDLE		hWaveIn;
1515
    UINT		ret;
1516

Andreas Mohr's avatar
Andreas Mohr committed
1517
    /* since layout of WAVEFORMATEX is the same for 16/32 bits, we directly
1518
     * call the 32 bit version
1519
     * however, we need to promote correctly the wave mapper id
1520
     * (0xFFFFFFFF and not 0x0000FFFF)
1521
     */
1522 1523
    ret = WAVE_Open(&hWaveIn, (uDeviceID == (UINT16)-1) ? (UINT)-1 : uDeviceID,
                    MMDRV_WAVEIN, lpFormat, dwCallback, dwInstance, dwFlags, FALSE);
1524

1525
    if (lphWaveIn != NULL) *lphWaveIn = HWAVEIN_16(hWaveIn);
1526
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
1527 1528
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1529 1530 1531 1532
/**************************************************************************
 * 				waveInClose			[MMSYSTEM.505]
 */
UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
Alexandre Julliard's avatar
Alexandre Julliard committed
1533
{
1534 1535 1536 1537
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1538
    ret = waveInClose(HWAVEIN_32(hWaveIn));
1539 1540
    RestoreThunkLock(level);
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
1541 1542
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1543
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1544 1545
 * 				waveInPrepareHeader		[MMSYSTEM.506]
 */
1546
UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn,       /* [in] */
1547
				    SEGPTR lpsegWaveInHdr,   /* [???] */
1548
				    UINT16 uSize)            /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
1549
{
1550
    LPWINE_MLD		wmld;
1551
    LPWAVEHDR		lpWaveInHdr = MapSL(lpsegWaveInHdr);
Alexandre Julliard's avatar
Alexandre Julliard committed
1552
    UINT16		ret;
1553

1554
    TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
1555

Alexandre Julliard's avatar
Alexandre Julliard committed
1556
    if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
1557
    if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1558
	return MMSYSERR_INVALHANDLE;
1559

Alexandre Julliard's avatar
Alexandre Julliard committed
1560
    lpWaveInHdr->dwBytesRecorded = 0;
1561

1562
    ret = MMDRV_Message(wmld, WIDM_PREPARE, (DWORD)lpsegWaveInHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1563
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
1564 1565
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1566 1567 1568
/**************************************************************************
 * 				waveInUnprepareHeader	[MMSYSTEM.507]
 */
1569
UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn,       /* [in] */
1570
				      SEGPTR lpsegWaveInHdr,   /* [???] */
1571
				      UINT16 uSize)            /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
1572
{
1573
    LPWINE_MLD		wmld;
1574
    LPWAVEHDR		lpWaveInHdr = MapSL(lpsegWaveInHdr);
1575

1576
    TRACE("(%04X, %08lx, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
1577 1578 1579 1580 1581 1582 1583

    if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;

    if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) {
	return MMSYSERR_NOERROR;
    }

1584
    if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1585
	return MMSYSERR_INVALHANDLE;
1586

1587
    return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpsegWaveInHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1588
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1589

Alexandre Julliard's avatar
Alexandre Julliard committed
1590 1591 1592
/**************************************************************************
 * 				waveInAddBuffer		[MMSYSTEM.508]
 */
1593 1594 1595
UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn,       /* [in] */
				WAVEHDR* lpsegWaveInHdr, /* [???] NOTE: SEGPTR */
				UINT16 uSize)            /* [in] */
Alexandre Julliard's avatar
Alexandre Julliard committed
1596
{
1597
    LPWINE_MLD		wmld;
1598

1599
    TRACE("(%04X, %p, %u);\n", hWaveIn, lpsegWaveInHdr, uSize);
Alexandre Julliard's avatar
Alexandre Julliard committed
1600

1601
    if (lpsegWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
1602
    if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1603
	return MMSYSERR_INVALHANDLE;
Alexandre Julliard's avatar
Alexandre Julliard committed
1604

1605
    return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD)lpsegWaveInHdr, uSize, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1606
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1607

1608 1609 1610 1611 1612 1613 1614 1615 1616
/**************************************************************************
 * 				waveInReset		[MMSYSTEM.511]
 */
UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn16)
{
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1617
    ret = waveInReset(HWAVEIN_32(hWaveIn16));
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630
    RestoreThunkLock(level);
    return ret;
}

/**************************************************************************
 * 				waveInStart		[MMSYSTEM.509]
 */
UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn16)
{
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1631
    ret = waveInStart(HWAVEIN_32(hWaveIn16));
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
    RestoreThunkLock(level);
    return ret;
}

/**************************************************************************
 * 				waveInStop		[MMSYSTEM.510]
 */
UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn16)
{
    DWORD	level;
    UINT16	ret;

    ReleaseThunkLock(&level);
1645
    ret = waveInStop(HWAVEIN_32(hWaveIn16));
1646 1647 1648
    RestoreThunkLock(level);
    return ret;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1649 1650

/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1651 1652
 * 				waveInGetPosition	[MMSYSTEM.512]
 */
1653
UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn, LPMMTIME16 lpTime,
Alexandre Julliard's avatar
Alexandre Julliard committed
1654
                                  UINT16 uSize)
Alexandre Julliard's avatar
Alexandre Julliard committed
1655
{
1656 1657 1658 1659
    UINT	ret;
    MMTIME	mmt;

    mmt.wType = lpTime->wType;
1660
    ret = waveInGetPosition(HWAVEIN_32(hWaveIn), &mmt, sizeof(mmt));
1661 1662
    MMSYSTEM_MMTIME32to16(lpTime, &mmt);
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
1663 1664
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1665
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1666 1667
 * 				waveInGetID			[MMSYSTEM.513]
 */
1668
UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16* lpuDeviceID)
Alexandre Julliard's avatar
Alexandre Julliard committed
1669
{
1670 1671 1672 1673
    LPWINE_MLD		wmld;

    TRACE("(%04X, %p);\n", hWaveIn, lpuDeviceID);

Alexandre Julliard's avatar
Alexandre Julliard committed
1674
    if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
1675

1676
    if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1677 1678 1679 1680
	return MMSYSERR_INVALHANDLE;

    *lpuDeviceID = wmld->uDeviceID;
    return MMSYSERR_NOERROR;
Alexandre Julliard's avatar
Alexandre Julliard committed
1681 1682
}

Alexandre Julliard's avatar
Alexandre Julliard committed
1683
/**************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1684 1685 1686 1687
 * 				waveInMessage 		[MMSYSTEM.514]
 */
DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
                             DWORD dwParam1, DWORD dwParam2)
Alexandre Julliard's avatar
Alexandre Julliard committed
1688
{
1689 1690 1691 1692 1693 1694 1695 1696
    LPWINE_MLD		wmld;

    TRACE("(%04x, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2);

    /* from M$ KB */
    if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
	return MMSYSERR_INVALPARAM;

1697
    if ((wmld = MMDRV_Get(HWAVEIN_32(hWaveIn), MMDRV_WAVEIN, FALSE)) == NULL)
1698 1699 1700
	return MMSYSERR_INVALHANDLE;

    return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
Alexandre Julliard's avatar
Alexandre Julliard committed
1701 1702
}

1703 1704 1705 1706 1707
/* ###################################################
 * #                     TASK                        #
 * ###################################################
 */

1708 1709
/*#define USE_MM_TSK_WINE*/

Alexandre Julliard's avatar
Alexandre Julliard committed
1710 1711
/**************************************************************************
 * 				mmTaskCreate		[MMSYSTEM.900]
1712 1713 1714
 *
 * Creates a 16 bit MM task. It's entry point is lpFunc, and it should be
 * called upon creation with dwPmt as parameter.
Alexandre Julliard's avatar
Alexandre Julliard committed
1715
 */
1716
HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD dwPmt)
Alexandre Julliard's avatar
Alexandre Julliard committed
1717
{
1718 1719
    HINSTANCE16 	ret;
    HINSTANCE16		handle;
1720 1721 1722 1723
    char cmdline[16];
    DWORD showCmd = 0x40002;
    LOADPARAMS16 lp;

1724
    TRACE("(%08lx, %p, %08lx);\n", spProc, lphMmTask, dwPmt);
1725 1726 1727 1728 1729 1730 1731
    /* This to work requires NE modules to be started with a binary command line
     * which is not currently the case. A patch exists but has never been committed.
     * A workaround would be to integrate code for mmtask.tsk into Wine, but
     * this requires tremendous work (starting with patching tools/build to
     * create NE executables (and not only DLLs) for builtins modules.
     * EP 99/04/25
     */
1732
    FIXME("This is currently broken. It will fail\n");
1733

Alexandre Julliard's avatar
Alexandre Julliard committed
1734
    cmdline[0] = 0x0d;
1735
    *(LPDWORD)(cmdline + 1) = (DWORD)spProc;
1736 1737
    *(LPDWORD)(cmdline + 5) = dwPmt;
    *(LPDWORD)(cmdline + 9) = 0;
1738

1739 1740 1741 1742
    lp.hEnvironment = 0;
    lp.cmdLine = MapLS(cmdline);
    lp.showCmd = MapLS(&showCmd);
    lp.reserved = 0;
1743

1744
#ifndef USE_MM_TSK_WINE
1745
    handle = LoadModule16("c:\\windows\\system\\mmtask.tsk", &lp);
1746
#else
1747
    handle = LoadModule16("mmtask.tsk", &lp);
1748
#endif
1749 1750
    if (handle < 32) {
	ret = (handle) ? 1 : 2;
Alexandre Julliard's avatar
Alexandre Julliard committed
1751
	handle = 0;
1752
    } else {
Alexandre Julliard's avatar
Alexandre Julliard committed
1753 1754
	ret = 0;
    }
1755 1756
    if (lphMmTask)
	*lphMmTask = handle;
1757

1758 1759
    UnMapLS( lp.cmdLine );
    UnMapLS( lp.showCmd );
1760
    TRACE("=> 0x%04x/%d\n", handle, ret);
Alexandre Julliard's avatar
Alexandre Julliard committed
1761
    return ret;
1762 1763
}

1764
#ifdef USE_MM_TSK_WINE
1765
/* C equivalent to mmtask.tsk binary content */
1766
void	mmTaskEntryPoint16(LPSTR cmdLine, WORD di, WORD si)
1767 1768 1769
{
    int	len = cmdLine[0x80];

1770
    if (len / 2 == 6) {
1771
	void	(*fpProc)(DWORD) = MapSL(*((DWORD*)(cmdLine + 1)));
1772 1773
	DWORD	dwPmt  = *((DWORD*)(cmdLine + 5));

1774
#if 0
1775
	InitTask16(); /* FIXME: pmts / from context ? */
1776
	InitApp(di);
1777
#endif
1778 1779 1780 1781
	if (SetMessageQueue16(0x40)) {
	    WaitEvent16(0);
	    if (HIWORD(fpProc)) {
		OldYield16();
1782
/* EPP 		StackEnter16(); */
1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793
		(fpProc)(dwPmt);
	    }
	}
    }
    OldYield16();
    OldYield16();
    OldYield16();
    ExitProcess(0);
}
#endif

1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807
/**************************************************************************
 * 				mmTaskBlock		[MMSYSTEM.902]
 */
void	WINAPI	mmTaskBlock16(HINSTANCE16 WINE_UNUSED hInst)
{
    MSG		msg;

    do {
	GetMessageA(&msg, 0, 0, 0);
	if (msg.hwnd) {
	    TranslateMessage(&msg);
	    DispatchMessageA(&msg);
	}
    } while (msg.message < 0x3A0);
Alexandre Julliard's avatar
Alexandre Julliard committed
1808 1809 1810 1811 1812
}

/**************************************************************************
 * 				mmTaskSignal		[MMSYSTEM.903]
 */
1813
LRESULT	WINAPI mmTaskSignal16(HTASK16 ht)
Alexandre Julliard's avatar
Alexandre Julliard committed
1814
{
1815
    TRACE("(%04x);\n", ht);
1816
    return PostThreadMessageW( HTASK_32(ht), WM_USER, 0, 0 );
Alexandre Julliard's avatar
Alexandre Julliard committed
1817
}
1818

1819 1820 1821 1822 1823 1824 1825 1826
/**************************************************************************
 * 				mmGetCurrentTask	[MMSYSTEM.904]
 */
HTASK16 WINAPI mmGetCurrentTask16(void)
{
    return GetCurrentTask();
}

1827
/**************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1828
 * 				mmTaskYield		[MMSYSTEM.905]
1829 1830 1831 1832 1833 1834
 */
void	WINAPI	mmTaskYield16(void)
{
    MSG		msg;

    if (PeekMessageA(&msg, 0, 0, 0, 0)) {
1835
	K32WOWYield16();
1836 1837 1838
    }
}

1839
extern DWORD	WINAPI	GetProcessFlags(DWORD);
1840

1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852
/******************************************************************
 *		WINMM_GetmmThread
 *
 *
 */
static  WINE_MMTHREAD*	WINMM_GetmmThread(HANDLE16 h)
{
    return (WINE_MMTHREAD*)MapSL( MAKESEGPTR(h, 0) );
}

void WINAPI WINE_mmThreadEntryPoint(DWORD);

1853 1854
/**************************************************************************
 * 				mmThreadCreate		[MMSYSTEM.1120]
1855 1856
 *
 * undocumented
1857 1858
 * Creates a MM thread, calling fpThreadAddr(dwPmt).
 * dwFlags:
1859
 * 	bit.0 set means create a 16 bit task instead of thread calling a 16 bit proc
1860
 *	bit.1 set means to open a VxD for this thread (unsupported)
1861
 */
1862
LRESULT	WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD dwPmt, DWORD dwFlags)
1863 1864 1865 1866
{
    HANDLE16		hndl;
    LRESULT		ret;

1867
    TRACE("(%p, %p, %08lx, %08lx)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags);
1868 1869 1870 1871 1872 1873

    hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT);

    if (hndl == 0) {
	ret = 2;
    } else {
1874
	WINE_MMTHREAD*	lpMMThd = WINMM_GetmmThread(hndl);
1875

1876 1877
#if 0
	/* force mmtask routines even if mmthread is required */
1878
	/* this will work only if the patch about binary cmd line and NE tasks
1879
	 * is committed
1880
	 */
1881
	dwFlags |= 1;
1882 1883
#endif

1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895
	lpMMThd->dwSignature 	= WINE_MMTHREAD_CREATED;
	lpMMThd->dwCounter   	= 0;
	lpMMThd->hThread     	= 0;
	lpMMThd->dwThreadID  	= 0;
	lpMMThd->fpThread    	= fpThreadAddr;
	lpMMThd->dwThreadPmt 	= dwPmt;
	lpMMThd->dwSignalCount	= 0;
	lpMMThd->hEvent      	= 0;
	lpMMThd->hVxD        	= 0;
	lpMMThd->dwStatus    	= 0;
	lpMMThd->dwFlags     	= dwFlags;
	lpMMThd->hTask       	= 0;
1896

1897
	if ((dwFlags & 1) == 0 && (GetProcessFlags(GetCurrentThreadId()) & 8) == 0) {
1898
	    lpMMThd->hEvent = CreateEventA(0, 0, 1, 0);
1899

1900
	    TRACE("Let's go crazy... trying new MM thread. lpMMThd=%p\n", lpMMThd);
1901
	    if (lpMMThd->dwFlags & 2) {
1902
		/* as long as we don't support MM VxD in wine, we don't need
1903 1904
		 * to care about this flag
		 */
1905
		/* FIXME("Don't know how to properly open VxD handles\n"); */
1906 1907 1908
		/* lpMMThd->hVxD = OpenVxDHandle(lpMMThd->hEvent); */
	    }

1909
	    lpMMThd->hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)WINE_mmThreadEntryPoint,
1910 1911
					    (LPVOID)(DWORD)hndl, CREATE_SUSPENDED, &lpMMThd->dwThreadID);
	    if (lpMMThd->hThread == 0) {
1912
		WARN("Couldn't create thread\n");
1913 1914 1915 1916
		/* clean-up(VxDhandle...); devicedirectio... */
		if (lpMMThd->hEvent != 0)
		    CloseHandle(lpMMThd->hEvent);
		ret = 2;
1917
	    } else {
1918
		TRACE("Got a nice thread hndl=%p id=0x%08lx\n", lpMMThd->hThread, lpMMThd->dwThreadID);
1919
		ret = 0;
1920
	    }
1921
	} else {
1922
	    /* get WINE_mmThreadEntryPoint()
1923 1924
	     * 2047 is its ordinal in mmsystem.spec
	     */
1925
	    FARPROC16	fp = GetProcAddress16(GetModuleHandle16("MMSYSTEM"), (LPCSTR)2047);
1926

1927
	    TRACE("farproc seg=0x%08lx lin=%p\n", (DWORD)fp, MapSL((SEGPTR)fp));
1928 1929

	    ret = (fp == 0) ? 2 : mmTaskCreate16((DWORD)fp, 0, hndl);
1930 1931
	}

1932 1933
	if (ret == 0) {
	    if (lpMMThd->hThread && !ResumeThread(lpMMThd->hThread))
1934
		WARN("Couldn't resume thread\n");
1935

1936
	    while (lpMMThd->dwStatus != 0x10) { /* test also HIWORD of dwStatus */
1937 1938 1939 1940 1941
		UserYield16();
	    }
	}
    }

1942 1943 1944 1945
    if (ret != 0) {
	GlobalFree16(hndl);
	hndl = 0;
    }
1946 1947 1948 1949

    if (lpHndl)
	*lpHndl = hndl;

1950
    TRACE("ok => %ld\n", ret);
1951 1952 1953 1954 1955 1956
    return ret;
}

/**************************************************************************
 * 				mmThreadSignal		[MMSYSTEM.1121]
 */
1957
void WINAPI mmThreadSignal16(HANDLE16 hndl)
1958
{
1959
    TRACE("(%04x)!\n", hndl);
1960 1961

    if (hndl) {
1962
	WINE_MMTHREAD*	lpMMThd = WINMM_GetmmThread(hndl);
1963 1964 1965

	lpMMThd->dwCounter++;
	if (lpMMThd->hThread != 0) {
1966 1967
	    InterlockedIncrement(&lpMMThd->dwSignalCount);
	    SetEvent(lpMMThd->hEvent);
1968 1969 1970 1971 1972 1973 1974
	} else {
	    mmTaskSignal16(lpMMThd->hTask);
	}
	lpMMThd->dwCounter--;
    }
}

1975 1976 1977 1978 1979 1980
static	void	MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd)
{
    MSG		msg;
    DWORD	ret;

    if (lpMMThd->dwThreadID != GetCurrentThreadId())
1981
	ERR("Not called by thread itself\n");
1982 1983 1984 1985 1986 1987

    for (;;) {
	ResetEvent(lpMMThd->hEvent);
	if (InterlockedDecrement(&lpMMThd->dwSignalCount) >= 0)
	    break;
	InterlockedIncrement(&lpMMThd->dwSignalCount);
1988

1989
	TRACE("S1\n");
1990

1991 1992 1993
	ret = MsgWaitForMultipleObjects(1, &lpMMThd->hEvent, FALSE, INFINITE, QS_ALLINPUT);
	switch (ret) {
	case WAIT_OBJECT_0:	/* Event */
1994
	    TRACE("S2.1\n");
1995 1996
	    break;
	case WAIT_OBJECT_0 + 1:	/* Msg */
1997
	    TRACE("S2.2\n");
1998 1999 2000
	    if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
		TranslateMessage(&msg);
		DispatchMessageA(&msg);
2001 2002 2003
	    }
	    break;
	default:
2004
	    WARN("S2.x unsupported ret val 0x%08lx\n", ret);
2005
	}
2006
	TRACE("S3\n");
2007 2008 2009
    }
}

2010 2011 2012
/**************************************************************************
 * 				mmThreadBlock		[MMSYSTEM.1122]
 */
2013
void	WINAPI mmThreadBlock16(HANDLE16 hndl)
2014
{
2015
    TRACE("(%04x)!\n", hndl);
2016 2017

    if (hndl) {
2018
	WINE_MMTHREAD*	lpMMThd = WINMM_GetmmThread(hndl);
2019

2020
	if (lpMMThd->hThread != 0) {
2021
	    DWORD	lc;
2022

2023
	    ReleaseThunkLock(&lc);
2024
	    MMSYSTEM_ThreadBlock(lpMMThd);
2025
	    RestoreThunkLock(lc);
2026 2027 2028 2029
	} else {
	    mmTaskBlock16(lpMMThd->hTask);
	}
    }
2030
    TRACE("done\n");
2031 2032 2033 2034 2035
}

/**************************************************************************
 * 				mmThreadIsCurrent	[MMSYSTEM.1123]
 */
2036
BOOL16	WINAPI mmThreadIsCurrent16(HANDLE16 hndl)
2037
{
2038
    BOOL16		ret = FALSE;
2039

2040
    TRACE("(%04x)!\n", hndl);
2041

2042
    if (hndl && mmThreadIsValid16(hndl)) {
2043
	WINE_MMTHREAD*	lpMMThd = WINMM_GetmmThread(hndl);
2044 2045
	ret = (GetCurrentThreadId() == lpMMThd->dwThreadID);
    }
2046
    TRACE("=> %d\n", ret);
2047
    return ret;
2048 2049 2050 2051 2052 2053 2054
}

/**************************************************************************
 * 				mmThreadIsValid		[MMSYSTEM.1124]
 */
BOOL16	WINAPI	mmThreadIsValid16(HANDLE16 hndl)
{
2055
    BOOL16		ret = FALSE;
2056

2057
    TRACE("(%04x)!\n", hndl);
2058

2059
    if (hndl) {
2060
	WINE_MMTHREAD*	lpMMThd = WINMM_GetmmThread(hndl);
2061

2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
	if (!IsBadWritePtr(lpMMThd, sizeof(WINE_MMTHREAD)) &&
	    lpMMThd->dwSignature == WINE_MMTHREAD_CREATED &&
	    IsTask16(lpMMThd->hTask)) {
	    lpMMThd->dwCounter++;
	    if (lpMMThd->hThread != 0) {
		DWORD	dwThreadRet;
		if (GetExitCodeThread(lpMMThd->hThread, &dwThreadRet) &&
		    dwThreadRet == STATUS_PENDING) {
		    ret = TRUE;
		}
	    } else {
		ret = TRUE;
	    }
	    lpMMThd->dwCounter--;
2076 2077
	}
    }
2078
    TRACE("=> %d\n", ret);
2079 2080 2081 2082 2083 2084
    return ret;
}

/**************************************************************************
 * 				mmThreadGetTask		[MMSYSTEM.1125]
 */
2085
HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl)
2086 2087 2088
{
    HANDLE16	ret = 0;

2089
    TRACE("(%04x)\n", hndl);
2090 2091

    if (mmThreadIsValid16(hndl)) {
2092
	WINE_MMTHREAD*	lpMMThd = WINMM_GetmmThread(hndl);
2093 2094 2095 2096 2097
	ret = lpMMThd->hTask;
    }
    return ret;
}

2098
/**************************************************************************
2099
 * 			        __wine_mmThreadEntryPoint (MMSYSTEM.2047)
2100
 */
2101
void WINAPI WINE_mmThreadEntryPoint(DWORD _pmt)
2102 2103
{
    HANDLE16		hndl = (HANDLE16)_pmt;
2104
    WINE_MMTHREAD*	lpMMThd = WINMM_GetmmThread(hndl);
2105

2106
    TRACE("(%04x %p)\n", hndl, lpMMThd);
2107 2108

    lpMMThd->hTask = LOWORD(GetCurrentTask());
2109
    TRACE("[10-%p] setting hTask to 0x%08x\n", lpMMThd->hThread, lpMMThd->hTask);
2110
    lpMMThd->dwStatus = 0x10;
2111
    MMSYSTEM_ThreadBlock(lpMMThd);
2112
    TRACE("[20-%p]\n", lpMMThd->hThread);
2113
    lpMMThd->dwStatus = 0x20;
2114
    if (lpMMThd->fpThread) {
2115
	MMSYSTEM_CallTo16_long_l(lpMMThd->fpThread, lpMMThd->dwThreadPmt);
2116
    }
2117
    lpMMThd->dwStatus = 0x30;
2118
    TRACE("[30-%p]\n", lpMMThd->hThread);
2119
    while (lpMMThd->dwCounter) {
2120
	Sleep(1);
2121
	/* K32WOWYield16();*/
2122
    }
2123
    TRACE("[XX-%p]\n", lpMMThd->hThread);
2124
    /* paranoia */
2125
    lpMMThd->dwSignature = WINE_MMTHREAD_DELETED;
2126
    /* close lpMMThread->hVxD directIO */
2127 2128
    if (lpMMThd->hEvent)
	CloseHandle(lpMMThd->hEvent);
2129
    GlobalFree16(hndl);
2130
    TRACE("done\n");
2131 2132
}

2133
typedef	BOOL16 (WINAPI *MMCPLCALLBACK)(HWND, LPCSTR, LPCSTR, LPCSTR);
2134

2135 2136 2137
/**************************************************************************
 * 			mmShowMMCPLPropertySheet	[MMSYSTEM.1150]
 */
2138
BOOL16	WINAPI	mmShowMMCPLPropertySheet16(HWND hWnd, LPCSTR lpStrDevice,
2139
					   LPCSTR lpStrTab, LPCSTR lpStrTitle)
2140
{
2141 2142 2143
    HANDLE	hndl;
    BOOL16	ret = FALSE;

2144
    TRACE("(%p \"%s\" \"%s\" \"%s\")\n", hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2145 2146 2147

    hndl = LoadLibraryA("MMSYS.CPL");
    if (hndl != 0) {
2148
	MMCPLCALLBACK	fp = (MMCPLCALLBACK)GetProcAddress(hndl, "ShowMMCPLPropertySheet");
2149
	if (fp != NULL) {
2150 2151
	    DWORD	lc;
	    ReleaseThunkLock(&lc);
2152
	    ret = (fp)(hWnd, lpStrDevice, lpStrTab, lpStrTitle);
2153
	    RestoreThunkLock(lc);
2154
	}
2155
	FreeLibrary(hndl);
2156
    }
2157

2158
    return ret;
2159
}
2160 2161

/**************************************************************************
2162
 * 			StackEnter		[MMSYSTEM.32]
2163
 */
2164
void WINAPI StackEnter16(void)
2165 2166 2167 2168 2169 2170
{
#ifdef __i386__
    /* mmsystem.dll from Win 95 does only this: so does Wine */
    __asm__("stc");
#endif
}
2171 2172

/**************************************************************************
2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184
 * 			StackLeave		[MMSYSTEM.33]
 */
void WINAPI StackLeave16(void)
{
#ifdef __i386__
    /* mmsystem.dll from Win 95 does only this: so does Wine */
    __asm__("stc");
#endif
}

/**************************************************************************
 * 			WMMMidiRunOnce	 	[MMSYSTEM.8]
2185 2186 2187
 */
void WINAPI WMMMidiRunOnce16(void)
{
2188
    FIXME("(), stub!\n");
2189
}
2190

2191 2192 2193
/* ###################################################
 * #                    DRIVER                       #
 * ###################################################
2194
 */
2195

2196
/**************************************************************************
2197
 *				DRIVER_MapMsg32To16		[internal]
2198 2199 2200
 *
 * Map a 32 bit driver message to a 16 bit driver message.
 */
2201
static WINMM_MapType DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214
{
    WINMM_MapType       ret = WINMM_MAP_MSGERROR;

    switch (wMsg) {
    case DRV_LOAD:
    case DRV_ENABLE:
    case DRV_DISABLE:
    case DRV_FREE:
    case DRV_QUERYCONFIGURE:
    case DRV_REMOVE:
    case DRV_EXITSESSION:
    case DRV_EXITAPPLICATION:
    case DRV_POWER:
2215 2216 2217 2218 2219
    case DRV_CLOSE:	/* should be 0/0 */
    case DRV_OPEN:	/* pass through */
	/* lParam1 and lParam2 are not used */
	ret = WINMM_MAP_OK;
	break;
2220 2221
    case DRV_CONFIGURE:
    case DRV_INSTALL:
2222 2223 2224 2225
	/* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
	 * lParam2 is a pointer to DRVCONFIGINFO
	 */
	if (*lParam2) {
2226
            LPDRVCONFIGINFO16 dci16 = HeapAlloc( GetProcessHeap(), 0, sizeof(*dci16) );
2227
            LPDRVCONFIGINFO	dci32 = (LPDRVCONFIGINFO)(*lParam2);
2228

2229 2230
	    if (dci16) {
		LPSTR str1;
2231

2232
		dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
2233

2234
		if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCISectionName)) != NULL)
2235
                {
2236 2237 2238 2239 2240
		    dci16->lpszDCISectionName = MapLS( str1 );
		} else {
		    return WINMM_MAP_NOMEM;
		}
		if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCIAliasName)) != NULL)
2241
                {
2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254
		    dci16->lpszDCIAliasName = MapLS( str1 );
		} else {
		    return WINMM_MAP_NOMEM;
		}
	    } else {
		return WINMM_MAP_NOMEM;
	    }
	    *lParam2 = MapLS( dci16 );
	    ret = WINMM_MAP_OKMEM;
	} else {
	    ret = WINMM_MAP_OK;
	}
	break;
2255
    default:
2256 2257 2258 2259
	if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
	   FIXME("Unknown message 0x%04x\n", wMsg);
	}
	ret = WINMM_MAP_OK;
2260 2261 2262 2263 2264
    }
    return ret;
}

/**************************************************************************
2265
 *				DRIVER_UnMapMsg32To16		[internal]
2266 2267 2268
 *
 * UnMap a 32 bit driver message to a 16 bit driver message.
 */
2269
static WINMM_MapType DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
2270
{
2271
    WINMM_MapType	ret = WINMM_MAP_MSGERROR;
2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284

    switch (wMsg) {
    case DRV_LOAD:
    case DRV_ENABLE:
    case DRV_DISABLE:
    case DRV_FREE:
    case DRV_QUERYCONFIGURE:
    case DRV_REMOVE:
    case DRV_EXITSESSION:
    case DRV_EXITAPPLICATION:
    case DRV_POWER:
    case DRV_OPEN:
    case DRV_CLOSE:
2285 2286
	/* lParam1 and lParam2 are not used */
	break;
2287 2288
    case DRV_CONFIGURE:
    case DRV_INSTALL:
2289 2290 2291
	/* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
	if (lParam2) {
	    LPDRVCONFIGINFO16	dci16 = MapSL(lParam2);
2292 2293 2294 2295 2296 2297
            HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCISectionName) );
            HeapFree( GetProcessHeap(), 0, MapSL(dci16->lpszDCIAliasName) );
            UnMapLS( lParam2 );
            UnMapLS( dci16->lpszDCISectionName );
            UnMapLS( dci16->lpszDCIAliasName );
            HeapFree( GetProcessHeap(), 0, dci16 );
2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361
	}
	ret = WINMM_MAP_OK;
	break;
    default:
	if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
	    FIXME("Unknown message 0x%04x\n", wMsg);
	}
	ret = WINMM_MAP_OK;
    }
    return ret;
}

/**************************************************************************
 *				DRIVER_TryOpenDriver16		[internal]
 *
 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
 */
static	LPWINE_DRIVER	DRIVER_OpenDriver16(LPCSTR fn, LPCSTR sn, LPARAM lParam2)
{
    LPWINE_DRIVER 	lpDrv = NULL;
    LPCSTR		cause = 0;

    TRACE("(%s, %08lX);\n", debugstr_a(sn), lParam2);

    lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
    if (lpDrv == NULL) {cause = "OOM"; goto exit;}

    /* FIXME: shall we do some black magic here on sn ?
     *	drivers32 => drivers
     *	mci32 => mci
     * ...
     */
    lpDrv->d.d16.hDriver16 = OpenDriver16(fn, sn, lParam2);
    if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;}
    lpDrv->dwFlags = WINE_GDF_16BIT;

    TRACE("=> %p\n", lpDrv);
    return lpDrv;
 exit:
    HeapFree(GetProcessHeap(), 0, lpDrv);
    TRACE("Unable to load 16 bit module %s: %s\n", debugstr_a(fn), cause);
    return NULL;
}

/******************************************************************
 *		DRIVER_SendMessage16
 *
 *
 */
static LRESULT  DRIVER_SendMessage16(HDRVR16 hDrv16, UINT msg, 
                                     LPARAM lParam1, LPARAM lParam2)
{
    LRESULT             ret = 0;
    WINMM_MapType	map;

    TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
          hDrv16, msg, lParam1, lParam2);

    switch (map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) {
    case WINMM_MAP_OKMEM:
    case WINMM_MAP_OK:
        ret = SendDriverMessage16(hDrv16, msg, lParam1, lParam2);
        if (map == WINMM_MAP_OKMEM)
            DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
2362
    default:
2363
        break;
2364 2365 2366 2367
    }
    return ret;
}

2368 2369 2370 2371 2372 2373 2374 2375 2376 2377
/******************************************************************
 *		DRIVER_CloseDriver16
 *
 *
 */
static LRESULT DRIVER_CloseDriver16(HDRVR16 hDrv16, LPARAM lParam1, LPARAM lParam2)
{
    return CloseDriver16(hDrv16, lParam1, lParam2);
}

2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431
/**************************************************************************
 * 				DrvOpen	       		[MMSYSTEM.1100]
 */
HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
{
    return OpenDriver16(lpDriverName, lpSectionName, lParam);
}

/**************************************************************************
 * 				DrvClose       		[MMSYSTEM.1101]
 */
LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
{
    return CloseDriver16(hDrv, lParam1, lParam2);
}

/**************************************************************************
 * 				DrvSendMessage		[MMSYSTEM.1102]
 */
LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
				LPARAM lParam2)
{
    return SendDriverMessage16(hDrv, msg, lParam1, lParam2);
}

/**************************************************************************
 * 				DrvGetModuleHandle	[MMSYSTEM.1103]
 */
HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
{
    return GetDriverModuleHandle16(hDrv);
}

/**************************************************************************
 * 				DrvDefDriverProc	[MMSYSTEM.1104]
 */
LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg,
				  DWORD dwParam1, DWORD dwParam2)
{
    return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
}

/**************************************************************************
 * 				DriverProc			[MMSYSTEM.6]
 */
LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
			    DWORD dwParam1, DWORD dwParam2)
{
    TRACE("dwDevID=%08lx hDrv=%04x wMsg=%04x dwParam1=%08lx dwParam2=%08lx\n",
	  dwDevID, hDrv, wMsg, dwParam1, dwParam2);

    return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
}

2432 2433 2434 2435 2436
/* ###################################################
 * #                     TIME                        #
 * ###################################################
 */

2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464
/******************************************************************
 *		MMSYSTEM_MMTIME32to16
 *
 *
 */
void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32)
{
    mmt16->wType = mmt32->wType;
    /* layout of rest is the same for 32/16,
     * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
     */
    memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u));
}

/******************************************************************
 *		MMSYSTEM_MMTIME16to32
 *
 *
 */
void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16)
{
    mmt32->wType = mmt16->wType;
    /* layout of rest is the same for 32/16,
     * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
     */
    memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u));
}

2465 2466 2467 2468 2469 2470 2471 2472 2473
/**************************************************************************
 * 				timeGetSystemTime	[MMSYSTEM.601]
 */
MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
{
    TRACE("(%p, %u);\n", lpTime, wSize);

    if (wSize >= sizeof(*lpTime)) {
	lpTime->wType = TIME_MS;
2474 2475
	TIME_MMTimeStart();
	lpTime->u.ms = WINMM_IData->mmSysTimeMS;
2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491

	TRACE("=> %lu\n", lpTime->u.ms);
    }

    return 0;
}

/**************************************************************************
 * 				timeSetEvent		[MMSYSTEM.602]
 */
MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16 lpFunc,
				 DWORD dwUser, UINT16 wFlags)
{
    if (wFlags & WINE_TIMER_IS32)
	WARN("Unknown windows flag... wine internally used.. ooch\n");

2492 2493
    return TIME_SetEventInternal(wDelay, wResol, (FARPROC16)lpFunc,
                                 dwUser, wFlags & ~WINE_TIMER_IS32);
2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551
}

/**************************************************************************
 * 				timeKillEvent		[MMSYSTEM.603]
 */
MMRESULT16 WINAPI timeKillEvent16(UINT16 wID)
{
    return timeKillEvent(wID);
}

/**************************************************************************
 * 				timeGetDevCaps		[MMSYSTEM.604]
 */
MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize)
{
    TIMECAPS    caps;
    MMRESULT    ret;

    TRACE("(%p, %u) !\n", lpCaps, wSize);

    ret = timeGetDevCaps(&caps, sizeof(caps));
    lpCaps->wPeriodMin = caps.wPeriodMin;
    lpCaps->wPeriodMax = caps.wPeriodMax;
    return 0;
}

/**************************************************************************
 * 				timeBeginPeriod	[MMSYSTEM.605]
 */
MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod)
{
    TRACE("(%u) !\n", wPeriod);

    return timeBeginPeriod(wPeriod);
}

/**************************************************************************
 * 				timeEndPeriod		[MMSYSTEM.606]
 */
MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod)
{
    TRACE("(%u) !\n", wPeriod);

    return timeEndPeriod(wPeriod);
}

/**************************************************************************
 * 				mciSendString			[MMSYSTEM.702]
 */
DWORD WINAPI mciSendString16(LPCSTR lpstrCommand, LPSTR lpstrRet,
			     UINT16 uRetLen, HWND16 hwndCallback)
{
    return mciSendStringA(lpstrCommand, lpstrRet, uRetLen, HWND_32(hwndCallback));
}

/**************************************************************************
 *                    	mciLoadCommandResource			[MMSYSTEM.705]
 */
2552
UINT16 WINAPI mciLoadCommandResource16(HINSTANCE16 hInst, LPCSTR resname, UINT16 type)
2553 2554
{
    LPCWSTR     ptr = HEAP_strdupAtoW(GetProcessHeap(), 0, resname);
2555
    UINT        ret = mciLoadCommandResource(HINSTANCE_32(hInst), ptr, type);
2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568
    HeapFree(GetProcessHeap(), 0, (LPWSTR)ptr);
    return ret;
}

/**************************************************************************
 *                    	mciFreeCommandResource			[MMSYSTEM.713]
 */
BOOL16 WINAPI mciFreeCommandResource16(UINT16 uTable)
{
    TRACE("(%04x)!\n", uTable);

    return mciFreeCommandResource(uTable);
}
2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630

/* ###################################################
 * #                     MMIO                        #
 * ###################################################
 */

/****************************************************************
 *       		MMIO_Map32To16			[INTERNAL]
 */
static LRESULT	MMIO_Map32To16(DWORD wMsg, LPARAM* lp1, LPARAM* lp2)
{
    switch (wMsg) {
    case MMIOM_CLOSE:
    case MMIOM_SEEK:
	/* nothing to do */
	break;
    case MMIOM_OPEN:
    case MMIOM_READ:
    case MMIOM_WRITE:
    case MMIOM_WRITEFLUSH:
        *lp1 = MapLS( (void *)*lp1 );
	break;
    case MMIOM_RENAME:
        *lp1 = MapLS( (void *)*lp1 );
        *lp2 = MapLS( (void *)*lp2 );
        break;
    default:
        if (wMsg < MMIOM_USER)
            TRACE("Not a mappable message (%ld)\n", wMsg);
    }
    return MMSYSERR_NOERROR;
}

/****************************************************************
 *       	MMIO_UnMap32To16 			[INTERNAL]
 */
static LRESULT	MMIO_UnMap32To16(DWORD wMsg, LPARAM lParam1, LPARAM lParam2,
				 LPARAM lp1, LPARAM lp2)
{
    switch (wMsg) {
    case MMIOM_CLOSE:
    case MMIOM_SEEK:
	/* nothing to do */
	break;
    case MMIOM_OPEN:
    case MMIOM_READ:
    case MMIOM_WRITE:
    case MMIOM_WRITEFLUSH:
        UnMapLS( lp1 );
	break;
    case MMIOM_RENAME:
        UnMapLS( lp1 );
        UnMapLS( lp2 );
	break;
    default:
        if (wMsg < MMIOM_USER)
            TRACE("Not a mappable message (%ld)\n", wMsg);
    }
    return MMSYSERR_NOERROR;
}

/******************************************************************
Eric Pouech's avatar
Eric Pouech committed
2631
 *		MMIO_Callback16
2632 2633 2634
 *
 *
 */
Eric Pouech's avatar
Eric Pouech committed
2635 2636
static LRESULT MMIO_Callback16(SEGPTR cb16, LPMMIOINFO lpmmioinfo, UINT uMessage,
                               LPARAM lParam1, LPARAM lParam2)
2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675
{
    LRESULT 		result;
    MMIOINFO16          mmioInfo16;
    SEGPTR		segmmioInfo16;
    LPARAM		lp1 = lParam1, lp2 = lParam2;

    memset(&mmioInfo16, 0, sizeof(MMIOINFO16));
    mmioInfo16.lDiskOffset = lpmmioinfo->lDiskOffset;
    mmioInfo16.adwInfo[0]  = lpmmioinfo->adwInfo[0];
    mmioInfo16.adwInfo[1]  = lpmmioinfo->adwInfo[1];
    mmioInfo16.adwInfo[2]  = lpmmioinfo->adwInfo[2];
    mmioInfo16.adwInfo[3]  = lpmmioinfo->adwInfo[3];
    /* map (lParam1, lParam2) into (lp1, lp2) 32=>16 */
    if ((result = MMIO_Map32To16(uMessage, &lp1, &lp2)) != MMSYSERR_NOERROR)
        return result;
    
    segmmioInfo16 = MapLS(&mmioInfo16);
    
    result = MMSYSTEM_CallTo16_long_lwll((LPMMIOPROC16)cb16, segmmioInfo16, uMessage, lp1, lp2);
    UnMapLS(segmmioInfo16);
    MMIO_UnMap32To16(uMessage, lParam1, lParam2, lp1, lp2);

    lpmmioinfo->lDiskOffset = mmioInfo16.lDiskOffset;
    lpmmioinfo->adwInfo[0]  = mmioInfo16.adwInfo[0];
    lpmmioinfo->adwInfo[1]  = mmioInfo16.adwInfo[1];
    lpmmioinfo->adwInfo[2]  = mmioInfo16.adwInfo[2];
    lpmmioinfo->adwInfo[3]  = mmioInfo16.adwInfo[3];

    return result;
}

/******************************************************************
 *             MMIO_ResetSegmentedData
 *
 */
static LRESULT     MMIO_SetSegmentedBuffer(HMMIO hmmio, SEGPTR ptr)
{
    LPWINE_MMIO		wm;

2676
    if ((wm = MMIO_Get(hmmio)) == NULL)
2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699
	return MMSYSERR_INVALHANDLE;
    wm->segBuffer16 = ptr;
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mmioOpen       		[MMSYSTEM.1210]
 */
HMMIO16 WINAPI mmioOpen16(LPSTR szFileName, MMIOINFO16* lpmmioinfo16,
			  DWORD dwOpenFlags)
{
    HMMIO 	ret;

    if (lpmmioinfo16) {
	MMIOINFO	mmioinfo;

	memset(&mmioinfo, 0, sizeof(mmioinfo));

	mmioinfo.dwFlags     = lpmmioinfo16->dwFlags;
	mmioinfo.fccIOProc   = lpmmioinfo16->fccIOProc;
	mmioinfo.pIOProc     = (LPMMIOPROC)lpmmioinfo16->pIOProc;
	mmioinfo.cchBuffer   = lpmmioinfo16->cchBuffer;
	mmioinfo.pchBuffer   = MapSL((DWORD)lpmmioinfo16->pchBuffer);
Eric Pouech's avatar
Eric Pouech committed
2700 2701 2702
        mmioinfo.adwInfo[0]  = lpmmioinfo16->adwInfo[0];
        /* if we don't have a file name, it's likely a passed open file descriptor */
        if (!szFileName) 
2703
            mmioinfo.adwInfo[0] = (DWORD)DosFileHandleToWin32Handle(mmioinfo.adwInfo[0]);
2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761
	mmioinfo.adwInfo[1]  = lpmmioinfo16->adwInfo[1];
	mmioinfo.adwInfo[2]  = lpmmioinfo16->adwInfo[2];
	mmioinfo.adwInfo[3]  = lpmmioinfo16->adwInfo[3];

	ret = MMIO_Open(szFileName, &mmioinfo, dwOpenFlags, MMIO_PROC_16);
        MMIO_SetSegmentedBuffer(mmioinfo.hmmio, (SEGPTR)lpmmioinfo16->pchBuffer);

	lpmmioinfo16->wErrorRet = mmioinfo.wErrorRet;
        lpmmioinfo16->hmmio     = HMMIO_16(mmioinfo.hmmio);
    } else {
	ret = MMIO_Open(szFileName, NULL, dwOpenFlags, MMIO_PROC_32A);
    }
    return HMMIO_16(ret);
}

/**************************************************************************
 * 				mmioClose      		[MMSYSTEM.1211]
 */
MMRESULT16 WINAPI mmioClose16(HMMIO16 hmmio, UINT16 uFlags)
{
    return mmioClose(HMMIO_32(hmmio), uFlags);
}

/**************************************************************************
 * 				mmioRead	       	[MMSYSTEM.1212]
 */
LONG WINAPI mmioRead16(HMMIO16 hmmio, HPSTR pch, LONG cch)
{
    return mmioRead(HMMIO_32(hmmio), pch, cch);
}

/**************************************************************************
 * 				mmioWrite      		[MMSYSTEM.1213]
 */
LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
{
    return mmioWrite(HMMIO_32(hmmio),pch,cch);
}

/**************************************************************************
 * 				mmioSeek       		[MMSYSTEM.1214]
 */
LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
{
    return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin);
}

/**************************************************************************
 * 				mmioGetInfo	       	[MMSYSTEM.1215]
 */
MMRESULT16 WINAPI mmioGetInfo16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
{
    MMIOINFO            mmioinfo;
    MMRESULT            ret;
    LPWINE_MMIO		wm;

    TRACE("(0x%04x,%p,0x%08x)\n", hmmio, lpmmioinfo, uFlags);

2762
    if ((wm = MMIO_Get(HMMIO_32(hmmio))) == NULL)
2763 2764 2765 2766 2767 2768 2769 2770 2771 2772
	return MMSYSERR_INVALHANDLE;

    ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
    if (ret != MMSYSERR_NOERROR) return ret;

    lpmmioinfo->dwFlags     = mmioinfo.dwFlags;
    lpmmioinfo->fccIOProc   = mmioinfo.fccIOProc;
    lpmmioinfo->pIOProc     = (wm->ioProc->type == MMIO_PROC_16) ?
        (LPMMIOPROC16)wm->ioProc->pIOProc : NULL;
    lpmmioinfo->wErrorRet   = mmioinfo.wErrorRet;
2773
    lpmmioinfo->hTask       = HTASK_16(mmioinfo.hTask);
2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970
    lpmmioinfo->cchBuffer   = mmioinfo.cchBuffer;
    lpmmioinfo->pchBuffer   = (void*)wm->segBuffer16;
    lpmmioinfo->pchNext     = (void*)(wm->segBuffer16 + (mmioinfo.pchNext - mmioinfo.pchBuffer));
    lpmmioinfo->pchEndRead  = (void*)(wm->segBuffer16 + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
    lpmmioinfo->pchEndWrite = (void*)(wm->segBuffer16 + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
    lpmmioinfo->lBufOffset  = mmioinfo.lBufOffset;
    lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
    lpmmioinfo->adwInfo[0]  = mmioinfo.adwInfo[0];
    lpmmioinfo->adwInfo[1]  = mmioinfo.adwInfo[1];
    lpmmioinfo->adwInfo[2]  = mmioinfo.adwInfo[2];
    lpmmioinfo->adwInfo[3]  = mmioinfo.adwInfo[3];
    lpmmioinfo->dwReserved1 = 0;
    lpmmioinfo->dwReserved2 = 0;
    lpmmioinfo->hmmio = HMMIO_16(mmioinfo.hmmio);

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mmioSetInfo  		[MMSYSTEM.1216]
 */
MMRESULT16 WINAPI mmioSetInfo16(HMMIO16 hmmio, const MMIOINFO16* lpmmioinfo, UINT16 uFlags)
{
    MMIOINFO            mmioinfo;
    MMRESULT            ret;

    TRACE("(0x%04x,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);

    ret = mmioGetInfo(HMMIO_32(hmmio), &mmioinfo, 0);
    if (ret != MMSYSERR_NOERROR) return ret;

    /* check if seg and lin buffers are the same */
    if (mmioinfo.cchBuffer != lpmmioinfo->cchBuffer  ||
        mmioinfo.pchBuffer != MapSL((DWORD)lpmmioinfo->pchBuffer)) 
	return MMSYSERR_INVALPARAM;

    /* check pointers coherence */
    if (lpmmioinfo->pchNext < lpmmioinfo->pchBuffer ||
	lpmmioinfo->pchNext > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
	lpmmioinfo->pchEndRead < lpmmioinfo->pchBuffer ||
	lpmmioinfo->pchEndRead > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer ||
	lpmmioinfo->pchEndWrite < lpmmioinfo->pchBuffer ||
	lpmmioinfo->pchEndWrite > lpmmioinfo->pchBuffer + lpmmioinfo->cchBuffer)
	return MMSYSERR_INVALPARAM;

    mmioinfo.pchNext     = mmioinfo.pchBuffer + (lpmmioinfo->pchNext     - lpmmioinfo->pchBuffer);
    mmioinfo.pchEndRead  = mmioinfo.pchBuffer + (lpmmioinfo->pchEndRead  - lpmmioinfo->pchBuffer);
    mmioinfo.pchEndWrite = mmioinfo.pchBuffer + (lpmmioinfo->pchEndWrite - lpmmioinfo->pchBuffer);

    return mmioSetInfo(HMMIO_32(hmmio), &mmioinfo, uFlags);
}

/**************************************************************************
 * 				mmioSetBuffer		[MMSYSTEM.1217]
 */
MMRESULT16 WINAPI mmioSetBuffer16(HMMIO16 hmmio, LPSTR pchBuffer,
                                  LONG cchBuffer, UINT16 uFlags)
{
    MMRESULT    ret = mmioSetBuffer(HMMIO_32(hmmio), MapSL((DWORD)pchBuffer), 
                                    cchBuffer, uFlags);

    if (ret == MMSYSERR_NOERROR)
        MMIO_SetSegmentedBuffer(HMMIO_32(hmmio), (DWORD)pchBuffer);
    return ret;
}

/**************************************************************************
 * 				mmioFlush      		[MMSYSTEM.1218]
 */
MMRESULT16 WINAPI mmioFlush16(HMMIO16 hmmio, UINT16 uFlags)
{
    return mmioFlush(HMMIO_32(hmmio), uFlags);
}

/***********************************************************************
 * 				mmioAdvance    		[MMSYSTEM.1219]
 */
MMRESULT16 WINAPI mmioAdvance16(HMMIO16 hmmio, MMIOINFO16* lpmmioinfo, UINT16 uFlags)
{
    MMIOINFO    mmioinfo;
    LRESULT     ret;

    /* WARNING: this heavily relies on mmioAdvance implementation (for choosing which
     * fields to init
     */
    if (lpmmioinfo)
    {
        mmioinfo.pchBuffer = MapSL((DWORD)lpmmioinfo->pchBuffer);
        mmioinfo.pchNext = MapSL((DWORD)lpmmioinfo->pchNext);
        mmioinfo.dwFlags = lpmmioinfo->dwFlags;
        mmioinfo.lBufOffset = lpmmioinfo->lBufOffset;
        ret = mmioAdvance(HMMIO_32(hmmio), &mmioinfo, uFlags);
    }
    else
        ret = mmioAdvance(HMMIO_32(hmmio), NULL, uFlags);
        
    if (ret != MMSYSERR_NOERROR) return ret;

    if (lpmmioinfo)
    {
        lpmmioinfo->dwFlags = mmioinfo.dwFlags;
        lpmmioinfo->pchNext     = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchNext - mmioinfo.pchBuffer));
        lpmmioinfo->pchEndRead  = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndRead - mmioinfo.pchBuffer));
        lpmmioinfo->pchEndWrite = (void*)(lpmmioinfo->pchBuffer + (mmioinfo.pchEndWrite - mmioinfo.pchBuffer));
        lpmmioinfo->lBufOffset  = mmioinfo.lBufOffset;
        lpmmioinfo->lDiskOffset = mmioinfo.lDiskOffset;
    }

    return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				mmioStringToFOURCC	[MMSYSTEM.1220]
 */
FOURCC WINAPI mmioStringToFOURCC16(LPCSTR sz, UINT16 uFlags)
{
    return mmioStringToFOURCCA(sz, uFlags);
}

/**************************************************************************
 *              mmioInstallIOProc    [MMSYSTEM.1221]
 */
LPMMIOPROC16 WINAPI mmioInstallIOProc16(FOURCC fccIOProc, LPMMIOPROC16 pIOProc,
                                        DWORD dwFlags)
{
    return (LPMMIOPROC16)MMIO_InstallIOProc(fccIOProc, (LPMMIOPROC)pIOProc,
                                            dwFlags, MMIO_PROC_16);
}

/**************************************************************************
 * 				mmioSendMessage	[MMSYSTEM.1222]
 */
LRESULT WINAPI mmioSendMessage16(HMMIO16 hmmio, UINT16 uMessage,
				 LPARAM lParam1, LPARAM lParam2)
{
    return MMIO_SendMessage(HMMIO_32(hmmio), uMessage, 
                            lParam1, lParam2, MMIO_PROC_16);
}

/**************************************************************************
 * 				mmioDescend	       	[MMSYSTEM.1223]
 */
MMRESULT16 WINAPI mmioDescend16(HMMIO16 hmmio, LPMMCKINFO lpck,
                                const MMCKINFO* lpckParent, UINT16 uFlags)
{
    return mmioDescend(HMMIO_32(hmmio), lpck, lpckParent, uFlags);
}

/**************************************************************************
 * 				mmioAscend     		[MMSYSTEM.1224]
 */
MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
{
    return mmioAscend(HMMIO_32(hmmio),lpck,uFlags);
}

/**************************************************************************
 * 				mmioCreateChunk		[MMSYSTEM.1225]
 */
MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags)
{
    return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags);
}

/**************************************************************************
 * 				mmioRename     		[MMSYSTEM.1226]
 */
MMRESULT16 WINAPI mmioRename16(LPCSTR szFileName, LPCSTR szNewFileName,
                               MMIOINFO16* lpmmioinfo, DWORD dwRenameFlags)
{
    BOOL        inst = FALSE;
    MMRESULT    ret;
    MMIOINFO    mmioinfo;

    if (lpmmioinfo != NULL && lpmmioinfo->pIOProc != NULL && 
        lpmmioinfo->fccIOProc == 0) {
        FIXME("Can't handle this case yet\n");
        return MMSYSERR_ERROR;
    }
     
    /* this is a bit hacky, but it'll work if we get a fourCC code or nothing.
     * but a non installed ioproc without a fourcc won't do
     */
    if (lpmmioinfo && lpmmioinfo->fccIOProc && lpmmioinfo->pIOProc) {
        MMIO_InstallIOProc(lpmmioinfo->fccIOProc, (LPMMIOPROC)lpmmioinfo->pIOProc,
                           MMIO_INSTALLPROC, MMIO_PROC_16);
        inst = TRUE;
    }
    memset(&mmioinfo, 0, sizeof(mmioinfo));
    mmioinfo.fccIOProc = lpmmioinfo->fccIOProc;
    ret = mmioRenameA(szFileName, szNewFileName, &mmioinfo, dwRenameFlags);
    if (inst) {
        MMIO_InstallIOProc(lpmmioinfo->fccIOProc, NULL,
                           MMIO_REMOVEPROC, MMIO_PROC_16);
    }
    return ret;
}
2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097

/* ###################################################
 * #                     JOYSTICK                    #
 * ###################################################
 */

/**************************************************************************
 * 				joyGetNumDevs		[MMSYSTEM.101]
 */
UINT16 WINAPI joyGetNumDevs16(void)
{
    return joyGetNumDevs();
}

/**************************************************************************
 * 				joyGetDevCaps		[MMSYSTEM.102]
 */
MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize)
{
    JOYCAPSA	jca;
    MMRESULT	ret = joyGetDevCapsA(wID, &jca, sizeof(jca));

    if (ret != JOYERR_NOERROR) return ret;
    lpCaps->wMid = jca.wMid;
    lpCaps->wPid = jca.wPid;
    strcpy(lpCaps->szPname, jca.szPname);
    lpCaps->wXmin = jca.wXmin;
    lpCaps->wXmax = jca.wXmax;
    lpCaps->wYmin = jca.wYmin;
    lpCaps->wYmax = jca.wYmax;
    lpCaps->wZmin = jca.wZmin;
    lpCaps->wZmax = jca.wZmax;
    lpCaps->wNumButtons = jca.wNumButtons;
    lpCaps->wPeriodMin = jca.wPeriodMin;
    lpCaps->wPeriodMax = jca.wPeriodMax;

    if (wSize >= sizeof(JOYCAPS16)) { /* Win95 extensions ? */
	lpCaps->wRmin = jca.wRmin;
	lpCaps->wRmax = jca.wRmax;
	lpCaps->wUmin = jca.wUmin;
	lpCaps->wUmax = jca.wUmax;
	lpCaps->wVmin = jca.wVmin;
	lpCaps->wVmax = jca.wVmax;
	lpCaps->wCaps = jca.wCaps;
	lpCaps->wMaxAxes = jca.wMaxAxes;
	lpCaps->wNumAxes = jca.wNumAxes;
	lpCaps->wMaxButtons = jca.wMaxButtons;
	strcpy(lpCaps->szRegKey, jca.szRegKey);
	strcpy(lpCaps->szOEMVxD, jca.szOEMVxD);
    }

    return ret;
}

/**************************************************************************
 *                              joyGetPosEx           [MMSYSTEM.110]
 */
MMRESULT16 WINAPI joyGetPosEx16(UINT16 wID, LPJOYINFOEX lpInfo)
{
    return joyGetPosEx(wID, lpInfo);
}

/**************************************************************************
 * 				joyGetPos	       	[MMSYSTEM.103]
 */
MMRESULT16 WINAPI joyGetPos16(UINT16 wID, LPJOYINFO16 lpInfo)
{
    JOYINFO	ji;
    MMRESULT	ret;

    TRACE("(%d, %p);\n", wID, lpInfo);

    if ((ret = joyGetPos(wID, &ji)) == JOYERR_NOERROR) {
	lpInfo->wXpos = ji.wXpos;
	lpInfo->wYpos = ji.wYpos;
	lpInfo->wZpos = ji.wZpos;
	lpInfo->wButtons = ji.wButtons;
    }
    return ret;
}

/**************************************************************************
 * 				joyGetThreshold		[MMSYSTEM.104]
 */
MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold)
{
    UINT        t;
    MMRESULT    ret;

    ret = joyGetThreshold(wID, &t);
    if (ret == JOYERR_NOERROR)
        *lpThreshold = t;
    return ret;
}

/**************************************************************************
 * 				joyReleaseCapture	[MMSYSTEM.105]
 */
MMRESULT16 WINAPI joyReleaseCapture16(UINT16 wID)
{
    return joyReleaseCapture(wID);
}

/**************************************************************************
 * 				joySetCapture		[MMSYSTEM.106]
 */
MMRESULT16 WINAPI joySetCapture16(HWND16 hWnd, UINT16 wID, UINT16 wPeriod, BOOL16 bChanged)
{
    return joySetCapture16(hWnd, wID, wPeriod, bChanged);
}

/**************************************************************************
 * 				joySetThreshold		[MMSYSTEM.107]
 */
MMRESULT16 WINAPI joySetThreshold16(UINT16 wID, UINT16 wThreshold)
{
    return joySetThreshold16(wID,wThreshold);
}

/**************************************************************************
 * 				joySetCalibration	[MMSYSTEM.109]
 */
MMRESULT16 WINAPI joySetCalibration16(UINT16 wID)
{
    FIXME("(%04X): stub.\n", wID);
    return JOYERR_NOCANDO;
}