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 LPMIXERCAPSW MixerCaps
= (LPMIXERCAPSW
) 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 LPWAVEOUTCAPSW WaveOutCaps
= (LPWAVEOUTCAPSW
) 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
= DeviceInfo
.u
.WaveOutCaps
.vDriverVersion
;
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
= DeviceInfo
.u
.WaveInCaps
.vDriverVersion
;
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;
219 case MIDI_IN_DEVICE_TYPE
:
221 LPMIDIINCAPSW MidiInCaps
= (LPMIDIINCAPSW
)Capabilities
;
223 DeviceInfo
.u
.MidiInCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
225 MidiInCaps
->vDriverVersion
= DeviceInfo
.u
.MidiInCaps
.vDriverVersion
;
226 MidiInCaps
->wMid
= DeviceInfo
.u
.MidiInCaps
.wMid
;
227 MidiInCaps
->wPid
= DeviceInfo
.u
.MidiInCaps
.wPid
;
228 MidiInCaps
->dwSupport
= DeviceInfo
.u
.MidiInCaps
.dwSupport
;
230 CopyWideString(MidiInCaps
->szPname
, DeviceInfo
.u
.MidiInCaps
.szPname
);
233 case MIDI_OUT_DEVICE_TYPE
:
235 LPMIDIOUTCAPSW MidiOutCaps
= (LPMIDIOUTCAPSW
)Capabilities
;
237 DeviceInfo
.u
.MidiOutCaps
.szPname
[MAXPNAMELEN
-1] = L
'\0';
239 MidiOutCaps
->vDriverVersion
= DeviceInfo
.u
.MidiOutCaps
.vDriverVersion
;
240 MidiOutCaps
->wMid
= DeviceInfo
.u
.MidiOutCaps
.wMid
;
241 MidiOutCaps
->wPid
= DeviceInfo
.u
.MidiOutCaps
.wPid
;
242 MidiOutCaps
->dwSupport
= DeviceInfo
.u
.MidiOutCaps
.dwSupport
;
244 CopyWideString(MidiOutCaps
->szPname
, DeviceInfo
.u
.MidiOutCaps
.szPname
);
249 return MMSYSERR_NOERROR
;
253 WdmAudOpenSoundDeviceByLegacy()
255 /* Only open this if it's not already open */
256 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
258 SND_TRACE(L
"Opening wdmaud device\n");
259 KernelHandle
= CreateFileW(KERNEL_DEVICE_NAME
,
260 GENERIC_READ
| GENERIC_WRITE
,
264 FILE_FLAG_OVERLAPPED
,
268 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
269 return MMSYSERR_ERROR
;
273 return MMSYSERR_NOERROR
;
277 WdmAudCloseSoundDeviceByLegacy(
278 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
281 WDMAUD_DEVICE_INFO DeviceInfo
;
283 MMDEVICE_TYPE DeviceType
;
284 PSOUND_DEVICE SoundDevice
;
286 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
288 if ( ! MMSUCCESS(Result
) )
290 return TranslateInternalMmResult(Result
);
293 if ( OpenCount
== 0 )
295 return MMSYSERR_NOERROR
;
298 SND_ASSERT( KernelHandle
!= INVALID_HANDLE_VALUE
);
300 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
301 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
303 if (SoundDeviceInstance
->Handle
!= (PVOID
)KernelHandle
)
305 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
307 DeviceInfo
.DeviceType
= DeviceType
;
308 DeviceInfo
.hDevice
= SoundDeviceInstance
->Handle
;
310 /* First stop the stream */
311 if (DeviceType
!= MIXER_DEVICE_TYPE
)
313 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
314 SyncOverlappedDeviceIoControl(KernelHandle
,
315 IOCTL_SETDEVICE_STATE
,
316 (LPVOID
) &DeviceInfo
,
317 sizeof(WDMAUD_DEVICE_INFO
),
318 (LPVOID
) &DeviceInfo
,
319 sizeof(WDMAUD_DEVICE_INFO
),
322 DeviceInfo
.u
.State
= KSSTATE_ACQUIRE
;
323 SyncOverlappedDeviceIoControl(KernelHandle
,
324 IOCTL_SETDEVICE_STATE
,
325 (LPVOID
) &DeviceInfo
,
326 sizeof(WDMAUD_DEVICE_INFO
),
327 (LPVOID
) &DeviceInfo
,
328 sizeof(WDMAUD_DEVICE_INFO
),
332 DeviceInfo
.u
.State
= KSSTATE_STOP
;
333 SyncOverlappedDeviceIoControl(KernelHandle
,
334 IOCTL_SETDEVICE_STATE
,
335 (LPVOID
) &DeviceInfo
,
336 sizeof(WDMAUD_DEVICE_INFO
),
337 (LPVOID
) &DeviceInfo
,
338 sizeof(WDMAUD_DEVICE_INFO
),
342 SyncOverlappedDeviceIoControl(KernelHandle
,
344 (LPVOID
) &DeviceInfo
,
345 sizeof(WDMAUD_DEVICE_INFO
),
346 (LPVOID
) &DeviceInfo
,
347 sizeof(WDMAUD_DEVICE_INFO
),
351 if (DeviceType
== MIXER_DEVICE_TYPE
)
353 SetEvent(SoundDeviceInstance
->hStopEvent
);
354 CloseHandle(SoundDeviceInstance
->hStopEvent
);
355 CloseHandle(SoundDeviceInstance
->hNotifyEvent
);
362 CloseHandle(KernelHandle
);
363 KernelHandle
= INVALID_HANDLE_VALUE
;
366 return MMSYSERR_NOERROR
;
370 WdmAudSetMixerDeviceFormatByLegacy(
371 IN PSOUND_DEVICE_INSTANCE Instance
,
373 IN PWAVEFORMATEX WaveFormat
,
374 IN DWORD WaveFormatSize
)
377 WDMAUD_DEVICE_INFO DeviceInfo
;
380 Instance
->hNotifyEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
381 if ( ! Instance
->hNotifyEvent
)
382 return MMSYSERR_NOMEM
;
384 if (Instance
->Handle
!= NULL
)
386 /* device is already open */
387 return MMSYSERR_NOERROR
;
390 Instance
->hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
391 if ( ! Instance
->hStopEvent
)
392 return MMSYSERR_NOMEM
;
394 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
395 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
396 DeviceInfo
.DeviceIndex
= DeviceId
;
397 DeviceInfo
.u
.hNotifyEvent
= Instance
->hNotifyEvent
;
399 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
401 (LPVOID
) &DeviceInfo
,
402 sizeof(WDMAUD_DEVICE_INFO
),
403 (LPVOID
) &DeviceInfo
,
404 sizeof(WDMAUD_DEVICE_INFO
),
407 if ( ! MMSUCCESS(Result
) )
409 CloseHandle(Instance
->hNotifyEvent
);
410 CloseHandle(Instance
->hStopEvent
);
411 return TranslateInternalMmResult(Result
);
414 hThread
= CreateThread(NULL
, 0, MixerEventThreadRoutine
, (LPVOID
)Instance
, 0, NULL
);
417 CloseHandle(hThread
);
420 /* Store sound device handle instance handle */
421 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
423 return MMSYSERR_NOERROR
;
427 WdmAudSetWaveDeviceFormatByLegacy(
428 IN PSOUND_DEVICE_INSTANCE Instance
,
430 IN PWAVEFORMATEX WaveFormat
,
431 IN DWORD WaveFormatSize
)
434 PSOUND_DEVICE SoundDevice
;
436 WDMAUD_DEVICE_INFO DeviceInfo
;
437 MMDEVICE_TYPE DeviceType
;
439 Result
= GetSoundDeviceFromInstance(Instance
, &SoundDevice
);
441 if ( ! MMSUCCESS(Result
) )
443 return TranslateInternalMmResult(Result
);
446 Result
= GetSoundDeviceIdentifier(SoundDevice
, &Identifier
);
448 if ( ! MMSUCCESS(Result
) )
450 return TranslateInternalMmResult(Result
);
453 if (Instance
->Handle
!= NULL
)
455 /* device is already open */
456 return MMSYSERR_NOERROR
;
459 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
461 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
463 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
464 DeviceInfo
.DeviceType
= DeviceType
;
465 DeviceInfo
.DeviceIndex
= DeviceId
;
466 DeviceInfo
.u
.WaveFormatEx
.cbSize
= sizeof(WAVEFORMATEX
); //WaveFormat->cbSize;
467 DeviceInfo
.u
.WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
468 #ifdef USERMODE_MIXER
469 DeviceInfo
.u
.WaveFormatEx
.nChannels
= 2;
470 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= 44100;
471 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= 4;
472 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= 176400;
473 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= 16;
475 DeviceInfo
.u
.WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
476 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
477 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
478 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
479 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
482 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
484 (LPVOID
) &DeviceInfo
,
485 sizeof(WDMAUD_DEVICE_INFO
),
486 (LPVOID
) &DeviceInfo
,
487 sizeof(WDMAUD_DEVICE_INFO
),
490 if ( ! MMSUCCESS(Result
) )
492 return TranslateInternalMmResult(Result
);
496 Instance
->WaveFormatEx
.cbSize
= WaveFormat
->cbSize
;
497 Instance
->WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
498 Instance
->WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
499 Instance
->WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
500 Instance
->WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
501 Instance
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
502 Instance
->WaveFormatEx
.wBitsPerSample
= WaveFormat
->wBitsPerSample
;
504 /* Store sound device handle instance handle */
505 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
507 /* Now determine framing requirements */
508 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
510 (LPVOID
) &DeviceInfo
,
511 sizeof(WDMAUD_DEVICE_INFO
),
512 (LPVOID
) &DeviceInfo
,
513 sizeof(WDMAUD_DEVICE_INFO
),
516 if ( MMSUCCESS(Result
) )
518 if (DeviceInfo
.u
.FrameSize
)
520 Instance
->FrameSize
= DeviceInfo
.u
.FrameSize
* 2;
521 Instance
->BufferCount
= WaveFormat
->nAvgBytesPerSec
/ Instance
->FrameSize
;
522 SND_TRACE(L
"FrameSize %u BufferCount %u\n", Instance
->FrameSize
, Instance
->BufferCount
);
527 // use a default of 100 buffers
528 Instance
->BufferCount
= 100;
531 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
533 /* Now start the stream */
534 DeviceInfo
.u
.State
= KSSTATE_RUN
;
535 SyncOverlappedDeviceIoControl(KernelHandle
,
536 IOCTL_SETDEVICE_STATE
,
537 (LPVOID
) &DeviceInfo
,
538 sizeof(WDMAUD_DEVICE_INFO
),
539 (LPVOID
) &DeviceInfo
,
540 sizeof(WDMAUD_DEVICE_INFO
),
544 return MMSYSERR_NOERROR
;
548 WdmAudCommitWaveBufferByLegacy(
549 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
552 IN PSOUND_OVERLAPPED Overlap
,
553 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
)
557 WDMAUD_DEVICE_INFO DeviceInfo
;
558 PSOUND_DEVICE SoundDevice
;
559 MMDEVICE_TYPE DeviceType
;
562 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance
);
563 VALIDATE_MMSYS_PARAMETER( OffsetPtr
);
564 VALIDATE_MMSYS_PARAMETER( Overlap
);
565 VALIDATE_MMSYS_PARAMETER( CompletionRoutine
);
567 GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
570 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
572 if ( ! MMSUCCESS(Result
) )
574 return TranslateInternalMmResult(Result
);
577 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
578 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
580 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
582 DeviceInfo
.Header
.FrameExtent
= Length
;
583 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
585 DeviceInfo
.Header
.DataUsed
= Length
;
587 DeviceInfo
.Header
.Data
= OffsetPtr
;
588 DeviceInfo
.Header
.Size
= sizeof(WDMAUD_DEVICE_INFO
);
589 DeviceInfo
.Header
.PresentationTime
.Numerator
= 1;
590 DeviceInfo
.Header
.PresentationTime
.Denominator
= 1;
591 DeviceInfo
.hDevice
= Handle
;
592 DeviceInfo
.DeviceType
= DeviceType
;
596 Overlap
->Standard
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
598 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
600 Ret
= WriteFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
602 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
604 else if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
606 Ret
= ReadFileEx(KernelHandle
, &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, CompletionRoutine
);
608 // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
611 return MMSYSERR_NOERROR
;
617 WdmAudSetWaveStateByLegacy(
618 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
622 PSOUND_DEVICE SoundDevice
;
623 WDMAUD_DEVICE_INFO DeviceInfo
;
624 MMDEVICE_TYPE DeviceType
;
627 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
629 if ( ! MMSUCCESS(Result
) )
631 return TranslateInternalMmResult(Result
);
634 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
635 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
637 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
638 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
640 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
641 DeviceInfo
.hDevice
= Handle
;
642 DeviceInfo
.DeviceType
= DeviceType
;
645 DeviceInfo
.u
.State
= KSSTATE_RUN
;
647 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
648 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
649 IOCTL_SETDEVICE_STATE
,
650 (LPVOID
) &DeviceInfo
,
651 sizeof(WDMAUD_DEVICE_INFO
),
652 (LPVOID
) &DeviceInfo
,
653 sizeof(WDMAUD_DEVICE_INFO
),
660 WdmAudGetDeviceInterfaceStringByLegacy(
661 IN MMDEVICE_TYPE DeviceType
,
664 IN DWORD InterfaceLength
,
665 OUT DWORD
* InterfaceSize
)
667 WDMAUD_DEVICE_INFO DeviceInfo
;
670 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
671 DeviceInfo
.DeviceType
= DeviceType
;
672 DeviceInfo
.DeviceIndex
= DeviceId
;
675 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
676 IOCTL_QUERYDEVICEINTERFACESTRING
,
677 (LPVOID
) &DeviceInfo
,
678 sizeof(WDMAUD_DEVICE_INFO
),
679 (LPVOID
) &DeviceInfo
,
680 sizeof(WDMAUD_DEVICE_INFO
),
684 if ( ! MMSUCCESS(Result
) )
686 return TranslateInternalMmResult(Result
);
692 SND_ASSERT(InterfaceSize
);
694 *InterfaceSize
= DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
;
695 return MMSYSERR_NOERROR
;
698 if (InterfaceLength
< DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
)
700 /* buffer is too small */
701 return MMSYSERR_MOREDATA
;
704 DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
= InterfaceLength
;
705 DeviceInfo
.u
.Interface
.DeviceInterfaceString
= Interface
;
707 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
708 IOCTL_QUERYDEVICEINTERFACESTRING
,
709 (LPVOID
) &DeviceInfo
,
710 sizeof(WDMAUD_DEVICE_INFO
),
711 (LPVOID
) &DeviceInfo
,
712 sizeof(WDMAUD_DEVICE_INFO
),
715 if ( MMSUCCESS(Result
) && InterfaceLength
> 2)
717 Interface
[1] = L
'\\';
718 Interface
[InterfaceLength
-1] = L
'\0';
725 WdmAudGetWavePositionByLegacy(
726 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
730 PSOUND_DEVICE SoundDevice
;
731 WDMAUD_DEVICE_INFO DeviceInfo
;
732 MMDEVICE_TYPE DeviceType
;
735 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
737 if ( ! MMSUCCESS(Result
) )
739 return TranslateInternalMmResult(Result
);
742 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
743 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
745 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
746 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
748 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
749 DeviceInfo
.hDevice
= Handle
;
750 DeviceInfo
.DeviceType
= DeviceType
;
752 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
754 (LPVOID
) &DeviceInfo
,
755 sizeof(WDMAUD_DEVICE_INFO
),
756 (LPVOID
) &DeviceInfo
,
757 sizeof(WDMAUD_DEVICE_INFO
),
760 if ( ! MMSUCCESS(Result
) )
762 return TranslateInternalMmResult(Result
);
765 Time
->wType
= TIME_BYTES
;
766 Time
->u
.cb
= (DWORD
)DeviceInfo
.u
.Position
;
768 return MMSYSERR_NOERROR
;
773 WdmAudResetStreamByLegacy(
774 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
775 IN MMDEVICE_TYPE DeviceType
,
776 IN BOOLEAN bStartReset
)
780 WDMAUD_DEVICE_INFO DeviceInfo
;
782 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
783 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
785 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
786 DeviceInfo
.hDevice
= Handle
;
787 DeviceInfo
.DeviceType
= DeviceType
;
788 DeviceInfo
.u
.ResetStream
= (bStartReset
? KSRESET_BEGIN
: KSRESET_END
);
790 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
792 (LPVOID
) &DeviceInfo
,
793 sizeof(WDMAUD_DEVICE_INFO
),
794 (LPVOID
) &DeviceInfo
,
795 sizeof(WDMAUD_DEVICE_INFO
),
801 WdmAudQueryMixerInfoByLegacy(
802 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
808 WDMAUD_DEVICE_INFO DeviceInfo
;
811 LPMIXERLINEW MixLine
;
812 LPMIXERLINECONTROLSW MixControls
;
813 LPMIXERCONTROLDETAILS MixDetails
;
815 SND_TRACE(L
"uMsg %x Flags %x\n", uMsg
, Flags
);
817 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
818 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
820 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
821 DeviceInfo
.hDevice
= Handle
;
822 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
823 DeviceInfo
.Flags
= Flags
;
825 MixLine
= (LPMIXERLINEW
)Parameter
;
826 MixControls
= (LPMIXERLINECONTROLSW
)Parameter
;
827 MixDetails
= (LPMIXERCONTROLDETAILS
)Parameter
;
831 case MXDM_GETLINEINFO
:
832 RtlCopyMemory(&DeviceInfo
.u
.MixLine
, MixLine
, sizeof(MIXERLINEW
));
833 IoControlCode
= IOCTL_GETLINEINFO
;
835 case MXDM_GETLINECONTROLS
:
836 RtlCopyMemory(&DeviceInfo
.u
.MixControls
, MixControls
, sizeof(MIXERLINECONTROLSW
));
837 IoControlCode
= IOCTL_GETLINECONTROLS
;
839 case MXDM_SETCONTROLDETAILS
:
840 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
841 IoControlCode
= IOCTL_SETCONTROLDETAILS
;
843 case MXDM_GETCONTROLDETAILS
:
844 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
845 IoControlCode
= IOCTL_GETCONTROLDETAILS
;
849 return MMSYSERR_NOTSUPPORTED
;
852 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
854 (LPVOID
) &DeviceInfo
,
855 sizeof(WDMAUD_DEVICE_INFO
),
856 (LPVOID
) &DeviceInfo
,
857 sizeof(WDMAUD_DEVICE_INFO
),
860 if ( ! MMSUCCESS(Result
) )
867 case MXDM_GETLINEINFO
:
869 RtlCopyMemory(MixLine
, &DeviceInfo
.u
.MixLine
, sizeof(MIXERLINEW
));