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(
669 InterlockedIncrement((PLONG
)&m_TotalPackets
);
671 DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets
, m_State
, m_IrpQueue
->NumData());
673 Status
= m_IrpQueue
->AddMapping(Irp
, &Data
);
675 if (NT_SUCCESS(Status
))
678 m_Position
.WriteOffset
+= Data
;
680 m_Position
.WriteOffset
+= Data
;
682 return STATUS_PENDING
;
691 CPortPinWavePci::DeviceIoControl(
692 IN PDEVICE_OBJECT DeviceObject
,
695 PIO_STACK_LOCATION IoStack
;
697 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
699 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
701 return HandleKsProperty(Irp
);
703 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
|| IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
705 return HandleKsStream(Irp
);
710 Irp
->IoStatus
.Information
= 0;
711 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
712 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
714 return STATUS_UNSUCCESSFUL
;
719 CPortPinWavePci::Read(
720 IN PDEVICE_OBJECT DeviceObject
,
723 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
728 CPortPinWavePci::Write(
729 IN PDEVICE_OBJECT DeviceObject
,
732 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
737 CPortPinWavePci::Flush(
738 IN PDEVICE_OBJECT DeviceObject
,
741 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
746 CPortPinWavePci::CloseStream()
748 PMINIPORTWAVEPCISTREAM Stream
;
749 ISubdevice
*ISubDevice
;
751 PSUBDEVICE_DESCRIPTOR Descriptor
;
755 if (m_State
!= KSSTATE_STOP
)
757 m_Stream
->SetState(KSSTATE_STOP
);
763 m_ServiceGroup
->RemoveMember(PSERVICESINK(this));
766 Status
= m_Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&ISubDevice
);
767 if (NT_SUCCESS(Status
))
769 Status
= ISubDevice
->GetDescriptor(&Descriptor
);
770 if (NT_SUCCESS(Status
))
772 Descriptor
->Factory
.Instances
[m_ConnectDetails
->PinId
].CurrentPinInstanceCount
--;
774 ISubDevice
->Release();
779 ExFreePool(m_Format
);
787 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
794 PinWavePciCloseStreamRoutine(
795 IN PDEVICE_OBJECT DeviceObject
,
798 CPortPinWavePci
* This
;
799 PCLOSESTREAM_CONTEXT Ctx
= (PCLOSESTREAM_CONTEXT
)Context
;
801 This
= (CPortPinWavePci
*)Ctx
->Pin
;
806 Ctx
->Irp
->IoStatus
.Information
= 0;
807 Ctx
->Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
808 IoCompleteRequest(Ctx
->Irp
, IO_NO_INCREMENT
);
810 // free the work item
811 IoFreeWorkItem(Ctx
->WorkItem
);
813 // free work item ctx
814 FreeItem(Ctx
, TAG_PORTCLASS
);
819 CPortPinWavePci::Close(
820 IN PDEVICE_OBJECT DeviceObject
,
823 PCLOSESTREAM_CONTEXT Ctx
;
827 Ctx
= (PCLOSESTREAM_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(CLOSESTREAM_CONTEXT
), TAG_PORTCLASS
);
830 DPRINT("Failed to allocate stream context\n");
834 Ctx
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
837 DPRINT("Failed to allocate work item\n");
842 Ctx
->Pin
= (PVOID
)this;
844 IoMarkIrpPending(Irp
);
845 Irp
->IoStatus
.Information
= 0;
846 Irp
->IoStatus
.Status
= STATUS_PENDING
;
849 IoQueueWorkItem(Ctx
->WorkItem
, PinWavePciCloseStreamRoutine
, DelayedWorkQueue
, (PVOID
)Ctx
);
851 return STATUS_PENDING
;
854 Irp
->IoStatus
.Information
= 0;
855 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
856 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
858 return STATUS_SUCCESS
;
863 FreeItem(Ctx
, TAG_PORTCLASS
);
865 Irp
->IoStatus
.Information
= 0;
866 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
867 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
868 return STATUS_UNSUCCESSFUL
;
874 CPortPinWavePci::QuerySecurity(
875 IN PDEVICE_OBJECT DeviceObject
,
878 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
883 CPortPinWavePci::SetSecurity(
884 IN PDEVICE_OBJECT DeviceObject
,
887 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
892 CPortPinWavePci::FastDeviceIoControl(
893 IN PFILE_OBJECT FileObject
,
895 IN PVOID InputBuffer
,
896 IN ULONG InputBufferLength
,
897 OUT PVOID OutputBuffer
,
898 IN ULONG OutputBufferLength
,
899 IN ULONG IoControlCode
,
900 OUT PIO_STATUS_BLOCK StatusBlock
,
901 IN PDEVICE_OBJECT DeviceObject
)
908 CPortPinWavePci::FastRead(
909 IN PFILE_OBJECT FileObject
,
910 IN PLARGE_INTEGER FileOffset
,
915 OUT PIO_STATUS_BLOCK StatusBlock
,
916 IN PDEVICE_OBJECT DeviceObject
)
923 CPortPinWavePci::FastWrite(
924 IN PFILE_OBJECT FileObject
,
925 IN PLARGE_INTEGER FileOffset
,
930 OUT PIO_STATUS_BLOCK StatusBlock
,
931 IN PDEVICE_OBJECT DeviceObject
)
939 CPortPinWavePci::Init(
940 IN PPORTWAVEPCI Port
,
941 IN PPORTFILTERWAVEPCI Filter
,
942 IN KSPIN_CONNECT
* ConnectDetails
,
943 IN KSPIN_DESCRIPTOR
* KsPinDescriptor
,
944 IN PDEVICE_OBJECT DeviceObject
)
947 PKSDATAFORMAT DataFormat
;
955 m_KsPinDescriptor
= KsPinDescriptor
;
956 m_ConnectDetails
= ConnectDetails
;
957 m_Miniport
= GetWavePciMiniport(Port
);
958 m_DeviceObject
= DeviceObject
;
960 DataFormat
= (PKSDATAFORMAT
)(ConnectDetails
+ 1);
962 DPRINT("IPortPinWavePci_fnInit entered\n");
964 m_Format
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
966 return STATUS_INSUFFICIENT_RESOURCES
;
968 RtlMoveMemory(m_Format
, DataFormat
, DataFormat
->FormatSize
);
970 if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_IN
)
974 else if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_OUT
)
980 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor
->Communication
, KsPinDescriptor
->DataFlow
);
985 Status
= m_Miniport
->NewStream(&m_Stream
,
988 PPORTWAVEPCISTREAM(this),
989 ConnectDetails
->PinId
,
995 DPRINT("IPortPinWavePci_fnInit Status %x\n", Status
);
997 if (!NT_SUCCESS(Status
))
1002 Status
= m_ServiceGroup
->AddMember(PSERVICESINK(this));
1003 if (!NT_SUCCESS(Status
))
1005 DPRINT("Failed to add pin to service group\n");
1008 m_ServiceGroup
->SupportDelayedService();
1011 // delay of 10 milisec
1012 m_Delay
= Int32x32To64(10, -10000);
1014 Status
= m_Stream
->GetAllocatorFraming(&m_AllocatorFraming
);
1015 if (!NT_SUCCESS(Status
))
1017 DPRINT("GetAllocatorFraming failed with %x\n", Status
);
1021 DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n",
1022 m_AllocatorFraming
.OptionsFlags
, m_AllocatorFraming
.RequirementsFlags
, m_AllocatorFraming
.PoolType
, m_AllocatorFraming
.Frames
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
);
1024 ISubdevice
* Subdevice
= NULL
;
1025 // get subdevice interface
1026 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&Subdevice
);
1028 if (!NT_SUCCESS(Status
))
1031 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
= NULL
;
1033 Status
= Subdevice
->GetDescriptor(&SubDeviceDescriptor
);
1034 if (!NT_SUCCESS(Status
))
1036 // failed to get descriptor
1037 Subdevice
->Release();
1041 /* set up subdevice descriptor */
1042 RtlZeroMemory(&m_Descriptor
, sizeof(SUBDEVICE_DESCRIPTOR
));
1043 m_Descriptor
.FilterPropertySet
= PinWavePciPropertySet
;
1044 m_Descriptor
.FilterPropertySetCount
= sizeof(PinWavePciPropertySet
) / sizeof(KSPROPERTY_SET
);
1045 m_Descriptor
.UnknownStream
= (PUNKNOWN
)m_Stream
;
1046 m_Descriptor
.DeviceDescriptor
= SubDeviceDescriptor
->DeviceDescriptor
;
1047 m_Descriptor
.UnknownMiniport
= SubDeviceDescriptor
->UnknownMiniport
;
1048 m_Descriptor
.PortPin
= (PVOID
)this;
1052 Status
= NewIrpQueue(&m_IrpQueue
);
1053 if (!NT_SUCCESS(Status
))
1056 Status
= m_IrpQueue
->Init(ConnectDetails
, m_Format
, DeviceObject
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
, NULL
);
1057 if (!NT_SUCCESS(Status
))
1059 DPRINT("IrpQueue_Init failed with %x\n", Status
);
1063 m_State
= KSSTATE_STOP
;
1064 m_Capture
= Capture
;
1066 return STATUS_SUCCESS
;
1071 CPortPinWavePci::GetIrpStream()
1073 return (PVOID
)m_IrpQueue
;
1079 CPortPinWavePci::GetMiniport()
1081 return (PMINIPORT
)m_Miniport
;
1087 OUT IPortPinWavePci
** OutPin
)
1089 CPortPinWavePci
* This
;
1091 This
= new(NonPagedPool
, TAG_PORTCLASS
) CPortPinWavePci(NULL
);
1093 return STATUS_INSUFFICIENT_RESOURCES
;
1098 *OutPin
= (IPortPinWavePci
*)This
;
1100 return STATUS_SUCCESS
;