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

📄 miniport.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Gets the topology.
// Pass back appropriate descriptor, depending on whether volume node is needed.
// ==============================================================================
STDMETHODIMP_(NTSTATUS)
CMiniportMidiFM::
GetDescription
(
    OUT     PPCFILTER_DESCRIPTOR *  OutFilterDescriptor
)
{
    PAGED_CODE();

    ASSERT(OutFilterDescriptor);

    _DbgPrintF(DEBUGLVL_VERBOSE,("CMiniportMidiFM::GetDescription"));

    if (m_volNodeNeeded)
    {
        *OutFilterDescriptor = &MiniportFilterWithVolDescriptor;
        _DbgPrintF(DEBUGLVL_VERBOSE, ("Getting descriptor of new FM miniport with volume node"));
    }
    else
    {
        *OutFilterDescriptor = &MiniportFilterDescriptor;
    }

    return STATUS_SUCCESS;
}

#pragma code_seg("PAGE")
// ==============================================================================
// CMiniportMidiStreamFM::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) CMiniportMidiStreamFM::NonDelegatingQueryInterface
(
REFIID  Interface,
PVOID * Object
)
{
    PAGED_CODE();

    ASSERT(Object);

    _DbgPrintF(DEBUGLVL_VERBOSE,("CMiniportMidiStreamFM::NonDelegatingQueryInterface"));

    if (IsEqualGUIDAligned(Interface,IID_IUnknown))
    {
        *Object = PVOID(PUNKNOWN(PMINIPORT(this)));
    }
    else
    if (IsEqualGUIDAligned(Interface,IID_IMiniportMidiStream))
    {
        *Object = PVOID(PMINIPORTMIDISTREAM(this));
    }
    else
    {
        *Object = NULL;
    }

    if (*Object)
    {
        //
        // We reference the interface for the caller.
        //
        PUNKNOWN(PMINIPORT(*Object))->AddRef();
        return STATUS_SUCCESS;
    }

    return STATUS_INVALID_PARAMETER;
}

#pragma code_seg("PAGE")
// ==============================================================================
// CMiniportMidiStreamFM::~CMiniportMidiStreamFM()
// Destructor.
// ==============================================================================
CMiniportMidiStreamFM::~CMiniportMidiStreamFM
(
void
)
{
    PAGED_CODE();

    _DbgPrintF(DEBUGLVL_VERBOSE,("CMiniportMidiStreamFM::~CMiniportMidiStreamFM"));

    Opl3_AllNotesOff();

    if (m_Miniport)
    {
        m_Miniport->m_fStreamExists = FALSE;
        m_Miniport->Release();
    }
}

#pragma code_seg("PAGE")
// ==============================================================================
// CMiniportMidiStreamFM::Init()
// Initializes a the miniport.
// ==============================================================================
NTSTATUS
CMiniportMidiStreamFM::
Init
(
    IN      CMiniportMidiFM *   Miniport,
    IN      PUCHAR              PortBase
)
{
    PAGED_CODE();

    ASSERT(Miniport);
    ASSERT(PortBase);

    int i;

    _DbgPrintF(DEBUGLVL_VERBOSE,("CMiniportMidiStreamFM::Init"));

    //
    // AddRef() is required because we are keeping this pointer.
    //
    m_Miniport = Miniport;
    m_Miniport->AddRef();

    m_PortBase = PortBase;

    // init some members
    m_dwCurTime = 1;    /* for note on/off */
    /* volume */
    m_wSynthAttenL = 0;        /* in 1.5dB steps */
    m_wSynthAttenR = 0;        /* in 1.5dB steps */

    m_MinVolValue  = 0xFFD0C000;    //  minimum -47.25(dB) * 0x10000
    m_MaxVolValue  = 0x00000000;    //  maximum  0    (dB) * 0x10000
    m_VolStepDelta = 0x0000C000;    //  steps of 0.75 (dB) * 0x10000
    m_SavedVolValue[CHAN_LEFT] = m_SavedVolValue[CHAN_RIGHT] = 0;

    /* start attenuations at -3 dB, which is 90 MIDI level */
    for (i = 0; i < NUMCHANNELS; i++) 
    {
        m_bChanAtten[i] = 4;
        m_bStereoMask[i] = 0xff;
    };

    return STATUS_SUCCESS;
}

#pragma code_seg("PAGE")
// ==============================================================================
// CMiniportMidiStreamFM::SetState()
// Sets the transport state.
// ==============================================================================
STDMETHODIMP_(NTSTATUS)
CMiniportMidiStreamFM::
SetState
(
    IN      KSSTATE     NewState
)
{
    PAGED_CODE();

    _DbgPrintF(DEBUGLVL_VERBOSE,("CMiniportMidiStreamFM::SetState"));

    NTSTATUS ntStatus = STATUS_SUCCESS;

    switch (NewState)
    {
    case KSSTATE_STOP:
    case KSSTATE_ACQUIRE:
    case KSSTATE_PAUSE:
        Opl3_AllNotesOff();
        break;

    case KSSTATE_RUN:
        break;
    }

    return ntStatus;
}

#pragma code_seg("PAGE")
// ==============================================================================
// CMiniportMidiStreamFM::SetFormat()
// Sets the format.
// ==============================================================================
STDMETHODIMP_(NTSTATUS)
CMiniportMidiStreamFM::
SetFormat
(
    IN      PKSDATAFORMAT   Format
)
{
    PAGED_CODE();

    ASSERT(Format);

    _DbgPrintF(DEBUGLVL_VERBOSE,("CMiniportMidiStreamFM::SetFormat"));

    return STATUS_SUCCESS;
}

#pragma code_seg("PAGE")
/*****************************************************************************
 * BasicSupportHandler()
 *****************************************************************************
 * Assists in BASICSUPPORT accesses on level properties - 
 * this is declared as a friend method in the header file.
 */
static
NTSTATUS BasicSupportHandler
(
    IN  PPCPROPERTY_REQUEST PropertyRequest
)
{
    PAGED_CODE();
    ASSERT(PropertyRequest);

    _DbgPrintF(DEBUGLVL_VERBOSE, ("BasicSupportHandler"));

    NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;

    if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION)))
    {
        // if return buffer can hold a KSPROPERTY_DESCRIPTION, return it
        PKSPROPERTY_DESCRIPTION PropDesc = PKSPROPERTY_DESCRIPTION(PropertyRequest->Value);

        PropDesc->AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT |
                                KSPROPERTY_TYPE_GET |
                                KSPROPERTY_TYPE_SET;
        PropDesc->DescriptionSize   = sizeof(KSPROPERTY_DESCRIPTION) +
                                      sizeof(KSPROPERTY_MEMBERSHEADER) +
                                      sizeof(KSPROPERTY_STEPPING_LONG);
        PropDesc->PropTypeSet.Set   = KSPROPTYPESETID_General;
        PropDesc->PropTypeSet.Id    = VT_I4;
        PropDesc->PropTypeSet.Flags = 0;
        PropDesc->MembersListCount  = 1;
        PropDesc->Reserved          = 0;

        // if return buffer can also hold a range description, return it too
        if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION) +
                                           sizeof(KSPROPERTY_MEMBERSHEADER) +
                                           sizeof(KSPROPERTY_STEPPING_LONG)))
        {
            // fill in the members header
            PKSPROPERTY_MEMBERSHEADER Members = PKSPROPERTY_MEMBERSHEADER(PropDesc + 1);

            Members->MembersFlags   = KSPROPERTY_MEMBER_STEPPEDRANGES;
            Members->MembersSize    = sizeof(KSPROPERTY_STEPPING_LONG);
            Members->MembersCount   = 1;
            Members->Flags          = 0;

            // fill in the stepped range
            PKSPROPERTY_STEPPING_LONG Range = PKSPROPERTY_STEPPING_LONG(Members + 1);

            switch (PropertyRequest->Node)
            {
                case eFMVolumeNode:
                    CMiniportMidiStreamFM *that = (CMiniportMidiStreamFM *)PropertyRequest->MinorTarget;

                    if (that)
                    {
                        Range->Bounds.SignedMinimum = that->m_MinVolValue;
                        Range->Bounds.SignedMaximum = that->m_MaxVolValue;
                        Range->SteppingDelta        = that->m_VolStepDelta;
                        break;
                    }
                    else
                    {
                        return STATUS_INVALID_PARAMETER;
                    }
            }

            Range->Reserved = 0;

            _DbgPrintF(DEBUGLVL_VERBOSE, ("---Node: %d  Max: 0x%X  Min: 0x%X  Step: 0x%X",PropertyRequest->Node,
                                       Range->Bounds.SignedMaximum,
                                       Range->Bounds.SignedMinimum,
                                       Range->SteppingDelta));

            // set the return value size
            PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
                                         sizeof(KSPROPERTY_MEMBERSHEADER) +
                                         sizeof(KSPROPERTY_STEPPING_LONG);
        }
        else
        {
            // set the return value size
            PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
        }
        ntStatus = STATUS_SUCCESS;

    }
    else if (PropertyRequest->ValueSize >= sizeof(ULONG))
    {
        // if return buffer can hold a ULONG, return the access flags
        PULONG AccessFlags = PULONG(PropertyRequest->Value);

        *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT |
                       KSPROPERTY_TYPE_GET |
                       KSPROPERTY_TYPE_SET;

        // set the return value size
        PropertyRequest->ValueSize = sizeof(ULONG);
        ntStatus = STATUS_SUCCESS;

    }
    return ntStatus;
}

#pragma code_seg("PAGE")
/*****************************************************************************
 * PropertyHandler_Level()
 *****************************************************************************
 * Accesses a KSAUDIO_LEVEL property.
 */
static
NTSTATUS PropertyHandler_Level
(
    IN  PPCPROPERTY_REQUEST PropertyRequest
)
{
    PAGED_CODE();

    ASSERT(PropertyRequest);

    _DbgPrintF(DEBUGLVL_VERBOSE,("PropertyHandler_Level"));


    NTSTATUS        ntStatus = STATUS_INVALID_PARAMETER;
    LONG            channel;

    // validate node
    if (PropertyRequest->Node == eFMVolumeNode)
    {
        if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
        {
            // get the instance channel parameter
            if (PropertyRequest->InstanceSize >= sizeof(LONG))
            {
                channel = *(PLONG(PropertyRequest->Instance));

                // only support get requests on either mono/left(0) or right(1) channels
                if ((channel == CHAN_LEFT) || (channel == CHAN_RIGHT))
                {
                    // validate and get the output parameter
                    if (PropertyRequest->ValueSize >= sizeof(LONG))
                    {
                        PLONG Level = (PLONG)PropertyRequest->Value;

                        // check if volume property request
                        if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_VOLUMELEVEL)
                        {
                            CMiniportMidiStreamFM *that = (CMiniportMidiStreamFM *)PropertyRequest->MinorTarget;
                            if (that)
                            {
                                *Level = that->GetFMAtten(channel);
                                PropertyRequest->ValueSize = sizeof(LONG);
                                ntStatus = STATUS_SUCCESS;
                            }
                            //  if (!that) return STATUS_INVALID_PARAMETER

                        }   // (PropertyItem->Id == KSPROPERTY_AUDIO_VOLUMELEVEL)
                    }     // (ValueSize >= sizeof(LONG))
                }       // ((channel == CHAN_LEFT) || (channel == CHAN_RIGHT))
            }         // (InstanceSize >= sizeof(LONG))
        }           // (Verb & KSPROPERTY_TYPE_GET)

        else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
        {
            // get the instance channel parameter
            if (PropertyRequest->InstanceSize >= sizeof(LONG))
            {
                channel = *(PLONG(PropertyRequest->Instance));

                // only support get requests on either mono/left (0), right (1), or master (-1) channels
                if ((channel == CHAN_LEFT) || (channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
                {
                    // validate and get the input parameter
                    if (PropertyRequest->ValueSize == sizeof(LONG))
                    {
                        PLONG level = (PLONG)PropertyRequest->Value;

                        if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_VOLUMELEVEL)
                        {
                            CMiniportMidiStreamFM *that = (CMiniportMidiStreamFM *)PropertyRequest->MinorTarget;
                            if (that)
                            {
                                that->SetFMAtten(channel,*level);
                                ntStatus = STATUS_SUCCESS;
                            }
                            //  if (!that) return STATUS_INVALID_PARAMETER

                        }   // (PropertyItem->Id == KSPROPERTY_AUDIO_VOLUMELEVEL)
                    }     // (ValueSize == sizeof(LONG))
                }       // ((channel == CHAN_LEFT) || (channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
            }         // (InstanceSize >= sizeof(LONG))
        }           // (Verb & KSPROPERTY_TYPE_SET)

        else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -