2 * PROJECT: ReactOS Sound System
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/wdmaud.drv/wdmaud.c
6 * PURPOSE: WDM Audio Driver (User-mode part)
7 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
9 * NOTES: Looking for wodMessage & co? You won't find them here. Try
10 * the MME Buddy library, which is where these routines are
11 * actually implemented.
23 #include "interface.h"
25 #define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
27 PWSTR UnknownWaveIn
= L
"Wave Input";
28 PWSTR UnknownWaveOut
= L
"Wave Output";
29 PWSTR UnknownMidiIn
= L
"Midi Input";
30 PWSTR UnknownMidiOut
= L
"Midi Output";
32 HANDLE KernelHandle
= INVALID_HANDLE_VALUE
;
37 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
40 IN PSOUND_OVERLAPPED Overlap
,
41 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
48 IN MMDEVICE_TYPE DeviceType
,
49 OUT DWORD
* DeviceCount
)
52 WDMAUD_DEVICE_INFO DeviceInfo
;
54 VALIDATE_MMSYS_PARAMETER( Handle
!= INVALID_HANDLE_VALUE
);
55 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType
) );
56 VALIDATE_MMSYS_PARAMETER( DeviceCount
);
58 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
59 DeviceInfo
.DeviceType
= DeviceType
;
61 Result
= SyncOverlappedDeviceIoControl(Handle
,
62 IOCTL_GETNUMDEVS_TYPE
,
64 sizeof(WDMAUD_DEVICE_INFO
),
66 sizeof(WDMAUD_DEVICE_INFO
),
69 if ( ! MMSUCCESS( Result
) )
71 SND_ERR(L
"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
73 return TranslateInternalMmResult(Result
);
76 *DeviceCount
= DeviceInfo
.DeviceCount
;
78 return MMSYSERR_NOERROR
;
82 GetWdmDeviceCapabilities(
83 IN PSOUND_DEVICE SoundDevice
,
85 OUT PVOID Capabilities
,
86 IN DWORD CapabilitiesSize
)
88 /* NOTE - At this time, WDMAUD does not support this properly */
91 MMDEVICE_TYPE DeviceType
;
92 WDMAUD_DEVICE_INFO DeviceInfo
;
94 SND_ASSERT( SoundDevice
);
95 SND_ASSERT( Capabilities
);
97 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
98 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
100 if ( ! MMSUCCESS(Result
) )
103 SND_TRACE(L
"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType
, DeviceId
);
105 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
106 DeviceInfo
.DeviceType
= DeviceType
;
107 DeviceInfo
.DeviceIndex
= DeviceId
;
109 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
110 IOCTL_GETCAPABILITIES
,
111 (LPVOID
) &DeviceInfo
,
112 sizeof(WDMAUD_DEVICE_INFO
),
113 (LPVOID
) &DeviceInfo
,
114 sizeof(WDMAUD_DEVICE_INFO
),
117 if ( ! MMSUCCESS(Result
) )
119 return TranslateInternalMmResult(Result
);
122 /* This is pretty much a big hack right now */
123 switch ( DeviceType
)
125 case MIXER_DEVICE_TYPE
:
127 LPMIXERCAPS MixerCaps
= (LPMIXERCAPS
) Capabilities
;
129 DeviceInfo
.u
.MixCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
130 CopyWideString(MixerCaps
->szPname
, DeviceInfo
.u
.MixCaps
.szPname
);
132 MixerCaps
->cDestinations
= DeviceInfo
.u
.MixCaps
.cDestinations
;
133 MixerCaps
->fdwSupport
= DeviceInfo
.u
.MixCaps
.fdwSupport
;
134 MixerCaps
->vDriverVersion
= DeviceInfo
.u
.MixCaps
.vDriverVersion
;
135 MixerCaps
->wMid
= DeviceInfo
.u
.MixCaps
.wMid
;
136 MixerCaps
->wPid
= DeviceInfo
.u
.MixCaps
.wPid
;
139 case WAVE_OUT_DEVICE_TYPE
:
141 LPWAVEOUTCAPS WaveOutCaps
= (LPWAVEOUTCAPS
) Capabilities
;
143 DeviceInfo
.u
.WaveOutCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
144 WaveOutCaps
->wMid
= DeviceInfo
.u
.WaveOutCaps
.wMid
;
145 WaveOutCaps
->wPid
= DeviceInfo
.u
.WaveOutCaps
.wPid
;
147 WaveOutCaps
->vDriverVersion
= 0x0001;
148 CopyWideString(WaveOutCaps
->szPname
, DeviceInfo
.u
.WaveOutCaps
.szPname
);
150 WaveOutCaps
->dwFormats
= DeviceInfo
.u
.WaveOutCaps
.dwFormats
;
151 WaveOutCaps
->wChannels
= DeviceInfo
.u
.WaveOutCaps
.wChannels
;
152 WaveOutCaps
->dwSupport
= DeviceInfo
.u
.WaveOutCaps
.dwSupport
;
155 case WAVE_IN_DEVICE_TYPE
:
157 LPWAVEINCAPSW WaveInCaps
= (LPWAVEINCAPSW
) Capabilities
;
159 DeviceInfo
.u
.WaveInCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
161 WaveInCaps
->wMid
= DeviceInfo
.u
.WaveInCaps
.wMid
;
162 WaveInCaps
->wPid
= DeviceInfo
.u
.WaveInCaps
.wPid
;
164 WaveInCaps
->vDriverVersion
= 0x0001;
165 CopyWideString(WaveInCaps
->szPname
, DeviceInfo
.u
.WaveInCaps
.szPname
);
167 WaveInCaps
->dwFormats
= DeviceInfo
.u
.WaveInCaps
.dwFormats
;
168 WaveInCaps
->wChannels
= DeviceInfo
.u
.WaveInCaps
.wChannels
;
169 WaveInCaps
->wReserved1
= 0;
174 return MMSYSERR_NOERROR
;
180 IN
struct _SOUND_DEVICE
* SoundDevice
, /* NOT USED */
183 /* Only open this if it's not already open */
184 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
186 SND_TRACE(L
"Opening wdmaud device\n");
187 KernelHandle
= CreateFileW(KERNEL_DEVICE_NAME
,
188 GENERIC_READ
| GENERIC_WRITE
,
192 FILE_FLAG_OVERLAPPED
,
196 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
197 return MMSYSERR_ERROR
;
199 SND_ASSERT( Handle
);
201 *Handle
= KernelHandle
;
204 return MMSYSERR_NOERROR
;
209 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
212 WDMAUD_DEVICE_INFO DeviceInfo
;
214 MMDEVICE_TYPE DeviceType
;
215 PSOUND_DEVICE SoundDevice
;
217 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
219 if ( ! MMSUCCESS(Result
) )
221 return TranslateInternalMmResult(Result
);
224 if ( OpenCount
== 0 )
226 return MMSYSERR_NOERROR
;
229 SND_ASSERT( KernelHandle
!= INVALID_HANDLE_VALUE
);
231 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
232 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
234 if (SoundDeviceInstance
->Handle
!= (PVOID
)KernelHandle
)
236 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
238 DeviceInfo
.DeviceType
= DeviceType
;
239 DeviceInfo
.hDevice
= SoundDeviceInstance
->Handle
;
241 /* First stop the stream */
242 if (DeviceType
!= MIXER_DEVICE_TYPE
)
244 DeviceInfo
.u
.State
= KSSTATE_STOP
;
245 SyncOverlappedDeviceIoControl(KernelHandle
,
246 IOCTL_SETDEVICE_STATE
,
247 (LPVOID
) &DeviceInfo
,
248 sizeof(WDMAUD_DEVICE_INFO
),
249 (LPVOID
) &DeviceInfo
,
250 sizeof(WDMAUD_DEVICE_INFO
),
254 SyncOverlappedDeviceIoControl(KernelHandle
,
256 (LPVOID
) &DeviceInfo
,
257 sizeof(WDMAUD_DEVICE_INFO
),
258 (LPVOID
) &DeviceInfo
,
259 sizeof(WDMAUD_DEVICE_INFO
),
267 CloseHandle(KernelHandle
);
268 KernelHandle
= INVALID_HANDLE_VALUE
;
271 return MMSYSERR_NOERROR
;
276 QueryWdmWaveDeviceFormatSupport(
277 IN PSOUND_DEVICE Device
,
278 IN PWAVEFORMATEX WaveFormat
,
279 IN DWORD WaveFormatSize
)
282 return MMSYSERR_NOERROR
;
287 SetWdmMixerDeviceFormat(
288 IN PSOUND_DEVICE_INSTANCE Instance
,
290 IN PWAVEFORMATEX WaveFormat
,
291 IN DWORD WaveFormatSize
)
294 WDMAUD_DEVICE_INFO DeviceInfo
;
296 if (Instance
->Handle
!= KernelHandle
)
298 /* device is already open */
299 return MMSYSERR_NOERROR
;
303 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
304 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
305 DeviceInfo
.DeviceIndex
= DeviceId
;
307 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
309 (LPVOID
) &DeviceInfo
,
310 sizeof(WDMAUD_DEVICE_INFO
),
311 (LPVOID
) &DeviceInfo
,
312 sizeof(WDMAUD_DEVICE_INFO
),
315 if ( ! MMSUCCESS(Result
) )
317 return TranslateInternalMmResult(Result
);
320 /* Store sound device handle instance handle */
321 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
323 return MMSYSERR_NOERROR
;
327 SetWdmWaveDeviceFormat(
328 IN PSOUND_DEVICE_INSTANCE Instance
,
330 IN PWAVEFORMATEX WaveFormat
,
331 IN DWORD WaveFormatSize
)
334 PSOUND_DEVICE SoundDevice
;
336 WDMAUD_DEVICE_INFO DeviceInfo
;
337 MMDEVICE_TYPE DeviceType
;
339 Result
= GetSoundDeviceFromInstance(Instance
, &SoundDevice
);
341 if ( ! MMSUCCESS(Result
) )
343 return TranslateInternalMmResult(Result
);
346 Result
= GetSoundDeviceIdentifier(SoundDevice
, &Identifier
);
348 if ( ! MMSUCCESS(Result
) )
350 return TranslateInternalMmResult(Result
);
353 if (Instance
->Handle
!= KernelHandle
)
355 /* device is already open */
356 return MMSYSERR_NOERROR
;
360 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
361 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
363 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
364 DeviceInfo
.DeviceType
= DeviceType
;
365 DeviceInfo
.DeviceIndex
= DeviceId
;
366 DeviceInfo
.u
.WaveFormatEx
.cbSize
= WaveFormat
->cbSize
;
367 DeviceInfo
.u
.WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
368 #ifdef USERMODE_MIXER
369 DeviceInfo
.u
.WaveFormatEx
.nChannels
= 2;
370 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= 44100;
371 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= 4;
372 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= 176400;
373 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= 16;
375 DeviceInfo
.u
.WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
376 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
377 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
378 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
379 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
382 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
384 (LPVOID
) &DeviceInfo
,
385 sizeof(WDMAUD_DEVICE_INFO
),
386 (LPVOID
) &DeviceInfo
,
387 sizeof(WDMAUD_DEVICE_INFO
),
390 if ( ! MMSUCCESS(Result
) )
392 return TranslateInternalMmResult(Result
);
396 Instance
->WaveFormatEx
.cbSize
= WaveFormat
->cbSize
;
397 Instance
->WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
398 Instance
->WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
399 Instance
->WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
400 Instance
->WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
401 Instance
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
402 Instance
->WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
404 /* Store sound device handle instance handle */
405 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
407 /* Now determine framing requirements */
408 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
410 (LPVOID
) &DeviceInfo
,
411 sizeof(WDMAUD_DEVICE_INFO
),
412 (LPVOID
) &DeviceInfo
,
413 sizeof(WDMAUD_DEVICE_INFO
),
416 if ( MMSUCCESS(Result
) )
418 if (DeviceInfo
.u
.FrameSize
)
420 Instance
->FrameSize
= DeviceInfo
.u
.FrameSize
* 2;
421 Instance
->BufferCount
= WaveFormat
->nAvgBytesPerSec
/ Instance
->FrameSize
;
422 SND_TRACE(L
"FrameSize %u BufferCount %u\n", Instance
->FrameSize
, Instance
->BufferCount
);
427 // use a default of 100 buffers
428 Instance
->BufferCount
= 100;
431 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
433 /* Now start the stream */
434 DeviceInfo
.u
.State
= KSSTATE_RUN
;
435 SyncOverlappedDeviceIoControl(KernelHandle
,
436 IOCTL_SETDEVICE_STATE
,
437 (LPVOID
) &DeviceInfo
,
438 sizeof(WDMAUD_DEVICE_INFO
),
439 (LPVOID
) &DeviceInfo
,
440 sizeof(WDMAUD_DEVICE_INFO
),
444 return MMSYSERR_NOERROR
;
448 WriteFileEx_Committer2(
449 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
452 IN PSOUND_OVERLAPPED Overlap
,
453 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
)
457 WDMAUD_DEVICE_INFO DeviceInfo
;
458 PSOUND_DEVICE SoundDevice
;
459 MMDEVICE_TYPE DeviceType
;
462 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance
);
463 VALIDATE_MMSYS_PARAMETER( OffsetPtr
);
464 VALIDATE_MMSYS_PARAMETER( Overlap
);
465 VALIDATE_MMSYS_PARAMETER( CompletionRoutine
);
467 GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
470 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
472 if ( ! MMSUCCESS(Result
) )
474 return TranslateInternalMmResult(Result
);
477 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
478 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
482 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
484 DeviceInfo
.Header
.FrameExtent
= Length
;
485 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
487 DeviceInfo
.Header
.DataUsed
= Length
;
489 DeviceInfo
.Header
.Data
= OffsetPtr
;
490 DeviceInfo
.Header
.Size
= sizeof(WDMAUD_DEVICE_INFO
);
491 DeviceInfo
.Header
.PresentationTime
.Numerator
= 1;
492 DeviceInfo
.Header
.PresentationTime
.Denominator
= 1;
493 DeviceInfo
.hDevice
= Handle
;
494 DeviceInfo
.DeviceType
= DeviceType
;
496 Overlap
->Standard
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
498 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
500 Ret
= WriteFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
502 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
504 else if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
506 Ret
= ReadFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
508 // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
511 return MMSYSERR_NOERROR
;
516 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
520 PSOUND_DEVICE SoundDevice
;
521 WDMAUD_DEVICE_INFO DeviceInfo
;
522 MMDEVICE_TYPE DeviceType
;
525 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
527 if ( ! MMSUCCESS(Result
) )
529 return TranslateInternalMmResult(Result
);
532 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
533 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
535 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
536 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
538 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
539 DeviceInfo
.hDevice
= Handle
;
540 DeviceInfo
.DeviceType
= DeviceType
;
543 DeviceInfo
.u
.State
= KSSTATE_RUN
;
545 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
546 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
547 IOCTL_SETDEVICE_STATE
,
548 (LPVOID
) &DeviceInfo
,
549 sizeof(WDMAUD_DEVICE_INFO
),
550 (LPVOID
) &DeviceInfo
,
551 sizeof(WDMAUD_DEVICE_INFO
),
558 GetDeviceInterfaceString(
559 IN MMDEVICE_TYPE DeviceType
,
562 IN DWORD InterfaceLength
,
563 OUT DWORD
* InterfaceSize
)
565 WDMAUD_DEVICE_INFO DeviceInfo
;
568 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
569 DeviceInfo
.DeviceType
= DeviceType
;
570 DeviceInfo
.DeviceIndex
= DeviceId
;
573 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
574 IOCTL_QUERYDEVICEINTERFACESTRING
,
575 (LPVOID
) &DeviceInfo
,
576 sizeof(WDMAUD_DEVICE_INFO
),
577 (LPVOID
) &DeviceInfo
,
578 sizeof(WDMAUD_DEVICE_INFO
),
582 if ( ! MMSUCCESS(Result
) )
584 return TranslateInternalMmResult(Result
);
590 SND_ASSERT(InterfaceSize
);
592 *InterfaceSize
= DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
;
593 return MMSYSERR_NOERROR
;
596 if (InterfaceLength
< DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
)
598 /* buffer is too small */
599 return MMSYSERR_MOREDATA
;
602 DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
= InterfaceLength
;
603 DeviceInfo
.u
.Interface
.DeviceInterfaceString
= Interface
;
605 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
606 IOCTL_QUERYDEVICEINTERFACESTRING
,
607 (LPVOID
) &DeviceInfo
,
608 sizeof(WDMAUD_DEVICE_INFO
),
609 (LPVOID
) &DeviceInfo
,
610 sizeof(WDMAUD_DEVICE_INFO
),
617 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
621 PSOUND_DEVICE SoundDevice
;
622 WDMAUD_DEVICE_INFO DeviceInfo
;
623 MMDEVICE_TYPE DeviceType
;
626 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
628 if ( ! MMSUCCESS(Result
) )
630 return TranslateInternalMmResult(Result
);
633 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
634 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
636 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
637 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
639 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
640 DeviceInfo
.hDevice
= Handle
;
641 DeviceInfo
.DeviceType
= DeviceType
;
643 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
645 (LPVOID
) &DeviceInfo
,
646 sizeof(WDMAUD_DEVICE_INFO
),
647 (LPVOID
) &DeviceInfo
,
648 sizeof(WDMAUD_DEVICE_INFO
),
651 if ( ! MMSUCCESS(Result
) )
653 return TranslateInternalMmResult(Result
);
656 Time
->wType
= TIME_BYTES
;
657 Time
->u
.cb
= (DWORD
)DeviceInfo
.u
.Position
;
659 return MMSYSERR_NOERROR
;
664 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
670 WDMAUD_DEVICE_INFO DeviceInfo
;
673 LPMIXERLINEW MixLine
;
674 LPMIXERLINECONTROLSW MixControls
;
675 LPMIXERCONTROLDETAILS MixDetails
;
677 SND_TRACE(L
"uMsg %x Flags %x\n", uMsg
, Flags
);
679 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
680 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
682 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
683 DeviceInfo
.hDevice
= Handle
;
684 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
685 DeviceInfo
.Flags
= Flags
;
687 MixLine
= (LPMIXERLINEW
)Parameter
;
688 MixControls
= (LPMIXERLINECONTROLSW
)Parameter
;
689 MixDetails
= (LPMIXERCONTROLDETAILS
)Parameter
;
693 case MXDM_GETLINEINFO
:
694 RtlCopyMemory(&DeviceInfo
.u
.MixLine
, MixLine
, sizeof(MIXERLINEW
));
695 IoControlCode
= IOCTL_GETLINEINFO
;
697 case MXDM_GETLINECONTROLS
:
698 RtlCopyMemory(&DeviceInfo
.u
.MixControls
, MixControls
, sizeof(MIXERLINECONTROLSW
));
699 IoControlCode
= IOCTL_GETLINECONTROLS
;
701 case MXDM_SETCONTROLDETAILS
:
702 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
703 IoControlCode
= IOCTL_SETCONTROLDETAILS
;
705 case MXDM_GETCONTROLDETAILS
:
706 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
707 IoControlCode
= IOCTL_GETCONTROLDETAILS
;
713 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
715 (LPVOID
) &DeviceInfo
,
716 sizeof(WDMAUD_DEVICE_INFO
),
717 (LPVOID
) &DeviceInfo
,
718 sizeof(WDMAUD_DEVICE_INFO
),
721 if ( ! MMSUCCESS(Result
) )
723 return TranslateInternalMmResult(Result
);
728 case MXDM_GETLINEINFO
:
730 RtlCopyMemory(MixLine
, &DeviceInfo
.u
.MixLine
, sizeof(MIXERLINEW
));
740 PopulateWdmDeviceList(
742 MMDEVICE_TYPE DeviceType
)
745 DWORD DeviceCount
= 0;
746 PSOUND_DEVICE SoundDevice
= NULL
;
747 MMFUNCTION_TABLE FuncTable
;
750 VALIDATE_MMSYS_PARAMETER( Handle
!= INVALID_HANDLE_VALUE
);
751 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType
) );
753 Result
= GetNumWdmDevs(Handle
, DeviceType
, &DeviceCount
);
755 if ( ! MMSUCCESS(Result
) )
757 SND_ERR(L
"Error %d while obtaining number of devices\n", Result
);
758 return TranslateInternalMmResult(Result
);
761 SND_TRACE(L
"%d devices of type %d found\n", DeviceCount
, DeviceType
);
764 for ( i
= 0; i
< DeviceCount
; ++ i
)
766 Result
= ListSoundDevice(DeviceType
, (PVOID
) i
, &SoundDevice
);
768 if ( ! MMSUCCESS(Result
) )
770 SND_ERR(L
"Failed to list sound device - error %d\n", Result
);
771 return TranslateInternalMmResult(Result
);
774 /* Set up our function table */
775 ZeroMemory(&FuncTable
, sizeof(MMFUNCTION_TABLE
));
776 FuncTable
.GetCapabilities
= GetWdmDeviceCapabilities
;
777 FuncTable
.QueryWaveFormatSupport
= QueryWdmWaveDeviceFormatSupport
;
778 if (DeviceType
== MIXER_DEVICE_TYPE
)
780 FuncTable
.SetWaveFormat
= SetWdmMixerDeviceFormat
;
781 FuncTable
.QueryMixerInfo
= QueryMixerInfo
;
785 FuncTable
.SetWaveFormat
= SetWdmWaveDeviceFormat
;
788 if (DeviceType
== WAVE_IN_DEVICE_TYPE
|| DeviceType
== WAVE_OUT_DEVICE_TYPE
)
790 FuncTable
.SetState
= SetWdmWaveState
;
793 FuncTable
.Open
= OpenWdmSoundDevice
;
794 FuncTable
.Close
= CloseWdmSoundDevice
;
795 FuncTable
.GetDeviceInterfaceString
= GetDeviceInterfaceString
;
796 #ifndef USERMODE_MIXER
797 FuncTable
.CommitWaveBuffer
= WriteFileEx_Committer2
;
799 FuncTable
.CommitWaveBuffer
= WriteFileEx_Remixer
;
801 FuncTable
.GetPos
= GetWdmPosition
;
803 SetSoundDeviceFunctionTable(SoundDevice
, &FuncTable
);
806 return MMSYSERR_NOERROR
;
827 SND_TRACE(L
"DRV_LOAD\n");
829 Result
= InitEntrypointMutexes();
831 if ( ! MMSUCCESS(Result
) )
834 OpenWdmSoundDevice(NULL
, &Handle
);
836 if ( Handle
== INVALID_HANDLE_VALUE
)
838 SND_ERR(L
"Failed to open %s\n", KERNEL_DEVICE_NAME
);
839 CleanupEntrypointMutexes();
841 //UnlistAllSoundDevices();
846 /* Populate the device lists */
847 SND_TRACE(L
"Populating device lists\n");
848 PopulateWdmDeviceList(KernelHandle
, WAVE_OUT_DEVICE_TYPE
);
849 PopulateWdmDeviceList(KernelHandle
, WAVE_IN_DEVICE_TYPE
);
850 PopulateWdmDeviceList(KernelHandle
, MIDI_OUT_DEVICE_TYPE
);
851 PopulateWdmDeviceList(KernelHandle
, MIDI_IN_DEVICE_TYPE
);
852 PopulateWdmDeviceList(KernelHandle
, AUX_DEVICE_TYPE
);
853 PopulateWdmDeviceList(KernelHandle
, MIXER_DEVICE_TYPE
);
855 SND_TRACE(L
"Initialisation complete\n");
862 SND_TRACE(L
"DRV_FREE\n");
864 if ( KernelHandle
!= INVALID_HANDLE_VALUE
)
866 CloseHandle(KernelHandle
);
867 KernelHandle
= INVALID_HANDLE_VALUE
;
870 /* TODO: Clean up the path names! */
871 UnlistAllSoundDevices();
873 CleanupEntrypointMutexes();
875 SND_TRACE(L
"Unfreed memory blocks: %d\n",
876 GetMemoryAllocationCount());
884 SND_TRACE(L
"DRV_ENABLE / DRV_DISABLE\n");
891 SND_TRACE(L
"DRV_OPEN / DRV_CLOSE\n");
895 case DRV_QUERYCONFIGURE
:
897 SND_TRACE(L
"DRV_QUERYCONFIGURE\n");
904 SND_TRACE(L
"Unhandled message %d\n", Message
);
905 return DefDriverProc(DriverId
,
921 case DLL_PROCESS_ATTACH
:
922 SND_TRACE(L
"WDMAUD.DRV - Process attached\n");
924 case DLL_PROCESS_DETACH
:
925 SND_TRACE(L
"WDMAUD.DRV - Process detached\n");
927 case DLL_THREAD_ATTACH
:
928 SND_TRACE(L
"WDMAUD.DRV - Thread attached\n");
930 case DLL_THREAD_DETACH
:
931 SND_TRACE(L
"WDMAUD.DRV - Thread detached\n");