mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +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 */
|
/* was the request for a pin/clock/node */
|
||||||
if (IoStack->FileObject)
|
if (IoStack->FileObject->FileName.Buffer)
|
||||||
{
|
{
|
||||||
/* store the object in the file object */
|
/* store the object in the file object */
|
||||||
ASSERT(IoStack->FileObject->FsContext == NULL);
|
ASSERT(IoStack->FileObject->FsContext == NULL);
|
||||||
|
@ -360,9 +360,10 @@ KsAllocateObjectHeader(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* the object header is for device */
|
/* the object header is for a audio filter */
|
||||||
ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems);
|
ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems);
|
||||||
DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader;
|
DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader;
|
||||||
|
IoStack->FileObject->FsContext = ObjectHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store result */
|
/* store result */
|
||||||
|
@ -720,7 +721,7 @@ KsCreate(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
//PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PDEVICE_EXTENSION DeviceExtension;
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
PKSIDEVICE_HEADER DeviceHeader;
|
PKSIDEVICE_HEADER DeviceHeader;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
@ -729,7 +730,7 @@ KsCreate(
|
||||||
|
|
||||||
DPRINT("KS / CREATE\n");
|
DPRINT("KS / CREATE\n");
|
||||||
/* get current stack location */
|
/* get current stack location */
|
||||||
//IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
/* get device extension */
|
/* get device extension */
|
||||||
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
/* get device header */
|
/* get device header */
|
||||||
|
@ -756,11 +757,41 @@ KsCreate(
|
||||||
return Status;
|
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 */
|
/* release lock */
|
||||||
KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
|
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
|
static NTAPI
|
||||||
|
@ -771,9 +802,17 @@ KsClose(
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PKSIOBJECT_HEADER ObjectHeader;
|
PKSIOBJECT_HEADER ObjectHeader;
|
||||||
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
|
PKSIDEVICE_HEADER DeviceHeader;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
/* get current stack location */
|
/* get current stack location */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
|
||||||
|
/* get device header */
|
||||||
|
DeviceHeader = DeviceExtension->DeviceHeader;
|
||||||
|
|
||||||
|
|
||||||
DPRINT("KS / CLOSE\n");
|
DPRINT("KS / CLOSE\n");
|
||||||
|
|
||||||
|
@ -782,11 +821,20 @@ KsClose(
|
||||||
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
||||||
|
|
||||||
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
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);
|
return ObjectHeader->DispatchTable.Close(DeviceObject, Irp);
|
||||||
}
|
}
|
||||||
else
|
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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -809,6 +857,15 @@ KsDeviceControl(
|
||||||
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
||||||
|
|
||||||
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
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);
|
return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <ntifs.h>
|
#include <ntifs.h>
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#define NDEBUG
|
#define YDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <portcls.h>
|
#include <portcls.h>
|
||||||
#include <ks.h>
|
#include <ks.h>
|
||||||
|
@ -16,6 +16,6 @@
|
||||||
|
|
||||||
#define TAG_DEVICE_HEADER TAG('H','D','S','K')
|
#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
|
#endif
|
||||||
|
|
|
@ -288,7 +288,7 @@ PcRegisterSubdevice(
|
||||||
*/
|
*/
|
||||||
Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject,
|
Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject,
|
||||||
&SubDeviceDescriptor->Interfaces[Index],
|
&SubDeviceDescriptor->Interfaces[Index],
|
||||||
&RefName,
|
NULL, //&RefName,
|
||||||
&SymbolicLinkName);
|
&SymbolicLinkName);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
|
@ -211,7 +211,8 @@ NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NewDispatchObject(
|
NewDispatchObject(
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN IIrpTarget * Target)
|
IN IIrpTarget * Target,
|
||||||
|
IN LPWSTR Name)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KSOBJECT_HEADER ObjectHeader;
|
KSOBJECT_HEADER ObjectHeader;
|
||||||
|
@ -223,6 +224,7 @@ NewDispatchObject(
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
CreateItem->Context = (PVOID)Target;
|
CreateItem->Context = (PVOID)Target;
|
||||||
|
RtlInitUnicodeString(&CreateItem->ObjectClass, Name);
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
ASSERT(IoStack->FileObject);
|
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 */
|
/* release reference to port */
|
||||||
This->Port->lpVtbl->Release(This->Port);
|
This->Port->lpVtbl->Release(This->Port);
|
||||||
|
|
||||||
|
/* get the miniport driver */
|
||||||
Miniport = GetWaveCyclicMiniport(This->Port);
|
Miniport = GetWaveCyclicMiniport(This->Port);
|
||||||
|
/* release miniport driver */
|
||||||
Miniport->lpVtbl->Release(Miniport);
|
Miniport->lpVtbl->Release(Miniport);
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,7 +258,7 @@ IPortFilterWaveCyclic_fnClose(
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -687,4 +687,26 @@ DECLARE_INTERFACE_(IDmaChannelInit, IUnknown)
|
||||||
|
|
||||||
#undef INTERFACE
|
#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
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@ typedef struct
|
||||||
|
|
||||||
PPCFILTER_DESCRIPTOR pDescriptor;
|
PPCFILTER_DESCRIPTOR pDescriptor;
|
||||||
PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
|
PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
|
||||||
|
IPortFilterTopology * Filter;
|
||||||
}IPortTopologyImpl;
|
}IPortTopologyImpl;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -44,27 +45,26 @@ static GUID InterfaceGuids[2] =
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterTopologyTopologySet, TopologyPropertyHandler);
|
||||||
static
|
DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterTopologyPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler);
|
||||||
KSPROPERTY_SET PinPropertySet =
|
|
||||||
{
|
|
||||||
&KSPROPSETID_Pin,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static
|
KSPROPERTY_SET TopologyPropertySet[] =
|
||||||
KSPROPERTY_SET TopologyPropertySet =
|
{
|
||||||
{
|
{
|
||||||
&KSPROPSETID_Topology,
|
&KSPROPSETID_Topology,
|
||||||
4,
|
sizeof(PortFilterTopologyTopologySet) / sizeof(KSPROPERTY_ITEM),
|
||||||
NULL,
|
(const KSPROPERTY_ITEM*)&PortFilterTopologyTopologySet,
|
||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&KSPROPSETID_Pin,
|
||||||
|
sizeof(PortFilterTopologyPinSet) / sizeof(KSPROPERTY_ITEM),
|
||||||
|
(const KSPROPERTY_ITEM*)&PortFilterTopologyPinSet,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
@ -228,8 +228,8 @@ IPortTopology_fnInit(
|
||||||
InterfaceGuids,
|
InterfaceGuids,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
2,
|
||||||
NULL,
|
TopologyPropertySet,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -339,10 +339,45 @@ ISubDevice_fnNewIrpTarget(
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN KSOBJECT_CREATE *CreateObject)
|
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
|
/* is there already an instance of the filter */
|
||||||
return STATUS_UNSUCCESSFUL;
|
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
|
static
|
||||||
|
@ -366,7 +401,7 @@ ISubDevice_fnGetDescriptor(
|
||||||
{
|
{
|
||||||
IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice);
|
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;
|
*Descriptor = This->SubDeviceDescriptor;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -477,7 +512,7 @@ CreatePinWorkerRoutine(
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* create the dispatch object */
|
/* create the dispatch object */
|
||||||
Status = NewDispatchObject(WorkerContext->Irp, Pin);
|
Status = NewDispatchObject(WorkerContext->Irp, Pin, NULL);
|
||||||
DPRINT("Pin %p\n", Pin);
|
DPRINT("Pin %p\n", Pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +608,7 @@ PcCreateItemDispatch(
|
||||||
if (IoStack->FileObject->FileName.Buffer == NULL)
|
if (IoStack->FileObject->FileName.Buffer == NULL)
|
||||||
{
|
{
|
||||||
/* create the dispatch object */
|
/* create the dispatch object */
|
||||||
Status = NewDispatchObject(Irp, Filter);
|
Status = NewDispatchObject(Irp, Filter, CreateItem->ObjectClass.Buffer);
|
||||||
|
|
||||||
DPRINT1("Filter %p\n", Filter);
|
DPRINT1("Filter %p\n", Filter);
|
||||||
}
|
}
|
||||||
|
@ -645,3 +680,11 @@ NewPortTopology(
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
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);
|
DPRINT("ISubDevice_NewIrpTarget this %p\n", This);
|
||||||
|
|
||||||
|
/* is there already an instance of the filter */
|
||||||
if (This->Filter)
|
if (This->Filter)
|
||||||
{
|
{
|
||||||
|
/* it is, let's return the result */
|
||||||
*OutTarget = (IIrpTarget*)This->Filter;
|
*OutTarget = (IIrpTarget*)This->Filter;
|
||||||
|
|
||||||
|
/* increment reference */
|
||||||
|
This->Filter->lpVtbl->AddRef(This->Filter);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* create new instance of filter */
|
||||||
Status = NewPortFilterWaveCyclic(&Filter);
|
Status = NewPortFilterWaveCyclic(&Filter);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* not enough memory */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize the filter */
|
||||||
Status = Filter->lpVtbl->Init(Filter, (IPortWaveCyclic*)This);
|
Status = Filter->lpVtbl->Init(Filter, (IPortWaveCyclic*)This);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* destroy filter */
|
||||||
Filter->lpVtbl->Release(Filter);
|
Filter->lpVtbl->Release(Filter);
|
||||||
|
/* return status */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* store result */
|
||||||
*OutTarget = (IIrpTarget*)Filter;
|
*OutTarget = (IIrpTarget*)Filter;
|
||||||
|
/* store for later re-use */
|
||||||
This->Filter = Filter;
|
This->Filter = Filter;
|
||||||
|
/* return status */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
<file>dma_slave.c</file>
|
<file>dma_slave.c</file>
|
||||||
<file>drm.c</file>
|
<file>drm.c</file>
|
||||||
<file>drm_port.c</file>
|
<file>drm_port.c</file>
|
||||||
|
<file>filter_topology.c</file>
|
||||||
<file>filter_dmus.c</file>
|
<file>filter_dmus.c</file>
|
||||||
<file>filter_wavecyclic.c</file>
|
<file>filter_wavecyclic.c</file>
|
||||||
<file>filter_wavepci.c</file>
|
<file>filter_wavepci.c</file>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#include <portcls.h>
|
#include <portcls.h>
|
||||||
#define NDEBUG
|
#define YDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <dmusicks.h>
|
#include <dmusicks.h>
|
||||||
|
@ -147,11 +147,20 @@ NewPortWaveRT(
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NewPortFilterTopology(
|
||||||
|
OUT IPortFilterTopology ** OutFilter);
|
||||||
|
|
||||||
|
PMINIPORTTOPOLOGY
|
||||||
|
GetTopologyMiniport(
|
||||||
|
PPORTTOPOLOGY Port);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NewDispatchObject(
|
NewDispatchObject(
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN IIrpTarget * Target);
|
IN IIrpTarget * Target,
|
||||||
|
IN LPWSTR Name);
|
||||||
|
|
||||||
PMINIPORTWAVECYCLIC
|
PMINIPORTWAVECYCLIC
|
||||||
GetWaveCyclicMiniport(
|
GetWaveCyclicMiniport(
|
||||||
|
|
|
@ -44,6 +44,7 @@ GetFilterIdAndPinId(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KSPIN_COMMUNICATION Communication;
|
KSPIN_COMMUNICATION Communication;
|
||||||
KSPIN_DATAFLOW DataFlow;
|
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)
|
||||||
{
|
{
|
||||||
|
@ -55,7 +56,9 @@ GetFilterIdAndPinId(
|
||||||
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
||||||
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
@ -69,7 +72,7 @@ GetFilterIdAndPinId(
|
||||||
Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
|
Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
|
||||||
Pin.PinId = 0;
|
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))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* enumerate now all pins */
|
/* enumerate now all pins */
|
||||||
|
@ -80,13 +83,13 @@ GetFilterIdAndPinId(
|
||||||
Communication = KSPIN_COMMUNICATION_NONE;
|
Communication = KSPIN_COMMUNICATION_NONE;
|
||||||
|
|
||||||
/* get pin communication type */
|
/* 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;
|
Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
|
||||||
DataFlow = 0;
|
DataFlow = 0;
|
||||||
|
|
||||||
/* get pin dataflow type */
|
/* 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)
|
if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
|
@ -132,6 +135,7 @@ WdmAudControlOpen(
|
||||||
IN PWDMAUD_CLIENT ClientInfo)
|
IN PWDMAUD_CLIENT ClientInfo)
|
||||||
{
|
{
|
||||||
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ACCESS_MASK DesiredAccess = 0;
|
ACCESS_MASK DesiredAccess = 0;
|
||||||
|
@ -169,7 +173,9 @@ WdmAudControlOpen(
|
||||||
InstanceInfo->Flags = 0;
|
InstanceInfo->Flags = 0;
|
||||||
InstanceInfo->DeviceNumber = FilterId;
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -204,7 +210,7 @@ WdmAudControlOpen(
|
||||||
PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
|
PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
|
||||||
PinConnect->Medium.Flags = 0;
|
PinConnect->Medium.Flags = 0;
|
||||||
PinConnect->PinId = PinId;
|
PinConnect->PinId = PinId;
|
||||||
PinConnect->PinToHandle = ClientInfo->hSysAudio;
|
PinConnect->PinToHandle = DeviceExtension->hSysAudio;
|
||||||
PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
|
PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
|
||||||
PinConnect->Priority.PrioritySubClass = 1;
|
PinConnect->Priority.PrioritySubClass = 1;
|
||||||
|
|
||||||
|
@ -231,7 +237,7 @@ WdmAudControlOpen(
|
||||||
|
|
||||||
/* ros specific pin creation request */
|
/* ros specific pin creation request */
|
||||||
InstanceInfo->Property.Id = (ULONG)-1;
|
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))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PHANDLE Handels;
|
PHANDLE Handels;
|
||||||
|
@ -283,8 +289,9 @@ WdmAudControlDeviceType(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KSPIN_COMMUNICATION Communication;
|
KSPIN_COMMUNICATION Communication;
|
||||||
KSPIN_DATAFLOW DataFlow;
|
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);
|
DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
|
||||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||||
|
@ -294,7 +301,8 @@ WdmAudControlDeviceType(
|
||||||
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
|
||||||
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status);
|
DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status);
|
||||||
|
@ -311,7 +319,7 @@ WdmAudControlDeviceType(
|
||||||
Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
|
Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
|
||||||
Pin.PinId = 0;
|
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))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* enumerate now all pins */
|
/* enumerate now all pins */
|
||||||
|
@ -322,13 +330,17 @@ WdmAudControlDeviceType(
|
||||||
Communication = KSPIN_COMMUNICATION_NONE;
|
Communication = KSPIN_COMMUNICATION_NONE;
|
||||||
|
|
||||||
/* get pin communication type */
|
/* 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;
|
Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
|
||||||
DataFlow = 0;
|
DataFlow = 0;
|
||||||
|
|
||||||
/* get pin dataflow type */
|
/* 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)
|
if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
|
@ -432,6 +444,7 @@ WdmAudCapabilities(
|
||||||
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
IN PWDMAUD_CLIENT ClientInfo)
|
IN PWDMAUD_CLIENT ClientInfo)
|
||||||
{
|
{
|
||||||
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||||
KSP_PIN PinProperty;
|
KSP_PIN PinProperty;
|
||||||
KSCOMPONENTID ComponentId;
|
KSCOMPONENTID ComponentId;
|
||||||
|
@ -462,7 +475,8 @@ WdmAudCapabilities(
|
||||||
|
|
||||||
RtlZeroMemory(&ComponentId, sizeof(KSCOMPONENTID));
|
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))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7;
|
DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7;
|
||||||
|
@ -476,7 +490,7 @@ WdmAudCapabilities(
|
||||||
PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
|
PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
|
||||||
BytesReturned = 0;
|
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)
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||||
{
|
{
|
||||||
return SetIrpIoStatus(Irp, Status, 0);
|
return SetIrpIoStatus(Irp, Status, 0);
|
||||||
|
@ -489,7 +503,7 @@ WdmAudCapabilities(
|
||||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ExFreePool(MultipleItem);
|
ExFreePool(MultipleItem);
|
||||||
|
|
|
@ -94,6 +94,8 @@ WdmAudOpenSysAudioDevices(
|
||||||
LPWSTR SymbolicLinkList;
|
LPWSTR SymbolicLinkList;
|
||||||
SYSAUDIO_ENTRY * Entry;
|
SYSAUDIO_ENTRY * Entry;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
HANDLE hSysAudio;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio");
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio");
|
||||||
|
|
||||||
if (DeviceExtension->DeviceInterfaceSupport)
|
if (DeviceExtension->DeviceInterfaceSupport)
|
||||||
|
@ -135,7 +137,28 @@ WdmAudOpenSysAudioDevices(
|
||||||
|
|
||||||
InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
|
InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
|
||||||
DeviceExtension->NumSysAudioDevices++;
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,10 +203,6 @@ WdmAudOpenSysaudio(
|
||||||
IN PWDMAUD_CLIENT *pClient)
|
IN PWDMAUD_CLIENT *pClient)
|
||||||
{
|
{
|
||||||
PWDMAUD_CLIENT Client;
|
PWDMAUD_CLIENT Client;
|
||||||
NTSTATUS Status;
|
|
||||||
HANDLE hSysAudio;
|
|
||||||
PSYSAUDIO_ENTRY SysEntry;
|
|
||||||
PFILE_OBJECT FileObject;
|
|
||||||
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
@ -200,34 +219,6 @@ WdmAudOpenSysaudio(
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT));
|
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;
|
*pClient = Client;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -215,8 +215,6 @@ WdmAudCleanup(
|
||||||
ExFreePool(pClient->hPins);
|
ExFreePool(pClient->hPins);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject(pClient->FileObject);
|
|
||||||
ZwClose(pClient->hSysAudio);
|
|
||||||
ExFreePool(pClient);
|
ExFreePool(pClient);
|
||||||
IoStack->FileObject->FsContext = NULL;
|
IoStack->FileObject->FsContext = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#include <portcls.h>
|
#include <portcls.h>
|
||||||
#include <ks.h>
|
#include <ks.h>
|
||||||
#define NDEBUG
|
#define YDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <ksmedia.h>
|
#include <ksmedia.h>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
|
@ -15,8 +15,6 @@
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
HANDLE hSysAudio;
|
|
||||||
PFILE_OBJECT FileObject;
|
|
||||||
ULONG NumPins;
|
ULONG NumPins;
|
||||||
HANDLE * hPins;
|
HANDLE * hPins;
|
||||||
|
|
||||||
|
@ -38,6 +36,8 @@ typedef struct
|
||||||
KSPIN_LOCK Lock;
|
KSPIN_LOCK Lock;
|
||||||
ULONG NumSysAudioDevices;
|
ULONG NumSysAudioDevices;
|
||||||
LIST_ENTRY SysAudioDeviceList;
|
LIST_ENTRY SysAudioDeviceList;
|
||||||
|
HANDLE hSysAudio;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
|
||||||
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
|
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,95 @@ const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ComputeCompatibleFormat(
|
ComputeCompatibleFormat(
|
||||||
IN PKSAUDIO_DEVICE_ENTRY Entry,
|
IN PKSAUDIO_SUBDEVICE_ENTRY Entry,
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
IN PSYSAUDIODEVEXT DeviceExtension,
|
IN PSYSAUDIODEVEXT DeviceExtension,
|
||||||
IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
|
IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
|
||||||
OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat);
|
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
|
NTSTATUS
|
||||||
SetIrpIoStatus(
|
SetIrpIoStatus(
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
|
@ -46,20 +128,39 @@ SetIrpIoStatus(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PKSAUDIO_DEVICE_ENTRY
|
PKSAUDIO_SUBDEVICE_ENTRY
|
||||||
GetListEntry(
|
GetListEntry(
|
||||||
IN PLIST_ENTRY Head,
|
IN PLIST_ENTRY Head,
|
||||||
IN ULONG Index)
|
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;
|
Entry = Entry->Flink;
|
||||||
|
|
||||||
if (Entry == Head)
|
}
|
||||||
|
DPRINT1("Not Found index %u\n", Index);
|
||||||
|
DbgBreakPoint();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -69,7 +170,7 @@ SysAudioOpenVirtualDevice(
|
||||||
PSYSAUDIODEVEXT DeviceExtension)
|
PSYSAUDIODEVEXT DeviceExtension)
|
||||||
{
|
{
|
||||||
PSYSAUDIO_CLIENT ClientInfo;
|
PSYSAUDIO_CLIENT ClientInfo;
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
|
||||||
/* access the create item */
|
/* access the create item */
|
||||||
|
@ -99,9 +200,6 @@ SysAudioOpenVirtualDevice(
|
||||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber);
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber);
|
||||||
ASSERT(Entry != NULL);
|
ASSERT(Entry != NULL);
|
||||||
|
|
||||||
/* increase usage count */
|
|
||||||
Entry->NumberOfClients++;
|
|
||||||
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,13 +315,12 @@ CreatePinWorkerRoutine(
|
||||||
ASSERT(WorkerContext->Entry->Pins);
|
ASSERT(WorkerContext->Entry->Pins);
|
||||||
ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId);
|
ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId);
|
||||||
|
|
||||||
|
|
||||||
/* Fetch input format */
|
/* Fetch input format */
|
||||||
InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(WorkerContext->PinConnect + 1);
|
InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(WorkerContext->PinConnect + 1);
|
||||||
|
|
||||||
|
|
||||||
/* Let's try to create the audio irp pin */
|
/* 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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -260,7 +357,7 @@ CreatePinWorkerRoutine(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retry with Mixer format */
|
/* 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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* This should not fail */
|
/* This should not fail */
|
||||||
|
@ -432,7 +529,7 @@ HandleSysAudioFilterPinProperties(
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
PKSP_PIN Pin;
|
PKSP_PIN Pin;
|
||||||
|
|
||||||
|
@ -519,7 +616,7 @@ HandleSysAudioFilterPinProperties(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ComputeCompatibleFormat(
|
ComputeCompatibleFormat(
|
||||||
IN PKSAUDIO_DEVICE_ENTRY Entry,
|
IN PKSAUDIO_SUBDEVICE_ENTRY Entry,
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
IN PSYSAUDIODEVEXT DeviceExtension,
|
IN PSYSAUDIODEVEXT DeviceExtension,
|
||||||
IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
|
IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
|
||||||
|
@ -653,7 +750,7 @@ ComputeCompatibleFormat(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
GetPinInstanceCount(
|
GetPinInstanceCount(
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry,
|
PKSAUDIO_SUBDEVICE_ENTRY Entry,
|
||||||
PKSPIN_CINSTANCES PinInstances,
|
PKSPIN_CINSTANCES PinInstances,
|
||||||
PKSPIN_CONNECT PinConnect)
|
PKSPIN_CONNECT PinConnect)
|
||||||
{
|
{
|
||||||
|
@ -723,7 +820,7 @@ HandleSysAudioFilterPinCreation(
|
||||||
PDEVICE_OBJECT DeviceObject)
|
PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||||
KSPIN_CONNECT * PinConnect;
|
KSPIN_CONNECT * PinConnect;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
||||||
|
@ -886,7 +983,7 @@ SysAudioHandleProperty(
|
||||||
PULONG Index;
|
PULONG Index;
|
||||||
PKSPROPERTY Property;
|
PKSPROPERTY Property;
|
||||||
PSYSAUDIODEVEXT DeviceExtension;
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||||
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
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_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 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_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}};
|
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
|
VOID
|
||||||
NTAPI
|
QueryFilterRoutine(
|
||||||
FilterPinWorkerRoutine(
|
IN PKSAUDIO_SUBDEVICE_ENTRY DeviceEntry)
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PVOID Context)
|
|
||||||
{
|
{
|
||||||
KSPROPERTY PropertyRequest;
|
KSPROPERTY PropertyRequest;
|
||||||
KSP_PIN PinRequest;
|
KSP_PIN PinRequest;
|
||||||
|
@ -27,15 +28,19 @@ FilterPinWorkerRoutine(
|
||||||
ULONG Count, Index;
|
ULONG Count, Index;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
PSYSAUDIODEVEXT DeviceExtension;
|
ULONG NumWaveOutPin, NumWaveInPin;
|
||||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
|
|
||||||
PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context;
|
|
||||||
|
|
||||||
DeviceEntry = Ctx->DeviceEntry;
|
|
||||||
|
|
||||||
|
|
||||||
DPRINT("Querying filter...\n");
|
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.Set = KSPROPSETID_Pin;
|
||||||
PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
|
PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
|
||||||
PropertyRequest.Id = KSPROPERTY_PIN_CTYPES;
|
PropertyRequest.Id = KSPROPERTY_PIN_CTYPES;
|
||||||
|
@ -45,13 +50,13 @@ FilterPinWorkerRoutine(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to query number of pins Status %x\n", Status);
|
DPRINT1("Failed to query number of pins Status %x\n", Status);
|
||||||
goto cleanup;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Count)
|
if (!Count)
|
||||||
{
|
{
|
||||||
DPRINT1("Filter has no pins!\n");
|
DPRINT1("Filter has no pins!\n");
|
||||||
goto cleanup;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate pin array */
|
/* allocate pin array */
|
||||||
|
@ -60,12 +65,14 @@ FilterPinWorkerRoutine(
|
||||||
{
|
{
|
||||||
/* no memory */
|
/* no memory */
|
||||||
DPRINT1("Failed to allocate memory Pins %u Block %x\n", Count, Count * sizeof(PIN_INFO));
|
DPRINT1("Failed to allocate memory Pins %u Block %x\n", Count, Count * sizeof(PIN_INFO));
|
||||||
goto cleanup;
|
return;
|
||||||
}
|
}
|
||||||
/* clear array */
|
/* clear array */
|
||||||
RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count);
|
RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count);
|
||||||
DeviceEntry->NumberOfPins = Count;
|
DeviceEntry->NumberOfPins = Count;
|
||||||
|
|
||||||
|
NumWaveInPin = 0;
|
||||||
|
NumWaveOutPin = 0;
|
||||||
for(Index = 0; Index < Count; Index++)
|
for(Index = 0; Index < Count; Index++)
|
||||||
{
|
{
|
||||||
/* get max instance count */
|
/* get max instance count */
|
||||||
|
@ -97,20 +104,41 @@ FilterPinWorkerRoutine(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
|
if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
|
||||||
DeviceEntry->NumWaveOutPin++;
|
NumWaveOutPin++;
|
||||||
|
|
||||||
if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
|
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);
|
DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, NumWaveInPin, 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);
|
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 */
|
/* free work item */
|
||||||
IoFreeWorkItem(Ctx->WorkItem);
|
IoFreeWorkItem(Ctx->WorkItem);
|
||||||
|
@ -118,14 +146,6 @@ FilterPinWorkerRoutine(
|
||||||
ExFreePool(Ctx);
|
ExFreePool(Ctx);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cleanup:
|
|
||||||
|
|
||||||
ObDereferenceObject(DeviceEntry->FileObject);
|
|
||||||
ZwClose(DeviceEntry->Handle);
|
|
||||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
|
||||||
ExFreePool(DeviceEntry);
|
|
||||||
IoFreeWorkItem(Ctx->WorkItem);
|
|
||||||
ExFreePool(Ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -184,6 +204,7 @@ DeviceInterfaceChangeCallback(
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PSYSAUDIODEVEXT DeviceExtension;
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL;
|
PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL;
|
||||||
|
PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry;
|
||||||
PIO_WORKITEM WorkItem = NULL;
|
PIO_WORKITEM WorkItem = NULL;
|
||||||
PFILTER_WORKER_CONTEXT Ctx = NULL;
|
PFILTER_WORKER_CONTEXT Ctx = NULL;
|
||||||
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
|
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
|
||||||
|
@ -195,6 +216,7 @@ DeviceInterfaceChangeCallback(
|
||||||
if (IsEqualGUIDAligned(&Event->Event,
|
if (IsEqualGUIDAligned(&Event->Event,
|
||||||
&GUID_DEVICE_INTERFACE_ARRIVAL))
|
&GUID_DEVICE_INTERFACE_ARRIVAL))
|
||||||
{
|
{
|
||||||
|
|
||||||
/* a new device has arrived */
|
/* a new device has arrived */
|
||||||
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
|
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
|
||||||
if (!DeviceEntry)
|
if (!DeviceEntry)
|
||||||
|
@ -226,7 +248,7 @@ DeviceInterfaceChangeCallback(
|
||||||
|
|
||||||
/* set device name */
|
/* set device name */
|
||||||
DeviceEntry->DeviceName.Length = 0;
|
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);
|
DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
|
||||||
|
|
||||||
if (!DeviceEntry->DeviceName.Buffer)
|
if (!DeviceEntry->DeviceName.Buffer)
|
||||||
|
@ -247,18 +269,42 @@ DeviceInterfaceChangeCallback(
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject);
|
/* FIXME Ros does not support device interface strings */
|
||||||
if (!NT_SUCCESS(Status))
|
/* Workarround: repeatly call IoCreateFile untill ks wont find a create item which has no object header attached */
|
||||||
{
|
|
||||||
DPRINT("ZwCreateFile failed with %x\n", Status);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
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->DeviceEntry = DeviceEntry;
|
||||||
Ctx->WorkItem = WorkItem;
|
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);
|
IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ Dispatch_fnClose(
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PSYSAUDIO_CLIENT Client;
|
PSYSAUDIO_CLIENT Client;
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||||
PIO_STACK_LOCATION IoStatus;
|
PIO_STACK_LOCATION IoStatus;
|
||||||
ULONG Index, SubIndex;
|
ULONG Index, SubIndex;
|
||||||
PSYSAUDIODEVEXT DeviceExtension;
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
|
|
|
@ -34,8 +34,9 @@ SysAudio_Shutdown(
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
|
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
|
||||||
|
PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry;
|
||||||
PSYSAUDIODEVEXT DeviceExtension;
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry, SubEntry;
|
||||||
|
|
||||||
DPRINT1("SysAudio_Shutdown called\n");
|
DPRINT1("SysAudio_Shutdown called\n");
|
||||||
|
|
||||||
|
@ -48,9 +49,17 @@ SysAudio_Shutdown(
|
||||||
|
|
||||||
DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName);
|
DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName);
|
||||||
RtlFreeUnicodeString(&DeviceEntry->DeviceName);
|
RtlFreeUnicodeString(&DeviceEntry->DeviceName);
|
||||||
ZwClose(DeviceEntry->Handle);
|
|
||||||
ObDereferenceObject(DeviceEntry->FileObject);
|
while(!IsListEmpty(&DeviceEntry->SubDeviceList))
|
||||||
ExFreePool(DeviceEntry->Pins);
|
{
|
||||||
|
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);
|
ExFreePool(DeviceEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
#include <ks.h>
|
#include <ks.h>
|
||||||
#include <ksmedia.h>
|
#include <ksmedia.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#define NDEBUG
|
#define YDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -43,20 +44,27 @@ typedef struct
|
||||||
KSPIN_COMMUNICATION Communication; // pin type
|
KSPIN_COMMUNICATION Communication; // pin type
|
||||||
}PIN_INFO;
|
}PIN_INFO;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry; // device entry for KsAudioDeviceList
|
LIST_ENTRY Entry; // linked list entry to KSAUDIO_DEVICE_ENTRY
|
||||||
HANDLE Handle; // handle to audio device
|
|
||||||
PFILE_OBJECT FileObject; // file object for audio device
|
HANDLE Handle; // handle to audio sub device
|
||||||
UNICODE_STRING DeviceName; // symbolic link of audio device
|
PFILE_OBJECT FileObject; // file objecto to audio sub device
|
||||||
ULONG NumberOfClients; // number of clients referenced audio device
|
|
||||||
|
|
||||||
ULONG NumberOfPins; // number of pins of audio device
|
ULONG NumberOfPins; // number of pins of audio device
|
||||||
PIN_INFO * Pins; // array of PIN_INFO
|
PIN_INFO * Pins; // array of PIN_INFO
|
||||||
|
|
||||||
ULONG NumWaveOutPin; // number of wave out pins
|
LPWSTR ObjectClass; // object class of sub device
|
||||||
ULONG NumWaveInPin; // number of wave in pins
|
|
||||||
|
}KSAUDIO_SUBDEVICE_ENTRY, *PKSAUDIO_SUBDEVICE_ENTRY;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LIST_ENTRY Entry; // device entry for KsAudioDeviceList
|
||||||
|
UNICODE_STRING DeviceName; // symbolic link of audio device
|
||||||
|
|
||||||
|
ULONG NumSubDevices; // number of subdevices
|
||||||
|
LIST_ENTRY SubDeviceList; // audio sub device list
|
||||||
|
|
||||||
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
|
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
|
||||||
|
|
||||||
|
@ -88,7 +96,7 @@ typedef struct
|
||||||
HANDLE Handle; // audio irp pin handle
|
HANDLE Handle; // audio irp pin handle
|
||||||
PFILE_OBJECT FileObject; // audio irp pin file object
|
PFILE_OBJECT FileObject; // audio irp pin file object
|
||||||
ULONG PinId; // pin id of device
|
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
|
HANDLE hMixerPin; // handle to mixer pin
|
||||||
PFILE_OBJECT MixerFileObject; // mixer file object
|
PFILE_OBJECT MixerFileObject; // mixer file object
|
||||||
|
@ -104,7 +112,7 @@ typedef struct
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
BOOL CreateRealPin;
|
BOOL CreateRealPin;
|
||||||
BOOL CreateMixerPin;
|
BOOL CreateMixerPin;
|
||||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||||
KSPIN_CONNECT * PinConnect;
|
KSPIN_CONNECT * PinConnect;
|
||||||
PDISPATCH_CONTEXT DispatchContext;
|
PDISPATCH_CONTEXT DispatchContext;
|
||||||
PSYSAUDIO_CLIENT AudioClient;
|
PSYSAUDIO_CLIENT AudioClient;
|
||||||
|
@ -148,7 +156,7 @@ OpenDevice(
|
||||||
IN PHANDLE HandleOut,
|
IN PHANDLE HandleOut,
|
||||||
IN PFILE_OBJECT * FileObjectOut);
|
IN PFILE_OBJECT * FileObjectOut);
|
||||||
|
|
||||||
PKSAUDIO_DEVICE_ENTRY
|
PKSAUDIO_SUBDEVICE_ENTRY
|
||||||
GetListEntry(
|
GetListEntry(
|
||||||
IN PLIST_ENTRY Head,
|
IN PLIST_ENTRY Head,
|
||||||
IN ULONG Index);
|
IN ULONG Index);
|
||||||
|
|
Loading…
Reference in a new issue