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

📄 pnp.c

📁 win2k kernel 的并口驱动程序模板
💻 C
📖 第 1 页 / 共 5 页
字号:
        PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - PowerRelations\n") );
        break;
    case TargetDeviceRelation:
        PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - TargetDeviceRelations\n") );
        break;
    default:
        PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - unrecognized Relations\n") );
        break;
    }

    return PptPnpPassThroughPnpIrpAndReleaseRemoveLock(DeviceObject->DeviceExtension, Irp);
}

NTSTATUS
PptPnpQueryStopDevice(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    )
/*++dvdf8

Routine Description:

    This function handles PnP IRP_MN_QUERY_STOP_DEVICE.

    FAIL the request if there are open handles, SUCCEED otherwise.
    
    Other drivers may cache pointers to the parallel port registers that 
      they obtained via IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO and there
      is currently no mechanism to find and inform all such drivers that the 
      parallel port registers have changed and their their cached pointers are 
      now invalid without breaking legacy drivers.

    This function is identical to PptPnpQueryStopDevice() except
      for the flag that gets set in extension->DeviceStateFlags.

Arguments:

    DeviceObject - The target device for the IRP
    Irp          - The IRP

Return Value:

    STATUS_SUCCESS     - No open handles - SUCCEED IRP
    STATUS_DEVICE_BUSY - Open handles - FAIL IRP

--*/
{
    NTSTATUS          status       = STATUS_SUCCESS;
    PDEVICE_EXTENSION extension    = DeviceObject->DeviceExtension;
    BOOLEAN           handlesOpen;

    //
    // RMT - dvdf - race condition - small timing window - sequence:
    //   1. Test indicates no open handles - decide to SUCCEED QUERY_STOP
    //   2. CREATE arrives and is SUCCEEDED - open handle
    //   3. We SUCCEED QUERY_STOP
    //   4. Client obtains register addresses via IOCTL
    //   5. PnP Rebalances us - registers change
    //   6. Client acquires port via IOCTL
    //   7. Client tries to access registers at pre-rebalance location
    //   8. BOOM!!!
    //

    ExAcquireFastMutex( &extension->OpenCloseMutex );
    handlesOpen = (BOOLEAN)( extension->OpenCloseRefCount > 0 );
    ExReleaseFastMutex( &extension->OpenCloseMutex );

    if( handlesOpen ) {
        
        status = STATUS_DEVICE_BUSY;
        PptFailRequest( Irp, status );
        PptReleaseRemoveLock( &extension->RemoveLock, Irp );

    } else {

        Irp->IoStatus.Status = STATUS_SUCCESS;
        status = PptPnpPassThroughPnpIrpAndReleaseRemoveLock( extension, Irp );

        ExAcquireFastMutex( &extension->ExtensionFastMutex );
        PptSetFlags( extension->DeviceStateFlags, ( PPT_DEVICE_STOP_PENDING | PPT_DEVICE_PAUSED ) );
        ExReleaseFastMutex( &extension->ExtensionFastMutex );
    }
    
    return status;
}

NTSTATUS
PptPnpCancelStopDevice(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    ) 
/*++dvdf8

Routine Description:

    This function handles PnP IRP_MN_CANCEL_STOP_DEVICE.

    If we previously SUCCEEDed a QUERY_STOP (PPT_DEVICE_STOP_PENDING 
      flag is set) then we reset the appropriate device state flags 
      and resume normal operation. Otherwise treat this as an
      informational message. 

    This function is identical to PptPnpCancelRemoveDevice() except for
      the extension->DeviceStateFlags.

Arguments:

    DeviceObject - The target device for the IRP
    Irp          - The IRP

Return Value:

    Status returned from IoCallDriver.

--*/
{
    PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;

    ExAcquireFastMutex( &extension->ExtensionFastMutex );
    if( extension->DeviceStateFlags & PPT_DEVICE_STOP_PENDING ) {
        PptClearFlags( extension->DeviceStateFlags, ( PPT_DEVICE_STOP_PENDING | PPT_DEVICE_PAUSED ) );
    }
    ExReleaseFastMutex( &extension->ExtensionFastMutex );

    Irp->IoStatus.Status = STATUS_SUCCESS;
    return PptPnpPassThroughPnpIrpAndReleaseRemoveLock( extension, Irp );
}

NTSTATUS
PptPnpStopDevice(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    ) 
/*++dvdf8

Routine Description:

    This function handles PnP IRP_MN_STOP_DEVICE.

    We previously SUCCEEDed QUERY_STOP. Set flags
      to indicate that we are now STOPPED.

Arguments:

    DeviceObject - The target device for the IRP
    Irp          - The IRP

Return Value:

    Status returned from IoCallDriver.

--*/
{
    PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;

    ExAcquireFastMutex( &extension->ExtensionFastMutex );

    //
    // Assert that we are in a STOP_PENDING state.
    //
    ASSERT( extension->DeviceStateFlags & PPT_DEVICE_STOP_PENDING );
    ASSERT( extension->DeviceStateFlags & PPT_DEVICE_PAUSED );

    //
    // PPT_DEVICE_PAUSED remains set
    //
    PptSetFlags( extension->DeviceStateFlags,   PPT_DEVICE_STOPPED );
    PptClearFlags( extension->DeviceStateFlags, ( PPT_DEVICE_STOP_PENDING | PPT_DEVICE_STARTED ) );

    ExReleaseFastMutex( &extension->ExtensionFastMutex );

    Irp->IoStatus.Status = STATUS_SUCCESS;
    return PptPnpPassThroughPnpIrpAndReleaseRemoveLock(extension, Irp);
}

NTSTATUS
PptPnpQueryRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp
    ) 
/*++dvdf8

Routine Description:

    This function handles PnP IRP_MN_QUERY_REMOVE_DEVICE.

    FAIL the request if there are open handles, SUCCEED otherwise.
    
    This function is identical to PptPnpQueryStopDevice() except
      for the flag that gets set in extension->DeviceStateFlags.

Arguments:

    DeviceObject - The target device for the IRP
    Irp          - The IRP

Return Value:

    STATUS_SUCCESS     - No open handles - SUCCEED IRP
    STATUS_DEVICE_BUSY - Open handles - FAIL IRP

--*/
{
    //
    // Always succeed query - PnP will veto Query Remove on our behalf if 
    //   there are open handles
    //

    PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;

    DDPnP1(("-- QueryRemove\n"));

    PptDump2(PARPNP1, ("pnp::PptPnpQueryRemoveDevice - SUCCEED - as always\n"));

    ExAcquireFastMutex( &extension->ExtensionFastMutex );
    PptSetFlags( extension->DeviceStateFlags, ( PPT_DEVICE_REMOVE_PENDING | PPT_DEVICE_PAUSED ) );
    ExReleaseFastMutex( &extension->ExtensionFastMutex );

    Irp->IoStatus.Status = STATUS_SUCCESS;

    return PptPnpPassThroughPnpIrpAndReleaseRemoveLock( extension, Irp );

#if 0

    // original code

    NTSTATUS          status       = STATUS_SUCCESS;
    PDEVICE_EXTENSION extension    = DeviceObject->DeviceExtension;
    BOOLEAN           handlesOpen;

    //
    // RMT - dvdf - race condition - small timing window 
    //            - see PptPnpQueryStop() for details.
    //

    ExAcquireFastMutex( &extension->OpenCloseMutex );
    handlesOpen = (BOOLEAN)( extension->OpenCloseRefCount > 0 );
    ExReleaseFastMutex( &extension->OpenCloseMutex );

    if( handlesOpen ) {
        
        PptDump2(PARPNP1, ("pnp::PptPnpQueryRemoveDevice - FAIL - handlesOpen=%d\n", handlesOpen));
        status = STATUS_DEVICE_BUSY;
        PptFailRequest( Irp, status );
        PptReleaseRemoveLock( &extension->RemoveLock, Irp );

    } else {

        PptDump2(PARPNP1, ("pnp::PptPnpQueryRemoveDevice - SUCCEED\n"));
        Irp->IoStatus.Status = STATUS_SUCCESS;
        status = PptPnpPassThroughPnpIrpAndReleaseRemoveLock( extension, Irp );

        ExAcquireFastMutex( &extension->ExtensionFastMutex );
        PptSetFlags( extension->DeviceStateFlags, ( PPT_DEVICE_REMOVE_PENDING | PPT_DEVICE_PAUSED ) );
        ExReleaseFastMutex( &extension->ExtensionFastMutex );
    }
    
    return status;
#endif
}
NTSTATUS
PptPnpCancelRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    ) 
/*++dvdf8

Routine Description:

    This function handles PnP IRP_MN_CANCEL_REMOVE_DEVICE.

    If we previously SUCCEEDed a QUERY_REMOVE (PPT_DEVICE_REMOVE_PENDING 
      flag is set) then we reset the appropriate device state flags 
      and resume normal operation. Otherwise treat this as an
      informational message. 

    This function is identical to PptPnpCancelStopDevice() except for
      the extension->DeviceStateFlags.

Arguments:

    DeviceObject - The target device for the IRP
    Irp          - The IRP

Return Value:

    Status returned from IoCallDriver.

--*/
{
    PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;

    DDPnP1(("-- CancelRemove\n"));

    ExAcquireFastMutex( &extension->ExtensionFastMutex );
    if( extension->DeviceStateFlags & PPT_DEVICE_REMOVE_PENDING ) {
        PptClearFlags( extension->DeviceStateFlags, ( PPT_DEVICE_REMOVE_PENDING | PPT_DEVICE_PAUSED ) );
    }
    ExReleaseFastMutex( &extension->ExtensionFastMutex );

    Irp->IoStatus.Status = STATUS_SUCCESS;
    return PptPnpPassThroughPnpIrpAndReleaseRemoveLock( extension, Irp );
}

NTSTATUS
PptPnpRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    ) 
/*++dvdf8

Routine Description:

    This function handles PnP IRP_MN_REMOVE_DEVICE.

    Notify those listening on our device interface GUID that 
      we have gone away, wait until all other IRPs that the
      device is processing have drained, and clean up.

Arguments:

    DeviceObject - The target device for the IRP
    Irp          - The IRP

Return Value:

    Status returned from IoCallDriver.

--*/
{
    PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
    NTSTATUS          status;

    DDPnP1(("-- RemoveDevice\n"));

    //
    // Set flags in our extension to indicate that we have received 
    //   IRP_MN_REMOVE_DEVICE so that we can fail new requests as appropriate.
    //
    ExAcquireFastMutex( &extension->ExtensionFastMutex );
    PptSetFlags( extension->DeviceStateFlags, PPT_DEVICE_REMOVED );
    ExReleaseFastMutex( &extension->ExtensionFastMutex );

    //
    // Unregister w/WMI
    //
    IoWMIRegistrationControl(DeviceObject, WMIREG_ACTION_DEREGISTER);

    //
    // Tell those listening on our device interface GUID that we have
    //   gone away. Ignore status from the call since we can do
    //   nothing on failure.
    //
    IoSetDeviceInterfaceState(&extension->SymbolicLinkName, FALSE);

    //
    // Pass the IRP down the stack and wait for all other IRPs
    //   that are being processed by the device to drain.
    //
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoSkipCurrentIrpStackLocation( Irp );
    status = IoCallDriver( extension->ParentDeviceObject, Irp );
    PptReleaseRemoveLockAndWait( &extension->RemoveLock, Irp );

    //
    // Clean up pool allocations
    // 
    PptCleanRemovalRelationsList( extension );
    RtlFreeUnicodeString( &extension->DeviceName);
    RtlFreeUnicodeString( &extension->SymbolicLinkName );
    if( extension->PnpInfo.PortName ) {
        ExFreePool( extension->PnpInfo.PortName );
        extension->PnpInfo.PortName = NULL;
    }

    //
    // Detach and delete our device object.
    //
    IoDetachDevice( extension->ParentDeviceObject );
    IoDeleteDevice( DeviceObject );
    

⌨️ 快捷键说明

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