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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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)