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 SND_TRACE(L
"WDMAUD - GetWdmDeviceCapabilities\n");
99 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
100 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
102 if ( ! MMSUCCESS(Result
) )
106 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
107 DeviceInfo
.DeviceType
= DeviceType
;
108 DeviceInfo
.DeviceIndex
= DeviceId
;
110 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
111 IOCTL_GETCAPABILITIES
,
112 (LPVOID
) &DeviceInfo
,
113 sizeof(WDMAUD_DEVICE_INFO
),
114 (LPVOID
) &DeviceInfo
,
115 sizeof(WDMAUD_DEVICE_INFO
),
118 if ( ! MMSUCCESS(Result
) )
120 return TranslateInternalMmResult(Result
);
123 SND_TRACE(L
"WDMAUD Name %S\n", DeviceInfo
.u
.WaveOutCaps
.szPname
);
125 /* This is pretty much a big hack right now */
126 switch ( DeviceType
)
128 case MIXER_DEVICE_TYPE
:
130 LPMIXERCAPS MixerCaps
= (LPMIXERCAPS
) Capabilities
;
132 CopyWideString(MixerCaps
->szPname
, DeviceInfo
.u
.WaveOutCaps
.szPname
);
134 MixerCaps
->cDestinations
= DeviceInfo
.u
.MixCaps
.cDestinations
;
135 MixerCaps
->fdwSupport
= DeviceInfo
.u
.MixCaps
.fdwSupport
;
136 MixerCaps
->vDriverVersion
= DeviceInfo
.u
.MixCaps
.vDriverVersion
;
137 MixerCaps
->wMid
= DeviceInfo
.u
.MixCaps
.wMid
;
138 MixerCaps
->wPid
= DeviceInfo
.u
.MixCaps
.wPid
;
141 case WAVE_OUT_DEVICE_TYPE
:
143 LPWAVEOUTCAPS WaveOutCaps
= (LPWAVEOUTCAPS
) Capabilities
;
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 LPWAVEINCAPS WaveInCaps
= (LPWAVEINCAPS
) Capabilities
;
158 CopyWideString(WaveInCaps
->szPname
, DeviceInfo
.u
.WaveOutCaps
.szPname
);
159 /* TODO... other fields */
164 return MMSYSERR_NOERROR
;
170 IN
struct _SOUND_DEVICE
* SoundDevice
, /* NOT USED */
173 /* Only open this if it's not already open */
174 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
176 SND_TRACE(L
"Opening wdmaud device\n");
177 KernelHandle
= CreateFileW(KERNEL_DEVICE_NAME
,
178 GENERIC_READ
| GENERIC_WRITE
,
182 FILE_FLAG_OVERLAPPED
,
186 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
187 return MMSYSERR_ERROR
;
189 SND_ASSERT( Handle
);
191 *Handle
= KernelHandle
;
194 return MMSYSERR_NOERROR
;
199 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
202 WDMAUD_DEVICE_INFO DeviceInfo
;
204 MMDEVICE_TYPE DeviceType
;
205 PSOUND_DEVICE SoundDevice
;
207 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
209 if ( ! MMSUCCESS(Result
) )
211 return TranslateInternalMmResult(Result
);
214 if ( OpenCount
== 0 )
216 return MMSYSERR_NOERROR
;
219 SND_ASSERT( KernelHandle
!= INVALID_HANDLE_VALUE
);
221 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
222 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
224 if (SoundDeviceInstance
->Handle
!= (PVOID
)KernelHandle
)
226 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
228 DeviceInfo
.DeviceType
= DeviceType
;
229 DeviceInfo
.hDevice
= SoundDeviceInstance
->Handle
;
231 /* First stop the stream */
232 if (DeviceType
!= MIXER_DEVICE_TYPE
)
234 DeviceInfo
.u
.State
= KSSTATE_STOP
;
235 SyncOverlappedDeviceIoControl(KernelHandle
,
236 IOCTL_SETDEVICE_STATE
,
237 (LPVOID
) &DeviceInfo
,
238 sizeof(WDMAUD_DEVICE_INFO
),
239 (LPVOID
) &DeviceInfo
,
240 sizeof(WDMAUD_DEVICE_INFO
),
244 SyncOverlappedDeviceIoControl(KernelHandle
,
246 (LPVOID
) &DeviceInfo
,
247 sizeof(WDMAUD_DEVICE_INFO
),
248 (LPVOID
) &DeviceInfo
,
249 sizeof(WDMAUD_DEVICE_INFO
),
257 CloseHandle(KernelHandle
);
258 KernelHandle
= INVALID_HANDLE_VALUE
;
261 return MMSYSERR_NOERROR
;
266 QueryWdmWaveDeviceFormatSupport(
267 IN PSOUND_DEVICE Device
,
268 IN PWAVEFORMATEX WaveFormat
,
269 IN DWORD WaveFormatSize
)
272 return MMSYSERR_NOERROR
;
277 SetWdmMixerDeviceFormat(
278 IN PSOUND_DEVICE_INSTANCE Instance
,
280 IN PWAVEFORMATEX WaveFormat
,
281 IN DWORD WaveFormatSize
)
284 WDMAUD_DEVICE_INFO DeviceInfo
;
286 if (Instance
->Handle
!= KernelHandle
)
288 /* device is already open */
289 return MMSYSERR_NOERROR
;
293 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
294 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
295 DeviceInfo
.DeviceIndex
= DeviceId
;
297 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
299 (LPVOID
) &DeviceInfo
,
300 sizeof(WDMAUD_DEVICE_INFO
),
301 (LPVOID
) &DeviceInfo
,
302 sizeof(WDMAUD_DEVICE_INFO
),
305 if ( ! MMSUCCESS(Result
) )
307 return TranslateInternalMmResult(Result
);
310 /* Store sound device handle instance handle */
311 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
313 return MMSYSERR_NOERROR
;
317 SetWdmWaveDeviceFormat(
318 IN PSOUND_DEVICE_INSTANCE Instance
,
320 IN PWAVEFORMATEX WaveFormat
,
321 IN DWORD WaveFormatSize
)
324 PSOUND_DEVICE SoundDevice
;
326 WDMAUD_DEVICE_INFO DeviceInfo
;
327 MMDEVICE_TYPE DeviceType
;
329 Result
= GetSoundDeviceFromInstance(Instance
, &SoundDevice
);
331 if ( ! MMSUCCESS(Result
) )
333 return TranslateInternalMmResult(Result
);
336 Result
= GetSoundDeviceIdentifier(SoundDevice
, &Identifier
);
338 if ( ! MMSUCCESS(Result
) )
340 return TranslateInternalMmResult(Result
);
343 if (Instance
->Handle
!= KernelHandle
)
345 /* device is already open */
346 return MMSYSERR_NOERROR
;
350 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
351 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
353 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
354 DeviceInfo
.DeviceType
= DeviceType
;
355 DeviceInfo
.DeviceIndex
= DeviceId
;
356 DeviceInfo
.u
.WaveFormatEx
.cbSize
= WaveFormat
->cbSize
;
357 DeviceInfo
.u
.WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
358 #ifdef USERMODE_MIXER
359 DeviceInfo
.u
.WaveFormatEx
.nChannels
= 2;
360 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= 44100;
361 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= 4;
362 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= 176400;
363 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= 16;
365 DeviceInfo
.u
.WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
366 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
367 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
368 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
369 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
372 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
374 (LPVOID
) &DeviceInfo
,
375 sizeof(WDMAUD_DEVICE_INFO
),
376 (LPVOID
) &DeviceInfo
,
377 sizeof(WDMAUD_DEVICE_INFO
),
380 if ( ! MMSUCCESS(Result
) )
382 return TranslateInternalMmResult(Result
);
386 Instance
->WaveFormatEx
.cbSize
= WaveFormat
->cbSize
;
387 Instance
->WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
388 Instance
->WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
389 Instance
->WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
390 Instance
->WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
391 Instance
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
392 Instance
->WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
394 /* Store sound device handle instance handle */
395 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
397 /* Now determine framing requirements */
398 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
400 (LPVOID
) &DeviceInfo
,
401 sizeof(WDMAUD_DEVICE_INFO
),
402 (LPVOID
) &DeviceInfo
,
403 sizeof(WDMAUD_DEVICE_INFO
),
406 if ( MMSUCCESS(Result
) )
408 if (DeviceInfo
.u
.FrameSize
)
410 //Instance->FrameSize = DeviceInfo.u.FrameSize;
411 Instance
->BufferCount
= WaveFormat
->nAvgBytesPerSec
/ Instance
->FrameSize
;
412 SND_TRACE(L
"FrameSize %u BufferCount %u\n", Instance
->FrameSize
, Instance
->BufferCount
);
416 /* Now start the stream */
417 DeviceInfo
.u
.State
= KSSTATE_RUN
;
418 SyncOverlappedDeviceIoControl(KernelHandle
,
419 IOCTL_SETDEVICE_STATE
,
420 (LPVOID
) &DeviceInfo
,
421 sizeof(WDMAUD_DEVICE_INFO
),
422 (LPVOID
) &DeviceInfo
,
423 sizeof(WDMAUD_DEVICE_INFO
),
426 return MMSYSERR_NOERROR
;
430 WriteFileEx_Committer2(
431 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
434 IN PSOUND_OVERLAPPED Overlap
,
435 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
)
439 WDMAUD_DEVICE_INFO DeviceInfo
;
440 PSOUND_DEVICE SoundDevice
;
441 MMDEVICE_TYPE DeviceType
;
444 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance
);
445 VALIDATE_MMSYS_PARAMETER( OffsetPtr
);
446 VALIDATE_MMSYS_PARAMETER( Overlap
);
447 VALIDATE_MMSYS_PARAMETER( CompletionRoutine
);
449 GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
452 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
454 if ( ! MMSUCCESS(Result
) )
456 return TranslateInternalMmResult(Result
);
459 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
460 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
464 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
466 DeviceInfo
.Header
.FrameExtent
= Length
;
467 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
469 DeviceInfo
.Header
.DataUsed
= Length
;
471 DeviceInfo
.Header
.Data
= OffsetPtr
;
472 DeviceInfo
.Header
.Size
= sizeof(WDMAUD_DEVICE_INFO
);
473 DeviceInfo
.Header
.PresentationTime
.Numerator
= 1;
474 DeviceInfo
.Header
.PresentationTime
.Denominator
= 1;
475 DeviceInfo
.hDevice
= Handle
;
476 DeviceInfo
.DeviceType
= DeviceType
;
478 Overlap
->Standard
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
480 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
482 Ret
= WriteFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
484 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
486 else if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
488 Ret
= ReadFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
490 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
493 return MMSYSERR_NOERROR
;
498 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
502 PSOUND_DEVICE SoundDevice
;
503 WDMAUD_DEVICE_INFO DeviceInfo
;
504 MMDEVICE_TYPE DeviceType
;
507 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
509 if ( ! MMSUCCESS(Result
) )
511 return TranslateInternalMmResult(Result
);
514 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
515 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
517 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
518 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
520 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
521 DeviceInfo
.hDevice
= Handle
;
522 DeviceInfo
.DeviceType
= DeviceType
;
524 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
526 (LPVOID
) &DeviceInfo
,
527 sizeof(WDMAUD_DEVICE_INFO
),
528 (LPVOID
) &DeviceInfo
,
529 sizeof(WDMAUD_DEVICE_INFO
),
532 if ( ! MMSUCCESS(Result
) )
534 return TranslateInternalMmResult(Result
);
537 Time
->wType
= TIME_BYTES
;
538 Time
->u
.cb
= (DWORD
)DeviceInfo
.u
.Position
;
540 return MMSYSERR_NOERROR
;
545 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
551 WDMAUD_DEVICE_INFO DeviceInfo
;
554 LPMIXERLINEW MixLine
;
555 LPMIXERLINECONTROLSW MixControls
;
556 LPMIXERCONTROLDETAILS MixDetails
;
558 SND_TRACE(L
"uMsg %x Flags %x\n", uMsg
, Flags
);
560 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
561 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
563 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
564 DeviceInfo
.hDevice
= Handle
;
565 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
566 DeviceInfo
.Flags
= Flags
;
568 MixLine
= (LPMIXERLINEW
)Parameter
;
569 MixControls
= (LPMIXERLINECONTROLSW
)Parameter
;
570 MixDetails
= (LPMIXERCONTROLDETAILS
)Parameter
;
574 case MXDM_GETLINEINFO
:
575 RtlCopyMemory(&DeviceInfo
.u
.MixLine
, MixLine
, sizeof(MIXERLINEW
));
576 IoControlCode
= IOCTL_GETLINEINFO
;
578 case MXDM_GETLINECONTROLS
:
579 RtlCopyMemory(&DeviceInfo
.u
.MixControls
, MixControls
, sizeof(MIXERLINECONTROLSW
));
580 IoControlCode
= IOCTL_GETLINECONTROLS
;
582 case MXDM_SETCONTROLDETAILS
:
583 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
584 IoControlCode
= IOCTL_SETCONTROLDETAILS
;
586 case MXDM_GETCONTROLDETAILS
:
587 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
588 IoControlCode
= IOCTL_GETCONTROLDETAILS
;
594 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
596 (LPVOID
) &DeviceInfo
,
597 sizeof(WDMAUD_DEVICE_INFO
),
598 (LPVOID
) &DeviceInfo
,
599 sizeof(WDMAUD_DEVICE_INFO
),
602 if ( ! MMSUCCESS(Result
) )
604 return TranslateInternalMmResult(Result
);
609 case MXDM_GETLINEINFO
:
611 RtlCopyMemory(MixLine
, &DeviceInfo
.u
.MixLine
, sizeof(MIXERLINEW
));
621 PopulateWdmDeviceList(
623 MMDEVICE_TYPE DeviceType
)
626 DWORD DeviceCount
= 0;
627 PSOUND_DEVICE SoundDevice
= NULL
;
628 MMFUNCTION_TABLE FuncTable
;
631 VALIDATE_MMSYS_PARAMETER( Handle
!= INVALID_HANDLE_VALUE
);
632 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType
) );
634 Result
= GetNumWdmDevs(Handle
, DeviceType
, &DeviceCount
);
636 if ( ! MMSUCCESS(Result
) )
638 SND_ERR(L
"Error %d while obtaining number of devices\n", Result
);
639 return TranslateInternalMmResult(Result
);
642 SND_TRACE(L
"%d devices of type %d found\n", DeviceCount
, DeviceType
);
645 for ( i
= 0; i
< DeviceCount
; ++ i
)
647 Result
= ListSoundDevice(DeviceType
, (PVOID
) i
, &SoundDevice
);
649 if ( ! MMSUCCESS(Result
) )
651 SND_ERR(L
"Failed to list sound device - error %d\n", Result
);
652 return TranslateInternalMmResult(Result
);
655 /* Set up our function table */
656 ZeroMemory(&FuncTable
, sizeof(MMFUNCTION_TABLE
));
657 FuncTable
.GetCapabilities
= GetWdmDeviceCapabilities
;
658 FuncTable
.QueryWaveFormatSupport
= QueryWdmWaveDeviceFormatSupport
;
659 if (DeviceType
== MIXER_DEVICE_TYPE
)
661 FuncTable
.SetWaveFormat
= SetWdmMixerDeviceFormat
;
662 FuncTable
.QueryMixerInfo
= QueryMixerInfo
;
666 FuncTable
.SetWaveFormat
= SetWdmWaveDeviceFormat
;
669 FuncTable
.Open
= OpenWdmSoundDevice
;
670 FuncTable
.Close
= CloseWdmSoundDevice
;
671 #ifndef USERMODE_MIXER
672 FuncTable
.CommitWaveBuffer
= WriteFileEx_Committer2
;
674 FuncTable
.CommitWaveBuffer
= WriteFileEx_Remixer
;
676 FuncTable
.GetPos
= GetWdmPosition
;
678 SetSoundDeviceFunctionTable(SoundDevice
, &FuncTable
);
681 return MMSYSERR_NOERROR
;
702 SND_TRACE(L
"DRV_LOAD\n");
704 Result
= InitEntrypointMutexes();
706 if ( ! MMSUCCESS(Result
) )
709 OpenWdmSoundDevice(NULL
, &Handle
);
711 if ( Handle
== INVALID_HANDLE_VALUE
)
713 SND_ERR(L
"Failed to open %s\n", KERNEL_DEVICE_NAME
);
714 CleanupEntrypointMutexes();
716 //UnlistAllSoundDevices();
721 /* Populate the device lists */
722 SND_TRACE(L
"Populating device lists\n");
723 PopulateWdmDeviceList(KernelHandle
, WAVE_OUT_DEVICE_TYPE
);
724 PopulateWdmDeviceList(KernelHandle
, WAVE_IN_DEVICE_TYPE
);
725 PopulateWdmDeviceList(KernelHandle
, MIDI_OUT_DEVICE_TYPE
);
726 PopulateWdmDeviceList(KernelHandle
, MIDI_IN_DEVICE_TYPE
);
727 PopulateWdmDeviceList(KernelHandle
, AUX_DEVICE_TYPE
);
728 PopulateWdmDeviceList(KernelHandle
, MIXER_DEVICE_TYPE
);
730 SND_TRACE(L
"Initialisation complete\n");
737 SND_TRACE(L
"DRV_FREE\n");
739 if ( KernelHandle
!= INVALID_HANDLE_VALUE
)
741 CloseHandle(KernelHandle
);
742 KernelHandle
= INVALID_HANDLE_VALUE
;
745 /* TODO: Clean up the path names! */
746 UnlistAllSoundDevices();
748 CleanupEntrypointMutexes();
750 SND_TRACE(L
"Unfreed memory blocks: %d\n",
751 GetMemoryAllocationCount());
759 SND_TRACE(L
"DRV_ENABLE / DRV_DISABLE\n");
766 SND_TRACE(L
"DRV_OPEN / DRV_CLOSE\n");
770 case DRV_QUERYCONFIGURE
:
772 SND_TRACE(L
"DRV_QUERYCONFIGURE\n");
779 SND_TRACE(L
"Unhandled message %d\n", Message
);
780 return DefDriverProc(DriverId
,
796 case DLL_PROCESS_ATTACH
:
797 SND_TRACE(L
"WDMAUD.DRV - Process attached\n");
799 case DLL_PROCESS_DETACH
:
800 SND_TRACE(L
"WDMAUD.DRV - Process detached\n");
802 case DLL_THREAD_ATTACH
:
803 SND_TRACE(L
"WDMAUD.DRV - Thread attached\n");
805 case DLL_THREAD_DETACH
:
806 SND_TRACE(L
"WDMAUD.DRV - Thread detached\n");