[ros-diffs] [janderwald] 39782: - Complete missing irp - Handle all properties of KSPROPSETID - Initialize filter properties in a deferred routine - Add more error checks

janderwald at svn.reactos.org janderwald at svn.reactos.org
Fri Feb 27 12:22:17 CET 2009


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/portcls/pin_wavecyclic.c?rev=39782&r1=39781&r2=39782&view=diff
==============================================================================
--- 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/portcls/port_topology.c?rev=39782&r1=39781&r2=39782&view=diff
==============================================================================
--- 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/control.c?rev=39782&r1=39781&r2=39782&view=diff
==============================================================================
--- 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/deviface.c?rev=39782&r1=39781&r2=39782&view=diff
==============================================================================
--- 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/main.c?rev=39782&r1=39781&r2=39782&view=diff
==============================================================================
--- 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/sysaudio.h?rev=39782&r1=39781&r2=39782&view=diff
==============================================================================
--- 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



More information about the Ros-diffs mailing list