mirror of
https://github.com/reactos/reactos.git
synced 2024-07-28 15:19:09 +00:00
- Fix a bug in KsTopologyPropertyHandler
- Create a KSTOPOLOGY struct when creating the subdevice descriptor and pass the struct to KsTopologyPropertyHandler - Implement enumerating mixer devices - Change handle array to contain the target device type. Mixer handles are not real handles, they are just pseudo handles - Forward KSPROPSETID_Topology request to portcls (sysaudio) svn path=/trunk/; revision=41352
This commit is contained in:
parent
0537f45d82
commit
fd1851d16a
|
@ -162,7 +162,7 @@ KsTopologyPropertyHandler(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KSPROPERTY_TOPOLOGY_CONNECTIONS:
|
case KSPROPERTY_TOPOLOGY_CONNECTIONS:
|
||||||
Size = sizeof(KSMULTIPLE_ITEM) + Topology->TopologyConnectionsCount * sizeof(GUID);
|
Size = sizeof(KSMULTIPLE_ITEM) + Topology->TopologyConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION);
|
||||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = Size;
|
Irp->IoStatus.Information = Size;
|
||||||
|
@ -174,7 +174,7 @@ KsTopologyPropertyHandler(
|
||||||
Item->Size = Size;
|
Item->Size = Size;
|
||||||
Item->Count = Topology->TopologyConnectionsCount;
|
Item->Count = Topology->TopologyConnectionsCount;
|
||||||
|
|
||||||
RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyConnections, Topology->TopologyConnectionsCount * sizeof(GUID));
|
RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyConnections, Topology->TopologyConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
|
||||||
Irp->IoStatus.Information = Size;
|
Irp->IoStatus.Information = Size;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -130,6 +130,7 @@ typedef struct
|
||||||
KSPROPERTY_SET_LIST FilterPropertySet;
|
KSPROPERTY_SET_LIST FilterPropertySet;
|
||||||
|
|
||||||
PPCFILTER_DESCRIPTOR DeviceDescriptor;
|
PPCFILTER_DESCRIPTOR DeviceDescriptor;
|
||||||
|
KSTOPOLOGY* Topology;
|
||||||
}SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
|
}SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
|
||||||
|
|
||||||
#undef INTERFACE
|
#undef INTERFACE
|
||||||
|
|
|
@ -223,7 +223,7 @@ SetStreamWorkerRoutine(
|
||||||
/* Set the state */
|
/* Set the state */
|
||||||
if (NT_SUCCESS(This->Stream->lpVtbl->SetState(This->Stream, State)))
|
if (NT_SUCCESS(This->Stream->lpVtbl->SetState(This->Stream, State)))
|
||||||
{
|
{
|
||||||
/* Set internal state to stop */
|
/* Set internal state */
|
||||||
This->State = State;
|
This->State = State;
|
||||||
|
|
||||||
if (This->State == KSSTATE_STOP)
|
if (This->State == KSSTATE_STOP)
|
||||||
|
@ -913,7 +913,7 @@ IPortPinWaveCyclic_fnFastWrite(
|
||||||
|
|
||||||
InterlockedIncrement((PLONG)&This->TotalPackets);
|
InterlockedIncrement((PLONG)&This->TotalPackets);
|
||||||
|
|
||||||
DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted);
|
DPRINT1("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted);
|
||||||
|
|
||||||
Packet = (PCONTEXT_WRITE)Buffer;
|
Packet = (PCONTEXT_WRITE)Buffer;
|
||||||
|
|
||||||
|
|
|
@ -353,10 +353,11 @@ TopologyPropertyHandler(
|
||||||
IN PKSIDENTIFIER Request,
|
IN PKSIDENTIFIER Request,
|
||||||
IN OUT PVOID Data)
|
IN OUT PVOID Data)
|
||||||
{
|
{
|
||||||
return KsTopologyPropertyHandler(Irp,
|
PSUBDEVICE_DESCRIPTOR Descriptor;
|
||||||
Request,
|
|
||||||
Data,
|
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
|
||||||
NULL /* FIXME */);
|
|
||||||
|
return KsTopologyPropertyHandler(Irp, Request, Data, Descriptor->Topology);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -210,6 +210,37 @@ PcCreateSubdeviceDescriptor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Descriptor->Topology = AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS);
|
||||||
|
if (!Descriptor->Topology)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (FilterDescription->ConnectionCount)
|
||||||
|
{
|
||||||
|
Descriptor->Topology->TopologyConnections = AllocateItem(NonPagedPool, sizeof(PCCONNECTION_DESCRIPTOR) * FilterDescription->ConnectionCount, TAG_PORTCLASS);
|
||||||
|
if (!Descriptor->Topology->TopologyConnections)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR));
|
||||||
|
Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FilterDescription->NodeCount)
|
||||||
|
{
|
||||||
|
Descriptor->Topology->TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
|
||||||
|
if (!Descriptor->Topology->TopologyNodes)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
Descriptor->Topology->TopologyNodesNames = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
|
||||||
|
if (!Descriptor->Topology->TopologyNodesNames)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for(Index = 0; Index < FilterDescription->NodeCount; Index++)
|
||||||
|
{
|
||||||
|
RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID));
|
||||||
|
RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID));
|
||||||
|
}
|
||||||
|
Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount;
|
||||||
|
}
|
||||||
|
|
||||||
if (FilterDescription->PinCount)
|
if (FilterDescription->PinCount)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@ const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF,
|
||||||
const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
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_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 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
|
NTSTATUS
|
||||||
SetIrpIoStatus(
|
SetIrpIoStatus(
|
||||||
|
@ -146,6 +147,11 @@ WdmAudControlOpen(
|
||||||
ULONG FilterId;
|
ULONG FilterId;
|
||||||
ULONG PinId;
|
ULONG PinId;
|
||||||
|
|
||||||
|
if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
||||||
|
}
|
||||||
|
|
||||||
if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
|
if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
DPRINT1("FIXME: only waveout / wavein devices are supported\n");
|
DPRINT1("FIXME: only waveout / wavein devices are supported\n");
|
||||||
|
@ -240,11 +246,11 @@ WdmAudControlOpen(
|
||||||
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned);
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PHANDLE Handels;
|
PWDMAUD_HANDLE Handels;
|
||||||
|
|
||||||
for(Index = 0; Index < ClientInfo->NumPins; Index++)
|
for(Index = 0; Index < ClientInfo->NumPins; Index++)
|
||||||
{
|
{
|
||||||
if (ClientInfo->hPins[Index] == PinHandle)
|
if (ClientInfo->hPins[Index].Handle == PinHandle)
|
||||||
{
|
{
|
||||||
/* the pin handle has been re-used */
|
/* the pin handle has been re-used */
|
||||||
DeviceInfo->hDevice = PinHandle;
|
DeviceInfo->hDevice = PinHandle;
|
||||||
|
@ -253,18 +259,19 @@ WdmAudControlOpen(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumPins+1));
|
Handels = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1));
|
||||||
|
|
||||||
if (Handels)
|
if (Handels)
|
||||||
{
|
{
|
||||||
if (ClientInfo->NumPins)
|
if (ClientInfo->NumPins)
|
||||||
{
|
{
|
||||||
RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(HANDLE) * ClientInfo->NumPins);
|
RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins);
|
||||||
ExFreePool(ClientInfo->hPins);
|
ExFreePool(ClientInfo->hPins);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientInfo->hPins = Handels;
|
ClientInfo->hPins = Handels;
|
||||||
ClientInfo->hPins[ClientInfo->NumPins] = PinHandle;
|
ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
|
||||||
|
ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceInfo->DeviceType;
|
||||||
ClientInfo->NumPins++;
|
ClientInfo->NumPins++;
|
||||||
}
|
}
|
||||||
DeviceInfo->hDevice = PinHandle;
|
DeviceInfo->hDevice = PinHandle;
|
||||||
|
@ -291,7 +298,13 @@ WdmAudControlDeviceType(
|
||||||
KSPIN_DATAFLOW DataFlow;
|
KSPIN_DATAFLOW DataFlow;
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE && DeviceInfo->DeviceType != MIXER_DEVICE_TYPE)
|
if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
DeviceInfo->DeviceCount = GetNumOfMixerDevices(DeviceObject);
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
|
DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
|
||||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
@ -563,11 +576,11 @@ WdmAudIoctlClose(
|
||||||
|
|
||||||
for(Index = 0; Index < ClientInfo->NumPins; Index++)
|
for(Index = 0; Index < ClientInfo->NumPins; Index++)
|
||||||
{
|
{
|
||||||
if (ClientInfo->hPins[Index] == DeviceInfo->hDevice)
|
if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
|
DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
|
||||||
ZwClose(DeviceInfo->hDevice);
|
ZwClose(DeviceInfo->hDevice);
|
||||||
ClientInfo->hPins[Index] = NULL;
|
ClientInfo->hPins[Index].Handle = NULL;
|
||||||
SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,9 +204,9 @@ WdmAudCleanup(
|
||||||
{
|
{
|
||||||
for (Index = 0; Index < pClient->NumPins; Index++)
|
for (Index = 0; Index < pClient->NumPins; Index++)
|
||||||
{
|
{
|
||||||
if (pClient->hPins[Index])
|
if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
ZwClose(pClient->hPins[Index]);
|
ZwClose(pClient->hPins[Index].Handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
209
reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c
Normal file
209
reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/wdmaud/mixer.c
|
||||||
|
* PURPOSE: System Audio graph builder
|
||||||
|
* PROGRAMMER: Andrew Greenwood
|
||||||
|
* Johannes Anderwald
|
||||||
|
*/
|
||||||
|
#include "wdmaud.h"
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
IsVirtualDeviceATopologyFilter(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
ULONG VirtualDeviceId)
|
||||||
|
{
|
||||||
|
KSP_PIN Pin;
|
||||||
|
ULONG Count, BytesReturned, Index, NumPins;
|
||||||
|
NTSTATUS Status;
|
||||||
|
KSPIN_COMMUNICATION Communication;
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
ULONG MixerPinCount;
|
||||||
|
|
||||||
|
Pin.Property.Set = KSPROPSETID_Sysaudio;
|
||||||
|
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
||||||
|
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
|
||||||
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (VirtualDeviceId >= Count)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* query number of pins */
|
||||||
|
Pin.Reserved = VirtualDeviceId; // see sysaudio
|
||||||
|
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
Pin.Property.Set = KSPROPSETID_Pin;
|
||||||
|
Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
|
||||||
|
Pin.PinId = 0;
|
||||||
|
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* enumerate now all pins */
|
||||||
|
MixerPinCount = 0;
|
||||||
|
for(Index = 0; Index < NumPins; Index++)
|
||||||
|
{
|
||||||
|
Pin.PinId = Index;
|
||||||
|
Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
|
||||||
|
Communication = KSPIN_COMMUNICATION_NONE;
|
||||||
|
|
||||||
|
/* get pin communication type */
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (Communication == KSPIN_COMMUNICATION_NONE)
|
||||||
|
MixerPinCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MixerPinCount == NumPins)
|
||||||
|
{
|
||||||
|
/* filter has no pins which can be instantiated -> topology filter */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
GetNumOfMixerPinsFromTopologyFilter(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
ULONG VirtualDeviceId)
|
||||||
|
{
|
||||||
|
KSP_PIN Pin;
|
||||||
|
ULONG BytesReturned, Index, NumPins;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PKSMULTIPLE_ITEM MultipleItem;
|
||||||
|
PKSTOPOLOGY_CONNECTION Conn;
|
||||||
|
|
||||||
|
Pin.PinId = 0;
|
||||||
|
Pin.Reserved = VirtualDeviceId;
|
||||||
|
Pin.Property.Set = KSPROPSETID_Topology;
|
||||||
|
Pin.Property.Id = KSPROPERTY_TOPOLOGY_CONNECTIONS;
|
||||||
|
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
|
||||||
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
BytesReturned = 0;
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned);
|
||||||
|
|
||||||
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
|
||||||
|
if (!MultipleItem)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
RtlZeroMemory(MultipleItem, BytesReturned);
|
||||||
|
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePool(MultipleItem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Conn = (PKSTOPOLOGY_CONNECTION)(MultipleItem + 1);
|
||||||
|
NumPins = 0;
|
||||||
|
for (Index = 0; Index < MultipleItem->Count; Index++)
|
||||||
|
{
|
||||||
|
if (Conn[Index].ToNode == PCFILTER_NODE)
|
||||||
|
{
|
||||||
|
NumPins++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePool(MultipleItem);
|
||||||
|
return NumPins;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
GetNumOfMixerDevices(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
KSP_PIN Pin;
|
||||||
|
ULONG Count, BytesReturned, Index, NumPins;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
|
||||||
|
Pin.Property.Set = KSPROPSETID_Sysaudio;
|
||||||
|
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
||||||
|
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
|
||||||
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
Count = 0;
|
||||||
|
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
|
||||||
|
if (!NT_SUCCESS(Status) || !Count)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
NumPins = 0;
|
||||||
|
for(Index = 0; Index < Count; Index++)
|
||||||
|
{
|
||||||
|
if (IsVirtualDeviceATopologyFilter(DeviceObject, Index))
|
||||||
|
{
|
||||||
|
NumPins += GetNumOfMixerPinsFromTopologyFilter(DeviceObject, Index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NumPins;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudControlOpenMixer(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
|
IN PWDMAUD_CLIENT ClientInfo)
|
||||||
|
{
|
||||||
|
ULONG Index;
|
||||||
|
PWDMAUD_HANDLE Handels;
|
||||||
|
|
||||||
|
if (DeviceInfo->DeviceIndex >= GetNumOfMixerDevices(DeviceObject))
|
||||||
|
{
|
||||||
|
/* mixer index doesnt exist */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Index = 0; Index < ClientInfo->NumPins; Index++)
|
||||||
|
{
|
||||||
|
if (ClientInfo->hPins[Index].Handle == (HANDLE)DeviceInfo->DeviceIndex && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
/* re-use pseudo handle */
|
||||||
|
DeviceInfo->hDevice = (HANDLE)DeviceInfo->DeviceIndex;
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Handels = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1));
|
||||||
|
|
||||||
|
if (Handels)
|
||||||
|
{
|
||||||
|
if (ClientInfo->NumPins)
|
||||||
|
{
|
||||||
|
RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins);
|
||||||
|
ExFreePool(ClientInfo->hPins);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientInfo->hPins = Handels;
|
||||||
|
ClientInfo->hPins[ClientInfo->NumPins].Handle = (HANDLE)DeviceInfo->DeviceIndex;
|
||||||
|
ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE;
|
||||||
|
ClientInfo->NumPins++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
|
}
|
||||||
|
DeviceInfo->hDevice = (HANDLE)DeviceInfo->DeviceIndex;
|
||||||
|
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
|
}
|
||||||
|
|
|
@ -12,11 +12,18 @@
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
HANDLE Handle;
|
||||||
|
SOUND_DEVICE_TYPE Type;
|
||||||
|
}WDMAUD_HANDLE, *PWDMAUD_HANDLE;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
ULONG NumPins;
|
ULONG NumPins;
|
||||||
HANDLE * hPins;
|
WDMAUD_HANDLE * hPins;
|
||||||
|
|
||||||
}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
|
}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
|
||||||
|
|
||||||
|
@ -83,5 +90,21 @@ WdmAudWrite(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp);
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudControlOpenMixer(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
|
IN PWDMAUD_CLIENT ClientInfo);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
GetNumOfMixerDevices(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
SetIrpIoStatus(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN NTSTATUS Status,
|
||||||
|
IN ULONG Length);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,5 +10,6 @@
|
||||||
<file>control.c</file>
|
<file>control.c</file>
|
||||||
<file>deviface.c</file>
|
<file>deviface.c</file>
|
||||||
<file>entry.c</file>
|
<file>entry.c</file>
|
||||||
|
<file>mixer.c</file>
|
||||||
<file>wdmaud.rc</file>
|
<file>wdmaud.rc</file>
|
||||||
</module>
|
</module>
|
||||||
|
|
|
@ -13,6 +13,7 @@ const GUID KSPROPSETID_Sysaudio_Pin = {0xA3A53220L, 0xC6E4, 0x11D0,
|
||||||
const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
||||||
const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
|
const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
|
||||||
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||||
|
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||||
const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
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_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 KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
|
||||||
|
@ -137,7 +138,6 @@ GetListEntry(
|
||||||
PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry;
|
PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry;
|
||||||
PLIST_ENTRY SubEntry, Entry = Head->Flink;
|
PLIST_ENTRY SubEntry, Entry = Head->Flink;
|
||||||
|
|
||||||
DPRINT1("device index %u\n", Index);
|
|
||||||
while(Entry != Head)
|
while(Entry != Head)
|
||||||
{
|
{
|
||||||
DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
|
DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
|
||||||
|
@ -158,8 +158,8 @@ GetListEntry(
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
|
|
||||||
}
|
}
|
||||||
DPRINT1("Not Found index %u\n", Index);
|
DPRINT1("Not Found index %u\n", Index);
|
||||||
DbgBreakPoint();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,6 +988,8 @@ SysAudioHandleProperty(
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
UNICODE_STRING GuidString;
|
UNICODE_STRING GuidString;
|
||||||
|
PKSP_PIN Pin;
|
||||||
|
|
||||||
|
|
||||||
/* access the create item */
|
/* access the create item */
|
||||||
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
||||||
|
@ -1007,6 +1009,27 @@ SysAudioHandleProperty(
|
||||||
{
|
{
|
||||||
return HandleSysAudioFilterPinProperties(Irp, Property, DeviceExtension);
|
return HandleSysAudioFilterPinProperties(Irp, Property, DeviceExtension);
|
||||||
}
|
}
|
||||||
|
else if(IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Topology))
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_PIN))
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSP_PIN));
|
||||||
|
}
|
||||||
|
Pin = (PKSP_PIN)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Pin->Reserved);
|
||||||
|
ASSERT(Entry != NULL);
|
||||||
|
|
||||||
|
/* forward request to the filter implementing the property */
|
||||||
|
Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY,
|
||||||
|
(PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
|
||||||
|
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
||||||
|
Irp->UserBuffer,
|
||||||
|
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
|
||||||
|
&BytesReturned);
|
||||||
|
|
||||||
|
return SetIrpIoStatus(Irp, Status, BytesReturned);
|
||||||
|
}
|
||||||
else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
|
else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
|
||||||
{
|
{
|
||||||
if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID)
|
if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID)
|
||||||
|
|
Loading…
Reference in a new issue