⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mintopo.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
 * 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 + -