mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 16:10:29 +00:00
- Allocate work item for each filter / pin being opened
- Use ExInterlockedInsertTailList to insert a new audio device to prevent race conditions when more than one audio device is present - Free work item in their target worker routine svn path=/trunk/; revision=40646
This commit is contained in:
parent
7a75a5802f
commit
67f6e0572a
4 changed files with 118 additions and 69 deletions
|
@ -236,6 +236,8 @@ CreatePinWorkerRoutine(
|
|||
{
|
||||
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
|
||||
ExFreePool(WorkerContext->DispatchContext);
|
||||
IoFreeWorkItem(WorkerContext->WorkItem);
|
||||
ExFreePool(WorkerContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -252,6 +254,8 @@ CreatePinWorkerRoutine(
|
|||
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
|
||||
ExFreePool(WorkerContext->DispatchContext);
|
||||
ExFreePool(MixerPinConnect);
|
||||
IoFreeWorkItem(WorkerContext->WorkItem);
|
||||
ExFreePool(WorkerContext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -391,9 +395,10 @@ CreatePinWorkerRoutine(
|
|||
*((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
|
||||
|
||||
SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE));
|
||||
IoFreeWorkItem(WorkerContext->WorkItem);
|
||||
ExFreePool(WorkerContext);
|
||||
return;
|
||||
|
||||
|
||||
cleanup:
|
||||
if (RealFileObject)
|
||||
ObDereferenceObject(RealFileObject);
|
||||
|
@ -410,7 +415,8 @@ cleanup:
|
|||
|
||||
ExFreePool(WorkerContext->DispatchContext);
|
||||
SetIrpIoStatus(WorkerContext->Irp, Status, 0);
|
||||
|
||||
IoFreeWorkItem(WorkerContext->WorkItem);
|
||||
ExFreePool(WorkerContext);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -722,8 +728,7 @@ HandleSysAudioFilterPinCreation(
|
|||
KSPIN_CINSTANCES PinInstances;
|
||||
PPIN_WORKER_CONTEXT WorkerContext;
|
||||
PDISPATCH_CONTEXT DispatchContext;
|
||||
|
||||
|
||||
PIO_WORKITEM WorkItem;
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
|
@ -806,10 +811,7 @@ HandleSysAudioFilterPinCreation(
|
|||
}
|
||||
}
|
||||
|
||||
ASSERT(DeviceExtension->WorkItem);
|
||||
ASSERT(DeviceExtension->WorkerContext);
|
||||
|
||||
/* create worker context */
|
||||
/* create dispatch pin context */
|
||||
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
|
||||
if (!DispatchContext)
|
||||
{
|
||||
|
@ -817,11 +819,24 @@ HandleSysAudioFilterPinCreation(
|
|||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// mutal exclusion
|
||||
/* allocate worker context */
|
||||
WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
|
||||
if (!WorkerContext)
|
||||
{
|
||||
/* no memory */
|
||||
ExFreePool(DispatchContext);
|
||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||
}
|
||||
|
||||
/* get worker context */
|
||||
WorkerContext = (PPIN_WORKER_CONTEXT)DeviceExtension->WorkerContext;
|
||||
/* allocate work item */
|
||||
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||
if (!WorkerContext)
|
||||
{
|
||||
/* no memory */
|
||||
ExFreePool(DispatchContext);
|
||||
ExFreePool(WorkerContext);
|
||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||
}
|
||||
|
||||
/* prepare context */
|
||||
RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT));
|
||||
|
@ -841,13 +856,14 @@ HandleSysAudioFilterPinCreation(
|
|||
WorkerContext->PinConnect = PinConnect;
|
||||
WorkerContext->AudioClient = ClientInfo;
|
||||
WorkerContext->DeviceExtension = DeviceExtension;
|
||||
WorkerContext->WorkItem = WorkItem;
|
||||
|
||||
DPRINT("Queing Irp %p\n", Irp);
|
||||
/* queue the work item */
|
||||
IoMarkIrpPending(Irp);
|
||||
Irp->IoStatus.Status = STATUS_PENDING;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoQueueWorkItem(DeviceExtension->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)WorkerContext);
|
||||
IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)WorkerContext);
|
||||
|
||||
/* mark irp as pending */
|
||||
return STATUS_PENDING;
|
||||
|
|
|
@ -28,7 +28,10 @@ FilterPinWorkerRoutine(
|
|||
NTSTATUS Status;
|
||||
ULONG BytesReturned;
|
||||
PSYSAUDIODEVEXT DeviceExtension;
|
||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)Context;
|
||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
|
||||
PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context;
|
||||
|
||||
DeviceEntry = Ctx->DeviceEntry;
|
||||
|
||||
|
||||
DPRINT("Querying filter...\n");
|
||||
|
@ -42,21 +45,13 @@ FilterPinWorkerRoutine(
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to query number of pins Status %x\n", Status);
|
||||
ObDereferenceObject(DeviceEntry->FileObject);
|
||||
ZwClose(DeviceEntry->Handle);
|
||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||
ExFreePool(DeviceEntry);
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!Count)
|
||||
{
|
||||
DPRINT1("Filter has no pins!\n");
|
||||
ObDereferenceObject(DeviceEntry->FileObject);
|
||||
ZwClose(DeviceEntry->Handle);
|
||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||
ExFreePool(DeviceEntry);
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* allocate pin array */
|
||||
|
@ -65,11 +60,7 @@ FilterPinWorkerRoutine(
|
|||
{
|
||||
/* no memory */
|
||||
DPRINT1("Failed to allocate memory Block %x\n", Count * sizeof(PIN_INFO));
|
||||
ObDereferenceObject(DeviceEntry->FileObject);
|
||||
ZwClose(DeviceEntry->Handle);
|
||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||
ExFreePool(DeviceEntry);
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
/* clear array */
|
||||
RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count);
|
||||
|
@ -114,12 +105,27 @@ FilterPinWorkerRoutine(
|
|||
}
|
||||
|
||||
DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, DeviceEntry->NumWaveInPin, DeviceEntry->NumWaveOutPin);
|
||||
|
||||
/* fetch device extension */
|
||||
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
|
||||
/* insert new audio device */
|
||||
ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock);
|
||||
/* increment audio device count */
|
||||
InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices);
|
||||
|
||||
InsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry);
|
||||
DeviceExtension->NumberOfKsAudioDevices++;
|
||||
/* free work item */
|
||||
IoFreeWorkItem(Ctx->WorkItem);
|
||||
/* free work item context */
|
||||
ExFreePool(Ctx);
|
||||
return;
|
||||
|
||||
cleanup:
|
||||
|
||||
ObDereferenceObject(DeviceEntry->FileObject);
|
||||
ZwClose(DeviceEntry->Handle);
|
||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||
ExFreePool(DeviceEntry);
|
||||
IoFreeWorkItem(Ctx->WorkItem);
|
||||
ExFreePool(Ctx);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -177,7 +183,9 @@ DeviceInterfaceChangeCallback(
|
|||
DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PSYSAUDIODEVEXT DeviceExtension;
|
||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
|
||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL;
|
||||
PIO_WORKITEM WorkItem = NULL;
|
||||
PFILTER_WORKER_CONTEXT Ctx = NULL;
|
||||
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
|
||||
|
||||
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
|
||||
|
@ -191,48 +199,67 @@ DeviceInterfaceChangeCallback(
|
|||
DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
|
||||
if (!DeviceEntry)
|
||||
{
|
||||
|
||||
/* no memory */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* initialize audio device entry */
|
||||
RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY));
|
||||
|
||||
/* allocate filter ctx */
|
||||
Ctx = ExAllocatePool(NonPagedPool, sizeof(FILTER_WORKER_CONTEXT));
|
||||
if (!Ctx)
|
||||
{
|
||||
/* no memory */
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* allocate work item */
|
||||
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||
if (!WorkItem)
|
||||
{
|
||||
/* no memory */
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* set device name */
|
||||
DeviceEntry->DeviceName.Length = 0;
|
||||
DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR);
|
||||
DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
|
||||
|
||||
if (!DeviceEntry->DeviceName.Buffer)
|
||||
{
|
||||
ExFreePool(DeviceEntry);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\")))
|
||||
{
|
||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||
ExFreePool(DeviceEntry);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
DPRINT1("RtlAppendUnicodeToString failed with %x\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName)))
|
||||
{
|
||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||
ExFreePool(DeviceEntry);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
DPRINT1("RtlAppendUnicodeStringToString failed with %x\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateFile failed with %x\n", Status);
|
||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||
ExFreePool(DeviceEntry);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DPRINT("Successfully opened audio device %u handle %p file object %p device object %p\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->Handle, DeviceEntry->FileObject, DeviceEntry->FileObject->DeviceObject);
|
||||
|
||||
//FIXME
|
||||
// mutal exclusion
|
||||
IoQueueWorkItem(DeviceExtension->WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)DeviceEntry);
|
||||
Ctx->DeviceEntry = DeviceEntry;
|
||||
Ctx->WorkItem = WorkItem;
|
||||
|
||||
IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx);
|
||||
return Status;
|
||||
}
|
||||
else
|
||||
|
@ -241,6 +268,23 @@ DeviceInterfaceChangeCallback(
|
|||
UNIMPLEMENTED
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (Ctx)
|
||||
ExFreePool(Ctx);
|
||||
|
||||
if (WorkItem)
|
||||
IoFreeWorkItem(WorkItem);
|
||||
|
||||
if (DeviceEntry)
|
||||
{
|
||||
if (DeviceEntry->DeviceName.Buffer)
|
||||
ExFreePool(DeviceEntry->DeviceName.Buffer);
|
||||
|
||||
ExFreePool(DeviceEntry);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -118,7 +118,7 @@ SysAudio_InstallDevice(
|
|||
RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
|
||||
|
||||
/* Initialize the mutex */
|
||||
KeInitializeMutex(&DeviceExtension->Mutex, 0);
|
||||
KeInitializeSpinLock(&DeviceExtension->Lock);
|
||||
|
||||
/* Initialize the ks audio device list */
|
||||
InitializeListHead(&DeviceExtension->KsAudioDeviceList);
|
||||
|
@ -131,22 +131,6 @@ SysAudio_InstallDevice(
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
/* allocate work item */
|
||||
DeviceExtension->WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||
if (!DeviceExtension->WorkItem)
|
||||
{
|
||||
DPRINT1("Failed to allocate work item\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* allocate work item context */
|
||||
DeviceExtension->WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
|
||||
if (!DeviceExtension->WorkerContext)
|
||||
{
|
||||
DPRINT1("Failed to allocate work item context\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Register device notification hooks */
|
||||
Status = SysAudioRegisterNotifications(DriverObject,
|
||||
DeviceObject);
|
||||
|
|
|
@ -70,14 +70,11 @@ typedef struct
|
|||
LIST_ENTRY KsAudioDeviceList; // audio device list
|
||||
PVOID KsAudioNotificationEntry; // ks audio notification hook
|
||||
PVOID EchoCancelNotificationEntry; // ks echo cancel notification hook
|
||||
KMUTEX Mutex; // audio device list mutex
|
||||
KSPIN_LOCK Lock; // audio device list mutex
|
||||
|
||||
PFILE_OBJECT KMixerFileObject; // mixer file object
|
||||
HANDLE KMixerHandle; // mixer file handle
|
||||
|
||||
PIO_WORKITEM WorkItem; // work item for pin creation
|
||||
PVOID WorkerContext; // work item context
|
||||
|
||||
}SYSAUDIODEVEXT, *PSYSAUDIODEVEXT;
|
||||
|
||||
// struct DISPATCH_CONTEXT
|
||||
|
@ -113,8 +110,16 @@ typedef struct
|
|||
PSYSAUDIO_CLIENT AudioClient;
|
||||
PSYSAUDIODEVEXT DeviceExtension;
|
||||
PKSDATAFORMAT_WAVEFORMATEX MixerFormat;
|
||||
PIO_WORKITEM WorkItem;
|
||||
}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PIO_WORKITEM WorkItem;
|
||||
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
|
||||
}FILTER_WORKER_CONTEXT, *PFILTER_WORKER_CONTEXT;
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SysAudioAllocateDeviceHeader(
|
||||
IN SYSAUDIODEVEXT *DeviceExtension);
|
||||
|
|
Loading…
Reference in a new issue