2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/legacy/wdmaud/wave.c
5 * PURPOSE: Wave Out enumeration
6 * PROGRAMMER: Andrew Greenwood
21 #define AUDIO_TEST_RANGE (5)
23 static AUDIO_RANGE TestRange
[AUDIO_TEST_RANGE
] =
65 /* allocate wav info */
66 LPWAVE_INFO WaveOutInfo
= ExAllocatePool(NonPagedPool
, sizeof(WAVE_INFO
));
70 /* zero wave info struct */
71 RtlZeroMemory(WaveOutInfo
, sizeof(WAVE_INFO
));
80 PKSPIN_CONNECT Connect
= ExAllocatePool(NonPagedPool
, sizeof(KSPIN_CONNECT
) + DataFormatSize
);
84 /* zero pin connect struct */
85 RtlZeroMemory(Connect
, sizeof(KSPIN_CONNECT
) + DataFormatSize
);
91 GetWaveInfoByIndexAndType(
92 IN PDEVICE_OBJECT DeviceObject
,
94 IN SOUND_DEVICE_TYPE DeviceType
,
95 OUT LPWAVE_INFO
*OutWaveInfo
)
97 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
99 PLIST_ENTRY Entry
, ListHead
;
100 LPWAVE_INFO WaveInfo
;
102 /* get device extension */
103 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
105 if (DeviceType
== WAVE_IN_DEVICE_TYPE
)
106 ListHead
= &DeviceExtension
->WaveInList
;
108 ListHead
= &DeviceExtension
->WaveOutList
;
110 /* get first entry */
111 Entry
= ListHead
->Flink
;
113 while(Entry
!= ListHead
)
115 WaveInfo
= (LPWAVE_INFO
)CONTAINING_RECORD(Entry
, WAVE_INFO
, Entry
);
117 if (Index
== DeviceIndex
)
119 *OutWaveInfo
= WaveInfo
;
120 return STATUS_SUCCESS
;
123 Entry
= Entry
->Flink
;
126 return STATUS_NOT_FOUND
;
131 InitializePinConnect(
132 IN OUT PKSPIN_CONNECT PinConnect
,
135 PinConnect
->Interface
.Set
= KSINTERFACESETID_Standard
;
136 PinConnect
->Interface
.Id
= KSINTERFACE_STANDARD_STREAMING
;
137 PinConnect
->Interface
.Flags
= 0;
138 PinConnect
->Medium
.Set
= KSMEDIUMSETID_Standard
;
139 PinConnect
->Medium
.Id
= KSMEDIUM_TYPE_ANYINSTANCE
;
140 PinConnect
->Medium
.Flags
= 0;
141 PinConnect
->PinToHandle
= NULL
;
142 PinConnect
->PinId
= PinId
;
143 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
144 PinConnect
->Priority
.PrioritySubClass
= 1;
148 InitializeDataFormat(
149 IN PKSDATAFORMAT_WAVEFORMATEX DataFormat
,
150 LPWAVEFORMATEX WaveFormatEx
)
153 DataFormat
->WaveFormatEx
.wFormatTag
= WaveFormatEx
->wFormatTag
;
154 DataFormat
->WaveFormatEx
.nChannels
= WaveFormatEx
->nChannels
;
155 DataFormat
->WaveFormatEx
.nSamplesPerSec
= WaveFormatEx
->nSamplesPerSec
;
156 DataFormat
->WaveFormatEx
.nBlockAlign
= WaveFormatEx
->nBlockAlign
;
157 DataFormat
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormatEx
->nAvgBytesPerSec
;
158 DataFormat
->WaveFormatEx
.wBitsPerSample
= WaveFormatEx
->wBitsPerSample
;
159 DataFormat
->WaveFormatEx
.cbSize
= 0;
160 DataFormat
->DataFormat
.FormatSize
= sizeof(KSDATAFORMAT
) + sizeof(WAVEFORMATEX
);
161 DataFormat
->DataFormat
.Flags
= 0;
162 DataFormat
->DataFormat
.Reserved
= 0;
163 DataFormat
->DataFormat
.MajorFormat
= KSDATAFORMAT_TYPE_AUDIO
;
165 DataFormat
->DataFormat
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
166 DataFormat
->DataFormat
.Specifier
= KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
;
167 DataFormat
->DataFormat
.SampleSize
= 4;
172 AttachToVirtualAudioDevice(
173 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
,
174 IN ULONG VirtualDeviceId
)
177 SYSAUDIO_INSTANCE_INFO InstanceInfo
;
179 /* setup property request */
180 InstanceInfo
.Property
.Set
= KSPROPSETID_Sysaudio
;
181 InstanceInfo
.Property
.Id
= KSPROPERTY_SYSAUDIO_INSTANCE_INFO
;
182 InstanceInfo
.Property
.Flags
= KSPROPERTY_TYPE_SET
;
183 InstanceInfo
.Flags
= 0;
184 InstanceInfo
.DeviceNumber
= VirtualDeviceId
;
186 /* attach to virtual device */
187 return KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&InstanceInfo
, sizeof(SYSAUDIO_INSTANCE_INFO
), NULL
, 0, &BytesReturned
);
192 GetAudioPinDataRanges(
193 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
,
196 IN OUT PKSMULTIPLE_ITEM
* OutMultipleItem
)
199 ULONG BytesReturned
= 0;
201 PKSMULTIPLE_ITEM MultipleItem
;
203 /* retrieve size of data ranges buffer */
204 PinProperty
.Reserved
= FilterId
;
205 PinProperty
.PinId
= PinId
;
206 PinProperty
.Property
.Set
= KSPROPSETID_Pin
;
207 PinProperty
.Property
.Id
= KSPROPERTY_PIN_DATARANGES
;
208 PinProperty
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
210 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinProperty
, sizeof(KSP_PIN
), (PVOID
)NULL
, 0, &BytesReturned
);
211 if (Status
!= STATUS_MORE_ENTRIES
)
216 MultipleItem
= ExAllocatePool(NonPagedPool
, BytesReturned
);
219 /* not enough memory */
220 return STATUS_INSUFFICIENT_RESOURCES
;
223 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinProperty
, sizeof(KSP_PIN
), (PVOID
)MultipleItem
, BytesReturned
, &BytesReturned
);
224 if (!NT_SUCCESS(Status
))
227 ExFreePool(MultipleItem
);
232 *OutMultipleItem
= MultipleItem
;
238 PKSMULTIPLE_ITEM MultipleItem
,
239 PKSDATARANGE_AUDIO
* OutDataRangeAudio
)
242 PKSDATARANGE_AUDIO DataRangeAudio
;
243 PKSDATARANGE DataRange
;
245 DataRange
= (PKSDATARANGE
) (MultipleItem
+ 1);
246 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
248 if (DataRange
->FormatSize
== sizeof(KSDATARANGE_AUDIO
))
250 DataRangeAudio
= (PKSDATARANGE_AUDIO
)DataRange
;
251 if (IsEqualGUIDAligned(&DataRangeAudio
->DataRange
.MajorFormat
, &KSDATAFORMAT_TYPE_AUDIO
) &&
252 IsEqualGUIDAligned(&DataRangeAudio
->DataRange
.SubFormat
, &KSDATAFORMAT_SUBTYPE_PCM
) &&
253 IsEqualGUIDAligned(&DataRangeAudio
->DataRange
.Specifier
, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
))
255 DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u\n", DataRangeAudio
->MinimumSampleFrequency
, DataRangeAudio
->MaximumSampleFrequency
,
256 DataRangeAudio
->MinimumBitsPerSample
, DataRangeAudio
->MaximumBitsPerSample
, DataRangeAudio
->MaximumChannels
);
257 *OutDataRangeAudio
= DataRangeAudio
;
258 return STATUS_SUCCESS
;
262 return STATUS_UNSUCCESSFUL
;
268 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
,
271 IN LPWAVEFORMATEX WaveFormatEx
,
272 IN ACCESS_MASK DesiredAccess
,
273 OUT PHANDLE PinHandle
)
275 PKSPIN_CONNECT PinConnect
;
276 PKSDATAFORMAT_WAVEFORMATEX DataFormat
;
279 /* allocate pin connect */
280 PinConnect
= AllocatePinConnect(sizeof(KSDATAFORMAT_WAVEFORMATEX
));
284 return STATUS_INSUFFICIENT_RESOURCES
;
287 /* initialize pin connect struct */
288 InitializePinConnect(PinConnect
, PinId
);
290 /* get offset to dataformat */
291 DataFormat
= (PKSDATAFORMAT_WAVEFORMATEX
) (PinConnect
+ 1);
292 /* initialize with requested wave format */
293 InitializeDataFormat(DataFormat
, WaveFormatEx
);
295 /* first attach to the virtual device */
296 Status
= AttachToVirtualAudioDevice(DeviceExtension
, FilterId
);
298 if (!NT_SUCCESS(Status
))
301 ExFreePool(PinConnect
);
305 /* now create the pin */
306 Status
= KsCreatePin(DeviceExtension
->hSysAudio
, PinConnect
, DesiredAccess
, PinHandle
);
308 /* free create info */
309 ExFreePool(PinConnect
);
316 PWDMAUD_DEVICE_EXTENSION DeviceExtension
,
321 KSPIN_CINSTANCES PinInstances
;
325 /* query the instance count */
326 PinRequest
.Reserved
= FilterId
;
327 PinRequest
.PinId
= PinId
;
328 PinRequest
.Property
.Set
= KSPROPSETID_Pin
;
329 PinRequest
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
330 PinRequest
.Property
.Id
= KSPROPERTY_PIN_CINSTANCES
;
332 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinRequest
, sizeof(KSP_PIN
), (PVOID
)&PinInstances
, sizeof(KSPIN_CINSTANCES
), &BytesReturned
);
333 ASSERT(Status
== STATUS_SUCCESS
);
334 return PinInstances
.CurrentCount
;
340 PWDMAUD_DEVICE_EXTENSION DeviceExtension
,
341 LPWAVE_INFO WaveInfo
,
346 NTSTATUS Status
= STATUS_SUCCESS
;
349 WAVEFORMATEX WaveFormat
;
352 /* clear wave format */
353 RtlZeroMemory(&WaveFormat
, sizeof(WAVEFORMATEX
));
355 WaveFormat
.wFormatTag
= WAVE_FORMAT_PCM
;
356 WaveFormat
.nChannels
= NumChannels
;
357 WaveFormat
.nSamplesPerSec
= SampleRate
;
358 WaveFormat
.nAvgBytesPerSec
= SampleRate
* NumChannels
* (BitsPerSample
/8);
359 WaveFormat
.nBlockAlign
= (NumChannels
* BitsPerSample
) / 8;
360 WaveFormat
.wBitsPerSample
= BitsPerSample
;
361 WaveFormat
.cbSize
= sizeof(WAVEFORMATEX
);
363 Status
= OpenWavePin(DeviceExtension
, WaveInfo
->FilterId
, WaveInfo
->PinId
, &WaveFormat
, GENERIC_READ
| GENERIC_WRITE
, &PinHandle
);
365 if (NT_SUCCESS(Status
))
370 while(GetPinInstanceCount(DeviceExtension
, WaveInfo
->FilterId
, WaveInfo
->PinId
))
371 KeStallExecutionProcessor(5);
374 DPRINT("SampleRate %u BitsPerSample %u NumChannels %u Status %x bInput %u\n", SampleRate
, BitsPerSample
, NumChannels
, Status
, WaveInfo
->bInput
);
384 PWDMAUD_DEVICE_EXTENSION DeviceExtension
,
385 PKSDATARANGE_AUDIO DataRangeAudio
,
386 LPWAVE_INFO WaveInfo
)
388 ULONG Index
, SampleFrequency
;
392 for(Index
= 0; Index
< AUDIO_TEST_RANGE
; Index
++)
394 SampleFrequency
= TestRange
[Index
].SampleRate
;
396 if (DataRangeAudio
->MinimumSampleFrequency
<= SampleFrequency
&& DataRangeAudio
->MaximumSampleFrequency
>= SampleFrequency
)
398 /* the audio adapter supports the sample frequency */
399 if (DataRangeAudio
->MinimumBitsPerSample
<= 8 && DataRangeAudio
->MaximumBitsPerSample
>= 8)
401 /* check if pin supports the sample rate in 8-Bit Mono */
402 Status
= CheckSampleFormat(DeviceExtension
, WaveInfo
, SampleFrequency
, 1, 8);
403 if (NT_SUCCESS(Status
))
405 Result
|= TestRange
[Index
].Bit8Mono
;
408 if (DataRangeAudio
->MaximumChannels
> 1)
410 /* check if pin supports the sample rate in 8-Bit Stereo */
411 Status
= CheckSampleFormat(DeviceExtension
, WaveInfo
, SampleFrequency
, 2, 8);
412 if (NT_SUCCESS(Status
))
414 Result
|= TestRange
[Index
].Bit8Stereo
;
419 if (DataRangeAudio
->MinimumBitsPerSample
<= 16 && DataRangeAudio
->MaximumBitsPerSample
>= 16)
421 /* check if pin supports the sample rate in 16-Bit Mono */
422 Status
= CheckSampleFormat(DeviceExtension
, WaveInfo
, SampleFrequency
, 1, 16);
423 if (NT_SUCCESS(Status
))
425 Result
|= TestRange
[Index
].Bit16Mono
;
428 if (DataRangeAudio
->MaximumChannels
> 1)
430 /* check if pin supports the sample rate in 16-Bit Stereo */
431 Status
= CheckSampleFormat(DeviceExtension
, WaveInfo
, SampleFrequency
, 2, 16);
432 if (NT_SUCCESS(Status
))
434 Result
|= TestRange
[Index
].Bit16Stereo
;
442 if (WaveInfo
->bInput
)
443 WaveInfo
->u
.InCaps
.dwFormats
= Result
;
445 WaveInfo
->u
.OutCaps
.dwFormats
= Result
;
447 DPRINT("Format %x bInput %u\n", Result
, WaveInfo
->bInput
);
450 return STATUS_SUCCESS
;
455 IN PDEVICE_OBJECT DeviceObject
,
461 KSCOMPONENTID ComponentId
;
464 WCHAR DeviceName
[MAX_PATH
];
465 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
466 PKSMULTIPLE_ITEM MultipleItem
;
467 PKSDATARANGE_AUDIO DataRangeAudio
;
468 LPWAVE_INFO WaveInfo
= AllocateWaveInfo();
472 return STATUS_INSUFFICIENT_RESOURCES
;
474 /* initialize wave info */
475 WaveInfo
->bInput
= bInput
;
476 WaveInfo
->FilterId
= FilterId
;
477 WaveInfo
->PinId
= PinId
;
479 /* setup request to return component id */
480 PinProperty
.PinId
= FilterId
;
481 PinProperty
.Property
.Set
= KSPROPSETID_Sysaudio
;
482 PinProperty
.Property
.Id
= KSPROPERTY_SYSAUDIO_COMPONENT_ID
;
483 PinProperty
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
485 /* get device extension */
486 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
488 /* query sysaudio for component id */
489 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinProperty
, sizeof(KSP_PIN
), (PVOID
)&ComponentId
, sizeof(KSCOMPONENTID
), &BytesReturned
);
490 if (NT_SUCCESS(Status
))
494 WaveInfo
->u
.InCaps
.wMid
= ComponentId
.Manufacturer
.Data1
- 0xd5a47fa7;
495 WaveInfo
->u
.InCaps
.vDriverVersion
= MAKELONG(ComponentId
.Version
, ComponentId
.Revision
);
499 WaveInfo
->u
.OutCaps
.wMid
= ComponentId
.Manufacturer
.Data1
- 0xd5a47fa7;
500 WaveInfo
->u
.OutCaps
.vDriverVersion
= MAKELONG(ComponentId
.Version
, ComponentId
.Revision
);
505 /* set up something useful */
508 WaveInfo
->u
.InCaps
.wMid
= MM_MICROSOFT
;
509 WaveInfo
->u
.InCaps
.wPid
= MM_PID_UNMAPPED
;
510 WaveInfo
->u
.InCaps
.vDriverVersion
= 1;
514 WaveInfo
->u
.OutCaps
.wMid
= MM_MICROSOFT
;
515 WaveInfo
->u
.OutCaps
.wPid
= MM_PID_UNMAPPED
;
516 WaveInfo
->u
.OutCaps
.vDriverVersion
= 1;
520 /* retrieve pnp base name */
521 PinProperty
.PinId
= FilterId
;
522 PinProperty
.Property
.Set
= KSPROPSETID_Sysaudio
;
523 PinProperty
.Property
.Id
= KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME
;
524 PinProperty
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
526 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinProperty
, sizeof(KSP_PIN
), (PVOID
)DeviceName
, sizeof(DeviceName
), &BytesReturned
);
527 if (NT_SUCCESS(Status
))
529 /* find product name */
531 Status
= FindProductName(DeviceName
, MAXPNAMELEN
, WaveInfo
->u
.OutCaps
.szPname
);
533 Status
= FindProductName(DeviceName
, MAXPNAMELEN
, WaveInfo
->u
.InCaps
.szPname
);
535 /* check for success */
536 if (!NT_SUCCESS(Status
))
539 WaveInfo
->u
.OutCaps
.szPname
[0] = L
'\0';
541 WaveInfo
->u
.InCaps
.szPname
[0] = L
'\0';
545 Status
= GetAudioPinDataRanges(DeviceExtension
, FilterId
, PinId
, &MultipleItem
);
546 if (NT_SUCCESS(Status
))
548 /* find a audio data range */
549 Status
= FindAudioDataRange(MultipleItem
, &DataRangeAudio
);
551 if (NT_SUCCESS(Status
))
555 WaveInfo
->u
.InCaps
.wChannels
= DataRangeAudio
->MaximumChannels
;
559 WaveInfo
->u
.OutCaps
.wChannels
= DataRangeAudio
->MaximumChannels
;
561 CheckFormat(DeviceExtension
, DataRangeAudio
, WaveInfo
);
563 ExFreePool(MultipleItem
);
568 InsertTailList(&DeviceExtension
->WaveInList
, &WaveInfo
->Entry
);
569 DeviceExtension
->WaveInDeviceCount
++;
573 InsertTailList(&DeviceExtension
->WaveOutList
, &WaveInfo
->Entry
);
574 DeviceExtension
->WaveOutDeviceCount
++;
578 return STATUS_SUCCESS
;
584 WdmAudWaveInitialize(
585 IN PDEVICE_OBJECT DeviceObject
)
588 ULONG Count
, BytesReturned
, Index
, SubIndex
, Result
, NumPins
;
590 KSPIN_COMMUNICATION Communication
;
591 KSPIN_DATAFLOW DataFlow
;
592 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
594 Pin
.Property
.Set
= KSPROPSETID_Sysaudio
;
595 Pin
.Property
.Id
= KSPROPERTY_SYSAUDIO_DEVICE_COUNT
;
596 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
598 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
600 /* set wave count to zero */
601 DeviceExtension
->WaveInDeviceCount
= 0;
602 DeviceExtension
->WaveOutDeviceCount
= 0;
604 /* intialize list head */
605 InitializeListHead(&DeviceExtension
->WaveInList
);
606 InitializeListHead(&DeviceExtension
->WaveOutList
);
608 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSPROPERTY
), (PVOID
)&Count
, sizeof(ULONG
), &BytesReturned
);
609 if (!NT_SUCCESS(Status
))
610 return STATUS_UNSUCCESSFUL
;
613 for(Index
= 0; Index
< Count
; Index
++)
615 /* query number of pins */
616 Pin
.Reserved
= Index
; // see sysaudio
617 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
618 Pin
.Property
.Set
= KSPROPSETID_Pin
;
619 Pin
.Property
.Id
= KSPROPERTY_PIN_CTYPES
;
622 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&NumPins
, sizeof(ULONG
), &BytesReturned
);
623 if (NT_SUCCESS(Status
))
625 /* enumerate now all pins */
626 for(SubIndex
= 0; SubIndex
< NumPins
; SubIndex
++)
628 Pin
.PinId
= SubIndex
;
629 Pin
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
630 Communication
= KSPIN_COMMUNICATION_NONE
;
632 /* get pin communication type */
633 KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&Communication
, sizeof(KSPIN_COMMUNICATION
), &BytesReturned
);
635 Pin
.Property
.Id
= KSPROPERTY_PIN_DATAFLOW
;
638 /* get pin dataflow type */
639 KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&DataFlow
, sizeof(KSPIN_DATAFLOW
), &BytesReturned
);
641 if (Communication
== KSPIN_COMMUNICATION_SINK
&& DataFlow
== KSPIN_DATAFLOW_IN
)
643 /* found a wave out device */
644 InitializeWaveInfo(DeviceObject
, Index
, SubIndex
, FALSE
);
646 else if (Communication
== KSPIN_COMMUNICATION_SINK
&& DataFlow
== KSPIN_DATAFLOW_OUT
)
648 /* found a wave in device */
649 InitializeWaveInfo(DeviceObject
, Index
, SubIndex
, TRUE
);
655 return STATUS_SUCCESS
;
659 WdmAudControlOpenWave(
660 IN PDEVICE_OBJECT DeviceObject
,
662 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
663 IN PWDMAUD_CLIENT ClientInfo
)
665 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
666 LPWAVE_INFO WaveInfo
;
668 ACCESS_MASK DesiredAccess
= 0;
672 if (DeviceInfo
->u
.WaveFormatEx
.wFormatTag
!= WAVE_FORMAT_PCM
)
674 DPRINT("FIXME: Only WAVE_FORMAT_PCM is supported RequestFormat %x\n", DeviceInfo
->u
.WaveFormatEx
.wFormatTag
);
675 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
678 /* get device extension */
679 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
681 /* find destination wave */
682 Status
= GetWaveInfoByIndexAndType(DeviceObject
, DeviceInfo
->DeviceIndex
, DeviceInfo
->DeviceType
, &WaveInfo
);
683 if (!NT_SUCCESS(Status
))
685 /* failed to find wave info */
687 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
690 /* close pin handle which uses same virtual audio device id and pin id */
691 FreeIndex
= ClosePin(ClientInfo
, WaveInfo
->FilterId
, WaveInfo
->PinId
, DeviceInfo
->DeviceType
);
693 /* get desired access */
694 if (DeviceInfo
->DeviceType
== WAVE_IN_DEVICE_TYPE
)
696 DesiredAccess
|= GENERIC_READ
;
698 else if (DeviceInfo
->DeviceType
== WAVE_OUT_DEVICE_TYPE
)
700 DesiredAccess
|= GENERIC_WRITE
;
703 /* now try open the pin */
704 Status
= OpenWavePin(DeviceExtension
, WaveInfo
->FilterId
, WaveInfo
->PinId
, &DeviceInfo
->u
.WaveFormatEx
, DesiredAccess
, &PinHandle
);
706 if (!NT_SUCCESS(Status
))
708 /* failed to open the pin */
709 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
712 /* store the handle */
713 Status
= InsertPinHandle(ClientInfo
, WaveInfo
->FilterId
, WaveInfo
->PinId
, DeviceInfo
->DeviceType
, PinHandle
, FreeIndex
);
714 if (!NT_SUCCESS(Status
))
716 /* failed to insert handle */
718 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
721 /* store pin handle */
722 DeviceInfo
->hDevice
= PinHandle
;
723 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
727 WdmAudWaveCapabilities(
728 IN PDEVICE_OBJECT DeviceObject
,
729 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
730 IN PWDMAUD_CLIENT ClientInfo
,
731 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension
)
733 LPWAVE_INFO WaveInfo
;
736 /* find destination wave */
737 Status
= GetWaveInfoByIndexAndType(DeviceObject
, DeviceInfo
->DeviceIndex
, DeviceInfo
->DeviceType
, &WaveInfo
);
738 if (!NT_SUCCESS(Status
))
740 /* failed to find wave info */
742 return STATUS_UNSUCCESSFUL
;
745 if (DeviceInfo
->DeviceType
== WAVE_IN_DEVICE_TYPE
)
747 RtlMoveMemory(&DeviceInfo
->u
.WaveInCaps
, &WaveInfo
->u
.InCaps
, sizeof(WAVEINCAPSW
));
751 RtlMoveMemory(&DeviceInfo
->u
.WaveOutCaps
, &WaveInfo
->u
.OutCaps
, sizeof(WAVEOUTCAPSW
));
754 return STATUS_SUCCESS
;