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_ALLOCATORFRAMING(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
,
127 return STATUS_NOT_IMPLEMENTED
;
132 PinWavePciAudioPosition(
134 IN PKSIDENTIFIER Request
,
137 CPortPinWavePci
*Pin
;
138 PSUBDEVICE_DESCRIPTOR Descriptor
;
140 // get sub device descriptor
141 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
144 PC_ASSERT(Descriptor
);
145 PC_ASSERT(Descriptor
->PortPin
);
146 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
149 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
152 PC_ASSERT(Pin
->m_Stream
);
154 if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
156 // FIXME non multithreading-safe
157 // copy audio position
158 RtlMoveMemory(Data
, &Pin
->m_Position
, sizeof(KSAUDIO_POSITION
));
160 DPRINT1("Play %lu Record %lu\n", Pin
->m_Position
.PlayOffset
, Pin
->m_Position
.WriteOffset
);
161 Irp
->IoStatus
.Information
= sizeof(KSAUDIO_POSITION
);
162 return STATUS_SUCCESS
;
166 return STATUS_NOT_SUPPORTED
;
174 IN PKSIDENTIFIER Request
,
177 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
178 CPortPinWavePci
*Pin
;
179 PSUBDEVICE_DESCRIPTOR Descriptor
;
180 PKSSTATE State
= (PKSSTATE
)Data
;
182 // get sub device descriptor
183 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
186 PC_ASSERT(Descriptor
);
187 PC_ASSERT(Descriptor
->PortPin
);
188 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
191 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
194 PC_ASSERT(Pin
->m_Stream
);
196 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
199 Status
= Pin
->m_Stream
->SetState(*State
);
201 DPRINT("Setting state %u %x\n", *State
, Status
);
202 if (NT_SUCCESS(Status
))
205 Pin
->m_State
= *State
;
208 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
211 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
213 // get current stream state
214 *State
= Pin
->m_State
;
216 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
218 return STATUS_SUCCESS
;
221 // unsupported request
222 return STATUS_NOT_SUPPORTED
;
227 PinWavePciDataFormat(
229 IN PKSIDENTIFIER Request
,
232 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
233 CPortPinWavePci
*Pin
;
234 PSUBDEVICE_DESCRIPTOR Descriptor
;
235 PIO_STACK_LOCATION IoStack
;
237 // get current irp stack location
238 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
240 // get sub device descriptor
241 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
244 PC_ASSERT(Descriptor
);
245 PC_ASSERT(Descriptor
->PortPin
);
248 Pin
= (CPortPinWavePci
*)Descriptor
->PortPin
;
251 PC_ASSERT(Pin
->m_Stream
);
252 PC_ASSERT(Pin
->m_Format
);
254 if (Request
->Flags
& KSPROPERTY_TYPE_SET
)
256 // try to change data format
257 PKSDATAFORMAT NewDataFormat
, DataFormat
= (PKSDATAFORMAT
)Irp
->UserBuffer
;
258 ULONG Size
= min(Pin
->m_Format
->FormatSize
, DataFormat
->FormatSize
);
260 if (RtlCompareMemory(DataFormat
, Pin
->m_Format
, Size
) == Size
)
262 // format is identical
263 Irp
->IoStatus
.Information
= DataFormat
->FormatSize
;
264 return STATUS_SUCCESS
;
267 // new change request
268 PC_ASSERT(Pin
->m_State
== KSSTATE_STOP
);
269 // FIXME queue a work item when Irql != PASSIVE_LEVEL
270 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
272 // allocate new data format
273 NewDataFormat
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
277 return STATUS_NO_MEMORY
;
280 // copy new data format
281 RtlMoveMemory(NewDataFormat
, DataFormat
, DataFormat
->FormatSize
);
284 Status
= Pin
->m_Stream
->SetFormat(NewDataFormat
);
285 if (NT_SUCCESS(Status
))
288 FreeItem(Pin
->m_Format
, TAG_PORTCLASS
);
290 // update irp queue with new format
291 Pin
->m_IrpQueue
->UpdateFormat((PKSDATAFORMAT
)NewDataFormat
);
294 Pin
->m_Format
= NewDataFormat
;
295 Irp
->IoStatus
.Information
= NewDataFormat
->FormatSize
;
298 PC_ASSERT(NewDataFormat
->FormatSize
== sizeof(KSDATAFORMAT_WAVEFORMATEX
));
299 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.MajorFormat
, KSDATAFORMAT_TYPE_AUDIO
));
300 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.SubFormat
, KSDATAFORMAT_SUBTYPE_PCM
));
301 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->DataFormat
.Specifier
, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
));
304 DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nChannels
,
305 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.wBitsPerSample
,
306 ((PKSDATAFORMAT_WAVEFORMATEX
)NewDataFormat
)->WaveFormatEx
.nSamplesPerSec
);
312 // failed to set format
313 FreeItem(NewDataFormat
, TAG_PORTCLASS
);
320 else if (Request
->Flags
& KSPROPERTY_TYPE_GET
)
322 // get current data format
323 PC_ASSERT(Pin
->m_Format
);
325 if (Pin
->m_Format
->FormatSize
> IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
328 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
329 return STATUS_MORE_ENTRIES
;
332 RtlMoveMemory(Data
, Pin
->m_Format
, Pin
->m_Format
->FormatSize
);
334 Irp
->IoStatus
.Information
= Pin
->m_Format
->FormatSize
;
337 return STATUS_SUCCESS
;
340 // unsupported request
341 return STATUS_NOT_SUPPORTED
;
345 //==================================================================================================================================
348 CPortPinWavePci::QueryInterface(
352 DPRINT("CPortPinWavePci::QueryInterface entered\n");
354 if (IsEqualGUIDAligned(refiid
, IID_IIrpTarget
) ||
355 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
357 *Output
= PVOID(PUNKNOWN((IIrpTarget
*)this));
358 PUNKNOWN(*Output
)->AddRef();
359 return STATUS_SUCCESS
;
362 if (IsEqualGUIDAligned(refiid
, IID_IServiceSink
))
364 *Output
= PVOID(PSERVICESINK(this));
365 PUNKNOWN(*Output
)->AddRef();
366 return STATUS_SUCCESS
;
370 if (IsEqualGUIDAligned(refiid
, IID_IPortWavePciStream
))
372 *Output
= PVOID(PPORTWAVEPCISTREAM(this));
373 PUNKNOWN(*Output
)->AddRef();
374 return STATUS_SUCCESS
;
377 return STATUS_UNSUCCESSFUL
;
382 CPortPinWavePci::GetMapping(
384 OUT PPHYSICAL_ADDRESS PhysicalAddress
,
385 OUT PVOID
*VirtualAddress
,
386 OUT PULONG ByteCount
,
390 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
391 return m_IrpQueue
->GetMappingWithTag(Tag
, PhysicalAddress
, VirtualAddress
, ByteCount
, Flags
);
396 CPortPinWavePci::ReleaseMapping(
400 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
401 return m_IrpQueue
->ReleaseMappingWithTag(Tag
);
406 CPortPinWavePci::TerminatePacket()
409 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
410 return STATUS_SUCCESS
;
415 CPortPinWavePci::SetState(KSSTATE State
)
417 ULONG MinimumDataThreshold
;
418 ULONG MaximumDataThreshold
;
420 // Has the audio stream resumed?
421 if (m_IrpQueue
->NumMappings() && State
== KSSTATE_STOP
)
425 if (NT_SUCCESS(m_Stream
->SetState(State
)))
427 // Save new internal state
430 if (m_State
== KSSTATE_STOP
)
432 // reset start stream
433 m_IrpQueue
->CancelBuffers(); //FIX function name
434 //This->ServiceGroup->lpVtbl->CancelDelayedService(This->ServiceGroup);
435 // increase stop counter
437 // get current data threshold
438 MinimumDataThreshold
= m_IrpQueue
->GetMinimumDataThreshold();
439 // get maximum data threshold
440 MaximumDataThreshold
= ((PKSDATAFORMAT_WAVEFORMATEX
)m_Format
)->WaveFormatEx
.nAvgBytesPerSec
;
441 // increase minimum data threshold by 10 frames
442 MinimumDataThreshold
+= m_AllocatorFraming
.FrameSize
* 10;
444 // assure it has not exceeded
445 MinimumDataThreshold
= min(MinimumDataThreshold
, MaximumDataThreshold
);
446 // store minimum data threshold
447 m_IrpQueue
->SetMinimumDataThreshold(MinimumDataThreshold
);
449 DPRINT1("Stopping TotalCompleted %u StopCount %u MinimumDataThreshold %u\n", m_TotalPackets
, m_StopCount
, MinimumDataThreshold
);
451 if (m_State
== KSSTATE_RUN
)
453 // start the notification timer
454 //m_ServiceGroup->RequestDelayedService(m_ServiceGroup, m_Delay);
463 PinWavePciSetStreamWorkerRoutine(
464 IN PDEVICE_OBJECT DeviceObject
,
467 CPortPinWavePci
* This
;
468 PSETSTREAM_CONTEXT Ctx
= (PSETSTREAM_CONTEXT
)Context
;
474 IoFreeWorkItem(Ctx
->WorkItem
);
475 FreeItem(Ctx
, TAG_PORTCLASS
);
477 This
->SetState(State
);
482 CPortPinWavePci::SetStreamState(
485 PDEVICE_OBJECT DeviceObject
;
486 PIO_WORKITEM WorkItem
;
487 PSETSTREAM_CONTEXT Context
;
489 PC_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL
);
491 // Has the audio stream resumed?
492 if (m_IrpQueue
->NumMappings() && State
== KSSTATE_STOP
)
495 // Has the audio state already been set?
496 if (m_State
== State
)
500 DeviceObject
= GetDeviceObjectFromPortWavePci(m_Port
);
502 // allocate set state context
503 Context
= (PSETSTREAM_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(SETSTREAM_CONTEXT
), TAG_PORTCLASS
);
508 // allocate work item
509 WorkItem
= IoAllocateWorkItem(DeviceObject
);
518 Context
->WorkItem
= WorkItem
;
519 Context
->State
= State
;
521 // queue the work item
522 IoQueueWorkItem(WorkItem
, PinWavePciSetStreamWorkerRoutine
, DelayedWorkQueue
, (PVOID
)Context
);
528 CPortPinWavePci::RequestService()
530 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
532 if (m_IrpQueue
->HasLastMappingFailed())
534 if (m_IrpQueue
->NumMappings() == 0)
536 DPRINT("Stopping stream...\n");
537 SetStreamState(KSSTATE_STOP
);
547 //==================================================================================================================================
551 CPortPinWavePci::NewIrpTarget(
552 OUT
struct IIrpTarget
**OutTarget
,
555 IN POOL_TYPE PoolType
,
556 IN PDEVICE_OBJECT DeviceObject
,
558 IN KSOBJECT_CREATE
*CreateObject
)
562 Irp
->IoStatus
.Information
= 0;
563 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
564 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
566 return STATUS_UNSUCCESSFUL
;
571 CPortPinWavePci::HandleKsProperty(
574 PKSPROPERTY Property
;
576 UNICODE_STRING GuidString
;
577 PIO_STACK_LOCATION IoStack
;
579 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
581 DPRINT("IPortPinWave_HandleKsProperty entered\n");
583 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
585 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
587 DPRINT1("Unhandled function %lx Length %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
589 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
591 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
592 return STATUS_SUCCESS
;
595 Status
= PcHandlePropertyWithTable(Irp
, m_Descriptor
.FilterPropertySetCount
, m_Descriptor
.FilterPropertySet
, &m_Descriptor
);
597 if (Status
== STATUS_NOT_FOUND
)
599 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
601 RtlStringFromGUID(Property
->Set
, &GuidString
);
602 DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString
.Buffer
, Property
->Id
, Property
->Flags
);
603 RtlFreeUnicodeString(&GuidString
);
606 if (Status
!= STATUS_PENDING
)
608 Irp
->IoStatus
.Status
= Status
;
609 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
616 else if (Property
->Id
== KSPROPERTY_CONNECTION_ALLOCATORFRAMING
)
618 PKSALLOCATOR_FRAMING Framing
= (PKSALLOCATOR_FRAMING
)OutputBuffer
;
620 PC_ASSERT_IRQL(DISPATCH_LEVEL
);
621 // Validate input buffer
622 if (OutputBufferLength
< sizeof(KSALLOCATOR_FRAMING
))
624 IoStatusBlock
->Information
= sizeof(KSALLOCATOR_FRAMING
);
625 IoStatusBlock
->Status
= STATUS_BUFFER_TOO_SMALL
;
626 return STATUS_BUFFER_TOO_SMALL
;
628 // copy frame allocator struct
629 RtlMoveMemory(Framing
, &m_AllocatorFraming
, sizeof(KSALLOCATOR_FRAMING
));
631 IoStatusBlock
->Information
= sizeof(KSALLOCATOR_FRAMING
);
632 IoStatusBlock
->Status
= STATUS_SUCCESS
;
633 return STATUS_SUCCESS
;
640 CPortPinWavePci::HandleKsStream(
644 InterlockedIncrement((PLONG
)&m_TotalPackets
);
646 DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets
, m_State
, m_IrpQueue
->NumData());
648 Status
= m_IrpQueue
->AddMapping(NULL
, 0, Irp
);
650 if (NT_SUCCESS(Status
))
653 PKSSTREAM_HEADER Header
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
657 m_Position
.WriteOffset
+= Header
->FrameExtent
;
659 m_Position
.WriteOffset
+= Header
->DataUsed
;
664 return STATUS_PENDING
;
670 CPortPinWavePci::DeviceIoControl(
671 IN PDEVICE_OBJECT DeviceObject
,
674 PIO_STACK_LOCATION IoStack
;
676 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
678 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
)
680 return HandleKsProperty(Irp
);
682 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_WRITE_STREAM
|| IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_READ_STREAM
)
684 return HandleKsStream(Irp
);
689 Irp
->IoStatus
.Information
= 0;
690 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
691 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
693 return STATUS_UNSUCCESSFUL
;
698 CPortPinWavePci::Read(
699 IN PDEVICE_OBJECT DeviceObject
,
702 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
707 CPortPinWavePci::Write(
708 IN PDEVICE_OBJECT DeviceObject
,
711 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
716 CPortPinWavePci::Flush(
717 IN PDEVICE_OBJECT DeviceObject
,
720 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
725 CPortPinWavePci::CloseStream()
727 PMINIPORTWAVEPCISTREAM Stream
;
728 ISubdevice
*ISubDevice
;
730 PSUBDEVICE_DESCRIPTOR Descriptor
;
734 if (m_State
!= KSSTATE_STOP
)
736 m_Stream
->SetState(KSSTATE_STOP
);
742 m_ServiceGroup
->RemoveMember(PSERVICESINK(this));
745 Status
= m_Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&ISubDevice
);
746 if (NT_SUCCESS(Status
))
748 Status
= ISubDevice
->GetDescriptor(&Descriptor
);
749 if (NT_SUCCESS(Status
))
751 Descriptor
->Factory
.Instances
[m_ConnectDetails
->PinId
].CurrentPinInstanceCount
--;
753 ISubDevice
->Release();
758 ExFreePool(m_Format
);
766 DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql());
773 PinWavePciCloseStreamRoutine(
774 IN PDEVICE_OBJECT DeviceObject
,
777 CPortPinWavePci
* This
;
778 PCLOSESTREAM_CONTEXT Ctx
= (PCLOSESTREAM_CONTEXT
)Context
;
780 This
= (CPortPinWavePci
*)Ctx
->Pin
;
785 Ctx
->Irp
->IoStatus
.Information
= 0;
786 Ctx
->Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
787 IoCompleteRequest(Ctx
->Irp
, IO_NO_INCREMENT
);
789 // free the work item
790 IoFreeWorkItem(Ctx
->WorkItem
);
792 // free work item ctx
793 FreeItem(Ctx
, TAG_PORTCLASS
);
798 CPortPinWavePci::Close(
799 IN PDEVICE_OBJECT DeviceObject
,
802 PCLOSESTREAM_CONTEXT Ctx
;
806 Ctx
= (PCLOSESTREAM_CONTEXT
)AllocateItem(NonPagedPool
, sizeof(CLOSESTREAM_CONTEXT
), TAG_PORTCLASS
);
809 DPRINT1("Failed to allocate stream context\n");
813 Ctx
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
816 DPRINT1("Failed to allocate work item\n");
821 Ctx
->Pin
= (PVOID
)this;
823 IoMarkIrpPending(Irp
);
824 Irp
->IoStatus
.Information
= 0;
825 Irp
->IoStatus
.Status
= STATUS_PENDING
;
828 IoQueueWorkItem(Ctx
->WorkItem
, PinWavePciCloseStreamRoutine
, DelayedWorkQueue
, (PVOID
)Ctx
);
830 return STATUS_PENDING
;
833 Irp
->IoStatus
.Information
= 0;
834 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
835 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
837 return STATUS_SUCCESS
;
842 FreeItem(Ctx
, TAG_PORTCLASS
);
844 Irp
->IoStatus
.Information
= 0;
845 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
846 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
847 return STATUS_UNSUCCESSFUL
;
853 CPortPinWavePci::QuerySecurity(
854 IN PDEVICE_OBJECT DeviceObject
,
857 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
862 CPortPinWavePci::SetSecurity(
863 IN PDEVICE_OBJECT DeviceObject
,
866 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
871 CPortPinWavePci::FastDeviceIoControl(
872 IN PFILE_OBJECT FileObject
,
874 IN PVOID InputBuffer
,
875 IN ULONG InputBufferLength
,
876 OUT PVOID OutputBuffer
,
877 IN ULONG OutputBufferLength
,
878 IN ULONG IoControlCode
,
879 OUT PIO_STATUS_BLOCK StatusBlock
,
880 IN PDEVICE_OBJECT DeviceObject
)
887 CPortPinWavePci::FastRead(
888 IN PFILE_OBJECT FileObject
,
889 IN PLARGE_INTEGER FileOffset
,
894 OUT PIO_STATUS_BLOCK StatusBlock
,
895 IN PDEVICE_OBJECT DeviceObject
)
902 CPortPinWavePci::FastWrite(
903 IN PFILE_OBJECT FileObject
,
904 IN PLARGE_INTEGER FileOffset
,
909 OUT PIO_STATUS_BLOCK StatusBlock
,
910 IN PDEVICE_OBJECT DeviceObject
)
918 CPortPinWavePci::Init(
919 IN PPORTWAVEPCI Port
,
920 IN PPORTFILTERWAVEPCI Filter
,
921 IN KSPIN_CONNECT
* ConnectDetails
,
922 IN KSPIN_DESCRIPTOR
* KsPinDescriptor
,
923 IN PDEVICE_OBJECT DeviceObject
)
926 PKSDATAFORMAT DataFormat
;
934 m_KsPinDescriptor
= KsPinDescriptor
;
935 m_ConnectDetails
= ConnectDetails
;
936 m_Miniport
= GetWavePciMiniport(Port
);
937 m_DeviceObject
= DeviceObject
;
939 DataFormat
= (PKSDATAFORMAT
)(ConnectDetails
+ 1);
941 DPRINT("IPortPinWavePci_fnInit entered\n");
943 m_Format
= (PKSDATAFORMAT
)AllocateItem(NonPagedPool
, DataFormat
->FormatSize
, TAG_PORTCLASS
);
945 return STATUS_INSUFFICIENT_RESOURCES
;
947 RtlMoveMemory(m_Format
, DataFormat
, DataFormat
->FormatSize
);
949 if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_IN
)
953 else if (KsPinDescriptor
->Communication
== KSPIN_COMMUNICATION_SINK
&& KsPinDescriptor
->DataFlow
== KSPIN_DATAFLOW_OUT
)
959 DPRINT1("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor
->Communication
, KsPinDescriptor
->DataFlow
);
963 Status
= m_Miniport
->NewStream(&m_Stream
,
966 PPORTWAVEPCISTREAM(this),
967 ConnectDetails
->PinId
,
973 DPRINT("IPortPinWavePci_fnInit Status %x\n", Status
);
975 if (!NT_SUCCESS(Status
))
980 Status
= m_ServiceGroup
->AddMember(PSERVICESINK(this));
981 if (!NT_SUCCESS(Status
))
983 DPRINT1("Failed to add pin to service group\n");
986 m_ServiceGroup
->SupportDelayedService();
989 // delay of 10 milisec
990 m_Delay
= Int32x32To64(10, -10000);
992 Status
= m_Stream
->GetAllocatorFraming(&m_AllocatorFraming
);
993 if (!NT_SUCCESS(Status
))
995 DPRINT1("GetAllocatorFraming failed with %x\n", Status
);
999 DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n",
1000 m_AllocatorFraming
.OptionsFlags
, m_AllocatorFraming
.RequirementsFlags
, m_AllocatorFraming
.PoolType
, m_AllocatorFraming
.Frames
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
);
1002 ISubdevice
* Subdevice
= NULL
;
1003 // get subdevice interface
1004 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&Subdevice
);
1006 if (!NT_SUCCESS(Status
))
1009 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
= NULL
;
1011 Status
= Subdevice
->GetDescriptor(&SubDeviceDescriptor
);
1012 if (!NT_SUCCESS(Status
))
1014 // failed to get descriptor
1015 Subdevice
->Release();
1019 /* set up subdevice descriptor */
1020 RtlZeroMemory(&m_Descriptor
, sizeof(SUBDEVICE_DESCRIPTOR
));
1021 m_Descriptor
.FilterPropertySet
= PinWavePciPropertySet
;
1022 m_Descriptor
.FilterPropertySetCount
= sizeof(PinWavePciPropertySet
) / sizeof(KSPROPERTY_SET
);
1023 m_Descriptor
.UnknownStream
= (PUNKNOWN
)m_Stream
;
1024 m_Descriptor
.DeviceDescriptor
= SubDeviceDescriptor
->DeviceDescriptor
;
1025 m_Descriptor
.UnknownMiniport
= SubDeviceDescriptor
->UnknownMiniport
;
1026 m_Descriptor
.PortPin
= (PVOID
)this;
1030 Status
= NewIrpQueue(&m_IrpQueue
);
1031 if (!NT_SUCCESS(Status
))
1034 Status
= m_IrpQueue
->Init(ConnectDetails
, m_Format
, DeviceObject
, m_AllocatorFraming
.FrameSize
, m_AllocatorFraming
.FileAlignment
, NULL
);
1035 if (!NT_SUCCESS(Status
))
1037 DPRINT1("IrpQueue_Init failed with %x\n", Status
);
1041 m_State
= KSSTATE_STOP
;
1042 m_Capture
= Capture
;
1044 return STATUS_SUCCESS
;
1049 CPortPinWavePci::GetIrpStream()
1051 return (PVOID
)m_IrpQueue
;
1057 CPortPinWavePci::GetMiniport()
1059 return (PMINIPORT
)m_Miniport
;
1065 OUT IPortPinWavePci
** OutPin
)
1067 CPortPinWavePci
* This
;
1069 This
= new(NonPagedPool
, TAG_PORTCLASS
) CPortPinWavePci(NULL
);
1071 return STATUS_INSUFFICIENT_RESOURCES
;
1076 *OutPin
= (IPortPinWavePci
*)This
;
1078 return STATUS_SUCCESS
;