2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp
5 * PURPOSE: WavePci IRP Audio Pin
6 * PROGRAMMER: Johannes Anderwald
11 class CPortPinWavePci
: public IPortPinWavePci
,
13 public IPortWavePciStream
16 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
18 STDMETHODIMP_(ULONG
) AddRef()
20 InterlockedIncrement(&m_Ref
);
23 STDMETHODIMP_(ULONG
) Release()
25 InterlockedDecrement(&m_Ref
);
36 IMP_IPortWavePciStream
;
37 CPortPinWavePci(IUnknown
*OuterUnknown
) {}
38 virtual ~CPortPinWavePci(){}
40 VOID NTAPI
SetState( IN KSSTATE State
);
41 VOID NTAPI
CloseStream();
44 friend NTSTATUS NTAPI
PinWavePciState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
45 friend NTSTATUS NTAPI
PinWavePciDataFormat(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
46 friend NTSTATUS NTAPI
PinWavePciAudioPosition(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
47 friend NTSTATUS NTAPI
PinWavePciAllocatorFraming(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
49 IPortWavePci
* m_Port
;
50 IPortFilterWavePci
* m_Filter
;
51 KSPIN_DESCRIPTOR
* m_KsPinDescriptor
;
52 PMINIPORTWAVEPCI m_Miniport
;
53 PSERVICEGROUP m_ServiceGroup
;
54 PDMACHANNEL m_DmaChannel
;
55 PMINIPORTWAVEPCISTREAM m_Stream
;
57 PKSDATAFORMAT m_Format
;
58 KSPIN_CONNECT
* m_ConnectDetails
;
61 PDEVICE_OBJECT m_DeviceObject
;
62 IIrpQueue
* m_IrpQueue
;
65 KSAUDIO_POSITION m_Position
;
71 ULONG m_PrefetchOffset
;
72 SUBDEVICE_DESCRIPTOR m_Descriptor
;
74 KSALLOCATOR_FRAMING m_AllocatorFraming
;
78 NTSTATUS NTAPI
HandleKsProperty(IN PIRP Irp
);
79 NTSTATUS NTAPI
HandleKsStream(IN PIRP Irp
);
82 VOID NTAPI
SetStreamState( IN KSSTATE State
);
88 PIO_WORKITEM WorkItem
;
90 }SETSTREAM_CONTEXT
, *PSETSTREAM_CONTEXT
;
92 NTSTATUS NTAPI
PinWavePciState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
93 NTSTATUS NTAPI
PinWavePciDataFormat(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
94 NTSTATUS NTAPI
PinWavePciAudioPosition(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
95 NTSTATUS NTAPI
PinWavePciAllocatorFraming(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
97 DEFINE_KSPROPERTY_CONNECTIONSET(PinWavePciConnectionSet
, PinWavePciState
, PinWavePciDataFormat
, PinWavePciAllocatorFraming
);
98 DEFINE_KSPROPERTY_AUDIOSET(PinWavePciAudioSet
, PinWavePciAudioPosition
);
100 KSPROPERTY_SET PinWavePciPropertySet
[] =
103 &KSPROPSETID_Connection
,
104 sizeof(PinWavePciConnectionSet
) / sizeof(KSPROPERTY_ITEM
),
105 (const KSPROPERTY_ITEM
*)&PinWavePciConnectionSet
,
111 sizeof(PinWavePciAudioSet
) / sizeof(KSPROPERTY_ITEM
),
112 (const KSPROPERTY_ITEM
*)&PinWavePciAudioSet
,
121 PinWavePciAllocatorFraming(
123 IN PKSIDENTIFIER Request
,
126 CPortPinWavePci
*Pin
;
127 PSUBDEVICE_DESCRIPTOR Descriptor
;
129 // get sub device descriptor
130 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
133 PC_ASSERT(Descriptor
);
134 PC_ASSERT(Descriptor
->PortPin
);
135 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
138 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
141 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
144 RtlMoveMemory(Data
, &Pin
->m_AllocatorFraming
, sizeof(KSALLOCATOR_FRAMING
));
146 Irp
->IoStatus
.Information
= sizeof(KSALLOCATOR_FRAMING
);
147 return STATUS_SUCCESS
;
151 return STATUS_NOT_SUPPORTED
;
156 PinWavePciAudioPosition(
158 IN PKSIDENTIFIER Request
,
161 CPortPinWavePci
*Pin
;
162 PSUBDEVICE_DESCRIPTOR Descriptor
;
164 // get sub device descriptor
165 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
168 PC_ASSERT(Descriptor
);
169 PC_ASSERT(Descriptor
->PortPin
);
170 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
173 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
176 PC_ASSERT(Pin
->m_Stream
);
178 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
180 // FIXME non multithreading-safe
181 // copy audio position
182 RtlMoveMemory(Data
, &Pin
->m_Position
, sizeof(KSAUDIO_POSITION
));
184 DPRINT("Play %lu Record %lu\n", Pin
->m_Position
.PlayOffset
, Pin
->m_Position
.WriteOffset
);
185 Irp
->IoStatus
.Information
= sizeof(KSAUDIO_POSITION
);
186 return STATUS_SUCCESS
;
190 return STATUS_NOT_SUPPORTED
;
198 IN PKSIDENTIFIER Request
,
201 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
202 CPortPinWavePci
*Pin
;
203 PSUBDEVICE_DESCRIPTOR Descriptor
;
204 PKSSTATE State
= (PKSSTATE
)Data
;
206 // get sub device descriptor
207 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
210 PC_ASSERT(Descriptor
);
211 PC_ASSERT(Descriptor
->PortPin
);
212 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
215 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
218 PC_ASSERT(Pin
->m_Stream
);
220 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
223 Status
= Pin
->m_Stream
->SetState(*State
);
225 DPRINT("Setting state %u %x\n", *State
, Status
);
226 if (NT_SUCCESS(Status
))
229 Pin
->m_State
= *State
;
232 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
235 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
237 // get current stream state
238 *State
= Pin
->m_State
;
240 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
242 return STATUS_SUCCESS
;
245 // unsupported request
246 return STATUS_NOT_SUPPORTED
;
251 PinWavePciDataFormat(
253 IN PKSIDENTIFIER Request
,
256 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
257 CPortPinWavePci
*Pin
;
258 PSUBDEVICE_DESCRIPTOR Descriptor
;
259 PIO_STACK_LOCATION IoStack
;
261 // get current irp stack location
262 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
264 // get sub device descriptor
265 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
268 PC_ASSERT(Descriptor
);
269 PC_ASSERT(Descriptor
->PortPin
);
272 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
275 PC_ASSERT(Pin
->m_Stream
);
276 PC_ASSERT(Pin
->m_Format
);
278 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
280 // try to change data format
281 PKSDATAFORMAT NewDataFormat
, DataFormat
= (PKSDATAFORMAT
)Irp
->UserBuffer
;
282 ULONG Size
= min(Pin
->m_Format
->FormatSize
, DataFormat
->FormatSize
);
284 if (RtlCompareMemory(DataFormat
, Pin
->m_Format
, Size
) == Size
)
286 // format is identical
287 Irp
->IoStatus
.Information
= DataFormat
->FormatSize
;
288 return STATUS_SUCCESS
;
291 // new change request
292 PC_ASSERT(Pin
->m_State
== KSSTATE_STOP
);
293 // FIXME queue a work item when Irql != PASSIVE_LEVEL
294 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
296 // allocate new data format
297 NewDataFormat
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
301 return STATUS_NO_MEMORY
;
304 // copy new data format
305 RtlMoveMemory(NewDataFormat
, DataFormat
, DataFormat
->FormatSize
);
308 Status
= Pin
->m_Stream
->SetFormat(NewDataFormat
);
309 if (NT_SUCCESS(Status
))
312 FreeItem(Pin
->m_Format
, TAG_PORTCLASS
);
314 // update irp queue with new format
315 Pin
->m_IrpQueue
->UpdateFormat((PKSDATAFORMAT
)NewDataFormat
);
318 Pin
->m_Format
= NewDataFormat
;
319 Irp
->IoStatus
.Information
= NewDataFormat
->FormatSize
;
322 PC_ASSERT(NewDataFormat
->FormatSize
== sizeof(KSDATAFORMAT_WAVEFORMATEX
));
323 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.MajorFormat
, KSDATAFORMAT_TYPE_AUDIO
));
324 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.SubFormat
, KSDATAFORMAT_SUBTYPE_PCM
));
325 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.Specifier
, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
));
328 DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nChannels
,
329 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.wBitsPerSample
,
330 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nSamplesPerSec
);
336 // failed to set format
337 FreeItem(NewDataFormat
, TAG_PORTCLASS
);
344 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
346 // get current data format
347 PC_ASSERT(Pin
->m_Format
);
349 if (Pin
->m_Format
->FormatSize
> IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
352 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
353 return STATUS_MORE_ENTRIES
;
356 RtlMoveMemory(Data
, Pin
->m_Format
, Pin
->m_Format
->FormatSize
);
358 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
361 return STATUS_SUCCESS
;
364 // unsupported request
365 return STATUS_NOT_SUPPORTED
;
369 //==================================================================================================================================
372 CPortPinWavePci::QueryInterface(
376 DPRINT("CPortPinWavePci::QueryInterface entered\n");
378 if (IsEqualGUIDAligned(refiid
, IID_IIrpTarget
) ||
379 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
381 *Output
= PVOID(PUNKNOWN((IIrpTarget
*)this));
382 PUNKNOWN(*Output
)->AddRef();
383 return STATUS_SUCCESS
;
386 if (IsEqualGUIDAligned(refiid
, IID_IServiceSink
))
388 *Output
= PVOID(PSERVICESINK(this));
389 PUNKNOWN(*Output
)->AddRef();
390 return STATUS_SUCCESS
;
394 if (IsEqualGUIDAligned(refiid
, IID_IPortWavePciStream
))
396 *Output
= PVOID(PPORTWAVEPCISTREAM(this));
397 PUNKNOWN(*Output
)->AddRef();
398 return STATUS_SUCCESS
;
401 return STATUS_UNSUCCESSFUL
;
406 CPortPinWavePci::GetMapping(
408 OUT PPHYSICAL_ADDRESS PhysicalAddress
,
409 OUT PVOID
*VirtualAddress
,
410 OUT PULONG ByteCount
,
414 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
415 return m_IrpQueue
->GetMappingWithTag(Tag
, PhysicalAddress
, VirtualAddress
, ByteCount
, Flags
);
420 CPortPinWavePci::ReleaseMapping(
424 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
425 return m_IrpQueue
->ReleaseMappingWithTag(Tag
);
430 CPortPinWavePci::TerminatePacket()
433 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
434 return STATUS_SUCCESS
;
439 CPortPinWavePci::SetState(KSSTATE State
)
441 ULONG MinimumDataThreshold
;
442 ULONG MaximumDataThreshold
;
444 // Has the audio stream resumed?
445 if (m_IrpQueue
->NumMappings() && State
== KSSTATE_STOP
)
449 if (NT_SUCCESS(m_Stream
->SetState(State
)))
451 // Save new internal state
454 if (m_State
== KSSTATE_STOP
)
456 // reset start stream
457 m_IrpQueue
->CancelBuffers(); //FIX function name
458 //This->ServiceGroup->lpVtbl->CancelDelayedService(This->ServiceGroup);
459 // increase stop counter
461 // get current data threshold
462 MinimumDataThreshold
= m_IrpQueue
->GetMinimumDataThreshold();
463 // get maximum data threshold
464 MaximumDataThreshold
= ((PKSDATAFORMAT_WAVEFORMATEX
)m_Format
)->WaveFormatEx
.nAvgBytesPerSec
;
465 // increase minimum data threshold by 10 frames
466 MinimumDataThreshold
+= m_AllocatorFraming
.FrameSize
* 10;
468 // assure it has not exceeded
469 MinimumDataThreshold
= min(MinimumDataThreshold
, MaximumDataThreshold
);
470 // store minimum data threshold
471 m_IrpQueue
->SetMinimumDataThreshold(MinimumDataThreshold
);
473 DPRINT("Stopping TotalCompleted %u StopCount %u MinimumDataThreshold %u\n", m_TotalPackets
, m_StopCount
, MinimumDataThreshold
);
475 if (m_State
== KSSTATE_RUN
)
477 // start the notification timer
478 //m_ServiceGroup->RequestDelayedService(m_ServiceGroup, m_Delay);
487 PinWavePciSetStreamWorkerRoutine(
488 IN PDEVICE_OBJECT DeviceObject
,
491 CPortPinWavePci
* This
;
492 PSETSTREAM_CONTEXT Ctx
= (PSETSTREAM_CONTEXT
)Context
;
498 IoFreeWorkItem(Ctx
->WorkItem
);
499 FreeItem(Ctx
, TAG_PORTCLASS
);
501 This
->SetState(State
);
506 CPortPinWavePci::SetStreamState(
509 PDEVICE_OBJECT DeviceObject
;
510 PIO_WORKITEM WorkItem
;
511 PSETSTREAM_CONTEXT Context
;
513 PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL
);
515 // Has the audio stream resumed?
516 if (m_IrpQueue
->NumMappings() && State
== KSSTATE_STOP
)
519 // Has the audio state already been set?
520 if (m_State
== State
)
524 DeviceObject
= GetDeviceObjectFromPortWavePci(m_Port
);
526 // allocate set state context
527 Context
= (PSETSTREAM_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(SETSTREAM_CONTEXT
), TAG_PORTCLASS
);
532 // allocate work item
533 WorkItem
= IoAllocateWorkItem(DeviceObject
);
542 Context
->WorkItem
= WorkItem
;
543 Context
->State
= State
;
545 // queue the work item
546 IoQueueWorkItem(WorkItem
, PinWavePciSetStreamWorkerRoutine
, DelayedWorkQueue
, (PVOID
)Context
);
552 CPortPinWavePci::RequestService()
554 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
556 if (m_IrpQueue
->HasLastMappingFailed())
558 if (m_IrpQueue
->NumMappings() == 0)
560 DPRINT("Stopping stream...\n");
561 SetStreamState(KSSTATE_STOP
);
571 //==================================================================================================================================
575 CPortPinWavePci::NewIrpTarget(
576 OUT
struct IIrpTarget
**OutTarget
,
579 IN POOL_TYPE PoolType
,
580 IN PDEVICE_OBJECT DeviceObject
,
582 IN KSOBJECT_CREATE
*CreateObject
)
586 Irp
->IoStatus
.Information
= 0;
587 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
588 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
590 return STATUS_UNSUCCESSFUL
;
595 CPortPinWavePci::HandleKsProperty(
598 PKSPROPERTY Property
;
600 UNICODE_STRING GuidString
;
601 PIO_STACK_LOCATION IoStack
;
603 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
605 DPRINT("IPortPinWave_HandleKsProperty entered\n");
607 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
609 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
611 DPRINT("Unhandled function %lx Length %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
613 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
615 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
616 return STATUS_SUCCESS
;
619 Status
= PcHandlePropertyWithTable(Irp
, m_Descriptor
.FilterPropertySetCount
, m_Descriptor
.FilterPropertySet
, &m_Descriptor
);
621 if (Status
== STATUS_NOT_FOUND
)
623 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
625 RtlStringFromGUID(Property
->Set
, &GuidString
);
626 DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
627 RtlFreeUnicodeString(&GuidString
);
630 if (Status
!= STATUS_PENDING
)
632 Irp
->IoStatus
.Status
= Status
;
633 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
640 else if (Property
->Id
== KSPROPERTY_CONNECTION_ALLOCATORFRAMING
)
642 PKSALLOCATOR_FRAMING Framing
= (PKSALLOCATOR_FRAMING
)OutputBuffer
;
644 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
645 // Validate input buffer
646 if (OutputBufferLength
< sizeof(KSALLOCATOR_FRAMING
))
648 IoStatusBlock
->Information
= sizeof(KSALLOCATOR_FRAMING
);
649 IoStatusBlock
->Status
= STATUS_BUFFER_TOO_SMALL
;
650 return STATUS_BUFFER_TOO_SMALL
;
652 // copy frame allocator struct
653 RtlMoveMemory(Framing
, &m_AllocatorFraming
, sizeof(KSALLOCATOR_FRAMING
));
655 IoStatusBlock
->Information
= sizeof(KSALLOCATOR_FRAMING
);
656 IoStatusBlock
->Status
= STATUS_SUCCESS
;
657 return STATUS_SUCCESS
;
664 CPortPinWavePci::HandleKsStream(
668 InterlockedIncrement((PLONG
)&m_TotalPackets
);
670 DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets
, m_State
, m_IrpQueue
->NumData());
672 Status
= m_IrpQueue
->AddMapping(NULL
, 0, Irp
);
674 if (NT_SUCCESS(Status
))
677 PKSSTREAM_HEADER Header
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
681 m_Position
.WriteOffset
+= Header
->FrameExtent
;
683 m_Position
.WriteOffset
+= Header
->DataUsed
;
688 return STATUS_PENDING
;
694 CPortPinWavePci::DeviceIoControl(
695 IN PDEVICE_OBJECT DeviceObject
,
698 PIO_STACK_LOCATION IoStack
;
700 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
702 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
704 return HandleKsProperty(Irp
);
706 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
|| IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
708 return HandleKsStream(Irp
);
713 Irp
->IoStatus
.Information
= 0;
714 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
715 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
717 return STATUS_UNSUCCESSFUL
;
722 CPortPinWavePci::Read(
723 IN PDEVICE_OBJECT DeviceObject
,
726 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
731 CPortPinWavePci::Write(
732 IN PDEVICE_OBJECT DeviceObject
,
735 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
740 CPortPinWavePci::Flush(
741 IN PDEVICE_OBJECT DeviceObject
,
744 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
749 CPortPinWavePci::CloseStream()
751 PMINIPORTWAVEPCISTREAM Stream
;
752 ISubdevice
*ISubDevice
;
754 PSUBDEVICE_DESCRIPTOR Descriptor
;
758 if (m_State
!= KSSTATE_STOP
)
760 m_Stream
->SetState(KSSTATE_STOP
);
766 m_ServiceGroup
->RemoveMember(PSERVICESINK(this));
769 Status
= m_Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&ISubDevice
);
770 if (NT_SUCCESS(Status
))
772 Status
= ISubDevice
->GetDescriptor(&Descriptor
);
773 if (NT_SUCCESS(Status
))
775 Descriptor
->Factory
.Instances
[m_ConnectDetails
->PinId
].CurrentPinInstanceCount
--;
777 ISubDevice
->Release();
782 ExFreePool(m_Format
);
790 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
797 PinWavePciCloseStreamRoutine(
798 IN PDEVICE_OBJECT DeviceObject
,
801 CPortPinWavePci
* This
;
802 PCLOSESTREAM_CONTEXT Ctx
= (PCLOSESTREAM_CONTEXT
)Context
;
804 This
= (CPortPinWavePci
*)Ctx
->Pin
;
809 Ctx
->Irp
->IoStatus
.Information
= 0;
810 Ctx
->Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
811 IoCompleteRequest(Ctx
->Irp
, IO_NO_INCREMENT
);
813 // free the work item
814 IoFreeWorkItem(Ctx
->WorkItem
);
816 // free work item ctx
817 FreeItem(Ctx
, TAG_PORTCLASS
);
822 CPortPinWavePci::Close(
823 IN PDEVICE_OBJECT DeviceObject
,
826 PCLOSESTREAM_CONTEXT Ctx
;
830 Ctx
= (PCLOSESTREAM_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(CLOSESTREAM_CONTEXT
), TAG_PORTCLASS
);
833 DPRINT("Failed to allocate stream context\n");
837 Ctx
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
840 DPRINT("Failed to allocate work item\n");
845 Ctx
->Pin
= (PVOID
)this;
847 IoMarkIrpPending(Irp
);
848 Irp
->IoStatus
.Information
= 0;
849 Irp
->IoStatus
.Status
= STATUS_PENDING
;
852 IoQueueWorkItem(Ctx
->WorkItem
, PinWavePciCloseStreamRoutine
, DelayedWorkQueue
, (PVOID
)Ctx
);
854 return STATUS_PENDING
;
857 Irp
->IoStatus
.Information
= 0;
858 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
859 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
861 return STATUS_SUCCESS
;
866 FreeItem(Ctx
, TAG_PORTCLASS
);
868 Irp
->IoStatus
.Information
= 0;
869 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
870 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
871 return STATUS_UNSUCCESSFUL
;
877 CPortPinWavePci::QuerySecurity(
878 IN PDEVICE_OBJECT DeviceObject
,
881 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
886 CPortPinWavePci::SetSecurity(
887 IN PDEVICE_OBJECT DeviceObject
,
890 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
895 CPortPinWavePci::FastDeviceIoControl(
896 IN PFILE_OBJECT FileObject
,
898 IN PVOID InputBuffer
,
899 IN ULONG InputBufferLength
,
900 OUT PVOID OutputBuffer
,
901 IN ULONG OutputBufferLength
,
902 IN ULONG IoControlCode
,
903 OUT PIO_STATUS_BLOCK StatusBlock
,
904 IN PDEVICE_OBJECT DeviceObject
)
911 CPortPinWavePci::FastRead(
912 IN PFILE_OBJECT FileObject
,
913 IN PLARGE_INTEGER FileOffset
,
918 OUT PIO_STATUS_BLOCK StatusBlock
,
919 IN PDEVICE_OBJECT DeviceObject
)
926 CPortPinWavePci::FastWrite(
927 IN PFILE_OBJECT FileObject
,
928 IN PLARGE_INTEGER FileOffset
,
933 OUT PIO_STATUS_BLOCK StatusBlock
,
934 IN PDEVICE_OBJECT DeviceObject
)
942 CPortPinWavePci::Init(
943 IN PPORTWAVEPCI Port
,
944 IN PPORTFILTERWAVEPCI Filter
,
945 IN KSPIN_CONNECT
* ConnectDetails
,
946 IN KSPIN_DESCRIPTOR
* KsPinDescriptor
,
947 IN PDEVICE_OBJECT DeviceObject
)
950 PKSDATAFORMAT DataFormat
;
958 m_KsPinDescriptor
= KsPinDescriptor
;
959 m_ConnectDetails
= ConnectDetails
;
960 m_Miniport
= GetWavePciMiniport(Port
);
961 m_DeviceObject
= DeviceObject
;
963 DataFormat
= (PKSDATAFORMAT
)(ConnectDetails
+ 1);
965 DPRINT("IPortPinWavePci_fnInit entered\n");
967 m_Format
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
969 return STATUS_INSUFFICIENT_RESOURCES
;
971 RtlMoveMemory(m_Format
, DataFormat
, DataFormat
->FormatSize
);
973 if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_IN
)
977 else if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_OUT
)
983 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor
->Communication
, KsPinDescriptor
->DataFlow
);
987 Status
= m_Miniport
->NewStream(&m_Stream
,
990 PPORTWAVEPCISTREAM(this),
991 ConnectDetails
->PinId
,
997 DPRINT("IPortPinWavePci_fnInit Status %x\n", Status
);
999 if (!NT_SUCCESS(Status
))
1004 Status
= m_ServiceGroup
->AddMember(PSERVICESINK(this));
1005 if (!NT_SUCCESS(Status
))
1007 DPRINT("Failed to add pin to service group\n");
1010 m_ServiceGroup
->SupportDelayedService();
1013 // delay of 10 milisec
1014 m_Delay
= Int32x32To64(10, -10000);
1016 Status
= m_Stream
->GetAllocatorFraming(&m_AllocatorFraming
);
1017 if (!NT_SUCCESS(Status
))
1019 DPRINT("GetAllocatorFraming failed with %x\n", Status
);
1023 DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n",
1024 m_AllocatorFraming
.OptionsFlags
, m_AllocatorFraming
.RequirementsFlags
, m_AllocatorFraming
.PoolType
, m_AllocatorFraming
.Frames
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
);
1026 ISubdevice
* Subdevice
= NULL
;
1027 // get subdevice interface
1028 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&Subdevice
);
1030 if (!NT_SUCCESS(Status
))
1033 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
= NULL
;
1035 Status
= Subdevice
->GetDescriptor(&SubDeviceDescriptor
);
1036 if (!NT_SUCCESS(Status
))
1038 // failed to get descriptor
1039 Subdevice
->Release();
1043 /* set up subdevice descriptor */
1044 RtlZeroMemory(&m_Descriptor
, sizeof(SUBDEVICE_DESCRIPTOR
));
1045 m_Descriptor
.FilterPropertySet
= PinWavePciPropertySet
;
1046 m_Descriptor
.FilterPropertySetCount
= sizeof(PinWavePciPropertySet
) / sizeof(KSPROPERTY_SET
);
1047 m_Descriptor
.UnknownStream
= (PUNKNOWN
)m_Stream
;
1048 m_Descriptor
.DeviceDescriptor
= SubDeviceDescriptor
->DeviceDescriptor
;
1049 m_Descriptor
.UnknownMiniport
= SubDeviceDescriptor
->UnknownMiniport
;
1050 m_Descriptor
.PortPin
= (PVOID
)this;
1054 Status
= NewIrpQueue(&m_IrpQueue
);
1055 if (!NT_SUCCESS(Status
))
1058 Status
= m_IrpQueue
->Init(ConnectDetails
, m_Format
, DeviceObject
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
, NULL
);
1059 if (!NT_SUCCESS(Status
))
1061 DPRINT("IrpQueue_Init failed with %x\n", Status
);
1065 m_State
= KSSTATE_STOP
;
1066 m_Capture
= Capture
;
1068 return STATUS_SUCCESS
;
1073 CPortPinWavePci::GetIrpStream()
1075 return (PVOID
)m_IrpQueue
;
1081 CPortPinWavePci::GetMiniport()
1083 return (PMINIPORT
)m_Miniport
;
1089 OUT IPortPinWavePci
** OutPin
)
1091 CPortPinWavePci
* This
;
1093 This
= new(NonPagedPool
, TAG_PORTCLASS
) CPortPinWavePci(NULL
);
1095 return STATUS_INSUFFICIENT_RESOURCES
;
1100 *OutPin
= (IPortPinWavePci
*)This
;
1102 return STATUS_SUCCESS
;