ReactOS  0.4.14-dev-52-g6116262
winmm.c
Go to the documentation of this file.
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2 
3 /*
4  * WINMM functions
5  *
6  * Copyright 1993 Martin Ayotte
7  * 1998-2002 Eric Pouech
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 /*
25  * Eric POUECH :
26  * 98/9 added Win32 MCI support
27  * 99/4 added midiStream support
28  * 99/9 added support for loadable low level drivers
29  */
30 
31 /* TODO
32  * + it seems that some programs check what's installed in
33  * registry against the value returned by drivers. Wine is
34  * currently broken regarding this point.
35  * + check thread-safeness for MMSYSTEM and WINMM entry points
36  * + unicode entry points are badly supported (would require
37  * moving 32 bit drivers as Unicode as they are supposed to be)
38  * + allow joystick and timer external calls as we do for wave,
39  * midi, mixer and aux
40  */
41 
42 #include "winemm.h"
43 
45 
46 /* ========================================================================
47  * G L O B A L S E T T I N G S
48  * ========================================================================*/
49 
53 
55 
56 /**************************************************************************
57  * WINMM_CreateIData [internal]
58  */
60 {
61  hWinMM32Instance = hInstDLL;
65  return TRUE;
66 }
67 
68 /**************************************************************************
69  * WINMM_DeleteIData [internal]
70  */
71 static void WINMM_DeleteIData(void)
72 {
74 
75  /* FIXME: should also free content and resources allocated
76  * inside WINMM_IData */
80 }
81 
82 /******************************************************************
83  * WINMM_LoadMMSystem
84  *
85  */
86 static HANDLE (WINAPI *pGetModuleHandle16)(LPCSTR);
87 static DWORD (WINAPI *pLoadLibrary16)(LPCSTR);
88 
90 {
91  /* 0 is not checked yet, -1 is not present, 1 is present */
92  static int loaded /* = 0 */;
93 
94  if (loaded == 0)
95  {
96  HANDLE h = GetModuleHandleA("kernel32");
97  loaded = -1;
98  if (h)
99  {
100  pGetModuleHandle16 = (void*)GetProcAddress(h, "GetModuleHandle16");
101  pLoadLibrary16 = (void*)GetProcAddress(h, (LPCSTR)35); /* ordinal for LoadLibrary16 */
102  if (pGetModuleHandle16 && pLoadLibrary16 &&
103  (pGetModuleHandle16("MMSYSTEM.DLL") || pLoadLibrary16("MMSYSTEM.DLL")))
104  loaded = 1;
105  }
106  }
107  return loaded > 0;
108 }
109 
110 /******************************************************************
111  * WINMM_ErrorToString
112  */
114 {
115 #define ERR_TO_STR(dev) case dev: return #dev
116  static char unknown[32];
117  switch (error) {
147  }
148  sprintf(unknown, "Unknown(0x%08x)", error);
149  return unknown;
150 #undef ERR_TO_STR
151 }
152 
153 /**************************************************************************
154  * DllMain (WINMM.init)
155  *
156  * WINMM DLL entry point
157  *
158  */
160 {
161  TRACE("%p 0x%x %p\n", hInstDLL, fdwReason, fImpLoad);
162 
163  switch (fdwReason) {
164  case DLL_PROCESS_ATTACH:
165  DisableThreadLibraryCalls(hInstDLL);
166 
167  if (!WINMM_CreateIData(hInstDLL))
168  return FALSE;
169  if (!MMDRV_Init()) {
171  return FALSE;
172  }
173  break;
174  case DLL_PROCESS_DETACH:
175  /* close all opened MCI drivers */
177  MMDRV_Exit();
178  /* There's no guarantee the drivers haven't already been unloaded on
179  * process shutdown.
180  */
181  if (!fImpLoad)
182  {
183  /* now unload all remaining drivers... */
185  }
186 
188  break;
189  }
190  return TRUE;
191 }
192 
193 /**************************************************************************
194  * WINMM_CheckCallback [internal]
195  */
196 MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer)
197 {
198  switch (fdwOpen & CALLBACK_TYPEMASK) {
199  case CALLBACK_NULL: /* dwCallback need not be NULL */
200  break;
201  case CALLBACK_WINDOW:
202  if (dwCallback && !IsWindow((HWND)dwCallback))
203  return MMSYSERR_INVALPARAM;
204  break;
205 
206  case CALLBACK_FUNCTION:
207  /* a NULL cb is acceptable since w2k, MMSYSERR_INVALPARAM earlier */
208  if (mixer)
209  return MMSYSERR_INVALFLAG; /* since w2k, MMSYSERR_NOTSUPPORTED earlier */
210  break;
211  case CALLBACK_THREAD:
212  case CALLBACK_EVENT:
213  if (mixer) /* FIXME: mixer supports THREAD+EVENT since w2k */
214  return MMSYSERR_NOTSUPPORTED; /* w9X */
215  break;
216  default:
217  WARN("Unknown callback type %d\n", HIWORD(fdwOpen));
218  }
219  return MMSYSERR_NOERROR;
220 }
221 
222 /**************************************************************************
223  * Mixer devices. New to Win95
224  */
225 
226 /**************************************************************************
227  * find out the real mixer ID depending on hmix (depends on dwFlags)
228  */
229 static UINT MIXER_GetDev(HMIXEROBJ hmix, DWORD dwFlags, LPWINE_MIXER * lplpwm)
230 {
231  LPWINE_MIXER lpwm = NULL;
232  UINT uRet = MMSYSERR_NOERROR;
233 
234  switch (dwFlags & 0xF0000000ul) {
235  case MIXER_OBJECTF_MIXER:
236  lpwm = (LPWINE_MIXER)MMDRV_Get(hmix, MMDRV_MIXER, TRUE);
237  break;
239  lpwm = (LPWINE_MIXER)MMDRV_Get(hmix, MMDRV_MIXER, FALSE);
240  break;
243  break;
246  break;
249  break;
252  break;
255  break;
258  break;
261  break;
264  break;
265  case MIXER_OBJECTF_AUX:
267  break;
268  default:
269  WARN("Unsupported flag (%08lx)\n", dwFlags & 0xF0000000ul);
270  lpwm = 0;
271  uRet = MMSYSERR_INVALFLAG;
272  break;
273  }
274  *lplpwm = lpwm;
275  if (lpwm == 0 && uRet == MMSYSERR_NOERROR)
276  uRet = MMSYSERR_INVALPARAM;
277  return uRet;
278 }
279 
280 /**************************************************************************
281  * mixerGetNumDevs [WINMM.@]
282  */
284 {
285  return MMDRV_GetNum(MMDRV_MIXER);
286 }
287 
288 /**************************************************************************
289  * mixerGetDevCapsA [WINMM.@]
290  */
292 {
293  MIXERCAPSW micW;
294  UINT ret;
295 
296  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
297 
298  ret = mixerGetDevCapsW(uDeviceID, &micW, sizeof(micW));
299 
300  if (ret == MMSYSERR_NOERROR) {
301  MIXERCAPSA micA;
302  micA.wMid = micW.wMid;
303  micA.wPid = micW.wPid;
304  micA.vDriverVersion = micW.vDriverVersion;
305  WideCharToMultiByte( CP_ACP, 0, micW.szPname, -1, micA.szPname,
306  sizeof(micA.szPname), NULL, NULL );
307  micA.fdwSupport = micW.fdwSupport;
308  micA.cDestinations = micW.cDestinations;
309  memcpy(lpCaps, &micA, min(uSize, sizeof(micA)));
310  }
311  return ret;
312 }
313 
314 /**************************************************************************
315  * mixerGetDevCapsW [WINMM.@]
316  */
318 {
319  LPWINE_MLD wmld;
320 
321  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
322 
323  if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIXER, TRUE)) == NULL)
324  return MMSYSERR_BADDEVICEID;
325 
326  return MMDRV_Message(wmld, MXDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
327 }
328 
329 static void CALLBACK MIXER_WCallback(HMIXEROBJ hmx, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam, DWORD_PTR param2)
330 {
331  HWND hWnd = (HWND)dwInstance;
332 
333  if (!dwInstance)
334  return;
335 
336  PostMessageW(hWnd, uMsg, (WPARAM)hmx, (LPARAM)dwParam);
337 }
338 
339 /**************************************************************************
340  * mixerOpen [WINMM.@]
341  */
342 UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback,
343  DWORD_PTR dwInstance, DWORD fdwOpen)
344 {
345  HANDLE hMix;
346  LPWINE_MLD wmld;
347  DWORD dwRet;
349 
350  TRACE("(%p, %d, %08lx, %08lx, %08x)\n",
351  lphMix, uDeviceID, dwCallback, dwInstance, fdwOpen);
352 
353  dwRet = WINMM_CheckCallback(dwCallback, fdwOpen, TRUE);
354  if(dwRet != MMSYSERR_NOERROR)
355  return dwRet;
356 
357  mod.dwCallback = (DWORD_PTR)MIXER_WCallback;
358  if ((fdwOpen & CALLBACK_TYPEMASK) == CALLBACK_WINDOW)
359  mod.dwInstance = dwCallback;
360  else
361  mod.dwInstance = 0;
362 
363  /* We're remapping to CALLBACK_FUNCTION because that's what old winmm is
364  * documented to do when opening the mixer driver.
365  * FIXME: Native supports CALLBACK_EVENT + CALLBACK_THREAD flags since w2k.
366  * FIXME: The non ALSA drivers ignore callback requests - bug.
367  */
368 
369  wmld = MMDRV_Alloc(sizeof(WINE_MIXER), MMDRV_MIXER, &hMix, &fdwOpen,
370  &dwCallback, &dwInstance);
371  wmld->uDeviceID = uDeviceID;
372  mod.hmx = hMix;
373 
375 
376  if (dwRet != MMSYSERR_NOERROR) {
377  MMDRV_Free(hMix, wmld);
378  hMix = 0;
379  }
380  if (lphMix) *lphMix = hMix;
381  TRACE("=> %d hMixer=%p\n", dwRet, hMix);
382 
383  return dwRet;
384 }
385 
386 /**************************************************************************
387  * mixerClose [WINMM.@]
388  */
389 UINT WINAPI mixerClose(HMIXER hMix)
390 {
391  LPWINE_MLD wmld;
392  DWORD dwRet;
393 
394  TRACE("(%p)\n", hMix);
395 
396  if ((wmld = MMDRV_Get(hMix, MMDRV_MIXER, FALSE)) == NULL) return MMSYSERR_INVALHANDLE;
397 
398  dwRet = MMDRV_Close(wmld, MXDM_CLOSE);
399  MMDRV_Free(hMix, wmld);
400 
401  return dwRet;
402 }
403 
404 /**************************************************************************
405  * mixerGetID [WINMM.@]
406  */
407 UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
408 {
409  LPWINE_MIXER lpwm;
410  UINT uRet = MMSYSERR_NOERROR;
411 
412  TRACE("(%p %p %08x)\n", hmix, lpid, fdwID);
413 
414  if ((uRet = MIXER_GetDev(hmix, fdwID, &lpwm)) != MMSYSERR_NOERROR)
415  return uRet;
416 
417  if (lpid)
418  *lpid = lpwm->mld.uDeviceID;
419 
420  return uRet;
421 }
422 
423 /**************************************************************************
424  * mixerGetControlDetailsW [WINMM.@]
425  */
427  DWORD fdwDetails)
428 {
429  LPWINE_MIXER lpwm;
430  UINT uRet = MMSYSERR_NOERROR;
431 
432  TRACE("(%p, %p, %08x)\n", hmix, lpmcdW, fdwDetails);
433 
434  if ((uRet = MIXER_GetDev(hmix, fdwDetails, &lpwm)) != MMSYSERR_NOERROR)
435  return uRet;
436 
437  if (lpmcdW == NULL || lpmcdW->cbStruct != sizeof(*lpmcdW))
438  return MMSYSERR_INVALPARAM;
439 
440  return MMDRV_Message(&lpwm->mld, MXDM_GETCONTROLDETAILS, (DWORD_PTR)lpmcdW,
441  fdwDetails);
442 }
443 
444 /**************************************************************************
445  * mixerGetControlDetailsA [WINMM.@]
446  */
448  DWORD fdwDetails)
449 {
451 
452  TRACE("(%p, %p, %08x)\n", hmix, lpmcdA, fdwDetails);
453 
454  if (lpmcdA == NULL || lpmcdA->cbStruct != sizeof(*lpmcdA))
455  return MMSYSERR_INVALPARAM;
456 
457  switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
459  /* can safely use A structure as it is, no string inside */
460  ret = mixerGetControlDetailsW(hmix, lpmcdA, fdwDetails);
461  break;
463  {
464  MIXERCONTROLDETAILS_LISTTEXTA *pDetailsA = lpmcdA->paDetails;
466  int size = max(1, lpmcdA->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
467  unsigned int i;
468 
469  if (lpmcdA->u.cMultipleItems != 0) {
470  size *= lpmcdA->u.cMultipleItems;
471  }
472  pDetailsW = HeapAlloc(GetProcessHeap(), 0, size);
473  lpmcdA->paDetails = pDetailsW;
474  lpmcdA->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
475  /* set up lpmcd->paDetails */
476  ret = mixerGetControlDetailsW(hmix, lpmcdA, fdwDetails);
477  /* copy from lpmcd->paDetails back to paDetailsW; */
478  if (ret == MMSYSERR_NOERROR) {
479  for (i = 0; i < lpmcdA->u.cMultipleItems * lpmcdA->cChannels; i++) {
480  pDetailsA->dwParam1 = pDetailsW->dwParam1;
481  pDetailsA->dwParam2 = pDetailsW->dwParam2;
482  WideCharToMultiByte( CP_ACP, 0, pDetailsW->szName, -1,
483  pDetailsA->szName,
484  sizeof(pDetailsA->szName), NULL, NULL );
485  pDetailsA++;
486  pDetailsW++;
487  }
488  pDetailsA -= lpmcdA->u.cMultipleItems * lpmcdA->cChannels;
489  pDetailsW -= lpmcdA->u.cMultipleItems * lpmcdA->cChannels;
490  }
491  HeapFree(GetProcessHeap(), 0, pDetailsW);
492  lpmcdA->paDetails = pDetailsA;
493  lpmcdA->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
494  }
495  break;
496  default:
497  ERR("Unsupported fdwDetails=0x%08x\n", fdwDetails);
498  }
499 
500  return ret;
501 }
502 
503 /**************************************************************************
504  * mixerGetLineControlsA [WINMM.@]
505  */
507  DWORD fdwControls)
508 {
509  MIXERLINECONTROLSW mlcW;
510  DWORD ret;
511  unsigned int i;
512 
513  TRACE("(%p, %p, %08x)\n", hmix, lpmlcA, fdwControls);
514 
515  if (lpmlcA == NULL || lpmlcA->cbStruct != sizeof(*lpmlcA) ||
516  lpmlcA->cbmxctrl != sizeof(MIXERCONTROLA))
517  return MMSYSERR_INVALPARAM;
518 
519  mlcW.cbStruct = sizeof(mlcW);
520  mlcW.dwLineID = lpmlcA->dwLineID;
521  mlcW.u.dwControlID = lpmlcA->u.dwControlID;
522  mlcW.u.dwControlType = lpmlcA->u.dwControlType;
523 
524  /* Debugging on Windows shows for MIXER_GETLINECONTROLSF_ONEBYTYPE only,
525  the control count is assumed to be 1 - This is relied upon by a game,
526  "Dynomite Deluze" */
528  mlcW.cControls = 1;
529  } else {
530  mlcW.cControls = lpmlcA->cControls;
531  }
532  mlcW.cbmxctrl = sizeof(MIXERCONTROLW);
533  mlcW.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
534  mlcW.cControls * mlcW.cbmxctrl);
535 
536  ret = mixerGetLineControlsW(hmix, &mlcW, fdwControls);
537 
538  if (ret == MMSYSERR_NOERROR) {
539  lpmlcA->dwLineID = mlcW.dwLineID;
540  lpmlcA->u.dwControlID = mlcW.u.dwControlID;
541  lpmlcA->u.dwControlType = mlcW.u.dwControlType;
542 
543  for (i = 0; i < mlcW.cControls; i++) {
544  lpmlcA->pamxctrl[i].cbStruct = sizeof(MIXERCONTROLA);
545  lpmlcA->pamxctrl[i].dwControlID = mlcW.pamxctrl[i].dwControlID;
546  lpmlcA->pamxctrl[i].dwControlType = mlcW.pamxctrl[i].dwControlType;
547  lpmlcA->pamxctrl[i].fdwControl = mlcW.pamxctrl[i].fdwControl;
550  lpmlcA->pamxctrl[i].szShortName,
551  sizeof(lpmlcA->pamxctrl[i].szShortName), NULL, NULL );
552  WideCharToMultiByte( CP_ACP, 0, mlcW.pamxctrl[i].szName, -1,
553  lpmlcA->pamxctrl[i].szName,
554  sizeof(lpmlcA->pamxctrl[i].szName), NULL, NULL );
555  /* sizeof(lpmlcA->pamxctrl[i].Bounds) ==
556  * sizeof(mlcW.pamxctrl[i].Bounds) */
557  memcpy(&lpmlcA->pamxctrl[i].Bounds, &mlcW.pamxctrl[i].Bounds,
558  sizeof(mlcW.pamxctrl[i].Bounds));
559  /* sizeof(lpmlcA->pamxctrl[i].Metrics) ==
560  * sizeof(mlcW.pamxctrl[i].Metrics) */
561  memcpy(&lpmlcA->pamxctrl[i].Metrics, &mlcW.pamxctrl[i].Metrics,
562  sizeof(mlcW.pamxctrl[i].Metrics));
563  }
564  }
565 
566  HeapFree(GetProcessHeap(), 0, mlcW.pamxctrl);
567 
568  return ret;
569 }
570 
571 /**************************************************************************
572  * mixerGetLineControlsW [WINMM.@]
573  */
575  DWORD fdwControls)
576 {
577  LPWINE_MIXER lpwm;
578  UINT uRet = MMSYSERR_NOERROR;
579 
580  TRACE("(%p, %p, %08x)\n", hmix, lpmlcW, fdwControls);
581 
582  if ((uRet = MIXER_GetDev(hmix, fdwControls, &lpwm)) != MMSYSERR_NOERROR)
583  return uRet;
584 
585  if (lpmlcW == NULL || lpmlcW->cbStruct != sizeof(*lpmlcW))
586  return MMSYSERR_INVALPARAM;
587 
588  return MMDRV_Message(&lpwm->mld, MXDM_GETLINECONTROLS, (DWORD_PTR)lpmlcW,
589  fdwControls);
590 }
591 
592 /**************************************************************************
593  * mixerGetLineInfoW [WINMM.@]
594  */
595 UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW, DWORD fdwInfo)
596 {
597  LPWINE_MIXER lpwm;
598  UINT uRet = MMSYSERR_NOERROR;
599 
600  TRACE("(%p, %p, %08x)\n", hmix, lpmliW, fdwInfo);
601 
602  if (lpmliW == NULL || lpmliW->cbStruct != sizeof(*lpmliW))
603  return MMSYSERR_INVALPARAM;
604 
605  if ((uRet = MIXER_GetDev(hmix, fdwInfo, &lpwm)) != MMSYSERR_NOERROR)
606  return uRet;
607 
608  return MMDRV_Message(&lpwm->mld, MXDM_GETLINEINFO, (DWORD_PTR)lpmliW,
609  fdwInfo);
610 }
611 
612 /**************************************************************************
613  * mixerGetLineInfoA [WINMM.@]
614  */
615 UINT WINAPI mixerGetLineInfoA(HMIXEROBJ hmix, LPMIXERLINEA lpmliA,
616  DWORD fdwInfo)
617 {
618  MIXERLINEW mliW;
619  UINT ret;
620 
621  TRACE("(%p, %p, %08x)\n", hmix, lpmliA, fdwInfo);
622 
623  if (lpmliA == NULL || lpmliA->cbStruct != sizeof(*lpmliA))
624  return MMSYSERR_INVALPARAM;
625 
626  mliW.cbStruct = sizeof(mliW);
627  switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
629  mliW.dwComponentType = lpmliA->dwComponentType;
630  break;
632  mliW.dwDestination = lpmliA->dwDestination;
633  break;
635  mliW.dwLineID = lpmliA->dwLineID;
636  break;
638  mliW.dwDestination = lpmliA->dwDestination;
639  mliW.dwSource = lpmliA->dwSource;
640  break;
642  mliW.Target.dwType = lpmliA->Target.dwType;
643  mliW.Target.wMid = lpmliA->Target.wMid;
644  mliW.Target.wPid = lpmliA->Target.wPid;
645  mliW.Target.vDriverVersion = lpmliA->Target.vDriverVersion;
646  MultiByteToWideChar( CP_ACP, 0, lpmliA->Target.szPname, -1, mliW.Target.szPname, sizeof(mliW.Target.szPname)/sizeof(WCHAR));
647  break;
648  default:
649  WARN("Unsupported fdwControls=0x%08x\n", fdwInfo);
650  return MMSYSERR_INVALFLAG;
651  }
652 
653  ret = mixerGetLineInfoW(hmix, &mliW, fdwInfo);
654 
655  if(ret == MMSYSERR_NOERROR)
656  {
657  lpmliA->dwDestination = mliW.dwDestination;
658  lpmliA->dwSource = mliW.dwSource;
659  lpmliA->dwLineID = mliW.dwLineID;
660  lpmliA->fdwLine = mliW.fdwLine;
661  lpmliA->dwUser = mliW.dwUser;
662  lpmliA->dwComponentType = mliW.dwComponentType;
663  lpmliA->cChannels = mliW.cChannels;
664  lpmliA->cConnections = mliW.cConnections;
665  lpmliA->cControls = mliW.cControls;
666  WideCharToMultiByte( CP_ACP, 0, mliW.szShortName, -1, lpmliA->szShortName,
667  sizeof(lpmliA->szShortName), NULL, NULL);
668  WideCharToMultiByte( CP_ACP, 0, mliW.szName, -1, lpmliA->szName,
669  sizeof(lpmliA->szName), NULL, NULL );
670  lpmliA->Target.dwType = mliW.Target.dwType;
671  lpmliA->Target.dwDeviceID = mliW.Target.dwDeviceID;
672  lpmliA->Target.wMid = mliW.Target.wMid;
673  lpmliA->Target.wPid = mliW.Target.wPid;
674  lpmliA->Target.vDriverVersion = mliW.Target.vDriverVersion;
675  WideCharToMultiByte( CP_ACP, 0, mliW.Target.szPname, -1, lpmliA->Target.szPname,
676  sizeof(lpmliA->Target.szPname), NULL, NULL );
677  }
678  return ret;
679 }
680 
681 /**************************************************************************
682  * mixerSetControlDetails [WINMM.@]
683  */
685  DWORD fdwDetails)
686 {
687  LPWINE_MIXER lpwm;
688  UINT uRet = MMSYSERR_NOERROR;
689 
690  TRACE("(%p, %p, %08x)\n", hmix, lpmcd, fdwDetails);
691 
692  if ((uRet = MIXER_GetDev(hmix, fdwDetails, &lpwm)) != MMSYSERR_NOERROR)
693  return uRet;
694 
695  return MMDRV_Message(&lpwm->mld, MXDM_SETCONTROLDETAILS, (DWORD_PTR)lpmcd,
696  fdwDetails);
697 }
698 
699 /**************************************************************************
700  * mixerMessage [WINMM.@]
701  */
702 DWORD WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
703 {
704  LPWINE_MLD wmld;
705 
706  TRACE("(%p, %d, %08lx, %08lx): semi-stub?\n",
707  hmix, uMsg, dwParam1, dwParam2);
708 
709  if ((wmld = MMDRV_Get(hmix, MMDRV_MIXER, FALSE)) == NULL)
710  return MMSYSERR_INVALHANDLE;
711 
712  return MMDRV_Message(wmld, uMsg, dwParam1, dwParam2);
713 }
714 
715 /**************************************************************************
716  * auxGetNumDevs [WINMM.@]
717  */
719 {
720  return MMDRV_GetNum(MMDRV_AUX);
721 }
722 
723 /**************************************************************************
724  * auxGetDevCapsW [WINMM.@]
725  */
727 {
728  LPWINE_MLD wmld;
729 
730  TRACE("(%04lX, %p, %d) !\n", uDeviceID, lpCaps, uSize);
731 
732  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
733 
734  if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
735  return MMSYSERR_INVALHANDLE;
736  return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
737 }
738 
739 /**************************************************************************
740  * auxGetDevCapsA [WINMM.@]
741  */
743 {
744  AUXCAPSW acW;
745  UINT ret;
746 
747  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
748 
749  ret = auxGetDevCapsW(uDeviceID, &acW, sizeof(acW));
750 
751  if (ret == MMSYSERR_NOERROR) {
752  AUXCAPSA acA;
753  acA.wMid = acW.wMid;
754  acA.wPid = acW.wPid;
755  acA.vDriverVersion = acW.vDriverVersion;
756  WideCharToMultiByte( CP_ACP, 0, acW.szPname, -1, acA.szPname,
757  sizeof(acA.szPname), NULL, NULL );
758  acA.wTechnology = acW.wTechnology;
759  acA.dwSupport = acW.dwSupport;
760  memcpy(lpCaps, &acA, min(uSize, sizeof(acA)));
761  }
762  return ret;
763 }
764 
765 /**************************************************************************
766  * auxGetVolume [WINMM.@]
767  */
768 UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD* lpdwVolume)
769 {
770  LPWINE_MLD wmld;
771 
772  TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
773 
774  if ((wmld = MMDRV_Get(UlongToHandle(uDeviceID), MMDRV_AUX, TRUE)) == NULL)
775  return MMSYSERR_INVALHANDLE;
776  return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L);
777 }
778 
779 /**************************************************************************
780  * auxSetVolume [WINMM.@]
781  */
782 UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume)
783 {
784  LPWINE_MLD wmld;
785 
786  TRACE("(%04X, %u) !\n", uDeviceID, dwVolume);
787 
788  if ((wmld = MMDRV_Get(UlongToHandle(uDeviceID), MMDRV_AUX, TRUE)) == NULL)
789  return MMSYSERR_INVALHANDLE;
790  return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L);
791 }
792 
793 /**************************************************************************
794  * auxOutMessage [WINMM.@]
795  */
796 UINT WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD_PTR dw1, DWORD_PTR dw2)
797 {
798  LPWINE_MLD wmld;
799 
800  if ((wmld = MMDRV_Get(UlongToHandle(uDeviceID), MMDRV_AUX, TRUE)) == NULL)
801  return MMSYSERR_INVALHANDLE;
802 
803  return MMDRV_Message(wmld, uMessage, dw1, dw2);
804 }
805 
806 /**************************************************************************
807  * midiOutGetNumDevs [WINMM.@]
808  */
810 {
811  return MMDRV_GetNum(MMDRV_MIDIOUT);
812 }
813 
814 /**************************************************************************
815  * midiOutGetDevCapsW [WINMM.@]
816  */
818  UINT uSize)
819 {
820  LPWINE_MLD wmld;
821 
822  TRACE("(%lu, %p, %u);\n", uDeviceID, lpCaps, uSize);
823 
824  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
825 
826  if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
827  return MMSYSERR_INVALHANDLE;
828 
829  return MMDRV_Message(wmld, MODM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
830 }
831 
832 /**************************************************************************
833  * midiOutGetDevCapsA [WINMM.@]
834  */
836  UINT uSize)
837 {
838  MIDIOUTCAPSW mocW;
839  UINT ret;
840 
841  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
842 
843  ret = midiOutGetDevCapsW(uDeviceID, &mocW, sizeof(mocW));
844 
845  if (ret == MMSYSERR_NOERROR) {
846  MIDIOUTCAPSA mocA;
847  mocA.wMid = mocW.wMid;
848  mocA.wPid = mocW.wPid;
849  mocA.vDriverVersion = mocW.vDriverVersion;
850  WideCharToMultiByte( CP_ACP, 0, mocW.szPname, -1, mocA.szPname,
851  sizeof(mocA.szPname), NULL, NULL );
852  mocA.wTechnology = mocW.wTechnology;
853  mocA.wVoices = mocW.wVoices;
854  mocA.wNotes = mocW.wNotes;
855  mocA.wChannelMask = mocW.wChannelMask;
856  mocA.dwSupport = mocW.dwSupport;
857  memcpy(lpCaps, &mocA, min(uSize, sizeof(mocA)));
858  }
859  return ret;
860 }
861 
862 /**************************************************************************
863  * midiOutGetErrorTextA [WINMM.@]
864  * midiInGetErrorTextA [WINMM.@]
865  */
867 {
868  UINT ret;
869 
870  if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
871  else if (uSize == 0) ret = MMSYSERR_NOERROR;
872  else
873  {
874  LPWSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize * sizeof(WCHAR));
875  if (!xstr) ret = MMSYSERR_NOMEM;
876  else
877  {
878  ret = midiOutGetErrorTextW(uError, xstr, uSize);
879  if (ret == MMSYSERR_NOERROR)
880  WideCharToMultiByte(CP_ACP, 0, xstr, -1, lpText, uSize, NULL, NULL);
881  HeapFree(GetProcessHeap(), 0, xstr);
882  }
883  }
884  return ret;
885 }
886 
887 /**************************************************************************
888  * midiOutGetErrorTextW [WINMM.@]
889  * midiInGetErrorTextW [WINMM.@]
890  */
892 {
894 
895  if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
896  else if (uSize == 0) ret = MMSYSERR_NOERROR;
897  else if (
898  /* test has been removed because MMSYSERR_BASE is 0, and gcc did emit
899  * a warning for the test was always true */
900  (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
901  (uError >= MIDIERR_BASE && uError <= MIDIERR_LASTERROR)) {
902  if (LoadStringW(hWinMM32Instance, uError, lpText, uSize) > 0) {
904  }
905  }
906  return ret;
907 }
908 
909 /**************************************************************************
910  * MIDI_OutAlloc [internal]
911  */
912 static LPWINE_MIDI MIDI_OutAlloc(HMIDIOUT* lphMidiOut, DWORD_PTR* lpdwCallback,
913  DWORD_PTR* lpdwInstance, LPDWORD lpdwFlags,
914  DWORD cIDs, MIDIOPENSTRMID* lpIDs)
915 {
916  HANDLE hMidiOut;
917  LPWINE_MIDI lpwm;
918  UINT size;
919 
920  size = sizeof(WINE_MIDI) + (cIDs ? (cIDs-1) : 0) * sizeof(MIDIOPENSTRMID);
921 
922  lpwm = (LPWINE_MIDI)MMDRV_Alloc(size, MMDRV_MIDIOUT, &hMidiOut, lpdwFlags,
923  lpdwCallback, lpdwInstance);
924 
925  *lphMidiOut = hMidiOut;
926 
927  if (lpwm) {
928  lpwm->mod.hMidi = hMidiOut;
929  lpwm->mod.dwCallback = *lpdwCallback;
930  lpwm->mod.dwInstance = *lpdwInstance;
931  lpwm->mod.dnDevNode = 0;
932  lpwm->mod.cIds = cIDs;
933  if (cIDs)
934  memcpy(&(lpwm->mod.rgIds), lpIDs, cIDs * sizeof(MIDIOPENSTRMID));
935  }
936  return lpwm;
937 }
938 
939 /**************************************************************************
940  * midiOutOpen [WINMM.@]
941  */
942 MMRESULT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID,
943  DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
944 {
945  HMIDIOUT hMidiOut;
946  LPWINE_MIDI lpwm;
947  UINT dwRet;
948 
949  TRACE("(%p, %d, %08lX, %08lX, %08X);\n",
950  lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
951 
952  if (lphMidiOut != NULL) *lphMidiOut = 0;
953 
954  dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
955  if (dwRet != MMSYSERR_NOERROR)
956  return dwRet;
957 
958  lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &dwFlags, 0, NULL);
959 
960  if (lpwm == NULL)
961  return MMSYSERR_NOMEM;
962 
963  lpwm->mld.uDeviceID = uDeviceID;
964 
965  dwRet = MMDRV_Open((LPWINE_MLD)lpwm, MODM_OPEN, (DWORD_PTR)&lpwm->mod, dwFlags);
966 
967  if (dwRet != MMSYSERR_NOERROR) {
968  MMDRV_Free(hMidiOut, (LPWINE_MLD)lpwm);
969  hMidiOut = 0;
970  }
971 
972  if (lphMidiOut) *lphMidiOut = hMidiOut;
973  TRACE("=> %d hMidi=%p\n", dwRet, hMidiOut);
974 
975  return dwRet;
976 }
977 
978 /**************************************************************************
979  * midiOutClose [WINMM.@]
980  */
981 UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
982 {
983  LPWINE_MLD wmld;
984  DWORD dwRet;
985 
986  TRACE("(%p)\n", hMidiOut);
987 
988  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
989  return MMSYSERR_INVALHANDLE;
990 
991  dwRet = MMDRV_Close(wmld, MODM_CLOSE);
992  MMDRV_Free(hMidiOut, wmld);
993 
994  return dwRet;
995 }
996 
997 /**************************************************************************
998  * midiOutPrepareHeader [WINMM.@]
999  */
1001  MIDIHDR* lpMidiOutHdr, UINT uSize)
1002 {
1003  LPWINE_MLD wmld;
1004 
1005  TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
1006 
1007  if (lpMidiOutHdr == NULL || uSize < sizeof (MIDIHDR))
1008  return MMSYSERR_INVALPARAM;
1009 
1010  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1011  return MMSYSERR_INVALHANDLE;
1012 
1013  return MMDRV_Message(wmld, MODM_PREPARE, (DWORD_PTR)lpMidiOutHdr, uSize);
1014 }
1015 
1016 /**************************************************************************
1017  * midiOutUnprepareHeader [WINMM.@]
1018  */
1020  MIDIHDR* lpMidiOutHdr, UINT uSize)
1021 {
1022  LPWINE_MLD wmld;
1023 
1024  TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
1025 
1026  if (lpMidiOutHdr == NULL || uSize < sizeof (MIDIHDR))
1027  return MMSYSERR_INVALPARAM;
1028 
1029  if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
1030  return MMSYSERR_NOERROR;
1031  }
1032 
1033  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1034  return MMSYSERR_INVALHANDLE;
1035 
1036  return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD_PTR)lpMidiOutHdr, uSize);
1037 }
1038 
1039 /**************************************************************************
1040  * midiOutShortMsg [WINMM.@]
1041  */
1042 UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
1043 {
1044  LPWINE_MLD wmld;
1045 
1046  TRACE("(%p, %08X)\n", hMidiOut, dwMsg);
1047 
1048  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1049  return MMSYSERR_INVALHANDLE;
1050 
1051  return MMDRV_Message(wmld, MODM_DATA, dwMsg, 0L);
1052 }
1053 
1054 /**************************************************************************
1055  * midiOutLongMsg [WINMM.@]
1056  */
1057 UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut,
1058  MIDIHDR* lpMidiOutHdr, UINT uSize)
1059 {
1060  LPWINE_MLD wmld;
1061 
1062  TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
1063 
1064  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1065  return MMSYSERR_INVALHANDLE;
1066 
1067  return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr, uSize);
1068 }
1069 
1070 /**************************************************************************
1071  * midiOutReset [WINMM.@]
1072  */
1073 UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
1074 {
1075  LPWINE_MLD wmld;
1076 
1077  TRACE("(%p)\n", hMidiOut);
1078 
1079  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1080  return MMSYSERR_INVALHANDLE;
1081 
1082  return MMDRV_Message(wmld, MODM_RESET, 0L, 0L);
1083 }
1084 
1085 /**************************************************************************
1086  * midiOutGetVolume [WINMM.@]
1087  */
1088 UINT WINAPI midiOutGetVolume(HMIDIOUT hMidiOut, DWORD* lpdwVolume)
1089 {
1090  LPWINE_MLD wmld;
1091 
1092  TRACE("(%p, %p);\n", hMidiOut, lpdwVolume);
1093 
1094  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) == NULL)
1095  return MMSYSERR_INVALHANDLE;
1096 
1097  return MMDRV_Message(wmld, MODM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L);
1098 }
1099 
1100 /**************************************************************************
1101  * midiOutSetVolume [WINMM.@]
1102  */
1103 UINT WINAPI midiOutSetVolume(HMIDIOUT hMidiOut, DWORD dwVolume)
1104 {
1105  LPWINE_MLD wmld;
1106 
1107  TRACE("(%p, %d);\n", hMidiOut, dwVolume);
1108 
1109  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) == NULL)
1110  return MMSYSERR_INVALHANDLE;
1111 
1112  return MMDRV_Message(wmld, MODM_SETVOLUME, dwVolume, 0L);
1113 }
1114 
1115 /**************************************************************************
1116  * midiOutCachePatches [WINMM.@]
1117  */
1118 UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank,
1119  WORD* lpwPatchArray, UINT uFlags)
1120 {
1121  /* not really necessary to support this */
1122  FIXME("not supported yet\n");
1123  return MMSYSERR_NOTSUPPORTED;
1124 }
1125 
1126 /**************************************************************************
1127  * midiOutCacheDrumPatches [WINMM.@]
1128  */
1129 UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch,
1130  WORD* lpwKeyArray, UINT uFlags)
1131 {
1132  FIXME("not supported yet\n");
1133  return MMSYSERR_NOTSUPPORTED;
1134 }
1135 
1136 /**************************************************************************
1137  * midiOutGetID [WINMM.@]
1138  */
1139 UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT* lpuDeviceID)
1140 {
1141  LPWINE_MLD wmld;
1142 
1143  TRACE("(%p, %p)\n", hMidiOut, lpuDeviceID);
1144 
1145  if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1146  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1147  return MMSYSERR_INVALHANDLE;
1148 
1149  *lpuDeviceID = wmld->uDeviceID;
1150  return MMSYSERR_NOERROR;
1151 }
1152 
1153 /**************************************************************************
1154  * midiOutMessage [WINMM.@]
1155  */
1156 UINT WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage,
1157  DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1158 {
1159  LPWINE_MLD wmld;
1160 
1161  TRACE("(%p, %04X, %08lX, %08lX)\n", hMidiOut, uMessage, dwParam1, dwParam2);
1162 
1163  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) {
1164  /* HACK... */
1165  if (uMessage == 0x0001) {
1166  *(LPDWORD)dwParam1 = 1;
1167  return 0;
1168  }
1169  if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) != NULL) {
1170  return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1171  }
1172  return MMSYSERR_INVALHANDLE;
1173  }
1174 
1175  switch (uMessage) {
1176  case MODM_OPEN:
1177  case MODM_CLOSE:
1178  FIXME("can't handle OPEN or CLOSE message!\n");
1179  return MMSYSERR_NOTSUPPORTED;
1180  }
1181  return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2);
1182 }
1183 
1184 /**************************************************************************
1185  * midiInGetNumDevs [WINMM.@]
1186  */
1188 {
1189  return MMDRV_GetNum(MMDRV_MIDIIN);
1190 }
1191 
1192 /**************************************************************************
1193  * midiInGetDevCapsW [WINMM.@]
1194  */
1196 {
1197  LPWINE_MLD wmld;
1198 
1199  TRACE("(%ld, %p, %d);\n", uDeviceID, lpCaps, uSize);
1200 
1201  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1202 
1203  if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIDIIN, TRUE)) == NULL)
1204  return MMSYSERR_INVALHANDLE;
1205 
1206  return MMDRV_Message(wmld, MIDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
1207 }
1208 
1209 /**************************************************************************
1210  * midiInGetDevCapsA [WINMM.@]
1211  */
1213 {
1214  MIDIINCAPSW micW;
1215  UINT ret;
1216 
1217  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1218 
1219  ret = midiInGetDevCapsW(uDeviceID, &micW, sizeof(micW));
1220 
1221  if (ret == MMSYSERR_NOERROR) {
1222  MIDIINCAPSA micA;
1223  micA.wMid = micW.wMid;
1224  micA.wPid = micW.wPid;
1225  micA.vDriverVersion = micW.vDriverVersion;
1226  WideCharToMultiByte( CP_ACP, 0, micW.szPname, -1, micA.szPname,
1227  sizeof(micA.szPname), NULL, NULL );
1228  micA.dwSupport = micW.dwSupport;
1229  memcpy(lpCaps, &micA, min(uSize, sizeof(micA)));
1230  }
1231  return ret;
1232 }
1233 
1234 /**************************************************************************
1235  * midiInOpen [WINMM.@]
1236  */
1237 MMRESULT WINAPI midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID,
1238  DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
1239 {
1240  HANDLE hMidiIn;
1241  LPWINE_MIDI lpwm;
1242  DWORD dwRet;
1243 
1244  TRACE("(%p, %d, %08lX, %08lX, %08X);\n",
1245  lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
1246 
1247  if (lphMidiIn != NULL) *lphMidiIn = 0;
1248 
1249  dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
1250  if (dwRet != MMSYSERR_NOERROR)
1251  return dwRet;
1252 
1253  lpwm = (LPWINE_MIDI)MMDRV_Alloc(sizeof(WINE_MIDI), MMDRV_MIDIIN, &hMidiIn,
1254  &dwFlags, &dwCallback, &dwInstance);
1255 
1256  if (lpwm == NULL)
1257  return MMSYSERR_NOMEM;
1258 
1259  lpwm->mod.hMidi = hMidiIn;
1260  lpwm->mod.dwCallback = dwCallback;
1261  lpwm->mod.dwInstance = dwInstance;
1262 
1263  lpwm->mld.uDeviceID = uDeviceID;
1264  dwRet = MMDRV_Open(&lpwm->mld, MIDM_OPEN, (DWORD_PTR)&lpwm->mod, dwFlags);
1265 
1266  if (dwRet != MMSYSERR_NOERROR) {
1267  MMDRV_Free(hMidiIn, &lpwm->mld);
1268  hMidiIn = 0;
1269  }
1270  if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
1271  TRACE("=> %d hMidi=%p\n", dwRet, hMidiIn);
1272 
1273  return dwRet;
1274 }
1275 
1276 /**************************************************************************
1277  * midiInClose [WINMM.@]
1278  */
1279 UINT WINAPI midiInClose(HMIDIIN hMidiIn)
1280 {
1281  LPWINE_MLD wmld;
1282  DWORD dwRet;
1283 
1284  TRACE("(%p)\n", hMidiIn);
1285 
1286  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1287  return MMSYSERR_INVALHANDLE;
1288 
1289  dwRet = MMDRV_Close(wmld, MIDM_CLOSE);
1290  MMDRV_Free(hMidiIn, wmld);
1291  return dwRet;
1292 }
1293 
1294 /**************************************************************************
1295  * midiInPrepareHeader [WINMM.@]
1296  */
1298  MIDIHDR* lpMidiInHdr, UINT uSize)
1299 {
1300  LPWINE_MLD wmld;
1301 
1302  TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
1303 
1304  if (lpMidiInHdr == NULL || uSize < sizeof (MIDIHDR))
1305  return MMSYSERR_INVALPARAM;
1306 
1307  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1308  return MMSYSERR_INVALHANDLE;
1309 
1310  return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD_PTR)lpMidiInHdr, uSize);
1311 }
1312 
1313 /**************************************************************************
1314  * midiInUnprepareHeader [WINMM.@]
1315  */
1317  MIDIHDR* lpMidiInHdr, UINT uSize)
1318 {
1319  LPWINE_MLD wmld;
1320 
1321  TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
1322 
1323  if (lpMidiInHdr == NULL || uSize < sizeof (MIDIHDR))
1324  return MMSYSERR_INVALPARAM;
1325 
1326  if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
1327  return MMSYSERR_NOERROR;
1328  }
1329 
1330  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1331  return MMSYSERR_INVALHANDLE;
1332 
1333  return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD_PTR)lpMidiInHdr, uSize);
1334 }
1335 
1336 /**************************************************************************
1337  * midiInAddBuffer [WINMM.@]
1338  */
1339 UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn,
1340  MIDIHDR* lpMidiInHdr, UINT uSize)
1341 {
1342  LPWINE_MLD wmld;
1343 
1344  TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
1345 
1346  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1347  return MMSYSERR_INVALHANDLE;
1348 
1349  return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD_PTR)lpMidiInHdr, uSize);
1350 }
1351 
1352 /**************************************************************************
1353  * midiInStart [WINMM.@]
1354  */
1355 UINT WINAPI midiInStart(HMIDIIN hMidiIn)
1356 {
1357  LPWINE_MLD wmld;
1358 
1359  TRACE("(%p)\n", hMidiIn);
1360 
1361  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1362  return MMSYSERR_INVALHANDLE;
1363 
1364  return MMDRV_Message(wmld, MIDM_START, 0L, 0L);
1365 }
1366 
1367 /**************************************************************************
1368  * midiInStop [WINMM.@]
1369  */
1370 UINT WINAPI midiInStop(HMIDIIN hMidiIn)
1371 {
1372  LPWINE_MLD wmld;
1373 
1374  TRACE("(%p)\n", hMidiIn);
1375 
1376  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1377  return MMSYSERR_INVALHANDLE;
1378 
1379  return MMDRV_Message(wmld, MIDM_STOP, 0L, 0L);
1380 }
1381 
1382 /**************************************************************************
1383  * midiInReset [WINMM.@]
1384  */
1385 UINT WINAPI midiInReset(HMIDIIN hMidiIn)
1386 {
1387  LPWINE_MLD wmld;
1388 
1389  TRACE("(%p)\n", hMidiIn);
1390 
1391  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1392  return MMSYSERR_INVALHANDLE;
1393 
1394  return MMDRV_Message(wmld, MIDM_RESET, 0L, 0L);
1395 }
1396 
1397 /**************************************************************************
1398  * midiInGetID [WINMM.@]
1399  */
1400 UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT* lpuDeviceID)
1401 {
1402  LPWINE_MLD wmld;
1403 
1404  TRACE("(%p, %p)\n", hMidiIn, lpuDeviceID);
1405 
1406  if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1407 
1408  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, TRUE)) == NULL)
1409  return MMSYSERR_INVALHANDLE;
1410 
1411  *lpuDeviceID = wmld->uDeviceID;
1412 
1413  return MMSYSERR_NOERROR;
1414 }
1415 
1416 /**************************************************************************
1417  * midiInMessage [WINMM.@]
1418  */
1419 UINT WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage,
1420  DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1421 {
1422  LPWINE_MLD wmld;
1423 
1424  TRACE("(%p, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
1425 
1426  if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1427  return MMSYSERR_INVALHANDLE;
1428 
1429  switch (uMessage) {
1430  case MIDM_OPEN:
1431  case MIDM_CLOSE:
1432  FIXME("can't handle OPEN or CLOSE message!\n");
1433  return MMSYSERR_NOTSUPPORTED;
1434  }
1435  return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2);
1436 }
1437 
1438 /**************************************************************************
1439  * midiConnect [WINMM.@]
1440  */
1441 MMRESULT WINAPI midiConnect(HMIDI hMidi, HMIDIOUT hmo, LPVOID pReserved)
1442 {
1443  FIXME("(%p, %p, %p): Stub\n", hMidi, hmo, pReserved);
1444  return MMSYSERR_ERROR;
1445 }
1446 
1447 /**************************************************************************
1448  * midiDisconnect [WINMM.@]
1449  */
1450 MMRESULT WINAPI midiDisconnect(HMIDI hMidi, HMIDIOUT hmo, LPVOID pReserved)
1451 {
1452  FIXME("(%p, %p, %p): Stub\n", hMidi, hmo, pReserved);
1453  return MMSYSERR_ERROR;
1454 }
1455 
1456 typedef struct WINE_MIDIStream {
1457  HMIDIOUT hDevice;
1468 } WINE_MIDIStream;
1469 
1470 #define WINE_MSM_HEADER (WM_USER+0)
1471 #define WINE_MSM_STOP (WM_USER+1)
1472 
1473 /**************************************************************************
1474  * MMSYSTEM_GetMidiStream [internal]
1475  */
1476 static BOOL MMSYSTEM_GetMidiStream(HMIDISTRM hMidiStrm, WINE_MIDIStream** lpMidiStrm, WINE_MIDI** lplpwm)
1477 {
1478  WINE_MIDI* lpwm = (LPWINE_MIDI)MMDRV_Get(hMidiStrm, MMDRV_MIDIOUT, FALSE);
1479 
1480  if (lplpwm)
1481  *lplpwm = lpwm;
1482 
1483  if (lpwm == NULL) {
1484  return FALSE;
1485  }
1486 
1487  *lpMidiStrm = (WINE_MIDIStream*)(ULONG_PTR)lpwm->mod.rgIds.dwStreamID; // FIXME: not 64 bit safe
1488 
1489  return *lpMidiStrm != NULL;
1490 }
1491 
1492 /**************************************************************************
1493  * MMSYSTEM_MidiStream_Convert [internal]
1494  */
1496 {
1497  DWORD ret = 0;
1498 
1499  if (lpMidiStrm->dwTimeDiv == 0) {
1500  FIXME("Shouldn't happen. lpMidiStrm->dwTimeDiv = 0\n");
1501  } else if (lpMidiStrm->dwTimeDiv > 0x8000) { /* SMPTE, unchecked FIXME? */
1502  int nf = -(char)HIBYTE(lpMidiStrm->dwTimeDiv); /* number of frames */
1503  int nsf = LOBYTE(lpMidiStrm->dwTimeDiv); /* number of sub-frames */
1504  ret = (pulse * 1000) / (nf * nsf);
1505  } else {
1506  ret = (DWORD)((double)pulse * ((double)lpMidiStrm->dwTempo / 1000) /
1507  (double)lpMidiStrm->dwTimeDiv);
1508  }
1509 
1510  return ret;
1511 }
1512 
1513 /**************************************************************************
1514  * MMSYSTEM_MidiStream_MessageHandler [internal]
1515  */
1517 {
1518  LPMIDIHDR lpMidiHdr;
1519  LPMIDIHDR* lpmh;
1520  LPBYTE lpData;
1521 
1522  switch (msg->message) {
1523  case WM_QUIT:
1524  SetEvent(lpMidiStrm->hEvent);
1525  return FALSE;
1526  case WINE_MSM_STOP:
1527  TRACE("STOP\n");
1528  /* this is not quite what MS doc says... */
1529  midiOutReset(lpMidiStrm->hDevice);
1530  /* empty list of already submitted buffers */
1531  for (lpMidiHdr = lpMidiStrm->lpMidiHdr; lpMidiHdr; lpMidiHdr = lpMidiHdr->lpNext) {
1532  lpMidiHdr->dwFlags |= MHDR_DONE;
1533  lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1534 
1535  DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
1536  (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
1537  lpwm->mod.dwInstance, (DWORD_PTR)lpMidiHdr, 0);
1538  }
1539  lpMidiStrm->lpMidiHdr = 0;
1540  SetEvent(lpMidiStrm->hEvent);
1541  break;
1542  case WINE_MSM_HEADER:
1543  /* sets initial tick count for first MIDIHDR */
1544  if (!lpMidiStrm->dwStartTicks)
1545  lpMidiStrm->dwStartTicks = GetTickCount();
1546 
1547  /* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
1548  * by native mcimidi, it doesn't look like a correct one".
1549  * this trick allows to throw it away... but I don't like it.
1550  * It looks like part of the file I'm trying to play and definitively looks
1551  * like raw midi content
1552  * I'd really like to understand why native mcimidi sends it. Perhaps a bad
1553  * synchronization issue where native mcimidi is still processing raw MIDI
1554  * content before generating MIDIEVENTs ?
1555  *
1556  * 4c 04 89 3b 00 81 7c 99 3b 43 00 99 23 5e 04 89 L..;..|.;C..#^..
1557  * 3b 00 00 89 23 00 7c 99 3b 45 00 99 28 62 04 89 ;...#.|.;E..(b..
1558  * 3b 00 00 89 28 00 81 7c 99 3b 4e 00 99 23 5e 04 ;...(..|.;N..#^.
1559  * 89 3b 00 00 89 23 00 7c 99 3b 45 00 99 23 78 04 .;...#.|.;E..#x.
1560  * 89 3b 00 00 89 23 00 81 7c 99 3b 48 00 99 23 5e .;...#..|.;H..#^
1561  * 04 89 3b 00 00 89 23 00 7c 99 3b 4e 00 99 28 62 ..;...#.|.;N..(b
1562  * 04 89 3b 00 00 89 28 00 81 7c 99 39 4c 00 99 23 ..;...(..|.9L..#
1563  * 5e 04 89 39 00 00 89 23 00 82 7c 99 3b 4c 00 99 ^..9...#..|.;L..
1564  * 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b 48 00 99 #^..;...#.|.;H..
1565  * 28 62 04 89 3b 00 00 89 28 00 81 7c 99 3b 3f 04 (b..;...(..|.;?.
1566  * 89 3b 00 1c 99 23 5e 04 89 23 00 5c 99 3b 45 00 .;...#^..#.\.;E.
1567  * 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 3b 46 .#x..;...#..|.;F
1568  * 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b 48 ..#^..;...#.|.;H
1569  * 00 99 28 62 04 89 3b 00 00 89 28 00 81 7c 99 3b ..(b..;...(..|.;
1570  * 46 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b F..#^..;...#.|.;
1571  * 48 00 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 H..#x..;...#..|.
1572  * 3b 4c 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 ;L..#^..;...#.|.
1573  */
1574  lpMidiHdr = (LPMIDIHDR)msg->lParam;
1575  lpData = (LPBYTE)lpMidiHdr->lpData;
1576  TRACE("Adding %s lpMidiHdr=%p [lpData=0x%p dwBufferLength=%u/%u dwFlags=0x%08x size=%lu]\n",
1577  (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", lpMidiHdr,
1578  lpMidiHdr, lpMidiHdr->dwBufferLength, lpMidiHdr->dwBytesRecorded,
1579  lpMidiHdr->dwFlags, msg->wParam);
1580 #if 0
1581  /* dumps content of lpMidiHdr->lpData
1582  * FIXME: there should be a debug routine somewhere that already does this
1583  * I hate spreading this type of shit all around the code
1584  */
1585  for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) {
1586  DWORD i;
1587  BYTE ch;
1588 
1589  for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++)
1590  printf("%02x ", lpData[dwToGo + i]);
1591  for (; i < 16; i++)
1592  printf(" ");
1593  for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) {
1594  ch = lpData[dwToGo + i];
1595  printf("%c", (ch >= 0x20 && ch <= 0x7F) ? ch : '.');
1596  }
1597  printf("\n");
1598  }
1599 #endif
1600  if (((LPMIDIEVENT)lpData)->dwStreamID != 0 &&
1601  ((LPMIDIEVENT)lpData)->dwStreamID != 0xFFFFFFFF &&
1602  /* FIXME: not 64 bit safe */
1603  ((LPMIDIEVENT)lpData)->dwStreamID != (DWORD_PTR)lpMidiStrm) {
1604  FIXME("Dropping bad %s lpMidiHdr (streamID=%08x)\n",
1605  (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular",
1606  ((LPMIDIEVENT)lpData)->dwStreamID);
1607  lpMidiHdr->dwFlags |= MHDR_DONE;
1608  lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1609 
1610  DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
1611  (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
1612  lpwm->mod.dwInstance, (DWORD_PTR)lpMidiHdr, 0);
1613  break;
1614  }
1615 
1616  for (lpmh = &lpMidiStrm->lpMidiHdr; *lpmh; lpmh = &(*lpmh)->lpNext);
1617  *lpmh = lpMidiHdr;
1618  lpMidiHdr = (LPMIDIHDR)msg->lParam;
1619  lpMidiHdr->lpNext = 0;
1620  lpMidiHdr->dwFlags |= MHDR_INQUEUE;
1621  lpMidiHdr->dwFlags &= ~MHDR_DONE;
1622  lpMidiHdr->dwOffset = 0;
1623 
1624  break;
1625  default:
1626  FIXME("Unknown message %d\n", msg->message);
1627  break;
1628  }
1629  return TRUE;
1630 }
1631 
1632 /**************************************************************************
1633  * MMSYSTEM_MidiStream_Player [internal]
1634  */
1636 {
1637  WINE_MIDIStream* lpMidiStrm = pmt;
1638  WINE_MIDI* lpwm;
1639  MSG msg;
1640  DWORD dwToGo;
1641  DWORD dwCurrTC;
1642  LPMIDIHDR lpMidiHdr;
1643  LPMIDIEVENT me;
1644  LPBYTE lpData = 0;
1645 
1646  TRACE("(%p)!\n", lpMidiStrm);
1647 
1648  if (!lpMidiStrm ||
1649  (lpwm = (LPWINE_MIDI)MMDRV_Get(lpMidiStrm->hDevice, MMDRV_MIDIOUT, FALSE)) == NULL)
1650  goto the_end;
1651 
1652  /* force thread's queue creation */
1653  /* Used to be InitThreadInput16(0, 5); */
1654  /* but following works also with hack in midiStreamOpen */
1655  PeekMessageA(&msg, 0, 0, 0, 0);
1656 
1657  /* FIXME: this next line must be called before midiStreamOut or midiStreamRestart are called */
1658  SetEvent(lpMidiStrm->hEvent);
1659  TRACE("Ready to go 1\n");
1660  /* thread is started in paused mode */
1661  SuspendThread(lpMidiStrm->hThread);
1662  TRACE("Ready to go 2\n");
1663 
1664  lpMidiStrm->dwStartTicks = 0;
1665  lpMidiStrm->dwPulses = 0;
1666 
1667  lpMidiStrm->lpMidiHdr = 0;
1668 
1669  for (;;) {
1670  lpMidiHdr = lpMidiStrm->lpMidiHdr;
1671  if (!lpMidiHdr) {
1672  /* for first message, block until one arrives, then process all that are available */
1673  GetMessageA(&msg, 0, 0, 0);
1674  do {
1675  if (!MMSYSTEM_MidiStream_MessageHandler(lpMidiStrm, lpwm, &msg))
1676  goto the_end;
1677  } while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE));
1678  lpData = 0;
1679  continue;
1680  }
1681 
1682  if (!lpData)
1683  lpData = (LPBYTE)lpMidiHdr->lpData;
1684 
1685  me = (LPMIDIEVENT)(lpData + lpMidiHdr->dwOffset);
1686 
1687  /* do we have to wait ? */
1688  if (me->dwDeltaTime) {
1689  lpMidiStrm->dwPositionMS += MMSYSTEM_MidiStream_Convert(lpMidiStrm, me->dwDeltaTime);
1690  lpMidiStrm->dwPulses += me->dwDeltaTime;
1691 
1692  dwToGo = lpMidiStrm->dwStartTicks + lpMidiStrm->dwPositionMS;
1693 
1694  TRACE("%d/%d/%d\n", dwToGo, GetTickCount(), me->dwDeltaTime);
1695  while ((dwCurrTC = GetTickCount()) < dwToGo) {
1696  if (MsgWaitForMultipleObjects(0, NULL, FALSE, dwToGo - dwCurrTC, QS_ALLINPUT) == WAIT_OBJECT_0) {
1697  /* got a message, handle it */
1698  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
1699  if (!MMSYSTEM_MidiStream_MessageHandler(lpMidiStrm, lpwm, &msg))
1700  goto the_end;
1701  }
1702  lpData = 0;
1703  } else {
1704  /* timeout, so me->dwDeltaTime is elapsed, can break the while loop */
1705  break;
1706  }
1707  }
1708  }
1709  switch (MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK)) {
1710  case MEVT_COMMENT:
1711  FIXME("NIY: MEVT_COMMENT\n");
1712  /* do nothing, skip bytes */
1713  break;
1714  case MEVT_LONGMSG:
1715  FIXME("NIY: MEVT_LONGMSG, aka sending Sysex event\n");
1716  break;
1717  case MEVT_NOP:
1718  break;
1719  case MEVT_SHORTMSG:
1720  midiOutShortMsg(lpMidiStrm->hDevice, MEVT_EVENTPARM(me->dwEvent));
1721  break;
1722  case MEVT_TEMPO:
1723  lpMidiStrm->dwTempo = MEVT_EVENTPARM(me->dwEvent);
1724  break;
1725  case MEVT_VERSION:
1726  break;
1727  default:
1728  FIXME("Unknown MEVT (0x%02x)\n", MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK));
1729  break;
1730  }
1731  if (me->dwEvent & MEVT_F_CALLBACK) {
1732  DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
1733  (HDRVR)lpMidiStrm->hDevice, MM_MOM_POSITIONCB,
1734  lpwm->mod.dwInstance, (LPARAM)lpMidiHdr, 0L);
1735  }
1736  lpMidiHdr->dwOffset += sizeof(MIDIEVENT) - sizeof(me->dwParms);
1737  if (me->dwEvent & MEVT_F_LONG)
1738  lpMidiHdr->dwOffset += (MEVT_EVENTPARM(me->dwEvent) + 3) & ~3;
1739  if (lpMidiHdr->dwOffset >= lpMidiHdr->dwBufferLength) {
1740  /* done with this header */
1741  lpMidiHdr->dwFlags |= MHDR_DONE;
1742  lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1743 
1744  lpMidiStrm->lpMidiHdr = lpMidiHdr->lpNext;
1745  DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
1746  (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
1747  lpwm->mod.dwInstance, (DWORD_PTR)lpMidiHdr, 0);
1748  lpData = 0;
1749  }
1750  }
1751 the_end:
1752  TRACE("End of thread\n");
1753  ExitThread(0);
1754  return 0; /* for removing the warning, never executed */
1755 }
1756 
1757 /**************************************************************************
1758  * MMSYSTEM_MidiStream_PostMessage [internal]
1759  */
1761 {
1762  if (PostThreadMessageA(lpMidiStrm->dwThreadID, msg, pmt1, pmt2)) {
1763  //DWORD count;
1764 
1765  //ReleaseThunkLock(&count);
1766  WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
1767  //RestoreThunkLock(count);
1768  } else {
1769  WARN("bad PostThreadMessageA\n");
1770  return FALSE;
1771  }
1772  return TRUE;
1773 }
1774 
1775 /**************************************************************************
1776  * midiStreamClose [WINMM.@]
1777  */
1778 MMRESULT WINAPI midiStreamClose(HMIDISTRM hMidiStrm)
1779 {
1780  WINE_MIDIStream* lpMidiStrm;
1781 
1782  TRACE("(%p)!\n", hMidiStrm);
1783 
1784  if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
1785  return MMSYSERR_INVALHANDLE;
1786 
1787  midiStreamStop(hMidiStrm);
1788  MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WM_QUIT, 0, 0);
1789  HeapFree(GetProcessHeap(), 0, lpMidiStrm);
1790  CloseHandle(lpMidiStrm->hEvent);
1791 
1792  return midiOutClose((HMIDIOUT)hMidiStrm);
1793 }
1794 
1795 /**************************************************************************
1796  * midiStreamOpen [WINMM.@]
1797  */
1798 MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
1799  DWORD cMidi, DWORD_PTR dwCallback,
1800  DWORD_PTR dwInstance, DWORD fdwOpen)
1801 {
1802  WINE_MIDIStream* lpMidiStrm;
1803  MMRESULT ret;
1804  MIDIOPENSTRMID mosm;
1805  LPWINE_MIDI lpwm;
1806  HMIDIOUT hMidiOut;
1807 
1808  TRACE("(%p, %p, %d, 0x%08lx, 0x%08lx, 0x%08x)!\n",
1809  lphMidiStrm, lpuDeviceID, cMidi, dwCallback, dwInstance, fdwOpen);
1810 
1811  if (cMidi != 1 || lphMidiStrm == NULL || lpuDeviceID == NULL)
1812  return MMSYSERR_INVALPARAM;
1813 
1814  ret = WINMM_CheckCallback(dwCallback, fdwOpen, FALSE);
1815  if (ret != MMSYSERR_NOERROR)
1816  return ret;
1817 
1818  lpMidiStrm = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_MIDIStream));
1819  if (!lpMidiStrm)
1820  return MMSYSERR_NOMEM;
1821 
1822  lpMidiStrm->dwTempo = 500000;
1823  lpMidiStrm->dwTimeDiv = 480; /* 480 is 120 quarter notes per minute *//* FIXME ??*/
1824  lpMidiStrm->dwPositionMS = 0;
1825 
1826  mosm.dwStreamID = (DWORD_PTR)lpMidiStrm; // FIXME: not 64 bit safe
1827  /* FIXME: the correct value is not allocated yet for MAPPER */
1828  mosm.wDeviceID = *lpuDeviceID;
1829  lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &fdwOpen, 1, &mosm);
1830  lpMidiStrm->hDevice = hMidiOut;
1831  *lphMidiStrm = (HMIDISTRM)hMidiOut;
1832 
1833  lpwm->mld.uDeviceID = *lpuDeviceID;
1834 
1835  ret = MMDRV_Open(&lpwm->mld, MODM_OPEN, (DWORD_PTR)&lpwm->mod, fdwOpen);
1836  lpMidiStrm->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1837  lpMidiStrm->wFlags = HIWORD(fdwOpen);
1838 
1840  lpMidiStrm, 0, &(lpMidiStrm->dwThreadID));
1841 
1842  if (!lpMidiStrm->hThread) {
1843  midiStreamClose((HMIDISTRM)hMidiOut);
1844  return MMSYSERR_NOMEM;
1845  }
1847 
1848  /* wait for thread to have started, and for its queue to be created */
1849  {
1850  //DWORD count;
1851 
1852  /* (Release|Restore)ThunkLock() is needed when this method is called from 16 bit code,
1853  * (meaning the Win16Lock is set), so that it's released and the 32 bit thread running
1854  * MMSYSTEM_MidiStreamPlayer can acquire Win16Lock to create its queue.
1855  */
1856  //ReleaseThunkLock(&count);
1857  WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
1858  //RestoreThunkLock(count);
1859  }
1860 
1861  TRACE("=> (%u/%d) hMidi=%p ret=%d lpMidiStrm=%p\n",
1862  *lpuDeviceID, lpwm->mld.uDeviceID, *lphMidiStrm, ret, lpMidiStrm);
1863  return ret;
1864 }
1865 
1866 /**************************************************************************
1867  * midiStreamOut [WINMM.@]
1868  */
1869 MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr,
1870  UINT cbMidiHdr)
1871 {
1872  WINE_MIDIStream* lpMidiStrm;
1874 
1875  TRACE("(%p, %p, %u)!\n", hMidiStrm, lpMidiHdr, cbMidiHdr);
1876 
1877  if (cbMidiHdr < offsetof(MIDIHDR,dwOffset) || !lpMidiHdr || !lpMidiHdr->lpData
1878  || lpMidiHdr->dwBufferLength < lpMidiHdr->dwBytesRecorded
1879  || lpMidiHdr->dwBytesRecorded % 4 /* player expects DWORD padding */)
1880  return MMSYSERR_INVALPARAM;
1881  /* FIXME: Native additionally checks if the MIDIEVENTs in lpData
1882  * exactly fit dwBytesRecorded. */
1883 
1884  if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
1885  return MIDIERR_UNPREPARED;
1886 
1887  if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
1888  return MIDIERR_STILLPLAYING;
1889 
1890  if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
1892  } else {
1893  lpMidiHdr->dwFlags |= MHDR_ISSTRM;
1894  if (!PostThreadMessageA(lpMidiStrm->dwThreadID,
1895  WINE_MSM_HEADER, cbMidiHdr,
1896  (LPARAM)lpMidiHdr)) {
1897  WARN("bad PostThreadMessageA\n");
1898  ret = MMSYSERR_ERROR;
1899  }
1900  }
1901  return ret;
1902 }
1903 
1904 /**************************************************************************
1905  * midiStreamPause [WINMM.@]
1906  */
1907 MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
1908 {
1909  WINE_MIDIStream* lpMidiStrm;
1911 
1912  TRACE("(%p)!\n", hMidiStrm);
1913 
1914  if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
1916  } else {
1917  if (SuspendThread(lpMidiStrm->hThread) == 0xFFFFFFFF) {
1918  WARN("bad Suspend (%d)\n", GetLastError());
1919  ret = MMSYSERR_ERROR;
1920  }
1921  }
1922  return ret;
1923 }
1924 
1925 /**************************************************************************
1926  * midiStreamPosition [WINMM.@]
1927  */
1928 MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbmmt)
1929 {
1930  WINE_MIDIStream* lpMidiStrm;
1932 
1933  TRACE("(%p, %p, %u)!\n", hMidiStrm, lpMMT, cbmmt);
1934 
1935  if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
1937  } else if (lpMMT == NULL || cbmmt != sizeof(MMTIME)) {
1939  } else {
1940  switch (lpMMT->wType) {
1941  case TIME_MS:
1942  lpMMT->u.ms = lpMidiStrm->dwPositionMS;
1943  TRACE("=> %d ms\n", lpMMT->u.ms);
1944  break;
1945  case TIME_TICKS:
1946  lpMMT->u.ticks = lpMidiStrm->dwPulses;
1947  TRACE("=> %d ticks\n", lpMMT->u.ticks);
1948  break;
1949  default:
1950  WARN("Unsupported time type %d\n", lpMMT->wType);
1951  lpMMT->wType = TIME_MS;
1953  break;
1954  }
1955  }
1956  return ret;
1957 }
1958 
1959 /**************************************************************************
1960  * midiStreamProperty [WINMM.@]
1961  */
1962 MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
1963 {
1964  WINE_MIDIStream* lpMidiStrm;
1966 
1967  TRACE("(%p, %p, %x)\n", hMidiStrm, lpPropData, dwProperty);
1968 
1969  if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
1971  } else if ((dwProperty & (MIDIPROP_GET|MIDIPROP_SET)) == 0) {
1973  } else if (dwProperty & MIDIPROP_TEMPO) {
1974  MIDIPROPTEMPO* mpt = (MIDIPROPTEMPO*)lpPropData;
1975 
1976  if (sizeof(MIDIPROPTEMPO) != mpt->cbStruct) {
1978  } else if (dwProperty & MIDIPROP_SET) {
1979  lpMidiStrm->dwTempo = mpt->dwTempo;
1980  TRACE("Setting tempo to %d\n", mpt->dwTempo);
1981  } else if (dwProperty & MIDIPROP_GET) {
1982  mpt->dwTempo = lpMidiStrm->dwTempo;
1983  TRACE("Getting tempo <= %d\n", mpt->dwTempo);
1984  }
1985  } else if (dwProperty & MIDIPROP_TIMEDIV) {
1986  MIDIPROPTIMEDIV* mptd = (MIDIPROPTIMEDIV*)lpPropData;
1987 
1988  if (sizeof(MIDIPROPTIMEDIV) != mptd->cbStruct) {
1990  } else if (dwProperty & MIDIPROP_SET) {
1991  lpMidiStrm->dwTimeDiv = mptd->dwTimeDiv;
1992  TRACE("Setting time div to %d\n", mptd->dwTimeDiv);
1993  } else if (dwProperty & MIDIPROP_GET) {
1994  mptd->dwTimeDiv = lpMidiStrm->dwTimeDiv;
1995  TRACE("Getting time div <= %d\n", mptd->dwTimeDiv);
1996  }
1997  } else {
1999  }
2000 
2001  return ret;
2002 }
2003 
2004 /**************************************************************************
2005  * midiStreamRestart [WINMM.@]
2006  */
2007 MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
2008 {
2009  WINE_MIDIStream* lpMidiStrm;
2011 
2012  TRACE("(%p)!\n", hMidiStrm);
2013 
2014  if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
2016  } else {
2017  DWORD ret;
2018 
2019  /* since we increase the thread suspend count on each midiStreamPause
2020  * there may be a need for several midiStreamResume
2021  */
2022  do {
2023  ret = ResumeThread(lpMidiStrm->hThread);
2024  } while (ret != 0xFFFFFFFF && ret != 0);
2025  if (ret == 0xFFFFFFFF) {
2026  WARN("bad Resume (%d)\n", GetLastError());
2027  ret = MMSYSERR_ERROR;
2028  } else {
2029  lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
2030  }
2031  }
2032  return ret;
2033 }
2034 
2035 /**************************************************************************
2036  * midiStreamStop [WINMM.@]
2037  */
2038 MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
2039 {
2040  WINE_MIDIStream* lpMidiStrm;
2042 
2043  TRACE("(%p)!\n", hMidiStrm);
2044 
2045  if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
2047  } else {
2048  /* in case stream has been paused... FIXME is the current state correct ? */
2049  midiStreamRestart(hMidiStrm);
2051  }
2052  return ret;
2053 }
2054 
2055 static UINT WAVE_Open(HANDLE* lphndl, UINT uDeviceID, UINT uType,
2056  LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback,
2057  DWORD_PTR dwInstance, DWORD dwFlags)
2058 {
2059  HANDLE handle;
2060  LPWINE_MLD wmld;
2061  DWORD dwRet;
2062  WAVEOPENDESC wod;
2063 
2064  TRACE("(%p, %d, %s, %p, %08lX, %08lX, %08X);\n",
2065  lphndl, (int)uDeviceID, (uType==MMDRV_WAVEOUT)?"Out":"In", lpFormat, dwCallback,
2066  dwInstance, dwFlags);
2067 
2068  if (dwFlags & WAVE_FORMAT_QUERY)
2069  TRACE("WAVE_FORMAT_QUERY requested !\n");
2070 
2071  dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
2072  if (dwRet != MMSYSERR_NOERROR)
2073  return dwRet;
2074 
2075  if (lpFormat == NULL) {
2076  WARN("bad format\n");
2077  return WAVERR_BADFORMAT;
2078  }
2079 
2080  if ((dwFlags & WAVE_MAPPED) && (uDeviceID == (UINT)-1)) {
2081  WARN("invalid parameter\n");
2082  return MMSYSERR_INVALPARAM;
2083  }
2084 
2085  /* may have a PCMWAVEFORMAT rather than a WAVEFORMATEX so don't read cbSize */
2086  TRACE("wFormatTag=%u, nChannels=%u, nSamplesPerSec=%u, nAvgBytesPerSec=%u, nBlockAlign=%u, wBitsPerSample=%u\n",
2087  lpFormat->wFormatTag, lpFormat->nChannels, lpFormat->nSamplesPerSec,
2088  lpFormat->nAvgBytesPerSec, lpFormat->nBlockAlign, lpFormat->wBitsPerSample);
2089 
2090  if ((wmld = MMDRV_Alloc(sizeof(WINE_WAVE), uType, &handle,
2091  &dwFlags, &dwCallback, &dwInstance)) == NULL) {
2092  return MMSYSERR_NOMEM;
2093  }
2094 
2095  wod.hWave = handle;
2096  wod.lpFormat = (LPWAVEFORMATEX)lpFormat; /* should the struct be copied iso pointer? */
2097  wod.dwCallback = dwCallback;
2098  wod.dwInstance = dwInstance;
2099  wod.dnDevNode = 0L;
2100 
2101  TRACE("cb=%08lx\n", wod.dwCallback);
2102 
2103  for (;;) {
2104  if (dwFlags & WAVE_MAPPED) {
2105  wod.uMappedDeviceID = uDeviceID;
2106  uDeviceID = WAVE_MAPPER;
2107  } else {
2108  wod.uMappedDeviceID = -1;
2109  }
2110  wmld->uDeviceID = uDeviceID;
2111 
2112  dwRet = MMDRV_Open(wmld, (uType == MMDRV_WAVEOUT) ? WODM_OPEN : WIDM_OPEN,
2113  (DWORD_PTR)&wod, dwFlags);
2114 
2115  TRACE("dwRet = %s\n", WINMM_ErrorToString(dwRet));
2116  if (dwRet != WAVERR_BADFORMAT ||
2117  ((dwFlags & (WAVE_MAPPED|WAVE_FORMAT_DIRECT)) != 0) || (uDeviceID == WAVE_MAPPER)) break;
2118  /* if we ask for a format which isn't supported by the physical driver,
2119  * let's try to map it through the wave mapper (except, if we already tried
2120  * or user didn't allow us to use acm codecs or the device is already the mapper)
2121  */
2122  dwFlags |= WAVE_MAPPED;
2123  /* we shall loop only one */
2124  }
2125 
2126  if ((dwFlags & WAVE_FORMAT_QUERY) || dwRet != MMSYSERR_NOERROR) {
2127  MMDRV_Free(handle, wmld);
2128  handle = 0;
2129  }
2130 
2131  if (lphndl != NULL) *lphndl = handle;
2132  TRACE("=> %s hWave=%p\n", WINMM_ErrorToString(dwRet), handle);
2133 
2134  return dwRet;
2135 }
2136 
2137 /**************************************************************************
2138  * waveOutGetNumDevs [WINMM.@]
2139  */
2141 {
2142  return MMDRV_GetNum(MMDRV_WAVEOUT);
2143 }
2144 
2145 /**************************************************************************
2146  * waveOutGetDevCapsA [WINMM.@]
2147  */
2149  UINT uSize)
2150 {
2151  WAVEOUTCAPSW wocW;
2152  UINT ret;
2153 
2154  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2155 
2156  ret = waveOutGetDevCapsW(uDeviceID, &wocW, sizeof(wocW));
2157 
2158  if (ret == MMSYSERR_NOERROR) {
2159  WAVEOUTCAPSA wocA;
2160  wocA.wMid = wocW.wMid;
2161  wocA.wPid = wocW.wPid;
2162  wocA.vDriverVersion = wocW.vDriverVersion;
2163  WideCharToMultiByte( CP_ACP, 0, wocW.szPname, -1, wocA.szPname,
2164  sizeof(wocA.szPname), NULL, NULL );
2165  wocA.dwFormats = wocW.dwFormats;
2166  wocA.wChannels = wocW.wChannels;
2167  wocA.dwSupport = wocW.dwSupport;
2168  memcpy(lpCaps, &wocA, min(uSize, sizeof(wocA)));
2169  }
2170  return ret;
2171 }
2172 
2173 /**************************************************************************
2174  * waveOutGetDevCapsW [WINMM.@]
2175  */
2177  UINT uSize)
2178 {
2179  LPWINE_MLD wmld;
2180 
2181  TRACE("(%lu %p %u)!\n", uDeviceID, lpCaps, uSize);
2182 
2183  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2184 
2185  if (uDeviceID == WAVE_MAPPER)
2186  {
2187  FIXME("Support WAVE_MAPPER\n");
2188  uDeviceID = 0;
2189  }
2190 
2191  if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEOUT, TRUE)) == NULL)
2192  return MMSYSERR_BADDEVICEID;
2193 
2194  return MMDRV_Message(wmld, WODM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
2195 }
2196 
2197 /**************************************************************************
2198  * waveOutGetErrorTextA [WINMM.@]
2199  * waveInGetErrorTextA [WINMM.@]
2200  */
2202 {
2203  UINT ret;
2204 
2205  if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
2206  else if (uSize == 0) ret = MMSYSERR_NOERROR;
2207  else
2208  {
2209  LPWSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize * sizeof(WCHAR));
2210  if (!xstr) ret = MMSYSERR_NOMEM;
2211  else
2212  {
2213  ret = waveOutGetErrorTextW(uError, xstr, uSize);
2214  if (ret == MMSYSERR_NOERROR)
2215  WideCharToMultiByte(CP_ACP, 0, xstr, -1, lpText, uSize, NULL, NULL);
2216  HeapFree(GetProcessHeap(), 0, xstr);
2217  }
2218  }
2219  return ret;
2220 }
2221 
2222 /**************************************************************************
2223  * waveOutGetErrorTextW [WINMM.@]
2224  * waveInGetErrorTextW [WINMM.@]
2225  */
2227 {
2229 
2230  if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
2231  else if (uSize == 0) ret = MMSYSERR_NOERROR;
2232  else if (
2233  /* test has been removed because MMSYSERR_BASE is 0, and gcc did emit
2234  * a warning for the test was always true */
2235  (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
2236  (uError >= WAVERR_BASE && uError <= WAVERR_LASTERROR)) {
2238  uError, lpText, uSize) > 0) {
2240  }
2241  }
2242  return ret;
2243 }
2244 
2245 /**************************************************************************
2246  * waveOutOpen [WINMM.@]
2247  * All the args/structs have the same layout as the win16 equivalents
2248  */
2250  LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback,
2251  DWORD_PTR dwInstance, DWORD dwFlags)
2252 {
2253  return WAVE_Open((HANDLE*)lphWaveOut, uDeviceID, MMDRV_WAVEOUT, lpFormat,
2254  dwCallback, dwInstance, dwFlags);
2255 }
2256 
2257 /**************************************************************************
2258  * waveOutClose [WINMM.@]
2259  */
2260 UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
2261 {
2262  LPWINE_MLD wmld;
2263  DWORD dwRet;
2264 
2265  TRACE("(%p)\n", hWaveOut);
2266 
2267  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2268  return MMSYSERR_INVALHANDLE;
2269 
2270  dwRet = MMDRV_Close(wmld, WODM_CLOSE);
2271  if (dwRet != WAVERR_STILLPLAYING)
2272  MMDRV_Free(hWaveOut, wmld);
2273 
2274  return dwRet;
2275 }
2276 
2277 /**************************************************************************
2278  * waveOutPrepareHeader [WINMM.@]
2279  */
2281  WAVEHDR* lpWaveOutHdr, UINT uSize)
2282 {
2283  LPWINE_MLD wmld;
2284  UINT result;
2285 
2286  TRACE("(%p, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2287 
2288  if (lpWaveOutHdr == NULL || uSize < sizeof (WAVEHDR))
2289  return MMSYSERR_INVALPARAM;
2290 
2291  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2292  return MMSYSERR_INVALHANDLE;
2293 
2294  if ((result = MMDRV_Message(wmld, WODM_PREPARE, (DWORD_PTR)lpWaveOutHdr,
2295  uSize)) != MMSYSERR_NOTSUPPORTED)
2296  return result;
2297 
2298  if (lpWaveOutHdr->dwFlags & WHDR_INQUEUE)
2299  return WAVERR_STILLPLAYING;
2300 
2301  lpWaveOutHdr->dwFlags |= WHDR_PREPARED;
2302  lpWaveOutHdr->dwFlags &= ~WHDR_DONE;
2303 
2304  return MMSYSERR_NOERROR;
2305 }
2306 
2307 /**************************************************************************
2308  * waveOutUnprepareHeader [WINMM.@]
2309  */
2311  LPWAVEHDR lpWaveOutHdr, UINT uSize)
2312 {
2313  LPWINE_MLD wmld;
2314  UINT result;
2315 
2316  TRACE("(%p, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2317 
2318  if (lpWaveOutHdr == NULL || uSize < sizeof (WAVEHDR))
2319  return MMSYSERR_INVALPARAM;
2320 
2321  if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
2322  return MMSYSERR_NOERROR;
2323  }
2324 
2325  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2326  return MMSYSERR_INVALHANDLE;
2327 
2328  if ((result = MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD_PTR)lpWaveOutHdr,
2329  uSize)) != MMSYSERR_NOTSUPPORTED)
2330  return result;
2331 
2332  if (lpWaveOutHdr->dwFlags & WHDR_INQUEUE)
2333  return WAVERR_STILLPLAYING;
2334 
2335  lpWaveOutHdr->dwFlags &= ~WHDR_PREPARED;
2336  lpWaveOutHdr->dwFlags |= WHDR_DONE;
2337 
2338  return MMSYSERR_NOERROR;
2339 }
2340 
2341 /**************************************************************************
2342  * waveOutWrite [WINMM.@]
2343  */
2344 UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr,
2345  UINT uSize)
2346 {
2347  LPWINE_MLD wmld;
2348 
2349  TRACE("(%p, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2350 
2351  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2352  return MMSYSERR_INVALHANDLE;
2353 
2354  return MMDRV_Message(wmld, WODM_WRITE, (DWORD_PTR)lpWaveOutHdr, uSize);
2355 }
2356 
2357 /**************************************************************************
2358  * waveOutBreakLoop [WINMM.@]
2359  */
2360 UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
2361 {
2362  LPWINE_MLD wmld;
2363 
2364  TRACE("(%p);\n", hWaveOut);
2365 
2366  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2367  return MMSYSERR_INVALHANDLE;
2368  return MMDRV_Message(wmld, WODM_BREAKLOOP, 0L, 0L);
2369 }
2370 
2371 /**************************************************************************
2372  * waveOutPause [WINMM.@]
2373  */
2374 UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
2375 {
2376  LPWINE_MLD wmld;
2377 
2378  TRACE("(%p);\n", hWaveOut);
2379 
2380  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2381  return MMSYSERR_INVALHANDLE;
2382  return MMDRV_Message(wmld, WODM_PAUSE, 0L, 0L);
2383 }
2384 
2385 /**************************************************************************
2386  * waveOutReset [WINMM.@]
2387  */
2388 UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
2389 {
2390  LPWINE_MLD wmld;
2391 
2392  TRACE("(%p);\n", hWaveOut);
2393 
2394  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2395  return MMSYSERR_INVALHANDLE;
2396  return MMDRV_Message(wmld, WODM_RESET, 0L, 0L);
2397 }
2398 
2399 /**************************************************************************
2400  * waveOutRestart [WINMM.@]
2401  */
2402 UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
2403 {
2404  LPWINE_MLD wmld;
2405 
2406  TRACE("(%p);\n", hWaveOut);
2407 
2408  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2409  return MMSYSERR_INVALHANDLE;
2410  return MMDRV_Message(wmld, WODM_RESTART, 0L, 0L);
2411 }
2412 
2413 /**************************************************************************
2414  * waveOutGetPosition [WINMM.@]
2415  */
2416 UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime,
2417  UINT uSize)
2418 {
2419  LPWINE_MLD wmld;
2420 
2421  TRACE("(%p, %p, %u);\n", hWaveOut, lpTime, uSize);
2422 
2423  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2424  return MMSYSERR_INVALHANDLE;
2425 
2426  return MMDRV_Message(wmld, WODM_GETPOS, (DWORD_PTR)lpTime, uSize);
2427 }
2428 
2429 /**************************************************************************
2430  * waveOutGetPitch [WINMM.@]
2431  */
2432 UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, LPDWORD lpdw)
2433 {
2434  LPWINE_MLD wmld;
2435 
2436  TRACE("(%p, %p);\n", hWaveOut, lpdw);
2437 
2438  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2439  return MMSYSERR_INVALHANDLE;
2440  return MMDRV_Message(wmld, WODM_GETPITCH, (DWORD_PTR)lpdw, 0L);
2441 }
2442 
2443 /**************************************************************************
2444  * waveOutSetPitch [WINMM.@]
2445  */
2446 UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dw)
2447 {
2448  LPWINE_MLD wmld;
2449 
2450  TRACE("(%p, %08x);\n", hWaveOut, dw);
2451 
2452  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2453  return MMSYSERR_INVALHANDLE;
2454  return MMDRV_Message(wmld, WODM_SETPITCH, dw, 0L);
2455 }
2456 
2457 /**************************************************************************
2458  * waveOutGetPlaybackRate [WINMM.@]
2459  */
2460 UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, LPDWORD lpdw)
2461 {
2462  LPWINE_MLD wmld;
2463 
2464  TRACE("(%p, %p);\n", hWaveOut, lpdw);
2465 
2466  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2467  return MMSYSERR_INVALHANDLE;
2468  return MMDRV_Message(wmld, WODM_GETPLAYBACKRATE, (DWORD_PTR)lpdw, 0L);
2469 }
2470 
2471 /**************************************************************************
2472  * waveOutSetPlaybackRate [WINMM.@]
2473  */
2475 {
2476  LPWINE_MLD wmld;
2477 
2478  TRACE("(%p, %08x);\n", hWaveOut, dw);
2479 
2480  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2481  return MMSYSERR_INVALHANDLE;
2482  return MMDRV_Message(wmld, WODM_SETPLAYBACKRATE, dw, 0L);
2483 }
2484 
2485 /**************************************************************************
2486  * waveOutGetVolume [WINMM.@]
2487  */
2488 UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
2489 {
2490  LPWINE_MLD wmld;
2491 
2492  TRACE("(%p, %p);\n", hWaveOut, lpdw);
2493 
2494  if (lpdw == NULL) {
2495  WARN("invalid parameter\n");
2496  return MMSYSERR_INVALPARAM;
2497  }
2498 
2499  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) == NULL)
2500  return MMSYSERR_INVALHANDLE;
2501 
2502  return MMDRV_Message(wmld, WODM_GETVOLUME, (DWORD_PTR)lpdw, 0L);
2503 }
2504 
2505 /**************************************************************************
2506  * waveOutSetVolume [WINMM.@]
2507  */
2508 UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
2509 {
2510  LPWINE_MLD wmld;
2511 
2512  TRACE("(%p, %08x);\n", hWaveOut, dw);
2513 
2514  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) == NULL)
2515  return MMSYSERR_INVALHANDLE;
2516 
2517  return MMDRV_Message(wmld, WODM_SETVOLUME, dw, 0L);
2518 }
2519 
2520 /**************************************************************************
2521  * waveOutGetID [WINMM.@]
2522  */
2523 UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT* lpuDeviceID)
2524 {
2525  LPWINE_MLD wmld;
2526 
2527  TRACE("(%p, %p);\n", hWaveOut, lpuDeviceID);
2528 
2529  if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
2530 
2531  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2532  return MMSYSERR_INVALHANDLE;
2533 
2534  *lpuDeviceID = wmld->uDeviceID;
2535  return 0;
2536 }
2537 
2538 /**************************************************************************
2539  * waveOutMessage [WINMM.@]
2540  */
2541 UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage,
2542  DWORD_PTR dwParam1, DWORD_PTR dwParam2)
2543 {
2544  LPWINE_MLD wmld;
2545 
2546  TRACE("(%p, %u, %ld, %ld)\n", hWaveOut, uMessage, dwParam1, dwParam2);
2547 
2548  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) {
2549  if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) != NULL) {
2550  return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
2551  }
2552  WARN("invalid handle\n");
2553  return MMSYSERR_INVALHANDLE;
2554  }
2555 
2556  /* from M$ KB */
2557  if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER)) {
2558  WARN("invalid parameter\n");
2559  return MMSYSERR_INVALPARAM;
2560  }
2561 
2562  return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2);
2563 }
2564 
2565 /**************************************************************************
2566  * waveInGetNumDevs [WINMM.@]
2567  */
2569 {
2570  return MMDRV_GetNum(MMDRV_WAVEIN);
2571 }
2572 
2573 /**************************************************************************
2574  * waveInGetDevCapsW [WINMM.@]
2575  */
2577 {
2578  LPWINE_MLD wmld;
2579 
2580  TRACE("(%lu %p %u)!\n", uDeviceID, lpCaps, uSize);
2581 
2582  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2583 
2584  if (uDeviceID == WAVE_MAPPER)
2585  {
2586  FIXME("Support WAVE_MAPPER\n");
2587  uDeviceID = 0;
2588  }
2589 
2590 
2591  if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEIN, TRUE)) == NULL)
2592  return MMSYSERR_BADDEVICEID;
2593 
2594  return MMDRV_Message(wmld, WIDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
2595 }
2596 
2597 /**************************************************************************
2598  * waveInGetDevCapsA [WINMM.@]
2599  */
2601 {
2602  WAVEINCAPSW wicW;
2603  UINT ret;
2604 
2605  if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2606 
2607  ret = waveInGetDevCapsW(uDeviceID, &wicW, sizeof(wicW));
2608 
2609  if (ret == MMSYSERR_NOERROR) {
2610  WAVEINCAPSA wicA;
2611  wicA.wMid = wicW.wMid;
2612  wicA.wPid = wicW.wPid;
2613  wicA.vDriverVersion = wicW.vDriverVersion;
2614  WideCharToMultiByte( CP_ACP, 0, wicW.szPname, -1, wicA.szPname,
2615  sizeof(wicA.szPname), NULL, NULL );
2616  wicA.dwFormats = wicW.dwFormats;
2617  wicA.wChannels = wicW.wChannels;
2618  memcpy(lpCaps, &wicA, min(uSize, sizeof(wicA)));
2619  }
2620  return ret;
2621 }
2622 
2623 /**************************************************************************
2624  * waveInOpen [WINMM.@]
2625  */
2626 MMRESULT WINAPI waveInOpen(HWAVEIN* lphWaveIn, UINT uDeviceID,
2627  LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback,
2628  DWORD_PTR dwInstance, DWORD dwFlags)
2629 {
2630  return WAVE_Open((HANDLE*)lphWaveIn, uDeviceID, MMDRV_WAVEIN, lpFormat,
2631  dwCallback, dwInstance, dwFlags);
2632 }
2633 
2634 /**************************************************************************
2635  * waveInClose [WINMM.@]
2636  */
2637 UINT WINAPI waveInClose(HWAVEIN hWaveIn)
2638 {
2639  LPWINE_MLD wmld;
2640  DWORD dwRet;
2641 
2642  TRACE("(%p)\n", hWaveIn);
2643 
2644  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2645  return MMSYSERR_INVALHANDLE;
2646 
2647  dwRet = MMDRV_Message(wmld, WIDM_CLOSE, 0L, 0L);
2648  if (dwRet != WAVERR_STILLPLAYING)
2649  MMDRV_Free(hWaveIn, wmld);
2650  return dwRet;
2651 }
2652 
2653 /**************************************************************************
2654  * waveInPrepareHeader [WINMM.@]
2655  */
2656 UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
2657  UINT uSize)
2658 {
2659  LPWINE_MLD wmld;
2660  UINT result;
2661 
2662  TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
2663 
2664  if (lpWaveInHdr == NULL || uSize < sizeof (WAVEHDR))
2665  return MMSYSERR_INVALPARAM;
2666 
2667  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2668  return MMSYSERR_INVALHANDLE;
2669 
2670  if ((result = MMDRV_Message(wmld, WIDM_PREPARE, (DWORD_PTR)lpWaveInHdr,
2671  uSize)) != MMSYSERR_NOTSUPPORTED)
2672  return result;
2673 
2674  if (lpWaveInHdr->dwFlags & WHDR_INQUEUE)
2675  return WAVERR_STILLPLAYING;
2676 
2677  lpWaveInHdr->dwFlags |= WHDR_PREPARED;
2678  lpWaveInHdr->dwFlags &= ~WHDR_DONE;
2679  lpWaveInHdr->dwBytesRecorded = 0;
2680 
2681  return MMSYSERR_NOERROR;
2682 }
2683 
2684 /**************************************************************************
2685  * waveInUnprepareHeader [WINMM.@]
2686  */
2687 UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
2688  UINT uSize)
2689 {
2690  LPWINE_MLD wmld;
2691  UINT result;
2692 
2693  TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
2694 
2695  if (lpWaveInHdr == NULL || uSize < sizeof (WAVEHDR))
2696  return MMSYSERR_INVALPARAM;
2697 
2698  if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED))
2699  return MMSYSERR_NOERROR;
2700 
2701  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2702  return MMSYSERR_INVALHANDLE;
2703 
2704  if ((result = MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD_PTR)lpWaveInHdr,
2705  uSize)) != MMSYSERR_NOTSUPPORTED)
2706  return result;
2707 
2708  if (lpWaveInHdr->dwFlags & WHDR_INQUEUE)
2709  return WAVERR_STILLPLAYING;
2710 
2711  lpWaveInHdr->dwFlags &= ~WHDR_PREPARED;
2712  lpWaveInHdr->dwFlags |= WHDR_DONE;
2713 
2714  return MMSYSERR_NOERROR;
2715 }
2716 
2717 /**************************************************************************
2718  * waveInAddBuffer [WINMM.@]
2719  */
2720 UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn,
2721  WAVEHDR* lpWaveInHdr, UINT uSize)
2722 {
2723  LPWINE_MLD wmld;
2724 
2725  TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
2726 
2727  if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
2728  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2729  return MMSYSERR_INVALHANDLE;
2730 
2731  return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD_PTR)lpWaveInHdr, uSize);
2732 }
2733 
2734 /**************************************************************************
2735  * waveInReset [WINMM.@]
2736  */
2737 UINT WINAPI waveInReset(HWAVEIN hWaveIn)
2738 {
2739  LPWINE_MLD wmld;
2740 
2741  TRACE("(%p);\n", hWaveIn);
2742 
2743  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2744  return MMSYSERR_INVALHANDLE;
2745 
2746  return MMDRV_Message(wmld, WIDM_RESET, 0L, 0L);
2747 }
2748 
2749 /**************************************************************************
2750  * waveInStart [WINMM.@]
2751  */
2752 UINT WINAPI waveInStart(HWAVEIN hWaveIn)
2753 {
2754  LPWINE_MLD wmld;
2755 
2756  TRACE("(%p);\n", hWaveIn);
2757 
2758  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2759  return MMSYSERR_INVALHANDLE;
2760 
2761  return MMDRV_Message(wmld, WIDM_START, 0L, 0L);
2762 }
2763 
2764 /**************************************************************************
2765  * waveInStop [WINMM.@]
2766  */
2767 UINT WINAPI waveInStop(HWAVEIN hWaveIn)
2768 {
2769  LPWINE_MLD wmld;
2770 
2771  TRACE("(%p);\n", hWaveIn);
2772 
2773  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2774  return MMSYSERR_INVALHANDLE;
2775 
2776  return MMDRV_Message(wmld,WIDM_STOP, 0L, 0L);
2777 }
2778 
2779 /**************************************************************************
2780  * waveInGetPosition [WINMM.@]
2781  */
2782 UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime,
2783  UINT uSize)
2784 {
2785  LPWINE_MLD wmld;
2786 
2787  TRACE("(%p, %p, %u);\n", hWaveIn, lpTime, uSize);
2788 
2789  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2790  return MMSYSERR_INVALHANDLE;
2791 
2792  return MMDRV_Message(wmld, WIDM_GETPOS, (DWORD_PTR)lpTime, uSize);
2793 }
2794 
2795 /**************************************************************************
2796  * waveInGetID [WINMM.@]
2797  */
2798 UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT* lpuDeviceID)
2799 {
2800  LPWINE_MLD wmld;
2801 
2802  TRACE("(%p, %p);\n", hWaveIn, lpuDeviceID);
2803 
2804  if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
2805 
2806  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2807  return MMSYSERR_INVALHANDLE;
2808 
2809  *lpuDeviceID = wmld->uDeviceID;
2810  return MMSYSERR_NOERROR;
2811 }
2812 
2813 /**************************************************************************
2814  * waveInMessage [WINMM.@]
2815  */
2816 UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage,
2817  DWORD_PTR dwParam1, DWORD_PTR dwParam2)
2818 {
2819  LPWINE_MLD wmld;
2820 
2821  TRACE("(%p, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2);
2822 
2823  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL) {
2824  if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, TRUE)) != NULL) {
2825  return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
2826  }
2827  return MMSYSERR_INVALHANDLE;
2828  }
2829 
2830  /* from M$ KB */
2831  if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
2832  return MMSYSERR_INVALPARAM;
2833 
2834 
2835  return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2);
2836 }
2837 
2839 {
2843 };
2844 
2845 static DWORD WINAPI mmTaskRun(void* pmt)
2846 {
2847  struct mm_starter mms;
2848 
2849  memcpy(&mms, pmt, sizeof(struct mm_starter));
2850  HeapFree(GetProcessHeap(), 0, pmt);
2851  mms.cb(mms.client);
2852  if (mms.event) SetEvent(mms.event);
2853  return 0;
2854 }
2855 
2856 /******************************************************************
2857  * mmTaskCreate (WINMM.@)
2858  */
2860 {
2861  HANDLE hThread;
2862  HANDLE hEvent = 0;
2863  struct mm_starter *mms;
2864 
2865  mms = HeapAlloc(GetProcessHeap(), 0, sizeof(struct mm_starter));
2866  if (mms == NULL) return TASKERR_OUTOFMEMORY;
2867 
2868  mms->cb = cb;
2869  mms->client = client;
2870  if (ph) hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
2871  mms->event = hEvent;
2872 
2873  hThread = CreateThread(0, 0, mmTaskRun, mms, 0, NULL);
2874  if (!hThread) {
2875  HeapFree(GetProcessHeap(), 0, mms);
2876  if (hEvent) CloseHandle(hEvent);
2877  return TASKERR_OUTOFMEMORY;
2878  }
2880  if (ph) *ph = hEvent;
2882  return 0;
2883 }
2884 
2885 /******************************************************************
2886  * mmTaskBlock (WINMM.@)
2887  */
2889 {
2890  MSG msg;
2891 
2892  do
2893  {
2894  GetMessageA(&msg, 0, 0, 0);
2895  if (msg.hwnd) DispatchMessageA(&msg);
2896  } while (msg.message != WM_USER);
2897 }
2898 
2899 /******************************************************************
2900  * mmTaskSignal (WINMM.@)
2901  */
2903 {
2904  return PostThreadMessageW(tid, WM_USER, 0, 0);
2905 }
2906 
2907 /******************************************************************
2908  * mmTaskYield (WINMM.@)
2909  */
2911 
2912 /******************************************************************
2913  * mmGetCurrentTask (WINMM.@)
2914  */
2916 {
2917  return GetCurrentThreadId();
2918 }
#define MMSYSERR_BADDB
Definition: mmsystem.h:110
DWORD dwTimeDiv
Definition: winmm.c:1461
UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime, UINT uSize)
Definition: winmm.c:2416
static LPWINE_MIDI MIDI_OutAlloc(HMIDIOUT *lphMidiOut, DWORD_PTR *lpdwCallback, DWORD_PTR *lpdwInstance, LPDWORD lpdwFlags, DWORD cIDs, MIDIOPENSTRMID *lpIDs)
Definition: winmm.c:912
DWORD dwSupport
Definition: mmsystem.h:1205
#define WAVERR_BADFORMAT
Definition: mmsystem.h:176
DWORD dwCallback
Definition: mmddk.h:413
WINE_MLD mld
Definition: winemm.h:109
#define MMSYSERR_KEYNOTFOUND
Definition: mmsystem.h:111
void DRIVER_UnloadAll(void)
Definition: driver.c:658
DWORD fdwSupport
Definition: mmsystem.h:1227
const char * WINMM_ErrorToString(MMRESULT error)
Definition: winmm.c:113
#define MIXER_OBJECTF_HWAVEIN
Definition: mmsystem.h:305
#define WODM_PAUSE
Definition: mmddk.h:115
UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
Definition: winmm.c:684
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1310
DWORD fdwLine
Definition: mmsystem.h:1236
LPWINE_MLD MMDRV_Get(HANDLE _hndl, UINT type, BOOL bCanBeID)
Definition: lolvldrv.c:250
struct WINE_MIXER * LPWINE_MIXER
#define max(a, b)
Definition: svc.c:63
#define WAVE_FORMAT_QUERY
Definition: mmsystem.h:188
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
Definition: winmm.c:2637
#define MIXER_GETCONTROLDETAILSF_VALUE
Definition: mmsystem.h:412
#define MMDRV_MIXER
Definition: winemm.h:77
#define MEVT_EVENTTYPE(x)
Definition: mmsystem.h:275
#define WIDM_GETDEVCAPS
Definition: mmddk.h:137
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define MMSYSERR_READERROR
Definition: mmsystem.h:112
#define TRUE
Definition: types.h:120
BOOL WINMM_CheckForMMSystem(void)
Definition: winmm.c:89
#define CloseHandle
Definition: compat.h:398
#define MIDM_CLOSE
Definition: mmddk.h:172
DWORD fdwSupport
Definition: mmsystem.h:1218
#define AUXDM_SETVOLUME
Definition: mmddk.h:185
UINT WINAPI midiOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
Definition: winmm.c:891
#define DRVM_IOCTL
Definition: mmddk.h:66
#define CALLBACK_WINDOW
Definition: mmsystem.h:148
VOID WINAPI mmTaskBlock(DWORD tid)
Definition: winmm.c:2888
DWORD cIds
Definition: mmddk.h:416
WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1309
#define WODM_GETDEVCAPS
Definition: mmddk.h:109
UINT WINAPI midiInStart(HMIDIIN hMidiIn)
Definition: winmm.c:1355
MMVERSION vDriverVersion
Definition: mmsystem.h:1145
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1217
#define DWORD_PTR
Definition: treelist.c:76
#define MMDRV_MIDIIN
Definition: winemm.h:78
UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW, DWORD fdwInfo)
Definition: winmm.c:595
#define WideCharToMultiByte
Definition: compat.h:101
LPMIXERCONTROLW pamxctrl
Definition: mmsystem.h:1350
#define error(str)
Definition: mkdosfs.c:1605
UINT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdW, DWORD fdwDetails)
Definition: winmm.c:426
DWORD dwUser
Definition: mmsystem.h:1237
#define MCI_WAIT
Definition: mmsystem.h:730
BOOL WINAPI IsWindow(_In_opt_ HWND)
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2541
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1060
#define LOBYTE(W)
Definition: jmemdos.c:487
DWORD dwPositionMS
Definition: winmm.c:1462
UINT WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:1156
MMRESULT WINAPI waveInOpen(HWAVEIN *lphWaveIn, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2626
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1050
#define MXDM_GETDEVCAPS
Definition: mmddk.h:192
UINT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA, DWORD fdwDetails)
Definition: winmm.c:447
DWORD dwControlType
Definition: mmsystem.h:1306
UINT WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:1419
union mmtime_tag::@2910 u
UINT WINAPI midiOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
Definition: winmm.c:866
#define WODM_GETPLAYBACKRATE
Definition: mmddk.h:123
DWORD dwInstance
Definition: mmddk.h:414
UINT WINAPI midiOutGetVolume(HMIDIOUT hMidiOut, DWORD *lpdwVolume)
Definition: winmm.c:1088
HANDLE hEvent
Definition: winmm.c:1466
WORD wDeviceID
Definition: mmddk.h:408
LPSTR lpData
Definition: mmsystem.h:1151
#define WIDM_RESET
Definition: mmddk.h:145
#define MXDM_CLOSE
Definition: mmddk.h:194
#define CP_ACP
Definition: compat.h:99
UINT wType
Definition: mmsystem.h:965
#define MIDIERR_STILLPLAYING
Definition: mmsystem.h:232
DWORD dwBufferLength
Definition: mmsystem.h:1152
DWORD dwCallback
Definition: mmddk.h:400
static BOOL MMSYSTEM_GetMidiStream(HMIDISTRM hMidiStrm, WINE_MIDIStream **lpMidiStrm, WINE_MIDI **lplpwm)
Definition: winmm.c:1476
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
MIDIOPENSTRMID rgIds
Definition: mmddk.h:417
#define WIDM_START
Definition: mmddk.h:143
#define WIDM_STOP
Definition: mmddk.h:144
LPTASKCALLBACK cb
Definition: winmm.c:2840
LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD *dwFlags, DWORD_PTR *dwCallback, DWORD_PTR *dwInstance)
Definition: lolvldrv.c:123
#define WARN(fmt,...)
Definition: debug.h:111
UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1316
#define MODM_LONGDATA
Definition: mmddk.h:161
WORD wTechnology
Definition: mmsystem.h:1203
MMRESULT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:942
MMRESULT WINAPI midiInOpen(HMIDIIN *lphMidiIn, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:1237
#define CALLBACK
Definition: compat.h:27
CHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1368
#define WINE_MSM_HEADER
Definition: winmm.c:1470
HWND hWnd
Definition: settings.c:17
UINT WINAPI mixerClose(HMIXER hMix)
Definition: winmm.c:389
#define MIXER_GETLINECONTROLSF_QUERYMASK
Definition: mmsystem.h:411
#define WM_QUIT
Definition: winuser.h:1605
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
#define HIBYTE(W)
Definition: jmemdos.c:486
#define MIXER_GETCONTROLDETAILSF_LISTTEXT
Definition: mmsystem.h:413
DWORD cDestinations
Definition: mmsystem.h:1228
HANDLE HWND
Definition: compat.h:13
UINT WINAPI midiOutSetVolume(HMIDIOUT hMidiOut, DWORD dwVolume)
Definition: winmm.c:1103
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
#define WINE_MSM_STOP
Definition: winmm.c:1471
BOOL WINAPI PostThreadMessageA(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
DWORD dwLineID
Definition: mmsystem.h:1258
#define WODM_RESTART
Definition: mmddk.h:116
WINE_DEFAULT_DEBUG_CHANNEL(winmm)
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
DWORD cMultipleItems
Definition: mmsystem.h:1308
UINT MMRESULT
Definition: mmsystem.h:962
#define WIDM_GETPOS
Definition: mmddk.h:146
#define MEVT_F_CALLBACK
Definition: mmsystem.h:274
uint32_t * LPUINT
Definition: typedefs.h:57
#define MIXER_OBJECTF_MIDIIN
Definition: mmsystem.h:308
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
#define MIXER_GETLINEINFOF_COMPONENTTYPE
Definition: mmsystem.h:347
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1146
UINT_PTR WPARAM
Definition: windef.h:207
#define MIDM_START
Definition: mmddk.h:176
#define WODM_OPEN
Definition: mmddk.h:110
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
MMVERSION vDriverVersion
Definition: mmsystem.h:1125
#define WODM_GETPITCH
Definition: mmddk.h:119
#define MIDM_RESET
Definition: mmddk.h:178
#define MIXER_OBJECTF_HMIDIOUT
Definition: mmsystem.h:307
UINT WINAPI midiInClose(HMIDIIN hMidiIn)
Definition: winmm.c:1279
static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream *lpMidiStrm, LPWINE_MIDI lpwm, LPMSG msg)
Definition: winmm.c:1516
UINT uFlags
Definition: api.c:60
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
Definition: winmm.c:1907
#define CALLBACK_TYPEMASK
Definition: mmsystem.h:146
MMVERSION vDriverVersion
Definition: mmsystem.h:1216
MMVERSION vDriverVersion
Definition: mmsystem.h:1113
UINT uMappedDeviceID
Definition: mmddk.h:402
#define MIXER_OBJECTF_MIDIOUT
Definition: mmsystem.h:306
#define MMDRV_WAVEOUT
Definition: winemm.h:81
char * LPSTR
Definition: xmlstorage.h:182
DWORD WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:702
static BOOL MMSYSTEM_MidiStream_PostMessage(WINE_MIDIStream *lpMidiStrm, WORD msg, DWORD pmt1, DWORD pmt2)
Definition: winmm.c:1760
struct tagMIXERCONTROLW MIXERCONTROLW
UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT *lpuDeviceID)
Definition: winmm.c:1139
union tagMIXERCONTROLA::@2916 Metrics
#define MODM_GETDEVCAPS
Definition: mmddk.h:155
MMRESULT WINAPI midiConnect(HMIDI hMidi, HMIDIOUT hmo, LPVOID pReserved)
Definition: winmm.c:1441
HWAVEOUT * LPHWAVEOUT
Definition: mmsystem.h:1009
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
DWORD dnDevNode
Definition: mmddk.h:403
UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2656
MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer)
Definition: winmm.c:196
HANDLE hThread
Definition: winmm.c:1458
UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2460
MIDIOPENDESC mod
Definition: winemm.h:110
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1114
UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank, WORD *lpwPatchArray, UINT uFlags)
Definition: winmm.c:1118
CHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1242
static DWORD(WINAPI *pLoadLibrary16)(LPCSTR)
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2816
#define MIDM_GETDEVCAPS
Definition: mmddk.h:170
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2280
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
static HANDLE hEvent
Definition: comm.c:54
WINE_MLD mld
Definition: winemm.h:114
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define WAVE_FORMAT_DIRECT
Definition: mmsystem.h:191
DWORD dwStartTicks
Definition: winmm.c:1464
UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
Definition: winmm.c:1042
BOOL WINAPI mmTaskSignal(DWORD tid)
Definition: winmm.c:2902
DWORD cControls
Definition: mmsystem.h:1241
HANDLE event
Definition: winmm.c:2842
UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2576
#define MMSYSERR_VALNOTFOUND
Definition: mmsystem.h:115
UINT WINAPI auxGetNumDevs(void)
Definition: winmm.c:718
UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2432
MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr, UINT cbMidiHdr)
Definition: winmm.c:1869
#define sprintf(buf, format,...)
Definition: sprintf.c:55
CHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1283
CRITICAL_SECTION WINMM_cs
Definition: winmm.c:54
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define CALLBACK_EVENT
Definition: mmsystem.h:152
void TIME_MMTimeStop(void)
Definition: time.c:270
HMIDIOUT * LPHMIDIOUT
Definition: mmsystem.h:1101
#define MIXER_OBJECTF_MIXER
Definition: mmsystem.h:300
#define MODM_PREPARE
Definition: mmddk.h:158
WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1265
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
union tagMIXERCONTROLW::@2920 Metrics
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2488
UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD *lpdwVolume)
Definition: winmm.c:768
#define ERR_TO_STR(dev)
DWORD dwControlType
Definition: mmsystem.h:1280
#define MIDIERR_UNPREPARED
Definition: mmsystem.h:231
DWORD dwSupport
Definition: mmsystem.h:1195
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
#define MMSYSERR_NODRIVERCB
Definition: mmsystem.h:116
unsigned char * LPBYTE
Definition: typedefs.h:52
UINT WINAPI midiOutGetDevCapsA(UINT_PTR uDeviceID, LPMIDIOUTCAPSA lpCaps, UINT uSize)
Definition: winmm.c:835
UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2176
#define MMDRV_AUX
Definition: winemm.h:76
LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType, BOOL bSrcCanBeID, UINT dstType)
Definition: lolvldrv.c:285
MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
Definition: winmm.c:2038
LPMIXERCONTROLA pamxctrl
Definition: mmsystem.h:1338
unsigned int BOOL
Definition: ntddk_ex.h:94
MMVERSION vDriverVersion
Definition: mmsystem.h:1059
#define MIDIPROP_GET
Definition: mmsystem.h:285
struct tagMIXERLINEA::@2913 Target
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
#define WAVERR_LASTERROR
Definition: mmsystem.h:180
#define MMSYSERR_HANDLEBUSY
Definition: mmsystem.h:108
#define MMDRV_WAVEIN
Definition: winemm.h:80
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
DWORD dwFlags
Definition: mmsystem.h:1018
MMVERSION vDriverVersion
Definition: mmsystem.h:1201
DWORD dwComponentType
Definition: mmsystem.h:1261
#define FIXME(fmt,...)
Definition: debug.h:110
UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2687
#define WIDM_ADDBUFFER
Definition: mmddk.h:142
DWORD dwFormats
Definition: mmsystem.h:1061
struct _WAVEFORMATEX * LPWAVEFORMATEX
MMVERSION vDriverVersion
Definition: mmsystem.h:1137
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
VOID WINAPI mmTaskYield(VOID)
Definition: winmm.c:2910
DWORD dwDestination
Definition: mmsystem.h:1256
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
MMVERSION vDriverVersion
Definition: mmsystem.h:1027
#define offsetof(TYPE, MEMBER)
unsigned char
Definition: typeof.h:29
MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbmmt)
Definition: winmm.c:1928
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2508
LONG_PTR LPARAM
Definition: windef.h:208
UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
Definition: winmm.c:2360
DWORD dnDevNode
Definition: mmddk.h:415
#define MCI_ALL_DEVICE_ID
Definition: mmsystem.h:679
DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD dwFlags)
Definition: lolvldrv.c:183
struct tagMIXERLINEW::@2914 Target
UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1339
UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT *lpuDeviceID)
Definition: winmm.c:1400
#define MIXER_OBJECTF_HMIDIIN
Definition: mmsystem.h:309
#define MIXER_GETLINEINFOF_DESTINATION
Definition: mmsystem.h:344
#define MMSYSERR_LASTERROR
Definition: mmsystem.h:118
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:364
#define WODM_GETVOLUME
Definition: mmddk.h:121
#define MHDR_ISSTRM
Definition: mmsystem.h:271
const char * LPCSTR
Definition: xmlstorage.h:183
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2140
UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
Definition: winmm.c:342
HMIXER * LPHMIXER
Definition: mmsystem.h:1211
#define MXDM_SETCONTROLDETAILS
Definition: mmddk.h:198
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:458
UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1000
DWORD ticks
Definition: mmsystem.h:970
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:699
UINT WINAPI auxGetDevCapsW(UINT_PTR uDeviceID, LPAUXCAPSW lpCaps, UINT uSize)
Definition: winmm.c:726
static BOOL WINMM_CreateIData(HINSTANCE hInstDLL)
Definition: winmm.c:59
#define MIXER_OBJECTF_HWAVEOUT
Definition: mmsystem.h:303
UINT WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD_PTR dw1, DWORD_PTR dw2)
Definition: winmm.c:796
#define DLL_PROCESS_DETACH
Definition: compat.h:119
HWAVE hWave
Definition: mmddk.h:398
UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
Definition: winmm.c:1073
#define MEVT_LONGMSG
Definition: mmsystem.h:280
DWORD dwThreadID
Definition: winmm.c:1459
MMRESULT WINAPI midiStreamClose(HMIDISTRM hMidiStrm)
Definition: winmm.c:1778
#define MODM_UNPREPARE
Definition: mmddk.h:159
#define AUXDM_GETVOLUME
Definition: mmddk.h:184
#define MXDM_GETCONTROLDETAILS
Definition: mmddk.h:197
WORD wTechnology
Definition: mmsystem.h:1193
DWORD cConnections
Definition: mmsystem.h:1240
static UINT MIXER_GetDev(HMIXEROBJ hmix, DWORD dwFlags, LPWINE_MIXER *lplpwm)
Definition: winmm.c:229
#define WODM_PREPARE
Definition: mmddk.h:112
DWORD cControls
Definition: mmsystem.h:1264
MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
Definition: winmm.c:2007
#define MIXER_GETLINEINFOF_LINEID
Definition: mmsystem.h:346
DWORD dwLineID
Definition: mmsystem.h:1235
#define MODM_CLOSE
Definition: mmddk.h:157
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1126
#define TRACE(s)
Definition: solgame.cpp:4
UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1297
#define MMDRV_MIDIOUT
Definition: winemm.h:79
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
#define WIDM_PREPARE
Definition: mmddk.h:140
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
MMVERSION vDriverVersion
Definition: mmsystem.h:1191
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define TASKERR_OUTOFMEMORY
Definition: mmddk.h:470
#define MIXER_OBJECTF_WAVEIN
Definition: mmsystem.h:304
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1374
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2374
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define MMSYSERR_ALLOCATED
Definition: mmsystem.h:100
UINT WINAPI waveOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
Definition: winmm.c:2226
DWORD dwSource
Definition: mmsystem.h:1257
UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
Definition: winmm.c:981
DWORD cChannels
Definition: mmsystem.h:1262
CHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1284
#define MIXER_OBJECTF_AUX
Definition: mmsystem.h:310
UINT WINAPI midiInGetDevCapsW(UINT_PTR uDeviceID, LPMIDIINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:1195
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define MIXER_GETLINEINFOF_TARGETTYPE
Definition: mmsystem.h:348
#define TIME_MS
Definition: mmsystem.h:28
UINT WINAPI mixerGetLineInfoA(HMIXEROBJ hmix, LPMIXERLINEA lpmliA, DWORD fdwInfo)
Definition: winmm.c:615
#define WODM_BREAKLOOP
Definition: mmddk.h:125
HMIDI hMidi
Definition: mmddk.h:412
struct tagMIXERCONTROLA MIXERCONTROLA
#define WODM_WRITE
Definition: mmddk.h:114
DWORD cbStruct
Definition: mmsystem.h:1255
DWORD dwFormats
Definition: mmsystem.h:1051
#define WINAPI
Definition: msvc.h:8
HMIDIOUT hDevice
Definition: winmm.c:1457
DWORD dwUser
Definition: mmsystem.h:1260
void MMDRV_Exit(void)
Definition: lolvldrv.c:607
DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: lolvldrv.c:71
DWORD fdwLine
Definition: mmsystem.h:1259
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1202
static FILE * client
Definition: client.c:41
unsigned short WORD
Definition: ntddk_ex.h:93
LPWAVEFORMATEX lpFormat
Definition: mmddk.h:399
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT WINAPI mixerGetLineControlsA(HMIXEROBJ hmix, LPMIXERLINECONTROLSA lpmlcA, DWORD fdwControls)
Definition: winmm.c:506
#define MEVT_NOP
Definition: mmsystem.h:279
#define CALLBACK_THREAD
Definition: mmsystem.h:151
#define MIDM_UNPREPARE
Definition: mmddk.h:174
CHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1243
#define MMSYSERR_INVALFLAG
Definition: mmsystem.h:106
#define MEVT_EVENTPARM(x)
Definition: mmsystem.h:276
static void WINMM_DeleteIData(void)
Definition: winmm.c:71
REFIID LPVOID DWORD dw
Definition: atlbase.h:40
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define MIDIPROP_SET
Definition: mmsystem.h:284
struct WINE_MIDIStream WINE_MIDIStream
#define WAVERR_SYNC
Definition: mmsystem.h:179
#define WODM_SETPITCH
Definition: mmddk.h:120
Definition: id3.c:18
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
static DWORD cb
Definition: integrity.c:41
#define MODM_OPEN
Definition: mmddk.h:156
#define MIXER_GETCONTROLDETAILSF_QUERYMASK
Definition: mmsystem.h:414
BOOL loaded
Definition: xmlview.c:54
#define MMSYSERR_NOTENABLED
Definition: mmsystem.h:99
#define MIDM_PREPARE
Definition: mmddk.h:173
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
Definition: winmm.c:159
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1039
UINT WINAPI waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2474
#define MIXER_OBJECTF_HMIXER
Definition: mmsystem.h:301
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2344
MMVERSION vDriverVersion
Definition: mmsystem.h:1225
DWORD dwFlags
Definition: mmsystem.h:1155
#define MIDIERR_INVALIDSETUP
Definition: mmsystem.h:236
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
MMRESULT WINAPI midiStreamOpen(HMIDISTRM *lphMidiStrm, LPUINT lpuDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
Definition: winmm.c:1798
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:278
int ret
UINT WINAPI mixerGetLineControlsW(HMIXEROBJ hmix, LPMIXERLINECONTROLSW lpmlcW, DWORD fdwControls)
Definition: winmm.c:574
#define WODM_SETVOLUME
Definition: mmddk.h:122
DWORD dwTempo
Definition: winmm.c:1460
#define MXDM_GETLINECONTROLS
Definition: mmddk.h:196
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:641
#define LPDWORD
Definition: nt_native.h:46
#define AUXDM_GETDEVCAPS
Definition: mmddk.h:183
#define MEVT_VERSION
Definition: mmsystem.h:282
#define MMSYSERR_DELETEERROR
Definition: mmsystem.h:114
static const WCHAR L[]
Definition: oid.c:1250
DWORD dwInstance
Definition: mmddk.h:401
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2720
DWORD cChannels
Definition: mmsystem.h:1239
#define MEVT_COMMENT
Definition: mmsystem.h:281
#define MMSYSERR_BADERRNUM
Definition: mmsystem.h:105
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
UINT WINAPI auxGetDevCapsA(UINT_PTR uDeviceID, LPAUXCAPSA lpCaps, UINT uSize)
Definition: winmm.c:742
unsigned char BYTE
Definition: mem.h:68
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
#define MODM_RESET
Definition: mmddk.h:162
#define MIDIPROP_TEMPO
Definition: mmsystem.h:287
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
UINT WINAPI mixerGetDevCapsW(UINT_PTR uDeviceID, LPMIXERCAPSW lpCaps, UINT uSize)
Definition: winmm.c:317
UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1019
LPCWSTR lpFormat
Definition: trayclock.cpp:32
#define MIXER_OBJECTF_WAVEOUT
Definition: mmsystem.h:302
UINT WINAPI mmTaskCreate(LPTASKCALLBACK cb, HANDLE *ph, DWORD_PTR client)
Definition: winmm.c:2859
UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: lolvldrv.c:303
static DWORD WINAPI mmTaskRun(void *pmt)
Definition: winmm.c:2845
uint32_t DWORD_PTR
Definition: typedefs.h:63
static DWORD CALLBACK MMSYSTEM_MidiStream_Player(LPVOID pmt)
Definition: winmm.c:1635
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
#define MIDIPROP_TIMEDIV
Definition: mmsystem.h:286
#define WM_USER
Definition: winuser.h:1877
struct tagMIXERCONTROLDETAILS_LISTTEXTW MIXERCONTROLDETAILS_LISTTEXTW
union tagMIXERCONTROLW::@2919 Bounds
static UINT WAVE_Open(HANDLE *lphndl, UINT uDeviceID, UINT uType, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2055
#define MHDR_DONE
Definition: mmsystem.h:268
#define WODM_CLOSE
Definition: mmddk.h:111
struct tagMIXERCONTROLDETAILS_LISTTEXTA MIXERCONTROLDETAILS_LISTTEXTA
#define DRVM_IOCTL_LAST
Definition: mmddk.h:69
#define MEVT_SHORTMSG
Definition: mmsystem.h:277
#define WIDM_UNPREPARE
Definition: mmddk.h:141
UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2446
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
Definition: winmm.c:2752
UINT WINAPI waveInReset(HWAVEIN hWaveIn)
Definition: winmm.c:2737
#define ERR(fmt,...)
Definition: debug.h:109
static HANDLE(WINAPI *pGetModuleHandle16)(LPCSTR)
#define MIDIERR_LASTERROR
Definition: mmsystem.h:239
UINT WINAPI waveOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
Definition: winmm.c:2201
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1138
HANDLE psStopEvent
Definition: winmm.c:52
MMVERSION vDriverVersion
Definition: mmsystem.h:1038
#define WAVERR_BASE
Definition: mmsystem.h:85
UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime, UINT uSize)
Definition: winmm.c:2782
DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
Definition: lolvldrv.c:228
TASKCALLBACK FAR * LPTASKCALLBACK
Definition: mmddk.h:33
DWORD dwDestination
Definition: mmsystem.h:1233
#define MIDM_OPEN
Definition: mmddk.h:171
#define CALLBACK_NULL
Definition: mmsystem.h:147
#define MODM_DATA
Definition: mmddk.h:160
UINT uDeviceID
Definition: winemm.h:94
void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
Definition: lolvldrv.c:165
#define MIXER_GETLINEINFOF_QUERYMASK
Definition: mmsystem.h:349
DWORD LPVOID fImpLoad
Definition: misc.cpp:155
DWORD cDestinations
Definition: mmsystem.h:1219
#define WODM_UNPREPARE
Definition: mmddk.h:113
struct midihdr_tag * LPMIDIHDR
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2249
UINT WINAPI waveInStop(HWAVEIN hWaveIn)
Definition: winmm.c:2767
UINT WINAPI mixerGetDevCapsA(UINT_PTR uDeviceID, LPMIXERCAPSA lpCaps, UINT uSize)
Definition: winmm.c:291
#define TIME_TICKS
Definition: mmsystem.h:33
UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch, WORD *lpwKeyArray, UINT uFlags)
Definition: winmm.c:1129
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define WHDR_INQUEUE
Definition: mmsystem.h:197
DWORD cbStruct
Definition: mmsystem.h:1232
static DWORD MMSYSTEM_MidiStream_Convert(WINE_MIDIStream *lpMidiStrm, DWORD pulse)
Definition: winmm.c:1495
#define MIDM_ADDBUFFER
Definition: mmddk.h:175
#define MIXER_GETLINEINFOF_SOURCE
Definition: mmsystem.h:345
DWORD dwSource
Definition: mmsystem.h:1234
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1266
#define QS_ALLINPUT
Definition: winuser.h:874
UINT WINAPI mixerGetNumDevs(void)
Definition: winmm.c:283
UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume)
Definition: winmm.c:782
UINT WINAPI midiInGetDevCapsA(UINT_PTR uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize)
Definition: winmm.c:1212
#define MHDR_INQUEUE
Definition: mmsystem.h:270
UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT *lpuDeviceID)
Definition: winmm.c:2523
MMRESULT WINAPI midiDisconnect(HMIDI hMidi, HMIDIOUT hmo, LPVOID pReserved)
Definition: winmm.c:1450
DWORD dwSupport
Definition: mmsystem.h:1147
#define WAVE_MAPPED
Definition: mmsystem.h:190
#define DRVM_MAPPER
Definition: mmsys.h:36
UINT WINAPI midiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:817
#define min(a, b)
Definition: monoChain.cc:55
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2260
unsigned int UINT
Definition: ndis.h:50
MMVERSION vDriverVersion
Definition: mmsystem.h:1049
DWORD cConnections
Definition: mmsystem.h:1263
DWORD dwStreamID
Definition: mmddk.h:407
#define MIXER_GETLINECONTROLSF_ONEBYTYPE
Definition: mmsystem.h:410
#define MCI_CLOSE
Definition: mmsystem.h:647
HANDLE hThread
Definition: wizard.c:27
struct midihdr_tag * lpNext
Definition: mmsystem.h:1156
#define WHDR_PREPARED
Definition: mmsystem.h:194
union tagMIXERCONTROLA::@2915 Bounds
UINT WINAPI waveOutGetDevCapsA(UINT_PTR uDeviceID, LPWAVEOUTCAPSA lpCaps, UINT uSize)
Definition: winmm.c:2148
#define MultiByteToWideChar
Definition: compat.h:100
BOOL MMDRV_Init(void)
Definition: lolvldrv.c:526
DWORD dwComponentType
Definition: mmsystem.h:1238
DWORD cMultipleItems
Definition: mmsystem.h:1282
UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1057
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1226
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2402
#define msg(x)
Definition: auth_time.c:54
UINT WINAPI midiInStop(HMIDIIN hMidiIn)
Definition: winmm.c:1370
#define WAVERR_UNPREPARED
Definition: mmsystem.h:178
UINT WINAPI waveInGetDevCapsA(UINT_PTR uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize)
Definition: winmm.c:2600
#define WODM_SETPLAYBACKRATE
Definition: mmddk.h:124
struct WINE_MIDI * LPWINE_MIDI
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT WINAPI midiInGetNumDevs(void)
Definition: winmm.c:1187
#define MEVT_F_LONG
Definition: mmsystem.h:273
LPMIDIHDR lpMidiHdr
Definition: winmm.c:1467
HINSTANCE hWinMM32Instance
Definition: winmm.c:50
#define WODM_GETPOS
Definition: mmddk.h:118
#define MIDM_STOP
Definition: mmddk.h:177
uint32_t * LPDWORD
Definition: typedefs.h:57
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:566
DWORD dwOffset
Definition: mmsystem.h:1158
static void CALLBACK MIXER_WCallback(HMIXEROBJ hmx, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam, DWORD_PTR param2)
Definition: winmm.c:329
#define HIWORD(l)
Definition: typedefs.h:246
#define WIDM_OPEN
Definition: mmddk.h:138
#define WHDR_DONE
Definition: mmsystem.h:193
#define MM_MOM_POSITIONCB
Definition: mmsystem.h:79
#define MHDR_PREPARED
Definition: mmsystem.h:269
#define GetProcAddress(x, y)
Definition: compat.h:410
DWORD dwSupport
Definition: mmsystem.h:1139
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2568
#define MEVT_TEMPO
Definition: mmsystem.h:278
#define MMSYSERR_INVALIDALIAS
Definition: mmsystem.h:109
UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT *lpuDeviceID)
Definition: winmm.c:2798
#define MIDIERR_NODEVICE
Definition: mmsystem.h:235
#define MMSYSERR_WRITEERROR
Definition: mmsystem.h:113
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1028
#define PM_REMOVE
Definition: winuser.h:1182
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev, UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
UINT WINAPI midiInReset(HMIDIIN hMidiIn)
Definition: winmm.c:1385
DWORD dwPulses
Definition: winmm.c:1463
#define WIDM_CLOSE
Definition: mmddk.h:139
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define MODM_GETVOLUME
Definition: mmddk.h:163
#define INFINITE
Definition: serial.h:102
struct midievent_tag MIDIEVENT
#define MODM_SETVOLUME
Definition: mmddk.h:164
#define MM_MOM_DONE
Definition: mmsystem.h:70
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1192
GLuint64EXT * result
Definition: glext.h:11304
HANDLE psLastEvent
Definition: winmm.c:51
DWORD ms
Definition: mmsystem.h:967
BOOL WINAPI PostThreadMessageW(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
static TfClientId tid
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388
UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
Definition: winmm.c:407
UINT MMDRV_GetNum(UINT type)
Definition: lolvldrv.c:61
UINT WINAPI midiOutGetNumDevs(void)
Definition: winmm.c:809
#define MXDM_GETLINEINFO
Definition: mmddk.h:195
#define HeapFree(x, y, z)
Definition: compat.h:394
#define MXDM_OPEN
Definition: mmddk.h:193
MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
Definition: winmm.c:1962
DWORD WINAPI mmGetCurrentTask(VOID)
Definition: winmm.c:2915
DWORD dwBytesRecorded
Definition: mmsystem.h:1153
DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: mci.c:1908
#define printf
Definition: config.h:203
static int mod
Definition: i386-dis.c:1273
#define MIDIERR_BASE
Definition: mmsystem.h:86
#define WODM_RESET
Definition: mmddk.h:117
DWORD client
Definition: winmm.c:2841