Author: janderwald Date: Fri Dec 12 09:01:31 2008 New Revision: 38027
URL: http://svn.reactos.org/svn/reactos?rev=38027&view=rev Log: - Partly implement IPortWavePci interface - Use IServiceSink interface for notification when capture frames are available
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] Fri Dec 12 09:01:31 2008 @@ -3,15 +3,269 @@ typedef struct { IPortWavePciVtbl *lpVtbl; - IPortClsVersion *lpVtblPortClsVersion; + IServiceSinkVtbl *lpVtblServiceSink; + #if 0 IUnregisterSubdevice *lpVtblUnregisterSubDevice; + IPortClsVersionVtbl *lpVtblPortClsVersion; #endif LONG ref;
- + PMINIPORTWAVEPCI Miniport; + PDEVICE_OBJECT pDeviceObject; + KDPC Dpc; + BOOL bInitialized; + PRESOURCELIST pResourceList; + PSERVICEGROUP ServiceGroup; }IPortWavePciImpl;
+ +const GUID IID_IPortWavePci; +const GUID IID_IMiniportWavePci; + +//--------------------------------------------------------------- +// IServiceSink +// + +static +NTSTATUS +NTAPI +IServiceSink_fnQueryInterface( + IServiceSink* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink); + + if (IsEqualGUIDAligned(refiid, &IID_IServiceSink)) + { + *Output = &This->lpVtblServiceSink; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +static +ULONG +NTAPI +IServiceSink_fnAddRef( + IServiceSink* iface) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink); + + return InterlockedIncrement(&This->ref); +} + +static +ULONG +NTAPI +IServiceSink_fnRelease( + IServiceSink* iface) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink); + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + ExFreePoolWithTag(This, TAG_PORTCLASS); + return 0; + } + /* Return new reference count */ + return This->ref; +} + +static +VOID +NTAPI +IServiceSink_fnRequestService( + IServiceSink* iface) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink); + + if (This->Miniport) + { + This->Miniport->lpVtbl->Service(This->Miniport); + } +} + +static IServiceSinkVtbl vt_IServiceSink = +{ + IServiceSink_fnQueryInterface, + IServiceSink_fnAddRef, + IServiceSink_fnRelease, + IServiceSink_fnRequestService +}; + +//--------------------------------------------------------------- +// IPortWavePci +// + +static +NTSTATUS +NTAPI +IPortWavePci_fnQueryInterface( + IPortWavePci* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)iface; + + if (IsEqualGUIDAligned(refiid, &IID_IPortWavePci)) + { + *Output = &This->lpVtbl; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, &IID_IServiceSink)) + { + *Output = &This->lpVtbl; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +static +ULONG +NTAPI +IPortWavePci_fnAddRef( + IPortWavePci* iface) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)iface; + return InterlockedIncrement(&This->ref); +} + +static +ULONG +NTAPI +IPortWavePci_fnRelease( + IPortWavePci* iface) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)iface; + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + ExFreePoolWithTag(This, TAG_PORTCLASS); + return 0; + } + /* Return new reference count */ + return This->ref; +} + +VOID +NTAPI +ServiceNotifyRoutine( + IN struct _KDPC *Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)DeferredContext; + if (This->ServiceGroup) + { + This->ServiceGroup->lpVtbl->RequestService(This->ServiceGroup); + } +} + + + +NTSTATUS +NTAPI +IPortWavePci_fnInit( + IN IPortWavePci * iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PUNKNOWN UnknownMiniport, + IN PUNKNOWN UnknownAdapter OPTIONAL, + IN PRESOURCELIST ResourceList) +{ + IMiniportWavePci * Miniport; + PSERVICEGROUP ServiceGroup; + NTSTATUS Status; + IPortWavePciImpl * This = (IPortWavePciImpl*)iface; + + if (This->bInitialized) + { + DPRINT("IPortWaveCyclic_Init called again\n"); + return STATUS_SUCCESS; + } + + Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportWavePci, (PVOID*)&Miniport); + if (!NT_SUCCESS(Status)) + { + DPRINT("IPortWaveCyclic_Init called with invalid IMiniport adapter\n"); + return STATUS_INVALID_PARAMETER; + } + + Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup); + if (!NT_SUCCESS(Status)) + { + DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status); + return Status; + } + + /* Initialize port object */ + This->Miniport = Miniport; + This->pDeviceObject = DeviceObject; + This->bInitialized = TRUE; + This->pResourceList = ResourceList; + This->ServiceGroup = ServiceGroup; + + /* initialize the dpc */ + KeInitializeDpc(&This->Dpc, ServiceNotifyRoutine, (PVOID)This); + + /* increment reference on miniport adapter */ + Miniport->lpVtbl->AddRef(Miniport); + /* increment reference on resource list */ + ResourceList->lpVtbl->AddRef(ResourceList); + + /* add ourselves to service group which is called when miniport receives an isr */ + ServiceGroup->lpVtbl->AddMember(ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink); + + /* increment reference on service group */ + ServiceGroup->lpVtbl->AddRef(ServiceGroup); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IPortWavePci_fnNewRegistryKey( + IN IPortWavePci * 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) +{ + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +IPortWavePci_fnGetDeviceProperty( + IN IPortWavePci * iface, + IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, + IN ULONG BufferLength, + OUT PVOID PropertyBuffer, + OUT PULONG ReturnLength) +{ + IPortWavePciImpl * This = (IPortWavePciImpl*)iface; + + if (!This->bInitialized) + { + DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initiazed\n"); + return STATUS_UNSUCCESSFUL; + } + + return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); +}
NTSTATUS NTAPI @@ -33,15 +287,46 @@ }
VOID +NTAPI IPortWavePci_fnNotify( IN IPortWavePci * iface, IN PSERVICEGROUP ServiceGroup) { -} + IPortWavePciImpl * This = (IPortWavePciImpl*)iface; + KeInsertQueueDpc(&This->Dpc, NULL, NULL); +} + +static IPortWavePciVtbl vt_IPortWavePci = +{ + /* IUnknown methods */ + IPortWavePci_fnQueryInterface, + IPortWavePci_fnAddRef, + IPortWavePci_fnRelease, + /* IPort methods */ + IPortWavePci_fnInit, + IPortWavePci_fnGetDeviceProperty, + IPortWavePci_fnNewRegistryKey, + /* IPortWavePci methods */ + IPortWavePci_fnNewMasterDmaChannel, + IPortWavePci_fnNotify +}; +
NTSTATUS NewPortWavePci( OUT PPORT* OutPort) { - return STATUS_UNSUCCESSFUL; -} + IPortWavePciImpl * This; + + This = ExAllocatePoolWithTag(NonPagedPool, sizeof(IPortWavePciImpl), TAG_PORTCLASS); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlZeroMemory(This, sizeof(IPortWavePciImpl)); + This->lpVtblServiceSink = &vt_IServiceSink; + This->lpVtbl = &vt_IPortWavePci; + This->ref = 1; + + *OutPort = (PPORT)&This->lpVtbl; + return STATUS_SUCCESS; +}