[MMIXER] Cleanup mixer notifications opened by an application when it is closed.

CORE-10735 #comment Please retest.

svn path=/trunk/; revision=75183
This commit is contained in:
Sylvain Deverre 2017-06-24 13:54:10 +00:00
parent 1f993d692c
commit 3e9107ceec
7 changed files with 120 additions and 11 deletions

View file

@ -166,11 +166,8 @@ WdmAudIoctlClose(
} }
else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE) else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
{ {
if (ClientInfo->hPins[Index].NotifyEvent) DPRINT1("Closing mixer %p\n", DeviceInfo->hDevice);
{ return WdmAudControlCloseMixer(DeviceObject, Irp, DeviceInfo, ClientInfo, Index);
ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent);
ClientInfo->hPins[Index].NotifyEvent = NULL;
}
} }
} }

View file

@ -471,6 +471,32 @@ WdmAudControlOpenMixer(
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 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 NTSTATUS
NTAPI NTAPI
WdmAudGetControlDetails( WdmAudGetControlDetails(

View file

@ -128,6 +128,14 @@ WdmAudControlOpenMixer(
IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo); 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 NTSTATUS
WdmAudControlOpenWave( WdmAudControlOpenWave(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,

View file

@ -1834,17 +1834,19 @@ MMixerAddEvent(
IN PMIXER_EVENT MixerEventRoutine) IN PMIXER_EVENT MixerEventRoutine)
{ {
//KSE_NODE Property; //KSE_NODE Property;
PEVENT_NOTIFICATION_ENTRY EventData; //KSEVENTDATA EventData
//ULONG BytesReturned; //ULONG BytesReturned;
//MIXER_STATUS Status; //MIXER_STATUS Status;
PEVENT_NOTIFICATION_ENTRY EventNotification;
EventData = (PEVENT_NOTIFICATION_ENTRY)MixerContext->AllocEventData(sizeof(EVENT_NOTIFICATION_ENTRY)); EventNotification = (PEVENT_NOTIFICATION_ENTRY)MixerContext->Alloc(sizeof(EVENT_NOTIFICATION_ENTRY));
if (!EventData) if (!EventNotification)
{ {
/* not enough memory */ /* not enough memory */
return MM_STATUS_NO_MEMORY; return MM_STATUS_NO_MEMORY;
} }
/* FIXME: what is it supposed to happen with KSEVENTDATA ? */
#if 0 #if 0
/* setup request */ /* setup request */
Property.Event.Set = KSEVENTSETID_AudioControlChange; Property.Event.Set = KSEVENTSETID_AudioControlChange;
@ -1864,10 +1866,39 @@ MMixerAddEvent(
#endif #endif
/* initialize notification entry */ /* initialize notification entry */
EventData->MixerEventContext = MixerEventContext; EventNotification->MixerEventContext = MixerEventContext;
EventData->MixerEventRoutine = MixerEventRoutine; EventNotification->MixerEventRoutine = MixerEventRoutine;
/* store event */ /* 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; return MM_STATUS_SUCCESS;
} }

View file

@ -112,6 +112,39 @@ MMixerOpen(
return MM_STATUS_SUCCESS; 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 MIXER_STATUS
MMixerGetLineInfo( MMixerGetLineInfo(
IN PMIXER_CONTEXT MixerContext, IN PMIXER_CONTEXT MixerContext,

View file

@ -146,6 +146,13 @@ MMixerOpen(
IN PMIXER_EVENT MixerEventRoutine, IN PMIXER_EVENT MixerEventRoutine,
OUT PHANDLE MixerHandle); OUT PHANDLE MixerHandle);
MIXER_STATUS
MMixerClose(
IN PMIXER_CONTEXT MixerContext,
IN ULONG MixerId,
IN PVOID MixerEventContext,
IN PMIXER_EVENT MixerEventRoutine);
MIXER_STATUS MIXER_STATUS
MMixerGetLineInfo( MMixerGetLineInfo(
IN PMIXER_CONTEXT MixerContext, IN PMIXER_CONTEXT MixerContext,

View file

@ -353,6 +353,13 @@ MMixerAddEvent(
IN PVOID MixerEvent, IN PVOID MixerEvent,
IN PMIXER_EVENT MixerEventRoutine); 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 MIXER_STATUS
MMixerGetDeviceName( MMixerGetDeviceName(
IN PMIXER_CONTEXT MixerContext, IN PMIXER_CONTEXT MixerContext,