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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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)