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; }
//============================================================================= 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
/***************************************************************************** * 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 ... }
_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; }