[SYSAUDIO]

- Don't build the pin descriptor as this will make problems with dynamic audio devices which dynamically adjust their audio pins
- Remove dead code

svn path=/trunk/; revision=47225
This commit is contained in:
Johannes Anderwald 2010-05-15 19:05:58 +00:00
parent 33284498ec
commit 0e5b61c534
5 changed files with 60 additions and 243 deletions

View file

@ -97,7 +97,6 @@ HandleSysAudioFilterPinProperties(
NTSTATUS Status;
PKSAUDIO_DEVICE_ENTRY Entry;
ULONG BytesReturned;
PKSP_PIN Pin;
// in order to access pin properties of a sysaudio device
// the caller must provide a KSP_PIN struct, where
@ -110,8 +109,6 @@ HandleSysAudioFilterPinProperties(
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY) + sizeof(ULONG));
}
Pin = (PKSP_PIN)Property;
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, ((KSP_PIN*)Property)->Reserved);
if (!Entry)
{
@ -119,64 +116,15 @@ HandleSysAudioFilterPinProperties(
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
}
if (!Entry->Pins)
{
/* expected pins */
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
}
if (Entry->PinDescriptorsCount <= Pin->PinId)
{
/* invalid pin id */
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
}
if (Property->Id == KSPROPERTY_PIN_CTYPES)
{
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
{
/* too small buffer */
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
}
/* store result */
*((PULONG)Irp->UserBuffer) = Entry->PinDescriptorsCount;
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
}
else if (Property->Id == KSPROPERTY_PIN_COMMUNICATION)
{
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPIN_COMMUNICATION))
{
/* too small buffer */
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPIN_COMMUNICATION));
}
/* store result */
*((KSPIN_COMMUNICATION*)Irp->UserBuffer) = Entry->PinDescriptors[Pin->PinId].Communication;
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSPIN_COMMUNICATION));
}
else if (Property->Id == KSPROPERTY_PIN_DATAFLOW)
{
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPIN_DATAFLOW))
{
/* too small buffer */
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPIN_DATAFLOW));
}
/* store result */
*((KSPIN_DATAFLOW*)Irp->UserBuffer) = Entry->PinDescriptors[Pin->PinId].DataFlow;
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSPIN_DATAFLOW));
}
else
{
/* forward request to the filter implementing the property */
Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY,
/* forward request to the filter implementing the property */
Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY,
(PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
IoStack->Parameters.DeviceIoControl.InputBufferLength,
Irp->UserBuffer,
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
&BytesReturned);
return SetIrpIoStatus(Irp, Status, BytesReturned);
}
return SetIrpIoStatus(Irp, Status, BytesReturned);
}
@ -328,7 +276,7 @@ GetPinInstanceCount(
PinRequest.Property.Set = KSPROPSETID_Pin;
PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
ASSERT(Entry->FileObject);
return KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
}

View file

@ -14,139 +14,6 @@ const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {
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}};
NTSTATUS
BuildPinDescriptor(
IN PKSAUDIO_DEVICE_ENTRY DeviceEntry,
IN ULONG Count)
{
ULONG Index;
KSP_PIN PinRequest;
KSPIN_DATAFLOW DataFlow;
KSPIN_COMMUNICATION Communication;
ULONG NumWaveOutPin, NumWaveInPin;
NTSTATUS Status;
ULONG BytesReturned;
NumWaveInPin = 0;
NumWaveOutPin = 0;
for(Index = 0; Index < Count; Index++)
{
/* retrieve data flow */
PinRequest.PinId = Index;
PinRequest.Property.Set = KSPROPSETID_Pin;
PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
/* get dataflow direction */
PinRequest.Property.Id = KSPROPERTY_PIN_DATAFLOW;
Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
if (NT_SUCCESS(Status))
{
DeviceEntry->PinDescriptors[Index].DataFlow = DataFlow;
}
/* get irp flow direction */
PinRequest.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
if (NT_SUCCESS(Status))
{
DeviceEntry->PinDescriptors[Index].Communication = Communication;
}
if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
NumWaveOutPin++;
if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
NumWaveInPin++;
/* FIXME query for interface, dataformat etc */
}
DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->PinDescriptorsCount, NumWaveInPin, NumWaveOutPin);
return STATUS_SUCCESS;
}
VOID
QueryFilterRoutine(
IN PKSAUDIO_DEVICE_ENTRY DeviceEntry)
{
KSPROPERTY PropertyRequest;
ULONG Count;
NTSTATUS Status;
ULONG BytesReturned;
DPRINT("Querying filter...\n");
PropertyRequest.Set = KSPROPSETID_Pin;
PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
PropertyRequest.Id = KSPROPERTY_PIN_CTYPES;
/* query for num of pins */
Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to query number of pins Status %x\n", Status);
return;
}
if (!Count)
{
DPRINT1("Filter has no pins!\n");
return;
}
/* allocate pin descriptor array */
DeviceEntry->PinDescriptors = ExAllocatePool(NonPagedPool, Count * sizeof(KSPIN_DESCRIPTOR));
if (!DeviceEntry->PinDescriptors)
{
/* no memory */
return;
}
/* zero array pin descriptor array */
RtlZeroMemory(DeviceEntry->PinDescriptors, Count * sizeof(KSPIN_DESCRIPTOR));
/* build the device descriptor */
Status = BuildPinDescriptor(DeviceEntry, Count);
if (!NT_SUCCESS(Status))
return;
/* allocate pin array */
DeviceEntry->Pins = ExAllocatePool(NonPagedPool, Count * sizeof(PIN_INFO));
if (!DeviceEntry->Pins)
{
/* no memory */
DPRINT1("Failed to allocate memory Pins %u Block %x\n", Count, Count * sizeof(PIN_INFO));
return;
}
/* clear array */
RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count);
DeviceEntry->PinDescriptorsCount = Count;
}
VOID
NTAPI
FilterPinWorkerRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context;
DeviceEntry = Ctx->DeviceEntry;
QueryFilterRoutine(DeviceEntry);
/* free work item */
IoFreeWorkItem(Ctx->WorkItem);
/* free work item context */
ExFreePool(Ctx);
return;
}
NTSTATUS
OpenDevice(
IN PUNICODE_STRING DeviceName,
@ -199,8 +66,6 @@ InsertAudioDevice(
IN PUNICODE_STRING DeviceName)
{
NTSTATUS Status = STATUS_SUCCESS;
PFILTER_WORKER_CONTEXT Ctx = NULL;
PIO_WORKITEM WorkItem = NULL;
PSYSAUDIODEVEXT DeviceExtension;
PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL;
@ -215,24 +80,6 @@ InsertAudioDevice(
/* initialize audio device entry */
RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY));
/* allocate filter ctx */
Ctx = ExAllocatePool(NonPagedPool, sizeof(FILTER_WORKER_CONTEXT));
if (!Ctx)
{
/* no memory */
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
/* allocate work item */
WorkItem = IoAllocateWorkItem(DeviceObject);
if (!WorkItem)
{
/* no memory */
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
/* set device name */
DeviceEntry->DeviceName.Length = 0;
DeviceEntry->DeviceName.MaximumLength = DeviceName->MaximumLength + 10 * sizeof(WCHAR);
@ -255,9 +102,6 @@ InsertAudioDevice(
goto cleanup;
}
Ctx->DeviceEntry = DeviceEntry;
Ctx->WorkItem = WorkItem;
/* fetch device extension */
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
/* insert new audio device */
@ -265,16 +109,9 @@ InsertAudioDevice(
InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices);
DPRINT("Successfully opened audio device %u Device %S\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->DeviceName.Buffer);
IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx);
return Status;
cleanup:
if (Ctx)
ExFreePool(Ctx);
if (WorkItem)
IoFreeWorkItem(WorkItem);
if (DeviceEntry)
{
if (DeviceEntry->DeviceName.Buffer)

View file

@ -53,10 +53,10 @@ SysAudio_Shutdown(
/* close audio device handle */
ZwClose(DeviceEntry->Handle);
/* free device string */
RtlFreeUnicodeString(&DeviceEntry->DeviceName);
/* free pins */
ExFreePool(DeviceEntry->Pins);
/* free audio device entry */
ExFreePool(DeviceEntry);
}

View file

@ -354,7 +354,7 @@ InstantiatePins(
}
#endif
DeviceEntry->Pins[Connect->PinId].References = 0;
//DeviceEntry->Pins[Connect->PinId].References = 0;
/* initialize dispatch context */
DispatchContext->Handle = RealPinHandle;
@ -385,6 +385,44 @@ InstantiatePins(
return Status;
}
NTSTATUS
GetConnectRequest(
IN PIRP Irp,
OUT PKSPIN_CONNECT * Result)
{
PIO_STACK_LOCATION IoStack;
ULONG ObjectLength, ParametersLength;
PVOID Buffer;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* get object class length */
ObjectLength = (wcslen(KSSTRING_Pin) + 2) * sizeof(WCHAR);
/* check for minium length requirement */
if (ObjectLength + sizeof(KSPIN_CONNECT) > IoStack->FileObject->FileName.MaximumLength)
return STATUS_UNSUCCESSFUL;
/* extract parameters length */
ParametersLength = IoStack->FileObject->FileName.MaximumLength - ObjectLength;
/* allocate buffer */
Buffer = ExAllocatePool(NonPagedPool, ParametersLength);
if (!Buffer)
return STATUS_INSUFFICIENT_RESOURCES;
/* copy parameters */
RtlMoveMemory(Buffer, &IoStack->FileObject->FileName.Buffer[ObjectLength / sizeof(WCHAR)], ParametersLength);
/* store result */
*Result = (PKSPIN_CONNECT)Buffer;
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
DispatchCreateSysAudioPin(
@ -394,7 +432,7 @@ DispatchCreateSysAudioPin(
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IoStack;
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
PKSPIN_CONNECT Connect = NULL;
PKSPIN_CONNECT Connect;
PDISPATCH_CONTEXT DispatchContext;
DPRINT("DispatchCreateSysAudioPin entered\n");
@ -410,9 +448,6 @@ DispatchCreateSysAudioPin(
/* get current attached virtual device */
DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)IoStack->FileObject->RelatedFileObject->FsContext;
/* now validate pin connect request */
Status = KsValidateConnectRequest(Irp, DeviceEntry->PinDescriptorsCount, DeviceEntry->PinDescriptors, &Connect);
/* check for success */
if (!NT_SUCCESS(Status))
{
@ -422,6 +457,19 @@ DispatchCreateSysAudioPin(
return Status;
}
/* get connect details */
Status = GetConnectRequest(Irp, &Connect);
/* check for success */
if (!NT_SUCCESS(Status))
{
/* failed to obtain connect details */
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
/* allocate dispatch context */
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
if (!DispatchContext)

View file

@ -24,9 +24,7 @@ typedef struct
HANDLE Handle; // handle to audio device
PFILE_OBJECT FileObject; // file objecto to audio device
PIN_INFO * Pins; // array of PIN_INFO
ULONG PinDescriptorsCount; // number of pin descriptors
KSPIN_DESCRIPTOR *PinDescriptors; // pin descriptors array
//PIN_INFO * Pins; // array of PIN_INFO
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
typedef struct
@ -62,20 +60,6 @@ typedef struct
HANDLE hMixerPin; // handle to mixer pin
}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
typedef struct
{
PIO_WORKITEM WorkItem;
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
}FILTER_WORKER_CONTEXT, *PFILTER_WORKER_CONTEXT;
typedef struct
{
PIRP Irp;
IO_STATUS_BLOCK StatusBlock;
}COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT;
NTSTATUS
SysAudioAllocateDeviceHeader(
IN SYSAUDIODEVEXT *DeviceExtension);