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
;
66 ULONG m_PrefetchOffset
;
67 SUBDEVICE_DESCRIPTOR m_Descriptor
;
69 KSALLOCATOR_FRAMING m_AllocatorFraming
;
73 NTSTATUS NTAPI
HandleKsProperty(IN PIRP Irp
);
74 NTSTATUS NTAPI
HandleKsStream(IN PIRP Irp
);
80 PIO_WORKITEM WorkItem
;
82 }SETSTREAM_CONTEXT
, *PSETSTREAM_CONTEXT
;
84 NTSTATUS NTAPI
PinWavePciState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
85 NTSTATUS NTAPI
PinWavePciDataFormat(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
86 NTSTATUS NTAPI
PinWavePciAudioPosition(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
87 NTSTATUS NTAPI
PinWavePciAllocatorFraming(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
89 DEFINE_KSPROPERTY_CONNECTIONSET(PinWavePciConnectionSet
, PinWavePciState
, PinWavePciDataFormat
, PinWavePciAllocatorFraming
);
90 DEFINE_KSPROPERTY_AUDIOSET(PinWavePciAudioSet
, PinWavePciAudioPosition
);
92 KSPROPERTY_SET PinWavePciPropertySet
[] =
95 &KSPROPSETID_Connection
,
96 sizeof(PinWavePciConnectionSet
) / sizeof(KSPROPERTY_ITEM
),
97 (const KSPROPERTY_ITEM
*)&PinWavePciConnectionSet
,
103 sizeof(PinWavePciAudioSet
) / sizeof(KSPROPERTY_ITEM
),
104 (const KSPROPERTY_ITEM
*)&PinWavePciAudioSet
,
113 PinWavePciAllocatorFraming(
115 IN PKSIDENTIFIER Request
,
118 CPortPinWavePci
*Pin
;
119 PSUBDEVICE_DESCRIPTOR Descriptor
;
121 // get sub device descriptor
122 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
125 PC_ASSERT(Descriptor
);
126 PC_ASSERT(Descriptor
->PortPin
);
127 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
130 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
133 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
136 RtlMoveMemory(Data
, &Pin
->m_AllocatorFraming
, sizeof(KSALLOCATOR_FRAMING
));
138 Irp
->IoStatus
.Information
= sizeof(KSALLOCATOR_FRAMING
);
139 return STATUS_SUCCESS
;
143 return STATUS_NOT_SUPPORTED
;
148 PinWavePciAudioPosition(
150 IN PKSIDENTIFIER Request
,
153 CPortPinWavePci
*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
= (CPortPinWavePci
*)Descriptor
->PortPin
;
168 PC_ASSERT(Pin
->m_Stream
);
170 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
172 // FIXME non multithreading-safe
173 // copy audio position
174 RtlMoveMemory(Data
, &Pin
->m_Position
, sizeof(KSAUDIO_POSITION
));
176 DPRINT("Play %lu Record %lu\n", Pin
->m_Position
.PlayOffset
, Pin
->m_Position
.WriteOffset
);
177 Irp
->IoStatus
.Information
= sizeof(KSAUDIO_POSITION
);
178 return STATUS_SUCCESS
;
182 return STATUS_NOT_SUPPORTED
;
190 IN PKSIDENTIFIER Request
,
193 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
194 CPortPinWavePci
*Pin
;
195 PSUBDEVICE_DESCRIPTOR Descriptor
;
196 PVOID FirstTag
, LastTag
;
197 ULONG MappingsRevoked
;
198 PKSSTATE State
= (PKSSTATE
)Data
;
200 // get sub device descriptor
201 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
204 PC_ASSERT(Descriptor
);
205 PC_ASSERT(Descriptor
->PortPin
);
206 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
209 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
212 PC_ASSERT(Pin
->m_Stream
);
214 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
217 Status
= Pin
->m_Stream
->SetState(*State
);
219 DPRINT("Setting state %u %x\n", *State
, Status
);
220 if (NT_SUCCESS(Status
))
223 Pin
->m_State
= *State
;
224 if (Pin
->m_ConnectDetails
->Interface
.Id
== KSINTERFACE_STANDARD_LOOPED_STREAMING
&& Pin
->m_State
== KSSTATE_STOP
)
227 // complete with successful state
228 Pin
->m_IrpQueue
->CancelBuffers();
229 while(Pin
->m_IrpQueue
->GetAcquiredTagRange(&FirstTag
, &LastTag
))
231 Status
= Pin
->m_Stream
->RevokeMappings(FirstTag
, LastTag
, &MappingsRevoked
);
232 DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status
, MappingsRevoked
);
233 KeStallExecutionProcessor(10);
235 Pin
->m_Position
.PlayOffset
= 0;
236 Pin
->m_Position
.WriteOffset
= 0;
238 else if (Pin
->m_State
== KSSTATE_STOP
)
240 Pin
->m_IrpQueue
->CancelBuffers();
241 while(Pin
->m_IrpQueue
->GetAcquiredTagRange(&FirstTag
, &LastTag
))
243 Status
= Pin
->m_Stream
->RevokeMappings(FirstTag
, LastTag
, &MappingsRevoked
);
244 DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status
, MappingsRevoked
);
245 KeStallExecutionProcessor(10);
247 Pin
->m_Position
.PlayOffset
= 0;
248 Pin
->m_Position
.WriteOffset
= 0;
251 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
255 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
258 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
260 // get current stream state
261 *State
= Pin
->m_State
;
263 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
265 return STATUS_SUCCESS
;
268 // unsupported request
269 return STATUS_NOT_SUPPORTED
;
274 PinWavePciDataFormat(
276 IN PKSIDENTIFIER Request
,
279 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
280 CPortPinWavePci
*Pin
;
281 PSUBDEVICE_DESCRIPTOR Descriptor
;
282 PIO_STACK_LOCATION IoStack
;
284 // get current irp stack location
285 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
287 // get sub device descriptor
288 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
291 PC_ASSERT(Descriptor
);
292 PC_ASSERT(Descriptor
->PortPin
);
295 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
298 PC_ASSERT(Pin
->m_Stream
);
299 PC_ASSERT(Pin
->m_Format
);
301 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
303 // try to change data format
304 PKSDATAFORMAT NewDataFormat
, DataFormat
= (PKSDATAFORMAT
)Irp
->UserBuffer
;
305 ULONG Size
= min(Pin
->m_Format
->FormatSize
, DataFormat
->FormatSize
);
307 if (RtlCompareMemory(DataFormat
, Pin
->m_Format
, Size
) == Size
)
309 // format is identical
310 Irp
->IoStatus
.Information
= DataFormat
->FormatSize
;
311 return STATUS_SUCCESS
;
314 // new change request
315 PC_ASSERT(Pin
->m_State
== KSSTATE_STOP
);
316 // FIXME queue a work item when Irql != PASSIVE_LEVEL
317 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
319 // allocate new data format
320 NewDataFormat
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
324 return STATUS_NO_MEMORY
;
327 // copy new data format
328 RtlMoveMemory(NewDataFormat
, DataFormat
, DataFormat
->FormatSize
);
331 Status
= Pin
->m_Stream
->SetFormat(NewDataFormat
);
332 if (NT_SUCCESS(Status
))
335 FreeItem(Pin
->m_Format
, TAG_PORTCLASS
);
338 Pin
->m_Format
= NewDataFormat
;
339 Irp
->IoStatus
.Information
= NewDataFormat
->FormatSize
;
342 PC_ASSERT(NewDataFormat
->FormatSize
== sizeof(KSDATAFORMAT_WAVEFORMATEX
));
343 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.MajorFormat
, KSDATAFORMAT_TYPE_AUDIO
));
344 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.SubFormat
, KSDATAFORMAT_SUBTYPE_PCM
));
345 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.Specifier
, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
));
348 DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nChannels
,
349 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.wBitsPerSample
,
350 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nSamplesPerSec
);
356 // failed to set format
357 FreeItem(NewDataFormat
, TAG_PORTCLASS
);
364 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
366 // get current data format
367 PC_ASSERT(Pin
->m_Format
);
369 if (Pin
->m_Format
->FormatSize
> IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
372 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
373 return STATUS_MORE_ENTRIES
;
376 RtlMoveMemory(Data
, Pin
->m_Format
, Pin
->m_Format
->FormatSize
);
378 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
381 return STATUS_SUCCESS
;
384 // unsupported request
385 return STATUS_NOT_SUPPORTED
;
389 //==================================================================================================================================
392 CPortPinWavePci::QueryInterface(
396 //DPRINT("CPortPinWavePci::QueryInterface entered\n");
398 if (IsEqualGUIDAligned(refiid
, IID_IIrpTarget
) ||
399 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
401 *Output
= PVOID(PUNKNOWN((IIrpTarget
*)this));
402 PUNKNOWN(*Output
)->AddRef();
403 return STATUS_SUCCESS
;
406 if (IsEqualGUIDAligned(refiid
, IID_IServiceSink
))
408 *Output
= PVOID(PSERVICESINK(this));
409 PUNKNOWN(*Output
)->AddRef();
410 return STATUS_SUCCESS
;
414 if (IsEqualGUIDAligned(refiid
, IID_IPortWavePciStream
))
416 *Output
= PVOID(PPORTWAVEPCISTREAM(this));
417 PUNKNOWN(*Output
)->AddRef();
418 return STATUS_SUCCESS
;
421 return STATUS_UNSUCCESSFUL
;
426 CPortPinWavePci::GetMapping(
428 OUT PPHYSICAL_ADDRESS PhysicalAddress
,
429 OUT PVOID
*VirtualAddress
,
430 OUT PULONG ByteCount
,
434 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
435 return m_IrpQueue
->GetMappingWithTag(Tag
, PhysicalAddress
, VirtualAddress
, ByteCount
, Flags
);
440 CPortPinWavePci::ReleaseMapping(
444 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
445 return m_IrpQueue
->ReleaseMappingWithTag(Tag
);
450 CPortPinWavePci::TerminatePacket()
453 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
454 return STATUS_SUCCESS
;
460 CPortPinWavePci::RequestService()
462 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
464 if (m_State
== KSSTATE_RUN
)
472 //==================================================================================================================================
476 CPortPinWavePci::NewIrpTarget(
477 OUT
struct IIrpTarget
**OutTarget
,
480 IN POOL_TYPE PoolType
,
481 IN PDEVICE_OBJECT DeviceObject
,
483 IN KSOBJECT_CREATE
*CreateObject
)
487 Irp
->IoStatus
.Information
= 0;
488 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
489 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
491 return STATUS_UNSUCCESSFUL
;
496 CPortPinWavePci::HandleKsProperty(
499 PKSPROPERTY Property
;
501 //UNICODE_STRING GuidString;
502 PIO_STACK_LOCATION IoStack
;
504 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
506 //DPRINT("IPortPinWave_HandleKsProperty entered\n");
508 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
510 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
512 //DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
514 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
516 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
517 return STATUS_SUCCESS
;
520 Status
= PcHandlePropertyWithTable(Irp
, m_Descriptor
.FilterPropertySetCount
, m_Descriptor
.FilterPropertySet
, &m_Descriptor
);
522 if (Status
== STATUS_NOT_FOUND
)
524 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
526 RtlStringFromGUID(Property
->Set
, &GuidString
);
527 //DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
528 RtlFreeUnicodeString(&GuidString
);
532 if (Status
!= STATUS_PENDING
)
534 Irp
->IoStatus
.Status
= Status
;
535 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
543 CPortPinWavePci::HandleKsStream(
549 InterlockedIncrement((PLONG
)&m_TotalPackets
);
551 DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets
, m_State
, m_IrpQueue
->NumData());
553 bFailed
= m_IrpQueue
->HasLastMappingFailed();
555 Status
= m_IrpQueue
->AddMapping(Irp
, &Data
);
557 if (NT_SUCCESS(Status
))
560 m_Position
.WriteOffset
+= Data
;
562 m_Position
.WriteOffset
+= Data
;
566 // notify stream of new mapping
567 m_Stream
->MappingAvailable();
570 return STATUS_PENDING
;
579 CPortPinWavePci::DeviceIoControl(
580 IN PDEVICE_OBJECT DeviceObject
,
583 PIO_STACK_LOCATION IoStack
;
585 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
587 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
589 return HandleKsProperty(Irp
);
591 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
|| IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
593 return HandleKsStream(Irp
);
598 Irp
->IoStatus
.Information
= 0;
599 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
600 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
602 return STATUS_UNSUCCESSFUL
;
607 CPortPinWavePci::Read(
608 IN PDEVICE_OBJECT DeviceObject
,
611 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
616 CPortPinWavePci::Write(
617 IN PDEVICE_OBJECT DeviceObject
,
620 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
625 CPortPinWavePci::Flush(
626 IN PDEVICE_OBJECT DeviceObject
,
629 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
634 CPortPinWavePci::Close(
635 IN PDEVICE_OBJECT DeviceObject
,
643 FreeItem(m_Format
, TAG_PORTCLASS
);
651 // cancel remaining irps
652 m_IrpQueue
->CancelBuffers();
655 m_IrpQueue
->Release();
664 // remove member from service group
665 m_ServiceGroup
->RemoveMember(PSERVICESINK(this));
667 // do not release service group, it is released by the miniport object
668 m_ServiceGroup
= NULL
;
673 if (m_State
!= KSSTATE_STOP
)
676 Status
= m_Stream
->SetState(KSSTATE_STOP
);
677 if (!NT_SUCCESS(Status
))
679 DPRINT("Warning: failed to stop stream with %x\n", Status
);
684 m_State
= KSSTATE_STOP
;
686 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
691 // stream is now freed
697 // disconnect pin from filter
698 m_Filter
->FreePin((PPORTPINWAVEPCI
)this);
700 // release filter reference
703 // pin is done with filter
709 // release reference to port driver
712 // work is done for port
716 // successfully complete irp
717 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
718 Irp
->IoStatus
.Information
= 0;
719 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
721 return STATUS_SUCCESS
;
726 CPortPinWavePci::QuerySecurity(
727 IN PDEVICE_OBJECT DeviceObject
,
730 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
735 CPortPinWavePci::SetSecurity(
736 IN PDEVICE_OBJECT DeviceObject
,
739 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
744 CPortPinWavePci::FastDeviceIoControl(
745 IN PFILE_OBJECT FileObject
,
747 IN PVOID InputBuffer
,
748 IN ULONG InputBufferLength
,
749 OUT PVOID OutputBuffer
,
750 IN ULONG OutputBufferLength
,
751 IN ULONG IoControlCode
,
752 OUT PIO_STATUS_BLOCK StatusBlock
,
753 IN PDEVICE_OBJECT DeviceObject
)
760 CPortPinWavePci::FastRead(
761 IN PFILE_OBJECT FileObject
,
762 IN PLARGE_INTEGER FileOffset
,
767 OUT PIO_STATUS_BLOCK StatusBlock
,
768 IN PDEVICE_OBJECT DeviceObject
)
775 CPortPinWavePci::FastWrite(
776 IN PFILE_OBJECT FileObject
,
777 IN PLARGE_INTEGER FileOffset
,
782 OUT PIO_STATUS_BLOCK StatusBlock
,
783 IN PDEVICE_OBJECT DeviceObject
)
791 CPortPinWavePci::Init(
792 IN PPORTWAVEPCI Port
,
793 IN PPORTFILTERWAVEPCI Filter
,
794 IN KSPIN_CONNECT
* ConnectDetails
,
795 IN KSPIN_DESCRIPTOR
* KsPinDescriptor
,
796 IN PDEVICE_OBJECT DeviceObject
)
799 PKSDATAFORMAT DataFormat
;
801 ISubdevice
* Subdevice
= NULL
;
802 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
= NULL
;
804 // check if it is a source / sink pin
805 if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_IN
)
810 else if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_OUT
)
817 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor
->Communication
, KsPinDescriptor
->DataFlow
);
822 // add port / filter reference
829 m_KsPinDescriptor
= KsPinDescriptor
;
830 m_ConnectDetails
= ConnectDetails
;
831 m_Miniport
= GetWavePciMiniport(Port
);
832 m_DeviceObject
= DeviceObject
;
833 m_State
= KSSTATE_STOP
;
836 DPRINT("IPortPinWavePci_fnInit entered\n");
839 DataFormat
= (PKSDATAFORMAT
)(ConnectDetails
+ 1);
841 // allocate data format
842 m_Format
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
845 // release references
849 // no dangling pointers
853 // failed to allocate data format
854 return STATUS_INSUFFICIENT_RESOURCES
;
858 RtlMoveMemory(m_Format
, DataFormat
, DataFormat
->FormatSize
);
860 // allocate new stream
861 Status
= m_Miniport
->NewStream(&m_Stream
,
864 PPORTWAVEPCISTREAM(this),
865 ConnectDetails
->PinId
,
871 DPRINT("IPortPinWavePci_fnInit Status %x\n", Status
);
873 if (!NT_SUCCESS(Status
))
880 FreeItem(m_Format
, TAG_PORTCLASS
);
882 // no dangling pointers
887 // failed to allocate stream
891 // get allocator requirements for pin
892 Status
= m_Stream
->GetAllocatorFraming(&m_AllocatorFraming
);
893 if (NT_SUCCESS(Status
))
895 DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n",
896 m_AllocatorFraming
.OptionsFlags
, m_AllocatorFraming
.RequirementsFlags
, m_AllocatorFraming
.PoolType
, m_AllocatorFraming
.Frames
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
);
899 // allocate new irp queue
900 Status
= NewIrpQueue(&m_IrpQueue
);
901 if (!NT_SUCCESS(Status
))
909 FreeItem(m_Format
, TAG_PORTCLASS
);
911 // no dangling pointers
917 // failed to allocate irp queue
921 // initialize irp queue
922 Status
= m_IrpQueue
->Init(ConnectDetails
, KsPinDescriptor
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
, TRUE
);
923 if (!NT_SUCCESS(Status
))
925 // this should never happen
929 // get subdevice interface
930 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&Subdevice
);
932 if (!NT_SUCCESS(Status
))
934 // this function should never fail
938 // get subdevice descriptor
939 Status
= Subdevice
->GetDescriptor(&SubDeviceDescriptor
);
940 if (!NT_SUCCESS(Status
))
942 // this function should never fail
947 Subdevice
->Release();
949 /* set up subdevice descriptor */
950 RtlZeroMemory(&m_Descriptor
, sizeof(SUBDEVICE_DESCRIPTOR
));
951 m_Descriptor
.FilterPropertySet
= PinWavePciPropertySet
;
952 m_Descriptor
.FilterPropertySetCount
= sizeof(PinWavePciPropertySet
) / sizeof(KSPROPERTY_SET
);
953 m_Descriptor
.UnknownStream
= (PUNKNOWN
)m_Stream
;
954 m_Descriptor
.DeviceDescriptor
= SubDeviceDescriptor
->DeviceDescriptor
;
955 m_Descriptor
.UnknownMiniport
= SubDeviceDescriptor
->UnknownMiniport
;
956 m_Descriptor
.PortPin
= (PVOID
)this;
960 Status
= m_ServiceGroup
->AddMember(PSERVICESINK(this));
961 if (!NT_SUCCESS(Status
))
969 FreeItem(m_Format
, TAG_PORTCLASS
);
971 // no dangling pointers
977 // failed to add to service group
983 return STATUS_SUCCESS
;
988 CPortPinWavePci::GetIrpStream()
990 return (PVOID
)m_IrpQueue
;
996 CPortPinWavePci::GetMiniport()
998 return (PMINIPORT
)m_Miniport
;
1004 OUT IPortPinWavePci
** OutPin
)
1006 CPortPinWavePci
* This
;
1008 This
= new(NonPagedPool
, TAG_PORTCLASS
) CPortPinWavePci(NULL
);
1010 return STATUS_INSUFFICIENT_RESOURCES
;
1015 *OutPin
= (IPortPinWavePci
*)This
;
1017 return STATUS_SUCCESS
;