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

📄 pdopnp.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "pch.h"

NTSTATUS PptPdoStartDevice( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoQueryRemove( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoRemoveDevice( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoCancelRemove( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoStopDevice( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoQueryStop( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoCancelStop( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoQueryDeviceRelations( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoQueryCapabilities( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoQueryDeviceText( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoQueryId( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoQueryPnpDeviceState( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoQueryBusInformation( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoSurpriseRemoval( PDEVICE_OBJECT DevObj, PIRP Irp );
NTSTATUS PptPdoDefaultPnpHandler( PDEVICE_OBJECT DevObj, PIRP Irp );

PDRIVER_DISPATCH 
PptPdoPnpDispatchTable[] =
{ 
    PptPdoStartDevice,          // IRP_MN_START_DEVICE                 0x00
    PptPdoQueryRemove,          // IRP_MN_QUERY_REMOVE_DEVICE          0x01
    PptPdoRemoveDevice,         // IRP_MN_REMOVE_DEVICE                0x02
    PptPdoCancelRemove,         // IRP_MN_CANCEL_REMOVE_DEVICE         0x03
    PptPdoStopDevice,           // IRP_MN_STOP_DEVICE                  0x04
    PptPdoQueryStop,            // IRP_MN_QUERY_STOP_DEVICE            0x05
    PptPdoCancelStop,           // IRP_MN_CANCEL_STOP_DEVICE           0x06
    PptPdoQueryDeviceRelations, // IRP_MN_QUERY_DEVICE_RELATIONS       0x07
    PptPdoDefaultPnpHandler,    // IRP_MN_QUERY_INTERFACE              0x08
    PptPdoQueryCapabilities,    // IRP_MN_QUERY_CAPABILITIES           0x09
    PptPdoDefaultPnpHandler,    // IRP_MN_QUERY_RESOURCES              0x0A
    PptPdoDefaultPnpHandler,    // IRP_MN_QUERY_RESOURCE_REQUIREMENTS  0x0B
    PptPdoQueryDeviceText,      // IRP_MN_QUERY_DEVICE_TEXT            0x0C
    PptPdoDefaultPnpHandler,    // IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
    PptPdoDefaultPnpHandler,    // no such PnP request                 0x0E
    PptPdoDefaultPnpHandler,    // IRP_MN_READ_CONFIG                  0x0F
    PptPdoDefaultPnpHandler,    // IRP_MN_WRITE_CONFIG                 0x10
    PptPdoDefaultPnpHandler,    // IRP_MN_EJECT                        0x11
    PptPdoDefaultPnpHandler,    // IRP_MN_SET_LOCK                     0x12
    PptPdoQueryId,              // IRP_MN_QUERY_ID                     0x13
    PptPdoQueryPnpDeviceState,  // IRP_MN_QUERY_PNP_DEVICE_STATE       0x14
    PptPdoQueryBusInformation,  // IRP_MN_QUERY_BUS_INFORMATION        0x15
    PptPdoDefaultPnpHandler,    // IRP_MN_DEVICE_USAGE_NOTIFICATION    0x16
    PptPdoSurpriseRemoval,      // IRP_MN_SURPRISE_REMOVAL             0x17
    PptPdoDefaultPnpHandler     // IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
};


NTSTATUS
PptPdoStartDevice(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    ) 
{
    PPDO_EXTENSION  pdx = Pdo->DeviceExtension;

    pdx->DeviceStateFlags = PPT_DEVICE_STARTED;
    KeSetEvent(&pdx->PauseEvent, 0, FALSE); // unpause any worker thread

    PptRegGetDeviceParameterDword( Pdo, L"Event22Delay", &pdx->Event22Delay );

    //
    // Register device interface for Legacy LPTx interface PDOs and set the interface active
    //  - succeed start even if the device interface code fails
    //
    if( PdoTypeRawPort == pdx->PdoType ) {

        // This is a legacy interface "raw port" PDO, don't set interface for other types of PDOs 

        NTSTATUS  status;
        BOOLEAN   setActive = FALSE;

        if( NULL == pdx->DeviceInterface.Buffer ) {
            // Register device interface
            status = IoRegisterDeviceInterface( Pdo, &GUID_PARCLASS_DEVICE, NULL, &pdx->DeviceInterface );
            if( STATUS_SUCCESS == status ) {
                setActive = TRUE;
            }
        }

        if( (TRUE == setActive) && (FALSE == pdx->DeviceInterfaceState) ) {
            // set interface active
            status = IoSetDeviceInterfaceState( &pdx->DeviceInterface, TRUE );
            if( STATUS_SUCCESS == status ) {
                pdx->DeviceInterfaceState = TRUE;
            }
        }
    }

    return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
}


NTSTATUS
PptPdoQueryRemove(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION  pdx = Pdo->DeviceExtension;

    // DDpnp2( ("PptPdoQueryRemove\n") );

    // PnP won't remove us if there are open handles to us - so WE don't need to check for open handles

    pdx->DeviceStateFlags |= (PPT_DEVICE_REMOVE_PENDING | PAR_DEVICE_PAUSED);
    KeClearEvent(&pdx->PauseEvent); // pause any worker thread

    return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
}


NTSTATUS
PptPdoRemoveDevice(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION  pdx     = Pdo->DeviceExtension;
    NTSTATUS        status;

    pdx->DeviceStateFlags = PAR_DEVICE_PAUSED;
    KeClearEvent(&pdx->PauseEvent); // pause any worker thread

    // Set Device Interface inactive for PdoTypeRawPort - other PDO types don't have device interfaces
    if( PdoTypeRawPort == pdx->PdoType ) {
        if( (pdx->DeviceInterface.Buffer != NULL) && (TRUE == pdx->DeviceInterfaceState) ) {
            IoSetDeviceInterfaceState( &pdx->DeviceInterface, FALSE );
            pdx->DeviceInterfaceState = FALSE;
        }
    }

    // If we were not reported in the last FDO BusRelations enumeration then it is safe to delete self
    if( pdx->DeleteOnRemoveOk ) {
        DD((PCE)pdx,DDT,"PptPdoRemoveDevice - DeleteOnRemoveOk == TRUE - cleaning up self\n");
        P4DestroyPdo( Pdo );
        status = P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
        return status;
    } else {
        return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
    }
}


NTSTATUS
PptPdoCancelRemove(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION  pdx = Pdo->DeviceExtension;

    pdx->DeviceStateFlags &= ~(PPT_DEVICE_REMOVE_PENDING | PAR_DEVICE_PAUSED);
    KeSetEvent(&pdx->PauseEvent, 0, FALSE); // unpause any worker thread

    return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
}


NTSTATUS
PptPdoStopDevice(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION  pdx = Pdo->DeviceExtension;

    // DDpnp2( ("PptPdoStopDevice\n") );

    pdx->DeviceStateFlags |=  PAR_DEVICE_PAUSED;
    pdx->DeviceStateFlags &= ~PPT_DEVICE_STARTED;
    KeClearEvent(&pdx->PauseEvent); // pause any worker thread

    return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
}


NTSTATUS
PptPdoQueryStop(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION  pdx = Pdo->DeviceExtension;

    // DDpnp2( ("PptPdoQueryStop\n") );

    pdx->DeviceStateFlags  |= (PPT_DEVICE_STOP_PENDING | PAR_DEVICE_PAUSED);
    KeClearEvent(&pdx->PauseEvent); // pause any worker thread

    return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
}


NTSTATUS
PptPdoCancelStop(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION  pdx = Pdo->DeviceExtension;

    pdx->DeviceStateFlags &= ~PPT_DEVICE_STOP_PENDING;
    KeSetEvent(&pdx->PauseEvent, 0, FALSE); // unpause any worker thread

    return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
}


NTSTATUS
PptPdoQueryDeviceRelations(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION        pdx         = Pdo->DeviceExtension;
    PIO_STACK_LOCATION    irpSp       = IoGetCurrentIrpStackLocation( Irp );
    DEVICE_RELATION_TYPE  requestType = irpSp->Parameters.QueryDeviceRelations.Type;
    NTSTATUS              status      = Irp->IoStatus.Status;
    ULONG_PTR             info        = Irp->IoStatus.Information;

    if( TargetDeviceRelation == requestType ) {
        PDEVICE_RELATIONS devRel = ExAllocatePool( PagedPool, sizeof(DEVICE_RELATIONS) );
        if( devRel ) {
            devRel->Count = 1;
            ObReferenceObject( Pdo );
            devRel->Objects[0] = Pdo;
            status = STATUS_SUCCESS;
            info   = (ULONG_PTR)devRel;
        } else {
            status = STATUS_NO_MEMORY;
        }
    } else {
        DD((PCE)pdx,DDT,"PptPdoQueryDeviceRelations - unhandled request Type = %d\n",requestType);
    }
    return P4CompleteRequest( Irp, status, info );
}


NTSTATUS
PptPdoQueryCapabilities(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION      pdx = Pdo->DeviceExtension;
    PIO_STACK_LOCATION  irpSp = IoGetCurrentIrpStackLocation( Irp );

    irpSp->Parameters.DeviceCapabilities.Capabilities->RawDeviceOK       = TRUE;
    if( PdoTypeRawPort == pdx->PdoType ) {
        // This is the legacy LPTx interface device - no driver should
        //  ever be installed for this so don't bother the user with a popup.
        irpSp->Parameters.DeviceCapabilities.Capabilities->SilentInstall = TRUE;
    }

    return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information );
}


NTSTATUS
PptPdoQueryDeviceText(
    IN PDEVICE_OBJECT  Pdo,
    IN PIRP            Irp
    )
{
    PPDO_EXTENSION      pdx        = Pdo->DeviceExtension;
    PIO_STACK_LOCATION  irpSp      = IoGetCurrentIrpStackLocation( Irp );
    PWSTR               buffer     = NULL;
    ULONG               bufLen;
    ULONG_PTR           info;
    NTSTATUS            status;

    if( DeviceTextDescription == irpSp->Parameters.QueryDeviceText.DeviceTextType ) {

        //
        // DeviceTextDescription is: catenation of MFG+<SPACE>+MDL
        //
        if( pdx->Mfg && pdx->Mdl ) {
            //
            // Construct UNICODE string to return from the ANSI strings
            //   that we have in our extension
            //
            // need space for <SPACE> and terminating NULL
            //
            bufLen = strlen( (const PCHAR)pdx->Mfg ) + strlen( (const PCHAR)pdx->Mdl ) + 2 * sizeof(CHAR);
            bufLen *= ( sizeof(WCHAR)/sizeof(CHAR) );
            buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen );
            if( buffer ) {
                RtlZeroMemory( buffer, bufLen );
                _snwprintf( buffer, bufLen/2, L"%S %S", pdx->Mfg, pdx->Mdl );
                DD((PCE)pdx,DDT,"PptPdoQueryDeviceText - DeviceTextDescription - <%S>\n",buffer);
                status = STATUS_SUCCESS;
            } else {
                status = STATUS_NO_MEMORY;
            }
        } else {
            DD((PCE)pdx,DDE,"PptPdoQueryDeviceText - MFG and/or MDL NULL - FAIL DeviceTextDescription\n");
            status = STATUS_UNSUCCESSFUL;
        }
    } else if( DeviceTextLocationInformation == irpSp->Parameters.QueryDeviceText.DeviceTextType ) {

        //
        // DeviceTextLocationInformation is LPTx or LPTx.y (note that
        //   this is also the symlink name minus the L"\\DosDevices\\"
        //   prefix)
        //

        if( pdx->Location ) {
            bufLen = strlen( (const PCHAR)pdx->Location ) + sizeof(CHAR);
            bufLen *= ( sizeof(WCHAR)/sizeof(CHAR) );
            buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen );
            if( buffer ) {
                RtlZeroMemory( buffer, bufLen );
                _snwprintf( buffer, bufLen/2, L"%S", pdx->Location );
                DD((PCE)pdx,DDT,"PptPdoQueryDeviceText - DeviceTextLocationInformation - <%S>\n",buffer);
                status = STATUS_SUCCESS;
            } else {
                status = STATUS_NO_MEMORY;
            }
        } else {
            DD((PCE)pdx,DDE,"PptPdoQueryDeviceText - Location NULL - FAIL DeviceTextLocationInformation\n");
            status = STATUS_UNSUCCESSFUL;
        }
    } else {

        // Unknown DeviceTextType - don't change anything in IRP
        buffer = NULL;
        status = Irp->IoStatus.Status;
    }

    if( (STATUS_SUCCESS == status) && buffer ) {
        info = (ULONG_PTR)buffer;
    } else {
        if( buffer ) {
            ExFreePool( buffer );
        }
        info = Irp->IoStatus.Information;
    }

    return P4CompleteRequest( Irp, status, info );
}


NTSTATUS
PptPdoQueryId( PDEVICE_OBJECT Pdo, PIRP Irp )
{
    PPDO_EXTENSION      pdx        = Pdo->DeviceExtension;
    PIO_STACK_LOCATION  irpSp      = IoGetCurrentIrpStackLocation( Irp );
    PWSTR               buffer     = NULL;
    ULONG               bufLen;
    NTSTATUS            status;
    ULONG_PTR           info;

    switch( irpSp->Parameters.QueryId.IdType ) {

⌨️ 快捷键说明

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