[ros-diffs] [janderwald] 39671: - Implement KSPROPERTY_CONNECTION_STATE & KSPROPERTY_CONNECTION_FORMAT for property set KSPROPSETID_Connection - Queue a work item when Irql is above dispatch level - Open the input / output stream when initializing the pin

janderwald at svn.reactos.org janderwald at svn.reactos.org
Thu Feb 19 00:27:11 CET 2009


Author: janderwald
Date: Wed Feb 18 17:27:10 2009
New Revision: 39671

URL: http://svn.reactos.org/svn/reactos?rev=39671&view=rev
Log:
- Implement KSPROPERTY_CONNECTION_STATE & KSPROPERTY_CONNECTION_FORMAT for property set KSPROPSETID_Connection
- Queue a work item when Irql is above dispatch level
- Open the input / output stream when initializing the pin

Modified:
    trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/private.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=39671&r1=39670&r2=39671&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] Wed Feb 18 17:27:10 2009
@@ -86,13 +86,13 @@
     ISubdevice * ISubDevice;
     NTSTATUS Status;
     IPortPinWaveCyclic * Pin;
-
     SUBDEVICE_DESCRIPTOR * Descriptor;
     PKSPIN_CONNECT ConnectDetails;
-
     IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
 
     ASSERT(This->Port);
+
+    DPRINT("IPortFilterWaveCyclic_fnNewIrpTarget entered\n");
 
     Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
     if (!NT_SUCCESS(Status))

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c?rev=39671&r1=39670&r2=39671&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] Wed Feb 18 17:27:10 2009
@@ -60,6 +60,7 @@
 
 const GUID KSPROPSETID_Topology                = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
 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}};
 
 ///
 /// undocumented guids

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=39671&r1=39670&r2=39671&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] Wed Feb 18 17:27:10 2009
@@ -9,6 +9,12 @@
     IPortWaveCyclic * Port;
     IPortFilterWaveCyclic * Filter;
     KSPIN_DESCRIPTOR * KsPinDescriptor;
+    PMINIPORTWAVECYCLIC Miniport;
+    PSERVICEGROUP ServiceGroup;
+    PDMACHANNEL DmaChannel;
+    PMINIPORTWAVECYCLICSTREAM Stream;
+    KSSTATE State;
+    PKSDATAFORMAT Format;
 
 }IPortPinWaveCyclicImpl;
 
@@ -165,6 +171,139 @@
     return STATUS_UNSUCCESSFUL;
 }
 
+NTSTATUS
+NTAPI
+IPortPinWaveCyclic_HandleKsProperty(
+    IN IPortPinWaveCyclic * iface,
+    IN PIRP Irp)
+{
+    PKSPROPERTY Property;
+    NTSTATUS Status;
+    UNICODE_STRING GuidString;
+    PIO_STACK_LOCATION IoStack;
+    IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT1("IPortPinWave_HandleKsProperty entered\n");
+
+    if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
+    {
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Connection))
+    {
+        if (Property->Id == KSPROPERTY_CONNECTION_STATE)
+        {
+            PKSSTATE State = (PKSSTATE)Irp->UserBuffer;
+
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE))
+            {
+                Irp->IoStatus.Information = sizeof(KSSTATE);
+                Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+                return STATUS_BUFFER_TOO_SMALL;
+            }
+
+            if (Property->Id & KSPROPERTY_TYPE_SET)
+            {
+                Irp->IoStatus.Information = 0;
+                Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+                if (This->Stream)
+                {
+                    Status = This->Stream->lpVtbl->SetState(This->Stream, *State);
+
+                    DPRINT1("Setting state %x\n", Status);
+                    if (NT_SUCCESS(Status))
+                    {
+                        This->State = *State;
+                        Irp->IoStatus.Information = sizeof(KSSTATE);
+                        Irp->IoStatus.Status = Status;
+                        return Status;
+                    }
+                    Irp->IoStatus.Status = Status;
+                }
+                return Irp->IoStatus.Status;
+            }
+            else if (Property->Id & KSPROPERTY_TYPE_GET)
+            {
+                *State = This->State;
+                Irp->IoStatus.Information = sizeof(KSSTATE);
+                Irp->IoStatus.Status = STATUS_SUCCESS;
+                return STATUS_SUCCESS;
+            }
+        }
+        else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT)
+        {
+            PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
+            if (Property->Id & KSPROPERTY_TYPE_SET)
+            {
+                PKSDATAFORMAT NewDataFormat = AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
+                if (!NewDataFormat)
+                {
+                    Irp->IoStatus.Information = 0;
+                    Irp->IoStatus.Status = STATUS_NO_MEMORY;
+                    return STATUS_NO_MEMORY;
+                }
+                RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);
+
+                if (This->Stream)
+                {
+                    Status = This->Stream->lpVtbl->SetFormat(This->Stream, DataFormat);
+                    if (NT_SUCCESS(Status))
+                    {
+                        if (This->Format)
+                            ExFreePoolWithTag(This->Format, TAG_PORTCLASS);
+                        This->Format = NewDataFormat;
+                        Irp->IoStatus.Information = DataFormat->FormatSize;
+                        Irp->IoStatus.Status = STATUS_SUCCESS;
+                        return STATUS_SUCCESS;
+                    }
+                }
+                Irp->IoStatus.Information = 0;
+                Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+                return STATUS_UNSUCCESSFUL;
+            }
+            else if (Property->Id & KSPROPERTY_TYPE_GET)
+            {
+                PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
+                if (!This->Format)
+                {
+                    DPRINT1("No format\n");
+                    Irp->IoStatus.Information = 0;
+                    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+                    return STATUS_UNSUCCESSFUL;
+                }
+                if (This->Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
+                {
+                    Irp->IoStatus.Information = This->Format->FormatSize;
+                    Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+                    return STATUS_BUFFER_TOO_SMALL;
+                }
+
+                RtlMoveMemory(DataFormat, This->Format, This->Format->FormatSize);
+                Irp->IoStatus.Information = DataFormat->FormatSize;
+                Irp->IoStatus.Status = STATUS_SUCCESS;
+                return STATUS_SUCCESS;
+            }
+        }
+    }
+    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.Status = STATUS_NOT_IMPLEMENTED;
+    Irp->IoStatus.Information = 0;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
 /*
  * @unimplemented
  */
@@ -181,11 +320,10 @@
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    DPRINT1("IPortPinWaveCyclic_fnDeviceIoControl\n");
+    DPRINT1("IPortPinWaveCyclic_fnDeviceIoControl %x %x\n",IoStack->Parameters.DeviceIoControl.IoControlCode,  IOCTL_KS_PROPERTY);
     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
     {
-        /// FIXME
-        /// handle property event
+       return IPortPinWaveCyclic_HandleKsProperty(iface, Irp);
     }
     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
     {
@@ -365,6 +503,8 @@
     IN KSPIN_CONNECT * ConnectDetails,
     IN KSPIN_DESCRIPTOR * KsPinDescriptor)
 {
+    NTSTATUS Status;
+    PKSDATAFORMAT DataFormat;
     IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
 
     Port->lpVtbl->AddRef(Port);
@@ -373,6 +513,42 @@
     This->Port = Port;
     This->Filter = Filter;
     This->KsPinDescriptor = KsPinDescriptor;
+    This->Miniport = GetWaveCyclicMiniport(Port);
+
+    DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
+
+    DPRINT("IPortPinWaveCyclic_fnInit entered\n");
+
+    This->Format = ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
+    if (!This->Format)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    RtlMoveMemory(This->Format, DataFormat, DataFormat->FormatSize);
+
+    Status = This->Miniport->lpVtbl->NewStream(This->Miniport,
+                                               &This->Stream,
+                                               NULL,
+                                               NonPagedPool,
+                                               FALSE, //FIXME
+                                               ConnectDetails->PinId,
+                                               This->Format,
+                                               &This->DmaChannel,
+                                               &This->ServiceGroup);
+
+    DPRINT("IPortPinWaveCyclic_fnInit Status %x\n", Status);
+
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    Status = This->ServiceGroup->lpVtbl->AddMember(This->ServiceGroup, 
+                                                   (PSERVICESINK)&This->lpVtblServiceSink);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to add pin to service group\n");
+        return Status;
+    }
+
+    This->State = KSSTATE_STOP;
 
     return STATUS_SUCCESS;
 }

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c?rev=39671&r1=39670&r2=39671&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c [iso-8859-1] Wed Feb 18 17:27:10 2009
@@ -172,7 +172,6 @@
     /* increment reference on miniport adapter */
     Miniport->lpVtbl->AddRef(Miniport);
 
-    DbgBreakPoint();
     Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup);
     if (!NT_SUCCESS(Status))
     {
@@ -181,8 +180,6 @@
         Miniport->lpVtbl->Release(Miniport);
         return Status;
     }
-
-	DPRINT1("IMiniportMidi sucessfully init\n");
 
     /* get the miniport device descriptor */
     Status = Miniport->lpVtbl->GetDescription(Miniport, &This->pDescriptor);

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=39671&r1=39670&r2=39671&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] Wed Feb 18 17:27:10 2009
@@ -17,6 +17,12 @@
     PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
 }IPortTopologyImpl;
 
+typedef struct
+{
+    PIRP Irp;
+    IIrpTarget *Filter;
+
+}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
 
 static GUID InterfaceGuids[2] = 
 {
@@ -432,6 +438,43 @@
     ISubDevice_fnPinCount
 };
 
+VOID
+NTAPI
+CreatePinWorkerRoutine(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PVOID  Context)
+{
+    NTSTATUS Status;
+    IIrpTarget *Pin;
+    PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
+
+    DPRINT("CreatePinWorkerRoutine called\n");
+
+    Status = WorkerContext->Filter->lpVtbl->NewIrpTarget(WorkerContext->Filter,
+                                                         &Pin,
+                                                         NULL,
+                                                         NULL,
+                                                         NonPagedPool,
+                                                         DeviceObject,
+                                                         WorkerContext->Irp,
+                                                         NULL);
+
+    DPRINT("CreatePinWorkerRoutine Status %x\n", Status);
+
+    if (NT_SUCCESS(Status))
+    {
+        /* create the dispatch object */
+        Status = NewDispatchObject(WorkerContext->Irp, Pin);
+        DPRINT("Pin %p\n", Pin);
+    }
+
+    DPRINT1("CreatePinWorkerRoutine completing irp\n");
+    WorkerContext->Irp->IoStatus.Status = Status;
+    WorkerContext->Irp->IoStatus.Information = 0;
+    IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT);
+}
+
+
 NTSTATUS
 NTAPI
 PcCreateItemDispatch(
@@ -521,7 +564,6 @@
         Status = NewDispatchObject(Irp, Filter);
 
         DPRINT1("Filter %p\n", Filter);
-        DbgBreakPoint();
     }
     else
     {
@@ -534,6 +576,34 @@
         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));
 
@@ -553,7 +623,8 @@
             }
         }
     }
-
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = Status;
     return Status;
 }
 

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c?rev=39671&r1=39670&r2=39671&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] Wed Feb 18 17:27:10 2009
@@ -709,6 +709,14 @@
 };
 
 
+///--------------------------------------------------------------
+PMINIPORTWAVECYCLIC
+GetWaveCyclicMiniport(
+    IN IPortWaveCyclic* iface)
+{
+    IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl *)iface;
+    return This->pMiniport;
+}
 
 //---------------------------------------------------------------
 // IPortWaveCyclic constructor

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=39671&r1=39670&r2=39671&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] Wed Feb 18 17:27:10 2009
@@ -94,7 +94,15 @@
     IN PIRP Irp,
     IN IIrpTarget * Target);
 
-PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag);
+PMINIPORTWAVECYCLIC
+GetWaveCyclicMiniport(
+    IN IPortWaveCyclic* iface);
+
+PVOID
+AllocateItem(
+    IN POOL_TYPE PoolType,
+    IN SIZE_T NumberOfBytes,
+    IN ULONG Tag);
 
 VOID
 FreeItem(



More information about the Ros-diffs mailing list