Author: janderwald
Date: Tue Nov 10 11:01:25 2009
New Revision: 44074
URL:
http://svn.reactos.org/svn/reactos?rev=44074&view=rev
Log:
[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
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp [iso-8859-1] Tue Nov 10
11:01:25 2009
@@ -80,6 +80,9 @@
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}};
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp [iso-8859-1] Tue Nov 10
11:01:25 2009
@@ -208,6 +208,11 @@
KSPIN_FACTORY Factory;
ULONG FilterPropertySetCount;
PKSPROPERTY_SET FilterPropertySet;
+
+ ULONG EventSetCount;
+ PKSEVENT_SET EventSet;
+ PLIST_ENTRY EventList;
+ PKSPIN_LOCK EventListLock;
PPCFILTER_DESCRIPTOR DeviceDescriptor;
KSTOPOLOGY* Topology;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] Tue
Nov 10 11:01:25 2009
@@ -41,6 +41,7 @@
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 @@
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 @@
KSALLOCATOR_FRAMING m_AllocatorFraming;
SUBDEVICE_DESCRIPTOR m_Descriptor;
+ KSPIN_LOCK m_EventListLock;
+ LIST_ENTRY m_EventList;
+
ULONG m_Delay;
LONG m_Ref;
@@ -84,18 +90,48 @@
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 @@
}
};
+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
@@ -141,6 +192,80 @@
}
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
@@ -154,7 +279,7 @@
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 @@
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 @@
NTSTATUS Status;
PUCHAR Buffer;
ULONG BufferSize;
+ ULONG OldCommonBufferOffset;
PC_ASSERT_IRQL(DISPATCH_LEVEL);
@@ -528,6 +706,8 @@
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 @@
{
UpdateCommonBuffer(Position, m_FrameSize);
}
+
+ GeneratePositionEvents(OldCommonBufferOffset, m_CommonBufferOffset);
}
NTSTATUS
@@ -569,16 +751,6 @@
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 @@
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status = STATUS_NOT_SUPPORTED;
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -639,13 +812,11 @@
}
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 @@
return KsDefaultDeviceIoCompletion(DeviceObject, Irp);
}
- UNIMPLEMENTED
-
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return STATUS_UNSUCCESSFUL;
+ if (Status != STATUS_PENDING)
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+
+ return Status;
}
NTSTATUS
@@ -912,8 +1083,8 @@
}
#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;
@@ -932,6 +1103,10 @@
Subdevice->Release();
return Status;
}
+
+ /* initialize event management */
+ InitializeListHead(&m_EventList);
+ KeInitializeSpinLock(&m_EventListLock);
/* set up subdevice descriptor */
RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR));
@@ -941,6 +1116,10 @@
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 @@
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();
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp [iso-8859-1] Tue Nov 10
11:01:25 2009
@@ -315,6 +315,20 @@
IN ULONG PropertySetCount,
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)\
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] Tue Nov 10
11:01:25 2009
@@ -58,6 +58,34 @@
// IIrpTarget is stored in Context member
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