[PORTCLS]

- Implement handling of enabling / disabling events
- Implement firing of events when certain position is reached
- Code not yet used as ks needs more work

svn path=/trunk/; revision=44074
This commit is contained in:
Johannes Anderwald 2009-11-10 10:01:25 +00:00
parent d129a33bad
commit dcb1336203
5 changed files with 256 additions and 33 deletions

View file

@ -80,6 +80,9 @@ const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
const GUID KSPROPTYPESETID_General = {0x97E99BA0L, 0xBDEA, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
const GUID KSEVENTSETID_LoopedStreaming = {0x4682B940L, 0xC6EF, 0x11D0, {0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D}};
const GUID KSEVENTSETID_Connection = {0x7f4bcbe0L, 0x9ea5, 0x11cf, {0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00}};
const GUID IID_IAllocatorMXF = {0xa5f0d62cL, 0xb30f, 0x11d2, {0xb7, 0xa3, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};

View file

@ -209,6 +209,11 @@ typedef struct
ULONG FilterPropertySetCount;
PKSPROPERTY_SET FilterPropertySet;
ULONG EventSetCount;
PKSEVENT_SET EventSet;
PLIST_ENTRY EventList;
PKSPIN_LOCK EventListLock;
PPCFILTER_DESCRIPTOR DeviceDescriptor;
KSTOPOLOGY* Topology;
LIST_ENTRY SymbolicLinkList;

View file

@ -41,6 +41,7 @@ protected:
VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount);
VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount);
VOID GeneratePositionEvents(IN ULONG OldCommonBufferOffset, IN ULONG NewCommonBufferOffset);
NTSTATUS NTAPI HandleKsStream(IN PIRP Irp);
NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp);
@ -49,6 +50,8 @@ protected:
friend NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
friend NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
friend NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
friend NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry);
friend NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry);
IPortWaveCyclic * m_Port;
IPortFilterWaveCyclic * m_Filter;
@ -76,6 +79,9 @@ protected:
KSALLOCATOR_FRAMING m_AllocatorFraming;
SUBDEVICE_DESCRIPTOR m_Descriptor;
KSPIN_LOCK m_EventListLock;
LIST_ENTRY m_EventList;
ULONG m_Delay;
LONG m_Ref;
@ -84,19 +90,49 @@ protected:
typedef struct
{
CPortPinWaveCyclic *Pin;
PIO_WORKITEM WorkItem;
KSSTATE State;
}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
ULONG bLoopedStreaming;
ULONGLONG Position;
}LOOPEDSTREAMING_EVENT_CONTEXT, *PLOOPEDSTREAMING_EVENT_CONTEXT;
typedef struct
{
ULONG bLoopedStreaming;
}ENDOFSTREAM_EVENT_CONTEXT, *PENDOFSTREAM_EVENT_CONTEXT;
NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry);
NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry);
DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat, PinWaveCyclicAllocatorFraming);
DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition);
KSEVENT_ITEM PinWaveCyclicConnectionEventSet =
{
KSEVENT_CONNECTION_ENDOFSTREAM,
sizeof(KSEVENTDATA),
sizeof(ENDOFSTREAM_EVENT_CONTEXT),
PinWaveCyclicAddEndOfStreamEvent,
0,
0
};
KSEVENT_ITEM PinWaveCyclicStreamingEventSet =
{
KSEVENT_LOOPEDSTREAMING_POSITION,
sizeof(LOOPEDSTREAMING_POSITION_EVENT_DATA),
sizeof(LOOPEDSTREAMING_EVENT_CONTEXT),
PinWaveCyclicAddLoopedStreamEvent,
0,
0
};
KSPROPERTY_SET PinWaveCyclicPropertySet[] =
{
{
@ -115,6 +151,21 @@ KSPROPERTY_SET PinWaveCyclicPropertySet[] =
}
};
KSEVENT_SET PinWaveCyclicEventSet[] =
{
{
&KSEVENTSETID_LoopedStreaming,
sizeof(PinWaveCyclicStreamingEventSet) / sizeof(KSEVENT_ITEM),
(const KSEVENT_ITEM*)&PinWaveCyclicStreamingEventSet
},
{
&KSEVENTSETID_Connection,
sizeof(PinWaveCyclicConnectionEventSet) / sizeof(KSEVENT_ITEM),
(const KSEVENT_ITEM*)&PinWaveCyclicConnectionEventSet
}
};
//==================================================================================================================================
NTSTATUS
@ -143,6 +194,80 @@ CPortPinWaveCyclic::QueryInterface(
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
NTAPI
PinWaveCyclicAddEndOfStreamEvent(
IN PIRP Irp,
IN PKSEVENTDATA EventData,
IN PKSEVENT_ENTRY EventEntry)
{
PENDOFSTREAM_EVENT_CONTEXT Entry;
PSUBDEVICE_DESCRIPTOR Descriptor;
CPortPinWaveCyclic *Pin;
// get sub device descriptor
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
// sanity check
PC_ASSERT(Descriptor);
PC_ASSERT(Descriptor->PortPin);
PC_ASSERT_IRQL(DISPATCH_LEVEL);
// cast to pin impl
Pin = (CPortPinWaveCyclic*)Descriptor->PortPin;
// get extra size
Entry = (PENDOFSTREAM_EVENT_CONTEXT)(EventEntry + 1);
// not a looped event
Entry->bLoopedStreaming = FALSE;
// insert item
(void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock);
// done
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
PinWaveCyclicAddLoopedStreamEvent(
IN PIRP Irp,
IN PKSEVENTDATA EventData,
IN PKSEVENT_ENTRY EventEntry)
{
PLOOPEDSTREAMING_POSITION_EVENT_DATA Data;
PLOOPEDSTREAMING_EVENT_CONTEXT Entry;
PSUBDEVICE_DESCRIPTOR Descriptor;
CPortPinWaveCyclic *Pin;
// get sub device descriptor
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSEVENT_ITEM_IRP_STORAGE(Irp);
// sanity check
PC_ASSERT(Descriptor);
PC_ASSERT(Descriptor->PortPin);
PC_ASSERT_IRQL(DISPATCH_LEVEL);
// cast to pin impl
Pin = (CPortPinWaveCyclic*)Descriptor->PortPin;
// cast to looped event
Data = (PLOOPEDSTREAMING_POSITION_EVENT_DATA)EventData;
// get extra size
Entry = (PLOOPEDSTREAMING_EVENT_CONTEXT)(EventEntry + 1);
Entry->bLoopedStreaming = TRUE;
Entry->Position = Data->Position;
// insert item
(void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock);
// done
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
PinWaveCyclicAllocatorFraming(
@ -154,7 +279,7 @@ PinWaveCyclicAllocatorFraming(
PSUBDEVICE_DESCRIPTOR Descriptor;
// get sub device descriptor
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSEVENT_ITEM_IRP_STORAGE(Irp);
// sanity check
PC_ASSERT(Descriptor);
@ -413,6 +538,58 @@ PinWaveCyclicDataFormat(
return STATUS_NOT_SUPPORTED;
}
VOID
CPortPinWaveCyclic::GeneratePositionEvents(
IN ULONG OldCommonBufferOffset,
IN ULONG NewCommonBufferOffset)
{
PLIST_ENTRY Entry;
PKSEVENT_ENTRY EventEntry;
PLOOPEDSTREAMING_EVENT_CONTEXT Context;
// acquire event lock
KeAcquireSpinLockAtDpcLevel(&m_EventListLock);
// point to first entry
Entry = m_EventList.Flink;
while(Entry != &m_EventList)
{
// get event entry
EventEntry = (PKSEVENT_ENTRY)CONTAINING_RECORD(Entry, KSEVENT_ENTRY, ListEntry);
// get event entry context
Context = (PLOOPEDSTREAMING_EVENT_CONTEXT)(EventEntry + 1);
if (Context->bLoopedStreaming == TRUE)
{
if (NewCommonBufferOffset > OldCommonBufferOffset)
{
/* buffer progress no overlap */
if (OldCommonBufferOffset < Context->Position && Context->Position <= NewCommonBufferOffset)
{
/* generate event */
KsGenerateEvent(EventEntry);
}
}
else
{
/* buffer wrap-arround */
if (OldCommonBufferOffset < Context->Position || NewCommonBufferOffset > Context->Position)
{
/* generate event */
KsGenerateEvent(EventEntry);
}
}
}
// move to next entry
Entry = Entry->Flink;
}
// release lock
KeReleaseSpinLockFromDpcLevel(&m_EventListLock);
}
VOID
CPortPinWaveCyclic::UpdateCommonBuffer(
@ -516,6 +693,7 @@ CPortPinWaveCyclic::RequestService()
NTSTATUS Status;
PUCHAR Buffer;
ULONG BufferSize;
ULONG OldCommonBufferOffset;
PC_ASSERT_IRQL(DISPATCH_LEVEL);
@ -528,6 +706,8 @@ CPortPinWaveCyclic::RequestService()
Status = m_Stream->GetPosition(&Position);
DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture);
OldCommonBufferOffset = m_CommonBufferOffset;
if (Position < m_CommonBufferOffset)
{
UpdateCommonBufferOverlap(Position, m_FrameSize);
@ -536,6 +716,8 @@ CPortPinWaveCyclic::RequestService()
{
UpdateCommonBuffer(Position, m_FrameSize);
}
GeneratePositionEvents(OldCommonBufferOffset, m_CommonBufferOffset);
}
NTSTATUS
@ -569,16 +751,6 @@ CPortPinWaveCyclic::HandleKsProperty(
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);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor);
if (Status == STATUS_NOT_FOUND)
@ -629,6 +801,7 @@ CPortPinWaveCyclic::DeviceIoControl(
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
NTSTATUS Status = STATUS_NOT_SUPPORTED;
IoStack = IoGetCurrentIrpStackLocation(Irp);
@ -639,13 +812,11 @@ CPortPinWaveCyclic::DeviceIoControl(
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
{
/// FIXME
/// handle enable event
Status = PcHandleEnableEventWithTable(Irp, &m_Descriptor);
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT)
{
/// FIXME
/// handle disable event
Status = PcHandleDisableEventWithTable(Irp, &m_Descriptor);
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE)
{
@ -661,13 +832,13 @@ CPortPinWaveCyclic::DeviceIoControl(
return KsDefaultDeviceIoCompletion(DeviceObject, Irp);
}
UNIMPLEMENTED
if (Status != STATUS_PENDING)
{
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
return Status;
}
NTSTATUS
@ -912,8 +1083,8 @@ CPortPinWaveCyclic::Init(
}
#endif
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);
DPRINT1("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture);
DPRINT1("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;
@ -933,6 +1104,10 @@ CPortPinWaveCyclic::Init(
return Status;
}
/* initialize event management */
InitializeListHead(&m_EventList);
KeInitializeSpinLock(&m_EventListLock);
/* set up subdevice descriptor */
RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR));
m_Descriptor.FilterPropertySet = PinWaveCyclicPropertySet;
@ -941,6 +1116,10 @@ CPortPinWaveCyclic::Init(
m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor;
m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport;
m_Descriptor.PortPin = (PVOID)this;
m_Descriptor.EventSetCount = sizeof(PinWaveCyclicEventSet) / sizeof(KSEVENT_SET);
m_Descriptor.EventSet = PinWaveCyclicEventSet;
m_Descriptor.EventList = &m_EventList;
m_Descriptor.EventListLock = &m_EventListLock;
// release subdevice descriptor
Subdevice->Release();
@ -993,12 +1172,6 @@ CPortPinWaveCyclic::Init(
RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
PKSDATAFORMAT_WAVEFORMATEX Wave = (PKSDATAFORMAT_WAVEFORMATEX)m_Format;
DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", Wave->WaveFormatEx.wBitsPerSample, Wave->WaveFormatEx.nSamplesPerSec, Wave->WaveFormatEx.nChannels, Wave->WaveFormatEx.wFormatTag, m_FrameSize);
Port->AddRef();
Filter->AddRef();

View file

@ -316,6 +316,20 @@ PcHandlePropertyWithTable(
IN PKSPROPERTY_SET PropertySet,
IN PSUBDEVICE_DESCRIPTOR Descriptor);
NTSTATUS
NTAPI
PcHandleEnableEventWithTable(
IN PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor);
NTSTATUS
NTAPI
PcHandleDisableEventWithTable(
IN PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor);
#define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\
PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\
DEFINE_KSPROPERTY_TABLE(PinSet) {\

View file

@ -59,6 +59,34 @@ KsoGetIrpTargetFromIrp(
return (IIrpTarget*)CreateItem->Context;
}
NTSTATUS
NTAPI
PcHandleEnableEventWithTable(
IN PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor)
{
// store descriptor
KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
// FIXME seh probing
return KsEnableEvent(Irp, Descriptor->EventSetCount, Descriptor->EventSet, NULL, KSEVENTS_NONE, NULL);
}
NTSTATUS
NTAPI
PcHandleDisableEventWithTable(
IN PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR Descriptor)
{
// store descriptor
KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
// FIXME seh probing
return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock);
}
NTSTATUS
NTAPI
PcHandlePropertyWithTable(