From 7a728c427a2651cbbba213cc87009d5accd1e76b Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 7 Jun 2009 18:22:24 +0000 Subject: [PATCH] - Also Store audio filter object header in FsContext member - Create the pin on the correct filter by using the filters object class - Remove filter object class before performing actual create request - Remove object header from audio filter when closing - Retrieve internal object class name with internal IOCTL_KS_OBJECT_CLASS - Avoid using interface name as ReactOS doesn't support it - Store object class name when creating the object header for the audio sub device - Implement IPortFilterTopology interface - Activate pin property handle for port topology driver - There is no need to create a handle to sysaudio for each application opening wdmaud, use only one connection per driver basis - Pass object create class to pin creation method by duplicating KsCreatePin - Audio devices should now be accessible again svn path=/trunk/; revision=41341 --- reactos/drivers/ksfilter/ks/irp.c | 69 +++- reactos/drivers/ksfilter/ks/priv.h | 4 +- .../wdm/audio/backpln/portcls/adapter.c | 2 +- .../wdm/audio/backpln/portcls/dispatcher.c | 4 +- .../audio/backpln/portcls/filter_topology.c | 364 ++++++++++++++++++ .../audio/backpln/portcls/filter_wavecyclic.c | 4 +- .../wdm/audio/backpln/portcls/interfaces.h | 22 ++ .../wdm/audio/backpln/portcls/port_topology.c | 97 +++-- .../audio/backpln/portcls/port_wavecyclic.c | 14 +- .../wdm/audio/backpln/portcls/portcls.rbuild | 1 + .../wdm/audio/backpln/portcls/private.h | 13 +- .../drivers/wdm/audio/legacy/wdmaud/control.c | 44 ++- .../wdm/audio/legacy/wdmaud/deviface.c | 55 ++- .../drivers/wdm/audio/legacy/wdmaud/entry.c | 2 - .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 6 +- reactos/drivers/wdm/audio/sysaudio/control.c | 137 ++++++- reactos/drivers/wdm/audio/sysaudio/deviface.c | 122 ++++-- .../drivers/wdm/audio/sysaudio/dispatcher.c | 2 +- reactos/drivers/wdm/audio/sysaudio/main.c | 17 +- reactos/drivers/wdm/audio/sysaudio/sysaudio.h | 32 +- 20 files changed, 843 insertions(+), 168 deletions(-) create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c diff --git a/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c index 7a36c3ee1af..5eef3bfb338 100644 --- a/reactos/drivers/ksfilter/ks/irp.c +++ b/reactos/drivers/ksfilter/ks/irp.c @@ -352,7 +352,7 @@ KsAllocateObjectHeader( } /* was the request for a pin/clock/node */ - if (IoStack->FileObject) + if (IoStack->FileObject->FileName.Buffer) { /* store the object in the file object */ ASSERT(IoStack->FileObject->FsContext == NULL); @@ -360,9 +360,10 @@ KsAllocateObjectHeader( } else { - /* the object header is for device */ + /* the object header is for a audio filter */ ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems); DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader; + IoStack->FileObject->FsContext = ObjectHeader; } /* store result */ @@ -720,7 +721,7 @@ KsCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - //PIO_STACK_LOCATION IoStack; + PIO_STACK_LOCATION IoStack; PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; ULONG Index; @@ -729,7 +730,7 @@ KsCreate( DPRINT("KS / CREATE\n"); /* get current stack location */ - //IoStack = IoGetCurrentIrpStackLocation(Irp); + IoStack = IoGetCurrentIrpStackLocation(Irp); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get device header */ @@ -756,11 +757,41 @@ KsCreate( return Status; } } + else if (DeviceHeader->ItemList[Index].bCreated && IoStack->FileObject->FileName.Buffer != NULL) + { + ULONG Length = wcslen(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer); + + /* filter for that type has already exists */ + if (!_wcsnicmp(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer, + IoStack->FileObject->FileName.Buffer, + Length)) + { + if (IoStack->FileObject->FileName.Buffer[0] != L'{') + { + RtlMoveMemory(IoStack->FileObject->FileName.Buffer, &IoStack->FileObject->FileName.Buffer[Length+1], + IoStack->FileObject->FileName.Length - Length * sizeof(WCHAR)); + + IoStack->FileObject->FileName.Length -= Length * sizeof(WCHAR); + } + + + KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem; + Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp); + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + return Status; + } + } + } /* release lock */ KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - return Status; + + Irp->IoStatus.Information = 0; + /* set return status */ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; } static NTAPI @@ -771,9 +802,17 @@ KsClose( { PIO_STACK_LOCATION IoStack; PKSIOBJECT_HEADER ObjectHeader; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + ULONG Index; /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + DPRINT("KS / CLOSE\n"); @@ -782,11 +821,20 @@ KsClose( ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; + + for(Index = 0; Index < DeviceHeader->MaxItems; Index++) + { + if (DeviceHeader->ItemList[Index].ObjectHeader == ObjectHeader) + { + DeviceHeader->ItemList[Index].ObjectHeader = NULL; + } + } return ObjectHeader->DispatchTable.Close(DeviceObject, Irp); } else { - DPRINT1("Expected Object Header\n"); + DPRINT1("Expected Object Header FileObject %p FsContext %p\n", IoStack->FileObject, IoStack->FileObject->FsContext); + KeBugCheckEx(0, 0, 0, 0, 0); return STATUS_SUCCESS; } } @@ -809,6 +857,15 @@ KsDeviceControl( ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; + + if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS) + { + *((LPWSTR*)Irp->UserBuffer) = ObjectHeader->CreateItem->ObjectClass.Buffer; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(LPWSTR); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp); } else diff --git a/reactos/drivers/ksfilter/ks/priv.h b/reactos/drivers/ksfilter/ks/priv.h index 79cb124f6c0..f05422f4aef 100644 --- a/reactos/drivers/ksfilter/ks/priv.h +++ b/reactos/drivers/ksfilter/ks/priv.h @@ -3,7 +3,7 @@ #include #include -#define NDEBUG +#define YDEBUG #include #include #include @@ -16,6 +16,6 @@ #define TAG_DEVICE_HEADER TAG('H','D','S','K') - +#define IOCTL_KS_OBJECT_CLASS CTL_CODE(FILE_DEVICE_KS, 0x7, METHOD_NEITHER, FILE_ANY_ACCESS) #endif diff --git a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c b/reactos/drivers/wdm/audio/backpln/portcls/adapter.c index 972fe7f334e..5849dd921c5 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/adapter.c @@ -288,7 +288,7 @@ PcRegisterSubdevice( */ Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject, &SubDeviceDescriptor->Interfaces[Index], - &RefName, + NULL, //&RefName, &SymbolicLinkName); if (NT_SUCCESS(Status)) { diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c b/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c index 6a5e82f940b..916e9a95a23 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c @@ -211,7 +211,8 @@ NTSTATUS NTAPI NewDispatchObject( IN PIRP Irp, - IN IIrpTarget * Target) + IN IIrpTarget * Target, + IN LPWSTR Name) { NTSTATUS Status; KSOBJECT_HEADER ObjectHeader; @@ -223,6 +224,7 @@ NewDispatchObject( return STATUS_INSUFFICIENT_RESOURCES; CreateItem->Context = (PVOID)Target; + RtlInitUnicodeString(&CreateItem->ObjectClass, Name); IoStack = IoGetCurrentIrpStackLocation(Irp); ASSERT(IoStack->FileObject); diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c new file mode 100644 index 00000000000..a09ffb77663 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c @@ -0,0 +1,364 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/filter_topology.c + * PURPOSE: portcls topology filter + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.h" + +typedef struct +{ + IPortFilterTopologyVtbl *lpVtbl; + + LONG ref; + + IPortTopology* Port; + SUBDEVICE_DESCRIPTOR * Descriptor; + +}IPortFilterTopologyImpl; + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnQueryInterface( + IPortFilterTopology* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; + + if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtbl; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, &IID_IPort)) + { + *Output = This->Port; + This->Port->lpVtbl->AddRef(This->Port); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +/* + * @implemented + */ +ULONG +NTAPI +IPortFilterTopology_fnAddRef( + IPortFilterTopology* iface) +{ + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; + + return InterlockedIncrement(&This->ref); +} + +/* + * @implemented + */ +ULONG +NTAPI +IPortFilterTopology_fnRelease( + IPortFilterTopology* iface) +{ + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + FreeItem(This, TAG_PORTCLASS); + return 0; + } + return This->ref; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnNewIrpTarget( + IN IPortFilterTopology* iface, + OUT struct IIrpTarget **OutTarget, + IN WCHAR * Name, + IN PUNKNOWN Unknown, + IN POOL_TYPE PoolType, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN KSOBJECT_CREATE *CreateObject) +{ + DPRINT("IPortFilterTopology_fnNewIrpTarget entered\n"); + + return STATUS_NOT_SUPPORTED; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnDeviceIoControl( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + ISubdevice *SubDevice = NULL; + SUBDEVICE_DESCRIPTOR * Descriptor; + NTSTATUS Status; + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); + Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice); + ASSERT(Status == STATUS_SUCCESS); + ASSERT(SubDevice != NULL); + + Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor); + ASSERT(Status == STATUS_SUCCESS); + ASSERT(Descriptor != NULL); + + SubDevice->lpVtbl->Release(SubDevice); + + return PcPropertyHandler(Irp, Descriptor); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnRead( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnWrite( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnFlush( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnClose( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + //PMINIPORTTOPOLOGY Miniport; + //IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface; + + /* release reference to port */ + //This->Port->lpVtbl->Release(This->Port); + + /* get the miniport driver */ + //Miniport = GetTopologyMiniport(This->Port); + /* release miniport driver */ + //Miniport->lpVtbl->Release(Miniport); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnQuerySecurity( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +IPortFilterTopology_fnSetSecurity( + IN IPortFilterTopology* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +IPortFilterTopology_fnFastDeviceIoControl( + IN IPortFilterTopology* iface, + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +IPortFilterTopology_fnFastRead( + IN IPortFilterTopology* iface, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + return FALSE; +} + +/* + * @implemented + */ +BOOLEAN +NTAPI +IPortFilterTopology_fnFastWrite( + IN IPortFilterTopology* iface, + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK StatusBlock, + IN PDEVICE_OBJECT DeviceObject) +{ + return FALSE; +} + +/* + * @implemented + */ +static +NTSTATUS +NTAPI +IPortFilterTopology_fnInit( + IN IPortFilterTopology* iface, + IN IPortTopology* Port) +{ + ISubdevice * ISubDevice; + SUBDEVICE_DESCRIPTOR * Descriptor; + NTSTATUS Status; + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; + + /* get our private interface */ + Status = Port->lpVtbl->QueryInterface(Port, &IID_ISubdevice, (PVOID*)&ISubDevice); + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + /* get the subdevice descriptor */ + Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor); + + /* release subdevice interface */ + ISubDevice->lpVtbl->Release(ISubDevice); + + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + /* save descriptor */ + This->Descriptor = Descriptor; + + /* increment reference count */ + Port->lpVtbl->AddRef(Port); + + /* store port object */ + This->Port = Port; + + return STATUS_SUCCESS; +} + +static IPortFilterTopologyVtbl vt_IPortFilterTopology = +{ + IPortFilterTopology_fnQueryInterface, + IPortFilterTopology_fnAddRef, + IPortFilterTopology_fnRelease, + IPortFilterTopology_fnNewIrpTarget, + IPortFilterTopology_fnDeviceIoControl, + IPortFilterTopology_fnRead, + IPortFilterTopology_fnWrite, + IPortFilterTopology_fnFlush, + IPortFilterTopology_fnClose, + IPortFilterTopology_fnQuerySecurity, + IPortFilterTopology_fnSetSecurity, + IPortFilterTopology_fnFastDeviceIoControl, + IPortFilterTopology_fnFastRead, + IPortFilterTopology_fnFastWrite, + IPortFilterTopology_fnInit +}; + +NTSTATUS +NewPortFilterTopology( + OUT IPortFilterTopology ** OutFilter) +{ + IPortFilterTopologyImpl * This; + + This = AllocateItem(NonPagedPool, sizeof(IPortFilterTopologyImpl), TAG_PORTCLASS); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + /* initialize IPortFilterTopology */ + This->ref = 1; + This->lpVtbl = &vt_IPortFilterTopology; + + /* return result */ + *OutFilter = (IPortFilterTopology*)&This->lpVtbl; + + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c index b3ba90b7540..b4677cdaeb3 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c @@ -248,7 +248,9 @@ IPortFilterWaveCyclic_fnClose( /* release reference to port */ This->Port->lpVtbl->Release(This->Port); + /* get the miniport driver */ Miniport = GetWaveCyclicMiniport(This->Port); + /* release miniport driver */ Miniport->lpVtbl->Release(Miniport); @@ -256,7 +258,7 @@ IPortFilterWaveCyclic_fnClose( Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; + return STATUS_SUCCESS; } /* diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h index fe136322477..8ac4647f5d9 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h @@ -687,4 +687,26 @@ DECLARE_INTERFACE_(IDmaChannelInit, IUnknown) #undef INTERFACE +/***************************************************************************** + * IPortFilterTopology + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IPortFilterTopology + +DECLARE_INTERFACE_(IPortFilterTopology, IIrpTarget) +{ + DEFINE_ABSTRACT_UNKNOWN() + + DEFINE_ABSTRACT_IRPTARGET() + + STDMETHOD_(NTSTATUS, Init)(THIS_ + IN PPORTTOPOLOGY Port)PURE; +}; + +typedef IPortFilterTopology *PPORTFILTERTOPOLOGY; + +#undef INTERFACE + #endif diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c index b97cd93008d..4b8b7e34d22 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c @@ -23,6 +23,7 @@ typedef struct PPCFILTER_DESCRIPTOR pDescriptor; PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor; + IPortFilterTopology * Filter; }IPortTopologyImpl; typedef struct @@ -44,27 +45,26 @@ static GUID InterfaceGuids[2] = } }; -#if 0 -static -KSPROPERTY_SET PinPropertySet = -{ - &KSPROPSETID_Pin, - 0, - NULL, - 0, - NULL -}; +DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterTopologyTopologySet, TopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterTopologyPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); -static -KSPROPERTY_SET TopologyPropertySet = +KSPROPERTY_SET TopologyPropertySet[] = { - &KSPROPSETID_Topology, - 4, - NULL, - 0, - NULL + { + &KSPROPSETID_Topology, + sizeof(PortFilterTopologyTopologySet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterTopologyTopologySet, + 0, + NULL + }, + { + &KSPROPSETID_Pin, + sizeof(PortFilterTopologyPinSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterTopologyPinSet, + 0, + NULL + } }; -#endif //--------------------------------------------------------------- @@ -223,13 +223,13 @@ IPortTopology_fnInit( } /* create the subdevice descriptor */ - Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor, + Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor, 2, InterfaceGuids, 0, NULL, - 0, - NULL, + 2, + TopologyPropertySet, 0, 0, 0, @@ -339,10 +339,45 @@ ISubDevice_fnNewIrpTarget( IN PIRP Irp, IN KSOBJECT_CREATE *CreateObject) { - //IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); + NTSTATUS Status; + IPortFilterTopology * Filter; + IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - UNIMPLEMENTED - return STATUS_UNSUCCESSFUL; + /* is there already an instance of the filter */ + if (This->Filter) + { + /* it is, let's return the result */ + *OutTarget = (IIrpTarget*)This->Filter; + + /* increment reference */ + This->Filter->lpVtbl->AddRef(This->Filter); + return STATUS_SUCCESS; + } + + /* create new instance of filter */ + Status = NewPortFilterTopology(&Filter); + if (!NT_SUCCESS(Status)) + { + /* not enough memory */ + return Status; + } + + /* initialize the filter */ + Status = Filter->lpVtbl->Init(Filter, (IPortTopology*)This); + if (!NT_SUCCESS(Status)) + { + /* destroy filter */ + Filter->lpVtbl->Release(Filter); + /* return status */ + return Status; + } + + /* store result */ + *OutTarget = (IIrpTarget*)Filter; + /* store for later re-use */ + This->Filter = Filter; + /* return status */ + return Status; } static @@ -366,7 +401,7 @@ ISubDevice_fnGetDescriptor( { IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - DPRINT("ISubDevice_GetDescriptor this %p\n", This); + DPRINT("ISubDevice_GetDescriptor this %p Descp %p\n", This, This->SubDeviceDescriptor); *Descriptor = This->SubDeviceDescriptor; return STATUS_SUCCESS; } @@ -477,7 +512,7 @@ CreatePinWorkerRoutine( if (NT_SUCCESS(Status)) { /* create the dispatch object */ - Status = NewDispatchObject(WorkerContext->Irp, Pin); + Status = NewDispatchObject(WorkerContext->Irp, Pin, NULL); DPRINT("Pin %p\n", Pin); } @@ -573,7 +608,7 @@ PcCreateItemDispatch( if (IoStack->FileObject->FileName.Buffer == NULL) { /* create the dispatch object */ - Status = NewDispatchObject(Irp, Filter); + Status = NewDispatchObject(Irp, Filter, CreateItem->ObjectClass.Buffer); DPRINT1("Filter %p\n", Filter); } @@ -645,3 +680,11 @@ NewPortTopology( return STATUS_SUCCESS; } + +PMINIPORTTOPOLOGY +GetTopologyMiniport( + PPORTTOPOLOGY Port) +{ + IPortTopologyImpl * This = (IPortTopologyImpl*)Port; + return This->pMiniport; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c index 9f1894b404d..801a43df7b1 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c @@ -593,28 +593,40 @@ ISubDevice_fnNewIrpTarget( DPRINT("ISubDevice_NewIrpTarget this %p\n", This); + /* is there already an instance of the filter */ if (This->Filter) { + /* it is, let's return the result */ *OutTarget = (IIrpTarget*)This->Filter; + + /* increment reference */ + This->Filter->lpVtbl->AddRef(This->Filter); return STATUS_SUCCESS; } - + /* create new instance of filter */ Status = NewPortFilterWaveCyclic(&Filter); if (!NT_SUCCESS(Status)) { + /* not enough memory */ return Status; } + /* initialize the filter */ Status = Filter->lpVtbl->Init(Filter, (IPortWaveCyclic*)This); if (!NT_SUCCESS(Status)) { + /* destroy filter */ Filter->lpVtbl->Release(Filter); + /* return status */ return Status; } + /* store result */ *OutTarget = (IIrpTarget*)Filter; + /* store for later re-use */ This->Filter = Filter; + /* return status */ return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild b/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild index 789471c3669..8a8ce649de7 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild +++ b/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild @@ -19,6 +19,7 @@ dma_slave.c drm.c drm_port.c + filter_topology.c filter_dmus.c filter_wavecyclic.c filter_wavepci.c diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.h b/reactos/drivers/wdm/audio/backpln/portcls/private.h index cc11eb9d5ee..96bd00a2c36 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.h @@ -9,7 +9,7 @@ #include #include -#define NDEBUG +#define YDEBUG #include #include @@ -147,11 +147,20 @@ NewPortWaveRT( #endif +NTSTATUS +NewPortFilterTopology( + OUT IPortFilterTopology ** OutFilter); + +PMINIPORTTOPOLOGY +GetTopologyMiniport( + PPORTTOPOLOGY Port); + NTSTATUS NTAPI NewDispatchObject( IN PIRP Irp, - IN IIrpTarget * Target); + IN IIrpTarget * Target, + IN LPWSTR Name); PMINIPORTWAVECYCLIC GetWaveCyclicMiniport( diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 78fd6d4953b..579b8353f28 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -44,6 +44,7 @@ GetFilterIdAndPinId( NTSTATUS Status; KSPIN_COMMUNICATION Communication; KSPIN_DATAFLOW DataFlow; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE) { @@ -55,7 +56,9 @@ GetFilterIdAndPinId( 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); + 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 STATUS_UNSUCCESSFUL; @@ -69,7 +72,7 @@ GetFilterIdAndPinId( 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); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned); if (NT_SUCCESS(Status)) { /* enumerate now all pins */ @@ -80,13 +83,13 @@ GetFilterIdAndPinId( 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); + KsSynchronousIoControlDevice(DeviceExtension->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); + KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE) { @@ -132,6 +135,7 @@ WdmAudControlOpen( IN PWDMAUD_CLIENT ClientInfo) { PSYSAUDIO_INSTANCE_INFO InstanceInfo; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; ULONG BytesReturned; NTSTATUS Status; ACCESS_MASK DesiredAccess = 0; @@ -169,7 +173,9 @@ WdmAudControlOpen( InstanceInfo->Flags = 0; InstanceInfo->DeviceNumber = FilterId; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned); + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned); if (!NT_SUCCESS(Status)) { @@ -204,7 +210,7 @@ WdmAudControlOpen( PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; PinConnect->Medium.Flags = 0; PinConnect->PinId = PinId; - PinConnect->PinToHandle = ClientInfo->hSysAudio; + PinConnect->PinToHandle = DeviceExtension->hSysAudio; PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; PinConnect->Priority.PrioritySubClass = 1; @@ -231,7 +237,7 @@ WdmAudControlOpen( /* 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); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned); if (NT_SUCCESS(Status)) { PHANDLE Handels; @@ -283,8 +289,9 @@ WdmAudControlDeviceType( NTSTATUS Status; KSPIN_COMMUNICATION Communication; KSPIN_DATAFLOW DataFlow; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; - 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 && DeviceInfo->DeviceType != MIXER_DEVICE_TYPE) { DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); @@ -294,7 +301,8 @@ WdmAudControlDeviceType( 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); + 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)) { DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status); @@ -311,7 +319,7 @@ WdmAudControlDeviceType( 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); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned); if (NT_SUCCESS(Status)) { /* enumerate now all pins */ @@ -322,13 +330,17 @@ WdmAudControlDeviceType( 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); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); + if (!NT_SUCCESS(Status)) + continue; 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); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); + if (!NT_SUCCESS(Status)) + continue; if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE) { @@ -432,6 +444,7 @@ WdmAudCapabilities( IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo) { + PWDMAUD_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status = STATUS_UNSUCCESSFUL; KSP_PIN PinProperty; KSCOMPONENTID ComponentId; @@ -462,7 +475,8 @@ WdmAudCapabilities( RtlZeroMemory(&ComponentId, sizeof(KSCOMPONENTID)); - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned); if (NT_SUCCESS(Status)) { DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7; @@ -476,7 +490,7 @@ WdmAudCapabilities( PinProperty.Property.Flags = KSPROPERTY_TYPE_GET; BytesReturned = 0; - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->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); @@ -489,7 +503,7 @@ WdmAudCapabilities( return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } - Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned); + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned); if (!NT_SUCCESS(Status)) { ExFreePool(MultipleItem); diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c b/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c index 8b0f5569cb4..4de2320f2aa 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c @@ -94,6 +94,8 @@ WdmAudOpenSysAudioDevices( LPWSTR SymbolicLinkList; SYSAUDIO_ENTRY * Entry; ULONG Length; + HANDLE hSysAudio; + PFILE_OBJECT FileObject; UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio"); if (DeviceExtension->DeviceInterfaceSupport) @@ -135,7 +137,28 @@ WdmAudOpenSysAudioDevices( InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry); DeviceExtension->NumSysAudioDevices++; + + DPRINT("Opening device %S\n", Entry->SymbolicLink.Buffer); + Status = WdmAudOpenSysAudioDevice(Entry->SymbolicLink.Buffer, &hSysAudio); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open sysaudio %x\n", Status); + return Status; + } + + /* get the file object */ + Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to reference FileObject %x\n", Status); + ZwClose(hSysAudio); + return Status; + } + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + DeviceExtension->hSysAudio = hSysAudio; + DeviceExtension->FileObject = FileObject; } + return Status; } @@ -180,10 +203,6 @@ WdmAudOpenSysaudio( IN PWDMAUD_CLIENT *pClient) { PWDMAUD_CLIENT Client; - NTSTATUS Status; - HANDLE hSysAudio; - PSYSAUDIO_ENTRY SysEntry; - PFILE_OBJECT FileObject; PWDMAUD_DEVICE_EXTENSION DeviceExtension; DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -200,34 +219,6 @@ WdmAudOpenSysaudio( } RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT)); - - - /* open the first sysaudio device available */ - SysEntry = (PSYSAUDIO_ENTRY)DeviceExtension->SysAudioDeviceList.Flink; - - DPRINT1("Opening device %S\n", SysEntry->SymbolicLink.Buffer); - Status = WdmAudOpenSysAudioDevice(SysEntry->SymbolicLink.Buffer, &hSysAudio); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to open sysaudio %x\n", Status); - ExFreePool(Client); - return Status; - } - - /* get the file object */ - Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to reference FileObject %x\n", Status); - ExFreePool(Client); - ZwClose(hSysAudio); - return Status; - } - - Client->hSysAudio = hSysAudio; - Client->FileObject = FileObject; - Client->hProcess = PsGetCurrentProcessId(); - *pClient = Client; return STATUS_SUCCESS; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c index cccfd40e152..842bf26e2a0 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c @@ -215,8 +215,6 @@ WdmAudCleanup( ExFreePool(pClient->hPins); } - ObDereferenceObject(pClient->FileObject); - ZwClose(pClient->hSysAudio); ExFreePool(pClient); IoStack->FileObject->FsContext = NULL; } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 6bd06995c2a..8c442909e0f 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -5,7 +5,7 @@ #include #include #include -#define NDEBUG +#define YDEBUG #include #include #include @@ -15,8 +15,6 @@ typedef struct { HANDLE hProcess; - HANDLE hSysAudio; - PFILE_OBJECT FileObject; ULONG NumPins; HANDLE * hPins; @@ -38,6 +36,8 @@ typedef struct KSPIN_LOCK Lock; ULONG NumSysAudioDevices; LIST_ENTRY SysAudioDeviceList; + HANDLE hSysAudio; + PFILE_OBJECT FileObject; }WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION; diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index 4bc8b8614f1..da9c3ca8f3c 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -19,13 +19,95 @@ const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, NTSTATUS ComputeCompatibleFormat( - IN PKSAUDIO_DEVICE_ENTRY Entry, + IN PKSAUDIO_SUBDEVICE_ENTRY Entry, IN ULONG PinId, IN PSYSAUDIODEVEXT DeviceExtension, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat); +NTSTATUS +NTAPI +KspCreateObjectType( + IN HANDLE ParentHandle, + IN LPWSTR ObjectType, + PVOID CreateParameters, + UINT CreateParametersSize, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE NodeHandle) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + + Name.Length = (wcslen(ObjectType) + 1) * sizeof(WCHAR) + CreateParametersSize; + Name.MaximumLength += sizeof(WCHAR); + Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength); + + if (!Name.Buffer) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + wcscpy(Name.Buffer, ObjectType); + Name.Buffer[wcslen(ObjectType)] = '\\'; + + RtlMoveMemory(Name.Buffer + wcslen(ObjectType) +1, CreateParameters, CreateParametersSize); + + Name.Buffer[Name.Length / 2] = L'\0'; + InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL); + + + Status = IoCreateFile(NodeHandle, + DesiredAccess, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + 0, + FILE_OPEN, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0, + CreateFileTypeNone, + NULL, + IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK); + + return Status; +} + +KSDDKAPI +NTSTATUS +NTAPI +KsoCreatePin( + IN HANDLE FilterHandle, + IN PKSPIN_CONNECT Connect, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE ConnectionHandle, + IN LPWSTR ObjectClass) +{ + WCHAR szBuffer[100]; + UINT ConnectSize = sizeof(KSPIN_CONNECT); + + PKSDATAFORMAT_WAVEFORMATEX Format = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1); + if (Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) || + Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX)) + { + ConnectSize += Format->DataFormat.FormatSize; + } + + swprintf(szBuffer, L"%s\\{146F1A80-4791-11D0-A5D6-28DB04C10000}", ObjectClass); + + return KspCreateObjectType(FilterHandle, + szBuffer, + (PVOID)Connect, + ConnectSize, + DesiredAccess, + ConnectionHandle); +} + + NTSTATUS SetIrpIoStatus( IN PIRP Irp, @@ -46,20 +128,39 @@ SetIrpIoStatus( } -PKSAUDIO_DEVICE_ENTRY +PKSAUDIO_SUBDEVICE_ENTRY GetListEntry( IN PLIST_ENTRY Head, IN ULONG Index) { - PLIST_ENTRY Entry = Head->Flink; + PKSAUDIO_DEVICE_ENTRY DeviceEntry; + PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; + PLIST_ENTRY SubEntry, Entry = Head->Flink; + + DPRINT1("device index %u\n", Index); + while(Entry != Head) + { + DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); + if (Index < DeviceEntry->NumSubDevices) + { + SubEntry = DeviceEntry->SubDeviceList.Flink; + while(SubEntry != &DeviceEntry->SubDeviceList && Index--) + SubEntry = SubEntry->Flink; + + SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(SubEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); + return SubDeviceEntry; + } + else + { + Index -= DeviceEntry->NumSubDevices; + } - while(Index-- && Entry != Head) Entry = Entry->Flink; - if (Entry == Head) - return NULL; - - return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); + } + DPRINT1("Not Found index %u\n", Index); + DbgBreakPoint(); + return NULL; } NTSTATUS @@ -69,7 +170,7 @@ SysAudioOpenVirtualDevice( PSYSAUDIODEVEXT DeviceExtension) { PSYSAUDIO_CLIENT ClientInfo; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; PKSOBJECT_CREATE_ITEM CreateItem; /* access the create item */ @@ -99,9 +200,6 @@ SysAudioOpenVirtualDevice( Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber); ASSERT(Entry != NULL); - /* increase usage count */ - Entry->NumberOfClients++; - return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); } @@ -217,13 +315,12 @@ CreatePinWorkerRoutine( ASSERT(WorkerContext->Entry->Pins); ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId); - /* Fetch input format */ InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(WorkerContext->PinConnect + 1); /* Let's try to create the audio irp pin */ - Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); + Status = KsoCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle, WorkerContext->Entry->ObjectClass); if (!NT_SUCCESS(Status)) { @@ -260,7 +357,7 @@ CreatePinWorkerRoutine( } /* Retry with Mixer format */ - Status = KsCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); + Status = KsoCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle, WorkerContext->Entry->ObjectClass); if (!NT_SUCCESS(Status)) { /* This should not fail */ @@ -432,7 +529,7 @@ HandleSysAudioFilterPinProperties( { PIO_STACK_LOCATION IoStack; NTSTATUS Status; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; ULONG BytesReturned; PKSP_PIN Pin; @@ -519,7 +616,7 @@ HandleSysAudioFilterPinProperties( NTSTATUS ComputeCompatibleFormat( - IN PKSAUDIO_DEVICE_ENTRY Entry, + IN PKSAUDIO_SUBDEVICE_ENTRY Entry, IN ULONG PinId, IN PSYSAUDIODEVEXT DeviceExtension, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, @@ -653,7 +750,7 @@ ComputeCompatibleFormat( NTSTATUS GetPinInstanceCount( - PKSAUDIO_DEVICE_ENTRY Entry, + PKSAUDIO_SUBDEVICE_ENTRY Entry, PKSPIN_CINSTANCES PinInstances, PKSPIN_CONNECT PinConnect) { @@ -723,7 +820,7 @@ HandleSysAudioFilterPinCreation( PDEVICE_OBJECT DeviceObject) { ULONG Length; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; KSPIN_CONNECT * PinConnect; PIO_STACK_LOCATION IoStack; PSYSAUDIO_INSTANCE_INFO InstanceInfo; @@ -886,7 +983,7 @@ SysAudioHandleProperty( PULONG Index; PKSPROPERTY Property; PSYSAUDIODEVEXT DeviceExtension; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; PSYSAUDIO_INSTANCE_INFO InstanceInfo; ULONG BytesReturned; PKSOBJECT_CREATE_ITEM CreateItem; diff --git a/reactos/drivers/wdm/audio/sysaudio/deviface.c b/reactos/drivers/wdm/audio/sysaudio/deviface.c index 7547db33eb4..d76cb5f3e81 100644 --- a/reactos/drivers/wdm/audio/sysaudio/deviface.c +++ b/reactos/drivers/wdm/audio/sysaudio/deviface.c @@ -11,13 +11,14 @@ const GUID GUID_DEVICE_INTERFACE_ARRIVAL = {0xCB3A4004L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}}; const GUID GUID_DEVICE_INTERFACE_REMOVAL = {0xCB3A4005L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}}; const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KS_CATEGORY_TOPOLOGY = {0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00}}; const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +#define IOCTL_KS_OBJECT_CLASS CTL_CODE(FILE_DEVICE_KS, 0x7, METHOD_NEITHER, FILE_ANY_ACCESS) + VOID -NTAPI -FilterPinWorkerRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) +QueryFilterRoutine( + IN PKSAUDIO_SUBDEVICE_ENTRY DeviceEntry) { KSPROPERTY PropertyRequest; KSP_PIN PinRequest; @@ -27,15 +28,19 @@ FilterPinWorkerRoutine( ULONG Count, Index; NTSTATUS Status; ULONG BytesReturned; - PSYSAUDIODEVEXT DeviceExtension; - PKSAUDIO_DEVICE_ENTRY DeviceEntry; - PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context; - - DeviceEntry = Ctx->DeviceEntry; - + ULONG NumWaveOutPin, NumWaveInPin; DPRINT("Querying filter...\n"); + Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_OBJECT_CLASS, NULL, 0, &DeviceEntry->ObjectClass, sizeof(LPWSTR), &BytesReturned); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to query object class Status %x\n", Status); + return; + } + + DPRINT("ObjectClass %S\n", DeviceEntry->ObjectClass); + PropertyRequest.Set = KSPROPSETID_Pin; PropertyRequest.Flags = KSPROPERTY_TYPE_GET; PropertyRequest.Id = KSPROPERTY_PIN_CTYPES; @@ -45,13 +50,13 @@ FilterPinWorkerRoutine( if (!NT_SUCCESS(Status)) { DPRINT1("Failed to query number of pins Status %x\n", Status); - goto cleanup; + return; } if (!Count) { DPRINT1("Filter has no pins!\n"); - goto cleanup; + return; } /* allocate pin array */ @@ -60,12 +65,14 @@ FilterPinWorkerRoutine( { /* no memory */ DPRINT1("Failed to allocate memory Pins %u Block %x\n", Count, Count * sizeof(PIN_INFO)); - goto cleanup; + return; } /* clear array */ RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count); DeviceEntry->NumberOfPins = Count; + NumWaveInPin = 0; + NumWaveOutPin = 0; for(Index = 0; Index < Count; Index++) { /* get max instance count */ @@ -97,20 +104,41 @@ FilterPinWorkerRoutine( } if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN) - DeviceEntry->NumWaveOutPin++; + NumWaveOutPin++; if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT) - DeviceEntry->NumWaveInPin++; + NumWaveInPin++; } - DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, DeviceEntry->NumWaveInPin, DeviceEntry->NumWaveOutPin); - /* fetch device extension */ - DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; - /* insert new audio device */ - ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock); - /* increment audio device count */ - InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices); + DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, NumWaveInPin, NumWaveOutPin); +} + + + + +VOID +NTAPI +FilterPinWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PKSAUDIO_DEVICE_ENTRY DeviceEntry; + PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; + PLIST_ENTRY ListEntry; + + PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context; + + DeviceEntry = Ctx->DeviceEntry; + + ListEntry = DeviceEntry->SubDeviceList.Flink; + while(ListEntry != &DeviceEntry->SubDeviceList) + { + SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(ListEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); + QueryFilterRoutine(SubDeviceEntry); + ListEntry = ListEntry->Flink; + } + /* free work item */ IoFreeWorkItem(Ctx->WorkItem); @@ -118,14 +146,6 @@ FilterPinWorkerRoutine( ExFreePool(Ctx); return; -cleanup: - - ObDereferenceObject(DeviceEntry->FileObject); - ZwClose(DeviceEntry->Handle); - ExFreePool(DeviceEntry->DeviceName.Buffer); - ExFreePool(DeviceEntry); - IoFreeWorkItem(Ctx->WorkItem); - ExFreePool(Ctx); } NTSTATUS @@ -184,6 +204,7 @@ DeviceInterfaceChangeCallback( NTSTATUS Status = STATUS_SUCCESS; PSYSAUDIODEVEXT DeviceExtension; PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL; + PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; PIO_WORKITEM WorkItem = NULL; PFILTER_WORKER_CONTEXT Ctx = NULL; PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context; @@ -195,6 +216,7 @@ DeviceInterfaceChangeCallback( if (IsEqualGUIDAligned(&Event->Event, &GUID_DEVICE_INTERFACE_ARRIVAL)) { + /* a new device has arrived */ DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY)); if (!DeviceEntry) @@ -226,7 +248,7 @@ DeviceInterfaceChangeCallback( /* set device name */ DeviceEntry->DeviceName.Length = 0; - DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR); + DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 10 * sizeof(WCHAR); DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength); if (!DeviceEntry->DeviceName.Buffer) @@ -247,18 +269,42 @@ DeviceInterfaceChangeCallback( goto cleanup; } - Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateFile failed with %x\n", Status); - goto cleanup; - } + /* FIXME Ros does not support device interface strings */ + /* Workarround: repeatly call IoCreateFile untill ks wont find a create item which has no object header attached */ - DPRINT("Successfully opened audio device %u handle %p file object %p device object %p\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->Handle, DeviceEntry->FileObject, DeviceEntry->FileObject->DeviceObject); + InitializeListHead(&DeviceEntry->SubDeviceList); + do + { + SubDeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_SUBDEVICE_ENTRY)); + if (SubDeviceEntry) + { + RtlZeroMemory(SubDeviceEntry, sizeof(KSAUDIO_SUBDEVICE_ENTRY)); + Status = OpenDevice(&DeviceEntry->DeviceName, &SubDeviceEntry->Handle, &SubDeviceEntry->FileObject); + if (NT_SUCCESS(Status)) + { + InsertTailList(&DeviceEntry->SubDeviceList, &SubDeviceEntry->Entry); + DeviceEntry->NumSubDevices++; + /* increment audio device count */ + InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices); + } + else + { + ExFreePool(SubDeviceEntry); + break; + } + } + }while(NT_SUCCESS(Status) && SubDeviceEntry != NULL); + + DPRINT("Successfully opened audio device %u Device %S NumberOfSubDevices %u\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->DeviceName.Buffer, DeviceEntry->NumSubDevices); Ctx->DeviceEntry = DeviceEntry; Ctx->WorkItem = WorkItem; + /* fetch device extension */ + DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; + /* insert new audio device */ + ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock); + IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx); return Status; } diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index 005d319c071..a3fff3d7f43 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -74,7 +74,7 @@ Dispatch_fnClose( PIRP Irp) { PSYSAUDIO_CLIENT Client; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; PIO_STACK_LOCATION IoStatus; ULONG Index, SubIndex; PSYSAUDIODEVEXT DeviceExtension; diff --git a/reactos/drivers/wdm/audio/sysaudio/main.c b/reactos/drivers/wdm/audio/sysaudio/main.c index 47c969531ff..628e8d1112b 100644 --- a/reactos/drivers/wdm/audio/sysaudio/main.c +++ b/reactos/drivers/wdm/audio/sysaudio/main.c @@ -34,8 +34,9 @@ SysAudio_Shutdown( IN PIRP Irp) { PKSAUDIO_DEVICE_ENTRY DeviceEntry; + PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; PSYSAUDIODEVEXT DeviceExtension; - PLIST_ENTRY Entry; + PLIST_ENTRY Entry, SubEntry; DPRINT1("SysAudio_Shutdown called\n"); @@ -48,9 +49,17 @@ SysAudio_Shutdown( DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName); RtlFreeUnicodeString(&DeviceEntry->DeviceName); - ZwClose(DeviceEntry->Handle); - ObDereferenceObject(DeviceEntry->FileObject); - ExFreePool(DeviceEntry->Pins); + + while(!IsListEmpty(&DeviceEntry->SubDeviceList)) + { + SubEntry = RemoveHeadList(&DeviceEntry->SubDeviceList); + SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(SubEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); + + ZwClose(SubDeviceEntry->Handle); + ObDereferenceObject(SubDeviceEntry->FileObject); + ExFreePool(SubDeviceEntry->Pins); + ExFreePool(SubDeviceEntry); + } ExFreePool(DeviceEntry); } diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h index bc556f33dc7..6e0d4e9aff4 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h @@ -7,8 +7,9 @@ #include #include #include -#define NDEBUG +#define YDEBUG #include +#include typedef struct { @@ -43,20 +44,27 @@ typedef struct KSPIN_COMMUNICATION Communication; // pin type }PIN_INFO; +typedef struct +{ + LIST_ENTRY Entry; // linked list entry to KSAUDIO_DEVICE_ENTRY + + HANDLE Handle; // handle to audio sub device + PFILE_OBJECT FileObject; // file objecto to audio sub device + + ULONG NumberOfPins; // number of pins of audio device + PIN_INFO * Pins; // array of PIN_INFO + + LPWSTR ObjectClass; // object class of sub device + +}KSAUDIO_SUBDEVICE_ENTRY, *PKSAUDIO_SUBDEVICE_ENTRY; typedef struct { LIST_ENTRY Entry; // device entry for KsAudioDeviceList - HANDLE Handle; // handle to audio device - PFILE_OBJECT FileObject; // file object for audio device UNICODE_STRING DeviceName; // symbolic link of audio device - ULONG NumberOfClients; // number of clients referenced audio device - ULONG NumberOfPins; // number of pins of audio device - PIN_INFO * Pins; // array of PIN_INFO - - ULONG NumWaveOutPin; // number of wave out pins - ULONG NumWaveInPin; // number of wave in pins + ULONG NumSubDevices; // number of subdevices + LIST_ENTRY SubDeviceList; // audio sub device list }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY; @@ -88,7 +96,7 @@ typedef struct HANDLE Handle; // audio irp pin handle PFILE_OBJECT FileObject; // audio irp pin file object ULONG PinId; // pin id of device - PKSAUDIO_DEVICE_ENTRY AudioEntry; // pointer to audio device entry + PKSAUDIO_SUBDEVICE_ENTRY AudioEntry; // pointer to audio device entry HANDLE hMixerPin; // handle to mixer pin PFILE_OBJECT MixerFileObject; // mixer file object @@ -104,7 +112,7 @@ typedef struct PIRP Irp; BOOL CreateRealPin; BOOL CreateMixerPin; - PKSAUDIO_DEVICE_ENTRY Entry; + PKSAUDIO_SUBDEVICE_ENTRY Entry; KSPIN_CONNECT * PinConnect; PDISPATCH_CONTEXT DispatchContext; PSYSAUDIO_CLIENT AudioClient; @@ -148,7 +156,7 @@ OpenDevice( IN PHANDLE HandleOut, IN PFILE_OBJECT * FileObjectOut); -PKSAUDIO_DEVICE_ENTRY +PKSAUDIO_SUBDEVICE_ENTRY GetListEntry( IN PLIST_ENTRY Head, IN ULONG Index);