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.
18 #define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
19 extern HANDLE KernelHandle
;
20 extern DWORD OpenCount
;
24 MixerEventThreadRoutine(
27 HANDLE WaitObjects
[2];
30 WDMAUD_DEVICE_INFO DeviceInfo
;
31 PSOUND_DEVICE_INSTANCE Instance
= (PSOUND_DEVICE_INSTANCE
)Parameter
;
33 /* setup wait objects */
34 WaitObjects
[0] = Instance
->hNotifyEvent
;
35 WaitObjects
[1] = Instance
->hStopEvent
;
37 /* zero device info */
38 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
40 DeviceInfo
.hDevice
= Instance
->Handle
;
41 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
45 dwResult
= WaitForMultipleObjects(2, WaitObjects
, FALSE
, INFINITE
);
47 if (dwResult
== WAIT_OBJECT_0
+ 1)
49 /* stop event was signalled */
55 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
56 IOCTL_GET_MIXER_EVENT
,
58 sizeof(WDMAUD_DEVICE_INFO
),
60 sizeof(WDMAUD_DEVICE_INFO
),
63 if (Result
== MMSYSERR_NOERROR
)
65 DriverCallback(Instance
->WinMM
.ClientCallback
,
66 HIWORD(Instance
->WinMM
.Flags
),
67 Instance
->WinMM
.Handle
,
68 DeviceInfo
.u
.MixerEvent
.NotificationType
,
69 Instance
->WinMM
.ClientCallbackInstanceData
,
70 (DWORD_PTR
)DeviceInfo
.u
.MixerEvent
.Value
,
73 }while(Result
== MMSYSERR_NOERROR
);
83 if ( KernelHandle
!= INVALID_HANDLE_VALUE
)
85 CloseHandle(KernelHandle
);
86 KernelHandle
= INVALID_HANDLE_VALUE
;
91 WdmAudGetNumWdmDevsByLegacy(
92 IN MMDEVICE_TYPE DeviceType
,
93 OUT DWORD
* DeviceCount
)
96 WDMAUD_DEVICE_INFO DeviceInfo
;
98 VALIDATE_MMSYS_PARAMETER( KernelHandle
!= INVALID_HANDLE_VALUE
);
99 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType
) );
100 VALIDATE_MMSYS_PARAMETER( DeviceCount
);
102 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
103 DeviceInfo
.DeviceType
= DeviceType
;
105 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
106 IOCTL_GETNUMDEVS_TYPE
,
107 (LPVOID
) &DeviceInfo
,
108 sizeof(WDMAUD_DEVICE_INFO
),
109 (LPVOID
) &DeviceInfo
,
110 sizeof(WDMAUD_DEVICE_INFO
),
113 if ( ! MMSUCCESS( Result
) )
115 SND_ERR(L
"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
117 return TranslateInternalMmResult(Result
);
120 *DeviceCount
= DeviceInfo
.DeviceCount
;
122 return MMSYSERR_NOERROR
;
126 WdmAudGetCapabilitiesByLegacy(
127 IN PSOUND_DEVICE SoundDevice
,
129 OUT PVOID Capabilities
,
130 IN DWORD CapabilitiesSize
)
133 MMDEVICE_TYPE DeviceType
;
134 WDMAUD_DEVICE_INFO DeviceInfo
;
136 SND_ASSERT( SoundDevice
);
137 SND_ASSERT( Capabilities
);
139 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
140 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
142 if ( ! MMSUCCESS(Result
) )
145 SND_TRACE(L
"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType
, DeviceId
);
147 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
148 DeviceInfo
.DeviceType
= DeviceType
;
149 DeviceInfo
.DeviceIndex
= DeviceId
;
151 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
152 IOCTL_GETCAPABILITIES
,
153 (LPVOID
) &DeviceInfo
,
154 sizeof(WDMAUD_DEVICE_INFO
),
155 (LPVOID
) &DeviceInfo
,
156 sizeof(WDMAUD_DEVICE_INFO
),
159 if ( ! MMSUCCESS(Result
) )
161 return TranslateInternalMmResult(Result
);
164 /* This is pretty much a big hack right now */
165 switch ( DeviceType
)
167 case MIXER_DEVICE_TYPE
:
169 LPMIXERCAPS MixerCaps
= (LPMIXERCAPS
) Capabilities
;
171 DeviceInfo
.u
.MixCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
172 CopyWideString(MixerCaps
->szPname
, DeviceInfo
.u
.MixCaps
.szPname
);
174 MixerCaps
->cDestinations
= DeviceInfo
.u
.MixCaps
.cDestinations
;
175 MixerCaps
->fdwSupport
= DeviceInfo
.u
.MixCaps
.fdwSupport
;
176 MixerCaps
->vDriverVersion
= DeviceInfo
.u
.MixCaps
.vDriverVersion
;
177 MixerCaps
->wMid
= DeviceInfo
.u
.MixCaps
.wMid
;
178 MixerCaps
->wPid
= DeviceInfo
.u
.MixCaps
.wPid
;
181 case WAVE_OUT_DEVICE_TYPE
:
183 LPWAVEOUTCAPS WaveOutCaps
= (LPWAVEOUTCAPS
) Capabilities
;
185 DeviceInfo
.u
.WaveOutCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
186 WaveOutCaps
->wMid
= DeviceInfo
.u
.WaveOutCaps
.wMid
;
187 WaveOutCaps
->wPid
= DeviceInfo
.u
.WaveOutCaps
.wPid
;
189 WaveOutCaps
->vDriverVersion
= 0x0001;
190 CopyWideString(WaveOutCaps
->szPname
, DeviceInfo
.u
.WaveOutCaps
.szPname
);
192 WaveOutCaps
->dwFormats
= DeviceInfo
.u
.WaveOutCaps
.dwFormats
;
193 WaveOutCaps
->wChannels
= DeviceInfo
.u
.WaveOutCaps
.wChannels
;
194 WaveOutCaps
->dwSupport
= DeviceInfo
.u
.WaveOutCaps
.dwSupport
;
197 case WAVE_IN_DEVICE_TYPE
:
199 LPWAVEINCAPSW WaveInCaps
= (LPWAVEINCAPSW
) Capabilities
;
201 DeviceInfo
.u
.WaveInCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
203 WaveInCaps
->wMid
= DeviceInfo
.u
.WaveInCaps
.wMid
;
204 WaveInCaps
->wPid
= DeviceInfo
.u
.WaveInCaps
.wPid
;
206 WaveInCaps
->vDriverVersion
= 0x0001;
207 CopyWideString(WaveInCaps
->szPname
, DeviceInfo
.u
.WaveInCaps
.szPname
);
209 WaveInCaps
->dwFormats
= DeviceInfo
.u
.WaveInCaps
.dwFormats
;
210 WaveInCaps
->wChannels
= DeviceInfo
.u
.WaveInCaps
.wChannels
;
211 WaveInCaps
->wReserved1
= 0;
216 return MMSYSERR_NOERROR
;
220 WdmAudOpenSoundDeviceByLegacy()
222 /* Only open this if it's not already open */
223 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
225 SND_TRACE(L
"Opening wdmaud device\n");
226 KernelHandle
= CreateFileW(KERNEL_DEVICE_NAME
,
227 GENERIC_READ
| GENERIC_WRITE
,
231 FILE_FLAG_OVERLAPPED
,
235 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
236 return MMSYSERR_ERROR
;
240 return MMSYSERR_NOERROR
;
244 WdmAudCloseSoundDeviceByLegacy(
245 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
248 WDMAUD_DEVICE_INFO DeviceInfo
;
250 MMDEVICE_TYPE DeviceType
;
251 PSOUND_DEVICE SoundDevice
;
253 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
255 if ( ! MMSUCCESS(Result
) )
257 return TranslateInternalMmResult(Result
);
260 if ( OpenCount
== 0 )
262 return MMSYSERR_NOERROR
;
265 SND_ASSERT( KernelHandle
!= INVALID_HANDLE_VALUE
);
267 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
268 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
270 if (SoundDeviceInstance
->Handle
!= (PVOID
)KernelHandle
)
272 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
274 DeviceInfo
.DeviceType
= DeviceType
;
275 DeviceInfo
.hDevice
= SoundDeviceInstance
->Handle
;
277 /* First stop the stream */
278 if (DeviceType
!= MIXER_DEVICE_TYPE
)
280 DeviceInfo
.u
.State
= KSSTATE_STOP
;
281 SyncOverlappedDeviceIoControl(KernelHandle
,
282 IOCTL_SETDEVICE_STATE
,
283 (LPVOID
) &DeviceInfo
,
284 sizeof(WDMAUD_DEVICE_INFO
),
285 (LPVOID
) &DeviceInfo
,
286 sizeof(WDMAUD_DEVICE_INFO
),
290 SyncOverlappedDeviceIoControl(KernelHandle
,
292 (LPVOID
) &DeviceInfo
,
293 sizeof(WDMAUD_DEVICE_INFO
),
294 (LPVOID
) &DeviceInfo
,
295 sizeof(WDMAUD_DEVICE_INFO
),
299 if (DeviceType
== MIXER_DEVICE_TYPE
)
301 SetEvent(SoundDeviceInstance
->hStopEvent
);
302 CloseHandle(SoundDeviceInstance
->hStopEvent
);
303 CloseHandle(SoundDeviceInstance
->hNotifyEvent
);
310 CloseHandle(KernelHandle
);
311 KernelHandle
= INVALID_HANDLE_VALUE
;
314 return MMSYSERR_NOERROR
;
318 WdmAudSetMixerDeviceFormatByLegacy(
319 IN PSOUND_DEVICE_INSTANCE Instance
,
321 IN PWAVEFORMATEX WaveFormat
,
322 IN DWORD WaveFormatSize
)
325 WDMAUD_DEVICE_INFO DeviceInfo
;
329 Instance
->hNotifyEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
330 if ( ! Instance
->hNotifyEvent
)
331 return MMSYSERR_NOMEM
;
333 if (Instance
->Handle
!= KernelHandle
)
335 /* device is already open */
336 return MMSYSERR_NOERROR
;
339 Instance
->hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
340 if ( ! Instance
->hStopEvent
)
341 return MMSYSERR_NOMEM
;
343 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
344 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
345 DeviceInfo
.DeviceIndex
= DeviceId
;
346 DeviceInfo
.u
.hNotifyEvent
= Instance
->hNotifyEvent
;
348 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
350 (LPVOID
) &DeviceInfo
,
351 sizeof(WDMAUD_DEVICE_INFO
),
352 (LPVOID
) &DeviceInfo
,
353 sizeof(WDMAUD_DEVICE_INFO
),
356 if ( ! MMSUCCESS(Result
) )
358 CloseHandle(Instance
->hNotifyEvent
);
359 CloseHandle(Instance
->hStopEvent
);
360 return TranslateInternalMmResult(Result
);
363 hThread
= CreateThread(NULL
, 0, MixerEventThreadRoutine
, (LPVOID
)Instance
, 0, NULL
);
366 CloseHandle(hThread
);
369 /* Store sound device handle instance handle */
370 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
372 return MMSYSERR_NOERROR
;
376 WdmAudSetWaveDeviceFormatByLegacy(
377 IN PSOUND_DEVICE_INSTANCE Instance
,
379 IN PWAVEFORMATEX WaveFormat
,
380 IN DWORD WaveFormatSize
)
383 PSOUND_DEVICE SoundDevice
;
385 WDMAUD_DEVICE_INFO DeviceInfo
;
386 MMDEVICE_TYPE DeviceType
;
388 Result
= GetSoundDeviceFromInstance(Instance
, &SoundDevice
);
390 if ( ! MMSUCCESS(Result
) )
392 return TranslateInternalMmResult(Result
);
395 Result
= GetSoundDeviceIdentifier(SoundDevice
, &Identifier
);
397 if ( ! MMSUCCESS(Result
) )
399 return TranslateInternalMmResult(Result
);
402 if (Instance
->Handle
!= KernelHandle
)
404 /* device is already open */
405 return MMSYSERR_NOERROR
;
408 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
410 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
412 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
413 DeviceInfo
.DeviceType
= DeviceType
;
414 DeviceInfo
.DeviceIndex
= DeviceId
;
415 DeviceInfo
.u
.WaveFormatEx
.cbSize
= sizeof(WAVEFORMATEX
); //WaveFormat->cbSize;
416 DeviceInfo
.u
.WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
417 #ifdef USERMODE_MIXER
418 DeviceInfo
.u
.WaveFormatEx
.nChannels
= 2;
419 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= 44100;
420 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= 4;
421 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= 176400;
422 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= 16;
424 DeviceInfo
.u
.WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
425 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
426 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
427 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
428 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
431 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
433 (LPVOID
) &DeviceInfo
,
434 sizeof(WDMAUD_DEVICE_INFO
),
435 (LPVOID
) &DeviceInfo
,
436 sizeof(WDMAUD_DEVICE_INFO
),
439 if ( ! MMSUCCESS(Result
) )
441 return TranslateInternalMmResult(Result
);
445 Instance
->WaveFormatEx
.cbSize
= WaveFormat
->cbSize
;
446 Instance
->WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
447 Instance
->WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
448 Instance
->WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
449 Instance
->WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
450 Instance
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
451 Instance
->WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
453 /* Store sound device handle instance handle */
454 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
456 /* Now determine framing requirements */
457 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
459 (LPVOID
) &DeviceInfo
,
460 sizeof(WDMAUD_DEVICE_INFO
),
461 (LPVOID
) &DeviceInfo
,
462 sizeof(WDMAUD_DEVICE_INFO
),
465 if ( MMSUCCESS(Result
) )
467 if (DeviceInfo
.u
.FrameSize
)
469 Instance
->FrameSize
= DeviceInfo
.u
.FrameSize
* 2;
470 Instance
->BufferCount
= WaveFormat
->nAvgBytesPerSec
/ Instance
->FrameSize
;
471 SND_TRACE(L
"FrameSize %u BufferCount %u\n", Instance
->FrameSize
, Instance
->BufferCount
);
476 // use a default of 100 buffers
477 Instance
->BufferCount
= 100;
480 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
482 /* Now start the stream */
483 DeviceInfo
.u
.State
= KSSTATE_RUN
;
484 SyncOverlappedDeviceIoControl(KernelHandle
,
485 IOCTL_SETDEVICE_STATE
,
486 (LPVOID
) &DeviceInfo
,
487 sizeof(WDMAUD_DEVICE_INFO
),
488 (LPVOID
) &DeviceInfo
,
489 sizeof(WDMAUD_DEVICE_INFO
),
493 return MMSYSERR_NOERROR
;
497 WriteFileEx_Committer2(
498 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
501 IN PSOUND_OVERLAPPED Overlap
,
502 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
)
506 WDMAUD_DEVICE_INFO DeviceInfo
;
507 PSOUND_DEVICE SoundDevice
;
508 MMDEVICE_TYPE DeviceType
;
511 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance
);
512 VALIDATE_MMSYS_PARAMETER( OffsetPtr
);
513 VALIDATE_MMSYS_PARAMETER( Overlap
);
514 VALIDATE_MMSYS_PARAMETER( CompletionRoutine
);
516 GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
519 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
521 if ( ! MMSUCCESS(Result
) )
523 return TranslateInternalMmResult(Result
);
526 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
527 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
531 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
533 DeviceInfo
.Header
.FrameExtent
= Length
;
534 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
536 DeviceInfo
.Header
.DataUsed
= Length
;
538 DeviceInfo
.Header
.Data
= OffsetPtr
;
539 DeviceInfo
.Header
.Size
= sizeof(WDMAUD_DEVICE_INFO
);
540 DeviceInfo
.Header
.PresentationTime
.Numerator
= 1;
541 DeviceInfo
.Header
.PresentationTime
.Denominator
= 1;
542 DeviceInfo
.hDevice
= Handle
;
543 DeviceInfo
.DeviceType
= DeviceType
;
545 Overlap
->Standard
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
547 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
549 Ret
= WriteFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
551 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
553 else if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
555 Ret
= ReadFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
557 // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
560 return MMSYSERR_NOERROR
;
566 WdmAudSetWaveStateByLegacy(
567 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
571 PSOUND_DEVICE SoundDevice
;
572 WDMAUD_DEVICE_INFO DeviceInfo
;
573 MMDEVICE_TYPE DeviceType
;
576 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
578 if ( ! MMSUCCESS(Result
) )
580 return TranslateInternalMmResult(Result
);
583 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
584 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
586 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
587 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
589 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
590 DeviceInfo
.hDevice
= Handle
;
591 DeviceInfo
.DeviceType
= DeviceType
;
594 DeviceInfo
.u
.State
= KSSTATE_RUN
;
596 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
597 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
598 IOCTL_SETDEVICE_STATE
,
599 (LPVOID
) &DeviceInfo
,
600 sizeof(WDMAUD_DEVICE_INFO
),
601 (LPVOID
) &DeviceInfo
,
602 sizeof(WDMAUD_DEVICE_INFO
),
609 WdmAudGetDeviceInterfaceStringByLegacy(
610 IN MMDEVICE_TYPE DeviceType
,
613 IN DWORD InterfaceLength
,
614 OUT DWORD
* InterfaceSize
)
616 WDMAUD_DEVICE_INFO DeviceInfo
;
619 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
620 DeviceInfo
.DeviceType
= DeviceType
;
621 DeviceInfo
.DeviceIndex
= DeviceId
;
624 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
625 IOCTL_QUERYDEVICEINTERFACESTRING
,
626 (LPVOID
) &DeviceInfo
,
627 sizeof(WDMAUD_DEVICE_INFO
),
628 (LPVOID
) &DeviceInfo
,
629 sizeof(WDMAUD_DEVICE_INFO
),
633 if ( ! MMSUCCESS(Result
) )
635 return TranslateInternalMmResult(Result
);
641 SND_ASSERT(InterfaceSize
);
643 *InterfaceSize
= DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
;
644 return MMSYSERR_NOERROR
;
647 if (InterfaceLength
< DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
)
649 /* buffer is too small */
650 return MMSYSERR_MOREDATA
;
653 DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
= InterfaceLength
;
654 DeviceInfo
.u
.Interface
.DeviceInterfaceString
= Interface
;
656 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
657 IOCTL_QUERYDEVICEINTERFACESTRING
,
658 (LPVOID
) &DeviceInfo
,
659 sizeof(WDMAUD_DEVICE_INFO
),
660 (LPVOID
) &DeviceInfo
,
661 sizeof(WDMAUD_DEVICE_INFO
),
664 if ( MMSUCCESS(Result
) && InterfaceLength
> 2)
666 Interface
[1] = L
'\\';
667 Interface
[InterfaceLength
-1] = L
'\0';
674 WdmAudGetWavePositionByLegacy(
675 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
679 PSOUND_DEVICE SoundDevice
;
680 WDMAUD_DEVICE_INFO DeviceInfo
;
681 MMDEVICE_TYPE DeviceType
;
684 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
686 if ( ! MMSUCCESS(Result
) )
688 return TranslateInternalMmResult(Result
);
691 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
692 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
694 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
695 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
697 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
698 DeviceInfo
.hDevice
= Handle
;
699 DeviceInfo
.DeviceType
= DeviceType
;
701 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
703 (LPVOID
) &DeviceInfo
,
704 sizeof(WDMAUD_DEVICE_INFO
),
705 (LPVOID
) &DeviceInfo
,
706 sizeof(WDMAUD_DEVICE_INFO
),
709 if ( ! MMSUCCESS(Result
) )
711 return TranslateInternalMmResult(Result
);
714 Time
->wType
= TIME_BYTES
;
715 Time
->u
.cb
= (DWORD
)DeviceInfo
.u
.Position
;
717 return MMSYSERR_NOERROR
;
722 WdmAudResetStreamByLegacy(
723 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
724 IN MMDEVICE_TYPE DeviceType
,
725 IN BOOLEAN bStartReset
)
729 WDMAUD_DEVICE_INFO DeviceInfo
;
731 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
732 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
734 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
735 DeviceInfo
.hDevice
= Handle
;
736 DeviceInfo
.DeviceType
= DeviceType
;
737 DeviceInfo
.u
.ResetStream
= (bStartReset
? KSRESET_BEGIN
: KSRESET_END
);
739 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
741 (LPVOID
) &DeviceInfo
,
742 sizeof(WDMAUD_DEVICE_INFO
),
743 (LPVOID
) &DeviceInfo
,
744 sizeof(WDMAUD_DEVICE_INFO
),
750 WdmAudQueryMixerInfoByLegacy(
751 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
757 WDMAUD_DEVICE_INFO DeviceInfo
;
760 LPMIXERLINEW MixLine
;
761 LPMIXERLINECONTROLSW MixControls
;
762 LPMIXERCONTROLDETAILS MixDetails
;
764 SND_TRACE(L
"uMsg %x Flags %x\n", uMsg
, Flags
);
766 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
767 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
769 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
770 DeviceInfo
.hDevice
= Handle
;
771 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
772 DeviceInfo
.Flags
= Flags
;
774 MixLine
= (LPMIXERLINEW
)Parameter
;
775 MixControls
= (LPMIXERLINECONTROLSW
)Parameter
;
776 MixDetails
= (LPMIXERCONTROLDETAILS
)Parameter
;
780 case MXDM_GETLINEINFO
:
781 RtlCopyMemory(&DeviceInfo
.u
.MixLine
, MixLine
, sizeof(MIXERLINEW
));
782 IoControlCode
= IOCTL_GETLINEINFO
;
784 case MXDM_GETLINECONTROLS
:
785 RtlCopyMemory(&DeviceInfo
.u
.MixControls
, MixControls
, sizeof(MIXERLINECONTROLSW
));
786 IoControlCode
= IOCTL_GETLINECONTROLS
;
788 case MXDM_SETCONTROLDETAILS
:
789 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
790 IoControlCode
= IOCTL_SETCONTROLDETAILS
;
792 case MXDM_GETCONTROLDETAILS
:
793 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
794 IoControlCode
= IOCTL_GETCONTROLDETAILS
;
798 return MMSYSERR_NOTSUPPORTED
;
801 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
803 (LPVOID
) &DeviceInfo
,
804 sizeof(WDMAUD_DEVICE_INFO
),
805 (LPVOID
) &DeviceInfo
,
806 sizeof(WDMAUD_DEVICE_INFO
),
809 if ( ! MMSUCCESS(Result
) )
816 case MXDM_GETLINEINFO
:
818 RtlCopyMemory(MixLine
, &DeviceInfo
.u
.MixLine
, sizeof(MIXERLINEW
));