ReactOS  0.4.13-dev-66-gc714b7f
legacy.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Sound System
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/win32/wdmaud.drv/wdmaud.c
5  *
6  * PURPOSE: WDM Audio Driver (User-mode part)
7  * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
8  Johannes Anderwald
9  *
10  * NOTES: Looking for wodMessage & co? You won't find them here. Try
11  * the MME Buddy library, which is where these routines are
12  * actually implemented.
13  *
14  */
15 
16 #include "wdmaud.h"
17 
18 #define NDEBUG
19 #include <debug.h>
20 #include <mmebuddy_debug.h>
21 
22 #define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
23 
26 
27 DWORD
28 WINAPI
31 {
32  HANDLE WaitObjects[2];
33  DWORD dwResult;
37 
38  /* setup wait objects */
39  WaitObjects[0] = Instance->hNotifyEvent;
40  WaitObjects[1] = Instance->hStopEvent;
41 
42  /* zero device info */
44 
45  DeviceInfo.hDevice = Instance->Handle;
46  DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
47 
48  do
49  {
50  dwResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE);
51 
52  if (dwResult == WAIT_OBJECT_0 + 1)
53  {
54  /* stop event was signalled */
55  break;
56  }
57 
58  do
59  {
62  (LPVOID) &DeviceInfo,
63  sizeof(WDMAUD_DEVICE_INFO),
64  (LPVOID) &DeviceInfo,
65  sizeof(WDMAUD_DEVICE_INFO),
66  NULL);
67 
68  if (Result == MMSYSERR_NOERROR)
69  {
70  DriverCallback(Instance->WinMM.ClientCallback,
71  HIWORD(Instance->WinMM.Flags),
72  Instance->WinMM.Handle,
73  DeviceInfo.u.MixerEvent.NotificationType,
74  Instance->WinMM.ClientCallbackInstanceData,
75  (DWORD_PTR)DeviceInfo.u.MixerEvent.Value,
76  0);
77  }
78  }while(Result == MMSYSERR_NOERROR);
79  }while(TRUE);
80 
81  /* done */
82  return 0;
83 }
84 
87 {
89  {
92  }
93 
94  return MMSYSERR_NOERROR;
95 }
96 
101 {
104 
108 
110  DeviceInfo.DeviceType = DeviceType;
111 
114  (LPVOID) &DeviceInfo,
115  sizeof(WDMAUD_DEVICE_INFO),
116  (LPVOID) &DeviceInfo,
117  sizeof(WDMAUD_DEVICE_INFO),
118  NULL);
119 
120  if ( ! MMSUCCESS( Result ) )
121  {
122  SND_ERR(L"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
123  *DeviceCount = 0;
125  }
126 
127  *DeviceCount = DeviceInfo.DeviceCount;
128 
129  return MMSYSERR_NOERROR;
130 }
131 
132 MMRESULT
134  IN PSOUND_DEVICE SoundDevice,
135  IN DWORD DeviceId,
137  IN DWORD CapabilitiesSize)
138 {
142 
143  SND_ASSERT( SoundDevice );
145 
146  Result = GetSoundDeviceType(SoundDevice, &DeviceType);
148 
149  if ( ! MMSUCCESS(Result) )
150  return Result;
151 
152  SND_TRACE(L"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType, DeviceId);
153 
155  DeviceInfo.DeviceType = DeviceType;
156  DeviceInfo.DeviceIndex = DeviceId;
157 
160  (LPVOID) &DeviceInfo,
161  sizeof(WDMAUD_DEVICE_INFO),
162  (LPVOID) &DeviceInfo,
163  sizeof(WDMAUD_DEVICE_INFO),
164  NULL);
165 
166  if ( ! MMSUCCESS(Result) )
167  {
169  }
170 
171  /* This is pretty much a big hack right now */
172  switch ( DeviceType )
173  {
174  case MIXER_DEVICE_TYPE:
175  {
176  LPMIXERCAPSW MixerCaps = (LPMIXERCAPSW) Capabilities;
177 
178  DeviceInfo.u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
179  CopyWideString(MixerCaps->szPname, DeviceInfo.u.MixCaps.szPname);
180 
181  MixerCaps->cDestinations = DeviceInfo.u.MixCaps.cDestinations;
182  MixerCaps->fdwSupport = DeviceInfo.u.MixCaps.fdwSupport;
183  MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion;
184  MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid;
185  MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid;
186  break;
187  }
188  case WAVE_OUT_DEVICE_TYPE :
189  {
191 
192  DeviceInfo.u.WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
193  WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
194  WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
195 
196  WaveOutCaps->vDriverVersion = DeviceInfo.u.WaveOutCaps.vDriverVersion;
197  CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
198 
199  WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
200  WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
201  WaveOutCaps->dwSupport = DeviceInfo.u.WaveOutCaps.dwSupport;
202  break;
203  }
204  case WAVE_IN_DEVICE_TYPE :
205  {
207 
208  DeviceInfo.u.WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0';
209 
210  WaveInCaps->wMid = DeviceInfo.u.WaveInCaps.wMid;
211  WaveInCaps->wPid = DeviceInfo.u.WaveInCaps.wPid;
212 
213  WaveInCaps->vDriverVersion = DeviceInfo.u.WaveInCaps.vDriverVersion;
214  CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveInCaps.szPname);
215 
216  WaveInCaps->dwFormats = DeviceInfo.u.WaveInCaps.dwFormats;
217  WaveInCaps->wChannels = DeviceInfo.u.WaveInCaps.wChannels;
218  WaveInCaps->wReserved1 = 0;
219  break;
220  }
221  case MIDI_IN_DEVICE_TYPE :
222  {
224 
225  DeviceInfo.u.MidiInCaps.szPname[MAXPNAMELEN-1] = L'\0';
226 
227  MidiInCaps->vDriverVersion = DeviceInfo.u.MidiInCaps.vDriverVersion;
228  MidiInCaps->wMid = DeviceInfo.u.MidiInCaps.wMid;
229  MidiInCaps->wPid = DeviceInfo.u.MidiInCaps.wPid;
230  MidiInCaps->dwSupport = DeviceInfo.u.MidiInCaps.dwSupport;
231 
232  CopyWideString(MidiInCaps->szPname, DeviceInfo.u.MidiInCaps.szPname);
233  break;
234  }
235  case MIDI_OUT_DEVICE_TYPE :
236  {
238 
239  DeviceInfo.u.MidiOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
240 
241  MidiOutCaps->vDriverVersion = DeviceInfo.u.MidiOutCaps.vDriverVersion;
242  MidiOutCaps->wMid = DeviceInfo.u.MidiOutCaps.wMid;
243  MidiOutCaps->wPid = DeviceInfo.u.MidiOutCaps.wPid;
244  MidiOutCaps->dwSupport = DeviceInfo.u.MidiOutCaps.dwSupport;
245 
246  CopyWideString(MidiOutCaps->szPname, DeviceInfo.u.MidiOutCaps.szPname);
247  break;
248  }
249  }
250 
251  return MMSYSERR_NOERROR;
252 }
253 
254 MMRESULT
256  IN PSOUND_DEVICE SoundDevice,
257  OUT PVOID *Handle)
258 {
259  HDEVINFO hDevInfo;
260  SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
261  GUID SWBusGuid = {STATIC_KSCATEGORY_WDMAUD};
262  PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData;
263 
265  {
267  if (!hDevInfo)
268  {
269  // failed
270  return MMSYSERR_ERROR;
271  }
272 
273  DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
274  if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &SWBusGuid, 0, &DeviceInterfaceData))
275  {
276  // failed
278  return MMSYSERR_ERROR;
279  }
280 
281  DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W));
282  if (!DeviceInterfaceDetailData)
283  {
284  // failed
286  return MMSYSERR_ERROR;
287  }
288 
289  DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
290  if (!SetupDiGetDeviceInterfaceDetailW(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData,MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W), NULL, NULL))
291  {
292  // failed
293  HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
295  return MMSYSERR_ERROR;
296  }
297  SND_TRACE(L"Opening wdmaud device '%s'\n",DeviceInterfaceDetailData->DevicePath);
298  KernelHandle = CreateFileW(DeviceInterfaceDetailData->DevicePath,
300  0,
301  NULL,
304  NULL);
305 
306  HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
308  }
309 
310 
312  return MMSYSERR_ERROR;
313 
314  ++ OpenCount;
315  return MMSYSERR_NOERROR;
316 
317 }
318 
319 MMRESULT
321  IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
322  IN PVOID Handle)
323 {
327  PSOUND_DEVICE SoundDevice;
328 
329  Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
330 
331  if ( ! MMSUCCESS(Result) )
332  {
334  }
335 
336  if ( OpenCount == 0 )
337  {
338  return MMSYSERR_NOERROR;
339  }
340 
342 
343  Result = GetSoundDeviceType(SoundDevice, &DeviceType);
345 
346  if (SoundDeviceInstance->Handle != (PVOID)KernelHandle)
347  {
349 
350  DeviceInfo.DeviceType = DeviceType;
351  DeviceInfo.hDevice = SoundDeviceInstance->Handle;
352 
353  /* First stop the stream */
355  {
356  DeviceInfo.u.State = KSSTATE_PAUSE;
359  (LPVOID) &DeviceInfo,
360  sizeof(WDMAUD_DEVICE_INFO),
361  (LPVOID) &DeviceInfo,
362  sizeof(WDMAUD_DEVICE_INFO),
363  NULL);
364 
365  DeviceInfo.u.State = KSSTATE_ACQUIRE;
368  (LPVOID) &DeviceInfo,
369  sizeof(WDMAUD_DEVICE_INFO),
370  (LPVOID) &DeviceInfo,
371  sizeof(WDMAUD_DEVICE_INFO),
372  NULL);
373 
374 
375  DeviceInfo.u.State = KSSTATE_STOP;
378  (LPVOID) &DeviceInfo,
379  sizeof(WDMAUD_DEVICE_INFO),
380  (LPVOID) &DeviceInfo,
381  sizeof(WDMAUD_DEVICE_INFO),
382  NULL);
383  }
384 
387  (LPVOID) &DeviceInfo,
388  sizeof(WDMAUD_DEVICE_INFO),
389  (LPVOID) &DeviceInfo,
390  sizeof(WDMAUD_DEVICE_INFO),
391  NULL);
392  }
393 
395  {
396  SetEvent(SoundDeviceInstance->hStopEvent);
397  CloseHandle(SoundDeviceInstance->hStopEvent);
398  CloseHandle(SoundDeviceInstance->hNotifyEvent);
399  }
400 
401  --OpenCount;
402 
403  if ( OpenCount < 1 )
404  {
407  }
408 
409  return MMSYSERR_NOERROR;
410 }
411 
412 MMRESULT
415  IN DWORD DeviceId,
416  IN PWAVEFORMATEX WaveFormat,
417  IN DWORD WaveFormatSize)
418 {
421  HANDLE hThread;
422 
423  Instance->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
424  if ( ! Instance->hNotifyEvent )
425  return MMSYSERR_NOMEM;
426 
427  if (Instance->Handle != NULL)
428  {
429  /* device is already open */
430  return MMSYSERR_NOERROR;
431  }
432 
433  Instance->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
434  if ( ! Instance->hStopEvent )
435  return MMSYSERR_NOMEM;
436 
438  DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
439  DeviceInfo.DeviceIndex = DeviceId;
440  DeviceInfo.u.hNotifyEvent = Instance->hNotifyEvent;
441 
444  (LPVOID) &DeviceInfo,
445  sizeof(WDMAUD_DEVICE_INFO),
446  (LPVOID) &DeviceInfo,
447  sizeof(WDMAUD_DEVICE_INFO),
448  NULL);
449 
450  if ( ! MMSUCCESS(Result) )
451  {
452  CloseHandle(Instance->hNotifyEvent);
453  CloseHandle(Instance->hStopEvent);
455  }
456 
458  if ( hThread )
459  {
461  }
462 
463  /* Store sound device handle instance handle */
464  Instance->Handle = (PVOID)DeviceInfo.hDevice;
465 
466  return MMSYSERR_NOERROR;
467 }
468 
469 MMRESULT
472  IN DWORD DeviceId,
473  IN PWAVEFORMATEX WaveFormat,
474  IN DWORD WaveFormatSize)
475 {
477  PSOUND_DEVICE SoundDevice;
478  PVOID Identifier;
481 
482  Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);
483 
484  if ( ! MMSUCCESS(Result) )
485  {
487  }
488 
489  Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);
490 
491  if ( ! MMSUCCESS(Result) )
492  {
494  }
495 
496  if (Instance->Handle != NULL)
497  {
498  /* device is already open */
499  return MMSYSERR_NOERROR;
500  }
501 
502  Result = GetSoundDeviceType(SoundDevice, &DeviceType);
503 
505 
507  DeviceInfo.DeviceType = DeviceType;
508  DeviceInfo.DeviceIndex = DeviceId;
509  DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize;
510  DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
511 #ifdef USERMODE_MIXER
512  DeviceInfo.u.WaveFormatEx.nChannels = 2;
513  DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100;
514  DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
515  DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400;
516  DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
517 #else
518  DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels;
519  DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
520  DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
521  DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
522  DeviceInfo.u.WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels);
523 #endif
524 
527  (LPVOID) &DeviceInfo,
528  sizeof(WDMAUD_DEVICE_INFO),
529  (LPVOID) &DeviceInfo,
530  sizeof(WDMAUD_DEVICE_INFO),
531  NULL);
532 
533  if ( ! MMSUCCESS(Result) )
534  {
536  }
537 
538  if (WaveFormatSize >= sizeof(WAVEFORMAT))
539  {
540  /* Store format */
541  Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
542  Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
543  Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
544  Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
545  Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
546  }
547 
548  /* store details */
549  Instance->WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
550  Instance->WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels);
551 
552  /* Store sound device handle instance handle */
553  Instance->Handle = (PVOID)DeviceInfo.hDevice;
554 
555  /* Now determine framing requirements */
558  (LPVOID) &DeviceInfo,
559  sizeof(WDMAUD_DEVICE_INFO),
560  (LPVOID) &DeviceInfo,
561  sizeof(WDMAUD_DEVICE_INFO),
562  NULL);
563 
564  if ( MMSUCCESS(Result) )
565  {
566  if (DeviceInfo.u.FrameSize)
567  {
568  Instance->FrameSize = DeviceInfo.u.FrameSize * 2;
569  Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize;
570  SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount);
571  }
572  }
573  else
574  {
575  // use a default of 100 buffers
576  Instance->BufferCount = 100;
577  }
578 
579  /* Now acquire resources */
580  DeviceInfo.u.State = KSSTATE_ACQUIRE;
582 
583  /* pause the pin */
584  DeviceInfo.u.State = KSSTATE_PAUSE;
586 
587  /* start the pin */
588  DeviceInfo.u.State = KSSTATE_RUN;
590 
591 
592  return MMSYSERR_NOERROR;
593 }
594 
595 VOID
596 CALLBACK
598  IN DWORD dwErrorCode,
599  IN DWORD dwNumberOfBytesTransferred,
601 {
602  PSOUND_OVERLAPPED Overlap;
604 
605  Overlap = (PSOUND_OVERLAPPED)lpOverlapped;
607 
608  /* Call mmebuddy overlap routine */
609  Overlap->OriginalCompletionRoutine(dwErrorCode, DeviceInfo->Header.DataUsed, lpOverlapped);
610 
612 }
613 
614 MMRESULT
616  IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
617  IN PVOID OffsetPtr,
618  IN DWORD Length,
619  IN PSOUND_OVERLAPPED Overlap,
621 {
622  HANDLE Handle;
625  PSOUND_DEVICE SoundDevice;
627  BOOL Ret;
628 
629  VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
630  VALIDATE_MMSYS_PARAMETER( OffsetPtr );
631  VALIDATE_MMSYS_PARAMETER( Overlap );
633 
634  GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
636 
637  Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
638 
639  if ( ! MMSUCCESS(Result) )
640  {
642  }
643 
644  Result = GetSoundDeviceType(SoundDevice, &DeviceType);
646 
648  if (!DeviceInfo)
649  {
650  // no memory
651  return MMSYSERR_NOMEM;
652  }
653 
654  DeviceInfo->Header.FrameExtent = Length;
656  {
657  DeviceInfo->Header.DataUsed = Length;
658  }
659  DeviceInfo->Header.Data = OffsetPtr;
660  DeviceInfo->Header.Size = sizeof(WDMAUD_DEVICE_INFO);
661  DeviceInfo->Header.PresentationTime.Numerator = 1;
662  DeviceInfo->Header.PresentationTime.Denominator = 1;
663  DeviceInfo->hDevice = Handle;
664  DeviceInfo->DeviceType = DeviceType;
665 
666 
667  // create completion event
668  Overlap->Standard.hEvent = Handle = CreateEventW(NULL, FALSE, FALSE, NULL);
669  if (Overlap->Standard.hEvent == NULL)
670  {
671  // no memory
673  return MMSYSERR_NOMEM;
674  }
675 
676  Overlap->OriginalCompletionRoutine = CompletionRoutine;
677  Overlap->CompletionContext = (PVOID)DeviceInfo;
678 
680  {
682  if (Ret)
684  }
685  else if (DeviceType == WAVE_IN_DEVICE_TYPE)
686  {
688  if (Ret)
690  }
691 
692  // close event handle
694 
695  return MMSYSERR_NOERROR;
696 }
697 
698 MMRESULT
700  IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
701  IN BOOL bStart)
702 {
704  PSOUND_DEVICE SoundDevice;
707  HANDLE Handle;
708 
709  Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
710 
711  if ( ! MMSUCCESS(Result) )
712  {
714  }
715 
716  Result = GetSoundDeviceType(SoundDevice, &DeviceType);
718 
719  Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
721 
723  DeviceInfo.hDevice = Handle;
724  DeviceInfo.DeviceType = DeviceType;
725 
726  if (bStart)
727  DeviceInfo.u.State = KSSTATE_RUN;
728  else
729  DeviceInfo.u.State = KSSTATE_PAUSE;
732  (LPVOID) &DeviceInfo,
733  sizeof(WDMAUD_DEVICE_INFO),
734  (LPVOID) &DeviceInfo,
735  sizeof(WDMAUD_DEVICE_INFO),
736  NULL);
737 
738  return Result;
739 }
740 
741 MMRESULT
744  IN DWORD DeviceId,
746  IN DWORD InterfaceLength,
747  OUT DWORD * InterfaceSize)
748 {
751 
753  DeviceInfo.DeviceType = DeviceType;
754  DeviceInfo.DeviceIndex = DeviceId;
755 
756 
759  (LPVOID) &DeviceInfo,
760  sizeof(WDMAUD_DEVICE_INFO),
761  (LPVOID) &DeviceInfo,
762  sizeof(WDMAUD_DEVICE_INFO),
763  NULL);
764 
765 
766  if ( ! MMSUCCESS(Result) )
767  {
769  }
770 
771 
772  if (!Interface)
773  {
774  SND_ASSERT(InterfaceSize);
775 
776  *InterfaceSize = DeviceInfo.u.Interface.DeviceInterfaceStringSize;
777  return MMSYSERR_NOERROR;
778  }
779 
780  if (InterfaceLength < DeviceInfo.u.Interface.DeviceInterfaceStringSize)
781  {
782  /* buffer is too small */
783  return MMSYSERR_MOREDATA;
784  }
785 
786  DeviceInfo.u.Interface.DeviceInterfaceStringSize = InterfaceLength;
787  DeviceInfo.u.Interface.DeviceInterfaceString = Interface;
788 
791  (LPVOID) &DeviceInfo,
792  sizeof(WDMAUD_DEVICE_INFO),
793  (LPVOID) &DeviceInfo,
794  sizeof(WDMAUD_DEVICE_INFO),
795  NULL);
796 
797  if ( MMSUCCESS(Result) && InterfaceLength > 2)
798  {
799  Interface[1] = L'\\';
800  Interface[InterfaceLength-1] = L'\0';
801  }
802 
803  return Result;
804 }
805 
806 MMRESULT
808  IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
809  IN MMTIME* Time)
810 {
812  PSOUND_DEVICE SoundDevice;
815  HANDLE Handle;
816 
817  Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
818 
819  if ( ! MMSUCCESS(Result) )
820  {
822  }
823 
824  Result = GetSoundDeviceType(SoundDevice, &DeviceType);
826 
827  Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
829 
831  DeviceInfo.hDevice = Handle;
832  DeviceInfo.DeviceType = DeviceType;
833 
836  (LPVOID) &DeviceInfo,
837  sizeof(WDMAUD_DEVICE_INFO),
838  (LPVOID) &DeviceInfo,
839  sizeof(WDMAUD_DEVICE_INFO),
840  NULL);
841 
842  if ( ! MMSUCCESS(Result) )
843  {
845  }
846 
847  Time->wType = TIME_BYTES;
848  Time->u.cb = (DWORD)DeviceInfo.u.Position;
849 
850  return MMSYSERR_NOERROR;
851 }
852 
853 
854 MMRESULT
856  IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
858  IN BOOLEAN bStartReset)
859 {
861  HANDLE Handle;
863 
864  Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
866 
868  DeviceInfo.hDevice = Handle;
869  DeviceInfo.DeviceType = DeviceType;
870  DeviceInfo.u.ResetStream = (bStartReset ? KSRESET_BEGIN : KSRESET_END);
871 
874  (LPVOID) &DeviceInfo,
875  sizeof(WDMAUD_DEVICE_INFO),
876  (LPVOID) &DeviceInfo,
877  sizeof(WDMAUD_DEVICE_INFO),
878  NULL);
879  return Result;
880 }
881 
882 MMRESULT
884  IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
885  IN DWORD DeviceId,
886  IN UINT uMsg,
888  IN DWORD Flags)
889 {
892  HANDLE Handle;
894  LPMIXERLINEW MixLine;
895  LPMIXERLINECONTROLSW MixControls;
896  LPMIXERCONTROLDETAILS MixDetails;
897 
898  SND_TRACE(L"uMsg %x Flags %x\n", uMsg, Flags);
899 
900  Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
902 
904  DeviceInfo.hDevice = Handle;
905  DeviceInfo.DeviceIndex = DeviceId;
906  DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
907  DeviceInfo.Flags = Flags;
908 
909  MixLine = (LPMIXERLINEW)Parameter;
910  MixControls = (LPMIXERLINECONTROLSW)Parameter;
911  MixDetails = (LPMIXERCONTROLDETAILS)Parameter;
912 
913  switch(uMsg)
914  {
915  case MXDM_GETLINEINFO:
916  RtlCopyMemory(&DeviceInfo.u.MixLine, MixLine, sizeof(MIXERLINEW));
918  break;
920  RtlCopyMemory(&DeviceInfo.u.MixControls, MixControls, sizeof(MIXERLINECONTROLSW));
922  break;
924  RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
926  break;
928  RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
930  break;
931  default:
932  SND_ASSERT(0);
933  return MMSYSERR_NOTSUPPORTED;
934  }
935 
938  (LPVOID) &DeviceInfo,
939  sizeof(WDMAUD_DEVICE_INFO),
940  (LPVOID) &DeviceInfo,
941  sizeof(WDMAUD_DEVICE_INFO),
942  NULL);
943 
944  if ( ! MMSUCCESS(Result) )
945  {
946  return Result;
947  }
948 
949  switch(uMsg)
950  {
951  case MXDM_GETLINEINFO:
952  {
953  RtlCopyMemory(MixLine, &DeviceInfo.u.MixLine, sizeof(MIXERLINEW));
954  break;
955  }
956  }
957 
958  return Result;
959 }
#define IOCTL_SETDEVICE_STATE
Definition: interface.h:134
struct tagWAVEINCAPSW * LPWAVEINCAPSW
DWORD fdwSupport
Definition: mmsystem.h:1227
#define IOCTL_GETCONTROLDETAILS
Definition: interface.h:325
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CloseHandle
Definition: compat.h:398
PVOID CompletionContext
Definition: mmebuddy.h:126
#define IOCTL_QUERYDEVICEINTERFACESTRING
Definition: interface.h:343
#define IOCTL_GETCAPABILITIES
Definition: interface.h:204
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG IoControlCode
Definition: fltkernel.h:1383
struct tMIXERCONTROLDETAILS * LPMIXERCONTROLDETAILS
MMVERSION vDriverVersion
Definition: mmsystem.h:1145
WCHAR DevicePath[ANYSIZE_ARRAY]
Definition: setupapi.h:850
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1060
#define STATIC_KSCATEGORY_WDMAUD
Definition: ksmedia.h:219
HANDLE KernelHandle
Definition: legacy.c:24
HDEVINFO WINAPI SetupDiGetClassDevsW(CONST GUID *class, LPCWSTR enumstr, HWND parent, DWORD flags)
Definition: devinst.c:2297
MMRESULT GetSoundDeviceIdentifier(IN PSOUND_DEVICE SoundDevice, OUT PVOID *Identifier)
Definition: devicelist.c:328
#define MMSUCCESS(result)
Definition: mmebuddy.h:80
DeviceType
Definition: mmdrv.h:41
struct tagMIXERCAPSW * LPMIXERCAPSW
BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:3016
#define IOCTL_GETLINEINFO
Definition: interface.h:272
#define CALLBACK
Definition: compat.h:27
DWORD cDestinations
Definition: mmsystem.h:1228
MMRESULT TranslateInternalMmResult(IN MMRESULT Result)
Definition: utility.c:132
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
MMRESULT WdmAudSetWaveDeviceFormatByLegacy(IN PSOUND_DEVICE_INSTANCE Instance, IN DWORD DeviceId, IN PWAVEFORMATEX WaveFormat, IN DWORD WaveFormatSize)
Definition: legacy.c:470
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
#define ZeroMemory
Definition: winbase.h:1635
UINT MMRESULT
Definition: mmsystem.h:962
#define CopyWideString(dest, source)
Definition: mmebuddy.h:39
MaybeUInt64 bStart[BZ_MAX_HANDLED_BLOCKS]
Definition: bzip2recover.c:296
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1146
MMVERSION vDriverVersion
Definition: mmsystem.h:1125
_In_ PVOID Parameter
Definition: ldrtypes.h:240
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
#define DWORD
Definition: nt_native.h:44
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:597
struct _SOUND_DEVICE_INSTANCE * PSOUND_DEVICE_INSTANCE
MMRESULT WdmAudQueryMixerInfoByLegacy(IN struct _SOUND_DEVICE_INSTANCE *SoundDeviceInstance, IN DWORD DeviceId, IN UINT uMsg, IN LPVOID Parameter, IN DWORD Flags)
Definition: legacy.c:883
UCHAR MMDEVICE_TYPE
Definition: mmebuddy.h:88
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_DEVICE_INTERFACE_DETAIL_DATA_W
MMRESULT WdmAudGetWavePositionByLegacy(IN struct _SOUND_DEVICE_INSTANCE *SoundDeviceInstance, IN MMTIME *Time)
Definition: legacy.c:807
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
DWORD WINAPI MixerEventThreadRoutine(LPVOID Parameter)
Definition: legacy.c:29
BOOL WINAPI ReadFileEx(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: rw.c:299
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
unsigned int BOOL
Definition: ntddk_ex.h:94
MMVERSION vDriverVersion
Definition: mmsystem.h:1059
MMRESULT WdmAudOpenSoundDeviceByLegacy(IN PSOUND_DEVICE SoundDevice, OUT PVOID *Handle)
Definition: legacy.c:255
ULONG DeviceCount
Definition: mpu401.c:26
#define GENERIC_WRITE
Definition: nt_native.h:90
#define IOCTL_GETLINECONTROLS
Definition: interface.h:290
DWORD dwFormats
Definition: mmsystem.h:1061
VOID CALLBACK LegacyCompletionRoutine(IN DWORD dwErrorCode, IN DWORD dwNumberOfBytesTransferred, IN LPOVERLAPPED lpOverlapped)
Definition: legacy.c:597
unsigned char BOOLEAN
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:112
smooth NULL
Definition: ftsmooth.c:416
#define SND_ASSERT(condition)
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
WCHAR Data[ANYSIZE_ARRAY]
void * PVOID
Definition: retypes.h:9
#define IOCTL_OPEN_WDMAUD
Definition: interface.h:82
struct tagMIDIINCAPSW * LPMIDIINCAPSW
#define MXDM_SETCONTROLDETAILS
Definition: mmddk.h:198
#define OPEN_EXISTING
Definition: compat.h:426
MMRESULT WdmAudGetNumWdmDevsByLegacy(IN MMDEVICE_TYPE DeviceType, OUT DWORD *DeviceCount)
Definition: legacy.c:98
MMRESULT WdmAudCleanupByLegacy()
Definition: legacy.c:86
#define MXDM_GETCONTROLDETAILS
Definition: mmddk.h:197
struct _SOUND_OVERLAPPED * PSOUND_OVERLAPPED
_In_ HANDLE Handle
Definition: extypes.h:390
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1126
#define WAIT_OBJECT_0
Definition: winbase.h:387
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SND_ERR(...)
struct tagWAVEOUTCAPSW * LPWAVEOUTCAPSW
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:2898
MMRESULT WdmAudResetStreamByLegacy(IN struct _SOUND_DEVICE_INSTANCE *SoundDeviceInstance, IN MMDEVICE_TYPE DeviceType, IN BOOLEAN bStartReset)
Definition: legacy.c:855
#define MAX_PATH
Definition: compat.h:26
#define IOCTL_GETNUMDEVS_TYPE
Definition: interface.h:117
#define WINAPI
Definition: msvc.h:8
struct _DeviceInfo DeviceInfo
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W * PSP_DEVICE_INTERFACE_DETAIL_DATA_W
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1039
MMVERSION vDriverVersion
Definition: mmsystem.h:1225
struct tagMIXERLINEW * LPMIXERLINEW
#define MXDM_GETLINECONTROLS
Definition: mmddk.h:196
static const WCHAR L[]
Definition: oid.c:1250
DWORD SyncOverlappedDeviceIoControl(IN HANDLE Handle, IN DWORD IoControlCode, IN LPVOID InBuffer, IN DWORD InBufferSize, OUT LPVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesTransferred OPTIONAL)
Definition: misc.c:301
#define GENERIC_READ
Definition: compat.h:124
MMRESULT WdmAudGetDeviceInterfaceStringByLegacy(IN MMDEVICE_TYPE DeviceType, IN DWORD DeviceId, IN LPWSTR Interface, IN DWORD InterfaceLength, OUT DWORD *InterfaceSize)
Definition: legacy.c:742
uint32_t DWORD_PTR
Definition: typedefs.h:63
MMRESULT WdmAudSetWaveStateByLegacy(IN struct _SOUND_DEVICE_INSTANCE *SoundDeviceInstance, IN BOOL bStart)
Definition: legacy.c:699
void(CALLBACK * LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD, DWORD, LPOVERLAPPED)
Definition: winbase.h:1404
MMVERSION vDriverVersion
Definition: mmsystem.h:1038
LPOVERLAPPED_COMPLETION_ROUTINE OriginalCompletionRoutine
Definition: mmebuddy.h:125
#define MMSYSERR_MOREDATA
Definition: mmsystem.h:117
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
MMRESULT GetSoundDeviceType(IN PSOUND_DEVICE SoundDevice, OUT PMMDEVICE_TYPE DeviceType)
Definition: devicelist.c:346
MMRESULT WdmAudGetCapabilitiesByLegacy(IN PSOUND_DEVICE SoundDevice, IN DWORD DeviceId, OUT PVOID Capabilities, IN DWORD CapabilitiesSize)
Definition: legacy.c:133
BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, CONST GUID *InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:2785
DWORD dwSupport
Definition: mmsystem.h:1147
#define TIME_BYTES
Definition: mmsystem.h:30
struct WDMAUD_DEVICE_INFO * PWDMAUD_DEVICE_INFO
unsigned int UINT
Definition: ndis.h:50
#define IS_VALID_SOUND_DEVICE_TYPE(x)
Definition: sndtypes.h:43
DWORD OpenCount
Definition: legacy.c:25
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
IN PVOID Instance
Definition: pci.h:359
HANDLE hThread
Definition: wizard.c:27
MMRESULT WdmAudCommitWaveBufferByLegacy(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID OffsetPtr, IN DWORD Length, IN PSOUND_OVERLAPPED Overlap, IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine)
Definition: legacy.c:615
#define MAXPNAMELEN
Definition: mmsystem.h:24
struct tagMIDIOUTCAPSW * LPMIDIOUTCAPSW
#define CreateFileW
Definition: compat.h:400
#define IOCTL_CLOSE_WDMAUD
Definition: interface.h:99
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1226
#define DIGCF_DEVICEINTERFACE
Definition: setupapi.h:174
MMRESULT WdmAudCloseSoundDeviceByLegacy(IN struct _SOUND_DEVICE_INSTANCE *SoundDeviceInstance, IN PVOID Handle)
Definition: legacy.c:320
struct _LARGE_INTEGER::@2192 u
#define OUT
Definition: typedefs.h:39
struct _SP_DEVICE_INTERFACE_DATA SP_DEVICE_INTERFACE_DATA
struct tagMIXERLINECONTROLSW * LPMIXERLINECONTROLSW
_In_ PIRP _In_opt_ PVOID _In_opt_ POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine
Definition: fsrtlfuncs.h:673
#define HIWORD(l)
Definition: typedefs.h:246
#define IOCTL_GET_MIXER_EVENT
Definition: interface.h:359
#define IOCTL_GETFRAMESIZE
Definition: interface.h:255
#define IOCTL_SETCONTROLDETAILS
Definition: interface.h:307
MMRESULT GetSoundDeviceFromInstance(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, OUT PSOUND_DEVICE *SoundDevice)
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev, UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
#define IOCTL_RESET_STREAM
Definition: interface.h:374
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
MMRESULT GetSoundDeviceInstanceHandle(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, OUT PVOID *Handle)
#define INFINITE
Definition: serial.h:102
BOOL WINAPI WriteFileEx(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: rw.c:262
MMRESULT WdmAudSetMixerDeviceFormatByLegacy(IN PSOUND_DEVICE_INSTANCE Instance, IN DWORD DeviceId, IN PWAVEFORMATEX WaveFormat, IN DWORD WaveFormatSize)
Definition: legacy.c:413
#define MXDM_GETLINEINFO
Definition: mmddk.h:195
#define HeapFree(x, y, z)
Definition: compat.h:394
static PLARGE_INTEGER Time
Definition: time.c:105
#define SND_TRACE(...)
#define DIGCF_PRESENT
Definition: setupapi.h:171