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
= (DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
* 8) / (DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
* DeviceInfo
.u
.WaveFormatEx
.nChannels
);
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
);
495 if (WaveFormatSize
>= sizeof(WAVEFORMAT
))
498 Instance
->WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
499 Instance
->WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
500 Instance
->WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
501 Instance
->WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
502 Instance
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
506 Instance
->WaveFormatEx
.cbSize
= sizeof(WAVEFORMATEX
);
507 Instance
->WaveFormatEx
.wBitsPerSample
= (DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
* 8) / (DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
* DeviceInfo
.u
.WaveFormatEx
.nChannels
);
509 /* Store sound device handle instance handle */
510 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
512 /* Now determine framing requirements */
513 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
515 (LPVOID
) &DeviceInfo
,
516 sizeof(WDMAUD_DEVICE_INFO
),
517 (LPVOID
) &DeviceInfo
,
518 sizeof(WDMAUD_DEVICE_INFO
),
521 if ( MMSUCCESS(Result
) )
523 if (DeviceInfo
.u
.FrameSize
)
525 Instance
->FrameSize
= DeviceInfo
.u
.FrameSize
* 2;
526 Instance
->BufferCount
= WaveFormat
->nAvgBytesPerSec
/ Instance
->FrameSize
;
527 SND_TRACE(L
"FrameSize %u BufferCount %u\n", Instance
->FrameSize
, Instance
->BufferCount
);
532 // use a default of 100 buffers
533 Instance
->BufferCount
= 100;
536 /* Now acquire resources */
537 DeviceInfo
.u
.State
= KSSTATE_ACQUIRE
;
538 SyncOverlappedDeviceIoControl(KernelHandle
, IOCTL_SETDEVICE_STATE
, (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), NULL
);
541 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
542 SyncOverlappedDeviceIoControl(KernelHandle
, IOCTL_SETDEVICE_STATE
, (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), NULL
);
545 DeviceInfo
.u
.State
= KSSTATE_RUN
;
546 SyncOverlappedDeviceIoControl(KernelHandle
, IOCTL_SETDEVICE_STATE
, (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), NULL
);
549 return MMSYSERR_NOERROR
;
554 LegacyCompletionRoutine(
555 IN DWORD dwErrorCode
,
556 IN DWORD dwNumberOfBytesTransferred
,
557 IN LPOVERLAPPED lpOverlapped
)
559 PSOUND_OVERLAPPED Overlap
;
560 PWDMAUD_DEVICE_INFO DeviceInfo
;
562 Overlap
= (PSOUND_OVERLAPPED
)lpOverlapped
;
563 DeviceInfo
= (PWDMAUD_DEVICE_INFO
)Overlap
->CompletionContext
;
565 /* Call mmebuddy overlap routine */
566 Overlap
->OriginalCompletionRoutine(dwErrorCode
, DeviceInfo
->Header
.DataUsed
, lpOverlapped
);
568 HeapFree(GetProcessHeap(), 0, DeviceInfo
);
572 WdmAudCommitWaveBufferByLegacy(
573 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
576 IN PSOUND_OVERLAPPED Overlap
,
577 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
)
581 PWDMAUD_DEVICE_INFO DeviceInfo
;
582 PSOUND_DEVICE SoundDevice
;
583 MMDEVICE_TYPE DeviceType
;
586 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance
);
587 VALIDATE_MMSYS_PARAMETER( OffsetPtr
);
588 VALIDATE_MMSYS_PARAMETER( Overlap
);
589 VALIDATE_MMSYS_PARAMETER( CompletionRoutine
);
591 GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
594 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
596 if ( ! MMSUCCESS(Result
) )
598 return TranslateInternalMmResult(Result
);
601 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
602 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
604 DeviceInfo
= (PWDMAUD_DEVICE_INFO
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(WDMAUD_DEVICE_INFO
));
608 return MMSYSERR_NOMEM
;
611 DeviceInfo
->Header
.FrameExtent
= Length
;
612 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
614 DeviceInfo
->Header
.DataUsed
= Length
;
616 DeviceInfo
->Header
.Data
= OffsetPtr
;
617 DeviceInfo
->Header
.Size
= sizeof(WDMAUD_DEVICE_INFO
);
618 DeviceInfo
->Header
.PresentationTime
.Numerator
= 1;
619 DeviceInfo
->Header
.PresentationTime
.Denominator
= 1;
620 DeviceInfo
->hDevice
= Handle
;
621 DeviceInfo
->DeviceType
= DeviceType
;
624 // create completion event
625 Overlap
->Standard
.hEvent
= Handle
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
626 if (Overlap
->Standard
.hEvent
== NULL
)
629 return MMSYSERR_NOMEM
;
632 Overlap
->OriginalCompletionRoutine
= CompletionRoutine
;
633 Overlap
->CompletionContext
= (PVOID
)DeviceInfo
;
635 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
637 Ret
= WriteFileEx(KernelHandle
, DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, LegacyCompletionRoutine
);
639 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
641 else if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
643 Ret
= ReadFileEx(KernelHandle
, DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, LegacyCompletionRoutine
);
645 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
648 // close event handle
651 return MMSYSERR_NOERROR
;
655 WdmAudSetWaveStateByLegacy(
656 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
660 PSOUND_DEVICE SoundDevice
;
661 WDMAUD_DEVICE_INFO DeviceInfo
;
662 MMDEVICE_TYPE DeviceType
;
665 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
667 if ( ! MMSUCCESS(Result
) )
669 return TranslateInternalMmResult(Result
);
672 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
673 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
675 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
676 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
678 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
679 DeviceInfo
.hDevice
= Handle
;
680 DeviceInfo
.DeviceType
= DeviceType
;
683 DeviceInfo
.u
.State
= KSSTATE_RUN
;
685 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
686 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
687 IOCTL_SETDEVICE_STATE
,
688 (LPVOID
) &DeviceInfo
,
689 sizeof(WDMAUD_DEVICE_INFO
),
690 (LPVOID
) &DeviceInfo
,
691 sizeof(WDMAUD_DEVICE_INFO
),
698 WdmAudGetDeviceInterfaceStringByLegacy(
699 IN MMDEVICE_TYPE DeviceType
,
702 IN DWORD InterfaceLength
,
703 OUT DWORD
* InterfaceSize
)
705 WDMAUD_DEVICE_INFO DeviceInfo
;
708 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
709 DeviceInfo
.DeviceType
= DeviceType
;
710 DeviceInfo
.DeviceIndex
= DeviceId
;
713 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
714 IOCTL_QUERYDEVICEINTERFACESTRING
,
715 (LPVOID
) &DeviceInfo
,
716 sizeof(WDMAUD_DEVICE_INFO
),
717 (LPVOID
) &DeviceInfo
,
718 sizeof(WDMAUD_DEVICE_INFO
),
722 if ( ! MMSUCCESS(Result
) )
724 return TranslateInternalMmResult(Result
);
730 SND_ASSERT(InterfaceSize
);
732 *InterfaceSize
= DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
;
733 return MMSYSERR_NOERROR
;
736 if (InterfaceLength
< DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
)
738 /* buffer is too small */
739 return MMSYSERR_MOREDATA
;
742 DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
= InterfaceLength
;
743 DeviceInfo
.u
.Interface
.DeviceInterfaceString
= Interface
;
745 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
746 IOCTL_QUERYDEVICEINTERFACESTRING
,
747 (LPVOID
) &DeviceInfo
,
748 sizeof(WDMAUD_DEVICE_INFO
),
749 (LPVOID
) &DeviceInfo
,
750 sizeof(WDMAUD_DEVICE_INFO
),
753 if ( MMSUCCESS(Result
) && InterfaceLength
> 2)
755 Interface
[1] = L
'\\';
756 Interface
[InterfaceLength
-1] = L
'\0';
763 WdmAudGetWavePositionByLegacy(
764 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
768 PSOUND_DEVICE SoundDevice
;
769 WDMAUD_DEVICE_INFO DeviceInfo
;
770 MMDEVICE_TYPE DeviceType
;
773 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
775 if ( ! MMSUCCESS(Result
) )
777 return TranslateInternalMmResult(Result
);
780 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
781 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
783 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
784 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
786 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
787 DeviceInfo
.hDevice
= Handle
;
788 DeviceInfo
.DeviceType
= DeviceType
;
790 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
792 (LPVOID
) &DeviceInfo
,
793 sizeof(WDMAUD_DEVICE_INFO
),
794 (LPVOID
) &DeviceInfo
,
795 sizeof(WDMAUD_DEVICE_INFO
),
798 if ( ! MMSUCCESS(Result
) )
800 return TranslateInternalMmResult(Result
);
803 Time
->wType
= TIME_BYTES
;
804 Time
->u
.cb
= (DWORD
)DeviceInfo
.u
.Position
;
806 return MMSYSERR_NOERROR
;
811 WdmAudResetStreamByLegacy(
812 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
813 IN MMDEVICE_TYPE DeviceType
,
814 IN BOOLEAN bStartReset
)
818 WDMAUD_DEVICE_INFO DeviceInfo
;
820 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
821 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
823 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
824 DeviceInfo
.hDevice
= Handle
;
825 DeviceInfo
.DeviceType
= DeviceType
;
826 DeviceInfo
.u
.ResetStream
= (bStartReset
? KSRESET_BEGIN
: KSRESET_END
);
828 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
830 (LPVOID
) &DeviceInfo
,
831 sizeof(WDMAUD_DEVICE_INFO
),
832 (LPVOID
) &DeviceInfo
,
833 sizeof(WDMAUD_DEVICE_INFO
),
839 WdmAudQueryMixerInfoByLegacy(
840 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
847 WDMAUD_DEVICE_INFO DeviceInfo
;
850 LPMIXERLINEW MixLine
;
851 LPMIXERLINECONTROLSW MixControls
;
852 LPMIXERCONTROLDETAILS MixDetails
;
854 SND_TRACE(L
"uMsg %x Flags %x\n", uMsg
, Flags
);
856 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
857 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
859 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
860 DeviceInfo
.hDevice
= Handle
;
861 DeviceInfo
.DeviceIndex
= DeviceId
;
862 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
863 DeviceInfo
.Flags
= Flags
;
865 MixLine
= (LPMIXERLINEW
)Parameter
;
866 MixControls
= (LPMIXERLINECONTROLSW
)Parameter
;
867 MixDetails
= (LPMIXERCONTROLDETAILS
)Parameter
;
871 case MXDM_GETLINEINFO
:
872 RtlCopyMemory(&DeviceInfo
.u
.MixLine
, MixLine
, sizeof(MIXERLINEW
));
873 IoControlCode
= IOCTL_GETLINEINFO
;
875 case MXDM_GETLINECONTROLS
:
876 RtlCopyMemory(&DeviceInfo
.u
.MixControls
, MixControls
, sizeof(MIXERLINECONTROLSW
));
877 IoControlCode
= IOCTL_GETLINECONTROLS
;
879 case MXDM_SETCONTROLDETAILS
:
880 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
881 IoControlCode
= IOCTL_SETCONTROLDETAILS
;
883 case MXDM_GETCONTROLDETAILS
:
884 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
885 IoControlCode
= IOCTL_GETCONTROLDETAILS
;
889 return MMSYSERR_NOTSUPPORTED
;
892 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
894 (LPVOID
) &DeviceInfo
,
895 sizeof(WDMAUD_DEVICE_INFO
),
896 (LPVOID
) &DeviceInfo
,
897 sizeof(WDMAUD_DEVICE_INFO
),
900 if ( ! MMSUCCESS(Result
) )
907 case MXDM_GETLINEINFO
:
909 RtlCopyMemory(MixLine
, &DeviceInfo
.u
.MixLine
, sizeof(MIXERLINEW
));