[PORTCLS]

- Remove dead code
- Disable last mapping failed status when a new mapping is inserted
- Notify IMiniportWavePciStream::MappingAvailable when a new mapping has arrived and the last one has failed
- Return STATUS_NOT_FOUND in IPortWavePciStream::GetMapping when no mapping is available
- Don't stop stream when no mapping is currently available 

svn path=/trunk/; revision=45859
This commit is contained in:
Johannes Anderwald 2010-03-05 09:09:14 +00:00
parent ea5024f932
commit e3fb834a19
6 changed files with 78 additions and 630 deletions

View file

@ -337,17 +337,10 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
STDMETHOD_(VOID, UpdateMapping)(THIS_
IN ULONG BytesWritten) PURE;
STDMETHOD_(ULONG, NumMappings)(THIS) PURE;
STDMETHOD_(ULONG, NumData)(THIS) PURE;
STDMETHOD_(BOOL, MinimumDataAvailable)(THIS) PURE;
STDMETHOD_(BOOL, CancelBuffers)(THIS) PURE;
STDMETHOD_(VOID, UpdateFormat)(THIS_
IN PKSDATAFORMAT DataFormat) PURE;
STDMETHOD_(NTSTATUS, GetMappingWithTag)(THIS_
IN PVOID Tag,
OUT PPHYSICAL_ADDRESS PhysicalAddress,
@ -358,11 +351,8 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
STDMETHOD_(NTSTATUS, ReleaseMappingWithTag)(THIS_
IN PVOID Tag) PURE;
STDMETHOD_(BOOL, HasLastMappingFailed)(THIS) PURE;
STDMETHOD_(BOOLEAN, HasLastMappingFailed)(THIS) PURE;
STDMETHOD_(ULONG, GetCurrentIrpOffset)(THIS) PURE;
STDMETHOD_(VOID, SetMinimumDataThreshold)(THIS_
IN ULONG MinimumDataThreshold) PURE;
STDMETHOD_(ULONG, GetMinimumDataThreshold)(THIS) PURE;
};
@ -386,17 +376,10 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
STDMETHODIMP_(VOID) UpdateMapping(THIS_ \
IN ULONG BytesWritten); \
\
STDMETHODIMP_(ULONG) NumMappings(THIS); \
\
STDMETHODIMP_(ULONG) NumData(THIS); \
\
STDMETHODIMP_(BOOL) MinimumDataAvailable(THIS); \
\
STDMETHODIMP_(BOOL) CancelBuffers(THIS); \
\
STDMETHODIMP_(VOID) UpdateFormat(THIS_ \
IN PKSDATAFORMAT DataFormat); \
\
STDMETHODIMP_(NTSTATUS) GetMappingWithTag(THIS_ \
IN PVOID Tag, \
OUT PPHYSICAL_ADDRESS PhysicalAddress, \
@ -407,11 +390,9 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
STDMETHODIMP_(NTSTATUS) ReleaseMappingWithTag( \
IN PVOID Tag); \
\
STDMETHODIMP_(BOOL) HasLastMappingFailed(THIS); \
STDMETHODIMP_(ULONG) GetCurrentIrpOffset(THIS); \
STDMETHODIMP_(VOID) SetMinimumDataThreshold( \
IN ULONG MinimumDataThreshold); \
STDMETHODIMP_(ULONG) GetMinimumDataThreshold(VOID)
STDMETHODIMP_(BOOLEAN) HasLastMappingFailed(THIS); \
STDMETHODIMP_(ULONG) GetCurrentIrpOffset(THIS);
/*****************************************************************************
* IKsWorkSink

View file

@ -225,6 +225,9 @@ CIrpQueue::AddMapping(
// add irp to cancelable queue
KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, Irp, KsListEntryTail, NULL);
// disable mapping failed status
m_OutOfMapping = FALSE;
// done
return Status;
}
@ -410,15 +413,6 @@ CIrpQueue::UpdateMapping(
}
}
ULONG
NTAPI
CIrpQueue::NumMappings()
{
// returns the amount of mappings available
return m_NumMappings;
}
ULONG
NTAPI
CIrpQueue::NumData()
@ -427,28 +421,6 @@ CIrpQueue::NumData()
return m_NumDataAvailable;
}
BOOL
NTAPI
CIrpQueue::MinimumDataAvailable()
{
BOOL Result;
if (m_StartStream)
return TRUE;
if (m_MinimumDataThreshold < m_NumDataAvailable)
{
m_StartStream = TRUE;
Result = TRUE;
}
else
{
Result = FALSE;
}
return Result;
}
BOOL
NTAPI
CIrpQueue::CancelBuffers()
@ -475,17 +447,6 @@ CIrpQueue::CancelBuffers()
return TRUE;
}
VOID
NTAPI
CIrpQueue::UpdateFormat(
PKSDATAFORMAT DataFormat)
{
m_DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat;
m_MinimumDataThreshold = m_DataFormat->WaveFormatEx.nAvgBytesPerSec / 3;
m_StartStream = FALSE;
m_NumDataAvailable = 0;
}
NTSTATUS
NTAPI
CIrpQueue::GetMappingWithTag(
@ -510,7 +471,7 @@ CIrpQueue::GetMappingWithTag(
// no irp available
m_OutOfMapping = TRUE;
m_StartStream = FALSE;
return STATUS_UNSUCCESSFUL;
return STATUS_NOT_FOUND;
}
//FIXME support more than one stream header
@ -578,7 +539,7 @@ CIrpQueue::ReleaseMappingWithTag(
return STATUS_SUCCESS;
}
BOOL
BOOLEAN
NTAPI
CIrpQueue::HasLastMappingFailed()
{
@ -593,23 +554,6 @@ CIrpQueue::GetCurrentIrpOffset()
return m_CurrentOffset;
}
VOID
NTAPI
CIrpQueue::SetMinimumDataThreshold(
ULONG MinimumDataThreshold)
{
m_MinimumDataThreshold = MinimumDataThreshold;
}
ULONG
NTAPI
CIrpQueue::GetMinimumDataThreshold()
{
return m_MinimumDataThreshold;
}
NTSTATUS
NTAPI
NewIrpQueue(

View file

@ -41,9 +41,6 @@ protected:
VOID TransferMidiDataToDMus();
VOID TransferMidiData();
VOID NTAPI SetStreamState(IN KSSTATE State);
IPortDMus * m_Port;
IPortFilterDMus * m_Filter;
KSPIN_DESCRIPTOR * m_KsPinDescriptor;
@ -75,10 +72,6 @@ protected:
ULONG m_LastTag;
LONG m_Ref;
friend VOID NTAPI SetStreamWorkerRoutineDMus(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context);
friend VOID NTAPI CloseStreamRoutineDMus(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context);
};
typedef struct
@ -198,92 +191,6 @@ CPortPinDMus::DisconnectOutput(
//==================================================================================================================================
VOID
NTAPI
SetStreamWorkerRoutineDMus(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
CPortPinDMus* This;
KSSTATE State;
NTSTATUS Status;
PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context;
This = Ctx->Pin;
State = Ctx->State;
IoFreeWorkItem(Ctx->WorkItem);
FreeItem(Ctx, TAG_PORTCLASS);
// Has the audio stream resumed?
if (This->m_IrpQueue->NumMappings() && State == KSSTATE_STOP)
return;
// Set the state
if (This->m_MidiStream)
{
Status = This->m_MidiStream->SetState(State);
}
else
{
Status = This->m_Mxf->SetState(State);
}
if (NT_SUCCESS(Status))
{
// Set internal state to requested state
This->m_State = State;
if (This->m_State == KSSTATE_STOP)
{
// reset start stream
This->m_IrpQueue->CancelBuffers(); //FIX function name
DPRINT("Stopping PreCompleted %u PostCompleted %u\n", This->m_PreCompleted, This->m_PostCompleted);
}
}
}
VOID
NTAPI
CPortPinDMus::SetStreamState(
IN KSSTATE State)
{
PIO_WORKITEM WorkItem;
PSETSTREAM_CONTEXT Context;
PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
// Has the audio stream resumed?
if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP)
return;
// Has the audio state already been set?
if (m_State == State)
return;
// allocate set state context
Context = (PSETSTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS);
if (!Context)
return;
// allocate work item
WorkItem = IoAllocateWorkItem(m_DeviceObject);
if (!WorkItem)
{
ExFreePool(Context);
return;
}
Context->Pin = this;
Context->WorkItem = WorkItem;
Context->State = State;
// queue the work item
IoQueueWorkItem(WorkItem, SetStreamWorkerRoutineDMus, DelayedWorkQueue, (PVOID)Context);
}
VOID
CPortPinDMus::TransferMidiData()
{
@ -297,7 +204,6 @@ CPortPinDMus::TransferMidiData()
Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize);
if (!NT_SUCCESS(Status))
{
SetStreamState(KSSTATE_STOP);
return;
}
@ -375,7 +281,6 @@ CPortPinDMus::TransferMidiDataToDMus()
if (!Root)
{
SetStreamState(KSSTATE_STOP);
return;
}
@ -482,128 +387,59 @@ CPortPinDMus::Flush(
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
VOID
NTAPI
CloseStreamRoutineDMus(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
PMINIPORTMIDISTREAM Stream = NULL;
NTSTATUS Status;
ISubdevice *ISubDevice;
PSUBDEVICE_DESCRIPTOR Descriptor;
CPortPinDMus * This;
PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
This = (CPortPinDMus*)Ctx->Pin;
if (This->m_MidiStream)
{
if (This->m_State != KSSTATE_STOP)
{
This->m_MidiStream->SetState(KSSTATE_STOP);
}
Stream = This->m_MidiStream;
This->m_MidiStream = NULL;
}
if (This->m_ServiceGroup)
{
This->m_ServiceGroup->RemoveMember(PSERVICESINK(This));
}
Status = This->m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice);
if (NT_SUCCESS(Status))
{
Status = ISubDevice->GetDescriptor(&Descriptor);
if (NT_SUCCESS(Status))
{
Descriptor->Factory.Instances[This->m_ConnectDetails->PinId].CurrentPinInstanceCount--;
ISubDevice->Release();
}
}
if (This->m_Format)
{
ExFreePool(This->m_Format);
This->m_Format = NULL;
}
// complete the irp
Ctx->Irp->IoStatus.Information = 0;
Ctx->Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT);
// free the work item
IoFreeWorkItem(Ctx->WorkItem);
// free work item ctx
FreeItem(Ctx, TAG_PORTCLASS);
// destroy DMus pin
This->m_Filter->FreePin(PPORTPINDMUS(This));
if (Stream)
{
DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
Stream->Release();
}
}
NTSTATUS
NTAPI
CPortPinDMus::Close(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PCLOSESTREAM_CONTEXT Ctx;
NTSTATUS Status;
ISubdevice * SubDevice;
PSUBDEVICE_DESCRIPTOR Descriptor;
if (m_MidiStream || m_Mxf)
if (m_ServiceGroup)
{
Ctx = (PCLOSESTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
if (!Ctx)
{
DPRINT("Failed to allocate stream context\n");
goto cleanup;
}
Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!Ctx->WorkItem)
{
DPRINT("Failed to allocate work item\n");
goto cleanup;
}
Ctx->Irp = Irp;
Ctx->Pin = this;
IoMarkIrpPending(Irp);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
// defer work item
IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutineDMus, DelayedWorkQueue, (PVOID)Ctx);
// Return result
return STATUS_PENDING;
m_ServiceGroup->RemoveMember(PSERVICESINK(this));
}
if (m_MidiStream)
{
if (m_State != KSSTATE_STOP)
{
m_MidiStream->SetState(KSSTATE_STOP);
m_State = KSSTATE_STOP;
}
DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
m_MidiStream->Release();
}
Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice);
if (NT_SUCCESS(Status))
{
Status = SubDevice->GetDescriptor(&Descriptor);
if (NT_SUCCESS(Status))
{
// release reference count
Descriptor->Factory.Instances[m_ConnectDetails->PinId].CurrentPinInstanceCount--;
}
SubDevice->Release();
}
if (m_Format)
{
ExFreePool(m_Format);
m_Format = NULL;
}
// complete the irp
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
// destroy DMus pin
m_Filter->FreePin(PPORTPINDMUS(this));
return STATUS_SUCCESS;
cleanup:
if (Ctx)
FreeItem(Ctx, TAG_PORTCLASS);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
NTSTATUS

View file

@ -543,9 +543,6 @@ PinWaveCyclicDataFormat(
// free old format
FreeItem(Pin->m_Format, TAG_PORTCLASS);
// update irp queue with new format
Pin->m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat);
// store new format
Pin->m_Format = NewDataFormat;
Irp->IoStatus.Information = NewDataFormat->FormatSize;

View file

@ -36,9 +36,6 @@ public:
IMP_IPortWavePciStream;
CPortPinWavePci(IUnknown *OuterUnknown) {}
virtual ~CPortPinWavePci(){}
VOID NTAPI SetState( IN KSSTATE State);
VOID NTAPI CloseStream();
protected:
friend NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
@ -77,9 +74,6 @@ protected:
NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp);
NTSTATUS NTAPI HandleKsStream(IN PIRP Irp);
VOID NTAPI SetStreamState( IN KSSTATE State);
};
typedef struct
@ -311,9 +305,6 @@ PinWavePciDataFormat(
// free old format
FreeItem(Pin->m_Format, TAG_PORTCLASS);
// update irp queue with new format
Pin->m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat);
// store new format
Pin->m_Format = NewDataFormat;
Irp->IoStatus.Information = NewDataFormat->FormatSize;
@ -373,7 +364,7 @@ CPortPinWavePci::QueryInterface(
IN REFIID refiid,
OUT PVOID* Output)
{
DPRINT("CPortPinWavePci::QueryInterface entered\n");
//DPRINT("CPortPinWavePci::QueryInterface entered\n");
if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) ||
IsEqualGUIDAligned(refiid, IID_IUnknown))
@ -435,134 +426,12 @@ CPortPinWavePci::TerminatePacket()
}
VOID
CPortPinWavePci::SetState(KSSTATE State)
{
ULONG MinimumDataThreshold;
ULONG MaximumDataThreshold;
// Has the audio stream resumed?
if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP)
return;
// Set the state
if (NT_SUCCESS(m_Stream->SetState(State)))
{
// Save new internal state
m_State = State;
if (m_State == KSSTATE_STOP)
{
// reset start stream
m_IrpQueue->CancelBuffers(); //FIX function name
//This->ServiceGroup->lpVtbl->CancelDelayedService(This->ServiceGroup);
// increase stop counter
m_StopCount++;
// get current data threshold
MinimumDataThreshold = m_IrpQueue->GetMinimumDataThreshold();
// get maximum data threshold
MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)m_Format)->WaveFormatEx.nAvgBytesPerSec;
// increase minimum data threshold by 10 frames
MinimumDataThreshold += m_AllocatorFraming.FrameSize * 10;
// assure it has not exceeded
MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold);
// store minimum data threshold
m_IrpQueue->SetMinimumDataThreshold(MinimumDataThreshold);
DPRINT("Stopping TotalCompleted %u StopCount %u MinimumDataThreshold %u\n", m_TotalPackets, m_StopCount, MinimumDataThreshold);
}
if (m_State == KSSTATE_RUN)
{
// start the notification timer
//m_ServiceGroup->RequestDelayedService(m_ServiceGroup, m_Delay);
}
}
}
VOID
NTAPI
PinWavePciSetStreamWorkerRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
CPortPinWavePci * This;
PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context;
KSSTATE State;
This = Ctx->Pin;
State = Ctx->State;
IoFreeWorkItem(Ctx->WorkItem);
FreeItem(Ctx, TAG_PORTCLASS);
This->SetState(State);
}
VOID
NTAPI
CPortPinWavePci::SetStreamState(
IN KSSTATE State)
{
PDEVICE_OBJECT DeviceObject;
PIO_WORKITEM WorkItem;
PSETSTREAM_CONTEXT Context;
PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
// Has the audio stream resumed?
if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP)
return;
// Has the audio state already been set?
if (m_State == State)
return;
// Get device object
DeviceObject = GetDeviceObjectFromPortWavePci(m_Port);
// allocate set state context
Context = (PSETSTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS);
if (!Context)
return;
// allocate work item
WorkItem = IoAllocateWorkItem(DeviceObject);
if (!WorkItem)
{
ExFreePool(Context);
return;
}
Context->Pin = this;
Context->WorkItem = WorkItem;
Context->State = State;
// queue the work item
IoQueueWorkItem(WorkItem, PinWavePciSetStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
}
VOID
NTAPI
CPortPinWavePci::RequestService()
{
PC_ASSERT_IRQL(DISPATCH_LEVEL);
if (m_IrpQueue->HasLastMappingFailed())
{
if (m_IrpQueue->NumMappings() == 0)
{
DPRINT("Stopping stream...\n");
SetStreamState(KSSTATE_STOP);
return;
}
}
m_Stream->Service();
//TODO
//generate events
@ -597,18 +466,18 @@ CPortPinWavePci::HandleKsProperty(
{
PKSPROPERTY Property;
NTSTATUS Status;
UNICODE_STRING GuidString;
//UNICODE_STRING GuidString;
PIO_STACK_LOCATION IoStack;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IPortPinWave_HandleKsProperty entered\n");
//DPRINT("IPortPinWave_HandleKsProperty entered\n");
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
{
DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
//DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
Irp->IoStatus.Status = STATUS_SUCCESS;
@ -621,10 +490,11 @@ CPortPinWavePci::HandleKsProperty(
if (Status == STATUS_NOT_FOUND)
{
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
#if 0
RtlStringFromGUID(Property->Set, &GuidString);
DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
//DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString);
#endif
}
if (Status != STATUS_PENDING)
@ -636,29 +506,6 @@ CPortPinWavePci::HandleKsProperty(
return Status;
}
#if 0
else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING)
{
PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)OutputBuffer;
PC_ASSERT_IRQL(DISPATCH_LEVEL);
// Validate input buffer
if (OutputBufferLength < sizeof(KSALLOCATOR_FRAMING))
{
IoStatusBlock->Information = sizeof(KSALLOCATOR_FRAMING);
IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
// copy frame allocator struct
RtlMoveMemory(Framing, &m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING));
IoStatusBlock->Information = sizeof(KSALLOCATOR_FRAMING);
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
}
#endif
NTSTATUS
NTAPI
CPortPinWavePci::HandleKsStream(
@ -666,10 +513,13 @@ CPortPinWavePci::HandleKsStream(
{
NTSTATUS Status;
ULONG Data = 0;
BOOLEAN bFailed;
InterlockedIncrement((PLONG)&m_TotalPackets);
DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
bFailed = m_IrpQueue->HasLastMappingFailed();
Status = m_IrpQueue->AddMapping(Irp, &Data);
if (NT_SUCCESS(Status))
@ -679,6 +529,12 @@ CPortPinWavePci::HandleKsStream(
else
m_Position.WriteOffset += Data;
if (bFailed)
{
// notify stream of new mapping
m_Stream->MappingAvailable();
}
return STATUS_PENDING;
}
@ -741,37 +597,39 @@ CPortPinWavePci::Flush(
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
VOID
NTSTATUS
NTAPI
CPortPinWavePci::CloseStream()
CPortPinWavePci::Close(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PMINIPORTWAVEPCISTREAM Stream;
ISubdevice *ISubDevice;
ISubdevice *SubDevice;
NTSTATUS Status;
PSUBDEVICE_DESCRIPTOR Descriptor;
if (m_ServiceGroup)
{
m_ServiceGroup->RemoveMember(PSERVICESINK(this));
}
if (m_Stream)
{
if (m_State != KSSTATE_STOP)
{
m_Stream->SetState(KSSTATE_STOP);
}
m_Stream->Release();
}
if (m_ServiceGroup)
{
m_ServiceGroup->RemoveMember(PSERVICESINK(this));
}
Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice);
Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice);
if (NT_SUCCESS(Status))
{
Status = ISubDevice->GetDescriptor(&Descriptor);
Status = SubDevice->GetDescriptor(&Descriptor);
if (NT_SUCCESS(Status))
{
Descriptor->Factory.Instances[m_ConnectDetails->PinId].CurrentPinInstanceCount--;
}
ISubDevice->Release();
SubDevice->Release();
}
if (m_Format)
@ -780,93 +638,11 @@ CPortPinWavePci::CloseStream()
m_Format = NULL;
}
if (m_Stream)
{
Stream = m_Stream;
m_Stream = 0;
DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
Stream->Release();
}
}
VOID
NTAPI
PinWavePciCloseStreamRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
CPortPinWavePci * This;
PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
This = (CPortPinWavePci*)Ctx->Pin;
This->CloseStream();
// complete the irp
Ctx->Irp->IoStatus.Information = 0;
Ctx->Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT);
// free the work item
IoFreeWorkItem(Ctx->WorkItem);
// free work item ctx
FreeItem(Ctx, TAG_PORTCLASS);
}
NTSTATUS
NTAPI
CPortPinWavePci::Close(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PCLOSESTREAM_CONTEXT Ctx;
if (m_Stream)
{
Ctx = (PCLOSESTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
if (!Ctx)
{
DPRINT("Failed to allocate stream context\n");
goto cleanup;
}
Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!Ctx->WorkItem)
{
DPRINT("Failed to allocate work item\n");
goto cleanup;
}
Ctx->Irp = Irp;
Ctx->Pin = (PVOID)this;
IoMarkIrpPending(Irp);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
// defer work item
IoQueueWorkItem(Ctx->WorkItem, PinWavePciCloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx);
// Return result
return STATUS_PENDING;
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
cleanup:
if (Ctx)
FreeItem(Ctx, TAG_PORTCLASS);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
NTSTATUS

View file

@ -100,91 +100,6 @@ CPortPinWaveRT::QueryInterface(
return STATUS_UNSUCCESSFUL;
}
VOID
NTAPI
SetStreamWorkerRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
CPortPinWaveRT * This;
PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context;
KSSTATE State;
This = Ctx->Pin;
State = Ctx->State;
IoFreeWorkItem(Ctx->WorkItem);
FreeItem(Ctx, TAG_PORTCLASS);
// Has the audio stream resumed?
if (This->m_IrpQueue->NumMappings() && State == KSSTATE_STOP)
return;
// Set the state
if (NT_SUCCESS(This->m_Stream->SetState(State)))
{
// Set internal state to stop
This->m_State = State;
if (This->m_State == KSSTATE_STOP)
{
// reset start stream
This->m_IrpQueue->CancelBuffers(); //FIX function name
DPRINT("Stopping PreCompleted %u PostCompleted %u\n", This->m_PreCompleted, This->m_PostCompleted);
}
if (This->m_State == KSSTATE_RUN)
{
// start the notification timer
}
}
}
VOID
NTAPI
CPortPinWaveRT::SetStreamState(
IN KSSTATE State)
{
PDEVICE_OBJECT DeviceObject;
PIO_WORKITEM WorkItem;
PSETSTREAM_CONTEXT Context;
PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
// Has the audio stream resumed?
if (m_IrpQueue->NumMappings() && State == KSSTATE_STOP)
return;
// Has the audio state already been set?
if (m_State == State)
return;
// Get device object
DeviceObject = GetDeviceObjectFromPortWaveRT(m_Port);
// allocate set state context
Context = (PSETSTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS);
if (!Context)
return;
// allocate work item
WorkItem = IoAllocateWorkItem(DeviceObject);
if (!WorkItem)
{
ExFreePool(Context);
return;
}
Context->Pin = this;
Context->WorkItem = WorkItem;
Context->State = State;
// queue the work item
IoQueueWorkItem(WorkItem, SetStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
}
//==================================================================================================================================
NTSTATUS
@ -313,7 +228,6 @@ CPortPinWaveRT::HandleKsProperty(
if (m_Format)
ExFreePoolWithTag(m_Format, TAG_PORTCLASS);
m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat);
m_Format = NewDataFormat;
Irp->IoStatus.Information = DataFormat->FormatSize;
Irp->IoStatus.Status = STATUS_SUCCESS;