Beispiel #1
0
NTSTATUS 
InstallEndpointRenderFilters(
    _In_ PDEVICE_OBJECT     DeviceObject, 
    _In_ PIRP               Irp, 
    _In_ PADAPTERCOMMON     AdapterCommon,
    _In_ PENDPOINT_MINIPAIR MiniportPairs
    )
{
    PAGED_CODE();

    NTSTATUS                    ntStatus                = STATUS_SUCCESS;
    PUNKNOWN                    unknownTopology         = NULL;
    PUNKNOWN                    unknownWave             = NULL;
    PPORTCLSETWHELPER           pPortClsEtwHelper       = NULL;
    
    UNREFERENCED_PARAMETER(DeviceObject);

    ntStatus = AdapterCommon->InstallEndpointFilters(
        Irp,
        MiniportPairs,
        NULL,
        &unknownTopology,
        &unknownWave);

    if (unknownWave) // IID_IPortClsEtwHelper and IID_IPortClsRuntimePower interfaces are only exposed on the WaveRT port.
    {
        ntStatus = unknownWave->QueryInterface (IID_IPortClsEtwHelper, (PVOID *)&pPortClsEtwHelper);
        if (NT_SUCCESS(ntStatus))
        {
            AdapterCommon->SetEtwHelper(pPortClsEtwHelper);
            ASSERT(pPortClsEtwHelper != NULL);
            pPortClsEtwHelper->Release();
        }
    }

    SAFE_RELEASE(unknownTopology);
    SAFE_RELEASE(unknownWave);

    return ntStatus;
}
Beispiel #2
0
/*****************************************************************************
 * StartDevice()
 *****************************************************************************
 *
 *  This function is called by the operating system when the device is started.
 *  It is responsible for starting the miniports.  This code is specific to
 *  the adapter because it calls out miniports for functions that are specific
 *  to the adapter.  A list of no resources is not the same as a NULL list ptr.
 *
 */
NTSTATUS
StartDevice
(
    IN      PDEVICE_OBJECT  pDeviceObject,  // Context for the class driver.
    IN      PIRP            pIrp,           // Context for the class driver.
    IN      PRESOURCELIST   ResourceList    // List of hardware resources.
)
{
    PAGED_CODE();

    _DbgPrintF(DEBUGLVL_VERBOSE, ("StartDevice"));

    ASSERT(ResourceList);
    if (!ResourceList)
    {
        return STATUS_INVALID_PARAMETER;
    }

    PPORT       port;
    NTSTATUS    ntStatus = PcNewPort(&port, CLSID_PortDMus);

    if (!NT_SUCCESS(ntStatus))
    {
        _DbgPrintF(DEBUGLVL_TERSE,("StartDevice PcNewPort failed (0x%08x)", ntStatus));
        return ntStatus;
    }
    ASSERT(port);

    PUNKNOWN miniport;
#ifdef USE_OBSOLETE_FUNCS
    ntStatus = CreateMiniportDmSynth(&miniport, NULL, NonPagedPool);
#else
    ntStatus = CreateMiniportDmSynth(&miniport, NULL, NonPagedPool, pDeviceObject);
#endif

    if (!NT_SUCCESS(ntStatus))
    {
        _DbgPrintF(DEBUGLVL_TERSE,("StartDevice CreateMiniportDmSynth failed (0x%08x)", ntStatus));
        port->Release();
        return ntStatus;
    }
    ASSERT(miniport);

    ntStatus =
        port->Init
        (
            pDeviceObject,
            pIrp,
            miniport,
            NULL,
            ResourceList
        );

    if (!NT_SUCCESS(ntStatus))
    {
        _DbgPrintF(DEBUGLVL_TERSE,("StartDevice port Init failed (0x%08x)", ntStatus));
        port->Release();
        miniport->Release();
        return ntStatus;
    }

    ntStatus = PcRegisterSubdevice( pDeviceObject,
                                    L"DDKSynth",
                                    port);
    if (!NT_SUCCESS(ntStatus))
    {
        _DbgPrintF(DEBUGLVL_TERSE,("StartDevice PcRegisterSubdevice failed (0x%08x)", ntStatus));
    }

    //
    // We don't need the miniport any more.  Either the port has it,
    // or we've failed, and it should be deleted.
    //
    miniport->Release();

    //
    // Release the reference which existed when PcNewPort() gave us the
    // pointer in the first place.  This is the right thing to do
    // regardless of the outcome.
    //
    port->Release();

    return ntStatus;
}
Beispiel #3
0
//=============================================================================
NTSTATUS StartDevice(
    IN  PDEVICE_OBJECT          DeviceObject,     
    IN  PIRP                    Irp,              
    IN  PRESOURCELIST           ResourceList      
)  
/*++
Routine Description:
  This function is called by the operating system when the device is 
  started.
  It is responsible for starting the miniports.  This code is specific to    
  the adapter because it calls out miniports for functions that are specific 
  to the adapter.                                                            

Arguments:
  DeviceObject - pointer to the driver object
  Irp - pointer to the irp 
  ResourceList - pointer to the resource list assigned by PnP manager

Return Value:
  NT status code.
--*/
{
    UNREFERENCED_PARAMETER(ResourceList);

    PAGED_CODE();
    
    ASSERT(DeviceObject);
    ASSERT(Irp);
    ASSERT(ResourceList);

    NTSTATUS       ntStatus        = STATUS_SUCCESS;
    PUNKNOWN       unknownTopology = NULL;
    PUNKNOWN       unknownWave     = NULL;
    PADAPTERCOMMON pAdapterCommon  = NULL;
    PUNKNOWN       pUnknownCommon  = NULL;

    DPF_ENTER(("[StartDevice]"));

    // create a new adapter common object
    ntStatus = NewAdapterCommon(&pUnknownCommon, IID_IAdapterCommon, NULL, NonPagedPool);
    if (NT_SUCCESS(ntStatus)) {
        ntStatus = pUnknownCommon->QueryInterface(IID_IAdapterCommon, (PVOID *) &pAdapterCommon);
        if (NT_SUCCESS(ntStatus)) {
            ntStatus = pAdapterCommon->Init(DeviceObject);
            if (NT_SUCCESS(ntStatus)) {
                // register with PortCls for power-management services
                ntStatus = PcRegisterAdapterPowerManagement(PUNKNOWN(pAdapterCommon), DeviceObject);
            }
        }
    }

    // install MSVAD topology miniport.
    if (NT_SUCCESS(ntStatus)) {
        ntStatus = InstallSubdevice(DeviceObject, Irp, L"Topology", CLSID_PortTopology, CLSID_PortTopology, CreateMiniportTopologyMSVAD, pAdapterCommon, NULL, IID_IPortTopology, NULL, &unknownTopology);
    }

    // install MSVAD wavecyclic miniport.
    if (NT_SUCCESS(ntStatus)) {
        ntStatus = InstallSubdevice(DeviceObject, Irp, L"Wave", CLSID_PortWaveCyclic, CLSID_PortWaveCyclic, CreateMiniportWaveCyclicMSVAD, pAdapterCommon, NULL, IID_IPortWaveCyclic, pAdapterCommon->WavePortDriverDest(), &unknownWave);
    }

    if (unknownTopology && unknownWave) {
        // register wave <=> topology connections
        // This will connect bridge pins of wavecyclic and topology
        // miniports.
        if ((TopologyPhysicalConnections.ulTopologyOut != (ULONG)-1) && (TopologyPhysicalConnections.ulWaveIn != (ULONG)-1)) {
            ntStatus = PcRegisterPhysicalConnection(DeviceObject, unknownTopology, TopologyPhysicalConnections.ulTopologyOut, unknownWave, TopologyPhysicalConnections.ulWaveIn);
        }

        if (NT_SUCCESS(ntStatus)) {
            if ((TopologyPhysicalConnections.ulWaveOut != (ULONG)-1) && (TopologyPhysicalConnections.ulTopologyIn != (ULONG)-1)) {
                ntStatus = PcRegisterPhysicalConnection(DeviceObject, unknownWave, TopologyPhysicalConnections.ulWaveOut, unknownTopology, TopologyPhysicalConnections.ulTopologyIn);
            }
        }
    }

    // Release the adapter common object.  It either has other references,
    // or we need to delete it anyway.
    if (pAdapterCommon) {
        pAdapterCommon->Release();
    }

    if (pUnknownCommon) {
        pUnknownCommon->Release();
    }
    
    if (unknownTopology) {
        unknownTopology->Release();
    }

    if (unknownWave) {
        unknownWave->Release();
    }

    return ntStatus;
} // StartDevice
Beispiel #4
0
//=============================================================================
NTSTATUS InstallSubdevice( 
    __in        PDEVICE_OBJECT    DeviceObject,
    __in        PIRP              Irp,
    __in        PWSTR             Name,
    __in        REFGUID           PortClassId,
    __in        REFGUID           MiniportClassId,
    __in_opt    PFNCREATEINSTANCE MiniportCreate,
    __in_opt    PUNKNOWN          UnknownAdapter,
    __in_opt    PRESOURCELIST     ResourceList,
    __in        REFGUID           PortInterfaceId,
    __out_opt   PUNKNOWN *        OutPortInterface,
    __out_opt   PUNKNOWN *        OutPortUnknown
)
/*++
Routine Description:
    This function creates and registers a subdevice consisting of a port       
    driver, a minport driver and a set of resources bound together.  It will   
    also optionally place a pointer to an interface on the port driver in a    
    specified location before initializing the port driver.  This is done so   
    that a common ISR can have access to the port driver during 
    initialization, when the ISR might fire.                                   

Arguments:
    DeviceObject - pointer to the driver object
    Irp - pointer to the irp object.
    Name - name of the miniport. Passes to PcRegisterSubDevice
    PortClassId - port class id. Passed to PcNewPort.
    MiniportClassId - miniport class id. Passed to PcNewMiniport.
    MiniportCreate - pointer to a miniport creation function. If NULL, 
                     PcNewMiniport is used.
    UnknownAdapter - pointer to the adapter object. 
                     Used for initializing the port.
    ResourceList - pointer to the resource list.
    PortInterfaceId - GUID that represents the port interface.
    OutPortInterface - pointer to store the port interface
    OutPortUnknown - pointer to store the unknown port interface.

Return Value:
    NT status code.
--*/
{
    PAGED_CODE();

    ASSERT(DeviceObject);
    ASSERT(Irp);
    ASSERT(Name);

    NTSTATUS ntStatus;
    PPORT    port = NULL;
    PUNKNOWN miniport = NULL;
     
    DPF_ENTER(("[InstallSubDevice %S]", Name));

    // Create the port driver object
    ntStatus = PcNewPort(&port, PortClassId);

    // Create the miniport object
    if (NT_SUCCESS(ntStatus)) {
        if (MiniportCreate) {
            ntStatus = MiniportCreate(&miniport, MiniportClassId, NULL, NonPagedPool  );
        } else {
            ntStatus = PcNewMiniport((PMINIPORT *) &miniport, MiniportClassId);
        }
    }

    // Init the port driver and miniport in one go.
    if (NT_SUCCESS(ntStatus)) {
        ntStatus = port->Init(DeviceObject, Irp, miniport, UnknownAdapter, ResourceList);

        if (NT_SUCCESS(ntStatus)) {
            // Register the subdevice (port/miniport combination).
            ntStatus = PcRegisterSubdevice(DeviceObject, Name, port);
        }

        // We don't need the miniport any more.  Either the port has it,
        // or we've failed, and it should be deleted.
        miniport->Release();
    }

    // Deposit the port interfaces if it's needed.
    if (NT_SUCCESS(ntStatus)) {
        if (OutPortUnknown) {
            ntStatus = port->QueryInterface(IID_IUnknown, (PVOID *)OutPortUnknown);
        }

        if (OutPortInterface) {
            ntStatus = port->QueryInterface(PortInterfaceId, (PVOID *) OutPortInterface);
        }
    }

    if (port) {
        port->Release();
    }

    return ntStatus;
} // InstallSubDevice
Beispiel #5
0
/*****************************************************************************
 * StartDevice
 *****************************************************************************
 * This function is called by the operating system when the device is started.
 * It is responsible for starting the miniports.  This code is specific to
 * the adapter because it calls out miniports for functions that are specific
 * to the adapter.
 */
NTSTATUS StartDevice
(
    IN  PDEVICE_OBJECT  DeviceObject,   // Device object.
    IN  PIRP            Irp,            // IO request packet.
    IN  PRESOURCELIST   ResourceList    // List of hardware resources.
)
{
    PAGED_CODE ();

    ASSERT (DeviceObject);
    ASSERT (Irp);
    ASSERT (ResourceList);

    NTSTATUS ntStatus;

    DOUT (DBG_PRINT, ("[StartDevice]"));

    //
    // Determine which version of the OS we are running under.  We don't want
    // to run under Win98G.
    //

    // create a wave cyclic port
    PPORT pPort = 0;
    ntStatus = PcNewPort (&pPort,CLSID_PortWaveCyclic);

    // check error code
    if (NT_SUCCESS (ntStatus))
    {
        // query for the event interface which is not supported in Win98 gold.
        PPORTEVENTS pPortEvents = 0;
        ntStatus = pPort->QueryInterface (IID_IPortEvents,
                                         (PVOID *)&pPortEvents);
        if (!NT_SUCCESS (ntStatus))
        {
            DOUT (DBG_ERROR, ("This driver is not for Win98 Gold!"));
            ntStatus = STATUS_UNSUCCESSFUL;     // change error code.
        }
        else
        {
            pPortEvents->Release ();
        }
        pPort->Release ();
    }

    // now return in case it was Win98 Gold.
    if (!NT_SUCCESS (ntStatus))
        return ntStatus;

    //
    // Validate the resources.
    // We don't have to split the resources into several resource lists cause
    // the topology miniport doesn't need a resource list, the wave pci miniport
    // needs all resources like the adapter common object.
    //
    ntStatus = ValidateResources (ResourceList);

    //
    // return immediately in case of an error
    //
    if (!NT_SUCCESS (ntStatus))
        return ntStatus;

    //
    // If the adapter has the right resources...
    //
    PADAPTERCOMMON pAdapterCommon = NULL;
    PUNKNOWN       pUnknownCommon;

    // create a new adapter common object
    ntStatus = NewAdapterCommon (&pUnknownCommon, IID_IAC97AdapterCommon,
                                 NULL, NonPagedPool);

    if (NT_SUCCESS (ntStatus))
    {
        // query for the IAC97AdapterCommon interface
        ntStatus = pUnknownCommon->QueryInterface (IID_IAC97AdapterCommon,
                                                   (PVOID *)&pAdapterCommon);
        if (NT_SUCCESS (ntStatus))
        {
            // Initialize the object
            ntStatus = pAdapterCommon->Init (ResourceList, DeviceObject);

            if (NT_SUCCESS (ntStatus))
            {
                // register with PortCls for power-management services
                ntStatus = PcRegisterAdapterPowerManagement ((PUNKNOWN)pAdapterCommon,
                                                             DeviceObject);
            }
        }

        // release the IID_IAC97AdapterCommon on adapter common
        pUnknownCommon->Release ();
    }

    // print error message.
    if (!NT_SUCCESS (ntStatus))
    {
        DOUT (DBG_ERROR, ("Could not create or query AdapterCommon."));
    }

    //
    // These are the port driver pointers we are keeping around for registering
    // physical connections.
    //
    PMINIPORT               miniTopology            = NULL;
    PUNKNOWN                unknownWave             = NULL;
    PUNKNOWN                unknownTopology         = NULL;
    PAC97MINIPORTTOPOLOGY   pMiniportTopology       = NULL;

    //
    // Start the topology miniport.
    //
    if (NT_SUCCESS (ntStatus))
    {
        ntStatus = InstallSubdevice (DeviceObject,
                                     Irp,
                                     L"Topology",
                                     CLSID_PortTopology,
                                     CLSID_PortTopology, // not used
                                     CreateAC97MiniportTopology,
                                     pAdapterCommon,
                                     NULL,
                                     GUID_NULL,
                                     &miniTopology,
                                     &unknownTopology);

        if (NT_SUCCESS (ntStatus))
        {
            // query for the IAC97MiniportTopology interface
            ntStatus = miniTopology->QueryInterface (IID_IAC97MiniportTopology,
                                                    (PVOID *)&pMiniportTopology);
            miniTopology->Release ();
            miniTopology = NULL;
        }

        // print error message.
        if (!NT_SUCCESS (ntStatus))
        {
            DOUT (DBG_ERROR, ("Could not create or query TopologyICH"));
        }
    }

    //
    // Start the wave miniport.
    //
    if (NT_SUCCESS (ntStatus))
    {
#if (NTDDI_VERSION >= NTDDI_VISTA)
        ntStatus = InstallSubdevice (DeviceObject,
                                     Irp,
                                     L"Wave",
                                     CLSID_PortWaveRT,
                                     CLSID_PortWaveRT,      // not used
                                     CreateAC97MiniportWaveRT,
                                     pAdapterCommon,
                                     ResourceList,
                                     IID_IPortWaveRT,
                                     NULL,
                                     &unknownWave);

        if (!NT_SUCCESS (ntStatus))
        {
#endif
            //
            // If creation of the RT port failed we can fall back to the WavePCI
            // or WaveCyc port of portcls. In this case, we try the WavePCI port.
            //
            ntStatus = InstallSubdevice (DeviceObject,
                                         Irp,
                                         L"Wave",
                                         CLSID_PortWavePci,
                                         CLSID_PortWavePci,   // not used
                                         CreateAC97MiniportWavePCI,
                                         pAdapterCommon,
                                         ResourceList,
                                         IID_IPortWavePci,
                                         NULL,
                                         &unknownWave);
#if (NTDDI_VERSION >= NTDDI_VISTA)
        }
#endif
        // print error message.
        if (!NT_SUCCESS (ntStatus))
        {
            DOUT (DBG_ERROR, ("WaveRT and WavePCI miniport installation failed!"));
        }
    }

    //
    // Establish physical connections between filters as shown.
    //
    //              +------+    +------+
    //              | Wave |    | Topo |
    //  Capture <---|2    3|<===|x     |<--- CD
    //              |      |    |      |
    //   Render --->|0    1|===>|y     |<--- Line In
    //              |      |    |      |
    //      Mic <---|4    5|<===|z     |<--- Mic
    //              +------+    |      |
    //                          |      |---> Line Out
    //                          +------+
    //
    // Note that the pin numbers for the nodes to be connected
    // vary depending on the hardware/codec configuration.
    // Also, the mic input may or may not be present.
    //
    // So,
    //      Do a QI on unknownTopology to get an interface to call
    //          a method on to get the topology miniport pin IDs.

    if (NT_SUCCESS (ntStatus))
    {
        ULONG ulWaveOut, ulWaveIn, ulMicIn;

        // get the pin numbers.
        DOUT (DBG_PRINT, ("Connecting topo and wave."));
        ntStatus = pMiniportTopology->GetPhysicalConnectionPins (&ulWaveOut,
                                            &ulWaveIn, &ulMicIn);

        // register wave render connection
        if (NT_SUCCESS (ntStatus))
        {
            ntStatus = PcRegisterPhysicalConnection (DeviceObject,
                                                     unknownWave,
                                                     PIN_WAVEOUT_BRIDGE,
                                                     unknownTopology,
                                                     ulWaveOut);
            // print error message.
            if (!NT_SUCCESS (ntStatus))
            {
                DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport"
                                  " (render)!"));
            }
        }


        if (NT_SUCCESS (ntStatus))
        {
            // register wave capture connection
            ntStatus = PcRegisterPhysicalConnection (DeviceObject,
                                                     unknownTopology,
                                                     ulWaveIn,
                                                     unknownWave,
                                                     PIN_WAVEIN_BRIDGE);
            // print error message.
            if (!NT_SUCCESS (ntStatus))
            {
                DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport"
                                  " (capture)!"));
            }
        }

        if (NT_SUCCESS (ntStatus))
        {
            // register mic capture connection
            if (pAdapterCommon->GetPinConfig (PINC_MICIN_PRESENT))
            {
                ntStatus = PcRegisterPhysicalConnection (DeviceObject,
                                                         unknownTopology,
                                                         ulMicIn,
                                                         unknownWave,
                                                         PIN_MICIN_BRIDGE);
                // print error message.
                if (!NT_SUCCESS (ntStatus))
                {
                    DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport"
                                      " (MIC)!"));
                }
            }
        }
    }

    //
    // Release the adapter common object.  It either has other references,
    // or we need to delete it anyway.
    //
    if (pAdapterCommon)
        pAdapterCommon->Release ();

    //
    // Release the unknowns.
    //
    if (unknownTopology)
        unknownTopology->Release ();
    if (unknownWave)
        unknownWave->Release ();

    // and the AC97 miniport.
    if (pMiniportTopology)
        pMiniportTopology->Release ();


    return ntStatus;    // whatever this is ...
}
Beispiel #6
0
_Use_decl_annotations_
NTSTATUS
StartDevice
( 
    PDEVICE_OBJECT          DeviceObject,     
    PIRP                    Irp,              
    PRESOURCELIST           ResourceList      
)  
{
/*++

Routine Description:

    This function is called by the operating system when the device is 
    started.
    It is responsible for starting the miniports.  This code is specific to    
    the adapter because it calls out miniports for functions that are specific 
    to the adapter.                                                            

Arguments:

    DeviceObject - pointer to the driver object

    Irp - pointer to the irp 

    ResourceList - pointer to the resource list assigned by PnP manager

Return Value:

    NT status code

--*/
    PAGED_CODE();

    UNREFERENCED_PARAMETER(ResourceList);

    ASSERT(DeviceObject);
    ASSERT(Irp);
    ASSERT(ResourceList);

    NTSTATUS                    ntStatus        = STATUS_SUCCESS;

    PADAPTERCOMMON              pAdapterCommon  = NULL;
    PUNKNOWN                    pUnknownCommon  = NULL;
    PortClassDeviceContext*     pExtension      = static_cast<PortClassDeviceContext*>(DeviceObject->DeviceExtension);

    DPF_ENTER(("[StartDevice]"));

    //
    // create a new adapter common object
    //
    ntStatus = NewAdapterCommon( 
                                &pUnknownCommon,
                                IID_IAdapterCommon,
                                NULL,
                                NonPagedPoolNx 
                                );
    IF_FAILED_JUMP(ntStatus, Exit);

    ntStatus = pUnknownCommon->QueryInterface( IID_IAdapterCommon,(PVOID *) &pAdapterCommon);
    IF_FAILED_JUMP(ntStatus, Exit);

    ntStatus = pAdapterCommon->Init(DeviceObject);
    IF_FAILED_JUMP(ntStatus, Exit);

    //
    // register with PortCls for power-management services
    ntStatus = PcRegisterAdapterPowerManagement( PUNKNOWN(pAdapterCommon), DeviceObject);
    IF_FAILED_JUMP(ntStatus, Exit);

    //
    // Install wave+topology filters for render devices
    //
    ntStatus = InstallAllRenderFilters(DeviceObject, Irp, pAdapterCommon);
    IF_FAILED_JUMP(ntStatus, Exit);

Exit:

    //
    // Stash the adapter common object in the device extension so
    // we can access it for cleanup on stop/removal.
    //
    if (pAdapterCommon)
    {
        ASSERT(pExtension != NULL);
        pExtension->m_pCommon = pAdapterCommon;
    }

    //
    // Release the adapter IUnknown interface.
    //
    SAFE_RELEASE(pUnknownCommon);
    
    return ntStatus;
}