const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
+const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
-NTSTATUS
-SetIrpIoStatus(
- IN PIRP Irp,
- IN NTSTATUS Status,
- IN ULONG Length)
-{
- Irp->IoStatus.Information = Length;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-
-}
-
-NTSTATUS
-GetFilterIdAndPinId(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo,
- IN PULONG FilterId,
- IN PULONG PinId)
-{
- KSP_PIN Pin;
- ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
- NTSTATUS Status;
- KSPIN_COMMUNICATION Communication;
- KSPIN_DATAFLOW DataFlow;
-
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
- {
- DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
- return STATUS_UNSUCCESSFUL;
- }
-
- Pin.Property.Set = KSPROPSETID_Sysaudio;
- Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
- if (!NT_SUCCESS(Status))
- return STATUS_UNSUCCESSFUL;
-
- Result = 0;
- for(Index = 0; Index < Count; Index++)
- {
- /* query number of pins */
- Pin.Reserved = Index; // see sysaudio
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
- Pin.Property.Set = KSPROPSETID_Pin;
- Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
- Pin.PinId = 0;
-
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned);
- if (NT_SUCCESS(Status))
- {
- /* enumerate now all pins */
- for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
- {
- Pin.PinId = SubIndex;
- Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
- Communication = KSPIN_COMMUNICATION_NONE;
-
- /* get pin communication type */
- KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
-
- Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
- DataFlow = 0;
-
- /* get pin dataflow type */
- KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
-
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
- {
- if(DeviceInfo->DeviceIndex == Result)
- {
- /* found the index */
- *FilterId = Index;
- *PinId = SubIndex;
- return STATUS_SUCCESS;
- }
-
- Result++;
- }
- }
- else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
- {
- if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
- {
- if(DeviceInfo->DeviceIndex == Result)
- {
- /* found the index */
- *FilterId = Index;
- *PinId = SubIndex;
- return STATUS_SUCCESS;
- }
- Result++;
- }
- }
- }
- }
- }
-
- return STATUS_UNSUCCESSFUL;
-}
NTSTATUS
WdmAudControlOpen(
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo)
{
- PSYSAUDIO_INSTANCE_INFO InstanceInfo;
- ULONG BytesReturned;
- NTSTATUS Status;
- ACCESS_MASK DesiredAccess = 0;
- HANDLE PinHandle;
- KSPIN_CONNECT * PinConnect;
- ULONG Length, Index;
- KSDATAFORMAT_WAVEFORMATEX * DataFormat;
- ULONG FilterId;
- ULONG PinId;
-
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
- {
- DPRINT1("FIXME: only waveout / wavein devices are supported\n");
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
- Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid device index %u\n", DeviceInfo->DeviceIndex);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
- Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
- InstanceInfo = ExAllocatePool(NonPagedPool, Length);
- if (!InstanceInfo)
- {
- /* no memory */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
-
- InstanceInfo->Property.Set = KSPROPSETID_Sysaudio;
- InstanceInfo->Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO;
- InstanceInfo->Property.Flags = KSPROPERTY_TYPE_SET;
- InstanceInfo->Flags = 0;
- InstanceInfo->DeviceNumber = FilterId;
-
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned);
-
- if (!NT_SUCCESS(Status))
- {
- /* failed to acquire audio device */
- DPRINT1("KsSynchronousIoControlDevice failed with %x\n", Status);
- ExFreePool(InstanceInfo);
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+ if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
- DesiredAccess |= GENERIC_READ;
+ return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo);
}
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE ||
- DeviceInfo->DeviceType == AUX_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+ if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
{
- DesiredAccess |= GENERIC_WRITE;
+ return WdmAudControlOpenWave(DeviceObject, Irp, DeviceInfo, ClientInfo);
}
- PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1);
-
-
- PinConnect->Interface.Set = KSINTERFACESETID_Standard;
- PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING;
- PinConnect->Interface.Flags = 0;
- PinConnect->Medium.Set = KSMEDIUMSETID_Standard;
- PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
- PinConnect->Medium.Flags = 0;
- PinConnect->PinId = PinId;
- PinConnect->PinToHandle = ClientInfo->hSysAudio;
- PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
- PinConnect->Priority.PrioritySubClass = 1;
-
-
- DataFormat = (KSDATAFORMAT_WAVEFORMATEX*) (PinConnect + 1);
- DataFormat->WaveFormatEx.wFormatTag = DeviceInfo->u.WaveFormatEx.wFormatTag;
- DataFormat->WaveFormatEx.nChannels = DeviceInfo->u.WaveFormatEx.nChannels;
- DataFormat->WaveFormatEx.nSamplesPerSec = DeviceInfo->u.WaveFormatEx.nSamplesPerSec;
- DataFormat->WaveFormatEx.nBlockAlign = DeviceInfo->u.WaveFormatEx.nBlockAlign;
- DataFormat->WaveFormatEx.nAvgBytesPerSec = DeviceInfo->u.WaveFormatEx.nAvgBytesPerSec;
- DataFormat->WaveFormatEx.wBitsPerSample = DeviceInfo->u.WaveFormatEx.wBitsPerSample;
- DataFormat->WaveFormatEx.cbSize = 0;
- DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
- DataFormat->DataFormat.Flags = 0;
- DataFormat->DataFormat.Reserved = 0;
- DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
-
- if (DeviceInfo->u.WaveFormatEx.wFormatTag != WAVE_FORMAT_PCM)
- DPRINT1("FIXME\n");
-
- DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
- DataFormat->DataFormat.SampleSize = 4;
-
- /* ros specific pin creation request */
- InstanceInfo->Property.Id = (ULONG)-1;
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned);
- if (NT_SUCCESS(Status))
- {
- PHANDLE Handels;
-
- for(Index = 0; Index < ClientInfo->NumPins; Index++)
- {
- if (ClientInfo->hPins[Index] == PinHandle)
- {
- /* the pin handle has been re-used */
- DeviceInfo->hDevice = PinHandle;
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
- }
-
- }
-
- Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumPins+1));
-
- if (Handels)
- {
- if (ClientInfo->NumPins)
- {
- RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(HANDLE) * ClientInfo->NumPins);
- ExFreePool(ClientInfo->hPins);
- }
-
- ClientInfo->hPins = Handels;
- ClientInfo->hPins[ClientInfo->NumPins] = PinHandle;
- ClientInfo->NumPins++;
- }
- DeviceInfo->hDevice = PinHandle;
- }
- else
- {
- DeviceInfo->hDevice = NULL;
- }
-
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
}
NTSTATUS
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo)
{
- KSP_PIN Pin;
- ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
- NTSTATUS Status;
- KSPIN_COMMUNICATION Communication;
- KSPIN_DATAFLOW DataFlow;
+ ULONG Result = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
- DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ Result = DeviceExtension->MixerInfoCount;
}
-
- Pin.Property.Set = KSPROPSETID_Sysaudio;
- Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
- if (!NT_SUCCESS(Status))
+ else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
{
- DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ Result = DeviceExtension->WaveOutDeviceCount;
}
- Result = 0;
- /* now enumerate all available filters */
- for(Index = 0; Index < Count; Index++)
+ else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
{
- /* query number of pins */
- Pin.Reserved = Index; // see sysaudio
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
- Pin.Property.Set = KSPROPSETID_Pin;
- Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
- Pin.PinId = 0;
-
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned);
- if (NT_SUCCESS(Status))
- {
- /* enumerate now all pins */
- for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
- {
- Pin.PinId = SubIndex;
- Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
- Communication = KSPIN_COMMUNICATION_NONE;
-
- /* get pin communication type */
- KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
-
- Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
- DataFlow = 0;
-
- /* get pin dataflow type */
- KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
-
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
- Result++;
- }
- else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
- {
- if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
- Result++;
- }
- }
- }
+ Result = DeviceExtension->WaveInDeviceCount;
}
+ /* store result count */
+ DeviceInfo->DeviceCount = Result;
- if (NT_SUCCESS(Status))
- DeviceInfo->DeviceCount = Result;
- else
- DeviceInfo->DeviceCount = 0;
-
- DPRINT1("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ DPRINT("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
}
NTSTATUS
ULONG BytesReturned;
PFILE_OBJECT FileObject;
- //DPRINT1("WdmAudControlDeviceState\n");
+ DPRINT("WdmAudControlDeviceState\n");
Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Error: invalid device handle provided %p\n", DeviceInfo->hDevice);
+ DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
}
Property.Id = KSPROPERTY_CONNECTION_STATE;
Property.Flags = KSPROPERTY_TYPE_SET;
- State = DeviceInfo->State;
+ State = DeviceInfo->u.State;
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesReturned);
ObDereferenceObject(FileObject);
- //DPRINT1("WdmAudControlDeviceState Status %x\n", Status);
+ DPRINT("WdmAudControlDeviceState Status %x\n", Status);
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
NTSTATUS
-NTAPI
-WdmAudWriteCompleted(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Ctx)
+WdmAudCapabilities(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo)
{
- PWRITE_CONTEXT Context = (PWRITE_CONTEXT)Ctx;
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ DPRINT("WdmAudCapabilities entered\n");
- Context->Irp->IoStatus.Information = Context->Length;
- Context->Irp->IoStatus.Status = Irp->IoStatus.Status;
- IoCompleteRequest(Context->Irp, IO_SOUND_INCREMENT);
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- ExFreePool(Context);
- return STATUS_SUCCESS;
+ if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+ {
+ Status = WdmAudMixerCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
+ }
+ else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ Status = WdmAudWaveCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
+ }
+
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
-ULONG
-CheckFormatSupport(
- IN PKSDATARANGE_AUDIO DataRangeAudio,
- ULONG SampleFrequency,
- ULONG Mono8Bit,
- ULONG Stereo8Bit,
- ULONG Mono16Bit,
- ULONG Stereo16Bit)
+NTSTATUS
+NTAPI
+WdmAudIoctlClose(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo)
{
- ULONG Result = 0;
+ ULONG Index;
- if (DataRangeAudio->MinimumSampleFrequency <= SampleFrequency && DataRangeAudio->MaximumSampleFrequency >= SampleFrequency)
+ for(Index = 0; Index < ClientInfo->NumPins; Index++)
{
- if (DataRangeAudio->MinimumBitsPerSample <= 8 && DataRangeAudio->MaximumBitsPerSample >= 8)
+ if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
{
- Result |= Mono8Bit;
- if (DataRangeAudio->MaximumChannels >= 2)
- {
- Result |= Stereo8Bit;
- }
+ DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
+ ZwClose(DeviceInfo->hDevice);
+ ClientInfo->hPins[Index].Handle = NULL;
+ SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+ return STATUS_SUCCESS;
}
-
- if (DataRangeAudio->MinimumBitsPerSample <= 16 && DataRangeAudio->MaximumBitsPerSample >= 16)
+ else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
{
- Result |= Mono16Bit;
- if (DataRangeAudio->MaximumChannels >= 2)
+ if (ClientInfo->hPins[Index].NotifyEvent)
{
- Result |= Stereo8Bit;
- }
+ ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent);
+ ClientInfo->hPins[Index].NotifyEvent = NULL;
+ }
}
}
- return Result;
+ SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
+ return STATUS_INVALID_PARAMETER;
}
NTSTATUS
-WdmAudCapabilities(
+NTAPI
+WdmAudFrameSize(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo)
{
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- KSP_PIN PinProperty;
- KSCOMPONENTID ComponentId;
- KSMULTIPLE_ITEM * MultipleItem;
+ PFILE_OBJECT FileObject;
+ KSPROPERTY Property;
ULONG BytesReturned;
- PKSDATARANGE_AUDIO DataRangeAudio;
- PKSDATARANGE DataRange;
- ULONG Index;
- ULONG wChannels = 0;
- ULONG dwFormats = 0;
- ULONG dwSupport = 0;
- ULONG FilterId;
- ULONG PinId;
-
- DPRINT("WdmAudCapabilities entered\n");
+ KSALLOCATOR_FRAMING Framing;
+ NTSTATUS Status;
- Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
+ /* Get sysaudio pin file object */
+ Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Invalid device index provided %u\n", DeviceInfo->DeviceIndex);
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+ DPRINT1("Invalid buffer handle %p\n", DeviceInfo->hDevice);
+ return SetIrpIoStatus(Irp, Status, 0);
}
- PinProperty.PinId = FilterId;
- PinProperty.Property.Set = KSPROPSETID_Sysaudio;
- PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_COMPONENT_ID;
- PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
-
- RtlZeroMemory(&ComponentId, sizeof(KSCOMPONENTID));
+ /* Setup get framing request */
+ Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+ Property.Set = KSPROPSETID_Connection;
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned);
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
+ /* Did we succeed */
if (NT_SUCCESS(Status))
{
- DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7;
- DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version, ComponentId.Revision);
+ /* Store framesize */
+ DeviceInfo->u.FrameSize = Framing.FrameSize;
}
- PinProperty.Reserved = DeviceInfo->DeviceIndex;
- PinProperty.PinId = PinId;
- PinProperty.Property.Set = KSPROPSETID_Pin;
- PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES;
- PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
+ /* Release file object */
+ ObDereferenceObject(FileObject);
- BytesReturned = 0;
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned);
- if (Status != STATUS_BUFFER_TOO_SMALL)
- {
- return SetIrpIoStatus(Irp, Status, 0);
- }
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
- MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
- if (!MultipleItem)
- {
- /* no memory */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
+}
- Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(MultipleItem);
- return SetIrpIoStatus(Irp, Status, 0);
- }
+NTSTATUS
+NTAPI
+WdmAudGetDeviceInterface(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo)
+{
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
+ LPWSTR Device;
+ LPWAVE_INFO WaveInfo;
+ ULONG Size, Length;
+
+ /* get device extension */
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- DataRange = (PKSDATARANGE) (MultipleItem + 1);
- for(Index = 0; Index < MultipleItem->Count; Index++)
+ /* get device interface string input length */
+ Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
+
+ if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
{
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
+ /* get wave info */
+ Status = GetWaveInfoByIndexAndType(DeviceObject, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &WaveInfo);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
{
- if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO))
- {
- DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange;
-
- if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) &&
- IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) &&
- IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
- {
- DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u\n", DataRangeAudio->MinimumSampleFrequency, DataRangeAudio->MaximumSampleFrequency,
- DataRangeAudio->MinimumBitsPerSample, DataRangeAudio->MaximumBitsPerSample, DataRangeAudio->MaximumChannels);
-
- dwFormats |= CheckFormatSupport(DataRangeAudio, 11025, WAVE_FORMAT_1M08, WAVE_FORMAT_1S08, WAVE_FORMAT_1M16, WAVE_FORMAT_1S16);
- dwFormats |= CheckFormatSupport(DataRangeAudio, 22050, WAVE_FORMAT_2M08, WAVE_FORMAT_2S08, WAVE_FORMAT_2M16, WAVE_FORMAT_2S16);
- dwFormats |= CheckFormatSupport(DataRangeAudio, 44100, WAVE_FORMAT_4M08, WAVE_FORMAT_4S08, WAVE_FORMAT_4M16, WAVE_FORMAT_4S16);
- dwFormats |= CheckFormatSupport(DataRangeAudio, 48000, WAVE_FORMAT_48M08, WAVE_FORMAT_48S08, WAVE_FORMAT_48M16, WAVE_FORMAT_48S16);
- dwFormats |= CheckFormatSupport(DataRangeAudio, 96000, WAVE_FORMAT_96M08, WAVE_FORMAT_96S08, WAVE_FORMAT_96M16, WAVE_FORMAT_96S16);
-
-
- wChannels = DataRangeAudio->MaximumChannels;
- dwSupport = WAVECAPS_VOLUME; //FIXME get info from nodes
- }
- }
+ /* invalid device id */
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ }
+
+ Status = GetSysAudioDevicePnpName(DeviceObject, WaveInfo->FilterId, &Device);
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* invalid device id */
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ }
+
+ /* calculate length */
+ Length = (wcslen(Device)+1) * sizeof(WCHAR);
+
+ if (!Size)
+ {
+ /* store device interface size */
+ DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+ }
+ else if (Size < Length)
+ {
+ /* buffer too small */
+ DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+ return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
+ }
+ else
+ {
+ //FIXME SEH
+ RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
}
- DataRange = (PKSDATARANGE)((PUCHAR)DataRange + DataRange->FormatSize);
+
+ ExFreePool(Device);
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
}
+ else if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+ {
+ if (DeviceInfo->DeviceIndex >= DeviceExtension->MixerInfoCount)
+ {
+ /* invalid device id */
+ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
+ }
- DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats;
- DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport;
- DeviceInfo->u.WaveOutCaps.wChannels = wChannels;
- DeviceInfo->u.WaveOutCaps.szPname[0] = L'\0';
+ Status = GetSysAudioDevicePnpName(DeviceObject, DeviceExtension->MixerInfo[DeviceInfo->DeviceIndex].DeviceIndex, &Device);
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* invalid device id */
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ }
+ /* calculate length */
+ Length = (wcslen(Device)+1) * sizeof(WCHAR);
- ExFreePool(MultipleItem);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ if (!Size)
+ {
+ /* store device interface size */
+ DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+ }
+ else if (Size < Length)
+ {
+ /* buffer too small */
+ DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+ return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
+ }
+ else
+ {
+ //FIXME SEH
+ RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
+ }
+
+ ExFreePool(Device);
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+ }
+
+ return SetIrpIoStatus(Irp, STATUS_INVALID_DEVICE_REQUEST, sizeof(WDMAUD_DEVICE_INFO));
}
NTSTATUS
NTAPI
-WdmAudIoctlClose(
+WdmAudResetStream(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
+ IN PWDMAUD_DEVICE_INFO DeviceInfo)
{
- ULONG Index;
+ KSRESET ResetStream;
+ NTSTATUS Status;
+ ULONG BytesReturned;
+ PFILE_OBJECT FileObject;
- for(Index = 0; Index < ClientInfo->NumPins; Index++)
+ DPRINT("WdmAudResetStream\n");
+
+ Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+ if (!NT_SUCCESS(Status))
{
- if (ClientInfo->hPins[Index] == DeviceInfo->hDevice)
- {
- DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
- ZwClose(DeviceInfo->hDevice);
- ClientInfo->hPins[Index] = NULL;
- SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- return STATUS_SUCCESS;
- }
+ DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
}
- SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
- return STATUS_INVALID_PARAMETER;
+
+ ResetStream = DeviceInfo->u.ResetStream;
+ ASSERT(ResetStream == KSRESET_BEGIN || ResetStream == KSRESET_END);
+
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_RESET_STATE, (PVOID)&ResetStream, sizeof(KSRESET), NULL, 0, &BytesReturned);
+
+ ObDereferenceObject(FileObject);
+
+ DPRINT("WdmAudResetStream Status %x\n", Status);
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
NTSTATUS
return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo);
case IOCTL_CLOSE_WDMAUD:
return WdmAudIoctlClose(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_GETFRAMESIZE:
+ return WdmAudFrameSize(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_GETLINEINFO:
+ return WdmAudGetLineInfo(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_GETLINECONTROLS:
+ return WdmAudGetLineControls(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_SETCONTROLDETAILS:
+ return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_GETCONTROLDETAILS:
+ return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_QUERYDEVICEINTERFACESTRING:
+ return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo);
+ case IOCTL_GET_MIXER_EVENT:
+ return WdmAudGetMixerEvent(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ case IOCTL_RESET_STREAM:
+ return WdmAudResetStream(DeviceObject, Irp, DeviceInfo);
+ case IOCTL_GETPOS:
case IOCTL_GETDEVID:
case IOCTL_GETVOLUME:
case IOCTL_SETVOLUME:
return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
}
+
NTSTATUS
NTAPI
-WdmAudWrite(
+WdmAudReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
PWDMAUD_DEVICE_INFO DeviceInfo;
- PWDMAUD_CLIENT ClientInfo;
- NTSTATUS Status = STATUS_SUCCESS;
- PUCHAR Buffer;
- PCONTEXT_WRITE Packet;
PFILE_OBJECT FileObject;
- IO_STATUS_BLOCK IoStatusBlock;
+ PIO_STACK_LOCATION IoStack;
+ ULONG Length;
+ PMDL Mdl;
+ BOOLEAN Read = TRUE;
+ /* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
- //DPRINT("WdmAudWrite entered\n");
+ /* store the input buffer in UserBuffer - as KsProbeStreamIrp operates on IRP_MJ_DEVICE_CONTROL */
+ Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
- if (IoStack->Parameters.Write.Length < sizeof(WDMAUD_DEVICE_INFO))
- {
- /* invalid parameter */
- DPRINT1("Input buffer too small size %u expected %u\n", IoStack->Parameters.Write.Length, sizeof(WDMAUD_DEVICE_INFO));
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
+ /* sanity check */
+ ASSERT(Irp->UserBuffer);
- DeviceInfo = (PWDMAUD_DEVICE_INFO)MmGetMdlVirtualAddress(Irp->MdlAddress);
+ /* get the length of the request length */
+ Length = IoStack->Parameters.Write.Length;
+ /* store outputbuffer length */
+ IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
- Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid buffer handle %x\n", DeviceInfo->hDevice);
- return SetIrpIoStatus(Irp, Status, 0);
- }
+ /* store mdl address */
+ Mdl = Irp->MdlAddress;
+ /* remove mdladdress as KsProbeStreamIrp will interprete it as an already probed audio buffer */
+ Irp->MdlAddress = NULL;
- //DPRINT("DeviceInfo %p %p %p\n", DeviceInfo, Irp->MdlAddress->StartVa, Irp->MdlAddress->MappedSystemVa);
- if (DeviceInfo->DeviceType < MIN_SOUND_DEVICE_TYPE || DeviceInfo->DeviceType > MAX_SOUND_DEVICE_TYPE)
+ /* check for success */
+
+ if (IoStack->MajorFunction == IRP_MJ_WRITE)
{
- /* invalid parameter */
- DPRINT1("Error: device type not set\n");
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+ /* probe the write stream irp */
+ Read = FALSE;
+ Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
}
-
- if (!IoStack->FileObject)
+ else
{
- /* file object parameter */
- DPRINT1("Error: file object is not attached\n");
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ /* probe the read stream irp */
+ Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMREAD | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
}
- ClientInfo = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
+ /* now free the mdl */
+ IoFreeMdl(Mdl);
- /* setup stream context */
- Packet = (PCONTEXT_WRITE)ExAllocatePool(NonPagedPool, sizeof(CONTEXT_WRITE));
- if (!Packet)
+ if (!NT_SUCCESS(Status))
{
- /* no memory */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+ DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status, Irp->Cancel);
+ return SetIrpIoStatus(Irp, Status, 0);
}
- Packet->Header.FrameExtent = DeviceInfo->BufferSize;
- Packet->Header.DataUsed = DeviceInfo->BufferSize;
- Packet->Header.Size = sizeof(KSSTREAM_HEADER);
- Packet->Header.PresentationTime.Numerator = 1;
- Packet->Header.PresentationTime.Denominator = 1;
- Packet->Irp = Irp;
+ /* get device info */
+ DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
+ ASSERT(DeviceInfo);
- Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize);
- if (!Buffer)
+ /* now get sysaudio file object */
+ Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+ if (!NT_SUCCESS(Status))
{
- /* no memory */
- ExFreePool(Packet);
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+ DPRINT1("Invalid pin handle %p\n", DeviceInfo->hDevice);
+ return SetIrpIoStatus(Irp, Status, 0);
}
- Packet->Header.Data = Buffer;
- _SEH2_TRY
+ /* skip current irp stack location */
+ IoSkipCurrentIrpStackLocation(Irp);
+
+ /* get next stack location */
+ IoStack = IoGetNextIrpStackLocation(Irp);
+
+ if (Read)
{
- ProbeForRead(DeviceInfo->Buffer, DeviceInfo->BufferSize, TYPE_ALIGNMENT(char));
- RtlMoveMemory(Buffer, DeviceInfo->Buffer, DeviceInfo->BufferSize);
+ IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_READ_STREAM;
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ else
{
- /* Exception, get the error code */
- Status = _SEH2_GetExceptionCode();
+ IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM;
}
- _SEH2_END;
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid buffer supplied\n");
- ExFreePool(Buffer);
- ExFreePool(Packet);
- return SetIrpIoStatus(Irp, Status, 0);
- }
+ /* attach file object */
+ IoStack->FileObject = FileObject;
+ IoStack->Parameters.Write.Length = Length;
+ IoStack->MajorFunction = IRP_MJ_WRITE;
- KsStreamIo(FileObject, NULL, NULL, NULL, NULL, 0, &IoStatusBlock, Packet, sizeof(CONTEXT_WRITE), KSSTREAM_WRITE, KernelMode);
+ /* mark irp as pending */
+// IoMarkIrpPending(Irp);
+ /* call the driver */
+ Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
+ /* dereference file object */
+ ObDereferenceObject(FileObject);
- return IoStatusBlock.Status;
+ return Status;
}
-