From ad2cf72549b9e95e537ff9291cd8187ae4948d38 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 11 Sep 2009 06:33:55 +0000 Subject: [PATCH] - Convert portcls to a C++ driver - Tested with Vbox 2.2.4 + AC97 with Winamp - WIP, Testing recommended svn path=/trunk/; revision=43026 --- .../wdm/audio/backpln/portcls/ResourceList.c | 255 ---- .../portcls/{adapter.c => adapter.cpp} | 201 ++- .../audio/backpln/portcls/{api.c => api.cpp} | 60 +- .../portcls/{connection.c => connection.cpp} | 189 ++- .../portcls/{dispatcher.c => dispatcher.cpp} | 78 +- .../audio/backpln/portcls/{dll.c => dll.cpp} | 17 +- .../wdm/audio/backpln/portcls/dma_slave.c | 572 -------- .../wdm/audio/backpln/portcls/dma_slave.cpp | 481 +++++++ .../audio/backpln/portcls/{drm.c => drm.cpp} | 38 +- .../wdm/audio/backpln/portcls/drm_port.c | 181 --- .../wdm/audio/backpln/portcls/drm_port.cpp | 152 ++ .../wdm/audio/backpln/portcls/filter_dmus.c | 503 ------- .../wdm/audio/backpln/portcls/filter_dmus.cpp | 332 +++++ .../audio/backpln/portcls/filter_topology.c | 372 ----- .../audio/backpln/portcls/filter_topology.cpp | 268 ++++ .../audio/backpln/portcls/filter_wavecyclic.c | 457 ------ .../backpln/portcls/filter_wavecyclic.cpp | 361 +++++ .../audio/backpln/portcls/filter_wavepci.c | 458 ------ .../audio/backpln/portcls/filter_wavepci.cpp | 302 ++++ .../wdm/audio/backpln/portcls/filter_wavert.c | 462 ------ .../audio/backpln/portcls/filter_wavert.cpp | 307 ++++ .../backpln/portcls/{guids.c => guids.cpp} | 16 +- .../portcls/{interfaces.h => interfaces.hpp} | 412 ++++-- .../wdm/audio/backpln/portcls/interrupt.c | 376 ----- .../wdm/audio/backpln/portcls/interrupt.cpp | 338 +++++ .../audio/backpln/portcls/{irp.c => irp.cpp} | 145 +- .../wdm/audio/backpln/portcls/irpstream.c | 563 -------- .../wdm/audio/backpln/portcls/irpstream.cpp | 499 +++++++ .../portcls/{miniport.c => miniport.cpp} | 22 +- .../wdm/audio/backpln/portcls/miniport_dmus.c | 172 --- .../audio/backpln/portcls/miniport_dmus.cpp | 135 ++ ...iniport_fmsynth.c => miniport_fmsynth.cpp} | 4 +- .../wdm/audio/backpln/portcls/pin_dmus.c | 1197 ---------------- .../wdm/audio/backpln/portcls/pin_dmus.cpp | 808 +++++++++++ .../audio/backpln/portcls/pin_wavecyclic.c | 1262 ----------------- .../audio/backpln/portcls/pin_wavecyclic.cpp | 1077 ++++++++++++++ .../wdm/audio/backpln/portcls/pin_wavepci.c | 1145 --------------- .../wdm/audio/backpln/portcls/pin_wavepci.cpp | 863 +++++++++++ .../wdm/audio/backpln/portcls/pin_wavert.c | 1126 --------------- .../wdm/audio/backpln/portcls/pin_wavert.cpp | 911 ++++++++++++ .../backpln/portcls/{pool.c => pool.cpp} | 2 +- .../backpln/portcls/{port.c => port.cpp} | 18 +- .../backpln/portcls/{port.h => port.hpp} | 0 .../wdm/audio/backpln/portcls/port_dmus.c | 701 --------- .../wdm/audio/backpln/portcls/port_dmus.cpp | 535 +++++++ .../{port_factory.c => port_factory.cpp} | 0 .../wdm/audio/backpln/portcls/port_topology.c | 823 ----------- .../audio/backpln/portcls/port_topology.cpp | 665 +++++++++ .../audio/backpln/portcls/port_wavecyclic.c | 807 ----------- .../audio/backpln/portcls/port_wavecyclic.cpp | 629 ++++++++ .../wdm/audio/backpln/portcls/port_wavepci.c | 822 ----------- .../audio/backpln/portcls/port_wavepci.cpp | 591 ++++++++ .../wdm/audio/backpln/portcls/port_wavert.c | 685 --------- .../wdm/audio/backpln/portcls/port_wavert.cpp | 498 +++++++ ...t_wavertstream.c => port_wavertstream.cpp} | 167 +-- .../wdm/audio/backpln/portcls/portcls.rbuild | 87 +- .../backpln/portcls/{power.c => power.cpp} | 20 +- .../portcls/{private.h => private.hpp} | 75 +- ...{propertyhandler.c => propertyhandler.cpp} | 103 +- .../wdm/audio/backpln/portcls/purecall.cpp | 23 + .../wdm/audio/backpln/portcls/registry.c | 388 ----- .../wdm/audio/backpln/portcls/registry.cpp | 342 +++++ .../wdm/audio/backpln/portcls/resource.c | 510 ------- .../wdm/audio/backpln/portcls/resource.cpp | 456 ++++++ .../wdm/audio/backpln/portcls/service_group.c | 346 ----- .../audio/backpln/portcls/service_group.cpp | 319 +++++ .../backpln/portcls/{undoc.c => undoc.cpp} | 72 +- .../portcls/{unregister.c => unregister.cpp} | 138 +- .../wdm/audio/backpln/portcls/version.c | 96 -- .../wdm/audio/backpln/portcls/version.cpp | 93 ++ 70 files changed, 11968 insertions(+), 15160 deletions(-) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/ResourceList.c rename reactos/drivers/wdm/audio/backpln/portcls/{adapter.c => adapter.cpp} (63%) rename reactos/drivers/wdm/audio/backpln/portcls/{api.c => api.cpp} (89%) rename reactos/drivers/wdm/audio/backpln/portcls/{connection.c => connection.cpp} (65%) rename reactos/drivers/wdm/audio/backpln/portcls/{dispatcher.c => dispatcher.cpp} (67%) rename reactos/drivers/wdm/audio/backpln/portcls/{dll.c => dll.cpp} (66%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{drm.c => drm.cpp} (75%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/drm_port.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/drm_port.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_topology.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{guids.c => guids.cpp} (90%) rename reactos/drivers/wdm/audio/backpln/portcls/{interfaces.h => interfaces.hpp} (56%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/interrupt.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{irp.c => irp.cpp} (75%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/irpstream.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{miniport.c => miniport.cpp} (64%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/miniport_dmus.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{miniport_fmsynth.c => miniport_fmsynth.cpp} (91%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{pool.c => pool.cpp} (89%) rename reactos/drivers/wdm/audio/backpln/portcls/{port.c => port.cpp} (70%) rename reactos/drivers/wdm/audio/backpln/portcls/{port.h => port.hpp} (100%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{port_factory.c => port_factory.cpp} (100%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_topology.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/port_wavert.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{port_wavertstream.c => port_wavertstream.cpp} (53%) rename reactos/drivers/wdm/audio/backpln/portcls/{power.c => power.cpp} (87%) rename reactos/drivers/wdm/audio/backpln/portcls/{private.h => private.hpp} (90%) rename reactos/drivers/wdm/audio/backpln/portcls/{propertyhandler.c => propertyhandler.cpp} (88%) create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/purecall.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/registry.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/registry.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/resource.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/resource.cpp delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/service_group.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/service_group.cpp rename reactos/drivers/wdm/audio/backpln/portcls/{undoc.c => undoc.cpp} (79%) rename reactos/drivers/wdm/audio/backpln/portcls/{unregister.c => unregister.cpp} (53%) delete mode 100644 reactos/drivers/wdm/audio/backpln/portcls/version.c create mode 100644 reactos/drivers/wdm/audio/backpln/portcls/version.cpp diff --git a/reactos/drivers/wdm/audio/backpln/portcls/ResourceList.c b/reactos/drivers/wdm/audio/backpln/portcls/ResourceList.c deleted file mode 100644 index ddc36b446fd..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/ResourceList.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS - * FILE: drivers/multimedia/portcls/helpers/ResourceList.c - * PURPOSE: Port Class driver / ResourceList implementation - * PROGRAMMER: Andrew Greenwood - * - * HISTORY: - * 27 Jan 07 Created - */ - -#include "private.h" -#include -#include - -typedef struct CResourceList -{ - union - { - IUnknown IUnknown; - IResourceList IResourceList; - }; - - LONG m_ref_count; - PUNKNOWN m_outer_unknown; - - PCM_RESOURCE_LIST translated_resources; - PCM_RESOURCE_LIST untranslated_resources; -} CResourceList; - - -/* - Basic IUnknown methods -*/ - -NTSTATUS -STDMETHODCALLTYPE -ResourceList_QueryInterface( - IResourceList* this_container, - IN REFIID refiid, - OUT PVOID* output) -{ - /* TODO */ - return STATUS_SUCCESS; -} - -ULONG -STDMETHODCALLTYPE -ResourceList_AddRef( - IResourceList* this_container) -{ - struct CUnknown* this = CONTAINING_RECORD(this_container, struct CUnknown, IUnknown); - -/* fixme */ -/* ExInterlockedIncrement(&this->m_ref_count); */ - return this->m_ref_count; -} - -ULONG -STDMETHODCALLTYPE -ResourceList_Release( - IResourceList* this_container) -{ - struct CUnknown* this = CONTAINING_RECORD(this_container, struct CUnknown, IUnknown); - -/* fixme */ -/* ExInterlockedDecrement(&this->m_ref_count); */ - - if ( this->m_ref_count == 0 ) - { - ExFreePool(this); - return 0; - } - - return this->m_ref_count; -} - - -/* - IResourceList methods -*/ - -ULONG -STDMETHODCALLTYPE -ResourceList_NumberOfEntries(IResourceList* this_container) -{ - return 0; -} - -ULONG -STDMETHODCALLTYPE -ResourceList_NumberOfEntriesOfType( - IResourceList* this_container, - IN CM_RESOURCE_TYPE type) -{ - /* I guess the translated and untranslated lists will be same length? */ - - CResourceList* this = CONTAINING_RECORD(this_container, CResourceList, IResourceList); - ULONG index, count = 0; - - for ( index = 0; index < this->translated_resources->Count; index ++ ) - { - PCM_FULL_RESOURCE_DESCRIPTOR full_desc = &this->translated_resources->List[index]; - ULONG sub_index; - - for ( sub_index = 0; sub_index < full_desc->PartialResourceList.Count; sub_index ++ ) - { - PCM_PARTIAL_RESOURCE_DESCRIPTOR partial_desc; - partial_desc = &full_desc->PartialResourceList.PartialDescriptors[sub_index]; - - if ( partial_desc->Type == type ) - { - /* Yay! Finally found one that matches! */ - count ++; - } - } - } - - DPRINT("Found %d\n", count); - return count; -} - -PCM_PARTIAL_RESOURCE_DESCRIPTOR -STDMETHODCALLTYPE -ResourceList_FindTranslatedEntry( - IResourceList* this_container, - IN CM_RESOURCE_TYPE Type, - IN ULONG Index) -{ - return NULL; -} - -PCM_PARTIAL_RESOURCE_DESCRIPTOR -STDMETHODCALLTYPE -ResourceList_FindUntranslatedEntry( - IResourceList* this_container, - IN CM_RESOURCE_TYPE Type, - IN ULONG Index) -{ - return NULL; -} - -NTSTATUS -STDMETHODCALLTYPE -ResourceList_AddEntry( - IResourceList* this_container, - IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, - IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Untranslated) -{ - return STATUS_SUCCESS; -} - -NTSTATUS -STDMETHODCALLTYPE -ResourceList_AddEntryFromParent( - IResourceList* this_container, - IN IResourceList* Parent, - IN CM_RESOURCE_TYPE Type, - IN ULONG Index) -{ - return STATUS_SUCCESS; -} - -PCM_RESOURCE_LIST -STDMETHODCALLTYPE -ResourceList_TranslatedList( - IResourceList* this_container) -{ - return NULL; -} - -PCM_RESOURCE_LIST -STDMETHODCALLTYPE -ResourceList_UntranslatedList( - IResourceList* this_container) -{ - return NULL; -} - - -/* - ResourceList V-Table -*/ -static const IResourceListVtbl ResourceListVtbl = -{ - /* IUnknown */ - ResourceList_QueryInterface, - ResourceList_AddRef, - ResourceList_Release, - - /* IResourceList */ - ResourceList_NumberOfEntries, - ResourceList_NumberOfEntriesOfType, - ResourceList_FindTranslatedEntry, - ResourceList_FindUntranslatedEntry, - ResourceList_AddEntry, - ResourceList_AddEntryFromParent, - ResourceList_TranslatedList, - ResourceList_UntranslatedList -}; - - -/* - Factory for creating a resource list -*/ -PORTCLASSAPI NTSTATUS NTAPI -PcNewResourceList( - OUT PRESOURCELIST* OutResourceList, - IN PUNKNOWN OuterUnknown OPTIONAL, - IN POOL_TYPE PoolType, - IN PCM_RESOURCE_LIST TranslatedResources, - IN PCM_RESOURCE_LIST UntranslatedResources) -{ - IResourceList* new_list = NULL; - CResourceList* this = NULL; - - /* TODO: Validate parameters */ - - DPRINT("PcNewResourceList\n"); - - new_list = ExAllocatePoolWithTag(sizeof(IResourceList), PoolType, TAG_PORTCLASS); - - if ( ! new_list ) - { - DPRINT("ExAllocatePoolWithTag failed\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Obtain our private data */ - this = CONTAINING_RECORD(new_list, CResourceList, IResourceList); - - ASSERT(this); - - /* Initialize */ - this->m_outer_unknown = OuterUnknown; - this->translated_resources = TranslatedResources; - this->untranslated_resources = UntranslatedResources; - - /* Increment our usage count and set the pointer to this object */ - *OutResourceList = new_list; - ResourceListVtbl.AddRef(*OutResourceList); - - return STATUS_SUCCESS; -} - -PORTCLASSAPI NTSTATUS NTAPI -PcNewResourceSublist( - OUT PRESOURCELIST* OutResourceList, - IN PUNKNOWN OuterUnknown OPTIONAL, - IN POOL_TYPE PoolType, - IN PRESOURCELIST ParentList, - IN ULONG MaximumEntries) -{ - return STATUS_UNSUCCESSFUL; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c b/reactos/drivers/wdm/audio/backpln/portcls/adapter.cpp similarity index 63% rename from reactos/drivers/wdm/audio/backpln/portcls/adapter.c rename to reactos/drivers/wdm/audio/backpln/portcls/adapter.cpp index 50ef8502eb5..7a08189d92a 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/adapter.cpp @@ -1,54 +1,37 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/api.c + * FILE: drivers/wdm/audio/backpln/portcls/api.cpp * PURPOSE: Port Class driver / DriverEntry and IRP handlers * PROGRAMMER: Andrew Greenwood - * + * Johannes Anderwald * HISTORY: * 27 Jan 07 Created */ -#include "private.h" +#include "private.hpp" -/* - This is called from DriverEntry so that PortCls can take care of some - IRPs and map some others to the main KS driver. In most cases this will - be the first function called by an audio driver. - - First 2 parameters are from DriverEntry. - - The AddDevice parameter is a driver-supplied pointer to a function which - typically then calls PcAddAdapterDevice (see below.) -*/ -NTSTATUS NTAPI +// +// This is called from DriverEntry so that PortCls can take care of some +// IRPs and map some others to the main KS driver. In most cases this will +// be the first function called by an audio driver. +// +// First 2 parameters are from DriverEntry. +// +// The AddDevice parameter is a driver-supplied pointer to a function which +// typically then calls PcAddAdapterDevice (see below.) +// +NTSTATUS +NTAPI PcInitializeAdapterDriver( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPathName, IN PDRIVER_ADD_DEVICE AddDevice) { - /* - (* = implement here, otherwise KS default) - IRP_MJ_CLOSE - * IRP_MJ_CREATE - IRP_MJ_DEVICE_CONTROL - IRP_MJ_FLUSH_BUFFERS - * IRP_MJ_PNP - * IRP_MJ_POWER - IRP_MJ_QUERY_SECURITY - IRP_MJ_READ - IRP_MJ_SET_SECURITY - * IRP_MJ_SYSTEM_CONTROL - IRP_MJ_WRITE - */ - - //NTSTATUS status; - //ULONG i; - DPRINT1("PcInitializeAdapterDriver\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - /* Our IRP handlers */ + // Our IRP handlers DPRINT1("Setting IRP handlers\n"); DriverObject->MajorFunction[IRP_MJ_CREATE] = PcDispatchIrp; DriverObject->MajorFunction[IRP_MJ_PNP] = PcDispatchIrp; @@ -56,10 +39,10 @@ PcInitializeAdapterDriver( DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PcDispatchIrp; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = PcDispatchIrp; - /* The driver-supplied AddDevice */ + // The driver-supplied AddDevice DriverObject->DriverExtension->AddDevice = AddDevice; - /* KS handles these */ + // KS handles these DPRINT("Setting KS function handlers\n"); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL); @@ -74,15 +57,16 @@ PcInitializeAdapterDriver( return STATUS_SUCCESS; } -/* - Typically called by a driver's AddDevice function, which is set when - calling PcInitializeAdapterDriver. This performs some common driver - operations, such as creating a device extension. - - The StartDevice parameter is a driver-supplied function which gets - called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE. -*/ -NTSTATUS NTAPI +// +// Typically called by a driver's AddDevice function, which is set when +// calling PcInitializeAdapterDriver. This performs some common driver +// operations, such as creating a device extension. +// +// The StartDevice parameter is a driver-supplied function which gets +// called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE. +// +NTSTATUS +NTAPI PcAddAdapterDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, @@ -96,27 +80,27 @@ PcAddAdapterDevice( PPCLASS_DEVICE_EXTENSION portcls_ext = NULL; DPRINT1("PcAddAdapterDevice called\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!DriverObject || !PhysicalDeviceObject || !StartDevice) { return STATUS_INVALID_PARAMETER; } - /* check if the DeviceExtensionSize is provided */ + // check if the DeviceExtensionSize is provided if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE ) { - /* driver does not need a device extension */ + // driver does not need a device extension if ( DeviceExtensionSize != 0 ) { - /* DeviceExtensionSize must be zero*/ + // DeviceExtensionSize must be zero return STATUS_INVALID_PARAMETER; } - /* set size to our extension size */ + // set size to our extension size DeviceExtensionSize = PORT_CLASS_DEVICE_EXTENSION_SIZE; } - /* create the device */ + // create the device status = IoCreateDevice(DriverObject, DeviceExtensionSize, NULL, @@ -131,69 +115,69 @@ PcAddAdapterDevice( return status; } - /* Obtain the new device extension */ + // Obtain the new device extension portcls_ext = (PPCLASS_DEVICE_EXTENSION) fdo->DeviceExtension; - /* initialize the device extension */ + // initialize the device extension RtlZeroMemory(portcls_ext, DeviceExtensionSize); - /* allocate create item */ - portcls_ext->CreateItems = AllocateItem(NonPagedPool, MaxObjects * sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS); + // allocate create item + portcls_ext->CreateItems = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, MaxObjects * sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS); if (!portcls_ext->CreateItems) { - /* not enough resources */ + // not enough resources status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } - /* store max subdevice count */ + // store max subdevice count portcls_ext->MaxSubDevices = MaxObjects; - /* store the physical device object */ + // store the physical device object portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject; - /* set up the start device function */ + // set up the start device function portcls_ext->StartDevice = StartDevice; - /* prepare the subdevice list */ + // prepare the subdevice list InitializeListHead(&portcls_ext->SubDeviceList); - /* prepare the physical connection list */ + // prepare the physical connection list InitializeListHead(&portcls_ext->PhysicalConnectionList); - /* initialize timer lock */ + // initialize timer lock KeInitializeSpinLock(&portcls_ext->TimerListLock); - /* initialize timer list */ + // initialize timer list InitializeListHead(&portcls_ext->TimerList); - /* initialize io timer */ + // initialize io timer IoInitializeTimer(fdo, PcIoTimerRoutine, NULL); - /* start the io timer */ + // start the io timer IoStartTimer(fdo); - /* set io flags */ + // set io flags fdo->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; - /* clear initializing flag */ + // clear initializing flag fdo->Flags &= ~ DO_DEVICE_INITIALIZING; - /* allocate the device header */ + // allocate the device header status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems); - /* did we succeed */ + // did we succeed if (!NT_SUCCESS(status)) { goto cleanup; } - /* attach device to device stack */ + // attach device to device stack PrevDeviceObject = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject); - /* did we succeed */ + // did we succeed if (PrevDeviceObject) { - /* store the device object in the device header */ + // store the device object in the device header //KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, fdo, PrevDeviceObject); portcls_ext->PrevDeviceObject = PrevDeviceObject; } else { - /* return error code */ + // return error code status = STATUS_UNSUCCESSFUL; goto cleanup; } - /* register shutdown notification */ + // register shutdown notification IoRegisterShutdownNotification(PhysicalDeviceObject); return status; @@ -202,17 +186,17 @@ cleanup: if (portcls_ext->KsDeviceHeader) { - /* free the device header */ + // free the device header KsFreeDeviceHeader(portcls_ext->KsDeviceHeader); } if (portcls_ext->CreateItems) { - /* free previously allocated create items */ + // free previously allocated create items FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); } - /* delete created fdo */ + // delete created fdo IoDeleteDevice(fdo); @@ -237,79 +221,80 @@ PcRegisterSubdevice( PSYMBOLICLINK_ENTRY SymEntry; DPRINT1("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - /* check if all parameters are valid */ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + // check if all parameters are valid if (!DeviceObject || !Name || !Unknown) { DPRINT("PcRegisterSubdevice invalid parameter\n"); return STATUS_INVALID_PARAMETER; } - /* get device extension */ + // get device extension DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; if (!DeviceExt) { - /* should not happen */ + // should not happen KeBugCheck(0); return STATUS_UNSUCCESSFUL; } - /* look up our undocumented interface */ - Status = Unknown->lpVtbl->QueryInterface(Unknown, &IID_ISubdevice, (LPVOID)&SubDevice); + // look up our undocumented interface + Status = Unknown->QueryInterface(IID_ISubdevice, (LPVOID*)&SubDevice); if (!NT_SUCCESS(Status)) { DPRINT1("No ISubdevice interface\n"); - /* the provided port driver doesnt support ISubdevice */ + // the provided port driver doesnt support ISubdevice return STATUS_INVALID_PARAMETER; } - /* get the subdevice descriptor */ - Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &SubDeviceDescriptor); + // get the subdevice descriptor + Status = SubDevice->GetDescriptor(&SubDeviceDescriptor); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to get subdevice descriptor %x\n", Status); - SubDevice->lpVtbl->Release(SubDevice); + SubDevice->Release(); return STATUS_UNSUCCESSFUL; } - /* allocate subdevice entry */ - Entry = AllocateItem(NonPagedPool, sizeof(SUBDEVICE_ENTRY), TAG_PORTCLASS); + // allocate subdevice entry + Entry = (PSUBDEVICE_ENTRY)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_ENTRY), TAG_PORTCLASS); if (!Entry) { - /* Insufficient memory */ - SubDevice->lpVtbl->Release(SubDevice); + // Insufficient memory + SubDevice->Release(); return STATUS_INSUFFICIENT_RESOURCES; } - /* add an create item to the device header */ + // add an create item to the device header Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PcCreateItemDispatch, (PVOID)SubDevice, Name, NULL); if (!NT_SUCCESS(Status)) { - /* failed to attach */ - SubDevice->lpVtbl->Release(SubDevice); + // failed to attach + SubDevice->Release(); FreeItem(Entry, TAG_PORTCLASS); DPRINT1("KsAddObjectCreateItemToDeviceHeader failed with %x\n", Status); return Status; } - /* initialize reference string */ + // initialize reference string RtlInitUnicodeString(&RefName, Name); - /* initialize subdevice entry */ + // initialize subdevice entry Entry->SubDevice = SubDevice; RtlInitUnicodeString(&Entry->Name, Name); InitializeListHead(&Entry->SymbolicLinkList); - /* store subdevice entry */ + // store subdevice entry InsertTailList(&DeviceExt->SubDeviceList, &Entry->Entry); for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++) { - /* FIXME - * check if reference string with that name already exists - */ + // FIXME + // check if reference string with that name already exists + Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject, &SubDeviceDescriptor->Interfaces[Index], &RefName, @@ -317,27 +302,27 @@ PcRegisterSubdevice( if (NT_SUCCESS(Status)) { - /* activate device interface */ + // activate device interface IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - /* allocate symbolic link entry */ - SymEntry = AllocateItem(NonPagedPool, sizeof(SYMBOLICLINK_ENTRY), TAG_PORTCLASS); + // allocate symbolic link entry + SymEntry = (PSYMBOLICLINK_ENTRY)AllocateItem(NonPagedPool, sizeof(SYMBOLICLINK_ENTRY), TAG_PORTCLASS); if (SymEntry) { - /* initialize symbolic link item */ + // initialize symbolic link item RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer); - /* store item */ + // store item InsertTailList(&Entry->SymbolicLinkList, &SymEntry->Entry); } else { - /* allocating failed */ + // allocating failed RtlFreeUnicodeString(&SymbolicLinkName); } } } - /* release SubDevice reference */ - SubDevice->lpVtbl->Release(SubDevice); + // release SubDevice reference + SubDevice->Release(); return STATUS_SUCCESS; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/api.c b/reactos/drivers/wdm/audio/backpln/portcls/api.cpp similarity index 89% rename from reactos/drivers/wdm/audio/backpln/portcls/api.c rename to reactos/drivers/wdm/audio/backpln/portcls/api.cpp index 067bd19701d..62739c85fac 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/api.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/api.cpp @@ -1,16 +1,13 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/api.c + * FILE: drivers/wdm/audio/backpln/portcls/api.cpp * PURPOSE: Port api functions * PROGRAMMER: Johannes Anderwald */ -#include "private.h" +#include "private.hpp" -/* - * @implemented - */ NTSTATUS NTAPI PcGetDeviceProperty( @@ -22,16 +19,13 @@ PcGetDeviceProperty( { PPCLASS_DEVICE_EXTENSION DeviceExtension; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); DeviceExtension = (PPCLASS_DEVICE_EXTENSION)((PDEVICE_OBJECT)DeviceObject)->DeviceExtension; return IoGetDeviceProperty(DeviceExtension->PhysicalDeviceObject, DeviceProperty, BufferLength, PropertyBuffer, ResultLength); } -/* - * @implemented - */ ULONGLONG NTAPI PcGetTimeInterval( @@ -44,10 +38,6 @@ PcGetTimeInterval( return (CurrentTime.QuadPart - Since); } -/* - * @implemented - */ - VOID NTAPI PcIoTimerRoutine( @@ -78,10 +68,8 @@ PcIoTimerRoutine( KeReleaseSpinLock(&DeviceExtension->TimerListLock, OldIrql); } -/* - * @implemented - */ -NTSTATUS NTAPI +NTSTATUS +NTAPI PcRegisterIoTimeout( IN PDEVICE_OBJECT pDeviceObject, IN PIO_TIMER_ROUTINE pTimerRoutine, @@ -94,14 +82,14 @@ PcRegisterIoTimeout( BOOLEAN bFound; PPCLASS_DEVICE_EXTENSION DeviceExtension; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!pDeviceObject || !pDeviceObject->DeviceExtension) return STATUS_INVALID_PARAMETER; DeviceExtension = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension; - TimerContext = AllocateItem(NonPagedPool, sizeof(TIMER_CONTEXT), TAG_PORTCLASS); + TimerContext = (PTIMER_CONTEXT)AllocateItem(NonPagedPool, sizeof(TIMER_CONTEXT), TAG_PORTCLASS); if (!TimerContext) { DPRINT1("Failed to allocate memory\n"); @@ -138,9 +126,6 @@ PcRegisterIoTimeout( return Status; } -/* - * @implemented - */ NTSTATUS NTAPI PcUnregisterIoTimeout( @@ -154,7 +139,7 @@ PcUnregisterIoTimeout( BOOLEAN bFound; PPCLASS_DEVICE_EXTENSION DeviceExtension; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!pDeviceObject || !pDeviceObject->DeviceExtension) return STATUS_INVALID_PARAMETER; @@ -191,41 +176,32 @@ PcUnregisterIoTimeout( } -/* - * @implemented - */ + NTSTATUS NTAPI PcCompletePendingPropertyRequest( IN PPCPROPERTY_REQUEST PropertyRequest, IN NTSTATUS NtStatus) { - /* sanity checks */ - ASSERT_IRQL(DISPATCH_LEVEL); + // sanity checks + PC_ASSERT_IRQL(DISPATCH_LEVEL); - if (!PropertyRequest) + if (!PropertyRequest || !PropertyRequest->Irp || NtStatus == STATUS_PENDING) return STATUS_INVALID_PARAMETER; - ASSERT(PropertyRequest->Irp); - ASSERT(NtStatus != STATUS_PENDING); - - /* set the final status code */ + // set the final status code PropertyRequest->Irp->IoStatus.Status = NtStatus; - /* complete the irp */ + // complete the irp IoCompleteRequest(PropertyRequest->Irp, IO_SOUND_INCREMENT); - /* free the property request */ + // free the property request ExFreePool(PropertyRequest); - /* return success */ + // return success return STATUS_SUCCESS; } - -/* - * @implemented - */ NTSTATUS NTAPI PcDmaMasterDescription( @@ -256,9 +232,7 @@ PcDmaMasterDescription( return STATUS_SUCCESS; } -/* - * @implemented - */ + NTSTATUS NTAPI PcDmaSlaveDescription( diff --git a/reactos/drivers/wdm/audio/backpln/portcls/connection.c b/reactos/drivers/wdm/audio/backpln/portcls/connection.cpp similarity index 65% rename from reactos/drivers/wdm/audio/backpln/portcls/connection.c rename to reactos/drivers/wdm/audio/backpln/portcls/connection.cpp index 79855baac61..45a455bc894 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/connection.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/connection.cpp @@ -7,62 +7,69 @@ */ -#include "private.h" +#include "private.hpp" -typedef struct +extern +"C" +NTSYSAPI +BOOLEAN +NTAPI +RtlCreateUnicodeString( + PUNICODE_STRING DestinationString, + PCWSTR SourceString +); + + +class CUnregisterPhysicalConnection : public IUnregisterPhysicalConnection { - IUnregisterPhysicalConnectionVtbl *lpVtbl; - LONG ref; +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); -}IUnregisterPhysicalConnectionImpl; + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IUnregisterPhysicalConnection; + + CUnregisterPhysicalConnection(IUnknown *OuterUnknown){} + + virtual ~CUnregisterPhysicalConnection(){} + +protected: + LONG m_Ref; + +}; NTSTATUS NTAPI -IUnregisterPhysicalConnection_fnQueryInterface( - IUnregisterPhysicalConnection* iface, +CUnregisterPhysicalConnection::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IUnregisterPhysicalConnectionImpl * This = (IUnregisterPhysicalConnectionImpl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) + if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); + *Output = PVOID(PUNKNOWN(this)); + + PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } return STATUS_UNSUCCESSFUL; } -ULONG -NTAPI -IUnregisterPhysicalConnection_fnAddRef( - IUnregisterPhysicalConnection* iface) -{ - IUnregisterPhysicalConnectionImpl * This = (IUnregisterPhysicalConnectionImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IUnregisterPhysicalConnection_fnRelease( - IUnregisterPhysicalConnection* iface) -{ - IUnregisterPhysicalConnectionImpl * This = (IUnregisterPhysicalConnectionImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - return This->ref; -} - static NTSTATUS UnRegisterConnection( @@ -86,15 +93,15 @@ UnRegisterConnection( if (FromUnknown) { - /* get our private interface */ - Status = FromUnknown->lpVtbl->QueryInterface(FromUnknown, &IID_ISubdevice, (PVOID*)&FromSubDevice); + // get our private interface + Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&FromSubDevice); if (!NT_SUCCESS(Status)) return STATUS_INVALID_PARAMETER; } if (ToUnknown) { - Status = ToUnknown->lpVtbl->QueryInterface(ToUnknown, &IID_ISubdevice, (PVOID*)&ToSubDevice); + Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&ToSubDevice); if (!NT_SUCCESS(Status)) goto cleanup; } @@ -102,11 +109,11 @@ UnRegisterConnection( Entry = DeviceExt->PhysicalConnectionList.Flink; bFound = FALSE; - /* loop physical connection list */ + // loop physical connection list while(Entry != &DeviceExt->PhysicalConnectionList) { Connection = (PPHYSICAL_CONNECTION)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION, Entry); - /* compare current entry */ + // compare current entry if (Connection->FromPin == FromPin && Connection->ToPin == ToPin && Connection->FromSubDevice == FromSubDevice && Connection->ToSubDevice == ToSubDevice) { @@ -114,7 +121,7 @@ UnRegisterConnection( { if (!RtlCompareUnicodeString(FromString, &Connection->FromUnicodeString, TRUE)) { - /* UnregisterPhysicalConnectionFromExternal */ + // UnregisterPhysicalConnectionFromExternal bFound = TRUE; break; } @@ -123,14 +130,14 @@ UnRegisterConnection( { if (!RtlCompareUnicodeString(ToString, &Connection->ToUnicodeString, TRUE)) { - /* UnregisterPhysicalConnectionToExternal */ + // UnregisterPhysicalConnectionToExternal bFound = TRUE; break; } } else { - /* UnregisterPhysicalConnection */ + // UnregisterPhysicalConnection bFound = TRUE; break; } @@ -140,21 +147,21 @@ UnRegisterConnection( if (!bFound) { - /* not found */ + // not found Status = STATUS_NOT_FOUND; goto cleanup; } - /* remove list entry */ + // remove list entry RemoveEntryList(&Connection->Entry); - /* release resources */ + // release resources if (Connection->FromSubDevice) - Connection->FromSubDevice->lpVtbl->Release(Connection->FromSubDevice); + Connection->FromSubDevice->Release(); if (Connection->ToSubDevice) - Connection->ToSubDevice->lpVtbl->Release(Connection->ToSubDevice); + Connection->ToSubDevice->Release(); if (Connection->FromUnicodeString.Buffer) RtlFreeUnicodeString(&Connection->FromUnicodeString); @@ -168,10 +175,10 @@ UnRegisterConnection( cleanup: if (FromSubDevice) - FromSubDevice->lpVtbl->Release(FromSubDevice); + FromSubDevice->Release(); if (ToSubDevice) - ToSubDevice->lpVtbl->Release(ToSubDevice); + ToSubDevice->Release(); return Status; @@ -179,8 +186,7 @@ cleanup: NTSTATUS NTAPI -IUnregisterPhysicalConnection_fnUnregisterPhysicalConnection( - IN IUnregisterPhysicalConnection* iface, +CUnregisterPhysicalConnection::UnregisterPhysicalConnection( IN PDEVICE_OBJECT DeviceObject, IN PUNKNOWN FromUnknown, IN ULONG FromPin, @@ -195,8 +201,7 @@ IUnregisterPhysicalConnection_fnUnregisterPhysicalConnection( NTSTATUS NTAPI -IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionToExternal( - IN IUnregisterPhysicalConnection* iface, +CUnregisterPhysicalConnection::UnregisterPhysicalConnectionToExternal( IN PDEVICE_OBJECT DeviceObject, IN PUNKNOWN FromUnknown, IN ULONG FromPin, @@ -211,8 +216,7 @@ IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionToExternal( NTSTATUS NTAPI -IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionFromExternal( - IN IUnregisterPhysicalConnection* iface, +CUnregisterPhysicalConnection::UnregisterPhysicalConnectionFromExternal( IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING FromString, IN ULONG FromPin, @@ -225,41 +229,22 @@ IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionFromExternal( return UnRegisterConnection(DeviceObject, NULL, FromString, FromPin, ToUnknown, NULL, ToPin); } -static IUnregisterPhysicalConnectionVtbl vt_IUnregisterPhysicalConnection = -{ - IUnregisterPhysicalConnection_fnQueryInterface, - IUnregisterPhysicalConnection_fnAddRef, - IUnregisterPhysicalConnection_fnRelease, - IUnregisterPhysicalConnection_fnUnregisterPhysicalConnection, - IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionToExternal, - IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionFromExternal -}; - NTSTATUS NTAPI NewIUnregisterPhysicalConnection( OUT PUNREGISTERPHYSICALCONNECTION *OutConnection) { - IUnregisterPhysicalConnectionImpl * This = (IUnregisterPhysicalConnectionImpl*)AllocateItem(NonPagedPool, sizeof(IUnregisterPhysicalConnectionImpl), TAG_PORTCLASS); - if (!This) + CUnregisterPhysicalConnection *new_ptr = new(NonPagedPool, TAG_PORTCLASS) CUnregisterPhysicalConnection(NULL); + + if (!new_ptr) return STATUS_INSUFFICIENT_RESOURCES; - This->lpVtbl = &vt_IUnregisterPhysicalConnection; - This->ref = 1; - *OutConnection = (PUNREGISTERPHYSICALCONNECTION)&This->lpVtbl; + new_ptr->AddRef(); + *OutConnection = (PUNREGISTERPHYSICALCONNECTION)new_ptr; return STATUS_SUCCESS; } -NTSYSAPI -BOOLEAN -NTAPI -RtlCreateUnicodeString( - PUNICODE_STRING DestinationString, - PCWSTR SourceString -); - -static NTSTATUS RegisterConnection( IN OUT PDEVICE_OBJECT DeviceObject, @@ -276,7 +261,7 @@ RegisterConnection( DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - NewConnection = AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION), TAG_PORTCLASS); + NewConnection = (PPHYSICAL_CONNECTION)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION), TAG_PORTCLASS); if (!NewConnection) { return STATUS_INSUFFICIENT_RESOURCES; @@ -285,7 +270,7 @@ RegisterConnection( if (FromUnknown) { - Status = FromUnknown->lpVtbl->QueryInterface(FromUnknown, &IID_ISubdevice, (PVOID*)&NewConnection->FromSubDevice); + Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&NewConnection->FromSubDevice); if (!NT_SUCCESS(Status)) goto cleanup; } @@ -300,7 +285,7 @@ RegisterConnection( if (ToUnknown) { - Status = ToUnknown->lpVtbl->QueryInterface(ToUnknown, &IID_ISubdevice, (PVOID*)&NewConnection->ToSubDevice); + Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&NewConnection->ToSubDevice); if (!NT_SUCCESS(Status)) goto cleanup; } @@ -319,10 +304,10 @@ RegisterConnection( cleanup: if (NewConnection->FromSubDevice) - NewConnection->FromSubDevice->lpVtbl->Release(NewConnection->FromSubDevice); + NewConnection->FromSubDevice->Release(); if (NewConnection->ToSubDevice) - NewConnection->ToSubDevice->lpVtbl->Release(NewConnection->ToSubDevice); + NewConnection->ToSubDevice->Release(); if (NewConnection->FromUnicodeString.Buffer) RtlFreeUnicodeString(&NewConnection->FromUnicodeString); @@ -335,10 +320,8 @@ cleanup: return Status; } -/* - * @implemented - */ -NTSTATUS NTAPI +NTSTATUS +NTAPI PcRegisterPhysicalConnection( IN PDEVICE_OBJECT DeviceObject, IN PUNKNOWN FromUnknown, @@ -347,7 +330,7 @@ PcRegisterPhysicalConnection( IN ULONG ToPin) { DPRINT("PcRegisterPhysicalConnection\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!DeviceObject || !FromUnknown || !ToUnknown) return STATUS_INVALID_PARAMETER; @@ -355,10 +338,8 @@ PcRegisterPhysicalConnection( return RegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, ToUnknown, NULL, ToPin); } -/* - * @implemented - */ -NTSTATUS NTAPI +NTSTATUS +NTAPI PcRegisterPhysicalConnectionFromExternal( IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING FromString, @@ -366,7 +347,7 @@ PcRegisterPhysicalConnectionFromExternal( IN PUNKNOWN ToUnknown, IN ULONG ToPin) { - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!DeviceObject || !FromString || !ToUnknown) return STATUS_INVALID_PARAMETER; @@ -374,10 +355,8 @@ PcRegisterPhysicalConnectionFromExternal( return RegisterConnection(DeviceObject, NULL, FromString, FromPin, ToUnknown, NULL, ToPin); } -/* - * @implemented - */ -NTSTATUS NTAPI +NTSTATUS +NTAPI PcRegisterPhysicalConnectionToExternal( IN PDEVICE_OBJECT DeviceObject, IN PUNKNOWN FromUnknown, @@ -385,7 +364,7 @@ PcRegisterPhysicalConnectionToExternal( IN PUNICODE_STRING ToString, IN ULONG ToPin) { - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!DeviceObject || !FromUnknown || !ToString) return STATUS_INVALID_PARAMETER; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c b/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp similarity index 67% rename from reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c rename to reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp index fff89490378..bc01c9819e4 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp @@ -7,7 +7,7 @@ */ -#include "private.h" +#include "private.hpp" NTSTATUS NTAPI @@ -18,14 +18,14 @@ Dispatch_fnDeviceIoControl( PIO_STACK_LOCATION IoStack; IIrpTarget * IrpTarget; - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->DeviceIoControl(IrpTarget, DeviceObject, Irp); + // let IrpTarget handle request + return IrpTarget->DeviceIoControl(DeviceObject, Irp); } NTSTATUS @@ -37,15 +37,15 @@ Dispatch_fnRead( PIO_STACK_LOCATION IoStack; IIrpTarget * IrpTarget; - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->Read(IrpTarget, DeviceObject, Irp); + // let IrpTarget handle request + return IrpTarget->Read(DeviceObject, Irp); } NTSTATUS @@ -57,15 +57,15 @@ Dispatch_fnWrite( PIO_STACK_LOCATION IoStack; IIrpTarget * IrpTarget; - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->Write(IrpTarget, DeviceObject, Irp); + // let IrpTarget handle request + return IrpTarget->Write(DeviceObject, Irp); } NTSTATUS @@ -77,15 +77,15 @@ Dispatch_fnFlush( PIO_STACK_LOCATION IoStack; IIrpTarget * IrpTarget; - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->Flush(IrpTarget, DeviceObject, Irp); + // let IrpTarget handle request + return IrpTarget->Flush(DeviceObject, Irp); } NTSTATUS @@ -97,15 +97,15 @@ Dispatch_fnClose( PIO_STACK_LOCATION IoStack; IIrpTarget * IrpTarget; - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->Close(IrpTarget, DeviceObject, Irp); + // let IrpTarget handle request + return IrpTarget->Close(DeviceObject, Irp); } NTSTATUS @@ -117,15 +117,15 @@ Dispatch_fnQuerySecurity( PIO_STACK_LOCATION IoStack; IIrpTarget * IrpTarget; - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->QuerySecurity(IrpTarget, DeviceObject, Irp); + // let IrpTarget handle request + return IrpTarget->QuerySecurity(DeviceObject, Irp); } NTSTATUS @@ -137,15 +137,15 @@ Dispatch_fnSetSecurity( PIO_STACK_LOCATION IoStack; IIrpTarget * IrpTarget; - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->SetSecurity(IrpTarget, DeviceObject, Irp); + // let IrpTarget handle request + return IrpTarget->SetSecurity(DeviceObject, Irp); } BOOLEAN @@ -163,11 +163,11 @@ Dispatch_fnFastDeviceIoControl( { IIrpTarget * IrpTarget; - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->FastDeviceIoControl(IrpTarget, FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject); + // let IrpTarget handle request + return IrpTarget->FastDeviceIoControl(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject); } @@ -185,11 +185,11 @@ Dispatch_fnFastRead( { IIrpTarget * IrpTarget; - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->FastRead(IrpTarget, FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); + // let IrpTarget handle request + return IrpTarget->FastRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); } BOOLEAN @@ -206,10 +206,10 @@ Dispatch_fnFastWrite( { IIrpTarget * IrpTarget; - /* access IrpTarget */ + // access IrpTarget IrpTarget = (IIrpTarget *)FileObject->FsContext2; - /* let IrpTarget handle request */ - return IrpTarget->lpVtbl->FastWrite(IrpTarget, FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); + // let IrpTarget handle request + return IrpTarget->FastWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); } static KSDISPATCH_TABLE DispatchTable = @@ -239,7 +239,7 @@ NewDispatchObject( KSOBJECT_HEADER ObjectHeader; PIO_STACK_LOCATION IoStack; - /* get current irp stack location */ + // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack->FileObject->FsContext2 = (PVOID)Target; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dll.c b/reactos/drivers/wdm/audio/backpln/portcls/dll.cpp similarity index 66% rename from reactos/drivers/wdm/audio/backpln/portcls/dll.c rename to reactos/drivers/wdm/audio/backpln/portcls/dll.cpp index 0f47e365264..cd658a5c6e2 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/dll.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/dll.cpp @@ -1,17 +1,14 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/dll.c + * FILE: drivers/wdm/audio/backpln/portcls/dll.cpp * PURPOSE: portcls generic dispatcher * PROGRAMMER: Andrew Greenwood */ -#include "private.h" +#include "private.hpp" -/* - * @implemented - */ ULONG NTAPI DllInitialize(ULONG Unknown) @@ -19,12 +16,14 @@ DllInitialize(ULONG Unknown) return 0; } -/* - * @implemented - */ + +extern +"C" +{ ULONG NTAPI -DllUnload(VOID) +DllUnload() { return 0; } +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c deleted file mode 100644 index 2ae9ed669e3..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/dma_Init.c - * PURPOSE: portcls dma support object - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - - -typedef struct -{ - IDmaChannelInitVtbl *lpVtbl; - - LONG ref; - - - PDEVICE_OBJECT pDeviceObject; - PDMA_ADAPTER pAdapter; - - BOOL DmaStarted; - - ULONG MapSize; - PVOID MapRegisterBase; - - ULONG LastTransferCount; - - ULONG MaximumBufferSize; - ULONG MaxMapRegisters; - ULONG AllocatedBufferSize; - ULONG BufferSize; - - PHYSICAL_ADDRESS Address; - PVOID Buffer; - PMDL Mdl; - BOOLEAN WriteToDevice; - -}IDmaChannelInitImpl; - -//--------------------------------------------------------------- -// IUnknown methods -// - -extern GUID IID_IDmaChannelSlave; - -NTSTATUS -NTAPI -IDmaChannelInit_fnQueryInterface( - IDmaChannelInit * iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || - IsEqualGUIDAligned(refiid, &IID_IDmaChannel) || - IsEqualGUIDAligned(refiid, &IID_IDmaChannelSlave)) - { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - DPRINT1("No interface!!!\n"); - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IDmaChannelInit_fnAddRef( - IDmaChannelInit * iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_AddRef: This %p\n", This); - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IDmaChannelInit_fnRelease( - IDmaChannelInit* iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - InterlockedDecrement(&This->ref); - - DPRINT("IDmaChannelInit_Release: This %p new ref %u\n", This, This->ref); - - if (This->ref == 0) - { - This->pAdapter->DmaOperations->PutDmaAdapter(This->pAdapter); - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - -//--------------------------------------------------------------- -// IDmaChannel methods -// - -NTSTATUS -NTAPI -IDmaChannelInit_fnAllocateBuffer( - IN IDmaChannelInit * iface, - IN ULONG BufferSize, - IN PPHYSICAL_ADDRESS PhysicalAddressConstraint OPTIONAL) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - /* Did the caller already allocate a buffer ?*/ - if (This->Buffer) - { - DPRINT1("IDmaChannelInit_AllocateBuffer free common buffer first \n"); - return STATUS_UNSUCCESSFUL; - } - - This->Buffer = This->pAdapter->DmaOperations->AllocateCommonBuffer(This->pAdapter, BufferSize, &This->Address, FALSE); - if (!This->Buffer) - { - DPRINT1("IDmaChannelInit_AllocateBuffer fAllocateCommonBuffer failed \n"); - return STATUS_UNSUCCESSFUL; - } - - This->BufferSize = BufferSize; - This->AllocatedBufferSize = BufferSize; - DPRINT1("IDmaChannelInit_fnAllocateBuffer Success Buffer %p BufferSize %u Address %x\n", This->Buffer, BufferSize, This->Address); - - return STATUS_SUCCESS; -} - -ULONG -NTAPI -IDmaChannelInit_fnAllocatedBufferSize( - IN IDmaChannelInit * iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_AllocatedBufferSize: This %p BufferSize %u\n", This, This->BufferSize); - return This->AllocatedBufferSize; -} - -VOID -NTAPI -IDmaChannelInit_fnCopyFrom( - IN IDmaChannelInit * iface, - IN PVOID Destination, - IN PVOID Source, - IN ULONG ByteCount - ) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_CopyFrom: This %p Destination %p Source %p ByteCount %u\n", This, Destination, Source, ByteCount); - - iface->lpVtbl->CopyTo(iface, Destination, Source, ByteCount); -} - -VOID -NTAPI -IDmaChannelInit_fnCopyTo( - IN IDmaChannelInit * iface, - IN PVOID Destination, - IN PVOID Source, - IN ULONG ByteCount - ) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_CopyTo: This %p Destination %p Source %p ByteCount %u\n", This, Destination, Source, ByteCount); - RtlCopyMemory(Destination, Source, ByteCount); -} - -VOID -NTAPI -IDmaChannelInit_fnFreeBuffer( - IN IDmaChannelInit * iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_FreeBuffer: This %p\n", This); - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->Buffer) - { - DPRINT1("IDmaChannelInit_FreeBuffer allocate common buffer first \n"); - return; - } - - This->pAdapter->DmaOperations->FreeCommonBuffer(This->pAdapter, This->AllocatedBufferSize, This->Address, This->Buffer, FALSE); - This->Buffer = NULL; - This->AllocatedBufferSize = 0; - This->Address.QuadPart = 0LL; - - if (This->Mdl) - { - IoFreeMdl(This->Mdl); - This->Mdl = NULL; - } -} - -PADAPTER_OBJECT -NTAPI -IDmaChannelInit_fnGetAdapterObject( - IN IDmaChannelInit * iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_GetAdapterObject: This %p\n", This); - return (PADAPTER_OBJECT)This->pAdapter; -} - -ULONG -NTAPI -IDmaChannelInit_fnMaximumBufferSize( - IN IDmaChannelInit * iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_MaximumBufferSize: This %p\n", This); - return This->MaximumBufferSize; -} - -PHYSICAL_ADDRESS -NTAPI -IDmaChannelInit_fnPhysicalAdress( - IN IDmaChannelInit * iface, - PPHYSICAL_ADDRESS Address) -{ - PHYSICAL_ADDRESS Result; - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - DPRINT("IDmaChannelInit_PhysicalAdress: This %p Virtuell %p Physical High %x Low %x%\n", This, This->Buffer, This->Address.HighPart, This->Address.LowPart); - - Address->QuadPart = This->Address.QuadPart; - Result.QuadPart = (PtrToUlong(Address)); - return Result; -} - -VOID -NTAPI -IDmaChannelInit_fnSetBufferSize( - IN IDmaChannelInit * iface, - IN ULONG BufferSize) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_SetBufferSize: This %p\n", This); - This->BufferSize = BufferSize; - -} - -ULONG -NTAPI -IDmaChannelInit_fnBufferSize( - IN IDmaChannelInit * iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - return This->BufferSize; -} - - -PVOID -NTAPI -IDmaChannelInit_fnSystemAddress( - IN IDmaChannelInit * iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_SystemAddress: This %p\n", This); - return This->Buffer; -} - -ULONG -NTAPI -IDmaChannelInit_fnTransferCount( - IN IDmaChannelInit * iface) -{ - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_TransferCount: This %p\n", This); - return This->LastTransferCount; -} - -ULONG -NTAPI -IDmaChannelInit_fnReadCounter( - IN IDmaChannelInit * iface) -{ - ULONG Counter; - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - ASSERT_IRQL(DISPATCH_LEVEL); - - Counter = This->pAdapter->DmaOperations->ReadDmaCounter(This->pAdapter); - - if (!This->DmaStarted || Counter >= This->LastTransferCount) //FIXME - Counter = 0; - - return Counter; -} - -IO_ALLOCATION_ACTION -NTAPI -AdapterControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID MapRegisterBase, - IN PVOID Context) -{ - ULONG Length; - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)Context; - - Length = This->MapSize; - This->MapRegisterBase = MapRegisterBase; - - This->pAdapter->DmaOperations->MapTransfer(This->pAdapter, - This->Mdl, - MapRegisterBase, - (PVOID)((ULONG_PTR)This->Mdl->StartVa + This->Mdl->ByteOffset), - &Length, - This->WriteToDevice); - - if (Length == This->BufferSize) - { - This->DmaStarted = TRUE; - } - - return KeepObject; -} - -NTSTATUS -NTAPI -IDmaChannelInit_fnStart( - IN IDmaChannelInit * iface, - ULONG MapSize, - BOOLEAN WriteToDevice) -{ - NTSTATUS Status; - ULONG MapRegisters; - KIRQL OldIrql; - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_Start: This %p\n", This); - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->DmaStarted) - return STATUS_UNSUCCESSFUL; - - if (!This->Mdl) - { - This->Mdl = IoAllocateMdl(This->Buffer, This->MaximumBufferSize, FALSE, FALSE, NULL); - if (!This->Mdl) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - MmBuildMdlForNonPagedPool(This->Mdl); - } - - This->MapSize = MapSize; - This->WriteToDevice = WriteToDevice; - This->LastTransferCount = MapSize; - - //FIXME - // synchronize access - // - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - - MapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES(This->Buffer, MapSize); - Status = This->pAdapter->DmaOperations->AllocateAdapterChannel(This->pAdapter, This->pDeviceObject, MapRegisters, AdapterControl, (PVOID)This); - KeLowerIrql(OldIrql); - - if(!NT_SUCCESS(Status)) - This->LastTransferCount = 0; - - return Status; -} - -NTSTATUS -NTAPI -IDmaChannelInit_fnStop( - IN IDmaChannelInit * iface) -{ - KIRQL OldIrql; - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - DPRINT("IDmaChannelInit_fnStop: This %p\n", This); - ASSERT_IRQL(DISPATCH_LEVEL); - - if (!This->DmaStarted) - return STATUS_SUCCESS; - - This->pAdapter->DmaOperations->FlushAdapterBuffers(This->pAdapter, - This->Mdl, - This->MapRegisterBase, - (PVOID)((ULONG_PTR)This->Mdl->StartVa + This->Mdl->ByteOffset), - This->MapSize, - This->WriteToDevice); - - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - - This->pAdapter->DmaOperations->FreeAdapterChannel(This->pAdapter); - - KeLowerIrql(OldIrql); - - This->DmaStarted = FALSE; - - IoFreeMdl(This->Mdl); - This->Mdl = NULL; - - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -IDmaChannelInit_fnWaitForTC( - IN IDmaChannelInit * iface, - ULONG Timeout) -{ - ULONG RetryCount; - ULONG BytesRemaining; - ULONG PrevBytesRemaining; - - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - BytesRemaining = This->pAdapter->DmaOperations->ReadDmaCounter(This->pAdapter); - if (!BytesRemaining) - { - return STATUS_SUCCESS; - } - - RetryCount = Timeout / 10; - PrevBytesRemaining = 0xFFFFFFFF; - do - { - BytesRemaining = This->pAdapter->DmaOperations->ReadDmaCounter(This->pAdapter); - - if (!BytesRemaining) - break; - - if (PrevBytesRemaining == BytesRemaining) - break; - - KeStallExecutionProcessor(10); - PrevBytesRemaining = BytesRemaining; - - }while(RetryCount-- >= 1); - - if (BytesRemaining) - { - return STATUS_UNSUCCESSFUL; - } - - return STATUS_SUCCESS; - -} - -NTSTATUS -NTAPI -IDmaChannelInit_fnInit( - IN IDmaChannelInit * iface, - IN PDEVICE_DESCRIPTION DeviceDescription, - IN PDEVICE_OBJECT DeviceObject) -{ - INTERFACE_TYPE BusType; - NTSTATUS Status; - PDMA_ADAPTER Adapter; - PPCLASS_DEVICE_EXTENSION DeviceExt; - ULONG MapRegisters; - ULONG ResultLength; - IDmaChannelInitImpl * This = (IDmaChannelInitImpl*)iface; - - /* Get bus type */ - Status = IoGetDeviceProperty(DeviceObject, DevicePropertyLegacyBusType, sizeof(BusType), (PVOID)&BusType, &ResultLength); - if (NT_SUCCESS(Status)) - { - DeviceDescription->InterfaceType = BusType; - } - /* Fetch device extension */ - DeviceExt = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; - /* Acquire dma adapter */ - Adapter = IoGetDmaAdapter(DeviceExt->PhysicalDeviceObject, DeviceDescription, &MapRegisters); - if (!Adapter) - { - FreeItem(This, TAG_PORTCLASS); - return STATUS_DEVICE_CONFIGURATION_ERROR; - } - - /* initialize object */ - This->ref = 1; - This->pAdapter = Adapter; - This->pDeviceObject = DeviceObject; - This->MaximumBufferSize = DeviceDescription->MaximumLength; - This->MaxMapRegisters = MapRegisters; - - return STATUS_SUCCESS; -} - - -IDmaChannelInitVtbl vt_IDmaChannelInitVtbl = -{ - /* IUnknown methods */ - IDmaChannelInit_fnQueryInterface, - IDmaChannelInit_fnAddRef, - IDmaChannelInit_fnRelease, - /* IDmaChannel methods */ - IDmaChannelInit_fnAllocateBuffer, - IDmaChannelInit_fnFreeBuffer, - IDmaChannelInit_fnTransferCount, - IDmaChannelInit_fnMaximumBufferSize, - IDmaChannelInit_fnAllocatedBufferSize, - IDmaChannelInit_fnBufferSize, - IDmaChannelInit_fnSetBufferSize, - IDmaChannelInit_fnSystemAddress, - IDmaChannelInit_fnPhysicalAdress, - IDmaChannelInit_fnGetAdapterObject, - IDmaChannelInit_fnCopyTo, - IDmaChannelInit_fnCopyFrom, - /* IDmaChannelSlave methods */ - IDmaChannelInit_fnStart, - IDmaChannelInit_fnStop, - IDmaChannelInit_fnReadCounter, - IDmaChannelInit_fnWaitForTC, - /* IDmaChannelInit methods */ - IDmaChannelInit_fnInit -}; - - -/* - * @unimplemented - */ -NTSTATUS NTAPI -PcNewDmaChannel( - OUT PDMACHANNEL* OutDmaChannel, - IN PUNKNOWN OuterUnknown OPTIONAL, - IN POOL_TYPE PoolType, - IN PDEVICE_DESCRIPTION DeviceDescription, - IN PDEVICE_OBJECT DeviceObject) -{ - NTSTATUS Status; - IDmaChannelInitImpl * This; - - DPRINT("OutDmaChannel %p OuterUnknown %p PoolType %p DeviceDescription %p DeviceObject %p\n", - OutDmaChannel, OuterUnknown, PoolType, DeviceDescription, DeviceObject); - - This = AllocateItem(PoolType, sizeof(IDmaChannelInitImpl), TAG_PORTCLASS); - if (!This) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* initialize object */ - Status = IDmaChannelInit_fnInit((IDmaChannelInit*)This, DeviceDescription, DeviceObject); - if (NT_SUCCESS(Status)) - { - /* store result */ - This->lpVtbl = &vt_IDmaChannelInitVtbl; - *OutDmaChannel = (PVOID)(&This->lpVtbl); - } - - return Status; - -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp new file mode 100644 index 00000000000..7c8202a2ac6 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp @@ -0,0 +1,481 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/dma_init.c + * PURPOSE: portcls dma support object + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CDmaChannelInit : public IDmaChannelInit +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IDmaChannelInit; + CDmaChannelInit(IUnknown * OuterUnknown){} + virtual ~CDmaChannelInit(){} + +protected: + + PDEVICE_OBJECT m_pDeviceObject; + PDMA_ADAPTER m_pAdapter; + + BOOL m_DmaStarted; + + ULONG m_MapSize; + PVOID m_MapRegisterBase; + + ULONG m_LastTransferCount; + + ULONG m_MaximumBufferSize; + ULONG m_MaxMapRegisters; + ULONG m_AllocatedBufferSize; + ULONG m_BufferSize; + + PHYSICAL_ADDRESS m_Address; + PVOID m_Buffer; + PMDL m_Mdl; + BOOLEAN m_WriteToDevice; + + friend IO_ALLOCATION_ACTION NTAPI AdapterControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context); + + LONG m_Ref; +}; + + + +//--------------------------------------------------------------- +// IUnknown methods +// + +extern GUID IID_IDmaChannelSlave; + +NTSTATUS +NTAPI +CDmaChannelInit::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + if (IsEqualGUIDAligned(refiid, IID_IUnknown) || + IsEqualGUIDAligned(refiid, IID_IDmaChannel)) + //IsEqualGUIDAligned(refiid, IID_IDmaChannelSlave)) // HACK + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + DPRINT1("No interface!!!\n"); + return STATUS_UNSUCCESSFUL; +} + +//--------------------------------------------------------------- +// IDmaChannel methods +// + +NTSTATUS +NTAPI +CDmaChannelInit::AllocateBuffer( + IN ULONG BufferSize, + IN PPHYSICAL_ADDRESS PhysicalAddressConstraint OPTIONAL) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + // Did the caller already allocate a buffer ?*/ + if (m_Buffer) + { + DPRINT1("CDmaChannelInit_AllocateBuffer free common buffer first \n"); + return STATUS_UNSUCCESSFUL; + } + + m_Buffer = m_pAdapter->DmaOperations->AllocateCommonBuffer(m_pAdapter, BufferSize, &m_Address, FALSE); + if (!m_Buffer) + { + DPRINT1("CDmaChannelInit_AllocateBuffer fAllocateCommonBuffer failed \n"); + return STATUS_UNSUCCESSFUL; + } + + m_BufferSize = BufferSize; + m_AllocatedBufferSize = BufferSize; + DPRINT1("CDmaChannelInit::AllocateBuffer Success Buffer %p BufferSize %u Address %x\n", m_Buffer, BufferSize, m_Address); + + return STATUS_SUCCESS; +} + +ULONG +NTAPI +CDmaChannelInit::AllocatedBufferSize() +{ + DPRINT("CDmaChannelInit_AllocatedBufferSize: this %p BufferSize %u\n", this, m_BufferSize); + return m_AllocatedBufferSize; +} + +VOID +NTAPI +CDmaChannelInit::CopyFrom( + IN PVOID Destination, + IN PVOID Source, + IN ULONG ByteCount + ) +{ + DPRINT("CDmaChannelInit_CopyFrom: this %p Destination %p Source %p ByteCount %u\n", this, Destination, Source, ByteCount); + + CopyTo(Destination, Source, ByteCount); +} + +VOID +NTAPI +CDmaChannelInit::CopyTo( + IN PVOID Destination, + IN PVOID Source, + IN ULONG ByteCount + ) +{ + DPRINT("CDmaChannelInit_CopyTo: this %p Destination %p Source %p ByteCount %u\n", this, Destination, Source, ByteCount); + RtlCopyMemory(Destination, Source, ByteCount); +} + +VOID +NTAPI +CDmaChannelInit::FreeBuffer() +{ + DPRINT("CDmaChannelInit_FreeBuffer: this %p\n", this); + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_Buffer) + { + DPRINT1("CDmaChannelInit_FreeBuffer allocate common buffer first \n"); + return; + } + + m_pAdapter->DmaOperations->FreeCommonBuffer(m_pAdapter, m_AllocatedBufferSize, m_Address, m_Buffer, FALSE); + m_Buffer = NULL; + m_AllocatedBufferSize = 0; + m_Address.QuadPart = 0LL; + + if (m_Mdl) + { + IoFreeMdl(m_Mdl); + m_Mdl = NULL; + } +} + +PADAPTER_OBJECT +NTAPI +CDmaChannelInit::GetAdapterObject() +{ + DPRINT("CDmaChannelInit_GetAdapterObject: this %p\n", this); + return (PADAPTER_OBJECT)m_pAdapter; +} + +ULONG +NTAPI +CDmaChannelInit::MaximumBufferSize() +{ + DPRINT("CDmaChannelInit_MaximumBufferSize: this %p\n", this); + return m_MaximumBufferSize; +} + +PHYSICAL_ADDRESS +NTAPI +CDmaChannelInit::PhysicalAddress() +{ + DPRINT("CDmaChannelInit_PhysicalAdress: this %p Virtuell %p Physical High %x Low %x%\n", this, m_Buffer, m_Address.HighPart, m_Address.LowPart); + + return m_Address; +} + +VOID +NTAPI +CDmaChannelInit::SetBufferSize( + IN ULONG BufferSize) +{ + DPRINT("CDmaChannelInit_SetBufferSize: this %p\n", this); + m_BufferSize = BufferSize; + +} + +ULONG +NTAPI +CDmaChannelInit::BufferSize() +{ + return m_BufferSize; +} + + +PVOID +NTAPI +CDmaChannelInit::SystemAddress() +{ + DPRINT("CDmaChannelInit_SystemAddress: this %p\n", this); + return m_Buffer; +} + +ULONG +NTAPI +CDmaChannelInit::TransferCount() +{ + DPRINT("CDmaChannelInit_TransferCount: this %p\n", this); + return m_LastTransferCount; +} + +ULONG +NTAPI +CDmaChannelInit::ReadCounter() +{ + ULONG Counter; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + Counter = m_pAdapter->DmaOperations->ReadDmaCounter(m_pAdapter); + + if (!m_DmaStarted || Counter >= m_LastTransferCount) + Counter = 0; + + return Counter; +} + +IO_ALLOCATION_ACTION +NTAPI +AdapterControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID MapRegisterBase, + IN PVOID Context) +{ + ULONG Length; + CDmaChannelInit * This = (CDmaChannelInit*)Context; + + Length = This->m_MapSize; + This->m_MapRegisterBase = MapRegisterBase; + + This->m_pAdapter->DmaOperations->MapTransfer(This->m_pAdapter, + This->m_Mdl, + MapRegisterBase, + (PVOID)((ULONG_PTR)This->m_Mdl->StartVa + This->m_Mdl->ByteOffset), + &Length, + This->m_WriteToDevice); + + if (Length == This->m_BufferSize) + { + This->m_DmaStarted = TRUE; + } + + return KeepObject; +} + +NTSTATUS +NTAPI +CDmaChannelInit::Start( + ULONG MapSize, + BOOLEAN WriteToDevice) +{ + NTSTATUS Status; + ULONG MapRegisters; + KIRQL OldIrql; + + DPRINT("CDmaChannelInit_Start: this %p\n", this); + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_DmaStarted) + return STATUS_UNSUCCESSFUL; + + if (!m_Mdl) + { + m_Mdl = IoAllocateMdl(m_Buffer, m_MaximumBufferSize, FALSE, FALSE, NULL); + if (!m_Mdl) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + MmBuildMdlForNonPagedPool(m_Mdl); + } + + m_MapSize = MapSize; + m_WriteToDevice = WriteToDevice; + m_LastTransferCount = MapSize; + + //FIXME + // synchronize access + // + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + + MapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES(m_Buffer, MapSize); + Status = m_pAdapter->DmaOperations->AllocateAdapterChannel(m_pAdapter, m_pDeviceObject, MapRegisters, AdapterControl, (PVOID)this); + KeLowerIrql(OldIrql); + + if(!NT_SUCCESS(Status)) + m_LastTransferCount = 0; + + return Status; +} + +NTSTATUS +NTAPI +CDmaChannelInit::Stop() +{ + KIRQL OldIrql; + + DPRINT("CDmaChannelInit::Stop: this %p\n", this); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + if (!m_DmaStarted) + return STATUS_SUCCESS; + + m_pAdapter->DmaOperations->FlushAdapterBuffers(m_pAdapter, + m_Mdl, + m_MapRegisterBase, + (PVOID)((ULONG_PTR)m_Mdl->StartVa + m_Mdl->ByteOffset), + m_MapSize, + m_WriteToDevice); + + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + + m_pAdapter->DmaOperations->FreeAdapterChannel(m_pAdapter); + + KeLowerIrql(OldIrql); + + m_DmaStarted = FALSE; + + IoFreeMdl(m_Mdl); + m_Mdl = NULL; + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CDmaChannelInit::WaitForTC( + ULONG Timeout) +{ + ULONG RetryCount; + ULONG BytesRemaining; + ULONG PrevBytesRemaining; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + BytesRemaining = m_pAdapter->DmaOperations->ReadDmaCounter(m_pAdapter); + if (!BytesRemaining) + { + return STATUS_SUCCESS; + } + + RetryCount = Timeout / 10; + PrevBytesRemaining = 0xFFFFFFFF; + do + { + BytesRemaining = m_pAdapter->DmaOperations->ReadDmaCounter(m_pAdapter); + + if (!BytesRemaining) + break; + + if (PrevBytesRemaining == BytesRemaining) + break; + + KeStallExecutionProcessor(10); + PrevBytesRemaining = BytesRemaining; + + }while(RetryCount-- >= 1); + + if (BytesRemaining) + { + return STATUS_UNSUCCESSFUL; + } + + return STATUS_SUCCESS; + +} + +NTSTATUS +NTAPI +CDmaChannelInit::Init( + IN PDEVICE_DESCRIPTION DeviceDescription, + IN PDEVICE_OBJECT DeviceObject) +{ + INTERFACE_TYPE BusType; + NTSTATUS Status; + PDMA_ADAPTER Adapter; + PPCLASS_DEVICE_EXTENSION DeviceExt; + ULONG MapRegisters; + ULONG ResultLength; + + // Get bus type + Status = IoGetDeviceProperty(DeviceObject, DevicePropertyLegacyBusType, sizeof(BusType), (PVOID)&BusType, &ResultLength); + if (NT_SUCCESS(Status)) + { + DeviceDescription->InterfaceType = BusType; + } + // Fetch device extension + DeviceExt = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; + // Acquire dma adapter + Adapter = IoGetDmaAdapter(DeviceExt->PhysicalDeviceObject, DeviceDescription, &MapRegisters); + if (!Adapter) + { + FreeItem(this, TAG_PORTCLASS); + return STATUS_DEVICE_CONFIGURATION_ERROR; + } + + // initialize object + m_pAdapter = Adapter; + m_pDeviceObject = DeviceObject; + m_MaximumBufferSize = DeviceDescription->MaximumLength; + m_MaxMapRegisters = MapRegisters; + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PcNewDmaChannel( + OUT PDMACHANNEL* OutDmaChannel, + IN PUNKNOWN OuterUnknown OPTIONAL, + IN POOL_TYPE PoolType, + IN PDEVICE_DESCRIPTION DeviceDescription, + IN PDEVICE_OBJECT DeviceObject) +{ + NTSTATUS Status; + CDmaChannelInit * This; + + DPRINT("OutDmaChannel %p OuterUnknown %p PoolType %p DeviceDescription %p DeviceObject %p\n", + OutDmaChannel, OuterUnknown, PoolType, DeviceDescription, DeviceObject); + + This = new(PoolType, TAG_PORTCLASS)CDmaChannelInit(OuterUnknown); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = This->QueryInterface(IID_IDmaChannel, (PVOID*)OutDmaChannel); + + if (!NT_SUCCESS(Status)) + { + delete This; + return Status; + } + + Status = This->Init(DeviceDescription, DeviceObject); + + if (!NT_SUCCESS(Status)) + { + delete This; + return Status; + } + + return Status; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/drm.c b/reactos/drivers/wdm/audio/backpln/portcls/drm.cpp similarity index 75% rename from reactos/drivers/wdm/audio/backpln/portcls/drm.c rename to reactos/drivers/wdm/audio/backpln/portcls/drm.cpp index 952e7398597..a6e6e358cea 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/drm.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/drm.cpp @@ -1,16 +1,14 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/drm.c + * FILE: drivers/wdm/audio/backpln/portcls/drm.cpp * PURPOSE: portcls drm functions * PROGRAMMER: Andrew Greenwood */ -#include "private.h" +#include "private.hpp" + -/* - * @implemented - */ NTSTATUS NTAPI PcAddContentHandlers( @@ -18,13 +16,10 @@ PcAddContentHandlers( IN PVOID *paHandlers, IN ULONG NumHandlers) { - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); return DrmAddContentHandlers(ContentId, paHandlers, NumHandlers); } -/* - * @implemented - */ NTSTATUS NTAPI PcCreateContentMixed( @@ -32,25 +27,19 @@ PcCreateContentMixed( IN ULONG cContentId, OUT PULONG pMixedContentId) { - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); return DrmCreateContentMixed(paContentId, cContentId, pMixedContentId); } -/* - * @implemented - */ NTSTATUS NTAPI PcDestroyContent( IN ULONG ContentId) { - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); return DrmDestroyContent(ContentId); } -/* - * @implemented - */ NTSTATUS NTAPI PcForwardContentToDeviceObject( @@ -58,26 +47,20 @@ PcForwardContentToDeviceObject( IN PVOID Reserved, IN PCDRMFORWARD DrmForward) { - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); return DrmForwardContentToDeviceObject(ContentId, Reserved, DrmForward); } -/* - * @implemented - */ NTSTATUS NTAPI PcForwardContentToFileObject( IN ULONG ContentId, IN PFILE_OBJECT FileObject) { - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); return DrmForwardContentToFileObject(ContentId, FileObject); } -/* - * @implemented - */ NTSTATUS NTAPI PcForwardContentToInterface( @@ -88,15 +71,12 @@ PcForwardContentToInterface( return DrmForwardContentToInterface(ContentId, pUnknown, NumMethods); } -/* - * @implemented - */ NTSTATUS NTAPI PcGetContentRights( IN ULONG ContentId, OUT PDRMRIGHTS DrmRights) { - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); return DrmGetContentRights(ContentId, DrmRights); } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/drm_port.c b/reactos/drivers/wdm/audio/backpln/portcls/drm_port.c deleted file mode 100644 index 0870dd7f143..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/drm_port.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/drm_port.c - * PURPOSE: portcls drm port object - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IDrmPort2Vtbl *lpVtbl; - LONG ref; -}IDrmPort2Impl; - -ULONG -NTAPI -IDrmPort2_fnAddRef( - IN IDrmPort2* iface) -{ - IDrmPort2Impl * This = (IDrmPort2Impl*)iface; - - DPRINT("IDrmPort2_AddRef: This %p\n", This); - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IDrmPort2_fnRelease( - IN IDrmPort2* iface) -{ - IDrmPort2Impl * This = (IDrmPort2Impl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - -NTSTATUS -NTAPI -IDrmPort2_fnQueryInterface( - IN IDrmPort2* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - UNICODE_STRING GuidString; - IDrmPort2Impl * This = (IDrmPort2Impl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IDrmPort) || - IsEqualGUIDAligned(refiid, &IID_IDrmPort2) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = (PVOID)&This->lpVtbl; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - - if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) - { - DPRINT1("IDrmPort2_QueryInterface no interface!!! iface %S\n", GuidString.Buffer); - RtlFreeUnicodeString(&GuidString); - } - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -IDrmPort2_fnCreateContentMixed( - IN IDrmPort2 * iface, - IN PULONG paContentId, - IN ULONG cContentId, - OUT PULONG pMixedContentId) -{ - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - return DrmCreateContentMixed(paContentId, cContentId, pMixedContentId); -} - -NTSTATUS -NTAPI -IDrmPort2_fnDestroyContent( - IN IDrmPort2 * iface, - IN ULONG ContentId) -{ - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - return DrmDestroyContent(ContentId); -} - -NTSTATUS -NTAPI -IDrmPort2_fnForwardContentToFileObject( - IN IDrmPort2 * iface, - IN ULONG ContentId, - IN PFILE_OBJECT FileObject) -{ - return DrmForwardContentToFileObject(ContentId, FileObject); -} - -NTSTATUS -NTAPI -IDrmPort2_fnForwardContentToInterface( - IN IDrmPort2 * iface, - IN ULONG ContentId, - IN PUNKNOWN pUnknown, - IN ULONG NumMethods) -{ - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - return DrmForwardContentToInterface(ContentId, pUnknown, NumMethods); -} - -NTSTATUS -NTAPI -IDrmPort2_fnGetContentRights( - IN IDrmPort2 * iface, - IN ULONG ContentId, - OUT PDRMRIGHTS DrmRights) -{ - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - return DrmGetContentRights(ContentId, DrmRights); -} - -NTSTATUS -NTAPI -IDrmPort2_fnAddContentHandlers( - IN IDrmPort2 * iface, - IN ULONG ContentId, - IN PVOID * paHandlers, - IN ULONG NumHandlers) -{ - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - return DrmAddContentHandlers(ContentId, paHandlers, NumHandlers); -} - -NTSTATUS -NTAPI -IDrmPort2_fnForwardContentToDeviceObject( - IN IDrmPort2 * iface, - IN ULONG ContentId, - IN PVOID Reserved, - IN PCDRMFORWARD DrmForward) -{ - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - return DrmForwardContentToDeviceObject(ContentId, Reserved, DrmForward); -} - -static IDrmPort2Vtbl vt_IDrmPort2 = -{ - /* IUnknown methods */ - IDrmPort2_fnQueryInterface, - IDrmPort2_fnAddRef, - IDrmPort2_fnRelease, - IDrmPort2_fnCreateContentMixed, - IDrmPort2_fnDestroyContent, - IDrmPort2_fnForwardContentToFileObject, - IDrmPort2_fnForwardContentToInterface, - IDrmPort2_fnGetContentRights, - IDrmPort2_fnAddContentHandlers, - IDrmPort2_fnForwardContentToDeviceObject -}; - -NTSTATUS -NewIDrmPort( - OUT PDRMPORT2 *OutPort) -{ - IDrmPort2Impl * This = AllocateItem(NonPagedPool, sizeof(IDrmPort2Impl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - This->lpVtbl = &vt_IDrmPort2; - This->ref = 1; - - *OutPort = (PDRMPORT2)&This->lpVtbl; - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/drm_port.cpp b/reactos/drivers/wdm/audio/backpln/portcls/drm_port.cpp new file mode 100644 index 00000000000..fd5f50e9c3b --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/drm_port.cpp @@ -0,0 +1,152 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/drm_port.cpp + * PURPOSE: portcls drm port object + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CDrmPort2 : public IDrmPort2 +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IDrmPort2; + CDrmPort2(IUnknown *OuterUnknown){} + virtual ~CDrmPort2(){} + +protected: + LONG m_Ref; + +}; + +NTSTATUS +NTAPI +CDrmPort2::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + UNICODE_STRING GuidString; + + if (IsEqualGUIDAligned(refiid, IID_IDrmPort) || + IsEqualGUIDAligned(refiid, IID_IDrmPort2) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) + { + DPRINT1("IDrmPort2_QueryInterface no interface!!! iface %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + } + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CDrmPort2::CreateContentMixed( + IN PULONG paContentId, + IN ULONG cContentId, + OUT PULONG pMixedContentId) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + return DrmCreateContentMixed(paContentId, cContentId, pMixedContentId); +} + +NTSTATUS +NTAPI +CDrmPort2::DestroyContent( + IN ULONG ContentId) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + return DrmDestroyContent(ContentId); +} + +NTSTATUS +NTAPI +CDrmPort2::ForwardContentToFileObject( + IN ULONG ContentId, + IN PFILE_OBJECT FileObject) +{ + return DrmForwardContentToFileObject(ContentId, FileObject); +} + +NTSTATUS +NTAPI +CDrmPort2::ForwardContentToInterface( + IN ULONG ContentId, + IN PUNKNOWN pUnknown, + IN ULONG NumMethods) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + return DrmForwardContentToInterface(ContentId, pUnknown, NumMethods); +} + +NTSTATUS +NTAPI +CDrmPort2::GetContentRights( + IN ULONG ContentId, + OUT PDRMRIGHTS DrmRights) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + return DrmGetContentRights(ContentId, DrmRights); +} + +NTSTATUS +NTAPI +CDrmPort2::AddContentHandlers( + IN ULONG ContentId, + IN PVOID * paHandlers, + IN ULONG NumHandlers) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + return DrmAddContentHandlers(ContentId, paHandlers, NumHandlers); +} + +NTSTATUS +NTAPI +CDrmPort2::ForwardContentToDeviceObject( + IN ULONG ContentId, + IN PVOID Reserved, + IN PCDRMFORWARD DrmForward) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + return DrmForwardContentToDeviceObject(ContentId, Reserved, DrmForward); +} + +NTSTATUS +NewIDrmPort( + OUT PDRMPORT2 *OutPort) +{ + CDrmPort2 * This = new(NonPagedPool, TAG_PORTCLASS)CDrmPort2(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + *OutPort = (PDRMPORT2)This; + return STATUS_SUCCESS; +} + + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c deleted file mode 100644 index dd0ebaa7615..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * 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; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.cpp b/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.cpp new file mode 100644 index 00000000000..2e6fae7add9 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_dmus.cpp @@ -0,0 +1,332 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/filter_dmus.cpp + * PURPOSE: portcls wave pci filter + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortFilterDMus : public IPortFilterDMus +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortFilterDMus; + CPortFilterDMus(IUnknown *OuterUnknown){} + virtual ~CPortFilterDMus(){} + +protected: + IPortDMus* m_Port; + IPortPinDMus ** m_Pins; + SUBDEVICE_DESCRIPTOR * m_Descriptor; + LONG m_Ref; +}; + +NTSTATUS +NTAPI +CPortFilterDMus::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPort)) + { + *Output = PUNKNOWN(m_Port); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortFilterDMus::NewIrpTarget( + 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; + + PC_ASSERT(m_Port); + PC_ASSERT(m_Descriptor); + PC_ASSERT(m_Pins); + + DPRINT("CPortFilterDMus::NewIrpTarget entered\n"); + + // let's verify the connection request + Status = PcValidateConnectRequest(Irp, &m_Descriptor->Factory, &ConnectDetails); + if (!NT_SUCCESS(Status)) + { + return STATUS_UNSUCCESSFUL; + } + + if (m_Pins[ConnectDetails->PinId] && m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount) + { + // release existing instance + PC_ASSERT(0); + } + + // now create the pin + Status = NewPortPinDMus(&Pin); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + // initialize the pin + Status = Pin->Init(m_Port, this, ConnectDetails, &m_Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], DeviceObject); + if (!NT_SUCCESS(Status)) + { + Pin->Release(); + return Status; + } + + // store pin + m_Pins[ConnectDetails->PinId] = Pin; + + // store result + *OutTarget = (IIrpTarget*)Pin; + + // increment current instance count + m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++; + + return Status; +} + +NTSTATUS +NTAPI +CPortFilterDMus::DeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return PcPropertyHandler(Irp, m_Descriptor); +} + +NTSTATUS +NTAPI +CPortFilterDMus::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterDMus::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterDMus::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterDMus::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortFilterDMus::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterDMus::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortFilterDMus::FastDeviceIoControl( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortFilterDMus::FastRead( + 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; +} + +BOOLEAN +NTAPI +CPortFilterDMus::FastWrite( + 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; +} + +NTSTATUS +NTAPI +CPortFilterDMus::Init( + IN IPortDMus* Port) +{ + ISubdevice * ISubDevice; + NTSTATUS Status; + + m_Port = Port; + + // get our private interface + Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // get the subdevice descriptor + Status = ISubDevice->GetDescriptor(&m_Descriptor); + + // release subdevice interface + ISubDevice->Release(); + + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // allocate pin array + m_Pins = (IPortPinDMus**)AllocateItem(NonPagedPool, m_Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinDMus*), TAG_PORTCLASS); + + if (!m_Pins) + return STATUS_UNSUCCESSFUL; + + // increment reference count + Port->AddRef(); + + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortFilterDMus::FreePin( + IN struct IPortPinDMus* Pin) +{ + ULONG Index; + + for(Index = 0; Index < m_Descriptor->Factory.PinDescriptorCount; Index++) + { + if (m_Pins[Index] == Pin) + { + m_Pins[Index]->Release(); + m_Pins[Index] = NULL; + return STATUS_SUCCESS; + } + } + return STATUS_UNSUCCESSFUL; +} + +VOID +NTAPI +CPortFilterDMus::NotifyPins() +{ + ULONG Index; + + DPRINT("Notifying %u pins\n", m_Descriptor->Factory.PinDescriptorCount); + + for(Index = 0; Index < m_Descriptor->Factory.PinDescriptorCount; Index++) + { + m_Pins[Index]->Notify(); + } +} + + +NTSTATUS +NewPortFilterDMus( + OUT PPORTFILTERDMUS * OutFilter) +{ + CPortFilterDMus * This; + + This = new(NonPagedPool, TAG_PORTCLASS) CPortFilterDMus(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // return result + *OutFilter = (CPortFilterDMus*)This; + + return STATUS_SUCCESS; +} + + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c deleted file mode 100644 index c2b34921060..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/filter_topology.c - * PURPOSE: portcls topology filter - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IPortFilterTopologyVtbl *lpVtbl; - - LONG ref; - - IPortTopology* Port; - SUBDEVICE_DESCRIPTOR * Descriptor; - ISubdevice *SubDevice; - -}IPortFilterTopologyImpl; - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnQueryInterface( - IPortFilterTopology* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)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 -IPortFilterTopology_fnAddRef( - IPortFilterTopology* iface) -{ - IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -/* - * @implemented - */ -ULONG -NTAPI -IPortFilterTopology_fnRelease( - IPortFilterTopology* iface) -{ - IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - return This->ref; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnNewIrpTarget( - IN IPortFilterTopology* 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) -{ - DPRINT("IPortFilterTopology_fnNewIrpTarget entered\n"); - - return STATUS_NOT_SUPPORTED; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnDeviceIoControl( - IN IPortFilterTopology* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface; - - IoStack = IoGetCurrentIrpStackLocation(Irp); - ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); - - return PcPropertyHandler(Irp, This->Descriptor); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnRead( - IN IPortFilterTopology* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnWrite( - IN IPortFilterTopology* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnFlush( - IN IPortFilterTopology* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnClose( - IN IPortFilterTopology* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - NTSTATUS Status = STATUS_SUCCESS; - IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface; - - /* FIXME handle DirectSound */ - - if (This->ref == 1) - { - /* release reference to port */ - This->SubDevice->lpVtbl->Release(This->SubDevice); - - /* time to shutdown the audio system */ - Status = This->SubDevice->lpVtbl->ReleaseChildren(This->SubDevice); - } - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnQuerySecurity( - IN IPortFilterTopology* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterTopology_fnSetSecurity( - IN IPortFilterTopology* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortFilterTopology_fnFastDeviceIoControl( - IN IPortFilterTopology* 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; - IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; - - Property = (PKSPROPERTY)InputBuffer; - - if (InputBufferLength < sizeof(KSPROPERTY)) - return FALSE; - - for(Index = 0; Index < This->Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++) - { - if (IsEqualGUIDAligned(&Property->Set, This->Descriptor->FilterPropertySet.Properties[Index].Set)) - { - FastPropertyHandler(FileObject, (PKSPROPERTY)InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock, - 1, - &This->Descriptor->FilterPropertySet.Properties[Index], - This->Descriptor, This->SubDevice); - } - } - return TRUE; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortFilterTopology_fnFastRead( - IN IPortFilterTopology* 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) -{ - return FALSE; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortFilterTopology_fnFastWrite( - IN IPortFilterTopology* 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) -{ - return FALSE; -} - -/* - * @implemented - */ -static -NTSTATUS -NTAPI -IPortFilterTopology_fnInit( - IN IPortFilterTopology* iface, - IN IPortTopology* Port) -{ - ISubdevice * ISubDevice; - SUBDEVICE_DESCRIPTOR * Descriptor; - NTSTATUS Status; - IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface; - - /* get our private interface */ - Status = Port->lpVtbl->QueryInterface(Port, &IID_ISubdevice, (PVOID*)&ISubDevice); - if (!NT_SUCCESS(Status)) - return STATUS_UNSUCCESSFUL; - - /* get the subdevice descriptor */ - Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor); - - /* store subdevice interface */ - This->SubDevice = ISubDevice; - - if (!NT_SUCCESS(Status)) - return STATUS_UNSUCCESSFUL; - - /* save descriptor */ - This->Descriptor = Descriptor; - - /* store port object */ - This->Port = Port; - - return STATUS_SUCCESS; -} - -static IPortFilterTopologyVtbl vt_IPortFilterTopology = -{ - IPortFilterTopology_fnQueryInterface, - IPortFilterTopology_fnAddRef, - IPortFilterTopology_fnRelease, - IPortFilterTopology_fnNewIrpTarget, - IPortFilterTopology_fnDeviceIoControl, - IPortFilterTopology_fnRead, - IPortFilterTopology_fnWrite, - IPortFilterTopology_fnFlush, - IPortFilterTopology_fnClose, - IPortFilterTopology_fnQuerySecurity, - IPortFilterTopology_fnSetSecurity, - IPortFilterTopology_fnFastDeviceIoControl, - IPortFilterTopology_fnFastRead, - IPortFilterTopology_fnFastWrite, - IPortFilterTopology_fnInit -}; - -NTSTATUS -NewPortFilterTopology( - OUT IPortFilterTopology ** OutFilter) -{ - IPortFilterTopologyImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IPortFilterTopologyImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - /* initialize IPortFilterTopology */ - This->ref = 1; - This->lpVtbl = &vt_IPortFilterTopology; - - /* return result */ - *OutFilter = (IPortFilterTopology*)&This->lpVtbl; - - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.cpp b/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.cpp new file mode 100644 index 00000000000..4be94fa1e4d --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.cpp @@ -0,0 +1,268 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/filter_topology.c + * PURPOSE: portcls topology filter + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortFilterTopology : public IPortFilterTopology +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortFilterTopology; + CPortFilterTopology(IUnknown *OuterUnknown){} + virtual ~CPortFilterTopology(){} + +protected: + IPortTopology * m_Port; + SUBDEVICE_DESCRIPTOR * m_Descriptor; + ISubdevice * m_SubDevice; + LONG m_Ref; +}; + + +NTSTATUS +NTAPI +CPortFilterTopology::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPort)) + { + *Output = PVOID(PUNKNOWN(m_Port)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortFilterTopology::NewIrpTarget( + 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) +{ + DPRINT("CPortFilterTopology::NewIrpTarget entered\n"); + + return STATUS_NOT_SUPPORTED; +} + + +NTSTATUS +NTAPI +CPortFilterTopology::DeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + PC_ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); + + return PcPropertyHandler(Irp, m_Descriptor); +} + +NTSTATUS +NTAPI +CPortFilterTopology::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterTopology::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterTopology::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterTopology::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + NTSTATUS Status = STATUS_SUCCESS; + + // FIXME handle DirectSound + +#if 0 +//FIXME + if (m_ref == 1) + { + // release reference to port + This->SubDevice->lpVtbl->Release(This->SubDevice); + + // time to shutdown the audio system + Status = This->SubDevice->lpVtbl->ReleaseChildren(This->SubDevice); + } +#endif + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortFilterTopology::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterTopology::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortFilterTopology::FastDeviceIoControl( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortFilterTopology::FastRead( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortFilterTopology::FastWrite( + 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) +{ + return FALSE; +} + +NTSTATUS +NTAPI +CPortFilterTopology::Init( + IN IPortTopology* Port) +{ + ISubdevice * ISubDevice; + SUBDEVICE_DESCRIPTOR * Descriptor; + NTSTATUS Status; + + + // get our private interface + Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // get the subdevice descriptor + Status = ISubDevice->GetDescriptor(&Descriptor); + + // store subdevice interface + m_SubDevice = ISubDevice; + + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // save descriptor + m_Descriptor = Descriptor; + + // store port object + m_Port = Port; + + return STATUS_SUCCESS; +} + +NTSTATUS +NewPortFilterTopology( + OUT IPortFilterTopology ** OutFilter) +{ + CPortFilterTopology * This; + + This = new(NonPagedPool, TAG_PORTCLASS)CPortFilterTopology(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // return result + *OutFilter = (CPortFilterTopology*)This; + + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c deleted file mode 100644 index b1f051e855b..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c - * PURPOSE: portcls wave cyclic filter - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IPortFilterWaveCyclicVtbl *lpVtbl; - - LONG ref; - - IPortWaveCyclic* Port; - IPortPinWaveCyclic ** Pins; - SUBDEVICE_DESCRIPTOR * Descriptor; - ISubdevice * SubDevice; - -}IPortFilterWaveCyclicImpl; - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnQueryInterface( - IPortFilterWaveCyclic* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)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 -IPortFilterWaveCyclic_fnAddRef( - IPortFilterWaveCyclic* iface) -{ - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -/* - * @implemented - */ -ULONG -NTAPI -IPortFilterWaveCyclic_fnRelease( - IPortFilterWaveCyclic* iface) -{ - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - return This->ref; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnNewIrpTarget( - IN IPortFilterWaveCyclic* 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; - IPortPinWaveCyclic * Pin; - PKSPIN_CONNECT ConnectDetails; - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface; - - ASSERT(This->Port); - ASSERT(This->Descriptor); - ASSERT(This->Pins); - - DPRINT("IPortFilterWaveCyclic_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 == This->Descriptor->Factory.Instances[ConnectDetails->PinId].MaxFilterInstanceCount)) - { - /* release existing instance */ - return STATUS_UNSUCCESSFUL; - } - - /* now create the pin */ - Status = NewPortPinWaveCyclic(&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]); - if (!NT_SUCCESS(Status)) - { - Pin->lpVtbl->Release(Pin); - return Status; - } - - /* 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 -IPortFilterWaveCyclic_fnDeviceIoControl( - IN IPortFilterWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface; - - IoStack = IoGetCurrentIrpStackLocation(Irp); - - if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) - { - DPRINT1("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength); - - Irp->IoStatus.Status = STATUS_SUCCESS; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } - - - ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); - - return PcPropertyHandler(Irp, This->Descriptor); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnRead( - IN IPortFilterWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnWrite( - IN IPortFilterWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnFlush( - IN IPortFilterWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnClose( - IN IPortFilterWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - ULONG Index; - NTSTATUS Status = STATUS_SUCCESS; - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface; - - DPRINT("IPortFilterWaveCyclic_fnClose ref %u\n", This->ref); - - if (This->ref == 1) - { - for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++) - { - /* all pins should have been closed by now */ - ASSERT(This->Pins[Index] == NULL); - } - - /* release reference to port */ - This->SubDevice->lpVtbl->Release(This->SubDevice); - - /* time to shutdown the audio system */ - Status = This->SubDevice->lpVtbl->ReleaseChildren(This->SubDevice); - } - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnQuerySecurity( - IN IPortFilterWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnSetSecurity( - IN IPortFilterWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortFilterWaveCyclic_fnFastDeviceIoControl( - IN IPortFilterWaveCyclic* 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 -IPortFilterWaveCyclic_fnFastRead( - IN IPortFilterWaveCyclic* 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 -IPortFilterWaveCyclic_fnFastWrite( - IN IPortFilterWaveCyclic* 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 -IPortFilterWaveCyclic_fnInit( - IN IPortFilterWaveCyclic* iface, - IN IPortWaveCyclic* Port) -{ - ISubdevice * ISubDevice; - SUBDEVICE_DESCRIPTOR * Descriptor; - NTSTATUS Status; - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface; - - /* get our private interface */ - Status = Port->lpVtbl->QueryInterface(Port, &IID_ISubdevice, (PVOID*)&ISubDevice); - if (!NT_SUCCESS(Status)) - return STATUS_UNSUCCESSFUL; - - /* get the subdevice descriptor */ - Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor); - - /* store subdevice interface */ - This->SubDevice = ISubDevice; - - if (!NT_SUCCESS(Status)) - return STATUS_UNSUCCESSFUL; - - /* save descriptor */ - This->Descriptor = Descriptor; - - /* allocate pin array */ - This->Pins = AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinWaveCyclic*), TAG_PORTCLASS); - - if (!This->Pins) - return STATUS_UNSUCCESSFUL; - - /* store port driver */ - This->Port = Port; - - return STATUS_SUCCESS; -} - - -static -NTSTATUS -NTAPI -IPortFilterWaveCyclic_fnFreePin( - IN IPortFilterWaveCyclic* iface, - IN struct IPortPinWaveCyclic* Pin) -{ - ULONG Index; - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface; - - for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++) - { - if (This->Pins[Index] == Pin) - { - This->Descriptor->Factory.Instances[Index].CurrentPinInstanceCount--; - This->Pins[Index]->lpVtbl->Release(This->Pins[Index]); - This->Pins[Index] = NULL; - return STATUS_SUCCESS; - } - } - return STATUS_UNSUCCESSFUL; -} - -static IPortFilterWaveCyclicVtbl vt_IPortFilterWaveCyclic = -{ - IPortFilterWaveCyclic_fnQueryInterface, - IPortFilterWaveCyclic_fnAddRef, - IPortFilterWaveCyclic_fnRelease, - IPortFilterWaveCyclic_fnNewIrpTarget, - IPortFilterWaveCyclic_fnDeviceIoControl, - IPortFilterWaveCyclic_fnRead, - IPortFilterWaveCyclic_fnWrite, - IPortFilterWaveCyclic_fnFlush, - IPortFilterWaveCyclic_fnClose, - IPortFilterWaveCyclic_fnQuerySecurity, - IPortFilterWaveCyclic_fnSetSecurity, - IPortFilterWaveCyclic_fnFastDeviceIoControl, - IPortFilterWaveCyclic_fnFastRead, - IPortFilterWaveCyclic_fnFastWrite, - IPortFilterWaveCyclic_fnInit, - IPortFilterWaveCyclic_fnFreePin -}; - -NTSTATUS -NewPortFilterWaveCyclic( - OUT IPortFilterWaveCyclic ** OutFilter) -{ - IPortFilterWaveCyclicImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IPortFilterWaveCyclicImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - /* initialize IPortFilterWaveCyclic */ - This->ref = 1; - This->lpVtbl = &vt_IPortFilterWaveCyclic; - - /* return result */ - *OutFilter = (IPortFilterWaveCyclic*)&This->lpVtbl; - - return STATUS_SUCCESS; -} - - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp new file mode 100644 index 00000000000..80a8d2b84bd --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp @@ -0,0 +1,361 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c + * PURPOSE: portcls wave cyclic filter + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortFilterWaveCyclic : public IPortFilterWaveCyclic +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortFilterWaveCyclic; + CPortFilterWaveCyclic(IUnknown *OuterUnknown){} + virtual ~CPortFilterWaveCyclic(){} + +protected: + IPortWaveCyclic* m_Port; + IPortPinWaveCyclic ** m_Pins; + SUBDEVICE_DESCRIPTOR * m_Descriptor; + ISubdevice * m_SubDevice; + LONG m_Ref; +}; + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPort)) + { + *Output = PUNKNOWN(m_Port); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::NewIrpTarget( + 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; + IPortPinWaveCyclic * Pin; + PKSPIN_CONNECT ConnectDetails; + +#if 0 + ASSERT(m_Port); + ASSERT(m_Descriptor); + ASSERT(m_Pins); +#endif + + DPRINT("CPortFilterWaveCyclic::NewIrpTarget entered\n"); + + // let's verify the connection request + Status = PcValidateConnectRequest(Irp, &m_Descriptor->Factory, &ConnectDetails); + if (!NT_SUCCESS(Status)) + { + return STATUS_UNSUCCESSFUL; + } + + if (m_Pins[ConnectDetails->PinId] && + (m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount == m_Descriptor->Factory.Instances[ConnectDetails->PinId].MaxFilterInstanceCount)) + { + // release existing instance + return STATUS_UNSUCCESSFUL; + } + + // now create the pin + Status = NewPortPinWaveCyclic(&Pin); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + // initialize the pin + Status = Pin->Init(m_Port, this, ConnectDetails, &m_Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId]); + if (!NT_SUCCESS(Status)) + { + Pin->Release(); + return Status; + } + + // store pin + m_Pins[ConnectDetails->PinId] = Pin; + + // store result + *OutTarget = (IIrpTarget*)Pin; + + // increment current instance count + m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++; + + return Status; +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::DeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) + { + DPRINT1("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength); + + Irp->IoStatus.Status = STATUS_SUCCESS; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + + PC_ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); + + return PcPropertyHandler(Irp, m_Descriptor); +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + //ULONG Index; + NTSTATUS Status = STATUS_SUCCESS; + +#if 0 + if (m_ref == 1) + { + for(Index = 0; Index < m_Descriptor->Factory.PinDescriptorCount; Index++) + { + // all pins should have been closed by now + ASSERT(m_Pins[Index] == NULL); + } + + // release reference to port + m_SubDevice->Release(m_SubDevice); + + // time to shutdown the audio system + Status = m_SubDevice->ReleaseChildren(m_SubDevice); + } +#endif + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortFilterWaveCyclic::FastDeviceIoControl( + 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; +} + +BOOLEAN +NTAPI +CPortFilterWaveCyclic::FastRead( + 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; +} + +BOOLEAN +NTAPI +CPortFilterWaveCyclic::FastWrite( + 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; +} + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::Init( + IN IPortWaveCyclic* Port) +{ + ISubdevice * ISubDevice; + SUBDEVICE_DESCRIPTOR * Descriptor; + NTSTATUS Status; + + // get our private interface + Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // get the subdevice descriptor + Status = ISubDevice->GetDescriptor(&Descriptor); + + // store subdevice interface + m_SubDevice = ISubDevice; + + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // save descriptor + m_Descriptor = Descriptor; + + // allocate pin array + m_Pins = (IPortPinWaveCyclic**)AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinWaveCyclic*), TAG_PORTCLASS); + + if (!m_Pins) + return STATUS_UNSUCCESSFUL; + + // store port driver + m_Port = Port; + + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortFilterWaveCyclic::FreePin( + IN struct IPortPinWaveCyclic* Pin) +{ + ULONG Index; + + for(Index = 0; Index < m_Descriptor->Factory.PinDescriptorCount; Index++) + { + if (m_Pins[Index] == Pin) + { + m_Descriptor->Factory.Instances[Index].CurrentPinInstanceCount--; + m_Pins[Index]->Release(); + m_Pins[Index] = NULL; + return STATUS_SUCCESS; + } + } + return STATUS_UNSUCCESSFUL; +} + + +NTSTATUS +NewPortFilterWaveCyclic( + OUT IPortFilterWaveCyclic ** OutFilter) +{ + CPortFilterWaveCyclic * This; + + This = new(NonPagedPool, TAG_PORTCLASS)CPortFilterWaveCyclic(NULL); + + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // return result + *OutFilter = (IPortFilterWaveCyclic*)This; + + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c deleted file mode 100644 index 59524758ab5..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/filter_wavepci.c - * PURPOSE: portcls wave pci filter - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IPortFilterWavePciVtbl *lpVtbl; - - LONG ref; - - IPortWavePci* Port; - IPortPinWavePci ** Pins; - SUBDEVICE_DESCRIPTOR * Descriptor; - -}IPortFilterWavePciImpl; - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWavePci_fnQueryInterface( - IPortFilterWavePci* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl*)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 -IPortFilterWavePci_fnAddRef( - IPortFilterWavePci* iface) -{ - IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -/* - * @implemented - */ -ULONG -NTAPI -IPortFilterWavePci_fnRelease( - IPortFilterWavePci* iface) -{ - IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - return This->ref; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWavePci_fnNewIrpTarget( - IN IPortFilterWavePci* 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; - IPortPinWavePci * Pin; - PKSPIN_CONNECT ConnectDetails; - IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl *)iface; - - ASSERT(This->Port); - ASSERT(This->Descriptor); - ASSERT(This->Pins); - - DPRINT("IPortFilterWavePci_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 = NewPortPinWavePci(&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], GetDeviceObjectFromPortWavePci(This->Port)); - if (!NT_SUCCESS(Status)) - { - Pin->lpVtbl->Release(Pin); - return Status; - } - - /* 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 -IPortFilterWavePci_fnDeviceIoControl( - IN IPortFilterWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - ISubdevice *SubDevice = NULL; - SUBDEVICE_DESCRIPTOR * Descriptor; - NTSTATUS Status; - IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl *)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 -IPortFilterWavePci_fnRead( - IN IPortFilterWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWavePci_fnWrite( - IN IPortFilterWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWavePci_fnFlush( - IN IPortFilterWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWavePci_fnClose( - IN IPortFilterWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - ULONG Index; - IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl *)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 -IPortFilterWavePci_fnQuerySecurity( - IN IPortFilterWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortFilterWavePci_fnSetSecurity( - IN IPortFilterWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortFilterWavePci_fnFastDeviceIoControl( - IN IPortFilterWavePci* 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; - IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl *)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 -IPortFilterWavePci_fnFastRead( - IN IPortFilterWavePci* 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 -IPortFilterWavePci_fnFastWrite( - IN IPortFilterWavePci* 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 -IPortFilterWavePci_fnInit( - IN IPortFilterWavePci* iface, - IN IPortWavePci* Port) -{ - ISubdevice * ISubDevice; - SUBDEVICE_DESCRIPTOR * Descriptor; - NTSTATUS Status; - IPortFilterWavePciImpl * This = (IPortFilterWavePciImpl*)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(IPortPinWavePci*), TAG_PORTCLASS); - - if (!This->Pins) - return STATUS_UNSUCCESSFUL; - - /* increment reference count */ - Port->lpVtbl->AddRef(Port); - - return STATUS_SUCCESS; -} - -static IPortFilterWavePciVtbl vt_IPortFilterWavePci = -{ - IPortFilterWavePci_fnQueryInterface, - IPortFilterWavePci_fnAddRef, - IPortFilterWavePci_fnRelease, - IPortFilterWavePci_fnNewIrpTarget, - IPortFilterWavePci_fnDeviceIoControl, - IPortFilterWavePci_fnRead, - IPortFilterWavePci_fnWrite, - IPortFilterWavePci_fnFlush, - IPortFilterWavePci_fnClose, - IPortFilterWavePci_fnQuerySecurity, - IPortFilterWavePci_fnSetSecurity, - IPortFilterWavePci_fnFastDeviceIoControl, - IPortFilterWavePci_fnFastRead, - IPortFilterWavePci_fnFastWrite, - IPortFilterWavePci_fnInit -}; - -NTSTATUS -NewPortFilterWavePci( - OUT IPortFilterWavePci ** OutFilter) -{ - IPortFilterWavePciImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IPortFilterWavePciImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - /* initialize IPortFilterWavePci */ - This->ref = 1; - This->lpVtbl = &vt_IPortFilterWavePci; - - /* return result */ - *OutFilter = (IPortFilterWavePci*)&This->lpVtbl; - - return STATUS_SUCCESS; -} - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp new file mode 100644 index 00000000000..c9e9a645eb8 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp @@ -0,0 +1,302 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp + * PURPOSE: portcls wave pci filter + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortFilterWavePci : public IPortFilterWavePci +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortFilterPci; + CPortFilterWavePci(IUnknown *OuterUnknown){} + virtual ~CPortFilterWavePci(){} + +protected: + IPortWavePci* m_Port; + IPortPinWavePci ** m_Pins; + SUBDEVICE_DESCRIPTOR * m_Descriptor; + + LONG m_Ref; +}; + +NTSTATUS +NTAPI +CPortFilterWavePci::QueryInterface( + + IN REFIID refiid, + OUT PVOID* Output) +{ + + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPort)) + { + *Output = PUNKNOWN(m_Port); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortFilterWavePci::NewIrpTarget( + 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; + IPortPinWavePci * Pin; + PKSPIN_CONNECT ConnectDetails; + +#if 0 + ASSERT(m_Port); + ASSERT(m_Descriptor); + ASSERT(m_Pins); +#endif + + DPRINT("CPortFilterWavePci::NewIrpTarget entered\n"); + + // let's verify the connection request + Status = PcValidateConnectRequest(Irp, &m_Descriptor->Factory, &ConnectDetails); + if (!NT_SUCCESS(Status)) + { + return STATUS_UNSUCCESSFUL; + } + + if (m_Pins[ConnectDetails->PinId] && m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount) + { + // release existing instance + PC_ASSERT(0); + m_Pins[ConnectDetails->PinId]->Close(DeviceObject, NULL); + } + + // now create the pin + Status = NewPortPinWavePci(&Pin); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + // initialize the pin + Status = Pin->Init(m_Port, this, ConnectDetails, &m_Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], GetDeviceObjectFromPortWavePci(m_Port)); + if (!NT_SUCCESS(Status)) + { + Pin->Release(); + return Status; + } + + // store pin + m_Pins[ConnectDetails->PinId] = Pin; + + // store result + *OutTarget = (IIrpTarget*)Pin; + + // increment current instance count + m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++; + + return Status; +} + +NTSTATUS +NTAPI +CPortFilterWavePci::DeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return PcPropertyHandler(Irp, m_Descriptor); +} + +NTSTATUS +NTAPI +CPortFilterWavePci::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWavePci::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWavePci::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWavePci::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortFilterWavePci::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWavePci::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortFilterWavePci::FastDeviceIoControl( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortFilterWavePci::FastRead( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortFilterWavePci::FastWrite( + 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) +{ + return FALSE; +} + +NTSTATUS +NTAPI +CPortFilterWavePci::Init( + IN IPortWavePci* Port) +{ + ISubdevice * ISubDevice; + SUBDEVICE_DESCRIPTOR * Descriptor; + NTSTATUS Status; + + m_Port = Port; + + // get our private interface + Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // get the subdevice descriptor + Status = ISubDevice->GetDescriptor(&Descriptor); + + // release subdevice interface + ISubDevice->Release(); + + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // save descriptor + m_Descriptor = Descriptor; + + // allocate pin array + m_Pins = (IPortPinWavePci**)AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinWavePci*), TAG_PORTCLASS); + + if (!m_Pins) + return STATUS_UNSUCCESSFUL; + + // increment reference count + Port->AddRef(); + + return STATUS_SUCCESS; +} + +NTSTATUS +NewPortFilterWavePci( + OUT IPortFilterWavePci ** OutFilter) +{ + CPortFilterWavePci * This; + + This = new(NonPagedPool, TAG_PORTCLASS)CPortFilterWavePci(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // return result + *OutFilter = (IPortFilterWavePci*)This; + + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.c deleted file mode 100644 index 1797f74c365..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * 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; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.cpp b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.cpp new file mode 100644 index 00000000000..b3f2ba23015 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavert.cpp @@ -0,0 +1,307 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/filter_wavert.cpp + * PURPOSE: portcls wave RT filter + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortFilterWaveRT : public IPortFilterWaveRT +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortFilterWaveRT; + CPortFilterWaveRT(IUnknown *OuterUnknown){} + virtual ~CPortFilterWaveRT(){} + +protected: + + + IPortWaveRT* m_Port; + IPortPinWaveRT ** m_Pins; + SUBDEVICE_DESCRIPTOR * m_Descriptor; + LONG m_Ref; +}; + +NTSTATUS +NTAPI +CPortFilterWaveRT::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPort)) + { + *Output = PUNKNOWN(m_Port); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::NewIrpTarget( + 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; + +#if 0 + ASSERT(m_Port); + ASSERT(m_Descriptor); + ASSERT(m_Pins); +#endif + + DPRINT("CPortFilterWaveRT::NewIrpTarget entered\n"); + + // let's verify the connection request + Status = PcValidateConnectRequest(Irp, &m_Descriptor->Factory, &ConnectDetails); + if (!NT_SUCCESS(Status)) + { + return STATUS_UNSUCCESSFUL; + } + + if (m_Pins[ConnectDetails->PinId] && m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount) + { + // release existing instance + PC_ASSERT(0); + m_Pins[ConnectDetails->PinId]->Close(DeviceObject, NULL); + } + + // now create the pin + Status = NewPortPinWaveRT(&Pin); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + // initialize the pin + Status = Pin->Init(m_Port, this, ConnectDetails, &m_Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], GetDeviceObjectFromPortWaveRT(m_Port)); + if (!NT_SUCCESS(Status)) + { + Pin->Release(); + return Status; + } + + // release existing pin + if (m_Pins[ConnectDetails->PinId]) + { + m_Pins[ConnectDetails->PinId]->Release(); + } + // store pin + m_Pins[ConnectDetails->PinId] = Pin; + + // store result + *OutTarget = (IIrpTarget*)Pin; + + // increment current instance count + m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++; + + return Status; +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::DeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return PcPropertyHandler(Irp, m_Descriptor); +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortFilterWaveRT::FastDeviceIoControl( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortFilterWaveRT::FastRead( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortFilterWaveRT::FastWrite( + + 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) +{ + return FALSE; +} + +NTSTATUS +NTAPI +CPortFilterWaveRT::Init( + IN IPortWaveRT* Port) +{ + ISubdevice * ISubDevice; + SUBDEVICE_DESCRIPTOR * Descriptor; + NTSTATUS Status; + + m_Port = Port; + + // get our private interface + Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // get the subdevice descriptor + Status = ISubDevice->GetDescriptor(&Descriptor); + + // release subdevice interface + ISubDevice->Release(); + + if (!NT_SUCCESS(Status)) + return STATUS_UNSUCCESSFUL; + + // save descriptor + m_Descriptor = Descriptor; + + // allocate pin array + m_Pins = (IPortPinWaveRT**)AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinWaveRT*), TAG_PORTCLASS); + + if (!m_Pins) + return STATUS_UNSUCCESSFUL; + + // increment reference count + Port->AddRef(); + + return STATUS_SUCCESS; +} + +NTSTATUS +NewPortFilterWaveRT( + OUT IPortFilterWaveRT ** OutFilter) +{ + CPortFilterWaveRT * This; + + This = new(NonPagedPool, TAG_PORTCLASS)CPortFilterWaveRT(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // return result + *OutFilter = (CPortFilterWaveRT*)This; + + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/guids.c b/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp similarity index 90% rename from reactos/drivers/wdm/audio/backpln/portcls/guids.c rename to reactos/drivers/wdm/audio/backpln/portcls/guids.cpp index b805c2d2320..a9ceaa7486e 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/guids.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp @@ -1,13 +1,13 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/guids.c + * FILE: drivers/wdm/audio/backpln/portcls/guids.cpp * PURPOSE: portcls guid mess * PROGRAMMER: Johannes Anderwald */ -#include "private.h" +#include "private.hpp" const GUID CLSID_PortTopology = {0xb4c90a32L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}}; const GUID CLSID_PortMidi = {0xb4c90a43L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}}; @@ -25,11 +25,13 @@ const GUID GUID_NULL ={0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x0 const GUID IID_IPortTopology = {0xb4c90a30L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}}; -const GUID CLSID_MiniportDriverDMusUART; -const GUID CLSID_MiniportDriverUart; -const GUID CLSID_MiniportDriverDMusUARTCapture; -const GUID CLSID_MiniportDriverFmSynth; -const GUID CLSID_MiniportDriverFmSynthWithVol; +const GUID CLSID_MiniportDriverDMusUART = {0xd3f0ce1c, 0xfffc, 0x11d1, {0x81, 0xb0, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}}; +const GUID CLSID_MiniportDriverDMusUARTCapture = {0xd3f0ce1d, 0xfffc, 0x11d1, {0x81, 0xb0, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}}; +const GUID CLSID_MiniportDriverUart = {0xb4c90ae1L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}}; + +const GUID CLSID_MiniportDriverFmSynth = {0xb4c90ae0L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}}; +const GUID CLSID_MiniportDriverFmSynthWithVol = {0xe5a3c139L, 0xf0f2, 0x11d1, {0x81, 0xaf, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}}; + const GUID IID_IPort = {0xb4c90a25L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}}; const GUID IID_IDrmPort = {0x286D3DF8L, 0xCA22, 0x4E2E, {0xB9, 0xBC, 0x20, 0xB4, 0xF0, 0xE2, 0x01, 0xCE}}; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp similarity index 56% rename from reactos/drivers/wdm/audio/backpln/portcls/interfaces.h rename to reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp index 7ee232afc70..a72be55813c 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp @@ -11,6 +11,75 @@ DEFINE_GUID(IID_IIrpTargetFactory, 0xB4C90A62, 0x5791, 0x11D0, 0xF9, 0x86, 0x00, ***************************************************************************** */ +#define IMP_IIrpTarget \ + STDMETHODIMP_(NTSTATUS) NewIrpTarget(THIS_ \ + 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); \ + \ + STDMETHODIMP_(NTSTATUS) DeviceIoControl(THIS_ \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp); \ + \ + STDMETHODIMP_(NTSTATUS) Read(THIS_ \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp); \ + \ + STDMETHODIMP_(NTSTATUS) Write(THIS_ \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp); \ + \ + STDMETHODIMP_(NTSTATUS) Flush(THIS_ \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp); \ + \ + STDMETHODIMP_(NTSTATUS) Close(THIS_ \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp); \ + \ + STDMETHODIMP_(NTSTATUS) QuerySecurity(THIS_ \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp); \ + \ + STDMETHODIMP_(NTSTATUS) SetSecurity(THIS_ \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp); \ + \ + STDMETHODIMP_(BOOLEAN) FastDeviceIoControl(THIS_ \ + 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); \ + \ + STDMETHODIMP_(BOOLEAN) FastRead(THIS_ \ + 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); \ + \ + STDMETHODIMP_(BOOLEAN) FastWrite(THIS_ \ + 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) + #define DEFINE_ABSTRACT_IRPTARGET() \ STDMETHOD_(NTSTATUS, NewIrpTarget)(THIS_ \ OUT struct IIrpTarget **OutTarget, \ @@ -80,6 +149,8 @@ DEFINE_GUID(IID_IIrpTargetFactory, 0xB4C90A62, 0x5791, 0x11D0, 0xF9, 0x86, 0x00, OUT PIO_STATUS_BLOCK StatusBlock, \ IN PDEVICE_OBJECT DeviceObject)PURE; + + #undef INTERFACE #define INTERFACE IIrpTarget @@ -136,50 +207,85 @@ typedef struct #undef INTERFACE #define INTERFACE ISubdevice -DECLARE_INTERFACE_(ISubdevice, IUnknown) -{ - STDMETHOD_(NTSTATUS, QueryInterface)(THIS_ - REFIID InterfaceId, - PVOID* Interface - ) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - STDMETHOD_(NTSTATUS, NewIrpTarget)(THIS_ - OUT IIrpTarget **OutTarget, - IN WCHAR * Name, - IN PUNKNOWN Unknown, - IN POOL_TYPE PoolType, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN KSOBJECT_CREATE *CreateObject) PURE; - - STDMETHOD_(NTSTATUS, ReleaseChildren)(THIS) PURE; - - STDMETHOD_(NTSTATUS, GetDescriptor)(THIS_ - IN SUBDEVICE_DESCRIPTOR **) PURE; - - STDMETHOD_(NTSTATUS, DataRangeIntersection)(THIS_ - IN ULONG PinId, - IN PKSDATARANGE DataRange, - IN PKSDATARANGE MatchingDataRange, - IN ULONG OutputBufferLength, - OUT PVOID ResultantFormat OPTIONAL, - OUT PULONG ResultantFormatLength) PURE; - - STDMETHOD_(NTSTATUS, PowerChangeNotify)(THIS_ - IN POWER_STATE PowerState) PURE; - - STDMETHOD_(NTSTATUS, PinCount)(THIS_ - IN ULONG PinId, - IN OUT PULONG FilterNecessary, - IN OUT PULONG FilterCurrent, - IN OUT PULONG FilterPossible, - IN OUT PULONG GlobalCurrent, +#define DEFINE_ABSTRACT_ISUBDEVICE() \ + STDMETHOD_(NTSTATUS, NewIrpTarget)(THIS_ \ + OUT IIrpTarget **OutTarget, \ + IN WCHAR * Name, \ + IN PUNKNOWN Unknown, \ + IN POOL_TYPE PoolType, \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp, \ + IN KSOBJECT_CREATE *CreateObject) PURE; \ + \ + STDMETHOD_(NTSTATUS, ReleaseChildren)(THIS) PURE; \ + \ + STDMETHOD_(NTSTATUS, GetDescriptor)(THIS_ \ + IN SUBDEVICE_DESCRIPTOR **) PURE; \ + \ + STDMETHOD_(NTSTATUS, DataRangeIntersection)(THIS_ \ + IN ULONG PinId, \ + IN PKSDATARANGE DataRange, \ + IN PKSDATARANGE MatchingDataRange, \ + IN ULONG OutputBufferLength, \ + OUT PVOID ResultantFormat OPTIONAL, \ + OUT PULONG ResultantFormatLength) PURE; \ + \ + STDMETHOD_(NTSTATUS, PowerChangeNotify)(THIS_ \ + IN POWER_STATE PowerState) PURE; \ + \ + STDMETHOD_(NTSTATUS, PinCount)(THIS_ \ + IN ULONG PinId, \ + IN OUT PULONG FilterNecessary, \ + IN OUT PULONG FilterCurrent, \ + IN OUT PULONG FilterPossible, \ + IN OUT PULONG GlobalCurrent, \ IN OUT PULONG GlobalPossible)PURE; + + +#define IMP_ISubdevice \ + STDMETHODIMP_(NTSTATUS) NewIrpTarget( \ + OUT IIrpTarget **OutTarget, \ + IN WCHAR * Name, \ + IN PUNKNOWN Unknown, \ + IN POOL_TYPE PoolType, \ + IN PDEVICE_OBJECT DeviceObject, \ + IN PIRP Irp, \ + IN KSOBJECT_CREATE *CreateObject); \ + \ + STDMETHODIMP_(NTSTATUS) ReleaseChildren(THIS); \ + \ + STDMETHODIMP_(NTSTATUS) GetDescriptor(THIS_ \ + IN SUBDEVICE_DESCRIPTOR **); \ + \ + STDMETHODIMP_(NTSTATUS) DataRangeIntersection( \ + IN ULONG PinId, \ + IN PKSDATARANGE DataRange, \ + IN PKSDATARANGE MatchingDataRange, \ + IN ULONG OutputBufferLength, \ + OUT PVOID ResultantFormat OPTIONAL, \ + OUT PULONG ResultantFormatLength); \ + \ + STDMETHODIMP_(NTSTATUS) PowerChangeNotify( \ + IN POWER_STATE PowerState); \ + \ + STDMETHODIMP_(NTSTATUS) PinCount( \ + IN ULONG PinId, \ + IN OUT PULONG FilterNecessary, \ + IN OUT PULONG FilterCurrent, \ + IN OUT PULONG FilterPossible, \ + IN OUT PULONG GlobalCurrent, \ + IN OUT PULONG GlobalPossible) + + +DECLARE_INTERFACE_(ISubdevice, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + DEFINE_ABSTRACT_ISUBDEVICE() }; +typedef ISubdevice *PSUBDEVICE; + /***************************************************************************** * IIrpQueue ***************************************************************************** @@ -241,6 +347,54 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown) }; +#define IMP_IIrpQueue \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN KSPIN_CONNECT *ConnectDetails, \ + IN PKSDATAFORMAT DataFormat, \ + IN PDEVICE_OBJECT DeviceObject, \ + IN ULONG FrameSize, \ + IN ULONG Alignment, \ + IN PVOID SilenceBuffer); \ + \ + STDMETHODIMP_(NTSTATUS) AddMapping(THIS_ \ + IN PUCHAR Buffer, \ + IN ULONG BufferSize, \ + IN PIRP Irp); \ + \ + STDMETHODIMP_(NTSTATUS) GetMapping(THIS_ \ + OUT PUCHAR * Buffer, \ + OUT PULONG BufferSize); \ + \ + STDMETHODIMP_(VOID) UpdateMapping(THIS_ \ + IN ULONG BytesWritten); \ + \ + STDMETHODIMP_(ULONG) NumMappings(THIS); \ + \ + STDMETHODIMP_(ULONG) NumData(THIS); \ + \ + STDMETHODIMP_(BOOL) MinimumDataAvailable(THIS); \ + \ + STDMETHODIMP_(BOOL) CancelBuffers(THIS); \ + \ + STDMETHODIMP_(VOID) UpdateFormat(THIS_ \ + IN PKSDATAFORMAT DataFormat); \ + \ + STDMETHODIMP_(NTSTATUS) GetMappingWithTag(THIS_ \ + IN PVOID Tag, \ + OUT PPHYSICAL_ADDRESS PhysicalAddress, \ + OUT PVOID *VirtualAddress, \ + OUT PULONG ByteCount, \ + OUT PULONG Flags); \ + \ + STDMETHODIMP_(NTSTATUS) ReleaseMappingWithTag( \ + IN PVOID Tag); \ + \ + STDMETHODIMP_(BOOL) HasLastMappingFailed(THIS); \ + STDMETHODIMP_(VOID) PrintQueueStatus(THIS); \ + STDMETHODIMP_(VOID) SetMinimumDataThreshold( \ + IN ULONG MinimumDataThreshold); \ + STDMETHODIMP_(ULONG) GetMinimumDataThreshold(VOID) + /***************************************************************************** * IKsWorkSink ***************************************************************************** @@ -453,6 +607,10 @@ DECLARE_INTERFACE_(IPortFilterWavePci, IIrpTarget) typedef IPortFilterWavePci *PPORTFILTERWAVEPCI; +#define IMP_IPortFilterPci \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTWAVEPCI Port) /***************************************************************************** * IPortPinWavePci @@ -479,8 +637,23 @@ DECLARE_INTERFACE_(IPortPinWavePci, IIrpTarget) STDMETHOD_(PMINIPORT, GetMiniport)(THIS); }; +#define IMP_IPortPinWavePci \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTWAVEPCI Port, \ + IN PPORTFILTERWAVEPCI Filter, \ + IN KSPIN_CONNECT * ConnectDetails, \ + IN KSPIN_DESCRIPTOR * PinDescriptor, \ + IN PDEVICE_OBJECT DeviceObject); \ + \ + STDMETHODIMP_(PVOID) GetIrpStream(THIS); \ + STDMETHODIMP_(PMINIPORT) GetMiniport(THIS) + + + typedef IPortPinWavePci *PPORTPINWAVEPCI; + #if (NTDDI_VERSION >= NTDDI_VISTA) /***************************************************************************** @@ -503,6 +676,12 @@ DECLARE_INTERFACE_(IPortFilterWaveRT, IIrpTarget) typedef IPortFilterWaveRT *PPORTFILTERWAVERT; +#define IMP_IPortFilterWaveRT \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTWAVERT Port) + + /***************************************************************************** * IPortPinWaveRT ***************************************************************************** @@ -527,6 +706,16 @@ DECLARE_INTERFACE_(IPortPinWaveRT, IIrpTarget) typedef IPortPinWaveRT *PPORTPINWAVERT; +#define IMP_IPortPinWaveRT \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTWAVERT Port, \ + IN PPORTFILTERWAVERT Filter, \ + IN KSPIN_CONNECT * ConnectDetails, \ + IN KSPIN_DESCRIPTOR * PinDescriptor, \ + IN PDEVICE_OBJECT DeviceObject) + + #endif /***************************************************************************** @@ -554,6 +743,14 @@ DECLARE_INTERFACE_(IPortFilterWaveCyclic, IIrpTarget) typedef IPortFilterWaveCyclic *PPORTFILTERWAVECYCLIC; +#define IMP_IPortFilterWaveCyclic \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTWAVECYCLIC Port); \ + STDMETHODIMP_(NTSTATUS) FreePin(THIS_ \ + IN struct IPortPinWaveCyclic* Pin) + + /***************************************************************************** * IPortPinWaveCyclic ***************************************************************************** @@ -581,6 +778,20 @@ DECLARE_INTERFACE_(IPortPinWaveCyclic, IIrpTarget) STDMETHOD_(PMINIPORT, GetMiniport)(THIS); }; +#define IMP_IPortPinWaveCyclic \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTWAVECYCLIC Port, \ + IN PPORTFILTERWAVECYCLIC Filter, \ + IN KSPIN_CONNECT * ConnectDetails, \ + IN KSPIN_DESCRIPTOR * PinDescriptor); \ + STDMETHODIMP_(ULONG) GetCompletedPosition(THIS); \ + STDMETHODIMP_(ULONG) GetCycleCount(THIS); \ + STDMETHODIMP_(ULONG) GetDeviceBufferSize(THIS); \ + STDMETHODIMP_(PVOID) GetIrpStream(THIS); \ + STDMETHODIMP_(PMINIPORT) GetMiniport(THIS) + + /***************************************************************************** * IPortFilterDMus ***************************************************************************** @@ -591,7 +802,7 @@ DECLARE_INTERFACE_(IPortPinWaveCyclic, IIrpTarget) struct IPortPinDMus; -DECLARE_INTERFACE_(IPortFilterDMus, IIrpTarget) +DECLARE_INTERFACE_(IPortFilterDMus, IUnknown) { DEFINE_ABSTRACT_UNKNOWN() @@ -608,6 +819,14 @@ DECLARE_INTERFACE_(IPortFilterDMus, IIrpTarget) typedef IPortFilterDMus *PPORTFILTERDMUS; +#define IMP_IPortFilterDMus \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTDMUS Port); \ + STDMETHODIMP_(NTSTATUS) FreePin(THIS_ \ + IN struct IPortPinDMus* Pin); \ + STDMETHODIMP_(VOID) NotifyPins(THIS) + /***************************************************************************** * IPortPinDMus ***************************************************************************** @@ -632,6 +851,16 @@ DECLARE_INTERFACE_(IPortPinDMus, IIrpTarget) STDMETHOD_(VOID, Notify)(THIS); }; +#define IMP_IPortPinDMus \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTDMUS Port, \ + IN PPORTFILTERDMUS Filter, \ + IN KSPIN_CONNECT * ConnectDetails, \ + IN KSPIN_DESCRIPTOR * PinDescriptor, \ + IN PDEVICE_OBJECT DeviceObject); \ + STDMETHODIMP_(VOID) Notify(THIS) + typedef IPortPinDMus *PPORTPINDMUS; /***************************************************************************** @@ -645,51 +874,23 @@ typedef IPortPinDMus *PPORTPINDMUS; DECLARE_INTERFACE_(IDmaChannelInit, IUnknown) { DEFINE_ABSTRACT_UNKNOWN() - - STDMETHOD_(NTSTATUS,AllocateBuffer)(THIS_ - IN ULONG BufferSize, - IN PPHYSICAL_ADDRESS PhysicalAddressConstraint OPTIONAL); - - STDMETHOD_(VOID, FreeBuffer)(THIS); - STDMETHOD_(ULONG, TransferCount)(THIS); - STDMETHOD_(ULONG, MaximumBufferSize)(THIS); - STDMETHOD_(ULONG, AllocatedBufferSize)(THIS); - STDMETHOD_(ULONG, BufferSize)(THIS); - - STDMETHOD_(VOID, SetBufferSize)(THIS_ - IN ULONG BufferSize); - - STDMETHOD_(PVOID, SystemAddress)(THIS); - STDMETHOD_(PHYSICAL_ADDRESS, PhysicalAddress)(THIS_ - IN PPHYSICAL_ADDRESS Address); - - STDMETHOD_(PADAPTER_OBJECT, GetAdapterObject)(THIS); - - STDMETHOD_(VOID, CopyTo)(THIS_ - IN PVOID Destination, - IN PVOID Source, - IN ULONG ByteCount); - - STDMETHOD_(VOID, CopyFrom)(THIS_ - IN PVOID Destination, - IN PVOID Source, - IN ULONG ByteCount); - - STDMETHOD_(NTSTATUS, Start)( THIS_ - IN ULONG MapSize, - IN BOOLEAN WriteToDevice) PURE; - - STDMETHOD_(NTSTATUS, Stop)( THIS ) PURE; - STDMETHOD_(ULONG, ReadCounter)( THIS ) PURE; - - STDMETHOD_(NTSTATUS, WaitForTC)( THIS_ - ULONG Timeout) PURE; + DEFINE_ABSTRACT_DMACHANNEL() + DEFINE_ABSTRACT_DMACHANNELSLAVE() STDMETHOD_(NTSTATUS, Init)( THIS_ IN PDEVICE_DESCRIPTION DeviceDescription, IN PDEVICE_OBJECT DeviceObject) PURE; }; + + +#define IMP_IDmaChannelInit\ + IMP_IDmaChannelSlave;\ + STDMETHODIMP_(NTSTATUS) Init( \ + IN PDEVICE_DESCRIPTION DeviceDescription, \ + IN PDEVICE_OBJECT DeviceObject) + + #undef INTERFACE /***************************************************************************** @@ -712,6 +913,11 @@ DECLARE_INTERFACE_(IPortFilterTopology, IIrpTarget) typedef IPortFilterTopology *PPORTFILTERTOPOLOGY; +#define IMP_IPortFilterTopology \ + IMP_IIrpTarget; \ + STDMETHODIMP_(NTSTATUS) Init(THIS_ \ + IN PPORTTOPOLOGY Port) + #undef INTERFACE /***************************************************************************** @@ -772,4 +978,50 @@ DECLARE_INTERFACE_(IPortWaveRTStreamInit, IUnknown) #undef INTERFACE +#define IMP_IPortWaveRTStreamInit \ + STDMETHODIMP_(PMDL) AllocatePagesForMdl \ + ( THIS_ \ + IN PHYSICAL_ADDRESS HighAddress, \ + IN SIZE_T TotalBytes \ + ); \ + \ + STDMETHODIMP_(PMDL) AllocateContiguousPagesForMdl \ + ( THIS_ \ + IN PHYSICAL_ADDRESS LowAddress, \ + IN PHYSICAL_ADDRESS HighAddress, \ + IN SIZE_T TotalBytes \ + ); \ + \ + STDMETHODIMP_(PVOID) MapAllocatedPages \ + ( THIS_ \ + IN PMDL MemoryDescriptorList, \ + IN MEMORY_CACHING_TYPE CacheType \ + ); \ + \ + STDMETHODIMP_(VOID) UnmapAllocatedPages \ + ( THIS_ \ + IN PVOID BaseAddress, \ + IN PMDL MemoryDescriptorList \ + ); \ + \ + STDMETHODIMP_(VOID) FreePagesFromMdl \ + ( THIS_ \ + IN PMDL MemoryDescriptorList \ + ); \ + \ + STDMETHODIMP_(ULONG) GetPhysicalPagesCount \ + ( THIS_ \ + IN PMDL MemoryDescriptorList \ + ); \ + \ + STDMETHODIMP_(PHYSICAL_ADDRESS) GetPhysicalPageAddress \ + ( THIS_ \ + IN PPHYSICAL_ADDRESS Address, \ + IN PMDL MemoryDescriptorList, \ + IN ULONG Index \ + ) + + + + #endif diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interrupt.c b/reactos/drivers/wdm/audio/backpln/portcls/interrupt.c deleted file mode 100644 index cb3ea1b2755..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/interrupt.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/interrupt.c - * PURPOSE: portcls interrupt object - * PROGRAMMER: Johannes Anderwald - */ - - -#include "private.h" - -typedef struct -{ - LIST_ENTRY ListEntry; - PINTERRUPTSYNCROUTINE SyncRoutine; - PVOID DynamicContext; -}SYNC_ENTRY, *PSYNC_ENTRY; - -typedef struct -{ - IInterruptSyncVtbl *lpVtbl; - - LONG ref; - KSPIN_LOCK Lock; - LIST_ENTRY ServiceRoutines; - PKINTERRUPT Interrupt; - INTERRUPTSYNCMODE Mode; - PRESOURCELIST ResourceList; - ULONG ResourceIndex; - - PINTERRUPTSYNCROUTINE SyncRoutine; - PVOID DynamicContext; -}IInterruptSyncImpl; - - -//--------------------------------------------------------------- -// IUnknown methods -// - - - -NTSTATUS -NTAPI -IInterruptSync_fnQueryInterface( - IInterruptSync * iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface; - - DPRINT("IInterruptSync_fnQueryInterface: This %p\n", This); - - if (IsEqualGUIDAligned(refiid, &IID_IInterruptSync) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - DPRINT1("IInterruptSync_fnQueryInterface: This %p UNKNOWN interface requested\n", This); - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IInterruptSync_fnAddRef( - IInterruptSync * iface) -{ - IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface; - - DPRINT("IInterruptSync_AddRef: This %p\n", This); - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IInterruptSync_fnRelease( - IInterruptSync* iface) -{ - PLIST_ENTRY CurEntry; - PSYNC_ENTRY Entry; - IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface; - - InterlockedDecrement(&This->ref); - - DPRINT("IInterruptSync_Release: This %p new ref %u\n", This, This->ref); - - if (This->ref == 0) - { - while(!IsListEmpty(&This->ServiceRoutines)) - { - CurEntry = RemoveHeadList(&This->ServiceRoutines); - Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry); - FreeItem(Entry, TAG_PORTCLASS); - } - - This->ResourceList->lpVtbl->Release(This->ResourceList); - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - -//--------------------------------------------------------------- -// IInterruptSync methods -// - - -BOOLEAN -NTAPI -IInterruptSynchronizedRoutine( - IN PVOID ServiceContext) -{ - IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext; - DPRINT("IInterruptSynchronizedRoutine This %p SyncRoutine %p Context %p\n", This, This->SyncRoutine, This->DynamicContext); - return This->SyncRoutine((IInterruptSync*)&This->lpVtbl, This->DynamicContext); -} - -NTSTATUS -NTAPI -IInterruptSync_fnCallSynchronizedRoutine( - IN IInterruptSync * iface, - IN PINTERRUPTSYNCROUTINE Routine, - IN PVOID DynamicContext) -{ - KIRQL OldIrql; - IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface; - - DPRINT("IInterruptSync_fnCallSynchronizedRoutine This %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", This, Routine, DynamicContext, KeGetCurrentIrql(), This->Interrupt); - - if (!This->Interrupt) - { - DPRINT("IInterruptSync_CallSynchronizedRoutine %p no interrupt connected\n", This); - if (KeGetCurrentIrql() > DISPATCH_LEVEL) - return STATUS_UNSUCCESSFUL; - - KeAcquireSpinLock(&This->Lock, &OldIrql); - This->SyncRoutine = Routine; - This->DynamicContext = DynamicContext; - IInterruptSynchronizedRoutine((PVOID)This); - KeReleaseSpinLock(&This->Lock, OldIrql); - - return STATUS_SUCCESS; - } - - This->SyncRoutine = Routine; - This->DynamicContext = DynamicContext; - - if (KeSynchronizeExecution(This->Interrupt, IInterruptSynchronizedRoutine, (PVOID)This)) - return STATUS_SUCCESS; - else - return STATUS_UNSUCCESSFUL; -} - -PKINTERRUPT -NTAPI -IInterruptSync_fnGetKInterrupt( - IN IInterruptSync * iface) -{ - IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface; - DPRINT("IInterruptSynchronizedRoutine\n"); - - return This->Interrupt; -} - -BOOLEAN -NTAPI -IInterruptServiceRoutine( - IN PKINTERRUPT Interrupt, - IN PVOID ServiceContext) -{ - PLIST_ENTRY CurEntry; - PSYNC_ENTRY Entry; - NTSTATUS Status; - BOOL Success; - IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext; - - //DPRINT("IInterruptServiceRoutine Mode %u\n", This->Mode); - - if (This->Mode == InterruptSyncModeNormal) - { - CurEntry = This->ServiceRoutines.Flink; - while (CurEntry != &This->ServiceRoutines) - { - Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry); - Status = Entry->SyncRoutine((IInterruptSync*)This, Entry->DynamicContext); - if (NT_SUCCESS(Status)) - { - return TRUE; - } - CurEntry = CurEntry->Flink; - } - return FALSE; - } - else if (This->Mode == InterruptSyncModeAll) - { - CurEntry = This->ServiceRoutines.Flink; - while (CurEntry != &This->ServiceRoutines) - { - Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry); - Status = Entry->SyncRoutine((IInterruptSync*)This, Entry->DynamicContext); - CurEntry = CurEntry->Flink; - } - DPRINT("Returning TRUE with mode InterruptSyncModeAll\n"); - return TRUE; //FIXME - } - else if (This->Mode == InterruptSyncModeRepeat) - { - do - { - Success = FALSE; - CurEntry = This->ServiceRoutines.Flink; - while (CurEntry != &This->ServiceRoutines) - { - Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry); - Status = Entry->SyncRoutine((IInterruptSync*)This, Entry->DynamicContext); - if (NT_SUCCESS(Status)) - Success = TRUE; - CurEntry = CurEntry->Flink; - } - }while(Success); - DPRINT("Returning TRUE with mode InterruptSyncModeRepeat\n"); - return TRUE; //FIXME - } - else - { - DPRINT("Unknown mode %u\n", This->Mode); - return FALSE; //FIXME - } -} - - -NTSTATUS -NTAPI -IInterruptSync_fnConnect( - IN IInterruptSync * iface) -{ - IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface; - NTSTATUS Status; - PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; - - DPRINT("IInterruptSync_fnConnect\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - Descriptor = This->ResourceList->lpVtbl->FindTranslatedEntry(This->ResourceList, CmResourceTypeInterrupt, This->ResourceIndex); - if (!Descriptor) - return STATUS_UNSUCCESSFUL; - - if (IsListEmpty(&This->ServiceRoutines)) - return STATUS_UNSUCCESSFUL; - - Status = IoConnectInterrupt(&This->Interrupt, - IInterruptServiceRoutine, - (PVOID)This, - &This->Lock, - Descriptor->u.Interrupt.Vector, - Descriptor->u.Interrupt.Level, - Descriptor->u.Interrupt.Level, - (Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED), - (Descriptor->Flags != CM_RESOURCE_INTERRUPT_LATCHED), - Descriptor->u.Interrupt.Affinity, - FALSE); - - DPRINT("IInterruptSync_fnConnect result %x\n", Status); - return Status; -} - - -VOID -NTAPI -IInterruptSync_fnDisconnect( - IN IInterruptSync * iface) -{ - IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface; - - DPRINT("IInterruptSync_fnDisconnect\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->Interrupt) - { - DPRINT("IInterruptSync_Disconnect %p no interrupt connected\n", This); - return; - } - - IoDisconnectInterrupt(This->Interrupt); - This->Interrupt = NULL; -} - -NTSTATUS -NTAPI -IInterruptSync_fnRegisterServiceRoutine( - IN IInterruptSync * iface, - IN PINTERRUPTSYNCROUTINE Routine, - IN PVOID DynamicContext, - IN BOOLEAN First) -{ - PSYNC_ENTRY NewEntry; - IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface; - - DPRINT("IInterruptSync_fnRegisterServiceRoutine\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - NewEntry = AllocateItem(NonPagedPool, sizeof(SYNC_ENTRY), TAG_PORTCLASS); - if (!NewEntry) - return STATUS_INSUFFICIENT_RESOURCES; - - NewEntry->SyncRoutine = Routine; - NewEntry->DynamicContext = DynamicContext; - - if (First) - InsertHeadList(&This->ServiceRoutines, &NewEntry->ListEntry); - else - InsertTailList(&This->ServiceRoutines, &NewEntry->ListEntry); - - return STATUS_SUCCESS; -} - -static IInterruptSyncVtbl vt_IInterruptSyncVtbl = -{ - /* IUnknown methods */ - IInterruptSync_fnQueryInterface, - IInterruptSync_fnAddRef, - IInterruptSync_fnRelease, - /* IInterruptSync methods */ - IInterruptSync_fnCallSynchronizedRoutine, - IInterruptSync_fnGetKInterrupt, - IInterruptSync_fnConnect, - IInterruptSync_fnDisconnect, - IInterruptSync_fnRegisterServiceRoutine -}; - -/* - * @implemented - */ -NTSTATUS NTAPI -PcNewInterruptSync( - OUT PINTERRUPTSYNC* OutInterruptSync, - IN PUNKNOWN OuterUnknown OPTIONAL, - IN PRESOURCELIST ResourceList, - IN ULONG ResourceIndex, - IN INTERRUPTSYNCMODE Mode) -{ - IInterruptSyncImpl * This; - - DPRINT("PcNewInterruptSync entered OutInterruptSync %p OuterUnknown %p ResourceList %p ResourceIndex %u Mode %d\n", - OutInterruptSync, OuterUnknown, ResourceList, ResourceIndex, Mode); - - if (!OutInterruptSync || !ResourceList || Mode < InterruptSyncModeNormal || Mode > InterruptSyncModeRepeat) - return STATUS_INVALID_PARAMETER; - - if (ResourceIndex > ResourceList->lpVtbl->NumberOfEntriesOfType(ResourceList, CmResourceTypeInterrupt)) - return STATUS_INVALID_PARAMETER; - - - ResourceList->lpVtbl->AddRef(ResourceList); - - This = AllocateItem(NonPagedPool, sizeof(IInterruptSyncImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - /* initialize object */ - This->lpVtbl = &vt_IInterruptSyncVtbl; - This->ref = 1; - This->Mode = Mode; - This->ResourceIndex = ResourceIndex; - This->ResourceList = ResourceList; - InitializeListHead(&This->ServiceRoutines); - KeInitializeSpinLock(&This->Lock); - - *OutInterruptSync = (PINTERRUPTSYNC)&This->lpVtbl; - DPRINT("PcNewInterruptSync success %p\n", *OutInterruptSync); - return STATUS_SUCCESS; -} - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp b/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp new file mode 100644 index 00000000000..a957fc1deef --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp @@ -0,0 +1,338 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/interrupt.cpp + * PURPOSE: portcls interrupt object + * PROGRAMMER: Johannes Anderwald + */ + + +#include "private.hpp" + +typedef struct +{ + LIST_ENTRY ListEntry; + PINTERRUPTSYNCROUTINE SyncRoutine; + PVOID DynamicContext; +}SYNC_ENTRY, *PSYNC_ENTRY; + +class CInterruptSync : public IInterruptSync +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IInterruptSync; + CInterruptSync(IUnknown *OuterUnknown){} + virtual ~CInterruptSync(){} + +public: + + KSPIN_LOCK m_Lock; + LIST_ENTRY m_ServiceRoutines; + PKINTERRUPT m_Interrupt; + INTERRUPTSYNCMODE m_Mode; + PRESOURCELIST m_ResourceList; + ULONG m_ResourceIndex; + + PINTERRUPTSYNCROUTINE m_SyncRoutine; + PVOID m_DynamicContext; + + LONG m_Ref; + + friend BOOLEAN NTAPI CInterruptSynchronizedRoutine(IN PVOID ServiceContext); + friend BOOLEAN NTAPI IInterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext); +}; + + +//--------------------------------------------------------------- +// IUnknown methods +// + + + +NTSTATUS +NTAPI +CInterruptSync::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + DPRINT("CInterruptSync::QueryInterface: this %p\n", this); + + if (IsEqualGUIDAligned(refiid, IID_IInterruptSync) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + DPRINT1("CInterruptSync::QueryInterface: this %p UNKNOWN interface requested\n", this); + return STATUS_UNSUCCESSFUL; +} + +//--------------------------------------------------------------- +// CInterruptSync methods +// + + +BOOLEAN +NTAPI +CInterruptSynchronizedRoutine( + IN PVOID ServiceContext) +{ + CInterruptSync * This = (CInterruptSync*)ServiceContext; + DPRINT("CInterruptSynchronizedRoutine this %p SyncRoutine %p Context %p\n", This, This->m_SyncRoutine, This->m_DynamicContext); + return This->m_SyncRoutine(This, This->m_DynamicContext); +} + +NTSTATUS +NTAPI +CInterruptSync::CallSynchronizedRoutine( + IN PINTERRUPTSYNCROUTINE Routine, + IN PVOID DynamicContext) +{ + KIRQL OldIrql; + + DPRINT("CInterruptSync::CallSynchronizedRoutine this %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", this, Routine, DynamicContext, KeGetCurrentIrql(), m_Interrupt); + + if (!m_Interrupt) + { + DPRINT("CInterruptSync_CallSynchronizedRoutine %p no interrupt connected\n", this); + if (KeGetCurrentIrql() > DISPATCH_LEVEL) + return STATUS_UNSUCCESSFUL; + + KeAcquireSpinLock(&m_Lock, &OldIrql); + m_SyncRoutine = Routine; + m_DynamicContext = DynamicContext; + CInterruptSynchronizedRoutine((PVOID)this); + KeReleaseSpinLock(&m_Lock, OldIrql); + + return STATUS_SUCCESS; + } + + m_SyncRoutine = Routine; + m_DynamicContext = DynamicContext; + + if (KeSynchronizeExecution(m_Interrupt, CInterruptSynchronizedRoutine, (PVOID)this)) + return STATUS_SUCCESS; + else + return STATUS_UNSUCCESSFUL; +} + +PKINTERRUPT +NTAPI +CInterruptSync::GetKInterrupt() +{ + DPRINT("CInterruptSynchronizedRoutine\n"); + + return m_Interrupt; +} + +BOOLEAN +NTAPI +IInterruptServiceRoutine( + IN PKINTERRUPT Interrupt, + IN PVOID ServiceContext) +{ + PLIST_ENTRY CurEntry; + PSYNC_ENTRY Entry; + NTSTATUS Status; + BOOL Success; + + //DPRINT("IInterruptServiceRoutine Mode %u\n", m_Mode); + + CInterruptSync * This = (CInterruptSync*)ServiceContext; + + if (This->m_Mode == InterruptSyncModeNormal) + { + CurEntry = This->m_ServiceRoutines.Flink; + while (CurEntry != &This->m_ServiceRoutines) + { + Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry); + Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext); + if (NT_SUCCESS(Status)) + { + return TRUE; + } + CurEntry = CurEntry->Flink; + } + return FALSE; + } + else if (This->m_Mode == InterruptSyncModeAll) + { + CurEntry = This->m_ServiceRoutines.Flink; + while (CurEntry != &This->m_ServiceRoutines) + { + Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry); + Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext); + CurEntry = CurEntry->Flink; + } + DPRINT("Returning TRUE with mode InterruptSyncModeAll\n"); + return TRUE; //FIXME + } + else if (This->m_Mode == InterruptSyncModeRepeat) + { + do + { + Success = FALSE; + CurEntry = This->m_ServiceRoutines.Flink; + while (CurEntry != &This->m_ServiceRoutines) + { + Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry); + Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext); + if (NT_SUCCESS(Status)) + Success = TRUE; + CurEntry = CurEntry->Flink; + } + }while(Success); + DPRINT("Returning TRUE with mode InterruptSyncModeRepeat\n"); + return TRUE; //FIXME + } + else + { + DPRINT("Unknown mode %u\n", This->m_Mode); + return FALSE; //FIXME + } +} + + +NTSTATUS +NTAPI +CInterruptSync::Connect() +{ + NTSTATUS Status; + PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; + + DPRINT("CInterruptSync::Connect\n"); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + Descriptor = m_ResourceList->FindTranslatedEntry(CmResourceTypeInterrupt, m_ResourceIndex); + if (!Descriptor) + return STATUS_UNSUCCESSFUL; + + if (IsListEmpty(&m_ServiceRoutines)) + return STATUS_UNSUCCESSFUL; + + Status = IoConnectInterrupt(&m_Interrupt, + IInterruptServiceRoutine, + (PVOID)this, + &m_Lock, + Descriptor->u.Interrupt.Vector, + Descriptor->u.Interrupt.Level, + Descriptor->u.Interrupt.Level, + (KINTERRUPT_MODE)(Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED), + (Descriptor->Flags != CM_RESOURCE_INTERRUPT_LATCHED), + Descriptor->u.Interrupt.Affinity, + FALSE); + + DPRINT("CInterruptSync::Connect result %x\n", Status); + return Status; +} + + +VOID +NTAPI +CInterruptSync::Disconnect() +{ + DPRINT("CInterruptSync::Disconnect\n"); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_Interrupt) + { + DPRINT("CInterruptSync_Disconnect %p no interrupt connected\n", this); + return; + } + + IoDisconnectInterrupt(m_Interrupt); + m_Interrupt = NULL; +} + +NTSTATUS +NTAPI +CInterruptSync::RegisterServiceRoutine( + IN PINTERRUPTSYNCROUTINE Routine, + IN PVOID DynamicContext, + IN BOOLEAN First) +{ + PSYNC_ENTRY NewEntry; + + DPRINT("CInterruptSync::RegisterServiceRoutine\n"); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + NewEntry = (PSYNC_ENTRY)AllocateItem(NonPagedPool, sizeof(SYNC_ENTRY), TAG_PORTCLASS); + if (!NewEntry) + return STATUS_INSUFFICIENT_RESOURCES; + + NewEntry->SyncRoutine = Routine; + NewEntry->DynamicContext = DynamicContext; + + if (First) + InsertHeadList(&m_ServiceRoutines, &NewEntry->ListEntry); + else + InsertTailList(&m_ServiceRoutines, &NewEntry->ListEntry); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PcNewInterruptSync( + OUT PINTERRUPTSYNC* OutInterruptSync, + IN PUNKNOWN OuterUnknown OPTIONAL, + IN PRESOURCELIST ResourceList, + IN ULONG ResourceIndex, + IN INTERRUPTSYNCMODE Mode) +{ + CInterruptSync * This; + NTSTATUS Status; + + DPRINT("PcNewInterruptSync entered OutInterruptSync %p OuterUnknown %p ResourceList %p ResourceIndex %u Mode %d\n", + OutInterruptSync, OuterUnknown, ResourceList, ResourceIndex, Mode); + + if (!OutInterruptSync || !ResourceList || Mode < InterruptSyncModeNormal || Mode > InterruptSyncModeRepeat) + return STATUS_INVALID_PARAMETER; + + if (ResourceIndex > ResourceList->NumberOfEntriesOfType(CmResourceTypeInterrupt)) + return STATUS_INVALID_PARAMETER; + + This = new(NonPagedPool, TAG_PORTCLASS)CInterruptSync(OuterUnknown); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = This->QueryInterface(IID_IInterruptSync, (PVOID*)OutInterruptSync); + + if (!NT_SUCCESS(Status)) + { + delete This; + return Status; + } + + ResourceList->AddRef(); + + // + // initialize object + // + This->m_Mode = Mode; + This->m_ResourceIndex = ResourceIndex; + This->m_ResourceList = ResourceList; + InitializeListHead(&This->m_ServiceRoutines); + KeInitializeSpinLock(&This->m_Lock); + + return Status; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irp.c b/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp similarity index 75% rename from reactos/drivers/wdm/audio/backpln/portcls/irp.c rename to reactos/drivers/wdm/audio/backpln/portcls/irp.cpp index a2111cb1abe..ff9b9ca958d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irp.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS - * FILE: drivers/wdm/audio/backpln/portcls/irp.c + * FILE: drivers/wdm/audio/backpln/portcls/irp.cpp * PURPOSE: Port Class driver / IRP Handling * PROGRAMMER: Andrew Greenwood * Johannes Anderwald @@ -10,13 +10,8 @@ */ -#include "private.h" -#include +#include "private.hpp" -/* - Handles IRP_MJ_CREATE, which occurs when someone wants to make use of - a device. -*/ NTSTATUS NTAPI PortClsCreate( @@ -29,10 +24,6 @@ PortClsCreate( } -/* - IRP_MJ_PNP handler - Used for things like IRP_MN_START_DEVICE -*/ NTSTATUS NTAPI PortClsPnp( @@ -44,24 +35,20 @@ PortClsPnp( PIO_STACK_LOCATION IoStack; IResourceList* resource_list = NULL; - DPRINT("PortClsPnp called\n"); - DeviceExt = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; IoStack = IoGetCurrentIrpStackLocation(Irp); - ASSERT(DeviceExt); - /* - if IRP_MN_START_DEVICE, call the driver's customer start device routine. - Before we do so, we must create a ResourceList to pass to the Start - routine. - */ + DPRINT("PortClsPnp called %u\n", IoStack->MinorFunction); + + //PC_ASSERT(DeviceExt); + switch (IoStack->MinorFunction) { case IRP_MN_START_DEVICE: DPRINT("IRP_MN_START_DEVICE\n"); - /* Create the resource list */ + // Create the resource list Status = PcNewResourceList( &resource_list, NULL, @@ -76,22 +63,22 @@ PortClsPnp( return Status; } - /* forward irp to lower device object */ + // forward irp to lower device object Status = PcForwardIrpSynchronous(DeviceObject, Irp); if (!NT_SUCCESS(Status)) { - /* lower device object failed to start */ - resource_list->lpVtbl->Release(resource_list); - /* complete the request */ + // lower device object failed to start + resource_list->Release(); + // complete the request IoCompleteRequest(Irp, IO_NO_INCREMENT); - /* return result */ + // return result return Status; } - /* sanity check */ - ASSERT(DeviceExt->StartDevice); - /* Call the StartDevice routine */ + // sanity check + //PC_ASSERT(DeviceExt->StartDevice); + // Call the StartDevice routine DPRINT("Calling StartDevice at 0x%8p\n", DeviceExt->StartDevice); Status = DeviceExt->StartDevice(DeviceObject, Irp, resource_list); if (!NT_SUCCESS(Status)) @@ -102,7 +89,7 @@ PortClsPnp( return Status; } - /* Assign the resource list to our extension */ + // Assign the resource list to our extension DeviceExt->resources = resource_list; Irp->IoStatus.Status = STATUS_SUCCESS; @@ -110,13 +97,13 @@ PortClsPnp( return Status; case IRP_MN_REMOVE_DEVICE: - /* Clean up */ + // Clean up DPRINT("IRP_MN_REMOVE_DEVICE\n"); - DeviceExt->resources->lpVtbl->Release(DeviceExt->resources); + DeviceExt->resources->Release(); IoDeleteDevice(DeviceObject); - /* Do not complete? */ + // Do not complete? Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; @@ -146,10 +133,6 @@ PortClsPnp( return STATUS_UNSUCCESSFUL; } -/* - Power management. Handles IRP_MJ_POWER - (not implemented) -*/ NTSTATUS NTAPI PortClsPower( @@ -158,7 +141,7 @@ PortClsPower( { DPRINT("PortClsPower called\n"); - /* TODO */ + // TODO Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -167,10 +150,6 @@ PortClsPower( return STATUS_SUCCESS; } -/* - System control. Handles IRP_MJ_SYSTEM_CONTROL - (not implemented) -*/ NTSTATUS NTAPI PortClsSysControl( @@ -179,7 +158,7 @@ PortClsSysControl( { DPRINT("PortClsSysControl called\n"); - /* TODO */ + // TODO Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -199,33 +178,33 @@ PortClsShutdown( PPHYSICAL_CONNECTION Connection; DPRINT("PortClsShutdown called\n"); - /* get device extension */ + // get device extension DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; while(!IsListEmpty(&DeviceExtension->PhysicalConnectionList)) { - /* get connection entry */ + // get connection entry Entry = RemoveHeadList(&DeviceExtension->PhysicalConnectionList); Connection = (PPHYSICAL_CONNECTION)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION, Entry); if (Connection->FromSubDevice) { - /* release subdevice */ - Connection->FromSubDevice->lpVtbl->Release(Connection->FromSubDevice); + // release subdevice + Connection->FromSubDevice->Release(); } if (Connection->ToSubDevice) { - /* release subdevice */ - Connection->ToSubDevice->lpVtbl->Release(Connection->ToSubDevice); + // release subdevice + Connection->ToSubDevice->Release(); } FreeItem(Connection, TAG_PORTCLASS); } if (DeviceExtension->AdapterPowerManagement) { - /* release adapter power management */ - DPRINT1("Power %u\n", DeviceExtension->AdapterPowerManagement->lpVtbl->Release(DeviceExtension->AdapterPowerManagement)); + // release adapter power management + DPRINT1("Power %u\n", DeviceExtension->AdapterPowerManagement->Release()); } Irp->IoStatus.Status = STATUS_SUCCESS; @@ -235,19 +214,8 @@ PortClsShutdown( return STATUS_SUCCESS; } - - -/* - ========================================================================== - API EXPORTS - ========================================================================== -*/ - -/* - Drivers may implement their own IRP handlers. If a driver decides to let - PortCls handle the IRP, it can do so by calling this. -*/ -NTSTATUS NTAPI +NTSTATUS +NTAPI PcDispatchIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) @@ -260,7 +228,7 @@ PcDispatchIrp( switch ( IoStack->MajorFunction ) { - /* PortCls */ + // PortCls case IRP_MJ_CREATE : return PortClsCreate(DeviceObject, Irp); @@ -287,7 +255,7 @@ PcDispatchIrp( break; }; - /* If we reach here, we just complete the IRP */ + // If we reach here, we just complete the IRP Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -295,9 +263,7 @@ PcDispatchIrp( return STATUS_SUCCESS; } -/* - * @implemented - */ + NTSTATUS NTAPI PcCompleteIrp( @@ -305,9 +271,11 @@ PcCompleteIrp( IN PIRP Irp, IN NTSTATUS Status) { - ASSERT(DeviceObject); - ASSERT(Irp); - ASSERT(Status != STATUS_PENDING); +#if 0 + PC_ASSERT(DeviceObject); + PC_ASSERT(Irp); + PC_ASSERT(Status != STATUS_PENDING); +#endif Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -329,11 +297,28 @@ CompletionRoutine( return STATUS_MORE_PROCESSING_REQUIRED; } +#undef IoSetCompletionRoutine +#define IoSetCompletionRoutine(_Irp, \ + _CompletionRoutine, \ + _Context, \ + _InvokeOnSuccess, \ + _InvokeOnError, \ + _InvokeOnCancel) \ +{ \ + PIO_STACK_LOCATION _IrpSp; \ + _IrpSp = IoGetNextIrpStackLocation(_Irp); \ + _IrpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)(_CompletionRoutine); \ + _IrpSp->Context = (_Context); \ + _IrpSp->Control = 0; \ + if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \ + if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \ + if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \ +} -/* - * @implemented - */ -NTSTATUS NTAPI + + +NTSTATUS +NTAPI PcForwardIrpSynchronous( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) @@ -342,23 +327,23 @@ PcForwardIrpSynchronous( PPCLASS_DEVICE_EXTENSION DeviceExt; NTSTATUS Status; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - /* initialize the notification event */ + // initialize the notification event KeInitializeEvent(&Event, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, CompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE); - /* now call the driver */ + // now call the driver Status = IoCallDriver(DeviceExt->PrevDeviceObject, Irp); - /* did the request complete yet */ + // did the request complete yet if (Status == STATUS_PENDING) { - /* not yet, lets wait a bit */ + // not yet, lets wait a bit KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = Irp->IoStatus.Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c deleted file mode 100644 index 64047a642de..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c +++ /dev/null @@ -1,563 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/irpstream.c - * PURPOSE: IRP Stream handling - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - - -typedef struct -{ - IIrpQueueVtbl *lpVtbl; - - LONG ref; - - ULONG CurrentOffset; - LONG NumMappings; - ULONG NumDataAvailable; - BOOL StartStream; - KSPIN_CONNECT *ConnectDetails; - PKSDATAFORMAT_WAVEFORMATEX DataFormat; - - KSPIN_LOCK IrpListLock; - LIST_ENTRY IrpList; - LIST_ENTRY FreeIrpList; - PIRP Irp; - PVOID SilenceBuffer; - - ULONG OutOfMapping; - ULONG MaxFrameSize; - ULONG Alignment; - ULONG MinimumDataThreshold; - -}IIrpQueueImpl; - -NTSTATUS -NTAPI -IIrpQueue_fnQueryInterface( - IIrpQueue* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtbl; - _InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IIrpQueue_fnAddRef( - IIrpQueue* iface) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - return _InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IIrpQueue_fnRelease( - IIrpQueue* iface) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - _InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - - -NTSTATUS -NTAPI -IIrpQueue_fnInit( - IN IIrpQueue *iface, - IN KSPIN_CONNECT *ConnectDetails, - IN PKSDATAFORMAT DataFormat, - IN PDEVICE_OBJECT DeviceObject, - IN ULONG FrameSize, - IN ULONG Alignment, - IN PVOID SilenceBuffer) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - This->ConnectDetails = ConnectDetails; - This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat; - This->MaxFrameSize = FrameSize; - This->SilenceBuffer = SilenceBuffer; - This->Alignment = Alignment; - This->MinimumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)DataFormat)->WaveFormatEx.nAvgBytesPerSec / 3; - - InitializeListHead(&This->IrpList); - InitializeListHead(&This->FreeIrpList); - KeInitializeSpinLock(&This->IrpListLock); - - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -IIrpQueue_fnAddMapping( - IN IIrpQueue *iface, - IN PUCHAR Buffer, - IN ULONG BufferSize, - IN PIRP Irp) -{ - PKSSTREAM_HEADER Header; - NTSTATUS Status = STATUS_SUCCESS; - PIO_STACK_LOCATION IoStack; - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - /* get current irp stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - - if (!Buffer) - { - /* probe the stream irp */ - Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0); - - /* check for success */ - if (!NT_SUCCESS(Status)) - { - DPRINT1("KsProbeStreamIrp failed with %x\n", Status); - return Status; - } - - /* get the stream header */ - Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; - ASSERT(Header); - ASSERT(Irp->MdlAddress); - - if (Irp->RequestorMode != KernelMode) - { - /* use allocated mdl */ - Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); - } - } - else - { - /* HACK */ - Header = (PKSSTREAM_HEADER)Buffer; - } - - /* HACK */ - Irp->Tail.Overlay.DriverContext[2] = (PVOID)Header; - - /* sanity check */ - ASSERT(Header); - - /* dont exceed max frame size */ - //ASSERT(This->MaxFrameSize >= Header->DataUsed); - - /* increment num mappings */ - InterlockedIncrement(&This->NumMappings); - - /* increment num data available */ - This->NumDataAvailable += Header->DataUsed; - - /* mark irp as pending */ - IoMarkIrpPending(Irp); - - /* add irp to cancelable queue */ - KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL); - - /* done */ - return Status; -} - -NTSTATUS -NTAPI -IIrpQueue_fnGetMapping( - IN IIrpQueue *iface, - OUT PUCHAR * Buffer, - OUT PULONG BufferSize) -{ - PIRP Irp; - ULONG Offset; - //PIO_STACK_LOCATION IoStack; - PKSSTREAM_HEADER StreamHeader; - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - /* check if there is an irp in the partially processed */ - if (This->Irp) - { - /* use last irp */ - if (This->Irp->Cancel == FALSE) - { - Irp = This->Irp; - Offset = This->CurrentOffset; - } - else - { - /* irp has been cancelled */ - This->Irp->IoStatus.Status = STATUS_CANCELLED; - IoCompleteRequest(This->Irp, IO_NO_INCREMENT); - This->Irp = Irp = NULL; - } - } - else - { - /* get a fresh new irp from the queue */ - This->Irp = Irp = KsRemoveIrpFromCancelableQueue(&This->IrpList, &This->IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem); - This->CurrentOffset = Offset = 0; - } - - if (!Irp) - { - /* no irp available, use silence buffer */ - *Buffer = This->SilenceBuffer; - *BufferSize = This->MaxFrameSize; - /* flag for port wave pci driver */ - This->OutOfMapping = TRUE; - /* indicate flag to restart fast buffering */ - This->StartStream = FALSE; - return STATUS_SUCCESS; - } - -#if 0 - /* get current irp stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - - /* get stream header */ - StreamHeader = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; -#else - /* HACK get stream header */ - StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2]; -#endif - - /* sanity check */ - ASSERT(StreamHeader); - - /* store buffersize */ - *BufferSize = StreamHeader->DataUsed - Offset; - - /* store buffer */ - *Buffer = &((PUCHAR)StreamHeader->Data)[Offset]; - - /* unset flag that no irps are available */ - This->OutOfMapping = FALSE; - - return STATUS_SUCCESS; -} - -VOID -NTAPI -IIrpQueue_fnUpdateMapping( - IN IIrpQueue *iface, - IN ULONG BytesWritten) -{ - //PIO_STACK_LOCATION IoStack; - PKSSTREAM_HEADER StreamHeader; - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - if (!This->Irp) - { - /* silence buffer was used */ - return; - } - -#if 0 - /* get current irp stack location */ - IoStack = IoGetCurrentIrpStackLocation(This->Irp); - - /* get stream header */ - StreamHeader = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; -#else - /* HACK get stream header */ - StreamHeader = (PKSSTREAM_HEADER)This->Irp->Tail.Overlay.DriverContext[2]; -#endif - - /* sanity check */ - ASSERT(StreamHeader); - - /* add to current offset */ - This->CurrentOffset += BytesWritten; - - /* decrement available data counter */ - This->NumDataAvailable -= BytesWritten; - - if (This->CurrentOffset >= StreamHeader->DataUsed) - { - /* irp has been processed completly */ - This->Irp->IoStatus.Status = STATUS_SUCCESS; - - /* frame extend contains the original request size, DataUsed contains the real buffer size - * is different when kmixer performs channel conversion, upsampling etc - */ - This->Irp->IoStatus.Information = StreamHeader->FrameExtent; - - if (This->Irp->RequestorMode != KernelMode) - { - /* HACK - WDMAUD should pass PKSSTREAM_HEADERs */ - ExFreePool(StreamHeader->Data); - ExFreePool(StreamHeader); - } - - /* complete the request */ - IoCompleteRequest(This->Irp, IO_SOUND_INCREMENT); - /* remove irp as it is complete */ - This->Irp = NULL; - This->CurrentOffset = 0; - } -} - -ULONG -NTAPI -IIrpQueue_fnNumMappings( - IN IIrpQueue *iface) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - /* returns the amount of mappings available */ - return This->NumMappings; -} - -ULONG -NTAPI -IIrpQueue_fnNumData( - IN IIrpQueue *iface) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - /* returns the amount of audio stream data available */ - return This->NumDataAvailable; -} - - -BOOL -NTAPI -IIrpQueue_fnMinimumDataAvailable( - IN IIrpQueue *iface) -{ - BOOL Result; - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - if (This->StartStream) - return TRUE; - - if (This->MinimumDataThreshold < This->NumDataAvailable) - { - This->StartStream = TRUE; - Result = TRUE; - } - else - { - Result = FALSE; - } - return Result; -} - -BOOL -NTAPI -IIrpQueue_fnCancelBuffers( - IN IIrpQueue *iface) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - This->StartStream = FALSE; - return TRUE; -} - -VOID -NTAPI -IIrpQueue_fnUpdateFormat( - IN IIrpQueue *iface, - PKSDATAFORMAT DataFormat) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat; - This->MinimumDataThreshold = This->DataFormat->WaveFormatEx.nAvgBytesPerSec / 3; - This->StartStream = FALSE; - This->NumDataAvailable = 0; -} - -NTSTATUS -NTAPI -IIrpQueue_fnGetMappingWithTag( - IN IIrpQueue *iface, - IN PVOID Tag, - OUT PPHYSICAL_ADDRESS PhysicalAddress, - OUT PVOID *VirtualAddress, - OUT PULONG ByteCount, - OUT PULONG Flags) -{ - PKSSTREAM_HEADER StreamHeader; - PIRP Irp; - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - *Flags = 0; - ASSERT(Tag != NULL); - - /* get an irp from the queue */ - Irp = KsRemoveIrpFromCancelableQueue(&This->IrpList, &This->IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem); - - /* check if there is an irp */ - if (!Irp) - { - /* no irp available */ - This->OutOfMapping = TRUE; - This->StartStream = FALSE; - return STATUS_UNSUCCESSFUL; - } - - /* HACK get stream header */ - StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2]; - - /* store mapping in the free list */ - ExInterlockedInsertTailList(&This->FreeIrpList, &Irp->Tail.Overlay.ListEntry, &This->IrpListLock); - - /* return mapping */ - *PhysicalAddress = MmGetPhysicalAddress(StreamHeader->Data); - *VirtualAddress = StreamHeader->Data; - *ByteCount = StreamHeader->DataUsed; - - /* decrement mapping count */ - InterlockedDecrement(&This->NumMappings); - /* decrement num data available */ - This->NumDataAvailable -= StreamHeader->DataUsed; - - /* store tag in irp */ - Irp->Tail.Overlay.DriverContext[3] = Tag; - - /* done */ - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -IIrpQueue_fnReleaseMappingWithTag( - IN IIrpQueue *iface, - IN PVOID Tag) -{ - PIRP Irp; - PLIST_ENTRY CurEntry; - PKSSTREAM_HEADER StreamHeader; - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - DPRINT("IIrpQueue_fnReleaseMappingWithTag Tag %p\n", Tag); - - /* remove irp from used list */ - CurEntry = ExInterlockedRemoveHeadList(&This->FreeIrpList, &This->IrpListLock); - /* sanity check */ - ASSERT(CurEntry); - - /* get irp from list entry */ - Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry); - - /* HACK get stream header */ - StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2]; - - /* driver must release items in the same order */ - ASSERT(Irp->Tail.Overlay.DriverContext[3] == Tag); - - /* irp has been processed completly */ - Irp->IoStatus.Status = STATUS_SUCCESS; - - /* frame extend contains the original request size, DataUsed contains the real buffer size - * is different when kmixer performs channel conversion, upsampling etc - */ - Irp->IoStatus.Information = StreamHeader->FrameExtent; - - /* free stream data, no tag as wdmaud.drv does it atm */ - ExFreePool(StreamHeader->Data); - - /* free stream header, no tag as wdmaud.drv allocates it atm */ - ExFreePool(StreamHeader); - - /* complete the request */ - IoCompleteRequest(Irp, IO_SOUND_INCREMENT); - - return STATUS_SUCCESS; -} - -BOOL -NTAPI -IIrpQueue_fnHasLastMappingFailed( - IN IIrpQueue *iface) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - return This->OutOfMapping; -} - -VOID -NTAPI -IIrpQueue_fnPrintQueueStatus( - IN IIrpQueue *iface) -{ - -} - -VOID -NTAPI -IIrpQueue_fnSetMinimumDataThreshold( - IN IIrpQueue *iface, - ULONG MinimumDataThreshold) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - This->MinimumDataThreshold = MinimumDataThreshold; -} - -ULONG -NTAPI -IIrpQueue_fnGetMinimumDataThreshold( - IN IIrpQueue *iface) -{ - IIrpQueueImpl * This = (IIrpQueueImpl*)iface; - - return This->MinimumDataThreshold; -} - - -static IIrpQueueVtbl vt_IIrpQueue = -{ - IIrpQueue_fnQueryInterface, - IIrpQueue_fnAddRef, - IIrpQueue_fnRelease, - IIrpQueue_fnInit, - IIrpQueue_fnAddMapping, - IIrpQueue_fnGetMapping, - IIrpQueue_fnUpdateMapping, - IIrpQueue_fnNumMappings, - IIrpQueue_fnNumData, - IIrpQueue_fnMinimumDataAvailable, - IIrpQueue_fnCancelBuffers, - IIrpQueue_fnUpdateFormat, - IIrpQueue_fnGetMappingWithTag, - IIrpQueue_fnReleaseMappingWithTag, - IIrpQueue_fnHasLastMappingFailed, - IIrpQueue_fnPrintQueueStatus, - IIrpQueue_fnSetMinimumDataThreshold, - IIrpQueue_fnGetMinimumDataThreshold -}; - -NTSTATUS -NTAPI -NewIrpQueue( - IN IIrpQueue **Queue) -{ - IIrpQueueImpl *This = AllocateItem(NonPagedPool, sizeof(IIrpQueueImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - This->ref = 1; - This->lpVtbl = &vt_IIrpQueue; - - *Queue = (IIrpQueue*)This; - return STATUS_SUCCESS; - -} - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp new file mode 100644 index 00000000000..b5753e05b6a --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -0,0 +1,499 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/irpstream.cpp + * PURPOSE: IRP Stream handling + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + + +class CIrpQueue : public IIrpQueue +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IIrpQueue; + CIrpQueue(IUnknown *OuterUnknown){} + virtual ~CIrpQueue(){} + +protected: + ULONG m_CurrentOffset; + LONG m_NumMappings; + ULONG m_NumDataAvailable; + BOOL m_StartStream; + KSPIN_CONNECT * m_ConnectDetails; + PKSDATAFORMAT_WAVEFORMATEX m_DataFormat; + + KSPIN_LOCK m_IrpListLock; + LIST_ENTRY m_IrpList; + LIST_ENTRY m_FreeIrpList; + PIRP m_Irp; + PVOID m_SilenceBuffer; + + ULONG m_OutOfMapping; + ULONG m_MaxFrameSize; + ULONG m_Alignment; + ULONG m_MinimumDataThreshold; + + LONG m_Ref; + +}; + +NTSTATUS +NTAPI +CIrpQueue::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + if (IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CIrpQueue::Init( + IN KSPIN_CONNECT *ConnectDetails, + IN PKSDATAFORMAT DataFormat, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG FrameSize, + IN ULONG Alignment, + IN PVOID SilenceBuffer) +{ + m_ConnectDetails = ConnectDetails; + m_DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat; + m_MaxFrameSize = FrameSize; + m_SilenceBuffer = SilenceBuffer; + m_Alignment = Alignment; + m_MinimumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)DataFormat)->WaveFormatEx.nAvgBytesPerSec / 3; + + InitializeListHead(&m_IrpList); + InitializeListHead(&m_FreeIrpList); + KeInitializeSpinLock(&m_IrpListLock); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CIrpQueue::AddMapping( + IN PUCHAR Buffer, + IN ULONG BufferSize, + IN PIRP Irp) +{ + PKSSTREAM_HEADER Header; + NTSTATUS Status = STATUS_SUCCESS; + PIO_STACK_LOCATION IoStack; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (!Buffer) + { + // probe the stream irp + Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0); + + // check for success + if (!NT_SUCCESS(Status)) + { + DPRINT1("KsProbeStreamIrp failed with %x\n", Status); + return Status; + } + + // get the stream header + Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + PC_ASSERT(Header); + PC_ASSERT(Irp->MdlAddress); + + if (Irp->RequestorMode != KernelMode) + { + // use allocated mdl + Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + } + } + else + { + // HACK + Header = (PKSSTREAM_HEADER)Buffer; + } + + // HACK + Irp->Tail.Overlay.DriverContext[2] = (PVOID)Header; + + // sanity check + PC_ASSERT(Header); + + // dont exceed max frame size + PC_ASSERT(m_MaxFrameSize >= Header->DataUsed); + + // increment num mappings + InterlockedIncrement(&m_NumMappings); + + // increment num data available + m_NumDataAvailable += Header->DataUsed; + + // mark irp as pending + IoMarkIrpPending(Irp); + + // add irp to cancelable queue + KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, Irp, KsListEntryTail, NULL); + + // done + return Status; +} + +NTSTATUS +NTAPI +CIrpQueue::GetMapping( + OUT PUCHAR * Buffer, + OUT PULONG BufferSize) +{ + PIRP Irp; + ULONG Offset; + //PIO_STACK_LOCATION IoStack; + PKSSTREAM_HEADER StreamHeader; + + // check if there is an irp in the partially processed + if (m_Irp) + { + // use last irp + if (m_Irp->Cancel == FALSE) + { + Irp = m_Irp; + Offset = m_CurrentOffset; + } + else + { + // irp has been cancelled + m_Irp->IoStatus.Status = STATUS_CANCELLED; + IoCompleteRequest(m_Irp, IO_NO_INCREMENT); + m_Irp = Irp = NULL; + } + } + else + { + // get a fresh new irp from the queue + m_Irp = Irp = KsRemoveIrpFromCancelableQueue(&m_IrpList, &m_IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem); + m_CurrentOffset = Offset = 0; + } + + if (!Irp) + { + // no irp available, use silence buffer + *Buffer = (PUCHAR)m_SilenceBuffer; + *BufferSize = m_MaxFrameSize; + // flag for port wave pci driver + m_OutOfMapping = TRUE; + // indicate flag to restart fast buffering + m_StartStream = FALSE; + return STATUS_SUCCESS; + } + +#if 0 + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get stream header + StreamHeader = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; +#else + // HACK get stream header + StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2]; +#endif + + // sanity check + PC_ASSERT(StreamHeader); + + // store buffersize + *BufferSize = StreamHeader->DataUsed - Offset; + + // store buffer + *Buffer = &((PUCHAR)StreamHeader->Data)[Offset]; + + // unset flag that no irps are available + m_OutOfMapping = FALSE; + + return STATUS_SUCCESS; +} + +VOID +NTAPI +CIrpQueue::UpdateMapping( + IN ULONG BytesWritten) +{ + //PIO_STACK_LOCATION IoStack; + PKSSTREAM_HEADER StreamHeader; + + if (!m_Irp) + { + // silence buffer was used + return; + } + +#if 0 + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(m_Irp); + + // get stream header + StreamHeader = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; +#else + // HACK get stream header + StreamHeader = (PKSSTREAM_HEADER)m_Irp->Tail.Overlay.DriverContext[2]; +#endif + + // sanity check + // ASSERT(StreamHeader); + + // add to current offset + m_CurrentOffset += BytesWritten; + + // decrement available data counter + m_NumDataAvailable -= BytesWritten; + + if (m_CurrentOffset >= StreamHeader->DataUsed) + { + // irp has been processed completly + m_Irp->IoStatus.Status = STATUS_SUCCESS; + + // frame extend contains the original request size, DataUsed contains the real buffer size + //is different when kmixer performs channel conversion, upsampling etc + + m_Irp->IoStatus.Information = StreamHeader->FrameExtent; + + if (m_Irp->RequestorMode != KernelMode) + { + // HACK - WDMAUD should pass PKSSTREAM_HEADERs + ExFreePool(StreamHeader->Data); + ExFreePool(StreamHeader); + } + + // complete the request + IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT); + // remove irp as it is complete + m_Irp = NULL; + m_CurrentOffset = 0; + } +} + +ULONG +NTAPI +CIrpQueue::NumMappings() +{ + + // returns the amount of mappings available + return m_NumMappings; +} + +ULONG +NTAPI +CIrpQueue::NumData() +{ + // returns the amount of audio stream data available + return m_NumDataAvailable; +} + + +BOOL +NTAPI +CIrpQueue::MinimumDataAvailable() +{ + BOOL Result; + + if (m_StartStream) + return TRUE; + + if (m_MinimumDataThreshold < m_NumDataAvailable) + { + m_StartStream = TRUE; + Result = TRUE; + } + else + { + Result = FALSE; + } + return Result; +} + +BOOL +NTAPI +CIrpQueue::CancelBuffers() +{ + + m_StartStream = FALSE; + return TRUE; +} + +VOID +NTAPI +CIrpQueue::UpdateFormat( + PKSDATAFORMAT DataFormat) +{ + m_DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat; + m_MinimumDataThreshold = m_DataFormat->WaveFormatEx.nAvgBytesPerSec / 3; + m_StartStream = FALSE; + m_NumDataAvailable = 0; +} + +NTSTATUS +NTAPI +CIrpQueue::GetMappingWithTag( + IN PVOID Tag, + OUT PPHYSICAL_ADDRESS PhysicalAddress, + OUT PVOID *VirtualAddress, + OUT PULONG ByteCount, + OUT PULONG Flags) +{ + PKSSTREAM_HEADER StreamHeader; + PIRP Irp; + + *Flags = 0; + PC_ASSERT(Tag != NULL); + + // get an irp from the queue + Irp = KsRemoveIrpFromCancelableQueue(&m_IrpList, &m_IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem); + + // check if there is an irp + if (!Irp) + { + // no irp available + m_OutOfMapping = TRUE; + m_StartStream = FALSE; + return STATUS_UNSUCCESSFUL; + } + + // HACK get stream header + StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2]; + + // store mapping in the free list + ExInterlockedInsertTailList(&m_FreeIrpList, &Irp->Tail.Overlay.ListEntry, &m_IrpListLock); + + // return mapping + *PhysicalAddress = MmGetPhysicalAddress(StreamHeader->Data); + *VirtualAddress = StreamHeader->Data; + *ByteCount = StreamHeader->DataUsed; + + // decrement mapping count + InterlockedDecrement(&m_NumMappings); + // decrement num data available + m_NumDataAvailable -= StreamHeader->DataUsed; + + // store tag in irp + Irp->Tail.Overlay.DriverContext[3] = Tag; + + // done + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CIrpQueue::ReleaseMappingWithTag( + IN PVOID Tag) +{ + PIRP Irp; + PLIST_ENTRY CurEntry; + PKSSTREAM_HEADER StreamHeader; + + DPRINT("CIrpQueue::ReleaseMappingWithTag Tag %p\n", Tag); + + // remove irp from used list + CurEntry = ExInterlockedRemoveHeadList(&m_FreeIrpList, &m_IrpListLock); + // sanity check + PC_ASSERT(CurEntry); + + // get irp from list entry + Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry); + + // HACK get stream header + StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2]; + + // driver must release items in the same order + PC_ASSERT(Irp->Tail.Overlay.DriverContext[3] == Tag); + + // irp has been processed completly + Irp->IoStatus.Status = STATUS_SUCCESS; + + // frame extend contains the original request size, DataUsed contains the real buffer size + // is different when kmixer performs channel conversion, upsampling etc + + Irp->IoStatus.Information = StreamHeader->FrameExtent; + + // free stream data, no tag as wdmaud.drv does it atm + ExFreePool(StreamHeader->Data); + + // free stream header, no tag as wdmaud.drv allocates it atm + ExFreePool(StreamHeader); + + // complete the request + IoCompleteRequest(Irp, IO_SOUND_INCREMENT); + + return STATUS_SUCCESS; +} + +BOOL +NTAPI +CIrpQueue::HasLastMappingFailed() +{ + return m_OutOfMapping; +} + +VOID +NTAPI +CIrpQueue::PrintQueueStatus() +{ + +} + +VOID +NTAPI +CIrpQueue::SetMinimumDataThreshold( + ULONG MinimumDataThreshold) +{ + + m_MinimumDataThreshold = MinimumDataThreshold; +} + +ULONG +NTAPI +CIrpQueue::GetMinimumDataThreshold() +{ + return m_MinimumDataThreshold; +} + + +NTSTATUS +NTAPI +NewIrpQueue( + IN IIrpQueue **Queue) +{ + CIrpQueue *This = new(NonPagedPool, TAG_PORTCLASS)CIrpQueue(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + *Queue = (IIrpQueue*)This; + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/miniport.c b/reactos/drivers/wdm/audio/backpln/portcls/miniport.cpp similarity index 64% rename from reactos/drivers/wdm/audio/backpln/portcls/miniport.c rename to reactos/drivers/wdm/audio/backpln/portcls/miniport.cpp index 3e81dfa05d2..a6856a67cc3 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/miniport.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/miniport.cpp @@ -1,17 +1,15 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/miniport.c + * FILE: drivers/wdm/audio/backpln/portcls/miniport.cpp * PURPOSE: Miniport construction api * PROGRAMMER: Andrew Greenwood */ -#include "private.h" +#include "private.hpp" -/* - * @implemented - */ -NTSTATUS NTAPI +NTSTATUS +NTAPI PcNewMiniport( OUT PMINIPORT* OutMiniport, IN REFCLSID ClassId) @@ -19,7 +17,7 @@ PcNewMiniport( NTSTATUS Status = STATUS_INVALID_PARAMETER; DPRINT("PcNewMiniport entered\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!OutMiniport) { @@ -27,14 +25,14 @@ PcNewMiniport( return STATUS_INVALID_PARAMETER; } - if (IsEqualGUIDAligned(ClassId, &CLSID_MiniportDriverDMusUART) || - IsEqualGUIDAligned(ClassId, &CLSID_MiniportDriverUart) || - IsEqualGUIDAligned(ClassId, &CLSID_MiniportDriverDMusUARTCapture)) + if (IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverDMusUART) || + IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverUart) || + IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverDMusUARTCapture)) { Status = NewMiniportDMusUART(OutMiniport, ClassId); } - else if (IsEqualGUIDAligned(ClassId, &CLSID_MiniportDriverFmSynth) || - IsEqualGUIDAligned(ClassId, &CLSID_MiniportDriverFmSynthWithVol)) + else if (IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverFmSynth) || + IsEqualGUIDAligned(ClassId, CLSID_MiniportDriverFmSynthWithVol)) { Status = NewMiniportFmSynth(OutMiniport, ClassId); } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/miniport_dmus.c b/reactos/drivers/wdm/audio/backpln/portcls/miniport_dmus.c deleted file mode 100644 index 7b929690c5f..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/miniport_dmus.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/miniport_dmus.c - * PURPOSE: DirectMusic miniport - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IMiniportDMusVtbl *lpVtbl; - LONG ref; - CLSID ClassId; - -}IMiniportDMusImpl; - - - -/* IUnknown methods */ - -NTSTATUS -NTAPI -IMiniportDMus_fnQueryInterface( - IMiniportDMus* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IMiniportDMusImpl * This = (IMiniportDMusImpl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IMiniportDMus)) - { - *Output = &This->lpVtbl; - _InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IMiniportDMus_fnAddRef( - IMiniportDMus* iface) -{ - IMiniportDMusImpl * This = (IMiniportDMusImpl*)iface; - - return _InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IMiniportDMust_fnRelease( - IMiniportDMus* iface) -{ - IMiniportDMusImpl * This = (IMiniportDMusImpl*)iface; - - _InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - -/* IMiniport methods */ - -NTSTATUS -NTAPI -IMiniportDMus_fnDataRangeIntersection( - IN IMiniportDMus * iface, - IN ULONG PinId, - IN PKSDATARANGE DataRange, - IN PKSDATARANGE MatchingDataRange, - IN ULONG OutputBufferLength, - OUT PVOID ResultantFormat OPTIONAL, - OUT PULONG ResultantFormatLength) -{ - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -IMiniportDMus_fnGetDescription( - IN IMiniportDMus * iface, - OUT PPCFILTER_DESCRIPTOR *Description - ) -{ - return STATUS_UNSUCCESSFUL; -} - -/* IMinIMiniportDMus methods */ - -HRESULT -NTAPI -IMiniportDMus_fnInit( - IN IMiniportDMus * iface, - IN PUNKNOWN pUnknownAdapter, - IN PRESOURCELIST pResourceList, - IN PPORTDMUS pPort, - OUT PSERVICEGROUP *ppServiceGroup - ) -{ - return STATUS_UNSUCCESSFUL; -} - -HRESULT -NTAPI -IMiniportDMus_fnNewStream( - IN IMiniportDMus * iface, - OUT PMXF *ppMXF, - IN PUNKNOWN pOuterUnknown OPTIONAL, - IN POOL_TYPE PoolType, - IN ULONG uPinId, - IN DMUS_STREAM_TYPE StreamType, - IN PKSDATAFORMAT pDataFormat, - OUT PSERVICEGROUP *ppServiceGroup, - IN PAllocatorMXF pAllocatorMXF, - IN PMASTERCLOCK pMasterClock, - OUT PULONGLONG puuSchedulePreFetch - ) -{ - return STATUS_UNSUCCESSFUL; -} - -VOID -NTAPI -IMiniportDMus_fnService( - IN IMiniportDMus * iface) -{ - -} - -static IMiniportDMusVtbl vt_PortDMusVtbl = -{ - /* IUnknown */ - IMiniportDMus_fnQueryInterface, - IMiniportDMus_fnAddRef, - IMiniportDMust_fnRelease, - /* IMiniport */ - IMiniportDMus_fnGetDescription, - IMiniportDMus_fnDataRangeIntersection, - /* IMiniportDMus */ - IMiniportDMus_fnInit, - IMiniportDMus_fnService, - IMiniportDMus_fnNewStream -}; - -NTSTATUS -NewMiniportDMusUART( - OUT PMINIPORT* OutMiniport, - IN REFCLSID ClassId) -{ - IMiniportDMusImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IMiniportDMusImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - /* Initialize IMiniportDMus */ - RtlCopyMemory(&This->ClassId, ClassId, sizeof(CLSID)); - This->ref = 1; - This->lpVtbl = &vt_PortDMusVtbl; - *OutMiniport = (PMINIPORT)&This->lpVtbl; - - return STATUS_SUCCESS; -} - - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp b/reactos/drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp new file mode 100644 index 00000000000..65d32ed5a33 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp @@ -0,0 +1,135 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp + * PURPOSE: DirectMusic miniport + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CMiniportDMus : public IMiniportDMus +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IMiniportDMus; + CMiniportDMus(IUnknown *OuterUnknown){} + virtual ~CMiniportDMus(){} + +protected: + LONG m_Ref; + +}; + +// IUnknown methods + +NTSTATUS +NTAPI +CMiniportDMus::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + if (IsEqualGUIDAligned(refiid, IID_IMiniportDMus)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +// IMiniport methods + +NTSTATUS +NTAPI +CMiniportDMus::DataRangeIntersection( + IN ULONG PinId, + IN PKSDATARANGE DataRange, + IN PKSDATARANGE MatchingDataRange, + IN ULONG OutputBufferLength, + OUT PVOID ResultantFormat OPTIONAL, + OUT PULONG ResultantFormatLength) +{ + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CMiniportDMus::GetDescription( + OUT PPCFILTER_DESCRIPTOR *Description) +{ + return STATUS_UNSUCCESSFUL; +} + +HRESULT +NTAPI +CMiniportDMus::Init( + IN PUNKNOWN pUnknownAdapter, + IN PRESOURCELIST pResourceList, + IN PPORTDMUS pPort, + OUT PSERVICEGROUP *ppServiceGroup + ) +{ + return STATUS_UNSUCCESSFUL; +} + +HRESULT +NTAPI +CMiniportDMus::NewStream( + OUT PMXF *ppMXF, + IN PUNKNOWN pOuterUnknown OPTIONAL, + IN POOL_TYPE PoolType, + IN ULONG uPinId, + IN DMUS_STREAM_TYPE StreamType, + IN PKSDATAFORMAT pDataFormat, + OUT PSERVICEGROUP *ppServiceGroup, + IN PAllocatorMXF pAllocatorMXF, + IN PMASTERCLOCK pMasterClock, + OUT PULONGLONG puuSchedulePreFetch + ) +{ + return STATUS_UNSUCCESSFUL; +} + +VOID +NTAPI +CMiniportDMus::Service() +{ + +} + +NTSTATUS +NewMiniportDMusUART( + OUT PMINIPORT* OutMiniport, + IN REFCLSID ClassId) +{ + CMiniportDMus * This; + + This = new(NonPagedPool, TAG_PORTCLASS)CMiniportDMus(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + *OutMiniport = (PMINIPORT)This; + This->AddRef(); + + return STATUS_SUCCESS; +} + + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/miniport_fmsynth.c b/reactos/drivers/wdm/audio/backpln/portcls/miniport_fmsynth.cpp similarity index 91% rename from reactos/drivers/wdm/audio/backpln/portcls/miniport_fmsynth.c rename to reactos/drivers/wdm/audio/backpln/portcls/miniport_fmsynth.cpp index b1db834cea1..54080a998b5 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/miniport_fmsynth.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/miniport_fmsynth.cpp @@ -1,12 +1,12 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/miniport_fmsynth.c + * FILE: drivers/wdm/audio/backpln/portcls/miniport_fmsynth.cpp * PURPOSE: Miniport FM Synth * PROGRAMMER: Johannes Anderwald */ -#include "private.h" +#include "private.hpp" NTSTATUS NewMiniportFmSynth( diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c deleted file mode 100644 index a971425202e..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c +++ /dev/null @@ -1,1197 +0,0 @@ -/* - * 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" - -typedef struct -{ - IPortPinDMusVtbl *lpVtbl; - IServiceSinkVtbl *lpVtblServiceSink; - IMasterClockVtbl *lpVtblMasterClock; - IAllocatorMXFVtbl *lpVtblAllocatorMXF; - IMXFVtbl *lpVtblMXF; - - LONG ref; - IPortDMus * Port; - IPortFilterDMus * Filter; - KSPIN_DESCRIPTOR * KsPinDescriptor; - PMINIPORTDMUS Miniport; - - PSERVICEGROUP ServiceGroup; - - PMXF Mxf; - ULONGLONG SchedulePreFetch; - NPAGED_LOOKASIDE_LIST LookAsideEvent; - NPAGED_LOOKASIDE_LIST LookAsideBuffer; - - PMINIPORTMIDI MidiMiniport; - PMINIPORTMIDISTREAM MidiStream; - - - KSSTATE State; - PKSDATAFORMAT Format; - KSPIN_CONNECT * ConnectDetails; - - BOOL Capture; - PDEVICE_OBJECT DeviceObject; - IIrpQueue * IrpQueue; - - ULONG TotalPackets; - ULONG PreCompleted; - ULONG PostCompleted; - - ULONG LastTag; - -}IPortPinDMusImpl; - -typedef struct -{ - DMUS_KERNEL_EVENT Event; - PVOID Tag; -}DMUS_KERNEL_EVENT_WITH_TAG, *PDMUS_KERNEL_EVENT_WITH_TAG; - -typedef struct -{ - IPortPinDMusImpl *Pin; - PIO_WORKITEM WorkItem; - KSSTATE State; -}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; - -//================================================================================================================================== - - -static -NTSTATUS -NTAPI -IMasterClock_fnQueryInterface( - IMasterClock* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblMasterClock); - - DPRINT("IServiceSink_fnQueryInterface entered\n"); - - if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtblServiceSink; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -static -ULONG -NTAPI -IMasterClock_fnAddRef( - IMasterClock* iface) -{ - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblMasterClock); - DPRINT("IServiceSink_fnAddRef entered\n"); - - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IMasterClock_fnRelease( - IMasterClock* iface) -{ - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblMasterClock); - - 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 -NTSTATUS -NTAPI -IMasterClock_fnGetTime( - IMasterClock* iface, - OUT REFERENCE_TIME *prtTime) -{ - UNIMPLEMENTED - return STATUS_SUCCESS; -} - -static IMasterClockVtbl vt_IMasterClock = -{ - IMasterClock_fnQueryInterface, - IMasterClock_fnAddRef, - IMasterClock_fnRelease, - IMasterClock_fnGetTime -}; - -//================================================================================================================================== - - -static -NTSTATUS -NTAPI -IAllocatorMXF_fnQueryInterface( - IAllocatorMXF* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); - - DPRINT("IServiceSink_fnQueryInterface entered\n"); - - if (IsEqualGUIDAligned(refiid, &IID_IAllocatorMXF) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtblServiceSink; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -static -ULONG -NTAPI -IAllocatorMXF_fnAddRef( - IAllocatorMXF* iface) -{ - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); - DPRINT("IServiceSink_fnAddRef entered\n"); - - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IAllocatorMXF_fnRelease( - IAllocatorMXF* iface) -{ - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); - - 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 -NTSTATUS -NTAPI -IAllocatorMXF_fnGetMessage( - IAllocatorMXF* iface, - OUT PDMUS_KERNEL_EVENT * ppDMKEvt) -{ - PVOID Buffer; - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); - - Buffer = ExAllocateFromNPagedLookasideList(&This->LookAsideEvent); - if (!Buffer) - return STATUS_INSUFFICIENT_RESOURCES; - - *ppDMKEvt = Buffer; - RtlZeroMemory(Buffer, sizeof(DMUS_KERNEL_EVENT)); - return STATUS_SUCCESS; -} - -static -USHORT -NTAPI -IAllocatorMXF_fnGetBufferSize( - IAllocatorMXF* iface) -{ - return PAGE_SIZE; -} - -static -NTSTATUS -NTAPI -IAllocatorMXF_fnGetBuffer( - IAllocatorMXF* iface, - OUT PBYTE * ppBuffer) -{ - PVOID Buffer; - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); - - Buffer = ExAllocateFromNPagedLookasideList(&This->LookAsideBuffer); - if (!Buffer) - return STATUS_INSUFFICIENT_RESOURCES; - - *ppBuffer = Buffer; - RtlZeroMemory(Buffer, PAGE_SIZE); - return STATUS_SUCCESS; -} - -static -NTSTATUS -NTAPI -IAllocatorMXF_fnPutBuffer( - IAllocatorMXF* iface, - IN PBYTE pBuffer) -{ - PDMUS_KERNEL_EVENT_WITH_TAG Event = (PDMUS_KERNEL_EVENT_WITH_TAG)pBuffer; - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); - - This->IrpQueue->lpVtbl->ReleaseMappingWithTag(This->IrpQueue, Event->Tag); - - ExFreeToNPagedLookasideList(&This->LookAsideBuffer, pBuffer); - return STATUS_SUCCESS; -} - -static -NTSTATUS -NTAPI -IAllocatorMXF_fnSetState( - IAllocatorMXF* iface, - IN KSSTATE State) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -static -NTSTATUS -NTAPI -IAllocatorMXF_fnPutMessage( - IAllocatorMXF* iface, - IN PDMUS_KERNEL_EVENT pDMKEvt) -{ - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); - - ExFreeToNPagedLookasideList(&This->LookAsideEvent, pDMKEvt); - return STATUS_SUCCESS; -} - -static -NTSTATUS -NTAPI -IAllocatorMXF_fnConnectOutput( - IAllocatorMXF* iface, - IN PMXF sinkMXF) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -static -NTSTATUS -NTAPI -IAllocatorMXF_fnDisconnectOutput( - IAllocatorMXF* iface, - IN PMXF sinkMXF) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -static IAllocatorMXFVtbl vt_IAllocatorMXF = -{ - IAllocatorMXF_fnQueryInterface, - IAllocatorMXF_fnAddRef, - IAllocatorMXF_fnRelease, - IAllocatorMXF_fnSetState, - IAllocatorMXF_fnPutMessage, - IAllocatorMXF_fnConnectOutput, - IAllocatorMXF_fnDisconnectOutput, - IAllocatorMXF_fnGetMessage, - IAllocatorMXF_fnGetBufferSize, - IAllocatorMXF_fnGetBuffer, - IAllocatorMXF_fnPutBuffer -}; - -//================================================================================================================================== - -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; - KSSTATE State; - NTSTATUS Status; - PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; - - 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 (This->MidiStream) - { - Status = This->MidiStream->lpVtbl->SetState(This->MidiStream, State); - } - else - { - Status = This->Mxf->lpVtbl->SetState(This->Mxf, State); - } - - if (NT_SUCCESS(Status)) - { - /* Set internal state to requested state */ - 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); - -} - -VOID -TransferMidiDataToDMus( - IPortPinDMusImpl * This) -{ - NTSTATUS Status; - PHYSICAL_ADDRESS PhysicalAddress; - ULONG BufferSize, Flags; - PVOID Buffer; - PDMUS_KERNEL_EVENT_WITH_TAG Event, LastEvent = NULL, Root = NULL; - - do - { - This->LastTag++; - Status = This->IrpQueue->lpVtbl->GetMappingWithTag(This->IrpQueue, UlongToPtr(This->LastTag), &PhysicalAddress, &Buffer, &BufferSize, &Flags); - if (!NT_SUCCESS(Status)) - { - break; - } - - Status = IAllocatorMXF_fnGetMessage((IAllocatorMXF*)&This->lpVtblAllocatorMXF, (PDMUS_KERNEL_EVENT*)&Event); - if (!NT_SUCCESS(Status)) - break; - - //FIXME - //set up struct - //Event->Event.usFlags = DMUS_KEF_EVENT_COMPLETE; - Event->Event.cbStruct = sizeof(DMUS_KERNEL_EVENT); - Event->Event.cbEvent = BufferSize; - Event->Event.uData.pbData = Buffer; - - - if (!Root) - Root = Event; - else - LastEvent->Event.pNextEvt = (struct _DMUS_KERNEL_EVENT *)Event; - - LastEvent = Event; - LastEvent->Event.pNextEvt = NULL; - LastEvent->Tag = UlongToPtr(This->LastTag); - - }while(TRUE); - - if (!Root) - { - SetStreamState(This, KSSTATE_STOP); - return; - } - - Status = This->Mxf->lpVtbl->PutMessage(This->Mxf, (PDMUS_KERNEL_EVENT)Root); - DPRINT("Status %x\n", Status); -} - - -static -VOID -NTAPI -IServiceSink_fnRequestService( - IServiceSink* iface) -{ - IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink); - - ASSERT_IRQL(DISPATCH_LEVEL); - - if (This->MidiStream) - { - TransferMidiData(This); - } - else if (This->Mxf) - { - TransferMidiDataToDMus(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 || This->Mxf) - { - 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; - - StatusBlock->Status = STATUS_PENDING; - 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; - - StatusBlock->Status = STATUS_PENDING; - return TRUE; -} - -/* - * @implemented - */ -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; - } - else - { - Status = This->Miniport->lpVtbl->NewStream(This->Miniport, - &This->Mxf, - NULL, - NonPagedPool, - ConnectDetails->PinId, - Capture, //FIXME - This->Format, - &This->ServiceGroup, - (PAllocatorMXF)&This->lpVtblAllocatorMXF, - (PMASTERCLOCK)&This->lpVtblMasterClock, - &This->SchedulePreFetch); - - DPRINT("IPortPinDMus_fnInit Status %x\n", Status); - - if (!NT_SUCCESS(Status)) - return Status; - - if (Capture == DMUS_STREAM_MIDI_CAPTURE) - { - Status = This->Mxf->lpVtbl->ConnectOutput(This->Mxf, (PMXF)&This->lpVtblMXF); - if (!NT_SUCCESS(Status)) - { - DPRINT("IMXF_ConnectOutput failed with Status %x\n", Status); - return Status; - } - } - - ExInitializeNPagedLookasideList(&This->LookAsideEvent, NULL, NULL, 0, sizeof(DMUS_KERNEL_EVENT_WITH_TAG), TAG_PORTCLASS, 0); - ExInitializeNPagedLookasideList(&This->LookAsideBuffer, NULL, NULL, 0, PAGE_SIZE, TAG_PORTCLASS, 0); - } - - 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, 0, NULL /*FIXME*/); - 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; - This->lpVtblMasterClock = &vt_IMasterClock; - This->lpVtblAllocatorMXF = &vt_IAllocatorMXF; - - - /* store result */ - *OutPin = (IPortPinDMus*)&This->lpVtbl; - - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp new file mode 100644 index 00000000000..c18acf047d4 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp @@ -0,0 +1,808 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/pin_dmus.cpp + * PURPOSE: DMus IRP Audio Pin + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortPinDMus : public IPortPinDMus +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortPinDMus; + IMP_IServiceSink; + IMP_IMasterClock; + IMP_IAllocatorMXF; + + CPortPinDMus(IUnknown * OuterUnknown){} + virtual ~CPortPinDMus(){} + +protected: + VOID TransferMidiDataToDMus(); + VOID TransferMidiData(); + + VOID NTAPI SetStreamState(IN KSSTATE State); + + + IPortDMus * m_Port; + IPortFilterDMus * m_Filter; + KSPIN_DESCRIPTOR * m_KsPinDescriptor; + PMINIPORTDMUS m_Miniport; + + PSERVICEGROUP m_ServiceGroup; + + PMXF m_Mxf; + ULONGLONG m_SchedulePreFetch; + NPAGED_LOOKASIDE_LIST m_LookAsideEvent; + NPAGED_LOOKASIDE_LIST m_LookAsideBuffer; + + PMINIPORTMIDI m_MidiMiniport; + PMINIPORTMIDISTREAM m_MidiStream; + + + KSSTATE m_State; + PKSDATAFORMAT m_Format; + KSPIN_CONNECT * m_ConnectDetails; + + DMUS_STREAM_TYPE m_Capture; + PDEVICE_OBJECT m_DeviceObject; + IIrpQueue * m_IrpQueue; + + ULONG m_TotalPackets; + ULONG m_PreCompleted; + ULONG m_PostCompleted; + + ULONG m_LastTag; + + LONG m_Ref; + + friend VOID NTAPI SetStreamWorkerRoutineDMus(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); + friend VOID NTAPI CloseStreamRoutineDMus(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); + +}; + +typedef struct +{ + DMUS_KERNEL_EVENT Event; + PVOID Tag; +}DMUS_KERNEL_EVENT_WITH_TAG, *PDMUS_KERNEL_EVENT_WITH_TAG; + +typedef struct +{ + CPortPinDMus *Pin; + PIO_WORKITEM WorkItem; + KSSTATE State; +}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; + +//================================================================================================================================== +NTSTATUS +NTAPI +CPortPinDMus::GetTime(OUT REFERENCE_TIME *prtTime) +{ + UNIMPLEMENTED + return STATUS_SUCCESS; +} + +//================================================================================================================================== +NTSTATUS +NTAPI +CPortPinDMus::GetMessage( + OUT PDMUS_KERNEL_EVENT * ppDMKEvt) +{ + PVOID Buffer; + + Buffer = ExAllocateFromNPagedLookasideList(&m_LookAsideEvent); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + *ppDMKEvt = (PDMUS_KERNEL_EVENT)Buffer; + RtlZeroMemory(Buffer, sizeof(DMUS_KERNEL_EVENT)); + return STATUS_SUCCESS; +} + +USHORT +NTAPI +CPortPinDMus::GetBufferSize() +{ + return PAGE_SIZE; +} + +NTSTATUS +NTAPI +CPortPinDMus::GetBuffer( + OUT PBYTE * ppBuffer) +{ + PVOID Buffer; + + Buffer = ExAllocateFromNPagedLookasideList(&m_LookAsideBuffer); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + *ppBuffer = (PBYTE)Buffer; + RtlZeroMemory(Buffer, PAGE_SIZE); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortPinDMus::PutBuffer( + IN PBYTE pBuffer) +{ + PDMUS_KERNEL_EVENT_WITH_TAG Event = (PDMUS_KERNEL_EVENT_WITH_TAG)pBuffer; + + m_IrpQueue->ReleaseMappingWithTag(Event->Tag); + + ExFreeToNPagedLookasideList(&m_LookAsideBuffer, pBuffer); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortPinDMus::SetState( + IN KSSTATE State) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +NTAPI +CPortPinDMus::PutMessage( + IN PDMUS_KERNEL_EVENT pDMKEvt) +{ + ExFreeToNPagedLookasideList(&m_LookAsideEvent, pDMKEvt); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortPinDMus::ConnectOutput( + IN PMXF sinkMXF) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +NTAPI +CPortPinDMus::DisconnectOutput( + IN PMXF sinkMXF) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +//================================================================================================================================== + +VOID +NTAPI +SetStreamWorkerRoutineDMus( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + CPortPinDMus* This; + KSSTATE State; + NTSTATUS Status; + PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; + + This = Ctx->Pin; + State = Ctx->State; + + IoFreeWorkItem(Ctx->WorkItem); + FreeItem(Ctx, TAG_PORTCLASS); + + // Has the audio stream resumed? + if (This->m_IrpQueue->NumMappings() && State == KSSTATE_STOP) + return; + + // Set the state + if (This->m_MidiStream) + { + Status = This->m_MidiStream->SetState(State); + } + else + { + Status = This->m_Mxf->SetState(State); + } + + if (NT_SUCCESS(Status)) + { + // Set internal state to requested state + This->m_State = State; + + if (This->m_State == KSSTATE_STOP) + { + // reset start stream + This->m_IrpQueue->CancelBuffers(); //FIX function name + DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->m_PreCompleted, This->m_PostCompleted); + } + } +} + +VOID +NTAPI +CPortPinDMus::SetStreamState( + IN KSSTATE State) +{ + PIO_WORKITEM WorkItem; + PSETSTREAM_CONTEXT Context; + + PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + // Has the audio stream resumed? + if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP) + return; + + // Has the audio state already been set? + if (m_State == State) + return; + + // allocate set state context + Context = (PSETSTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS); + + if (!Context) + return; + + // allocate work item + WorkItem = IoAllocateWorkItem(m_DeviceObject); + + if (!WorkItem) + { + ExFreePool(Context); + return; + } + + Context->Pin = this; + Context->WorkItem = WorkItem; + Context->State = State; + + // queue the work item + IoQueueWorkItem(WorkItem, SetStreamWorkerRoutineDMus, DelayedWorkQueue, (PVOID)Context); +} + +VOID +CPortPinDMus::TransferMidiData() +{ + NTSTATUS Status; + PUCHAR Buffer; + ULONG BufferSize; + ULONG BytesWritten; + + do + { + Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + { + SetStreamState(KSSTATE_STOP); + return; + } + + if (m_Capture) + { + Status = m_MidiStream->Read(Buffer, BufferSize, &BytesWritten); + if (!NT_SUCCESS(Status)) + { + DPRINT("Read failed with %x\n", Status); + return; + } + } + else + { + Status = m_MidiStream->Write(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; + } + + m_IrpQueue->UpdateMapping(BytesWritten); + + }while(TRUE); + +} + +VOID +CPortPinDMus::TransferMidiDataToDMus() +{ + NTSTATUS Status; + PHYSICAL_ADDRESS PhysicalAddress; + ULONG BufferSize, Flags; + PVOID Buffer; + PDMUS_KERNEL_EVENT_WITH_TAG Event, LastEvent = NULL, Root = NULL; + + do + { + m_LastTag++; + Status = m_IrpQueue->GetMappingWithTag(UlongToPtr(m_LastTag), &PhysicalAddress, &Buffer, &BufferSize, &Flags); + if (!NT_SUCCESS(Status)) + { + break; + } + + Status = GetMessage((PDMUS_KERNEL_EVENT*)&Event); + if (!NT_SUCCESS(Status)) + break; + + //FIXME + //set up struct + //Event->Event.usFlags = DMUS_KEF_EVENT_COMPLETE; + Event->Event.cbStruct = sizeof(DMUS_KERNEL_EVENT); + Event->Event.cbEvent = BufferSize; + Event->Event.uData.pbData = (PBYTE)Buffer; + + + if (!Root) + Root = Event; + else + LastEvent->Event.pNextEvt = (struct _DMUS_KERNEL_EVENT *)Event; + + LastEvent = Event; + LastEvent->Event.pNextEvt = NULL; + LastEvent->Tag = UlongToPtr(m_LastTag); + + }while(TRUE); + + if (!Root) + { + SetStreamState(KSSTATE_STOP); + return; + } + + Status = m_Mxf->PutMessage((PDMUS_KERNEL_EVENT)Root); + DPRINT("Status %x\n", Status); +} + + + +VOID +NTAPI +CPortPinDMus::RequestService() +{ + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + if (m_MidiStream) + { + TransferMidiData(); + } + else if (m_Mxf) + { + TransferMidiDataToDMus(); + } +} + +//================================================================================================================================== +NTSTATUS +NTAPI +CPortPinDMus::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortPinDMus::NewIrpTarget( + 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; +} + +NTSTATUS +NTAPI +CPortPinDMus::DeviceIoControl( + 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; +} + +NTSTATUS +NTAPI +CPortPinDMus::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinDMus::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinDMus::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + + +VOID +NTAPI +CloseStreamRoutineDMus( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PMINIPORTMIDISTREAM Stream = NULL; + NTSTATUS Status; + ISubdevice *ISubDevice; + PSUBDEVICE_DESCRIPTOR Descriptor; + CPortPinDMus * This; + PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; + + This = (CPortPinDMus*)Ctx->Pin; + + if (This->m_MidiStream) + { + if (This->m_State != KSSTATE_STOP) + { + This->m_MidiStream->SetState(KSSTATE_STOP); + } + Stream = This->m_MidiStream; + This->m_MidiStream = NULL; + } + + if (This->m_ServiceGroup) + { + This->m_ServiceGroup->RemoveMember(PSERVICESINK(This)); + } + + Status = This->m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); + if (NT_SUCCESS(Status)) + { + Status = ISubDevice->GetDescriptor(&Descriptor); + if (NT_SUCCESS(Status)) + { + Descriptor->Factory.Instances[This->m_ConnectDetails->PinId].CurrentPinInstanceCount--; + ISubDevice->Release(); + } + } + + if (This->m_Format) + { + ExFreePool(This->m_Format); + This->m_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->m_Filter->FreePin(PPORTPINDMUS(This)); + + if (Stream) + { + DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql()); + Stream->Release(); + } +} + +NTSTATUS +NTAPI +CPortPinDMus::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PCLOSESTREAM_CONTEXT Ctx; + + if (m_MidiStream || m_Mxf) + { + Ctx = (PCLOSESTREAM_CONTEXT)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 = this; + + IoMarkIrpPending(Irp); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_PENDING; + + // defer work item + IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutineDMus, 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; + +} + +NTSTATUS +NTAPI +CPortPinDMus::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinDMus::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortPinDMus::FastDeviceIoControl( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortPinDMus::FastRead( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortPinDMus::FastWrite( + 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) +{ + return FALSE; +} + +NTSTATUS +NTAPI +CPortPinDMus::Init( + IN PPORTDMUS Port, + IN PPORTFILTERDMUS Filter, + IN KSPIN_CONNECT * ConnectDetails, + IN KSPIN_DESCRIPTOR * KsPinDescriptor, + IN PDEVICE_OBJECT DeviceObject) +{ + NTSTATUS Status; + PKSDATAFORMAT DataFormat; + DMUS_STREAM_TYPE Type; + + Port->AddRef(); + Filter->AddRef(); + + m_Port = Port; + m_Filter = Filter; + m_KsPinDescriptor = KsPinDescriptor; + m_ConnectDetails = ConnectDetails; + m_DeviceObject = DeviceObject; + + GetDMusMiniport(Port, &m_Miniport, &m_MidiMiniport); + + DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); + + DPRINT("CPortPinDMus::Init entered\n"); + + m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!m_Format) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); + + if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) + { + Type = DMUS_STREAM_MIDI_RENDER; + } + else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) + { + Type = DMUS_STREAM_MIDI_CAPTURE; + } + else + { + DPRINT1("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow); + KeBugCheck(0); + } + + Status = NewIrpQueue(&m_IrpQueue); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to allocate IrpQueue with %x\n", Status); + return Status; + } + + if (m_MidiMiniport) + { + Status = m_MidiMiniport->NewStream(&m_MidiStream, NULL, NonPagedPool, ConnectDetails->PinId, Type, m_Format, &m_ServiceGroup); + + DPRINT("CPortPinDMus::Init Status %x\n", Status); + + if (!NT_SUCCESS(Status)) + return Status; + } + else + { + Status = m_Miniport->NewStream(&m_Mxf, NULL, NonPagedPool, ConnectDetails->PinId, Type, m_Format, &m_ServiceGroup, PAllocatorMXF(this), PMASTERCLOCK(this),&m_SchedulePreFetch); + + DPRINT("CPortPinDMus::Init Status %x\n", Status); + + if (!NT_SUCCESS(Status)) + return Status; + + if (Type == DMUS_STREAM_MIDI_CAPTURE) + { + Status = m_Mxf->ConnectOutput(PMXF(this)); + if (!NT_SUCCESS(Status)) + { + DPRINT("IMXF_ConnectOutput failed with Status %x\n", Status); + return Status; + } + } + + ExInitializeNPagedLookasideList(&m_LookAsideEvent, NULL, NULL, 0, sizeof(DMUS_KERNEL_EVENT_WITH_TAG), TAG_PORTCLASS, 0); + ExInitializeNPagedLookasideList(&m_LookAsideBuffer, NULL, NULL, 0, PAGE_SIZE, TAG_PORTCLASS, 0); + } + + if (m_ServiceGroup) + { + Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to add pin to service group\n"); + return Status; + } + m_ServiceGroup->SupportDelayedService(); + } + + Status = m_IrpQueue->Init(ConnectDetails, m_Format, DeviceObject, 0, 0, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IrpQueue_Init failed with %x\n", Status); + return Status; + } + + m_State = KSSTATE_STOP; + m_Capture = Type; + + return STATUS_SUCCESS; +} + +VOID +NTAPI +CPortPinDMus::Notify() +{ + m_ServiceGroup->RequestService(); +} + +NTSTATUS +NewPortPinDMus( + OUT IPortPinDMus ** OutPin) +{ + CPortPinDMus * This; + + This = new (NonPagedPool, TAG_PORTCLASS)CPortPinDMus(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // store result + *OutPin = (IPortPinDMus*)This; + + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c deleted file mode 100644 index 69b480e9636..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c +++ /dev/null @@ -1,1262 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c - * PURPOSE: WaveCyclic IRP Audio Pin - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IPortPinWaveCyclicVtbl *lpVtbl; - IServiceSinkVtbl *lpVtblServiceSink; - - LONG ref; - IPortWaveCyclic * Port; - IPortFilterWaveCyclic * Filter; - KSPIN_DESCRIPTOR * KsPinDescriptor; - PMINIPORTWAVECYCLIC Miniport; - PSERVICEGROUP ServiceGroup; - PDMACHANNEL DmaChannel; - PMINIPORTWAVECYCLICSTREAM Stream; - KSSTATE State; - PKSDATAFORMAT Format; - KSPIN_CONNECT * ConnectDetails; - - PVOID CommonBuffer; - ULONG CommonBufferSize; - ULONG CommonBufferOffset; - - IIrpQueue * IrpQueue; - - ULONG FrameSize; - BOOL Capture; - - ULONG TotalPackets; - ULONG StopCount; - - ULONG Delay; -}IPortPinWaveCyclicImpl; - - -typedef struct -{ - IPortPinWaveCyclicImpl *Pin; - PIO_WORKITEM WorkItem; - KSSTATE State; -}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; - -NTSTATUS -NTAPI -IPortWaveCyclic_fnProcessNewIrp( - IPortPinWaveCyclicImpl * This); - -//================================================================================================================================== - -static -NTSTATUS -NTAPI -IServiceSink_fnQueryInterface( - IServiceSink* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, 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) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, lpVtblServiceSink); - DPRINT("IServiceSink_fnAddRef entered\n"); - - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IServiceSink_fnRelease( - IServiceSink* iface) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, 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 -UpdateCommonBuffer( - IPortPinWaveCyclicImpl * This, - ULONG Position, - ULONG MaxTransferCount) -{ - ULONG BufferLength; - ULONG BytesToCopy; - ULONG BufferSize; - PUCHAR Buffer; - NTSTATUS Status; - - BufferLength = Position - This->CommonBufferOffset; - BufferLength = min(BufferLength, MaxTransferCount); - - while(BufferLength) - { - Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - return; - - BytesToCopy = min(BufferLength, BufferSize); - - if (This->Capture) - { - This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, - Buffer, - (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, - BytesToCopy); - } - else - { - This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, - (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, - Buffer, - BytesToCopy); - } - - This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy); - This->CommonBufferOffset += BytesToCopy; - - BufferLength = Position - This->CommonBufferOffset; - } -} - -static -VOID -UpdateCommonBufferOverlap( - IPortPinWaveCyclicImpl * This, - ULONG Position, - ULONG MaxTransferCount) -{ - ULONG BufferLength, Length, Gap; - ULONG BytesToCopy; - ULONG BufferSize; - PUCHAR Buffer; - NTSTATUS Status; - - - BufferLength = Gap = This->CommonBufferSize - This->CommonBufferOffset; - BufferLength = Length = min(BufferLength, MaxTransferCount); - while(BufferLength) - { - Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - return; - - BytesToCopy = min(BufferLength, BufferSize); - - if (This->Capture) - { - This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, - Buffer, - (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, - BytesToCopy); - } - else - { - This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, - (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, - Buffer, - BytesToCopy); - } - - This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy); - This->CommonBufferOffset += BytesToCopy; - - BufferLength = This->CommonBufferSize - This->CommonBufferOffset; - } - - if (Gap == Length) - { - This->CommonBufferOffset = 0; - - MaxTransferCount -= Length; - - if (MaxTransferCount) - { - UpdateCommonBuffer(This, Position, MaxTransferCount); - } - } -} - -VOID -NTAPI -SetStreamWorkerRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - IPortPinWaveCyclicImpl * This; - PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; - KSSTATE State; - ULONG MinimumDataThreshold; - ULONG MaximumDataThreshold; - - 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; - - /* Has the audio state already been set? */ - if (This->State == State) - return; - - /* Set the state */ - if (NT_SUCCESS(This->Stream->lpVtbl->SetState(This->Stream, State))) - { - /* Set internal state */ - This->State = State; - - if (This->State == KSSTATE_STOP) - { - /* reset start stream */ - This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name - - /* increase stop counter */ - This->StopCount++; - /* get current data threshold */ - MinimumDataThreshold = This->IrpQueue->lpVtbl->GetMinimumDataThreshold(This->IrpQueue); - /* get maximum data threshold */ - MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec; - /* increase minimum data threshold by a third sec */ - MinimumDataThreshold += This->FrameSize * 10; - - /* assure it has not exceeded */ - MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold); - /* store minimum data threshold */ - This->IrpQueue->lpVtbl->SetMinimumDataThreshold(This->IrpQueue, MinimumDataThreshold); - - DPRINT1("Stopping TotalPackets %u StopCount %u\n", This->TotalPackets, This->StopCount); - } - if (This->State == KSSTATE_RUN) - { - DPRINT1("State RUN %x MinAvailable %u CommonBufferSize %u Offset %u\n", State, This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue), This->CommonBufferSize, This->CommonBufferOffset); - } - } -} - -VOID -NTAPI -SetStreamState( - IN IPortPinWaveCyclicImpl * 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 = GetDeviceObject(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); -} - -static -VOID -NTAPI -IServiceSink_fnRequestService( - IServiceSink* iface) -{ - ULONG Position; - NTSTATUS Status; - PUCHAR Buffer; - ULONG BufferSize; - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, 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("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u\n", Position, Buffer, This->CommonBufferSize, BufferSize); - - if (Position < This->CommonBufferOffset) - { - UpdateCommonBufferOverlap(This, Position, This->FrameSize); - } - else if (Position >= This->CommonBufferOffset) - { - UpdateCommonBuffer(This, Position, This->FrameSize); - } -} - -static IServiceSinkVtbl vt_IServiceSink = -{ - IServiceSink_fnQueryInterface, - IServiceSink_fnAddRef, - IServiceSink_fnRelease, - IServiceSink_fnRequestService -}; - -//================================================================================================================================== -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnQueryInterface( - IPortPinWaveCyclic* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)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 -IPortPinWaveCyclic_fnAddRef( - IPortPinWaveCyclic* iface) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -/* - * @implemented - */ -ULONG -NTAPI -IPortPinWaveCyclic_fnRelease( - IPortPinWaveCyclic* iface) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - return This->ref; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnNewIrpTarget( - IN IPortPinWaveCyclic* 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 -IPortPinWaveCyclic_HandleKsProperty( - IN IPortPinWaveCyclic * iface, - IN PIRP Irp) -{ - PKSPROPERTY Property; - NTSTATUS Status; - UNICODE_STRING GuidString; - PIO_STACK_LOCATION IoStack; - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)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, &GUID_NULL)) - { - if (Property->Flags & KSPROPERTY_TYPE_SETSUPPORT) - { - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID)) - { - /* buffer too small */ - Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; - Irp->IoStatus.Information = sizeof(GUID); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_BUFFER_OVERFLOW; - } - /* FIXME copy guids - * KSPROPSETID_Audio when available - * KSPROPSETID_Sysaudio_Pin - */ - RtlMoveMemory(Irp->UserBuffer, &KSPROPSETID_Connection, sizeof(GUID)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(GUID); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; - } - } - - - if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Connection)) - { - if (Property->Id == KSPROPERTY_CONNECTION_STATE) - { - PKSSTATE State = (PKSSTATE)Irp->UserBuffer; - - ASSERT_IRQL(DISPATCH_LEVEL); - 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; - } - } - else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING) - { - PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)Irp->UserBuffer; - - ASSERT_IRQL(DISPATCH_LEVEL); - /* Validate input buffer */ - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSALLOCATOR_FRAMING)) - { - Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_BUFFER_TOO_SMALL; - } - /* Clear frame structure */ - RtlZeroMemory(Framing, sizeof(KSALLOCATOR_FRAMING)); - /* store requested frame size */ - Framing->FrameSize = This->FrameSize; - /* FIXME fill in struct */ - - Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); - 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); - RtlFreeUnicodeString(&GuidString); - - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -IPortPinWaveCyclic_HandleKsStream( - IN IPortPinWaveCyclic * iface, - IN PIRP Irp) -{ - NTSTATUS Status; - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - InterlockedIncrement((PLONG)&This->TotalPackets); - - DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u Pre %u Post %u State %x MinData %u\n", This->TotalPackets, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue)); - - Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, NULL, 0, Irp); - - return STATUS_PENDING; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnDeviceIoControl( - IN IPortPinWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - - IoStack = IoGetCurrentIrpStackLocation(Irp); - - - if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) - { - return IPortPinWaveCyclic_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 IPortPinWaveCyclic_HandleKsStream(iface, Irp); - } - else - { - return KsDefaultDeviceIoCompletion(DeviceObject, Irp); - } - - UNIMPLEMENTED - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_UNSUCCESSFUL; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnRead( - IN IPortPinWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnWrite( - IN IPortPinWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnFlush( - IN IPortPinWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -VOID -NTAPI -CloseStreamRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PMINIPORTWAVECYCLICSTREAM Stream; - IPortPinWaveCyclicImpl * This; - NTSTATUS Status; - PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; - - This = (IPortPinWaveCyclicImpl*)Ctx->Pin; - - if (This->State != KSSTATE_STOP) - { - /* stop stream in case it hasn't been */ - Status = This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); - if (!NT_SUCCESS(Status)) - DPRINT1("Warning: failed to stop stream with %x\n", Status); - - This->State = KSSTATE_STOP; - } - - if (This->Format) - { - /* free 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); - - /* release reference to port driver */ - This->Port->lpVtbl->Release(This->Port); - - /* release reference to filter instance */ - This->Filter->lpVtbl->Release(This->Filter); - - if (This->Stream) - { - Stream = This->Stream; - This->Stream = NULL; - This->Filter->lpVtbl->FreePin(This->Filter, (IPortPinWaveCyclic*)This); - DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql()); - Stream->lpVtbl->Release(Stream); - } -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnClose( - IN IPortPinWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PCLOSESTREAM_CONTEXT Ctx; - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - if (This->Stream) - { - /* allocate a close context */ - Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS); - if (!Ctx) - { - DPRINT1("Failed to allocate stream context\n"); - goto cleanup; - } - /* allocate work context */ - Ctx->WorkItem = IoAllocateWorkItem(DeviceObject); - if (!Ctx->WorkItem) - { - DPRINT1("Failed to allocate work item\n"); - goto cleanup; - } - /* setup the close context */ - Ctx->Irp = Irp; - Ctx->Pin = (PVOID)This; - - IoMarkIrpPending(Irp); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_PENDING; - - /* remove member from service group */ - This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink); - - /* 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 -IPortPinWaveCyclic_fnQuerySecurity( - IN IPortPinWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnSetSecurity( - IN IPortPinWaveCyclic* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortPinWaveCyclic_fnFastDeviceIoControl( - IN IPortPinWaveCyclic* 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) -{ - return KsDispatchFastIoDeviceControlFailure(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, StatusBlock, DeviceObject); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortPinWaveCyclic_fnFastRead( - IN IPortPinWaveCyclic* 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; - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - /* HACK to be removed */ - - DPRINT("IPortPinWaveCyclic_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; - - StatusBlock->Status = STATUS_PENDING; - - return TRUE; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortPinWaveCyclic_fnFastWrite( - IN IPortPinWaveCyclic* 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; - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - /* HACK to be removed */ - - InterlockedIncrement((PLONG)&This->TotalPackets); - - DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u State %x MinData %u\n", This->TotalPackets, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue)); - - Packet = (PCONTEXT_WRITE)Buffer; - Irp = Packet->Irp; - - Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer, Length, Irp); - - if (!NT_SUCCESS(Status)) - return FALSE; - - StatusBlock->Status = STATUS_PENDING; - - return TRUE; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWaveCyclic_fnInit( - IN IPortPinWaveCyclic* iface, - IN PPORTWAVECYCLIC Port, - IN PPORTFILTERWAVECYCLIC Filter, - IN KSPIN_CONNECT * ConnectDetails, - IN KSPIN_DESCRIPTOR * KsPinDescriptor) -{ - NTSTATUS Status; - PKSDATAFORMAT DataFormat; - PDEVICE_OBJECT DeviceObject; - BOOL Capture; - PVOID SilenceBuffer; - //IDrmAudioStream * DrmAudio = NULL; - - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - This->KsPinDescriptor = KsPinDescriptor; - This->ConnectDetails = ConnectDetails; - This->Miniport = GetWaveCyclicMiniport(Port); - - DeviceObject = GetDeviceObject(Port); - - DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); - - DPRINT("IPortPinWaveCyclic_fnInit entered\n"); - - This->Format = ExAllocatePoolWithTag(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)) - return Status; - - 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, - NULL, - NonPagedPool, - ConnectDetails->PinId, - Capture, - This->Format, - &This->DmaChannel, - &This->ServiceGroup); -#if 0 - Status = This->Stream->lpVtbl->QueryInterface(This->Stream, &IID_IDrmAudioStream, (PVOID*)&DrmAudio); - if (NT_SUCCESS(Status)) - { - DRMRIGHTS DrmRights; - DPRINT1("Got IID_IDrmAudioStream interface %p\n", DrmAudio); - - DrmRights.CopyProtect = FALSE; - DrmRights.Reserved = 0; - DrmRights.DigitalOutputDisable = FALSE; - - Status = DrmAudio->lpVtbl->SetContentId(DrmAudio, 1, &DrmRights); - DPRINT("Status %x\n", Status); - } -#endif - - DPRINT("IPortPinWaveCyclic_fnInit Status %x\n", Status); - - if (!NT_SUCCESS(Status)) - return Status; - - 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); - This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); - This->State = KSSTATE_STOP; - This->CommonBufferOffset = 0; - This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel); - This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel); - This->Capture = Capture; - /* delay of 10 milisec */ - This->Delay = Int32x32To64(10, -10000); - - Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize); - - SilenceBuffer = AllocateItem(NonPagedPool, This->FrameSize, TAG_PORTCLASS); - if (!SilenceBuffer) - return STATUS_INSUFFICIENT_RESOURCES; - - This->Stream->lpVtbl->Silence(This->Stream, SilenceBuffer, This->FrameSize); - - Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, DataFormat, DeviceObject, This->FrameSize, 0, SilenceBuffer); - if (!NT_SUCCESS(Status)) - { - This->IrpQueue->lpVtbl->Release(This->IrpQueue); - return Status; - } - - Port->lpVtbl->AddRef(Port); - Filter->lpVtbl->AddRef(Filter); - - This->Port = Port; - This->Filter = Filter; - - //This->Stream->lpVtbl->SetFormat(This->Stream, (PKSDATAFORMAT)This->Format); - DPRINT1("Setting state to acquire %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_ACQUIRE)); - DPRINT1("Setting state to pause %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE)); - This->State = KSSTATE_PAUSE; - - //This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, This->Delay); - - return STATUS_SUCCESS; -} - -/* - * @unimplemented - */ -ULONG -NTAPI -IPortPinWaveCyclic_fnGetCompletedPosition( - IN IPortPinWaveCyclic* iface) -{ - UNIMPLEMENTED; - return 0; -} - -/* - * @unimplemented - */ -ULONG -NTAPI -IPortPinWaveCyclic_fnGetCycleCount( - IN IPortPinWaveCyclic* iface) -{ - UNIMPLEMENTED; - return 0; -} - -/* - * @implemented - */ -ULONG -NTAPI -IPortPinWaveCyclic_fnGetDeviceBufferSize( - IN IPortPinWaveCyclic* iface) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - return This->CommonBufferSize; -} - -/* - * @implemented - */ -PVOID -NTAPI -IPortPinWaveCyclic_fnGetIrpStream( - IN IPortPinWaveCyclic* iface) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - return (PVOID)This->IrpQueue; -} - - -/* - * @implemented - */ -PMINIPORT -NTAPI -IPortPinWaveCyclic_fnGetMiniport( - IN IPortPinWaveCyclic* iface) -{ - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; - - return (PMINIPORT)This->Miniport; -} - -static IPortPinWaveCyclicVtbl vt_IPortPinWaveCyclic = -{ - IPortPinWaveCyclic_fnQueryInterface, - IPortPinWaveCyclic_fnAddRef, - IPortPinWaveCyclic_fnRelease, - IPortPinWaveCyclic_fnNewIrpTarget, - IPortPinWaveCyclic_fnDeviceIoControl, - IPortPinWaveCyclic_fnRead, - IPortPinWaveCyclic_fnWrite, - IPortPinWaveCyclic_fnFlush, - IPortPinWaveCyclic_fnClose, - IPortPinWaveCyclic_fnQuerySecurity, - IPortPinWaveCyclic_fnSetSecurity, - IPortPinWaveCyclic_fnFastDeviceIoControl, - IPortPinWaveCyclic_fnFastRead, - IPortPinWaveCyclic_fnFastWrite, - IPortPinWaveCyclic_fnInit, - IPortPinWaveCyclic_fnGetCompletedPosition, - IPortPinWaveCyclic_fnGetCycleCount, - IPortPinWaveCyclic_fnGetDeviceBufferSize, - IPortPinWaveCyclic_fnGetIrpStream, - IPortPinWaveCyclic_fnGetMiniport -}; - - - - -NTSTATUS NewPortPinWaveCyclic( - OUT IPortPinWaveCyclic ** OutPin) -{ - IPortPinWaveCyclicImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IPortPinWaveCyclicImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - /* initialize IPortPinWaveCyclic */ - This->ref = 1; - This->lpVtbl = &vt_IPortPinWaveCyclic; - This->lpVtblServiceSink = &vt_IServiceSink; - - - /* store result */ - *OutPin = (IPortPinWaveCyclic*)&This->lpVtbl; - - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp new file mode 100644 index 00000000000..3a5d014f01b --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -0,0 +1,1077 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp + * PURPOSE: WaveCyclic IRP Audio Pin + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortPinWaveCyclic : public IPortPinWaveCyclic, + public IServiceSink +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortPinWaveCyclic; + IMP_IServiceSink; + CPortPinWaveCyclic(IUnknown *OuterUnknown){} + virtual ~CPortPinWaveCyclic(){} + + VOID SetState(KSSTATE State); + +protected: + + VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount); + VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount); + VOID NTAPI SetStreamState(IN KSSTATE State); + NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); + NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); + + + friend VOID NTAPI CloseStreamRoutineWaveCyclic(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); + friend VOID NTAPI SetStreamWorkerRoutineWaveCyclic(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); + + IPortWaveCyclic * m_Port; + IPortFilterWaveCyclic * m_Filter; + KSPIN_DESCRIPTOR * m_KsPinDescriptor; + PMINIPORTWAVECYCLIC m_Miniport; + PSERVICEGROUP m_ServiceGroup; + PDMACHANNEL m_DmaChannel; + PMINIPORTWAVECYCLICSTREAM m_Stream; + KSSTATE m_State; + PKSDATAFORMAT m_Format; + KSPIN_CONNECT * m_ConnectDetails; + + PVOID m_CommonBuffer; + ULONG m_CommonBufferSize; + ULONG m_CommonBufferOffset; + + IIrpQueue * m_IrpQueue; + + ULONG m_FrameSize; + BOOL m_Capture; + + ULONG m_TotalPackets; + ULONG m_StopCount; + + ULONG m_Delay; + + LONG m_Ref; +}; + + +typedef struct +{ + CPortPinWaveCyclic *Pin; + PIO_WORKITEM WorkItem; + KSSTATE State; +}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; + +//================================================================================================================================== + +NTSTATUS +NTAPI +CPortPinWaveCyclic::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + DPRINT("IServiceSink_fnQueryInterface entered\n"); + + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) + { + *Output = PVOID(PUNKNOWN(PSERVICESINK(this))); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + + +VOID +CPortPinWaveCyclic::UpdateCommonBuffer( + ULONG Position, + ULONG MaxTransferCount) +{ + ULONG BufferLength; + ULONG BytesToCopy; + ULONG BufferSize; + PUCHAR Buffer; + NTSTATUS Status; + + BufferLength = Position - m_CommonBufferOffset; + BufferLength = min(BufferLength, MaxTransferCount); + + while(BufferLength) + { + Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + return; + + BytesToCopy = min(BufferLength, BufferSize); + + if (m_Capture) + { + m_DmaChannel->CopyTo(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); + } + else + { + m_DmaChannel->CopyTo((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy); + } + + m_IrpQueue->UpdateMapping(BytesToCopy); + m_CommonBufferOffset += BytesToCopy; + + BufferLength = Position - m_CommonBufferOffset; + } +} + +VOID +CPortPinWaveCyclic::UpdateCommonBufferOverlap( + ULONG Position, + ULONG MaxTransferCount) +{ + ULONG BufferLength, Length, Gap; + ULONG BytesToCopy; + ULONG BufferSize; + PUCHAR Buffer; + NTSTATUS Status; + + + BufferLength = Gap = m_CommonBufferSize - m_CommonBufferOffset; + BufferLength = Length = min(BufferLength, MaxTransferCount); + while(BufferLength) + { + Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + return; + + BytesToCopy = min(BufferLength, BufferSize); + + if (m_Capture) + { + m_DmaChannel->CopyTo(Buffer, + (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, + BytesToCopy); + } + else + { + m_DmaChannel->CopyTo((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, + Buffer, + BytesToCopy); + } + + m_IrpQueue->UpdateMapping(BytesToCopy); + m_CommonBufferOffset += BytesToCopy; + + BufferLength = m_CommonBufferSize - m_CommonBufferOffset; + } + + if (Gap == Length) + { + m_CommonBufferOffset = 0; + + MaxTransferCount -= Length; + + if (MaxTransferCount) + { + UpdateCommonBuffer(Position, MaxTransferCount); + } + } +} + +VOID +NTAPI +SetStreamWorkerRoutineWaveCyclic( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + CPortPinWaveCyclic * This; + PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; + KSSTATE State; + ULONG MinimumDataThreshold; + ULONG MaximumDataThreshold; + + This = Ctx->Pin; + State = Ctx->State; + + IoFreeWorkItem(Ctx->WorkItem); + FreeItem(Ctx, TAG_PORTCLASS); + + // Has the audio stream resumed? + if (This->m_IrpQueue->NumMappings() && State == KSSTATE_STOP) + return; + + // Has the audio state already been set? + if (This->m_State == State) + return; + + // Set the state + if (NT_SUCCESS(This->m_Stream->SetState(State))) + { + // Set internal state + This->m_State = State; + + if (This->m_State == KSSTATE_STOP) + { + // reset start stream + This->m_IrpQueue->CancelBuffers(); //FIX function name + + // increase stop counter + This->m_StopCount++; + // get current data threshold + MinimumDataThreshold = This->m_IrpQueue->GetMinimumDataThreshold(); + // get maximum data threshold + MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)This->m_Format)->WaveFormatEx.nAvgBytesPerSec; + // increase minimum data threshold by a third sec + MinimumDataThreshold += This->m_FrameSize * 10; + + // assure it has not exceeded + MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold); + // store minimum data threshold + This->m_IrpQueue->SetMinimumDataThreshold(MinimumDataThreshold); + + DPRINT1("Stopping TotalPackets %u StopCount %u\n", This->m_TotalPackets, This->m_StopCount); + } + if (This->m_State == KSSTATE_RUN) + { + DPRINT1("State RUN %x MinAvailable %u CommonBufferSize %u Offset %u\n", State, This->m_IrpQueue->MinimumDataAvailable(), This->m_CommonBufferSize, This->m_CommonBufferOffset); + } + } +} + +VOID +NTAPI +CPortPinWaveCyclic::SetStreamState( + IN KSSTATE State) +{ + PDEVICE_OBJECT DeviceObject; + PIO_WORKITEM WorkItem; + PSETSTREAM_CONTEXT Context; + + PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + // Has the audio stream resumed? + if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP) + return; + + // Has the audio state already been set? + if (m_State == State) + return; + + // Get device object + DeviceObject = GetDeviceObject(m_Port); + + // allocate set state context + Context = (PSETSTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS); + + if (!Context) + return; + + // allocate work item + WorkItem = IoAllocateWorkItem(DeviceObject); + + if (!WorkItem) + { + ExFreePool(Context); + return; + } + + Context->Pin = this; + Context->WorkItem = WorkItem; + Context->State = State; + + // queue the work item + IoQueueWorkItem(WorkItem, SetStreamWorkerRoutineWaveCyclic, DelayedWorkQueue, (PVOID)Context); +} + +VOID +NTAPI +CPortPinWaveCyclic::RequestService() +{ + ULONG Position; + NTSTATUS Status; + PUCHAR Buffer; + ULONG BufferSize; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + { + //SetStreamState(This, KSSTATE_STOP); + return; + } + + Status = m_Stream->GetPosition(&Position); + DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u\n", Position, Buffer, m_CommonBufferSize, BufferSize); + + if (Position < m_CommonBufferOffset) + { + UpdateCommonBufferOverlap(Position, m_FrameSize); + } + else if (Position >= m_CommonBufferOffset) + { + UpdateCommonBuffer(Position, m_FrameSize); + } +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::NewIrpTarget( + 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 + DbgBreakPoint(); + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::HandleKsProperty( + IN PIRP Irp) +{ + PKSPROPERTY Property; + NTSTATUS Status; + UNICODE_STRING GuidString; + PIO_STACK_LOCATION IoStack; + + 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, GUID_NULL)) + { + if (Property->Flags & KSPROPERTY_TYPE_SETSUPPORT) + { + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID)) + { + // buffer too small + Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; + Irp->IoStatus.Information = sizeof(GUID); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_BUFFER_OVERFLOW; + } + // FIXME copy guids + // KSPROPSETID_Audio when available + // KSPROPSETID_Sysaudio_Pin + + RtlMoveMemory(Irp->UserBuffer, &KSPROPSETID_Connection, sizeof(GUID)); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(GUID); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + } + } + + + if (IsEqualGUIDAligned(Property->Set, KSPROPSETID_Connection)) + { + if (Property->Id == KSPROPERTY_CONNECTION_STATE) + { + PKSSTATE State = (PKSSTATE)Irp->UserBuffer; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + 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 (m_Stream) + { + Status = m_Stream->SetState(*State); + + DPRINT1("Setting state %u %x\n", *State, Status); + if (NT_SUCCESS(Status)) + { + m_State = *State; + } + } + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + else if (Property->Flags & KSPROPERTY_TYPE_GET) + { + *State = m_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, m_Format, DataFormat->FormatSize)) + { + Irp->IoStatus.Information = DataFormat->FormatSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + + NewDataFormat = (PKSDATAFORMAT)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 (m_Stream) + { + PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); + + PC_ASSERT(m_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 = m_Stream->SetFormat(NewDataFormat); + if (NT_SUCCESS(Status)) + { + if (m_Format) + ExFreePoolWithTag(m_Format, TAG_PORTCLASS); + + m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat); + m_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 (!m_Format) + { + DPRINT1("No format\n"); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + if (m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + Irp->IoStatus.Information = m_Format->FormatSize; + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + + RtlMoveMemory(DataFormat, m_Format, m_Format->FormatSize); + Irp->IoStatus.Information = DataFormat->FormatSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + } + else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING) + { + PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)Irp->UserBuffer; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + // Validate input buffer + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSALLOCATOR_FRAMING)) + { + Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + // Clear frame structure + RtlZeroMemory(Framing, sizeof(KSALLOCATOR_FRAMING)); + // store requested frame size + Framing->FrameSize = m_FrameSize; + // FIXME fill in struct + + Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); + 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); + RtlFreeUnicodeString(&GuidString); + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::HandleKsStream( + IN PIRP Irp) +{ + InterlockedIncrement((PLONG)&m_TotalPackets); + + DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u Pre %u Post %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); + + m_IrpQueue->AddMapping(NULL, 0, Irp); + + return STATUS_PENDING; +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::DeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) + { + return HandleKsProperty(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 HandleKsStream(Irp); + } + else + { + return KsDefaultDeviceIoCompletion(DeviceObject, Irp); + } + + UNIMPLEMENTED + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +VOID +NTAPI +CloseStreamRoutineWaveCyclic( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PMINIPORTWAVECYCLICSTREAM Stream; + CPortPinWaveCyclic * This; + NTSTATUS Status; + PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; + + This = (CPortPinWaveCyclic*)Ctx->Pin; + + if (This->m_State != KSSTATE_STOP) + { + // stop stream in case it hasn't been + Status = This->m_Stream->SetState(KSSTATE_STOP); + if (!NT_SUCCESS(Status)) + DPRINT1("Warning: failed to stop stream with %x\n", Status); + + This->m_State = KSSTATE_STOP; + } + + if (This->m_Format) + { + // free format + ExFreePool(This->m_Format); + This->m_Format = NULL; + } + + if (This->m_IrpQueue) + { + This->m_IrpQueue->Release(); + } + + // 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); + + // release reference to port driver + This->m_Port->Release(); + + // release reference to filter instance + This->m_Filter->Release(); + + if (This->m_Stream) + { + Stream = This->m_Stream; + This->m_Stream = NULL; + This->m_Filter->FreePin(This); + DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql()); + Stream->Release(); + } +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PCLOSESTREAM_CONTEXT Ctx; + + if (m_Stream) + { + // allocate a close context + Ctx = (PCLOSESTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS); + if (!Ctx) + { + DPRINT1("Failed to allocate stream context\n"); + goto cleanup; + } + // allocate work context + Ctx->WorkItem = IoAllocateWorkItem(DeviceObject); + if (!Ctx->WorkItem) + { + DPRINT1("Failed to allocate work item\n"); + goto cleanup; + } + // setup the close context + Ctx->Irp = Irp; + Ctx->Pin = this; + + IoMarkIrpPending(Irp); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_PENDING; + + // remove member from service group + m_ServiceGroup->RemoveMember(PSERVICESINK(this)); + + // defer work item + IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutineWaveCyclic, 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; + +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWaveCyclic::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortPinWaveCyclic::FastDeviceIoControl( + 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) +{ + return KsDispatchFastIoDeviceControlFailure(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, StatusBlock, DeviceObject); +} + + +BOOLEAN +NTAPI +CPortPinWaveCyclic::FastRead( + 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; + + // HACK to be removed + + DPRINT("CPortPinWaveCyclic::FastRead entered\n"); + + Packet = (PCONTEXT_WRITE)Buffer; + + Irp = Packet->Irp; + StatusBlock->Status = STATUS_PENDING; + + Status = m_IrpQueue->AddMapping((PUCHAR)Buffer, Length, Irp); + + if (!NT_SUCCESS(Status)) + return FALSE; + + StatusBlock->Status = STATUS_PENDING; + + return TRUE; +} + + +BOOLEAN +NTAPI +CPortPinWaveCyclic::FastWrite( + 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; + + // HACK to be removed + + InterlockedIncrement((PLONG)&m_TotalPackets); + + DPRINT("CPortPinWaveCyclic::FastWrite entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); + + Packet = (PCONTEXT_WRITE)Buffer; + Irp = Packet->Irp; + + Status = m_IrpQueue->AddMapping((PUCHAR)Buffer, Length, Irp); + + if (!NT_SUCCESS(Status)) + return FALSE; + + StatusBlock->Status = STATUS_PENDING; + + return TRUE; +} + + +NTSTATUS +NTAPI +CPortPinWaveCyclic::Init( + IN PPORTWAVECYCLIC Port, + IN PPORTFILTERWAVECYCLIC Filter, + IN KSPIN_CONNECT * ConnectDetails, + IN KSPIN_DESCRIPTOR * KsPinDescriptor) +{ + NTSTATUS Status; + PKSDATAFORMAT DataFormat; + PDEVICE_OBJECT DeviceObject; + BOOL Capture; + PVOID SilenceBuffer; + //IDrmAudioStream * DrmAudio = NULL; + + m_KsPinDescriptor = KsPinDescriptor; + m_ConnectDetails = ConnectDetails; + m_Miniport = GetWaveCyclicMiniport(Port); + + DeviceObject = GetDeviceObject(Port); + + DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); + + DPRINT("CPortPinWaveCyclic::Init entered Size %u\n", DataFormat->FormatSize); + + m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!m_Format) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); + + Status = NewIrpQueue(&m_IrpQueue); + if (!NT_SUCCESS(Status)) + return Status; + + 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 = m_Miniport->NewStream(&m_Stream, + NULL, + NonPagedPool, + ConnectDetails->PinId, + Capture, + m_Format, + &m_DmaChannel, + &m_ServiceGroup); +#if 0 + Status = m_Stream->QueryInterface(IID_IDrmAudioStream, (PVOID*)&DrmAudio); + if (NT_SUCCESS(Status)) + { + DRMRIGHTS DrmRights; + DPRINT1("Got IID_IDrmAudioStream interface %p\n", DrmAudio); + + DrmRights.CopyProtect = FALSE; + DrmRights.Reserved = 0; + DrmRights.DigitalOutputDisable = FALSE; + + Status = DrmAudio->SetContentId(1, &DrmRights); + DPRINT("Status %x\n", Status); + } +#endif + + DPRINT("CPortPinWaveCyclic::Init Status %x\n", Status); + + if (!NT_SUCCESS(Status)) + return Status; + + Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to add pin to service group\n"); + return Status; + } + + m_ServiceGroup->SupportDelayedService(); + m_Stream->SetState(KSSTATE_STOP); + m_State = KSSTATE_STOP; + m_CommonBufferOffset = 0; + m_CommonBufferSize = m_DmaChannel->AllocatedBufferSize(); + m_CommonBuffer = m_DmaChannel->SystemAddress(); + m_Capture = Capture; + // delay of 10 milisec + m_Delay = Int32x32To64(10, -10000); + + Status = m_Stream->SetNotificationFreq(10, &m_FrameSize); + + SilenceBuffer = AllocateItem(NonPagedPool, m_FrameSize, TAG_PORTCLASS); + if (!SilenceBuffer) + return STATUS_INSUFFICIENT_RESOURCES; + + m_Stream->Silence(SilenceBuffer, m_FrameSize); + + Status = m_IrpQueue->Init(ConnectDetails, DataFormat, DeviceObject, m_FrameSize, 0, SilenceBuffer); + if (!NT_SUCCESS(Status)) + { + m_IrpQueue->Release(); + return Status; + } + + Port->AddRef(); + Filter->AddRef(); + + m_Port = Port; + m_Filter = Filter; + + DPRINT1("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); + DPRINT1("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); + m_State = KSSTATE_PAUSE; + + //m_ServiceGroup->RequestDelayedService(m_Delay); + + return STATUS_SUCCESS; +} + + +ULONG +NTAPI +CPortPinWaveCyclic::GetCompletedPosition() +{ + UNIMPLEMENTED; + return 0; +} + + +ULONG +NTAPI +CPortPinWaveCyclic::GetCycleCount() +{ + UNIMPLEMENTED; + return 0; +} + + +ULONG +NTAPI +CPortPinWaveCyclic::GetDeviceBufferSize() +{ + return m_CommonBufferSize; +} + + +PVOID +NTAPI +CPortPinWaveCyclic::GetIrpStream() +{ + return (PVOID)m_IrpQueue; +} + + +PMINIPORT +NTAPI +CPortPinWaveCyclic::GetMiniport() +{ + return (PMINIPORT)m_Miniport; +} + + +NTSTATUS +NewPortPinWaveCyclic( + OUT IPortPinWaveCyclic ** OutPin) +{ + CPortPinWaveCyclic * This; + + This = new(NonPagedPool, TAG_PORTCLASS)CPortPinWaveCyclic(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // store result + *OutPin = (IPortPinWaveCyclic*)This; + + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c deleted file mode 100644 index 6d92ed269bf..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/pin_WavePci.c - * PURPOSE: WavePci IRP Audio Pin - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IPortPinWavePciVtbl *lpVtbl; - IServiceSinkVtbl *lpVtblServiceSink; - IPortWavePciStreamVtbl *lpVtblPortWavePciStream; - - LONG ref; - IPortWavePci * Port; - IPortFilterWavePci * Filter; - KSPIN_DESCRIPTOR * KsPinDescriptor; - PMINIPORTWAVEPCI Miniport; - PSERVICEGROUP ServiceGroup; - PDMACHANNEL DmaChannel; - PMINIPORTWAVEPCISTREAM Stream; - KSSTATE State; - PKSDATAFORMAT Format; - KSPIN_CONNECT * ConnectDetails; - - BOOL Capture; - PDEVICE_OBJECT DeviceObject; - IIrpQueue * IrpQueue; - - ULONG TotalPackets; - ULONG PreCompleted; - ULONG PostCompleted; - ULONG StopCount; - - ULONG Delay; - - BOOL bUsePrefetch; - ULONG PrefetchOffset; - - KSALLOCATOR_FRAMING AllocatorFraming; - -}IPortPinWavePciImpl; - -typedef struct -{ - IPortPinWavePciImpl *Pin; - PIO_WORKITEM WorkItem; - KSSTATE State; -}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; - -//================================================================================================================================== -static -NTSTATUS -NTAPI -IPortWavePciStream_fnQueryInterface( - IPortWavePciStream* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); - - DPRINT("IPortWavePciStream_fnQueryInterface entered\n"); - - if (IsEqualGUIDAligned(refiid, &IID_IPortWavePciStream) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - - return STATUS_UNSUCCESSFUL; -} - -static -ULONG -NTAPI -IPortWavePciStream_fnAddRef( - IPortWavePciStream* iface) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); - DPRINT("IPortWavePciStream_fnAddRef entered\n"); - - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IPortWavePciStream_fnRelease( - IPortWavePciStream* iface) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); - - InterlockedDecrement(&This->ref); - - DPRINT("IPortWavePciStream_fnRelease entered %u\n", This->ref); - - /* Return new reference count */ - return This->ref; -} - -static -NTSTATUS -NTAPI -IPortWavePciStream_fnGetMapping( - IN IPortWavePciStream *iface, - IN PVOID Tag, - OUT PPHYSICAL_ADDRESS PhysicalAddress, - OUT PVOID *VirtualAddress, - OUT PULONG ByteCount, - OUT PULONG Flags) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); - - ASSERT_IRQL(DISPATCH_LEVEL); - return This->IrpQueue->lpVtbl->GetMappingWithTag(This->IrpQueue, Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags); -} - -static -NTSTATUS -NTAPI -IPortWavePciStream_fnReleaseMapping( - IN IPortWavePciStream *iface, - IN PVOID Tag) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); - - ASSERT_IRQL(DISPATCH_LEVEL); - return This->IrpQueue->lpVtbl->ReleaseMappingWithTag(This->IrpQueue, Tag); -} - -static -NTSTATUS -NTAPI -IPortWavePciStream_fnTerminatePacket( - IN IPortWavePciStream *iface) -{ - UNIMPLEMENTED - ASSERT_IRQL(DISPATCH_LEVEL); - return STATUS_SUCCESS; -} - - -static IPortWavePciStreamVtbl vt_PortWavePciStream = -{ - IPortWavePciStream_fnQueryInterface, - IPortWavePciStream_fnAddRef, - IPortWavePciStream_fnRelease, - IPortWavePciStream_fnGetMapping, - IPortWavePciStream_fnReleaseMapping, - IPortWavePciStream_fnTerminatePacket -}; - - -static -NTSTATUS -NTAPI -IServiceSink_fnQueryInterface( - IServiceSink* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, 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) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblServiceSink); - DPRINT("IServiceSink_fnAddRef entered\n"); - - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IServiceSink_fnRelease( - IServiceSink* iface) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, 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) -{ - IPortPinWavePciImpl * This; - PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; - KSSTATE State; - ULONG MinimumDataThreshold; - ULONG MaximumDataThreshold; - - 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); - /* increase stop counter */ - This->StopCount++; - /* get current data threshold */ - MinimumDataThreshold = This->IrpQueue->lpVtbl->GetMinimumDataThreshold(This->IrpQueue); - /* get maximum data threshold */ - MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec; - /* increase minimum data threshold by 10 frames */ - MinimumDataThreshold += This->AllocatorFraming.FrameSize * 10; - - /* assure it has not exceeded */ - MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold); - /* store minimum data threshold */ - This->IrpQueue->lpVtbl->SetMinimumDataThreshold(This->IrpQueue, MinimumDataThreshold); - - DPRINT1("Stopping PreCompleted %u PostCompleted %u StopCount %u MinimumDataThreshold %u\n", This->PreCompleted, This->PostCompleted, This->StopCount, MinimumDataThreshold); - } - if (This->State == KSSTATE_RUN) - { - /* start the notification timer */ - //This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, This->Delay); - } - } -} -static -VOID -NTAPI -SetStreamState( - IN IPortPinWavePciImpl * 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 = GetDeviceObjectFromPortWavePci(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); -} - -static -VOID -NTAPI -IServiceSink_fnRequestService( - IServiceSink* iface) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblServiceSink); - - ASSERT_IRQL(DISPATCH_LEVEL); - - if (This->IrpQueue->lpVtbl->HasLastMappingFailed(This->IrpQueue)) - { - if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) == 0) - { - DPRINT("Stopping stream...\n"); - SetStreamState(This, KSSTATE_STOP); - return; - } - } - - This->Stream->lpVtbl->Service(This->Stream); - //TODO - //generate events -} - -static IServiceSinkVtbl vt_IServiceSink = -{ - IServiceSink_fnQueryInterface, - IServiceSink_fnAddRef, - IServiceSink_fnRelease, - IServiceSink_fnRequestService -}; - -//================================================================================================================================== -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnQueryInterface( - IPortPinWavePci* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)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 -IPortPinWavePci_fnAddRef( - IPortPinWavePci* iface) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -/* - * @implemented - */ -ULONG -NTAPI -IPortPinWavePci_fnRelease( - IPortPinWavePci* iface) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - return This->ref; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnNewIrpTarget( - IN IPortPinWavePci* 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; -} - -NTSTATUS -NTAPI -IPortPinWavePci_HandleKsProperty( - IN IPortPinWavePci * iface, - IN PVOID InputBuffer, - IN ULONG InputBufferLength, - IN PVOID OutputBuffer, - IN ULONG OutputBufferLength, - IN PIO_STATUS_BLOCK IoStatusBlock) -{ - PKSPROPERTY Property; - NTSTATUS Status; - UNICODE_STRING GuidString; - - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; - - - DPRINT("IPortPinWavePci_HandleKsProperty entered\n"); - - if (InputBufferLength < sizeof(KSPROPERTY)) - { - IoStatusBlock->Information = 0; - IoStatusBlock->Status = STATUS_INVALID_PARAMETER; - return STATUS_INVALID_PARAMETER; - } - - Property = (PKSPROPERTY)InputBuffer; - - if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Connection)) - { - if (Property->Id == KSPROPERTY_CONNECTION_STATE) - { - PKSSTATE State = (PKSSTATE)OutputBuffer; - - ASSERT_IRQL(DISPATCH_LEVEL); - if (OutputBufferLength < sizeof(KSSTATE)) - { - IoStatusBlock->Information = sizeof(KSSTATE); - IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL; - return STATUS_BUFFER_TOO_SMALL; - } - - if (Property->Flags & KSPROPERTY_TYPE_SET) - { - Status = STATUS_UNSUCCESSFUL; - IoStatusBlock->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; - } - } - IoStatusBlock->Status = Status; - return Status; - } - else if (Property->Flags & KSPROPERTY_TYPE_GET) - { - *State = This->State; - IoStatusBlock->Information = sizeof(KSSTATE); - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - } - else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT) - { - PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)OutputBuffer; - if (Property->Flags & KSPROPERTY_TYPE_SET) - { - PKSDATAFORMAT NewDataFormat; - if (!RtlCompareMemory(DataFormat, This->Format, DataFormat->FormatSize)) - { - IoStatusBlock->Information = DataFormat->FormatSize; - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - - NewDataFormat = AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); - if (!NewDataFormat) - { - IoStatusBlock->Information = 0; - IoStatusBlock->Status = STATUS_NO_MEMORY; - 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; - IoStatusBlock->Information = DataFormat->FormatSize; - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - } - DPRINT1("Failed to set format\n"); - IoStatusBlock->Information = 0; - IoStatusBlock->Status = STATUS_UNSUCCESSFUL; - return STATUS_UNSUCCESSFUL; - } - else if (Property->Flags & KSPROPERTY_TYPE_GET) - { - if (!This->Format) - { - DPRINT1("No format\n"); - IoStatusBlock->Information = 0; - IoStatusBlock->Status = STATUS_UNSUCCESSFUL; - return STATUS_UNSUCCESSFUL; - } - if (This->Format->FormatSize > OutputBufferLength) - { - IoStatusBlock->Information = This->Format->FormatSize; - IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL; - return STATUS_BUFFER_TOO_SMALL; - } - - RtlMoveMemory(DataFormat, This->Format, This->Format->FormatSize); - IoStatusBlock->Information = DataFormat->FormatSize; - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - } - else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING) - { - PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)OutputBuffer; - - ASSERT_IRQL(DISPATCH_LEVEL); - /* Validate input buffer */ - if (OutputBufferLength < sizeof(KSALLOCATOR_FRAMING)) - { - IoStatusBlock->Information = sizeof(KSALLOCATOR_FRAMING); - IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL; - return STATUS_BUFFER_TOO_SMALL; - } - /* copy frame allocator struct */ - RtlMoveMemory(Framing, &This->AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); - - IoStatusBlock->Information = sizeof(KSALLOCATOR_FRAMING); - IoStatusBlock->Status = STATUS_SUCCESS; - return STATUS_SUCCESS; - } - } - - RtlStringFromGUID(&Property->Set, &GuidString); - DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); - RtlFreeUnicodeString(&GuidString); - - IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED; - IoStatusBlock->Information = 0; - return STATUS_NOT_IMPLEMENTED; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnDeviceIoControl( - IN IPortPinWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - NTSTATUS Status; - - IoStack = IoGetCurrentIrpStackLocation(Irp); - - if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) - { - Status = IPortPinWavePci_HandleKsProperty(iface, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; - } - - - UNIMPLEMENTED - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_UNSUCCESSFUL; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnRead( - IN IPortPinWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnWrite( - IN IPortPinWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnFlush( - IN IPortPinWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -static -VOID -NTAPI -CloseStreamRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PMINIPORTWAVEPCISTREAM Stream; - NTSTATUS Status; - ISubdevice *ISubDevice; - PSUBDEVICE_DESCRIPTOR Descriptor; - IPortPinWavePciImpl * This; - PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; - - This = (IPortPinWavePciImpl*)Ctx->Pin; - - if (This->Stream) - { - if (This->State != KSSTATE_STOP) - { - This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); - } - } - - if (This->ServiceGroup) - { - This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink); - } - - 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)) - { - Descriptor->Factory.Instances[This->ConnectDetails->PinId].CurrentPinInstanceCount--; - } - ISubDevice->lpVtbl->Release(ISubDevice); - } - - 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); - - if (This->Stream) - { - Stream = This->Stream; - This->Stream = NULL; - DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql()); - Stream->lpVtbl->Release(Stream); - } -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnClose( - IN IPortPinWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PCLOSESTREAM_CONTEXT Ctx; - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)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 -IPortPinWavePci_fnQuerySecurity( - IN IPortPinWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnSetSecurity( - IN IPortPinWavePci* iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortPinWavePci_fnFastDeviceIoControl( - IN IPortPinWavePci* 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) -{ - NTSTATUS Status; - - if (IoControlCode == IOCTL_KS_PROPERTY) - { - Status = IPortPinWavePci_HandleKsProperty(iface, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock); - if (NT_SUCCESS(Status)) - { - return TRUE; - } - } - - return FALSE; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortPinWavePci_fnFastRead( - IN IPortPinWavePci* 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; - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; - - DPRINT("IPortPinWavePci_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; - - /* set pending status as result */ - StatusBlock->Status = STATUS_PENDING; - return TRUE; -} - -/* - * @implemented - */ -BOOLEAN -NTAPI -IPortPinWavePci_fnFastWrite( - IN IPortPinWavePci* 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; - ULONG MinimumDataThreshold; - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; - - DPRINT("IPortPinWavePci_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted); - - InterlockedIncrement((PLONG)&This->TotalPackets); - - 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; - - StatusBlock->Status = STATUS_PENDING; - - if (This->IrpQueue->lpVtbl->HasLastMappingFailed(This->IrpQueue)) - { - /* get minimum data threshold */ - MinimumDataThreshold = This->IrpQueue->lpVtbl->GetMinimumDataThreshold(This->IrpQueue); - - if (MinimumDataThreshold < This->IrpQueue->lpVtbl->NumData(This->IrpQueue)) - { - /* notify port driver that new mapping is available */ - DPRINT("Notifying of new mapping\n"); - This->Stream->lpVtbl->MappingAvailable(This->Stream); - } - } - - return TRUE; -} - -/* - * @unimplemented - */ -NTSTATUS -NTAPI -IPortPinWavePci_fnInit( - IN IPortPinWavePci* iface, - IN PPORTWAVEPCI Port, - IN PPORTFILTERWAVEPCI Filter, - IN KSPIN_CONNECT * ConnectDetails, - IN KSPIN_DESCRIPTOR * KsPinDescriptor, - IN PDEVICE_OBJECT DeviceObject) -{ - NTSTATUS Status; - PKSDATAFORMAT DataFormat; - BOOL Capture; - - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; - - Port->lpVtbl->AddRef(Port); - Filter->lpVtbl->AddRef(Filter); - - This->Port = Port; - This->Filter = Filter; - This->KsPinDescriptor = KsPinDescriptor; - This->ConnectDetails = ConnectDetails; - This->Miniport = GetWavePciMiniport(Port); - This->DeviceObject = DeviceObject; - - DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); - - DPRINT("IPortPinWavePci_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 = This->Miniport->lpVtbl->NewStream(This->Miniport, - &This->Stream, - NULL, - NonPagedPool, - (PPORTWAVEPCISTREAM)&This->lpVtblPortWavePciStream, - ConnectDetails->PinId, - Capture, - This->Format, - &This->DmaChannel, - &This->ServiceGroup); - - DPRINT("IPortPinWavePci_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); - } - - /* delay of 10 milisec */ - This->Delay = Int32x32To64(10, -10000); - - Status = This->Stream->lpVtbl->GetAllocatorFraming(This->Stream, &This->AllocatorFraming); - if (!NT_SUCCESS(Status)) - { - DPRINT1("GetAllocatorFraming failed with %x\n", Status); - return Status; - } - - DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", - This->AllocatorFraming.OptionsFlags, This->AllocatorFraming.RequirementsFlags, This->AllocatorFraming.PoolType, This->AllocatorFraming.Frames, This->AllocatorFraming.FrameSize, This->AllocatorFraming.FileAlignment); - - Status = NewIrpQueue(&This->IrpQueue); - if (!NT_SUCCESS(Status)) - return Status; - - Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, This->Format, DeviceObject, This->AllocatorFraming.FrameSize, This->AllocatorFraming.FileAlignment, NULL); - 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 - */ -PVOID -NTAPI -IPortPinWavePci_fnGetIrpStream( - IN IPortPinWavePci* iface) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; - - return (PVOID)This->IrpQueue; -} - - -/* - * @implemented - */ -PMINIPORT -NTAPI -IPortPinWavePci_fnGetMiniport( - IN IPortPinWavePci* iface) -{ - IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; - - return (PMINIPORT)This->Miniport; -} - -static IPortPinWavePciVtbl vt_IPortPinWavePci = -{ - IPortPinWavePci_fnQueryInterface, - IPortPinWavePci_fnAddRef, - IPortPinWavePci_fnRelease, - IPortPinWavePci_fnNewIrpTarget, - IPortPinWavePci_fnDeviceIoControl, - IPortPinWavePci_fnRead, - IPortPinWavePci_fnWrite, - IPortPinWavePci_fnFlush, - IPortPinWavePci_fnClose, - IPortPinWavePci_fnQuerySecurity, - IPortPinWavePci_fnSetSecurity, - IPortPinWavePci_fnFastDeviceIoControl, - IPortPinWavePci_fnFastRead, - IPortPinWavePci_fnFastWrite, - IPortPinWavePci_fnInit, - IPortPinWavePci_fnGetIrpStream, - IPortPinWavePci_fnGetMiniport -}; - - - - -NTSTATUS NewPortPinWavePci( - OUT IPortPinWavePci ** OutPin) -{ - IPortPinWavePciImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IPortPinWavePciImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - /* initialize IPortPinWavePci */ - This->ref = 1; - This->lpVtbl = &vt_IPortPinWavePci; - This->lpVtblServiceSink = &vt_IServiceSink; - This->lpVtblPortWavePciStream = &vt_PortWavePciStream; - - - /* store result */ - *OutPin = (IPortPinWavePci*)&This->lpVtbl; - - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp new file mode 100644 index 00000000000..abeb39a5950 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp @@ -0,0 +1,863 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp + * PURPOSE: WavePci IRP Audio Pin + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortPinWavePci : public IPortPinWavePci, + public IServiceSink, + public IPortWavePciStream +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortPinWavePci; + IMP_IServiceSink; + IMP_IPortWavePciStream; + CPortPinWavePci(IUnknown *OuterUnknown) {} + virtual ~CPortPinWavePci(){} + + VOID NTAPI SetState( IN KSSTATE State); + VOID NTAPI CloseStream(); +protected: + + IPortWavePci * m_Port; + IPortFilterWavePci * m_Filter; + KSPIN_DESCRIPTOR * m_KsPinDescriptor; + PMINIPORTWAVEPCI m_Miniport; + PSERVICEGROUP m_ServiceGroup; + PDMACHANNEL m_DmaChannel; + PMINIPORTWAVEPCISTREAM m_Stream; + KSSTATE m_State; + PKSDATAFORMAT m_Format; + KSPIN_CONNECT * m_ConnectDetails; + + BOOL m_Capture; + PDEVICE_OBJECT m_DeviceObject; + IIrpQueue * m_IrpQueue; + + ULONG m_TotalPackets; + ULONG m_PreCompleted; + ULONG m_PostCompleted; + ULONG m_StopCount; + + ULONG m_Delay; + + BOOL m_bUsePrefetch; + ULONG m_PrefetchOffset; + + KSALLOCATOR_FRAMING m_AllocatorFraming; + + LONG m_Ref; + + NTSTATUS NTAPI HandleKsProperty(IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN PIO_STATUS_BLOCK IoStatusBlock); + VOID NTAPI SetStreamState( IN KSSTATE State); +}; + +typedef struct +{ + CPortPinWavePci *Pin; + PIO_WORKITEM WorkItem; + KSSTATE State; +}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; + +//================================================================================================================================== +NTSTATUS +NTAPI +CPortPinWavePci::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + DPRINT("CPortPinWavePci::QueryInterface entered\n"); + + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) + { + *Output = PVOID(PSERVICESINK(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + + if (IsEqualGUIDAligned(refiid, IID_IPortWavePciStream)) + { + *Output = PVOID(PPORTWAVEPCISTREAM(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortPinWavePci::GetMapping( + IN PVOID Tag, + OUT PPHYSICAL_ADDRESS PhysicalAddress, + OUT PVOID *VirtualAddress, + OUT PULONG ByteCount, + OUT PULONG Flags) +{ + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + return m_IrpQueue->GetMappingWithTag(Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags); +} + +NTSTATUS +NTAPI +CPortPinWavePci::ReleaseMapping( + IN PVOID Tag) +{ + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + return m_IrpQueue->ReleaseMappingWithTag(Tag); +} + +NTSTATUS +NTAPI +CPortPinWavePci::TerminatePacket() +{ + UNIMPLEMENTED + PC_ASSERT_IRQL(DISPATCH_LEVEL); + return STATUS_SUCCESS; +} + + +VOID +CPortPinWavePci::SetState(KSSTATE State) +{ + ULONG MinimumDataThreshold; + ULONG MaximumDataThreshold; + + // Has the audio stream resumed? + if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP) + return; + + // Set the state + if (NT_SUCCESS(m_Stream->SetState(State))) + { + // Save new internal state + m_State = State; + + if (m_State == KSSTATE_STOP) + { + // reset start stream + m_IrpQueue->CancelBuffers(); //FIX function name + //This->ServiceGroup->lpVtbl->CancelDelayedService(This->ServiceGroup); + // increase stop counter + m_StopCount++; + // get current data threshold + MinimumDataThreshold = m_IrpQueue->GetMinimumDataThreshold(); + // get maximum data threshold + MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)m_Format)->WaveFormatEx.nAvgBytesPerSec; + // increase minimum data threshold by 10 frames + MinimumDataThreshold += m_AllocatorFraming.FrameSize * 10; + + // assure it has not exceeded + MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold); + // store minimum data threshold + m_IrpQueue->SetMinimumDataThreshold(MinimumDataThreshold); + + DPRINT1("Stopping PreCompleted %u PostCompleted %u StopCount %u MinimumDataThreshold %u\n", m_PreCompleted, m_PostCompleted, m_StopCount, MinimumDataThreshold); + } + if (m_State == KSSTATE_RUN) + { + // start the notification timer + //m_ServiceGroup->RequestDelayedService(m_ServiceGroup, m_Delay); + } + } + + +} + +VOID +NTAPI +PinWavePciSetStreamWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + CPortPinWavePci * This; + PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; + KSSTATE State; + + This = Ctx->Pin; + State = Ctx->State; + + IoFreeWorkItem(Ctx->WorkItem); + FreeItem(Ctx, TAG_PORTCLASS); + + This->SetState(State); +} + +VOID +NTAPI +CPortPinWavePci::SetStreamState( + IN KSSTATE State) +{ + PDEVICE_OBJECT DeviceObject; + PIO_WORKITEM WorkItem; + PSETSTREAM_CONTEXT Context; + + PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + // Has the audio stream resumed? + if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP) + return; + + // Has the audio state already been set? + if (m_State == State) + return; + + // Get device object + DeviceObject = GetDeviceObjectFromPortWavePci(m_Port); + + // allocate set state context + Context = (PSETSTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS); + + if (!Context) + return; + + // allocate work item + WorkItem = IoAllocateWorkItem(DeviceObject); + + if (!WorkItem) + { + ExFreePool(Context); + return; + } + + Context->Pin = this; + Context->WorkItem = WorkItem; + Context->State = State; + + // queue the work item + IoQueueWorkItem(WorkItem, PinWavePciSetStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context); +} + + +VOID +NTAPI +CPortPinWavePci::RequestService() +{ + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + if (m_IrpQueue->HasLastMappingFailed()) + { + if (m_IrpQueue->NumMappings() == 0) + { + DPRINT("Stopping stream...\n"); + SetStreamState(KSSTATE_STOP); + return; + } + } + + m_Stream->Service(); + //TODO + //generate events +} + +//================================================================================================================================== + +NTSTATUS +NTAPI +CPortPinWavePci::NewIrpTarget( + 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; +} + +NTSTATUS +NTAPI +CPortPinWavePci::HandleKsProperty( + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + IN PVOID OutputBuffer, + IN ULONG OutputBufferLength, + IN PIO_STATUS_BLOCK IoStatusBlock) +{ + PKSPROPERTY Property; + NTSTATUS Status; + UNICODE_STRING GuidString; + + DPRINT("IPortPinWavePci_HandleKsProperty entered\n"); + + if (InputBufferLength < sizeof(KSPROPERTY)) + { + IoStatusBlock->Information = 0; + IoStatusBlock->Status = STATUS_INVALID_PARAMETER; + return STATUS_INVALID_PARAMETER; + } + + Property = (PKSPROPERTY)InputBuffer; + + if (IsEqualGUIDAligned(Property->Set, KSPROPSETID_Connection)) + { + if (Property->Id == KSPROPERTY_CONNECTION_STATE) + { + PKSSTATE State = (PKSSTATE)OutputBuffer; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + if (OutputBufferLength < sizeof(KSSTATE)) + { + IoStatusBlock->Information = sizeof(KSSTATE); + IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + + if (Property->Flags & KSPROPERTY_TYPE_SET) + { + Status = STATUS_UNSUCCESSFUL; + IoStatusBlock->Information = 0; + + if (m_Stream) + { + Status = m_Stream->SetState(*State); + + DPRINT1("Setting state %u %x\n", *State, Status); + if (NT_SUCCESS(Status)) + { + m_State = *State; + } + } + IoStatusBlock->Status = Status; + return Status; + } + else if (Property->Flags & KSPROPERTY_TYPE_GET) + { + *State = m_State; + IoStatusBlock->Information = sizeof(KSSTATE); + IoStatusBlock->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + } + } + else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT) + { + PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)OutputBuffer; + if (Property->Flags & KSPROPERTY_TYPE_SET) + { + PKSDATAFORMAT NewDataFormat; + if (!RtlCompareMemory(DataFormat, m_Format, DataFormat->FormatSize)) + { + IoStatusBlock->Information = DataFormat->FormatSize; + IoStatusBlock->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + } + + NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!NewDataFormat) + { + IoStatusBlock->Information = 0; + IoStatusBlock->Status = STATUS_NO_MEMORY; + return STATUS_NO_MEMORY; + } + RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); + + if (m_Stream) + { +#if 0 + 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); +#endif + 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 = m_Stream->SetFormat(NewDataFormat); + if (NT_SUCCESS(Status)) + { + if (m_Format) + ExFreePoolWithTag(m_Format, TAG_PORTCLASS); + + m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat); + m_Format = NewDataFormat; + IoStatusBlock->Information = DataFormat->FormatSize; + IoStatusBlock->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + } + } + DPRINT1("Failed to set format\n"); + IoStatusBlock->Information = 0; + IoStatusBlock->Status = STATUS_UNSUCCESSFUL; + return STATUS_UNSUCCESSFUL; + } + else if (Property->Flags & KSPROPERTY_TYPE_GET) + { + if (!m_Format) + { + DPRINT1("No format\n"); + IoStatusBlock->Information = 0; + IoStatusBlock->Status = STATUS_UNSUCCESSFUL; + return STATUS_UNSUCCESSFUL; + } + if (m_Format->FormatSize > OutputBufferLength) + { + IoStatusBlock->Information = m_Format->FormatSize; + IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + + RtlMoveMemory(DataFormat, m_Format, m_Format->FormatSize); + IoStatusBlock->Information = DataFormat->FormatSize; + IoStatusBlock->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + } + } + else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING) + { + PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)OutputBuffer; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + // Validate input buffer + if (OutputBufferLength < sizeof(KSALLOCATOR_FRAMING)) + { + IoStatusBlock->Information = sizeof(KSALLOCATOR_FRAMING); + IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + // copy frame allocator struct + RtlMoveMemory(Framing, &m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); + + IoStatusBlock->Information = sizeof(KSALLOCATOR_FRAMING); + IoStatusBlock->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + } + } + + RtlStringFromGUID(Property->Set, &GuidString); + DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); + RtlFreeUnicodeString(&GuidString); + + IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED; + IoStatusBlock->Information = 0; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +CPortPinWavePci::DeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) + { + Status = HandleKsProperty(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + + UNIMPLEMENTED + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortPinWavePci::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWavePci::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWavePci::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +VOID +NTAPI +CPortPinWavePci::CloseStream() +{ + PMINIPORTWAVEPCISTREAM Stream; + ISubdevice *ISubDevice; + NTSTATUS Status; + PSUBDEVICE_DESCRIPTOR Descriptor; + + if (m_Stream) + { + if (m_State != KSSTATE_STOP) + { + m_Stream->SetState(KSSTATE_STOP); + } + } + + if (m_ServiceGroup) + { + m_ServiceGroup->RemoveMember(PSERVICESINK(this)); + } + + Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); + if (NT_SUCCESS(Status)) + { + Status = ISubDevice->GetDescriptor(&Descriptor); + if (NT_SUCCESS(Status)) + { + Descriptor->Factory.Instances[m_ConnectDetails->PinId].CurrentPinInstanceCount--; + } + ISubDevice->Release(); + } + + if (m_Format) + { + ExFreePool(m_Format); + m_Format = NULL; + } + + if (m_Stream) + { + Stream = m_Stream; + m_Stream = 0; + DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql()); + Stream->Release(); + } +} + +VOID +NTAPI +PinWavePciCloseStreamRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + CPortPinWavePci * This; + PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; + + This = (CPortPinWavePci*)Ctx->Pin; + + This->CloseStream(); + + // 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); +} + +NTSTATUS +NTAPI +CPortPinWavePci::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PCLOSESTREAM_CONTEXT Ctx; + + if (m_Stream) + { + Ctx = (PCLOSESTREAM_CONTEXT)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, PinWavePciCloseStreamRoutine, 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; + +} + +NTSTATUS +NTAPI +CPortPinWavePci::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWavePci::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortPinWavePci::FastDeviceIoControl( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortPinWavePci::FastRead( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortPinWavePci::FastWrite( + 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) +{ + return FALSE; +} + + +NTSTATUS +NTAPI +CPortPinWavePci::Init( + IN PPORTWAVEPCI Port, + IN PPORTFILTERWAVEPCI Filter, + IN KSPIN_CONNECT * ConnectDetails, + IN KSPIN_DESCRIPTOR * KsPinDescriptor, + IN PDEVICE_OBJECT DeviceObject) +{ + NTSTATUS Status; + PKSDATAFORMAT DataFormat; + BOOL Capture; + + Port->AddRef(); + Filter->AddRef(); + + m_Port = Port; + m_Filter = Filter; + m_KsPinDescriptor = KsPinDescriptor; + m_ConnectDetails = ConnectDetails; + m_Miniport = GetWavePciMiniport(Port); + m_DeviceObject = DeviceObject; + + DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); + + DPRINT("IPortPinWavePci_fnInit entered\n"); + + m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!m_Format) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlMoveMemory(m_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 = m_Miniport->NewStream(&m_Stream, + NULL, + NonPagedPool, + PPORTWAVEPCISTREAM(this), + ConnectDetails->PinId, + Capture, + m_Format, + &m_DmaChannel, + &m_ServiceGroup); + + DPRINT("IPortPinWavePci_fnInit Status %x\n", Status); + + if (!NT_SUCCESS(Status)) + return Status; + + if (m_ServiceGroup) + { + Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to add pin to service group\n"); + return Status; + } + m_ServiceGroup->SupportDelayedService(); + } + + // delay of 10 milisec + m_Delay = Int32x32To64(10, -10000); + + Status = m_Stream->GetAllocatorFraming(&m_AllocatorFraming); + if (!NT_SUCCESS(Status)) + { + DPRINT1("GetAllocatorFraming failed with %x\n", Status); + return Status; + } + + DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", + m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); + + Status = NewIrpQueue(&m_IrpQueue); + if (!NT_SUCCESS(Status)) + return Status; + + Status = m_IrpQueue->Init(ConnectDetails, m_Format, DeviceObject, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IrpQueue_Init failed with %x\n", Status); + return Status; + } + + m_State = KSSTATE_STOP; + m_Capture = Capture; + + return STATUS_SUCCESS; +} + +PVOID +NTAPI +CPortPinWavePci::GetIrpStream() +{ + return (PVOID)m_IrpQueue; +} + + +PMINIPORT +NTAPI +CPortPinWavePci::GetMiniport() +{ + return (PMINIPORT)m_Miniport; +} + + +NTSTATUS +NewPortPinWavePci( + OUT IPortPinWavePci ** OutPin) +{ + CPortPinWavePci * This; + + This = new(NonPagedPool, TAG_PORTCLASS) CPortPinWavePci(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // store result + *OutPin = (IPortPinWavePci*)This; + + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c deleted file mode 100644 index 9f2e3dcc03d..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * 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 -VOID -UpdateCommonBuffer( - IPortPinWaveRTImpl * This, - ULONG Position) -{ - ULONG BufferLength; - ULONG BytesToCopy; - ULONG BufferSize; - PUCHAR Buffer; - NTSTATUS Status; - - BufferLength = Position - This->CommonBufferOffset; - while(BufferLength) - { - Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - return; - - BytesToCopy = min(BufferLength, BufferSize); - - if (This->Capture) - { - RtlMoveMemory(Buffer, (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, BytesToCopy); - } - else - { - RtlMoveMemory((PUCHAR)This->CommonBuffer + This->CommonBufferOffset, Buffer, BytesToCopy); - } - - This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy); - This->CommonBufferOffset += BytesToCopy; - - BufferLength = Position - This->CommonBufferOffset; - } -} - -static -VOID -UpdateCommonBufferOverlap( - IPortPinWaveRTImpl * This, - ULONG Position) -{ - ULONG BufferLength; - ULONG BytesToCopy; - ULONG BufferSize; - PUCHAR Buffer; - NTSTATUS Status; - - - BufferLength = This->CommonBufferSize - This->CommonBufferOffset; - while(BufferLength) - { - Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - return; - - BytesToCopy = min(BufferLength, BufferSize); - - if (This->Capture) - { - RtlMoveMemory(Buffer, (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, BytesToCopy); - } - else - { - RtlMoveMemory((PUCHAR)This->CommonBuffer + This->CommonBufferOffset, Buffer, BytesToCopy); - } - - This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy); - This->CommonBufferOffset += BytesToCopy; - - BufferLength = This->CommonBufferSize - This->CommonBufferOffset; - } - This->CommonBufferOffset = 0; - UpdateCommonBuffer(This, Position); -} - - - -//================================================================================================================================== -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 %lu WriteOffset %lu Buffer %p BufferSize %u CommonBufferSize %u\n", Position.PlayOffset, Position.WriteOffset, Buffer, BufferSize, This->CommonBufferSize); - - if (Position.PlayOffset < This->CommonBufferOffset) - { - UpdateCommonBufferOverlap(This, Position.PlayOffset); - } - else if (Position.PlayOffset >= This->CommonBufferOffset) - { - UpdateCommonBuffer(This, Position.PlayOffset); - } -} - -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)) - { - Descriptor->Factory.Instances[This->ConnectDetails->PinId].CurrentPinInstanceCount--; - } - ISubDevice->lpVtbl->Release(ISubDevice); - } - - 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); - } -} - -/* - * @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; - - StatusBlock->Status = STATUS_PENDING; - 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; - - StatusBlock->Status = STATUS_PENDING; - 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, 0, NULL); - 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); - /* delay of 10 milisec */ - This->Delay = Int32x32To64(10, -10000); - - Status = This->Stream->lpVtbl->AllocateAudioBuffer(This->Stream, 16384 * 11, &This->Mdl, &This->CommonBufferSize, &This->CommonBufferOffset, &This->CacheType); - if (!NT_SUCCESS(Status)) - { - DPRINT1("AllocateAudioBuffer failed with %x\n", Status); - goto cleanup; - } - - This->CommonBuffer = MmGetSystemAddressForMdlSafe(This->Mdl, NormalPagePriority); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to get system address %x\n", Status); - IoFreeMdl(This->Mdl); - This->Mdl = NULL; - goto cleanup; - } - - DPRINT1("Setting state to acquire %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_ACQUIRE)); - DPRINT1("Setting state to pause %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE)); - This->State = KSSTATE_PAUSE; - 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->Stream) - { - This->Stream->lpVtbl->Release(This->Stream); - This->Stream = NULL; - } - else - { - 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; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp new file mode 100644 index 00000000000..7fa2b58d495 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp @@ -0,0 +1,911 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/pin_wavert.cpp + * PURPOSE: WaveRT IRP Audio Pin + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortPinWaveRT : public IPortPinWaveRT, + public IServiceSink //hack +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortPinWaveRT; + IMP_IServiceSink; //HACK + CPortPinWaveRT(IUnknown *OuterUnknown){} + virtual ~CPortPinWaveRT(){} + +protected: + + IPortWaveRT * m_Port; + IPortFilterWaveRT * m_Filter; + KSPIN_DESCRIPTOR * m_KsPinDescriptor; + PMINIPORTWAVERT m_Miniport; + PMINIPORTWAVERTSTREAM m_Stream; + PPORTWAVERTSTREAM m_PortStream; + PSERVICEGROUP m_ServiceGroup; + KSSTATE m_State; + PKSDATAFORMAT m_Format; + KSPIN_CONNECT * m_ConnectDetails; + + PVOID m_CommonBuffer; + ULONG m_CommonBufferSize; + ULONG m_CommonBufferOffset; + + IIrpQueue * m_IrpQueue; + + BOOL m_Capture; + + ULONG m_TotalPackets; + ULONG m_PreCompleted; + ULONG m_PostCompleted; + + ULONGLONG m_Delay; + + MEMORY_CACHING_TYPE m_CacheType; + PMDL m_Mdl; + + LONG m_Ref; + + NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); + NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); + VOID NTAPI SetStreamState(IN KSSTATE State); + VOID UpdateCommonBuffer(ULONG Position); + VOID UpdateCommonBufferOverlap(ULONG Position); + friend VOID NTAPI SetStreamWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); + friend VOID NTAPI CloseStreamRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); + +}; + + +typedef struct +{ + CPortPinWaveRT *Pin; + PIO_WORKITEM WorkItem; + KSSTATE State; +}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; + + +VOID +CPortPinWaveRT::UpdateCommonBuffer( + ULONG Position) +{ + ULONG BufferLength; + ULONG BytesToCopy; + ULONG BufferSize; + PUCHAR Buffer; + NTSTATUS Status; + + BufferLength = Position - m_CommonBufferOffset; + while(BufferLength) + { + Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + return; + + BytesToCopy = min(BufferLength, BufferSize); + + if (m_Capture) + { + RtlMoveMemory(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); + } + else + { + RtlMoveMemory((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy); + } + + m_IrpQueue->UpdateMapping(BytesToCopy); + m_CommonBufferOffset += BytesToCopy; + + BufferLength = Position - m_CommonBufferOffset; + } +} + +VOID +CPortPinWaveRT::UpdateCommonBufferOverlap( + ULONG Position) +{ + ULONG BufferLength; + ULONG BytesToCopy; + ULONG BufferSize; + PUCHAR Buffer; + NTSTATUS Status; + + + BufferLength = m_CommonBufferSize - m_CommonBufferOffset; + while(BufferLength) + { + Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + return; + + BytesToCopy = min(BufferLength, BufferSize); + + if (m_Capture) + { + RtlMoveMemory(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); + } + else + { + RtlMoveMemory((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy); + } + + m_IrpQueue->UpdateMapping(BytesToCopy); + m_CommonBufferOffset += BytesToCopy; + + BufferLength = m_CommonBufferSize - m_CommonBufferOffset; + } + m_CommonBufferOffset = 0; + UpdateCommonBuffer(Position); +} + + + +//================================================================================================================================== +NTSTATUS +NTAPI +CPortPinWaveRT::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + DPRINT("IServiceSink_fnQueryInterface entered\n"); + + if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) + { + *Output = PVOID(PSERVICEGROUP(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +VOID +NTAPI +CPortPinWaveRT::RequestService() +{ + KSAUDIO_POSITION Position; + NTSTATUS Status; + PUCHAR Buffer; + ULONG BufferSize; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + { + SetStreamState(KSSTATE_STOP); + return; + } + + Status = m_Stream->GetPosition(&Position); + DPRINT("PlayOffset %lu WriteOffset %lu Buffer %p BufferSize %u CommonBufferSize %u\n", Position.PlayOffset, Position.WriteOffset, Buffer, BufferSize, m_CommonBufferSize); + + if (Position.PlayOffset < m_CommonBufferOffset) + { + UpdateCommonBufferOverlap(Position.PlayOffset); + } + else if (Position.PlayOffset >= m_CommonBufferOffset) + { + UpdateCommonBuffer(Position.PlayOffset); + } +} + +VOID +NTAPI +SetStreamWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + CPortPinWaveRT * 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->m_IrpQueue->NumMappings() && State == KSSTATE_STOP) + return; + + // Set the state + if (NT_SUCCESS(This->m_Stream->SetState(State))) + { + // Set internal state to stop + This->m_State = State; + + if (This->m_State == KSSTATE_STOP) + { + // reset start stream + This->m_IrpQueue->CancelBuffers(); //FIX function name + This->m_ServiceGroup->CancelDelayedService(); + DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->m_PreCompleted, This->m_PostCompleted); + } + + if (This->m_State == KSSTATE_RUN) + { + // start the notification timer + This->m_ServiceGroup->RequestDelayedService(This->m_Delay); + } + } +} + +VOID +NTAPI +CPortPinWaveRT::SetStreamState( + IN KSSTATE State) +{ + PDEVICE_OBJECT DeviceObject; + PIO_WORKITEM WorkItem; + PSETSTREAM_CONTEXT Context; + + PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + // Has the audio stream resumed? + if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP) + return; + + // Has the audio state already been set? + if (m_State == State) + return; + + // Get device object + DeviceObject = GetDeviceObjectFromPortWaveRT(m_Port); + + // allocate set state context + Context = (PSETSTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS); + + if (!Context) + return; + + // allocate work item + WorkItem = IoAllocateWorkItem(DeviceObject); + + if (!WorkItem) + { + ExFreePool(Context); + return; + } + + Context->Pin = this; + Context->WorkItem = WorkItem; + Context->State = State; + + // queue the work item + IoQueueWorkItem(WorkItem, SetStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context); +} + +//================================================================================================================================== + +NTSTATUS +NTAPI +CPortPinWaveRT::NewIrpTarget( + 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 +CPortPinWaveRT::HandleKsProperty( + IN PIRP Irp) +{ + PKSPROPERTY Property; + NTSTATUS Status; + UNICODE_STRING GuidString; + PIO_STACK_LOCATION IoStack; + + 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 (m_Stream) + { + Status = m_Stream->SetState(*State); + + DPRINT1("Setting state %u %x\n", *State, Status); + if (NT_SUCCESS(Status)) + { + m_State = *State; + } + } + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + else if (Property->Flags & KSPROPERTY_TYPE_GET) + { + *State = m_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, m_Format, DataFormat->FormatSize)) + { + Irp->IoStatus.Information = DataFormat->FormatSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + + NewDataFormat = (PKSDATAFORMAT)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 (m_Stream) + { +#if 0 + 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(m_State == KSSTATE_STOP); +#endif + 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 = m_Stream->SetFormat(NewDataFormat); + if (NT_SUCCESS(Status)) + { + if (m_Format) + ExFreePoolWithTag(m_Format, TAG_PORTCLASS); + + m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat); + m_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 (!m_Format) + { + DPRINT1("No format\n"); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + if (m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + Irp->IoStatus.Information = m_Format->FormatSize; + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + + RtlMoveMemory(DataFormat, m_Format, m_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); + RtlFreeUnicodeString(&GuidString); + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +CPortPinWaveRT::HandleKsStream( + IN PIRP Irp) +{ + DPRINT("IPortPinWaveRT_HandleKsStream entered State %u Stream %p\n", m_State, m_Stream); + + return STATUS_PENDING; +} + +NTSTATUS +NTAPI +CPortPinWaveRT::DeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) + { + return HandleKsProperty(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 HandleKsStream(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; +} + +NTSTATUS +NTAPI +CPortPinWaveRT::Read( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWaveRT::Write( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWaveRT::Flush( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +VOID +NTAPI +CloseStreamRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PMINIPORTWAVERTSTREAM Stream; + NTSTATUS Status; + ISubdevice *ISubDevice; + PSUBDEVICE_DESCRIPTOR Descriptor; + CPortPinWaveRT * This; + PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; + + This = (CPortPinWaveRT*)Ctx->Pin; + + if (This->m_Stream) + { + if (This->m_State != KSSTATE_STOP) + { + This->m_Stream->SetState(KSSTATE_STOP); + KeStallExecutionProcessor(10); + } + } + + Status = This->m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); + if (NT_SUCCESS(Status)) + { + Status = ISubDevice->GetDescriptor(&Descriptor); + if (NT_SUCCESS(Status)) + { + Descriptor->Factory.Instances[This->m_ConnectDetails->PinId].CurrentPinInstanceCount--; + } + ISubDevice->Release(); + } + + if (This->m_Format) + { + ExFreePool(This->m_Format); + This->m_Format = NULL; + } + + if (This->m_IrpQueue) + { + This->m_IrpQueue->Release(); + } + + // 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->m_Stream) + { + Stream = This->m_Stream; + This->m_Stream = NULL; + DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql()); + Stream->Release(); + } +} + +NTSTATUS +NTAPI +CPortPinWaveRT::Close( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PCLOSESTREAM_CONTEXT Ctx; + + if (m_Stream) + { + Ctx = (PCLOSESTREAM_CONTEXT)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 = 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; + +} + +NTSTATUS +NTAPI +CPortPinWaveRT::QuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +NTSTATUS +NTAPI +CPortPinWaveRT::SetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); +} + +BOOLEAN +NTAPI +CPortPinWaveRT::FastDeviceIoControl( + 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; +} + +BOOLEAN +NTAPI +CPortPinWaveRT::FastRead( + 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) +{ + return FALSE; +} + +BOOLEAN +NTAPI +CPortPinWaveRT::FastWrite( + 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) +{ + return FALSE; +} + +NTSTATUS +NTAPI +CPortPinWaveRT::Init( + 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; + + Port->AddRef(); + Filter->AddRef(); + + m_Port = Port; + m_Filter = Filter; + m_KsPinDescriptor = KsPinDescriptor; + m_ConnectDetails = ConnectDetails; + m_Miniport = GetWaveRTMiniport(Port); + + DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); + + DPRINT("CPortPinWaveRT::Init entered\n"); + + m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!m_Format) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); + + Status = NewIrpQueue(&m_IrpQueue); + if (!NT_SUCCESS(Status)) + { + goto cleanup; + } + + Status = m_IrpQueue->Init(ConnectDetails, DataFormat, DeviceObject, 0, 0, NULL); + if (!NT_SUCCESS(Status)) + { + goto cleanup; + } + + Status = NewPortWaveRTStream(&m_PortStream); + if (!NT_SUCCESS(Status)) + { + goto cleanup; + } + + Status = PcNewServiceGroup(&m_ServiceGroup, NULL); + if (!NT_SUCCESS(Status)) + { + goto cleanup; + } + + m_ServiceGroup->AddMember(PSERVICESINK(this)); + m_ServiceGroup->SupportDelayedService(); + + 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 = m_Miniport->NewStream(&m_Stream, m_PortStream, ConnectDetails->PinId, Capture, m_Format); + DPRINT("CPortPinWaveRT::Init Status %x\n", Status); + + if (!NT_SUCCESS(Status)) + goto cleanup; + + m_Stream->GetHWLatency(&Latency); + // delay of 10 milisec + m_Delay = Int32x32To64(10, -10000); + + Status = m_Stream->AllocateAudioBuffer(16384 * 11, &m_Mdl, &m_CommonBufferSize, &m_CommonBufferOffset, &m_CacheType); + if (!NT_SUCCESS(Status)) + { + DPRINT1("AllocateAudioBuffer failed with %x\n", Status); + goto cleanup; + } + + m_CommonBuffer = MmGetSystemAddressForMdlSafe(m_Mdl, NormalPagePriority); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to get system address %x\n", Status); + IoFreeMdl(m_Mdl); + m_Mdl = NULL; + goto cleanup; + } + + DPRINT1("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); + DPRINT1("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); + m_State = KSSTATE_PAUSE; + return STATUS_SUCCESS; + +cleanup: + if (m_IrpQueue) + { + m_IrpQueue->Release(); + m_IrpQueue = NULL; + } + + if (m_Format) + { + FreeItem(m_Format, TAG_PORTCLASS); + m_Format = NULL; + } + + if (m_Stream) + { + m_Stream->Release(); + m_Stream = NULL; + } + else + { + if (m_PortStream) + { + m_PortStream->Release(); + m_PortStream = NULL; + } + + } + return Status; +} + + +NTSTATUS +NewPortPinWaveRT( + OUT IPortPinWaveRT ** OutPin) +{ + CPortPinWaveRT * This; + + This = new(NonPagedPool, TAG_PORTCLASS) CPortPinWaveRT(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + // store result + *OutPin = (PPORTPINWAVERT)This; + + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pool.c b/reactos/drivers/wdm/audio/backpln/portcls/pool.cpp similarity index 89% rename from reactos/drivers/wdm/audio/backpln/portcls/pool.c rename to reactos/drivers/wdm/audio/backpln/portcls/pool.cpp index 9e4dcbd64c7..53ef1ca3df4 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pool.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/pool.cpp @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/pool.c + * FILE: drivers/wdm/audio/backpln/portcls/pool.cpp * PURPOSE: Memory functions * PROGRAMMER: Johannes Anderwald */ diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port.c b/reactos/drivers/wdm/audio/backpln/portcls/port.cpp similarity index 70% rename from reactos/drivers/wdm/audio/backpln/portcls/port.c rename to reactos/drivers/wdm/audio/backpln/portcls/port.cpp index 2fdb7c8b529..20df798ae1b 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port.cpp @@ -1,13 +1,13 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/port.c + * FILE: drivers/wdm/audio/backpln/portcls/port.cpp * PURPOSE: Port construction API * PROGRAMMER: Johannes Anderwald * Andrew Greenwood */ -#include "private.h" +#include "private.hpp" @@ -22,7 +22,7 @@ PcNewPort( DPRINT("PcNewPort entered\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!OutPort) { @@ -30,17 +30,17 @@ PcNewPort( return STATUS_INVALID_PARAMETER; } - if (IsEqualGUIDAligned(ClassId, &CLSID_PortMidi)) + if (IsEqualGUIDAligned(ClassId, CLSID_PortMidi)) Status = NewPortDMus(OutPort); - else if (IsEqualGUIDAligned(ClassId, &CLSID_PortDMus)) + else if (IsEqualGUIDAligned(ClassId, CLSID_PortDMus)) Status = NewPortDMus(OutPort); - else if (IsEqualGUIDAligned(ClassId, &CLSID_PortTopology)) + else if (IsEqualGUIDAligned(ClassId, CLSID_PortTopology)) Status = NewPortTopology(OutPort); - else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWaveCyclic)) + else if (IsEqualGUIDAligned(ClassId, CLSID_PortWaveCyclic)) Status = NewPortWaveCyclic(OutPort); - else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWavePci)) + else if (IsEqualGUIDAligned(ClassId, CLSID_PortWavePci)) Status = NewPortWavePci(OutPort); - else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWaveRT)) + else if (IsEqualGUIDAligned(ClassId, CLSID_PortWaveRT)) Status = NewPortWaveRT(OutPort); else { diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port.h b/reactos/drivers/wdm/audio/backpln/portcls/port.hpp similarity index 100% rename from reactos/drivers/wdm/audio/backpln/portcls/port.h rename to reactos/drivers/wdm/audio/backpln/portcls/port.hpp diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c deleted file mode 100644 index d00d793699a..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c +++ /dev/null @@ -1,701 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/port_dmus.c - * PURPOSE: DirectMusic Port driver - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -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; - -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} - } -}; - -DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterDMusTopologySet, TopologyPropertyHandler); -DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterDMusPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); - -KSPROPERTY_SET PortDMusPropertySet[] = -{ - { - &KSPROPSETID_Topology, - sizeof(PortFilterDMusTopologySet) / sizeof(KSPROPERTY_ITEM), - (const KSPROPERTY_ITEM*)&PortFilterDMusTopologySet, - 0, - NULL - }, - { - &KSPROPSETID_Pin, - sizeof(PortFilterDMusPinSet) / sizeof(KSPROPERTY_ITEM), - (const KSPROPERTY_ITEM*)&PortFilterDMusPinSet, - 0, - NULL - } -}; - - -//--------------------------------------------------------------- -// IUnknown interface functions -// - -NTSTATUS -NTAPI -IPortDMus_fnQueryInterface( - IPortDMus* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - 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); - 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); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) - { - return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) - { - return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); - } - - if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) - { - DPRINT1("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); - RtlFreeUnicodeString(&GuidString); - } - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IPortDMus_fnAddRef( - IPortDMus* iface) -{ - IPortDMusImpl * This = (IPortDMusImpl*)iface; - - return _InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IPortDMus_fnRelease( - IPortDMus* iface) -{ - IPortDMusImpl * This = (IPortDMusImpl*)iface; - - _InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - if (This->bInitialized) - { - This->pMiniport->lpVtbl->Release(This->pMiniport); - } - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - - -//--------------------------------------------------------------- -// IPort interface functions -// - -NTSTATUS -NTAPI -IPortDMus_fnGetDeviceProperty( - IN IPortDMus * iface, - IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, - IN ULONG BufferLength, - OUT PVOID PropertyBuffer, - OUT PULONG ReturnLength) -{ - IPortDMusImpl * This = (IPortDMusImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortDMus_fnNewRegistryKey called w/o initiazed\n"); - return STATUS_UNSUCCESSFUL; - } - - return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); -} - -NTSTATUS -NTAPI -IPortDMus_fnInit( - IN IPortDMus * iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PUNKNOWN UnknownMiniport, - IN PUNKNOWN UnknownAdapter OPTIONAL, - IN PRESOURCELIST ResourceList) -{ - IMiniportDMus * Miniport = NULL; - IMiniportMidi * MidiMiniport = NULL; - NTSTATUS Status; - PSERVICEGROUP ServiceGroup = NULL; - PPINCOUNT PinCount; - PPOWERNOTIFY PowerNotify; - IPortDMusImpl * This = (IPortDMusImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->bInitialized) - { - DPRINT("IPortDMus_Init called again\n"); - return STATUS_SUCCESS; - } - - Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportDMus, (PVOID*)&Miniport); - if (!NT_SUCCESS(Status)) - { - /* 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; - } - } - - /* Initialize port object */ - This->pMiniport = Miniport; - This->pMiniportMidi = MidiMiniport; - This->pDeviceObject = DeviceObject; - This->bInitialized = TRUE; - - 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); - 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; - } - - /* increment reference on miniport adapter */ - Miniport->lpVtbl->AddRef(Miniport); - - } - 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); - This->bInitialized = FALSE; - 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); - This->bInitialized = FALSE; - return Status; - } - - /* increment reference on miniport adapter */ - MidiMiniport->lpVtbl->AddRef(MidiMiniport); - } - - /* create the subdevice descriptor */ - Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor, - 3, - InterfaceGuids, - 0, - NULL, - 2, - PortDMusPropertySet, - 0, - 0, - 0, - NULL, - 0, - NULL, - This->pDescriptor); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create descriptior\n"); - - if (Miniport) - Miniport->lpVtbl->Release(Miniport); - else - MidiMiniport->lpVtbl->Release(MidiMiniport); - - This->bInitialized = FALSE; - return Status; - } - - if (This->ServiceGroup == NULL && ServiceGroup) - { - /* register service group */ - This->ServiceGroup = ServiceGroup; - } - - /* 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; -} - - -NTSTATUS -NTAPI -IPortDMus_fnNewRegistryKey( - IN IPortDMus * 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) -{ - IPortDMusImpl * This = (IPortDMusImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortDMus_fnNewRegistryKey called w/o initialized\n"); - return STATUS_UNSUCCESSFUL; - } - - return PcNewRegistryKey(OutRegistryKey, - OuterUnknown, - RegistryKeyType, - DesiredAccess, - This->pDeviceObject, - NULL,//FIXME - ObjectAttributes, - CreateOptions, - Disposition); -} - -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) -{ - 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; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp new file mode 100644 index 00000000000..551fccf403e --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp @@ -0,0 +1,535 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/port_dmus.cpp + * PURPOSE: DirectMusic Port driver + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortDMus : public IPortDMus, + public ISubdevice +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortDMus; + IMP_ISubdevice; + CPortDMus(IUnknown *OuterUnknown){} + virtual ~CPortDMus(){} + +protected: + + BOOL m_bInitialized; + IMiniportDMus * m_pMiniport; + IMiniportMidi * m_pMiniportMidi; + DEVICE_OBJECT * m_pDeviceObject; + PSERVICEGROUP m_ServiceGroup; + PPINCOUNT m_pPinCount; + PPOWERNOTIFY m_pPowerNotify; + PPORTFILTERDMUS m_Filter; + + PPCFILTER_DESCRIPTOR m_pDescriptor; + PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; + + LONG m_Ref; + + friend VOID GetDMusMiniport(IN IPortDMus * iface, IN PMINIPORTDMUS * Miniport, IN PMINIPORTMIDI * MidiMiniport); + +}; + +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} + } +}; + +DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterDMusTopologySet, TopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterDMusPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); + +KSPROPERTY_SET PortDMusPropertySet[] = +{ + { + &KSPROPSETID_Topology, + sizeof(PortFilterDMusTopologySet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterDMusTopologySet, + 0, + NULL + }, + { + &KSPROPSETID_Pin, + sizeof(PortFilterDMusPinSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterDMusPinSet, + 0, + NULL + } +}; + + +//--------------------------------------------------------------- +// IUnknown interface functions +// + +NTSTATUS +NTAPI +CPortDMus::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + UNICODE_STRING GuidString; + + if (IsEqualGUIDAligned(refiid, IID_IPortDMus) || + IsEqualGUIDAligned(refiid, IID_IPortMidi) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN((IPortDMus*)this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_ISubdevice)) + { + *Output = PVOID(PSUBDEVICE(this)); + PUNKNOWN(*Output)->AddRef(); + 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); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } + + if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) + { + DPRINT1("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + } + return STATUS_UNSUCCESSFUL; +} + +//--------------------------------------------------------------- +// IPort interface functions +// + +NTSTATUS +NTAPI +CPortDMus::GetDeviceProperty( + IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, + IN ULONG BufferLength, + OUT PVOID PropertyBuffer, + OUT PULONG ReturnLength) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortDMus_fnNewRegistryKey called w/o initiazed\n"); + return STATUS_UNSUCCESSFUL; + } + + return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); +} + +NTSTATUS +NTAPI +CPortDMus::Init( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PUNKNOWN UnknownMiniport, + IN PUNKNOWN UnknownAdapter OPTIONAL, + IN PRESOURCELIST ResourceList) +{ + IMiniportDMus * Miniport = NULL; + IMiniportMidi * MidiMiniport = NULL; + NTSTATUS Status; + PSERVICEGROUP ServiceGroup = NULL; + PPINCOUNT PinCount; + PPOWERNOTIFY PowerNotify; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_bInitialized) + { + DPRINT("IPortDMus_Init called again\n"); + return STATUS_SUCCESS; + } + + Status = UnknownMiniport->QueryInterface(IID_IMiniportDMus, (PVOID*)&Miniport); + if (!NT_SUCCESS(Status)) + { + // check for legacy interface + Status = UnknownMiniport->QueryInterface(IID_IMiniportMidi, (PVOID*)&MidiMiniport); + if (!NT_SUCCESS(Status)) + { + DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n"); + return STATUS_INVALID_PARAMETER; + } + } + + // Initialize port object + m_pMiniport = Miniport; + m_pMiniportMidi = MidiMiniport; + m_pDeviceObject = DeviceObject; + m_bInitialized = TRUE; + + if (Miniport) + { + // initialize IMiniportDMus + Status = Miniport->Init(UnknownAdapter, ResourceList, this, &ServiceGroup); + if (!NT_SUCCESS(Status)) + { + DPRINT("IMiniportDMus_Init failed with %x\n", Status); + m_bInitialized = FALSE; + return Status; + } + + // get the miniport device descriptor + Status = Miniport->GetDescription(&m_pDescriptor); + if (!NT_SUCCESS(Status)) + { + DPRINT1("failed to get description\n"); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // increment reference on miniport adapter + Miniport->AddRef(); + + } + else + { + // initialize IMiniportMidi + Status = MidiMiniport->Init(UnknownAdapter, ResourceList, (IPortMidi*)this, &ServiceGroup); + if (!NT_SUCCESS(Status)) + { + DPRINT("IMiniportMidi_Init failed with %x\n", Status); + m_bInitialized = FALSE; + return Status; + } + + // get the miniport device descriptor + Status = MidiMiniport->GetDescription(&m_pDescriptor); + if (!NT_SUCCESS(Status)) + { + DPRINT1("failed to get description\n"); + MidiMiniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // increment reference on miniport adapter + MidiMiniport->AddRef(); + } + + // create the subdevice descriptor + Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, + 3, + InterfaceGuids, + 0, + NULL, + 2, + PortDMusPropertySet, + 0, + 0, + 0, + NULL, + 0, + NULL, + m_pDescriptor); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create descriptior\n"); + + if (Miniport) + Miniport->Release(); + else + MidiMiniport->Release(); + + m_bInitialized = FALSE; + return Status; + } + + if (m_ServiceGroup == NULL && ServiceGroup) + { + // register service group + m_ServiceGroup = ServiceGroup; + } + + // check if it supports IPinCount interface + Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount); + if (NT_SUCCESS(Status)) + { + // store IPinCount interface + m_pPinCount = PinCount; + } + + // does the Miniport adapter support IPowerNotify interface*/ + Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify); + if (NT_SUCCESS(Status)) + { + // store reference + m_pPowerNotify = PowerNotify; + } + + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortDMus::NewRegistryKey( + 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) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortDMus_fnNewRegistryKey called w/o initialized\n"); + return STATUS_UNSUCCESSFUL; + } + + return PcNewRegistryKey(OutRegistryKey, + OuterUnknown, + RegistryKeyType, + DesiredAccess, + m_pDeviceObject, + NULL,//FIXME + ObjectAttributes, + CreateOptions, + Disposition); +} + +VOID +NTAPI +CPortDMus::Notify( + IN PSERVICEGROUP ServiceGroup OPTIONAL) +{ + if (ServiceGroup) + { + ServiceGroup->RequestService (); + return; + } + + PC_ASSERT(m_ServiceGroup); + + // notify miniport service group + m_ServiceGroup->RequestService(); + + // notify stream miniport service group + if (m_Filter) + { + m_Filter->NotifyPins(); + } +} + +VOID +NTAPI +CPortDMus::RegisterServiceGroup( + IN PSERVICEGROUP ServiceGroup) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + m_ServiceGroup = ServiceGroup; + + ServiceGroup->AddMember(PSERVICESINK(this)); +} +//--------------------------------------------------------------- +// ISubdevice interface +// + +NTSTATUS +NTAPI +CPortDMus::NewIrpTarget( + 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; + + DPRINT("ISubDevice_NewIrpTarget this %p\n", this); + + if (m_Filter) + { + *OutTarget = (IIrpTarget*)m_Filter; + return STATUS_SUCCESS; + } + + + Status = NewPortFilterDMus(&Filter); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status = Filter->Init(PPORTDMUS(this)); + if (!NT_SUCCESS(Status)) + { + Filter->Release(); + return Status; + } + + *OutTarget = (IIrpTarget*)Filter; + return Status; +} + +NTSTATUS +NTAPI +CPortDMus::ReleaseChildren() +{ + UNIMPLEMENTED + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortDMus::GetDescriptor( + IN SUBDEVICE_DESCRIPTOR ** Descriptor) +{ + DPRINT("ISubDevice_GetDescriptor this %p\n", this); + *Descriptor = m_SubDeviceDescriptor; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortDMus::DataRangeIntersection( + IN ULONG PinId, + IN PKSDATARANGE DataRange, + IN PKSDATARANGE MatchingDataRange, + IN ULONG OutputBufferLength, + OUT PVOID ResultantFormat OPTIONAL, + OUT PULONG ResultantFormatLength) +{ + DPRINT("ISubDevice_DataRangeIntersection this %p\n", this); + + if (m_pMiniport) + { + return m_pMiniport->DataRangeIntersection (PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength); + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortDMus::PowerChangeNotify( + IN POWER_STATE PowerState) +{ + if (m_pPowerNotify) + { + m_pPowerNotify->PowerChangeNotify(PowerState); + } + + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortDMus::PinCount( + IN ULONG PinId, + IN OUT PULONG FilterNecessary, + IN OUT PULONG FilterCurrent, + IN OUT PULONG FilterPossible, + IN OUT PULONG GlobalCurrent, + IN OUT PULONG GlobalPossible) +{ + if (m_pPinCount) + { + m_pPinCount->PinCount(PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible); + return STATUS_SUCCESS; + } + + // FIXME + // scan filter descriptor + + return STATUS_UNSUCCESSFUL; +} + + + +NTSTATUS +NewPortDMus( + OUT PPORT* OutPort) +{ + NTSTATUS Status; + CPortDMus * Port = new(NonPagedPool, TAG_PORTCLASS) CPortDMus(NULL); + if (!Port) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = Port->QueryInterface(IID_IPort, (PVOID*)OutPort); + + if (!NT_SUCCESS(Status)) + { + delete Port; + } + + DPRINT("NewPortDMus %p Status %u\n", Port, Status); + return Status; + +} + + + +VOID +GetDMusMiniport( + IN IPortDMus * iface, + IN PMINIPORTDMUS * Miniport, + IN PMINIPORTMIDI * MidiMiniport) +{ + CPortDMus * This = (CPortDMus*)iface; + + *Miniport = This->m_pMiniport; + *MidiMiniport = This->m_pMiniportMidi; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_factory.c b/reactos/drivers/wdm/audio/backpln/portcls/port_factory.cpp similarity index 100% rename from reactos/drivers/wdm/audio/backpln/portcls/port_factory.c rename to reactos/drivers/wdm/audio/backpln/portcls/port_factory.cpp diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c deleted file mode 100644 index 6f3f30cfd61..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c +++ /dev/null @@ -1,823 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/port_topology.c - * PURPOSE: Topology Port driver - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IPortTopologyVtbl *lpVtbl; - ISubdeviceVtbl *lpVtblSubDevice; - IPortEventsVtbl *lpVtblPortEvents; - - LONG ref; - BOOL bInitialized; - - PMINIPORTTOPOLOGY pMiniport; - PDEVICE_OBJECT pDeviceObject; - PPINCOUNT pPinCount; - PPOWERNOTIFY pPowerNotify; - - PPCFILTER_DESCRIPTOR pDescriptor; - PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor; - IPortFilterTopology * Filter; -}IPortTopologyImpl; - -typedef struct -{ - PIRP Irp; - IIrpTarget *Filter; - PIO_WORKITEM WorkItem; -}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT; - -static GUID InterfaceGuids[2] = -{ - { - /// KS_CATEGORY_TOPOLOGY - 0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00} - }, - { - /// KS_CATEGORY_AUDIO - 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} - } -}; - -DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterTopologyTopologySet, TopologyPropertyHandler); -DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterTopologyPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); - -KSPROPERTY_SET TopologyPropertySet[] = -{ - { - &KSPROPSETID_Topology, - sizeof(PortFilterTopologyTopologySet) / sizeof(KSPROPERTY_ITEM), - (const KSPROPERTY_ITEM*)&PortFilterTopologyTopologySet, - 0, - NULL - }, - { - &KSPROPSETID_Pin, - sizeof(PortFilterTopologyPinSet) / sizeof(KSPROPERTY_ITEM), - (const KSPROPERTY_ITEM*)&PortFilterTopologyPinSet, - 0, - NULL - } -}; - -//--------------------------------------------------------------- -// IPortEvents -// - -static -NTSTATUS -NTAPI -IPortEvents_fnQueryInterface( - IPortEvents* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblPortEvents); - - DPRINT("IPortEvents_fnQueryInterface entered\n"); - - if (IsEqualGUIDAligned(refiid, &IID_IPortEvents) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtblPortEvents; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -static -ULONG -NTAPI -IPortEvents_fnAddRef( - IPortEvents* iface) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblPortEvents); - DPRINT("IPortEvents_fnQueryInterface entered\n"); - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IPortEvents_fnRelease( - IPortEvents* iface) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, 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 -IPortTopology_fnQueryInterface( - IPortTopology* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - UNICODE_STRING GuidString; - IPortTopologyImpl * This = (IPortTopologyImpl*)iface; - - DPRINT("IPortTopology_fnQueryInterface\n"); - - if (IsEqualGUIDAligned(refiid, &IID_IPortTopology) || - 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_IPortEvents)) - { - *Output = &This->lpVtblPortEvents; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion)) - { - return NewPortClsVersion((PPORTCLSVERSION*)Output); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) - { - return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) - { - return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); - } - - if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) - { - DPRINT1("IPortTopology_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); - RtlFreeUnicodeString(&GuidString); - } - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IPortTopology_fnAddRef( - IPortTopology* iface) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)iface; - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IPortTopology_fnRelease( - IPortTopology* iface) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)iface; - - InterlockedDecrement(&This->ref); - DPRINT("Reference Count %u\n", This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - - -//--------------------------------------------------------------- -// IPort interface functions -// - -NTSTATUS -NTAPI -IPortTopology_fnGetDeviceProperty( - IN IPortTopology * iface, - IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, - IN ULONG BufferLength, - OUT PVOID PropertyBuffer, - OUT PULONG ReturnLength) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)iface; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortTopology_fnNewRegistryKey called w/o initiazed\n"); - return STATUS_UNSUCCESSFUL; - } - - return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); -} - -NTSTATUS -NTAPI -IPortTopology_fnInit( - IN IPortTopology * iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PUNKNOWN UnknownMiniport, - IN PUNKNOWN UnknownAdapter OPTIONAL, - IN PRESOURCELIST ResourceList) -{ - IMiniportTopology * Miniport; - NTSTATUS Status; - IPortTopologyImpl * This = (IPortTopologyImpl*)iface; - - DPRINT("IPortTopology_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("IPortTopology_Init called again\n"); - return STATUS_SUCCESS; - } - - Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportTopology, (PVOID*)&Miniport); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IPortTopology_Init called with invalid IMiniport adapter\n"); - return STATUS_INVALID_PARAMETER; - } - - /* Initialize port object */ - This->pMiniport = Miniport; - This->pDeviceObject = DeviceObject; - This->bInitialized = TRUE; - - /* now initialize the miniport driver */ - Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IPortTopology_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; - } - - /* create the subdevice descriptor */ - Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor, - 2, - InterfaceGuids, - 0, - NULL, - 2, - TopologyPropertySet, - 0, - 0, - 0, - NULL, - 0, - NULL, - This->pDescriptor); - - - DPRINT("IPortTopology_fnInit success\n"); - return STATUS_SUCCESS; -} - - -NTSTATUS -NTAPI -IPortTopology_fnNewRegistryKey( - IN IPortTopology * 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) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)iface; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortTopology_fnNewRegistryKey called w/o initialized\n"); - return STATUS_UNSUCCESSFUL; - } - return PcNewRegistryKey(OutRegistryKey, - OuterUnknown, - RegistryKeyType, - DesiredAccess, - This->pDeviceObject, - NULL,//FIXME - ObjectAttributes, - CreateOptions, - Disposition); -} - -static IPortTopologyVtbl vt_IPortTopology = -{ - /* IUnknown methods */ - IPortTopology_fnQueryInterface, - IPortTopology_fnAddRef, - IPortTopology_fnRelease, - /* IPort methods */ - IPortTopology_fnInit, - IPortTopology_fnGetDeviceProperty, - IPortTopology_fnNewRegistryKey -}; - -//--------------------------------------------------------------- -// ISubdevice interface -// - -static -NTSTATUS -NTAPI -ISubDevice_fnQueryInterface( - IN ISubdevice *iface, - IN REFIID InterfaceId, - IN PVOID* Interface) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - - return IPortTopology_fnQueryInterface((IPortTopology*)This, InterfaceId, Interface); -} - -static -ULONG -NTAPI -ISubDevice_fnAddRef( - IN ISubdevice *iface) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - - return IPortTopology_fnAddRef((IPortTopology*)This); -} - -static -ULONG -NTAPI -ISubDevice_fnRelease( - IN ISubdevice *iface) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - - return IPortTopology_fnRelease((IPortTopology*)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; - IPortFilterTopology * Filter; - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - - /* is there already an instance of the filter */ - if (This->Filter) - { - /* it is, let's return the result */ - *OutTarget = (IIrpTarget*)This->Filter; - - /* increment reference */ - This->Filter->lpVtbl->AddRef(This->Filter); - return STATUS_SUCCESS; - } - - /* create new instance of filter */ - Status = NewPortFilterTopology(&Filter); - if (!NT_SUCCESS(Status)) - { - /* not enough memory */ - return Status; - } - - /* initialize the filter */ - Status = Filter->lpVtbl->Init(Filter, (IPortTopology*)This); - if (!NT_SUCCESS(Status)) - { - /* destroy filter */ - Filter->lpVtbl->Release(Filter); - /* return status */ - return Status; - } - - /* store result */ - *OutTarget = (IIrpTarget*)Filter; - /* store for later re-use */ - This->Filter = Filter; - /* return status */ - return Status; -} - -static -NTSTATUS -NTAPI -ISubDevice_fnReleaseChildren( - IN ISubdevice *iface) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - - DPRINT1("ISubDevice_fnReleaseChildren with ref %u\n", This->ref); - - /* release the filter */ - This->Filter->lpVtbl->Release(This->Filter); - - /* release the miniport */ - DPRINT("Refs %u %u\n", This->pMiniport->lpVtbl->Release(This->pMiniport), This->ref); - - return STATUS_SUCCESS; -} - -static -NTSTATUS -NTAPI -ISubDevice_fnGetDescriptor( - IN ISubdevice *iface, - IN SUBDEVICE_DESCRIPTOR ** Descriptor) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - - DPRINT("ISubDevice_GetDescriptor this %p Descp %p\n", This, This->SubDeviceDescriptor); - *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) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, 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) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, 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) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, 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 -}; - -VOID -NTAPI -CreatePinWorkerRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - NTSTATUS Status; - IIrpTarget *Pin; - PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; - - DPRINT("CreatePinWorkerRoutine called\n"); - /* create the pin */ - Status = WorkerContext->Filter->lpVtbl->NewIrpTarget(WorkerContext->Filter, - &Pin, - NULL, - NULL, - NonPagedPool, - DeviceObject, - WorkerContext->Irp, - NULL); - - DPRINT1("CreatePinWorkerRoutine Status %x\n", Status); - - if (NT_SUCCESS(Status)) - { - /* create the dispatch object */ - /* FIXME need create item for clock */ - Status = NewDispatchObject(WorkerContext->Irp, Pin, 0, NULL); - DPRINT("Pin %p\n", Pin); - } - - DPRINT("CreatePinWorkerRoutine completing irp %p\n", WorkerContext->Irp); - /* save status in irp */ - WorkerContext->Irp->IoStatus.Status = Status; - WorkerContext->Irp->IoStatus.Information = 0; - /* complete the request */ - IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT); - /* free allocated work item */ - IoFreeWorkItem(WorkerContext->WorkItem); - /* free context */ - FreeItem(WorkerContext, TAG_PORTCLASS); -} - -NTSTATUS -NTAPI -PcCreatePinDispatch( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - IIrpTarget *Filter; - PKSOBJECT_CREATE_ITEM CreateItem; - PPIN_WORKER_CONTEXT Context; - - /* access the create item */ - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - /* sanity check */ - ASSERT(CreateItem); - - DPRINT1("PcCreatePinDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer); - - Filter = (IIrpTarget*)CreateItem->Context; - - /* sanity checks */ - ASSERT(Filter != NULL); - - -#if KS_IMPLEMENTED - Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader); - if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED) - { - DPRINT1("PcCreatePinDispatch failed to reference device header\n"); - - FreeItem(Entry, TAG_PORTCLASS); - goto cleanup; - } -#endif - - /* new pins are instantiated at passive level, - * so allocate a work item and context for it - */ - - Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS); - if (!Context) - { - DPRINT("Failed to allocate worker context\n"); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* allocate work item */ - Context->WorkItem = IoAllocateWorkItem(DeviceObject); - if (!Context->WorkItem) - { - DPRINT("Failed to allocate workitem\n"); - FreeItem(Context, TAG_PORTCLASS); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Context->Filter = Filter; - Context->Irp = Irp; - - DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql()); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_PENDING; - IoMarkIrpPending(Irp); - IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); - return STATUS_PENDING; -} - - - -NTSTATUS -NTAPI -PcCreateItemDispatch( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - NTSTATUS Status; - ISubdevice * SubDevice; - IIrpTarget *Filter; - PKSOBJECT_CREATE_ITEM CreateItem, PinCreateItem; - - static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; - - /* access the create item */ - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - - DPRINT1("PcCreateItemDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer); - - /* get the subdevice */ - SubDevice = (ISubdevice*)CreateItem->Context; - - /* sanity checks */ - ASSERT(SubDevice != NULL); - -#if KS_IMPLEMENTED - Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader); - if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED) - { - DPRINT1("PcCreateItemDispatch failed to reference device header\n"); - - FreeItem(Entry, TAG_PORTCLASS); - goto cleanup; - } -#endif - - /* get filter object - * is implemented as a singleton - */ - Status = SubDevice->lpVtbl->NewIrpTarget(SubDevice, - &Filter, - NULL, - NULL, - NonPagedPool, - DeviceObject, - Irp, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to get filter object\n"); - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; - } - - /* allocate pin create item */ - PinCreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS); - if (!PinCreateItem) - { - /* not enough memory */ - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* initialize pin create item */ - PinCreateItem->Context = (PVOID)Filter; - PinCreateItem->Create = PcCreatePinDispatch; - RtlInitUnicodeString(&PinCreateItem->ObjectClass, KS_NAME_PIN); - /* FIXME copy security descriptor */ - - /* now allocate a dispatch object */ - Status = NewDispatchObject(Irp, Filter, 1, PinCreateItem); - - /* complete request */ - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; -} - -NTSTATUS -NewPortTopology( - OUT PPORT* OutPort) -{ - IPortTopologyImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IPortTopologyImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - This->lpVtbl = &vt_IPortTopology; - This->lpVtblSubDevice = &vt_ISubdeviceVtbl; - This->lpVtblPortEvents = &vt_IPortEvents; - This->ref = 1; - *OutPort = (PPORT)(&This->lpVtbl); - DPRINT("NewPortTopology result %p\n", *OutPort); - - return STATUS_SUCCESS; -} - -PMINIPORTTOPOLOGY -GetTopologyMiniport( - PPORTTOPOLOGY Port) -{ - IPortTopologyImpl * This = (IPortTopologyImpl*)Port; - return This->pMiniport; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp new file mode 100644 index 00000000000..291a017bc29 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp @@ -0,0 +1,665 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/port_topology.cpp + * PURPOSE: Topology Port driver + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortTopology : public IPortTopology, + public ISubdevice, + public IPortEvents +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortTopology; + IMP_ISubdevice; + IMP_IPortEvents; + CPortTopology(IUnknown *OuterUnknown){} + virtual ~CPortTopology(){} + +protected: + BOOL m_bInitialized; + + PMINIPORTTOPOLOGY m_pMiniport; + PDEVICE_OBJECT m_pDeviceObject; + PPINCOUNT m_pPinCount; + PPOWERNOTIFY m_pPowerNotify; + + PPCFILTER_DESCRIPTOR m_pDescriptor; + PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; + IPortFilterTopology * m_Filter; + + LONG m_Ref; + + friend PMINIPORTTOPOLOGY GetTopologyMiniport(PPORTTOPOLOGY Port); + +}; + +typedef struct +{ + PIRP Irp; + IIrpTarget *Filter; + PIO_WORKITEM WorkItem; +}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT; + +static GUID InterfaceGuids[2] = +{ + { + /// KS_CATEGORY_TOPOLOGY + 0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00} + }, + { + /// KS_CATEGORY_AUDIO + 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96} + } +}; + +DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterTopologyTopologySet, TopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterTopologyPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); + +KSPROPERTY_SET TopologyPropertySet[] = +{ + { + &KSPROPSETID_Topology, + sizeof(PortFilterTopologyTopologySet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterTopologyTopologySet, + 0, + NULL + }, + { + &KSPROPSETID_Pin, + sizeof(PortFilterTopologyPinSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterTopologyPinSet, + 0, + NULL + } +}; + +//--------------------------------------------------------------- +// IPortEvents +// + + +void +NTAPI +CPortTopology::AddEventToEventList( + IN PKSEVENT_ENTRY EventEntry) +{ + UNIMPLEMENTED +} + +void +NTAPI +CPortTopology::GenerateEventList( + IN GUID* Set OPTIONAL, + IN ULONG EventId, + IN BOOL PinEvent, + IN ULONG PinId, + IN BOOL NodeEvent, + IN ULONG NodeId) +{ + UNIMPLEMENTED +} + + +//--------------------------------------------------------------- +// IUnknown interface functions +// + +NTSTATUS +NTAPI +CPortTopology::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + UNICODE_STRING GuidString; + + DPRINT("IPortTopology_fnQueryInterface\n"); + + if (IsEqualGUIDAligned(refiid, IID_IPortTopology) || + IsEqualGUIDAligned(refiid, IID_IPort) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PUNKNOWN((IPortTopology*)this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_ISubdevice)) + { + *Output = PVOID(PSUBDEVICE(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPortEvents)) + { + *Output = PVOID(PPORTEVENTS(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion)) + { + return NewPortClsVersion((PPORTCLSVERSION*)Output); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } + + if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) + { + DPRINT1("IPortTopology_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + } + return STATUS_UNSUCCESSFUL; +} + +//--------------------------------------------------------------- +// IPort interface functions +// + +NTSTATUS +NTAPI +CPortTopology::GetDeviceProperty( + IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, + IN ULONG BufferLength, + OUT PVOID PropertyBuffer, + OUT PULONG ReturnLength) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortTopology_fnNewRegistryKey called w/o initiazed\n"); + return STATUS_UNSUCCESSFUL; + } + + return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); +} + +NTSTATUS +NTAPI +CPortTopology::Init( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PUNKNOWN UnknownMiniport, + IN PUNKNOWN UnknownAdapter OPTIONAL, + IN PRESOURCELIST ResourceList) +{ + IMiniportTopology * Miniport; + NTSTATUS Status; + + DPRINT("IPortTopology_fnInit entered This %p DeviceObject %p Irp %p UnknownMiniport %p UnknownAdapter %p ResourceList %p\n", + this, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList); + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_bInitialized) + { + DPRINT1("IPortTopology_Init called again\n"); + return STATUS_SUCCESS; + } + + Status = UnknownMiniport->QueryInterface(IID_IMiniportTopology, (PVOID*)&Miniport); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IPortTopology_Init called with invalid IMiniport adapter\n"); + return STATUS_INVALID_PARAMETER; + } + + // Initialize port object + m_pMiniport = Miniport; + m_pDeviceObject = DeviceObject; + m_bInitialized = TRUE; + + // now initialize the miniport driver + Status = Miniport->Init(UnknownAdapter, ResourceList, this); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IPortTopology_Init failed with %x\n", Status); + m_bInitialized = FALSE; + Miniport->Release(); + return Status; + } + + // get the miniport device descriptor + Status = Miniport->GetDescription(&m_pDescriptor); + if (!NT_SUCCESS(Status)) + { + DPRINT1("failed to get description\n"); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // create the subdevice descriptor + Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, + 2, + InterfaceGuids, + 0, + NULL, + 2, + TopologyPropertySet, + 0, + 0, + 0, + NULL, + 0, + NULL, + m_pDescriptor); + + + DPRINT("IPortTopology_fnInit success\n"); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortTopology::NewRegistryKey( + 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) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortTopology_fnNewRegistryKey called w/o initialized\n"); + return STATUS_UNSUCCESSFUL; + } + return PcNewRegistryKey(OutRegistryKey, + OuterUnknown, + RegistryKeyType, + DesiredAccess, + m_pDeviceObject, + NULL,//FIXME + ObjectAttributes, + CreateOptions, + Disposition); +} + +//--------------------------------------------------------------- +// ISubdevice interface +// + +NTSTATUS +NTAPI +CPortTopology::NewIrpTarget( + 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; + IPortFilterTopology * Filter; + + // is there already an instance of the filter + if (m_Filter) + { + // it is, let's return the result + *OutTarget = (IIrpTarget*)m_Filter; + + // increment reference + m_Filter->AddRef(); + return STATUS_SUCCESS; + } + + // create new instance of filter + Status = NewPortFilterTopology(&Filter); + if (!NT_SUCCESS(Status)) + { + // not enough memory + return Status; + } + + // initialize the filter + Status = Filter->Init((IPortTopology*)this); + if (!NT_SUCCESS(Status)) + { + // destroy filter + Filter->Release(); + // return status + return Status; + } + + // store result + *OutTarget = (IIrpTarget*)Filter; + // store for later re-use + m_Filter = Filter; + // return status + return Status; +} + +NTSTATUS +NTAPI +CPortTopology::ReleaseChildren() +{ + DPRINT1("ISubDevice_fnReleaseChildren\n"); + + // release the filter + m_Filter->Release(); + + // release the miniport + DPRINT("Refs %u\n", m_pMiniport->Release()); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortTopology::GetDescriptor( + IN SUBDEVICE_DESCRIPTOR ** Descriptor) +{ + DPRINT("ISubDevice_GetDescriptor this %p Descp %p\n", this, m_SubDeviceDescriptor); + *Descriptor = m_SubDeviceDescriptor; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortTopology::DataRangeIntersection( + IN ULONG PinId, + IN PKSDATARANGE DataRange, + IN PKSDATARANGE MatchingDataRange, + IN ULONG OutputBufferLength, + OUT PVOID ResultantFormat OPTIONAL, + OUT PULONG ResultantFormatLength) +{ + DPRINT("ISubDevice_DataRangeIntersection this %p\n", this); + + if (m_pMiniport) + { + return m_pMiniport->DataRangeIntersection (PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength); + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortTopology::PowerChangeNotify( + IN POWER_STATE PowerState) +{ + if (m_pPowerNotify) + { + m_pPowerNotify->PowerChangeNotify(PowerState); + } + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortTopology::PinCount( + IN ULONG PinId, + IN OUT PULONG FilterNecessary, + IN OUT PULONG FilterCurrent, + IN OUT PULONG FilterPossible, + IN OUT PULONG GlobalCurrent, + IN OUT PULONG GlobalPossible) +{ + if (m_pPinCount) + { + m_pPinCount->PinCount(PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible); + return STATUS_SUCCESS; + } + + // FIXME + // scan filter descriptor + + return STATUS_UNSUCCESSFUL; +} + + +VOID +NTAPI +CreatePinWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + NTSTATUS Status; + IIrpTarget *Pin; + PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; + + DPRINT("CreatePinWorkerRoutine called\n"); + // create the pin + Status = WorkerContext->Filter->NewIrpTarget(&Pin, + NULL, + NULL, + NonPagedPool, + DeviceObject, + WorkerContext->Irp, + NULL); + + DPRINT1("CreatePinWorkerRoutine Status %x\n", Status); + + if (NT_SUCCESS(Status)) + { + // create the dispatch object + // FIXME need create item for clock + Status = NewDispatchObject(WorkerContext->Irp, Pin, 0, NULL); + DPRINT("Pin %p\n", Pin); + } + + DPRINT("CreatePinWorkerRoutine completing irp %p\n", WorkerContext->Irp); + // save status in irp + WorkerContext->Irp->IoStatus.Status = Status; + WorkerContext->Irp->IoStatus.Information = 0; + // complete the request + IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT); + // free allocated work item + IoFreeWorkItem(WorkerContext->WorkItem); + // free context + FreeItem(WorkerContext, TAG_PORTCLASS); +} + +NTSTATUS +NTAPI +PcCreatePinDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + IIrpTarget *Filter; + PKSOBJECT_CREATE_ITEM CreateItem; + PPIN_WORKER_CONTEXT Context; + + // access the create item + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + // sanity check + PC_ASSERT(CreateItem); + + DPRINT1("PcCreatePinDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer); + + Filter = (IIrpTarget*)CreateItem->Context; + + // sanity checks + PC_ASSERT(Filter != NULL); + + +#if KS_IMPLEMENTED + Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader); + if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED) + { + DPRINT1("PcCreatePinDispatch failed to reference device header\n"); + + FreeItem(Entry, TAG_PORTCLASS); + goto cleanup; + } +#endif + + // new pins are instantiated at passive level, + // so allocate a work item and context for it + + + Context = (PPIN_WORKER_CONTEXT)AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS); + if (!Context) + { + DPRINT("Failed to allocate worker context\n"); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // allocate work item + Context->WorkItem = IoAllocateWorkItem(DeviceObject); + if (!Context->WorkItem) + { + DPRINT("Failed to allocate workitem\n"); + FreeItem(Context, TAG_PORTCLASS); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Context->Filter = Filter; + Context->Irp = Irp; + + DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql()); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_PENDING; + IoMarkIrpPending(Irp); + IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); + return STATUS_PENDING; +} + + + +NTSTATUS +NTAPI +PcCreateItemDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + NTSTATUS Status; + ISubdevice * SubDevice; + IIrpTarget *Filter; + PKSOBJECT_CREATE_ITEM CreateItem, PinCreateItem; + + // access the create item + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + + DPRINT1("PcCreateItemDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer); + + // get the subdevice + SubDevice = (ISubdevice*)CreateItem->Context; + + // sanity checks + PC_ASSERT(SubDevice != NULL); + +#if KS_IMPLEMENTED + Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader); + if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED) + { + DPRINT1("PcCreateItemDispatch failed to reference device header\n"); + + FreeItem(Entry, TAG_PORTCLASS); + goto cleanup; + } +#endif + + // get filter object + Status = SubDevice->NewIrpTarget(&Filter, + NULL, + NULL, + NonPagedPool, + DeviceObject, + Irp, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to get filter object\n"); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + // allocate pin create item + PinCreateItem = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS); + if (!PinCreateItem) + { + // not enough memory + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // initialize pin create item + PinCreateItem->Context = (PVOID)Filter; + PinCreateItem->Create = PcCreatePinDispatch; + RtlInitUnicodeString(&PinCreateItem->ObjectClass, KSSTRING_Pin); + // FIXME copy security descriptor + + // now allocate a dispatch object + Status = NewDispatchObject(Irp, Filter, 1, PinCreateItem); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + + +NTSTATUS +NewPortTopology( + OUT PPORT* OutPort) +{ + CPortTopology * This; + NTSTATUS Status; + + This= new(NonPagedPool, TAG_PORTCLASS) CPortTopology(NULL); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = This->QueryInterface(IID_IPort, (PVOID*)OutPort); + + if (!NT_SUCCESS(Status)) + { + delete This; + } + + DPRINT("NewPortTopology %p Status %x\n", *OutPort, Status); + return Status; +} + + +PMINIPORTTOPOLOGY +GetTopologyMiniport( + PPORTTOPOLOGY Port) +{ + CPortTopology * This = (CPortTopology*)Port; + return This->m_pMiniport; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c deleted file mode 100644 index ea18ad2473a..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/port_wavecyclic.c - * PURPOSE: WaveCyclic Port Driver - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -extern GUID IID_IDmaChannelSlave; - -typedef struct -{ - IPortWaveCyclicVtbl *lpVtbl; - IPortEventsVtbl *lpVtblPortEvents; - ISubdeviceVtbl *lpVtblSubDevice; - - LONG ref; - - BOOL bInitialized; - PDEVICE_OBJECT pDeviceObject; - PMINIPORTWAVECYCLIC pMiniport; - PRESOURCELIST pResourceList; - PPINCOUNT pPinCount; - PPOWERNOTIFY pPowerNotify; - PPCFILTER_DESCRIPTOR pDescriptor; - PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor; - IPortFilterWaveCyclic * Filter; -}IPortWaveCyclicImpl; - -GUID KSPROPERTY_SETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; - -static GUID InterfaceGuids[4] = -{ - { - /// 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} - }, - { - ///KSCATEGORY_AUDIO_DEVICE - 0xFBF6F530L, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88} - } - -}; - -DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWaveCyclicTopologySet, TopologyPropertyHandler); -DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWaveCyclicPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); - -KSPROPERTY_SET WaveCyclicPropertySet[] = -{ - { - &KSPROPSETID_Topology, - sizeof(PortFilterWaveCyclicTopologySet) / sizeof(KSPROPERTY_ITEM), - (const KSPROPERTY_ITEM*)&PortFilterWaveCyclicTopologySet, - 0, - NULL - }, - { - &KSPROPSETID_Pin, - sizeof(PortFilterWaveCyclicPinSet) / sizeof(KSPROPERTY_ITEM), - (const KSPROPERTY_ITEM*)&PortFilterWaveCyclicPinSet, - 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) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblPortEvents); - - DPRINT("IPortEvents_fnQueryInterface entered\n"); - - if (IsEqualGUIDAligned(refiid, &IID_IPortEvents) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtblPortEvents; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -static -ULONG -NTAPI -IPortEvents_fnAddRef( - IPortEvents* iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblPortEvents); - DPRINT("IPortEvents_fnQueryInterface entered\n"); - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IPortEvents_fnRelease( - IPortEvents* iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, 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 -IPortWaveCyclic_fnQueryInterface( - IPortWaveCyclic* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - UNICODE_STRING GuidString; - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IPortWaveCyclic) || - 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); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) - { - return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) - { - return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); - } - - if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) - { - DPRINT1("IPortWaveCyclic_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); - RtlFreeUnicodeString(&GuidString); - } - - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IPortWaveCyclic_fnAddRef( - IPortWaveCyclic* iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - DPRINT("IPortWaveCyclic_fnAddRef %u entered\n", This->ref); - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IPortWaveCyclic_fnRelease( - IPortWaveCyclic* iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - - InterlockedDecrement(&This->ref); - DPRINT("IPortWaveCyclic_fnRelease %u entered\n", This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - - -//--------------------------------------------------------------- -// IPort interface functions -// - -NTSTATUS -NTAPI -IPortWaveCyclic_fnGetDeviceProperty( - IN IPortWaveCyclic * iface, - IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, - IN ULONG BufferLength, - OUT PVOID PropertyBuffer, - OUT PULONG ReturnLength) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initiazed\n"); - return STATUS_UNSUCCESSFUL; - } - - return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); -} - -NTSTATUS -NTAPI -IPortWaveCyclic_fnInit( - IN IPortWaveCyclic * iface, - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PUNKNOWN UnknownMiniport, - IN PUNKNOWN UnknownAdapter OPTIONAL, - IN PRESOURCELIST ResourceList) -{ - IMiniportWaveCyclic * Miniport; - NTSTATUS Status; - PPINCOUNT PinCount; - PPOWERNOTIFY PowerNotify; - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - - DPRINT("IPortWaveCyclic_Init entered %p\n", This); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->bInitialized) - { - DPRINT("IPortWaveCyclic_Init called again\n"); - return STATUS_SUCCESS; - } - - Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportWaveCyclic, (PVOID*)&Miniport); - if (!NT_SUCCESS(Status)) - { - DPRINT("IPortWaveCyclic_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; - - - if (ResourceList) - { - /* increment reference on resource list */ - ResourceList->lpVtbl->AddRef(ResourceList); - } - - Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface); - if (!NT_SUCCESS(Status)) - { - DPRINT("IMiniportWaveCyclic_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, - 4, - InterfaceGuids, - 0, - NULL, - 2, - WaveCyclicPropertySet, - 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; - } - - DPRINT("IPortWaveCyclic successfully initialized\n"); - return STATUS_SUCCESS; -} - - -NTSTATUS -NTAPI -IPortWaveCyclic_fnNewRegistryKey( - IN IPortWaveCyclic * 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) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n"); - return STATUS_UNSUCCESSFUL; - } - return PcNewRegistryKey(OutRegistryKey, OuterUnknown, RegistryKeyType, DesiredAccess, This->pDeviceObject, NULL /*FIXME*/, ObjectAttributes, CreateOptions, Disposition); -} - - -//--------------------------------------------------------------- -// IPortWaveCyclic interface functions -// - -NTSTATUS -NTAPI -IPortWaveCyclic_fnNewMasterDmaChannel( - IN IPortWaveCyclic * iface, - OUT PDMACHANNEL* DmaChannel, - IN PUNKNOWN OuterUnknown, - IN PRESOURCELIST ResourceList OPTIONAL, - IN ULONG MaximumLength, - IN BOOL Dma32BitAddresses, - IN BOOL Dma64BitAddresses, - IN DMA_WIDTH DmaWidth, - IN DMA_SPEED DmaSpeed) -{ - NTSTATUS Status; - DEVICE_DESCRIPTION DeviceDescription; - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n"); - return STATUS_UNSUCCESSFUL; - } - - Status = PcDmaMasterDescription(ResourceList, (Dma32BitAddresses | Dma64BitAddresses), Dma32BitAddresses, 0, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, 0, &DeviceDescription); - if (NT_SUCCESS(Status)) - { - return PcNewDmaChannel(DmaChannel, OuterUnknown, NonPagedPool, &DeviceDescription, This->pDeviceObject); - } - - return Status; -} - -NTSTATUS -NTAPI -IPortWaveCyclic_fnNewSlaveDmaChannel( - IN IPortWaveCyclic * iface, - OUT PDMACHANNELSLAVE* OutDmaChannel, - IN PUNKNOWN OuterUnknown, - IN PRESOURCELIST ResourceList OPTIONAL, - IN ULONG DmaIndex, - IN ULONG MaximumLength, - IN BOOL DemandMode, - IN DMA_SPEED DmaSpeed) -{ - DEVICE_DESCRIPTION DeviceDescription; - PDMACHANNEL DmaChannel; - NTSTATUS Status; - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n"); - return STATUS_UNSUCCESSFUL; - } - - // FIXME - // Check for F-Type DMA Support - // - - Status = PcDmaSlaveDescription(ResourceList, DmaIndex, DemandMode, TRUE, DmaSpeed, MaximumLength, 0, &DeviceDescription); - if (NT_SUCCESS(Status)) - { - Status = PcNewDmaChannel(&DmaChannel, OuterUnknown, NonPagedPool, &DeviceDescription, This->pDeviceObject); - if (NT_SUCCESS(Status)) - { - Status = DmaChannel->lpVtbl->QueryInterface(DmaChannel, &IID_IDmaChannelSlave, (PVOID*)OutDmaChannel); - DmaChannel->lpVtbl->Release(DmaChannel); - } - } - - return Status; -} - -VOID -NTAPI -IPortWaveCyclic_fnNotify( - IN IPortWaveCyclic * iface, - IN PSERVICEGROUP ServiceGroup) -{ - ServiceGroup->lpVtbl->RequestService (ServiceGroup); -} - -static IPortWaveCyclicVtbl vt_IPortWaveCyclicVtbl = -{ - IPortWaveCyclic_fnQueryInterface, - IPortWaveCyclic_fnAddRef, - IPortWaveCyclic_fnRelease, - IPortWaveCyclic_fnInit, - IPortWaveCyclic_fnGetDeviceProperty, - IPortWaveCyclic_fnNewRegistryKey, - IPortWaveCyclic_fnNotify, - IPortWaveCyclic_fnNewSlaveDmaChannel, - IPortWaveCyclic_fnNewMasterDmaChannel -}; - -//--------------------------------------------------------------- -// ISubdevice interface -// - -static -NTSTATUS -NTAPI -ISubDevice_fnQueryInterface( - IN ISubdevice *iface, - IN REFIID InterfaceId, - IN PVOID* Interface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); - - return IPortWaveCyclic_fnQueryInterface((IPortWaveCyclic*)This, InterfaceId, Interface); -} - -static -ULONG -NTAPI -ISubDevice_fnAddRef( - IN ISubdevice *iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); - - return IPortWaveCyclic_fnAddRef((IPortWaveCyclic*)This); -} - -static -ULONG -NTAPI -ISubDevice_fnRelease( - IN ISubdevice *iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); - - return IPortWaveCyclic_fnRelease((IPortWaveCyclic*)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; - IPortFilterWaveCyclic * Filter; - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); - - DPRINT("ISubDevice_NewIrpTarget this %p\n", This); - - /* is there already an instance of the filter */ - if (This->Filter) - { - /* it is, let's return the result */ - *OutTarget = (IIrpTarget*)This->Filter; - - /* increment reference */ - This->Filter->lpVtbl->AddRef(This->Filter); - return STATUS_SUCCESS; - } - - /* create new instance of filter */ - Status = NewPortFilterWaveCyclic(&Filter); - if (!NT_SUCCESS(Status)) - { - /* not enough memory */ - return Status; - } - - /* initialize the filter */ - Status = Filter->lpVtbl->Init(Filter, (IPortWaveCyclic*)This); - if (!NT_SUCCESS(Status)) - { - /* destroy filter */ - Filter->lpVtbl->Release(Filter); - /* return status */ - return Status; - } - - /* store result */ - *OutTarget = (IIrpTarget*)Filter; - /* store for later re-use */ - This->Filter = Filter; - /* return status */ - return Status; -} - -static -NTSTATUS -NTAPI -ISubDevice_fnReleaseChildren( - IN ISubdevice *iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); - - DPRINT("ISubDevice_fnReleaseChildren ref %u\n", This->ref); - - /* release the filter */ - This->Filter->lpVtbl->Release(This->Filter); - - if (This->pPinCount) - { - /* release pincount interface */ - This->pPinCount->lpVtbl->Release(This->pPinCount); - } - - if (This->pPowerNotify) - { - /* release power notify interface */ - This->pPowerNotify->lpVtbl->Release(This->pPowerNotify); - } - - /* now release the miniport */ - This->pMiniport->lpVtbl->Release(This->pMiniport); - - return STATUS_SUCCESS; -} - -static -NTSTATUS -NTAPI -ISubDevice_fnGetDescriptor( - IN ISubdevice *iface, - IN SUBDEVICE_DESCRIPTOR ** Descriptor) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, 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) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, 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) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, 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) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, 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 -}; - - -///-------------------------------------------------------------- -PMINIPORTWAVECYCLIC -GetWaveCyclicMiniport( - IN IPortWaveCyclic* iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl *)iface; - return This->pMiniport; -} - -PDEVICE_OBJECT -GetDeviceObject( - PPORTWAVECYCLIC iface) -{ - IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl *)iface; - return This->pDeviceObject; -} - -//--------------------------------------------------------------- -// IPortWaveCyclic constructor -// - -NTSTATUS -NewPortWaveCyclic( - OUT PPORT* OutPort) -{ - IPortWaveCyclicImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IPortWaveCyclicImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - This->lpVtbl = &vt_IPortWaveCyclicVtbl; - This->lpVtblSubDevice = &vt_ISubdeviceVtbl; - This->lpVtblPortEvents = &vt_IPortEvents; - This->ref = 1; - *OutPort = (PPORT)(&This->lpVtbl); - - DPRINT("NewPortWaveCyclic %p\n", *OutPort); - - return STATUS_SUCCESS; -} - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp new file mode 100644 index 00000000000..af7c602d8db --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp @@ -0,0 +1,629 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp + * PURPOSE: WaveCyclic Port Driver + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +GUID IID_IDmaChannelSlave; + +class CPortWaveCyclic : public IPortWaveCyclic, + public IPortEvents, + public ISubdevice +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + DPRINT1("Release %u\n", m_Ref); + if (!m_Ref) + { + //delete this; + return 0; + } + return m_Ref; + } + IMP_IPortWaveCyclic; + IMP_ISubdevice; + IMP_IPortEvents; + CPortWaveCyclic(IUnknown *OuterUnknown){} + virtual ~CPortWaveCyclic(){} + +protected: + BOOL m_bInitialized; + PDEVICE_OBJECT m_pDeviceObject; + PMINIPORTWAVECYCLIC m_pMiniport; + PRESOURCELIST m_pResourceList; + PPINCOUNT m_pPinCount; + PPOWERNOTIFY m_pPowerNotify; + PPCFILTER_DESCRIPTOR m_pDescriptor; + PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; + IPortFilterWaveCyclic * m_Filter; + + LONG m_Ref; + + friend PMINIPORTWAVECYCLIC GetWaveCyclicMiniport(IN IPortWaveCyclic* iface); + friend PDEVICE_OBJECT GetDeviceObject(PPORTWAVECYCLIC iface); +}; + +GUID KSPROPERTY_SETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; + +static GUID InterfaceGuids[4] = +{ + { + /// 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} + }, + { + ///KSCATEGORY_AUDIO_DEVICE + 0xFBF6F530L, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88} + } + +}; + +DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWaveCyclicTopologySet, TopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWaveCyclicPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); + +KSPROPERTY_SET WaveCyclicPropertySet[] = +{ + { + &KSPROPSETID_Topology, + sizeof(PortFilterWaveCyclicTopologySet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterWaveCyclicTopologySet, + 0, + NULL + }, + { + &KSPROPSETID_Pin, + sizeof(PortFilterWaveCyclicPinSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterWaveCyclicPinSet, + 0, + NULL + } +}; + +//KSEVENTSETID_LoopedStreaming, Type = KSEVENT_LOOPEDSTREAMING_POSITION +//KSEVENTSETID_Connection, Type = KSEVENT_CONNECTION_ENDOFSTREAM, + + +//--------------------------------------------------------------- +// IPortEvents +// + +void +NTAPI +CPortWaveCyclic::AddEventToEventList( + IN PKSEVENT_ENTRY EventEntry) +{ + UNIMPLEMENTED +} + + +void +NTAPI +CPortWaveCyclic::GenerateEventList( + IN GUID* Set OPTIONAL, + IN ULONG EventId, + IN BOOL PinEvent, + IN ULONG PinId, + IN BOOL NodeEvent, + IN ULONG NodeId) +{ + UNIMPLEMENTED +} + +//--------------------------------------------------------------- +// IUnknown interface functions +// + +NTSTATUS +NTAPI +CPortWaveCyclic::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + UNICODE_STRING GuidString; + + if (IsEqualGUIDAligned(refiid, IID_IPortWaveCyclic) || + IsEqualGUIDAligned(refiid, IID_IPort) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PPORTWAVECYCLIC(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPortEvents)) + { + *Output = PVOID(PPORTEVENTS(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_ISubdevice)) + { + *Output = PVOID(PSUBDEVICE(this)); + PUNKNOWN(*Output)->AddRef(); + 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); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } + + if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) + { + DPRINT1("IPortWaveCyclic_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + } + + return STATUS_UNSUCCESSFUL; +} + +//--------------------------------------------------------------- +// IPort interface functions +// + +NTSTATUS +NTAPI +CPortWaveCyclic::GetDeviceProperty( + IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, + IN ULONG BufferLength, + OUT PVOID PropertyBuffer, + OUT PULONG ReturnLength) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initiazed\n"); + return STATUS_UNSUCCESSFUL; + } + + return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); +} + +NTSTATUS +NTAPI +CPortWaveCyclic::Init( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PUNKNOWN UnknownMiniport, + IN PUNKNOWN UnknownAdapter OPTIONAL, + IN PRESOURCELIST ResourceList) +{ + IMiniportWaveCyclic * Miniport; + NTSTATUS Status; + PPINCOUNT PinCount; + PPOWERNOTIFY PowerNotify; + + DPRINT("IPortWaveCyclic_Init entered %p\n", this); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_bInitialized) + { + DPRINT("IPortWaveCyclic_Init called again\n"); + return STATUS_SUCCESS; + } + + Status = UnknownMiniport->QueryInterface(IID_IMiniportWaveCyclic, (PVOID*)&Miniport); + if (!NT_SUCCESS(Status)) + { + DPRINT("IPortWaveCyclic_Init called with invalid IMiniport adapter\n"); + return STATUS_INVALID_PARAMETER; + } + + // Initialize port object + m_pMiniport = Miniport; + m_pDeviceObject = DeviceObject; + m_bInitialized = TRUE; + m_pResourceList = ResourceList; + + + if (ResourceList) + { + // increment reference on resource list + ResourceList->AddRef(); + } + + Status = Miniport->Init(UnknownAdapter, ResourceList, this); + if (!NT_SUCCESS(Status)) + { + DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + + // get the miniport device descriptor + Status = Miniport->GetDescription(&m_pDescriptor); + if (!NT_SUCCESS(Status)) + { + DPRINT1("failed to get description\n"); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // create the subdevice descriptor + Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, + 4, + InterfaceGuids, + 0, + NULL, + 2, + WaveCyclicPropertySet, + 0, + 0, + 0, + NULL, + 0, + NULL, + m_pDescriptor); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // check if it supports IPinCount interface + Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount); + if (NT_SUCCESS(Status)) + { + // store IPinCount interface + m_pPinCount = PinCount; + } + + // does the Miniport adapter support IPowerNotify interface*/ + Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify); + if (NT_SUCCESS(Status)) + { + // store reference + m_pPowerNotify = PowerNotify; + } + + DPRINT("IPortWaveCyclic successfully initialized\n"); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortWaveCyclic::NewRegistryKey( + 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) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n"); + return STATUS_UNSUCCESSFUL; + } + return PcNewRegistryKey(OutRegistryKey, OuterUnknown, RegistryKeyType, DesiredAccess, m_pDeviceObject, NULL /*FIXME*/, ObjectAttributes, CreateOptions, Disposition); +} + + +//--------------------------------------------------------------- +// IPortWaveCyclic interface functions +// + +NTSTATUS +NTAPI +CPortWaveCyclic::NewMasterDmaChannel( + OUT PDMACHANNEL* DmaChannel, + IN PUNKNOWN OuterUnknown, + IN PRESOURCELIST ResourceList OPTIONAL, + IN ULONG MaximumLength, + IN BOOL Dma32BitAddresses, + IN BOOL Dma64BitAddresses, + IN DMA_WIDTH DmaWidth, + IN DMA_SPEED DmaSpeed) +{ + NTSTATUS Status; + DEVICE_DESCRIPTION DeviceDescription; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n"); + return STATUS_UNSUCCESSFUL; + } + + Status = PcDmaMasterDescription(ResourceList, (Dma32BitAddresses | Dma64BitAddresses), Dma32BitAddresses, 0, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, 0, &DeviceDescription); + if (NT_SUCCESS(Status)) + { + return PcNewDmaChannel(DmaChannel, OuterUnknown, NonPagedPool, &DeviceDescription, m_pDeviceObject); + } + + return Status; +} + +NTSTATUS +NTAPI +CPortWaveCyclic::NewSlaveDmaChannel( + OUT PDMACHANNELSLAVE* OutDmaChannel, + IN PUNKNOWN OuterUnknown, + IN PRESOURCELIST ResourceList OPTIONAL, + IN ULONG DmaIndex, + IN ULONG MaximumLength, + IN BOOL DemandMode, + IN DMA_SPEED DmaSpeed) +{ + DEVICE_DESCRIPTION DeviceDescription; + PDMACHANNEL DmaChannel; + NTSTATUS Status; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n"); + return STATUS_UNSUCCESSFUL; + } + + // FIXME + // Check for F-Type DMA Support + // + + Status = PcDmaSlaveDescription(ResourceList, DmaIndex, DemandMode, TRUE, DmaSpeed, MaximumLength, 0, &DeviceDescription); + if (NT_SUCCESS(Status)) + { + Status = PcNewDmaChannel(&DmaChannel, OuterUnknown, NonPagedPool, &DeviceDescription, m_pDeviceObject); + if (NT_SUCCESS(Status)) + { + Status = DmaChannel->QueryInterface(IID_IDmaChannelSlave, (PVOID*)OutDmaChannel); + DmaChannel->Release(); + } + } + + return Status; +} + +VOID +NTAPI +CPortWaveCyclic::Notify( + IN PSERVICEGROUP ServiceGroup) +{ + ServiceGroup->RequestService (); +} + +//--------------------------------------------------------------- +// ISubdevice interface +// + +NTSTATUS +NTAPI +CPortWaveCyclic::NewIrpTarget( + 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; + IPortFilterWaveCyclic * Filter; + + DPRINT("ISubDevice_NewIrpTarget this %p\n", this); + + // is there already an instance of the filter + if (m_Filter) + { + // it is, let's return the result + *OutTarget = (IIrpTarget*)m_Filter; + + // increment reference + m_Filter->AddRef(); + return STATUS_SUCCESS; + } + + // create new instance of filter + Status = NewPortFilterWaveCyclic(&Filter); + if (!NT_SUCCESS(Status)) + { + // not enough memory + return Status; + } + + // initialize the filter + Status = Filter->Init((IPortWaveCyclic*)this); + if (!NT_SUCCESS(Status)) + { + // destroy filter + Filter->Release(); + // return status + return Status; + } + + // store result + *OutTarget = (IIrpTarget*)Filter; + // store for later re-use + m_Filter = Filter; + // return status + return Status; +} + + +NTSTATUS +NTAPI +CPortWaveCyclic::ReleaseChildren() +{ + DPRINT("ISubDevice_fnReleaseChildren\n"); + + // release the filter + m_Filter->Release(); + + if (m_pPinCount) + { + // release pincount interface + m_pPinCount->Release(); + } + + if (m_pPowerNotify) + { + // release power notify interface + m_pPowerNotify->Release(); + } + + // now release the miniport + m_pMiniport->Release(); + + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortWaveCyclic::GetDescriptor( + IN SUBDEVICE_DESCRIPTOR ** Descriptor) +{ + PC_ASSERT(m_SubDeviceDescriptor != NULL); + + *Descriptor = m_SubDeviceDescriptor; + + DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", this, m_SubDeviceDescriptor); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortWaveCyclic::DataRangeIntersection( + IN ULONG PinId, + IN PKSDATARANGE DataRange, + IN PKSDATARANGE MatchingDataRange, + IN ULONG OutputBufferLength, + OUT PVOID ResultantFormat OPTIONAL, + OUT PULONG ResultantFormatLength) +{ + DPRINT("ISubDevice_DataRangeIntersection this %p\n", this); + + if (m_pMiniport) + { + return m_pMiniport->DataRangeIntersection (PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength); + } + + return STATUS_UNSUCCESSFUL; +} + + +NTSTATUS +NTAPI +CPortWaveCyclic::PowerChangeNotify( + IN POWER_STATE PowerState) +{ + if (m_pPowerNotify) + { + m_pPowerNotify->PowerChangeNotify(PowerState); + } + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortWaveCyclic::PinCount( + IN ULONG PinId, + IN OUT PULONG FilterNecessary, + IN OUT PULONG FilterCurrent, + IN OUT PULONG FilterPossible, + IN OUT PULONG GlobalCurrent, + IN OUT PULONG GlobalPossible) +{ + if (m_pPinCount) + { + m_pPinCount->PinCount(PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible); + return STATUS_SUCCESS; + } + + // FIXME + // scan filter descriptor + + return STATUS_UNSUCCESSFUL; +} + + +///-------------------------------------------------------------- +PMINIPORTWAVECYCLIC +GetWaveCyclicMiniport( + IN IPortWaveCyclic* iface) +{ + CPortWaveCyclic * This = (CPortWaveCyclic *)iface; + return This->m_pMiniport; +} + +PDEVICE_OBJECT +GetDeviceObject( + PPORTWAVECYCLIC iface) +{ + CPortWaveCyclic * This = (CPortWaveCyclic *)iface; + return This->m_pDeviceObject; +} + +//--------------------------------------------------------------- +// IPortWaveCyclic constructor +// + +NTSTATUS +NewPortWaveCyclic( + OUT PPORT* OutPort) +{ + NTSTATUS Status; + CPortWaveCyclic * Port; + + Port = new(NonPagedPool, TAG_PORTCLASS)CPortWaveCyclic(NULL); + if (!Port) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = Port->QueryInterface(IID_IPort, (PVOID*)OutPort); + + if (!NT_SUCCESS(Status)) + { + delete Port; + } + + DPRINT("NewPortWaveCyclic %p Status %u\n", Port, Status); + return Status; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c deleted file mode 100644 index 621ad535524..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c +++ /dev/null @@ -1,822 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/port_wavepci.c - * PURPOSE: Wave PCI Port driver - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IPortWavePciVtbl *lpVtbl; - IServiceSinkVtbl *lpVtblServiceSink; - IPortEventsVtbl *lpVtblPortEvents; - ISubdeviceVtbl *lpVtblSubDevice; - -#if 0 - IUnregisterSubdevice *lpVtblUnregisterSubDevice; -#endif - LONG ref; - - PMINIPORTWAVEPCI Miniport; - PDEVICE_OBJECT pDeviceObject; - BOOL bInitialized; - PRESOURCELIST pResourceList; - PSERVICEGROUP ServiceGroup; - PPINCOUNT pPinCount; - PPOWERNOTIFY pPowerNotify; - PPCFILTER_DESCRIPTOR pDescriptor; - PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor; - IPortFilterWavePci * Filter; - - LIST_ENTRY EventList; - KSPIN_LOCK EventListLock; - -}IPortWavePciImpl; - -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(PortFilterWavePciTopologySet, TopologyPropertyHandler); -DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWavePciPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); - -KSPROPERTY_SET WavePciPropertySet[] = -{ - { - &KSPROPSETID_Topology, - sizeof(PortFilterWavePciTopologySet) / sizeof(KSPROPERTY_ITEM), - (const KSPROPERTY_ITEM*)&PortFilterWavePciTopologySet, - 0, - NULL - }, - { - &KSPROPSETID_Pin, - sizeof(PortFilterWavePciPinSet) / sizeof(KSPROPERTY_ITEM), - (const KSPROPERTY_ITEM*)&PortFilterWavePciPinSet, - 0, - NULL - } -}; - - -//--------------------------------------------------------------- -// IPortEvents -// - -static -NTSTATUS -NTAPI -IPortEvents_fnQueryInterface( - IPortEvents* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblPortEvents); - - DPRINT("IPortEvents_fnQueryInterface entered\n"); - - if (IsEqualGUIDAligned(refiid, &IID_IPortEvents) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtblPortEvents; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -static -ULONG -NTAPI -IPortEvents_fnAddRef( - IPortEvents* iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblPortEvents); - DPRINT("IPortEvents_fnAddRef entered\n"); - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IPortEvents_fnRelease( - IPortEvents* iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, 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) -{ - KIRQL OldIrql; - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblPortEvents); - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - KeAcquireSpinLock(&This->EventListLock, &OldIrql); - InsertTailList(&This->EventList, &EventEntry->ListEntry); - KeReleaseSpinLock(&This->EventListLock, OldIrql); -} - - -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 -}; - -//--------------------------------------------------------------- -// IServiceSink -// - -static -NTSTATUS -NTAPI -IServiceSink_fnQueryInterface( - IServiceSink* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, 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) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink); - DPRINT("IServiceSink_fnAddRef entered\n"); - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IServiceSink_fnRelease( - IServiceSink* iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink); - DPRINT("IServiceSink_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 -IServiceSink_fnRequestService( - IServiceSink* iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblServiceSink); - //DPRINT("IServiceSink_fnRequestService entered\n"); - 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) -{ - UNICODE_STRING GuidString; - IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - - DPRINT("IPortWavePci_fnQueryInterface entered\n"); - - if (IsEqualGUIDAligned(refiid, &IID_IPortWavePci) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - else if (IsEqualGUIDAligned(refiid, &IID_IServiceSink)) - { - *Output = &This->lpVtblServiceSink; - 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_IUnregisterSubdevice)) - { - return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) - { - return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); - } - - if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) - { - DPRINT1("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); - RtlFreeUnicodeString(&GuidString); - } - - return STATUS_UNSUCCESSFUL; -} - -static -ULONG -NTAPI -IPortWavePci_fnAddRef( - IPortWavePci* iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - - DPRINT("IPortWavePci_fnAddRef entered\n"); - - return InterlockedIncrement(&This->ref); -} - -static -ULONG -NTAPI -IPortWavePci_fnRelease( - IPortWavePci* iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - - DPRINT("IPortWavePci_fnRelease entered\n"); - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - -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; - PPINCOUNT PinCount; - PPOWERNOTIFY PowerNotify; - IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - - DPRINT("IPortWavePci_fnInit entered with 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) - { - DPRINT("IPortWavePci_fnInit called again\n"); - return STATUS_SUCCESS; - } - - Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportWavePci, (PVOID*)&Miniport); - if (!NT_SUCCESS(Status)) - { - DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n"); - return STATUS_INVALID_PARAMETER; - } - - /* Initialize port object */ - This->Miniport = Miniport; - This->pDeviceObject = DeviceObject; - This->bInitialized = TRUE; - This->pResourceList = ResourceList; - InitializeListHead(&This->EventList); - KeInitializeSpinLock(&This->EventListLock); - - /* increment reference on miniport adapter */ - Miniport->lpVtbl->AddRef(Miniport); - /* increment reference on resource list */ - ResourceList->lpVtbl->AddRef(ResourceList); - - Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup); - if (!NT_SUCCESS(Status)) - { - DPRINT("IPortWavePci_fnInit failed with %x\n", Status); - This->bInitialized = FALSE; - /* release reference on miniport adapter */ - Miniport->lpVtbl->Release(Miniport); - /* increment reference on resource list */ - ResourceList->lpVtbl->Release(ResourceList); - return Status; - } - - /* check if the miniport adapter provides a valid 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, - WavePciPropertySet, - 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; - } - - /* did we get a service group */ - if (ServiceGroup) - { - /* store service group in context */ - This->ServiceGroup = ServiceGroup; - - /* 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); - } - - /* 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; - } - - DPRINT("IPortWavePci_Init sucessfully initialized\n"); - 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) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - - DPRINT("IPortWavePci_fnNewRegistryKey entered\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n"); - return STATUS_UNSUCCESSFUL; - } - - return PcNewRegistryKey(OutRegistryKey, - OuterUnknown, - RegistryKeyType, - DesiredAccess, - This->pDeviceObject, - NULL,//FIXME - ObjectAttributes, - CreateOptions, - Disposition); -} - -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; - - DPRINT("IPortWavePci_fnGetDeviceProperty entered\n"); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->bInitialized) - { - DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n"); - return STATUS_UNSUCCESSFUL; - } - - return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); -} - -NTSTATUS -NTAPI -IPortWavePci_fnNewMasterDmaChannel( - IN IPortWavePci * iface, - OUT PDMACHANNEL *DmaChannel, - IN PUNKNOWN OuterUnknown OPTIONAL, - IN POOL_TYPE PoolType, - IN PRESOURCELIST ResourceList OPTIONAL, - IN BOOLEAN ScatterGather, - IN BOOLEAN Dma32BitAddresses, - IN BOOLEAN Dma64BitAddresses, - IN BOOLEAN IgnoreCount, - IN DMA_WIDTH DmaWidth, - IN DMA_SPEED DmaSpeed, - IN ULONG MaximumLength, - IN ULONG DmaPort) -{ - NTSTATUS Status; - DEVICE_DESCRIPTION DeviceDescription; - IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - - DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", This); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - Status = PcDmaMasterDescription(ResourceList, ScatterGather, Dma32BitAddresses, IgnoreCount, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, DmaPort, &DeviceDescription); - if (NT_SUCCESS(Status)) - { - return PcNewDmaChannel(DmaChannel, OuterUnknown, PoolType, &DeviceDescription, This->pDeviceObject); - } - - return Status; -} - -VOID -NTAPI -IPortWavePci_fnNotify( - IN IPortWavePci * iface, - IN PSERVICEGROUP ServiceGroup) -{ - //IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - - //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup); - - if (ServiceGroup) - { - ServiceGroup->lpVtbl->RequestService (ServiceGroup); - } -} - -static IPortWavePciVtbl vt_IPortWavePci = -{ - /* IUnknown methods */ - IPortWavePci_fnQueryInterface, - IPortWavePci_fnAddRef, - IPortWavePci_fnRelease, - /* IPort methods */ - IPortWavePci_fnInit, - IPortWavePci_fnGetDeviceProperty, - IPortWavePci_fnNewRegistryKey, - /* IPortWavePci methods */ - IPortWavePci_fnNotify, - IPortWavePci_fnNewMasterDmaChannel, -}; - -//--------------------------------------------------------------- -// ISubdevice interface -// - -static -NTSTATUS -NTAPI -ISubDevice_fnQueryInterface( - IN ISubdevice *iface, - IN REFIID InterfaceId, - IN PVOID* Interface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice); - - return IPortWavePci_fnQueryInterface((IPortWavePci*)This, InterfaceId, Interface); -} - -static -ULONG -NTAPI -ISubDevice_fnAddRef( - IN ISubdevice *iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice); - - return IPortWavePci_fnAddRef((IPortWavePci*)This); -} - -static -ULONG -NTAPI -ISubDevice_fnRelease( - IN ISubdevice *iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice); - - return IPortWavePci_fnRelease((IPortWavePci*)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; - IPortFilterWavePci * Filter; - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice); - - DPRINT("ISubDevice_NewIrpTarget this %p\n", This); - - if (This->Filter) - { - *OutTarget = (IIrpTarget*)This->Filter; - return STATUS_SUCCESS; - } - - Status = NewPortFilterWavePci(&Filter); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Status = Filter->lpVtbl->Init(Filter, (IPortWavePci*)This); - if (!NT_SUCCESS(Status)) - { - Filter->lpVtbl->Release(Filter); - return Status; - } - - *OutTarget = (IIrpTarget*)Filter; - This->Filter = Filter; - return Status; -} - -static -NTSTATUS -NTAPI -ISubDevice_fnReleaseChildren( - IN ISubdevice *iface) -{ - //IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice); - - UNIMPLEMENTED - return STATUS_UNSUCCESSFUL; -} - -static -NTSTATUS -NTAPI -ISubDevice_fnGetDescriptor( - IN ISubdevice *iface, - IN SUBDEVICE_DESCRIPTOR ** Descriptor) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice); - - DPRINT1("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) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice); - - DPRINT("ISubDevice_DataRangeIntersection this %p\n", This); - - if (This->Miniport) - { - return This->Miniport->lpVtbl->DataRangeIntersection (This->Miniport, PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength); - } - - return STATUS_UNSUCCESSFUL; -} - -static -NTSTATUS -NTAPI -ISubDevice_fnPowerChangeNotify( - IN ISubdevice *iface, - IN POWER_STATE PowerState) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, 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) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, 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 -NewPortWavePci( - OUT PPORT* OutPort) -{ - IPortWavePciImpl * This; - - This = AllocateItem(NonPagedPool, sizeof(IPortWavePciImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - This->lpVtblServiceSink = &vt_IServiceSink; - This->lpVtbl = &vt_IPortWavePci; - This->lpVtblSubDevice = &vt_ISubdeviceVtbl; - This->lpVtblPortEvents = &vt_IPortEvents; - This->ref = 1; - - *OutPort = (PPORT)&This->lpVtbl; - DPRINT("NewPortWavePci %p\n", *OutPort); - return STATUS_SUCCESS; -} - -PDEVICE_OBJECT -GetDeviceObjectFromPortWavePci( - IPortWavePci* iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - return This->pDeviceObject; -} - -PMINIPORTWAVEPCI -GetWavePciMiniport( - PPORTWAVEPCI iface) -{ - IPortWavePciImpl * This = (IPortWavePciImpl*)iface; - return This->Miniport; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.cpp new file mode 100644 index 00000000000..be8512cad44 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.cpp @@ -0,0 +1,591 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/port_wavepci.cpp + * PURPOSE: Wave PCI Port driver + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortWavePci : public IPortWavePci, + public IPortEvents, + public ISubdevice, + public IServiceSink +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortWavePci; + IMP_ISubdevice; + IMP_IPortEvents; + IMP_IServiceSink; + CPortWavePci(IUnknown *OuterUnknown){} + virtual ~CPortWavePci() {} + +protected: + + PMINIPORTWAVEPCI m_Miniport; + PDEVICE_OBJECT m_pDeviceObject; + BOOL m_bInitialized; + PRESOURCELIST m_pResourceList; + PSERVICEGROUP m_ServiceGroup; + PPINCOUNT m_pPinCount; + PPOWERNOTIFY m_pPowerNotify; + PPCFILTER_DESCRIPTOR m_pDescriptor; + PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; + IPortFilterWavePci * m_Filter; + + LIST_ENTRY m_EventList; + KSPIN_LOCK m_EventListLock; + + LONG m_Ref; + + friend PDEVICE_OBJECT GetDeviceObjectFromPortWavePci(IPortWavePci* iface); + friend PMINIPORTWAVEPCI GetWavePciMiniport(PPORTWAVEPCI iface); + +}; + +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(PortFilterWavePciTopologySet, TopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWavePciPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); + +KSPROPERTY_SET WavePciPropertySet[] = +{ + { + &KSPROPSETID_Topology, + sizeof(PortFilterWavePciTopologySet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterWavePciTopologySet, + 0, + NULL + }, + { + &KSPROPSETID_Pin, + sizeof(PortFilterWavePciPinSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterWavePciPinSet, + 0, + NULL + } +}; + + +//--------------------------------------------------------------- +// IPortEvents +// + +void +NTAPI +CPortWavePci::AddEventToEventList( + IN PKSEVENT_ENTRY EventEntry) +{ + KIRQL OldIrql; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + KeAcquireSpinLock(&m_EventListLock, &OldIrql); + InsertTailList(&m_EventList, &EventEntry->ListEntry); + KeReleaseSpinLock(&m_EventListLock, OldIrql); +} + + + +void +NTAPI +CPortWavePci::GenerateEventList( + IN GUID* Set OPTIONAL, + IN ULONG EventId, + IN BOOL PinEvent, + IN ULONG PinId, + IN BOOL NodeEvent, + IN ULONG NodeId) +{ + UNIMPLEMENTED +} +//--------------------------------------------------------------- +// IServiceSink +// + +VOID +NTAPI +CPortWavePci::RequestService() +{ + //DPRINT("IServiceSink_fnRequestService entered\n"); + if (m_Miniport) + { + m_Miniport->Service(); + } +} + +//--------------------------------------------------------------- +// IPortWavePci +// + +NTSTATUS +NTAPI +CPortWavePci::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + UNICODE_STRING GuidString; + + DPRINT("IPortWavePci_fnQueryInterface entered\n"); + + if (IsEqualGUIDAligned(refiid, IID_IPortWavePci) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PPORTWAVEPCI(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) + { + *Output = PVOID(PSERVICESINK(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPortEvents)) + { + *Output = PVOID(PPORTEVENTS(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_ISubdevice)) + { + *Output = PVOID(PSUBDEVICE(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion)) + { + return NewPortClsVersion((PPORTCLSVERSION*)Output); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } + + if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) + { + DPRINT1("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortWavePci::Init( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PUNKNOWN UnknownMiniport, + IN PUNKNOWN UnknownAdapter OPTIONAL, + IN PRESOURCELIST ResourceList) +{ + IMiniportWavePci * Miniport; + PSERVICEGROUP ServiceGroup; + NTSTATUS Status; + PPINCOUNT PinCount; + PPOWERNOTIFY PowerNotify; + + DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n", + this, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_bInitialized) + { + DPRINT("IPortWavePci_fnInit called again\n"); + return STATUS_SUCCESS; + } + + Status = UnknownMiniport->QueryInterface(IID_IMiniportWavePci, (PVOID*)&Miniport); + if (!NT_SUCCESS(Status)) + { + DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n"); + return STATUS_INVALID_PARAMETER; + } + + // Initialize port object + m_Miniport = Miniport; + m_pDeviceObject = DeviceObject; + m_bInitialized = TRUE; + m_pResourceList = ResourceList; + InitializeListHead(&m_EventList); + KeInitializeSpinLock(&m_EventListLock); + + // increment reference on miniport adapter + Miniport->AddRef(); + // increment reference on resource list + ResourceList->AddRef(); + + Status = Miniport->Init(UnknownAdapter, ResourceList, this, &ServiceGroup); + if (!NT_SUCCESS(Status)) + { + DPRINT("IPortWavePci_fnInit failed with %x\n", Status); + m_bInitialized = FALSE; + // release reference on miniport adapter + Miniport->Release(); + // increment reference on resource list + ResourceList->Release(); + return Status; + } + + // check if the miniport adapter provides a valid device descriptor + Status = Miniport->GetDescription(&m_pDescriptor); + if (!NT_SUCCESS(Status)) + { + DPRINT1("failed to get description\n"); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // create the subdevice descriptor + Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, + 3, + InterfaceGuids, + 0, + NULL, + 2, + WavePciPropertySet, + 0, + 0, + 0, + NULL, + 0, + NULL, + m_pDescriptor); + + + if (!NT_SUCCESS(Status)) + { + DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // did we get a service group + if (ServiceGroup) + { + // store service group in context + m_ServiceGroup = ServiceGroup; + + // add ourselves to service group which is called when miniport receives an isr + m_ServiceGroup->AddMember(PSERVICESINK(this)); + + // increment reference on service group + m_ServiceGroup->AddRef(); + } + + // check if it supports IPinCount interface + Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount); + if (NT_SUCCESS(Status)) + { + // store IPinCount interface + m_pPinCount = PinCount; + } + + // does the Miniport adapter support IPowerNotify interface*/ + Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify); + if (NT_SUCCESS(Status)) + { + // store reference + m_pPowerNotify = PowerNotify; + } + + DPRINT("IPortWavePci_Init sucessfully initialized\n"); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortWavePci::NewRegistryKey( + 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) +{ + DPRINT("IPortWavePci_fnNewRegistryKey entered\n"); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n"); + return STATUS_UNSUCCESSFUL; + } + + return PcNewRegistryKey(OutRegistryKey, + OuterUnknown, + RegistryKeyType, + DesiredAccess, + m_pDeviceObject, + NULL,//FIXME + ObjectAttributes, + CreateOptions, + Disposition); +} + +NTSTATUS +NTAPI +CPortWavePci::GetDeviceProperty( + IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, + IN ULONG BufferLength, + OUT PVOID PropertyBuffer, + OUT PULONG ReturnLength) +{ + DPRINT("IPortWavePci_fnGetDeviceProperty entered\n"); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortWavePci_fnNewRegistryKey called w/o initiazed\n"); + return STATUS_UNSUCCESSFUL; + } + + return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); +} + +NTSTATUS +NTAPI +CPortWavePci::NewMasterDmaChannel( + OUT PDMACHANNEL *DmaChannel, + IN PUNKNOWN OuterUnknown OPTIONAL, + IN POOL_TYPE PoolType, + IN PRESOURCELIST ResourceList OPTIONAL, + IN BOOLEAN ScatterGather, + IN BOOLEAN Dma32BitAddresses, + IN BOOLEAN Dma64BitAddresses, + IN BOOLEAN IgnoreCount, + IN DMA_WIDTH DmaWidth, + IN DMA_SPEED DmaSpeed, + IN ULONG MaximumLength, + IN ULONG DmaPort) +{ + NTSTATUS Status; + DEVICE_DESCRIPTION DeviceDescription; + + DPRINT("IPortWavePci_fnNewMasterDmaChannel This %p entered\n", this); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + Status = PcDmaMasterDescription(ResourceList, ScatterGather, Dma32BitAddresses, IgnoreCount, Dma64BitAddresses, DmaWidth, DmaSpeed, MaximumLength, DmaPort, &DeviceDescription); + if (NT_SUCCESS(Status)) + { + return PcNewDmaChannel(DmaChannel, OuterUnknown, PoolType, &DeviceDescription, m_pDeviceObject); + } + + return Status; +} + +VOID +NTAPI +CPortWavePci::Notify( + IN PSERVICEGROUP ServiceGroup) +{ + //IPortWavePciImpl * This = (IPortWavePciImpl*)iface; + + //DPRINT("IPortWavePci_fnNotify entered %p, ServiceGroup %p\n", This, ServiceGroup); + + if (ServiceGroup) + { + ServiceGroup->RequestService (); + } +} + +//--------------------------------------------------------------- +// ISubdevice interface +// + +NTSTATUS +NTAPI +CPortWavePci::NewIrpTarget( + 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; + IPortFilterWavePci * Filter; + + DPRINT("ISubDevice_NewIrpTarget this %p\n", this); + + if (m_Filter) + { + *OutTarget = (IIrpTarget*)m_Filter; + return STATUS_SUCCESS; + } + + Status = NewPortFilterWavePci(&Filter); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status = Filter->Init((IPortWavePci*)this); + if (!NT_SUCCESS(Status)) + { + Filter->Release(); + return Status; + } + + *OutTarget = (IIrpTarget*)Filter; + m_Filter = Filter; + return Status; +} + +NTSTATUS +NTAPI +CPortWavePci::ReleaseChildren() +{ + //IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblSubDevice); + + UNIMPLEMENTED + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortWavePci::GetDescriptor( + IN SUBDEVICE_DESCRIPTOR ** Descriptor) +{ + DPRINT1("ISubDevice_GetDescriptor this %p\n", this); + *Descriptor = m_SubDeviceDescriptor; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortWavePci::DataRangeIntersection( + IN ULONG PinId, + IN PKSDATARANGE DataRange, + IN PKSDATARANGE MatchingDataRange, + IN ULONG OutputBufferLength, + OUT PVOID ResultantFormat OPTIONAL, + OUT PULONG ResultantFormatLength) +{ + DPRINT("ISubDevice_DataRangeIntersection this %p\n", this); + + if (m_Miniport) + { + return m_Miniport->DataRangeIntersection (PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength); + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortWavePci::PowerChangeNotify( + IN POWER_STATE PowerState) +{ + if (m_pPowerNotify) + { + m_pPowerNotify->PowerChangeNotify(PowerState); + } + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortWavePci::PinCount( + IN ULONG PinId, + IN OUT PULONG FilterNecessary, + IN OUT PULONG FilterCurrent, + IN OUT PULONG FilterPossible, + IN OUT PULONG GlobalCurrent, + IN OUT PULONG GlobalPossible) +{ + if (m_pPinCount) + { + m_pPinCount->PinCount(PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible); + return STATUS_SUCCESS; + } + + // FIXME + // scan filter descriptor + + return STATUS_UNSUCCESSFUL; +} + + +NTSTATUS +NewPortWavePci( + OUT PPORT* OutPort) +{ + CPortWavePci * Port; + NTSTATUS Status; + + Port = new(NonPagedPool, TAG_PORTCLASS) CPortWavePci(NULL); + if (!Port) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = Port->QueryInterface(IID_IPort, (PVOID*)OutPort); + + if (!NT_SUCCESS(Status)) + { + delete Port; + } + + DPRINT("NewPortWavePci %p Status %u\n", Port, Status); + return Status; + +} + + +PDEVICE_OBJECT +GetDeviceObjectFromPortWavePci( + IPortWavePci* iface) +{ + CPortWavePci * This = (CPortWavePci*)iface; + return This->m_pDeviceObject; +} + +PMINIPORTWAVEPCI +GetWavePciMiniport( + PPORTWAVEPCI iface) +{ + CPortWavePci * This = (CPortWavePci*)iface; + return This->m_Miniport; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c deleted file mode 100644 index 14a6a113f5d..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * 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); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) - { - return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); - } - else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) - { - return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)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; - This->Filter = 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; -} - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.cpp new file mode 100644 index 00000000000..ec11429eec3 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.cpp @@ -0,0 +1,498 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/port_wavert.cpp + * PURPOSE: WaveRT Port Driver + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CPortWaveRT : public IPortWaveRT, + public IPortEvents, + public ISubdevice +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortWaveRT; + IMP_ISubdevice; + IMP_IPortEvents; + CPortWaveRT(IUnknown *OuterUnknown) {} + virtual ~CPortWaveRT() {} + +protected: + + BOOL m_bInitialized; + PDEVICE_OBJECT m_pDeviceObject; + PMINIPORTWAVERT m_pMiniport; + PRESOURCELIST m_pResourceList; + PPINCOUNT m_pPinCount; + PPOWERNOTIFY m_pPowerNotify; + PPCFILTER_DESCRIPTOR m_pDescriptor; + PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; + IPortFilterWaveRT * m_Filter; + + friend PMINIPORTWAVERT GetWaveRTMiniport(IN IPortWaveRT* iface); + friend PDEVICE_OBJECT GetDeviceObjectFromPortWaveRT(PPORTWAVERT iface); + + LONG m_Ref; +}; + +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, + + + +//--------------------------------------------------------------- +// IPortEvents +// + +void +NTAPI +CPortWaveRT::AddEventToEventList( + IN PKSEVENT_ENTRY EventEntry) +{ + UNIMPLEMENTED +} + + +void +NTAPI +CPortWaveRT::GenerateEventList( + IN GUID* Set OPTIONAL, + IN ULONG EventId, + IN BOOL PinEvent, + IN ULONG PinId, + IN BOOL NodeEvent, + IN ULONG NodeId) +{ + UNIMPLEMENTED +} + +//--------------------------------------------------------------- +// IUnknown interface functions +// + +NTSTATUS +NTAPI +CPortWaveRT::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + UNICODE_STRING GuidString; + + if (IsEqualGUIDAligned(refiid, IID_IPortWaveRT) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PPORTWAVERT(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_IPortEvents)) + { + *Output = PVOID(PPORTEVENTS(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, IID_ISubdevice)) + { + *Output = PVOID(PSUBDEVICE(this)); + PUNKNOWN(*Output)->AddRef(); + 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); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } + + if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) + { + DPRINT1("IPortWaveRT_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + } + + return STATUS_UNSUCCESSFUL; +} +//--------------------------------------------------------------- +// IPort interface functions +// + +NTSTATUS +NTAPI +CPortWaveRT::GetDeviceProperty( + IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty, + IN ULONG BufferLength, + OUT PVOID PropertyBuffer, + OUT PULONG ReturnLength) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortWaveRT_fnNewRegistryKey called w/o initiazed\n"); + return STATUS_UNSUCCESSFUL; + } + + return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength); +} + +NTSTATUS +NTAPI +CPortWaveRT::Init( + 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; + + DPRINT("IPortWaveRT_Init entered %p\n", this); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_bInitialized) + { + DPRINT("IPortWaveRT_Init called again\n"); + return STATUS_SUCCESS; + } + + Status = UnknownMiniport->QueryInterface(IID_IMiniportWaveRT, (PVOID*)&Miniport); + if (!NT_SUCCESS(Status)) + { + DPRINT("IPortWaveRT_Init called with invalid IMiniport adapter\n"); + return STATUS_INVALID_PARAMETER; + } + + // Initialize port object + m_pMiniport = Miniport; + m_pDeviceObject = DeviceObject; + m_bInitialized = TRUE; + m_pResourceList = ResourceList; + + // increment reference on miniport adapter + Miniport->AddRef(); + + Status = Miniport->Init(UnknownAdapter, ResourceList, this); + if (!NT_SUCCESS(Status)) + { + DPRINT("IMiniportWaveRT_Init failed with %x\n", Status); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + + // get the miniport device descriptor + Status = Miniport->GetDescription(&m_pDescriptor); + if (!NT_SUCCESS(Status)) + { + DPRINT1("failed to get description\n"); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // create the subdevice descriptor + Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, + 3, + InterfaceGuids, + 0, + NULL, + 2, + WaveRTPropertySet, + 0, + 0, + 0, + NULL, + 0, + NULL, + m_pDescriptor); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status); + Miniport->Release(); + m_bInitialized = FALSE; + return Status; + } + + // check if it supports IPinCount interface + Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount); + if (NT_SUCCESS(Status)) + { + // store IPinCount interface + m_pPinCount = PinCount; + } + + // does the Miniport adapter support IPowerNotify interface*/ + Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify); + if (NT_SUCCESS(Status)) + { + // store reference + m_pPowerNotify = PowerNotify; + } + + // increment reference on resource list + ResourceList->AddRef(); + + + DPRINT("IPortWaveRT successfully initialized\n"); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +CPortWaveRT::NewRegistryKey( + 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) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_bInitialized) + { + DPRINT("IPortWaveRT_fnNewRegistryKey called w/o initialized\n"); + return STATUS_UNSUCCESSFUL; + } + return PcNewRegistryKey(OutRegistryKey, OuterUnknown, RegistryKeyType, DesiredAccess, m_pDeviceObject, NULL /*FIXME*/, ObjectAttributes, CreateOptions, Disposition); +} +//--------------------------------------------------------------- +// ISubdevice interface +// + +NTSTATUS +NTAPI +CPortWaveRT::NewIrpTarget( + 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; + + DPRINT("ISubDevice_NewIrpTarget this %p\n", this); + + if (m_Filter) + { + *OutTarget = (IIrpTarget*)m_Filter; + return STATUS_SUCCESS; + } + + + Status = NewPortFilterWaveRT(&Filter); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Status = Filter->Init(this); + if (!NT_SUCCESS(Status)) + { + Filter->Release(); + return Status; + } + + *OutTarget = (IIrpTarget*)Filter; + m_Filter = Filter; + return Status; +} + +NTSTATUS +NTAPI +CPortWaveRT::ReleaseChildren() +{ + UNIMPLEMENTED + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortWaveRT::GetDescriptor( + IN SUBDEVICE_DESCRIPTOR ** Descriptor) +{ + PC_ASSERT(m_SubDeviceDescriptor != NULL); + + *Descriptor = m_SubDeviceDescriptor; + + DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", this, m_SubDeviceDescriptor); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortWaveRT::DataRangeIntersection( + IN ULONG PinId, + IN PKSDATARANGE DataRange, + IN PKSDATARANGE MatchingDataRange, + IN ULONG OutputBufferLength, + OUT PVOID ResultantFormat OPTIONAL, + OUT PULONG ResultantFormatLength) +{ + DPRINT("ISubDevice_DataRangeIntersection this %p\n", this); + + if (m_pMiniport) + { + return m_pMiniport->DataRangeIntersection (PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength); + } + + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CPortWaveRT::PowerChangeNotify( + IN POWER_STATE PowerState) +{ + if (m_pPowerNotify) + { + m_pPowerNotify->PowerChangeNotify(PowerState); + } + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CPortWaveRT::PinCount( + IN ULONG PinId, + IN OUT PULONG FilterNecessary, + IN OUT PULONG FilterCurrent, + IN OUT PULONG FilterPossible, + IN OUT PULONG GlobalCurrent, + IN OUT PULONG GlobalPossible) +{ + if (m_pPinCount) + { + m_pPinCount->PinCount(PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible); + return STATUS_SUCCESS; + } + + // FIXME + // scan filter descriptor + + return STATUS_UNSUCCESSFUL; +} + +///-------------------------------------------------------------- +PMINIPORTWAVERT +GetWaveRTMiniport( + IN IPortWaveRT* iface) +{ + CPortWaveRT * This = (CPortWaveRT *)iface; + return This->m_pMiniport; +} + +PDEVICE_OBJECT +GetDeviceObjectFromPortWaveRT( + PPORTWAVERT iface) +{ + CPortWaveRT * This = (CPortWaveRT *)iface; + return This->m_pDeviceObject; +} + +//--------------------------------------------------------------- +// IPortWaveRT constructor +// + + +NTSTATUS +NewPortWaveRT( + OUT PPORT* OutPort) +{ + CPortWaveRT * Port; + NTSTATUS Status; + + Port = new(NonPagedPool, TAG_PORTCLASS) CPortWaveRT(NULL); + if (!Port) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = Port->QueryInterface(IID_IPort, (PVOID*)OutPort); + + if (!NT_SUCCESS(Status)) + { + delete Port; + } + + DPRINT("NewPortWaveRT %p Status %u\n", Port, Status); + return Status; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp similarity index 53% rename from reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c rename to reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp index 45ee9a7e60b..c141aabd32f 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp @@ -1,106 +1,75 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/port_wavertstream.c + * FILE: drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp * PURPOSE: WaveRTStream helper object * PROGRAMMER: Johannes Anderwald */ -#include "private.h" +#include "private.hpp" -typedef struct +class CPortWaveRTStreamInit : public IPortWaveRTStreamInit { - IPortWaveRTStreamInitVtbl *lpVtbl; - LONG ref; +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); -}IPortWaveRTStreamImpl; + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + IMP_IPortWaveRTStreamInit; + CPortWaveRTStreamInit(IUnknown *OuterUnknown) {} + virtual ~CPortWaveRTStreamInit() {} + +protected: + LONG m_Ref; + +}; -/* - * @implemented - */ -static NTSTATUS NTAPI -IPortWaveRTStreamInit_fnQueryInterface( - IPortWaveRTStreamInit * iface, +CPortWaveRTStreamInit::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface; DPRINT("IPortWaveRTStream_fnQueryInterface entered\n"); - if (IsEqualGUIDAligned(refiid, &IID_IPortWaveRTStream) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) + if (IsEqualGUIDAligned(refiid, IID_IPortWaveRTStream) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); + *Output = PVOID(PPORTWAVERTSTREAM(this)); + PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } return STATUS_UNSUCCESSFUL; } -/* - * @implemented - */ -static -ULONG -NTAPI -IPortWaveRTStreamInit_fnAddRef( - IPortWaveRTStreamInit * iface) -{ - IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface; - DPRINT("IPortWaveRTStream_fnAddRef entered\n"); - return InterlockedIncrement(&This->ref); -} - -/* - * @implemented - */ -static -ULONG -NTAPI -IPortWaveRTStreamInit_fnRelease( - IPortWaveRTStreamInit * 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 -IPortWaveRTStreamInit_fnAllocatePagesForMdl( - IN IPortWaveRTStreamInit * iface, +CPortWaveRTStreamInit::AllocatePagesForMdl( IN PHYSICAL_ADDRESS HighAddress, IN SIZE_T TotalBytes) { return MmAllocatePagesForMdl(RtlConvertUlongToLargeInteger(0), HighAddress, RtlConvertUlongToLargeInteger(0), TotalBytes); } -/* - * @implemented - */ -static PMDL NTAPI -IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl( - IN IPortWaveRTStreamInit * iface, +CPortWaveRTStreamInit::AllocateContiguousPagesForMdl( IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN SIZE_T TotalBytes) @@ -139,69 +108,44 @@ IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl( return Mdl; } -/* - * @implemented - */ -static PVOID NTAPI -IPortWaveRTStreamInit_fnMapAllocatedPages( - IN IPortWaveRTStreamInit * iface, +CPortWaveRTStreamInit::MapAllocatedPages( IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType) { return MmMapLockedPagesSpecifyCache(MemoryDescriptorList, KernelMode, CacheType, NULL, 0, NormalPagePriority); } -/* - * @implemented - */ -static VOID NTAPI -IPortWaveRTStreamInit_fnUnmapAllocatedPages( - IN IPortWaveRTStreamInit * iface, +CPortWaveRTStreamInit::UnmapAllocatedPages( IN PVOID BaseAddress, IN PMDL MemoryDescriptorList) { MmUnmapLockedPages(BaseAddress, MemoryDescriptorList); } -/* - * @implemented - */ -static VOID NTAPI -IPortWaveRTStreamInit_fnFreePagesFromMdl( - IN IPortWaveRTStreamInit * iface, +CPortWaveRTStreamInit::FreePagesFromMdl( IN PMDL MemoryDescriptorList) { MmFreePagesFromMdl(MemoryDescriptorList); ExFreePool(MemoryDescriptorList); } -/* - * @implemented - */ -static ULONG NTAPI -IPortWaveRTStreamInit_fnGetPhysicalPagesCount( - IN IPortWaveRTStreamInit * iface, +CPortWaveRTStreamInit::GetPhysicalPagesCount( IN PMDL MemoryDescriptorList) { return ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList)); } -/* - * @implemented - */ -static PHYSICAL_ADDRESS NTAPI -IPortWaveRTStreamInit_fnGetPhysicalPageAddress( - IN IPortWaveRTStreamInit * iface, +CPortWaveRTStreamInit::GetPhysicalPageAddress( IN PPHYSICAL_ADDRESS Address, IN PMDL MemoryDescriptorList, IN ULONG Index) @@ -226,31 +170,24 @@ IPortWaveRTStreamInit_fnGetPhysicalPageAddress( return Result; } -static IPortWaveRTStreamInitVtbl vt_PortWaveRTStream = -{ - IPortWaveRTStreamInit_fnQueryInterface, - IPortWaveRTStreamInit_fnAddRef, - IPortWaveRTStreamInit_fnRelease, - IPortWaveRTStreamInit_fnAllocatePagesForMdl, - IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl, - IPortWaveRTStreamInit_fnMapAllocatedPages, - IPortWaveRTStreamInit_fnUnmapAllocatedPages, - IPortWaveRTStreamInit_fnFreePagesFromMdl, - IPortWaveRTStreamInit_fnGetPhysicalPagesCount, - IPortWaveRTStreamInit_fnGetPhysicalPageAddress -}; NTSTATUS NewPortWaveRTStream( PPORTWAVERTSTREAM *OutStream) { - IPortWaveRTStreamImpl* This = AllocateItem(NonPagedPool, sizeof(IPortWaveRTStreamImpl), TAG_PORTCLASS); + NTSTATUS Status; + CPortWaveRTStreamInit* This = new(NonPagedPool, TAG_PORTCLASS) CPortWaveRTStreamInit(NULL); if (!This) return STATUS_INSUFFICIENT_RESOURCES; - This->ref = 1; - This->lpVtbl = &vt_PortWaveRTStream; + Status = This->QueryInterface(IID_IPortWaveRTStream, (PVOID*)OutStream); - *OutStream = (PPORTWAVERTSTREAM)&This->lpVtbl; - return STATUS_SUCCESS; + if (!NT_SUCCESS(Status)) + { + delete This; + return Status; + } + + *OutStream = (PPORTWAVERTSTREAM)This; + return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild b/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild index ac75bc25911..91ca72f436a 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild +++ b/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild @@ -11,45 +11,52 @@ hal libcntpr pseh - adapter.c - api.c - connection.c - dispatcher.c - dll.c - dma_slave.c - drm.c - drm_port.c - filter_topology.c - filter_dmus.c - filter_wavecyclic.c - filter_wavepci.c - filter_wavert.c - guids.c - interrupt.c - irp.c - irpstream.c - miniport.c - miniport_dmus.c - miniport_fmsynth.c - pin_dmus.c - pin_wavecyclic.c - pin_wavepci.c - pin_wavert.c - pool.c - port.c - port_dmus.c - port_topology.c - port_wavecyclic.c - port_wavepci.c - port_wavert.c - port_wavertstream.c - power.c - propertyhandler.c - registry.c - resource.c - service_group.c - undoc.c - unregister.c - version.c + + + -fno-exceptions + -fno-rtti + + + adapter.cpp + api.cpp + connection.cpp + dispatcher.cpp + dll.cpp + dma_slave.cpp + drm.cpp + drm_port.cpp + filter_topology.cpp + filter_dmus.cpp + filter_wavecyclic.cpp + filter_wavepci.cpp + filter_wavert.cpp + guids.cpp + interrupt.cpp + irp.cpp + irpstream.cpp + miniport.cpp + miniport_dmus.cpp + miniport_fmsynth.cpp + pin_dmus.cpp + pin_wavecyclic.cpp + pin_wavepci.cpp + pin_wavert.cpp + pool.cpp + port.cpp + port_dmus.cpp + port_topology.cpp + port_wavecyclic.cpp + port_wavepci.cpp + port_wavert.cpp + port_wavertstream.cpp + power.cpp + propertyhandler.cpp + purecall.cpp + registry.cpp + resource.cpp + service_group.cpp + undoc.cpp + unregister.cpp + version.cpp portcls.rc diff --git a/reactos/drivers/wdm/audio/backpln/portcls/power.c b/reactos/drivers/wdm/audio/backpln/portcls/power.cpp similarity index 87% rename from reactos/drivers/wdm/audio/backpln/portcls/power.c rename to reactos/drivers/wdm/audio/backpln/portcls/power.cpp index 4b6e6e76781..2aaf72db4d2 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/power.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/power.cpp @@ -1,16 +1,12 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/power.c + * FILE: drivers/wdm/audio/backpln/portcls/power.cpp * PURPOSE: Power support functions * PROGRAMMER: Johannes Anderwald */ -#include "private.h" - -/* - * @implemented - */ +#include "private.hpp" NTSTATUS NTAPI @@ -24,7 +20,7 @@ PcRegisterAdapterPowerManagement( IAdapterPowerManagement * pPower; DPRINT("PcRegisterAdapterPowerManagement pUnknown %p pvContext %p\n", pUnknown, pvContext); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!pUnknown || !pvContext) return STATUS_INVALID_PARAMETER; @@ -33,7 +29,7 @@ PcRegisterAdapterPowerManagement( pDeviceObject = (PDEVICE_OBJECT)pvContext; DeviceExt = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension; - Status = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IAdapterPowerManagement, (PVOID*)&pPower); + Status = pUnknown->QueryInterface(IID_IAdapterPowerManagement, (PVOID*)&pPower); if (!NT_SUCCESS(Status)) { DPRINT1("PcRegisterAdapterPowerManagement no IAdapterPowerManagement interface %x\n", Status); @@ -60,10 +56,8 @@ PwrCompletionCallback( KeSetEvent((PRKEVENT)Context, IO_NO_INCREMENT, FALSE); } -/* - * @implemented - */ -NTSTATUS NTAPI +NTSTATUS +NTAPI PcRequestNewPowerState( IN PDEVICE_OBJECT DeviceObject, IN DEVICE_POWER_STATE RequestedNewState) @@ -73,7 +67,7 @@ PcRequestNewPowerState( POWER_STATE PowerState; PPCLASS_DEVICE_EXTENSION DeviceExt; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!DeviceObject || !RequestedNewState) return STATUS_INVALID_PARAMETER; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.h b/reactos/drivers/wdm/audio/backpln/portcls/private.hpp similarity index 90% rename from reactos/drivers/wdm/audio/backpln/portcls/private.h rename to reactos/drivers/wdm/audio/backpln/portcls/private.hpp index 0fb8f49c3a0..9d173658e3d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.hpp @@ -8,86 +8,114 @@ #define PORTCLS_PRIVATE_H //#define _KS_NO_ANONYMOUS_STRUCTURES_ +#define PC_IMPLEMENTATION #include #include -#define NDEBUG +#define YDEBUG #include #include - -#include "interfaces.h" +#include +#include "stdunk.h" +#include "interfaces.hpp" #include #include #include #include #include +#include + #define TAG_PORTCLASS 'SLCP' -#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x)) +#define PC_ASSERT(exp) \ + (VOID)((!(exp)) ? \ + RtlAssert((PVOID) #exp, (PVOID)__FILE__, __LINE__, NULL ), FALSE : TRUE) +#define PC_ASSERT_IRQL(x) PC_ASSERT(KeGetCurrentIrql() <= (x)) +#define PC_ASSERT_IRQL_EQUAL(x) PC_ASSERT(KeGetCurrentIrql()==(x)) + +extern +"C" NTSTATUS NTAPI PortClsCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +extern +"C" NTSTATUS NTAPI PortClsPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +extern +"C" NTSTATUS NTAPI PortClsPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +extern +"C" NTSTATUS NTAPI PortClsSysControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); -NTSTATUS NewMiniportDMusUART( +NTSTATUS +NewMiniportDMusUART( OUT PMINIPORT* OutMiniport, IN REFCLSID ClassId); -NTSTATUS NewMiniportFmSynth( +NTSTATUS +NewMiniportFmSynth( OUT PMINIPORT* OutMiniport, IN REFCLSID ClassId); -NTSTATUS NewPortDMus( +NTSTATUS +NewPortDMus( OUT PPORT* OutPort); -NTSTATUS NewPortTopology( +NTSTATUS +NewPortTopology( OUT PPORT* OutPort); -NTSTATUS NewPortWaveCyclic( +NTSTATUS +NewPortWaveCyclic( OUT PPORT* OutPort); -NTSTATUS NewPortWavePci( +NTSTATUS +NewPortWavePci( OUT PPORT* OutPort); -NTSTATUS NewIDrmPort( +NTSTATUS +NewIDrmPort( OUT PDRMPORT2 *OutPort); -NTSTATUS NewPortClsVersion( +NTSTATUS +NewPortClsVersion( OUT PPORTCLSVERSION * OutVersion); -NTSTATUS NewPortFilterWaveCyclic( +NTSTATUS +NewPortFilterWaveCyclic( OUT IPortFilterWaveCyclic ** OutFilter); -NTSTATUS NewPortPinWaveCyclic( +NTSTATUS +NewPortPinWaveCyclic( OUT IPortPinWaveCyclic ** OutPin); NTSTATUS NewPortFilterWavePci( OUT IPortFilterWavePci ** OutFilter); -NTSTATUS NewPortPinWavePci( +NTSTATUS +NewPortPinWavePci( OUT IPortPinWavePci ** OutPin); PDEVICE_OBJECT @@ -102,11 +130,14 @@ PMINIPORTWAVEPCI GetWavePciMiniport( PPORTWAVEPCI Port); + NTSTATUS NewPortFilterDMus( OUT PPORTFILTERDMUS * OutFilter); -NTSTATUS NewPortPinDMus( + +NTSTATUS +NewPortPinDMus( OUT PPORTPINDMUS * OutPin); VOID @@ -121,7 +152,8 @@ NTSTATUS NewPortFilterWaveRT( OUT IPortFilterWaveRT ** OutFilter); -NTSTATUS NewPortPinWaveRT( +NTSTATUS +NewPortPinWaveRT( OUT IPortPinWaveRT ** OutPin); PMINIPORTWAVERT @@ -132,6 +164,7 @@ PDEVICE_OBJECT GetDeviceObjectFromPortWaveRT( IPortWaveRT* iface); + NTSTATUS NewPortWaveRTStream( PPORTWAVERTSTREAM *OutStream); @@ -193,6 +226,8 @@ PinPropertyHandler( IN PKSIDENTIFIER Request, IN OUT PVOID Data); +extern +"C" NTSTATUS NTAPI PcDmaMasterDescription( @@ -207,6 +242,8 @@ PcDmaMasterDescription( IN ULONG DmaPort, OUT PDEVICE_DESCRIPTION DeviceDescription); +extern +"C" NTSTATUS NTAPI PcDmaSlaveDescription( @@ -219,6 +256,8 @@ PcDmaSlaveDescription( IN ULONG DmaPort, OUT PDEVICE_DESCRIPTION DeviceDescription); +extern +"C" NTSTATUS NTAPI PcCreateSubdeviceDescriptor( @@ -237,6 +276,8 @@ PcCreateSubdeviceDescriptor( IN KSEVENT_SET * EventSet, IN PPCFILTER_DESCRIPTOR FilterDescription); +extern +"C" NTSTATUS NTAPI PcValidateConnectRequest( diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp similarity index 88% rename from reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c rename to reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp index 53051965b8c..112c3f9ffab 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp @@ -1,12 +1,12 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/propertyhandler.c + * FILE: drivers/wdm/audio/backpln/portcls/propertyhandler.cpp * PURPOSE: Pin property handler * PROGRAMMER: Johannes Anderwald */ -#include "private.h" +#include "private.hpp" NTSTATUS FindPropertyHandler( @@ -90,24 +90,24 @@ HandleDataIntersection( NTSTATUS Status = STATUS_NO_MATCH; ULONG Index, Length; - /* Access parameters */ + // Access parameters MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); DataRange = (PKSDATARANGE)(MultipleItem + 1); for(Index = 0; Index < MultipleItem->Count; Index++) { - /* Call miniport's properitary handler */ - ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRangesCount); - ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0]); - Status = SubDevice->lpVtbl->DataRangeIntersection(SubDevice, Pin->PinId, DataRange, (PKSDATARANGE)Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0], - DataLength, Data, &Length); + // Call miniport's properitary handler + PC_ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRangesCount); + PC_ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0]); + Status = SubDevice->DataRangeIntersection(Pin->PinId, DataRange, (PKSDATARANGE)Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0], + DataLength, Data, &Length); if (Status == STATUS_SUCCESS) { IoStatus->Information = Length; break; } - DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize); + DataRange = (PKSDATARANGE) UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize); } IoStatus->Status = Status; @@ -133,15 +133,15 @@ PinPropertyHandler( NTSTATUS Status = STATUS_UNSUCCESSFUL; Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); - ASSERT(Descriptor); + PC_ASSERT(Descriptor); - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* Get the IrpTarget */ + // Get the IrpTarget IrpTarget = (IIrpTarget*)IoStack->FileObject->FsContext2; - /* Get the parent */ - Status = IrpTarget->lpVtbl->QueryInterface(IrpTarget, &IID_IPort, (PVOID*)&Port); + // Get the parent + Status = IrpTarget->QueryInterface(IID_IPort, (PVOID*)&Port); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to obtain IPort interface from filter\n"); @@ -150,15 +150,15 @@ PinPropertyHandler( return STATUS_UNSUCCESSFUL; } - /* Get private ISubdevice interface */ - Status = Port->lpVtbl->QueryInterface(Port, &IID_ISubdevice, (PVOID*)&SubDevice); + // Get private ISubdevice interface + Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to obtain ISubdevice interface from port driver\n"); KeBugCheck(0); } - /* get current stack location */ + // get current stack location IoStack = IoGetCurrentIrpStackLocation(Irp); switch(Request->Id) @@ -197,11 +197,11 @@ PinPropertyHandler( Status = STATUS_UNSUCCESSFUL; } - /* Release reference */ - Port->lpVtbl->Release(Port); + // Release reference + Port->Release(); - /* Release subdevice reference */ - SubDevice->lpVtbl->Release(SubDevice); + // Release subdevice reference + SubDevice->Release(); return Status; } @@ -226,18 +226,18 @@ FastPropertyHandler( ULONG Size, Index; PKSMULTIPLE_ITEM Item; - ASSERT(Descriptor); + PC_ASSERT(Descriptor); - if (!IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Pin)) + if (!IsEqualGUIDAligned(Property->Set, KSPROPSETID_Pin)) { - /* the fast handler only supports pin properties atm*/ + // the fast handler only supports pin properties atm*/ DPRINT("Only KSPROPSETID_Pin is supported\n"); IoStatus->Status = Status = STATUS_NOT_IMPLEMENTED; IoStatus->Information = 0; return Status; } - /* property handler is used to verify input parameters */ + // property handler is used to verify input parameters Status = FindPropertyHandler(IoStatus, Descriptor, Property, PropertyLength, DataLength, Data, &PropertyHandler); if (!NT_SUCCESS(Status)) { @@ -378,7 +378,7 @@ FindPropertyHandler( for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++) { - if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set)) + if (IsEqualGUIDAligned(Property->Set, *Descriptor->FilterPropertySet.Properties[Index].Set)) { for(ItemIndex = 0; ItemIndex < Descriptor->FilterPropertySet.Properties[Index].PropertiesCount; ItemIndex++) { @@ -394,14 +394,14 @@ FindPropertyHandler( { if (sizeof(ULONG) > OutputBufferLength) { - /* too small buffer */ + // too small buffer return STATUS_INVALID_PARAMETER; } - /* get output buffer */ + // get output buffer Flags = (PULONG)OutputBuffer; - /* clear flags */ + // clear flags *Flags = KSPROPERTY_TYPE_BASICSUPPORT; if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].GetSupported) @@ -414,10 +414,10 @@ FindPropertyHandler( if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) { - /* get output buffer */ + // get output buffer Description = (PKSPROPERTY_DESCRIPTION)OutputBuffer; - /* store result */ + // store result Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); Description->PropTypeSet.Set = KSPROPTYPESETID_General; Description->PropTypeSet.Id = 0; @@ -434,7 +434,7 @@ FindPropertyHandler( if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty > InputBufferLength) { - /* too small input buffer */ + // too small input buffer IoStatus->Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty; IoStatus->Status = STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL; @@ -442,7 +442,7 @@ FindPropertyHandler( if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData > OutputBufferLength) { - /* too small output buffer */ + // too small output buffer IoStatus->Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData; IoStatus->Status = STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL; @@ -465,7 +465,7 @@ PcCountProperties( PIO_STACK_LOCATION IoStack; LPGUID Guid; - /* count property items */ + // count property items Properties = Descriptor->FilterPropertySet.FreeKsPropertySetOffset; if (Descriptor->DeviceDescriptor->AutomationTable) @@ -473,26 +473,26 @@ PcCountProperties( Properties = Descriptor->DeviceDescriptor->AutomationTable->PropertyCount; } - /* get current irp stack */ + // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - /* store output size */ + // store output size Irp->IoStatus.Information = sizeof(GUID) * Properties; if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * Properties) { - /* buffer too small */ + // buffer too small Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_BUFFER_OVERFLOW; } - /* get output buffer */ - Guid = Irp->UserBuffer; + // get output buffer + Guid = (LPGUID)Irp->UserBuffer; - /* copy property guids from filter */ + // copy property guids from filter Offset = 0; for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++) { @@ -502,7 +502,7 @@ PcCountProperties( if (Descriptor->DeviceDescriptor->AutomationTable) { - /* copy property guids from driver */ + // copy property guids from driver for(Index = 0; Index < Descriptor->DeviceDescriptor->AutomationTable->PropertyCount; Index++) { RtlMoveMemory(&Guid[Offset], Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Set, sizeof(GUID)); @@ -510,7 +510,7 @@ PcCountProperties( } } - /* done */ + // done Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -535,29 +535,29 @@ PcPropertyHandler( IoStack = IoGetCurrentIrpStackLocation(Irp); Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - ASSERT(Property); + PC_ASSERT(Property); - if (IsEqualGUIDAligned(&Property->Set, &GUID_NULL) && Property->Id == 0 && Property->Flags == KSPROPERTY_TYPE_SETSUPPORT) + if (IsEqualGUIDAligned(Property->Set, GUID_NULL) && Property->Id == 0 && Property->Flags == KSPROPERTY_TYPE_SETSUPPORT) { return PcCountProperties(Irp, Descriptor); } - /* check properties provided by the driver */ + // check properties provided by the driver if (Descriptor->DeviceDescriptor->AutomationTable) { for(Index = 0; Index < Descriptor->DeviceDescriptor->AutomationTable->PropertyCount; Index++) { - if (IsEqualGUID(Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Set, &Property->Set)) + if (IsEqualGUID(*Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Set, Property->Set)) { if (Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Id == Property->Id) { if(Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Flags & Property->Flags) { - PropertyRequest = ExAllocatePool(NonPagedPool, sizeof(PCPROPERTY_REQUEST)); + PropertyRequest = (PPCPROPERTY_REQUEST)ExAllocatePool(NonPagedPool, sizeof(PCPROPERTY_REQUEST)); if (!PropertyRequest) { - /* no memory */ + // no memory Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -585,18 +585,19 @@ PcPropertyHandler( Status = FindPropertyHandler(&Irp->IoStatus, Descriptor, Property, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &PropertyHandler); if (NT_SUCCESS(Status) && PropertyHandler) { - KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)Descriptor; + // HACK + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (const KSPROPERTY_ITEM*)Descriptor; DPRINT("Calling property handler %p\n", PropertyHandler); Status = PropertyHandler(Irp, Property, Irp->UserBuffer); } else if (!NT_SUCCESS(Status)) { - RtlStringFromGUID(&Property->Set, &GuidString); + RtlStringFromGUID(Property->Set, &GuidString); DPRINT1("Unhandeled property: Set %S Id %u Flags %x InputLength %u OutputLength %u\n", GuidString.Buffer, Property->Id, Property->Flags, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength); RtlFreeUnicodeString(&GuidString); } - /* the information member is set by the handler */ + // the information member is set by the handler Irp->IoStatus.Status = Status; DPRINT("Result %x Length %u\n", Status, Irp->IoStatus.Information); IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/wdm/audio/backpln/portcls/purecall.cpp b/reactos/drivers/wdm/audio/backpln/portcls/purecall.cpp new file mode 100644 index 00000000000..dd92ebe7584 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/purecall.cpp @@ -0,0 +1,23 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/connection.c + * PURPOSE: purecall stub + * PROGRAMMER: Johannes Anderwald + */ + + +#include "private.hpp" + + +extern "C" { + void + __cxa_pure_virtual() + { + // put error handling here + + KeBugCheck(0); + + } +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/registry.c b/reactos/drivers/wdm/audio/backpln/portcls/registry.c deleted file mode 100644 index e7eaf5f71e5..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/registry.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/registry.c - * PURPOSE: Registry access object - * PROGRAMMER: Johannes Anderwald - */ - -#include "private.h" - -typedef struct -{ - IRegistryKeyVtbl * lpVtbl; - - LONG ref; - HANDLE hKey; - BOOL Deleted; - -}IRegistryKeyImpl; - -ULONG -NTAPI -IRegistryKey_fnAddRef( - IN IRegistryKey* iface) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - - DPRINT("IRegistryKey_AddRef: This %p\n", This); - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IRegistryKey_fnRelease( - IN IRegistryKey* iface) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - - InterlockedDecrement(&This->ref); - DPRINT("IRegistryKey_fnRelease ref %u this %p entered\n", This->ref, This); - if (This->ref == 0) - { - if (This->hKey) - { - ZwClose(This->hKey); - } - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - -NTSTATUS -NTAPI -IRegistryKey_fnQueryInterface( - IN IRegistryKey* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - DPRINT("IRegistryKey_fnQueryInterface entered\n"); - if (IsEqualGUIDAligned(refiid, &IID_IRegistryKey)) - { - *Output = (PVOID)&This->lpVtbl; - _InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - - DPRINT("IRegistryKey_QueryInterface: This %p unknown iid\n", This, This->ref); - DbgBreakPoint(); - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -IRegistryKey_fnDeleteKey( - IN IRegistryKey* iface) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - NTSTATUS Status; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->Deleted) - { - return STATUS_INVALID_HANDLE; - } - - Status = ZwDeleteKey(This->hKey); - if (NT_SUCCESS(Status)) - { - This->Deleted = TRUE; - } - return Status; -} - -NTSTATUS -NTAPI -IRegistryKey_fnEnumerateKey( - IN IRegistryKey* iface, - IN ULONG Index, - IN KEY_INFORMATION_CLASS KeyInformationClass, - OUT PVOID KeyInformation, - IN ULONG Length, - OUT PULONG ResultLength) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->Deleted) - { - return STATUS_INVALID_HANDLE; - } - - return ZwEnumerateKey(This->hKey, Index, KeyInformationClass, KeyInformation, Length, ResultLength); -} - -NTSTATUS -NTAPI -IRegistryKey_fnEnumerateKeyValue( - IN IRegistryKey* iface, - IN ULONG Index, - IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, - OUT PVOID KeyValueInformation, - IN ULONG Length, - OUT PULONG ResultLength) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->Deleted) - { - return STATUS_INVALID_HANDLE; - } - - return ZwEnumerateValueKey(This->hKey, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); -} - -NTSTATUS -NTAPI -IRegistryKey_fnNewSubKey( - IN IRegistryKey* iface, - OUT PREGISTRYKEY *RegistrySubKey, - IN PUNKNOWN OuterUnknown, - IN ACCESS_MASK DesiredAccess, - IN PUNICODE_STRING SubKeyName, - IN ULONG CreateOptions, - OUT PULONG Disposition OPTIONAL) -{ - OBJECT_ATTRIBUTES Attributes; - NTSTATUS Status; - HANDLE hKey; - IRegistryKeyImpl * NewThis, *This = (IRegistryKeyImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - DPRINT("IRegistryKey_fnNewSubKey entered %S\n", SubKeyName->Buffer); - - if (This->Deleted) - { - return STATUS_INVALID_HANDLE; - } - - InitializeObjectAttributes(&Attributes, SubKeyName, 0, This->hKey, NULL); - Status = ZwCreateKey(&hKey, KEY_READ | KEY_WRITE, &Attributes, 0, NULL, 0, Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IRegistryKey_fnNewSubKey failed with %x\n", Status); - DbgBreakPoint(); - return Status; - } - - NewThis = AllocateItem(NonPagedPool, sizeof(IRegistryKeyImpl), TAG_PORTCLASS); - if (!NewThis) - { - ZwClose(hKey); - return STATUS_INSUFFICIENT_RESOURCES; - } - - if (OuterUnknown) - OuterUnknown->lpVtbl->AddRef(OuterUnknown); - - NewThis->hKey = hKey; - NewThis->ref = 1; - NewThis->lpVtbl = This->lpVtbl; - *RegistrySubKey = (PREGISTRYKEY)&NewThis->lpVtbl; - - DPRINT("IRegistryKey_fnNewSubKey RESULT %p\n", *RegistrySubKey ); - - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -IRegistryKey_fnQueryKey( - IN IRegistryKey* iface, - IN KEY_INFORMATION_CLASS KeyInformationClass, - OUT PVOID KeyInformation, - IN ULONG Length, - OUT PULONG ResultLength) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->Deleted) - { - return STATUS_INVALID_HANDLE; - } - - return ZwQueryKey(This->hKey, KeyInformationClass, KeyInformation, Length, ResultLength); -} - -NTSTATUS -NTAPI -IRegistryKey_fnQueryRegistryValues( - IN IRegistryKey* iface, - IN PRTL_QUERY_REGISTRY_TABLE QueryTable, - IN PVOID Context OPTIONAL) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->Deleted) - { - return STATUS_INVALID_HANDLE; - } - - return RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, (PCWSTR)This->hKey, QueryTable, Context, NULL); -} - -NTSTATUS -NTAPI -IRegistryKey_fnQueryValueKey( - IN IRegistryKey* iface, - IN PUNICODE_STRING ValueName, - IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, - OUT PVOID KeyValueInformation, - IN ULONG Length, - OUT PULONG ResultLength) -{ - NTSTATUS Status; - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->Deleted) - { - return STATUS_INVALID_HANDLE; - } - - Status = ZwQueryValueKey(This->hKey, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); - DPRINT("IRegistryKey_fnQueryValueKey entered %p value %wZ Status %x\n", This, ValueName, Status); - return Status; -} - -NTSTATUS -NTAPI -IRegistryKey_fnSetValueKey( - IN IRegistryKey* iface, - IN PUNICODE_STRING ValueName OPTIONAL, - IN ULONG Type, - IN PVOID Data, - IN ULONG DataSize - ) -{ - IRegistryKeyImpl * This = (IRegistryKeyImpl*)iface; - DPRINT("IRegistryKey_fnSetValueKey entered %S\n", ValueName->Buffer); - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (This->Deleted) - { - return STATUS_INVALID_HANDLE; - } - - return ZwSetValueKey(This->hKey, ValueName, 0, Type, Data, DataSize); -} - -static IRegistryKeyVtbl vt_IRegistryKey = -{ - /* IUnknown methods */ - IRegistryKey_fnQueryInterface, - IRegistryKey_fnAddRef, - IRegistryKey_fnRelease, - /* IRegistryKey methods */ - IRegistryKey_fnQueryKey, - IRegistryKey_fnEnumerateKey, - IRegistryKey_fnQueryValueKey, - IRegistryKey_fnEnumerateKeyValue, - IRegistryKey_fnSetValueKey, - IRegistryKey_fnQueryRegistryValues, - IRegistryKey_fnNewSubKey, - IRegistryKey_fnDeleteKey -}; - -/* - * @implemented - */ -NTSTATUS NTAPI -PcNewRegistryKey( - OUT PREGISTRYKEY* OutRegistryKey, - IN PUNKNOWN OuterUnknown OPTIONAL, - IN ULONG RegistryKeyType, - IN ACCESS_MASK DesiredAccess, - IN PVOID DeviceObject OPTIONAL, - IN PVOID SubDevice OPTIONAL, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN ULONG CreateOptions OPTIONAL, - OUT PULONG Disposition OPTIONAL) -{ - HANDLE hHandle; - NTSTATUS Status = STATUS_UNSUCCESSFUL; - IRegistryKeyImpl * This; - PPCLASS_DEVICE_EXTENSION DeviceExt; - - DPRINT("PcNewRegistryKey entered\n"); - - if (!OutRegistryKey) - return STATUS_INVALID_PARAMETER; - - if (RegistryKeyType != GeneralRegistryKey && - RegistryKeyType != DeviceRegistryKey && - RegistryKeyType != DriverRegistryKey && - RegistryKeyType != HwProfileRegistryKey && - RegistryKeyType != DeviceInterfaceRegistryKey) - { - return STATUS_INVALID_PARAMETER; - } - - /* check for the key type */ - if (RegistryKeyType == GeneralRegistryKey) - { - /* do we have the required object attributes */ - if (!ObjectAttributes) - { - /* object attributes is mandatory */ - return STATUS_INVALID_PARAMETER; - } - /* try to open the key */ - Status = ZwOpenKey(&hHandle, DesiredAccess, ObjectAttributes); - } - else if (RegistryKeyType == DeviceRegistryKey || - RegistryKeyType == DriverRegistryKey || - RegistryKeyType == HwProfileRegistryKey) - { - /* check for HwProfileRegistryKey case */ - if (RegistryKeyType == HwProfileRegistryKey) - { - /* IoOpenDeviceRegistryKey used different constant */ - RegistryKeyType = PLUGPLAY_REGKEY_CURRENT_HWPROFILE; - } - - /* obtain the new device extension */ - DeviceExt = (PPCLASS_DEVICE_EXTENSION) ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension; - - Status = IoOpenDeviceRegistryKey(DeviceExt->PhysicalDeviceObject, RegistryKeyType, DesiredAccess, &hHandle); - } - else if (RegistryKeyType == DeviceInterfaceRegistryKey) - { - /* FIXME */ - UNIMPLEMENTED - DbgBreakPoint(); - } - - if (!NT_SUCCESS(Status)) - { - return Status; - } - - This = AllocateItem(NonPagedPool, sizeof(IRegistryKeyImpl), TAG_PORTCLASS); - if (!This) - { - ZwClose(hHandle); - return STATUS_INSUFFICIENT_RESOURCES; - } - - if (OuterUnknown) - OuterUnknown->lpVtbl->AddRef(OuterUnknown); - - This->hKey = hHandle; - This->lpVtbl = &vt_IRegistryKey; - This->ref = 1; - - *OutRegistryKey = (PREGISTRYKEY)&This->lpVtbl; - DPRINT("PcNewRegistryKey result %p\n", *OutRegistryKey); - return STATUS_SUCCESS; -} - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/registry.cpp b/reactos/drivers/wdm/audio/backpln/portcls/registry.cpp new file mode 100644 index 00000000000..de9a48d0058 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/registry.cpp @@ -0,0 +1,342 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/registry.cpp + * PURPOSE: Registry access object + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.hpp" + +class CRegistryKey : public IRegistryKey +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + + IMP_IRegistryKey; + CRegistryKey(IUnknown * OuterUnknown, HANDLE hKey) : m_hKey(hKey){} + virtual ~CRegistryKey(); + +protected: + + HANDLE m_hKey; + BOOL m_Deleted; + LONG m_Ref; +}; + +CRegistryKey::~CRegistryKey() +{ + if (m_hKey) + ZwClose(m_hKey); +} + + +NTSTATUS +NTAPI +CRegistryKey::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + DPRINT("CRegistryKey::QueryInterface entered\n"); + if (IsEqualGUIDAligned(refiid, IID_IRegistryKey) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PREGISTRYKEY(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + DPRINT("IRegistryKey_QueryInterface: This %p\n", this); + DbgBreakPoint(); + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +CRegistryKey::DeleteKey() +{ + NTSTATUS Status; + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_Deleted) + { + return STATUS_INVALID_HANDLE; + } + + Status = ZwDeleteKey(m_hKey); + if (NT_SUCCESS(Status)) + { + m_Deleted = TRUE; + } + return Status; +} + +NTSTATUS +NTAPI +CRegistryKey::EnumerateKey( + IN ULONG Index, + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_Deleted) + { + return STATUS_INVALID_HANDLE; + } + + return ZwEnumerateKey(m_hKey, Index, KeyInformationClass, KeyInformation, Length, ResultLength); +} + +NTSTATUS +NTAPI +CRegistryKey::EnumerateValueKey( + IN ULONG Index, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + OUT PVOID KeyValueInformation, + IN ULONG Length, + OUT PULONG ResultLength) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_Deleted) + { + return STATUS_INVALID_HANDLE; + } + + return ZwEnumerateValueKey(m_hKey, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); +} + +NTSTATUS +NTAPI +CRegistryKey::NewSubKey( + OUT PREGISTRYKEY *RegistrySubKey, + IN PUNKNOWN OuterUnknown, + IN ACCESS_MASK DesiredAccess, + IN PUNICODE_STRING SubKeyName, + IN ULONG CreateOptions, + OUT PULONG Disposition OPTIONAL) +{ + OBJECT_ATTRIBUTES Attributes; + NTSTATUS Status; + HANDLE hKey; + CRegistryKey * RegistryKey; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + DPRINT("CRegistryKey::NewSubKey entered %S\n", SubKeyName->Buffer); + + if (m_Deleted) + { + return STATUS_INVALID_HANDLE; + } + + InitializeObjectAttributes(&Attributes, SubKeyName, 0, m_hKey, NULL); + Status = ZwCreateKey(&hKey, KEY_READ | KEY_WRITE, &Attributes, 0, NULL, 0, Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CRegistryKey::NewSubKey failed with %x\n", Status); + return Status; + } + + RegistryKey = new(NonPagedPool, TAG_PORTCLASS)CRegistryKey(OuterUnknown, hKey); + if (!RegistryKey) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = RegistryKey->QueryInterface(IID_IRegistryKey, (PVOID*)RegistrySubKey); + + if (!NT_SUCCESS(Status)) + { + ZwClose(hKey); + delete RegistryKey; + } + + *RegistrySubKey = (PREGISTRYKEY)RegistryKey; + + DPRINT("CRegistryKey::NewSubKey RESULT %p\n", *RegistrySubKey); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CRegistryKey::QueryKey( + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_Deleted) + { + return STATUS_INVALID_HANDLE; + } + + return ZwQueryKey(m_hKey, KeyInformationClass, KeyInformation, Length, ResultLength); +} + +NTSTATUS +NTAPI +CRegistryKey::QueryRegistryValues( + IN PRTL_QUERY_REGISTRY_TABLE QueryTable, + IN PVOID Context OPTIONAL) +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_Deleted) + { + return STATUS_INVALID_HANDLE; + } + + return RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, (PCWSTR)m_hKey, QueryTable, Context, NULL); +} + +NTSTATUS +NTAPI +CRegistryKey::QueryValueKey( + IN PUNICODE_STRING ValueName, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + OUT PVOID KeyValueInformation, + IN ULONG Length, + OUT PULONG ResultLength) +{ + NTSTATUS Status; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_Deleted) + { + return STATUS_INVALID_HANDLE; + } + + Status = ZwQueryValueKey(m_hKey, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); + DPRINT("CRegistryKey::QueryValueKey entered %p value %wZ Status %x\n", this, ValueName, Status); + return Status; +} + +NTSTATUS +NTAPI +CRegistryKey::SetValueKey( + IN PUNICODE_STRING ValueName OPTIONAL, + IN ULONG Type, + IN PVOID Data, + IN ULONG DataSize + ) +{ + DPRINT("CRegistryKey::SetValueKey entered %S\n", ValueName->Buffer); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (m_Deleted) + { + return STATUS_INVALID_HANDLE; + } + + return ZwSetValueKey(m_hKey, ValueName, 0, Type, Data, DataSize); +} + +NTSTATUS +NTAPI +PcNewRegistryKey( + OUT PREGISTRYKEY* OutRegistryKey, + IN PUNKNOWN OuterUnknown OPTIONAL, + IN ULONG RegistryKeyType, + IN ACCESS_MASK DesiredAccess, + IN PVOID DeviceObject OPTIONAL, + IN PVOID SubDevice OPTIONAL, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN ULONG CreateOptions OPTIONAL, + OUT PULONG Disposition OPTIONAL) +{ + HANDLE hHandle; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + CRegistryKey * RegistryKey; + PPCLASS_DEVICE_EXTENSION DeviceExt; + + DPRINT("PcNewRegistryKey entered\n"); + + if (!OutRegistryKey) + return STATUS_INVALID_PARAMETER; + + if (RegistryKeyType != GeneralRegistryKey && + RegistryKeyType != DeviceRegistryKey && + RegistryKeyType != DriverRegistryKey && + RegistryKeyType != HwProfileRegistryKey && + RegistryKeyType != DeviceInterfaceRegistryKey) + { + return STATUS_INVALID_PARAMETER; + } + + // check for the key type + if (RegistryKeyType == GeneralRegistryKey) + { + // do we have the required object attributes + if (!ObjectAttributes) + { + // object attributes is mandatory + return STATUS_INVALID_PARAMETER; + } + // try to open the key + Status = ZwOpenKey(&hHandle, DesiredAccess, ObjectAttributes); + } + else if (RegistryKeyType == DeviceRegistryKey || + RegistryKeyType == DriverRegistryKey || + RegistryKeyType == HwProfileRegistryKey) + { + // check for HwProfileRegistryKey case + if (RegistryKeyType == HwProfileRegistryKey) + { + // IoOpenDeviceRegistryKey used different constant + RegistryKeyType = PLUGPLAY_REGKEY_CURRENT_HWPROFILE; + } + + // obtain the new device extension + DeviceExt = (PPCLASS_DEVICE_EXTENSION) ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension; + + Status = IoOpenDeviceRegistryKey(DeviceExt->PhysicalDeviceObject, RegistryKeyType, DesiredAccess, &hHandle); + } + else if (RegistryKeyType == DeviceInterfaceRegistryKey) + { + // FIXME + UNIMPLEMENTED + DbgBreakPoint(); + } + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + RegistryKey = new(NonPagedPool, TAG_PORTCLASS)CRegistryKey(OuterUnknown, hHandle); + if (!RegistryKey) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = RegistryKey->QueryInterface(IID_IRegistryKey, (PVOID*)OutRegistryKey); + + if (!NT_SUCCESS(Status)) + { + delete RegistryKey; + } + + DPRINT("PcNewRegistryKey result %p\n", *OutRegistryKey); + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/resource.c b/reactos/drivers/wdm/audio/backpln/portcls/resource.c deleted file mode 100644 index be443f3fe13..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/resource.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS - * FILE: drivers/wdm/audio/backpln/portcls/resource.c - * PURPOSE: Port Class driver / ResourceList implementation - * PROGRAMMER: Andrew Greenwood - * Johannes Anderwald - * HISTORY: - * 27 Jan 07 Created - */ - -#include "private.h" -#include -#include -#include - -typedef struct CResourceList -{ - IResourceListVtbl *lpVtbl; - LONG ref; - PUNKNOWN OuterUnknown; - POOL_TYPE PoolType; - PCM_RESOURCE_LIST TranslatedResourceList; - PCM_RESOURCE_LIST UntranslatedResourceList; - ULONG NumberOfEntries; -} IResourceListImpl; - -/* - Basic IUnknown methods -*/ - -NTSTATUS -NTAPI -IResourceList_fnQueryInterface( - IResourceList* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - UNICODE_STRING GuidString; - - IResourceListImpl * This = (IResourceListImpl*)iface; - if (IsEqualGUIDAligned(refiid, &IID_IResourceList) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - - if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) - { - DPRINT1("IResourceList_QueryInterface no interface!!! iface %S\n", GuidString.Buffer); - RtlFreeUnicodeString(&GuidString); - } - - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IResourceList_fnAddRef( - IResourceList* iface) -{ - IResourceListImpl * This = (IResourceListImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IResourceList_fnRelease( - IResourceList* iface) -{ - IResourceListImpl * This = (IResourceListImpl*)iface; - - InterlockedDecrement(&This->ref); - - DPRINT("IResourceList_fnRelease %p ref %x\n", This, This->ref); - - if (This->ref == 0) - { - FreeItem(This->TranslatedResourceList, TAG_PORTCLASS); - FreeItem(This->UntranslatedResourceList, TAG_PORTCLASS); - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - - -/* - IResourceList methods -*/ - -ULONG -NTAPI -IResourceList_fnNumberOfEntries(IResourceList* iface) -{ - IResourceListImpl * This = (IResourceListImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - return This->NumberOfEntries; -} - -ULONG -NTAPI -IResourceList_fnNumberOfEntriesOfType( - IResourceList* iface, - IN CM_RESOURCE_TYPE Type) -{ - IResourceListImpl * This = (IResourceListImpl*)iface; - ULONG Index, Count = 0; - PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->TranslatedResourceList) - { - /* no resource list */ - return 0; - } - - /* I guess the translated and untranslated lists will be same length? */ - for (Index = 0; Index < This->TranslatedResourceList->List[0].PartialResourceList.Count; Index ++ ) - { - PartialDescriptor = &This->TranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[Index]; - DPRINT("Descriptor Type %u\n", PartialDescriptor->Type); - if (PartialDescriptor->Type == Type) - { - /* Yay! Finally found one that matches! */ - Count++; - } - } - - DPRINT("Found %d type %d\n", Count, Type); - return Count; -} - -PCM_PARTIAL_RESOURCE_DESCRIPTOR -NTAPI -IResourceList_fnFindTranslatedEntry( - IResourceList* iface, - IN CM_RESOURCE_TYPE Type, - IN ULONG Index) -{ - IResourceListImpl * This = (IResourceListImpl*)iface; - ULONG DescIndex, Count = 0; - PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->TranslatedResourceList) - { - /* no resource list */ - return NULL; - } - - for (DescIndex = 0; DescIndex < This->TranslatedResourceList->List[0].PartialResourceList.Count; DescIndex ++ ) - { - PartialDescriptor = &This->TranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[DescIndex]; - - if (PartialDescriptor->Type == Type) - { - /* Yay! Finally found one that matches! */ - if (Index == Count) - { - return PartialDescriptor; - } - Count++; - } - } - - return NULL; -} - -PCM_PARTIAL_RESOURCE_DESCRIPTOR -NTAPI -IResourceList_fnFindUntranslatedEntry( - IResourceList* iface, - IN CM_RESOURCE_TYPE Type, - IN ULONG Index) -{ - IResourceListImpl * This = (IResourceListImpl*)iface; - ULONG DescIndex, Count = 0; - PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - if (!This->UntranslatedResourceList) - { - /* no resource list */ - return NULL; - } - - for (DescIndex = 0; DescIndex < This->UntranslatedResourceList->List[0].PartialResourceList.Count; DescIndex ++ ) - { - PartialDescriptor = &This->UntranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[DescIndex]; - - if (PartialDescriptor->Type == Type) - { - /* Yay! Finally found one that matches! */ - if (Index == Count) - { - return PartialDescriptor; - } - Count++; - } - } - return NULL; -} - -NTSTATUS -NTAPI -IResourceList_fnAddEntry( - IResourceList* iface, - IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, - IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Untranslated) -{ - PCM_RESOURCE_LIST NewUntranslatedResources, NewTranslatedResources; - ULONG NewTranslatedSize, NewUntranslatedSize, TranslatedSize, UntranslatedSize, ResourceCount; - IResourceListImpl * This = (IResourceListImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - /* calculate translated resource list size */ - ResourceCount = This->TranslatedResourceList->List[0].PartialResourceList.Count; - NewTranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount+1]); - TranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); - - - NewTranslatedResources = AllocateItem(This->PoolType, NewTranslatedSize, TAG_PORTCLASS); - if (!NewTranslatedResources) - return STATUS_INSUFFICIENT_RESOURCES; - - - /* calculate untranslated resouce list size */ - ResourceCount = This->UntranslatedResourceList->List[0].PartialResourceList.Count; - NewUntranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount+1]); - UntranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); - - - /* allocate untranslated resource list size */ - NewUntranslatedResources = AllocateItem(This->PoolType, NewUntranslatedSize, TAG_PORTCLASS); - if (!NewUntranslatedResources) - { - FreeItem(NewTranslatedResources, TAG_PORTCLASS); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* now copy translated resource list */ - RtlMoveMemory(NewTranslatedResources, This->TranslatedResourceList, TranslatedSize); - RtlMoveMemory((PUCHAR)NewTranslatedResources + TranslatedSize, Translated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); - - /* now copy untranslated resource list */ - RtlMoveMemory(NewUntranslatedResources, This->UntranslatedResourceList, UntranslatedSize); - RtlMoveMemory((PUCHAR)NewUntranslatedResources + UntranslatedSize, Untranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); - - /* free old lists */ - FreeItem(This->TranslatedResourceList, TAG_PORTCLASS); - FreeItem(This->UntranslatedResourceList, TAG_PORTCLASS); - - /* store new lists */ - This->UntranslatedResourceList = NewUntranslatedResources; - This->TranslatedResourceList = NewTranslatedResources; - - /* increment descriptor count */ - NewUntranslatedResources->List[0].PartialResourceList.Count++; - NewTranslatedResources->List[0].PartialResourceList.Count++; - - /* add entry count */ - This->NumberOfEntries++; - - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -IResourceList_fnAddEntryFromParent( - IResourceList* iface, - IN IResourceList* Parent, - IN CM_RESOURCE_TYPE Type, - IN ULONG Index) -{ - PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, Untranslated; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - Translated = Parent->lpVtbl->FindTranslatedEntry(Parent, Type, Index); - Untranslated = Parent->lpVtbl->FindUntranslatedEntry(Parent, Type, Index); - - if (Translated && Untranslated) - { - /* add entry from parent */ - return iface->lpVtbl->AddEntry(iface, Translated, Untranslated); - } - - /* entry not found */ - return STATUS_INVALID_PARAMETER; -} - -PCM_RESOURCE_LIST -NTAPI -IResourceList_fnTranslatedList( - IResourceList* iface) -{ - IResourceListImpl * This = (IResourceListImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - return This->TranslatedResourceList; -} - -PCM_RESOURCE_LIST -NTAPI -IResourceList_fnUntranslatedList( - IResourceList* iface) -{ - IResourceListImpl * This = (IResourceListImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - return This->UntranslatedResourceList; -} - - -/* - ResourceList V-Table -*/ -static const IResourceListVtbl vt_ResourceListVtbl = -{ - /* IUnknown */ - IResourceList_fnQueryInterface, - IResourceList_fnAddRef, - IResourceList_fnRelease, - /* IResourceList */ - IResourceList_fnNumberOfEntries, - IResourceList_fnNumberOfEntriesOfType, - IResourceList_fnFindTranslatedEntry, - IResourceList_fnFindUntranslatedEntry, - IResourceList_fnAddEntry, - IResourceList_fnAddEntryFromParent, - IResourceList_fnTranslatedList, - IResourceList_fnUntranslatedList -}; - - -/* - Factory for creating a resource list -*/ -PORTCLASSAPI -NTSTATUS -NTAPI -PcNewResourceList( - OUT PRESOURCELIST* OutResourceList, - IN PUNKNOWN OuterUnknown OPTIONAL, - IN POOL_TYPE PoolType, - IN PCM_RESOURCE_LIST TranslatedResourceList, - IN PCM_RESOURCE_LIST UntranslatedResourceList) -{ - PCM_RESOURCE_LIST NewUntranslatedResources, NewTranslatedResources; - ULONG NewTranslatedSize, NewUntranslatedSize, ResourceCount; - IResourceListImpl* NewList; - - if (!TranslatedResourceList) - { - /* if the untranslated resource list is also not provided, it becomes an empty resource list */ - if (UntranslatedResourceList) - { - /* invalid parameter mix */ - return STATUS_INVALID_PARAMETER; - } - } - else - { - /* if the translated resource list is also not provided, it becomes an empty resource list */ - if (!UntranslatedResourceList) - { - /* invalid parameter mix */ - return STATUS_INVALID_PARAMETER; - } - } - - /* allocate resource list ctx */ - NewList = AllocateItem(PoolType, sizeof(IResourceListImpl), TAG_PORTCLASS); - /* check for success */ - if (!NewList) - { - DPRINT("AllocateItem failed\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Initialize */ - NewList->lpVtbl = (IResourceListVtbl*)&vt_ResourceListVtbl; - NewList->ref = 1; - NewList->OuterUnknown = OuterUnknown; - NewList->PoolType = PoolType; - - if (!TranslatedResourceList || !UntranslatedResourceList) - { - /* empty resource list */ - *OutResourceList = (IResourceList*)&NewList->lpVtbl; - return STATUS_SUCCESS; - } - - /* calculate translated resource list size */ - ResourceCount = TranslatedResourceList->List[0].PartialResourceList.Count; - NewTranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); - - /* store resource count */ - NewList->NumberOfEntries = ResourceCount; - - /* calculate untranslated resouce list size */ - ResourceCount = UntranslatedResourceList->List[0].PartialResourceList.Count; - NewUntranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); - - /* allocate translated resource list */ - NewTranslatedResources = AllocateItem(PoolType, NewTranslatedSize, TAG_PORTCLASS); - if (!NewTranslatedResources) - { - FreeItem(NewList, TAG_PORTCLASS); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* allocate untranslated resource list */ - NewUntranslatedResources = AllocateItem(PoolType, NewUntranslatedSize, TAG_PORTCLASS); - if (!NewUntranslatedResources) - { - FreeItem(NewList, TAG_PORTCLASS); - FreeItem(NewTranslatedResources, TAG_PORTCLASS); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* copy resource lists */ - RtlCopyMemory(NewTranslatedResources, TranslatedResourceList, NewTranslatedSize); - RtlCopyMemory(NewUntranslatedResources, UntranslatedResourceList, NewUntranslatedSize); - - /* store resource lists */ - NewList->TranslatedResourceList= NewTranslatedResources; - NewList->UntranslatedResourceList = NewUntranslatedResources; - - /* Increment our usage count and set the pointer to this object */ - *OutResourceList = (IResourceList*)&NewList->lpVtbl; - - return STATUS_SUCCESS; -} - -PORTCLASSAPI -NTSTATUS -NTAPI -PcNewResourceSublist( - OUT PRESOURCELIST* OutResourceList, - IN PUNKNOWN OuterUnknown OPTIONAL, - IN POOL_TYPE PoolType, - IN PRESOURCELIST ParentList, - IN ULONG MaximumEntries) -{ - IResourceListImpl* NewList, *Parent; - - if (!OutResourceList || !ParentList || !MaximumEntries) - return STATUS_INVALID_PARAMETER; - - Parent = (IResourceListImpl*)ParentList; - - DPRINT("PcNewResourceSublist entered\n"); - - if (!Parent->TranslatedResourceList->List->PartialResourceList.Count || - !Parent->UntranslatedResourceList->List->PartialResourceList.Count) - { - /* parent list can't be empty */ - return STATUS_INVALID_PARAMETER; - } - - NewList = AllocateItem(PoolType, sizeof(IResourceListImpl), TAG_PORTCLASS); - if (!NewList) - return STATUS_INSUFFICIENT_RESOURCES; - - NewList->TranslatedResourceList = AllocateItem(PoolType, sizeof(CM_RESOURCE_LIST), TAG_PORTCLASS); - if (!NewList->TranslatedResourceList) - { - FreeItem(NewList, TAG_PORTCLASS); - return STATUS_INSUFFICIENT_RESOURCES; - } - - NewList->UntranslatedResourceList = AllocateItem(PoolType, sizeof(CM_RESOURCE_LIST), TAG_PORTCLASS); - if (!NewList->UntranslatedResourceList) - { - FreeItem(NewList->TranslatedResourceList, TAG_PORTCLASS); - FreeItem(NewList, TAG_PORTCLASS); - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlCopyMemory(NewList->TranslatedResourceList, Parent->TranslatedResourceList, sizeof(CM_RESOURCE_LIST)); - RtlCopyMemory(NewList->UntranslatedResourceList, Parent->UntranslatedResourceList, sizeof(CM_RESOURCE_LIST)); - - /* mark list as empty */ - NewList->TranslatedResourceList->List->PartialResourceList.Count = 0; - NewList->UntranslatedResourceList->List->PartialResourceList.Count = 0; - - NewList->lpVtbl = (IResourceListVtbl*)&vt_ResourceListVtbl; - NewList->ref = 1; - NewList->OuterUnknown = OuterUnknown; - NewList->PoolType = PoolType; - - *OutResourceList = (IResourceList*)&NewList->lpVtbl; - - DPRINT("PcNewResourceSublist OutResourceList %p OuterUnknown %p ParentList %p\n", *OutResourceList, OuterUnknown, ParentList); - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/resource.cpp b/reactos/drivers/wdm/audio/backpln/portcls/resource.cpp new file mode 100644 index 00000000000..347e8063697 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/resource.cpp @@ -0,0 +1,456 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS + * FILE: drivers/wdm/audio/backpln/portcls/resource.cpp + * PURPOSE: Port Class driver / ResourceList implementation + * PROGRAMMER: Andrew Greenwood + * Johannes Anderwald + * HISTORY: + * 27 Jan 07 Created + */ + +#include "private.hpp" + +class CResourceList : public IResourceList +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + + IMP_IResourceList; + CResourceList(IUnknown * OuterUnknown) {} + virtual ~CResourceList() {} + +public: + PUNKNOWN m_OuterUnknown; + POOL_TYPE m_PoolType; + PCM_RESOURCE_LIST m_TranslatedResourceList; + PCM_RESOURCE_LIST m_UntranslatedResourceList; + ULONG m_NumberOfEntries; + + LONG m_Ref; +}; + + +NTSTATUS +NTAPI +CResourceList::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + UNICODE_STRING GuidString; + + if (IsEqualGUIDAligned(refiid, IID_IResourceList) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PRESOURCELIST(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) + { + DPRINT1("IResourceList_QueryInterface no interface!!! iface %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + } + + return STATUS_UNSUCCESSFUL; +} + +ULONG +NTAPI +CResourceList::NumberOfEntries() +{ + // ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + return m_NumberOfEntries; +} + +ULONG +NTAPI +CResourceList::NumberOfEntriesOfType( + IN CM_RESOURCE_TYPE Type) +{ + ULONG Index, Count = 0; + PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_TranslatedResourceList) + { + // no resource list + return 0; + } + + // I guess the translated and untranslated lists will be same length? + for (Index = 0; Index < m_TranslatedResourceList->List[0].PartialResourceList.Count; Index ++ ) + { + PartialDescriptor = &m_TranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[Index]; + DPRINT("Descriptor Type %u\n", PartialDescriptor->Type); + if (PartialDescriptor->Type == Type) + { + // Yay! Finally found one that matches! + Count++; + } + } + + DPRINT("Found %d type %d\n", Count, Type); + return Count; +} + +PCM_PARTIAL_RESOURCE_DESCRIPTOR +NTAPI +CResourceList::FindTranslatedEntry( + IN CM_RESOURCE_TYPE Type, + IN ULONG Index) +{ + ULONG DescIndex, Count = 0; + PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_TranslatedResourceList) + { + // no resource list + return NULL; + } + + for (DescIndex = 0; DescIndex < m_TranslatedResourceList->List[0].PartialResourceList.Count; DescIndex ++ ) + { + PartialDescriptor = &m_TranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[DescIndex]; + + if (PartialDescriptor->Type == Type) + { + // Yay! Finally found one that matches! + if (Index == Count) + { + return PartialDescriptor; + } + Count++; + } + } + + return NULL; +} + +PCM_PARTIAL_RESOURCE_DESCRIPTOR +NTAPI +CResourceList::FindUntranslatedEntry( + IN CM_RESOURCE_TYPE Type, + IN ULONG Index) +{ + ULONG DescIndex, Count = 0; + PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + if (!m_UntranslatedResourceList) + { + // no resource list + return NULL; + } + + for (DescIndex = 0; DescIndex < m_UntranslatedResourceList->List[0].PartialResourceList.Count; DescIndex ++ ) + { + PartialDescriptor = &m_UntranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[DescIndex]; + + if (PartialDescriptor->Type == Type) + { + // Yay! Finally found one that matches! + if (Index == Count) + { + return PartialDescriptor; + } + Count++; + } + } + return NULL; +} + +NTSTATUS +NTAPI +CResourceList::AddEntry( + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Untranslated) +{ + PCM_RESOURCE_LIST NewUntranslatedResources, NewTranslatedResources; + ULONG NewTranslatedSize, NewUntranslatedSize, TranslatedSize, UntranslatedSize, ResourceCount; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + // calculate translated resource list size + ResourceCount = m_TranslatedResourceList->List[0].PartialResourceList.Count; +#ifdef _MSC_VER + NewTranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount+1]); + TranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); +#else + NewTranslatedSize = sizeof(CM_RESOURCE_LIST) + (ResourceCount > 0 ? (ResourceCount+1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) : 0); + TranslatedSize = sizeof(CM_RESOURCE_LIST) + (ResourceCount > 0 ? (ResourceCount) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) : 0); + +#endif + NewTranslatedResources = (PCM_RESOURCE_LIST)AllocateItem(m_PoolType, NewTranslatedSize, TAG_PORTCLASS); + if (!NewTranslatedResources) + return STATUS_INSUFFICIENT_RESOURCES; + + + // calculate untranslated resouce list size + ResourceCount = m_UntranslatedResourceList->List[0].PartialResourceList.Count; + +#ifdef _MSC_VER + NewUntranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount+1]); + UntranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); +#else + NewUntranslatedSize = sizeof(CM_RESOURCE_LIST) + (ResourceCount > 0 ? (ResourceCount+1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) : 0); + UntranslatedSize = sizeof(CM_RESOURCE_LIST) + (ResourceCount > 0 ? (ResourceCount) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) : 0); + +#endif + + + // allocate untranslated resource list size + NewUntranslatedResources = (PCM_RESOURCE_LIST)AllocateItem(m_PoolType, NewUntranslatedSize, TAG_PORTCLASS); + if (!NewUntranslatedResources) + { + FreeItem(NewTranslatedResources, TAG_PORTCLASS); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // now copy translated resource list + RtlMoveMemory(NewTranslatedResources, m_TranslatedResourceList, TranslatedSize); + RtlMoveMemory((PUCHAR)NewTranslatedResources + TranslatedSize, Translated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + + // now copy untranslated resource list + RtlMoveMemory(NewUntranslatedResources, m_UntranslatedResourceList, UntranslatedSize); + RtlMoveMemory((PUCHAR)NewUntranslatedResources + UntranslatedSize, Untranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + + // free old lists + FreeItem(m_TranslatedResourceList, TAG_PORTCLASS); + FreeItem(m_UntranslatedResourceList, TAG_PORTCLASS); + + // store new lists + m_UntranslatedResourceList = NewUntranslatedResources; + m_TranslatedResourceList = NewTranslatedResources; + + // increment descriptor count + NewUntranslatedResources->List[0].PartialResourceList.Count++; + NewTranslatedResources->List[0].PartialResourceList.Count++; + + // add entry count + m_NumberOfEntries++; + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CResourceList::AddEntryFromParent( + IN IResourceList* Parent, + IN CM_RESOURCE_TYPE Type, + IN ULONG Index) +{ + PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, Untranslated; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + Translated = Parent->FindTranslatedEntry(Type, Index); + Untranslated = Parent->FindUntranslatedEntry(Type, Index); + + if (Translated && Untranslated) + { + // add entry from parent + return AddEntry(Translated, Untranslated); + } + + // entry not found + return STATUS_INVALID_PARAMETER; +} + +PCM_RESOURCE_LIST +NTAPI +CResourceList::TranslatedList() +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + return m_TranslatedResourceList; +} + +PCM_RESOURCE_LIST +NTAPI +CResourceList::UntranslatedList() +{ + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + return m_UntranslatedResourceList; +} + + +PORTCLASSAPI +NTSTATUS +NTAPI +PcNewResourceList( + OUT PRESOURCELIST* OutResourceList, + IN PUNKNOWN OuterUnknown OPTIONAL, + IN POOL_TYPE PoolType, + IN PCM_RESOURCE_LIST TranslatedResourceList, + IN PCM_RESOURCE_LIST UntranslatedResourceList) +{ + PCM_RESOURCE_LIST NewUntranslatedResources, NewTranslatedResources; + ULONG NewTranslatedSize, NewUntranslatedSize, ResourceCount; + CResourceList* NewList; + NTSTATUS Status; + + if (!TranslatedResourceList) + { + // + // if the untranslated resource list is also not provided, it becomes an empty resource list + // + if (UntranslatedResourceList) + { + // invalid parameter mix + return STATUS_INVALID_PARAMETER; + } + } + else + { + // + // if the translated resource list is also not provided, it becomes an empty resource list + // + if (!UntranslatedResourceList) + { + // invalid parameter mix + return STATUS_INVALID_PARAMETER; + } + } + + NewList = new(PoolType, TAG_PORTCLASS)CResourceList(OuterUnknown); + if (!NewList) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = NewList->QueryInterface(IID_IResourceList, (PVOID*)OutResourceList); + + if (!NT_SUCCESS(Status)) + { + delete NewList; + } + + // calculate translated resource list size + ResourceCount = TranslatedResourceList->List[0].PartialResourceList.Count; +#ifdef _MSC_VER + NewTranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); +#else + NewTranslatedSize = sizeof(CM_RESOURCE_LIST) + (ResourceCount > 0 ? (ResourceCount-1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) : 0); +#endif + + // store resource count + NewList->m_NumberOfEntries = ResourceCount; + + // calculate untranslated resouce list size + ResourceCount = UntranslatedResourceList->List[0].PartialResourceList.Count; +#ifdef _MSC_VER + NewUntranslatedSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[ResourceCount]); +#else + NewUntranslatedSize = sizeof(CM_RESOURCE_LIST) + (ResourceCount > 0 ? (ResourceCount-1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) : 0); +#endif + + // allocate translated resource list + NewTranslatedResources = (PCM_RESOURCE_LIST)AllocateItem(PoolType, NewTranslatedSize, TAG_PORTCLASS); + if (!NewTranslatedResources) + { + FreeItem(NewList, TAG_PORTCLASS); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // allocate untranslated resource list + NewUntranslatedResources = (PCM_RESOURCE_LIST)AllocateItem(PoolType, NewUntranslatedSize, TAG_PORTCLASS); + if (!NewUntranslatedResources) + { + FreeItem(NewList, TAG_PORTCLASS); + FreeItem(NewTranslatedResources, TAG_PORTCLASS); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // copy resource lists + RtlCopyMemory(NewTranslatedResources, TranslatedResourceList, NewTranslatedSize); + RtlCopyMemory(NewUntranslatedResources, UntranslatedResourceList, NewUntranslatedSize); + + // store resource lists + NewList->m_TranslatedResourceList= NewTranslatedResources; + NewList->m_UntranslatedResourceList = NewUntranslatedResources; + + return STATUS_SUCCESS; +} + +PORTCLASSAPI +NTSTATUS +NTAPI +PcNewResourceSublist( + OUT PRESOURCELIST* OutResourceList, + IN PUNKNOWN OuterUnknown OPTIONAL, + IN POOL_TYPE PoolType, + IN PRESOURCELIST ParentList, + IN ULONG MaximumEntries) +{ + CResourceList* NewList, *Parent; + + if (!OutResourceList || !ParentList || !MaximumEntries) + return STATUS_INVALID_PARAMETER; + + Parent = (CResourceList*)ParentList; + + if (!Parent->m_TranslatedResourceList->List->PartialResourceList.Count || + !Parent->m_UntranslatedResourceList->List->PartialResourceList.Count) + { + // parent list can't be empty + return STATUS_INVALID_PARAMETER; + } + + NewList = new(PoolType, TAG_PORTCLASS) CResourceList(OuterUnknown); + if (!NewList) + return STATUS_INSUFFICIENT_RESOURCES; + + NewList->m_TranslatedResourceList = (PCM_RESOURCE_LIST)AllocateItem(PoolType, sizeof(CM_RESOURCE_LIST), TAG_PORTCLASS); + if (!NewList->m_TranslatedResourceList) + { + delete NewList; + return STATUS_INSUFFICIENT_RESOURCES; + } + + NewList->m_UntranslatedResourceList = (PCM_RESOURCE_LIST)AllocateItem(PoolType, sizeof(CM_RESOURCE_LIST), TAG_PORTCLASS); + if (!NewList->m_UntranslatedResourceList) + { + delete NewList; + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyMemory(NewList->m_TranslatedResourceList, Parent->m_TranslatedResourceList, sizeof(CM_RESOURCE_LIST)); + RtlCopyMemory(NewList->m_UntranslatedResourceList, Parent->m_UntranslatedResourceList, sizeof(CM_RESOURCE_LIST)); + + // mark list as empty + NewList->m_TranslatedResourceList->List->PartialResourceList.Count = 0; + NewList->m_UntranslatedResourceList->List->PartialResourceList.Count = 0; + // store members + NewList->m_OuterUnknown = OuterUnknown; + NewList->m_PoolType = PoolType; + NewList->m_Ref = 1; + + *OutResourceList = (IResourceList*)NewList; + + DPRINT("PcNewResourceSublist OutResourceList %p OuterUnknown %p ParentList %p\n", *OutResourceList, OuterUnknown, ParentList); + return STATUS_SUCCESS; +} + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/service_group.c b/reactos/drivers/wdm/audio/backpln/portcls/service_group.c deleted file mode 100644 index 7c73c44957e..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/service_group.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/service_group.c - * PURPOSE: ServiceGroup object implementation - * PROGRAMMER: Johannes Anderwald - */ - - -#include "private.h" - -typedef struct -{ - LIST_ENTRY Entry; - IN PSERVICESINK pServiceSink; -}GROUP_ENTRY, *PGROUP_ENTRY; - -typedef struct -{ - IServiceGroupVtbl *lpVtbl; - - LONG ref; - LIST_ENTRY ServiceSinkHead; - - BOOL Initialized; - BOOL TimerActive; - KTIMER Timer; - KDPC Dpc; - KEVENT Event; - LONG ThreadActive; -}IServiceGroupImpl; - - - -//--------------------------------------------------------------- -// IUnknown methods -// - - -NTSTATUS -NTAPI -IServiceGroup_fnQueryInterface( - IServiceGroup* iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - UNICODE_STRING GuidString; - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IServiceGroup) || - IsEqualGUIDAligned(refiid, &IID_IServiceSink) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - - if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) - { - DPRINT1("IServiceGroup_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); - RtlFreeUnicodeString(&GuidString); - } - - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IServiceGroup_fnAddRef( - IServiceGroup* iface) -{ - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IServiceGroup_fnRelease( - IServiceGroup* iface) -{ - PLIST_ENTRY CurEntry; - PGROUP_ENTRY Entry; - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - while(!IsListEmpty(&This->ServiceSinkHead)) - { - CurEntry = RemoveHeadList(&This->ServiceSinkHead); - Entry = CONTAINING_RECORD(CurEntry, GROUP_ENTRY, Entry); - Entry->pServiceSink->lpVtbl->Release(Entry->pServiceSink); - FreeItem(Entry, TAG_PORTCLASS); - } - KeCancelTimer(&This->Timer); - if (This->ThreadActive) - { - KeSetEvent(&This->Event, 0, TRUE); - } - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - - - -//--------------------------------------------------------------- -// IServiceSink methods -// - -VOID -NTAPI -IServiceGroup_fnRequestService( - IN IServiceGroup * iface) -{ - KIRQL OldIrql; - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - if (KeGetCurrentIrql() > DISPATCH_LEVEL) - { - KeInsertQueueDpc(&This->Dpc, NULL, NULL); - return; - } - - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - KeInsertQueueDpc(&This->Dpc, NULL, NULL); - KeLowerIrql(OldIrql); -} - -//--------------------------------------------------------------- -// IServiceGroup methods -// - -NTSTATUS -NTAPI -IServiceGroup_fnAddMember( - IN IServiceGroup * iface, - IN PSERVICESINK pServiceSink) -{ - PGROUP_ENTRY Entry; - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - Entry = AllocateItem(NonPagedPool, sizeof(GROUP_ENTRY), TAG_PORTCLASS); - if (!Entry) - return STATUS_INSUFFICIENT_RESOURCES; - - Entry->pServiceSink = pServiceSink; - pServiceSink->lpVtbl->AddRef(pServiceSink); - - InsertTailList(&This->ServiceSinkHead, &Entry->Entry); - - return STATUS_SUCCESS; -} - -VOID -NTAPI -IServiceGroup_fnRemoveMember( - IN IServiceGroup * iface, - IN PSERVICESINK pServiceSink) -{ - PLIST_ENTRY CurEntry; - PGROUP_ENTRY Entry; - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - - CurEntry = This->ServiceSinkHead.Flink; - while (CurEntry != &This->ServiceSinkHead) - { - Entry = CONTAINING_RECORD(CurEntry, GROUP_ENTRY, Entry); - if (Entry->pServiceSink == pServiceSink) - { - RemoveEntryList(&Entry->Entry); - pServiceSink->lpVtbl->Release(pServiceSink); - FreeItem(Entry, TAG_PORTCLASS); - return; - } - CurEntry = CurEntry->Flink; - } - -} - -VOID -NTAPI -IServiceGroupDpc( - IN struct _KDPC *Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2 - ) -{ - PLIST_ENTRY CurEntry; - PGROUP_ENTRY Entry; - IServiceGroupImpl * This = (IServiceGroupImpl*)DeferredContext; - - CurEntry = This->ServiceSinkHead.Flink; - while (CurEntry != &This->ServiceSinkHead) - { - Entry = CONTAINING_RECORD(CurEntry, GROUP_ENTRY, Entry); - Entry->pServiceSink->lpVtbl->RequestService(Entry->pServiceSink); - CurEntry = CurEntry->Flink; - } -} - - -VOID -NTAPI -ServiceGroupThread(IN PVOID StartContext) -{ - NTSTATUS Status; - KWAIT_BLOCK WaitBlockArray[2]; - PVOID WaitObjects[2]; - IServiceGroupImpl * This = (IServiceGroupImpl*)StartContext; - - /* Set thread state */ - InterlockedIncrement(&This->ThreadActive); - - /* Setup the wait objects */ - WaitObjects[0] = &This->Timer; - WaitObjects[1] = &This->Event; - - do - { - /* Wait on our objects */ - Status = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, Executive, KernelMode, FALSE, NULL, WaitBlockArray); - - switch(Status) - { - case STATUS_WAIT_0: - IServiceGroupDpc(&This->Dpc, (PVOID)This, NULL, NULL); - break; - case STATUS_WAIT_1: - PsTerminateSystemThread(STATUS_SUCCESS); - return; - } - }while(TRUE); -} - -VOID -NTAPI -IServiceGroup_fnSupportDelayedService( - IN IServiceGroup * iface) -{ - NTSTATUS Status; - HANDLE ThreadHandle; - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - ASSERT_IRQL(DISPATCH_LEVEL); - - if (This->Initialized) - return; - - KeInitializeTimerEx(&This->Timer, NotificationTimer); - - Status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, NULL, 0, NULL, ServiceGroupThread, (PVOID)This); - if (NT_SUCCESS(Status)) - { - ZwClose(ThreadHandle); - This->Initialized = TRUE; - } -} - -VOID -NTAPI -IServiceGroup_fnRequestDelayedService( - IN IServiceGroup * iface, - IN ULONGLONG ullDelay) -{ - LARGE_INTEGER DueTime; - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - ASSERT_IRQL(DISPATCH_LEVEL); - - DueTime.QuadPart = ullDelay; - - if (This->Initialized) - { - if (KeGetCurrentIrql() <= DISPATCH_LEVEL) - KeSetTimer(&This->Timer, DueTime, &This->Dpc); - else - KeInsertQueueDpc(&This->Dpc, NULL, NULL); - } -} - -VOID -NTAPI -IServiceGroup_fnCancelDelayedService( - IN IServiceGroup * iface) -{ - IServiceGroupImpl * This = (IServiceGroupImpl*)iface; - - ASSERT_IRQL(DISPATCH_LEVEL); - - if (This->Initialized) - { - KeCancelTimer(&This->Timer); - } -} - -static IServiceGroupVtbl vt_IServiceGroup = -{ - /* IUnknown methods */ - IServiceGroup_fnQueryInterface, - IServiceGroup_fnAddRef, - IServiceGroup_fnRelease, - IServiceGroup_fnRequestService, - IServiceGroup_fnAddMember, - IServiceGroup_fnRemoveMember, - IServiceGroup_fnSupportDelayedService, - IServiceGroup_fnRequestDelayedService, - IServiceGroup_fnCancelDelayedService -}; - -/* - * @implemented - */ -NTSTATUS NTAPI -PcNewServiceGroup( - OUT PSERVICEGROUP* OutServiceGroup, - IN PUNKNOWN OuterUnknown OPTIONAL) -{ - IServiceGroupImpl * This; - - DPRINT("PcNewServiceGroup entered\n"); - - This = AllocateItem(NonPagedPool, sizeof(IServiceGroupImpl), TAG_PORTCLASS); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - This->lpVtbl = &vt_IServiceGroup; - This->ref = 1; - KeInitializeDpc(&This->Dpc, IServiceGroupDpc, (PVOID)This); - KeSetImportanceDpc(&This->Dpc, HighImportance); - KeInitializeEvent(&This->Event, NotificationEvent, FALSE); - InitializeListHead(&This->ServiceSinkHead); - *OutServiceGroup = (PSERVICEGROUP)&This->lpVtbl; - - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/service_group.cpp b/reactos/drivers/wdm/audio/backpln/portcls/service_group.cpp new file mode 100644 index 00000000000..af71d2cccc8 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/service_group.cpp @@ -0,0 +1,319 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/service_group.cpp + * PURPOSE: ServiceGroup object implementation + * PROGRAMMER: Johannes Anderwald + */ + + +#include "private.hpp" + +VOID +NTAPI +IServiceGroupDpc( + IN struct _KDPC *Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 + ); + +typedef struct +{ + LIST_ENTRY Entry; + IN PSERVICESINK pServiceSink; +}GROUP_ENTRY, *PGROUP_ENTRY; + +class CServiceGroup : public IServiceGroup +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + + IMP_IServiceGroup; + CServiceGroup(IUnknown * OuterUnknown); + virtual ~CServiceGroup() {} + +protected: + + LIST_ENTRY m_ServiceSinkHead; + + BOOL m_Initialized; + BOOL m_TimerActive; + KTIMER m_Timer; + KDPC m_Dpc; + KEVENT m_Event; + LONG m_ThreadActive; + + friend VOID NTAPI IServiceGroupDpc(IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2); + + LONG m_Ref; + +}; + + + +//--------------------------------------------------------------- +// IUnknown methods +// + + +NTSTATUS +NTAPI +CServiceGroup::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + UNICODE_STRING GuidString; + + if (IsEqualGUIDAligned(refiid, IID_IServiceGroup) || + IsEqualGUIDAligned(refiid, IID_IServiceSink) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PSERVICEGROUP(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + + if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) + { + DPRINT1("CServiceGroup::QueryInterface no interface!!! iface %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + } + + return STATUS_UNSUCCESSFUL; +} +//--------------------------------------------------------------- +// IServiceSink methods +// + +CServiceGroup::CServiceGroup(IUnknown * OuterUnknown) +{ + KeInitializeDpc(&m_Dpc, IServiceGroupDpc, (PVOID)this); + KeSetImportanceDpc(&m_Dpc, HighImportance); + KeInitializeEvent(&m_Event, NotificationEvent, FALSE); + InitializeListHead(&m_ServiceSinkHead); +} + +VOID +NTAPI +CServiceGroup::RequestService() +{ + KIRQL OldIrql; + + if (KeGetCurrentIrql() > DISPATCH_LEVEL) + { + KeInsertQueueDpc(&m_Dpc, NULL, NULL); + return; + } + + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + KeInsertQueueDpc(&m_Dpc, NULL, NULL); + KeLowerIrql(OldIrql); +} + +//--------------------------------------------------------------- +// IServiceGroup methods +// + +NTSTATUS +NTAPI +CServiceGroup::AddMember( + IN PSERVICESINK pServiceSink) +{ + PGROUP_ENTRY Entry; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + Entry = (PGROUP_ENTRY)AllocateItem(NonPagedPool, sizeof(GROUP_ENTRY), TAG_PORTCLASS); + if (!Entry) + return STATUS_INSUFFICIENT_RESOURCES; + + Entry->pServiceSink = pServiceSink; + pServiceSink->AddRef(); + + InsertTailList(&m_ServiceSinkHead, &Entry->Entry); + + return STATUS_SUCCESS; +} + +VOID +NTAPI +CServiceGroup::RemoveMember( + IN PSERVICESINK pServiceSink) +{ + PLIST_ENTRY CurEntry; + PGROUP_ENTRY Entry; + + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + CurEntry = m_ServiceSinkHead.Flink; + while (CurEntry != &m_ServiceSinkHead) + { + Entry = CONTAINING_RECORD(CurEntry, GROUP_ENTRY, Entry); + if (Entry->pServiceSink == pServiceSink) + { + RemoveEntryList(&Entry->Entry); + pServiceSink->Release(); + FreeItem(Entry, TAG_PORTCLASS); + return; + } + CurEntry = CurEntry->Flink; + } + +} + +VOID +NTAPI +IServiceGroupDpc( + IN struct _KDPC *Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 + ) +{ + PLIST_ENTRY CurEntry; + PGROUP_ENTRY Entry; + CServiceGroup * This = (CServiceGroup*)DeferredContext; + + CurEntry = This->m_ServiceSinkHead.Flink; + while (CurEntry != &This->m_ServiceSinkHead) + { + Entry = (PGROUP_ENTRY)CONTAINING_RECORD(CurEntry, GROUP_ENTRY, Entry); + Entry->pServiceSink->RequestService(); + CurEntry = CurEntry->Flink; + } +} + + +#if 0 +VOID +NTAPI +ServiceGroupThread(IN PVOID StartContext) +{ + NTSTATUS Status; + KWAIT_BLOCK WaitBlockArray[2]; + PVOID WaitObjects[2]; + CServiceGroup * This = (CServiceGroup*)StartContext; + + // Set thread state + InterlockedIncrement(&This->m_ThreadActive); + + // Setup the wait objects + WaitObjects[0] = &m_Timer; + WaitObjects[1] = &m_Event; + + do + { + // Wait on our objects + Status = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, Executive, KernelMode, FALSE, NULL, WaitBlockArray); + + switch(Status) + { + case STATUS_WAIT_0: + IServiceGroupDpc(&This->m_Dpc, (PVOID)This, NULL, NULL); + break; + case STATUS_WAIT_1: + PsTerminateSystemThread(STATUS_SUCCESS); + return; + } + }while(TRUE); +} + +#endif +VOID +NTAPI +CServiceGroup::SupportDelayedService() +{ + //NTSTATUS Status; + //HANDLE ThreadHandle; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + if (m_Initialized) + return; + + KeInitializeTimerEx(&m_Timer, NotificationTimer); + +#if 0 + Status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, NULL, 0, NULL, ServiceGroupThread, (PVOID)This); + if (NT_SUCCESS(Status)) + { + ZwClose(ThreadHandle); + m_Initialized = TRUE; + } +#endif +} + +VOID +NTAPI +CServiceGroup::RequestDelayedService( + IN ULONGLONG ullDelay) +{ + LARGE_INTEGER DueTime; + + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + DueTime.QuadPart = ullDelay; + + if (m_Initialized) + { + if (KeGetCurrentIrql() <= DISPATCH_LEVEL) + KeSetTimer(&m_Timer, DueTime, &m_Dpc); + else + KeInsertQueueDpc(&m_Dpc, NULL, NULL); + } +} + +VOID +NTAPI +CServiceGroup::CancelDelayedService() +{ + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + if (m_Initialized) + { + KeCancelTimer(&m_Timer); + } +} + +NTSTATUS +NTAPI +PcNewServiceGroup( + OUT PSERVICEGROUP* OutServiceGroup, + IN PUNKNOWN OuterUnknown OPTIONAL) +{ + CServiceGroup * This; + NTSTATUS Status; + DPRINT("PcNewServiceGroup entered\n"); + + This = new(NonPagedPool, TAG_PORTCLASS)CServiceGroup(OuterUnknown); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = This->QueryInterface(IID_IServiceSink, (PVOID*)OutServiceGroup); + + if (!NT_SUCCESS(Status)) + { + delete This; + return Status; + } + + return Status; +} diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.c b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp similarity index 79% rename from reactos/drivers/wdm/audio/backpln/portcls/undoc.c rename to reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp index 4e3cc28a564..573ecb9b353 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -1,20 +1,13 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/api.c + * FILE: drivers/wdm/audio/backpln/portcls/api.cpp * PURPOSE: Port api functions * PROGRAMMER: Johannes Anderwald */ -/* - Undocumented PortCls exports -*/ +#include "private.hpp" -#include "private.h" - -/* - * @unimplemented - */ NTSTATUS NTAPI KsoDispatchCreateWithGenericFactory( @@ -25,23 +18,17 @@ KsoDispatchCreateWithGenericFactory( return STATUS_NOT_IMPLEMENTED; } -/* - * @implemented - */ IIrpTarget * NTAPI KsoGetIrpTargetFromFileObject( PFILE_OBJECT FileObject) { - ASSERT(FileObject); + PC_ASSERT(FileObject); - /* IrpTarget is stored in FsContext2 */ - return FileObject->FsContext2; + // IrpTarget is stored in FsContext2 + return (IIrpTarget*)FileObject->FsContext2; } -/* - * @implemented - */ IIrpTarget * NTAPI KsoGetIrpTargetFromIrp( @@ -49,16 +36,13 @@ KsoGetIrpTargetFromIrp( { PKSOBJECT_CREATE_ITEM CreateItem; - /* access the create item */ + // access the create item CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - /* IIrpTarget is stored in Context member */ - return CreateItem->Context; + // IIrpTarget is stored in Context member + return (IIrpTarget*)CreateItem->Context; } -/* - * @unimplemented - */ VOID NTAPI PcAcquireFormatResources( @@ -68,7 +52,6 @@ PcAcquireFormatResources( LONG Unknown4) { UNIMPLEMENTED; - return; } NTSTATUS @@ -126,7 +109,7 @@ AddToPropertyTable( if (FilterProperty->PropertiesCount) { - Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].PropertyItem = AllocateItem(NonPagedPool, + Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].PropertyItem = (const KSPROPERTY_ITEM*)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_ITEM) * FilterProperty->PropertiesCount, TAG_PORTCLASS); @@ -140,13 +123,13 @@ AddToPropertyTable( sizeof(KSPROPERTY_ITEM) * FilterProperty->PropertiesCount); } - Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set = AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS); + Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS); if (!Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set) return STATUS_INSUFFICIENT_RESOURCES; RtlCopyMemory((PVOID)Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set, FilterProperty->Set, sizeof(GUID)); - /* ignore fast io table for now */ + // ignore fast io table for now Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].FastIoCount = 0; Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].FastIoTable = NULL; @@ -155,9 +138,6 @@ AddToPropertyTable( return STATUS_SUCCESS; } -/* - * @unimplemented - */ NTSTATUS NTAPI PcCreateSubdeviceDescriptor( @@ -181,15 +161,15 @@ PcCreateSubdeviceDescriptor( PKSDATARANGE DataRange; NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; - Descriptor = AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS); + Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS); if (!Descriptor) return STATUS_INSUFFICIENT_RESOURCES; - Descriptor->Interfaces = AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS); + Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS); if (!Descriptor->Interfaces) goto cleanup; - /* copy interface guids */ + // copy interface guids RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount); Descriptor->InterfaceCount = InterfaceCount; @@ -197,7 +177,7 @@ PcCreateSubdeviceDescriptor( { /// FIXME /// handle driver properties - Descriptor->FilterPropertySet.Properties = AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS); + Descriptor->FilterPropertySet.Properties = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS); if (! Descriptor->FilterPropertySet.Properties) goto cleanup; @@ -210,13 +190,13 @@ PcCreateSubdeviceDescriptor( } } - Descriptor->Topology = AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); + Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); if (!Descriptor->Topology) goto cleanup; if (FilterDescription->ConnectionCount) { - Descriptor->Topology->TopologyConnections = AllocateItem(NonPagedPool, sizeof(PCCONNECTION_DESCRIPTOR) * FilterDescription->ConnectionCount, TAG_PORTCLASS); + Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS); if (!Descriptor->Topology->TopologyConnections) goto cleanup; @@ -226,11 +206,11 @@ PcCreateSubdeviceDescriptor( if (FilterDescription->NodeCount) { - Descriptor->Topology->TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); if (!Descriptor->Topology->TopologyNodes) goto cleanup; - Descriptor->Topology->TopologyNodesNames = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); if (!Descriptor->Topology->TopologyNodesNames) goto cleanup; @@ -250,31 +230,31 @@ PcCreateSubdeviceDescriptor( if (FilterDescription->PinCount) { - Descriptor->Factory.KsPinDescriptor = AllocateItem(NonPagedPool, FilterDescription->PinSize * FilterDescription->PinCount, TAG_PORTCLASS); + Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, FilterDescription->PinSize * FilterDescription->PinCount, TAG_PORTCLASS); if (!Descriptor->Factory.KsPinDescriptor) goto cleanup; - Descriptor->Factory.Instances = AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS); + Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS); if (!Descriptor->Factory.Instances) goto cleanup; Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount; Descriptor->Factory.PinDescriptorSize = FilterDescription->PinSize; - /* copy pin factories */ + // copy pin factories for(Index = 0; Index < FilterDescription->PinCount; Index++) { RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &FilterDescription->Pins[Index].KsPinDescriptor, FilterDescription->PinSize); if (FilterDescription->Pins[Index].KsPinDescriptor.DataRangesCount) { - Descriptor->Factory.KsPinDescriptor[Index].DataRanges = AllocateItem(NonPagedPool, FilterDescription->Pins[Index].KsPinDescriptor.DataRangesCount * sizeof(PKSDATARANGE), TAG_PORTCLASS); + Descriptor->Factory.KsPinDescriptor[Index].DataRanges = (const PKSDATARANGE*)AllocateItem(NonPagedPool, FilterDescription->Pins[Index].KsPinDescriptor.DataRangesCount * sizeof(PKSDATARANGE), TAG_PORTCLASS); if(!Descriptor->Factory.KsPinDescriptor[Index].DataRanges) goto cleanup; for (SubIndex = 0; SubIndex < FilterDescription->Pins[Index].KsPinDescriptor.DataRangesCount; SubIndex++) { - DataRange = AllocateItem(NonPagedPool, FilterDescription->Pins[Index].KsPinDescriptor.DataRanges[SubIndex]->FormatSize, TAG_PORTCLASS); + DataRange = (PKSDATARANGE)AllocateItem(NonPagedPool, FilterDescription->Pins[Index].KsPinDescriptor.DataRanges[SubIndex]->FormatSize, TAG_PORTCLASS); if (!DataRange) goto cleanup; @@ -313,10 +293,6 @@ cleanup: return Status; } -/* - * @implemented - */ - NTSTATUS NTAPI PcValidateConnectRequest( diff --git a/reactos/drivers/wdm/audio/backpln/portcls/unregister.c b/reactos/drivers/wdm/audio/backpln/portcls/unregister.cpp similarity index 53% rename from reactos/drivers/wdm/audio/backpln/portcls/unregister.c rename to reactos/drivers/wdm/audio/backpln/portcls/unregister.cpp index 62fb1169a18..3a90d5c945a 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/unregister.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/unregister.cpp @@ -1,71 +1,66 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/unregister.c + * FILE: drivers/wdm/audio/backpln/portcls/unregister.cpp * PURPOSE: Unregisters a subdevice * PROGRAMMER: Johannes Anderwald */ -#include "private.h" +#include "private.hpp" -typedef struct +class CUnregisterSubdevice : public IUnregisterSubdevice { - IUnregisterSubdeviceVtbl *lpVtbl; - LONG ref; +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); -}IUnregisterSubdeviceImpl; + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + + + IMP_IUnregisterSubdevice; + + CUnregisterSubdevice(IUnknown * OuterUnknown) : m_Ref(0) {} + virtual ~CUnregisterSubdevice(){} + +protected: + LONG m_Ref; + +}; NTSTATUS NTAPI -IUnregisterSubdevice_fnQueryInterface( - IUnregisterSubdevice* iface, +CUnregisterSubdevice::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IUnregisterSubdeviceImpl * This = (IUnregisterSubdeviceImpl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) + if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) { - *Output = &This->lpVtbl; - InterlockedIncrement(&This->ref); + *Output = PVOID(PUNREGISTERSUBDEVICE(this)); + PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } return STATUS_UNSUCCESSFUL; } -ULONG -NTAPI -IUnregisterSubdevice_fnAddRef( - IUnregisterSubdevice* iface) -{ - IUnregisterSubdeviceImpl * This = (IUnregisterSubdeviceImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IUnregisterSubdevice_fnRelease( - IUnregisterSubdevice* iface) -{ - IUnregisterSubdeviceImpl * This = (IUnregisterSubdeviceImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - return This->ref; -} - NTSTATUS NTAPI -IUnregisterSubdevice_fnUnregisterSubdevice( - IUnregisterSubdevice* iface, +CUnregisterSubdevice::UnregisterSubdevice( IN PDEVICE_OBJECT DeviceObject, IN PUNKNOWN Unknown) { @@ -78,7 +73,7 @@ IUnregisterSubdevice_fnUnregisterSubdevice( ULONG Index; NTSTATUS Status; - ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); #if defined(__GNUC__) && \ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ == 40400) @@ -87,20 +82,20 @@ IUnregisterSubdevice_fnUnregisterSubdevice( #endif DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - ASSERT(DeviceExtension); + PC_ASSERT(DeviceExtension); - /* look up our undocumented interface */ - Status = Unknown->lpVtbl->QueryInterface(Unknown, &IID_ISubdevice, (LPVOID)&SubDevice); + // look up our undocumented interface + Status = Unknown->QueryInterface(IID_ISubdevice, (LPVOID*)&SubDevice); if (!NT_SUCCESS(Status)) { DPRINT1("No ISubdevice interface\n"); - /* the provided port driver doesnt support ISubdevice */ + // the provided port driver doesnt support ISubdevice return STATUS_INVALID_PARAMETER; } Entry = DeviceExtension->SubDeviceList.Flink; Found = FALSE; - /* loop subdevice entry list and search for the subdevice */ + // loop subdevice entry list and search for the subdevice while(Entry != &DeviceExtension->SubDeviceList) { SubDeviceEntry = (PSUBDEVICE_ENTRY)CONTAINING_RECORD(Entry, SUBDEVICE_ENTRY, Entry); @@ -111,16 +106,16 @@ IUnregisterSubdevice_fnUnregisterSubdevice( } Entry = Entry->Flink; } - /* release the subdevice */ - SubDevice->lpVtbl->Release(SubDevice); + // release the subdevice + SubDevice->Release(); if (!Found) return STATUS_NOT_FOUND; - /* remove subdevice entry */ + // remove subdevice entry RemoveEntryList(&SubDeviceEntry->Entry); - /* loop our create items and disable the create handler */ + // loop our create items and disable the create handler for(Index = 0; Index < DeviceExtension->MaxSubDevices; Index++) { if (!RtlCompareUnicodeString(&SubDeviceEntry->Name, &DeviceExtension->CreateItems[Index].ObjectClass, TRUE)) @@ -131,48 +126,45 @@ IUnregisterSubdevice_fnUnregisterSubdevice( } } - /* now unregister device interfaces */ + // now unregister device interfaces while(!IsListEmpty(&SubDeviceEntry->SymbolicLinkList)) { - /* remove entry */ + // remove entry Entry = RemoveHeadList(&SubDeviceEntry->SymbolicLinkList); - /* get symlink entry */ + // get symlink entry SymLinkEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLICLINK_ENTRY, Entry); - /* unregister device interface */ + // unregister device interface IoSetDeviceInterfaceState(&SymLinkEntry->SymbolicLink, FALSE); - /* free symbolic link */ + // free symbolic link RtlFreeUnicodeString(&SymLinkEntry->SymbolicLink); - /* free sym entry */ + // free sym entry FreeItem(SymLinkEntry, TAG_PORTCLASS); } - /* free subdevice entry */ + // free subdevice entry ExFreePool(SubDeviceEntry); return STATUS_SUCCESS; } -static IUnregisterSubdeviceVtbl vt_IUnregisterSubdeviceVtbl = -{ - IUnregisterSubdevice_fnQueryInterface, - IUnregisterSubdevice_fnAddRef, - IUnregisterSubdevice_fnRelease, - IUnregisterSubdevice_fnUnregisterSubdevice -}; - NTSTATUS NTAPI NewIUnregisterSubdevice( OUT PUNREGISTERSUBDEVICE *OutDevice) { - IUnregisterSubdeviceImpl * This = AllocateItem(NonPagedPool, sizeof(IUnregisterSubdeviceImpl), TAG_PORTCLASS); + NTSTATUS Status; + CUnregisterSubdevice * This = new(NonPagedPool, TAG_PORTCLASS) CUnregisterSubdevice(NULL); if (!This) return STATUS_INSUFFICIENT_RESOURCES; - This->lpVtbl = &vt_IUnregisterSubdeviceVtbl; - This->ref = 1; + Status = This->QueryInterface(IID_IUnregisterSubdevice, (PVOID*)OutDevice); + if (!NT_SUCCESS(Status)) + { + delete This; + return Status; + } - *OutDevice = (PUNREGISTERSUBDEVICE)&This->lpVtbl; - return STATUS_SUCCESS; + *OutDevice = (PUNREGISTERSUBDEVICE)This; + return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/version.c b/reactos/drivers/wdm/audio/backpln/portcls/version.c deleted file mode 100644 index 4131b734ca6..00000000000 --- a/reactos/drivers/wdm/audio/backpln/portcls/version.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "private.h" - - -typedef struct -{ - IPortClsVersionVtbl *lpVtbl; - LONG ref; -}IPortClsVersionImpl; - - - -//--------------------------------------------------------------- -// IPortClsVersion interface functions -// - -NTSTATUS -NTAPI -IPortClsVersion_fnQueryInterface( - IPortClsVersion * iface, - IN REFIID refiid, - OUT PVOID* Output) -{ - IPortClsVersionImpl * This = (IPortClsVersionImpl*)iface; - - if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion) || - IsEqualGUIDAligned(refiid, &IID_IUnknown)) - { - *Output = &This->lpVtbl; - _InterlockedIncrement(&This->ref); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -ULONG -NTAPI -IPortClsVersion_fnAddRef( - IPortClsVersion * iface) -{ - IPortClsVersionImpl * This = (IPortClsVersionImpl*)iface; - - return InterlockedIncrement(&This->ref); -} - -ULONG -NTAPI -IPortClsVersion_fnRelease( - IPortClsVersion * iface) -{ - IPortClsVersionImpl * This = (IPortClsVersionImpl*)iface; - - InterlockedDecrement(&This->ref); - - if (This->ref == 0) - { - FreeItem(This, TAG_PORTCLASS); - return 0; - } - /* Return new reference count */ - return This->ref; -} - -DWORD -NTAPI -IPortClsVersion_fnGetVersion( - IPortClsVersion * iface) -{ - return kVersionWinXP_UAAQFE; -} - -static IPortClsVersionVtbl vt_PortClsVersion = -{ - /* IUnknown methods */ - IPortClsVersion_fnQueryInterface, - IPortClsVersion_fnAddRef, - IPortClsVersion_fnRelease, - IPortClsVersion_fnGetVersion -}; - -NTSTATUS NewPortClsVersion( - OUT PPORTCLSVERSION * OutVersion) -{ - IPortClsVersionImpl * This = AllocateItem(NonPagedPool, sizeof(IPortClsVersionImpl), TAG_PORTCLASS); - - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - This->lpVtbl = &vt_PortClsVersion; - This->ref = 1; - *OutVersion = (PPORTCLSVERSION)&This->lpVtbl; - - return STATUS_SUCCESS; - -} - - diff --git a/reactos/drivers/wdm/audio/backpln/portcls/version.cpp b/reactos/drivers/wdm/audio/backpln/portcls/version.cpp new file mode 100644 index 00000000000..6378e4944c2 --- /dev/null +++ b/reactos/drivers/wdm/audio/backpln/portcls/version.cpp @@ -0,0 +1,93 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/version.cpp + * PURPOSE: Implements IPortClsVersion interface + * PROGRAMMER: Johannes Anderwald + */ + + +#include "private.hpp" + + +class CPortClsVersion : public IPortClsVersion +{ +public: + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + + IMP_IPortClsVersion; + + CPortClsVersion(IUnknown *OuterUnknown) + { + m_Ref = 0; + } + virtual ~CPortClsVersion() + { + + } + +protected: + LONG m_Ref; + +}; + + + +//--------------------------------------------------------------- +// IPortClsVersion interface functions +// + +NTSTATUS +NTAPI +CPortClsVersion::QueryInterface( + IN REFIID refiid, + OUT PVOID* Output) +{ + if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion) || + IsEqualGUIDAligned(refiid, IID_IUnknown)) + { + *Output = PVOID(PPORTCLSVERSION(this)); + PUNKNOWN(*Output)->AddRef(); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +DWORD +NTAPI +CPortClsVersion::GetVersion() +{ + return kVersionWinXP_UAAQFE; +} + +NTSTATUS NewPortClsVersion( + OUT PPORTCLSVERSION * OutVersion) +{ + CPortClsVersion * This = new(NonPagedPool, TAG_PORTCLASS) CPortClsVersion(NULL); + + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->AddRef(); + + *OutVersion = (PPORTCLSVERSION)This; + + return STATUS_SUCCESS; +}