[ros-diffs] [janderwald] 39715: - Implement a common property handler for filter property requests - Always queue a work item for pin creation requests - Handle KSPROPERTY_PIN_DATAFLOW, KSPROPERTY_PIN_DATARANGES, KSPROPERTY_PIN_INTERFACES, KSPROPERTY_PIN_MEDIUMS, KSPROPERTY_PIN_COMMUNICATION, KSPROPERTY_PIN_CATEGORY, qKSPROPERTY_PIN_NAME, KSPROPERTY_PIN_GLOBALCINSTANCES, KSPROPERTY_PIN_CINSTANCES, KSPROPERTY_PIN_NECESSARYINSTANCES - Fix several bugs in property copying code - Change the pin creation path in sysaudio in order to have client information as this was previously not available (see DPRINT using hack) - Close file handels in wdmaud / sysaudio - set Iostatus before queing an irp as the irp might complete before accessing status io

janderwald at svn.reactos.org janderwald at svn.reactos.org
Sun Feb 22 19:58:52 CET 2009


Author: janderwald
Date: Sun Feb 22 21:58:51 2009
New Revision: 39715

URL: http://svn.reactos.org/svn/reactos?rev=39715&view=rev
Log:
- Implement a common property handler for filter property requests
- Always queue a work item for pin creation requests
- Handle KSPROPERTY_PIN_DATAFLOW, KSPROPERTY_PIN_DATARANGES, KSPROPERTY_PIN_INTERFACES, KSPROPERTY_PIN_MEDIUMS, KSPROPERTY_PIN_COMMUNICATION, KSPROPERTY_PIN_CATEGORY,  qKSPROPERTY_PIN_NAME, KSPROPERTY_PIN_GLOBALCINSTANCES, KSPROPERTY_PIN_CINSTANCES, KSPROPERTY_PIN_NECESSARYINSTANCES
- Fix several bugs in property copying code
- Change the pin creation path in sysaudio in order to have client information as this was previously not available (see DPRINT using hack)
- Close file handels in wdmaud / sysaudio
- set Iostatus before queing an irp as the irp might complete before accessing status io 

Modified:
    trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
    trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
    trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
    trunk/reactos/drivers/wdm/audio/sysaudio/control.c
    trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
    trunk/reactos/drivers/wdm/audio/sysaudio/pin.c
    trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -133,7 +133,7 @@
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 NTAPI
@@ -142,8 +142,23 @@
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-
-    return STATUS_UNSUCCESSFUL;
+    PIO_STACK_LOCATION IoStack;
+    ISubdevice *SubDevice = NULL;
+    SUBDEVICE_DESCRIPTOR * Descriptor;
+
+    IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
+    ASSERT(This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice) == STATUS_SUCCESS);
+    ASSERT(SubDevice != NULL);
+
+    ASSERT(SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor) == STATUS_SUCCESS);
+    ASSERT(Descriptor != NULL);
+
+    SubDevice->lpVtbl->Release(SubDevice);
+
+    return PcPropertyHandler(Irp, Descriptor);
 }
 
 /*

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -99,9 +99,20 @@
 
 typedef struct
 {
+    ULONG MaxGlobalInstanceCount;
+    ULONG MaxFilterInstanceCount;
+    ULONG MinFilterInstanceCount;
+    ULONG CurrentFilterInstanceCount;
+
+}PIN_INSTANCE_INFO, *PPIN_INSTANCE_INFO;
+
+
+typedef struct
+{
     ULONG PinDescriptorCount;
     ULONG PinDescriptorSize;
     KSPIN_DESCRIPTOR * KsPinDescriptor;
+    PIN_INSTANCE_INFO * Instances;
 }KSPIN_FACTORY;
 
 typedef struct

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=39715&r1=39714&r2=39715&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] Sun Feb 22 21:58:51 2009
@@ -486,8 +486,10 @@
     ISubdevice * SubDevice;
     PPCLASS_DEVICE_EXTENSION DeviceExt;
     SUBDEVICE_ENTRY * Entry;
-    IIrpTarget *Filter, *Pin;
+    IIrpTarget *Filter;
     PKSOBJECT_CREATE_ITEM CreateItem;
+    PPIN_WORKER_CONTEXT Context;
+    PIO_WORKITEM WorkItem;
 
     DPRINT1("PcCreateItemDispatch called DeviceObject %p\n", DeviceObject);
 
@@ -567,7 +569,6 @@
     }
     else
     {
-        KSOBJECT_CREATE Create;
         LPWSTR Buffer = IoStack->FileObject->FileName.Buffer;
 
         static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
@@ -576,51 +577,33 @@
         if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
         {
             /* try to create new pin */
-
-           if (KeGetCurrentIrql() >= APC_LEVEL)
-           {
-              PPIN_WORKER_CONTEXT Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
-              if (!Context)
-               {
-                   Irp->IoStatus.Information = 0;
-                   Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-                   return STATUS_INSUFFICIENT_RESOURCES;
-               }
-               Context->Filter = Filter;
-               Context->Irp = Irp;
-
-              PIO_WORKITEM WorkItem = IoAllocateWorkItem(DeviceObject);
-               if (!WorkItem)
-               {
-                   Irp->IoStatus.Information = 0;
-                   Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-                   return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-               IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
-               Irp->IoStatus.Information = 0;
-               Irp->IoStatus.Status = STATUS_PENDING;
-               IoMarkIrpPending(Irp);
-               return STATUS_PENDING;
-          }
-
-            Create.CreateItemsCount = 1;
-            Create.CreateItemsList = (PKSOBJECT_CREATE_ITEM)(IoStack->FileObject->FileName.Buffer + (wcslen(KS_NAME_PIN) + 1));
-
-            Status = Filter->lpVtbl->NewIrpTarget(Filter,
-                                                  &Pin,
-                                                  KS_NAME_PIN,
-                                                  NULL,
-                                                  NonPagedPool,
-                                                  DeviceObject,
-                                                  Irp,
-                                                  &Create);
-            if (NT_SUCCESS(Status))
+            Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
+            if (!Context)
             {
-                /* create the dispatch object */
-                Status = NewDispatchObject(Irp, Pin);
-                DPRINT1("Pin %p\n", Pin);
+                Irp->IoStatus.Information = 0;
+                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return STATUS_INSUFFICIENT_RESOURCES;
             }
+            Context->Filter = Filter;
+            Context->Irp = Irp;
+
+            WorkItem = IoAllocateWorkItem(DeviceObject);
+            if (!WorkItem)
+            {
+                Irp->IoStatus.Information = 0;
+                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+                FreeItem(Context, TAG_PORTCLASS);
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+            DPRINT1("Queueing IRP %p\n", Irp);
+            Irp->IoStatus.Information = 0;
+            Irp->IoStatus.Status = STATUS_PENDING;
+            IoMarkIrpPending(Irp);
+            IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
+
+            return STATUS_PENDING;
         }
     }
     Irp->IoStatus.Information = 0;

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -220,5 +220,11 @@
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp);
 
+NTSTATUS
+NTAPI
+PcPropertyHandler(
+    IN PIRP Irp,
+    IN PSUBDEVICE_DESCRIPTOR Descriptor);
+
 
 #endif

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -1,4 +1,62 @@
 #include "private.h"
+
+NTSTATUS
+HandlePropertyInstances(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER  Request,
+    IN OUT PVOID  Data,
+    IN PSUBDEVICE_DESCRIPTOR Descriptor,
+    IN BOOL Global)
+{
+    KSPIN_CINSTANCES * Instances;
+    KSP_PIN * Pin = (KSP_PIN*)Request;
+
+    if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
+    {
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    Instances = (KSPIN_CINSTANCES*)Data;
+
+    if (Global)
+        Instances->PossibleCount = Descriptor->Factory.Instances[Pin->PinId].MaxGlobalInstanceCount;
+    else
+        Instances->PossibleCount = Descriptor->Factory.Instances[Pin->PinId].MaxFilterInstanceCount;
+
+    Instances->CurrentCount = Descriptor->Factory.Instances[Pin->PinId].CurrentFilterInstanceCount;
+
+    Irp->IoStatus.Information = sizeof(KSPIN_CINSTANCES);
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+HandleNecessaryPropertyInstances(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER  Request,
+    IN OUT PVOID  Data,
+    IN PSUBDEVICE_DESCRIPTOR Descriptor)
+{
+    PULONG Result;
+    KSP_PIN * Pin = (KSP_PIN*)Request;
+
+    if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
+    {
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    Result = (PULONG)Data;
+    *Result = Descriptor->Factory.Instances[Pin->PinId].MinFilterInstanceCount;
+
+    Irp->IoStatus.Information = sizeof(ULONG);
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    return STATUS_SUCCESS;
+}
+
 
 NTSTATUS
 NTAPI
@@ -7,7 +65,11 @@
     IN PKSIDENTIFIER  Request,
     IN OUT PVOID  Data)
 {
+    PSUBDEVICE_DESCRIPTOR Descriptor;
     NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+    Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
+    ASSERT(Descriptor);
 
     switch(Request->Id)
     {
@@ -19,12 +81,19 @@
         case KSPROPERTY_PIN_COMMUNICATION:
         case KSPROPERTY_PIN_CATEGORY:
         case KSPROPERTY_PIN_NAME:
-            // KsPinPropertyHandler
-            break;
+            Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor);
+            break;
+        case KSPROPERTY_PIN_GLOBALCINSTANCES:
+            Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, TRUE);
+            break;
+        case KSPROPERTY_PIN_CINSTANCES:
+            Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, FALSE);
+            break;
+        case KSPROPERTY_PIN_NECESSARYINSTANCES:
+            Status = HandleNecessaryPropertyInstances(Irp, Request, Data, Descriptor);
+            break;
+
         case KSPROPERTY_PIN_DATAINTERSECTION:
-        case KSPROPERTY_PIN_CINSTANCES:
-        case KSPROPERTY_PIN_GLOBALCINSTANCES:
-        case KSPROPERTY_PIN_NECESSARYINSTANCES:
         case KSPROPERTY_PIN_PHYSICALCONNECTION:
         case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
             DPRINT1("Unhandled %x\n", Request->Id);
@@ -52,3 +121,85 @@
                                      NULL /* FIXME */);
 }
 
+NTSTATUS
+NTAPI
+PcPropertyHandler(
+    IN PIRP Irp,
+    IN PSUBDEVICE_DESCRIPTOR Descriptor)
+{
+    ULONG Index, ItemIndex;
+    PIO_STACK_LOCATION IoStack;
+    PKSPROPERTY Property;
+    PFNKSHANDLER PropertyHandler = NULL;
+    UNICODE_STRING GuidString;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+    ASSERT(Property);
+
+    DPRINT1("Num of Property Sets %u\n", Descriptor->FilterPropertySet.FreeKsPropertySetOffset);
+    for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
+    {
+        RtlStringFromGUID ((GUID*)Descriptor->FilterPropertySet.Properties[Index].Set, &GuidString);
+        DPRINT1("Current GUID %S\n", GuidString.Buffer);
+        RtlFreeUnicodeString(&GuidString);
+
+        if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
+        {
+            DPRINT1("Found Property Set Properties %u\n",  Descriptor->FilterPropertySet.Properties[Index].PropertiesCount);
+            for(ItemIndex = 0; ItemIndex < Descriptor->FilterPropertySet.Properties[Index].PropertiesCount; ItemIndex++)
+            {
+                if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].PropertyId == Property->Id)
+                {
+                    DPRINT1("Found property set identifier %u\n", Property->Id);
+                    if (Property->Flags & KSPROPERTY_TYPE_SET)
+                        PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].SetPropertyHandler;
+
+                    if (Property->Flags & KSPROPERTY_TYPE_GET)
+                        PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].GetPropertyHandler;
+
+                    if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty > IoStack->Parameters.DeviceIoControl.InputBufferLength)
+                    {
+                        /* too small input buffer */
+                        Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty;
+                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+                        return STATUS_BUFFER_TOO_SMALL;
+                    }
+
+                    if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
+                    {
+                        /* too small output buffer */
+                        Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData;
+                        Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+                        return STATUS_BUFFER_TOO_SMALL;
+                    }
+
+                    if (PropertyHandler)
+                    {
+                        KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)Descriptor;
+                        DPRINT1("Calling property handler %p\n", PropertyHandler);
+                        Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
+                    }
+
+                    /* the information member is set by the handler */
+                    Irp->IoStatus.Status = Status;
+                    DPRINT1("Result %x\n", Status);
+                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                    return Status;
+                }
+            }
+        }
+    }
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT1("Unhandeled property: Set %S Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
+    DbgBreakPoint();
+    RtlFreeUnicodeString(&GuidString);
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.c [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -108,7 +108,17 @@
         RtlMoveMemory((PVOID)Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].PropertyItem,
                       FilterProperty->PropertyItem,
                       sizeof(KSPROPERTY_ITEM) * FilterProperty->PropertiesCount);
-    }
+
+    }
+    Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set = AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS);
+    if (!Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    RtlCopyMemory((PVOID)Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set, FilterProperty->Set, sizeof(GUID));
+
+    /* ignore fast io table for now */
+    Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].FastIoCount = 0;
+    Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].FastIoTable = NULL;
 
     Descriptor->FilterPropertySet.FreeKsPropertySetOffset++;
 
@@ -177,12 +187,22 @@
         if (!Descriptor->Factory.KsPinDescriptor)
             goto cleanup;
 
+        Descriptor->Factory.Instances = AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
+        if (!Descriptor->Factory.Instances)
+            goto cleanup;
+
         Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
         Descriptor->Factory.PinDescriptorSize = FilterDescription->PinSize;
 
         /* copy pin factories */
         for(Index = 0; Index < FilterDescription->PinCount; Index++)
+        {
             RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &FilterDescription->Pins[Index].KsPinDescriptor, FilterDescription->PinSize);
+            Descriptor->Factory.Instances[Index].CurrentFilterInstanceCount = 0;
+            Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = FilterDescription->Pins[Index].MaxFilterInstanceCount;
+            Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = FilterDescription->Pins[Index].MaxGlobalInstanceCount;
+            Descriptor->Factory.Instances[Index].MinFilterInstanceCount = FilterDescription->Pins[Index].MinFilterInstanceCount;
+        }
     }
 
     *OutSubdeviceDescriptor = Descriptor;

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -44,6 +44,7 @@
     ACCESS_MASK DesiredAccess = 0;
     HANDLE PinHandle;
     KSPIN_CONNECT * PinConnect;
+    ULONG Length;
     KSDATAFORMAT_WAVEFORMATEX * DataFormat;
 
     if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
@@ -52,7 +53,8 @@
         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
     }
 
-    InstanceInfo = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT));
+    Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
+    InstanceInfo = ExAllocatePool(NonPagedPool, Length);
     if (!InstanceInfo)
     {
         /* no memory */
@@ -90,7 +92,7 @@
         DesiredAccess |= GENERIC_WRITE;
     }
 
-    PinConnect = (KSPIN_CONNECT*)InstanceInfo;
+    PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1);
 
 
     PinConnect->Interface.Set = KSINTERFACESETID_Standard;
@@ -100,7 +102,7 @@
     PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
     PinConnect->Medium.Flags = 0;
     PinConnect->PinId = 0; //FIXME
-    PinConnect->PinToHandle = NULL;
+    PinConnect->PinToHandle = ClientInfo->hSysAudio;
     PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
     PinConnect->Priority.PrioritySubClass = 1;
 
@@ -125,16 +127,25 @@
     DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
     DataFormat->DataFormat.SampleSize = 4;
 
-
-    Status = KsCreatePin(ClientInfo->hSysAudio, PinConnect, DesiredAccess, &PinHandle);
-    DPRINT1("KsCreatePin Status %x\n", Status);
-
-
-    /* free buffer */
-    ExFreePool(InstanceInfo);
-
+    /* ros specific pin creation request */
+    InstanceInfo->Property.Id = (ULONG)-1;
+    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned);
     if (NT_SUCCESS(Status))
     {
+        PHANDLE Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumPins+1));
+
+        if (Handels)
+        {
+            if (ClientInfo->NumPins)
+            {
+                RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(HANDLE) * ClientInfo->NumPins);
+                ExFreePool(ClientInfo->hPins);
+            }
+
+            ClientInfo->hPins = Handels;
+            ClientInfo->hPins[ClientInfo->NumPins] = PinHandle;
+            ClientInfo->NumPins++;
+        }
         DeviceInfo->hDevice = PinHandle;
     }
     else
@@ -338,7 +349,6 @@
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
     DPRINT1("WdmAudDeviceControl entered\n");
-    DbgBreakPoint();
 
     if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
     {

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -167,53 +167,64 @@
 {
     NTSTATUS Status = STATUS_SUCCESS;
     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+
+    DPRINT1("WdmAudClose\n");
+
+    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+#if KS_IMPLEMENTED
+    Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
+
+    if (NT_SUCCESS(Status))
+    {
+        if (DeviceExtension->SysAudioNotification)
+            Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
+    }
+#endif
+
+    Irp->IoStatus.Status = Status;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+WdmAudCleanup(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp)
+{
     PIO_STACK_LOCATION IoStack;
     WDMAUD_CLIENT *pClient;
-
-    DPRINT1("WdmAudClose\n");
-
-    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-#if KS_IMPLEMENTED
-    Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
-
-    if (NT_SUCCESS(Status))
-    {
-        if (DeviceExtension->SysAudioNotification)
-            Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
-    }
-#endif
+    ULONG Index;
+
+    DPRINT1("WdmAudCleanup\n");
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
     pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext;
+
     if (pClient)
     {
+        for (Index = 0; Index < pClient->NumPins; Index++)
+           ZwClose(pClient->hPins[Index]);
+
+        if (pClient->hPins)
+        {
+            ExFreePool(pClient->hPins);
+        }
+
         ObDereferenceObject(pClient->FileObject);
         ZwClose(pClient->hSysAudio);
         ExFreePool(pClient);
         IoStack->FileObject->FsContext = NULL;
     }
 
-    Irp->IoStatus.Status = Status;
-    Irp->IoStatus.Information = 0;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return Status;
-}
-
-NTSTATUS
-NTAPI
-WdmAudCleanup(
-    IN  PDEVICE_OBJECT DeviceObject,
-    IN  PIRP Irp)
-{
-    UNIMPLEMENTED
-
     Irp->IoStatus.Status = STATUS_SUCCESS;
     Irp->IoStatus.Information = 0;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+    DPRINT1("WdmAudCleanup complete\n");
     return STATUS_SUCCESS;
 }
 

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -65,6 +65,8 @@
     HANDLE hProcess;
     HANDLE hSysAudio;
     PFILE_OBJECT FileObject;
+    ULONG NumPins;
+    HANDLE * hPins;
 
 }WDMAUD_CLIENT, *PWDMAUD_CLIENT;
 

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=39715&r1=39714&r2=39715&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] Sun Feb 22 21:58:51 2009
@@ -19,6 +19,8 @@
 const GUID KSPROPSETID_Sysaudio                 = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
 const GUID KSPROPSETID_Sysaudio_Pin             = {0xA3A53220L, 0xC6E4, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
 const GUID KSPROPSETID_General                  = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
+const GUID KSPROPSETID_Pin                     = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
+const GUID KSPROPSETID_Connection              = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
 
 
 NTSTATUS
@@ -57,6 +59,7 @@
     PSYSAUDIODEVEXT DeviceExtension)
 {
     PULONG Index;
+    PHANDLE Handle;
     ULONG Count;
     PSYSAUDIO_CLIENT ClientInfo;
     PKSAUDIO_DEVICE_ENTRY Entry;
@@ -88,8 +91,17 @@
             /* no memory */
             return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
         }
+
+        ClientInfo->Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE));
+        if (!ClientInfo->Devices)
+        {
+            /* no memory */
+            return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+        }
+
         ClientInfo->NumDevices = 1;
         ClientInfo->Devices[0] = DeviceNumber;
+        ClientInfo->Handels[0] = NULL;
         /* increase usage count */
         Entry->NumberOfClients++;
         return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
@@ -111,18 +123,157 @@
         /* no memory */
         return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
     }
+
+    Handle = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumDevices + 1));
+    if (!Handle)
+    {
+        /* no memory */
+        ExFreePool(Index);
+        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+    }
+
     /* increase usage count */
     Entry->NumberOfClients++;
 
     /* copy device count array */
-    RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG));
+    if (ClientInfo->NumDevices)
+	{
+        RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG));
+        RtlMoveMemory(Handle, ClientInfo->Handels, ClientInfo->NumDevices * sizeof(HANDLE));
+	}
+
     Index[ClientInfo->NumDevices] = DeviceNumber;
+    Handle[ClientInfo->NumDevices] = NULL;
+	ExFreePool(ClientInfo->Handels);
     ExFreePool(ClientInfo->Devices);
     ClientInfo->NumDevices++;
     ClientInfo->Devices = Index;
+	ClientInfo->Handels = Handle;
 
     return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
-
+}
+
+VOID
+NTAPI
+CreatePinWorkerRoutine(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PVOID  Context)
+{
+    NTSTATUS Status;
+    HANDLE PinHandle;
+    HANDLE Filter;
+    PFILE_OBJECT FileObject;
+    PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
+    Filter = WorkerContext->PinConnect->PinToHandle;
+
+    WorkerContext->PinConnect->PinToHandle = NULL;
+
+
+    if (WorkerContext->CreateRealPin)
+    {
+        /* create the real pin */
+        Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to create Pin with %x\n", Status);
+            SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
+            ExFreePool(WorkerContext);
+            return;
+        }
+
+        /* get pin file object */
+        Status = ObReferenceObjectByHandle(PinHandle,
+                                           GENERIC_READ | GENERIC_WRITE, 
+                                           IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+
+        WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = PinHandle;
+        WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 1;
+        WorkerContext->DispatchContext->Handle = PinHandle;
+        WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
+        WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
+
+        if (NT_SUCCESS(Status))
+            WorkerContext->DispatchContext->FileObject = FileObject;
+        else
+            WorkerContext->DispatchContext->FileObject = NULL;
+    }
+    else
+    {
+        WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
+        WorkerContext->DispatchContext->Handle = WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle;
+        WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
+
+        /* get pin file object */
+        Status = ObReferenceObjectByHandle(PinHandle,
+                                           GENERIC_READ | GENERIC_WRITE, 
+                                           IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to get file object with %x\n", Status);
+            SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
+            ExFreePool(WorkerContext);
+            return;
+        }
+        WorkerContext->DispatchContext->FileObject = FileObject;
+    }
+
+    DPRINT1("creating virtual pin\n");
+    /* now create the virtual audio pin which is exposed to wdmaud */
+    Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create virtual pin with %x\n", Status);
+        if (WorkerContext->CreateRealPin)
+        {
+            /* mark pin as free to use */
+            WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
+        }
+
+        SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
+        ExFreePool(WorkerContext);
+        return;
+    }
+
+   /* get pin file object */
+    Status = ObReferenceObjectByHandle(PinHandle,
+                                      GENERIC_READ | GENERIC_WRITE, 
+                                      IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to get file object with %x\n", Status);
+        if (WorkerContext->CreateRealPin)
+        {
+            /* mark pin as free to use */
+            WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
+        }
+
+        ZwClose(PinHandle);
+        SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
+        ExFreePool(WorkerContext);
+        return;
+    }
+
+    ASSERT(WorkerContext->DispatchContext);
+    ASSERT(WorkerContext->DispatchContext->AudioEntry != NULL);
+    ASSERT(WorkerContext->DispatchContext->FileObject != NULL);
+    ASSERT(WorkerContext->DispatchContext->Handle != NULL);
+    ASSERT(WorkerContext->AudioClient);
+	ASSERT(WorkerContext->AudioClient->Handels);
+    ASSERT(WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices -1] == NULL);
+
+    /* store pin context */
+    FileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
+
+    /* store pin handle in client specific struct */
+	WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices-1] = PinHandle;
+
+    DPRINT1("Successfully created Pin %p\n", WorkerContext->Irp);
+    *((PHANDLE)WorkerContext->Irp->UserBuffer) = PinHandle;
+
+    SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE));
 }
 
 
@@ -144,6 +295,14 @@
     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);
@@ -279,6 +438,194 @@
                 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
             }
         }
+        else if (Property->Id == (ULONG)-1)
+        {
+            /* 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->Devices != NULL);
+            ASSERT(ClientInfo->Devices[ClientInfo->NumDevices-1] == 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;
+
+            //RtlZeroMemory(&PinInstances, sizeof(KSPIN_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);
+            }
+            DPRINT1("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, 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 */
+                DPRINT1("Pins %p\n", Entry->Pins);
+                DbgBreakPoint();
+                ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
+
+                if (Entry->Pins[PinConnect->PinId].References != 0)
+                {
+                    /* FIXME need ksmixer */
+                    DPRINT1("Device %u Pin %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId);
+                    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;
+        }
     }
 
     RtlStringFromGUID(&Property->Set, &GuidString);
@@ -288,5 +635,3 @@
 
     return Status;
 }
-
-

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -66,7 +66,11 @@
     PIRP Irp)
 {
     DPRINT1("Dispatch_fnFlush called DeviceObject %p Irp %p\n", DeviceObject);
-
+    //FIXME
+    // cleanup resources
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_SUCCESS;
 }
 
@@ -76,9 +80,39 @@
     PDEVICE_OBJECT DeviceObject,
     PIRP Irp)
 {
+    PSYSAUDIO_CLIENT Client;
+    PIO_STACK_LOCATION IoStatus;
+    ULONG Index;
+
+
     DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
 
-
+	IoStatus = IoGetCurrentIrpStackLocation(Irp);
+
+    Client = (PSYSAUDIO_CLIENT)IoStatus->FileObject->FsContext2;
+
+    DPRINT1("Client %p NumDevices %u\n", Client, Client->NumDevices);
+    for(Index = 0; Index < Client->NumDevices; Index++)
+	{
+        if (Client->Handels[Index])
+		{
+           ZwClose(Client->Handels[Index]);
+		}
+	}
+
+	if (Client->Handels)
+		ExFreePool(Client->Handels);
+
+	if (Client->Devices)
+		ExFreePool(Client->Devices);
+
+	ExFreePool(Client);
+
+    //FIXME
+    // cleanup resources
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_SUCCESS;
 }
 
@@ -175,61 +209,6 @@
     Dispatch_fnFastWrite,
 };
 
-VOID
-NTAPI
-CreatePinWorkerRoutine(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PVOID  Context)
-{
-    NTSTATUS Status;
-    HANDLE PinHandle;
-    HANDLE * Handels;
-    PFILE_OBJECT FileObject;
-    PIRP Irp;
-    PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
-
-    Handels = ExAllocatePool(NonPagedPool, (WorkerContext->Entry->NumberOfPins + 1) * sizeof(HANDLE));
-    if (!Handels)
-    {
-        DPRINT1("No Memory \n");
-        WorkerContext->Irp->IoStatus.Status = STATUS_NO_MEMORY;
-        WorkerContext->Irp->IoStatus.Information = 0;
-        IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT);
-        return;
-    }
-
-
-    Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
-    DPRINT1("KsCreatePin status %x\n", Status);
-
-    if (NT_SUCCESS(Status))
-    {
-         Status = ObReferenceObjectByHandle(PinHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
-         if (NT_SUCCESS(Status))
-         {
-             Status = CreateDispatcher(WorkerContext->Irp, PinHandle, FileObject);
-             DPRINT1("Pins %x\n", WorkerContext->Entry->NumberOfPins);
-             if (WorkerContext->Entry->NumberOfPins)
-             {
-                 RtlMoveMemory(Handels, WorkerContext->Entry->Pins, WorkerContext->Entry->NumberOfPins * sizeof(HANDLE));
-                 ExFreePool(WorkerContext->Entry->Pins);
-             }
-             Handels[WorkerContext->Entry->NumberOfPins-1] = PinHandle;
-             WorkerContext->Entry->Pins = Handels;
-             WorkerContext->Entry->NumberOfPins++;
-         }
-    }
-
-    DPRINT1("CreatePinWorkerRoutine completing irp\n");
-    WorkerContext->Irp->IoStatus.Status = Status;
-    WorkerContext->Irp->IoStatus.Information = 0;
-
-    Irp = WorkerContext->Irp;
-    ExFreePool(Context);
-
-    IoCompleteRequest(Irp, IO_SOUND_INCREMENT);
-}
-
 NTSTATUS
 NTAPI
 DispatchCreateSysAudio(
@@ -242,12 +221,7 @@
     PKSOBJECT_CREATE_ITEM CreateItem;
     PIO_STACK_LOCATION IoStatus;
     LPWSTR Buffer;
-    ULONG Length, DeviceIndex;
-    PSYSAUDIODEVEXT DeviceExtension;
-    PKSAUDIO_DEVICE_ENTRY Entry;
-    KSPIN_CONNECT * PinConnect;
-    PIO_WORKITEM WorkItem;
-    PPIN_WORKER_CONTEXT Context;
+
     static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
 
     IoStatus = IoGetCurrentIrpStackLocation(Irp);
@@ -260,57 +234,12 @@
         /* is the request for a new pin */
         if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
         {
-            Client = (PSYSAUDIO_CLIENT)Irp->Tail.Overlay.OriginalFileObject->FsContext2;
-            DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
-            if (Client)
-            {
-                ASSERT(Client->NumDevices >= 1);
-                DeviceIndex = Client->Devices[Client->NumDevices-1];
-            }
-            else
-            {
-                DPRINT1("Warning: using HACK\n");
-                DeviceIndex = 0;
-            }
-            ASSERT(DeviceIndex < DeviceExtension->NumberOfKsAudioDevices);
-            Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceIndex);
-            ASSERT(Entry);
-
-            Length = (IoStatus->FileObject->FileName.Length - ((wcslen(KS_NAME_PIN)+1) * sizeof(WCHAR)));
-            PinConnect = ExAllocatePool(NonPagedPool, Length);
-            if (!PinConnect)
-            {
-                Irp->IoStatus.Status = STATUS_NO_MEMORY;
-                Irp->IoStatus.Information = 0;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
-                return STATUS_NO_MEMORY;
-            }
-            RtlMoveMemory(PinConnect, IoStatus->FileObject->FileName.Buffer + (wcslen(KS_NAME_PIN)+1), Length);
-            Context = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
-            if (!Context)
-            {
-                Irp->IoStatus.Information = 0;
-                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-            Context->PinConnect = PinConnect;
-            Context->Entry = Entry;
-            Context->Irp = Irp;
-
-            WorkItem = IoAllocateWorkItem(DeviceObject);
-            if (!WorkItem)
-            {
-                Irp->IoStatus.Information = 0;
-                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-            IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
+            Status = CreateDispatcher(Irp);
+            DPRINT1("Virtual pin Status %x\n", Status);
             Irp->IoStatus.Information = 0;
-            Irp->IoStatus.Status = STATUS_PENDING;
-            IoMarkIrpPending(Irp);
-            return STATUS_PENDING;
+            Irp->IoStatus.Status = Status;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
         }
     }
 
@@ -341,6 +270,10 @@
     Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
 
     DPRINT1("KsAllocateObjectHeader result %x\n", Status);
+    /* complete the irp */
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }
 

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/pin.c?rev=39715&r1=39714&r2=39715&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] Sun Feb 22 21:58:51 2009
@@ -23,18 +23,16 @@
     PIRP Irp)
 {
     PDISPATCH_CONTEXT Context;
-    PKSOBJECT_CREATE_ITEM CreateItem;
     NTSTATUS Status;
     ULONG BytesReturned;
     PIO_STACK_LOCATION IoStack;
 
     DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
 
-    /* access the create item */
-    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
-    Context = (PDISPATCH_CONTEXT)CreateItem->Context;
-
     IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
+    ASSERT(Context);
 
     Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
                                           IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
@@ -84,18 +82,16 @@
     PIRP Irp)
 {
     PDISPATCH_CONTEXT Context;
-    PKSOBJECT_CREATE_ITEM CreateItem;
     PIO_STACK_LOCATION IoStack;
     ULONG BytesReturned;
     NTSTATUS Status;
 
     DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject);
 
-   /* access the create item */
-    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
-    Context = (PDISPATCH_CONTEXT)CreateItem->Context;
-
     IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
+    ASSERT(Context);
 
     Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
                                           IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
@@ -228,34 +224,12 @@
 
 NTSTATUS
 CreateDispatcher(
-    IN PIRP Irp,
-    IN HANDLE Handle,
-    IN PFILE_OBJECT FileObject)
-{
-    PKSOBJECT_CREATE_ITEM CreateItem;
+    IN PIRP Irp)
+{
     NTSTATUS Status;
     KSOBJECT_HEADER ObjectHeader;
-    PDISPATCH_CONTEXT Context;
-
-    /* allocate create item */
-    CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
-    if (!CreateItem)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    Context = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
-    if (!Context)
-    {
-        ExFreePool(CreateItem);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    Context->Handle = Handle;
-    Context->FileObject = FileObject;
-
-
-     CreateItem->Context = (PVOID)Context;
 
     /* allocate object header */
-    Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &PinTable);
+    Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable);
     return Status;
 }

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=39715&r1=39714&r2=39715&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] Sun Feb 22 21:58:51 2009
@@ -5,8 +5,15 @@
 {
     ULONG NumDevices;
     PULONG Devices;
+    PHANDLE Handels;
 
 }SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
+
+typedef struct
+{
+    HANDLE PinHandle;
+    ULONG References;
+}PIN_INFO;
 
 
 typedef struct
@@ -18,7 +25,7 @@
     ULONG NumberOfClients;
 
     ULONG NumberOfPins;
-    HANDLE * Pins;
+    PIN_INFO * Pins;
 
 }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
 
@@ -38,17 +45,22 @@
 
 typedef struct
 {
-    PIRP Irp;
-    PKSAUDIO_DEVICE_ENTRY Entry;
-    KSPIN_CONNECT * PinConnect;
+    HANDLE Handle;
+    PFILE_OBJECT FileObject;
+    ULONG PinId;
+    PKSAUDIO_DEVICE_ENTRY AudioEntry;
 
-}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
+}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
 
 typedef struct
 {
-    HANDLE Handle;
-    PFILE_OBJECT FileObject;
-}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
+    PIRP Irp;
+    BOOL CreateRealPin;
+    PKSAUDIO_DEVICE_ENTRY Entry;
+    KSPIN_CONNECT * PinConnect;
+    PDISPATCH_CONTEXT DispatchContext;
+    PSYSAUDIO_CLIENT AudioClient;
+}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
 
 NTSTATUS
 SysAudioAllocateDeviceHeader(
@@ -75,8 +87,6 @@
 
 NTSTATUS
 CreateDispatcher(
-    IN PIRP Irp,
-    IN HANDLE Handle,
-    IN PFILE_OBJECT FileObject);
+    IN PIRP Irp);
 
 #endif



More information about the Ros-diffs mailing list