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
;
549 LegacyCompletionRoutine(
550 IN DWORD dwErrorCode
,
551 IN DWORD dwNumberOfBytesTransferred
,
552 IN LPOVERLAPPED lpOverlapped
)
554 PSOUND_OVERLAPPED Overlap
;
555 PWDMAUD_DEVICE_INFO DeviceInfo
;
557 Overlap
= (PSOUND_OVERLAPPED
)lpOverlapped
;
558 DeviceInfo
= (PWDMAUD_DEVICE_INFO
)Overlap
->CompletionContext
;
560 /* Call mmebuddy overlap routine */
561 Overlap
->OriginalCompletionRoutine(dwErrorCode
, DeviceInfo
->Header
.DataUsed
, lpOverlapped
);
563 HeapFree(GetProcessHeap(), 0, DeviceInfo
);
567 WdmAudCommitWaveBufferByLegacy(
568 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
571 IN PSOUND_OVERLAPPED Overlap
,
572 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
)
576 PWDMAUD_DEVICE_INFO DeviceInfo
;
577 PSOUND_DEVICE SoundDevice
;
578 MMDEVICE_TYPE DeviceType
;
581 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance
);
582 VALIDATE_MMSYS_PARAMETER( OffsetPtr
);
583 VALIDATE_MMSYS_PARAMETER( Overlap
);
584 VALIDATE_MMSYS_PARAMETER( CompletionRoutine
);
586 GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
589 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
591 if ( ! MMSUCCESS(Result
) )
593 return TranslateInternalMmResult(Result
);
596 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
597 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
599 DeviceInfo
= (PWDMAUD_DEVICE_INFO
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(WDMAUD_DEVICE_INFO
));
603 return MMSYSERR_NOMEM
;
606 DeviceInfo
->Header
.FrameExtent
= Length
;
607 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
609 DeviceInfo
->Header
.DataUsed
= Length
;
611 DeviceInfo
->Header
.Data
= OffsetPtr
;
612 DeviceInfo
->Header
.Size
= sizeof(WDMAUD_DEVICE_INFO
);
613 DeviceInfo
->Header
.PresentationTime
.Numerator
= 1;
614 DeviceInfo
->Header
.PresentationTime
.Denominator
= 1;
615 DeviceInfo
->hDevice
= Handle
;
616 DeviceInfo
->DeviceType
= DeviceType
;
619 // create completion event
620 Overlap
->Standard
.hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
621 if (Overlap
->Standard
.hEvent
== NULL
)
624 return MMSYSERR_NOMEM
;
627 Overlap
->OriginalCompletionRoutine
= CompletionRoutine
;
628 Overlap
->CompletionContext
= (PVOID
)DeviceInfo
;
630 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
632 Ret
= WriteFileEx(KernelHandle
, DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, LegacyCompletionRoutine
);
634 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
636 else if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
638 Ret
= ReadFileEx(KernelHandle
, DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, LegacyCompletionRoutine
);
640 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
643 // close event handle
644 CloseHandle(Overlap
->Standard
.hEvent
);
646 return MMSYSERR_NOERROR
;
652 WdmAudSetWaveStateByLegacy(
653 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
657 PSOUND_DEVICE SoundDevice
;
658 WDMAUD_DEVICE_INFO DeviceInfo
;
659 MMDEVICE_TYPE DeviceType
;
662 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
664 if ( ! MMSUCCESS(Result
) )
666 return TranslateInternalMmResult(Result
);
669 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
670 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
672 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
673 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
675 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
676 DeviceInfo
.hDevice
= Handle
;
677 DeviceInfo
.DeviceType
= DeviceType
;
680 DeviceInfo
.u
.State
= KSSTATE_RUN
;
682 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
683 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
684 IOCTL_SETDEVICE_STATE
,
685 (LPVOID
) &DeviceInfo
,
686 sizeof(WDMAUD_DEVICE_INFO
),
687 (LPVOID
) &DeviceInfo
,
688 sizeof(WDMAUD_DEVICE_INFO
),
695 WdmAudGetDeviceInterfaceStringByLegacy(
696 IN MMDEVICE_TYPE DeviceType
,
699 IN DWORD InterfaceLength
,
700 OUT DWORD
* InterfaceSize
)
702 WDMAUD_DEVICE_INFO DeviceInfo
;
705 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
706 DeviceInfo
.DeviceType
= DeviceType
;
707 DeviceInfo
.DeviceIndex
= DeviceId
;
710 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
711 IOCTL_QUERYDEVICEINTERFACESTRING
,
712 (LPVOID
) &DeviceInfo
,
713 sizeof(WDMAUD_DEVICE_INFO
),
714 (LPVOID
) &DeviceInfo
,
715 sizeof(WDMAUD_DEVICE_INFO
),
719 if ( ! MMSUCCESS(Result
) )
721 return TranslateInternalMmResult(Result
);
727 SND_ASSERT(InterfaceSize
);
729 *InterfaceSize
= DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
;
730 return MMSYSERR_NOERROR
;
733 if (InterfaceLength
< DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
)
735 /* buffer is too small */
736 return MMSYSERR_MOREDATA
;
739 DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
= InterfaceLength
;
740 DeviceInfo
.u
.Interface
.DeviceInterfaceString
= Interface
;
742 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
743 IOCTL_QUERYDEVICEINTERFACESTRING
,
744 (LPVOID
) &DeviceInfo
,
745 sizeof(WDMAUD_DEVICE_INFO
),
746 (LPVOID
) &DeviceInfo
,
747 sizeof(WDMAUD_DEVICE_INFO
),
750 if ( MMSUCCESS(Result
) && InterfaceLength
> 2)
752 Interface
[1] = L
'\\';
753 Interface
[InterfaceLength
-1] = L
'\0';
760 WdmAudGetWavePositionByLegacy(
761 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
765 PSOUND_DEVICE SoundDevice
;
766 WDMAUD_DEVICE_INFO DeviceInfo
;
767 MMDEVICE_TYPE DeviceType
;
770 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
772 if ( ! MMSUCCESS(Result
) )
774 return TranslateInternalMmResult(Result
);
777 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
778 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
780 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
781 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
783 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
784 DeviceInfo
.hDevice
= Handle
;
785 DeviceInfo
.DeviceType
= DeviceType
;
787 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
789 (LPVOID
) &DeviceInfo
,
790 sizeof(WDMAUD_DEVICE_INFO
),
791 (LPVOID
) &DeviceInfo
,
792 sizeof(WDMAUD_DEVICE_INFO
),
795 if ( ! MMSUCCESS(Result
) )
797 return TranslateInternalMmResult(Result
);
800 Time
->wType
= TIME_BYTES
;
801 Time
->u
.cb
= (DWORD
)DeviceInfo
.u
.Position
;
803 return MMSYSERR_NOERROR
;
808 WdmAudResetStreamByLegacy(
809 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
810 IN MMDEVICE_TYPE DeviceType
,
811 IN BOOLEAN bStartReset
)
815 WDMAUD_DEVICE_INFO DeviceInfo
;
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
= DeviceType
;
823 DeviceInfo
.u
.ResetStream
= (bStartReset
? KSRESET_BEGIN
: KSRESET_END
);
825 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
827 (LPVOID
) &DeviceInfo
,
828 sizeof(WDMAUD_DEVICE_INFO
),
829 (LPVOID
) &DeviceInfo
,
830 sizeof(WDMAUD_DEVICE_INFO
),
836 WdmAudQueryMixerInfoByLegacy(
837 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
844 WDMAUD_DEVICE_INFO DeviceInfo
;
847 LPMIXERLINEW MixLine
;
848 LPMIXERLINECONTROLSW MixControls
;
849 LPMIXERCONTROLDETAILS MixDetails
;
851 SND_TRACE(L
"uMsg %x Flags %x\n", uMsg
, Flags
);
853 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
854 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
856 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
857 DeviceInfo
.hDevice
= Handle
;
858 DeviceInfo
.DeviceIndex
= DeviceId
;
859 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
860 DeviceInfo
.Flags
= Flags
;
862 MixLine
= (LPMIXERLINEW
)Parameter
;
863 MixControls
= (LPMIXERLINECONTROLSW
)Parameter
;
864 MixDetails
= (LPMIXERCONTROLDETAILS
)Parameter
;
868 case MXDM_GETLINEINFO
:
869 RtlCopyMemory(&DeviceInfo
.u
.MixLine
, MixLine
, sizeof(MIXERLINEW
));
870 IoControlCode
= IOCTL_GETLINEINFO
;
872 case MXDM_GETLINECONTROLS
:
873 RtlCopyMemory(&DeviceInfo
.u
.MixControls
, MixControls
, sizeof(MIXERLINECONTROLSW
));
874 IoControlCode
= IOCTL_GETLINECONTROLS
;
876 case MXDM_SETCONTROLDETAILS
:
877 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
878 IoControlCode
= IOCTL_SETCONTROLDETAILS
;
880 case MXDM_GETCONTROLDETAILS
:
881 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
882 IoControlCode
= IOCTL_GETCONTROLDETAILS
;
886 return MMSYSERR_NOTSUPPORTED
;
889 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
891 (LPVOID
) &DeviceInfo
,
892 sizeof(WDMAUD_DEVICE_INFO
),
893 (LPVOID
) &DeviceInfo
,
894 sizeof(WDMAUD_DEVICE_INFO
),
897 if ( ! MMSUCCESS(Result
) )
904 case MXDM_GETLINEINFO
:
906 RtlCopyMemory(MixLine
, &DeviceInfo
.u
.MixLine
, sizeof(MIXERLINEW
));