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)
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.
20 #define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
22 HANDLE KernelHandle
= INVALID_HANDLE_VALUE
;
27 MixerEventThreadRoutine(
30 HANDLE WaitObjects
[2];
33 WDMAUD_DEVICE_INFO DeviceInfo
;
34 PSOUND_DEVICE_INSTANCE Instance
= (PSOUND_DEVICE_INSTANCE
)Parameter
;
36 /* setup wait objects */
37 WaitObjects
[0] = Instance
->hNotifyEvent
;
38 WaitObjects
[1] = Instance
->hStopEvent
;
40 /* zero device info */
41 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
43 DeviceInfo
.hDevice
= Instance
->Handle
;
44 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
48 dwResult
= WaitForMultipleObjects(2, WaitObjects
, FALSE
, INFINITE
);
50 if (dwResult
== WAIT_OBJECT_0
+ 1)
52 /* stop event was signalled */
58 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
59 IOCTL_GET_MIXER_EVENT
,
61 sizeof(WDMAUD_DEVICE_INFO
),
63 sizeof(WDMAUD_DEVICE_INFO
),
66 if (Result
== MMSYSERR_NOERROR
)
68 DriverCallback(Instance
->WinMM
.ClientCallback
,
69 HIWORD(Instance
->WinMM
.Flags
),
70 Instance
->WinMM
.Handle
,
71 DeviceInfo
.u
.MixerEvent
.NotificationType
,
72 Instance
->WinMM
.ClientCallbackInstanceData
,
73 (DWORD_PTR
)DeviceInfo
.u
.MixerEvent
.Value
,
76 }while(Result
== MMSYSERR_NOERROR
);
84 WdmAudCleanupByLegacy()
86 if (KernelHandle
!= INVALID_HANDLE_VALUE
)
88 CloseHandle(KernelHandle
);
89 KernelHandle
= INVALID_HANDLE_VALUE
;
92 return MMSYSERR_NOERROR
;
96 WdmAudGetNumWdmDevsByLegacy(
97 IN MMDEVICE_TYPE DeviceType
,
98 OUT DWORD
* DeviceCount
)
101 WDMAUD_DEVICE_INFO DeviceInfo
;
103 VALIDATE_MMSYS_PARAMETER( KernelHandle
!= INVALID_HANDLE_VALUE
);
104 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType
) );
105 VALIDATE_MMSYS_PARAMETER( DeviceCount
);
107 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
108 DeviceInfo
.DeviceType
= DeviceType
;
110 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
111 IOCTL_GETNUMDEVS_TYPE
,
112 (LPVOID
) &DeviceInfo
,
113 sizeof(WDMAUD_DEVICE_INFO
),
114 (LPVOID
) &DeviceInfo
,
115 sizeof(WDMAUD_DEVICE_INFO
),
118 if ( ! MMSUCCESS( Result
) )
120 SND_ERR(L
"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
122 return TranslateInternalMmResult(Result
);
125 *DeviceCount
= DeviceInfo
.DeviceCount
;
127 return MMSYSERR_NOERROR
;
131 WdmAudGetCapabilitiesByLegacy(
132 IN PSOUND_DEVICE SoundDevice
,
134 OUT PVOID Capabilities
,
135 IN DWORD CapabilitiesSize
)
138 MMDEVICE_TYPE DeviceType
;
139 WDMAUD_DEVICE_INFO DeviceInfo
;
141 SND_ASSERT( SoundDevice
);
142 SND_ASSERT( Capabilities
);
144 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
145 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
147 if ( ! MMSUCCESS(Result
) )
150 SND_TRACE(L
"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType
, DeviceId
);
152 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
153 DeviceInfo
.DeviceType
= DeviceType
;
154 DeviceInfo
.DeviceIndex
= DeviceId
;
156 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
157 IOCTL_GETCAPABILITIES
,
158 (LPVOID
) &DeviceInfo
,
159 sizeof(WDMAUD_DEVICE_INFO
),
160 (LPVOID
) &DeviceInfo
,
161 sizeof(WDMAUD_DEVICE_INFO
),
164 if ( ! MMSUCCESS(Result
) )
166 return TranslateInternalMmResult(Result
);
169 /* This is pretty much a big hack right now */
170 switch ( DeviceType
)
172 case MIXER_DEVICE_TYPE
:
174 LPMIXERCAPS MixerCaps
= (LPMIXERCAPS
) Capabilities
;
176 DeviceInfo
.u
.MixCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
177 CopyWideString(MixerCaps
->szPname
, DeviceInfo
.u
.MixCaps
.szPname
);
179 MixerCaps
->cDestinations
= DeviceInfo
.u
.MixCaps
.cDestinations
;
180 MixerCaps
->fdwSupport
= DeviceInfo
.u
.MixCaps
.fdwSupport
;
181 MixerCaps
->vDriverVersion
= DeviceInfo
.u
.MixCaps
.vDriverVersion
;
182 MixerCaps
->wMid
= DeviceInfo
.u
.MixCaps
.wMid
;
183 MixerCaps
->wPid
= DeviceInfo
.u
.MixCaps
.wPid
;
186 case WAVE_OUT_DEVICE_TYPE
:
188 LPWAVEOUTCAPS WaveOutCaps
= (LPWAVEOUTCAPS
) Capabilities
;
190 DeviceInfo
.u
.WaveOutCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
191 WaveOutCaps
->wMid
= DeviceInfo
.u
.WaveOutCaps
.wMid
;
192 WaveOutCaps
->wPid
= DeviceInfo
.u
.WaveOutCaps
.wPid
;
194 WaveOutCaps
->vDriverVersion
= 0x0001;
195 CopyWideString(WaveOutCaps
->szPname
, DeviceInfo
.u
.WaveOutCaps
.szPname
);
197 WaveOutCaps
->dwFormats
= DeviceInfo
.u
.WaveOutCaps
.dwFormats
;
198 WaveOutCaps
->wChannels
= DeviceInfo
.u
.WaveOutCaps
.wChannels
;
199 WaveOutCaps
->dwSupport
= DeviceInfo
.u
.WaveOutCaps
.dwSupport
;
202 case WAVE_IN_DEVICE_TYPE
:
204 LPWAVEINCAPSW WaveInCaps
= (LPWAVEINCAPSW
) Capabilities
;
206 DeviceInfo
.u
.WaveInCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
208 WaveInCaps
->wMid
= DeviceInfo
.u
.WaveInCaps
.wMid
;
209 WaveInCaps
->wPid
= DeviceInfo
.u
.WaveInCaps
.wPid
;
211 WaveInCaps
->vDriverVersion
= 0x0001;
212 CopyWideString(WaveInCaps
->szPname
, DeviceInfo
.u
.WaveInCaps
.szPname
);
214 WaveInCaps
->dwFormats
= DeviceInfo
.u
.WaveInCaps
.dwFormats
;
215 WaveInCaps
->wChannels
= DeviceInfo
.u
.WaveInCaps
.wChannels
;
216 WaveInCaps
->wReserved1
= 0;
221 return MMSYSERR_NOERROR
;
225 WdmAudOpenSoundDeviceByLegacy()
227 /* Only open this if it's not already open */
228 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
230 SND_TRACE(L
"Opening wdmaud device\n");
231 KernelHandle
= CreateFileW(KERNEL_DEVICE_NAME
,
232 GENERIC_READ
| GENERIC_WRITE
,
236 FILE_FLAG_OVERLAPPED
,
240 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
241 return MMSYSERR_ERROR
;
245 return MMSYSERR_NOERROR
;
249 WdmAudCloseSoundDeviceByLegacy(
250 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
253 WDMAUD_DEVICE_INFO DeviceInfo
;
255 MMDEVICE_TYPE DeviceType
;
256 PSOUND_DEVICE SoundDevice
;
258 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
260 if ( ! MMSUCCESS(Result
) )
262 return TranslateInternalMmResult(Result
);
265 if ( OpenCount
== 0 )
267 return MMSYSERR_NOERROR
;
270 SND_ASSERT( KernelHandle
!= INVALID_HANDLE_VALUE
);
272 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
273 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
275 if (SoundDeviceInstance
->Handle
!= (PVOID
)KernelHandle
)
277 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
279 DeviceInfo
.DeviceType
= DeviceType
;
280 DeviceInfo
.hDevice
= SoundDeviceInstance
->Handle
;
282 /* First stop the stream */
283 if (DeviceType
!= MIXER_DEVICE_TYPE
)
285 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
286 SyncOverlappedDeviceIoControl(KernelHandle
,
287 IOCTL_SETDEVICE_STATE
,
288 (LPVOID
) &DeviceInfo
,
289 sizeof(WDMAUD_DEVICE_INFO
),
290 (LPVOID
) &DeviceInfo
,
291 sizeof(WDMAUD_DEVICE_INFO
),
294 DeviceInfo
.u
.State
= KSSTATE_ACQUIRE
;
295 SyncOverlappedDeviceIoControl(KernelHandle
,
296 IOCTL_SETDEVICE_STATE
,
297 (LPVOID
) &DeviceInfo
,
298 sizeof(WDMAUD_DEVICE_INFO
),
299 (LPVOID
) &DeviceInfo
,
300 sizeof(WDMAUD_DEVICE_INFO
),
304 DeviceInfo
.u
.State
= KSSTATE_STOP
;
305 SyncOverlappedDeviceIoControl(KernelHandle
,
306 IOCTL_SETDEVICE_STATE
,
307 (LPVOID
) &DeviceInfo
,
308 sizeof(WDMAUD_DEVICE_INFO
),
309 (LPVOID
) &DeviceInfo
,
310 sizeof(WDMAUD_DEVICE_INFO
),
314 SyncOverlappedDeviceIoControl(KernelHandle
,
316 (LPVOID
) &DeviceInfo
,
317 sizeof(WDMAUD_DEVICE_INFO
),
318 (LPVOID
) &DeviceInfo
,
319 sizeof(WDMAUD_DEVICE_INFO
),
323 if (DeviceType
== MIXER_DEVICE_TYPE
)
325 SetEvent(SoundDeviceInstance
->hStopEvent
);
326 CloseHandle(SoundDeviceInstance
->hStopEvent
);
327 CloseHandle(SoundDeviceInstance
->hNotifyEvent
);
334 CloseHandle(KernelHandle
);
335 KernelHandle
= INVALID_HANDLE_VALUE
;
338 return MMSYSERR_NOERROR
;
342 WdmAudSetMixerDeviceFormatByLegacy(
343 IN PSOUND_DEVICE_INSTANCE Instance
,
345 IN PWAVEFORMATEX WaveFormat
,
346 IN DWORD WaveFormatSize
)
349 WDMAUD_DEVICE_INFO DeviceInfo
;
352 Instance
->hNotifyEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
353 if ( ! Instance
->hNotifyEvent
)
354 return MMSYSERR_NOMEM
;
356 if (Instance
->Handle
!= NULL
)
358 /* device is already open */
359 return MMSYSERR_NOERROR
;
362 Instance
->hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
363 if ( ! Instance
->hStopEvent
)
364 return MMSYSERR_NOMEM
;
366 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
367 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
368 DeviceInfo
.DeviceIndex
= DeviceId
;
369 DeviceInfo
.u
.hNotifyEvent
= Instance
->hNotifyEvent
;
371 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
373 (LPVOID
) &DeviceInfo
,
374 sizeof(WDMAUD_DEVICE_INFO
),
375 (LPVOID
) &DeviceInfo
,
376 sizeof(WDMAUD_DEVICE_INFO
),
379 if ( ! MMSUCCESS(Result
) )
381 CloseHandle(Instance
->hNotifyEvent
);
382 CloseHandle(Instance
->hStopEvent
);
383 return TranslateInternalMmResult(Result
);
386 hThread
= CreateThread(NULL
, 0, MixerEventThreadRoutine
, (LPVOID
)Instance
, 0, NULL
);
389 CloseHandle(hThread
);
392 /* Store sound device handle instance handle */
393 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
395 return MMSYSERR_NOERROR
;
399 WdmAudSetWaveDeviceFormatByLegacy(
400 IN PSOUND_DEVICE_INSTANCE Instance
,
402 IN PWAVEFORMATEX WaveFormat
,
403 IN DWORD WaveFormatSize
)
406 PSOUND_DEVICE SoundDevice
;
408 WDMAUD_DEVICE_INFO DeviceInfo
;
409 MMDEVICE_TYPE DeviceType
;
411 Result
= GetSoundDeviceFromInstance(Instance
, &SoundDevice
);
413 if ( ! MMSUCCESS(Result
) )
415 return TranslateInternalMmResult(Result
);
418 Result
= GetSoundDeviceIdentifier(SoundDevice
, &Identifier
);
420 if ( ! MMSUCCESS(Result
) )
422 return TranslateInternalMmResult(Result
);
425 if (Instance
->Handle
!= NULL
)
427 /* device is already open */
428 return MMSYSERR_NOERROR
;
431 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
433 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
435 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
436 DeviceInfo
.DeviceType
= DeviceType
;
437 DeviceInfo
.DeviceIndex
= DeviceId
;
438 DeviceInfo
.u
.WaveFormatEx
.cbSize
= sizeof(WAVEFORMATEX
); //WaveFormat->cbSize;
439 DeviceInfo
.u
.WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
440 #ifdef USERMODE_MIXER
441 DeviceInfo
.u
.WaveFormatEx
.nChannels
= 2;
442 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= 44100;
443 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= 4;
444 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= 176400;
445 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= 16;
447 DeviceInfo
.u
.WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
448 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
449 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
450 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
451 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
454 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
456 (LPVOID
) &DeviceInfo
,
457 sizeof(WDMAUD_DEVICE_INFO
),
458 (LPVOID
) &DeviceInfo
,
459 sizeof(WDMAUD_DEVICE_INFO
),
462 if ( ! MMSUCCESS(Result
) )
464 return TranslateInternalMmResult(Result
);
468 Instance
->WaveFormatEx
.cbSize
= WaveFormat
->cbSize
;
469 Instance
->WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
470 Instance
->WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
471 Instance
->WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
472 Instance
->WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
473 Instance
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
474 Instance
->WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
476 /* Store sound device handle instance handle */
477 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
479 /* Now determine framing requirements */
480 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
482 (LPVOID
) &DeviceInfo
,
483 sizeof(WDMAUD_DEVICE_INFO
),
484 (LPVOID
) &DeviceInfo
,
485 sizeof(WDMAUD_DEVICE_INFO
),
488 if ( MMSUCCESS(Result
) )
490 if (DeviceInfo
.u
.FrameSize
)
492 Instance
->FrameSize
= DeviceInfo
.u
.FrameSize
* 2;
493 Instance
->BufferCount
= WaveFormat
->nAvgBytesPerSec
/ Instance
->FrameSize
;
494 SND_TRACE(L
"FrameSize %u BufferCount %u\n", Instance
->FrameSize
, Instance
->BufferCount
);
499 // use a default of 100 buffers
500 Instance
->BufferCount
= 100;
503 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
505 /* Now start the stream */
506 DeviceInfo
.u
.State
= KSSTATE_RUN
;
507 SyncOverlappedDeviceIoControl(KernelHandle
,
508 IOCTL_SETDEVICE_STATE
,
509 (LPVOID
) &DeviceInfo
,
510 sizeof(WDMAUD_DEVICE_INFO
),
511 (LPVOID
) &DeviceInfo
,
512 sizeof(WDMAUD_DEVICE_INFO
),
516 return MMSYSERR_NOERROR
;
520 WdmAudCommitWaveBufferByLegacy(
521 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
524 IN PSOUND_OVERLAPPED Overlap
,
525 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
)
529 WDMAUD_DEVICE_INFO DeviceInfo
;
530 PSOUND_DEVICE SoundDevice
;
531 MMDEVICE_TYPE DeviceType
;
534 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance
);
535 VALIDATE_MMSYS_PARAMETER( OffsetPtr
);
536 VALIDATE_MMSYS_PARAMETER( Overlap
);
537 VALIDATE_MMSYS_PARAMETER( CompletionRoutine
);
539 GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
542 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
544 if ( ! MMSUCCESS(Result
) )
546 return TranslateInternalMmResult(Result
);
549 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
550 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
552 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
554 DeviceInfo
.Header
.FrameExtent
= Length
;
555 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
557 DeviceInfo
.Header
.DataUsed
= Length
;
559 DeviceInfo
.Header
.Data
= OffsetPtr
;
560 DeviceInfo
.Header
.Size
= sizeof(WDMAUD_DEVICE_INFO
);
561 DeviceInfo
.Header
.PresentationTime
.Numerator
= 1;
562 DeviceInfo
.Header
.PresentationTime
.Denominator
= 1;
563 DeviceInfo
.hDevice
= Handle
;
564 DeviceInfo
.DeviceType
= DeviceType
;
568 Overlap
->Standard
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
570 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
572 Ret
= WriteFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
574 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
576 else if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
578 Ret
= ReadFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
580 // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
583 return MMSYSERR_NOERROR
;
589 WdmAudSetWaveStateByLegacy(
590 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
594 PSOUND_DEVICE SoundDevice
;
595 WDMAUD_DEVICE_INFO DeviceInfo
;
596 MMDEVICE_TYPE DeviceType
;
599 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
601 if ( ! MMSUCCESS(Result
) )
603 return TranslateInternalMmResult(Result
);
606 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
607 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
609 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
610 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
612 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
613 DeviceInfo
.hDevice
= Handle
;
614 DeviceInfo
.DeviceType
= DeviceType
;
617 DeviceInfo
.u
.State
= KSSTATE_RUN
;
619 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
620 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
621 IOCTL_SETDEVICE_STATE
,
622 (LPVOID
) &DeviceInfo
,
623 sizeof(WDMAUD_DEVICE_INFO
),
624 (LPVOID
) &DeviceInfo
,
625 sizeof(WDMAUD_DEVICE_INFO
),
632 WdmAudGetDeviceInterfaceStringByLegacy(
633 IN MMDEVICE_TYPE DeviceType
,
636 IN DWORD InterfaceLength
,
637 OUT DWORD
* InterfaceSize
)
639 WDMAUD_DEVICE_INFO DeviceInfo
;
642 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
643 DeviceInfo
.DeviceType
= DeviceType
;
644 DeviceInfo
.DeviceIndex
= DeviceId
;
647 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
648 IOCTL_QUERYDEVICEINTERFACESTRING
,
649 (LPVOID
) &DeviceInfo
,
650 sizeof(WDMAUD_DEVICE_INFO
),
651 (LPVOID
) &DeviceInfo
,
652 sizeof(WDMAUD_DEVICE_INFO
),
656 if ( ! MMSUCCESS(Result
) )
658 return TranslateInternalMmResult(Result
);
664 SND_ASSERT(InterfaceSize
);
666 *InterfaceSize
= DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
;
667 return MMSYSERR_NOERROR
;
670 if (InterfaceLength
< DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
)
672 /* buffer is too small */
673 return MMSYSERR_MOREDATA
;
676 DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
= InterfaceLength
;
677 DeviceInfo
.u
.Interface
.DeviceInterfaceString
= Interface
;
679 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
680 IOCTL_QUERYDEVICEINTERFACESTRING
,
681 (LPVOID
) &DeviceInfo
,
682 sizeof(WDMAUD_DEVICE_INFO
),
683 (LPVOID
) &DeviceInfo
,
684 sizeof(WDMAUD_DEVICE_INFO
),
687 if ( MMSUCCESS(Result
) && InterfaceLength
> 2)
689 Interface
[1] = L
'\\';
690 Interface
[InterfaceLength
-1] = L
'\0';
697 WdmAudGetWavePositionByLegacy(
698 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
702 PSOUND_DEVICE SoundDevice
;
703 WDMAUD_DEVICE_INFO DeviceInfo
;
704 MMDEVICE_TYPE DeviceType
;
707 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
709 if ( ! MMSUCCESS(Result
) )
711 return TranslateInternalMmResult(Result
);
714 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
715 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
717 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
718 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
720 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
721 DeviceInfo
.hDevice
= Handle
;
722 DeviceInfo
.DeviceType
= DeviceType
;
724 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
726 (LPVOID
) &DeviceInfo
,
727 sizeof(WDMAUD_DEVICE_INFO
),
728 (LPVOID
) &DeviceInfo
,
729 sizeof(WDMAUD_DEVICE_INFO
),
732 if ( ! MMSUCCESS(Result
) )
734 return TranslateInternalMmResult(Result
);
737 Time
->wType
= TIME_BYTES
;
738 Time
->u
.cb
= (DWORD
)DeviceInfo
.u
.Position
;
740 return MMSYSERR_NOERROR
;
745 WdmAudResetStreamByLegacy(
746 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
747 IN MMDEVICE_TYPE DeviceType
,
748 IN BOOLEAN bStartReset
)
752 WDMAUD_DEVICE_INFO DeviceInfo
;
754 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
755 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
757 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
758 DeviceInfo
.hDevice
= Handle
;
759 DeviceInfo
.DeviceType
= DeviceType
;
760 DeviceInfo
.u
.ResetStream
= (bStartReset
? KSRESET_BEGIN
: KSRESET_END
);
762 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
764 (LPVOID
) &DeviceInfo
,
765 sizeof(WDMAUD_DEVICE_INFO
),
766 (LPVOID
) &DeviceInfo
,
767 sizeof(WDMAUD_DEVICE_INFO
),
773 WdmAudQueryMixerInfoByLegacy(
774 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
780 WDMAUD_DEVICE_INFO DeviceInfo
;
783 LPMIXERLINEW MixLine
;
784 LPMIXERLINECONTROLSW MixControls
;
785 LPMIXERCONTROLDETAILS MixDetails
;
787 SND_TRACE(L
"uMsg %x Flags %x\n", uMsg
, Flags
);
789 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
790 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
792 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
793 DeviceInfo
.hDevice
= Handle
;
794 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
795 DeviceInfo
.Flags
= Flags
;
797 MixLine
= (LPMIXERLINEW
)Parameter
;
798 MixControls
= (LPMIXERLINECONTROLSW
)Parameter
;
799 MixDetails
= (LPMIXERCONTROLDETAILS
)Parameter
;
803 case MXDM_GETLINEINFO
:
804 RtlCopyMemory(&DeviceInfo
.u
.MixLine
, MixLine
, sizeof(MIXERLINEW
));
805 IoControlCode
= IOCTL_GETLINEINFO
;
807 case MXDM_GETLINECONTROLS
:
808 RtlCopyMemory(&DeviceInfo
.u
.MixControls
, MixControls
, sizeof(MIXERLINECONTROLSW
));
809 IoControlCode
= IOCTL_GETLINECONTROLS
;
811 case MXDM_SETCONTROLDETAILS
:
812 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
813 IoControlCode
= IOCTL_SETCONTROLDETAILS
;
815 case MXDM_GETCONTROLDETAILS
:
816 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
817 IoControlCode
= IOCTL_GETCONTROLDETAILS
;
821 return MMSYSERR_NOTSUPPORTED
;
824 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
826 (LPVOID
) &DeviceInfo
,
827 sizeof(WDMAUD_DEVICE_INFO
),
828 (LPVOID
) &DeviceInfo
,
829 sizeof(WDMAUD_DEVICE_INFO
),
832 if ( ! MMSUCCESS(Result
) )
839 case MXDM_GETLINEINFO
:
841 RtlCopyMemory(MixLine
, &DeviceInfo
.u
.MixLine
, sizeof(MIXERLINEW
));