Author: janderwald
Date: Fri Feb 27 14:22:16 2009
New Revision: 39782
URL:
http://svn.reactos.org/svn/reactos?rev=39782&view=rev
Log:
- Complete missing irp
- Handle all properties of KSPROPSETID
- Initialize filter properties in a deferred routine
- Add more error checks
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c
trunk/reactos/drivers/wdm/audio/sysaudio/control.c
trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c
trunk/reactos/drivers/wdm/audio/sysaudio/main.c
trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Fri Feb
27 14:22:16 2009
@@ -813,15 +813,16 @@
}
/*
- * @unimplemented
+ * @implemented
*/
ULONG
NTAPI
IPortPinWaveCyclic_fnGetDeviceBufferSize(
IN IPortPinWaveCyclic* iface)
{
- UNIMPLEMENTED;
- return 0;
+ IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
+
+ return This->CommonBufferSize;
}
/*
@@ -845,8 +846,9 @@
IPortPinWaveCyclic_fnGetMiniport(
IN IPortPinWaveCyclic* iface)
{
- UNIMPLEMENTED;
- return NULL;
+ IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
+
+ return (PMINIPORT)This->Miniport;
}
static IPortPinWaveCyclicVtbl vt_IPortPinWaveCyclic =
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Fri Feb
27 14:22:16 2009
@@ -608,6 +608,7 @@
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Fri Feb 27 14:22:16
2009
@@ -308,6 +308,295 @@
ExFreePool(WorkerContext);
}
+NTSTATUS
+HandleSysAudioFilterPinProperties(
+ PIRP Irp,
+ PKSPROPERTY Property,
+ PSYSAUDIODEVEXT DeviceExtension)
+{
+ PIO_STACK_LOCATION IoStack;
+ 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
+ // Reserved member points to virtual device index
+
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_PIN))
+ {
+ /* too small buffer */
+ 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)
+ {
+ /* invalid device index */
+ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+ }
+
+ if (!Entry->Pins)
+ {
+ /* expected pins */
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
+
+ if (Entry->NumberOfPins <= 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->NumberOfPins;
+ 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->Pins[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->Pins[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,
+
(PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
+
IoStack->Parameters.DeviceIoControl.InputBufferLength,
+ Irp->UserBuffer,
+
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
+ &BytesReturned);
+
+ return SetIrpIoStatus(Irp, Status, BytesReturned);
+ }
+}
+
+NTSTATUS
+HandleSysAudioFilterPinCreation(
+ PIRP Irp,
+ PKSPROPERTY Property,
+ PSYSAUDIODEVEXT DeviceExtension,
+ PDEVICE_OBJECT DeviceObject)
+{
+ ULONG Length, BytesReturned;
+ PKSAUDIO_DEVICE_ENTRY Entry;
+ KSPIN_CONNECT * PinConnect;
+ PIO_STACK_LOCATION IoStack;
+ PSYSAUDIO_INSTANCE_INFO InstanceInfo;
+ PSYSAUDIO_CLIENT ClientInfo;
+ PKSOBJECT_CREATE_ITEM CreateItem;
+ KSP_PIN PinRequest;
+ NTSTATUS Status;
+ KSPIN_CINSTANCES PinInstances;
+ PIO_WORKITEM WorkItem;
+ PFILE_OBJECT FileObject;
+ PPIN_WORKER_CONTEXT WorkerContext;
+ PDISPATCH_CONTEXT DispatchContext;
+
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ Length = sizeof(KSDATAFORMAT) + sizeof(KSPIN_CONNECT) +
sizeof(SYSAUDIO_INSTANCE_INFO);
+ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Length ||
+ IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HANDLE))
+ {
+ /* invalid parameters */
+ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+ }
+
+ /* access the create item */
+ CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+
+ /* get input parameter */
+ InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property;
+ if (DeviceExtension->NumberOfKsAudioDevices <= InstanceInfo->DeviceNumber)
+ {
+ /* invalid parameters */
+ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+ }
+
+ /* get client context */
+ ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
+ if (!ClientInfo || !ClientInfo->NumDevices || !ClientInfo->Devs ||
+ ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId !=
InstanceInfo->DeviceNumber)
+ {
+ /* we have a problem */
+ KeBugCheckEx(0, 0, 0, 0, 0);
+ }
+
+ /* get sysaudio entry */
+ Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList,
InstanceInfo->DeviceNumber);
+ if (!Entry)
+ {
+ /* invalid device index */
+ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+ }
+
+ if (!Entry->Pins)
+ {
+ /* should not happen */
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
+
+ /* get connect details */
+ PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1);
+
+ if (Entry->NumberOfPins <= PinConnect->PinId)
+ {
+ DPRINT("Invalid PinId %x\n", PinConnect->PinId);
+ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+ }
+
+ PinRequest.PinId = PinConnect->PinId;
+ PinRequest.Property.Set = KSPROPSETID_Pin;
+ PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
+ PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
+
+ Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances,
sizeof(KSPIN_CINSTANCES), &BytesReturned);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Property Request KSPROPERTY_PIN_GLOBALCINSTANCES failed with
%x\n", Status);
+ return SetIrpIoStatus(Irp, Status, 0);
+ }
+
+ if (PinInstances.PossibleCount == 0)
+ {
+ /* caller wanted to open an instance-less pin */
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
+
+ if (PinInstances.CurrentCount == PinInstances.PossibleCount)
+ {
+ /* pin already exists */
+ ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
+ if (Entry->Pins[PinConnect->PinId].References > 1)
+ {
+ /* FIXME need ksmixer */
+ DPRINT1("Device %u Pin %u References %u is already occupied, try
later\n", InstanceInfo->DeviceNumber, PinConnect->PinId,
Entry->Pins[PinConnect->PinId].References);
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
+ }
+
+ WorkItem = IoAllocateWorkItem(DeviceObject);
+ if (!WorkItem)
+ {
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* create worker context */
+ WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
+ if (!WorkerContext)
+ {
+ /* invalid parameters */
+ IoFreeWorkItem(WorkItem);
+ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+ }
+
+ /* create worker context */
+ DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
+ if (!DispatchContext)
+ {
+ /* invalid parameters */
+ IoFreeWorkItem(WorkItem);
+ ExFreePool(WorkerContext);
+ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+ }
+ /* prepare context */
+ RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT));
+ RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT));
+
+ if (PinInstances.CurrentCount == PinInstances.PossibleCount)
+ {
+ /* re-using pin */
+ PinRequest.Property.Set = KSPROPSETID_Connection;
+ PinRequest.Property.Flags = KSPROPERTY_TYPE_SET;
+ PinRequest.Property.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
+
+ /* get pin file object */
+ Status =
ObReferenceObjectByHandle(Entry->Pins[PinConnect->PinId].PinHandle,
+ GENERIC_READ | GENERIC_WRITE,
+ IoFileObjectType, KernelMode,
(PVOID*)&FileObject, NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to get pin file object with %x\n", Status);
+ IoFreeWorkItem(WorkItem);
+ ExFreePool(WorkerContext);
+ ExFreePool(DispatchContext);
+ return SetIrpIoStatus(Irp, Status, 0);
+ }
+
+ Length -= sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
(PVOID)&PinRequest, sizeof(KSPROPERTY),
+ (PVOID)(PinConnect + 1), Length,
&BytesReturned);
+
+ ObDereferenceObject(FileObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to set format with Status %x\n", Status);
+ IoFreeWorkItem(WorkItem);
+ ExFreePool(WorkerContext);
+ ExFreePool(DispatchContext);
+ return SetIrpIoStatus(Irp, Status, 0);
+ }
+
+ }
+ else
+ {
+ /* create the real pin */
+ WorkerContext->CreateRealPin = TRUE;
+ }
+
+ /* set up context */
+
+ WorkerContext->DispatchContext = DispatchContext;
+ WorkerContext->Entry = Entry;
+ WorkerContext->Irp = Irp;
+ WorkerContext->PinConnect = PinConnect;
+ WorkerContext->AudioClient = ClientInfo;
+
+ DPRINT("Queing Irp %p\n", Irp);
+ /* queue the work item */
+ IoMarkIrpPending(Irp);
+ Irp->IoStatus.Status = STATUS_PENDING;
+ Irp->IoStatus.Information = 0;
+ IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue,
(PVOID)WorkerContext);
+
+ /* mark irp as pending */
+ return STATUS_PENDING;
+}
NTSTATUS
SysAudioHandleProperty(
@@ -327,24 +616,15 @@
ULONG Count, BytesReturned;
PKSOBJECT_CREATE_ITEM CreateItem;
UNICODE_STRING GuidString;
- ULONG Length;
- KSPIN_CONNECT * PinConnect;
- KSP_PIN PinRequest;
- KSPIN_CINSTANCES PinInstances;
- PPIN_WORKER_CONTEXT WorkerContext;
- PDISPATCH_CONTEXT DispatchContext;
- PIO_WORKITEM WorkItem;
- PFILE_OBJECT FileObject;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
-
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(KSPROPERTY))
{
- /* buffer must be atleast of sizeof KSPROPERTY */
+ /* buffer must be at least of sizeof KSPROPERTY */
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY));
}
@@ -353,33 +633,7 @@
if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Pin))
{
- /* ros specific request */
- if (Property->Id == KSPROPERTY_PIN_DATARANGES)
- {
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(KSP_PIN))
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY) +
sizeof(ULONG));
- }
-
- Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList,
((KSP_PIN*)Property)->Reserved);
- if (!Entry)
- {
- /* too small buffer */
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
-
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode,
IOCTL_KS_PROPERTY,
-
(PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
-
IoStack->Parameters.DeviceIoControl.InputBufferLength,
- Irp->UserBuffer,
-
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
- &BytesReturned);
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = BytesReturned;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
- }
+ return HandleSysAudioFilterPinProperties(Irp, Property, DeviceExtension);
}
else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
{
@@ -428,6 +682,7 @@
/* too small buffer */
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
}
+
*((PULONG)Irp->UserBuffer) = DeviceExtension->NumberOfKsAudioDevices;
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
}
@@ -504,187 +759,7 @@
{
/* ros specific pin creation request */
DPRINT1("Initiating create request\n");
-
- Length = sizeof(KSDATAFORMAT) + sizeof(KSPIN_CONNECT) +
sizeof(SYSAUDIO_INSTANCE_INFO);
- if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Length ||
- IoStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(HANDLE))
- {
- /* invalid parameters */
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
-
- /* get input parameter */
- InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property;
- if (DeviceExtension->NumberOfKsAudioDevices <=
InstanceInfo->DeviceNumber)
- {
- /* invalid parameters */
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
-
- /* get client context */
- ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
- ASSERT(ClientInfo);
- ASSERT(ClientInfo->NumDevices >= 1);
- ASSERT(ClientInfo->Devs != NULL);
- ASSERT(ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId ==
InstanceInfo->DeviceNumber);
-
- /* get sysaudio entry */
- Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList,
InstanceInfo->DeviceNumber);
- ASSERT(Entry != NULL);
-
- if (!Entry->Pins)
- {
- PropertyRequest.Set = KSPROPSETID_Pin;
- PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
- PropertyRequest.Id = KSPROPERTY_PIN_CTYPES;
-
- /* query for num of pins */
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&Count,
sizeof(ULONG), &BytesReturned);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Property Request KSPROPERTY_PIN_CTYPES failed with
%x\n", Status);
- return SetIrpIoStatus(Irp, Status, 0);
- }
- DPRINT("KSPROPERTY_TYPE_GET num pins %d\n", Count);
-
- Entry->Pins = ExAllocatePool(NonPagedPool, Count * sizeof(PIN_INFO));
- if (!Entry->Pins)
- {
- /* invalid parameters */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
- /* clear array */
- RtlZeroMemory(Entry->Pins, sizeof(PIN_INFO) * Count);
- Entry->NumberOfPins = Count;
-
- }
-
- /* get connect details */
- PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1);
-
- if (Entry->NumberOfPins <= PinConnect->PinId)
- {
- DPRINT("Invalid PinId %x\n", PinConnect->PinId);
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
-
- PinRequest.PinId = PinConnect->PinId;
- PinRequest.Property.Set = KSPROPSETID_Pin;
- PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
- PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
-
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances,
sizeof(KSPIN_CINSTANCES), &BytesReturned);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Property Request KSPROPERTY_PIN_GLOBALCINSTANCES failed with
%x\n", Status);
- return SetIrpIoStatus(Irp, Status, 0);
- }
- DPRINT("PinInstances Current %u Max %u\n",
PinInstances.CurrentCount, PinInstances.PossibleCount);
- Entry->Pins[PinConnect->PinId].MaxPinInstanceCount =
PinInstances.PossibleCount;
-
- WorkItem = IoAllocateWorkItem(DeviceObject);
- if (!WorkItem)
- {
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* create worker context */
- WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
- if (!WorkerContext)
- {
- /* invalid parameters */
- IoFreeWorkItem(WorkItem);
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
-
- /* create worker context */
- DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
- if (!DispatchContext)
- {
- /* invalid parameters */
- IoFreeWorkItem(WorkItem);
- ExFreePool(WorkerContext);
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
- /* prepare context */
- RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT));
- RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT));
-
- if (PinInstances.CurrentCount == PinInstances.PossibleCount)
- {
- /* pin already exists */
- ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
-
- if (Entry->Pins[PinConnect->PinId].References > 1)
- {
- /* FIXME need ksmixer */
- DPRINT1("Device %u Pin %u References %u is already occupied, try
later\n", InstanceInfo->DeviceNumber, PinConnect->PinId,
Entry->Pins[PinConnect->PinId].References);
- IoFreeWorkItem(WorkItem);
- ExFreePool(WorkerContext);
- ExFreePool(DispatchContext);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
- /* re-using pin */
- PropertyRequest.Set = KSPROPSETID_Connection;
- PropertyRequest.Flags = KSPROPERTY_TYPE_SET;
- PropertyRequest.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
-
- /* get pin file object */
- Status =
ObReferenceObjectByHandle(Entry->Pins[PinConnect->PinId].PinHandle,
- GENERIC_READ | GENERIC_WRITE,
- IoFileObjectType, KernelMode,
(PVOID*)&FileObject, NULL);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get pin file object with %x\n",
Status);
- IoFreeWorkItem(WorkItem);
- ExFreePool(WorkerContext);
- ExFreePool(DispatchContext);
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- Length -= sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
- Status = KsSynchronousIoControlDevice(FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY),
- (PVOID)(PinConnect + 1), Length,
&BytesReturned);
-
- ObDereferenceObject(FileObject);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to set format with Status %x\n", Status);
- IoFreeWorkItem(WorkItem);
- ExFreePool(WorkerContext);
- ExFreePool(DispatchContext);
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- }
- else
- {
- /* create the real pin */
- WorkerContext->CreateRealPin = TRUE;
- }
-
- /* set up context */
-
- WorkerContext->DispatchContext = DispatchContext;
- WorkerContext->Entry = Entry;
- WorkerContext->Irp = Irp;
- WorkerContext->PinConnect = PinConnect;
- WorkerContext->AudioClient = ClientInfo;
-
- DPRINT("Queing Irp %p\n", Irp);
- /* queue the work item */
- IoMarkIrpPending(Irp);
- Irp->IoStatus.Status = STATUS_PENDING;
- Irp->IoStatus.Information = 0;
- IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue,
(PVOID)WorkerContext);
-
- /* mark irp as pending */
- return STATUS_PENDING;
+ return HandleSysAudioFilterPinCreation(Irp, Property, DeviceExtension,
DeviceObject);
}
}
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] Fri Feb 27 14:22:16
2009
@@ -21,6 +21,93 @@
const GUID KS_CATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3,
0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, {0x8A,
0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
+VOID
+NTAPI
+FilterPinWorkerRoutine(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context)
+{
+ KSPROPERTY PropertyRequest;
+ KSP_PIN PinRequest;
+ KSPIN_DATAFLOW DataFlow;
+ KSPIN_COMMUNICATION Communication;
+ KSPIN_CINSTANCES PinInstances;
+ ULONG Count, Index;
+ NTSTATUS Status;
+ ULONG BytesReturned;
+ PKSAUDIO_DEVICE_ENTRY DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)Context;
+
+
+ DPRINT1("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))
+ {
+ return;
+ }
+
+ if (!Count)
+ return;
+
+ /* allocate pin array */
+ DeviceEntry->Pins = ExAllocatePool(NonPagedPool, Count * sizeof(PIN_INFO));
+ if (!DeviceEntry->Pins)
+ {
+ /* no memory */
+ return;
+ }
+ /* clear array */
+ RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count);
+ DeviceEntry->NumberOfPins = Count;
+
+ for(Index = 0; Index < Count; Index++)
+ {
+ /* get max instance count */
+ PinRequest.PinId = Index;
+ PinRequest.Property.Set = KSPROPSETID_Pin;
+ PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
+ PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
+
+ Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances,
sizeof(KSPIN_CINSTANCES), &BytesReturned);
+ if (NT_SUCCESS(Status))
+ {
+ DeviceEntry->Pins[Index].MaxPinInstanceCount =
PinInstances.PossibleCount;
+ }
+
+ /* 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->Pins[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->Pins[Index].Communication = Communication;
+ }
+
+ if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow ==
KSPIN_DATAFLOW_IN)
+ DeviceEntry->NumWaveOutPin++;
+
+ if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow ==
KSPIN_DATAFLOW_OUT)
+ DeviceEntry->NumWaveInPin++;
+
+ }
+
+ DPRINT1("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n",
DeviceEntry->NumberOfPins, DeviceEntry->NumWaveInPin,
DeviceEntry->NumWaveOutPin);
+}
+
+
+
NTSTATUS
NTAPI
@@ -29,8 +116,11 @@
IN PVOID Context)
{
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
- SYSAUDIODEVEXT *DeviceExtension = (SYSAUDIODEVEXT*)Context;
NTSTATUS Status = STATUS_SUCCESS;
+ PSYSAUDIODEVEXT DeviceExtension;
+ PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
+
+ DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
@@ -44,7 +134,7 @@
HANDLE NodeHandle;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
-
+ PIO_WORKITEM WorkItem;
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
if (!DeviceEntry)
@@ -116,10 +206,16 @@
DeviceEntry->Handle = NodeHandle;
DeviceEntry->FileObject = FileObject;
+ DPRINT1("Successfully opened audio device %u handle %p file object %p device
object %p\n", DeviceExtension->KsAudioDeviceList, NodeHandle, FileObject,
FileObject->DeviceObject);
+ DeviceExtension->NumberOfKsAudioDevices++;
+
+ WorkItem = IoAllocateWorkItem(DeviceObject);
+ if (WorkItem)
+ {
+ IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue,
(PVOID)DeviceEntry);
+ }
InsertTailList(&DeviceExtension->KsAudioDeviceList,
&DeviceEntry->Entry);
- DeviceExtension->NumberOfKsAudioDevices++;
-
- DPRINT1("Successfully opened audio device handle %p file object %p device
object %p\n", NodeHandle, FileObject, FileObject->DeviceObject);
+
return Status;
}
else if (IsEqualGUIDAligned(&Event->Event,
@@ -144,18 +240,20 @@
NTSTATUS
SysAudioRegisterNotifications(
- IN PDRIVER_OBJECT DriverObject,
- SYSAUDIODEVEXT *DeviceExtension)
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
-
+ PSYSAUDIODEVEXT DeviceExtension;
+
+ DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
(PVOID)&KS_CATEGORY_AUDIO,
DriverObject,
DeviceInterfaceChangeCallback,
- (PVOID)DeviceExtension,
+ (PVOID)DeviceObject,
(PVOID*)&DeviceExtension->KsAudioNotificationEntry);
if (!NT_SUCCESS(Status))
@@ -168,7 +266,7 @@
(PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
DriverObject,
DeviceInterfaceChangeCallback,
- (PVOID)DeviceExtension,
+ (PVOID)DeviceObject,
(PVOID*)&DeviceExtension->EchoCancelNotificationEntry);
if (!NT_SUCCESS(Status))
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] Fri Feb 27 14:22:16 2009
@@ -133,7 +133,7 @@
}
Status = SysAudioRegisterNotifications(DriverObject,
- DeviceExtension);
+ DeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to register device notifications\n");
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Fri Feb 27 14:22:16
2009
@@ -29,6 +29,8 @@
ULONG MaxPinInstanceCount;
HANDLE PinHandle;
ULONG References;
+ KSPIN_DATAFLOW DataFlow;
+ KSPIN_COMMUNICATION Communication;
}PIN_INFO;
@@ -42,6 +44,9 @@
ULONG NumberOfPins;
PIN_INFO * Pins;
+
+ ULONG NumWaveOutPin;
+ ULONG NumWaveInPin;
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
@@ -88,8 +93,8 @@
NTSTATUS
SysAudioRegisterNotifications(
- IN PDRIVER_OBJECT DriverObject,
- SYSAUDIODEVEXT *DeviceExtension);
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject);
NTSTATUS
SysAudioHandleProperty(
@@ -105,4 +110,9 @@
CreateDispatcher(
IN PIRP Irp);
+ULONG
+GetDeviceCount(
+ PSYSAUDIODEVEXT DeviceExtension,
+ BOOL WaveIn);
+
#endif