minwave.cpp
来自「winddk src目录下的WDM源码压缩!」· C++ 代码 · 共 1,666 行 · 第 1/5 页
CPP
1,666 行
// We only have a set defined.
if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
{
// validate buffer size.
if (PropertyRequest->ValueSize < sizeof(LONG))
return ntStatus;
// The "Value" is the input buffer with the channel config.
if (PropertyRequest->Value)
{
// We can accept different channel configurations, depending
// on the number of channels we can play.
if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
{
if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
{
// we accept 5.1
if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_5POINT1)
{
that->m_dwChannelMask = *(PLONG)PropertyRequest->Value;
that->m_wChannels = 6;
that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask);
ntStatus = STATUS_SUCCESS;
}
}
// accept also surround or quad.
if ((*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_QUAD) ||
(*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_SURROUND))
{
that->m_dwChannelMask = *(PLONG)PropertyRequest->Value;
that->m_wChannels = 4;
that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask);
ntStatus = STATUS_SUCCESS;
}
}
// accept also stereo speakers.
if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_STEREO)
{
that->m_dwChannelMask = *(PLONG)PropertyRequest->Value;
that->m_wChannels = 2;
that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask);
ntStatus = STATUS_SUCCESS;
}
}
}
return ntStatus;
}
/*****************************************************************************
* CreateMiniportWaveICH
*****************************************************************************
* Creates a ICH wave miniport object for the ICH adapter.
* This uses a macro from STDUNK.H to do all the work.
*/
NTSTATUS CreateMiniportWaveICH
(
OUT PUNKNOWN *Unknown,
IN REFCLSID,
IN PUNKNOWN UnknownOuter OPTIONAL,
IN POOL_TYPE PoolType
)
{
PAGED_CODE ();
ASSERT (Unknown);
DOUT (DBG_PRINT, ("[CreateMiniportWaveICH]"));
STD_CREATE_BODY_(CMiniportWaveICH,Unknown,UnknownOuter,PoolType,
PMINIPORTWAVEPCI);
}
/*****************************************************************************
* CMiniportWaveICH::NonDelegatingQueryInterface
*****************************************************************************
* Obtains an interface. This function works just like a COM QueryInterface
* call and is used if the object is not being aggregated.
*/
STDMETHODIMP_(NTSTATUS) CMiniportWaveICH::NonDelegatingQueryInterface
(
IN REFIID Interface,
OUT PVOID *Object
)
{
PAGED_CODE ();
ASSERT (Object);
DOUT (DBG_PRINT, ("[CMiniportWaveICH::NonDelegatingQueryInterface]"));
// Is it IID_IUnknown?
if (IsEqualGUIDAligned (Interface, IID_IUnknown))
{
*Object = (PVOID)(PUNKNOWN)(PMINIPORTWAVEPCI)this;
}
// or IID_IMiniport ...
else if (IsEqualGUIDAligned (Interface, IID_IMiniport))
{
*Object = (PVOID)(PMINIPORT)this;
}
// or IID_IMiniportWavePci ...
else if (IsEqualGUIDAligned (Interface, IID_IMiniportWavePci))
{
*Object = (PVOID)(PMINIPORTWAVEPCI)this;
}
// or IID_IPowerNotify ...
else if (IsEqualGUIDAligned (Interface, IID_IPowerNotify))
{
*Object = (PVOID)(PPOWERNOTIFY)this;
}
else
{
// nothing found, must be an unknown interface.
*Object = NULL;
return STATUS_INVALID_PARAMETER;
}
//
// We reference the interface for the caller.
//
((PUNKNOWN)(*Object))->AddRef();
return STATUS_SUCCESS;
}
/*****************************************************************************
* CMiniportWaveICH::~CMiniportWaveICH
*****************************************************************************
* Destructor.
*/
CMiniportWaveICH::~CMiniportWaveICH ()
{
PAGED_CODE ();
DOUT (DBG_PRINT, ("[CMiniportWaveICH::~CMiniportWaveICH]"));
//
// Release the DMA channel.
//
if (DmaChannel)
{
DmaChannel->Release ();
DmaChannel = NULL;
}
//
// Release the interrupt sync.
//
if (InterruptSync)
{
InterruptSync->Release ();
InterruptSync = NULL;
}
//
// Release adapter common object.
//
if (AdapterCommon)
{
AdapterCommon->Release ();
AdapterCommon = NULL;
}
//
// Release the port.
//
if (Port)
{
Port->Release ();
Port = NULL;
}
}
/*****************************************************************************
* CMiniportWaveICH::Init
*****************************************************************************
* Initializes the miniport.
* Initializes variables and modifies the wave topology if needed.
*/
STDMETHODIMP_(NTSTATUS) CMiniportWaveICH::Init
(
IN PUNKNOWN UnknownAdapter,
IN PRESOURCELIST ResourceList,
IN PPORTWAVEPCI Port_,
OUT PSERVICEGROUP *ServiceGroup_
)
{
PAGED_CODE ();
ASSERT (UnknownAdapter);
ASSERT (ResourceList);
ASSERT (Port_);
DOUT (DBG_PRINT, ("[CMiniportWaveICH::Init]"));
//
// AddRef() is required because we are keeping this pointer.
//
Port = Port_;
Port->AddRef ();
//
// No miniport service group
//
*ServiceGroup_ = NULL;
//
// Set initial device power state
//
m_PowerState = PowerDeviceD0;
NTSTATUS ntStatus = UnknownAdapter->
QueryInterface (IID_IAdapterCommon, (PVOID *)&AdapterCommon);
if (NT_SUCCESS (ntStatus))
{
//
// Alter the topology for the wave miniport.
//
if (!(AdapterCommon->GetPinConfig (PINC_MICIN_PRESENT) &&
AdapterCommon->GetPinConfig (PINC_MIC_PRESENT)))
{
//
// Remove the pins, nodes and connections for the MICIN.
//
MiniportFilterDescriptor.PinCount = SIZEOF_ARRAY(MiniportPins) - 2;
MiniportFilterDescriptor.NodeCount = SIZEOF_ARRAY(MiniportNodes) - 1;
MiniportFilterDescriptor.ConnectionCount = SIZEOF_ARRAY(MiniportConnections) - 2;
}
//
// Process the resources.
//
ntStatus = ProcessResources (ResourceList);
//
// Get the default channel config
//
AdapterCommon->ReadChannelConfigDefault (&m_dwChannelMask, &m_wChannels);
//
// If we came till that point, check the CoDec for supported standard
// sample rates. This function will then fill the data range information
//
if (NT_SUCCESS (ntStatus))
ntStatus = BuildDataRangeInformation ();
}
//
// If we fail we get destroyed anyway (that's where we clean up).
//
return ntStatus;
}
/*****************************************************************************
* CMiniportWaveICH::ProcessResources
*****************************************************************************
* Processes the resource list, setting up helper objects accordingly.
* Sets up the Interrupt + Service routine and DMA.
*/
NTSTATUS CMiniportWaveICH::ProcessResources
(
IN PRESOURCELIST ResourceList
)
{
PAGED_CODE ();
ASSERT (ResourceList);
DOUT (DBG_PRINT, ("[CMiniportWaveICH::ProcessResources]"));
ULONG countIRQ = ResourceList->NumberOfInterrupts ();
if (countIRQ < 1)
{
DOUT (DBG_ERROR, ("Unknown configuration for wave miniport!"));
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
//
// Create an interrupt sync object
//
NTSTATUS ntStatus = STATUS_SUCCESS;
ntStatus = PcNewInterruptSync (&InterruptSync,
NULL,
ResourceList,
0,
InterruptSyncModeNormal);
if (!NT_SUCCESS (ntStatus) || !InterruptSync)
{
DOUT (DBG_ERROR, ("Failed to create an interrupt sync!"));
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Register our ISR.
//
ntStatus = InterruptSync->RegisterServiceRoutine (InterruptServiceRoutine,
(PVOID)this, FALSE);
if (!NT_SUCCESS (ntStatus))
{
DOUT (DBG_ERROR, ("Failed to register ISR!"));
return ntStatus;
}
//
// Connect the interrupt.
//
ntStatus = InterruptSync->Connect ();
if (!NT_SUCCESS (ntStatus))
{
DOUT (DBG_ERROR, ("Failed to connect the ISR with InterruptSync!"));
return ntStatus;
}
//
// Create the DMA Channel object.
//
ntStatus = Port->NewMasterDmaChannel (&DmaChannel, // OutDmaChannel
NULL, // OuterUnknown (opt)
NonPagedPool, // Pool Type
NULL, // ResourceList (opt)
TRUE, // ScatterGather
TRUE, // Dma32BitAddresses
FALSE, // Dma64BitAddresses
FALSE, // IgnoreCount
Width32Bits, // DmaWidth
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?