diff --git a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c b/reactos/drivers/wdm/audio/backpln/portcls/adapter.c index c420d69083a..12e11b0f32e 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/adapter.c @@ -91,7 +91,7 @@ PcAddAdapterDevice( NTSTATUS status = STATUS_UNSUCCESSFUL; PDEVICE_OBJECT fdo = NULL; PDEVICE_OBJECT PrevDeviceObject; - PPCLASS_DEVICE_EXTENSION portcls_ext; + PPCLASS_DEVICE_EXTENSION portcls_ext = NULL; DPRINT1("PcAddAdapterDevice called\n"); @@ -138,8 +138,8 @@ PcAddAdapterDevice( if (!portcls_ext->CreateItems) { /* not enough resources */ - IoDeleteDevice(fdo); - return STATUS_INSUFFICIENT_RESOURCES; + status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; } /* store the physical device object */ @@ -157,32 +157,41 @@ PcAddAdapterDevice( fdo->Flags &= ~ DO_DEVICE_INITIALIZING; /* allocate work item */ - portcls_ext->WorkItem = IoAllocateWorkItem(fdo); + portcls_ext->CloseWorkItem = IoAllocateWorkItem(fdo); - if (!portcls_ext->WorkItem) + if (!portcls_ext->CloseWorkItem) { /* not enough resources */ - FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); - /* delete created fdo */ - IoDeleteDevice(fdo); - /* return error code */ - return STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + status = STATUS_INSUFFICIENT_RESOURCES; } + /* allocate work item */ + portcls_ext->StartWorkItem = IoAllocateWorkItem(fdo); + + if (!portcls_ext->StartWorkItem) + { + /* not enough resources */ + goto cleanup; + status = STATUS_INSUFFICIENT_RESOURCES; + } + + /* allocate work item */ + portcls_ext->StopWorkItem = IoAllocateWorkItem(fdo); + + if (!portcls_ext->StopWorkItem) + { + /* not enough resources */ + goto cleanup; + status = STATUS_INSUFFICIENT_RESOURCES; + } /* allocate the device header */ status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems); /* did we succeed */ if (!NT_SUCCESS(status)) { - /* free previously allocated create items */ - FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); - /* free allocated work item */ - IoFreeWorkItem(portcls_ext->WorkItem); - /* delete created fdo */ - IoDeleteDevice(fdo); - /* return error code */ - return status; + goto cleanup; } /* attach device to device stack */ @@ -196,16 +205,52 @@ PcAddAdapterDevice( } else { - /* free the device header */ - KsFreeDeviceHeader(portcls_ext->KsDeviceHeader); - /* free previously allocated create items */ - FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); - /* free allocated work item */ - IoFreeWorkItem(portcls_ext->WorkItem); + /* return error code */ + status = STATUS_UNSUCCESSFUL; + goto cleanup; + } + return status; + +cleanup: + + if (portcls_ext) + { + + if (portcls_ext->KsDeviceHeader) + { + /* free the device header */ + KsFreeDeviceHeader(portcls_ext->KsDeviceHeader); + } + + if (portcls_ext->CloseWorkItem) + { + /* free allocated work item */ + IoFreeWorkItem(portcls_ext->CloseWorkItem); + } + + if (portcls_ext->StartWorkItem) + { + /* free allocated work item */ + IoFreeWorkItem(portcls_ext->StartWorkItem); + } + + if (portcls_ext->StopWorkItem) + { + /* free allocated work item */ + IoFreeWorkItem(portcls_ext->StopWorkItem); + } + + if (portcls_ext->CreateItems) + { + /* free previously allocated create items */ + FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); + } + } + + if (fdo) + { /* delete created fdo */ IoDeleteDevice(fdo); - /* return error code */ - return STATUS_UNSUCCESSFUL; } return status; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c index 068ccee74d0..eb81969c692 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.c @@ -405,6 +405,9 @@ IDmaChannelSlave_fnStop( This->DmaStarted = FALSE; + IoFreeMdl(This->Mdl); + This->Mdl = NULL; + 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 index 04559a0e66f..f0649f0818f 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c @@ -113,6 +113,7 @@ IPortFilterWaveCyclic_fnNewIrpTarget( 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); } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c index 84e939ebdb1..d2d226695be 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c @@ -199,12 +199,18 @@ StopStreamWorkerRoutine( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { + PPCLASS_DEVICE_EXTENSION DeviceExtension; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context; - DPRINT1("Stopping %u Irql %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql()); - + /* Set the state to stop */ This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); + /* Set internal state to stop */ This->State = KSSTATE_STOP; + + /* Get device extension */ + DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + DPRINT1("Stopping %u Irql %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql()); } VOID @@ -219,15 +225,24 @@ StopStreamRoutine( PPCLASS_DEVICE_EXTENSION DeviceExtension; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext; + ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + /* Has the audio stream resumed? */ if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue)) return; + /* Has the audio stream already stopped */ + if (This->State == KSSTATE_STOP) + return; + /* Get device object */ DeviceObject = GetDeviceObject(This->Port); + /* Get device extension */ DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* queue the work item */ - IoQueueWorkItem(DeviceExtension->WorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This); + IoQueueWorkItem(DeviceExtension->StopWorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This); } static @@ -696,23 +711,18 @@ IPortPinWaveCyclic_fnClose( if (This->Stream) { - if (Irp) - { - This->CloseIrp = Irp; - IoMarkIrpPending(Irp); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_PENDING; - } /* Get device extension */ DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - /* defer work item */ - IoQueueWorkItem(DeviceExtension->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This); - if (Irp) - { - /* The WaveCyclic filter passes close request with NULL / IRP */ - return STATUS_PENDING; - } + This->CloseIrp = Irp; + IoMarkIrpPending(Irp); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_PENDING; + + /* defer work item */ + IoQueueWorkItem(DeviceExtension->CloseWorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This); + /* Return result */ + return STATUS_PENDING; } if (Irp) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c index d83913d612a..6b9c31e310c 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c @@ -602,8 +602,7 @@ PcCreateItemDispatch( Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_PENDING; IoMarkIrpPending(Irp); - IoQueueWorkItem(DeviceExt->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); - + IoQueueWorkItem(DeviceExt->StartWorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); return STATUS_PENDING; } } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.h b/reactos/drivers/wdm/audio/backpln/portcls/private.h index 65b1edf376d..dc9c97f8bb1 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.h @@ -156,7 +156,10 @@ typedef struct ULONG MaxSubDevices; KSOBJECT_CREATE_ITEM * CreateItems; - PIO_WORKITEM WorkItem; + PIO_WORKITEM StartWorkItem; + PIO_WORKITEM StopWorkItem; + PIO_WORKITEM CloseWorkItem; + IResourceList* resources; LIST_ENTRY SubDeviceList; LIST_ENTRY PhysicalConnectionList; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/resource.c b/reactos/drivers/wdm/audio/backpln/portcls/resource.c index bac7095fc7d..c8f3eaff2a6 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/resource.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/resource.c @@ -29,7 +29,7 @@ typedef struct CResourceList */ NTSTATUS -STDMETHODCALLTYPE +NTAPI IResourceList_fnQueryInterface( IResourceList* iface, IN REFIID refiid, @@ -56,7 +56,7 @@ IResourceList_fnQueryInterface( } ULONG -STDMETHODCALLTYPE +NTAPI IResourceList_fnAddRef( IResourceList* iface) { @@ -66,7 +66,7 @@ IResourceList_fnAddRef( } ULONG -STDMETHODCALLTYPE +NTAPI IResourceList_fnRelease( IResourceList* iface) { @@ -93,7 +93,7 @@ IResourceList_fnRelease( */ ULONG -STDMETHODCALLTYPE +NTAPI IResourceList_fnNumberOfEntries(IResourceList* iface) { IResourceListImpl * This = (IResourceListImpl*)iface; @@ -102,7 +102,7 @@ IResourceList_fnNumberOfEntries(IResourceList* iface) } ULONG -STDMETHODCALLTYPE +NTAPI IResourceList_fnNumberOfEntriesOfType( IResourceList* iface, IN CM_RESOURCE_TYPE Type) @@ -129,7 +129,7 @@ IResourceList_fnNumberOfEntriesOfType( } PCM_PARTIAL_RESOURCE_DESCRIPTOR -STDMETHODCALLTYPE +NTAPI IResourceList_fnFindTranslatedEntry( IResourceList* iface, IN CM_RESOURCE_TYPE Type, @@ -158,7 +158,7 @@ IResourceList_fnFindTranslatedEntry( } PCM_PARTIAL_RESOURCE_DESCRIPTOR -STDMETHODCALLTYPE +NTAPI IResourceList_fnFindUntranslatedEntry( IResourceList* iface, IN CM_RESOURCE_TYPE Type, @@ -186,7 +186,7 @@ IResourceList_fnFindUntranslatedEntry( } NTSTATUS -STDMETHODCALLTYPE +NTAPI IResourceList_fnAddEntry( IResourceList* iface, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated, @@ -242,7 +242,7 @@ IResourceList_fnAddEntry( } NTSTATUS -STDMETHODCALLTYPE +NTAPI IResourceList_fnAddEntryFromParent( IResourceList* iface, IN IResourceList* Parent, @@ -281,7 +281,7 @@ IResourceList_fnAddEntryFromParent( } PCM_RESOURCE_LIST -STDMETHODCALLTYPE +NTAPI IResourceList_fnTranslatedList( IResourceList* iface) { @@ -291,7 +291,7 @@ IResourceList_fnTranslatedList( } PCM_RESOURCE_LIST -STDMETHODCALLTYPE +NTAPI IResourceList_fnUntranslatedList( IResourceList* iface) { @@ -325,7 +325,9 @@ static const IResourceListVtbl vt_ResourceListVtbl = /* Factory for creating a resource list */ -PORTCLASSAPI NTSTATUS NTAPI +PORTCLASSAPI +NTSTATUS +NTAPI PcNewResourceList( OUT PRESOURCELIST* OutResourceList, IN PUNKNOWN OuterUnknown OPTIONAL, @@ -339,8 +341,6 @@ PcNewResourceList( /* TODO: Validate parameters */ - DPRINT("PcNewResourceList\n"); - NewList = AllocateItem(PoolType, sizeof(IResourceListImpl), TAG_PORTCLASS); if (!NewList)