lpszName of NULL is handled (removes some warnings).
[wine/multimedia.git] / multimedia / mmsystem.c
blobc1711468474ca8acd1a1ece57f38f02809cbf4e1
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * MMSYTEM functions
6 * Copyright 1993 Martin Ayotte
7 */
9 /*
10 * Eric POUECH :
11 * 98/9 added support for Win32 MCI
14 /* FIXME: I think there are some segmented vs. linear pointer weirdnesses
15 * and long term pointers to 16 bit space in here
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <sys/ioctl.h>
24 #include "windows.h"
25 #include "win.h"
26 #include "heap.h"
27 #include "ldt.h"
28 #include "user.h"
29 #include "driver.h"
30 #include "file.h"
31 #include "mmsystem.h"
32 #include "multimedia.h"
33 #include "debug.h"
34 #include "xmalloc.h"
35 #include "callback.h"
36 #include "module.h"
37 #include "selectors.h"
39 int mciInstalledCount;
40 int mciInstalledListLen;
41 LPSTR lpmciInstallNames = NULL;
43 struct WINE_MCIDRIVER mciDrv[MAXMCIDRIVERS];
45 UINT16 WINAPI midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
46 static UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
47 LONG WINAPI DrvDefDriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
48 DWORD dwParam1, DWORD dwParam2);
50 #define mciGetDrv(wDevID) (&mciDrv[MMSYSTEM_DevIDToIndex(wDevID)])
51 #define mciGetOpenDrv(wDevID) (&(mciGetDrv(wDevID)->mop))
53 /* The wDevID's returned by wine were originally in the range
54 * 0 - (MAXMCIDRIVERS - 1) and used directly as array indices.
55 * Unfortunately, ms-windows uses wDevID of zero to indicate
56 * errors. Now, multimedia drivers must pass the wDevID through
57 * MMSYSTEM_DevIDToIndex to get an index in that range. An
58 * arbitrary value, MMSYSTEM_MAGIC is added to the wDevID seen
59 * by the windows programs.
62 #define MMSYSTEM_MAGIC 0x0F00
64 /**************************************************************************
65 * MMSYSTEM_DevIDToIndex [internal]
67 int MMSYSTEM_DevIDToIndex(UINT16 wDevID)
69 return wDevID - MMSYSTEM_MAGIC;
72 /**************************************************************************
73 * MMSYSTEM_FirstDevId [internal]
75 UINT16 MMSYSTEM_FirstDevID(void)
77 return MMSYSTEM_MAGIC;
80 /**************************************************************************
81 * MMSYSTEM_NextDevId [internal]
83 UINT16 MMSYSTEM_NextDevID(UINT16 wDevID)
85 return wDevID + 1;
88 /**************************************************************************
89 * MMSYSTEM_DevIDValid [internal]
91 BOOL32 MMSYSTEM_DevIDValid(UINT16 wDevID)
93 return wDevID >= 0x0F00 && wDevID < (0x0F00 + MAXMCIDRIVERS);
96 /**************************************************************************
97 * MMSYSTEM_WEP [MMSYSTEM.1]
99 int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
100 WORD cbHeapSize, LPSTR lpCmdLine)
102 FIXME(mmsys, "STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
103 return(TRUE);
106 static void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16,LPMMTIME32 mmt32)
108 mmt16->wType = mmt32->wType;
109 /* layout of rest is the same for 32/16 */
110 memcpy(&(mmt32->u),&(mmt16->u),sizeof(mmt16->u));
113 static void MMSYSTEM_MMTIME16to32(LPMMTIME32 mmt32,LPMMTIME16 mmt16)
115 mmt32->wType = mmt16->wType;
116 /* layout of rest is the same for 32/16,
117 * Note: mmt16->u is 2 bytes smaller than mmt32->u
119 memcpy(&(mmt16->u),&(mmt32->u),sizeof(mmt16->u));
122 static HANDLE32 PlaySound_hThread = 0;
123 static HANDLE32 PlaySound_hPlayEvent = 0;
124 static HANDLE32 PlaySound_hReadyEvent = 0;
125 static HANDLE32 PlaySound_hMiddleEvent = 0;
126 static BOOL32 PlaySound_Result = FALSE;
127 static int PlaySound_Stop = FALSE;
128 static int PlaySound_Playing = FALSE;
130 static LPCSTR PlaySound_pszSound = NULL;
131 static HMODULE32 PlaySound_hmod = 0;
132 static DWORD PlaySound_fdwSound = 0;
133 static int PlaySound_Loop = FALSE;
134 static int PlaySound_SearchMode = 0; /* 1 - sndPlaySound search order
135 2 - PlaySound order */
137 static HMMIO16 get_mmioFromFile(LPCSTR lpszName)
139 return mmioOpen16((LPSTR)lpszName, NULL,
140 MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
143 static HMMIO16 get_mmioFromProfile(UINT32 uFlags, LPCSTR lpszName)
145 char str[128];
146 LPSTR ptr;
147 HMMIO16 hmmio;
149 TRACE(mmsys, "searching in SystemSound List !\n");
150 GetProfileString32A("Sounds", (LPSTR)lpszName, "", str, sizeof(str));
151 if (strlen(str) == 0) {
152 if (uFlags & SND_NODEFAULT) return 0;
153 GetProfileString32A("Sounds", "Default", "", str, sizeof(str));
154 if (strlen(str) == 0) return 0;
156 if ( (ptr = (LPSTR)strchr(str, ',')) != NULL) *ptr = '\0';
157 hmmio = get_mmioFromFile(str);
158 if (hmmio == 0) {
159 WARN(mmsys, "can't find SystemSound='%s' !\n", str);
160 return 0;
162 return hmmio;
165 static BOOL16 WINAPI proc_PlaySound(LPCSTR lpszSoundName, UINT32 uFlags)
167 BOOL16 bRet = FALSE;
168 HMMIO16 hmmio;
169 MMCKINFO ckMainRIFF;
171 TRACE(mmsys, "SoundName='%s' uFlags=%04X !\n", lpszSoundName, uFlags);
172 if (lpszSoundName == NULL) {
173 TRACE(mmsys, "Stop !\n");
174 return FALSE;
176 if (uFlags & SND_MEMORY) {
177 MMIOINFO16 mminfo;
178 memset(&mminfo, 0, sizeof(mminfo));
179 mminfo.fccIOProc = FOURCC_MEM;
180 mminfo.pchBuffer = (LPSTR)lpszSoundName;
181 mminfo.cchBuffer = -1;
182 TRACE(mmsys, "Memory sound %p\n",lpszSoundName);
183 hmmio = mmioOpen16(NULL, &mminfo, MMIO_READ);
184 } else {
185 hmmio = 0;
186 if (uFlags & SND_ALIAS)
187 if ((hmmio=get_mmioFromProfile(uFlags, lpszSoundName)) == 0)
188 return FALSE;
190 if (uFlags & SND_FILENAME)
191 if ((hmmio=get_mmioFromFile(lpszSoundName)) == 0) return FALSE;
193 if (PlaySound_SearchMode == 1) {
194 PlaySound_SearchMode = 0;
195 if ((hmmio=get_mmioFromFile(lpszSoundName)) == 0)
196 if ((hmmio=get_mmioFromProfile(uFlags, lpszSoundName)) == 0)
197 return FALSE;
200 if (PlaySound_SearchMode == 2) {
201 PlaySound_SearchMode = 0;
202 if ((hmmio=get_mmioFromProfile(uFlags | SND_NODEFAULT, lpszSoundName)) == 0)
203 if ((hmmio=get_mmioFromFile(lpszSoundName)) == 0)
204 if ((hmmio=get_mmioFromProfile(uFlags, lpszSoundName)) == 0) return FALSE;
208 if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0) == 0)
209 do {
210 TRACE(mmsys, "ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
211 (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
213 if ((ckMainRIFF.ckid == FOURCC_RIFF) &&
214 (ckMainRIFF.fccType == mmioFOURCC('W', 'A', 'V', 'E'))) {
215 MMCKINFO mmckInfo;
217 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
219 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0) {
220 PCMWAVEFORMAT pcmWaveFormat;
222 TRACE(mmsys, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
223 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
225 if (mmioRead32(hmmio,(HPSTR)&pcmWaveFormat,
226 (long) sizeof(PCMWAVEFORMAT)) == (long) sizeof(PCMWAVEFORMAT)) {
227 TRACE(mmsys, "wFormatTag=%04X !\n", pcmWaveFormat.wf.wFormatTag);
228 TRACE(mmsys, "nChannels=%d \n", pcmWaveFormat.wf.nChannels);
229 TRACE(mmsys, "nSamplesPerSec=%ld\n", pcmWaveFormat.wf.nSamplesPerSec);
230 TRACE(mmsys, "nAvgBytesPerSec=%ld\n", pcmWaveFormat.wf.nAvgBytesPerSec);
231 TRACE(mmsys, "nBlockAlign=%d \n", pcmWaveFormat.wf.nBlockAlign);
232 TRACE(mmsys, "wBitsPerSample=%u !\n", pcmWaveFormat.wBitsPerSample);
234 mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
235 if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0) {
236 WAVEOPENDESC waveDesc;
237 DWORD dwRet;
239 TRACE(mmsys, "Chunk Found \
240 ckid=%.4s fccType=%.4s cksize=%08lX \n", (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
242 pcmWaveFormat.wf.nAvgBytesPerSec = pcmWaveFormat.wf.nSamplesPerSec *
243 pcmWaveFormat.wf.nBlockAlign;
244 waveDesc.hWave = 0;
245 waveDesc.lpFormat = (LPWAVEFORMAT)&pcmWaveFormat;
247 dwRet = wodMessage( 0, WODM_OPEN, 0, (DWORD)&waveDesc, CALLBACK_NULL);
248 if (dwRet == MMSYSERR_NOERROR) {
249 WAVEHDR waveHdr;
250 HGLOBAL16 hData;
251 INT32 count, bufsize, left = mmckInfo.cksize;
253 bufsize = 64000;
254 hData = GlobalAlloc16(GMEM_MOVEABLE, bufsize);
255 waveHdr.lpData = (LPSTR)GlobalLock16(hData);
256 waveHdr.dwBufferLength = bufsize;
257 waveHdr.dwUser = 0L;
258 waveHdr.dwFlags = 0L;
259 waveHdr.dwLoops = 0L;
261 dwRet = wodMessage(0,WODM_PREPARE,0,(DWORD)&waveHdr,sizeof(WAVEHDR));
262 if (dwRet == MMSYSERR_NOERROR) {
263 while (left) {
264 if (PlaySound_Stop) {
265 PlaySound_Stop = FALSE;
266 PlaySound_Loop = FALSE;
267 break;
269 if (bufsize > left) bufsize = left;
270 count = mmioRead32(hmmio,waveHdr.lpData,bufsize);
271 if (count < 1) break;
272 left -= count;
273 waveHdr.dwBufferLength = count;
274 /* waveHdr.dwBytesRecorded = count; */
275 /* FIXME: doesn't expect async ops */
276 wodMessage( 0, WODM_WRITE, 0, (DWORD)&waveHdr, sizeof(WAVEHDR));
278 wodMessage( 0, WODM_UNPREPARE, 0, (DWORD)&waveHdr, sizeof(WAVEHDR));
279 wodMessage( 0, WODM_CLOSE, 0, 0L, 0L);
281 bRet = TRUE;
282 } else
283 WARN(mmsys, "can't prepare WaveOut device !\n");
285 GlobalUnlock16(hData);
286 GlobalFree16(hData);
292 } while (PlaySound_Loop);
294 if (hmmio != 0) mmioClose32(hmmio, 0);
295 return bRet;
298 static DWORD WINAPI PlaySound_Thread(LPVOID arg)
300 DWORD res;
302 for (;;) {
303 PlaySound_Playing = FALSE;
304 SetEvent(PlaySound_hReadyEvent);
305 res = WaitForSingleObject(PlaySound_hPlayEvent, INFINITE32);
306 ResetEvent(PlaySound_hReadyEvent);
307 SetEvent(PlaySound_hMiddleEvent);
308 if (res == WAIT_FAILED) ExitThread(2);
309 if (res != WAIT_OBJECT_0) continue;
310 PlaySound_Playing = TRUE;
312 if ((PlaySound_fdwSound & SND_RESOURCE) == SND_RESOURCE) {
313 HRSRC32 hRES;
314 HGLOBAL32 hGLOB;
315 void *ptr;
317 if ((hRES = FindResource32A(PlaySound_hmod, PlaySound_pszSound, "WAVE")) == 0) {
318 PlaySound_Result = FALSE;
319 continue;
321 if ((hGLOB = LoadResource32(PlaySound_hmod, hRES)) == 0) {
322 PlaySound_Result = FALSE;
323 continue;
325 if ((ptr = LockResource32(hGLOB)) == NULL) {
326 FreeResource32(hGLOB);
327 PlaySound_Result = FALSE;
328 continue;
330 PlaySound_Result = proc_PlaySound(ptr,
331 ((UINT16)PlaySound_fdwSound ^ SND_RESOURCE) | SND_MEMORY);
332 FreeResource32(hGLOB);
333 continue;
335 PlaySound_Result=proc_PlaySound(PlaySound_pszSound, (UINT16)PlaySound_fdwSound);
339 /**************************************************************************
340 * PlaySoundA [WINMM.1]
342 BOOL32 WINAPI PlaySound32A(LPCSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
344 static LPSTR StrDup = NULL;
346 TRACE(mmsys, "pszSound='%p' hmod=%04X fdwSound=%08lX\n",
347 pszSound, hmod, fdwSound);
349 if (PlaySound_hThread == 0) { /* This is the first time they called us */
350 DWORD id;
351 if ((PlaySound_hReadyEvent = CreateEvent32A(NULL, TRUE, FALSE, NULL)) == 0)
352 return FALSE;
353 if ((PlaySound_hMiddleEvent = CreateEvent32A(NULL, FALSE, FALSE, NULL)) == 0)
354 return FALSE;
355 if ((PlaySound_hPlayEvent = CreateEvent32A(NULL, FALSE, FALSE, NULL)) == 0)
356 return FALSE;
357 if ((PlaySound_hThread = CreateThread(NULL, 0, PlaySound_Thread, 0, 0, &id)) == 0)
358 return FALSE;
361 /* FIXME? I see no difference between SND_WAIT and SND_NOSTOP ! */
362 if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && PlaySound_Playing)
363 return FALSE;
365 /* Trying to stop if playing */
366 if (PlaySound_Playing) PlaySound_Stop = TRUE;
368 /* Waiting playing thread to get ready. I think 10 secs is ok & if not then leave*/
369 if (WaitForSingleObject(PlaySound_hReadyEvent, 1000*10) != WAIT_OBJECT_0)
370 return FALSE;
372 if (!pszSound || (fdwSound & SND_PURGE))
373 return FALSE; /* We stoped playing so leaving */
375 if (PlaySound_SearchMode != 1) PlaySound_SearchMode = 2;
376 if (!(fdwSound & SND_ASYNC)) {
377 if (fdwSound & SND_LOOP)
378 return FALSE;
379 PlaySound_pszSound = pszSound;
380 PlaySound_hmod = hmod;
381 PlaySound_fdwSound = fdwSound;
382 PlaySound_Result = FALSE;
383 SetEvent(PlaySound_hPlayEvent);
384 if (WaitForSingleObject(PlaySound_hMiddleEvent, INFINITE32) != WAIT_OBJECT_0)
385 return FALSE;
386 if (WaitForSingleObject(PlaySound_hReadyEvent, INFINITE32) != WAIT_OBJECT_0)
387 return FALSE;
388 return PlaySound_Result;
389 } else {
390 PlaySound_hmod = hmod;
391 PlaySound_fdwSound = fdwSound;
392 PlaySound_Result = FALSE;
393 if (StrDup) {
394 HeapFree(GetProcessHeap(), 0, StrDup);
395 StrDup = NULL;
397 if (!((fdwSound & SND_MEMORY) || ((fdwSound & SND_RESOURCE) &&
398 !((DWORD)pszSound >> 16)) || !pszSound)) {
399 StrDup = HEAP_strdupA(GetProcessHeap(),0,pszSound);
400 PlaySound_pszSound = StrDup;
401 } else PlaySound_pszSound = pszSound;
402 PlaySound_Loop = fdwSound & SND_LOOP;
403 SetEvent(PlaySound_hPlayEvent);
404 ResetEvent(PlaySound_hMiddleEvent);
405 return TRUE;
407 return FALSE;
410 /**************************************************************************
411 * PlaySoundW [WINMM.18]
413 BOOL32 WINAPI PlaySound32W(LPCWSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
415 LPSTR pszSoundA;
416 BOOL32 bSound;
418 if (!((fdwSound & SND_MEMORY) || ((fdwSound & SND_RESOURCE) &&
419 !((DWORD)pszSound >> 16)) || !pszSound)) {
420 pszSoundA = HEAP_strdupWtoA(GetProcessHeap(),0,pszSound);
421 bSound = PlaySound32A(pszSoundA, hmod, fdwSound);
422 HeapFree(GetProcessHeap(),0,pszSoundA);
423 } else
424 bSound = PlaySound32A((LPCSTR)pszSound, hmod, fdwSound);
426 return bSound;
429 /**************************************************************************
430 * sndPlaySound [MMSYSTEM.2]
432 BOOL16 WINAPI sndPlaySound(LPCSTR lpszSoundName, UINT16 uFlags)
434 PlaySound_SearchMode = 1;
435 return PlaySound32A(lpszSoundName, 0, uFlags);
438 /**************************************************************************
439 * mmsystemGetVersion [WINMM.134]
441 UINT32 WINAPI mmsystemGetVersion32()
443 return mmsystemGetVersion16();
446 /**************************************************************************
447 * mmsystemGetVersion [MMSYSTEM.5]
448 * return value borrowed from Win95 winmm.dll ;)
450 UINT16 WINAPI mmsystemGetVersion16()
452 TRACE(mmsys, "3.10 (Win95?)\n");
453 return 0x030a;
456 /**************************************************************************
457 * DriverProc [MMSYSTEM.6]
459 LRESULT WINAPI DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
460 DWORD dwParam1, DWORD dwParam2)
462 return DrvDefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
465 /**************************************************************************
466 * DriverCallback [MMSYSTEM.31]
468 BOOL16 WINAPI DriverCallback(DWORD dwCallBack, UINT16 uFlags, HANDLE16 hDev,
469 WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
471 TRACE(mmsys, "(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
472 dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
473 switch (uFlags & DCB_TYPEMASK) {
474 case DCB_NULL:
475 TRACE(mmsys, "CALLBACK_NULL !\n");
476 break;
477 case DCB_WINDOW:
478 TRACE(mmsys, "CALLBACK_WINDOW = %04lX handle = %04X!\n",
479 dwCallBack,hDev);
480 if (!IsWindow32(dwCallBack) || USER_HEAP_LIN_ADDR(hDev) == NULL)
481 return FALSE;
483 PostMessage16((HWND16)dwCallBack, wMsg, hDev, dwParam1);
484 break;
485 case DCB_TASK:
486 TRACE(mmsys, "CALLBACK_TASK !\n");
487 return FALSE;
488 case DCB_FUNCTION:
489 TRACE(mmsys, "CALLBACK_FUNCTION !\n");
490 Callbacks->CallDriverCallback( (FARPROC16)dwCallBack,
491 hDev, wMsg, dwUser,
492 dwParam1, dwParam2 );
493 break;
494 case DCB_FUNC32:
495 TRACE(mmsys, "CALLBACK_FUNCTION !\n");
496 ((LPDRVCALLBACK32)dwCallBack)( hDev, wMsg, dwUser,
497 dwParam1, dwParam2 );
498 break;
499 default:
500 WARN(mmsys, "Unknown callback type\n");
501 break;
503 return TRUE;
506 /**************************************************************************
507 * Mixer devices. New to Win95
509 /**************************************************************************
510 * find out the real mixer ID depending on hmix (depends on dwFlags)
511 * FIXME: also fix dwInstance passing to mixMessage
513 static UINT32 _get_mixerID_from_handle(HMIXEROBJ32 hmix,DWORD dwFlags) {
514 /* FIXME: Check dwFlags for MIXER_OBJECTF_xxxx entries and modify hmix
515 * accordingly. For now we always use mixerdevice 0.
517 return 0;
519 /**************************************************************************
520 * mixerGetNumDevs [WINMM.108]
522 UINT32 WINAPI mixerGetNumDevs32()
524 return mixerGetNumDevs16();
527 /**************************************************************************
528 * mixerGetNumDevs
530 UINT16 WINAPI mixerGetNumDevs16()
532 UINT16 count;
534 count = mixMessage(0,MXDM_GETNUMDEVS,0L,0L,0L);
535 TRACE(mmaux,"mixerGetNumDevs returns %d\n",count);
536 return count;
539 /**************************************************************************
540 * mixerGetDevCapsW [WINMM.102]
542 UINT32 WINAPI mixerGetDevCaps32W(UINT32 devid,LPMIXERCAPS32W mixcaps,UINT32 size)
544 MIXERCAPS16 mic16;
545 UINT32 ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
547 mixcaps->wMid = mic16.wMid;
548 mixcaps->wPid = mic16.wPid;
549 mixcaps->vDriverVersion = mic16.vDriverVersion;
550 lstrcpyAtoW(mixcaps->szPname,mic16.szPname);
551 mixcaps->fdwSupport = mic16.fdwSupport;
552 mixcaps->cDestinations = mic16.cDestinations;
553 return ret;
555 /**************************************************************************
556 * mixerGetDevCaps [WINMM.101]
558 UINT32 WINAPI mixerGetDevCaps32A(UINT32 devid,LPMIXERCAPS32A mixcaps,UINT32 size)
560 MIXERCAPS16 mic16;
561 UINT32 ret = mixerGetDevCaps16(devid,&mic16,sizeof(mic16));
563 mixcaps->wMid = mic16.wMid;
564 mixcaps->wPid = mic16.wPid;
565 mixcaps->vDriverVersion = mic16.vDriverVersion;
566 strcpy(mixcaps->szPname,mic16.szPname);
567 mixcaps->fdwSupport = mic16.fdwSupport;
568 mixcaps->cDestinations = mic16.cDestinations;
569 return ret;
572 /**************************************************************************
573 * mixerGetDevCaps
575 UINT16 WINAPI mixerGetDevCaps16(UINT16 devid,LPMIXERCAPS16 mixcaps,UINT16 size)
577 FIXME(mmsys,"should this be a fixme?\n");
578 return mixMessage(devid,MXDM_GETDEVCAPS,0L,(DWORD)mixcaps,(DWORD)size);
581 /**************************************************************************
582 * mixerOpen [WINMM.110]
584 UINT32 WINAPI mixerOpen32(LPHMIXER32 lphmix,UINT32 uDeviceID,DWORD dwCallback,
585 DWORD dwInstance,DWORD fdwOpen)
587 HMIXER16 hmix16;
588 UINT32 ret;
590 FIXME(mmsys,"(%p,%d,%08lx,%08lx,%08lx): semi stub?\n",
591 lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen);
592 ret = mixerOpen16(&hmix16,uDeviceID,dwCallback,dwInstance,fdwOpen);
593 if (lphmix) *lphmix = hmix16;
594 return ret;
597 /**************************************************************************
598 * mixerOpen
600 UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix,UINT16 uDeviceID,DWORD dwCallback,
601 DWORD dwInstance,DWORD fdwOpen)
603 HMIXER16 hmix;
604 LPMIXEROPENDESC lpmod;
605 BOOL32 mapperflag = (uDeviceID==0);
606 DWORD dwRet;
608 TRACE(mmsys,"(%p,%d,%08lx,%08lx,%08lx)\n",
609 lphmix,uDeviceID,dwCallback,dwInstance,fdwOpen);
610 hmix = USER_HEAP_ALLOC(sizeof(MIXEROPENDESC));
611 if (lphmix) *lphmix = hmix;
612 lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
613 lpmod->hmx = hmix;
614 lpmod->dwCallback = dwCallback;
615 lpmod->dwInstance = dwInstance;
616 if (uDeviceID >= MAXMIXERDRIVERS)
617 uDeviceID = 0;
618 while (uDeviceID < MAXMIXERDRIVERS) {
619 dwRet=mixMessage(uDeviceID,MXDM_OPEN,dwInstance,(DWORD)lpmod,fdwOpen);
620 if (dwRet == MMSYSERR_NOERROR) break;
621 if (!mapperflag) break;
622 uDeviceID++;
624 lpmod->uDeviceID = uDeviceID;
625 return dwRet;
628 /**************************************************************************
629 * mixerClose [WINMM.98]
631 UINT32 WINAPI mixerClose32(HMIXER32 hmix)
633 return mixerClose16(hmix);
636 /**************************************************************************
637 * mixerClose
639 UINT16 WINAPI mixerClose16(HMIXER16 hmix)
641 LPMIXEROPENDESC lpmod;
643 FIXME(mmsys,"(%04x): semi-stub?\n",hmix);
644 lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
645 return mixMessage(lpmod->uDeviceID,MXDM_CLOSE,lpmod->dwInstance,0L,0L);
648 /**************************************************************************
649 * mixerGetID [WINMM.103]
651 UINT32 WINAPI mixerGetID32(HMIXEROBJ32 hmix,LPUINT32 lpid,DWORD fdwID)
653 UINT16 xid;
654 UINT32 ret = mixerGetID16(hmix,&xid,fdwID);
656 if (*lpid) *lpid = xid;
657 return ret;
660 /**************************************************************************
661 * mixerGetID
663 UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix,LPUINT16 lpid,DWORD fdwID)
665 FIXME(mmsys,"(%04x): semi-stub\n",hmix);
666 return _get_mixerID_from_handle(hmix,fdwID);
669 /**************************************************************************
670 * mixerGetControlDetailsA [WINMM.99]
672 UINT32 WINAPI mixerGetControlDetails32A(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails)
674 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
675 return MMSYSERR_NOTENABLED;
678 /**************************************************************************
679 * mixerGetControlDetailsW [WINMM.100]
681 UINT32 WINAPI mixerGetControlDetails32W(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails)
683 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n", hmix,lpmcd,fdwDetails);
684 return MMSYSERR_NOTENABLED;
687 /**************************************************************************
688 * mixerGetControlDetails [MMSYSTEM.808]
690 UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails)
692 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
693 return MMSYSERR_NOTENABLED;
696 /**************************************************************************
697 * mixerGetLineControlsA [WINMM.104]
699 UINT32 WINAPI mixerGetLineControls32A(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32A lpmlc,DWORD fdwControls)
701 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
702 return MMSYSERR_NOTENABLED;
705 /**************************************************************************
706 * mixerGetLineControlsW [WINMM.105]
708 UINT32 WINAPI mixerGetLineControls32W(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32W lpmlc,DWORD fdwControls)
710 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
711 return MMSYSERR_NOTENABLED;
714 /**************************************************************************
715 * mixerGetLineControls [MMSYSTEM.807]
717 UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,LPMIXERLINECONTROLS16 lpmlc,DWORD fdwControls)
719 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmlc,fdwControls);
720 return MMSYSERR_NOTENABLED;
723 /**************************************************************************
724 * mixerGetLineInfoA [WINMM.106]
726 UINT32 WINAPI mixerGetLineInfo32A(HMIXEROBJ32 hmix,LPMIXERLINE32A lpml,DWORD fdwInfo)
728 MIXERLINE16 ml16;
729 UINT32 ret;
731 ml16.dwDestination = lpml->dwDestination;
732 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpml,fdwInfo);
733 ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
734 lpml->cbStruct = sizeof(*lpml);
735 lpml->dwSource = ml16.dwSource;
736 lpml->dwLineID = ml16.dwLineID;
737 lpml->fdwLine = ml16.fdwLine;
738 lpml->dwUser = ml16.dwUser;
739 lpml->dwComponentType = ml16.dwComponentType;
740 lpml->cChannels = ml16.cChannels;
741 lpml->cConnections = ml16.cConnections;
742 lpml->cControls = ml16.cControls;
743 strcpy(lpml->szShortName,ml16.szShortName);
744 strcpy(lpml->szName,ml16.szName);
745 lpml->Target.dwType = ml16.Target.dwType;
746 lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
747 lpml->Target.wMid = ml16.Target.wMid;
748 lpml->Target.wPid = ml16.Target.wPid;
749 lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
750 strcpy(lpml->Target.szPname,ml16.Target.szPname);
751 return ret;
754 /**************************************************************************
755 * mixerGetLineInfoW [WINMM.107]
757 UINT32 WINAPI mixerGetLineInfo32W(HMIXEROBJ32 hmix,LPMIXERLINE32W lpml,DWORD fdwInfo)
759 MIXERLINE16 ml16;
760 UINT32 ret;
762 ml16.dwDestination = lpml->dwDestination;
763 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpml,fdwInfo);
764 ret = mixerGetLineInfo16(hmix,&ml16,fdwInfo);
765 lpml->cbStruct = sizeof(*lpml);
766 lpml->dwSource = ml16.dwSource;
767 lpml->dwLineID = ml16.dwLineID;
768 lpml->fdwLine = ml16.fdwLine;
769 lpml->dwUser = ml16.dwUser;
770 lpml->dwComponentType = ml16.dwComponentType;
771 lpml->cChannels = ml16.cChannels;
772 lpml->cConnections = ml16.cConnections;
773 lpml->cControls = ml16.cControls;
774 lstrcpyAtoW(lpml->szShortName,ml16.szShortName);
775 lstrcpyAtoW(lpml->szName,ml16.szName);
776 lpml->Target.dwType = ml16.Target.dwType;
777 lpml->Target.dwDeviceID = ml16.Target.dwDeviceID;
778 lpml->Target.wMid = ml16.Target.wMid;
779 lpml->Target.wPid = ml16.Target.wPid;
780 lpml->Target.vDriverVersion = ml16.Target.vDriverVersion;
781 /*lstrcpyAtoW(lpml->Target.szPname,ml16.Target.szPname);*/
782 return ret;
785 /**************************************************************************
786 * mixerGetLineInfo [MMSYSTEM.805]
788 UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix,LPMIXERLINE16 lpml,DWORD fdwInfo)
790 UINT16 devid = _get_mixerID_from_handle(hmix,fdwInfo);
792 FIXME(mmsys,"(%04x,%p[line %08lx],%08lx) - semi-stub?\n",
793 hmix,lpml,lpml->dwDestination,fdwInfo);
794 return mixMessage(devid,MXDM_GETLINEINFO,0,(DWORD)lpml,fdwInfo);
797 /**************************************************************************
798 * mixerSetControlDetails [WINMM.111]
800 UINT32 WINAPI mixerSetControlDetails32(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails)
802 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
803 return MMSYSERR_NOTENABLED;
806 /**************************************************************************
807 * mixerSetControlDetails [MMSYSTEM.809]
809 UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails)
811 FIXME(mmsys,"(%04x,%p,%08lx): stub!\n",hmix,lpmcd,fdwDetails);
812 return MMSYSERR_NOTENABLED;
815 /**************************************************************************
816 * mixerMessage [WINMM.109]
818 UINT32 WINAPI mixerMessage32(HMIXER32 hmix,UINT32 uMsg,DWORD dwParam1,DWORD dwParam2)
820 LPMIXEROPENDESC lpmod;
821 UINT16 uDeviceID;
823 lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
824 if (lpmod)
825 uDeviceID = lpmod->uDeviceID;
826 else
827 uDeviceID = 0;
828 FIXME(mmsys,"(%04lx,%d,%08lx,%08lx): semi-stub?\n",
829 (DWORD)hmix,uMsg,dwParam1,dwParam2);
830 return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
833 /**************************************************************************
834 * mixerMessage [MMSYSTEM.804]
836 UINT16 WINAPI mixerMessage16(HMIXER16 hmix,UINT16 uMsg,DWORD dwParam1,DWORD dwParam2)
838 LPMIXEROPENDESC lpmod;
839 UINT16 uDeviceID;
841 lpmod = (LPMIXEROPENDESC)USER_HEAP_LIN_ADDR(hmix);
842 if (lpmod)
843 uDeviceID = lpmod->uDeviceID;
844 else
845 uDeviceID = 0;
846 FIXME(mmsys,"(%04x,%d,%08lx,%08lx) - semi-stub?\n",
847 hmix,uMsg,dwParam1,dwParam2);
848 return mixMessage(uDeviceID,uMsg,0L,dwParam1,dwParam2);
851 /**************************************************************************
852 * auxGetNumDevs [WINMM.22]
854 UINT32 WINAPI auxGetNumDevs32()
856 return auxGetNumDevs16();
859 /**************************************************************************
860 * auxGetNumDevs [MMSYSTEM.350]
862 UINT16 WINAPI auxGetNumDevs16()
864 UINT16 count = 0;
865 TRACE(mmsys, "auxGetNumDevs !\n");
866 count += auxMessage(0, AUXDM_GETNUMDEVS, 0L, 0L, 0L);
867 TRACE(mmsys, "auxGetNumDevs return %u \n", count);
868 return count;
871 /**************************************************************************
872 * auxGetDevCaps [WINMM.20]
874 UINT32 WINAPI auxGetDevCaps32W(UINT32 uDeviceID,LPAUXCAPS32W lpCaps,UINT32 uSize)
876 AUXCAPS16 ac16;
877 UINT32 ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
879 lpCaps->wMid = ac16.wMid;
880 lpCaps->wPid = ac16.wPid;
881 lpCaps->vDriverVersion = ac16.vDriverVersion;
882 lstrcpyAtoW(lpCaps->szPname,ac16.szPname);
883 lpCaps->wTechnology = ac16.wTechnology;
884 lpCaps->dwSupport = ac16.dwSupport;
885 return ret;
888 /**************************************************************************
889 * auxGetDevCaps [WINMM.21]
891 UINT32 WINAPI auxGetDevCaps32A(UINT32 uDeviceID,LPAUXCAPS32A lpCaps,UINT32 uSize)
893 AUXCAPS16 ac16;
894 UINT32 ret = auxGetDevCaps16(uDeviceID,&ac16,sizeof(ac16));
896 lpCaps->wMid = ac16.wMid;
897 lpCaps->wPid = ac16.wPid;
898 lpCaps->vDriverVersion = ac16.vDriverVersion;
899 strcpy(lpCaps->szPname,ac16.szPname);
900 lpCaps->wTechnology = ac16.wTechnology;
901 lpCaps->dwSupport = ac16.dwSupport;
902 return ret;
905 /**************************************************************************
906 * auxGetDevCaps [MMSYSTEM.351]
908 UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID,LPAUXCAPS16 lpCaps, UINT16 uSize)
910 TRACE(mmsys, "(%04X, %p, %d) !\n",
911 uDeviceID, lpCaps, uSize);
912 return auxMessage(uDeviceID, AUXDM_GETDEVCAPS,
913 0L, (DWORD)lpCaps, (DWORD)uSize);
916 /**************************************************************************
917 * auxGetVolume [WINM.23]
919 UINT32 WINAPI auxGetVolume32(UINT32 uDeviceID, DWORD * lpdwVolume)
921 return auxGetVolume16(uDeviceID,lpdwVolume);
924 /**************************************************************************
925 * auxGetVolume [MMSYSTEM.352]
927 UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, DWORD * lpdwVolume)
929 TRACE(mmsys, "(%04X, %p) !\n", uDeviceID, lpdwVolume);
930 return auxMessage(uDeviceID, AUXDM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
933 /**************************************************************************
934 * auxSetVolume [WINMM.25]
936 UINT32 WINAPI auxSetVolume32(UINT32 uDeviceID, DWORD dwVolume)
938 return auxSetVolume16(uDeviceID,dwVolume);
941 /**************************************************************************
942 * auxSetVolume [MMSYSTEM.353]
944 UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
946 TRACE(mmsys, "(%04X, %08lX) !\n", uDeviceID, dwVolume);
947 return auxMessage(uDeviceID, AUXDM_SETVOLUME, 0L, dwVolume, 0L);
950 /**************************************************************************
951 * auxOutMessage [MMSYSTEM.354]
953 DWORD WINAPI auxOutMessage32(UINT32 uDeviceID,UINT32 uMessage,DWORD dw1,DWORD dw2)
955 switch (uMessage) {
956 case AUXDM_GETNUMDEVS:
957 case AUXDM_GETVOLUME:
958 case AUXDM_SETVOLUME:
959 /* no argument conversion needed */
960 break;
961 case AUXDM_GETDEVCAPS:
962 return auxGetDevCaps32A(uDeviceID,(LPAUXCAPS32A)dw1,dw2);
963 default:
964 ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
965 uDeviceID,uMessage,dw1,dw2);
966 break;
968 return auxMessage(uDeviceID,uMessage,0L,dw1,dw2);
971 /**************************************************************************
972 * auxOutMessage [MMSYSTEM.354]
974 DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
976 TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n",
977 uDeviceID, uMessage, dw1, dw2);
978 switch (uMessage) {
979 case AUXDM_GETNUMDEVS:
980 case AUXDM_SETVOLUME:
981 /* no argument conversion needed */
982 break;
983 case AUXDM_GETVOLUME:
984 return auxGetVolume16(uDeviceID,(LPDWORD)PTR_SEG_TO_LIN(dw1));
985 case AUXDM_GETDEVCAPS:
986 return auxGetDevCaps16(uDeviceID,(LPAUXCAPS16)PTR_SEG_TO_LIN(dw1),dw2);
987 default:
988 ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
989 uDeviceID,uMessage,dw1,dw2);
990 break;
992 return auxMessage(uDeviceID, uMessage, 0L, dw1, dw2);
995 /**************************************************************************
996 * mciGetErrorStringW [WINMM.46]
998 BOOL32 WINAPI mciGetErrorString32W(DWORD wError,LPWSTR lpstrBuffer,UINT32 uLength)
1000 LPSTR bufstr = HeapAlloc(GetProcessHeap(),0,uLength);
1001 BOOL32 ret = mciGetErrorString32A(wError,bufstr,uLength);
1003 lstrcpyAtoW(lpstrBuffer,bufstr);
1004 HeapFree(GetProcessHeap(),0,bufstr);
1005 return ret;
1008 /**************************************************************************
1009 * mciGetErrorStringA [WINMM.45]
1011 BOOL32 WINAPI mciGetErrorString32A(DWORD wError,LPSTR lpstrBuffer,UINT32 uLength)
1013 return mciGetErrorString16(wError,lpstrBuffer,uLength);
1016 /**************************************************************************
1017 * mciGetErrorString [MMSYSTEM.706]
1019 BOOL16 WINAPI mciGetErrorString16(DWORD wError,LPSTR lpstrBuffer,UINT16 uLength)
1021 LPSTR msgptr;
1022 TRACE(mmsys, "(%08lX, %p, %d);\n",
1023 wError, lpstrBuffer, uLength);
1024 if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE);
1025 lpstrBuffer[0] = '\0';
1026 switch (wError) {
1027 case MCIERR_INVALID_DEVICE_ID:
1028 msgptr = "Invalid MCI device ID. Use the ID returned when opening the MCI device.";
1029 break;
1030 case MCIERR_UNRECOGNIZED_KEYWORD:
1031 msgptr = "The driver cannot recognize the specified command parameter.";
1032 break;
1033 case MCIERR_UNRECOGNIZED_COMMAND:
1034 msgptr = "The driver cannot recognize the specified command.";
1035 break;
1036 case MCIERR_HARDWARE:
1037 msgptr = "There is a problem with your media device. Make sure it is working correctly or contact the device manufacturer.";
1038 break;
1039 case MCIERR_INVALID_DEVICE_NAME:
1040 msgptr = "The specified device is not open or is not recognized by MCI.";
1041 break;
1042 case MCIERR_OUT_OF_MEMORY:
1043 msgptr = "Not enough memory available for this task. \nQuit one or more applications to increase available memory, and then try again.";
1044 break;
1045 case MCIERR_DEVICE_OPEN:
1046 msgptr = "The device name is already being used as an alias by this application. Use a unique alias.";
1047 break;
1048 case MCIERR_CANNOT_LOAD_DRIVER:
1049 msgptr = "There is an undetectable problem in loading the specified device driver.";
1050 break;
1051 case MCIERR_MISSING_COMMAND_STRING:
1052 msgptr = "No command was specified.";
1053 break;
1054 case MCIERR_PARAM_OVERFLOW:
1055 msgptr = "The output string was to large to fit in the return buffer. Increase the size of the buffer.";
1056 break;
1057 case MCIERR_MISSING_STRING_ARGUMENT:
1058 msgptr = "The specified command requires a character-string parameter. Please provide one.";
1059 break;
1060 case MCIERR_BAD_INTEGER:
1061 msgptr = "The specified integer is invalid for this command.";
1062 break;
1063 case MCIERR_PARSER_INTERNAL:
1064 msgptr = "The device driver returned an invalid return type. Check with the device manufacturer about obtaining a new driver.";
1065 break;
1066 case MCIERR_DRIVER_INTERNAL:
1067 msgptr = "There is a problem with the device driver. Check with the device manufacturer about obtaining a new driver.";
1068 break;
1069 case MCIERR_MISSING_PARAMETER:
1070 msgptr = "The specified command requires a parameter. Please supply one.";
1071 break;
1072 case MCIERR_UNSUPPORTED_FUNCTION:
1073 msgptr = "The MCI device you are using does not support the specified command.";
1074 break;
1075 case MCIERR_FILE_NOT_FOUND:
1076 msgptr = "Cannot find the specified file. Make sure the path and filename are correct.";
1077 break;
1078 case MCIERR_DEVICE_NOT_READY:
1079 msgptr = "The device driver is not ready.";
1080 break;
1081 case MCIERR_INTERNAL:
1082 msgptr = "A problem occurred in initializing MCI. Try restarting Windows.";
1083 break;
1084 case MCIERR_DRIVER:
1085 msgptr = "There is a problem with the device driver. The driver has closed. Cannot access error.";
1086 break;
1087 case MCIERR_CANNOT_USE_ALL:
1088 msgptr = "Cannot use 'all' as the device name with the specified command.";
1089 break;
1090 case MCIERR_MULTIPLE:
1091 msgptr = "Errors occurred in more than one device. Specify each command and device separately to determine which devices caused the error";
1092 break;
1093 case MCIERR_EXTENSION_NOT_FOUND:
1094 msgptr = "Cannot determine the device type from the given filename extension.";
1095 break;
1096 case MCIERR_OUTOFRANGE:
1097 msgptr = "The specified parameter is out of range for the specified command.";
1098 break;
1099 case MCIERR_FLAGS_NOT_COMPATIBLE:
1100 msgptr = "The specified parameters cannot be used together.";
1101 break;
1102 case MCIERR_FILE_NOT_SAVED:
1103 msgptr = "Cannot save the specified file. Make sure you have enough disk space or are still connected to the network.";
1104 break;
1105 case MCIERR_DEVICE_TYPE_REQUIRED:
1106 msgptr = "Cannot find the specified device. Make sure it is installed or that the device name is spelled correctly.";
1107 break;
1108 case MCIERR_DEVICE_LOCKED:
1109 msgptr = "The specified device is now being closed. Wait a few seconds, and then try again.";
1110 break;
1111 case MCIERR_DUPLICATE_ALIAS:
1112 msgptr = "The specified alias is already being used in this application. Use a unique alias.";
1113 break;
1114 case MCIERR_BAD_CONSTANT:
1115 msgptr = "The specified parameter is invalid for this command.";
1116 break;
1117 case MCIERR_MUST_USE_SHAREABLE:
1118 msgptr = "The device driver is already in use. To share it, use the 'shareable' parameter with each 'open' command.";
1119 break;
1120 case MCIERR_MISSING_DEVICE_NAME:
1121 msgptr = "The specified command requires an alias, file, driver, or device name. Please supply one.";
1122 break;
1123 case MCIERR_BAD_TIME_FORMAT:
1124 msgptr = "The specified value for the time format is invalid. Refer to the MCI documentation for valid formats.";
1125 break;
1126 case MCIERR_NO_CLOSING_QUOTE:
1127 msgptr = "A closing double-quotation mark is missing from the parameter value. Please supply one.";
1128 break;
1129 case MCIERR_DUPLICATE_FLAGS:
1130 msgptr = "A parameter or value was specified twice. Only specify it once.";
1131 break;
1132 case MCIERR_INVALID_FILE:
1133 msgptr = "The specified file cannot be played on the specified MCI device. The file may be corrupt, or not in the correct format.";
1134 break;
1135 case MCIERR_NULL_PARAMETER_BLOCK:
1136 msgptr = "A null parameter block was passed to MCI.";
1137 break;
1138 case MCIERR_UNNAMED_RESOURCE:
1139 msgptr = "Cannot save an unnamed file. Supply a filename.";
1140 break;
1141 case MCIERR_NEW_REQUIRES_ALIAS:
1142 msgptr = "You must specify an alias when using the 'new' parameter.";
1143 break;
1144 case MCIERR_NOTIFY_ON_AUTO_OPEN:
1145 msgptr = "Cannot use the 'notify' flag with auto-opened devices.";
1146 break;
1147 case MCIERR_NO_ELEMENT_ALLOWED:
1148 msgptr = "Cannot use a filename with the specified device.";
1149 break;
1150 case MCIERR_NONAPPLICABLE_FUNCTION:
1151 msgptr = "Cannot carry out the commands in the order specified. Correct the command sequence, and then try again.";
1152 break;
1153 case MCIERR_ILLEGAL_FOR_AUTO_OPEN:
1154 msgptr = "Cannot carry out the specified command on an auto-opened device. Wait until the device is closed, and then try again.";
1155 break;
1156 case MCIERR_FILENAME_REQUIRED:
1157 msgptr = "The filename is invalid. Make sure the filename is not longer than 8 characters, followed by a period and an extension.";
1158 break;
1159 case MCIERR_EXTRA_CHARACTERS:
1160 msgptr = "Cannot specify extra characters after a string enclosed in quotation marks.";
1161 break;
1162 case MCIERR_DEVICE_NOT_INSTALLED:
1163 msgptr = "The specified device is not installed on the system. Use the Drivers option in Control Panel to install the device.";
1164 break;
1165 case MCIERR_GET_CD:
1166 msgptr = "Cannot access the specified file or MCI device. Try changing directories or restarting your computer.";
1167 break;
1168 case MCIERR_SET_CD:
1169 msgptr = "Cannot access the specified file or MCI device because the application cannot change directories.";
1170 break;
1171 case MCIERR_SET_DRIVE:
1172 msgptr = "Cannot access specified file or MCI device because the application cannot change drives.";
1173 break;
1174 case MCIERR_DEVICE_LENGTH:
1175 msgptr = "Specify a device or driver name that is less than 79 characters.";
1176 break;
1177 case MCIERR_DEVICE_ORD_LENGTH:
1178 msgptr = "Specify a device or driver name that is less than 69 characters.";
1179 break;
1180 case MCIERR_NO_INTEGER:
1181 msgptr = "The specified command requires an integer parameter. Please provide one.";
1182 break;
1183 case MCIERR_WAVE_OUTPUTSINUSE:
1184 msgptr = "All wave devices that can play files in the current format are in use. Wait until a wave device is free, and then try again.";
1185 break;
1186 case MCIERR_WAVE_SETOUTPUTINUSE:
1187 msgptr = "Cannot set the current wave device for play back because it is in use. Wait until the device is free, and then try again.";
1188 break;
1189 case MCIERR_WAVE_INPUTSINUSE:
1190 msgptr = "All wave devices that can record files in the current format are in use. Wait until a wave device is free, and then try again.";
1191 break;
1192 case MCIERR_WAVE_SETINPUTINUSE:
1193 msgptr = "Cannot set the current wave device for recording because it is in use. Wait until the device is free, and then try again.";
1194 break;
1195 case MCIERR_WAVE_OUTPUTUNSPECIFIED:
1196 msgptr = "Any compatible waveform playback device may be used.";
1197 break;
1198 case MCIERR_WAVE_INPUTUNSPECIFIED:
1199 msgptr = "Any compatible waveform recording device may be used.";
1200 break;
1201 case MCIERR_WAVE_OUTPUTSUNSUITABLE:
1202 msgptr = "No wave device that can play files in the current format is installed. Use the Drivers option to install the wave device.";
1203 break;
1204 case MCIERR_WAVE_SETOUTPUTUNSUITABLE:
1205 msgptr = "The device you are trying to play to cannot recognize the current file format.";
1206 break;
1207 case MCIERR_WAVE_INPUTSUNSUITABLE:
1208 msgptr = "No wave device that can record files in the current format is installed. Use the Drivers option to install the wave device.";
1209 break;
1210 case MCIERR_WAVE_SETINPUTUNSUITABLE:
1211 msgptr = "The device you are trying to record from cannot recognize the current file format.";
1212 break;
1213 case MCIERR_NO_WINDOW:
1214 msgptr = "There is no display window.";
1215 break;
1216 case MCIERR_CREATEWINDOW:
1217 msgptr = "Could not create or use window.";
1218 break;
1219 case MCIERR_FILE_READ:
1220 msgptr = "Cannot read the specified file. Make sure the file is still present, or check your disk or network connection.";
1221 break;
1222 case MCIERR_FILE_WRITE:
1223 msgptr = "Cannot write to the specified file. Make sure you have enough disk space or are still connected to the network.";
1224 break;
1225 case MCIERR_SEQ_DIV_INCOMPATIBLE:
1226 msgptr = "The time formats of the \"song pointer\" and SMPTE are mutually exclusive. You can't use them together.";
1227 break;
1228 case MCIERR_SEQ_NOMIDIPRESENT:
1229 msgptr = "The system has no installed MIDI devices. Use the Drivers option from the Control Panel to install a MIDI driver.";
1230 break;
1231 case MCIERR_SEQ_PORT_INUSE:
1232 msgptr = "The specified MIDI port is already in use. Wait until it is free; the try again.";
1233 break;
1234 case MCIERR_SEQ_PORT_MAPNODEVICE:
1235 msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use the MIDI Mapper option from the Control Panel to edit the setup.";
1236 break;
1237 case MCIERR_SEQ_PORT_MISCERROR:
1238 msgptr = "An error occurred with the specified port.";
1239 break;
1240 case MCIERR_SEQ_PORT_NONEXISTENT:
1241 msgptr = "The specified MIDI device is not installed on the system. Use the Drivers option from the Control Panel to install a MIDI device.";
1242 break;
1243 case MCIERR_SEQ_PORTUNSPECIFIED:
1244 msgptr = "The system doesnot have a current MIDI port specified.";
1245 break;
1246 case MCIERR_SEQ_TIMER:
1247 msgptr = "All multimedia timers are being used by other applications. Quit one of these applications; then, try again.";
1248 break;
1251 msg# 513 : vcr
1252 msg# 514 : videodisc
1253 msg# 515 : overlay
1254 msg# 516 : cdaudio
1255 msg# 517 : dat
1256 msg# 518 : scanner
1257 msg# 519 : animation
1258 msg# 520 : digitalvideo
1259 msg# 521 : other
1260 msg# 522 : waveaudio
1261 msg# 523 : sequencer
1262 msg# 524 : not ready
1263 msg# 525 : stopped
1264 msg# 526 : playing
1265 msg# 527 : recording
1266 msg# 528 : seeking
1267 msg# 529 : paused
1268 msg# 530 : open
1269 msg# 531 : false
1270 msg# 532 : true
1271 msg# 533 : milliseconds
1272 msg# 534 : hms
1273 msg# 535 : msf
1274 msg# 536 : frames
1275 msg# 537 : smpte 24
1276 msg# 538 : smpte 25
1277 msg# 539 : smpte 30
1278 msg# 540 : smpte 30 drop
1279 msg# 541 : bytes
1280 msg# 542 : samples
1281 msg# 543 : tmsf
1283 default:
1284 msgptr = "Unknown MCI Error !\n";
1285 break;
1287 lstrcpyn32A(lpstrBuffer, msgptr, uLength);
1288 TRACE(mmsys, "msg = %s;\n", msgptr);
1289 return TRUE;
1293 /**************************************************************************
1294 * mciDriverNotify [MMSYSTEM.711]
1296 BOOL16 WINAPI mciDriverNotify(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
1298 TRACE(mmsys, "(%04X, %u, %04X)\n", hWndCallBack, wDevID, wStatus);
1299 if (!IsWindow32(hWndCallBack)) return FALSE;
1300 TRACE(mmsys, "before PostMessage\n");
1301 PostMessage16( hWndCallBack, MM_MCINOTIFY, wStatus,
1302 MAKELONG(wDevID, 0));
1303 return TRUE;
1306 /**************************************************************************
1307 * mciOpen16 [internal]
1309 static DWORD mciOpen16(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms)
1311 char str[128];
1312 LPMCI_OPEN_PARMS16 lpParms;
1313 UINT16 uDevTyp = 0;
1314 UINT16 wDevID = MMSYSTEM_FirstDevID();
1315 DWORD dwret;
1317 lpParms = PTR_SEG_TO_LIN(lp16Parms);
1318 TRACE(mmsys, "(%08lX, %p (%p))\n", dwParam, lp16Parms, lpParms);
1319 if (lp16Parms == NULL) return MCIERR_INTERNAL;
1321 while (mciGetDrv(wDevID)->modp.wType != 0) {
1322 wDevID = MMSYSTEM_NextDevID(wDevID);
1323 if (!MMSYSTEM_DevIDValid(wDevID)) {
1324 TRACE(mmsys, "MAXMCIDRIVERS reached !\n");
1325 return MCIERR_INTERNAL;
1328 TRACE(mmsys, "wDevID=%04X \n", wDevID);
1329 memcpy(mciGetOpenDrv(wDevID), lpParms, sizeof(*lpParms));
1331 if (dwParam & MCI_OPEN_ELEMENT) {
1332 char *s,*t;
1334 TRACE(mmsys,"lpstrElementName='%s'\n",
1335 (char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName)
1337 s = (char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
1338 t = strrchr(s,'.');
1339 if (t) {
1340 GetProfileString32A("mci extensions",t+1,"*",str,sizeof(str));
1341 CharUpper32A(str);
1342 TRACE(mmsys, "str = %s \n", str);
1343 if (strcmp(str, "CDAUDIO") == 0) {
1344 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
1345 } else if (strcmp(str, "WAVEAUDIO") == 0) {
1346 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
1347 } else if (strcmp(str, "SEQUENCER") == 0) {
1348 uDevTyp = MCI_DEVTYPE_SEQUENCER;
1349 } else if (strcmp(str, "ANIMATION1") == 0) {
1350 uDevTyp = MCI_DEVTYPE_ANIMATION;
1351 } else if (strcmp(str, "AVIVIDEO") == 0) {
1352 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
1353 } else if (strcmp(str,"*") == 0) {
1354 TRACE(mmsys,"No [mci extensions] entry for %s found.\n",t);
1355 return MCIERR_EXTENSION_NOT_FOUND;
1356 #if testing16
1357 } else {
1358 HDRVR16 hdrv = OpenDriver(str,"mci",NULL);
1359 if (hdrv) {
1360 HMODULE16 hmod;
1362 hmod = GetDriverModuleHandle(hdrv);
1363 mciGetDrv(wDevID)->hDrv = hdrv;
1364 mciGetDrv(wDevID)->driverProc = GetProcAddress16(hmod,SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
1365 uDevTyp = MCI_DEVTYPE_OTHER;
1366 } else {
1367 FIXME(mmsys, "[mci extensions] entry %s for %s not supported.\n",str,t);
1368 return MCIERR_DEVICE_NOT_INSTALLED;
1370 #endif
1372 } else
1373 return MCIERR_EXTENSION_NOT_FOUND;
1376 if (dwParam & MCI_OPEN_ALIAS) {
1377 TRACE(mmsys, "Alias='%s' !\n",
1378 (char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
1379 mciGetOpenDrv(wDevID)->lpstrAlias = strdup(PTR_SEG_TO_LIN(lpParms->lpstrAlias));
1380 /* mplayer does allocate alias to CDAUDIO */
1382 if (dwParam & MCI_OPEN_TYPE) {
1383 if (dwParam & MCI_OPEN_TYPE_ID) {
1384 TRACE(mmsys, "Dev=%08lx!\n", (DWORD)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
1385 uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
1386 mciGetOpenDrv(wDevID)->lpstrDeviceType=strdup(PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
1387 } else {
1388 if (lpParms->lpstrDeviceType == NULL) return MCIERR_INTERNAL;
1389 TRACE(mmsys, "Dev='%s' !\n",
1390 (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
1391 mciGetOpenDrv(wDevID)->lpstrDeviceType=strdup(PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
1392 strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
1393 CharUpper32A(str);
1394 if (strcmp(str, "CDAUDIO") == 0) {
1395 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
1396 } else if (strcmp(str, "WAVEAUDIO") == 0) {
1397 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
1398 } else if (strcmp(str, "SEQUENCER") == 0) {
1399 uDevTyp = MCI_DEVTYPE_SEQUENCER;
1400 } else if (strcmp(str, "ANIMATION1") == 0) {
1401 uDevTyp = MCI_DEVTYPE_ANIMATION;
1402 } else if (strcmp(str, "AVIVIDEO") == 0) {
1403 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
1404 } else {
1405 #if testing16
1406 HDRVR16 hdrv;
1407 TRACE(mmsys,"trying to load driver...\n");
1408 hdrv = OpenDriver(str,"mci",NULL);
1409 if (hdrv) {
1410 HMODULE16 hmod;
1412 hmod = GetDriverModuleHandle(hdrv);
1413 mciGetDrv(wDevID)->hDrv = hdrv;
1414 mciGetDrv(wDevID)->driverProc = GetProcAddress16(hmod,SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
1415 uDevTyp = MCI_DEVTYPE_OTHER;
1416 } else
1417 #endif
1418 return MCIERR_DEVICE_NOT_INSTALLED;
1422 mciGetDrv(wDevID)->modp.wType = uDevTyp;
1423 mciGetDrv(wDevID)->modp.wDeviceID = 0; /* FIXME? for multiple devices */
1424 lpParms->wDeviceID = wDevID;
1425 TRACE(mmsys, "mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n",
1426 wDevID, uDevTyp, lpParms->wDeviceID);
1427 switch (uDevTyp) {
1428 case MCI_DEVTYPE_CD_AUDIO:
1429 dwret = CDAUDIO_DriverProc16(0, 0, MCI_OPEN_DRIVER, dwParam, (DWORD)lp16Parms);
1430 break;
1431 case MCI_DEVTYPE_WAVEFORM_AUDIO:
1432 dwret = WAVE_DriverProc16(0, 0, MCI_OPEN_DRIVER, dwParam, (DWORD)lp16Parms);
1433 break;
1434 case MCI_DEVTYPE_SEQUENCER:
1435 dwret = MIDI_DriverProc16(0, 0, MCI_OPEN_DRIVER, dwParam, (DWORD)lp16Parms);
1436 break;
1437 case MCI_DEVTYPE_ANIMATION:
1438 dwret = ANIM_DriverProc16(0, 0, MCI_OPEN_DRIVER, dwParam, (DWORD)lp16Parms);
1439 break;
1440 case MCI_DEVTYPE_DIGITAL_VIDEO:
1441 TRACE(mmsys, "No DIGITAL_VIDEO yet !\n");
1442 return MCIERR_DEVICE_NOT_INSTALLED;
1443 default:
1444 #if testing16
1445 dwret = Callbacks->CallDriverProc(mciGetDrv(wDevID)->driverProc,0,mciGetDrv(wDevID)->hDrv,MCI_OPEN_DRIVER,dwParam,(DWORD)lp16Parms);
1446 WARN(mmsys, "Invalid Device Name '%08lx' !\n", (DWORD)lpParms->lpstrDeviceType);
1447 #endif
1448 return MCIERR_INVALID_DEVICE_NAME;
1452 if (dwParam & MCI_NOTIFY)
1453 mciDriverNotify(lpParms->dwCallback, wDevID,
1454 (dwret==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
1456 /* only handled devices fall through */
1457 TRACE(mmsys, "wDevID = %04X wDeviceID = %d dwret = %ld\n",wDevID, lpParms->wDeviceID, dwret);
1458 return dwret;
1461 /**************************************************************************
1462 * mciGetDriverData [MMSYSTEM.708]
1464 DWORD WINAPI mciGetDriverData16(HDRVR16 hdrv)
1466 FIXME(mmsys,"(%04x): stub!\n",hdrv);
1467 return 0x42;
1470 /**************************************************************************
1471 * mciSetDriverData [MMSYSTEM.707]
1473 DWORD WINAPI mciSetDriverData16(HDRVR16 hdrv,DWORD data)
1475 FIXME(mmsys,"(%04x,%08lx): stub!\n",hdrv,data);
1476 return 0;
1479 /**************************************************************************
1480 * mciClose16 [internal]
1482 static DWORD mciClose16(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
1484 DWORD dwRet = MCIERR_INTERNAL;
1486 TRACE(mmsys, "(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
1488 if(wDevID == MCI_ALL_DEVICE_ID) {
1489 FIXME(mmsys, "unhandled MCI_ALL_DEVICE_ID\n");
1490 return MCIERR_CANNOT_USE_ALL;
1493 switch (mciGetDrv(wDevID)->modp.wType) {
1494 case MCI_DEVTYPE_CD_AUDIO:
1495 dwRet = CDAUDIO_DriverProc16(mciGetDrv(wDevID)->modp.wDeviceID,0,
1496 MCI_CLOSE, dwParam, (DWORD)lpParms);
1497 break;
1498 case MCI_DEVTYPE_WAVEFORM_AUDIO:
1499 dwRet = WAVE_DriverProc16(mciGetDrv(wDevID)->modp.wDeviceID, 0,
1500 MCI_CLOSE, dwParam,
1501 (DWORD)lpParms);
1502 break;
1503 case MCI_DEVTYPE_SEQUENCER:
1504 dwRet = MIDI_DriverProc16(mciGetDrv(wDevID)->modp.wDeviceID, 0,
1505 MCI_CLOSE, dwParam,
1506 (DWORD)lpParms);
1507 break;
1509 case MCI_DEVTYPE_ANIMATION:
1510 dwRet = ANIM_DriverProc16(mciGetDrv(wDevID)->modp.wDeviceID, 0,
1511 MCI_CLOSE, dwParam,
1512 (DWORD)lpParms);
1513 break;
1515 default:
1516 dwRet = Callbacks->CallDriverProc(mciGetDrv(wDevID)->driverProc,
1517 mciGetDrv(wDevID)->modp.wDeviceID,
1518 mciGetDrv(wDevID)->hDrv,MCI_CLOSE,dwParam,
1519 (DWORD)lpParms);
1521 mciGetDrv(wDevID)->modp.wType = 0;
1523 if (dwParam&MCI_NOTIFY)
1524 mciDriverNotify(lpParms->dwCallback,wDevID,
1525 (dwRet==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
1527 TRACE(mmsys, "returns %ld\n",dwRet);
1528 return dwRet;
1532 /**************************************************************************
1533 * mciSysinfo16 [internal]
1535 static DWORD mciSysInfo16(DWORD dwFlags, LPMCI_SYSINFO_PARMS16 lpParms)
1537 LPSTR lpstrReturn;
1538 DWORD *lpdwRet;
1540 TRACE(mci, "(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
1541 lpstrReturn = PTR_SEG_TO_LIN(lpParms->lpstrReturn);
1542 switch (dwFlags) {
1543 case MCI_SYSINFO_QUANTITY:
1544 TRACE(mci, "MCI_SYSINFO_QUANTITY \n");
1545 lpdwRet = (DWORD *)lpstrReturn;
1546 *(lpdwRet) = mciInstalledCount;
1547 return 0;
1548 case MCI_SYSINFO_INSTALLNAME:
1549 TRACE(mci, "MCI_SYSINFO_INSTALLNAME \n");
1550 if (lpParms->dwRetSize < mciInstalledListLen)
1551 lstrcpyn32A(lpstrReturn, lpmciInstallNames, lpParms->dwRetSize - 1);
1552 else
1553 strcpy(lpstrReturn, lpmciInstallNames);
1554 return 0;
1555 case MCI_SYSINFO_NAME:
1556 TRACE(mci, "MCI_SYSINFO_NAME\n");
1557 if (lpParms->dwNumber > mciInstalledCount)
1558 return MMSYSERR_INVALPARAM;
1560 DWORD count = lpParms->dwNumber;
1561 LPSTR ptr = lpmciInstallNames;
1563 while (--count > 0)
1564 ptr += strlen(ptr) + 1;
1565 if (lpParms->dwRetSize < strlen(ptr))
1566 lstrcpyn32A(lpstrReturn, ptr, lpParms->dwRetSize - 1);
1567 else
1568 strcpy(lpstrReturn, ptr);
1570 TRACE(mci, "(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn);
1571 return 0;
1572 case MCI_SYSINFO_OPEN:
1573 TRACE(mci, "MCI_SYSINFO_OPEN \n");
1574 return 0;
1576 return MMSYSERR_INVALPARAM;
1579 /**************************************************************************
1580 * mciLoadCommandResource16 [MMSYSTEM.705]
1582 UINT16 WINAPI mciLoadCommandResource16(HANDLE16 hinst,LPCSTR resname,UINT16 type)
1584 char buf[200];
1585 OFSTRUCT ofs;
1586 HANDLE16 xhinst;
1587 HRSRC16 hrsrc;
1588 HGLOBAL16 hmem;
1589 LPSTR segstr;
1590 SEGPTR xmem;
1591 LPBYTE lmem;
1592 static UINT16 mcidevtype = 0;
1594 FIXME(mmsys,"(%04x,%s,%d): stub!\n",hinst,resname,type);
1595 if (!lstrcmpi32A(resname,"core")) {
1596 FIXME(mmsys,"(...,\"core\",...), have to use internal tables... (not there yet)\n");
1597 return 0;
1599 /* if file exists "resname.mci", then load resource "resname" from it
1600 * otherwise directly from driver
1602 strcpy(buf,resname);
1603 strcat(buf,".mci");
1604 if (OpenFile32(buf,&ofs,OF_EXIST)!=HFILE_ERROR32) {
1605 xhinst = LoadLibrary16(buf);
1606 if (xhinst >32)
1607 hinst = xhinst;
1608 } /* else use passed hinst */
1609 segstr = SEGPTR_STRDUP(resname);
1610 hrsrc = FindResource16(hinst,SEGPTR_GET(segstr),type);
1611 SEGPTR_FREE(segstr);
1612 if (!hrsrc) {
1613 WARN(mmsys,"no special commandlist found in resource\n");
1614 return MCI_NO_COMMAND_TABLE;
1616 hmem = LoadResource16(hinst,hrsrc);
1617 if (!hmem) {
1618 WARN(mmsys,"couldn't load resource??\n");
1619 return MCI_NO_COMMAND_TABLE;
1621 xmem = WIN16_LockResource16(hmem);
1622 if (!xmem) {
1623 WARN(mmsys,"couldn't lock resource??\n");
1624 FreeResource16(hmem);
1625 return MCI_NO_COMMAND_TABLE;
1627 lmem = PTR_SEG_TO_LIN(xmem);
1628 TRACE(mmsys,"first resource entry is %s\n",(char*)lmem);
1629 /* parse resource, register stuff, return unique id */
1630 return ++mcidevtype;
1634 /**************************************************************************
1635 * mciSound [internal]
1636 * not used anymore ??
1638 DWORD mciSound(UINT16 wDevID, DWORD dwParam, LPMCI_SOUND_PARMS lpParms)
1640 if (lpParms == NULL) return MCIERR_INTERNAL;
1641 if (dwParam & MCI_SOUND_NAME)
1642 TRACE(mci, "file='%s' !\n", lpParms->lpstrSoundName);
1643 return MCIERR_INVALID_DEVICE_ID;
1648 static const char *_mciCommandToString(UINT16 wMsg)
1650 static char buffer[100];
1652 #define CASE(s) case (s): return #s
1654 switch (wMsg) {
1655 CASE(MCI_OPEN);
1656 CASE(MCI_CLOSE);
1657 CASE(MCI_ESCAPE);
1658 CASE(MCI_PLAY);
1659 CASE(MCI_SEEK);
1660 CASE(MCI_STOP);
1661 CASE(MCI_PAUSE);
1662 CASE(MCI_INFO);
1663 CASE(MCI_GETDEVCAPS);
1664 CASE(MCI_SPIN);
1665 CASE(MCI_SET);
1666 CASE(MCI_STEP);
1667 CASE(MCI_RECORD);
1668 CASE(MCI_SYSINFO);
1669 CASE(MCI_BREAK);
1670 CASE(MCI_SAVE);
1671 CASE(MCI_STATUS);
1672 CASE(MCI_CUE);
1673 CASE(MCI_REALIZE);
1674 CASE(MCI_WINDOW);
1675 CASE(MCI_PUT);
1676 CASE(MCI_WHERE);
1677 CASE(MCI_FREEZE);
1678 CASE(MCI_UNFREEZE);
1679 CASE(MCI_LOAD);
1680 CASE(MCI_CUT);
1681 CASE(MCI_COPY);
1682 CASE(MCI_PASTE);
1683 CASE(MCI_UPDATE);
1684 CASE(MCI_RESUME);
1685 CASE(MCI_DELETE);
1686 default:
1687 sprintf(buffer, "%04X", wMsg);
1688 return buffer;
1693 /**************************************************************************
1694 * mciOpen32 [internal]
1697 static DWORD mciOpen32(DWORD dwParam, LPMCI_OPEN_PARMS32A lpParms)
1699 char str[128];
1700 UINT16 uDevTyp = 0;
1701 UINT16 wDevID = MMSYSTEM_FirstDevID();
1702 DWORD dwret;
1704 TRACE(mmsys, "(%08lX, %p)\n", dwParam, lpParms);
1705 if (lpParms == NULL) return MCIERR_INTERNAL;
1707 if ((dwParam & ~(MCI_OPEN_ELEMENT|MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_NOTIFY)) != 0) {
1708 FIXME(mmsys, "unsupported yet dwFlags=%08lX\n",
1709 (dwParam & ~(MCI_OPEN_ELEMENT|MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_NOTIFY)));
1712 while (mciGetDrv(wDevID)->modp.wType != 0) {
1713 wDevID = MMSYSTEM_NextDevID(wDevID);
1714 if (!MMSYSTEM_DevIDValid(wDevID)) {
1715 TRACE(mmsys, "MAXMCIDRIVERS reached !\n");
1716 return MCIERR_INTERNAL;
1719 TRACE(mmsys, "wDevID=%04X \n", wDevID);
1720 memcpy(mciGetOpenDrv(wDevID), lpParms, sizeof(*lpParms));
1722 if (dwParam & MCI_OPEN_ELEMENT) {
1723 char *s,*t;
1725 TRACE(mmsys,"lpstrElementName='%s'\n", lpParms->lpstrElementName);
1726 s = lpParms->lpstrElementName;
1727 t = strrchr(s, '.');
1728 if (t) {
1729 GetProfileString32A("mci extensions", t+1, "*", str, sizeof(str));
1730 CharUpper32A(str);
1731 TRACE(mmsys, "str = %s \n", str);
1732 if (strcmp(str, "CDAUDIO") == 0) {
1733 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
1734 } else if (strcmp(str, "WAVEAUDIO") == 0) {
1735 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
1736 } else if (strcmp(str, "SEQUENCER") == 0) {
1737 uDevTyp = MCI_DEVTYPE_SEQUENCER;
1738 } else if (strcmp(str, "ANIMATION1") == 0) {
1739 uDevTyp = MCI_DEVTYPE_ANIMATION;
1740 } else if (strcmp(str, "AVIVIDEO") == 0) {
1741 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
1742 } else if (strcmp(str,"*") == 0) {
1743 TRACE(mmsys,"No [mci extensions] entry for %s found.\n",t);
1744 return MCIERR_EXTENSION_NOT_FOUND;
1745 #if testing32
1746 /* FIXME has to written, seems to be experimental 16 bit code anyway */
1747 } else {
1748 HDRVR16 hdrv = OpenDriver(str, "mci", NULL);
1749 if (hdrv) {
1750 HMODULE16 hmod;
1752 hmod = GetDriverModuleHandle(hdrv);
1753 mciGetDrv(wDevID)->hDrv = hdrv;
1754 mciGetDrv(wDevID)->driverProc = GetProcAddress16(hmod,oouch SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
1755 uDevTyp = MCI_DEVTYPE_OTHER;
1756 } else {
1757 FIXME(mmsys, "[mci extensions] entry %s for %s not supported.\n",str,t);
1758 return MCIERR_DEVICE_NOT_INSTALLED;
1760 #endif
1762 } else
1763 return MCIERR_EXTENSION_NOT_FOUND;
1766 if (dwParam & MCI_OPEN_ALIAS) {
1767 TRACE(mmsys, "Alias='%s' !\n", lpParms->lpstrAlias);
1768 /* FIXME is there any memory leak here ? */
1769 mciGetOpenDrv(wDevID)->lpstrAlias = strdup(lpParms->lpstrAlias);
1770 /* mplayer does allocate alias to CDAUDIO */
1772 if (dwParam & MCI_OPEN_TYPE) {
1773 if (dwParam & MCI_OPEN_TYPE_ID) {
1774 TRACE(mmsys, "Dev=%08lx!\n", (DWORD)lpParms->lpstrDeviceType);
1775 uDevTyp = LOWORD((DWORD)lpParms->lpstrDeviceType);
1776 mciGetOpenDrv(wDevID)->lpstrDeviceType = lpParms->lpstrDeviceType;
1777 } else {
1778 if (lpParms->lpstrDeviceType == NULL)
1779 return MCIERR_INTERNAL;
1780 TRACE(mmsys, "Dev='%s' !\n", lpParms->lpstrDeviceType);
1781 /* FIXME is there any memory leak here ? */
1782 mciGetOpenDrv(wDevID)->lpstrDeviceType = strdup(lpParms->lpstrDeviceType);
1783 strcpy(str, lpParms->lpstrDeviceType);
1784 CharUpper32A(str);
1785 if (strcmp(str, "CDAUDIO") == 0) {
1786 uDevTyp = MCI_DEVTYPE_CD_AUDIO;
1787 } else if (strcmp(str, "WAVEAUDIO") == 0) {
1788 uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
1789 } else if (strcmp(str, "SEQUENCER") == 0) {
1790 uDevTyp = MCI_DEVTYPE_SEQUENCER;
1791 } else if (strcmp(str, "ANIMATION1") == 0) {
1792 uDevTyp = MCI_DEVTYPE_ANIMATION;
1793 } else if (strcmp(str, "AVIVIDEO") == 0) {
1794 uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
1795 } else {
1796 #if testing32
1797 /* FIXME has to written, seems to be experimental 16 bit code anyway */
1798 HDRVR16 hdrv;
1799 TRACE(mmsys,"trying to load driver...\n");
1800 hdrv = OpenDriver(str,"mci",NULL);
1801 if (hdrv) {
1802 HMODULE16 hmod;
1804 hmod = GetDriverModuleHandle(hdrv);
1805 mciGetDrv(wDevID)->hDrv = hdrv;
1806 mciGetDrv(wDevID)->driverProc = GetProcAddress16(hmod,oouch SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
1807 uDevTyp = MCI_DEVTYPE_OTHER;
1808 } else
1809 #endif
1810 return MCIERR_DEVICE_NOT_INSTALLED;
1814 mciGetDrv(wDevID)->modp.wType = uDevTyp;
1815 mciGetDrv(wDevID)->modp.wDeviceID = 0; /* FIXME? for multiple devices */
1816 lpParms->wDeviceID = wDevID;
1817 TRACE(mmsys, "mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n",
1818 wDevID, uDevTyp, lpParms->wDeviceID);
1819 switch (uDevTyp) {
1820 case MCI_DEVTYPE_CD_AUDIO:
1821 dwret = CDAUDIO_DriverProc32( 0, 0, MCI_OPEN_DRIVER,
1822 dwParam, (DWORD)lpParms);
1823 break;
1824 case MCI_DEVTYPE_WAVEFORM_AUDIO:
1825 dwret = WAVE_DriverProc32( 0, 0, MCI_OPEN_DRIVER,
1826 dwParam, (DWORD)lpParms);
1827 break;
1828 case MCI_DEVTYPE_SEQUENCER:
1829 dwret = MIDI_DriverProc32( 0, 0, MCI_OPEN_DRIVER,
1830 dwParam, (DWORD)lpParms);
1831 break;
1832 case MCI_DEVTYPE_ANIMATION:
1833 dwret = ANIM_DriverProc32( 0, 0, MCI_OPEN_DRIVER,
1834 dwParam, (DWORD)lpParms);
1835 break;
1836 case MCI_DEVTYPE_DIGITAL_VIDEO:
1837 TRACE(mmsys, "No DIGITAL_VIDEO yet !\n");
1838 return MCIERR_DEVICE_NOT_INSTALLED;
1839 default:
1840 #if testing32
1841 dwret = Callbacks->CallDriverProc(mciGetDrv(wDevID)->driverProc,0,mciGetDrv(wDevID)->hdrv,MCI_OPEN_DRIVER,dwParam,(DWORD)lpParms);
1842 WARN(mmsys, "Invalid Device Name '%08lx' !\n", (DWORD)lpParms->lpstrDeviceType);
1843 #endif
1844 return MCIERR_INVALID_DEVICE_NAME;
1848 if (dwParam & MCI_NOTIFY)
1849 mciDriverNotify(lpParms->dwCallback,wDevID,
1850 (dwret==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
1852 /* only handled devices fall through */
1853 TRACE(mmsys, "wDevID = %04X wDeviceID = %d dwret = %ld\n",wDevID, lpParms->wDeviceID, dwret);
1854 return dwret;
1857 /**************************************************************************
1858 * mciClose32 [internal]
1860 static DWORD mciClose32(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
1862 DWORD dwRet = MCIERR_INTERNAL;
1864 TRACE(mmsys, "(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
1866 if (wDevID == MCI_ALL_DEVICE_ID) {
1867 FIXME(mmsys, "unhandled MCI_ALL_DEVICE_ID\n");
1868 return MCIERR_CANNOT_USE_ALL;
1871 switch (mciGetDrv(wDevID)->modp.wType) {
1872 case MCI_DEVTYPE_CD_AUDIO:
1873 dwRet = CDAUDIO_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,
1874 MCI_CLOSE, dwParam, (DWORD)lpParms);
1875 break;
1876 case MCI_DEVTYPE_WAVEFORM_AUDIO:
1877 dwRet = WAVE_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID, 0,
1878 MCI_CLOSE, dwParam,
1879 (DWORD)lpParms);
1880 break;
1881 case MCI_DEVTYPE_SEQUENCER:
1882 dwRet = MIDI_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID, 0,
1883 MCI_CLOSE, dwParam,
1884 (DWORD)lpParms);
1885 break;
1887 case MCI_DEVTYPE_ANIMATION:
1888 dwRet = ANIM_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID, 0,
1889 MCI_CLOSE, dwParam,
1890 (DWORD)lpParms);
1891 break;
1893 default:
1894 dwRet = Callbacks->CallDriverProc(mciGetDrv(wDevID)->driverProc,
1895 mciGetDrv(wDevID)->modp.wDeviceID,
1896 mciGetDrv(wDevID)->hDrv,MCI_CLOSE,dwParam,
1897 (DWORD)lpParms);
1899 mciGetDrv(wDevID)->modp.wType = 0;
1901 if (dwParam&MCI_NOTIFY)
1902 mciDriverNotify(lpParms->dwCallback,wDevID,
1903 (dwRet==0?MCI_NOTIFY_SUCCESSFUL:MCI_NOTIFY_FAILURE));
1905 TRACE(mmsys, "returns %ld\n",dwRet);
1906 return dwRet;
1909 /**************************************************************************
1910 * mciSysinfo32 [internal]
1912 static DWORD mciSysInfo32(DWORD dwFlags, LPMCI_SYSINFO_PARMS32A lpParms)
1914 TRACE(mci, "(%08lX, %08lX)\n", dwFlags, (DWORD)lpParms);
1915 switch (dwFlags) {
1916 case MCI_SYSINFO_QUANTITY:
1917 TRACE(mci, "MCI_SYSINFO_QUANTITY \n");
1918 *(DWORD*)lpParms->lpstrReturn = mciInstalledCount;
1919 return 0;
1920 case MCI_SYSINFO_INSTALLNAME:
1921 TRACE(mci, "MCI_SYSINFO_INSTALLNAME \n");
1922 if (lpParms->dwRetSize < mciInstalledListLen)
1923 lstrcpyn32A(lpParms->lpstrReturn, lpmciInstallNames, lpParms->dwRetSize - 1);
1924 else
1925 strcpy(lpParms->lpstrReturn, lpmciInstallNames);
1926 return 0;
1927 case MCI_SYSINFO_NAME:
1928 TRACE(mci, "MCI_SYSINFO_NAME\n"); fflush(stddeb);
1929 if (lpParms->dwNumber > mciInstalledCount)
1930 return MMSYSERR_INVALPARAM;
1932 DWORD count = lpParms->dwNumber;
1933 LPSTR ptr = lpmciInstallNames;
1935 while (--count > 0)
1936 ptr += strlen(ptr) + 1;
1937 if (lpParms->dwRetSize < strlen(ptr))
1938 lstrcpyn32A(lpParms->lpstrReturn, ptr, lpParms->dwRetSize - 1);
1939 else
1940 strcpy(lpParms->lpstrReturn, ptr);
1942 TRACE(mci, "(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn);
1943 return 0;
1944 case MCI_SYSINFO_OPEN:
1945 TRACE(mci, "MCI_SYSINFO_OPEN \n");
1946 return 0;
1948 return MMSYSERR_INVALPARAM;
1951 struct SCA32 {
1952 UINT32 wDevID;
1953 UINT32 wMsg;
1954 DWORD dwParam1;
1955 DWORD dwParam2;
1958 DWORD WINAPI mciSendCommand32A(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1, DWORD dwParam2);
1960 static DWORD WINAPI mciSCAStarter32(LPVOID arg)
1962 struct SCA32* sca = (struct SCA32*)arg;
1963 DWORD ret;
1965 TRACE(mci, "In thread for async command (%08x,%s,%08lx,%08lx)\n",
1966 sca->wDevID, _mciCommandToString(sca->wMsg), sca->dwParam1, sca->dwParam2);
1967 ret = mciSendCommand32A(sca->wDevID, sca->wMsg, sca->dwParam1 | MCI_WAIT, sca->dwParam2);
1968 free(sca);
1969 return ret;
1972 /**************************************************************************
1973 * mciSendCommandAsync32 [internal]
1975 DWORD mciSendCommandAsync32(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1, DWORD dwParam2)
1977 struct SCA32* sca = malloc(sizeof(struct SCA32));
1979 if (sca == 0) return MCIERR_OUT_OF_MEMORY;
1981 sca->wDevID = wDevID;
1982 sca->wMsg = wMsg;
1983 sca->dwParam1 = dwParam1;
1984 sca->dwParam2 = dwParam2;
1986 if (CreateThread(NULL, 0, mciSCAStarter32, sca, 0, NULL) == 0) {
1987 WARN(mci, "Couldn't allocate thread for async command handling, sending synchonously\n");
1988 return mciSCAStarter32(&sca);
1990 return 0;
1993 /**************************************************************************
1994 * mciSendCommand32A [WINMM.49]
1996 DWORD WINAPI mciSendCommand32A(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1, DWORD dwParam2)
1998 TRACE(mci,"(%08x,%s,%08lx,%08lx)\n",
1999 wDevID,_mciCommandToString(wMsg),dwParam1,dwParam2);
2001 switch (wMsg) {
2002 case MCI_OPEN:
2003 return mciOpen32(dwParam1, (LPMCI_OPEN_PARMS32A)dwParam2);
2004 case MCI_CLOSE:
2005 return mciClose32(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
2006 case MCI_SYSINFO:
2007 return mciSysInfo32(dwParam1, (LPMCI_SYSINFO_PARMS32A)dwParam2);
2008 default:
2010 DWORD dwRet = MCIERR_INTERNAL;
2011 LONG (*proc)(DWORD, HDRVR16, DWORD, DWORD, DWORD) = 0;
2013 if (wDevID == MCI_ALL_DEVICE_ID) {
2014 FIXME(mci, "unhandled MCI_ALL_DEVICE_ID\n");
2015 return MCIERR_CANNOT_USE_ALL;
2018 if (!MMSYSTEM_DevIDValid(wDevID))
2019 return MMSYSERR_INVALPARAM;
2021 switch (mciGetDrv(wDevID)->modp.wType) {
2022 case MCI_DEVTYPE_CD_AUDIO: proc = CDAUDIO_DriverProc32; break;
2023 case MCI_DEVTYPE_WAVEFORM_AUDIO: proc = WAVE_DriverProc32; break;
2024 case MCI_DEVTYPE_SEQUENCER: proc = MIDI_DriverProc32; break;
2025 /* case MCI_DEVTYPE_ANIMATION: proc = ANIM_DriverProc32; break;*/
2027 if (proc) {
2028 dwRet = (proc)(mciGetDrv(wDevID)->modp.wDeviceID, mciGetDrv(wDevID)->hDrv, wMsg, dwParam1, dwParam2);
2029 } else if (mciGetDrv(wDevID)->driverProc) {
2030 FIXME(mmsys, "is that correct ?\n");
2031 dwRet = Callbacks->CallDriverProc(mciGetDrv(wDevID)->driverProc,
2032 mciGetDrv(wDevID)->modp.wDeviceID,
2033 mciGetDrv(wDevID)->hDrv,wMsg, dwParam1, dwParam2);
2034 } else {
2035 WARN(mmsys, "unknown device type=%04X !\n", mciGetDrv(wDevID)->modp.wType);
2037 return dwRet;
2040 return 0x1; /* !ok */
2042 /**************************************************************************
2043 * mciSendCommand [MMSYSTEM.701]
2045 DWORD WINAPI mciSendCommand(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1,
2046 DWORD dwParam2)
2048 TRACE(mmsys, "(%04X, %s, %08lX, %08lX)\n",
2049 wDevID, _mciCommandToString(wMsg), dwParam1, dwParam2);
2051 switch (wMsg) {
2052 case MCI_OPEN:
2053 return mciOpen16(dwParam1, (LPMCI_OPEN_PARMS16)dwParam2);
2054 case MCI_CLOSE:
2055 return mciClose16(wDevID, dwParam1,
2056 (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
2057 case MCI_SYSINFO:
2058 return mciSysInfo16(dwParam1,
2059 (LPMCI_SYSINFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
2060 default:
2062 DWORD dwRet = MCIERR_INTERNAL;
2063 LONG (*proc)(DWORD, HDRVR16, WORD, DWORD, DWORD) = 0;
2065 if (wDevID == MCI_ALL_DEVICE_ID) {
2066 FIXME(mci, "unhandled MCI_ALL_DEVICE_ID\n");
2067 return MCIERR_CANNOT_USE_ALL;
2070 if (!MMSYSTEM_DevIDValid(wDevID))
2071 return MMSYSERR_INVALPARAM;
2073 switch (mciGetDrv(wDevID)->modp.wType) {
2074 case MCI_DEVTYPE_CD_AUDIO: proc = CDAUDIO_DriverProc16; break;
2075 case MCI_DEVTYPE_WAVEFORM_AUDIO: proc = WAVE_DriverProc16; break;
2076 case MCI_DEVTYPE_SEQUENCER: proc = MIDI_DriverProc16; break;
2077 /* case MCI_DEVTYPE_ANIMATION: proc = ANIM_DriverProc16; break;*/
2079 if (proc) {
2080 dwRet = (proc)(mciGetDrv(wDevID)->modp.wDeviceID, mciGetDrv(wDevID)->hDrv, wMsg, dwParam1, dwParam2);
2081 } else if (mciGetDrv(wDevID)->driverProc) {
2082 dwRet = Callbacks->CallDriverProc(mciGetDrv(wDevID)->driverProc,
2083 mciGetDrv(wDevID)->modp.wDeviceID,
2084 mciGetDrv(wDevID)->hDrv,wMsg, dwParam1, dwParam2);
2085 } else {
2086 WARN(mmsys, "unknown device type=%04X !\n", mciGetDrv(wDevID)->modp.wType);
2088 return dwRet;
2091 return MMSYSERR_INVALPARAM;
2094 /**************************************************************************
2095 * mciGetDeviceID [MMSYSTEM.703]
2097 UINT16 WINAPI mciGetDeviceID(LPCSTR lpstrName)
2099 UINT16 wDevID;
2101 TRACE(mmsys, "(\"%s\")\n", lpstrName);
2103 if (!lpstrName)
2104 return 0;
2106 if (!lstrcmpi32A(lpstrName, "ALL"))
2107 return MCI_ALL_DEVICE_ID;
2109 wDevID = MMSYSTEM_FirstDevID();
2110 while (MMSYSTEM_DevIDValid(wDevID) && mciGetDrv(wDevID)->modp.wType) {
2111 if (mciGetOpenDrv(wDevID)->lpstrDeviceType && strcmp(mciGetOpenDrv(wDevID)->lpstrDeviceType, lpstrName) == 0)
2112 return wDevID;
2114 if (mciGetOpenDrv(wDevID)->lpstrAlias && strcmp(mciGetOpenDrv(wDevID)->lpstrAlias, lpstrName) == 0)
2115 return wDevID;
2117 wDevID = MMSYSTEM_NextDevID(wDevID);
2120 return 0;
2123 /**************************************************************************
2124 * mciSetYieldProc [MMSYSTEM.714]
2126 BOOL16 WINAPI mciSetYieldProc (UINT16 uDeviceID,
2127 YIELDPROC fpYieldProc, DWORD dwYieldData)
2129 return FALSE;
2132 /**************************************************************************
2133 * mciGetDeviceIDFromElementID [MMSYSTEM.715]
2135 UINT16 WINAPI mciGetDeviceIDFromElementID(DWORD dwElementID, LPCSTR lpstrType)
2137 return 0;
2140 /**************************************************************************
2141 * mciGetYieldProc [MMSYSTEM.716]
2143 YIELDPROC WINAPI mciGetYieldProc(UINT16 uDeviceID, DWORD * lpdwYieldData)
2145 return NULL;
2148 /**************************************************************************
2149 * mciGetCreatorTask [MMSYSTEM.717]
2151 HTASK16 WINAPI mciGetCreatorTask(UINT16 uDeviceID)
2153 return 0;
2156 /**************************************************************************
2157 * midiOutGetNumDevs [WINMM.80]
2159 UINT32 WINAPI midiOutGetNumDevs32(void)
2161 return midiOutGetNumDevs16();
2163 /**************************************************************************
2164 * midiOutGetNumDevs [MMSYSTEM.201]
2166 UINT16 WINAPI midiOutGetNumDevs16(void)
2168 UINT16 count = modMessage(0, MODM_GETNUMDEVS, 0L, 0L, 0L);
2169 TRACE(mmsys, "returns %u\n", count);
2170 return count;
2173 /**************************************************************************
2174 * midiOutGetDevCapsW [WINMM.76]
2176 UINT32 WINAPI midiOutGetDevCaps32W(UINT32 uDeviceID,LPMIDIOUTCAPS32W lpCaps, UINT32 uSize)
2178 MIDIOUTCAPS16 moc16;
2179 UINT32 ret;
2181 ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
2182 lpCaps->wMid = moc16.wMid;
2183 lpCaps->wPid = moc16.wPid;
2184 lpCaps->vDriverVersion = moc16.vDriverVersion;
2185 lstrcpyAtoW(lpCaps->szPname,moc16.szPname);
2186 lpCaps->wTechnology = moc16.wTechnology;
2187 lpCaps->wVoices = moc16.wVoices;
2188 lpCaps->wNotes = moc16.wNotes;
2189 lpCaps->wChannelMask = moc16.wChannelMask;
2190 lpCaps->dwSupport = moc16.dwSupport;
2191 return ret;
2193 /**************************************************************************
2194 * midiOutGetDevCapsA [WINMM.75]
2196 UINT32 WINAPI midiOutGetDevCaps32A(UINT32 uDeviceID,LPMIDIOUTCAPS32A lpCaps, UINT32 uSize)
2198 MIDIOUTCAPS16 moc16;
2199 UINT32 ret;
2201 ret = midiOutGetDevCaps16(uDeviceID,&moc16,sizeof(moc16));
2202 lpCaps->wMid = moc16.wMid;
2203 lpCaps->wPid = moc16.wPid;
2204 lpCaps->vDriverVersion = moc16.vDriverVersion;
2205 strcpy(lpCaps->szPname,moc16.szPname);
2206 lpCaps->wTechnology = moc16.wTechnology;
2207 lpCaps->wVoices = moc16.wVoices;
2208 lpCaps->wNotes = moc16.wNotes;
2209 lpCaps->wChannelMask = moc16.wChannelMask;
2210 lpCaps->dwSupport = moc16.dwSupport;
2211 return ret;
2214 /**************************************************************************
2215 * midiOutGetDevCaps [MMSYSTEM.202]
2217 UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID,LPMIDIOUTCAPS16 lpCaps, UINT16 uSize)
2219 TRACE(mmsys, "midiOutGetDevCaps\n");
2220 return modMessage(uDeviceID,MODM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);
2223 /**************************************************************************
2224 * midiOutGetErrorTextA [WINMM.77]
2226 UINT32 WINAPI midiOutGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
2228 TRACE(mmsys, "midiOutGetErrorText\n");
2229 return midiGetErrorText(uError, lpText, uSize);
2232 /**************************************************************************
2233 * midiOutGetErrorTextW [WINMM.78]
2235 UINT32 WINAPI midiOutGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
2237 LPSTR xstr = HeapAlloc(GetProcessHeap(),0,uSize);
2238 UINT32 ret;
2240 TRACE(mmsys, "midiOutGetErrorText\n");
2241 ret = midiGetErrorText(uError, xstr, uSize);
2242 lstrcpyAtoW(lpText,xstr);
2243 HeapFree(GetProcessHeap(),0,xstr);
2244 return ret;
2247 /**************************************************************************
2248 * midiOutGetErrorText [MMSYSTEM.203]
2250 UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
2252 TRACE(mmsys, "midiOutGetErrorText\n");
2253 return midiGetErrorText(uError, lpText, uSize);
2256 /**************************************************************************
2257 * midiGetErrorText [internal]
2259 UINT16 WINAPI midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
2261 LPSTR msgptr;
2262 if ((lpText == NULL) || (uSize < 1)) return(FALSE);
2263 lpText[0] = '\0';
2264 switch (uError) {
2265 case MIDIERR_UNPREPARED:
2266 msgptr = "The MIDI header was not prepared. Use the Prepare function to prepare the header, and then try again.";
2267 break;
2268 case MIDIERR_STILLPLAYING:
2269 msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
2270 break;
2271 case MIDIERR_NOMAP:
2272 msgptr = "A MIDI map was not found. There may be a problem with the driver, or the MIDIMAP.CFG file may be corrupt or missing.";
2273 break;
2274 case MIDIERR_NOTREADY:
2275 msgptr = "The port is transmitting data to the device. Wait until the data has been transmitted, and then try again.";
2276 break;
2277 case MIDIERR_NODEVICE:
2278 msgptr = "The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.";
2279 break;
2280 case MIDIERR_INVALIDSETUP:
2281 msgptr = "The current MIDI setup is damaged. Copy the original MIDIMAP.CFG file to the Windows SYSTEM directory, and then try again.";
2282 break;
2284 msg# 336 : Cannot use the song-pointer time format and the SMPTE time-format together.
2285 msg# 337 : The specified MIDI device is already in use. Wait until it is free, and then try again.
2286 msg# 338 : The specified MIDI device is not installed on the system. Use the Drivers option in Control Panel to install the driver.
2287 msg# 339 : The current MIDI Mapper setup refers to a MIDI device that is not installed on the system. Use MIDI Mapper to edit the setup.
2288 msg# 340 : An error occurred using the specified port.
2289 msg# 341 : All multimedia timers are being used by other applications. Quit one of these applications, and then try again.
2290 msg# 342 : There is no current MIDI port.
2291 msg# 343 : There are no MIDI devices installed on the system. Use the Drivers option in Control Panel to install the driver.
2293 default:
2294 msgptr = "Unknown MIDI Error !\n";
2295 break;
2297 lstrcpyn32A(lpText, msgptr, uSize);
2298 return TRUE;
2301 /**************************************************************************
2302 * midiOutOpen [WINM.84]
2304 UINT32 WINAPI midiOutOpen32(HMIDIOUT32 * lphMidiOut, UINT32 uDeviceID,
2305 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
2307 HMIDIOUT16 hmo16;
2308 UINT32 ret;
2310 ret = midiOutOpen16(&hmo16,uDeviceID,dwCallback,dwInstance,
2311 CALLBACK32CONV(dwFlags));
2312 if (lphMidiOut) *lphMidiOut = hmo16;
2313 return ret;
2316 /**************************************************************************
2317 * midiOutOpen [MMSYSTEM.204]
2319 UINT16 WINAPI midiOutOpen16(HMIDIOUT16 * lphMidiOut, UINT16 uDeviceID,
2320 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
2322 HMIDI16 hMidiOut;
2323 LPMIDIOPENDESC lpDesc;
2324 DWORD dwRet = 0;
2325 BOOL32 bMapperFlg = FALSE;
2327 if (lphMidiOut != NULL) *lphMidiOut = 0;
2328 TRACE(mmsys, "(%p, %d, %08lX, %08lX, %08lX);\n",
2329 lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
2330 if (uDeviceID == (UINT16)MIDI_MAPPER) {
2331 TRACE(mmsys, "MIDI_MAPPER mode requested !\n");
2332 bMapperFlg = TRUE;
2333 uDeviceID = 0;
2335 hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
2336 if (lphMidiOut != NULL)
2337 *lphMidiOut = hMidiOut;
2338 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2339 if (lpDesc == NULL)
2340 return MMSYSERR_NOMEM;
2341 lpDesc->hMidi = hMidiOut;
2342 lpDesc->dwCallback = dwCallback;
2343 lpDesc->dwInstance = dwInstance;
2345 while (uDeviceID < MAXMIDIDRIVERS) {
2346 dwRet = modMessage(uDeviceID, MODM_OPEN,
2347 lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
2348 if (dwRet == MMSYSERR_NOERROR) break;
2349 if (!bMapperFlg) break;
2350 uDeviceID++;
2351 TRACE(mmsys, "MIDI_MAPPER mode ! try next driver...\n");
2353 lpDesc->wDevID = uDeviceID;
2354 return dwRet;
2357 /**************************************************************************
2358 * midiOutClose [WINMM.74]
2360 UINT32 WINAPI midiOutClose32(HMIDIOUT32 hMidiOut)
2362 return midiOutClose16(hMidiOut);
2365 /**************************************************************************
2366 * midiOutClose [MMSYSTEM.205]
2368 UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
2370 LPMIDIOPENDESC lpDesc;
2371 TRACE(mmsys, "(%04X)\n", hMidiOut);
2372 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2373 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2374 return modMessage(lpDesc->wDevID, MODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
2377 /**************************************************************************
2378 * midiOutPrepareHeader [WINMM.85]
2380 UINT32 WINAPI midiOutPrepareHeader32(HMIDIOUT32 hMidiOut,
2381 MIDIHDR * lpMidiOutHdr, UINT32 uSize)
2383 LPMIDIOPENDESC lpDesc;
2384 TRACE(mmsys, "(%04X, %p, %d)\n",
2385 hMidiOut, lpMidiOutHdr, uSize);
2386 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2387 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2388 lpMidiOutHdr->reserved = (DWORD)lpMidiOutHdr->lpData;
2389 return modMessage(lpDesc->wDevID, MODM_PREPARE, lpDesc->dwInstance,
2390 (DWORD)lpMidiOutHdr, (DWORD)uSize);
2393 /**************************************************************************
2394 * midiOutPrepareHeader [MMSYSTEM.206]
2396 UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut,
2397 MIDIHDR * lpMidiOutHdr, UINT16 uSize)
2399 LPMIDIOPENDESC lpDesc;
2400 TRACE(mmsys, "(%04X, %p, %d)\n",
2401 hMidiOut, lpMidiOutHdr, uSize);
2402 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2403 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2404 lpMidiOutHdr->reserved = (DWORD)PTR_SEG_TO_LIN(lpMidiOutHdr->lpData);
2405 return modMessage(lpDesc->wDevID, MODM_PREPARE, lpDesc->dwInstance,
2406 (DWORD)lpMidiOutHdr, (DWORD)uSize);
2409 /**************************************************************************
2410 * midiOutUnprepareHeader [WINMM.89]
2412 UINT32 WINAPI midiOutUnprepareHeader32(HMIDIOUT32 hMidiOut,
2413 MIDIHDR * lpMidiOutHdr, UINT32 uSize)
2415 return midiOutUnprepareHeader16(hMidiOut,lpMidiOutHdr,uSize);
2418 /**************************************************************************
2419 * midiOutUnprepareHeader [MMSYSTEM.207]
2421 UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut,
2422 MIDIHDR * lpMidiOutHdr, UINT16 uSize)
2424 LPMIDIOPENDESC lpDesc;
2425 TRACE(mmsys, "(%04X, %p, %d)\n",
2426 hMidiOut, lpMidiOutHdr, uSize);
2427 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2428 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2429 return modMessage(lpDesc->wDevID, MODM_UNPREPARE, lpDesc->dwInstance,
2430 (DWORD)lpMidiOutHdr, (DWORD)uSize);
2433 /**************************************************************************
2434 * midiOutShortMsg [WINMM.88]
2436 UINT32 WINAPI midiOutShortMsg32(HMIDIOUT32 hMidiOut, DWORD dwMsg)
2438 return midiOutShortMsg16(hMidiOut,dwMsg);
2441 /**************************************************************************
2442 * midiOutShortMsg [MMSYSTEM.208]
2444 UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
2446 LPMIDIOPENDESC lpDesc;
2447 TRACE(mmsys, "(%04X, %08lX)\n", hMidiOut, dwMsg);
2448 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2449 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2450 return modMessage(lpDesc->wDevID, MODM_DATA, lpDesc->dwInstance, dwMsg, 0L);
2453 /**************************************************************************
2454 * midiOutLongMsg [WINMM.82]
2456 UINT32 WINAPI midiOutLongMsg32(HMIDIOUT32 hMidiOut,
2457 MIDIHDR * lpMidiOutHdr, UINT32 uSize)
2459 return midiOutLongMsg16(hMidiOut,lpMidiOutHdr,uSize);
2462 /**************************************************************************
2463 * midiOutLongMsg [MMSYSTEM.209]
2465 UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut,
2466 MIDIHDR * lpMidiOutHdr, UINT16 uSize)
2468 LPMIDIOPENDESC lpDesc;
2469 TRACE(mmsys, "(%04X, %p, %d)\n",
2470 hMidiOut, lpMidiOutHdr, uSize);
2471 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2472 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2473 return modMessage(lpDesc->wDevID, MODM_LONGDATA, lpDesc->dwInstance,
2474 (DWORD)lpMidiOutHdr, (DWORD)uSize);
2477 /**************************************************************************
2478 * midiOutReset [WINMM.86]
2480 UINT32 WINAPI midiOutReset32(HMIDIOUT32 hMidiOut)
2482 return midiOutReset16(hMidiOut);
2485 /**************************************************************************
2486 * midiOutReset [MMSYSTEM.210]
2488 UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
2490 LPMIDIOPENDESC lpDesc;
2491 TRACE(mmsys, "(%04X)\n", hMidiOut);
2492 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2493 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2494 return modMessage(lpDesc->wDevID, MODM_RESET, lpDesc->dwInstance, 0L, 0L);
2497 /**************************************************************************
2498 * midiOutGetVolume [WINM.81]
2500 UINT32 WINAPI midiOutGetVolume32(UINT32 uDeviceID, DWORD * lpdwVolume)
2502 return midiOutGetVolume16(uDeviceID,lpdwVolume);
2504 /**************************************************************************
2505 * midiOutGetVolume [MMSYSTEM.211]
2507 UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD * lpdwVolume)
2509 TRACE(mmsys, "(%04X, %p);\n", uDeviceID, lpdwVolume);
2510 return modMessage(uDeviceID, MODM_GETVOLUME, 0L, (DWORD)lpdwVolume, 0L);
2513 /**************************************************************************
2514 * midiOutSetVolume [WINMM.87]
2516 UINT32 WINAPI midiOutSetVolume32(UINT32 uDeviceID, DWORD dwVolume)
2518 return midiOutSetVolume16(uDeviceID,dwVolume);
2521 /**************************************************************************
2522 * midiOutSetVolume [MMSYSTEM.212]
2524 UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
2526 TRACE(mmsys, "(%04X, %08lX);\n", uDeviceID, dwVolume);
2527 return modMessage(uDeviceID, MODM_SETVOLUME, 0L, dwVolume, 0L);
2530 /**************************************************************************
2531 * midiOutCachePatches [WINMM.73]
2533 UINT32 WINAPI midiOutCachePatches32(HMIDIOUT32 hMidiOut, UINT32 uBank,
2534 WORD * lpwPatchArray, UINT32 uFlags)
2536 return midiOutCachePatches16(hMidiOut,uBank,lpwPatchArray,uFlags);
2539 /**************************************************************************
2540 * midiOutCachePatches [MMSYSTEM.213]
2542 UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
2543 WORD * lpwPatchArray, UINT16 uFlags)
2545 /* not really necessary to support this */
2546 FIXME(mmsys, "not supported yet\n");
2547 return MMSYSERR_NOTSUPPORTED;
2550 /**************************************************************************
2551 * midiOutCacheDrumPatches [WINMM.72]
2553 UINT32 WINAPI midiOutCacheDrumPatches32(HMIDIOUT32 hMidiOut, UINT32 uPatch,
2554 WORD * lpwKeyArray, UINT32 uFlags)
2556 return midiOutCacheDrumPatches16(hMidiOut,uPatch,lpwKeyArray,uFlags);
2559 /**************************************************************************
2560 * midiOutCacheDrumPatches [MMSYSTEM.214]
2562 UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
2563 WORD * lpwKeyArray, UINT16 uFlags)
2565 FIXME(mmsys, "not supported yet\n");
2566 return MMSYSERR_NOTSUPPORTED;
2569 /**************************************************************************
2570 * midiOutGetID [WINMM.79]
2572 UINT32 WINAPI midiOutGetID32(HMIDIOUT32 hMidiOut, UINT32 * lpuDeviceID)
2574 UINT16 xid;
2575 UINT32 ret;
2577 ret = midiOutGetID16(hMidiOut,&xid);
2578 *lpuDeviceID = xid;
2579 return ret;
2582 /**************************************************************************
2583 * midiOutGetID [MMSYSTEM.215]
2585 UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16 * lpuDeviceID)
2587 TRACE(mmsys, "midiOutGetID\n");
2588 return 0;
2591 /**************************************************************************
2592 * midiOutMessage [WINMM.83]
2594 DWORD WINAPI midiOutMessage32(HMIDIOUT32 hMidiOut, UINT32 uMessage,
2595 DWORD dwParam1, DWORD dwParam2)
2597 LPMIDIOPENDESC lpDesc;
2599 TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n",
2600 hMidiOut, uMessage, dwParam1, dwParam2);
2601 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2602 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2603 switch (uMessage) {
2604 case MODM_OPEN:
2605 FIXME(mmsys,"can't handle MODM_OPEN!\n");
2606 return 0;
2607 case MODM_GETDEVCAPS:
2608 return midiOutGetDevCaps32A(hMidiOut,(LPMIDIOUTCAPS32A)dwParam1,dwParam2);
2609 case MODM_GETNUMDEVS:
2610 case MODM_RESET:
2611 case MODM_CLOSE:
2612 case MODM_GETVOLUME:
2613 case MODM_SETVOLUME:
2614 case MODM_LONGDATA:
2615 case MODM_PREPARE:
2616 case MODM_UNPREPARE:
2617 /* no argument conversion needed */
2618 break;
2619 default:
2620 ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
2621 hMidiOut,uMessage,dwParam1,dwParam2);
2622 break;
2624 return modMessage(lpDesc->wDevID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2627 /**************************************************************************
2628 * midiOutMessage [MMSYSTEM.216]
2630 DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage,
2631 DWORD dwParam1, DWORD dwParam2)
2633 LPMIDIOPENDESC lpDesc;
2635 TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n",
2636 hMidiOut, uMessage, dwParam1, dwParam2);
2637 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiOut);
2638 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2639 switch (uMessage) {
2640 case MODM_OPEN:
2641 FIXME(mmsys,"can't handle MODM_OPEN!\n");
2642 return 0;
2643 case MODM_GETNUMDEVS:
2644 case MODM_RESET:
2645 case MODM_CLOSE:
2646 case MODM_SETVOLUME:
2647 /* no argument conversion needed */
2648 break;
2649 case MODM_GETVOLUME:
2650 return midiOutGetVolume16(hMidiOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
2651 case MODM_LONGDATA:
2652 return midiOutLongMsg16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2653 case MODM_PREPARE:
2654 return midiOutPrepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2655 case MODM_UNPREPARE:
2656 return midiOutUnprepareHeader16(hMidiOut,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
2657 default:
2658 ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
2659 hMidiOut,uMessage,dwParam1,dwParam2);
2660 break;
2662 return modMessage(lpDesc->wDevID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
2665 /**************************************************************************
2666 * midiInGetNumDevs [WINMM.64]
2668 UINT32 WINAPI midiInGetNumDevs32(void)
2670 return midiInGetNumDevs16();
2673 /**************************************************************************
2674 * midiInGetNumDevs [MMSYSTEM.301]
2676 UINT16 WINAPI midiInGetNumDevs16(void)
2678 UINT16 count = 0;
2679 TRACE(mmsys, "midiInGetNumDevs\n");
2680 count += midMessage(0, MIDM_GETNUMDEVS, 0L, 0L, 0L);
2681 TRACE(mmsys, "midiInGetNumDevs return %u \n", count);
2682 return count;
2685 /**************************************************************************
2686 * midiInGetDevCaps [WINMM.60]
2688 UINT32 WINAPI midiInGetDevCaps32W(UINT32 uDeviceID,
2689 LPMIDIINCAPS32W lpCaps, UINT32 uSize)
2691 MIDIINCAPS16 mic16;
2692 UINT32 ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
2694 lpCaps->wMid = mic16.wMid;
2695 lpCaps->wPid = mic16.wPid;
2696 lpCaps->vDriverVersion = mic16.vDriverVersion;
2697 lstrcpyAtoW(lpCaps->szPname,mic16.szPname);
2698 lpCaps->dwSupport = mic16.dwSupport;
2699 return ret;
2702 /**************************************************************************
2703 * midiInGetDevCaps [WINMM.59]
2705 UINT32 WINAPI midiInGetDevCaps32A(UINT32 uDeviceID,
2706 LPMIDIINCAPS32A lpCaps, UINT32 uSize)
2708 MIDIINCAPS16 mic16;
2709 UINT32 ret = midiInGetDevCaps16(uDeviceID,&mic16,uSize);
2711 lpCaps->wMid = mic16.wMid;
2712 lpCaps->wPid = mic16.wPid;
2713 lpCaps->vDriverVersion = mic16.vDriverVersion;
2714 strcpy(lpCaps->szPname,mic16.szPname);
2715 lpCaps->dwSupport = mic16.dwSupport;
2716 return ret;
2719 /**************************************************************************
2720 * midiInGetDevCaps [MMSYSTEM.302]
2722 UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID,
2723 LPMIDIINCAPS16 lpCaps, UINT16 uSize)
2725 TRACE(mmsys, "midiInGetDevCaps\n");
2726 return midMessage(uDeviceID,MIDM_GETDEVCAPS,0,(DWORD)lpCaps,uSize);;
2729 /**************************************************************************
2730 * midiInGetErrorText [WINMM.62]
2732 UINT32 WINAPI midiInGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
2734 LPSTR xstr = HeapAlloc(GetProcessHeap(),0,uSize);
2735 UINT32 ret = midiInGetErrorText16(uError,xstr,uSize);
2736 lstrcpyAtoW(lpText,xstr);
2737 HeapFree(GetProcessHeap(),0,xstr);
2738 return ret;
2740 /**************************************************************************
2741 * midiInGetErrorText [WINMM.61]
2743 UINT32 WINAPI midiInGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
2745 return midiInGetErrorText16(uError,lpText,uSize);
2748 /**************************************************************************
2749 * midiInGetErrorText [MMSYSTEM.303]
2751 UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
2753 TRACE(mmsys, "midiInGetErrorText\n");
2754 return (midiGetErrorText(uError, lpText, uSize));
2757 /**************************************************************************
2758 * midiInOpen [WINMM.66]
2760 UINT32 WINAPI midiInOpen32(HMIDIIN32 * lphMidiIn, UINT32 uDeviceID,
2761 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
2763 HMIDIIN16 xhmid16;
2764 UINT32 ret = midiInOpen16(&xhmid16,uDeviceID,dwCallback,dwInstance,
2765 CALLBACK32CONV(dwFlags));
2766 if (lphMidiIn)
2767 *lphMidiIn = xhmid16;
2768 return ret;
2771 /**************************************************************************
2772 * midiInOpen [MMSYSTEM.304]
2774 UINT16 WINAPI midiInOpen16(HMIDIIN16 * lphMidiIn, UINT16 uDeviceID,
2775 DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
2777 HMIDI16 hMidiIn;
2778 LPMIDIOPENDESC lpDesc;
2779 DWORD dwRet = 0;
2780 BOOL32 bMapperFlg = FALSE;
2782 if (lphMidiIn != NULL)
2783 *lphMidiIn = 0;
2784 TRACE(mmsys, "(%p, %d, %08lX, %08lX, %08lX);\n",
2785 lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
2786 if (uDeviceID == (UINT16)MIDI_MAPPER) {
2787 TRACE(mmsys, "MIDI_MAPPER mode requested !\n");
2788 bMapperFlg = TRUE;
2789 uDeviceID = 0;
2791 hMidiIn = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC));
2792 if (lphMidiIn != NULL)
2793 *lphMidiIn = hMidiIn;
2794 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2795 if (lpDesc == NULL)
2796 return MMSYSERR_NOMEM;
2797 lpDesc->hMidi = hMidiIn;
2798 lpDesc->dwCallback = dwCallback;
2799 lpDesc->dwInstance = dwInstance;
2801 while (uDeviceID < MAXMIDIDRIVERS) {
2802 dwRet = midMessage(uDeviceID, MIDM_OPEN,
2803 lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
2804 if (dwRet == MMSYSERR_NOERROR)
2805 break;
2806 if (!bMapperFlg)
2807 break;
2808 uDeviceID++;
2809 TRACE(mmsys, "MIDI_MAPPER mode ! try next driver...\n");
2811 lpDesc->wDevID = uDeviceID;
2812 return dwRet;
2815 /**************************************************************************
2816 * midiInClose [WINMM.58]
2818 UINT32 WINAPI midiInClose32(HMIDIIN32 hMidiIn)
2820 return midiInClose16(hMidiIn);
2823 /**************************************************************************
2824 * midiInClose [MMSYSTEM.305]
2826 UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
2828 LPMIDIOPENDESC lpDesc;
2829 TRACE(mmsys, "(%04X)\n", hMidiIn);
2830 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2831 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2832 return midMessage(lpDesc->wDevID, MIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
2835 /**************************************************************************
2836 * midiInPrepareHeader [WINMM.67]
2838 UINT32 WINAPI midiInPrepareHeader32(HMIDIIN32 hMidiIn,
2839 MIDIHDR * lpMidiInHdr, UINT32 uSize)
2841 LPMIDIOPENDESC lpDesc;
2843 TRACE(mmsys, "(%04X, %p, %d)\n",
2844 hMidiIn, lpMidiInHdr, uSize);
2845 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2846 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2847 lpMidiInHdr->reserved = (DWORD)lpMidiInHdr->lpData;
2848 return midMessage(lpDesc->wDevID, MIDM_PREPARE, lpDesc->dwInstance,
2849 (DWORD)lpMidiInHdr, (DWORD)uSize);
2852 /**************************************************************************
2853 * midiInPrepareHeader [MMSYSTEM.306]
2855 UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn,
2856 MIDIHDR * lpMidiInHdr, UINT16 uSize)
2858 LPMIDIOPENDESC lpDesc;
2860 TRACE(mmsys, "(%04X, %p, %d)\n",
2861 hMidiIn, lpMidiInHdr, uSize);
2862 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2863 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2864 lpMidiInHdr->reserved = (DWORD)PTR_SEG_TO_LIN(lpMidiInHdr->lpData);
2865 return midMessage(lpDesc->wDevID, MIDM_PREPARE, lpDesc->dwInstance,
2866 (DWORD)lpMidiInHdr, (DWORD)uSize);
2869 /**************************************************************************
2870 * midiInUnprepareHeader [WINMM.71]
2872 UINT32 WINAPI midiInUnprepareHeader32(HMIDIIN32 hMidiIn,
2873 MIDIHDR * lpMidiInHdr, UINT32 uSize)
2875 return midiInUnprepareHeader16(hMidiIn,lpMidiInHdr,uSize);
2878 /**************************************************************************
2879 * midiInUnprepareHeader [MMSYSTEM.307]
2881 UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn,
2882 MIDIHDR * lpMidiInHdr, UINT16 uSize)
2884 LPMIDIOPENDESC lpDesc;
2885 TRACE(mmsys, "(%04X, %p, %d)\n",
2886 hMidiIn, lpMidiInHdr, uSize);
2887 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2888 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
2889 return midMessage(lpDesc->wDevID, MIDM_UNPREPARE, lpDesc->dwInstance,
2890 (DWORD)lpMidiInHdr, (DWORD)uSize);
2893 /**************************************************************************
2894 * midiInAddBuffer [WINMM.57]
2896 UINT32 WINAPI midiInAddBuffer32(HMIDIIN32 hMidiIn,
2897 MIDIHDR * lpMidiInHdr, UINT32 uSize)
2899 return midiInAddBuffer16(hMidiIn,lpMidiInHdr,uSize);
2902 /**************************************************************************
2903 * midiInAddBuffer [MMSYSTEM.308]
2905 UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn,
2906 MIDIHDR * lpMidiInHdr, UINT16 uSize)
2908 TRACE(mmsys, "midiInAddBuffer\n");
2909 return 0;
2912 /**************************************************************************
2913 * midiInStart [WINMM.69]
2915 UINT32 WINAPI midiInStart32(HMIDIIN32 hMidiIn)
2917 return midiInStart16(hMidiIn);
2920 /**************************************************************************
2921 * midiInStart [MMSYSTEM.309]
2923 UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
2925 LPMIDIOPENDESC lpDesc;
2927 TRACE(mmsys, "(%04X)\n", hMidiIn);
2928 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2929 if (lpDesc == NULL)
2930 return MMSYSERR_INVALHANDLE;
2931 return midMessage(lpDesc->wDevID, MIDM_START, lpDesc->dwInstance, 0L, 0L);
2934 /**************************************************************************
2935 * midiInStop [WINMM.70]
2937 UINT32 WINAPI midiInStop32(HMIDIIN32 hMidiIn)
2939 return midiInStop16(hMidiIn);
2942 /**************************************************************************
2943 * midiInStop [MMSYSTEM.310]
2945 UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
2947 LPMIDIOPENDESC lpDesc;
2949 TRACE(mmsys, "(%04X)\n", hMidiIn);
2950 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2951 if (lpDesc == NULL)
2952 return MMSYSERR_INVALHANDLE;
2953 return midMessage(lpDesc->wDevID, MIDM_STOP, lpDesc->dwInstance, 0L, 0L);
2956 /**************************************************************************
2957 * midiInReset [WINMM.68]
2959 UINT32 WINAPI midiInReset32(HMIDIIN32 hMidiIn)
2961 return midiInReset16(hMidiIn);
2964 /**************************************************************************
2965 * midiInReset [MMSYSTEM.311]
2967 UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
2969 LPMIDIOPENDESC lpDesc;
2971 TRACE(mmsys, "(%04X)\n", hMidiIn);
2972 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2973 if (lpDesc == NULL)
2974 return MMSYSERR_INVALHANDLE;
2975 return midMessage(lpDesc->wDevID, MIDM_RESET, lpDesc->dwInstance, 0L, 0L);
2978 /**************************************************************************
2979 * midiInGetID [WINMM.63]
2981 UINT32 WINAPI midiInGetID32(HMIDIIN32 hMidiIn, UINT32* lpuDeviceID)
2983 LPMIDIOPENDESC lpDesc;
2985 TRACE(mmsys, "(%04X, %p)\n", hMidiIn, lpuDeviceID);
2986 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
2987 if (lpDesc == NULL)
2988 return MMSYSERR_INVALHANDLE;
2989 if (lpuDeviceID == NULL)
2990 return MMSYSERR_INVALPARAM;
2991 *lpuDeviceID = lpDesc->wDevID;
2993 return MMSYSERR_NOERROR;
2996 /**************************************************************************
2997 * midiInGetID [MMSYSTEM.312]
2999 UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
3001 LPMIDIOPENDESC lpDesc;
3003 TRACE(mmsys, "(%04X, %p)\n", hMidiIn, lpuDeviceID);
3004 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
3005 if (lpDesc == NULL)
3006 return MMSYSERR_INVALHANDLE;
3007 if (lpuDeviceID == NULL)
3008 return MMSYSERR_INVALPARAM;
3009 *lpuDeviceID = lpDesc->wDevID;
3011 return MMSYSERR_NOERROR;
3014 /**************************************************************************
3015 * midiInMessage [WINMM.65]
3017 DWORD WINAPI midiInMessage32(HMIDIIN32 hMidiIn, UINT32 uMessage,
3018 DWORD dwParam1, DWORD dwParam2)
3020 LPMIDIOPENDESC lpDesc;
3022 TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n",
3023 hMidiIn, uMessage, dwParam1, dwParam2);
3024 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
3025 if (lpDesc == NULL)
3026 return MMSYSERR_INVALHANDLE;
3028 switch (uMessage) {
3029 case MIDM_OPEN:
3030 FIXME(mmsys,"can't handle MIDM_OPEN!\n");
3031 return 0;
3032 case MIDM_GETDEVCAPS:
3033 return midiInGetDevCaps32A(hMidiIn,(LPMIDIINCAPS32A)dwParam1,dwParam2);
3034 case MIDM_GETNUMDEVS:
3035 case MIDM_RESET:
3036 case MIDM_STOP:
3037 case MIDM_START:
3038 case MIDM_CLOSE:
3039 /* no argument conversion needed */
3040 break;
3041 case MIDM_PREPARE:
3042 return midiInPrepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
3043 case MIDM_UNPREPARE:
3044 return midiInUnprepareHeader32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
3045 case MIDM_ADDBUFFER:
3046 return midiInAddBuffer32(hMidiIn,(LPMIDIHDR)dwParam1,dwParam2);
3047 default:
3048 ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
3049 hMidiIn,uMessage,dwParam1,dwParam2);
3050 break;
3052 return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
3055 /**************************************************************************
3056 * midiInMessage [MMSYSTEM.313]
3058 DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage,
3059 DWORD dwParam1, DWORD dwParam2)
3061 LPMIDIOPENDESC lpDesc;
3062 TRACE(mmsys, "(%04X, %04X, %08lX, %08lX)\n",
3063 hMidiIn, uMessage, dwParam1, dwParam2);
3064 lpDesc = (LPMIDIOPENDESC) USER_HEAP_LIN_ADDR(hMidiIn);
3065 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3066 switch (uMessage) {
3067 case MIDM_OPEN:
3068 WARN(mmsys,"can't handle MIDM_OPEN!\n");
3069 return 0;
3070 case MIDM_GETDEVCAPS:
3071 return midiInGetDevCaps16(hMidiIn,(LPMIDIINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3072 case MIDM_GETNUMDEVS:
3073 case MIDM_RESET:
3074 case MIDM_STOP:
3075 case MIDM_START:
3076 case MIDM_CLOSE:
3077 /* no argument conversion needed */
3078 break;
3079 case MIDM_PREPARE:
3080 return midiInPrepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3081 case MIDM_UNPREPARE:
3082 return midiInUnprepareHeader16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3083 case MIDM_ADDBUFFER:
3084 return midiInAddBuffer16(hMidiIn,(LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3085 default:
3086 ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
3087 hMidiIn,uMessage,dwParam1,dwParam2);
3088 break;
3090 return midMessage(0, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
3093 /**************************************************************************
3094 * midiStreamOpen [MMSYSTEM.91]
3096 MMRESULT32 WINAPI midiStreamOpen32(HMIDISTRM32 *phms,LPUINT32 devid,DWORD cMidi,DWORD dwCallback,DWORD dwInstance,DWORD fdwOpen) {
3097 FIXME(midi,"(%p,%p,%d,%p,%p,0x%08lx),stub!\n",phms,devid,cMidi,dwCallback,dwInstance,fdwOpen);
3098 return MMSYSERR_NOTSUPPORTED;
3102 /**************************************************************************
3103 * waveOutGetNumDevs [MMSYSTEM.401]
3105 UINT32 WINAPI waveOutGetNumDevs32() {
3106 return waveOutGetNumDevs16();
3109 /**************************************************************************
3110 * waveOutGetNumDevs [WINMM.167]
3112 UINT16 WINAPI waveOutGetNumDevs16()
3114 UINT16 count = 0;
3115 TRACE(mmsys, "waveOutGetNumDevs\n");
3116 count += wodMessage( MMSYSTEM_FirstDevID(), WODM_GETNUMDEVS, 0L, 0L, 0L);
3117 TRACE(mmsys, "waveOutGetNumDevs return %u \n", count);
3118 return count;
3121 /**************************************************************************
3122 * waveOutGetDevCaps [MMSYSTEM.402]
3124 UINT16 WINAPI waveOutGetDevCaps16(UINT16 uDeviceID, WAVEOUTCAPS16 * lpCaps,
3125 UINT16 uSize)
3127 if (uDeviceID > waveOutGetNumDevs16() - 1) return MMSYSERR_BADDEVICEID;
3128 if (uDeviceID == (UINT16)WAVE_MAPPER) return MMSYSERR_BADDEVICEID; /* FIXME: do we have a wave mapper ? */
3129 TRACE(mmsys, "waveOutGetDevCaps\n");
3130 return wodMessage(uDeviceID, WODM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
3133 /**************************************************************************
3134 * waveOutGetDevCapsA [WINMM.162]
3136 UINT32 WINAPI waveOutGetDevCaps32A(UINT32 uDeviceID, LPWAVEOUTCAPS32A lpCaps,
3137 UINT32 uSize)
3139 WAVEOUTCAPS16 woc16;
3140 UINT16 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
3142 lpCaps->wMid = woc16.wMid;
3143 lpCaps->wPid = woc16.wPid;
3144 lpCaps->vDriverVersion = woc16.vDriverVersion;
3145 strcpy(lpCaps->szPname,woc16.szPname);
3146 lpCaps->dwFormats = woc16.dwFormats;
3147 lpCaps->wChannels = woc16.wChannels;
3148 lpCaps->dwSupport = woc16.dwSupport;
3149 return ret;
3152 /**************************************************************************
3153 * waveOutGetDevCapsW [WINMM.163]
3155 UINT32 WINAPI waveOutGetDevCaps32W(UINT32 uDeviceID, LPWAVEOUTCAPS32W lpCaps,
3156 UINT32 uSize)
3158 WAVEOUTCAPS16 woc16;
3159 UINT32 ret = waveOutGetDevCaps16(uDeviceID,&woc16,sizeof(woc16));
3161 lpCaps->wMid = woc16.wMid;
3162 lpCaps->wPid = woc16.wPid;
3163 lpCaps->vDriverVersion = woc16.vDriverVersion;
3164 lstrcpyAtoW(lpCaps->szPname,woc16.szPname);
3165 lpCaps->dwFormats = woc16.dwFormats;
3166 lpCaps->wChannels = woc16.wChannels;
3167 lpCaps->dwSupport = woc16.dwSupport;
3168 return ret;
3171 /**************************************************************************
3172 * waveOutGetErrorText [MMSYSTEM.403]
3174 UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
3176 TRACE(mmsys, "waveOutGetErrorText\n");
3177 return(waveGetErrorText(uError, lpText, uSize));
3180 /**************************************************************************
3181 * waveOutGetErrorTextA [WINMM.164]
3183 UINT32 WINAPI waveOutGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
3185 return(waveOutGetErrorText16(uError, lpText, uSize));
3188 /**************************************************************************
3189 * waveOutGetErrorTextW [WINMM.165]
3191 UINT32 WINAPI waveOutGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
3193 LPSTR xstr = HeapAlloc(GetProcessHeap(),0,uSize);
3194 UINT32 ret = waveOutGetErrorText32A(uError, xstr, uSize);
3196 lstrcpyAtoW(lpText,xstr);
3197 HeapFree(GetProcessHeap(),0,xstr);
3198 return ret;
3202 /**************************************************************************
3203 * waveGetErrorText [internal]
3205 static UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
3207 LPSTR msgptr;
3208 TRACE(mmsys, "(%04X, %p, %d);\n",
3209 uError, lpText, uSize);
3210 if ((lpText == NULL) || (uSize < 1)) return(FALSE);
3211 lpText[0] = '\0';
3212 switch (uError) {
3213 case MMSYSERR_NOERROR:
3214 msgptr = "The specified command was carried out.";
3215 break;
3216 case MMSYSERR_ERROR:
3217 msgptr = "Undefined external error.";
3218 break;
3219 case MMSYSERR_BADDEVICEID:
3220 msgptr = "A device ID has been used that is out of range for your system.";
3221 break;
3222 case MMSYSERR_NOTENABLED:
3223 msgptr = "The driver was not enabled.";
3224 break;
3225 case MMSYSERR_ALLOCATED:
3226 msgptr = "The specified device is already in use. Wait until it is free, and then try again.";
3227 break;
3228 case MMSYSERR_INVALHANDLE:
3229 msgptr = "The specified device handle is invalid.";
3230 break;
3231 case MMSYSERR_NODRIVER:
3232 msgptr = "There is no driver installed on your system !\n";
3233 break;
3234 case MMSYSERR_NOMEM:
3235 msgptr = "Not enough memory available for this task. Quit one or more applications to increase available memory, and then try again.";
3236 break;
3237 case MMSYSERR_NOTSUPPORTED:
3238 msgptr = "This function is not supported. Use the Capabilities function to determine which functions and messages the driver supports.";
3239 break;
3240 case MMSYSERR_BADERRNUM:
3241 msgptr = "An error number was specified that is not defined in the system.";
3242 break;
3243 case MMSYSERR_INVALFLAG:
3244 msgptr = "An invalid flag was passed to a system function.";
3245 break;
3246 case MMSYSERR_INVALPARAM:
3247 msgptr = "An invalid parameter was passed to a system function.";
3248 break;
3249 case WAVERR_BADFORMAT:
3250 msgptr = "The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats";
3251 break;
3252 case WAVERR_STILLPLAYING:
3253 msgptr = "Cannot perform this operation while media data is still playing. Reset the device, or wait until the data is finished playing.";
3254 break;
3255 case WAVERR_UNPREPARED:
3256 msgptr = "The wave header was not prepared. Use the Prepare function to prepare the header, and then try again.";
3257 break;
3258 case WAVERR_SYNC:
3259 msgptr = "Cannot open the device without using the WAVE_ALLOWSYNC flag. Use the flag, and then try again.";
3260 break;
3261 default:
3262 msgptr = "Unknown MMSYSTEM Error !\n";
3263 break;
3265 lstrcpyn32A(lpText, msgptr, uSize);
3266 return TRUE;
3269 /**************************************************************************
3270 * waveOutOpen [WINMM.173]
3271 * All the args/structs have the same layout as the win16 equivalents
3273 UINT32 WINAPI waveOutOpen32(HWAVEOUT32 * lphWaveOut, UINT32 uDeviceID,
3274 const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
3275 DWORD dwInstance, DWORD dwFlags)
3277 HWAVEOUT16 hwo16;
3278 UINT32 ret = waveOutOpen16(&hwo16,uDeviceID,lpFormat,dwCallback,dwInstance,
3279 CALLBACK32CONV(dwFlags));
3281 if (lphWaveOut) *lphWaveOut=hwo16;
3282 return ret;
3284 /**************************************************************************
3285 * waveOutOpen [MMSYSTEM.404]
3287 UINT16 WINAPI waveOutOpen16(HWAVEOUT16 * lphWaveOut, UINT16 uDeviceID,
3288 const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
3289 DWORD dwInstance, DWORD dwFlags)
3291 HWAVEOUT16 hWaveOut;
3292 LPWAVEOPENDESC lpDesc;
3293 DWORD dwRet = 0;
3294 BOOL32 bMapperFlg = FALSE;
3296 TRACE(mmsys, "(%p, %d, %p, %08lX, %08lX, %08lX);\n",
3297 lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
3298 if (dwFlags & WAVE_FORMAT_QUERY)
3299 TRACE(mmsys, "WAVE_FORMAT_QUERY requested !\n");
3300 if (uDeviceID == (UINT16)WAVE_MAPPER) {
3301 TRACE(mmsys, "WAVE_MAPPER mode requested !\n");
3302 bMapperFlg = TRUE;
3303 uDeviceID = 0;
3305 if (lpFormat == NULL) return WAVERR_BADFORMAT;
3307 hWaveOut = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
3308 if (lphWaveOut != NULL) *lphWaveOut = hWaveOut;
3309 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3310 if (lpDesc == NULL) return MMSYSERR_NOMEM;
3311 lpDesc->hWave = hWaveOut;
3312 lpDesc->lpFormat = (LPWAVEFORMAT)lpFormat; /* should the struct be copied iso pointer? */
3313 lpDesc->dwCallBack = dwCallback;
3314 lpDesc->dwInstance = dwInstance;
3315 if (uDeviceID >= MAXWAVEDRIVERS)
3316 uDeviceID = 0;
3317 while (uDeviceID < MAXWAVEDRIVERS) {
3318 dwRet = wodMessage(uDeviceID, WODM_OPEN,
3319 lpDesc->dwInstance, (DWORD)lpDesc, dwFlags);
3320 if (dwRet == MMSYSERR_NOERROR) break;
3321 if (!bMapperFlg) break;
3322 uDeviceID++;
3323 TRACE(mmsys, "WAVE_MAPPER mode ! try next driver...\n");
3325 lpDesc->uDeviceID = uDeviceID; /* save physical Device ID */
3326 if (dwFlags & WAVE_FORMAT_QUERY) {
3327 TRACE(mmsys, "End of WAVE_FORMAT_QUERY !\n");
3328 dwRet = waveOutClose32(hWaveOut);
3330 return dwRet;
3333 /**************************************************************************
3334 * waveOutClose [WINMM.161]
3336 UINT32 WINAPI waveOutClose32(HWAVEOUT32 hWaveOut)
3338 return waveOutClose16(hWaveOut);
3340 /**************************************************************************
3341 * waveOutClose [MMSYSTEM.405]
3343 UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
3345 LPWAVEOPENDESC lpDesc;
3347 TRACE(mmsys, "(%04X)\n", hWaveOut);
3348 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3349 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3350 return wodMessage( lpDesc->uDeviceID, WODM_CLOSE, lpDesc->dwInstance, 0L, 0L);
3353 /**************************************************************************
3354 * waveOutPrepareHeader [WINMM.175]
3356 UINT32 WINAPI waveOutPrepareHeader32(HWAVEOUT32 hWaveOut,
3357 WAVEHDR * lpWaveOutHdr, UINT32 uSize)
3359 LPWAVEOPENDESC lpDesc;
3361 TRACE(mmsys, "(%04X, %p, %u);\n",
3362 hWaveOut, lpWaveOutHdr, uSize);
3363 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3364 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3365 return wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance,
3366 (DWORD)lpWaveOutHdr,uSize);
3368 /**************************************************************************
3369 * waveOutPrepareHeader [MMSYSTEM.406]
3371 UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut,
3372 WAVEHDR * lpWaveOutHdr, UINT16 uSize)
3374 LPWAVEOPENDESC lpDesc;
3375 LPBYTE saveddata = lpWaveOutHdr->lpData;
3376 UINT16 ret;
3378 TRACE(mmsys, "(%04X, %p, %u);\n",
3379 hWaveOut, lpWaveOutHdr, uSize);
3380 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3381 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3382 lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
3383 ret = wodMessage( lpDesc->uDeviceID, WODM_PREPARE, lpDesc->dwInstance,
3384 (DWORD)lpWaveOutHdr,uSize);
3385 lpWaveOutHdr->lpData = saveddata;
3386 return ret;
3389 /**************************************************************************
3390 * waveOutUnprepareHeader [WINMM.181]
3392 UINT32 WINAPI waveOutUnprepareHeader32(HWAVEOUT32 hWaveOut,
3393 WAVEHDR * lpWaveOutHdr, UINT32 uSize)
3395 LPWAVEOPENDESC lpDesc;
3397 TRACE(mmsys, "(%04X, %p, %u);\n",
3398 hWaveOut, lpWaveOutHdr, uSize);
3399 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3400 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3401 return wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance,
3402 (DWORD)lpWaveOutHdr, uSize);
3404 /**************************************************************************
3405 * waveOutUnprepareHeader [MMSYSTEM.407]
3407 UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut,
3408 WAVEHDR * lpWaveOutHdr, UINT16 uSize)
3410 LPWAVEOPENDESC lpDesc;
3411 LPBYTE saveddata = lpWaveOutHdr->lpData;
3412 UINT16 ret;
3414 TRACE(mmsys, "(%04X, %p, %u);\n",
3415 hWaveOut, lpWaveOutHdr, uSize);
3416 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3417 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3418 lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
3419 ret = wodMessage(lpDesc->uDeviceID,WODM_UNPREPARE,lpDesc->dwInstance,
3420 (DWORD)lpWaveOutHdr, uSize);
3421 lpWaveOutHdr->lpData = saveddata;
3422 return ret;
3425 /**************************************************************************
3426 * waveOutWrite [MMSYSTEM.408]
3428 UINT32 WINAPI waveOutWrite32(HWAVEOUT32 hWaveOut, WAVEHDR * lpWaveOutHdr,
3429 UINT32 uSize)
3431 LPWAVEOPENDESC lpDesc;
3432 TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
3433 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3434 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3435 lpWaveOutHdr->reserved = (DWORD)lpWaveOutHdr->lpData;
3436 return wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
3438 /**************************************************************************
3439 * waveOutWrite [MMSYSTEM.408]
3441 UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, WAVEHDR * lpWaveOutHdr,
3442 UINT16 uSize)
3444 LPWAVEOPENDESC lpDesc;
3445 UINT16 ret;
3447 TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
3448 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3449 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3450 lpWaveOutHdr->reserved=(DWORD)lpWaveOutHdr->lpData;/*save original ptr*/
3451 lpWaveOutHdr->lpData = PTR_SEG_TO_LIN(lpWaveOutHdr->lpData);
3452 ret = wodMessage( lpDesc->uDeviceID, WODM_WRITE, lpDesc->dwInstance, (DWORD)lpWaveOutHdr, uSize);
3453 lpWaveOutHdr->lpData = (LPBYTE)lpWaveOutHdr->reserved;
3454 return ret;
3457 /**************************************************************************
3458 * waveOutPause [WINMM.174]
3460 UINT32 WINAPI waveOutPause32(HWAVEOUT32 hWaveOut)
3462 return waveOutPause16(hWaveOut);
3465 /**************************************************************************
3466 * waveOutPause [MMSYSTEM.409]
3468 UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut)
3470 LPWAVEOPENDESC lpDesc;
3472 TRACE(mmsys, "(%04X)\n", hWaveOut);
3473 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3474 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3475 return wodMessage( lpDesc->uDeviceID, WODM_PAUSE, lpDesc->dwInstance, 0L, 0L);
3478 /**************************************************************************
3479 * waveOutRestart [WINMM.177]
3481 UINT32 WINAPI waveOutRestart32(HWAVEOUT32 hWaveOut)
3483 return waveOutRestart16(hWaveOut);
3486 /**************************************************************************
3487 * waveOutRestart [MMSYSTEM.410]
3489 UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut)
3491 LPWAVEOPENDESC lpDesc;
3493 TRACE(mmsys, "(%04X)\n", hWaveOut);
3494 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3495 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3496 return wodMessage( lpDesc->uDeviceID, WODM_RESTART, lpDesc->dwInstance, 0L, 0L);
3499 /**************************************************************************
3500 * waveOutReset [WINMM.176]
3502 UINT32 WINAPI waveOutReset32(HWAVEOUT32 hWaveOut)
3504 return waveOutReset16(hWaveOut);
3507 /**************************************************************************
3508 * waveOutReset [MMSYSTEM.411]
3510 UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut)
3512 LPWAVEOPENDESC lpDesc;
3513 TRACE(mmsys, "(%04X)\n", hWaveOut);
3514 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3515 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3516 return wodMessage( lpDesc->uDeviceID, WODM_RESET, lpDesc->dwInstance, 0L, 0L);
3519 /**************************************************************************
3520 * waveOutGetPosition [WINMM.170]
3522 UINT32 WINAPI waveOutGetPosition32(HWAVEOUT32 hWaveOut, LPMMTIME32 lpTime,
3523 UINT32 uSize)
3525 MMTIME16 mmt16;
3526 UINT32 ret;
3528 mmt16.wType = lpTime->wType;
3529 ret = waveOutGetPosition16(hWaveOut,&mmt16,sizeof(mmt16));
3530 MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
3531 return ret;
3533 /**************************************************************************
3534 * waveOutGetPosition [MMSYSTEM.412]
3536 UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut,LPMMTIME16 lpTime,
3537 UINT16 uSize)
3539 LPWAVEOPENDESC lpDesc;
3540 TRACE(mmsys, "(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
3541 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3542 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3543 return wodMessage( lpDesc->uDeviceID, WODM_GETPOS, lpDesc->dwInstance,
3544 (DWORD)lpTime, (DWORD)uSize);
3547 #define WAVEOUT_SHORTCUT_1(xx,XX,atype) \
3548 UINT32 WINAPI waveOut##xx##32(HWAVEOUT32 hWaveOut, atype x) \
3550 return waveOut##xx##16(hWaveOut,x); \
3552 UINT16 WINAPI waveOut##xx##16(HWAVEOUT16 hWaveOut, atype x) \
3554 LPWAVEOPENDESC lpDesc; \
3555 TRACE(mmsys, "waveOut"#xx"(%04X, %08lx);\n", hWaveOut,(DWORD)x);\
3556 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut); \
3557 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE; \
3558 return wodMessage(lpDesc->uDeviceID, WODM_##XX, lpDesc->dwInstance,\
3559 (DWORD)x, 0L); \
3562 WAVEOUT_SHORTCUT_1(GetPitch,GETPITCH,DWORD*)
3563 WAVEOUT_SHORTCUT_1(SetPitch,SETPITCH,DWORD)
3564 WAVEOUT_SHORTCUT_1(GetPlaybackRate,GETPLAYBACKRATE,DWORD*)
3565 WAVEOUT_SHORTCUT_1(SetPlaybackRate,SETPLAYBACKRATE,DWORD)
3567 #define WAVEOUT_SHORTCUT_2(xx,XX,atype) \
3568 UINT32 WINAPI waveOut##xx##32(UINT32 devid, atype x) \
3570 return waveOut##xx##16(devid,x); \
3572 UINT16 WINAPI waveOut##xx##16(UINT16 devid, atype x) \
3574 TRACE(mmsys, "waveOut"#xx"(%04X, %08lx);\n", devid,(DWORD)x); \
3575 return wodMessage(devid, WODM_##XX, 0L, (DWORD)x, 0L); \
3579 WAVEOUT_SHORTCUT_2(GetVolume,GETVOLUME,DWORD*)
3580 WAVEOUT_SHORTCUT_2(SetVolume,SETVOLUME,DWORD)
3583 /**************************************************************************
3584 * waveOutBreakLoop [MMSYSTEM.419]
3586 UINT32 WINAPI waveOutBreakLoop32(HWAVEOUT32 hWaveOut)
3588 return waveOutBreakLoop16(hWaveOut);
3590 /**************************************************************************
3591 * waveOutBreakLoop [MMSYSTEM.419]
3593 UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut)
3595 TRACE(mmsys, "(%04X)\n", hWaveOut);
3596 return MMSYSERR_INVALHANDLE;
3599 /**************************************************************************
3600 * waveOutGetID [MMSYSTEM.420]
3602 UINT32 WINAPI waveOutGetID32(HWAVEOUT32 hWaveOut, UINT32 * lpuDeviceID)
3604 LPWAVEOPENDESC lpDesc;
3605 TRACE(mmsys, "(%04X, %p);\n", hWaveOut, lpuDeviceID);
3606 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3607 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3608 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
3609 *lpuDeviceID = lpDesc->uDeviceID;
3610 return 0;
3612 /**************************************************************************
3613 * waveOutGetID [MMSYSTEM.420]
3615 UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16 * lpuDeviceID)
3617 LPWAVEOPENDESC lpDesc;
3618 TRACE(mmsys, "(%04X, %p);\n", hWaveOut, lpuDeviceID);
3619 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3620 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3621 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
3622 *lpuDeviceID = lpDesc->uDeviceID;
3623 return 0;
3626 /**************************************************************************
3627 * waveOutMessage [MMSYSTEM.421]
3629 DWORD WINAPI waveOutMessage32(HWAVEOUT32 hWaveOut, UINT32 uMessage,
3630 DWORD dwParam1, DWORD dwParam2)
3632 LPWAVEOPENDESC lpDesc;
3634 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3635 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3636 switch (uMessage) {
3637 case WODM_GETNUMDEVS:
3638 case WODM_GETPOS:
3639 case WODM_GETVOLUME:
3640 case WODM_GETPITCH:
3641 case WODM_GETPLAYBACKRATE:
3642 case WODM_SETVOLUME:
3643 case WODM_SETPITCH:
3644 case WODM_SETPLAYBACKRATE:
3645 case WODM_RESET:
3646 case WODM_PAUSE:
3647 case WODM_PREPARE:
3648 case WODM_UNPREPARE:
3649 case WODM_STOP:
3650 case WODM_CLOSE:
3651 /* no argument conversion needed */
3652 break;
3653 case WODM_WRITE:
3654 return waveOutWrite32(hWaveOut,(LPWAVEHDR)dwParam1,dwParam2);
3655 case WODM_GETDEVCAPS:
3656 /* FIXME: UNICODE/ANSI? */
3657 return waveOutGetDevCaps32A(hWaveOut,(LPWAVEOUTCAPS32A)dwParam1,dwParam2);
3658 case WODM_OPEN:
3659 FIXME(mmsys,"can't handle WODM_OPEN, please report.\n");
3660 break;
3661 default:
3662 ERR(mmsys,"(0x%04x,0x%04x,%08lx,%08lx): unhandled message\n",
3663 hWaveOut,uMessage,dwParam1,dwParam2);
3664 break;
3666 return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
3669 /**************************************************************************
3670 * waveOutMessage [MMSYSTEM.421]
3672 DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage,
3673 DWORD dwParam1, DWORD dwParam2)
3675 LPWAVEOPENDESC lpDesc;
3677 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveOut);
3678 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3679 switch (uMessage) {
3680 case WODM_GETNUMDEVS:
3681 case WODM_SETVOLUME:
3682 case WODM_SETPITCH:
3683 case WODM_SETPLAYBACKRATE:
3684 case WODM_RESET:
3685 case WODM_PAUSE:
3686 case WODM_STOP:
3687 case WODM_CLOSE:
3688 /* no argument conversion needed */
3689 break;
3690 case WODM_GETPOS:
3691 return waveOutGetPosition16(hWaveOut,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3692 case WODM_GETVOLUME:
3693 return waveOutGetVolume16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
3694 case WODM_GETPITCH:
3695 return waveOutGetPitch16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
3696 case WODM_GETPLAYBACKRATE:
3697 return waveOutGetPlaybackRate16(hWaveOut,(LPDWORD)PTR_SEG_TO_LIN(dwParam1));
3698 case WODM_GETDEVCAPS:
3699 return waveOutGetDevCaps16(hWaveOut,(LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3700 case WODM_PREPARE:
3701 return waveOutPrepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3702 case WODM_UNPREPARE:
3703 return waveOutUnprepareHeader16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3704 case WODM_WRITE:
3705 return waveOutWrite16(hWaveOut,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
3706 case WODM_OPEN:
3707 FIXME(mmsys,"can't handle WODM_OPEN, please report.\n");
3708 break;
3709 default:
3710 ERR(mmsys,"(0x%04x,0x%04x,%08lx,%08lx): unhandled message\n",
3711 hWaveOut,uMessage,dwParam1,dwParam2);
3713 return wodMessage( lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
3716 /**************************************************************************
3717 * waveInGetNumDevs [WINMM.151]
3719 UINT32 WINAPI waveInGetNumDevs32()
3721 return waveInGetNumDevs16();
3724 /**************************************************************************
3725 * waveInGetNumDevs [MMSYSTEM.501]
3727 UINT16 WINAPI waveInGetNumDevs16()
3729 UINT16 count = 0;
3730 TRACE(mmsys, "waveInGetNumDevs\n");
3731 count += widMessage(0, WIDM_GETNUMDEVS, 0L, 0L, 0L);
3732 TRACE(mmsys, "waveInGetNumDevs return %u \n", count);
3733 return count;
3736 /**************************************************************************
3737 * waveInGetDevCapsA [WINMM.147]
3739 UINT32 WINAPI waveInGetDevCaps32W(UINT32 uDeviceID, LPWAVEINCAPS32W lpCaps, UINT32 uSize)
3741 WAVEINCAPS16 wic16;
3742 UINT32 ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
3744 lpCaps->wMid = wic16.wMid;
3745 lpCaps->wPid = wic16.wPid;
3746 lpCaps->vDriverVersion = wic16.vDriverVersion;
3747 lstrcpyAtoW(lpCaps->szPname,wic16.szPname);
3748 lpCaps->dwFormats = wic16.dwFormats;
3749 lpCaps->wChannels = wic16.wChannels;
3751 return ret;
3753 /**************************************************************************
3754 * waveInGetDevCapsA [WINMM.146]
3756 UINT32 WINAPI waveInGetDevCaps32A(UINT32 uDeviceID, LPWAVEINCAPS32A lpCaps, UINT32 uSize)
3758 WAVEINCAPS16 wic16;
3759 UINT32 ret = waveInGetDevCaps16(uDeviceID,&wic16,uSize);
3761 lpCaps->wMid = wic16.wMid;
3762 lpCaps->wPid = wic16.wPid;
3763 lpCaps->vDriverVersion = wic16.vDriverVersion;
3764 strcpy(lpCaps->szPname,wic16.szPname);
3765 lpCaps->dwFormats = wic16.dwFormats;
3766 lpCaps->wChannels = wic16.wChannels;
3767 return ret;
3769 /**************************************************************************
3770 * waveInGetDevCaps [MMSYSTEM.502]
3772 UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps, UINT16 uSize)
3774 TRACE(mmsys, "waveInGetDevCaps\n");
3775 return widMessage(uDeviceID, WIDM_GETDEVCAPS, 0L, (DWORD)lpCaps, uSize);
3778 /**************************************************************************
3779 * waveInGetErrorTextA [WINMM.148]
3781 UINT32 WINAPI waveInGetErrorText32A(UINT32 uError, LPSTR lpText, UINT32 uSize)
3783 TRACE(mmsys, "waveInGetErrorText\n");
3784 return(waveGetErrorText(uError, lpText, uSize));
3787 /**************************************************************************
3788 * waveInGetErrorTextW [WINMM.149]
3790 UINT32 WINAPI waveInGetErrorText32W(UINT32 uError, LPWSTR lpText, UINT32 uSize)
3792 LPSTR txt = HeapAlloc(GetProcessHeap(),0,uSize);
3793 UINT32 ret = waveGetErrorText(uError, txt, uSize);
3795 lstrcpyAtoW(lpText,txt);
3796 HeapFree(GetProcessHeap(),0,txt);
3797 return ret;
3800 /**************************************************************************
3801 * waveInGetErrorText [MMSYSTEM.503]
3803 UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
3805 TRACE(mmsys, "waveInGetErrorText\n");
3806 return(waveGetErrorText(uError, lpText, uSize));
3810 /**************************************************************************
3811 * waveInOpen [WINMM.154]
3813 UINT32 WINAPI waveInOpen32(HWAVEIN32 * lphWaveIn, UINT32 uDeviceID,
3814 const LPWAVEFORMAT lpFormat, DWORD dwCallback,
3815 DWORD dwInstance, DWORD dwFlags)
3817 HWAVEIN16 hwin16;
3818 UINT32 ret = waveInOpen16(&hwin16,uDeviceID,lpFormat,dwCallback,dwInstance,
3819 CALLBACK32CONV(dwFlags));
3820 if (lphWaveIn) *lphWaveIn = hwin16;
3821 return ret;
3824 /**************************************************************************
3825 * waveInOpen [MMSYSTEM.504]
3827 UINT16 WINAPI waveInOpen16(HWAVEIN16 * lphWaveIn, UINT16 uDeviceID,
3828 const LPWAVEFORMAT lpFormat, DWORD dwCallback,
3829 DWORD dwInstance, DWORD dwFlags)
3831 HWAVEIN16 hWaveIn;
3832 LPWAVEOPENDESC lpDesc;
3833 DWORD dwRet = 0;
3834 BOOL32 bMapperFlg = FALSE;
3835 TRACE(mmsys, "(%p, %d, %p, %08lX, %08lX, %08lX);\n",
3836 lphWaveIn, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
3837 if (dwFlags & WAVE_FORMAT_QUERY)
3838 TRACE(mmsys, "WAVE_FORMAT_QUERY requested !\n");
3839 if (uDeviceID == (UINT16)WAVE_MAPPER) {
3840 TRACE(mmsys, "WAVE_MAPPER mode requested !\n");
3841 bMapperFlg = TRUE;
3842 uDeviceID = 0;
3844 if (lpFormat == NULL) return WAVERR_BADFORMAT;
3845 hWaveIn = USER_HEAP_ALLOC(sizeof(WAVEOPENDESC));
3846 if (lphWaveIn != NULL) *lphWaveIn = hWaveIn;
3847 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3848 if (lpDesc == NULL) return MMSYSERR_NOMEM;
3849 lpDesc->hWave = hWaveIn;
3850 lpDesc->lpFormat = lpFormat;
3851 lpDesc->dwCallBack = dwCallback;
3852 lpDesc->dwInstance = dwInstance;
3853 while (uDeviceID < MAXWAVEDRIVERS) {
3854 dwRet = widMessage(uDeviceID, WIDM_OPEN,
3855 lpDesc->dwInstance, (DWORD)lpDesc, 0L);
3856 if (dwRet == MMSYSERR_NOERROR) break;
3857 if (!bMapperFlg) break;
3858 uDeviceID++;
3859 TRACE(mmsys, "WAVE_MAPPER mode ! try next driver...\n");
3861 lpDesc->uDeviceID = uDeviceID;
3862 if (dwFlags & WAVE_FORMAT_QUERY) {
3863 TRACE(mmsys, "End of WAVE_FORMAT_QUERY !\n");
3864 dwRet = waveInClose16(hWaveIn);
3866 return dwRet;
3869 /**************************************************************************
3870 * waveInClose [WINMM.145]
3872 UINT32 WINAPI waveInClose32(HWAVEIN32 hWaveIn)
3874 return waveInClose16(hWaveIn);
3876 /**************************************************************************
3877 * waveInClose [MMSYSTEM.505]
3879 UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
3881 LPWAVEOPENDESC lpDesc;
3883 TRACE(mmsys, "(%04X)\n", hWaveIn);
3884 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3885 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3886 return widMessage(lpDesc->uDeviceID, WIDM_CLOSE, lpDesc->dwInstance, 0L, 0L);
3889 /**************************************************************************
3890 * waveInPrepareHeader [WINMM.155]
3892 UINT32 WINAPI waveInPrepareHeader32(HWAVEIN32 hWaveIn,
3893 WAVEHDR * lpWaveInHdr, UINT32 uSize)
3895 LPWAVEOPENDESC lpDesc;
3897 TRACE(mmsys, "(%04X, %p, %u);\n",
3898 hWaveIn, lpWaveInHdr, uSize);
3899 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3900 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3901 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3902 lpWaveInHdr = lpWaveInHdr;
3903 lpWaveInHdr->lpNext = NULL;
3904 lpWaveInHdr->dwBytesRecorded = 0;
3905 TRACE(mmsys, "lpData=%p size=%lu \n",
3906 lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
3907 return widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance,
3908 (DWORD)lpWaveInHdr, uSize);
3910 /**************************************************************************
3911 * waveInPrepareHeader [MMSYSTEM.506]
3913 UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn,
3914 WAVEHDR * lpWaveInHdr, UINT16 uSize)
3916 LPWAVEOPENDESC lpDesc;
3917 LPBYTE saveddata = lpWaveInHdr->lpData;
3918 UINT16 ret;
3920 TRACE(mmsys, "(%04X, %p, %u);\n",
3921 hWaveIn, lpWaveInHdr, uSize);
3922 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3923 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3924 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3925 lpWaveInHdr = lpWaveInHdr;
3926 lpWaveInHdr->lpNext = NULL;
3927 lpWaveInHdr->dwBytesRecorded = 0;
3929 TRACE(mmsys, "lpData=%p size=%lu \n",
3930 lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
3931 lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
3932 ret = widMessage(lpDesc->uDeviceID,WIDM_PREPARE,lpDesc->dwInstance,
3933 (DWORD)lpWaveInHdr,uSize);
3934 lpWaveInHdr->lpData = saveddata;
3935 return ret;
3939 /**************************************************************************
3940 * waveInUnprepareHeader [WINMM.159]
3942 UINT32 WINAPI waveInUnprepareHeader32(HWAVEIN32 hWaveIn,
3943 WAVEHDR * lpWaveInHdr, UINT32 uSize)
3945 LPWAVEOPENDESC lpDesc;
3947 TRACE(mmsys, "(%04X, %p, %u);\n",
3948 hWaveIn, lpWaveInHdr, uSize);
3949 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3950 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3951 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3952 /*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
3953 lpWaveInHdr->lpData = NULL;
3954 lpWaveInHdr->lpNext = NULL;
3955 return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance,
3956 (DWORD)lpWaveInHdr, uSize);
3958 /**************************************************************************
3959 * waveInUnprepareHeader [MMSYSTEM.507]
3961 UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn,
3962 WAVEHDR * lpWaveInHdr, UINT16 uSize)
3964 LPWAVEOPENDESC lpDesc;
3966 TRACE(mmsys, "(%04X, %p, %u);\n",
3967 hWaveIn, lpWaveInHdr, uSize);
3968 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3969 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3970 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3971 /*USER_HEAP_FREE(HIWORD((DWORD)lpWaveInHdr->lpData)); FIXME */
3972 lpWaveInHdr->lpData = NULL;
3973 lpWaveInHdr->lpNext = NULL;
3974 return widMessage(lpDesc->uDeviceID,WIDM_UNPREPARE,lpDesc->dwInstance,
3975 (DWORD)lpWaveInHdr, uSize);
3978 /**************************************************************************
3979 * waveInAddBuffer [WINMM.144]
3981 UINT32 WINAPI waveInAddBuffer32(HWAVEIN32 hWaveIn,
3982 WAVEHDR * lpWaveInHdr, UINT32 uSize)
3984 LPWAVEOPENDESC lpDesc;
3986 TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
3987 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
3988 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
3989 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
3990 lpWaveInHdr->lpNext = NULL;
3991 lpWaveInHdr->dwBytesRecorded = 0;
3992 TRACE(mmsys, "lpData=%p size=%lu \n",
3993 lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
3994 return widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
3995 (DWORD)lpWaveInHdr, uSize);
3999 /**************************************************************************
4000 * waveInAddBuffer [MMSYSTEM.508]
4002 UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn,
4003 WAVEHDR * lpWaveInHdr, UINT16 uSize)
4005 LPWAVEOPENDESC lpDesc;
4006 UINT16 ret;
4008 TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
4009 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4010 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4011 if (lpWaveInHdr == NULL) return MMSYSERR_INVALHANDLE;
4012 lpWaveInHdr->lpNext = NULL;
4013 lpWaveInHdr->dwBytesRecorded = 0;
4014 lpWaveInHdr->lpData = PTR_SEG_TO_LIN(lpWaveInHdr->lpData);
4015 TRACE(mmsys, "lpData=%p size=%lu \n",
4016 lpWaveInHdr->lpData, lpWaveInHdr->dwBufferLength);
4017 ret = widMessage(lpDesc->uDeviceID, WIDM_ADDBUFFER, lpDesc->dwInstance,
4018 (DWORD)lpWaveInHdr, uSize);
4019 /*lpWaveInHdr->lpData = saveddata;*/
4020 return ret;
4023 /**************************************************************************
4024 * waveInStart [WINMM.157]
4026 UINT32 WINAPI waveInStart32(HWAVEIN32 hWaveIn)
4028 return waveInStart16(hWaveIn);
4031 /**************************************************************************
4032 * waveInStart [MMSYSTEM.509]
4034 UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn)
4036 LPWAVEOPENDESC lpDesc;
4038 TRACE(mmsys, "(%04X)\n", hWaveIn);
4039 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4040 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4041 return widMessage(lpDesc->uDeviceID,WIDM_START,lpDesc->dwInstance,0,0);
4044 /**************************************************************************
4045 * waveInStop [WINMM.158]
4047 UINT32 WINAPI waveInStop32(HWAVEIN32 hWaveIn)
4049 return waveInStop16(hWaveIn);
4052 /**************************************************************************
4053 * waveInStop [MMSYSTEM.510]
4055 UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn)
4057 LPWAVEOPENDESC lpDesc;
4059 TRACE(mmsys, "(%04X)\n", hWaveIn);
4060 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4061 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4062 return widMessage(lpDesc->uDeviceID, WIDM_STOP, lpDesc->dwInstance, 0L, 0L);
4065 /**************************************************************************
4066 * waveInReset [WINMM.156]
4068 UINT32 WINAPI waveInReset32(HWAVEIN32 hWaveIn)
4070 return waveInReset16(hWaveIn);
4073 /**************************************************************************
4074 * waveInReset [MMSYSTEM.511]
4076 UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn)
4078 LPWAVEOPENDESC lpDesc;
4080 TRACE(mmsys, "(%04X)\n", hWaveIn);
4081 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4082 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4083 return widMessage(lpDesc->uDeviceID,WIDM_RESET,lpDesc->dwInstance,0,0);
4086 /**************************************************************************
4087 * waveInGetPosition [WINMM.152]
4089 UINT32 WINAPI waveInGetPosition32(HWAVEIN32 hWaveIn, LPMMTIME32 lpTime,
4090 UINT32 uSize)
4092 MMTIME16 mmt16;
4093 UINT32 ret = waveInGetPosition16(hWaveIn,&mmt16,uSize);
4095 MMSYSTEM_MMTIME16to32(lpTime,&mmt16);
4096 return ret;
4099 /**************************************************************************
4100 * waveInGetPosition [MMSYSTEM.512]
4102 UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn,LPMMTIME16 lpTime,
4103 UINT16 uSize)
4105 LPWAVEOPENDESC lpDesc;
4107 TRACE(mmsys, "(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
4108 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4109 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4110 return widMessage(lpDesc->uDeviceID, WIDM_GETPOS, lpDesc->dwInstance,
4111 (DWORD)lpTime, (DWORD)uSize);
4114 /**************************************************************************
4115 * waveInGetID [WINMM.150]
4117 UINT32 WINAPI waveInGetID32(HWAVEIN32 hWaveIn, UINT32 * lpuDeviceID)
4119 LPWAVEOPENDESC lpDesc;
4121 TRACE(mmsys, "waveInGetID\n");
4122 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
4123 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4124 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4125 *lpuDeviceID = lpDesc->uDeviceID;
4126 return 0;
4130 /**************************************************************************
4131 * waveInGetID [MMSYSTEM.513]
4133 UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16 * lpuDeviceID)
4135 LPWAVEOPENDESC lpDesc;
4137 TRACE(mmsys, "waveInGetID\n");
4138 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
4139 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4140 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4141 *lpuDeviceID = lpDesc->uDeviceID;
4142 return 0;
4145 /**************************************************************************
4146 * waveInMessage [WINMM.153]
4148 DWORD WINAPI waveInMessage32(HWAVEIN32 hWaveIn, UINT32 uMessage,
4149 DWORD dwParam1, DWORD dwParam2)
4151 LPWAVEOPENDESC lpDesc;
4153 FIXME(mmsys, "(%04X, %04X, %08lX, %08lX),FIXME!\n",
4154 hWaveIn, uMessage, dwParam1, dwParam2);
4155 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4156 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4157 switch (uMessage) {
4158 case WIDM_OPEN:
4159 FIXME(mmsys, "cannot handle WIDM_OPEN, please report.\n");
4160 break;
4161 case WIDM_GETNUMDEVS:
4162 case WIDM_GETPOS:
4163 case WIDM_CLOSE:
4164 case WIDM_STOP :
4165 case WIDM_RESET:
4166 case WIDM_START:
4167 case WIDM_PREPARE:
4168 case WIDM_UNPREPARE:
4169 case WIDM_ADDBUFFER:
4170 case WIDM_PAUSE:
4171 /* no argument conversion needed */
4172 break;
4173 case WIDM_GETDEVCAPS:
4174 /*FIXME: ANSI/UNICODE */
4175 return waveInGetDevCaps32A(hWaveIn,(LPWAVEINCAPS32A)dwParam1,dwParam2);
4176 default:
4177 ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
4178 hWaveIn,uMessage,dwParam1,dwParam2);
4179 break;
4181 return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
4184 /**************************************************************************
4185 * waveInMessage [MMSYSTEM.514]
4187 DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
4188 DWORD dwParam1, DWORD dwParam2)
4190 LPWAVEOPENDESC lpDesc;
4192 FIXME(mmsys, "(%04X, %04X, %08lX, %08lX),FIXME!\n",
4193 hWaveIn, uMessage, dwParam1, dwParam2);
4194 lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
4195 if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
4196 switch (uMessage) {
4197 case WIDM_OPEN:
4198 FIXME(mmsys,"cannot handle WIDM_OPEN, please report.\n");
4199 break;
4200 case WIDM_GETNUMDEVS:
4201 case WIDM_CLOSE:
4202 case WIDM_STOP :
4203 case WIDM_RESET:
4204 case WIDM_START:
4205 case WIDM_PAUSE:
4206 /* no argument conversion needed */
4207 break;
4208 case WIDM_GETDEVCAPS:
4209 return waveInGetDevCaps16(hWaveIn,(LPWAVEINCAPS16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
4210 case WIDM_GETPOS:
4211 return waveInGetPosition16(hWaveIn,(LPMMTIME16)PTR_SEG_TO_LIN(dwParam1),dwParam2);
4212 case WIDM_PREPARE:
4213 return waveInPrepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
4214 case WIDM_UNPREPARE:
4215 return waveInUnprepareHeader16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
4216 case WIDM_ADDBUFFER:
4217 return waveInAddBuffer16(hWaveIn,(LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1),dwParam2);
4218 default:
4219 ERR(mmsys,"(%04x,%04x,%08lx,%08lx): unhandled message\n",
4220 hWaveIn,uMessage,dwParam1,dwParam2);
4221 break;
4223 return widMessage(lpDesc->uDeviceID, uMessage, lpDesc->dwInstance, dwParam1, dwParam2);
4226 /**************************************************************************
4227 * DrvOpen [MMSYSTEM.1100]
4229 HDRVR16 WINAPI DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
4231 TRACE(mmsys,"('%s','%s',%08lX);\n",lpDriverName,lpSectionName,lParam);
4232 return OpenDriver16(lpDriverName, lpSectionName, lParam);
4236 /**************************************************************************
4237 * DrvClose [MMSYSTEM.1101]
4239 LRESULT WINAPI DrvClose(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
4241 TRACE(mmsys, "(%04X, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
4242 return CloseDriver16(hDrvr, lParam1, lParam2);
4246 /**************************************************************************
4247 * DrvSendMessage [MMSYSTEM.1102]
4249 LRESULT WINAPI DrvSendMessage(HDRVR16 hDriver, WORD msg, LPARAM lParam1,
4250 LPARAM lParam2)
4252 DWORD dwDriverID = 0;
4253 FIXME(mmsys, "(%04X, %04X, %08lX, %08lX);\n",
4254 hDriver, msg, lParam1, lParam2);
4255 /* FIXME: wrong ... */
4256 return CDAUDIO_DriverProc16(dwDriverID, hDriver, msg, lParam1, lParam2);
4259 /**************************************************************************
4260 * DrvGetModuleHandle [MMSYSTEM.1103]
4262 HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrvr)
4264 return GetDriverModuleHandle16(hDrvr);
4267 /**************************************************************************
4268 * DrvDefDriverProc [MMSYSTEM.1104]
4270 LRESULT WINAPI DrvDefDriverProc(DWORD dwDriverID, HDRVR16 hDriv, WORD wMsg,
4271 DWORD dwParam1, DWORD dwParam2)
4273 return DefDriverProc16(dwDriverID, hDriv, wMsg, dwParam1, dwParam2);
4276 /**************************************************************************
4277 * DefDriverProc32 [WINMM.5]
4279 LRESULT WINAPI DefDriverProc32(DWORD dwDriverIdentifier, HDRVR32 hdrvr,
4280 UINT32 Msg, LPARAM lParam1, LPARAM lParam2)
4282 switch (Msg) {
4283 case DRV_LOAD:
4284 case DRV_DISABLE:
4285 case DRV_INSTALL:
4286 return 0;
4287 case DRV_ENABLE:
4288 case DRV_FREE:
4289 case DRV_REMOVE:
4290 return 1;
4291 default:
4292 return 0;
4296 /**************************************************************************
4297 * mmThreadCreate [MMSYSTEM.1120]
4299 LRESULT WINAPI mmThreadCreate16(LPVOID x1, LPWORD x2, DWORD x3, DWORD x4) {
4300 FIXME(mmsys,"(%p,%p,%08lx,%08lx): stub!\n",x1,x2,x3,x4);
4301 *x2 = 0xbabe;
4302 return 0;
4305 /**************************************************************************
4306 * mmThreadGetTask [MMSYSTEM.1125]
4308 LRESULT WINAPI mmThreadGetTask16(WORD hnd) {
4309 FIXME(mmsys,"(%04x): stub!\n",hnd);
4310 return GetCurrentTask();
4313 /**************************************************************************
4314 * mmThreadSignal [MMSYSTEM.1121]
4316 LRESULT WINAPI mmThreadSignal16(WORD hnd) {
4317 FIXME(mmsys,"(%04x): stub!\n",hnd);
4318 return 0;
4321 /**************************************************************************
4322 * mmTaskCreate [MMSYSTEM.900]
4324 HINSTANCE16 WINAPI mmTaskCreate16(LPWORD lphnd,HINSTANCE16 *hMmTask,DWORD x2)
4326 DWORD showCmd = 0x40002;
4327 LPSTR cmdline;
4328 WORD sel1, sel2;
4329 LOADPARAMS *lp;
4330 HINSTANCE16 ret, handle;
4332 TRACE(mmsys,"(%p,%p,%08lx);\n",lphnd,hMmTask,x2);
4333 cmdline = (LPSTR)HeapAlloc(GetProcessHeap(), 0, 0x0d);
4334 cmdline[0] = 0x0d;
4335 (DWORD)cmdline[1] = (DWORD)lphnd;
4336 (DWORD)cmdline[5] = x2;
4337 (DWORD)cmdline[9] = 0;
4339 sel1 = SELECTOR_AllocBlock(cmdline, 0x0d, SEGMENT_DATA, FALSE, FALSE);
4340 sel2 = SELECTOR_AllocBlock(&showCmd, sizeof(showCmd),
4341 SEGMENT_DATA, FALSE, FALSE);
4343 lp = (LOADPARAMS *)HeapAlloc(GetProcessHeap(), 0, sizeof(LOADPARAMS));
4344 lp->hEnvironment = 0;
4345 lp->cmdLine = PTR_SEG_OFF_TO_SEGPTR(sel1, 0);
4346 lp->showCmd = PTR_SEG_OFF_TO_SEGPTR(sel2, 0);
4347 lp->reserved = 0;
4349 ret = LoadModule16("c:\\windows\\mmtask.tsk", lp);
4350 if (ret < 32) {
4351 if (ret)
4352 ret = 1;
4353 else
4354 ret = 2;
4355 handle = 0;
4357 else {
4358 handle = ret;
4359 ret = 0;
4361 if (hMmTask)
4362 *(HINSTANCE16 *)PTR_SEG_TO_LIN(hMmTask) = handle;
4364 UnMapLS(PTR_SEG_OFF_TO_SEGPTR(sel2, 0));
4365 UnMapLS(PTR_SEG_OFF_TO_SEGPTR(sel1, 0));
4367 HeapFree(GetProcessHeap(), 0, lp);
4368 HeapFree(GetProcessHeap(), 0, cmdline);
4370 return ret;
4373 /**************************************************************************
4374 * mmTaskSignal [MMSYSTEM.903]
4376 LRESULT WINAPI mmTaskSignal16(HTASK16 ht)
4378 TRACE(mmsys,"(%04x);\n",ht);
4379 return PostAppMessage16(ht,WM_USER,0,0);
4382 /**************************************************************************
4383 * mciDriverYield [MMSYSTEM.710]
4385 LRESULT WINAPI mciDriverYield16(HANDLE16 hnd)
4387 FIXME(mmsys,"(%04x): stub!\n",hnd);
4388 return 0;