[ros-diffs] [janderwald] 40835: - Implement IPortMidi, IPortFilterDMus, IPortPinDMus - Implement reading / writing midi stream data using IMiniportMidiStream interface - Delete old IPortMidi implementation

janderwald at svn.reactos.org janderwald at svn.reactos.org
Fri May 8 11:36:02 CEST 2009


Author: janderwald
Date: Fri May  8 13:36:02 2009
New Revision: 40835

URL: http://svn.reactos.org/svn/reactos?rev=40835&view=rev
Log:
- Implement IPortMidi, IPortFilterDMus, IPortPinDMus
- Implement reading / writing midi stream data using IMiniportMidiStream interface
- Delete old IPortMidi implementation

Added:
    trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c   (with props)
    trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c   (with props)
Removed:
    trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c
Modified:
    trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
    trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild
    trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h

Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c?rev=40835&view=auto
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c (added)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c [iso-8859-1] Fri May  8 13:36:02 2009
@@ -1,0 +1,503 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel Streaming
+ * FILE:            drivers/wdm/audio/backpln/portcls/filter_dmus.c
+ * PURPOSE:         portcls wave pci filter
+ * PROGRAMMER:      Johannes Anderwald
+ */
+
+#include "private.h"
+
+typedef struct
+{
+    IPortFilterDMusVtbl *lpVtbl;
+
+    LONG ref;
+
+    IPortDMus* Port;
+    IPortPinDMus ** Pins;
+    SUBDEVICE_DESCRIPTOR * Descriptor;
+
+}IPortFilterDMusImpl;
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnQueryInterface(
+    IPortFilterDMus* iface,
+    IN  REFIID refiid,
+    OUT PVOID* Output)
+{
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
+
+    if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
+        IsEqualGUIDAligned(refiid, &IID_IUnknown))
+    {
+        *Output = &This->lpVtbl;
+        InterlockedIncrement(&This->ref);
+        return STATUS_SUCCESS;
+    }
+    else if (IsEqualGUIDAligned(refiid, &IID_IPort))
+    {
+        *Output = This->Port;
+        This->Port->lpVtbl->AddRef(This->Port);
+        return STATUS_SUCCESS;
+    }
+
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+IPortFilterDMus_fnAddRef(
+    IPortFilterDMus* iface)
+{
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
+
+    return InterlockedIncrement(&This->ref);
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+IPortFilterDMus_fnRelease(
+    IPortFilterDMus* iface)
+{
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
+
+    InterlockedDecrement(&This->ref);
+
+    if (This->ref == 0)
+    {
+        FreeItem(This, TAG_PORTCLASS);
+        return 0;
+    }
+    return This->ref;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnNewIrpTarget(
+    IN IPortFilterDMus* iface,
+    OUT struct IIrpTarget **OutTarget,
+    IN WCHAR * Name,
+    IN PUNKNOWN Unknown,
+    IN POOL_TYPE PoolType,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp,
+    IN KSOBJECT_CREATE *CreateObject)
+{
+    NTSTATUS Status;
+    IPortPinDMus * Pin;
+    PKSPIN_CONNECT ConnectDetails;
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl *)iface;
+
+    ASSERT(This->Port);
+    ASSERT(This->Descriptor);
+    ASSERT(This->Pins);
+
+    DPRINT("IPortFilterDMus_fnNewIrpTarget entered\n");
+
+    /* let's verify the connection request */
+    Status = PcValidateConnectRequest(Irp, &This->Descriptor->Factory, &ConnectDetails);
+    if (!NT_SUCCESS(Status))
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    if (This->Pins[ConnectDetails->PinId] && This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount)
+    {
+        /* release existing instance */
+        ASSERT(0);
+    }
+
+    /* now create the pin */
+    Status = NewPortPinDMus(&Pin);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* initialize the pin */
+    Status = Pin->lpVtbl->Init(Pin, This->Port, iface, ConnectDetails, &This->Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], DeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        Pin->lpVtbl->Release(Pin);
+        return Status;
+    }
+
+    /* release existing pin */
+    if (This->Pins[ConnectDetails->PinId])
+    {
+        This->Pins[ConnectDetails->PinId]->lpVtbl->Release(This->Pins[ConnectDetails->PinId]);
+    }
+    /* store pin */
+    This->Pins[ConnectDetails->PinId] = Pin;
+
+    /* store result */
+    *OutTarget = (IIrpTarget*)Pin;
+
+    /* increment current instance count */
+    This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++;
+
+    return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnDeviceIoControl(
+    IN IPortFilterDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack;
+    ISubdevice *SubDevice = NULL;
+    SUBDEVICE_DESCRIPTOR * Descriptor;
+    NTSTATUS Status;
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl *)iface;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
+    Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice);
+    ASSERT(Status == STATUS_SUCCESS);
+    ASSERT(SubDevice != NULL);
+
+    Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor);
+    ASSERT(Status == STATUS_SUCCESS);
+    ASSERT(Descriptor != NULL);
+
+    SubDevice->lpVtbl->Release(SubDevice);
+
+    return PcPropertyHandler(Irp, Descriptor);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnRead(
+    IN IPortFilterDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnWrite(
+    IN IPortFilterDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnFlush(
+    IN IPortFilterDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnClose(
+    IN IPortFilterDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    ULONG Index;
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl *)iface;
+
+    for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++)
+    {
+        if (This->Pins[Index])
+        {
+            This->Pins[Index]->lpVtbl->Close(This->Pins[Index], DeviceObject, NULL);
+        }
+    }
+
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnQuerySecurity(
+    IN IPortFilterDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnSetSecurity(
+    IN IPortFilterDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortFilterDMus_fnFastDeviceIoControl(
+    IN IPortFilterDMus* iface,
+    IN PFILE_OBJECT FileObject,
+    IN BOOLEAN Wait,
+    IN PVOID InputBuffer,
+    IN ULONG InputBufferLength,
+    OUT PVOID OutputBuffer,
+    IN ULONG OutputBufferLength,
+    IN ULONG IoControlCode,
+    OUT PIO_STATUS_BLOCK StatusBlock,
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    ULONG Index;
+    PKSPROPERTY Property;
+    NTSTATUS Status;
+    ISubdevice * SubDevice = NULL;
+    PSUBDEVICE_DESCRIPTOR Descriptor = NULL;
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl *)iface;
+
+    Property = (PKSPROPERTY)InputBuffer;
+
+    if (InputBufferLength < sizeof(KSPROPERTY))
+        return FALSE;
+
+
+    /* get private interface */
+    Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice);
+    if (!NT_SUCCESS(Status))
+        return FALSE;
+
+    /* get descriptor */
+    Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor);
+    if (!NT_SUCCESS(Status))
+    {
+        SubDevice->lpVtbl->Release(SubDevice);
+        return FALSE;
+    }
+
+    for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
+    {
+        if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
+        {
+            FastPropertyHandler(FileObject, (PKSPROPERTY)InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock,
+                                1,
+                                &Descriptor->FilterPropertySet.Properties[Index],
+                                Descriptor, SubDevice);
+        }
+    }
+    return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortFilterDMus_fnFastRead(
+    IN IPortFilterDMus* iface,
+    IN PFILE_OBJECT FileObject,
+    IN PLARGE_INTEGER FileOffset,
+    IN ULONG Length,
+    IN BOOLEAN Wait,
+    IN ULONG LockKey,
+    IN PVOID Buffer,
+    OUT PIO_STATUS_BLOCK StatusBlock,
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    UNIMPLEMENTED
+    return FALSE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortFilterDMus_fnFastWrite(
+    IN IPortFilterDMus* iface,
+    IN PFILE_OBJECT FileObject,
+    IN PLARGE_INTEGER FileOffset,
+    IN ULONG Length,
+    IN BOOLEAN Wait,
+    IN ULONG LockKey,
+    IN PVOID Buffer,
+    OUT PIO_STATUS_BLOCK StatusBlock,
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    UNIMPLEMENTED
+    return FALSE;
+}
+
+/*
+ * @implemented
+ */
+static
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnInit(
+    IN IPortFilterDMus* iface,
+    IN IPortDMus* Port)
+{
+    ISubdevice * ISubDevice;
+    SUBDEVICE_DESCRIPTOR * Descriptor;
+    NTSTATUS Status;
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
+
+    This->Port = Port;
+
+    /* get our private interface */
+    Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
+    if (!NT_SUCCESS(Status))
+        return STATUS_UNSUCCESSFUL;
+
+    /* get the subdevice descriptor */
+    Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
+
+    /* release subdevice interface */
+    ISubDevice->lpVtbl->Release(ISubDevice);
+
+    if (!NT_SUCCESS(Status))
+        return STATUS_UNSUCCESSFUL;
+
+    /* save descriptor */
+    This->Descriptor = Descriptor;
+
+    /* allocate pin array */
+    This->Pins = AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinDMus*), TAG_PORTCLASS);
+
+    if (!This->Pins)
+        return STATUS_UNSUCCESSFUL;
+
+    /* increment reference count */
+    Port->lpVtbl->AddRef(Port);
+
+    return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+NTAPI
+IPortFilterDMus_fnFreePin(
+    IN IPortFilterDMus* iface,
+    IN struct IPortPinDMus* Pin)
+{
+    ULONG Index;
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
+
+    for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++)
+    {
+        if (This->Pins[Index] == Pin)
+        {
+            This->Pins[Index]->lpVtbl->Release(This->Pins[Index]);
+            This->Pins[Index] = NULL;
+            return STATUS_SUCCESS;
+        }
+    }
+    return STATUS_UNSUCCESSFUL;
+}
+
+static
+VOID
+NTAPI
+IPortFilterDMus_fnNotifyPins(
+    IN IPortFilterDMus* iface)
+{
+    ULONG Index;
+    IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
+
+    DPRINT("Notifying %u pins\n", This->Descriptor->Factory.PinDescriptorCount);
+
+    for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++)
+    {
+        This->Pins[Index]->lpVtbl->Notify(This->Pins[Index]);
+    }
+}
+
+static IPortFilterDMusVtbl vt_IPortFilterDMus =
+{
+    IPortFilterDMus_fnQueryInterface,
+    IPortFilterDMus_fnAddRef,
+    IPortFilterDMus_fnRelease,
+    IPortFilterDMus_fnNewIrpTarget,
+    IPortFilterDMus_fnDeviceIoControl,
+    IPortFilterDMus_fnRead,
+    IPortFilterDMus_fnWrite,
+    IPortFilterDMus_fnFlush,
+    IPortFilterDMus_fnClose,
+    IPortFilterDMus_fnQuerySecurity,
+    IPortFilterDMus_fnSetSecurity,
+    IPortFilterDMus_fnFastDeviceIoControl,
+    IPortFilterDMus_fnFastRead,
+    IPortFilterDMus_fnFastWrite,
+    IPortFilterDMus_fnInit,
+    IPortFilterDMus_fnFreePin,
+    IPortFilterDMus_fnNotifyPins
+};
+
+NTSTATUS 
+NewPortFilterDMus(
+    OUT PPORTFILTERDMUS * OutFilter)
+{
+    IPortFilterDMusImpl * This;
+
+    This = AllocateItem(NonPagedPool, sizeof(IPortFilterDMusImpl), TAG_PORTCLASS);
+    if (!This)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* initialize IPortFilterDMus */
+    This->ref = 1;
+    This->lpVtbl = &vt_IPortFilterDMus;
+
+    /* return result */
+    *OutFilter = (IPortFilterDMus*)&This->lpVtbl;
+
+    return STATUS_SUCCESS;
+}

Propchange: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c
------------------------------------------------------------------------------
    svn:eol-style = native

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=40835&r1=40834&r2=40835&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] Fri May  8 13:36:02 2009
@@ -13,10 +13,14 @@
 const GUID CLSID_PortMidi = {0xb4c90a43L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
 const GUID CLSID_PortWaveCyclic = {0xb4c90a2aL, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
 const GUID CLSID_PortWavePci = {0xb4c90a54L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
-const GUID CLSID_PortDMus;
-const GUID IID_IMiniportDMus;
+const GUID CLSID_PortDMus    = {0xb7902fe9L, 0xfb0a, 0x11d1, {0x81, 0xb0, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
 
+const GUID IID_IMiniportDMus = {0xc096df9dL, 0xfb09, 0x11d1, {0x81, 0xb0, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
 const GUID IID_IMiniportTopology = {0xb4c90a31L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
+const GUID IID_IMiniportMidi    = {0xb4c90a41L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
+const GUID IID_IMiniportWavePci = {0xb4c90a52L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
+
+
 const GUID IID_IPortTopology = {0xb4c90a30L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
 
 const GUID CLSID_MiniportDriverDMusUART;
@@ -32,8 +36,7 @@
 const GUID IID_IPortWavePci = {0xb4c90a50L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
 const GUID IID_IPortWavePciStream = {0xb4c90a51L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
 const GUID IID_IPortMidi    = {0xb4c90a40L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
-const GUID IID_IMiniportMidi    = {0xb4c90a41L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
-const GUID IID_IMiniportWavePci = {0xb4c90a52L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
+const GUID IID_IPortDMus    = {0xc096df9cL, 0xfb09, 0x11d1, {0x81, 0xb0, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
 const GUID IID_IAdapterPowerManagement = {0x793417D0L, 0x35FE, 0x11D1, {0xAD, 0x08, 0x00, 0xA0, 0xC9, 0x0A, 0xB1, 0xB0}};
 
 const GUID IID_IMiniportWaveCyclic = {0xb4c90a27L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};

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=40835&r1=40834&r2=40835&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] Fri May  8 13:36:02 2009
@@ -497,7 +497,7 @@
 typedef IPortFilterWaveRT *PPORTFILTERWAVERT;
 
 /*****************************************************************************
- * IPortPinWavePci
+ * IPortPinWaveRT
  *****************************************************************************
  */
 
@@ -570,6 +570,59 @@
 };
 
 /*****************************************************************************
+ * IPortFilterDMus
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IPortFilterDMus
+
+struct IPortPinDMus;
+
+DECLARE_INTERFACE_(IPortFilterDMus, IIrpTarget)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IRPTARGET()
+
+    STDMETHOD_(NTSTATUS, Init)(THIS_
+        IN PPORTDMUS Port)PURE;
+
+    STDMETHOD_(NTSTATUS, FreePin)(THIS_
+        IN struct IPortPinDMus* Pin)PURE;
+
+    STDMETHOD_(VOID, NotifyPins)(THIS);
+};
+
+typedef IPortFilterDMus *PPORTFILTERDMUS;
+
+/*****************************************************************************
+ * IPortPinDMus
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IPortPinDMus
+
+DECLARE_INTERFACE_(IPortPinDMus, IIrpTarget)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    DEFINE_ABSTRACT_IRPTARGET()
+
+    STDMETHOD_(NTSTATUS, Init)(THIS_
+        IN PPORTDMUS Port,
+        IN PPORTFILTERDMUS Filter,
+        IN KSPIN_CONNECT * ConnectDetails,
+        IN KSPIN_DESCRIPTOR * PinDescriptor,
+        IN PDEVICE_OBJECT DeviceObject) PURE;
+
+    STDMETHOD_(VOID, Notify)(THIS);
+};
+
+typedef IPortPinDMus *PPORTPINDMUS;
+
+/*****************************************************************************
  * IDmaChannelInit
  *****************************************************************************
  */

Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c?rev=40835&view=auto
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c (added)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c [iso-8859-1] Fri May  8 13:36:02 2009
@@ -1,0 +1,844 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel Streaming
+ * FILE:            drivers/wdm/audio/backpln/portcls/pin_dmus.c
+ * PURPOSE:         DMus IRP Audio Pin
+ * PROGRAMMER:      Johannes Anderwald
+ */
+
+#include "private.h"
+
+#include "private.h"
+
+typedef struct
+{
+    IPortPinDMusVtbl *lpVtbl;
+    IServiceSinkVtbl *lpVtblServiceSink;
+
+    LONG ref;
+    IPortDMus * Port;
+    IPortFilterDMus * Filter;
+    KSPIN_DESCRIPTOR * KsPinDescriptor;
+    PMINIPORTDMUS Miniport;
+
+    PSERVICEGROUP ServiceGroup;
+
+    PMINIPORTMIDI MidiMiniport;
+    PMINIPORTMIDISTREAM MidiStream;
+
+
+    KSSTATE State;
+    PKSDATAFORMAT Format;
+    KSPIN_CONNECT * ConnectDetails;
+
+    BOOL Capture;
+    PDEVICE_OBJECT DeviceObject;
+    IIrpQueue * IrpQueue;
+
+    ULONG TotalPackets;
+    ULONG PreCompleted;
+    ULONG PostCompleted;
+
+}IPortPinDMusImpl;
+
+
+typedef struct
+{
+    IPortPinDMusImpl *Pin;
+    PIO_WORKITEM WorkItem;
+    KSSTATE State;
+}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
+
+NTSTATUS
+NTAPI
+IPortDMus_fnProcessNewIrp(
+    IPortPinDMusImpl * This);
+
+//==================================================================================================================================
+
+static
+NTSTATUS
+NTAPI
+IServiceSink_fnQueryInterface(
+    IServiceSink* iface,
+    IN  REFIID refiid,
+    OUT PVOID* Output)
+{
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink);
+
+    DPRINT("IServiceSink_fnQueryInterface entered\n");
+
+    if (IsEqualGUIDAligned(refiid, &IID_IServiceSink) ||
+        IsEqualGUIDAligned(refiid, &IID_IUnknown))
+    {
+        *Output = &This->lpVtblServiceSink;
+        InterlockedIncrement(&This->ref);
+        return STATUS_SUCCESS;
+    }
+    return STATUS_UNSUCCESSFUL;
+}
+
+static
+ULONG
+NTAPI
+IServiceSink_fnAddRef(
+    IServiceSink* iface)
+{
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink);
+    DPRINT("IServiceSink_fnAddRef entered\n");
+
+    return InterlockedIncrement(&This->ref);
+}
+
+static
+ULONG
+NTAPI
+IServiceSink_fnRelease(
+    IServiceSink* iface)
+{
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink);
+
+    InterlockedDecrement(&This->ref);
+
+    DPRINT("IServiceSink_fnRelease entered %u\n", This->ref);
+
+    if (This->ref == 0)
+    {
+        FreeItem(This, TAG_PORTCLASS);
+        return 0;
+    }
+    /* Return new reference count */
+    return This->ref;
+}
+static
+VOID
+NTAPI
+SetStreamWorkerRoutine(
+    IN PDEVICE_OBJECT  DeviceObject,
+    IN PVOID  Context)
+{
+    IPortPinDMusImpl * This;
+    PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context;
+    KSSTATE State;
+
+    This = Ctx->Pin;
+    State = Ctx->State;
+
+    IoFreeWorkItem(Ctx->WorkItem);
+    FreeItem(Ctx, TAG_PORTCLASS);
+
+    /* Has the audio stream resumed? */
+    if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) && State == KSSTATE_STOP)
+        return;
+
+    /* Set the state */
+    if (NT_SUCCESS(This->MidiStream->lpVtbl->SetState(This->MidiStream, State)))
+    {
+        /* Set internal state to stop */
+        This->State = State;
+
+        if (This->State == KSSTATE_STOP)
+        {
+            /* reset start stream */
+            This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name
+            DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->PreCompleted, This->PostCompleted);
+        }
+    }
+}
+static
+VOID
+NTAPI
+SetStreamState(
+   IN IPortPinDMusImpl * This,
+   IN KSSTATE State)
+{
+    PIO_WORKITEM WorkItem;
+    PSETSTREAM_CONTEXT Context;
+
+    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+    /* Has the audio stream resumed? */
+    if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) && State == KSSTATE_STOP)
+        return;
+
+    /* Has the audio state already been set? */
+    if (This->State == State)
+        return;
+
+    /* allocate set state context */
+    Context = AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS);
+
+    if (!Context)
+        return;
+
+    /* allocate work item */
+    WorkItem = IoAllocateWorkItem(This->DeviceObject);
+
+    if (!WorkItem)
+    {
+        ExFreePool(Context);
+        return;
+    }
+
+    Context->Pin = (PVOID)This;
+    Context->WorkItem = WorkItem;
+    Context->State = State;
+
+    /* queue the work item */
+    IoQueueWorkItem(WorkItem, SetStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
+}
+
+VOID
+TransferMidiData(
+    IPortPinDMusImpl * This)
+{
+    NTSTATUS Status;
+    PUCHAR Buffer;
+    ULONG BufferSize;
+    ULONG BytesWritten;
+
+    do
+    {
+        Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
+        if (!NT_SUCCESS(Status))
+        {
+            SetStreamState(This, KSSTATE_STOP);
+            return;
+        }
+
+        if (This->Capture)
+        {
+            Status = This->MidiStream->lpVtbl->Read(This->MidiStream, Buffer, BufferSize, &BytesWritten);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT("Read failed with %x\n", Status);
+                return;
+            }
+        }
+        else
+        {
+            Status = This->MidiStream->lpVtbl->Write(This->MidiStream, Buffer, BufferSize, &BytesWritten);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT("Write failed with %x\n", Status);
+                return;
+            }
+        }
+
+        if (!BytesWritten)
+        {
+            DPRINT("Device is busy retry later\n");
+            return;
+        }
+
+        This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesWritten);
+
+    }while(TRUE);
+
+}
+
+static
+VOID
+NTAPI
+IServiceSink_fnRequestService(
+    IServiceSink* iface)
+{
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink);
+
+    ASSERT_IRQL(DISPATCH_LEVEL);
+
+    if (This->MidiStream)
+    {
+        TransferMidiData(This);
+    }
+
+
+}
+
+static IServiceSinkVtbl vt_IServiceSink = 
+{
+    IServiceSink_fnQueryInterface,
+    IServiceSink_fnAddRef,
+    IServiceSink_fnRelease,
+    IServiceSink_fnRequestService
+};
+
+//==================================================================================================================================
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnQueryInterface(
+    IPortPinDMus* iface,
+    IN  REFIID refiid,
+    OUT PVOID* Output)
+{
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
+
+    if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) || 
+        IsEqualGUIDAligned(refiid, &IID_IUnknown))
+    {
+        *Output = &This->lpVtbl;
+        InterlockedIncrement(&This->ref);
+        return STATUS_SUCCESS;
+    }
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+IPortPinDMus_fnAddRef(
+    IPortPinDMus* iface)
+{
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
+
+    return InterlockedIncrement(&This->ref);
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+IPortPinDMus_fnRelease(
+    IPortPinDMus* iface)
+{
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
+
+    InterlockedDecrement(&This->ref);
+
+    if (This->ref == 0)
+    {
+        FreeItem(This, TAG_PORTCLASS);
+        return 0;
+    }
+    return This->ref;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnNewIrpTarget(
+    IN IPortPinDMus* iface,
+    OUT struct IIrpTarget **OutTarget,
+    IN WCHAR * Name,
+    IN PUNKNOWN Unknown,
+    IN POOL_TYPE PoolType,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp,
+    IN KSOBJECT_CREATE *CreateObject)
+{
+    UNIMPLEMENTED
+
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnDeviceIoControl(
+    IN IPortPinDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    UNIMPLEMENTED
+
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnRead(
+    IN IPortPinDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnWrite(
+    IN IPortPinDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnFlush(
+    IN IPortPinDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+static
+VOID
+NTAPI
+CloseStreamRoutine(
+    IN PDEVICE_OBJECT  DeviceObject,
+    IN PVOID Context)
+{
+    PMINIPORTMIDISTREAM Stream = NULL;
+    NTSTATUS Status;
+    ISubdevice *ISubDevice;
+    PSUBDEVICE_DESCRIPTOR Descriptor;
+    IPortPinDMusImpl * This;
+    PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
+
+    This = (IPortPinDMusImpl*)Ctx->Pin;
+
+    if (This->MidiStream)
+    {
+        if (This->State != KSSTATE_STOP)
+        {
+            This->MidiStream->lpVtbl->SetState(This->MidiStream, KSSTATE_STOP);
+            KeStallExecutionProcessor(10);
+        }
+        Stream = This->MidiStream;
+        This->MidiStream = NULL;
+    }
+
+    if (This->ServiceGroup)
+    {
+        This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
+        This->ServiceGroup->lpVtbl->Release(This->ServiceGroup);
+    }
+
+    Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
+    if (NT_SUCCESS(Status))
+    {
+        Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
+        if (NT_SUCCESS(Status))
+        {
+            ISubDevice->lpVtbl->Release(ISubDevice);
+            Descriptor->Factory.Instances[This->ConnectDetails->PinId].CurrentPinInstanceCount--;
+        }
+    }
+
+    if (This->Format)
+    {
+        ExFreePool(This->Format);
+        This->Format = NULL;
+    }
+
+    /* complete the irp */
+    Ctx->Irp->IoStatus.Information = 0;
+    Ctx->Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT);
+
+    /* free the work item */
+    IoFreeWorkItem(Ctx->WorkItem);
+
+    /* free work item ctx */
+    FreeItem(Ctx, TAG_PORTCLASS);
+
+    /* destroy DMus pin */
+    This->Filter->lpVtbl->FreePin(This->Filter, (PPORTPINDMUS)This);
+
+    if (Stream)
+    {
+        DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql());
+        Stream->lpVtbl->Release(Stream);
+    }
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnClose(
+    IN IPortPinDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    PCLOSESTREAM_CONTEXT Ctx;
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
+
+    if (This->MidiStream)
+    {
+        Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
+        if (!Ctx)
+        {
+            DPRINT1("Failed to allocate stream context\n");
+            goto cleanup;
+        }
+
+        Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
+        if (!Ctx->WorkItem)
+        {
+            DPRINT1("Failed to allocate work item\n");
+            goto cleanup;
+        }
+
+        Ctx->Irp = Irp;
+        Ctx->Pin = (PVOID)This;
+
+        IoMarkIrpPending(Irp);
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = STATUS_PENDING;
+
+        /* defer work item */
+        IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx);
+        /* Return result */
+        return STATUS_PENDING;
+    }
+
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return STATUS_SUCCESS;
+
+cleanup:
+
+    if (Ctx)
+        FreeItem(Ctx, TAG_PORTCLASS);
+
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_UNSUCCESSFUL;
+
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnQuerySecurity(
+    IN IPortPinDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnSetSecurity(
+    IN IPortPinDMus* iface,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortPinDMus_fnFastDeviceIoControl(
+    IN IPortPinDMus* iface,
+    IN PFILE_OBJECT FileObject,
+    IN BOOLEAN Wait,
+    IN PVOID InputBuffer,
+    IN ULONG InputBufferLength,
+    OUT PVOID OutputBuffer,
+    IN ULONG OutputBufferLength,
+    IN ULONG IoControlCode,
+    OUT PIO_STATUS_BLOCK StatusBlock,
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    UNIMPLEMENTED
+    return FALSE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortPinDMus_fnFastRead(
+    IN IPortPinDMus* iface,
+    IN PFILE_OBJECT FileObject,
+    IN PLARGE_INTEGER FileOffset,
+    IN ULONG Length,
+    IN BOOLEAN Wait,
+    IN ULONG LockKey,
+    IN PVOID Buffer,
+    OUT PIO_STATUS_BLOCK StatusBlock,
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    NTSTATUS Status;
+    PCONTEXT_WRITE Packet;
+    PIRP Irp;
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
+
+    DPRINT("IPortPinDMus_fnFastRead entered\n");
+
+    Packet = (PCONTEXT_WRITE)Buffer;
+
+    Irp = Packet->Irp;
+    StatusBlock->Status = STATUS_PENDING;
+
+    Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer, Length, Irp);
+
+    if (!NT_SUCCESS(Status))
+        return FALSE;
+
+    if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
+    {
+        /* some should initiate a state request but didnt do it */
+        DPRINT1("Starting stream with %lu mappings\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue));
+        SetStreamState(This, KSSTATE_RUN);
+    }
+    return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortPinDMus_fnFastWrite(
+    IN IPortPinDMus* iface,
+    IN PFILE_OBJECT FileObject,
+    IN PLARGE_INTEGER FileOffset,
+    IN ULONG Length,
+    IN BOOLEAN Wait,
+    IN ULONG LockKey,
+    IN PVOID Buffer,
+    OUT PIO_STATUS_BLOCK StatusBlock,
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    NTSTATUS Status;
+    PCONTEXT_WRITE Packet;
+    PIRP Irp;
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
+
+    InterlockedIncrement((PLONG)&This->TotalPackets);
+
+    DPRINT("IPortPinDMus_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted);
+
+    Packet = (PCONTEXT_WRITE)Buffer;
+
+
+    if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue))
+    {
+        Irp = Packet->Irp;
+        StatusBlock->Status = STATUS_PENDING;
+        InterlockedIncrement((PLONG)&This->PostCompleted);
+    }
+    else
+    {
+        Irp = NULL;
+        Packet->Irp->IoStatus.Status = STATUS_SUCCESS;
+        Packet->Irp->IoStatus.Information = Packet->Header.FrameExtent;
+        IoCompleteRequest(Packet->Irp, IO_SOUND_INCREMENT);
+        StatusBlock->Status = STATUS_SUCCESS;
+        InterlockedIncrement((PLONG)&This->PreCompleted);
+    }
+
+    Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer, Length, Irp);
+
+    if (!NT_SUCCESS(Status))
+        return FALSE;
+
+    if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
+    {
+        SetStreamState(This, KSSTATE_RUN);
+        /* some should initiate a state request but didnt do it */
+        DPRINT1("Starting stream with %lu mappings Status %x\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), Status);
+    }
+
+    return TRUE;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IPortPinDMus_fnInit(
+    IN IPortPinDMus* iface,
+    IN PPORTDMUS Port,
+    IN PPORTFILTERDMUS Filter,
+    IN KSPIN_CONNECT * ConnectDetails,
+    IN KSPIN_DESCRIPTOR * KsPinDescriptor,
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    NTSTATUS Status;
+    PKSDATAFORMAT DataFormat;
+    BOOL Capture;
+
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
+
+    Port->lpVtbl->AddRef(Port);
+    Filter->lpVtbl->AddRef(Filter);
+
+    This->Port = Port;
+    This->Filter = Filter;
+    This->KsPinDescriptor = KsPinDescriptor;
+    This->ConnectDetails = ConnectDetails;
+    This->DeviceObject = DeviceObject;
+    GetDMusMiniport(Port, &This->Miniport, &This->MidiMiniport);
+
+    DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
+
+    DPRINT("IPortPinDMus_fnInit entered\n");
+
+    This->Format = ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
+    if (!This->Format)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    RtlMoveMemory(This->Format, DataFormat, DataFormat->FormatSize);
+
+    if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
+    {
+        Capture = FALSE;
+    }
+    else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
+    {
+        Capture = TRUE;
+    }
+    else
+    {
+        DPRINT1("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
+        KeBugCheck(0);
+    }
+
+    Status = NewIrpQueue(&This->IrpQueue);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to allocate IrpQueue with %x\n", Status);
+        return Status;
+    }
+
+    if (This->MidiMiniport)
+    {
+        Status = This->MidiMiniport->lpVtbl->NewStream(This->MidiMiniport,
+                                                       &This->MidiStream,
+                                                       NULL,
+                                                       NonPagedPool,
+                                                       ConnectDetails->PinId,
+                                                       Capture,
+                                                       This->Format,
+                                                       &This->ServiceGroup);
+
+        DPRINT("IPortPinDMus_fnInit Status %x\n", Status);
+
+        if (!NT_SUCCESS(Status))
+            return Status;
+    }
+
+    if (This->ServiceGroup)
+    {
+        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->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
+    }
+
+    Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, This->Format, DeviceObject, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IrpQueue_Init failed with %x\n", Status);
+        return Status;
+    }
+
+    This->State = KSSTATE_STOP;
+    This->Capture = Capture;
+
+    return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+IPortPinDMus_fnNotify(
+    IN IPortPinDMus* iface)
+{
+    IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
+
+    This->ServiceGroup->lpVtbl->RequestService(This->ServiceGroup);
+}
+
+static IPortPinDMusVtbl vt_IPortPinDMus =
+{
+    IPortPinDMus_fnQueryInterface,
+    IPortPinDMus_fnAddRef,
+    IPortPinDMus_fnRelease,
+    IPortPinDMus_fnNewIrpTarget,
+    IPortPinDMus_fnDeviceIoControl,
+    IPortPinDMus_fnRead,
+    IPortPinDMus_fnWrite,
+    IPortPinDMus_fnFlush,
+    IPortPinDMus_fnClose,
+    IPortPinDMus_fnQuerySecurity,
+    IPortPinDMus_fnSetSecurity,
+    IPortPinDMus_fnFastDeviceIoControl,
+    IPortPinDMus_fnFastRead,
+    IPortPinDMus_fnFastWrite,
+    IPortPinDMus_fnInit,
+    IPortPinDMus_fnNotify
+};
+
+
+
+
+NTSTATUS NewPortPinDMus(
+    OUT IPortPinDMus ** OutPin)
+{
+    IPortPinDMusImpl * This;
+
+    This = AllocateItem(NonPagedPool, sizeof(IPortPinDMusImpl), TAG_PORTCLASS);
+    if (!This)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* initialize IPortPinDMus */
+    This->ref = 1;
+    This->lpVtbl = &vt_IPortPinDMus;
+    This->lpVtblServiceSink = &vt_IServiceSink;
+
+
+    /* store result */
+    *OutPin = (IPortPinDMus*)&This->lpVtbl;
+
+    return STATUS_SUCCESS;
+}
+
+
+

Propchange: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c?rev=40835&r1=40834&r2=40835&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c [iso-8859-1] Fri May  8 13:36:02 2009
@@ -31,7 +31,7 @@
     }
 
     if (IsEqualGUIDAligned(ClassId, &CLSID_PortMidi))
-        Status = NewPortMidi(OutPort);
+        Status = NewPortDMus(OutPort);
     else if (IsEqualGUIDAligned(ClassId, &CLSID_PortDMus))
         Status = NewPortDMus(OutPort);
     else if (IsEqualGUIDAligned(ClassId, &CLSID_PortTopology))

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c?rev=40835&r1=40834&r2=40835&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] Fri May  8 13:36:02 2009
@@ -11,16 +11,39 @@
 typedef struct
 {
     IPortDMusVtbl *lpVtbl;
+    IServiceSinkVtbl *lpVtblServiceSink;
+    ISubdeviceVtbl *lpVtblSubDevice;
 
     LONG ref;
     BOOL bInitialized;
     IMiniportDMus *pMiniport;
+    IMiniportMidi *pMiniportMidi;
     DEVICE_OBJECT *pDeviceObject;
     PSERVICEGROUP ServiceGroup;
+    PPINCOUNT pPinCount;
+    PPOWERNOTIFY pPowerNotify;
+    PPORTFILTERDMUS Filter;
+
+    PPCFILTER_DESCRIPTOR pDescriptor;
+    PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
 
 }IPortDMusImpl;
 
-const GUID IID_IPortDMus;
+static GUID InterfaceGuids[3] = 
+{
+    {
+        /// KS_CATEGORY_AUDIO
+        0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
+    },
+    {
+        /// KS_CATEGORY_RENDER
+        0x65E8773E, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
+    },
+    {
+        /// KS_CATEGORY_CAPTURE
+        0x65E8773D, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
+    }
+};
 
 //---------------------------------------------------------------
 // IUnknown interface functions
@@ -33,19 +56,39 @@
     IN  REFIID refiid,
     OUT PVOID* Output)
 {
-    IPortDMusImpl * This = (IPortDMusImpl*)iface;
+    UNICODE_STRING GuidString;
+    IPortDMusImpl * This = (IPortDMusImpl*)iface;
+
+
     if (IsEqualGUIDAligned(refiid, &IID_IPortDMus) ||
+        IsEqualGUIDAligned(refiid, &IID_IPortMidi) ||
         IsEqualGUIDAligned(refiid, &IID_IUnknown))
     {
         *Output = &This->lpVtbl;
-        _InterlockedIncrement(&This->ref);
+        InterlockedIncrement(&This->ref);
         return STATUS_SUCCESS;
     }
+    else if (IsEqualGUIDAligned(refiid, &IID_ISubdevice))
+    {
+        *Output = &This->lpVtblSubDevice;
+        InterlockedIncrement(&This->ref);
+        return STATUS_SUCCESS;
+    }
+    else if (IsEqualGUIDAligned(refiid, &IID_IDrmPort) ||
+             IsEqualGUIDAligned(refiid, &IID_IDrmPort2))
+    {
+        return NewIDrmPort((PDRMPORT2*)Output);
+    }
     else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
     {
         return NewPortClsVersion((PPORTCLSVERSION*)Output);
     }
 
+    if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
+    {
+        DPRINT1("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
+        RtlFreeUnicodeString(&GuidString);
+    }
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -118,8 +161,12 @@
     IN PUNKNOWN  UnknownAdapter  OPTIONAL,
     IN PRESOURCELIST  ResourceList)
 {
-    IMiniportDMus * Miniport;
+    IMiniportDMus * Miniport = NULL;
+    IMiniportMidi * MidiMiniport = NULL;
     NTSTATUS Status;
+    PSERVICEGROUP ServiceGroup;
+    PPINCOUNT PinCount;
+    PPOWERNOTIFY PowerNotify;
     IPortDMusImpl * This = (IPortDMusImpl*)iface;
 
     ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
@@ -133,24 +180,110 @@
     Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportDMus, (PVOID*)&Miniport);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n");
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &This->ServiceGroup);
+        /* check for legacy interface */
+        Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportMidi, (PVOID*)&MidiMiniport);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n");
+            return STATUS_INVALID_PARAMETER;
+        }
+    }
+
+    if (Miniport)
+    {
+        /* initialize IMiniportDMus */
+        Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IMiniportDMus_Init failed with %x\n", Status);
+            return Status;
+        }
+
+        /* get the miniport device descriptor */
+        Status = Miniport->lpVtbl->GetDescription(Miniport, &This->pDescriptor);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("failed to get description\n");
+            Miniport->lpVtbl->Release(Miniport);
+            return Status;
+        }
+    }
+    else
+    {
+        /* initialize IMiniportMidi */
+        Status = MidiMiniport->lpVtbl->Init(MidiMiniport, UnknownAdapter, ResourceList, (IPortMidi*)iface, &ServiceGroup);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IMiniportMidi_Init failed with %x\n", Status);
+            return Status;
+        }
+
+        /* get the miniport device descriptor */
+        Status = MidiMiniport->lpVtbl->GetDescription(MidiMiniport, &This->pDescriptor);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("failed to get description\n");
+            MidiMiniport->lpVtbl->Release(MidiMiniport);
+            return Status;
+        }
+    }
+
+    /* create the subdevice descriptor */
+    Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor, 
+                                         3,
+                                         InterfaceGuids, 
+                                         0, 
+                                         NULL,
+                                         0, 
+                                         NULL,
+                                         0,
+                                         0,
+                                         0,
+                                         NULL,
+                                         0,
+                                         NULL,
+                                         This->pDescriptor);
+
     if (!NT_SUCCESS(Status))
     {
-        DPRINT("IMinIPortDMus_Init failed with %x\n", Status);
+        DPRINT1("Failed to create descriptior\n");
+
+        if (Miniport)
+            Miniport->lpVtbl->Release(Miniport);
+        else
+            MidiMiniport->lpVtbl->Release(MidiMiniport);
+
         return Status;
     }
+
+    ASSERT(This->ServiceGroup);
+    ASSERT(ServiceGroup == This->ServiceGroup);
 
     /* Initialize port object */
     This->pMiniport = Miniport;
+    This->pMiniportMidi = MidiMiniport;
     This->pDeviceObject = DeviceObject;
     This->bInitialized = TRUE;
 
     /* increment reference on miniport adapter */
     Miniport->lpVtbl->AddRef(Miniport);
+
+
+    /* check if it supports IPinCount interface */
+    Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IPinCount, (PVOID*)&PinCount);
+    if (NT_SUCCESS(Status))
+    {
+        /* store IPinCount interface */
+        This->pPinCount = PinCount;
+    }
+
+    /* does the Miniport adapter support IPowerNotify interface*/
+    Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IPowerNotify, (PVOID*)&PowerNotify);
+    if (NT_SUCCESS(Status))
+    {
+        /* store reference */
+        This->pPowerNotify = PowerNotify;
+    }
 
     return STATUS_SUCCESS;
 }
@@ -180,11 +313,339 @@
     return STATUS_UNSUCCESSFUL;
 }
 
+VOID
+NTAPI
+IPortDMus_fnNotify(
+    IN IPortDMus * iface,
+    IN PSERVICEGROUP  ServiceGroup  OPTIONAL)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)iface;
+
+    if (ServiceGroup)
+    {
+        ServiceGroup->lpVtbl->RequestService (ServiceGroup);
+        return;
+    }
+
+    ASSERT(This->ServiceGroup);
+
+    /* notify miniport service group */
+    This->ServiceGroup->lpVtbl->RequestService(This->ServiceGroup);
+
+    /* notify stream miniport service group */
+    if (This->Filter)
+    {
+        This->Filter->lpVtbl->NotifyPins(This->Filter);
+    }
+}
+
+VOID
+NTAPI
+IPortDMus_fnRegisterServiceGroup(
+    IN IPortDMus * iface,
+    IN PSERVICEGROUP  ServiceGroup)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)iface;
+
+    ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
+
+    This->ServiceGroup = ServiceGroup;
+
+    ServiceGroup->lpVtbl->AddRef(ServiceGroup);
+    ServiceGroup->lpVtbl->AddMember(ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
+}
+
+static IPortDMusVtbl vt_IPortDMus =
+{
+    /* IUnknown methods */
+    IPortDMus_fnQueryInterface,
+    IPortDMus_fnAddRef,
+    IPortDMus_fnRelease,
+    /* IPort methods */
+    IPortDMus_fnInit,
+    IPortDMus_fnGetDeviceProperty,
+    IPortDMus_fnNewRegistryKey,
+    IPortDMus_fnNotify,
+    IPortDMus_fnRegisterServiceGroup
+};
+
+//---------------------------------------------------------------
+// ISubdevice interface
+//
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnQueryInterface(
+    IN ISubdevice *iface,
+    IN REFIID InterfaceId,
+    IN PVOID* Interface)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    return IPortDMus_fnQueryInterface((IPortDMus*)This, InterfaceId, Interface);
+}
+
+static
+ULONG
+NTAPI
+ISubDevice_fnAddRef(
+    IN ISubdevice *iface)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    return IPortDMus_fnAddRef((IPortDMus*)This);
+}
+
+static
+ULONG
+NTAPI
+ISubDevice_fnRelease(
+    IN ISubdevice *iface)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    return IPortDMus_fnRelease((IPortDMus*)This);
+}
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnNewIrpTarget(
+    IN ISubdevice *iface,
+    OUT struct IIrpTarget **OutTarget,
+    IN WCHAR * Name,
+    IN PUNKNOWN Unknown,
+    IN POOL_TYPE PoolType,
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp, 
+    IN KSOBJECT_CREATE *CreateObject)
+{
+    NTSTATUS Status;
+    PPORTFILTERDMUS Filter;
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    DPRINT("ISubDevice_NewIrpTarget this %p\n", This);
+
+    if (This->Filter)
+    {
+        *OutTarget = (IIrpTarget*)This->Filter;
+        return STATUS_SUCCESS;
+    }
+
+
+    Status = NewPortFilterDMus(&Filter);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    Status = Filter->lpVtbl->Init(Filter, (PPORTDMUS)This);
+    if (!NT_SUCCESS(Status))
+    {
+        Filter->lpVtbl->Release(Filter);
+        return Status;
+    }
+
+    *OutTarget = (IIrpTarget*)Filter;
+    return Status;
+}
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnReleaseChildren(
+    IN ISubdevice *iface)
+{
+    //IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    UNIMPLEMENTED
+    return STATUS_UNSUCCESSFUL;
+}
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnGetDescriptor(
+    IN ISubdevice *iface,
+    IN SUBDEVICE_DESCRIPTOR ** Descriptor)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    DPRINT("ISubDevice_GetDescriptor this %p\n", This);
+    *Descriptor = This->SubDeviceDescriptor;
+    return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnDataRangeIntersection(
+    IN ISubdevice *iface,
+    IN  ULONG PinId,
+    IN  PKSDATARANGE DataRange,
+    IN  PKSDATARANGE MatchingDataRange,
+    IN  ULONG OutputBufferLength,
+    OUT PVOID ResultantFormat OPTIONAL,
+    OUT PULONG ResultantFormatLength)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    DPRINT("ISubDevice_DataRangeIntersection this %p\n", This);
+
+    if (This->pMiniport)
+    {
+        return This->pMiniport->lpVtbl->DataRangeIntersection (This->pMiniport, PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength);
+    }
+
+    return STATUS_UNSUCCESSFUL;
+}
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnPowerChangeNotify(
+    IN ISubdevice *iface,
+    IN POWER_STATE PowerState)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    if (This->pPowerNotify)
+    {
+        This->pPowerNotify->lpVtbl->PowerChangeNotify(This->pPowerNotify, PowerState);
+    }
+
+    return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnPinCount(
+    IN ISubdevice *iface,
+    IN ULONG  PinId,
+    IN OUT PULONG  FilterNecessary,
+    IN OUT PULONG  FilterCurrent,
+    IN OUT PULONG  FilterPossible,
+    IN OUT PULONG  GlobalCurrent,
+    IN OUT PULONG  GlobalPossible)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
+
+    if (This->pPinCount)
+    {
+       This->pPinCount->lpVtbl->PinCount(This->pPinCount, PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible);
+       return STATUS_SUCCESS;
+    }
+
+    /* FIXME
+     * scan filter descriptor 
+     */
+    return STATUS_UNSUCCESSFUL;
+}
+
+static ISubdeviceVtbl vt_ISubdevice = 
+{
+    ISubDevice_fnQueryInterface,
+    ISubDevice_fnAddRef,
+    ISubDevice_fnRelease,
+    ISubDevice_fnNewIrpTarget,
+    ISubDevice_fnReleaseChildren,
+    ISubDevice_fnGetDescriptor,
+    ISubDevice_fnDataRangeIntersection,
+    ISubDevice_fnPowerChangeNotify,
+    ISubDevice_fnPinCount
+};
+
+
+static
+NTSTATUS
+NTAPI
+IServiceSink_fnQueryInterface(
+    IServiceSink* iface,
+    IN  REFIID refiid,
+    OUT PVOID* Output)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblServiceSink);
+
+    if (IsEqualGUIDAligned(refiid, &IID_IServiceSink) ||
+        IsEqualGUIDAligned(refiid, &IID_IUnknown))
+    {
+        *Output = &This->lpVtblServiceSink;
+        InterlockedIncrement(&This->ref);
+        return STATUS_SUCCESS;
+    }
+
+    DPRINT("Unknown interface requested\n");
+    return STATUS_UNSUCCESSFUL;
+}
+
+static
+ULONG
+NTAPI
+IServiceSink_fnAddRef(
+    IServiceSink* iface)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblServiceSink);
+    return IPortDMus_fnAddRef((IPortDMus*)This);
+}
+
+static
+ULONG
+NTAPI
+IServiceSink_fnRelease(
+    IServiceSink* iface)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblServiceSink);
+    return IPortDMus_fnRelease((IPortDMus*)This);
+}
+
+static
+VOID
+NTAPI
+IServiceSink_fnRequestService(
+    IServiceSink* iface)
+{
+    UNIMPLEMENTED
+}
+
+static IServiceSinkVtbl vt_IServiceSink = 
+{
+    IServiceSink_fnQueryInterface,
+    IServiceSink_fnAddRef,
+    IServiceSink_fnRelease,
+    IServiceSink_fnRequestService
+};
+
 NTSTATUS
 NewPortDMus(
     OUT PPORT* OutPort)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
-}
-
+    IPortDMusImpl * This = AllocateItem(NonPagedPool, sizeof(IPortDMusImpl), TAG_PORTCLASS);
+
+    if (!This)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    This->ref = 1;
+    This->lpVtbl = &vt_IPortDMus;
+    This->lpVtblServiceSink = &vt_IServiceSink;
+    This->lpVtblSubDevice = &vt_ISubdevice;
+
+    *OutPort = (PPORT)&This->lpVtbl;
+
+    return STATUS_SUCCESS;
+}
+
+VOID
+GetDMusMiniport(
+    IN IPortDMus * iface, 
+    IN PMINIPORTDMUS * Miniport,
+    IN PMINIPORTMIDI * MidiMiniport)
+{
+    IPortDMusImpl * This = (IPortDMusImpl*)iface;
+
+    *Miniport = This->pMiniport;
+    *MidiMiniport = This->pMiniportMidi;
+}

Removed: 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=40834&view=auto
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c (removed)
@@ -1,481 +1,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS Kernel Streaming
- * FILE:            drivers/wdm/audio/backpln/portcls/port_midi.c
- * PURPOSE:         Midi Port driver
- * PROGRAMMER:      Johannes Anderwald
- */
-
-#include "private.h"
-
-typedef struct
-{
-    IPortMidiVtbl *lpVtbl;
-    ISubdeviceVtbl *lpVtblSubDevice;
-
-    LONG ref;
-    BOOL bInitialized;
-
-    PMINIPORTMIDI pMiniport;
-    PDEVICE_OBJECT pDeviceObject;
-    PPINCOUNT pPinCount;
-    PPOWERNOTIFY pPowerNotify;
-    PSERVICEGROUP pServiceGroup;
-
-    PPCFILTER_DESCRIPTOR pDescriptor;
-    PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
-}IPortMidiImpl;
-
-static GUID InterfaceGuids[3] = 
-{
-    {
-        /// KS_CATEGORY_AUDIO
-        0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
-    },
-    {
-        /// KS_CATEGORY_RENDER
-        0x65E8773E, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
-    },
-    {
-        /// KS_CATEGORY_CAPTURE
-        0x65E8773D, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
-    }
-};
-
-//---------------------------------------------------------------
-// IUnknown interface functions
-//
-
-NTSTATUS
-NTAPI
-IPortMidi_fnQueryInterface(
-    IPortMidi* iface,
-    IN  REFIID refiid,
-    OUT PVOID* Output)
-{
-    UNICODE_STRING GuidString;
-    IPortMidiImpl * This = (IPortMidiImpl*)iface;
-
-    DPRINT("IPortMidi_fnQueryInterface\n");
-
-    if (IsEqualGUIDAligned(refiid, &IID_IPortMidi) ||
-        IsEqualGUIDAligned(refiid, &IID_IPort) ||
-        IsEqualGUIDAligned(refiid, &IID_IUnknown))
-    {
-        *Output = &This->lpVtbl;
-        InterlockedIncrement(&This->ref);
-        return STATUS_SUCCESS;
-    }
-    else if (IsEqualGUIDAligned(refiid, &IID_ISubdevice))
-    {
-        *Output = &This->lpVtblSubDevice;
-        InterlockedIncrement(&This->ref);
-        return STATUS_SUCCESS;
-    }
-    else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
-    {
-        return NewPortClsVersion((PPORTCLSVERSION*)Output);
-    }
-    else if (IsEqualGUIDAligned(refiid, &IID_IDrmPort) ||
-             IsEqualGUIDAligned(refiid, &IID_IDrmPort2))
-    {
-        return NewIDrmPort((PDRMPORT2*)Output);
-    }
-
-    if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
-    {
-        DPRINT1("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
-        RtlFreeUnicodeString(&GuidString);
-    }
-    return STATUS_UNSUCCESSFUL;
-}
-
-ULONG
-NTAPI
-IPortMidi_fnAddRef(
-    IPortMidi* iface)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)iface;
-
-    return InterlockedIncrement(&This->ref);
-}
-
-ULONG
-NTAPI
-IPortMidi_fnRelease(
-    IPortMidi* iface)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)iface;
-
-    InterlockedDecrement(&This->ref);
-
-    if (This->ref == 0)
-    {
-        FreeItem(This, TAG_PORTCLASS);
-        return 0;
-    }
-    /* Return new reference count */
-    return This->ref;
-}
-
-
-//---------------------------------------------------------------
-// IPort interface functions
-//
-
-NTSTATUS
-NTAPI
-IPortMidi_fnGetDeviceProperty(
-    IN IPortMidi * iface,
-    IN DEVICE_REGISTRY_PROPERTY  DeviceRegistryProperty,
-    IN ULONG  BufferLength,
-    OUT PVOID  PropertyBuffer,
-    OUT PULONG  ReturnLength)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)iface;
-
-    ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
-
-    if (!This->bInitialized)
-    {
-        DPRINT("IPortMidi_fnNewRegistryKey called w/o initiazed\n");
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
-}
-
-NTSTATUS
-NTAPI
-IPortMidi_fnInit(
-    IN IPortMidi * iface,
-    IN PDEVICE_OBJECT  DeviceObject,
-    IN PIRP  Irp,
-    IN PUNKNOWN  UnknownMiniport,
-    IN PUNKNOWN  UnknownAdapter  OPTIONAL,
-    IN PRESOURCELIST  ResourceList)
-{
-    IMiniportMidi * Miniport;
-    IServiceGroup * ServiceGroup = NULL;
-    NTSTATUS Status;
-    IPortMidiImpl * This = (IPortMidiImpl*)iface;
-
-    DPRINT("IPortMidi_fnInit entered This %p DeviceObject %p Irp %p UnknownMiniport %p UnknownAdapter %p ResourceList %p\n",
-            This, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList);
-    ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
-
-    if (This->bInitialized)
-    {
-        DPRINT1("IPortMidi_Init called again\n");
-        return STATUS_SUCCESS;
-    }
-
-    Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportMidi, (PVOID*)&Miniport);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("IPortMidi_Init called with invalid IMiniport adapter\n");
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Initialize port object */
-    This->pMiniport = Miniport;
-    This->pDeviceObject = DeviceObject;
-    This->bInitialized = TRUE;
-
-    /* increment reference on miniport adapter */
-    Miniport->lpVtbl->AddRef(Miniport);
-
-    Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("IPortMidi_Init failed with %x\n", Status);
-        This->bInitialized = FALSE;
-        Miniport->lpVtbl->Release(Miniport);
-        return Status;
-    }
-
-    /* get the miniport device descriptor */
-    Status = Miniport->lpVtbl->GetDescription(Miniport, &This->pDescriptor);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("failed to get description\n");
-        Miniport->lpVtbl->Release(Miniport);
-        This->bInitialized = FALSE;
-        return Status;
-    }
-
-    This->pServiceGroup = ServiceGroup;
-
-    /* create the subdevice descriptor */
-    Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor, 
-                                         3,
-                                         InterfaceGuids, 
-                                         0, 
-                                         NULL,
-                                         0, 
-                                         NULL,
-                                         0,
-                                         0,
-                                         0,
-                                         NULL,
-                                         0,
-                                         NULL,
-                                         This->pDescriptor);
-
-
-    DPRINT("IPortMidi_fnInit success\n");
-    return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-NTAPI
-IPortMidi_fnNewRegistryKey(
-    IN IPortMidi * iface,
-    OUT PREGISTRYKEY  *OutRegistryKey,
-    IN PUNKNOWN  OuterUnknown  OPTIONAL,
-    IN ULONG  RegistryKeyType,
-    IN ACCESS_MASK  DesiredAccess,
-    IN POBJECT_ATTRIBUTES  ObjectAttributes  OPTIONAL,
-    IN ULONG  CreateOptions  OPTIONAL,
-    OUT PULONG  Disposition  OPTIONAL)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)iface;
-
-    ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
-
-    if (!This->bInitialized)
-    {
-        DPRINT("IPortMidi_fnNewRegistryKey called w/o initialized\n");
-        return STATUS_UNSUCCESSFUL;
-    }
-    return PcNewRegistryKey(OutRegistryKey, 
-                            OuterUnknown,
-                            RegistryKeyType,
-                            DesiredAccess,
-                            This->pDeviceObject,
-                            NULL,//FIXME
-                            ObjectAttributes,
-                            CreateOptions,
-                            Disposition);
-}
-
-
-VOID
-NTAPI
-IPortMidi_fnNotify(
-    IN IPortMidi * iface,
-    IN PSERVICEGROUP  ServiceGroup  OPTIONAL)
-{
-    UNIMPLEMENTED
-}
-
-NTSTATUS
-NTAPI
-IPortMidi_fnRegisterServiceGroup(
-    IN IPortMidi * iface,
-    IN PSERVICEGROUP  ServiceGroup)
-{
-    UNIMPLEMENTED
-    ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
-    return STATUS_SUCCESS;
-}
-
-static IPortMidiVtbl vt_IPortMidi =
-{
-    /* IUnknown methods */
-    IPortMidi_fnQueryInterface,
-    IPortMidi_fnAddRef,
-    IPortMidi_fnRelease,
-    /* IPort methods */
-    IPortMidi_fnInit,
-    IPortMidi_fnGetDeviceProperty,
-    IPortMidi_fnNewRegistryKey,
-    IPortMidi_fnNotify,
-    IPortMidi_fnRegisterServiceGroup
-};
-
-//---------------------------------------------------------------
-// ISubdevice interface
-//
-
-static
-NTSTATUS
-NTAPI
-ISubDevice_fnQueryInterface(
-    IN ISubdevice *iface,
-    IN REFIID InterfaceId,
-    IN PVOID* Interface)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    return IPortMidi_fnQueryInterface((IPortMidi*)This, InterfaceId, Interface);
-}
-
-static
-ULONG
-NTAPI
-ISubDevice_fnAddRef(
-    IN ISubdevice *iface)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    return IPortMidi_fnAddRef((IPortMidi*)This);
-}
-
-static
-ULONG
-NTAPI
-ISubDevice_fnRelease(
-    IN ISubdevice *iface)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    return IPortMidi_fnRelease((IPortMidi*)This);
-}
-
-static
-NTSTATUS
-NTAPI
-ISubDevice_fnNewIrpTarget(
-    IN ISubdevice *iface,
-    OUT struct IIrpTarget **OutTarget,
-    IN WCHAR * Name,
-    IN PUNKNOWN Unknown,
-    IN POOL_TYPE PoolType,
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp, 
-    IN KSOBJECT_CREATE *CreateObject)
-{
-    //IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    UNIMPLEMENTED
-    return STATUS_UNSUCCESSFUL;
-}
-
-static
-NTSTATUS
-NTAPI
-ISubDevice_fnReleaseChildren(
-    IN ISubdevice *iface)
-{
-    //IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    UNIMPLEMENTED
-    return STATUS_UNSUCCESSFUL;
-}
-
-static
-NTSTATUS
-NTAPI
-ISubDevice_fnGetDescriptor(
-    IN ISubdevice *iface,
-    IN SUBDEVICE_DESCRIPTOR ** Descriptor)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    DPRINT("ISubDevice_GetDescriptor this %p\n", This);
-    *Descriptor = This->SubDeviceDescriptor;
-    return STATUS_SUCCESS;
-}
-
-static
-NTSTATUS
-NTAPI
-ISubDevice_fnDataRangeIntersection(
-    IN ISubdevice *iface,
-    IN  ULONG PinId,
-    IN  PKSDATARANGE DataRange,
-    IN  PKSDATARANGE MatchingDataRange,
-    IN  ULONG OutputBufferLength,
-    OUT PVOID ResultantFormat OPTIONAL,
-    OUT PULONG ResultantFormatLength)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    DPRINT("ISubDevice_DataRangeIntersection this %p\n", This);
-
-    if (This->pMiniport)
-    {
-        return This->pMiniport->lpVtbl->DataRangeIntersection (This->pMiniport, PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength);
-    }
-
-    return STATUS_UNSUCCESSFUL;
-}
-
-static
-NTSTATUS
-NTAPI
-ISubDevice_fnPowerChangeNotify(
-    IN ISubdevice *iface,
-    IN POWER_STATE PowerState)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    if (This->pPowerNotify)
-    {
-        This->pPowerNotify->lpVtbl->PowerChangeNotify(This->pPowerNotify, PowerState);
-    }
-
-    return STATUS_SUCCESS;
-}
-
-static
-NTSTATUS
-NTAPI
-ISubDevice_fnPinCount(
-    IN ISubdevice *iface,
-    IN ULONG  PinId,
-    IN OUT PULONG  FilterNecessary,
-    IN OUT PULONG  FilterCurrent,
-    IN OUT PULONG  FilterPossible,
-    IN OUT PULONG  GlobalCurrent,
-    IN OUT PULONG  GlobalPossible)
-{
-    IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
-
-    if (This->pPinCount)
-    {
-       This->pPinCount->lpVtbl->PinCount(This->pPinCount, PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible);
-       return STATUS_SUCCESS;
-    }
-
-    /* FIXME
-     * scan filter descriptor 
-     */
-    return STATUS_UNSUCCESSFUL;
-}
-
-static ISubdeviceVtbl vt_ISubdeviceVtbl = 
-{
-    ISubDevice_fnQueryInterface,
-    ISubDevice_fnAddRef,
-    ISubDevice_fnRelease,
-    ISubDevice_fnNewIrpTarget,
-    ISubDevice_fnReleaseChildren,
-    ISubDevice_fnGetDescriptor,
-    ISubDevice_fnDataRangeIntersection,
-    ISubDevice_fnPowerChangeNotify,
-    ISubDevice_fnPinCount
-};
-
-
-NTSTATUS
-NewPortMidi(
-    OUT PPORT* OutPort)
-{
-    IPortMidiImpl * This;
-
-    This = AllocateItem(NonPagedPool, sizeof(IPortMidiImpl), TAG_PORTCLASS);
-    if (!This)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    This->lpVtbl = &vt_IPortMidi;
-    This->lpVtblSubDevice = &vt_ISubdeviceVtbl;
-    This->ref = 1;
-    *OutPort = (PPORT)(&This->lpVtbl);
-
-    DPRINT("NewPortMidi result %p\n", *OutPort);
-
-    return STATUS_SUCCESS;
-}

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild?rev=40835&r1=40834&r2=40835&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] Fri May  8 13:36:02 2009
@@ -19,6 +19,7 @@
 	<file>dma_slave.c</file>
 	<file>drm.c</file>
 	<file>drm_port.c</file>
+	<file>filter_dmus.c</file>
 	<file>filter_wavecyclic.c</file>
 	<file>filter_wavepci.c</file>
 	<file>filter_wavert.c</file>
@@ -29,13 +30,13 @@
 	<file>miniport.c</file>
 	<file>miniport_dmus.c</file>
 	<file>miniport_fmsynth.c</file>
+	<file>pin_dmus.c</file>
 	<file>pin_wavecyclic.c</file>
 	<file>pin_wavepci.c</file>
 	<file>pin_wavert.c</file>
 	<file>pool.c</file>
 	<file>port.c</file>
 	<file>port_dmus.c</file>
-	<file>port_midi.c</file>
 	<file>port_topology.c</file>
 	<file>port_wavecyclic.c</file>
 	<file>port_wavepci.c</file>

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=40835&r1=40834&r2=40835&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] Fri May  8 13:36:02 2009
@@ -63,9 +63,6 @@
     OUT PMINIPORT* OutMiniport,
     IN  REFCLSID ClassId);
 
-NTSTATUS NewPortMidi(
-    OUT PPORT* OutPort);
-
 NTSTATUS NewPortDMus(
     OUT PPORT* OutPort);
 
@@ -108,6 +105,19 @@
 PMINIPORTWAVEPCI
 GetWavePciMiniport(
     PPORTWAVEPCI Port);
+
+NTSTATUS 
+NewPortFilterDMus(
+    OUT PPORTFILTERDMUS * OutFilter);
+
+NTSTATUS NewPortPinDMus(
+    OUT PPORTPINDMUS * OutPin);
+
+VOID
+GetDMusMiniport(
+    IN IPortDMus * iface, 
+    IN PMINIPORTDMUS * Miniport,
+    IN PMINIPORTMIDI * MidiMiniport);
 
 #if (NTDDI_VERSION >= NTDDI_VISTA)
 



More information about the Ros-diffs mailing list