[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)
{
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);
}
}

View file

@ -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(

View file

@ -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,

View file

@ -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;
}

View file

@ -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,

View file

@ -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,

View file

@ -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,