mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +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;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PLIST_ENTRY Entry;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PIRP Irp;
|
||||
KIRQL OldLevel;
|
||||
|
||||
|
@ -1253,6 +1254,9 @@ KsCancelIo(
|
|||
/* get irp offset */
|
||||
Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
||||
|
||||
/* get next entry */
|
||||
NextEntry = Entry->Flink;
|
||||
|
||||
/* set cancelled bit */
|
||||
Irp->Cancel = TRUE;
|
||||
|
||||
|
@ -1275,8 +1279,9 @@ KsCancelIo(
|
|||
/* re-acquire spinlock */
|
||||
KeAcquireSpinLock(SpinLock, &OldLevel);
|
||||
}
|
||||
|
||||
/* move on to next entry */
|
||||
Entry = Entry->Flink;
|
||||
Entry = NextEntry;
|
||||
}
|
||||
|
||||
/* the irp has already been canceled */
|
||||
|
@ -1785,7 +1790,7 @@ KspCreate(
|
|||
PKSIOBJECT_HEADER ObjectHeader;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("KS / CREATE\n");
|
||||
DPRINT1("KS / CREATE\n");
|
||||
/* get current stack location */
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
/* get device extension */
|
||||
|
@ -1838,7 +1843,6 @@ KspCreate(
|
|||
return Status;
|
||||
}
|
||||
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
/* set return status */
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
|
|
|
@ -441,8 +441,20 @@ BOOL
|
|||
NTAPI
|
||||
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;
|
||||
// done
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -268,7 +268,14 @@ PinWaveCyclicState(
|
|||
{
|
||||
// store new 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
|
||||
Irp->IoStatus.Information = sizeof(KSSTATE);
|
||||
return Status;
|
||||
|
@ -905,7 +912,8 @@ CPortPinWaveCyclic::Init(
|
|||
}
|
||||
#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))
|
||||
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] =
|
||||
{
|
||||
{
|
||||
|
@ -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
|
||||
NTAPI
|
||||
PcCreatePinDispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
IIrpTarget *Filter;
|
||||
IIrpTarget *Pin;
|
||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||
PPIN_WORKER_CONTEXT Context;
|
||||
|
||||
// access the create item
|
||||
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
||||
|
@ -511,6 +463,7 @@ PcCreatePinDispatch(
|
|||
|
||||
// sanity checks
|
||||
PC_ASSERT(Filter != NULL);
|
||||
PC_ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
|
||||
|
||||
#if KS_IMPLEMENTED
|
||||
|
@ -524,45 +477,33 @@ PcCreatePinDispatch(
|
|||
}
|
||||
#endif
|
||||
|
||||
// new pins are instantiated at passive level,
|
||||
// so allocate a work item and context for it
|
||||
|
||||
Status = Filter->NewIrpTarget(&Pin,
|
||||
KSSTRING_Pin,
|
||||
NULL,
|
||||
NonPagedPool,
|
||||
DeviceObject,
|
||||
Irp,
|
||||
NULL);
|
||||
|
||||
Context = (PPIN_WORKER_CONTEXT)AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
|
||||
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;
|
||||
}
|
||||
DPRINT("PcCreatePinDispatch Status %x\n", Status);
|
||||
|
||||
// allocate work item
|
||||
Context->WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||
if (!Context->WorkItem)
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Failed to allocate workitem\n");
|
||||
FreeItem(Context, TAG_PORTCLASS);
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
// create the dispatch object
|
||||
// FIXME need create item for clock
|
||||
Status = NewDispatchObject(Irp, Pin, 0, NULL);
|
||||
DPRINT("Pin %p\n", Pin);
|
||||
}
|
||||
|
||||
Context->Filter = Filter;
|
||||
Context->Irp = Irp;
|
||||
|
||||
DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql());
|
||||
DPRINT("CreatePinWorkerRoutine completing irp %p\n", Irp);
|
||||
// save status in irp
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_PENDING;
|
||||
IoMarkIrpPending(Irp);
|
||||
IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
|
||||
return STATUS_PENDING;
|
||||
// complete the request
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PcCreateItemDispatch(
|
||||
|
@ -585,6 +526,7 @@ PcCreateItemDispatch(
|
|||
// sanity checks
|
||||
PC_ASSERT(SubDevice != NULL);
|
||||
|
||||
|
||||
#if KS_IMPLEMENTED
|
||||
Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
|
||||
|
|
Loading…
Reference in a new issue