Author: janderwald
Date: Tue May 5 20:01:39 2009
New Revision: 40797
URL:
http://svn.reactos.org/svn/reactos?rev=40797&view=rev
Log:
- Implement IPortWaveRT, IPortFilterWaveRT, IPortPinWaveRT interface for audio drivers
>= Vista
Added:
trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.c (with props)
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c (with props)
trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c (with props)
trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c (with props)
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/pin_wavecyclic.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.c (added)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.c [iso-8859-1] Tue May
5 20:01:39 2009
@@ -1,0 +1,462 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/wdm/audio/backpln/portcls/filter_wavert.c
+ * PURPOSE: portcls wave RT filter
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+#include "private.h"
+
+typedef struct
+{
+ IPortFilterWaveRTVtbl *lpVtbl;
+
+ LONG ref;
+
+ IPortWaveRT* Port;
+ IPortPinWaveRT ** Pins;
+ SUBDEVICE_DESCRIPTOR * Descriptor;
+
+}IPortFilterWaveRTImpl;
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterWaveRT_fnQueryInterface(
+ IPortFilterWaveRT* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl*)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
+IPortFilterWaveRT_fnAddRef(
+ IPortFilterWaveRT* iface)
+{
+ IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl*)iface;
+
+ return InterlockedIncrement(&This->ref);
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+IPortFilterWaveRT_fnRelease(
+ IPortFilterWaveRT* iface)
+{
+ IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl*)iface;
+
+ InterlockedDecrement(&This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ return This->ref;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterWaveRT_fnNewIrpTarget(
+ IN IPortFilterWaveRT* 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;
+ IPortPinWaveRT * Pin;
+ PKSPIN_CONNECT ConnectDetails;
+ IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl *)iface;
+
+ ASSERT(This->Port);
+ ASSERT(This->Descriptor);
+ ASSERT(This->Pins);
+
+ DPRINT("IPortFilterWaveRT_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);
+
This->Pins[ConnectDetails->PinId]->lpVtbl->Close(This->Pins[ConnectDetails->PinId],
DeviceObject, NULL);
+ }
+
+ /* now create the pin */
+ Status = NewPortPinWaveRT(&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],
GetDeviceObjectFromPortWaveRT(This->Port));
+ 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
+IPortFilterWaveRT_fnDeviceIoControl(
+ IN IPortFilterWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ ISubdevice *SubDevice = NULL;
+ SUBDEVICE_DESCRIPTOR * Descriptor;
+ NTSTATUS Status;
+ IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl *)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
+IPortFilterWaveRT_fnRead(
+ IN IPortFilterWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterWaveRT_fnWrite(
+ IN IPortFilterWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterWaveRT_fnFlush(
+ IN IPortFilterWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterWaveRT_fnClose(
+ IN IPortFilterWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ ULONG Index;
+ IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl *)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
+IPortFilterWaveRT_fnQuerySecurity(
+ IN IPortFilterWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortFilterWaveRT_fnSetSecurity(
+ IN IPortFilterWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortFilterWaveRT_fnFastDeviceIoControl(
+ IN IPortFilterWaveRT* 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;
+ IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl *)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
+IPortFilterWaveRT_fnFastRead(
+ IN IPortFilterWaveRT* 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
+IPortFilterWaveRT_fnFastWrite(
+ IN IPortFilterWaveRT* 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
+IPortFilterWaveRT_fnInit(
+ IN IPortFilterWaveRT* iface,
+ IN IPortWaveRT* Port)
+{
+ ISubdevice * ISubDevice;
+ SUBDEVICE_DESCRIPTOR * Descriptor;
+ NTSTATUS Status;
+ IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl*)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(IPortPinWaveRT*), TAG_PORTCLASS);
+
+ if (!This->Pins)
+ return STATUS_UNSUCCESSFUL;
+
+ /* increment reference count */
+ Port->lpVtbl->AddRef(Port);
+
+ return STATUS_SUCCESS;
+}
+
+static IPortFilterWaveRTVtbl vt_IPortFilterWaveRT =
+{
+ IPortFilterWaveRT_fnQueryInterface,
+ IPortFilterWaveRT_fnAddRef,
+ IPortFilterWaveRT_fnRelease,
+ IPortFilterWaveRT_fnNewIrpTarget,
+ IPortFilterWaveRT_fnDeviceIoControl,
+ IPortFilterWaveRT_fnRead,
+ IPortFilterWaveRT_fnWrite,
+ IPortFilterWaveRT_fnFlush,
+ IPortFilterWaveRT_fnClose,
+ IPortFilterWaveRT_fnQuerySecurity,
+ IPortFilterWaveRT_fnSetSecurity,
+ IPortFilterWaveRT_fnFastDeviceIoControl,
+ IPortFilterWaveRT_fnFastRead,
+ IPortFilterWaveRT_fnFastWrite,
+ IPortFilterWaveRT_fnInit
+};
+
+NTSTATUS
+NewPortFilterWaveRT(
+ OUT IPortFilterWaveRT ** OutFilter)
+{
+ IPortFilterWaveRTImpl * This;
+
+ This = AllocateItem(NonPagedPool, sizeof(IPortFilterWaveRTImpl), TAG_PORTCLASS);
+ if (!This)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* initialize IPortFilterWaveRT */
+ This->ref = 1;
+ This->lpVtbl = &vt_IPortFilterWaveRT;
+
+ /* return result */
+ *OutFilter = (IPortFilterWaveRT*)&This->lpVtbl;
+
+ return STATUS_SUCCESS;
+}
Propchange: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.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] Tue May 5
20:01:39 2009
@@ -76,3 +76,14 @@
const GUID IID_IIrpTarget = {0xB4C90A60, 0x5791, 0x11D0, {0xF9, 0x86, 0x00, 0xA0, 0xC9,
0x11, 0xB5, 0x44}};
const GUID IID_IIrpTargetFactory = {0xB4C90A62, 0x5791, 0x11D0, {0xF9, 0x86, 0x00, 0xA0,
0xC9, 0x11, 0xB5, 0x44}};
+
+///
+/// >= Vista GUIDs
+///
+const GUID IID_IPortWaveRT = {0x339ff909, 0x68a9, 0x4310, {0xb0,
0x9b, 0x27, 0x4e, 0x96, 0xee, 0x4c, 0xbd}};
+const GUID IID_IPortWaveRTStream = {0x1809ce5a, 0x64bc, 0x4e62, {0xbd,
0x7d, 0x95, 0xbc, 0xe4, 0x3d, 0xe3, 0x93}};
+const GUID IID_IMiniportWaveRT = {0x0f9fc4d6, 0x6061, 0x4f3c, {0xb1,
0xfc, 0x7, 0x5e, 0x35, 0xf7, 0x96, 0xa}};
+const GUID IID_IMiniportWaveRTStream = {0x000ac9ab, 0xfaab, 0x4f3d, {0x94,
0x55, 0x6f, 0xf8, 0x30, 0x6a, 0x74, 0xa0}};
+const GUID IID_IMiniportWaveRTStreamNotification = {0x23759128, 0x96f1, 0x423b, {0xab,
0x4d, 0x81, 0x63, 0x5b, 0xcf, 0x8c, 0xa1}};
+
+
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] Tue May 5
20:01:39 2009
@@ -475,6 +475,50 @@
typedef IPortPinWavePci *PPORTPINWAVEPCI;
/*****************************************************************************
+ * IPortFilterWaveRT
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IPortFilterWaveRT
+
+DECLARE_INTERFACE_(IPortFilterWaveRT, IIrpTarget)
+{
+ DEFINE_ABSTRACT_UNKNOWN()
+
+ DEFINE_ABSTRACT_IRPTARGET()
+
+ STDMETHOD_(NTSTATUS, Init)(THIS_
+ IN PPORTWAVERT Port)PURE;
+};
+
+typedef IPortFilterWaveRT *PPORTFILTERWAVERT;
+
+/*****************************************************************************
+ * IPortPinWavePci
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IPortPinWaveRT
+
+DECLARE_INTERFACE_(IPortPinWaveRT, IIrpTarget)
+{
+ DEFINE_ABSTRACT_UNKNOWN()
+
+ DEFINE_ABSTRACT_IRPTARGET()
+
+ STDMETHOD_(NTSTATUS, Init)(THIS_
+ IN PPORTWAVERT Port,
+ IN PPORTFILTERWAVERT Filter,
+ IN KSPIN_CONNECT * ConnectDetails,
+ IN KSPIN_DESCRIPTOR * PinDescriptor,
+ IN PDEVICE_OBJECT DeviceObject) PURE;
+};
+
+typedef IPortPinWavePci *PPORTPINWAVERT;
+
+/*****************************************************************************
* IPortFilterWaveCyclic
*****************************************************************************
*/
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Tue May
5 20:01:39 2009
@@ -31,9 +31,6 @@
IIrpQueue * IrpQueue;
- PUCHAR ActiveIrpBuffer;
- ULONG ActiveIrpBufferSize;
- ULONG ActiveIrpOffset;
ULONG FrameSize;
BOOL Capture;
Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c (added)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c [iso-8859-1] Tue May 5
20:01:39 2009
@@ -1,0 +1,1044 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/wdm/audio/backpln/portcls/pin_wavert.c
+ * PURPOSE: WaveRT IRP Audio Pin
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+#include "private.h"
+
+typedef struct
+{
+ IPortPinWaveRTVtbl *lpVtbl;
+ IServiceSinkVtbl *lpVtblServiceSink;
+ LONG ref;
+
+ IPortWaveRT * Port;
+ IPortFilterWaveRT * Filter;
+ KSPIN_DESCRIPTOR * KsPinDescriptor;
+ PMINIPORTWAVERT Miniport;
+ PMINIPORTWAVERTSTREAM Stream;
+ PPORTWAVERTSTREAM PortStream;
+ PSERVICEGROUP ServiceGroup;
+ KSSTATE State;
+ PKSDATAFORMAT Format;
+ KSPIN_CONNECT * ConnectDetails;
+
+ PVOID CommonBuffer;
+ ULONG CommonBufferSize;
+ ULONG CommonBufferOffset;
+
+ IIrpQueue * IrpQueue;
+
+ BOOL Capture;
+
+ ULONG TotalPackets;
+ ULONG PreCompleted;
+ ULONG PostCompleted;
+
+ ULONGLONG Delay;
+
+ MEMORY_CACHING_TYPE CacheType;
+ PMDL Mdl;
+
+}IPortPinWaveRTImpl;
+
+
+typedef struct
+{
+ IPortPinWaveRTImpl *Pin;
+ PIO_WORKITEM WorkItem;
+ KSSTATE State;
+}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
+
+static
+VOID
+NTAPI
+SetStreamState(
+ IN IPortPinWaveRTImpl * This,
+ IN KSSTATE State);
+
+//==================================================================================================================================
+static
+NTSTATUS
+NTAPI
+IServiceSink_fnQueryInterface(
+ IServiceSink* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)CONTAINING_RECORD(iface,
IPortPinWaveRTImpl, 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)
+{
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)CONTAINING_RECORD(iface,
IPortPinWaveRTImpl, lpVtblServiceSink);
+ DPRINT("IServiceSink_fnAddRef entered\n");
+
+ return InterlockedIncrement(&This->ref);
+}
+
+static
+ULONG
+NTAPI
+IServiceSink_fnRelease(
+ IServiceSink* iface)
+{
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)CONTAINING_RECORD(iface,
IPortPinWaveRTImpl, 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
+IServiceSink_fnRequestService(
+ IServiceSink* iface)
+{
+ KSAUDIO_POSITION Position;
+ NTSTATUS Status;
+ PUCHAR Buffer;
+ ULONG BufferSize;
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)CONTAINING_RECORD(iface,
IPortPinWaveRTImpl, lpVtblServiceSink);
+
+ ASSERT_IRQL(DISPATCH_LEVEL);
+
+ Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer,
&BufferSize);
+ if (!NT_SUCCESS(Status))
+ {
+ SetStreamState(This, KSSTATE_STOP);
+ return;
+ }
+
+ Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
+ DPRINT("PlayOffset %llu WriteOffset %llu %u Buffer %p BufferSize %u\n",
Position.PlayOffset, Position.WriteOffset, Buffer, This->CommonBufferSize,
BufferSize);
+
+ //FIXME
+ // implement writing into cyclic buffer
+ //
+
+ /* reschedule the timer */
+ This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup,
This->Delay);
+}
+
+static IServiceSinkVtbl vt_IServiceSink =
+{
+ IServiceSink_fnQueryInterface,
+ IServiceSink_fnAddRef,
+ IServiceSink_fnRelease,
+ IServiceSink_fnRequestService
+};
+
+
+static
+VOID
+NTAPI
+SetStreamWorkerRoutine(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context)
+{
+ IPortPinWaveRTImpl * 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->Stream->lpVtbl->SetState(This->Stream, 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
+
This->ServiceGroup->lpVtbl->CancelDelayedService(This->ServiceGroup);
+ DPRINT1("Stopping PreCompleted %u PostCompleted %u\n",
This->PreCompleted, This->PostCompleted);
+ }
+
+ if (This->State == KSSTATE_RUN)
+ {
+ /* start the notification timer */
+
This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup,
This->Delay);
+ }
+ }
+}
+
+static
+VOID
+NTAPI
+SetStreamState(
+ IN IPortPinWaveRTImpl * This,
+ IN KSSTATE State)
+{
+ PDEVICE_OBJECT DeviceObject;
+ 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;
+
+ /* Get device object */
+ DeviceObject = GetDeviceObjectFromPortWaveRT(This->Port);
+
+ /* allocate set state context */
+ Context = AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS);
+
+ if (!Context)
+ return;
+
+ /* allocate work item */
+ WorkItem = IoAllocateWorkItem(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);
+}
+
+//==================================================================================================================================
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWaveRT_fnQueryInterface(
+ IPortPinWaveRT* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)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
+IPortPinWaveRT_fnAddRef(
+ IPortPinWaveRT* iface)
+{
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)iface;
+
+ return InterlockedIncrement(&This->ref);
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+IPortPinWaveRT_fnRelease(
+ IPortPinWaveRT* iface)
+{
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)iface;
+
+ InterlockedDecrement(&This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ return This->ref;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWaveRT_fnNewIrpTarget(
+ IN IPortPinWaveRT* 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
+ return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+NTAPI
+IPortPinWaveRT_HandleKsProperty(
+ IN IPortPinWaveRT * iface,
+ IN PIRP Irp)
+{
+ PKSPROPERTY Property;
+ NTSTATUS Status;
+ UNICODE_STRING GuidString;
+ PIO_STACK_LOCATION IoStack;
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)iface;
+
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ DPRINT("IPortPinWave_HandleKsProperty entered\n");
+
+ if (IoStack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(KSPROPERTY))
+ {
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+ if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Connection))
+ {
+ if (Property->Id == KSPROPERTY_CONNECTION_STATE)
+ {
+ PKSSTATE State = (PKSSTATE)Irp->UserBuffer;
+
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(KSSTATE))
+ {
+ Irp->IoStatus.Information = sizeof(KSSTATE);
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if (Property->Flags & KSPROPERTY_TYPE_SET)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+
+ if (This->Stream)
+ {
+ Status = This->Stream->lpVtbl->SetState(This->Stream,
*State);
+
+ DPRINT1("Setting state %u %x\n", *State, Status);
+ if (NT_SUCCESS(Status))
+ {
+ This->State = *State;
+ }
+ }
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+ }
+ else if (Property->Flags & KSPROPERTY_TYPE_GET)
+ {
+ *State = This->State;
+ Irp->IoStatus.Information = sizeof(KSSTATE);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+ }
+ else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT)
+ {
+ PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
+ if (Property->Flags & KSPROPERTY_TYPE_SET)
+ {
+ PKSDATAFORMAT NewDataFormat;
+ if (!RtlCompareMemory(DataFormat, This->Format,
DataFormat->FormatSize))
+ {
+ Irp->IoStatus.Information = DataFormat->FormatSize;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
+ NewDataFormat = AllocateItem(NonPagedPool, DataFormat->FormatSize,
TAG_PORTCLASS);
+ if (!NewDataFormat)
+ {
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_NO_MEMORY;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NO_MEMORY;
+ }
+ RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);
+
+ if (This->Stream)
+ {
+ ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+ ASSERT(NewDataFormat->FormatSize ==
sizeof(KSDATAFORMAT_WAVEFORMATEX));
+
ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat,
&KSDATAFORMAT_TYPE_AUDIO));
+
ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat,
&KSDATAFORMAT_SUBTYPE_PCM));
+
ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier,
&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX));
+
+ ASSERT(This->State == KSSTATE_STOP);
+ DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n",
((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels,
+
((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample,
+
((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec);
+
+ Status = This->Stream->lpVtbl->SetFormat(This->Stream,
NewDataFormat);
+ if (NT_SUCCESS(Status))
+ {
+ if (This->Format)
+ ExFreePoolWithTag(This->Format, TAG_PORTCLASS);
+
+ This->IrpQueue->lpVtbl->UpdateFormat(This->IrpQueue,
(PKSDATAFORMAT)NewDataFormat);
+ This->Format = NewDataFormat;
+ Irp->IoStatus.Information = DataFormat->FormatSize;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+ }
+ DPRINT1("Failed to set format\n");
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+ }
+ else if (Property->Flags & KSPROPERTY_TYPE_GET)
+ {
+ if (!This->Format)
+ {
+ DPRINT1("No format\n");
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+ }
+ if (This->Format->FormatSize >
IoStack->Parameters.DeviceIoControl.OutputBufferLength)
+ {
+ Irp->IoStatus.Information = This->Format->FormatSize;
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ RtlMoveMemory(DataFormat, This->Format,
This->Format->FormatSize);
+ Irp->IoStatus.Information = DataFormat->FormatSize;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+ }
+
+ }
+ RtlStringFromGUID(&Property->Set, &GuidString);
+ DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer,
Property->Id, Property->Flags);
+ DbgBreakPoint();
+ RtlFreeUnicodeString(&GuidString);
+
+ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+IPortPinWaveRT_HandleKsStream(
+ IN IPortPinWaveRT * iface,
+ IN PIRP Irp)
+{
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)iface;
+
+ DPRINT("IPortPinWaveRT_HandleKsStream entered State %u Stream %p\n",
This->State, This->Stream);
+
+ return STATUS_PENDING;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWaveRT_fnDeviceIoControl(
+ IN IPortPinWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
+ {
+ return IPortPinWaveRT_HandleKsProperty(iface, Irp);
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_KS_ENABLE_EVENT)
+ {
+ /// FIXME
+ /// handle enable event
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_KS_DISABLE_EVENT)
+ {
+ /// FIXME
+ /// handle disable event
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_KS_RESET_STATE)
+ {
+ /// FIXME
+ /// handle reset state
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_KS_READ_STREAM)
+ {
+ return IPortPinWaveRT_HandleKsStream(iface, Irp);
+ }
+ else
+ {
+ return KsDefaultDeviceIoCompletion(DeviceObject, Irp);
+ }
+
+ UNIMPLEMENTED
+ DbgBreakPoint();
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWaveRT_fnRead(
+ IN IPortPinWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWaveRT_fnWrite(
+ IN IPortPinWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWaveRT_fnFlush(
+ IN IPortPinWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+static
+VOID
+NTAPI
+CloseStreamRoutine(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context)
+{
+ PMINIPORTWAVERTSTREAM Stream;
+ NTSTATUS Status;
+ ISubdevice *ISubDevice;
+ PSUBDEVICE_DESCRIPTOR Descriptor;
+ IPortPinWaveRTImpl * This;
+ PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
+
+ This = (IPortPinWaveRTImpl*)Ctx->Pin;
+
+ if (This->Stream)
+ {
+ if (This->State != KSSTATE_STOP)
+ {
+ This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
+ KeStallExecutionProcessor(10);
+ }
+ }
+
+ 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;
+ }
+
+ if (This->IrpQueue)
+ {
+ This->IrpQueue->lpVtbl->Release(This->IrpQueue);
+ }
+
+ /* 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);
+
+ if (This->Stream)
+ {
+ Stream = This->Stream;
+ This->Stream = NULL;
+ DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql());
+ Stream->lpVtbl->Release(Stream);
+ /* this line is never reached */
+ }
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWaveRT_fnClose(
+ IN IPortPinWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PCLOSESTREAM_CONTEXT Ctx;
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)iface;
+
+ if (This->Stream)
+ {
+ 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
+IPortPinWaveRT_fnQuerySecurity(
+ IN IPortPinWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWaveRT_fnSetSecurity(
+ IN IPortPinWaveRT* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortPinWaveRT_fnFastDeviceIoControl(
+ IN IPortPinWaveRT* 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
+IPortPinWaveRT_fnFastRead(
+ IN IPortPinWaveRT* 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;
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)iface;
+
+ DPRINT("IPortPinWaveRT_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));
+
+ This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
+ This->State = KSSTATE_RUN;
+ }
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortPinWaveRT_fnFastWrite(
+ IN IPortPinWaveRT* 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;
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)iface;
+
+ InterlockedIncrement((PLONG)&This->TotalPackets);
+
+ DPRINT("IPortPinWaveRT_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
+IPortPinWaveRT_fnInit(
+ IN IPortPinWaveRT* iface,
+ IN PPORTWAVERT Port,
+ IN PPORTFILTERWAVERT Filter,
+ IN KSPIN_CONNECT * ConnectDetails,
+ IN KSPIN_DESCRIPTOR * KsPinDescriptor,
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ NTSTATUS Status;
+ PKSDATAFORMAT DataFormat;
+ BOOL Capture;
+ KSRTAUDIO_HWLATENCY Latency;
+ IPortPinWaveRTImpl * This = (IPortPinWaveRTImpl*)iface;
+
+ Port->lpVtbl->AddRef(Port);
+ Filter->lpVtbl->AddRef(Filter);
+
+ This->Port = Port;
+ This->Filter = Filter;
+ This->KsPinDescriptor = KsPinDescriptor;
+ This->ConnectDetails = ConnectDetails;
+ This->Miniport = GetWaveRTMiniport(Port);
+
+ DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
+
+ DPRINT("IPortPinWaveRT_fnInit entered\n");
+
+ This->Format = AllocateItem(NonPagedPool, DataFormat->FormatSize,
TAG_PORTCLASS);
+ if (!This->Format)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlMoveMemory(This->Format, DataFormat, DataFormat->FormatSize);
+
+ Status = NewIrpQueue(&This->IrpQueue);
+ if (!NT_SUCCESS(Status))
+ {
+ goto cleanup;
+ }
+
+ Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails,
DataFormat, DeviceObject, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ goto cleanup;
+ }
+
+ Status = NewPortWaveRTStream(&This->PortStream);
+ if (!NT_SUCCESS(Status))
+ {
+ goto cleanup;
+ }
+
+ Status = PcNewServiceGroup(&This->ServiceGroup, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ goto cleanup;
+ }
+
+ This->ServiceGroup->lpVtbl->AddMember(This->ServiceGroup,
(PSERVICESINK)&This->lpVtblServiceSink);
+ This->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
+
+ 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 = This->Miniport->lpVtbl->NewStream(This->Miniport,
+ &This->Stream,
+ This->PortStream,
+ ConnectDetails->PinId,
+ Capture,
+ This->Format);
+ DPRINT("IPortPinWaveRT_fnInit Status %x\n", Status);
+
+ if (!NT_SUCCESS(Status))
+ goto cleanup;
+
+ This->Stream->lpVtbl->GetHWLatency(This->Stream, &Latency);
+ /* minimum delay of 10 milisec */
+ This->Delay = Int32x32To64(min(max(Latency.ChipsetDelay + Latency.CodecDelay +
Latency.FifoSize, 10), 10), -10000);
+
+ Status = This->Stream->lpVtbl->AllocateAudioBuffer(This->Stream, 16384,
&This->Mdl, &This->CommonBufferSize, &This->CommonBufferOffset,
&This->CacheType);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("AllocateAudioBuffer failed with %x\n", Status);
+ goto cleanup;
+ }
+
+ This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
+ This->State = KSSTATE_STOP;
+ This->Capture = Capture;
+
+ This->Stream->lpVtbl->SetFormat(This->Stream,
(PKSDATAFORMAT)This->Format);
+ return STATUS_SUCCESS;
+
+cleanup:
+ if (This->IrpQueue)
+ {
+ This->IrpQueue->lpVtbl->Release(This->IrpQueue);
+ This->IrpQueue = NULL;
+ }
+
+ if (This->Format)
+ {
+ FreeItem(This->Format, TAG_PORTCLASS);
+ This->Format = NULL;
+ }
+
+ if (This->ServiceGroup)
+ {
+ This->ServiceGroup->lpVtbl->Release(This->ServiceGroup);
+ This->ServiceGroup = NULL;
+ }
+
+ if (This->PortStream)
+ {
+ This->PortStream->lpVtbl->Release(This->PortStream);
+ This->PortStream = NULL;
+ }
+
+ return Status;
+}
+
+static IPortPinWaveRTVtbl vt_IPortPinWaveRT =
+{
+ IPortPinWaveRT_fnQueryInterface,
+ IPortPinWaveRT_fnAddRef,
+ IPortPinWaveRT_fnRelease,
+ IPortPinWaveRT_fnNewIrpTarget,
+ IPortPinWaveRT_fnDeviceIoControl,
+ IPortPinWaveRT_fnRead,
+ IPortPinWaveRT_fnWrite,
+ IPortPinWaveRT_fnFlush,
+ IPortPinWaveRT_fnClose,
+ IPortPinWaveRT_fnQuerySecurity,
+ IPortPinWaveRT_fnSetSecurity,
+ IPortPinWaveRT_fnFastDeviceIoControl,
+ IPortPinWaveRT_fnFastRead,
+ IPortPinWaveRT_fnFastWrite,
+ IPortPinWaveRT_fnInit
+};
+
+NTSTATUS NewPortPinWaveRT(
+ OUT IPortPinWaveRT ** OutPin)
+{
+ IPortPinWaveRTImpl * This;
+
+ This = AllocateItem(NonPagedPool, sizeof(IPortPinWaveRTImpl), TAG_PORTCLASS);
+ if (!This)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* initialize IPortPinWaveRT */
+ This->ref = 1;
+ This->lpVtbl = &vt_IPortPinWaveRT;
+ This->lpVtblServiceSink = &vt_IServiceSink;
+
+ /* store result */
+ *OutPin = (IPortPinWaveRT*)&This->lpVtbl;
+
+ return STATUS_SUCCESS;
+}
Propchange: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c (added)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c [iso-8859-1] Tue May 5
20:01:39 2009
@@ -1,0 +1,676 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/wdm/audio/backpln/portcls/port_wavert.c
+ * PURPOSE: WaveRT Port Driver
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+#include "private.h"
+
+typedef struct
+{
+ IPortWaveRTVtbl *lpVtbl;
+ IPortEventsVtbl *lpVbtlPortEvents;
+ IUnregisterSubdeviceVtbl *lpVtblUnregisterSubdevice;
+ IUnregisterPhysicalConnectionVtbl *lpVtblPhysicalConnection;
+ IPortEventsVtbl *lpVtblPortEvents;
+ ISubdeviceVtbl *lpVtblSubDevice;
+
+ LONG ref;
+
+ BOOL bInitialized;
+ PDEVICE_OBJECT pDeviceObject;
+ PMINIPORTWAVERT pMiniport;
+ PRESOURCELIST pResourceList;
+ PPINCOUNT pPinCount;
+ PPOWERNOTIFY pPowerNotify;
+ PPCFILTER_DESCRIPTOR pDescriptor;
+ PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
+ IPortFilterWaveRT * Filter;
+}IPortWaveRTImpl;
+
+static GUID InterfaceGuids[3] =
+{
+ {
+ /// KSCATEGORY_RENDER
+ 0x65E8773EL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
+ },
+ {
+ /// KSCATEGORY_CAPTURE
+ 0x65E8773DL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
+ },
+ {
+ /// KS_CATEGORY_AUDIO
+ 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
+ }
+};
+
+DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWaveRTTopologySet, TopologyPropertyHandler);
+DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWaveRTPinSet, PinPropertyHandler,
PinPropertyHandler, PinPropertyHandler);
+
+KSPROPERTY_SET WaveRTPropertySet[] =
+{
+ {
+ &KSPROPSETID_Topology,
+ sizeof(PortFilterWaveRTTopologySet) / sizeof(KSPROPERTY_ITEM),
+ (const KSPROPERTY_ITEM*)&PortFilterWaveRTTopologySet,
+ 0,
+ NULL
+ },
+ {
+ &KSPROPSETID_Pin,
+ sizeof(PortFilterWaveRTPinSet) / sizeof(KSPROPERTY_ITEM),
+ (const KSPROPERTY_ITEM*)&PortFilterWaveRTPinSet,
+ 0,
+ NULL
+ }
+};
+
+//KSEVENTSETID_LoopedStreaming, Type = KSEVENT_LOOPEDSTREAMING_POSITION
+//KSEVENTSETID_Connection, Type = KSEVENT_CONNECTION_ENDOFSTREAM,
+
+
+
+#if 0
+static const KSIDENTIFIER Identifiers[] =
+{
+ {
+ &KSINTERFACESETID_Standard,
+ 0,
+ 0
+ },
+ {
+ &KSINTERFACESETID_Standard,
+ 1,
+ 0
+ }
+};
+#endif
+
+//---------------------------------------------------------------
+// IPortEvents
+//
+
+static
+NTSTATUS
+NTAPI
+IPortEvents_fnQueryInterface(
+ IPortEvents* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
lpVtblPortEvents);
+
+ DPRINT("IPortEvents_fnQueryInterface entered\n");
+
+ if (IsEqualGUIDAligned(refiid, &IID_IPortEvents) ||
+ IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->lpVbtlPortEvents;
+ InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+static
+ULONG
+NTAPI
+IPortEvents_fnAddRef(
+ IPortEvents* iface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
lpVtblPortEvents);
+ DPRINT("IPortEvents_fnQueryInterface entered\n");
+ return InterlockedIncrement(&This->ref);
+}
+
+static
+ULONG
+NTAPI
+IPortEvents_fnRelease(
+ IPortEvents* iface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
lpVtblPortEvents);
+
+ DPRINT("IPortEvents_fnRelease entered\n");
+ InterlockedDecrement(&This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ /* Return new reference count */
+ return This->ref;
+}
+
+static
+void
+NTAPI
+IPortEvents_fnAddEventToEventList(
+ IPortEvents* iface,
+ IN PKSEVENT_ENTRY EventEntry)
+{
+ UNIMPLEMENTED
+}
+
+
+static
+void
+NTAPI
+IPortEvents_fnGenerateEventList(
+ IPortEvents* iface,
+ IN GUID* Set OPTIONAL,
+ IN ULONG EventId,
+ IN BOOL PinEvent,
+ IN ULONG PinId,
+ IN BOOL NodeEvent,
+ IN ULONG NodeId)
+{
+ UNIMPLEMENTED
+}
+
+static IPortEventsVtbl vt_IPortEvents =
+{
+ IPortEvents_fnQueryInterface,
+ IPortEvents_fnAddRef,
+ IPortEvents_fnRelease,
+ IPortEvents_fnAddEventToEventList,
+ IPortEvents_fnGenerateEventList
+};
+
+//---------------------------------------------------------------
+// IUnknown interface functions
+//
+
+NTSTATUS
+NTAPI
+IPortWaveRT_fnQueryInterface(
+ IPortWaveRT* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ UNICODE_STRING GuidString;
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)iface;
+
+ if (IsEqualGUIDAligned(refiid, &IID_IPortWaveRT) ||
+ IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->lpVtbl;
+ InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ else if (IsEqualGUIDAligned(refiid, &IID_IPortEvents))
+ {
+ *Output = &This->lpVtblPortEvents;
+ 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("IPortWaveRT_fnQueryInterface no interface!!! iface %S\n",
GuidString.Buffer);
+ RtlFreeUnicodeString(&GuidString);
+ }
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+ULONG
+NTAPI
+IPortWaveRT_fnAddRef(
+ IPortWaveRT* iface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)iface;
+
+ return InterlockedIncrement(&This->ref);
+}
+
+ULONG
+NTAPI
+IPortWaveRT_fnRelease(
+ IPortWaveRT* iface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)iface;
+
+ InterlockedDecrement(&This->ref);
+
+ if (This->ref == 0)
+ {
+ if (This->bInitialized)
+ {
+ This->pMiniport->lpVtbl->Release(This->pMiniport);
+ }
+ if (This->pPinCount)
+ This->pPinCount->lpVtbl->Release(This->pPinCount);
+
+ if (This->pPowerNotify)
+ This->pPowerNotify->lpVtbl->Release(This->pPowerNotify);
+
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ /* Return new reference count */
+ return This->ref;
+}
+
+
+//---------------------------------------------------------------
+// IPort interface functions
+//
+
+NTSTATUS
+NTAPI
+IPortWaveRT_fnGetDeviceProperty(
+ IN IPortWaveRT * iface,
+ IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty,
+ IN ULONG BufferLength,
+ OUT PVOID PropertyBuffer,
+ OUT PULONG ReturnLength)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)iface;
+ ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
+
+ if (!This->bInitialized)
+ {
+ DPRINT("IPortWaveRT_fnNewRegistryKey called w/o initiazed\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty,
BufferLength, PropertyBuffer, ReturnLength);
+}
+
+NTSTATUS
+NTAPI
+IPortWaveRT_fnInit(
+ IN IPortWaveRT * iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PUNKNOWN UnknownMiniport,
+ IN PUNKNOWN UnknownAdapter OPTIONAL,
+ IN PRESOURCELIST ResourceList)
+{
+ IMiniportWaveRT * Miniport;
+ NTSTATUS Status;
+ PPINCOUNT PinCount;
+ PPOWERNOTIFY PowerNotify;
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)iface;
+
+ DPRINT("IPortWaveRT_Init entered %p\n", This);
+ ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
+
+ if (This->bInitialized)
+ {
+ DPRINT("IPortWaveRT_Init called again\n");
+ return STATUS_SUCCESS;
+ }
+
+ Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport,
&IID_IMiniportWaveRT, (PVOID*)&Miniport);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IPortWaveRT_Init called with invalid IMiniport adapter\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Initialize port object */
+ This->pMiniport = Miniport;
+ This->pDeviceObject = DeviceObject;
+ This->bInitialized = TRUE;
+ This->pResourceList = ResourceList;
+
+ /* increment reference on miniport adapter */
+ Miniport->lpVtbl->AddRef(Miniport);
+
+ Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList,
iface);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IMiniportWaveRT_Init failed with %x\n", Status);
+ Miniport->lpVtbl->Release(Miniport);
+ This->bInitialized = FALSE;
+ 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;
+ }
+
+ /* create the subdevice descriptor */
+ Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor,
+ 3,
+ InterfaceGuids,
+ 0,
+ NULL,
+ 2,
+ WaveRTPropertySet,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ This->pDescriptor);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status);
+ Miniport->lpVtbl->Release(Miniport);
+ This->bInitialized = FALSE;
+ return Status;
+ }
+
+ /* 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;
+ }
+
+ /* increment reference on resource list */
+ ResourceList->lpVtbl->AddRef(ResourceList);
+
+
+ DPRINT("IPortWaveRT successfully initialized\n");
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+IPortWaveRT_fnNewRegistryKey(
+ IN IPortWaveRT * 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)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)iface;
+
+ ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
+
+ if (!This->bInitialized)
+ {
+ DPRINT("IPortWaveRT_fnNewRegistryKey called w/o initialized\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+ return PcNewRegistryKey(OutRegistryKey, OuterUnknown, RegistryKeyType, DesiredAccess,
This->pDeviceObject, NULL /*FIXME*/, ObjectAttributes, CreateOptions, Disposition);
+}
+
+static IPortWaveRTVtbl vt_IPortWaveRTVtbl =
+{
+ IPortWaveRT_fnQueryInterface,
+ IPortWaveRT_fnAddRef,
+ IPortWaveRT_fnRelease,
+ IPortWaveRT_fnInit,
+ IPortWaveRT_fnGetDeviceProperty,
+ IPortWaveRT_fnNewRegistryKey
+};
+
+//---------------------------------------------------------------
+// ISubdevice interface
+//
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnQueryInterface(
+ IN ISubdevice *iface,
+ IN REFIID InterfaceId,
+ IN PVOID* Interface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
lpVtblSubDevice);
+
+ return IPortWaveRT_fnQueryInterface((IPortWaveRT*)This, InterfaceId, Interface);
+}
+
+static
+ULONG
+NTAPI
+ISubDevice_fnAddRef(
+ IN ISubdevice *iface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
lpVtblSubDevice);
+
+ return IPortWaveRT_fnAddRef((IPortWaveRT*)This);
+}
+
+static
+ULONG
+NTAPI
+ISubDevice_fnRelease(
+ IN ISubdevice *iface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
lpVtblSubDevice);
+
+ return IPortWaveRT_fnRelease((IPortWaveRT*)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;
+ IPortFilterWaveRT * Filter;
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
lpVtblSubDevice);
+
+ DPRINT("ISubDevice_NewIrpTarget this %p\n", This);
+
+ if (This->Filter)
+ {
+ *OutTarget = (IIrpTarget*)This->Filter;
+ return STATUS_SUCCESS;
+ }
+
+
+ Status = NewPortFilterWaveRT(&Filter);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ Status = Filter->lpVtbl->Init(Filter, (IPortWaveRT*)This);
+ if (!NT_SUCCESS(Status))
+ {
+ Filter->lpVtbl->Release(Filter);
+ return Status;
+ }
+
+ *OutTarget = (IIrpTarget*)Filter;
+ return Status;
+}
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnReleaseChildren(
+ IN ISubdevice *iface)
+{
+ //IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface,
IPortWaveRTImpl, lpVtblSubDevice);
+
+ UNIMPLEMENTED
+ return STATUS_UNSUCCESSFUL;
+}
+
+static
+NTSTATUS
+NTAPI
+ISubDevice_fnGetDescriptor(
+ IN ISubdevice *iface,
+ IN SUBDEVICE_DESCRIPTOR ** Descriptor)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
lpVtblSubDevice);
+
+ ASSERT(This->SubDeviceDescriptor != NULL);
+
+ *Descriptor = This->SubDeviceDescriptor;
+
+ DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", This,
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)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
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)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
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)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl,
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
+};
+
+
+///--------------------------------------------------------------
+PMINIPORTWAVERT
+GetWaveRTMiniport(
+ IN IPortWaveRT* iface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl *)iface;
+ return This->pMiniport;
+}
+
+PDEVICE_OBJECT
+GetDeviceObjectFromPortWaveRT(
+ PPORTWAVERT iface)
+{
+ IPortWaveRTImpl * This = (IPortWaveRTImpl *)iface;
+ return This->pDeviceObject;
+}
+
+//---------------------------------------------------------------
+// IPortWaveRT constructor
+//
+
+NTSTATUS
+NewPortWaveRT(
+ OUT PPORT* OutPort)
+{
+ IPortWaveRTImpl * This;
+
+ This = AllocateItem(NonPagedPool, sizeof(IPortWaveRTImpl), TAG_PORTCLASS);
+ if (!This)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ This->lpVtbl = &vt_IPortWaveRTVtbl;
+ This->lpVtblSubDevice = &vt_ISubdeviceVtbl;
+ This->lpVtblPortEvents = &vt_IPortEvents;
+ This->ref = 1;
+ *OutPort = (PPORT)(&This->lpVtbl);
+
+ DPRINT("NewPortWaveRT %p\n", *OutPort);
+
+ return STATUS_SUCCESS;
+}
+
Propchange: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c (added)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c [iso-8859-1] Tue
May 5 20:01:39 2009
@@ -1,0 +1,247 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/wdm/audio/backpln/portcls/port_wavertstream.c
+ * PURPOSE: WaveRTStream helper object
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+#include "private.h"
+
+typedef struct
+{
+ IPortWaveRTStreamVtbl *lpVtbl;
+ LONG ref;
+
+}IPortWaveRTStreamImpl;
+
+/*
+ * @implemented
+ */
+static
+NTSTATUS
+NTAPI
+IPortWaveRTStream_fnQueryInterface(
+ IPortWaveRTStream* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
+
+ DPRINT("IPortWaveRTStream_fnQueryInterface entered\n");
+
+ if (IsEqualGUIDAligned(refiid, &IID_IPortWaveRTStream) ||
+ IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->lpVtbl;
+ InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @implemented
+ */
+static
+ULONG
+NTAPI
+IPortWaveRTStream_fnAddRef(
+ IPortWaveRTStream* iface)
+{
+ IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
+ DPRINT("IPortWaveRTStream_fnAddRef entered\n");
+
+ return InterlockedIncrement(&This->ref);
+}
+
+/*
+ * @implemented
+ */
+static
+ULONG
+NTAPI
+IPortWaveRTStream_fnRelease(
+ IPortWaveRTStream* iface)
+{
+ IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
+
+ InterlockedDecrement(&This->ref);
+
+ DPRINT("IPortWaveRTStream_fnRelease entered %u\n", This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ /* Return new reference count */
+ return This->ref;
+}
+
+/*
+ * @implemented
+ */
+static
+PMDL
+NTAPI
+IPortWaveRTStream_fnAllocatePagesForMdl(
+ IN IPortWaveRTStream* iface,
+ IN PHYSICAL_ADDRESS HighAddress,
+ IN SIZE_T TotalBytes)
+{
+ return MmAllocatePagesForMdl(RtlConvertUlongToLargeInteger(0), HighAddress,
RtlConvertUlongToLargeInteger(0), TotalBytes);
+}
+
+/*
+ * @implemented
+ */
+static
+PMDL
+NTAPI
+IPortWaveRTStream_fnAllocateContiguousPagesForMdl(
+ IN IPortWaveRTStream* iface,
+ IN PHYSICAL_ADDRESS LowAddress,
+ IN PHYSICAL_ADDRESS HighAddress,
+ IN SIZE_T TotalBytes)
+{
+ PMDL Mdl;
+ PVOID Buffer;
+ PHYSICAL_ADDRESS Address;
+
+ Buffer = MmAllocateContiguousMemorySpecifyCache(TotalBytes, LowAddress, HighAddress,
RtlConvertUlongToLargeInteger(0), MmNonCached);
+ if (!Buffer)
+ {
+ DPRINT1("MmAllocateContiguousMemorySpecifyCache failed\n");
+ return NULL;
+ }
+
+ Address = MmGetPhysicalAddress(Buffer);
+
+ MmFreeContiguousMemorySpecifyCache(Buffer, TotalBytes, MmNonCached);
+
+ Mdl = MmAllocatePagesForMdl(Address, HighAddress, RtlConvertUlongToLargeInteger(0),
TotalBytes);
+ if (!Mdl)
+ {
+ DPRINT1("MmAllocatePagesForMdl failed\n");
+ return NULL;
+ }
+
+ if (MmGetMdlByteCount(Mdl) < TotalBytes)
+ {
+ MmFreePagesFromMdl(Mdl);
+ ExFreePool(Mdl);
+ return NULL;
+ }
+
+ return NULL;
+}
+
+/*
+ * @implemented
+ */
+static
+PVOID
+NTAPI
+IPortWaveRTStream_fnMapAllocatedPages(
+ IN IPortWaveRTStream* iface,
+ IN PMDL MemoryDescriptorList,
+ IN MEMORY_CACHING_TYPE CacheType)
+{
+ return MmMapLockedPagesSpecifyCache(MemoryDescriptorList, KernelMode, CacheType,
NULL, 0, NormalPagePriority);
+}
+
+/*
+ * @implemented
+ */
+static
+VOID
+NTAPI
+IPortWaveRTStream_fnUnmapAllocatedPages(
+ IN IPortWaveRTStream* iface,
+ IN PVOID BaseAddress,
+ IN PMDL MemoryDescriptorList)
+{
+ MmUnmapLockedPages(BaseAddress, MemoryDescriptorList);
+}
+
+/*
+ * @implemented
+ */
+static
+VOID
+NTAPI
+IPortWaveRTStream_fnFreePagesFromMdl(
+ IN IPortWaveRTStream* iface,
+ IN PMDL MemoryDescriptorList)
+{
+ MmFreePagesFromMdl(MemoryDescriptorList);
+ ExFreePool(MemoryDescriptorList);
+}
+
+/*
+ * @implemented
+ */
+static
+ULONG
+NTAPI
+IPortWaveRTStream_fnGetPhysicalPagesCount(
+ IN IPortWaveRTStream* iface,
+ IN PMDL MemoryDescriptorList)
+{
+ return ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
+}
+
+/*
+ * @implemented
+ */
+static
+PHYSICAL_ADDRESS
+NTAPI
+IPortWaveRTStream_fnGetPhysicalPageAddress(
+ IN IPortWaveRTStream* iface,
+ IN PMDL MemoryDescriptorList,
+ IN ULONG Index)
+{
+ PVOID Buffer;
+ ULONG Pages;
+
+ Pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
+ if (Pages <= Index)
+ {
+ DPRINT1("OutOfBounds: Pages %u Index %u\n", Pages, Index);
+ return RtlConvertUlongToLargeInteger(0);
+ }
+
+ Buffer = UlongToPtr(PtrToUlong(MmGetSystemAddressForMdl(MemoryDescriptorList)) +
Index * PAGE_SIZE);
+ return MmGetPhysicalAddress(Buffer);
+}
+
+static IPortWaveRTStreamVtbl vt_PortWaveRTStream =
+{
+ IPortWaveRTStream_fnQueryInterface,
+ IPortWaveRTStream_fnAddRef,
+ IPortWaveRTStream_fnRelease,
+ IPortWaveRTStream_fnAllocatePagesForMdl,
+ IPortWaveRTStream_fnAllocateContiguousPagesForMdl,
+ IPortWaveRTStream_fnMapAllocatedPages,
+ IPortWaveRTStream_fnUnmapAllocatedPages,
+ IPortWaveRTStream_fnFreePagesFromMdl,
+ IPortWaveRTStream_fnGetPhysicalPagesCount,
+ IPortWaveRTStream_fnGetPhysicalPageAddress
+};
+
+NTSTATUS
+NewPortWaveRTStream(
+ PPORTWAVERTSTREAM *OutStream)
+{
+ IPortWaveRTStreamImpl* This = AllocateItem(NonPagedPool,
sizeof(IPortWaveRTStreamImpl), TAG_PORTCLASS);
+ if (!This)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ This->ref = 1;
+ This->lpVtbl = &vt_PortWaveRTStream;
+
+ *OutStream = (PPORTWAVERTSTREAM)&This->lpVtbl;
+ return STATUS_SUCCESS;
+}
Propchange: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c
------------------------------------------------------------------------------
svn:eol-style = native
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] Tue May 5
20:01:39 2009
@@ -108,6 +108,25 @@
PMINIPORTWAVEPCI
GetWavePciMiniport(
PPORTWAVEPCI Port);
+
+NTSTATUS
+NewPortFilterWaveRT(
+ OUT IPortFilterWaveRT ** OutFilter);
+
+NTSTATUS NewPortPinWaveRT(
+ OUT IPortPinWaveRT ** OutPin);
+
+PMINIPORTWAVERT
+GetWaveRTMiniport(
+ IN IPortWaveRT* iface);
+
+PDEVICE_OBJECT
+GetDeviceObjectFromPortWaveRT(
+ IPortWaveRT* iface);
+
+NTSTATUS
+NewPortWaveRTStream(
+ PPORTWAVERTSTREAM *OutStream);
NTSTATUS
NTAPI