mirror of
https://github.com/reactos/reactos.git
synced 2025-04-29 10:39:07 +00:00
[KS]
- Fix a bug in KsCancelIo which accessed already freed memory [PORTCLS] - Cancel all audio stream irps when the it is used in looped stream mode. Fixes re-opening of playback / capture devices in DSound. - Remove dead code svn path=/trunk/; revision=43945
This commit is contained in:
parent
420a4f5f4b
commit
c5fab80345
4 changed files with 51 additions and 85 deletions
|
@ -1240,6 +1240,7 @@ KsCancelIo(
|
||||||
PDRIVER_CANCEL OldDriverCancel;
|
PDRIVER_CANCEL OldDriverCancel;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
|
PLIST_ENTRY NextEntry;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
KIRQL OldLevel;
|
KIRQL OldLevel;
|
||||||
|
|
||||||
|
@ -1253,6 +1254,9 @@ KsCancelIo(
|
||||||
/* get irp offset */
|
/* get irp offset */
|
||||||
Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
/* get next entry */
|
||||||
|
NextEntry = Entry->Flink;
|
||||||
|
|
||||||
/* set cancelled bit */
|
/* set cancelled bit */
|
||||||
Irp->Cancel = TRUE;
|
Irp->Cancel = TRUE;
|
||||||
|
|
||||||
|
@ -1275,8 +1279,9 @@ KsCancelIo(
|
||||||
/* re-acquire spinlock */
|
/* re-acquire spinlock */
|
||||||
KeAcquireSpinLock(SpinLock, &OldLevel);
|
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move on to next entry */
|
/* move on to next entry */
|
||||||
Entry = Entry->Flink;
|
Entry = NextEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the irp has already been canceled */
|
/* the irp has already been canceled */
|
||||||
|
@ -1785,7 +1790,7 @@ KspCreate(
|
||||||
PKSIOBJECT_HEADER ObjectHeader;
|
PKSIOBJECT_HEADER ObjectHeader;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("KS / CREATE\n");
|
DPRINT1("KS / CREATE\n");
|
||||||
/* get current stack location */
|
/* get current stack location */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
/* get device extension */
|
/* get device extension */
|
||||||
|
@ -1838,7 +1843,6 @@ KspCreate(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
/* set return status */
|
/* set return status */
|
||||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||||
|
|
|
@ -441,8 +441,20 @@ BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
CIrpQueue::CancelBuffers()
|
CIrpQueue::CancelBuffers()
|
||||||
{
|
{
|
||||||
|
// is there an active irp
|
||||||
|
if (m_Irp)
|
||||||
|
{
|
||||||
|
// re-insert it to cancelable queue
|
||||||
|
KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, m_Irp, KsListEntryTail, NULL);
|
||||||
|
//set it to zero
|
||||||
|
m_Irp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel all irps
|
||||||
|
KsCancelIo(&m_IrpList, &m_IrpListLock);
|
||||||
|
// reset stream start flag
|
||||||
m_StartStream = FALSE;
|
m_StartStream = FALSE;
|
||||||
|
// done
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,14 @@ PinWaveCyclicState(
|
||||||
{
|
{
|
||||||
// store new state
|
// store new state
|
||||||
Pin->m_State = *State;
|
Pin->m_State = *State;
|
||||||
|
|
||||||
|
if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP)
|
||||||
|
{
|
||||||
|
/* FIXME complete pending irps with successfull state */
|
||||||
|
Pin->m_IrpQueue->CancelBuffers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// store result
|
// store result
|
||||||
Irp->IoStatus.Information = sizeof(KSSTATE);
|
Irp->IoStatus.Information = sizeof(KSSTATE);
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -905,7 +912,8 @@ CPortPinWaveCyclic::Init(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DPRINT("CPortPinWaveCyclic::Init Status %x\n", Status);
|
DPRINT("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture);
|
||||||
|
DPRINT("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -55,13 +55,6 @@ protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PIRP Irp;
|
|
||||||
IIrpTarget *Filter;
|
|
||||||
PIO_WORKITEM WorkItem;
|
|
||||||
}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
|
|
||||||
|
|
||||||
static GUID InterfaceGuids[2] =
|
static GUID InterfaceGuids[2] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -448,57 +441,16 @@ CPortTopology::PinCount(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
CreatePinWorkerRoutine(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PVOID Context)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
IIrpTarget *Pin;
|
|
||||||
PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
|
|
||||||
|
|
||||||
DPRINT("CreatePinWorkerRoutine called\n");
|
|
||||||
// create the pin
|
|
||||||
Status = WorkerContext->Filter->NewIrpTarget(&Pin,
|
|
||||||
KSSTRING_Pin,
|
|
||||||
NULL,
|
|
||||||
NonPagedPool,
|
|
||||||
DeviceObject,
|
|
||||||
WorkerContext->Irp,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
DPRINT("CreatePinWorkerRoutine Status %x\n", Status);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
// create the dispatch object
|
|
||||||
// FIXME need create item for clock
|
|
||||||
Status = NewDispatchObject(WorkerContext->Irp, Pin, 0, NULL);
|
|
||||||
DPRINT("Pin %p\n", Pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("CreatePinWorkerRoutine completing irp %p\n", WorkerContext->Irp);
|
|
||||||
// save status in irp
|
|
||||||
WorkerContext->Irp->IoStatus.Status = Status;
|
|
||||||
WorkerContext->Irp->IoStatus.Information = 0;
|
|
||||||
// complete the request
|
|
||||||
IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT);
|
|
||||||
// free allocated work item
|
|
||||||
IoFreeWorkItem(WorkerContext->WorkItem);
|
|
||||||
// free context
|
|
||||||
FreeItem(WorkerContext, TAG_PORTCLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PcCreatePinDispatch(
|
PcCreatePinDispatch(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
IIrpTarget *Filter;
|
IIrpTarget *Filter;
|
||||||
|
IIrpTarget *Pin;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
PPIN_WORKER_CONTEXT Context;
|
|
||||||
|
|
||||||
// access the create item
|
// access the create item
|
||||||
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
||||||
|
@ -511,6 +463,7 @@ PcCreatePinDispatch(
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
PC_ASSERT(Filter != NULL);
|
PC_ASSERT(Filter != NULL);
|
||||||
|
PC_ASSERT_IRQL(PASSIVE_LEVEL);
|
||||||
|
|
||||||
|
|
||||||
#if KS_IMPLEMENTED
|
#if KS_IMPLEMENTED
|
||||||
|
@ -524,45 +477,33 @@ PcCreatePinDispatch(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// new pins are instantiated at passive level,
|
Status = Filter->NewIrpTarget(&Pin,
|
||||||
// so allocate a work item and context for it
|
KSSTRING_Pin,
|
||||||
|
NULL,
|
||||||
|
NonPagedPool,
|
||||||
|
DeviceObject,
|
||||||
|
Irp,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
DPRINT("PcCreatePinDispatch Status %x\n", Status);
|
||||||
|
|
||||||
Context = (PPIN_WORKER_CONTEXT)AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
|
if (NT_SUCCESS(Status))
|
||||||
if (!Context)
|
|
||||||
{
|
|
||||||
DPRINT("Failed to allocate worker context\n");
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate work item
|
|
||||||
Context->WorkItem = IoAllocateWorkItem(DeviceObject);
|
|
||||||
if (!Context->WorkItem)
|
|
||||||
{
|
{
|
||||||
DPRINT("Failed to allocate workitem\n");
|
// create the dispatch object
|
||||||
FreeItem(Context, TAG_PORTCLASS);
|
// FIXME need create item for clock
|
||||||
Irp->IoStatus.Information = 0;
|
Status = NewDispatchObject(Irp, Pin, 0, NULL);
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
DPRINT("Pin %p\n", Pin);
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Context->Filter = Filter;
|
DPRINT("CreatePinWorkerRoutine completing irp %p\n", Irp);
|
||||||
Context->Irp = Irp;
|
// save status in irp
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql());
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
// complete the request
|
||||||
IoMarkIrpPending(Irp);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
|
return Status;
|
||||||
return STATUS_PENDING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PcCreateItemDispatch(
|
PcCreateItemDispatch(
|
||||||
|
@ -585,6 +526,7 @@ PcCreateItemDispatch(
|
||||||
// sanity checks
|
// sanity checks
|
||||||
PC_ASSERT(SubDevice != NULL);
|
PC_ASSERT(SubDevice != NULL);
|
||||||
|
|
||||||
|
|
||||||
#if KS_IMPLEMENTED
|
#if KS_IMPLEMENTED
|
||||||
Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
|
Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
|
||||||
if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
|
if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
|
||||||
|
|
Loading…
Reference in a new issue