- Refactor irp handling to support playing new stream irps properly

- Complete several irps to allow audio devices to be shutdown properly and re-used

svn path=/trunk/; revision=39757
This commit is contained in:
Johannes Anderwald 2009-02-25 22:30:20 +00:00
parent 1675e01073
commit 5f60162daa
4 changed files with 38 additions and 40 deletions

View file

@ -169,7 +169,7 @@ IInterruptServiceRoutine(
BOOL Success; BOOL Success;
IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext; IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext;
DPRINT1("IInterruptServiceRoutine\n"); DPRINT("IInterruptServiceRoutine\n");
if (This->Mode == InterruptSyncModeNormal) if (This->Mode == InterruptSyncModeNormal)
{ {

View file

@ -111,11 +111,6 @@ IServiceSink_fnRequestService(
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE); This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE);
if (KeGetCurrentIrql() > DISPATCH_LEVEL) if (KeGetCurrentIrql() > DISPATCH_LEVEL)
{ {
if (This->DelayedRequestInProgress)
return;
This->ActiveIrp->IoStatus.Information = This->ActiveIrpBufferSize;
This->ActiveIrp->IoStatus.Status = STATUS_SUCCESS;
This->DelayedRequestInProgress = TRUE; This->DelayedRequestInProgress = TRUE;
This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L); This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
return; return;
@ -127,19 +122,14 @@ IServiceSink_fnRequestService(
This->ActiveIrp->IoStatus.Status = STATUS_SUCCESS; This->ActiveIrp->IoStatus.Status = STATUS_SUCCESS;
This->ActiveIrp->IoStatus.Information = This->ActiveIrpBufferSize; This->ActiveIrp->IoStatus.Information = This->ActiveIrpBufferSize;
IoCompleteRequest(This->ActiveIrp, IO_SOUND_INCREMENT); IoCompleteRequest(This->ActiveIrp, IO_SOUND_INCREMENT);
This->ActiveIrp = NULL;
} }
This->ActiveIrp = KsRemoveIrpFromCancelableQueue(&This->QueueHead, &This->QueueLock, KsListEntryTail, KsAcquireAndRemove); Status = IPortWaveCyclic_fnProcessNewIrp(This);
if (!This->ActiveIrp) if (Status == STATUS_SUCCESS)
{ This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
else
This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L); This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
return;
}
DPRINT1("processing next irp\n");
IPortWaveCyclic_fnProcessNewIrp(This);
This->DelayedRequestInProgress = FALSE;
return; return;
} }
} }
@ -148,26 +138,18 @@ IServiceSink_fnRequestService(
{ {
if (KeGetCurrentIrql() > DISPATCH_LEVEL) if (KeGetCurrentIrql() > DISPATCH_LEVEL)
{ {
if (This->DelayedRequestInProgress)
return;
This->DelayedRequestInProgress = TRUE;
This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L); This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
return; return;
} }
This->ActiveIrp = KsRemoveIrpFromCancelableQueue(&This->QueueHead, &This->QueueLock, KsListEntryTail, KsAcquireAndRemove);
if (!This->ActiveIrp)
{
This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
return;
}
IPortWaveCyclic_fnProcessNewIrp(This); Status = IPortWaveCyclic_fnProcessNewIrp(This);
This->DelayedRequestInProgress = FALSE; if (Status == STATUS_SUCCESS)
return; This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
else
This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
return;
} }
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position); Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
DPRINT("Position %u BufferSize %u ActiveIrpOffset %u\n", Position, This->CommonBufferSize, This->ActiveIrpOffset); DPRINT("Position %u BufferSize %u ActiveIrpOffset %u\n", Position, This->CommonBufferSize, This->ActiveIrpOffset);
@ -215,7 +197,7 @@ IServiceSink_fnRequestService(
if (!BytesToCopy) if (!BytesToCopy)
{ {
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE); This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
return; return;
} }
@ -323,18 +305,27 @@ IPortWaveCyclic_fnProcessNewIrp(
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PKSSTREAM_HEADER Header; PKSSTREAM_HEADER Header;
DPRINT1("ActiveIrp %p\n", This->ActiveIrp); This->ActiveIrp = KsRemoveIrpFromCancelableQueue(&This->QueueHead, &This->QueueLock, KsListEntryTail, KsAcquireAndRemove);
if (!This->ActiveIrp)
{
This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
return STATUS_PENDING;
}
DPRINT("ActiveIrp %p\n", This->ActiveIrp);
IoStack = IoGetCurrentIrpStackLocation(This->ActiveIrp); IoStack = IoGetCurrentIrpStackLocation(This->ActiveIrp);
if (IoStack->Parameters.DeviceIoControl.InputBufferLength != sizeof(KSSTREAM_HEADER)) if (IoStack->Parameters.DeviceIoControl.InputBufferLength != sizeof(KSSTREAM_HEADER))
{ {
DPRINT1("Irp has unexpected header\n"); DPRINT1("Irp has unexpected header\n");
IoCompleteRequest(This->ActiveIrp, IO_NO_INCREMENT);
This->ActiveIrp = NULL;
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
Header = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; Header = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
DPRINT1("Header %p Size %u\n", Header, Header->Size); DPRINT("Header %p Size %u\n", Header, Header->Size);
This->ActiveIrpOffset = 0; This->ActiveIrpOffset = 0;
@ -364,6 +355,7 @@ IPortPinWaveCyclic_HandleKsProperty(
{ {
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -379,6 +371,7 @@ IPortPinWaveCyclic_HandleKsProperty(
{ {
Irp->IoStatus.Information = sizeof(KSSTATE); Irp->IoStatus.Information = sizeof(KSSTATE);
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
@ -427,6 +420,7 @@ IPortPinWaveCyclic_HandleKsProperty(
*State = This->State; *State = This->State;
Irp->IoStatus.Information = sizeof(KSSTATE); Irp->IoStatus.Information = sizeof(KSSTATE);
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
@ -440,6 +434,7 @@ IPortPinWaveCyclic_HandleKsProperty(
{ {
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);
@ -454,33 +449,37 @@ IPortPinWaveCyclic_HandleKsProperty(
This->Format = NewDataFormat; This->Format = NewDataFormat;
Irp->IoStatus.Information = DataFormat->FormatSize; Irp->IoStatus.Information = DataFormat->FormatSize;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
else if (Property->Flags & KSPROPERTY_TYPE_GET) else if (Property->Flags & KSPROPERTY_TYPE_GET)
{ {
PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
if (!This->Format) if (!This->Format)
{ {
DPRINT1("No format\n"); DPRINT1("No format\n");
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if (This->Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) if (This->Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
{ {
Irp->IoStatus.Information = This->Format->FormatSize; Irp->IoStatus.Information = This->Format->FormatSize;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
RtlMoveMemory(DataFormat, This->Format, This->Format->FormatSize); RtlMoveMemory(DataFormat, This->Format, This->Format->FormatSize);
Irp->IoStatus.Information = DataFormat->FormatSize; Irp->IoStatus.Information = DataFormat->FormatSize;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
@ -493,6 +492,7 @@ IPortPinWaveCyclic_HandleKsProperty(
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
@ -511,10 +511,10 @@ IPortPinWaveCyclic_HandleKsStream(
if (!This->Stream) if (!This->Stream)
{ {
IoCancelIrp(Irp);
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
return Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
} }
KsAddIrpToCancelableQueue(&This->QueueHead, &This->QueueLock, Irp, KsListEntryTail, NULL); KsAddIrpToCancelableQueue(&This->QueueHead, &This->QueueLock, Irp, KsListEntryTail, NULL);
@ -774,7 +774,7 @@ IPortPinWaveCyclic_fnInit(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return Status;
Status = This->ServiceGroup->lpVtbl->AddMember(This->ServiceGroup, Status = This->ServiceGroup->lpVtbl->AddMember(This->ServiceGroup,
(PSERVICESINK)&This->lpVtblServiceSink); (PSERVICESINK)&This->lpVtblServiceSink);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -616,8 +616,6 @@ SysAudioHandleProperty(
if (PinInstances.CurrentCount == PinInstances.PossibleCount) if (PinInstances.CurrentCount == PinInstances.PossibleCount)
{ {
/* pin already exists */ /* pin already exists */
DPRINT1("Pins %p\n", Entry->Pins);
DbgBreakPoint();
ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL); ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
if (Entry->Pins[PinConnect->PinId].References > 1) if (Entry->Pins[PinConnect->PinId].References > 1)

View file

@ -269,7 +269,7 @@ DispatchCreateSysAudio(
{ {
Status = CreateDispatcher(Irp); Status = CreateDispatcher(Irp);
DPRINT1("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject); DPRINT1("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject);
DbgBreakPoint();
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);