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(
254 IN PSOUND_DEVICE SoundDevice
,
258 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
259 GUID SWBusGuid
= {STATIC_KSCATEGORY_WDMAUD
};
260 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
;
262 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
264 hDevInfo
= SetupDiGetClassDevsW(&SWBusGuid
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
268 return MMSYSERR_ERROR
;
271 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
272 if (!SetupDiEnumDeviceInterfaces(hDevInfo
, NULL
, &SWBusGuid
, 0, &DeviceInterfaceData
))
275 SetupDiDestroyDeviceInfoList(hDevInfo
);
276 return MMSYSERR_ERROR
;
279 DeviceInterfaceDetailData
= (PSP_DEVICE_INTERFACE_DETAIL_DATA_W
)HeapAlloc(GetProcessHeap(), 0, MAX_PATH
* sizeof(WCHAR
) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
));
280 if (!DeviceInterfaceDetailData
)
283 SetupDiDestroyDeviceInfoList(hDevInfo
);
284 return MMSYSERR_ERROR
;
287 DeviceInterfaceDetailData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
);
288 if (!SetupDiGetDeviceInterfaceDetailW(hDevInfo
, &DeviceInterfaceData
, DeviceInterfaceDetailData
,MAX_PATH
* sizeof(WCHAR
) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
), NULL
, NULL
))
291 HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData
);
292 SetupDiDestroyDeviceInfoList(hDevInfo
);
293 return MMSYSERR_ERROR
;
295 SND_TRACE(L
"Opening wdmaud device '%s'\n",DeviceInterfaceDetailData
->DevicePath
);
296 KernelHandle
= CreateFileW(DeviceInterfaceDetailData
->DevicePath
,
297 GENERIC_READ
| GENERIC_WRITE
,
301 FILE_FLAG_OVERLAPPED
,
304 HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData
);
305 SetupDiDestroyDeviceInfoList(hDevInfo
);
309 if ( KernelHandle
== INVALID_HANDLE_VALUE
)
310 return MMSYSERR_ERROR
;
313 return MMSYSERR_NOERROR
;
318 WdmAudCloseSoundDeviceByLegacy(
319 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
322 WDMAUD_DEVICE_INFO DeviceInfo
;
324 MMDEVICE_TYPE DeviceType
;
325 PSOUND_DEVICE SoundDevice
;
327 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
329 if ( ! MMSUCCESS(Result
) )
331 return TranslateInternalMmResult(Result
);
334 if ( OpenCount
== 0 )
336 return MMSYSERR_NOERROR
;
339 SND_ASSERT( KernelHandle
!= INVALID_HANDLE_VALUE
);
341 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
342 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
344 if (SoundDeviceInstance
->Handle
!= (PVOID
)KernelHandle
)
346 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
348 DeviceInfo
.DeviceType
= DeviceType
;
349 DeviceInfo
.hDevice
= SoundDeviceInstance
->Handle
;
351 /* First stop the stream */
352 if (DeviceType
!= MIXER_DEVICE_TYPE
)
354 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
355 SyncOverlappedDeviceIoControl(KernelHandle
,
356 IOCTL_SETDEVICE_STATE
,
357 (LPVOID
) &DeviceInfo
,
358 sizeof(WDMAUD_DEVICE_INFO
),
359 (LPVOID
) &DeviceInfo
,
360 sizeof(WDMAUD_DEVICE_INFO
),
363 DeviceInfo
.u
.State
= KSSTATE_ACQUIRE
;
364 SyncOverlappedDeviceIoControl(KernelHandle
,
365 IOCTL_SETDEVICE_STATE
,
366 (LPVOID
) &DeviceInfo
,
367 sizeof(WDMAUD_DEVICE_INFO
),
368 (LPVOID
) &DeviceInfo
,
369 sizeof(WDMAUD_DEVICE_INFO
),
373 DeviceInfo
.u
.State
= KSSTATE_STOP
;
374 SyncOverlappedDeviceIoControl(KernelHandle
,
375 IOCTL_SETDEVICE_STATE
,
376 (LPVOID
) &DeviceInfo
,
377 sizeof(WDMAUD_DEVICE_INFO
),
378 (LPVOID
) &DeviceInfo
,
379 sizeof(WDMAUD_DEVICE_INFO
),
383 SyncOverlappedDeviceIoControl(KernelHandle
,
385 (LPVOID
) &DeviceInfo
,
386 sizeof(WDMAUD_DEVICE_INFO
),
387 (LPVOID
) &DeviceInfo
,
388 sizeof(WDMAUD_DEVICE_INFO
),
392 if (DeviceType
== MIXER_DEVICE_TYPE
)
394 SetEvent(SoundDeviceInstance
->hStopEvent
);
395 CloseHandle(SoundDeviceInstance
->hStopEvent
);
396 CloseHandle(SoundDeviceInstance
->hNotifyEvent
);
403 CloseHandle(KernelHandle
);
404 KernelHandle
= INVALID_HANDLE_VALUE
;
407 return MMSYSERR_NOERROR
;
411 WdmAudSetMixerDeviceFormatByLegacy(
412 IN PSOUND_DEVICE_INSTANCE Instance
,
414 IN PWAVEFORMATEX WaveFormat
,
415 IN DWORD WaveFormatSize
)
418 WDMAUD_DEVICE_INFO DeviceInfo
;
421 Instance
->hNotifyEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
422 if ( ! Instance
->hNotifyEvent
)
423 return MMSYSERR_NOMEM
;
425 if (Instance
->Handle
!= NULL
)
427 /* device is already open */
428 return MMSYSERR_NOERROR
;
431 Instance
->hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
432 if ( ! Instance
->hStopEvent
)
433 return MMSYSERR_NOMEM
;
435 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
436 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
437 DeviceInfo
.DeviceIndex
= DeviceId
;
438 DeviceInfo
.u
.hNotifyEvent
= Instance
->hNotifyEvent
;
440 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
442 (LPVOID
) &DeviceInfo
,
443 sizeof(WDMAUD_DEVICE_INFO
),
444 (LPVOID
) &DeviceInfo
,
445 sizeof(WDMAUD_DEVICE_INFO
),
448 if ( ! MMSUCCESS(Result
) )
450 CloseHandle(Instance
->hNotifyEvent
);
451 CloseHandle(Instance
->hStopEvent
);
452 return TranslateInternalMmResult(Result
);
455 hThread
= CreateThread(NULL
, 0, MixerEventThreadRoutine
, (LPVOID
)Instance
, 0, NULL
);
458 CloseHandle(hThread
);
461 /* Store sound device handle instance handle */
462 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
464 return MMSYSERR_NOERROR
;
468 WdmAudSetWaveDeviceFormatByLegacy(
469 IN PSOUND_DEVICE_INSTANCE Instance
,
471 IN PWAVEFORMATEX WaveFormat
,
472 IN DWORD WaveFormatSize
)
475 PSOUND_DEVICE SoundDevice
;
477 WDMAUD_DEVICE_INFO DeviceInfo
;
478 MMDEVICE_TYPE DeviceType
;
480 Result
= GetSoundDeviceFromInstance(Instance
, &SoundDevice
);
482 if ( ! MMSUCCESS(Result
) )
484 return TranslateInternalMmResult(Result
);
487 Result
= GetSoundDeviceIdentifier(SoundDevice
, &Identifier
);
489 if ( ! MMSUCCESS(Result
) )
491 return TranslateInternalMmResult(Result
);
494 if (Instance
->Handle
!= NULL
)
496 /* device is already open */
497 return MMSYSERR_NOERROR
;
500 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
502 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
504 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
505 DeviceInfo
.DeviceType
= DeviceType
;
506 DeviceInfo
.DeviceIndex
= DeviceId
;
507 DeviceInfo
.u
.WaveFormatEx
.cbSize
= sizeof(WAVEFORMATEX
); //WaveFormat->cbSize;
508 DeviceInfo
.u
.WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
509 #ifdef USERMODE_MIXER
510 DeviceInfo
.u
.WaveFormatEx
.nChannels
= 2;
511 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= 44100;
512 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= 4;
513 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= 176400;
514 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= 16;
516 DeviceInfo
.u
.WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
517 DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
518 DeviceInfo
.u
.WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
519 DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
520 DeviceInfo
.u
.WaveFormatEx
.wBitsPerSample
= (DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
* 8) / (DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
* DeviceInfo
.u
.WaveFormatEx
.nChannels
);
523 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
525 (LPVOID
) &DeviceInfo
,
526 sizeof(WDMAUD_DEVICE_INFO
),
527 (LPVOID
) &DeviceInfo
,
528 sizeof(WDMAUD_DEVICE_INFO
),
531 if ( ! MMSUCCESS(Result
) )
533 return TranslateInternalMmResult(Result
);
536 if (WaveFormatSize
>= sizeof(WAVEFORMAT
))
539 Instance
->WaveFormatEx
.wFormatTag
= WaveFormat
->wFormatTag
;
540 Instance
->WaveFormatEx
.nChannels
= WaveFormat
->nChannels
;
541 Instance
->WaveFormatEx
.nSamplesPerSec
= WaveFormat
->nSamplesPerSec
;
542 Instance
->WaveFormatEx
.nBlockAlign
= WaveFormat
->nBlockAlign
;
543 Instance
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormat
->nAvgBytesPerSec
;
547 Instance
->WaveFormatEx
.cbSize
= sizeof(WAVEFORMATEX
);
548 Instance
->WaveFormatEx
.wBitsPerSample
= (DeviceInfo
.u
.WaveFormatEx
.nAvgBytesPerSec
* 8) / (DeviceInfo
.u
.WaveFormatEx
.nSamplesPerSec
* DeviceInfo
.u
.WaveFormatEx
.nChannels
);
550 /* Store sound device handle instance handle */
551 Instance
->Handle
= (PVOID
)DeviceInfo
.hDevice
;
553 /* Now determine framing requirements */
554 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
556 (LPVOID
) &DeviceInfo
,
557 sizeof(WDMAUD_DEVICE_INFO
),
558 (LPVOID
) &DeviceInfo
,
559 sizeof(WDMAUD_DEVICE_INFO
),
562 if ( MMSUCCESS(Result
) )
564 if (DeviceInfo
.u
.FrameSize
)
566 Instance
->FrameSize
= DeviceInfo
.u
.FrameSize
* 2;
567 Instance
->BufferCount
= WaveFormat
->nAvgBytesPerSec
/ Instance
->FrameSize
;
568 SND_TRACE(L
"FrameSize %u BufferCount %u\n", Instance
->FrameSize
, Instance
->BufferCount
);
573 // use a default of 100 buffers
574 Instance
->BufferCount
= 100;
577 /* Now acquire resources */
578 DeviceInfo
.u
.State
= KSSTATE_ACQUIRE
;
579 SyncOverlappedDeviceIoControl(KernelHandle
, IOCTL_SETDEVICE_STATE
, (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), NULL
);
582 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
583 SyncOverlappedDeviceIoControl(KernelHandle
, IOCTL_SETDEVICE_STATE
, (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), NULL
);
586 DeviceInfo
.u
.State
= KSSTATE_RUN
;
587 SyncOverlappedDeviceIoControl(KernelHandle
, IOCTL_SETDEVICE_STATE
, (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPVOID
) &DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), NULL
);
590 return MMSYSERR_NOERROR
;
595 LegacyCompletionRoutine(
596 IN DWORD dwErrorCode
,
597 IN DWORD dwNumberOfBytesTransferred
,
598 IN LPOVERLAPPED lpOverlapped
)
600 PSOUND_OVERLAPPED Overlap
;
601 PWDMAUD_DEVICE_INFO DeviceInfo
;
603 Overlap
= (PSOUND_OVERLAPPED
)lpOverlapped
;
604 DeviceInfo
= (PWDMAUD_DEVICE_INFO
)Overlap
->CompletionContext
;
606 /* Call mmebuddy overlap routine */
607 Overlap
->OriginalCompletionRoutine(dwErrorCode
, DeviceInfo
->Header
.DataUsed
, lpOverlapped
);
609 HeapFree(GetProcessHeap(), 0, DeviceInfo
);
613 WdmAudCommitWaveBufferByLegacy(
614 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
617 IN PSOUND_OVERLAPPED Overlap
,
618 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
)
622 PWDMAUD_DEVICE_INFO DeviceInfo
;
623 PSOUND_DEVICE SoundDevice
;
624 MMDEVICE_TYPE DeviceType
;
627 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance
);
628 VALIDATE_MMSYS_PARAMETER( OffsetPtr
);
629 VALIDATE_MMSYS_PARAMETER( Overlap
);
630 VALIDATE_MMSYS_PARAMETER( CompletionRoutine
);
632 GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
635 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
637 if ( ! MMSUCCESS(Result
) )
639 return TranslateInternalMmResult(Result
);
642 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
643 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
645 DeviceInfo
= (PWDMAUD_DEVICE_INFO
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(WDMAUD_DEVICE_INFO
));
649 return MMSYSERR_NOMEM
;
652 DeviceInfo
->Header
.FrameExtent
= Length
;
653 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
655 DeviceInfo
->Header
.DataUsed
= Length
;
657 DeviceInfo
->Header
.Data
= OffsetPtr
;
658 DeviceInfo
->Header
.Size
= sizeof(WDMAUD_DEVICE_INFO
);
659 DeviceInfo
->Header
.PresentationTime
.Numerator
= 1;
660 DeviceInfo
->Header
.PresentationTime
.Denominator
= 1;
661 DeviceInfo
->hDevice
= Handle
;
662 DeviceInfo
->DeviceType
= DeviceType
;
665 // create completion event
666 Overlap
->Standard
.hEvent
= Handle
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
667 if (Overlap
->Standard
.hEvent
== NULL
)
670 HeapFree(GetProcessHeap(), 0, DeviceInfo
);
671 return MMSYSERR_NOMEM
;
674 Overlap
->OriginalCompletionRoutine
= CompletionRoutine
;
675 Overlap
->CompletionContext
= (PVOID
)DeviceInfo
;
677 if (DeviceType
== WAVE_OUT_DEVICE_TYPE
)
679 Ret
= WriteFileEx(KernelHandle
, DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, LegacyCompletionRoutine
);
681 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
683 else if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
685 Ret
= ReadFileEx(KernelHandle
, DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
), (LPOVERLAPPED
)Overlap
, LegacyCompletionRoutine
);
687 WaitForSingleObjectEx (KernelHandle
, INFINITE
, TRUE
);
690 // close event handle
693 return MMSYSERR_NOERROR
;
697 WdmAudSetWaveStateByLegacy(
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
;
725 DeviceInfo
.u
.State
= KSSTATE_RUN
;
727 DeviceInfo
.u
.State
= KSSTATE_PAUSE
;
728 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
729 IOCTL_SETDEVICE_STATE
,
730 (LPVOID
) &DeviceInfo
,
731 sizeof(WDMAUD_DEVICE_INFO
),
732 (LPVOID
) &DeviceInfo
,
733 sizeof(WDMAUD_DEVICE_INFO
),
740 WdmAudGetDeviceInterfaceStringByLegacy(
741 IN MMDEVICE_TYPE DeviceType
,
744 IN DWORD InterfaceLength
,
745 OUT DWORD
* InterfaceSize
)
747 WDMAUD_DEVICE_INFO DeviceInfo
;
750 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
751 DeviceInfo
.DeviceType
= DeviceType
;
752 DeviceInfo
.DeviceIndex
= DeviceId
;
755 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
756 IOCTL_QUERYDEVICEINTERFACESTRING
,
757 (LPVOID
) &DeviceInfo
,
758 sizeof(WDMAUD_DEVICE_INFO
),
759 (LPVOID
) &DeviceInfo
,
760 sizeof(WDMAUD_DEVICE_INFO
),
764 if ( ! MMSUCCESS(Result
) )
766 return TranslateInternalMmResult(Result
);
772 SND_ASSERT(InterfaceSize
);
774 *InterfaceSize
= DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
;
775 return MMSYSERR_NOERROR
;
778 if (InterfaceLength
< DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
)
780 /* buffer is too small */
781 return MMSYSERR_MOREDATA
;
784 DeviceInfo
.u
.Interface
.DeviceInterfaceStringSize
= InterfaceLength
;
785 DeviceInfo
.u
.Interface
.DeviceInterfaceString
= Interface
;
787 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
788 IOCTL_QUERYDEVICEINTERFACESTRING
,
789 (LPVOID
) &DeviceInfo
,
790 sizeof(WDMAUD_DEVICE_INFO
),
791 (LPVOID
) &DeviceInfo
,
792 sizeof(WDMAUD_DEVICE_INFO
),
795 if ( MMSUCCESS(Result
) && InterfaceLength
> 2)
797 Interface
[1] = L
'\\';
798 Interface
[InterfaceLength
-1] = L
'\0';
805 WdmAudGetWavePositionByLegacy(
806 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
810 PSOUND_DEVICE SoundDevice
;
811 WDMAUD_DEVICE_INFO DeviceInfo
;
812 MMDEVICE_TYPE DeviceType
;
815 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
817 if ( ! MMSUCCESS(Result
) )
819 return TranslateInternalMmResult(Result
);
822 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
823 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
825 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
826 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
828 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
829 DeviceInfo
.hDevice
= Handle
;
830 DeviceInfo
.DeviceType
= DeviceType
;
832 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
834 (LPVOID
) &DeviceInfo
,
835 sizeof(WDMAUD_DEVICE_INFO
),
836 (LPVOID
) &DeviceInfo
,
837 sizeof(WDMAUD_DEVICE_INFO
),
840 if ( ! MMSUCCESS(Result
) )
842 return TranslateInternalMmResult(Result
);
845 Time
->wType
= TIME_BYTES
;
846 Time
->u
.cb
= (DWORD
)DeviceInfo
.u
.Position
;
848 return MMSYSERR_NOERROR
;
853 WdmAudResetStreamByLegacy(
854 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
855 IN MMDEVICE_TYPE DeviceType
,
856 IN BOOLEAN bStartReset
)
860 WDMAUD_DEVICE_INFO DeviceInfo
;
862 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
863 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
865 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
866 DeviceInfo
.hDevice
= Handle
;
867 DeviceInfo
.DeviceType
= DeviceType
;
868 DeviceInfo
.u
.ResetStream
= (bStartReset
? KSRESET_BEGIN
: KSRESET_END
);
870 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
872 (LPVOID
) &DeviceInfo
,
873 sizeof(WDMAUD_DEVICE_INFO
),
874 (LPVOID
) &DeviceInfo
,
875 sizeof(WDMAUD_DEVICE_INFO
),
881 WdmAudQueryMixerInfoByLegacy(
882 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
889 WDMAUD_DEVICE_INFO DeviceInfo
;
892 LPMIXERLINEW MixLine
;
893 LPMIXERLINECONTROLSW MixControls
;
894 LPMIXERCONTROLDETAILS MixDetails
;
896 SND_TRACE(L
"uMsg %x Flags %x\n", uMsg
, Flags
);
898 Result
= GetSoundDeviceInstanceHandle(SoundDeviceInstance
, &Handle
);
899 SND_ASSERT( Result
== MMSYSERR_NOERROR
);
901 ZeroMemory(&DeviceInfo
, sizeof(WDMAUD_DEVICE_INFO
));
902 DeviceInfo
.hDevice
= Handle
;
903 DeviceInfo
.DeviceIndex
= DeviceId
;
904 DeviceInfo
.DeviceType
= MIXER_DEVICE_TYPE
;
905 DeviceInfo
.Flags
= Flags
;
907 MixLine
= (LPMIXERLINEW
)Parameter
;
908 MixControls
= (LPMIXERLINECONTROLSW
)Parameter
;
909 MixDetails
= (LPMIXERCONTROLDETAILS
)Parameter
;
913 case MXDM_GETLINEINFO
:
914 RtlCopyMemory(&DeviceInfo
.u
.MixLine
, MixLine
, sizeof(MIXERLINEW
));
915 IoControlCode
= IOCTL_GETLINEINFO
;
917 case MXDM_GETLINECONTROLS
:
918 RtlCopyMemory(&DeviceInfo
.u
.MixControls
, MixControls
, sizeof(MIXERLINECONTROLSW
));
919 IoControlCode
= IOCTL_GETLINECONTROLS
;
921 case MXDM_SETCONTROLDETAILS
:
922 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
923 IoControlCode
= IOCTL_SETCONTROLDETAILS
;
925 case MXDM_GETCONTROLDETAILS
:
926 RtlCopyMemory(&DeviceInfo
.u
.MixDetails
, MixDetails
, sizeof(MIXERCONTROLDETAILS
));
927 IoControlCode
= IOCTL_GETCONTROLDETAILS
;
931 return MMSYSERR_NOTSUPPORTED
;
934 Result
= SyncOverlappedDeviceIoControl(KernelHandle
,
936 (LPVOID
) &DeviceInfo
,
937 sizeof(WDMAUD_DEVICE_INFO
),
938 (LPVOID
) &DeviceInfo
,
939 sizeof(WDMAUD_DEVICE_INFO
),
942 if ( ! MMSUCCESS(Result
) )
949 case MXDM_GETLINEINFO
:
951 RtlCopyMemory(MixLine
, &DeviceInfo
.u
.MixLine
, sizeof(MIXERLINEW
));