📄 mintopo.cpp
字号:
/*****************************************************************************
* mintopo.cpp - SB16 topology miniport implementation
*****************************************************************************
* Copyright (c) 1997-2000 Microsoft Corporation. All Rights Reserved.
*/
#include "limits.h"
#include "mintopo.h"
#define STR_MODULENAME "sb16topo: "
#define CHAN_LEFT 0
#define CHAN_RIGHT 1
#define CHAN_MASTER (-1)
#pragma code_seg("PAGE")
/*****************************************************************************
* CreateMiniportTopologySB16()
*****************************************************************************
* Creates a topology miniport object for the SB16 adapter. This uses a
* macro from STDUNK.H to do all the work.
*/
NTSTATUS
CreateMiniportTopologySB16
(
OUT PUNKNOWN * Unknown,
IN REFCLSID,
IN PUNKNOWN UnknownOuter OPTIONAL,
IN POOL_TYPE PoolType
)
{
PAGED_CODE();
ASSERT(Unknown);
STD_CREATE_BODY_(CMiniportTopologySB16,Unknown,UnknownOuter,PoolType,PMINIPORTTOPOLOGY);
}
/*****************************************************************************
* CMiniportTopologySB16::NonDelegatingQueryInterface()
*****************************************************************************
* Obtains an interface. This function works just like a COM QueryInterface
* call and is used if the object is not being aggregated.
*/
STDMETHODIMP
CMiniportTopologySB16::
NonDelegatingQueryInterface
(
IN REFIID Interface,
OUT PVOID * Object
)
{
PAGED_CODE();
ASSERT(Object);
_DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportTopologySB16::NonDelegatingQueryInterface]"));
if (IsEqualGUIDAligned(Interface,IID_IUnknown))
{
*Object = PVOID(PUNKNOWN(PMINIPORTTOPOLOGY(this)));
}
else
if (IsEqualGUIDAligned(Interface,IID_IMiniport))
{
*Object = PVOID(PMINIPORT(this));
}
else
if (IsEqualGUIDAligned(Interface,IID_IMiniportTopology))
{
*Object = PVOID(PMINIPORTTOPOLOGY(this));
}
else
{
*Object = NULL;
}
if (*Object)
{
//
// We reference the interface for the caller.
//
PUNKNOWN(*Object)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}
/*****************************************************************************
* CMiniportTopologySB16::~CMiniportTopologySB16()
*****************************************************************************
* Destructor.
*/
CMiniportTopologySB16::
~CMiniportTopologySB16
( void
)
{
PAGED_CODE();
_DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportTopologySB16::~CMiniportTopologySB16]"));
if (AdapterCommon)
{
#ifdef EVENT_SUPPORT
AdapterCommon->SetTopologyMiniport (NULL);
#endif
AdapterCommon->SaveMixerSettingsToRegistry();
AdapterCommon->Release();
}
#ifdef EVENT_SUPPORT
if (PortEvents)
{
PortEvents->Release ();
PortEvents = NULL;
}
#endif
}
/*****************************************************************************
* CMiniportTopologySB16::Init()
*****************************************************************************
* Initializes a the miniport.
*/
STDMETHODIMP
CMiniportTopologySB16::
Init
(
IN PUNKNOWN UnknownAdapter,
IN PRESOURCELIST ResourceList,
IN PPORTTOPOLOGY Port
)
{
PAGED_CODE();
ASSERT(UnknownAdapter);
ASSERT(Port);
_DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportTopologySB16::Init]"));
NTSTATUS ntStatus =
UnknownAdapter->QueryInterface
(
IID_IAdapterCommon,
(PVOID *) &AdapterCommon
);
if (NT_SUCCESS(ntStatus))
{
#ifdef EVENT_SUPPORT
//
// Get the port event interface.
//
NTSTATUS ntStatus2 = Port->QueryInterface (IID_IPortEvents, (PVOID *)&PortEvents);
if (NT_SUCCESS(ntStatus2))
{
//
// We need to notify AdapterCommon of the miniport interface.
// AdapterCommon needs this in his ISR to fire the event.
//
AdapterCommon->SetTopologyMiniport ((PTOPOMINIPORTSB16)this);
//
// Enable external volume control interrupt.
//
BYTE bIntrMask = AdapterCommon->MixerRegRead (0x83);
bIntrMask |= 0x10;
AdapterCommon->MixerRegWrite (0x83, bIntrMask);
}
#endif
AdapterCommon->MixerReset();
}
return ntStatus;
}
/*****************************************************************************
* CMiniportTopologySB16::GetDescription()
*****************************************************************************
* Gets the topology.
*/
STDMETHODIMP
CMiniportTopologySB16::
GetDescription
(
OUT PPCFILTER_DESCRIPTOR * OutFilterDescriptor
)
{
PAGED_CODE();
ASSERT(OutFilterDescriptor);
_DbgPrintF(DEBUGLVL_VERBOSE,("[CMiniportTopologySB16::GetDescription]"));
*OutFilterDescriptor = &MiniportFilterDescriptor;
return STATUS_SUCCESS;
}
/*****************************************************************************
* PropertyHandler_OnOff()
*****************************************************************************
* Accesses a KSAUDIO_ONOFF value property.
*/
static
NTSTATUS
PropertyHandler_OnOff
(
IN PPCPROPERTY_REQUEST PropertyRequest
)
{
PAGED_CODE();
ASSERT(PropertyRequest);
_DbgPrintF(DEBUGLVL_VERBOSE,("[PropertyHandler_OnOff]"));
CMiniportTopologySB16 *that =
(CMiniportTopologySB16 *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget);
NTSTATUS ntStatus = STATUS_INVALID_PARAMETER;
BYTE data;
LONG channel;
// validate node
if (PropertyRequest->Node != ULONG(-1))
{
if(PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
// get the instance channel parameter
if(PropertyRequest->InstanceSize >= sizeof(LONG))
{
channel = *(PLONG(PropertyRequest->Instance));
// validate and get the output parameter
if (PropertyRequest->ValueSize >= sizeof(BOOL))
{
PBOOL OnOff = PBOOL(PropertyRequest->Value);
// switch on node id
switch(PropertyRequest->Node)
{
case MIC_AGC: // Microphone AGC Control (mono)
// check if AGC property request on mono/left channel
if( ( PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_AGC ) &&
( channel == CHAN_LEFT ) )
{
data = that->ReadBitsFromMixer( DSP_MIX_AGCIDX,
1,
MIXBIT_MIC_AGC );
*OnOff = data ? FALSE : TRUE;
PropertyRequest->ValueSize = sizeof(BOOL);
ntStatus = STATUS_SUCCESS;
}
break;
case MIC_LINEOUT_MUTE: // Microphone Lineout Mute Control (mono)
// check if MUTE property request on mono/left channel
if( ( PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MUTE ) &&
( channel == CHAN_LEFT ) )
{
data = that->ReadBitsFromMixer( DSP_MIX_OUTMIXIDX,
1,
MIXBIT_MIC_LINEOUT );
*OnOff = data ? FALSE : TRUE;
PropertyRequest->ValueSize = sizeof(BOOL);
ntStatus = STATUS_SUCCESS;
}
break;
}
}
}
} else if(PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
{
// get the instance channel parameter
if(PropertyRequest->InstanceSize >= sizeof(LONG))
{
channel = *(PLONG(PropertyRequest->Instance));
// validate and get the input parameter
if (PropertyRequest->ValueSize == sizeof(BOOL))
{
BYTE value = *(PBOOL(PropertyRequest->Value)) ? 0 : 1;
// switch on the node id
switch(PropertyRequest->Node)
{
case MIC_AGC: // Microphone AGC Control (mono)
// check if AGC property request on mono/left channel
if( ( PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_AGC ) &&
( channel == CHAN_LEFT ) )
{
that->WriteBitsToMixer( DSP_MIX_AGCIDX,
1,
MIXBIT_MIC_AGC,
value );
ntStatus = STATUS_SUCCESS;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -