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

📄 adapter.cpp

📁 微软提供的实现mpu-401音频设备的标准功能的wdm驱动例程。
💻 CPP
字号:
/*****************************************************************************
 * adapter.cpp - MPU401 adapter driver implementation.
 *****************************************************************************
 * Copyright (c) 1997-1999 Microsoft Corporation.  All rights reserved.
 *
 * Created 6/19/97, a-seemap
 *
 */

//
// All the GUIDS for all the miniports end up in this object.
//
#define PUT_GUIDS_HERE

#define STR_MODULENAME "MPU401Adapter: "
#define PC_NEW_NAMES 1

#define kUseDMusicMiniport 1

#include "portcls.h"
#include "ksdebug.h"

#if (kUseDMusicMiniport)
#include "dmusicks.h"
#endif  //  kUseDMusicMiniport

/*****************************************************************************
 * Defines
 */

#define MAX_MINIPORTS 1

#if (DBG)
#define SUCCEEDS(s) ASSERT(NT_SUCCESS(s))
#else
#define SUCCEEDS(s) (s)
#endif

/*****************************************************************************
 * Referenced forward
 */
extern "C"
NTSTATUS
AddDevice
(
        IN PVOID        Context1,
        IN PVOID        Context2
);

NTSTATUS
StartDevice
(
    IN      PDEVICE_OBJECT  pDeviceObject,  // Context for the class driver.
    IN      PIRP            pIrp,           // Context for the class driver.
    IN      PRESOURCELIST   ResourceList    // List of hardware resources.
);


#pragma code_seg("INIT")
/*****************************************************************************
 * DriverEntry()
 *****************************************************************************
 * This function is called by the operating system when the driver is loaded.
 * All adapter drivers can use this code without change.
 */
extern "C"
NTSTATUS
DriverEntry
(
    IN      PVOID   Context1,   // Context for the class driver.
    IN      PVOID   Context2    // Context for the class driver.
)
{
    PAGED_CODE();
    _DbgPrintF(DEBUGLVL_VERBOSE, ("DriverEntry"));
//    _DbgPrintF(DEBUGLVL_ERROR, ("Starting breakpoint for debugging"));

    //
    // Tell the class driver to initialize the driver.
    //
    return PcInitializeAdapterDriver((PDRIVER_OBJECT)Context1,
                                     (PUNICODE_STRING)Context2,
                                     (PDRIVER_ADD_DEVICE)AddDevice);
}

#pragma code_seg("PAGE")
/*****************************************************************************
 * AddDevice()
 *****************************************************************************
 * This function is called by the operating system when the device is added.
 * All adapter drivers can use this code without change.
 */
NTSTATUS
AddDevice
(
    IN      PVOID   Context1,   // Context for the class driver.
    IN      PVOID   Context2    // Context for the class driver.
)
{
    PAGED_CODE();
    _DbgPrintF(DEBUGLVL_VERBOSE, ("AddDevice"));

    //
    // Tell the class driver to add the device.
    //
    return PcAddAdapterDevice((PDRIVER_OBJECT)Context1,(PDEVICE_OBJECT)Context2,StartDevice,MAX_MINIPORTS,0);
}

#pragma code_seg("PAGE")
/*****************************************************************************
 * InstallSubdevice()
 *****************************************************************************
 * This function creates and registers a subdevice consisting of a port
 * driver, a minport driver and a set of resources bound together.  It will
 * also optionally place a pointer to an interface on the port driver in a
 * specified location before initializing the port driver.  This is done so
 * that a common ISR can have access to the port driver during initialization,
 * when the ISR might fire.
 */
NTSTATUS
InstallSubdevice
(
    IN      PVOID               Context1,
    IN      PVOID               Context2,
    IN      PWCHAR              Name,
    IN      REFGUID             PortClassId,
    IN      REFGUID             MiniportClassId,
    IN      PUNKNOWN            UnknownAdapter      OPTIONAL,   //not used - null
    IN      PRESOURCELIST       ResourceList,                   //not optional, but can be EMPTY!
    IN      REFGUID             PortInterfaceId,
    OUT     PUNKNOWN *          OutPortInterface,   OPTIONAL    //not used - null
    OUT     PUNKNOWN *          OutPortUnknown      OPTIONAL    //not used - null
)
{
    PAGED_CODE();
    _DbgPrintF(DEBUGLVL_VERBOSE, ("InstallSubdevice"));

    ASSERT(Context1);
    ASSERT(Context2);
    ASSERT(Name);
    ASSERT(ResourceList);

    //
    // Create the port driver object
    //
    PPORT       port;
    NTSTATUS    ntStatus = PcNewPort(&port,PortClassId);

    if (NT_SUCCESS(ntStatus))
    {
        //
        // Deposit the port somewhere if it's needed.
        //
        if (OutPortInterface)
        {
            //
            //  Failure here doesn't cause the entire routine to fail.
            //
            (void) port->QueryInterface
            (
                PortInterfaceId,
                (PVOID *) OutPortInterface
            );
        }

        PMINIPORT miniport;
        //
        // Create the miniport object
        //
        ntStatus = PcNewMiniport(&miniport,MiniportClassId);

        if (NT_SUCCESS(ntStatus))
        {
            //
            // Init the port driver and miniport in one go.
            //
            ntStatus = port->Init( (PDEVICE_OBJECT)Context1,
                                   (PIRP)Context2,
                                   miniport,
                                   NULL,   // interruptsync created in miniport.
                                   ResourceList);

            if (NT_SUCCESS(ntStatus))
            {
                //
                // Register the subdevice (port/miniport combination).
                //
                ntStatus = PcRegisterSubdevice( (PDEVICE_OBJECT)Context1,
                                                Name,
                                                port    );
#if DBG
                if (!(NT_SUCCESS(ntStatus)))
                {
                    _DbgPrintF(DEBUGLVL_TERSE, ("StartDevice: PcRegisterSubdevice failed"));
                }
#endif
            }
            else
            {
                _DbgPrintF(DEBUGLVL_TERSE, ("InstallSubdevice: port->Init failed"));
            }

            //
            // We don't need the miniport any more.  Either the port has it,
            // or we've failed, and it should be deleted.
            //
            miniport->Release();
        }
        else
        {
            _DbgPrintF(DEBUGLVL_TERSE, ("InstallSubdevice: PcNewMiniport failed"));
        }

        if (NT_SUCCESS(ntStatus))
        {
            //
            // Deposit the port as an unknown if it's needed.
            //
            if (OutPortUnknown)
            {
                //
                //  Failure here doesn't cause the entire routine to fail.
                //
                (void) port->QueryInterface
                (
                    IID_IUnknown,
                    (PVOID *) OutPortUnknown
                );
            }
        }
        else
        {
            //
            // Retract previously delivered port interface.
            //
            if (OutPortInterface && (*OutPortInterface))
            {
                (*OutPortInterface)->Release();
                *OutPortInterface = NULL;
            }
        }

        //
        // Release the reference which existed when PcNewPort() gave us the
        // pointer in the first place.  This is the right thing to do
        // regardless of the outcome.
        //
        port->Release();
    }
    else
    {
        _DbgPrintF(DEBUGLVL_TERSE, ("InstallSubdevice: PcNewPort failed"));
    }

    return ntStatus;
}

#pragma code_seg("PAGE")
/*****************************************************************************
 * StartDevice()
 *****************************************************************************
 * This function is called by the operating system when the device is started.
 * It is responsible for starting the miniport. 
 * 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  pDeviceObject,  // Context for the class driver.
    IN      PIRP            pIrp,           // Context for the class driver.
    IN      PRESOURCELIST   ResourceList    // List of hardware resources.
)
{
    PAGED_CODE();

    ASSERT(pDeviceObject);
    ASSERT(pIrp);
    ASSERT(ResourceList);
    if (!ResourceList)
    {
        _DbgPrintF(DEBUGLVL_TERSE, ("StartDevice: NULL resource list"));
        return STATUS_INVALID_PARAMETER;
    }

    NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    
    if (ResourceList->NumberOfEntries())
    {
#if (kUseDMusicMiniport)
        //
        // Start the UART miniport.
        //
        ntStatus = InstallSubdevice(
                                    pDeviceObject,
                                    pIrp,
                                    L"Uart",
                                    CLSID_PortDMus,
                                    CLSID_MiniportDriverDMusUART,
                                    NULL,
                                    ResourceList,
                                    IID_IPortDMus,
                                    NULL,
                                    NULL    // Not physically connected to anything.
                                    );
#else   //  (kUseDMusicMiniport)
        //
        // Start the UART miniport.
        //
        ntStatus = InstallSubdevice(
                                    pDeviceObject,
                                    pIrp,
                                    L"Uart",
                                    CLSID_PortMidi,
                                    CLSID_MiniportDriverUart,
                                    NULL,
                                    ResourceList,
                                    IID_IPortMidi,
                                    NULL,
                                    NULL    // Not physically connected to anything.
                                    );
#endif  //  (kUseDMusicMiniport)
    }
    else
    {
        _DbgPrintF(DEBUGLVL_TERSE, ("StartDevice: no entries in resource list"));
    }
    return ntStatus;
}

⌨️ 快捷键说明

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