2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
5 * PURPOSE: WaveCyclic IRP Audio Pin
6 * PROGRAMMER: Johannes Anderwald
11 class CPortPinWaveCyclic
: public IPortPinWaveCyclic
,
15 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
17 STDMETHODIMP_(ULONG
) AddRef()
19 InterlockedIncrement(&m_Ref
);
22 STDMETHODIMP_(ULONG
) Release()
24 InterlockedDecrement(&m_Ref
);
33 IMP_IPortPinWaveCyclic
;
35 CPortPinWaveCyclic(IUnknown
*OuterUnknown
){}
36 virtual ~CPortPinWaveCyclic(){}
38 VOID
SetState(KSSTATE State
);
42 VOID
UpdateCommonBuffer(ULONG Position
, ULONG MaxTransferCount
);
43 VOID
UpdateCommonBufferOverlap(ULONG Position
, ULONG MaxTransferCount
);
44 NTSTATUS NTAPI
HandleKsStream(IN PIRP Irp
);
45 NTSTATUS NTAPI
HandleKsProperty(IN PIRP Irp
);
48 friend NTSTATUS NTAPI
PinWaveCyclicState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
49 friend NTSTATUS NTAPI
PinWaveCyclicDataFormat(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
50 friend NTSTATUS NTAPI
PinWaveCyclicAudioPosition(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
51 friend NTSTATUS NTAPI
PinWaveCyclicAllocatorFraming(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
53 IPortWaveCyclic
* m_Port
;
54 IPortFilterWaveCyclic
* m_Filter
;
55 KSPIN_DESCRIPTOR
* m_KsPinDescriptor
;
56 PMINIPORTWAVECYCLIC m_Miniport
;
57 PSERVICEGROUP m_ServiceGroup
;
58 PDMACHANNEL m_DmaChannel
;
59 PMINIPORTWAVECYCLICSTREAM m_Stream
;
61 PKSDATAFORMAT m_Format
;
62 KSPIN_CONNECT
* m_ConnectDetails
;
65 ULONG m_CommonBufferSize
;
66 ULONG m_CommonBufferOffset
;
68 IIrpQueue
* m_IrpQueue
;
75 KSAUDIO_POSITION m_Position
;
76 KSALLOCATOR_FRAMING m_AllocatorFraming
;
77 SUBDEVICE_DESCRIPTOR m_Descriptor
;
87 CPortPinWaveCyclic
*Pin
;
88 PIO_WORKITEM WorkItem
;
90 }SETSTREAM_CONTEXT
, *PSETSTREAM_CONTEXT
;
92 NTSTATUS NTAPI
PinWaveCyclicState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
93 NTSTATUS NTAPI
PinWaveCyclicDataFormat(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
94 NTSTATUS NTAPI
PinWaveCyclicAudioPosition(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
95 NTSTATUS NTAPI
PinWaveCyclicAllocatorFraming(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
97 DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet
, PinWaveCyclicState
, PinWaveCyclicDataFormat
, PinWaveCyclicAllocatorFraming
);
98 DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet
, PinWaveCyclicAudioPosition
);
100 KSPROPERTY_SET PinWaveCyclicPropertySet
[] =
103 &KSPROPSETID_Connection
,
104 sizeof(PinWaveCyclicConnectionSet
) / sizeof(KSPROPERTY_ITEM
),
105 (const KSPROPERTY_ITEM
*)&PinWaveCyclicConnectionSet
,
111 sizeof(PinWaveCyclicAudioSet
) / sizeof(KSPROPERTY_ITEM
),
112 (const KSPROPERTY_ITEM
*)&PinWaveCyclicAudioSet
,
118 //==================================================================================================================================
122 CPortPinWaveCyclic::QueryInterface(
126 DPRINT("IServiceSink_fnQueryInterface entered\n");
128 if (IsEqualGUIDAligned(refiid
, IID_IIrpTarget
) ||
129 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
131 *Output
= PVOID(PUNKNOWN((IIrpTarget
*)this));
132 PUNKNOWN(*Output
)->AddRef();
133 return STATUS_SUCCESS
;
136 if (IsEqualGUIDAligned(refiid
, IID_IServiceSink
))
138 *Output
= PVOID(PUNKNOWN(PSERVICESINK(this)));
139 PUNKNOWN(*Output
)->AddRef();
140 return STATUS_SUCCESS
;
143 return STATUS_UNSUCCESSFUL
;
148 PinWaveCyclicAllocatorFraming(
150 IN PKSIDENTIFIER Request
,
153 CPortPinWaveCyclic
*Pin
;
154 PSUBDEVICE_DESCRIPTOR Descriptor
;
156 // get sub device descriptor
157 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
160 PC_ASSERT(Descriptor
);
161 PC_ASSERT(Descriptor
->PortPin
);
162 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
165 Pin
= (CPortPinWaveCyclic
*)Descriptor
->PortPin
;
168 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
171 RtlMoveMemory(Data
, &Pin
->m_AllocatorFraming
, sizeof(KSALLOCATOR_FRAMING
));
173 Irp
->IoStatus
.Information
= sizeof(KSALLOCATOR_FRAMING
);
174 return STATUS_SUCCESS
;
178 return STATUS_NOT_SUPPORTED
;
183 PinWaveCyclicAudioPosition(
185 IN PKSIDENTIFIER Request
,
188 CPortPinWaveCyclic
*Pin
;
189 PSUBDEVICE_DESCRIPTOR Descriptor
;
191 // get sub device descriptor
192 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
195 PC_ASSERT(Descriptor
);
196 PC_ASSERT(Descriptor
->PortPin
);
197 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
200 Pin
= (CPortPinWaveCyclic
*)Descriptor
->PortPin
;
203 PC_ASSERT(Pin
->m_Stream
);
205 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
207 // FIXME non multithreading-safe
208 // copy audio position
209 RtlMoveMemory(Data
, &Pin
->m_Position
, sizeof(KSAUDIO_POSITION
));
211 DPRINT("Play %lu Record %lu\n", Pin
->m_Position
.PlayOffset
, Pin
->m_Position
.WriteOffset
);
212 Irp
->IoStatus
.Information
= sizeof(KSAUDIO_POSITION
);
213 return STATUS_SUCCESS
;
217 return STATUS_NOT_SUPPORTED
;
225 IN PKSIDENTIFIER Request
,
228 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
229 CPortPinWaveCyclic
*Pin
;
230 PSUBDEVICE_DESCRIPTOR Descriptor
;
231 PKSSTATE State
= (PKSSTATE
)Data
;
233 // get sub device descriptor
234 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
237 PC_ASSERT(Descriptor
);
238 PC_ASSERT(Descriptor
->PortPin
);
239 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
242 Pin
= (CPortPinWaveCyclic
*)Descriptor
->PortPin
;
245 PC_ASSERT(Pin
->m_Stream
);
247 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
250 Status
= Pin
->m_Stream
->SetState(*State
);
252 DPRINT("Setting state %u %x\n", *State
, Status
);
253 if (NT_SUCCESS(Status
))
256 Pin
->m_State
= *State
;
259 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
262 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
264 // get current stream state
265 *State
= Pin
->m_State
;
267 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
269 return STATUS_SUCCESS
;
272 // unsupported request
273 return STATUS_NOT_SUPPORTED
;
278 PinWaveCyclicDataFormat(
280 IN PKSIDENTIFIER Request
,
283 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
284 CPortPinWaveCyclic
*Pin
;
285 PSUBDEVICE_DESCRIPTOR Descriptor
;
286 PIO_STACK_LOCATION IoStack
;
288 // get current irp stack location
289 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
291 // get sub device descriptor
292 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
295 PC_ASSERT(Descriptor
);
296 PC_ASSERT(Descriptor
->PortPin
);
299 Pin
= (CPortPinWaveCyclic
*)Descriptor
->PortPin
;
302 PC_ASSERT(Pin
->m_Stream
);
303 PC_ASSERT(Pin
->m_Format
);
305 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
307 // try to change data format
308 PKSDATAFORMAT NewDataFormat
, DataFormat
= (PKSDATAFORMAT
)Irp
->UserBuffer
;
309 ULONG Size
= min(Pin
->m_Format
->FormatSize
, DataFormat
->FormatSize
);
311 if (RtlCompareMemory(DataFormat
, Pin
->m_Format
, Size
) == Size
)
313 // format is identical
314 Irp
->IoStatus
.Information
= DataFormat
->FormatSize
;
315 return STATUS_SUCCESS
;
318 // new change request
319 PC_ASSERT(Pin
->m_State
== KSSTATE_STOP
);
320 // FIXME queue a work item when Irql != PASSIVE_LEVEL
321 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
323 // allocate new data format
324 NewDataFormat
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
328 return STATUS_NO_MEMORY
;
331 // copy new data format
332 RtlMoveMemory(NewDataFormat
, DataFormat
, DataFormat
->FormatSize
);
335 Status
= Pin
->m_Stream
->SetFormat(NewDataFormat
);
336 if (NT_SUCCESS(Status
))
339 FreeItem(Pin
->m_Format
, TAG_PORTCLASS
);
341 // update irp queue with new format
342 Pin
->m_IrpQueue
->UpdateFormat((PKSDATAFORMAT
)NewDataFormat
);
345 Pin
->m_Format
= NewDataFormat
;
346 Irp
->IoStatus
.Information
= NewDataFormat
->FormatSize
;
349 PC_ASSERT(NewDataFormat
->FormatSize
== sizeof(KSDATAFORMAT_WAVEFORMATEX
));
350 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.MajorFormat
, KSDATAFORMAT_TYPE_AUDIO
));
351 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.SubFormat
, KSDATAFORMAT_SUBTYPE_PCM
));
352 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.Specifier
, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
));
355 DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nChannels
,
356 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.wBitsPerSample
,
357 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nSamplesPerSec
);
363 // failed to set format
364 FreeItem(NewDataFormat
, TAG_PORTCLASS
);
371 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
373 // get current data format
374 PC_ASSERT(Pin
->m_Format
);
376 if (Pin
->m_Format
->FormatSize
> IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
379 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
380 return STATUS_MORE_ENTRIES
;
383 RtlMoveMemory(Data
, Pin
->m_Format
, Pin
->m_Format
->FormatSize
);
385 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
388 return STATUS_SUCCESS
;
391 // unsupported request
392 return STATUS_NOT_SUPPORTED
;
397 CPortPinWaveCyclic::UpdateCommonBuffer(
399 ULONG MaxTransferCount
)
407 BufferLength
= Position
- m_CommonBufferOffset
;
408 BufferLength
= min(BufferLength
, MaxTransferCount
);
412 Status
= m_IrpQueue
->GetMapping(&Buffer
, &BufferSize
);
413 if (!NT_SUCCESS(Status
))
416 BytesToCopy
= min(BufferLength
, BufferSize
);
420 m_DmaChannel
->CopyFrom(Buffer
, (PUCHAR
)m_CommonBuffer
+ m_CommonBufferOffset
, BytesToCopy
);
424 m_DmaChannel
->CopyTo((PUCHAR
)m_CommonBuffer
+ m_CommonBufferOffset
, Buffer
, BytesToCopy
);
427 m_IrpQueue
->UpdateMapping(BytesToCopy
);
428 m_CommonBufferOffset
+= BytesToCopy
;
430 BufferLength
= Position
- m_CommonBufferOffset
;
431 m_Position
.PlayOffset
+= BytesToCopy
;
436 CPortPinWaveCyclic::UpdateCommonBufferOverlap(
438 ULONG MaxTransferCount
)
440 ULONG BufferLength
, Length
, Gap
;
447 BufferLength
= Gap
= m_CommonBufferSize
- m_CommonBufferOffset
;
448 BufferLength
= Length
= min(BufferLength
, MaxTransferCount
);
451 Status
= m_IrpQueue
->GetMapping(&Buffer
, &BufferSize
);
452 if (!NT_SUCCESS(Status
))
455 BytesToCopy
= min(BufferLength
, BufferSize
);
459 m_DmaChannel
->CopyFrom(Buffer
,
460 (PUCHAR
)m_CommonBuffer
+ m_CommonBufferOffset
,
465 m_DmaChannel
->CopyTo((PUCHAR
)m_CommonBuffer
+ m_CommonBufferOffset
,
470 m_IrpQueue
->UpdateMapping(BytesToCopy
);
471 m_CommonBufferOffset
+= BytesToCopy
;
472 m_Position
.PlayOffset
+= BytesToCopy
;
474 BufferLength
= m_CommonBufferSize
- m_CommonBufferOffset
;
479 m_CommonBufferOffset
= 0;
481 MaxTransferCount
-= Length
;
483 if (MaxTransferCount
)
485 UpdateCommonBuffer(Position
, MaxTransferCount
);
492 CPortPinWaveCyclic::RequestService()
499 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
501 Status
= m_IrpQueue
->GetMapping(&Buffer
, &BufferSize
);
502 if (!NT_SUCCESS(Status
))
507 Status
= m_Stream
->GetPosition(&Position
);
508 DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position
, Buffer
, m_CommonBufferSize
, BufferSize
, m_Capture
);
510 if (Position
< m_CommonBufferOffset
)
512 UpdateCommonBufferOverlap(Position
, m_FrameSize
);
514 else if (Position
>= m_CommonBufferOffset
)
516 UpdateCommonBuffer(Position
, m_FrameSize
);
522 CPortPinWaveCyclic::NewIrpTarget(
523 OUT
struct IIrpTarget
**OutTarget
,
526 IN POOL_TYPE PoolType
,
527 IN PDEVICE_OBJECT DeviceObject
,
529 IN KSOBJECT_CREATE
*CreateObject
)
532 return STATUS_UNSUCCESSFUL
;
537 CPortPinWaveCyclic::HandleKsProperty(
540 PKSPROPERTY Property
;
542 UNICODE_STRING GuidString
;
543 PIO_STACK_LOCATION IoStack
;
545 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
547 DPRINT("IPortPinWave_HandleKsProperty entered\n");
549 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
551 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
553 DPRINT("Unhandled function %lx Length %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
555 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
557 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
558 return STATUS_SUCCESS
;
561 Status
= PcHandlePropertyWithTable(Irp
, m_Descriptor
.FilterPropertySetCount
, m_Descriptor
.FilterPropertySet
, &m_Descriptor
);
563 if (Status
== STATUS_NOT_FOUND
)
565 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
567 RtlStringFromGUID(Property
->Set
, &GuidString
);
568 DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
569 RtlFreeUnicodeString(&GuidString
);
572 if (Status
!= STATUS_PENDING
)
574 Irp
->IoStatus
.Status
= Status
;
575 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
583 CPortPinWaveCyclic::HandleKsStream(
587 InterlockedIncrement((PLONG
)&m_TotalPackets
);
589 DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets
, m_State
, m_IrpQueue
->NumData());
591 Status
= m_IrpQueue
->AddMapping(NULL
, 0, Irp
);
593 if (NT_SUCCESS(Status
))
596 PKSSTREAM_HEADER Header
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
600 m_Position
.WriteOffset
+= Header
->FrameExtent
;
602 m_Position
.WriteOffset
+= Header
->DataUsed
;
604 return STATUS_PENDING
;
613 CPortPinWaveCyclic::DeviceIoControl(
614 IN PDEVICE_OBJECT DeviceObject
,
617 PIO_STACK_LOCATION IoStack
;
619 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
622 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
624 return HandleKsProperty(Irp
);
626 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_ENABLE_EVENT
)
629 /// handle enable event
631 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_DISABLE_EVENT
)
634 /// handle disable event
636 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_RESET_STATE
)
639 /// handle reset state
641 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
|| IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
643 return HandleKsStream(Irp
);
647 return KsDefaultDeviceIoCompletion(DeviceObject
, Irp
);
652 Irp
->IoStatus
.Information
= 0;
653 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
654 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
656 return STATUS_UNSUCCESSFUL
;
661 CPortPinWaveCyclic::Read(
662 IN PDEVICE_OBJECT DeviceObject
,
665 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
670 CPortPinWaveCyclic::Write(
671 IN PDEVICE_OBJECT DeviceObject
,
674 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
679 CPortPinWaveCyclic::Flush(
680 IN PDEVICE_OBJECT DeviceObject
,
683 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
688 CPortPinWaveCyclic::Close(
689 IN PDEVICE_OBJECT DeviceObject
,
692 DPRINT("CPortPinWaveCyclic::Close entered\n");
694 PC_ASSERT_IRQL(PASSIVE_LEVEL
);
699 ExFreePool(m_Format
);
706 m_IrpQueue
->Release();
712 // release reference to port driver
719 // remove member from service group
720 m_ServiceGroup
->RemoveMember(PSERVICESINK(this));
721 m_ServiceGroup
= NULL
;
726 if (m_State
!= KSSTATE_STOP
)
729 NTSTATUS Status
= m_Stream
->SetState(KSSTATE_STOP
);
730 if (!NT_SUCCESS(Status
))
732 DPRINT("Warning: failed to stop stream with %x\n", Status
);
737 m_State
= KSSTATE_STOP
;
740 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
749 // release reference to filter instance
750 m_Filter
->FreePin((PPORTPINWAVECYCLIC
)this);
755 Irp
->IoStatus
.Information
= 0;
756 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
757 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
761 return STATUS_SUCCESS
;
766 CPortPinWaveCyclic::QuerySecurity(
767 IN PDEVICE_OBJECT DeviceObject
,
770 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
775 CPortPinWaveCyclic::SetSecurity(
776 IN PDEVICE_OBJECT DeviceObject
,
779 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
784 CPortPinWaveCyclic::FastDeviceIoControl(
785 IN PFILE_OBJECT FileObject
,
787 IN PVOID InputBuffer
,
788 IN ULONG InputBufferLength
,
789 OUT PVOID OutputBuffer
,
790 IN ULONG OutputBufferLength
,
791 IN ULONG IoControlCode
,
792 OUT PIO_STATUS_BLOCK StatusBlock
,
793 IN PDEVICE_OBJECT DeviceObject
)
795 return KsDispatchFastIoDeviceControlFailure(FileObject
, Wait
, InputBuffer
, InputBufferLength
, OutputBuffer
, OutputBufferLength
, IoControlCode
, StatusBlock
, DeviceObject
);
801 CPortPinWaveCyclic::FastRead(
802 IN PFILE_OBJECT FileObject
,
803 IN PLARGE_INTEGER FileOffset
,
808 OUT PIO_STATUS_BLOCK StatusBlock
,
809 IN PDEVICE_OBJECT DeviceObject
)
811 return KsDispatchFastReadFailure(FileObject
, FileOffset
, Length
, Wait
, LockKey
, Buffer
, StatusBlock
, DeviceObject
);
817 CPortPinWaveCyclic::FastWrite(
818 IN PFILE_OBJECT FileObject
,
819 IN PLARGE_INTEGER FileOffset
,
824 OUT PIO_STATUS_BLOCK StatusBlock
,
825 IN PDEVICE_OBJECT DeviceObject
)
827 return KsDispatchFastReadFailure(FileObject
, FileOffset
, Length
, Wait
, LockKey
, Buffer
, StatusBlock
, DeviceObject
);
833 CPortPinWaveCyclic::Init(
834 IN PPORTWAVECYCLIC Port
,
835 IN PPORTFILTERWAVECYCLIC Filter
,
836 IN KSPIN_CONNECT
* ConnectDetails
,
837 IN KSPIN_DESCRIPTOR
* KsPinDescriptor
)
840 PKSDATAFORMAT DataFormat
;
841 PDEVICE_OBJECT DeviceObject
;
844 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
= NULL
;
845 //IDrmAudioStream * DrmAudio = NULL;
847 m_KsPinDescriptor
= KsPinDescriptor
;
848 m_ConnectDetails
= ConnectDetails
;
849 m_Miniport
= GetWaveCyclicMiniport(Port
);
851 DeviceObject
= GetDeviceObject(Port
);
853 DataFormat
= (PKSDATAFORMAT
)(ConnectDetails
+ 1);
855 DPRINT("CPortPinWaveCyclic::Init entered Size %u\n", DataFormat
->FormatSize
);
857 Status
= NewIrpQueue(&m_IrpQueue
);
858 if (!NT_SUCCESS(Status
))
861 if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_IN
)
865 else if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_OUT
)
871 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor
->Communication
, KsPinDescriptor
->DataFlow
);
877 Status
= m_Miniport
->NewStream(&m_Stream
,
880 ConnectDetails
->PinId
,
886 Status
= m_Stream
->QueryInterface(IID_IDrmAudioStream
, (PVOID
*)&DrmAudio
);
887 if (NT_SUCCESS(Status
))
890 DPRINT("Got IID_IDrmAudioStream interface %p\n", DrmAudio
);
892 DrmRights
.CopyProtect
= FALSE
;
893 DrmRights
.Reserved
= 0;
894 DrmRights
.DigitalOutputDisable
= FALSE
;
896 Status
= DrmAudio
->SetContentId(1, &DrmRights
);
897 DPRINT("Status %x\n", Status
);
901 DPRINT("CPortPinWaveCyclic::Init Status %x\n", Status
);
903 if (!NT_SUCCESS(Status
))
906 ISubdevice
* Subdevice
= NULL
;
907 // get subdevice interface
908 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&Subdevice
);
910 if (!NT_SUCCESS(Status
))
913 Status
= Subdevice
->GetDescriptor(&SubDeviceDescriptor
);
914 if (!NT_SUCCESS(Status
))
916 // failed to get descriptor
917 Subdevice
->Release();
921 /* set up subdevice descriptor */
922 RtlZeroMemory(&m_Descriptor
, sizeof(SUBDEVICE_DESCRIPTOR
));
923 m_Descriptor
.FilterPropertySet
= PinWaveCyclicPropertySet
;
924 m_Descriptor
.FilterPropertySetCount
= sizeof(PinWaveCyclicPropertySet
) / sizeof(KSPROPERTY_SET
);
925 m_Descriptor
.UnknownStream
= (PUNKNOWN
)m_Stream
;
926 m_Descriptor
.DeviceDescriptor
= SubDeviceDescriptor
->DeviceDescriptor
;
927 m_Descriptor
.UnknownMiniport
= SubDeviceDescriptor
->UnknownMiniport
;
928 m_Descriptor
.PortPin
= (PVOID
)this;
930 // release subdevice descriptor
931 Subdevice
->Release();
933 // add ourselves to service group
934 Status
= m_ServiceGroup
->AddMember(PSERVICESINK(this));
935 if (!NT_SUCCESS(Status
))
937 DPRINT("Failed to add pin to service group\n");
941 m_ServiceGroup
->SupportDelayedService();
942 m_Stream
->SetState(KSSTATE_STOP
);
943 m_State
= KSSTATE_STOP
;
944 m_CommonBufferOffset
= 0;
945 m_CommonBufferSize
= m_DmaChannel
->AllocatedBufferSize();
946 m_CommonBuffer
= m_DmaChannel
->SystemAddress();
948 // delay of 10 milisec
949 m_Delay
= Int32x32To64(10, -10000);
951 Status
= m_Stream
->SetNotificationFreq(10, &m_FrameSize
);
953 SilenceBuffer
= AllocateItem(NonPagedPool
, m_FrameSize
, TAG_PORTCLASS
);
955 return STATUS_INSUFFICIENT_RESOURCES
;
958 /* set up allocator framing */
959 m_AllocatorFraming
.RequirementsFlags
= KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY
| KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY
;
960 m_AllocatorFraming
.PoolType
= NonPagedPool
;
961 m_AllocatorFraming
.Frames
= 8;
962 m_AllocatorFraming
.FileAlignment
= FILE_64_BYTE_ALIGNMENT
;
963 m_AllocatorFraming
.Reserved
= 0;
964 m_AllocatorFraming
.FrameSize
= m_FrameSize
;
966 m_Stream
->Silence(SilenceBuffer
, m_FrameSize
);
968 Status
= m_IrpQueue
->Init(ConnectDetails
, DataFormat
, DeviceObject
, m_FrameSize
, 0, SilenceBuffer
);
969 if (!NT_SUCCESS(Status
))
971 m_IrpQueue
->Release();
975 m_Format
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
977 return STATUS_INSUFFICIENT_RESOURCES
;
979 RtlMoveMemory(m_Format
, DataFormat
, DataFormat
->FormatSize
);
981 PKSDATAFORMAT_WAVEFORMATEX Wave
= (PKSDATAFORMAT_WAVEFORMATEX
)m_Format
;
983 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
);
993 DPRINT("Setting state to acquire %x\n", m_Stream
->SetState(KSSTATE_ACQUIRE
));
994 DPRINT("Setting state to pause %x\n", m_Stream
->SetState(KSSTATE_PAUSE
));
996 return STATUS_SUCCESS
;
1002 CPortPinWaveCyclic::GetCompletedPosition()
1011 CPortPinWaveCyclic::GetCycleCount()
1020 CPortPinWaveCyclic::GetDeviceBufferSize()
1022 return m_CommonBufferSize
;
1028 CPortPinWaveCyclic::GetIrpStream()
1030 return (PVOID
)m_IrpQueue
;
1036 CPortPinWaveCyclic::GetMiniport()
1038 return (PMINIPORT
)m_Miniport
;
1043 NewPortPinWaveCyclic(
1044 OUT IPortPinWaveCyclic
** OutPin
)
1046 CPortPinWaveCyclic
* This
;
1048 This
= new(NonPagedPool
, TAG_PORTCLASS
)CPortPinWaveCyclic(NULL
);
1050 return STATUS_INSUFFICIENT_RESOURCES
;
1055 *OutPin
= (IPortPinWaveCyclic
*)This
;
1057 return STATUS_SUCCESS
;