Пример #1
0
//==================================================================================================================================
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;
}
Пример #2
0
VOID
NTAPI
CPortDMus::RegisterServiceGroup(
    IN PSERVICEGROUP  ServiceGroup)
{
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    m_ServiceGroup = ServiceGroup;

    ServiceGroup->AddMember(PSERVICESINK(this));
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}