From 3e9107ceecf96beab7f480084c54467119979948 Mon Sep 17 00:00:00 2001 From: Sylvain Deverre Date: Sat, 24 Jun 2017 13:54:10 +0000 Subject: [PATCH] [MMIXER] Cleanup mixer notifications opened by an application when it is closed. CORE-10735 #comment Please retest. svn path=/trunk/; revision=75183 --- .../drivers/wdm/audio/legacy/wdmaud/control.c | 7 +-- .../drivers/wdm/audio/legacy/wdmaud/mmixer.c | 26 +++++++++++ .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 8 ++++ .../sdk/lib/drivers/sound/mmixer/controls.c | 43 ++++++++++++++++--- reactos/sdk/lib/drivers/sound/mmixer/mixer.c | 33 ++++++++++++++ reactos/sdk/lib/drivers/sound/mmixer/mmixer.h | 7 +++ .../sdk/lib/drivers/sound/mmixer/precomp.h | 7 +++ 7 files changed, 120 insertions(+), 11 deletions(-) diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index fcc66819577..f9ae9a32339 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -166,11 +166,8 @@ WdmAudIoctlClose( } else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE) { - if (ClientInfo->hPins[Index].NotifyEvent) - { - ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent); - ClientInfo->hPins[Index].NotifyEvent = NULL; - } + DPRINT1("Closing mixer %p\n", DeviceInfo->hDevice); + return WdmAudControlCloseMixer(DeviceObject, Irp, DeviceInfo, ClientInfo, Index); } } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c index 8623b5333ef..9887d0974a2 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c @@ -471,6 +471,32 @@ WdmAudControlOpenMixer( return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); } +NTSTATUS +WdmAudControlCloseMixer( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo, + IN ULONG Index) +{ + /* Remove event associated to this client */ + if (MMixerClose(&MixerContext, DeviceInfo->DeviceIndex, ClientInfo, EventCallback)) + { + DPRINT1("Failed to close mixer\n"); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); + } + + /* Dereference event */ + if (ClientInfo->hPins[Index].NotifyEvent) + { + ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent); + ClientInfo->hPins[Index].NotifyEvent = NULL; + } + + /* FIXME: do we need to free ClientInfo->hPins ? */ + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); +} + NTSTATUS NTAPI WdmAudGetControlDetails( diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 93310be3adb..04d8975b9ad 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -128,6 +128,14 @@ WdmAudControlOpenMixer( IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo); +NTSTATUS +WdmAudControlCloseMixer( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo, + IN ULONG Index); + NTSTATUS WdmAudControlOpenWave( IN PDEVICE_OBJECT DeviceObject, diff --git a/reactos/sdk/lib/drivers/sound/mmixer/controls.c b/reactos/sdk/lib/drivers/sound/mmixer/controls.c index 44fe5972eb1..376a443a7a8 100644 --- a/reactos/sdk/lib/drivers/sound/mmixer/controls.c +++ b/reactos/sdk/lib/drivers/sound/mmixer/controls.c @@ -1834,17 +1834,19 @@ MMixerAddEvent( IN PMIXER_EVENT MixerEventRoutine) { //KSE_NODE Property; - PEVENT_NOTIFICATION_ENTRY EventData; + //KSEVENTDATA EventData //ULONG BytesReturned; //MIXER_STATUS Status; + PEVENT_NOTIFICATION_ENTRY EventNotification; - EventData = (PEVENT_NOTIFICATION_ENTRY)MixerContext->AllocEventData(sizeof(EVENT_NOTIFICATION_ENTRY)); - if (!EventData) + EventNotification = (PEVENT_NOTIFICATION_ENTRY)MixerContext->Alloc(sizeof(EVENT_NOTIFICATION_ENTRY)); + if (!EventNotification) { /* not enough memory */ return MM_STATUS_NO_MEMORY; } + /* FIXME: what is it supposed to happen with KSEVENTDATA ? */ #if 0 /* setup request */ Property.Event.Set = KSEVENTSETID_AudioControlChange; @@ -1864,10 +1866,39 @@ MMixerAddEvent( #endif /* initialize notification entry */ - EventData->MixerEventContext = MixerEventContext; - EventData->MixerEventRoutine = MixerEventRoutine; + EventNotification->MixerEventContext = MixerEventContext; + EventNotification->MixerEventRoutine = MixerEventRoutine; /* store event */ - InsertTailList(&MixerInfo->EventList, &EventData->Entry); + InsertTailList(&MixerInfo->EventList, &EventNotification->Entry); + return MM_STATUS_SUCCESS; +} + +MIXER_STATUS +MMixerRemoveEvent( + IN PMIXER_CONTEXT MixerContext, + IN OUT LPMIXER_INFO MixerInfo, + IN PVOID MixerEventContext, + IN PMIXER_EVENT MixerEventRoutine) +{ + PLIST_ENTRY EventList; + PEVENT_NOTIFICATION_ENTRY NotificationEntry; + + /* Lookup through mixers */ + EventList = MixerInfo->EventList.Flink; + while(EventList != &MixerInfo->EventList) + { + NotificationEntry = CONTAINING_RECORD(EventList, EVENT_NOTIFICATION_ENTRY, Entry); + EventList = EventList->Flink; + /* TODO: find a better way to identify an event ? */ + if(NotificationEntry->MixerEventRoutine == MixerEventRoutine && + NotificationEntry->MixerEventContext == MixerEventContext) + { + DPRINT1("Freeing entry %p\n", NotificationEntry); + /* We found the event to remove */ + RemoveEntryList(&NotificationEntry->Entry); + MixerContext->Free(NotificationEntry); + } + } return MM_STATUS_SUCCESS; } diff --git a/reactos/sdk/lib/drivers/sound/mmixer/mixer.c b/reactos/sdk/lib/drivers/sound/mmixer/mixer.c index b9335ba59e7..3b8d900bef6 100644 --- a/reactos/sdk/lib/drivers/sound/mmixer/mixer.c +++ b/reactos/sdk/lib/drivers/sound/mmixer/mixer.c @@ -112,6 +112,39 @@ MMixerOpen( return MM_STATUS_SUCCESS; } +MIXER_STATUS +MMixerClose( + IN PMIXER_CONTEXT MixerContext, + IN ULONG MixerId, + IN PVOID MixerEventContext, + IN PMIXER_EVENT MixerEventRoutine) +{ + MIXER_STATUS Status; + LPMIXER_INFO MixerInfo; + + /* verify mixer context */ + Status = MMixerVerifyContext(MixerContext); + + if (Status != MM_STATUS_SUCCESS) + { + /* invalid context passed */ + DPRINT1("invalid context\n"); + return Status; + } + + /* get mixer info */ + MixerInfo = MMixerGetMixerInfoByIndex(MixerContext, MixerId); + if (!MixerInfo) + { + /* invalid mixer id */ + DPRINT1("invalid mixer id %lu\n", MixerId); + return MM_STATUS_INVALID_PARAMETER; + } + + /* remove event from list */ + return MMixerRemoveEvent(MixerContext, MixerInfo, MixerEventContext, MixerEventRoutine); +} + MIXER_STATUS MMixerGetLineInfo( IN PMIXER_CONTEXT MixerContext, diff --git a/reactos/sdk/lib/drivers/sound/mmixer/mmixer.h b/reactos/sdk/lib/drivers/sound/mmixer/mmixer.h index 5cd530abffa..7d88125ce36 100644 --- a/reactos/sdk/lib/drivers/sound/mmixer/mmixer.h +++ b/reactos/sdk/lib/drivers/sound/mmixer/mmixer.h @@ -146,6 +146,13 @@ MMixerOpen( IN PMIXER_EVENT MixerEventRoutine, OUT PHANDLE MixerHandle); +MIXER_STATUS +MMixerClose( + IN PMIXER_CONTEXT MixerContext, + IN ULONG MixerId, + IN PVOID MixerEventContext, + IN PMIXER_EVENT MixerEventRoutine); + MIXER_STATUS MMixerGetLineInfo( IN PMIXER_CONTEXT MixerContext, diff --git a/reactos/sdk/lib/drivers/sound/mmixer/precomp.h b/reactos/sdk/lib/drivers/sound/mmixer/precomp.h index c03adceac55..4ffc3f7129b 100644 --- a/reactos/sdk/lib/drivers/sound/mmixer/precomp.h +++ b/reactos/sdk/lib/drivers/sound/mmixer/precomp.h @@ -353,6 +353,13 @@ MMixerAddEvent( IN PVOID MixerEvent, IN PMIXER_EVENT MixerEventRoutine); +MIXER_STATUS +MMixerRemoveEvent( + IN PMIXER_CONTEXT MixerContext, + IN OUT LPMIXER_INFO MixerInfo, + IN PVOID MixerEventContext, + IN PMIXER_EVENT MixerEventRoutine); + MIXER_STATUS MMixerGetDeviceName( IN PMIXER_CONTEXT MixerContext, -- 2.17.1