mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
- 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
This commit is contained in:
parent
60e3f374fa
commit
7a728c427a
20 changed files with 843 additions and 168 deletions
|
@ -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
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <ntifs.h>
|
||||
#include <ntddk.h>
|
||||
#define NDEBUG
|
||||
#define YDEBUG
|
||||
#include <debug.h>
|
||||
#include <portcls.h>
|
||||
#include <ks.h>
|
||||
|
@ -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
|
||||
|
|
|
@ -288,7 +288,7 @@ PcRegisterSubdevice(
|
|||
*/
|
||||
Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject,
|
||||
&SubDeviceDescriptor->Interfaces[Index],
|
||||
&RefName,
|
||||
NULL, //&RefName,
|
||||
&SymbolicLinkName);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
364
reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c
Normal file
364
reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<file>dma_slave.c</file>
|
||||
<file>drm.c</file>
|
||||
<file>drm_port.c</file>
|
||||
<file>filter_topology.c</file>
|
||||
<file>filter_dmus.c</file>
|
||||
<file>filter_wavecyclic.c</file>
|
||||
<file>filter_wavepci.c</file>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <ntddk.h>
|
||||
#include <portcls.h>
|
||||
#define NDEBUG
|
||||
#define YDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include <dmusicks.h>
|
||||
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -215,8 +215,6 @@ WdmAudCleanup(
|
|||
ExFreePool(pClient->hPins);
|
||||
}
|
||||
|
||||
ObDereferenceObject(pClient->FileObject);
|
||||
ZwClose(pClient->hSysAudio);
|
||||
ExFreePool(pClient);
|
||||
IoStack->FileObject->FsContext = NULL;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <ntddk.h>
|
||||
#include <portcls.h>
|
||||
#include <ks.h>
|
||||
#define NDEBUG
|
||||
#define YDEBUG
|
||||
#include <debug.h>
|
||||
#include <ksmedia.h>
|
||||
#include <mmsystem.h>
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
#include <math.h>
|
||||
#define NDEBUG
|
||||
#define YDEBUG
|
||||
#include <debug.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue