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(){}
41 friend NTSTATUS NTAPI
PinWavePciState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
42 friend NTSTATUS NTAPI
PinWavePciDataFormat(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
43 friend NTSTATUS NTAPI
PinWavePciAudioPosition(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
44 friend NTSTATUS NTAPI
PinWavePciAllocatorFraming(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
46 IPortWavePci
* m_Port
;
47 IPortFilterWavePci
* m_Filter
;
48 KSPIN_DESCRIPTOR
* m_KsPinDescriptor
;
49 PMINIPORTWAVEPCI m_Miniport
;
50 PSERVICEGROUP m_ServiceGroup
;
51 PDMACHANNEL m_DmaChannel
;
52 PMINIPORTWAVEPCISTREAM m_Stream
;
54 PKSDATAFORMAT m_Format
;
55 KSPIN_CONNECT
* m_ConnectDetails
;
58 PDEVICE_OBJECT m_DeviceObject
;
59 IIrpQueue
* m_IrpQueue
;
62 KSAUDIO_POSITION m_Position
;
65 ULONG m_PrefetchOffset
;
66 SUBDEVICE_DESCRIPTOR m_Descriptor
;
68 KSALLOCATOR_FRAMING m_AllocatorFraming
;
72 NTSTATUS NTAPI
HandleKsProperty(IN PIRP Irp
);
73 NTSTATUS NTAPI
HandleKsStream(IN PIRP Irp
);
79 PIO_WORKITEM WorkItem
;
81 }SETSTREAM_CONTEXT
, *PSETSTREAM_CONTEXT
;
83 NTSTATUS NTAPI
PinWavePciState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
84 NTSTATUS NTAPI
PinWavePciDataFormat(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
85 NTSTATUS NTAPI
PinWavePciAudioPosition(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
86 NTSTATUS NTAPI
PinWavePciAllocatorFraming(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
88 DEFINE_KSPROPERTY_CONNECTIONSET(PinWavePciConnectionSet
, PinWavePciState
, PinWavePciDataFormat
, PinWavePciAllocatorFraming
);
89 DEFINE_KSPROPERTY_AUDIOSET(PinWavePciAudioSet
, PinWavePciAudioPosition
);
91 KSPROPERTY_SET PinWavePciPropertySet
[] =
94 &KSPROPSETID_Connection
,
95 sizeof(PinWavePciConnectionSet
) / sizeof(KSPROPERTY_ITEM
),
96 (const KSPROPERTY_ITEM
*)&PinWavePciConnectionSet
,
102 sizeof(PinWavePciAudioSet
) / sizeof(KSPROPERTY_ITEM
),
103 (const KSPROPERTY_ITEM
*)&PinWavePciAudioSet
,
112 PinWavePciAllocatorFraming(
114 IN PKSIDENTIFIER Request
,
117 CPortPinWavePci
*Pin
;
118 PSUBDEVICE_DESCRIPTOR Descriptor
;
120 // get sub device descriptor
121 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
124 PC_ASSERT(Descriptor
);
125 PC_ASSERT(Descriptor
->PortPin
);
126 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
129 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
132 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
135 RtlMoveMemory(Data
, &Pin
->m_AllocatorFraming
, sizeof(KSALLOCATOR_FRAMING
));
137 Irp
->IoStatus
.Information
= sizeof(KSALLOCATOR_FRAMING
);
138 return STATUS_SUCCESS
;
142 return STATUS_NOT_SUPPORTED
;
147 PinWavePciAudioPosition(
149 IN PKSIDENTIFIER Request
,
152 CPortPinWavePci
*Pin
;
153 PSUBDEVICE_DESCRIPTOR Descriptor
;
155 // get sub device descriptor
156 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
159 PC_ASSERT(Descriptor
);
160 PC_ASSERT(Descriptor
->PortPin
);
161 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
164 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
167 PC_ASSERT(Pin
->m_Stream
);
169 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
171 // FIXME non multithreading-safe
172 // copy audio position
173 RtlMoveMemory(Data
, &Pin
->m_Position
, sizeof(KSAUDIO_POSITION
));
175 DPRINT("Play %lu Record %lu\n", Pin
->m_Position
.PlayOffset
, Pin
->m_Position
.WriteOffset
);
176 Irp
->IoStatus
.Information
= sizeof(KSAUDIO_POSITION
);
177 return STATUS_SUCCESS
;
181 return STATUS_NOT_SUPPORTED
;
189 IN PKSIDENTIFIER Request
,
192 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
193 CPortPinWavePci
*Pin
;
194 PSUBDEVICE_DESCRIPTOR Descriptor
;
195 PVOID FirstTag
, LastTag
;
196 ULONG MappingsRevoked
;
197 PKSSTATE State
= (PKSSTATE
)Data
;
199 // get sub device descriptor
200 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
203 PC_ASSERT(Descriptor
);
204 PC_ASSERT(Descriptor
->PortPin
);
205 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
208 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
211 PC_ASSERT(Pin
->m_Stream
);
213 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
216 Status
= Pin
->m_Stream
->SetState(*State
);
218 DPRINT("Setting state %u %x\n", *State
, Status
);
219 if (NT_SUCCESS(Status
))
222 Pin
->m_State
= *State
;
223 if (Pin
->m_ConnectDetails
->Interface
.Id
== KSINTERFACE_STANDARD_LOOPED_STREAMING
&& Pin
->m_State
== KSSTATE_STOP
)
226 // complete with successful state
227 Pin
->m_IrpQueue
->CancelBuffers();
228 while(Pin
->m_IrpQueue
->GetAcquiredTagRange(&FirstTag
, &LastTag
))
230 Status
= Pin
->m_Stream
->RevokeMappings(FirstTag
, LastTag
, &MappingsRevoked
);
231 DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status
, MappingsRevoked
);
232 KeStallExecutionProcessor(10);
234 Pin
->m_Position
.PlayOffset
= 0;
235 Pin
->m_Position
.WriteOffset
= 0;
237 else if (Pin
->m_State
== KSSTATE_STOP
)
239 Pin
->m_IrpQueue
->CancelBuffers();
240 while(Pin
->m_IrpQueue
->GetAcquiredTagRange(&FirstTag
, &LastTag
))
242 Status
= Pin
->m_Stream
->RevokeMappings(FirstTag
, LastTag
, &MappingsRevoked
);
243 DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status
, MappingsRevoked
);
244 KeStallExecutionProcessor(10);
246 Pin
->m_Position
.PlayOffset
= 0;
247 Pin
->m_Position
.WriteOffset
= 0;
250 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
254 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
257 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
259 // get current stream state
260 *State
= Pin
->m_State
;
262 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
264 return STATUS_SUCCESS
;
267 // unsupported request
268 return STATUS_NOT_SUPPORTED
;
273 PinWavePciDataFormat(
275 IN PKSIDENTIFIER Request
,
278 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
279 CPortPinWavePci
*Pin
;
280 PSUBDEVICE_DESCRIPTOR Descriptor
;
281 PIO_STACK_LOCATION IoStack
;
283 // get current irp stack location
284 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
286 // get sub device descriptor
287 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
290 PC_ASSERT(Descriptor
);
291 PC_ASSERT(Descriptor
->PortPin
);
294 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
297 PC_ASSERT(Pin
->m_Stream
);
298 PC_ASSERT(Pin
->m_Format
);
300 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
302 // try to change data format
303 PKSDATAFORMAT NewDataFormat
, DataFormat
= (PKSDATAFORMAT
)Irp
->UserBuffer
;
304 ULONG Size
= min(Pin
->m_Format
->FormatSize
, DataFormat
->FormatSize
);
306 if (RtlCompareMemory(DataFormat
, Pin
->m_Format
, Size
) == Size
)
308 // format is identical
309 Irp
->IoStatus
.Information
= DataFormat
->FormatSize
;
310 return STATUS_SUCCESS
;
313 // new change request
314 PC_ASSERT(Pin
->m_State
== KSSTATE_STOP
);
315 // FIXME queue a work item when Irql != PASSIVE_LEVEL
316 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
318 // allocate new data format
319 NewDataFormat
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
323 return STATUS_NO_MEMORY
;
326 // copy new data format
327 RtlMoveMemory(NewDataFormat
, DataFormat
, DataFormat
->FormatSize
);
330 Status
= Pin
->m_Stream
->SetFormat(NewDataFormat
);
331 if (NT_SUCCESS(Status
))
334 FreeItem(Pin
->m_Format
, TAG_PORTCLASS
);
337 Pin
->m_Format
= NewDataFormat
;
338 Irp
->IoStatus
.Information
= NewDataFormat
->FormatSize
;
341 PC_ASSERT(NewDataFormat
->FormatSize
== sizeof(KSDATAFORMAT_WAVEFORMATEX
));
342 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.MajorFormat
, KSDATAFORMAT_TYPE_AUDIO
));
343 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.SubFormat
, KSDATAFORMAT_SUBTYPE_PCM
));
344 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.Specifier
, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
));
347 DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nChannels
,
348 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.wBitsPerSample
,
349 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nSamplesPerSec
);
355 // failed to set format
356 FreeItem(NewDataFormat
, TAG_PORTCLASS
);
363 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
365 // get current data format
366 PC_ASSERT(Pin
->m_Format
);
368 if (Pin
->m_Format
->FormatSize
> IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
371 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
372 return STATUS_MORE_ENTRIES
;
375 RtlMoveMemory(Data
, Pin
->m_Format
, Pin
->m_Format
->FormatSize
);
377 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
380 return STATUS_SUCCESS
;
383 // unsupported request
384 return STATUS_NOT_SUPPORTED
;
388 //==================================================================================================================================
391 CPortPinWavePci::QueryInterface(
395 //DPRINT("CPortPinWavePci::QueryInterface entered\n");
397 if (IsEqualGUIDAligned(refiid
, IID_IIrpTarget
) ||
398 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
400 *Output
= PVOID(PUNKNOWN((IIrpTarget
*)this));
401 PUNKNOWN(*Output
)->AddRef();
402 return STATUS_SUCCESS
;
405 if (IsEqualGUIDAligned(refiid
, IID_IServiceSink
))
407 *Output
= PVOID(PSERVICESINK(this));
408 PUNKNOWN(*Output
)->AddRef();
409 return STATUS_SUCCESS
;
413 if (IsEqualGUIDAligned(refiid
, IID_IPortWavePciStream
))
415 *Output
= PVOID(PPORTWAVEPCISTREAM(this));
416 PUNKNOWN(*Output
)->AddRef();
417 return STATUS_SUCCESS
;
420 return STATUS_UNSUCCESSFUL
;
425 CPortPinWavePci::GetMapping(
427 OUT PPHYSICAL_ADDRESS PhysicalAddress
,
428 OUT PVOID
*VirtualAddress
,
429 OUT PULONG ByteCount
,
433 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
434 return m_IrpQueue
->GetMappingWithTag(Tag
, PhysicalAddress
, VirtualAddress
, ByteCount
, Flags
);
439 CPortPinWavePci::ReleaseMapping(
443 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
444 return m_IrpQueue
->ReleaseMappingWithTag(Tag
);
449 CPortPinWavePci::TerminatePacket()
452 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
453 return STATUS_SUCCESS
;
459 CPortPinWavePci::RequestService()
461 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
463 if (m_State
== KSSTATE_RUN
)
471 //==================================================================================================================================
475 CPortPinWavePci::NewIrpTarget(
476 OUT
struct IIrpTarget
**OutTarget
,
479 IN POOL_TYPE PoolType
,
480 IN PDEVICE_OBJECT DeviceObject
,
482 IN KSOBJECT_CREATE
*CreateObject
)
486 Irp
->IoStatus
.Information
= 0;
487 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
488 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
490 return STATUS_UNSUCCESSFUL
;
495 CPortPinWavePci::HandleKsProperty(
498 PKSPROPERTY Property
;
500 //UNICODE_STRING GuidString;
501 PIO_STACK_LOCATION IoStack
;
503 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
505 //DPRINT("IPortPinWave_HandleKsProperty entered\n");
507 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
509 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
511 //DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
513 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
515 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
516 return STATUS_SUCCESS
;
519 Status
= PcHandlePropertyWithTable(Irp
, m_Descriptor
.FilterPropertySetCount
, m_Descriptor
.FilterPropertySet
, &m_Descriptor
);
521 if (Status
== STATUS_NOT_FOUND
)
523 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
525 RtlStringFromGUID(Property
->Set
, &GuidString
);
526 //DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
527 RtlFreeUnicodeString(&GuidString
);
531 if (Status
!= STATUS_PENDING
)
533 Irp
->IoStatus
.Status
= Status
;
534 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
542 CPortPinWavePci::HandleKsStream(
548 InterlockedIncrement((PLONG
)&m_TotalPackets
);
550 DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets
, m_State
, m_IrpQueue
->NumData());
552 bFailed
= m_IrpQueue
->HasLastMappingFailed();
554 Status
= m_IrpQueue
->AddMapping(Irp
, &Data
);
556 if (NT_SUCCESS(Status
))
559 m_Position
.WriteOffset
+= Data
;
561 m_Position
.WriteOffset
+= Data
;
565 // notify stream of new mapping
566 m_Stream
->MappingAvailable();
569 return STATUS_PENDING
;
578 CPortPinWavePci::DeviceIoControl(
579 IN PDEVICE_OBJECT DeviceObject
,
582 PIO_STACK_LOCATION IoStack
;
584 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
586 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
588 return HandleKsProperty(Irp
);
590 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
|| IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
592 return HandleKsStream(Irp
);
597 Irp
->IoStatus
.Information
= 0;
598 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
599 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
601 return STATUS_UNSUCCESSFUL
;
606 CPortPinWavePci::Read(
607 IN PDEVICE_OBJECT DeviceObject
,
610 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
615 CPortPinWavePci::Write(
616 IN PDEVICE_OBJECT DeviceObject
,
619 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
624 CPortPinWavePci::Flush(
625 IN PDEVICE_OBJECT DeviceObject
,
628 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
633 CPortPinWavePci::Close(
634 IN PDEVICE_OBJECT DeviceObject
,
642 FreeItem(m_Format
, TAG_PORTCLASS
);
650 // cancel remaining irps
651 m_IrpQueue
->CancelBuffers();
654 m_IrpQueue
->Release();
663 // remove member from service group
664 m_ServiceGroup
->RemoveMember(PSERVICESINK(this));
666 // do not release service group, it is released by the miniport object
667 m_ServiceGroup
= NULL
;
672 if (m_State
!= KSSTATE_STOP
)
675 Status
= m_Stream
->SetState(KSSTATE_STOP
);
676 if (!NT_SUCCESS(Status
))
678 DPRINT("Warning: failed to stop stream with %x\n", Status
);
683 m_State
= KSSTATE_STOP
;
685 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
690 // stream is now freed
696 // disconnect pin from filter
697 m_Filter
->FreePin((PPORTPINWAVEPCI
)this);
699 // release filter reference
702 // pin is done with filter
708 // release reference to port driver
711 // work is done for port
715 // successfully complete irp
716 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
717 Irp
->IoStatus
.Information
= 0;
718 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
720 return STATUS_SUCCESS
;
725 CPortPinWavePci::QuerySecurity(
726 IN PDEVICE_OBJECT DeviceObject
,
729 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
734 CPortPinWavePci::SetSecurity(
735 IN PDEVICE_OBJECT DeviceObject
,
738 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
743 CPortPinWavePci::FastDeviceIoControl(
744 IN PFILE_OBJECT FileObject
,
746 IN PVOID InputBuffer
,
747 IN ULONG InputBufferLength
,
748 OUT PVOID OutputBuffer
,
749 IN ULONG OutputBufferLength
,
750 IN ULONG IoControlCode
,
751 OUT PIO_STATUS_BLOCK StatusBlock
,
752 IN PDEVICE_OBJECT DeviceObject
)
759 CPortPinWavePci::FastRead(
760 IN PFILE_OBJECT FileObject
,
761 IN PLARGE_INTEGER FileOffset
,
766 OUT PIO_STATUS_BLOCK StatusBlock
,
767 IN PDEVICE_OBJECT DeviceObject
)
774 CPortPinWavePci::FastWrite(
775 IN PFILE_OBJECT FileObject
,
776 IN PLARGE_INTEGER FileOffset
,
781 OUT PIO_STATUS_BLOCK StatusBlock
,
782 IN PDEVICE_OBJECT DeviceObject
)
790 CPortPinWavePci::Init(
791 IN PPORTWAVEPCI Port
,
792 IN PPORTFILTERWAVEPCI Filter
,
793 IN KSPIN_CONNECT
* ConnectDetails
,
794 IN KSPIN_DESCRIPTOR
* KsPinDescriptor
,
795 IN PDEVICE_OBJECT DeviceObject
)
798 PKSDATAFORMAT DataFormat
;
800 ISubdevice
* Subdevice
= NULL
;
801 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
= NULL
;
803 // check if it is a source / sink pin
804 if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_IN
)
809 else if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_OUT
)
816 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor
->Communication
, KsPinDescriptor
->DataFlow
);
821 // add port / filter reference
828 m_KsPinDescriptor
= KsPinDescriptor
;
829 m_ConnectDetails
= ConnectDetails
;
830 m_Miniport
= GetWavePciMiniport(Port
);
831 m_DeviceObject
= DeviceObject
;
832 m_State
= KSSTATE_STOP
;
835 DPRINT("IPortPinWavePci_fnInit entered\n");
838 DataFormat
= (PKSDATAFORMAT
)(ConnectDetails
+ 1);
840 // allocate data format
841 m_Format
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
844 // release references
848 // no dangling pointers
852 // failed to allocate data format
853 return STATUS_INSUFFICIENT_RESOURCES
;
857 RtlMoveMemory(m_Format
, DataFormat
, DataFormat
->FormatSize
);
859 // allocate new stream
860 Status
= m_Miniport
->NewStream(&m_Stream
,
863 PPORTWAVEPCISTREAM(this),
864 ConnectDetails
->PinId
,
870 DPRINT("IPortPinWavePci_fnInit Status %x\n", Status
);
872 if (!NT_SUCCESS(Status
))
879 FreeItem(m_Format
, TAG_PORTCLASS
);
881 // no dangling pointers
886 // failed to allocate stream
890 // get allocator requirements for pin
891 Status
= m_Stream
->GetAllocatorFraming(&m_AllocatorFraming
);
892 if (NT_SUCCESS(Status
))
894 DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n",
895 m_AllocatorFraming
.OptionsFlags
, m_AllocatorFraming
.RequirementsFlags
, m_AllocatorFraming
.PoolType
, m_AllocatorFraming
.Frames
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
);
898 // allocate new irp queue
899 Status
= NewIrpQueue(&m_IrpQueue
);
900 if (!NT_SUCCESS(Status
))
908 FreeItem(m_Format
, TAG_PORTCLASS
);
910 // no dangling pointers
916 // failed to allocate irp queue
920 // initialize irp queue
921 Status
= m_IrpQueue
->Init(ConnectDetails
, KsPinDescriptor
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
, TRUE
);
922 if (!NT_SUCCESS(Status
))
924 // this should never happen
928 // get subdevice interface
929 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&Subdevice
);
931 if (!NT_SUCCESS(Status
))
933 // this function should never fail
937 // get subdevice descriptor
938 Status
= Subdevice
->GetDescriptor(&SubDeviceDescriptor
);
939 if (!NT_SUCCESS(Status
))
941 // this function should never fail
946 Subdevice
->Release();
948 /* set up subdevice descriptor */
949 RtlZeroMemory(&m_Descriptor
, sizeof(SUBDEVICE_DESCRIPTOR
));
950 m_Descriptor
.FilterPropertySet
= PinWavePciPropertySet
;
951 m_Descriptor
.FilterPropertySetCount
= sizeof(PinWavePciPropertySet
) / sizeof(KSPROPERTY_SET
);
952 m_Descriptor
.UnknownStream
= (PUNKNOWN
)m_Stream
;
953 m_Descriptor
.DeviceDescriptor
= SubDeviceDescriptor
->DeviceDescriptor
;
954 m_Descriptor
.UnknownMiniport
= SubDeviceDescriptor
->UnknownMiniport
;
955 m_Descriptor
.PortPin
= (PVOID
)this;
959 Status
= m_ServiceGroup
->AddMember(PSERVICESINK(this));
960 if (!NT_SUCCESS(Status
))
968 FreeItem(m_Format
, TAG_PORTCLASS
);
970 // no dangling pointers
976 // failed to add to service group
982 return STATUS_SUCCESS
;
987 CPortPinWavePci::GetIrpStream()
989 return (PVOID
)m_IrpQueue
;
995 CPortPinWavePci::GetMiniport()
997 return (PMINIPORT
)m_Miniport
;
1003 OUT IPortPinWavePci
** OutPin
)
1005 CPortPinWavePci
* This
;
1007 This
= new(NonPagedPool
, TAG_PORTCLASS
) CPortPinWavePci(NULL
);
1009 return STATUS_INSUFFICIENT_RESOURCES
;
1014 *OutPin
= (IPortPinWavePci
*)This
;
1016 return STATUS_SUCCESS
;