//================================================================================================================================== NTSTATUS NTAPI CPortPinWavePci::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { //DPRINT("CPortPinWavePci::QueryInterface entered\n"); if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || IsEqualGUIDAligned(refiid, IID_IUnknown)) { *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) { *Output = PVOID(PSERVICESINK(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } if (IsEqualGUIDAligned(refiid, IID_IPortWavePciStream)) { *Output = PVOID(PPORTWAVEPCISTREAM(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } return STATUS_UNSUCCESSFUL; }
VOID NTAPI CPortDMus::RegisterServiceGroup( IN PSERVICEGROUP ServiceGroup) { PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); m_ServiceGroup = ServiceGroup; ServiceGroup->AddMember(PSERVICESINK(this)); }
NTSTATUS NTAPI CPortWavePci::Init( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PUNKNOWN UnknownMiniport, IN PUNKNOWN UnknownAdapter OPTIONAL, IN PRESOURCELIST ResourceList) { IMiniportWavePci * Miniport; PSERVICEGROUP ServiceGroup = 0; NTSTATUS Status; PPINCOUNT PinCount; PPOWERNOTIFY PowerNotify; DPRINT("IPortWavePci_fnInit entered with This %p, DeviceObject %p Irp %p UnknownMiniport %p, UnknownAdapter %p ResourceList %p\n", this, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList); PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); Status = UnknownMiniport->QueryInterface(IID_IMiniportWavePci, (PVOID*)&Miniport); if (!NT_SUCCESS(Status)) { DPRINT("IPortWavePci_fnInit called with invalid IMiniport adapter\n"); return STATUS_INVALID_PARAMETER; } // Initialize port object m_Miniport = Miniport; m_pDeviceObject = DeviceObject; InitializeListHead(&m_EventList); KeInitializeSpinLock(&m_EventListLock); // increment reference on miniport adapter Miniport->AddRef(); Status = Miniport->Init(UnknownAdapter, ResourceList, this, &ServiceGroup); if (!NT_SUCCESS(Status)) { DPRINT("IPortWavePci_fnInit failed with %x\n", Status); // release reference on miniport adapter Miniport->Release(); return Status; } // check if the miniport adapter provides a valid device descriptor Status = Miniport->GetDescription(&m_pDescriptor); if (!NT_SUCCESS(Status)) { DPRINT("failed to get description\n"); Miniport->Release(); return Status; } // create the subdevice descriptor Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, 3, InterfaceGuids, 0, NULL, 2, WavePciPropertySet, 0, 0, 0, NULL, 0, NULL, m_pDescriptor); if (!NT_SUCCESS(Status)) { DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status); Miniport->Release(); return Status; } // did we get a service group if (ServiceGroup) { // store service group in context m_ServiceGroup = ServiceGroup; // add ourselves to service group which is called when miniport receives an isr m_ServiceGroup->AddMember(PSERVICESINK(this)); // increment reference on service group m_ServiceGroup->AddRef(); } // store for node property requests m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport; // check if it supports IPinCount interface Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount); if (NT_SUCCESS(Status)) { // store IPinCount interface m_pPinCount = PinCount; } // does the Miniport adapter support IPowerNotify interface*/ Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify); if (NT_SUCCESS(Status)) { // store reference m_pPowerNotify = PowerNotify; } DPRINT("IPortWavePci_Init successfully initialized\n"); return STATUS_SUCCESS; }
NTSTATUS NTAPI CPortWavePci::QueryInterface( IN REFIID refiid, OUT PVOID* Output) { UNICODE_STRING GuidString; DPRINT("IPortWavePci_fnQueryInterface entered\n"); if (IsEqualGUIDAligned(refiid, IID_IPortWavePci) || IsEqualGUIDAligned(refiid, IID_IUnknown) || IsEqualGUIDAligned(refiid, IID_IPort)) { *Output = PVOID(PPORTWAVEPCI(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } else if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) { *Output = PVOID(PSERVICESINK(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } else if (IsEqualGUIDAligned(refiid, IID_IPortEvents)) { *Output = PVOID(PPORTEVENTS(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } else if (IsEqualGUIDAligned(refiid, IID_ISubdevice)) { *Output = PVOID(PSUBDEVICE(this)); PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } else if (IsEqualGUIDAligned(refiid, IID_IDrmPort) || IsEqualGUIDAligned(refiid, IID_IDrmPort2)) { return NewIDrmPort((PDRMPORT2*)Output); } else if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion)) { return NewPortClsVersion((PPORTCLSVERSION*)Output); } else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice)) { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); } else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection)) { return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); } if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) { DPRINT("IPortWavePci_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer); RtlFreeUnicodeString(&GuidString); } return STATUS_UNSUCCESSFUL; }
NTSTATUS NTAPI CPortPinWavePci::Init( IN PPORTWAVEPCI Port, IN PPORTFILTERWAVEPCI Filter, IN KSPIN_CONNECT * ConnectDetails, IN KSPIN_DESCRIPTOR * KsPinDescriptor, IN PDEVICE_OBJECT DeviceObject) { NTSTATUS Status; PKSDATAFORMAT DataFormat; BOOLEAN Capture; ISubdevice * Subdevice = NULL; PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; // check if it is a source / sink pin if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) { // sink pin Capture = FALSE; } else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) { // source pin Capture = TRUE; } else { DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow); DbgBreakPoint(); while(TRUE); } // add port / filter reference Port->AddRef(); Filter->AddRef(); // initialize pin m_Port = Port; m_Filter = Filter; m_KsPinDescriptor = KsPinDescriptor; m_ConnectDetails = ConnectDetails; m_Miniport = GetWavePciMiniport(Port); m_DeviceObject = DeviceObject; m_State = KSSTATE_STOP; m_Capture = Capture; DPRINT("IPortPinWavePci_fnInit entered\n"); // get dataformat DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); // allocate data format m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); if (!m_Format) { // release references m_Port->Release(); m_Filter->Release(); // no dangling pointers Port = NULL; Filter = NULL; // failed to allocate data format return STATUS_INSUFFICIENT_RESOURCES; } // copy data format RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); // allocate new stream Status = m_Miniport->NewStream(&m_Stream, NULL, NonPagedPool, PPORTWAVEPCISTREAM(this), ConnectDetails->PinId, Capture, m_Format, &m_DmaChannel, &m_ServiceGroup); DPRINT("IPortPinWavePci_fnInit Status %x\n", Status); if (!NT_SUCCESS(Status)) { // free references Port->Release(); Filter->Release(); // free data format FreeItem(m_Format, TAG_PORTCLASS); // no dangling pointers m_Port = NULL; m_Filter = NULL; m_Format = NULL; // failed to allocate stream return Status; } // get allocator requirements for pin Status = m_Stream->GetAllocatorFraming(&m_AllocatorFraming); if (NT_SUCCESS(Status)) { DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); } // allocate new irp queue Status = NewIrpQueue(&m_IrpQueue); if (!NT_SUCCESS(Status)) { // free references Port->Release(); Filter->Release(); m_Stream->Release(); // free data format FreeItem(m_Format, TAG_PORTCLASS); // no dangling pointers m_Port = NULL; m_Filter = NULL; m_Format = NULL; m_Stream = NULL; // failed to allocate irp queue return Status; } // initialize irp queue Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment, TRUE); if (!NT_SUCCESS(Status)) { // this should never happen ASSERT(0); } // get subdevice interface Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice); if (!NT_SUCCESS(Status)) { // this function should never fail ASSERT(0); } // get subdevice descriptor Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); if (!NT_SUCCESS(Status)) { // this function should never fail ASSERT(0); } // release subdevice Subdevice->Release(); /* set up subdevice descriptor */ RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); m_Descriptor.FilterPropertySet = PinWavePciPropertySet; m_Descriptor.FilterPropertySetCount = sizeof(PinWavePciPropertySet) / sizeof(KSPROPERTY_SET); m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream; m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor; m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; m_Descriptor.PortPin = (PVOID)this; if (m_ServiceGroup) { Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); if (!NT_SUCCESS(Status)) { // free references m_Stream->Release(); Port->Release(); Filter->Release(); // free data format FreeItem(m_Format, TAG_PORTCLASS); // no dangling pointers m_Stream = NULL; m_Port = NULL; m_Filter = NULL; m_Format = NULL; // failed to add to service group return Status; } } return STATUS_SUCCESS; }
NTSTATUS NTAPI CPortPinWavePci::Close( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status; if (m_Format) { // free format FreeItem(m_Format, TAG_PORTCLASS); // format is freed m_Format = NULL; } if (m_IrpQueue) { // cancel remaining irps m_IrpQueue->CancelBuffers(); // release irp queue m_IrpQueue->Release(); // queue is freed m_IrpQueue = NULL; } if (m_ServiceGroup) { // remove member from service group m_ServiceGroup->RemoveMember(PSERVICESINK(this)); // do not release service group, it is released by the miniport object m_ServiceGroup = NULL; } if (m_Stream) { if (m_State != KSSTATE_STOP) { // stop stream Status = m_Stream->SetState(KSSTATE_STOP); if (!NT_SUCCESS(Status)) { DPRINT("Warning: failed to stop stream with %x\n", Status); PC_ASSERT(0); } } // set state to stop m_State = KSSTATE_STOP; DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); // release stream m_Stream->Release(); // stream is now freed m_Stream = NULL; } if (m_Filter) { // disconnect pin from filter m_Filter->FreePin((PPORTPINWAVEPCI)this); // release filter reference m_Filter->Release(); // pin is done with filter m_Filter = NULL; } if (m_Port) { // release reference to port driver m_Port->Release(); // work is done for port m_Port = NULL; } // successfully complete irp Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }