📄 pnpmn.cpp
字号:
//****************************************************************************
// File PNPMN.CPP
//
// PnP / Power handlers
//
// Copyright (c) APSoft, 1998-2002.
// All rights reserved.
//
//****************************************************************************
extern "C"
{
#include <ntddk.h> // Main DDK's include
}
#include <pnpdev.h> // Device class
#include <utils.h> // Utils methods
///////////////////////////////////////////////////////////////////////////////
// --- PnP dispatch table --- //
///////////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (CPnpDevice::*PFNPNPHANDLER)(PIRP pIrp);
static PFNPNPHANDLER PnPDispatch[] =
{
CPnpDevice::OnStartDevice, // IRP_MN_START_DEVICE
CPnpDevice::OnQueryRemoveDevice, // IRP_MN_QUERY_REMOVE_DEVICE
CPnpDevice::OnRemoveDevice, // IRP_MN_REMOVE_DEVICE
CPnpDevice::OnCancelRemoveDevice, // IRP_MN_CANCEL_REMOVE_DEVICE
CPnpDevice::OnStopDevice, // IRP_MN_STOP_DEVICE
CPnpDevice::OnQueryStopDevice, // IRP_MN_QUERY_STOP_DEVICE
CPnpDevice::OnCancelStopDevice, // IRP_MN_CANCEL_STOP_DEVICE
CPnpDevice::OnQueryDeviceRelations, // IRP_MN_QUERY_DEVICE_RELATIONS
CPnpDevice::OnQueryInterface, // IRP_MN_QUERY_INTERFACE
CPnpDevice::OnQueryCapabilities, // IRP_MN_QUERY_CAPABILITIES
CPnpDevice::OnQueryResources, // IRP_MN_QUERY_RESOURCES
CPnpDevice::OnQueryResourceReq, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
CPnpDevice::OnQueryDeviceText, // IRP_MN_QUERY_DEVICE_TEXT
CPnpDevice::OnFilterResReq, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
CPnpDevice::DefPnPHandler, //
CPnpDevice::OnReadConfig, // IRP_MN_READ_CONFIG
CPnpDevice::OnWriteConfig, // IRP_MN_WRITE_CONFIG
CPnpDevice::OnEject, // IRP_MN_EJECT
CPnpDevice::OnSetLock, // IRP_MN_SET_LOCK
CPnpDevice::OnQueryID, // IRP_MN_QUERY_ID
CPnpDevice::OnDeviceState, // IRP_MN_PNP_DEVICE_STATE
CPnpDevice::OnQueryBusInfo, // IRP_MN_QUERY_BUS_INFORMATION
CPnpDevice::OnDeviceUsageNotify, // IRP_MN_QUERY_BUS_INFORMATION
CPnpDevice::OnSurpriseRemoval, // IRP_MN_SURPRISE_REMOVAL
CPnpDevice::OnQueryLegacyBusInfo // IRP_MN_QUERY_LEGACY_BUS_INFORMATION
};
///////////////////////////////////////////////////////////////////////////////
// --- Class CPnpDevice --- //
///////////////////////////////////////////////////////////////////////////////
//****************************************************************************
// --- PowerRequest ---
//
// Purpose: Complete PoRequestPowerIrp
// Input: PDEVICE_OBJECT pDeviceObject - Device object
// UCHAR uMinor - Minor function
// POWER_STATE pwState - Power state
// PVOID pContext - Context (KEVENT)
// PIO_STATUS_BLOCK pIoStatus - I/O status
// Output: none
// Written: by Anton V. Krivenko 11.12.2000
//****************************************************************************
static void PowerRequest(PDEVICE_OBJECT pDeviceObject, UCHAR uMinor,
POWER_STATE pwState, PVOID pContext,
PIO_STATUS_BLOCK pIoStatus)
{
KeSetEvent((PRKEVENT)pContext, IO_NO_INCREMENT, FALSE);
}
//****************************************************************************
// --- CPnpDevice::OnWorkItem ---
//
// Purpose: Work item routine
// Input: none
// Output: none
// Written: by Anton V. Krivenko 09.02.2001
//****************************************************************************
void CPnpDevice::OnWorkItem(void)
{
STRACE_PNPDRV(">> CPnpDevice::OnWorkItem()\n");
KEVENT kEvent; // Complete event
NTSTATUS ntStatus; // PoRequestPowerIrp status
POWER_STATE pwState;
pwState.DeviceState = PowerDeviceD0;
//--------------------- Send power IRP to our device -------------------------
KeInitializeEvent(&kEvent, NotificationEvent, FALSE);
ntStatus = PoRequestPowerIrp(m_pDevObject, IRP_MN_SET_POWER, pwState,
PowerRequest, &kEvent, NULL);
//--------------------------- Wait IRP complete ------------------------------
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
IoFreeWorkItem(m_pWorkItem);
STRACE_PNPDRV("<< CPnpDevice::OnWorkItem()\n");
}
//****************************************************************************
// --- CPnpDevice::OnPowerComplete ---
//
// Purpose: Power completion rouitine
// Input: PIRP pIrp - Power IRP
// Output: NTSTATUS - STATUS_SUCCESS
// Written: by Eduard J. Mishkurov 25.11.2000
//****************************************************************************
NTSTATUS CPnpDevice::OnPowerComplete(PIRP pIrp)
{
STRACE_PNPDRV(">> CPnpDevice::OnPowerComplete()\n");
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
POWER_STATE_TYPE pwType = pStack->Parameters.Power.Type;
POWER_STATE pwState = pStack->Parameters.Power.State;
switch (pStack->MinorFunction)
{
case IRP_MN_QUERY_POWER:
ASSERTS_PNPDRV(FALSE);
break;
case IRP_MN_SET_POWER:
switch (pwType)
{
case DevicePowerState:
if (m_DeviceState < pwState.DeviceState)
{
//
// Powering down
//
ASSERTS_PNPDRV(FALSE);
}
else
if (pwState.DeviceState < m_DeviceState)
{
//
// Powering Up
//
PoSetPowerState(m_pDevObject, pwType, pwState);
m_DeviceState = pwState.DeviceState;
PowerOn();
}
break;
case SystemPowerState:
if (m_SystemState < pwState.SystemState)
{
//
// Powering down
//
ASSERTS_PNPDRV(FALSE);
}
else
if (pwState.SystemState < m_SystemState)
{
//
// Powering Up
//
if (pwState.SystemState == PowerSystemWorking &&
m_DeviceState != PowerDeviceD0)
{
//
// Do the system start up stuff here
//
m_pWorkItem = IoAllocateWorkItem(m_pDevObject);
IoQueueWorkItem(m_pWorkItem,
WorkItemRoutine,
DelayedWorkQueue,
this);
}
m_SystemState = pwState.SystemState;
}
break;
} // switch (pwrType)
break;
default:
ASSERTS_PNPDRV(FALSE);
break;
} // switch (pStack->MinorFunction)
PoStartNextPowerIrp(pIrp);
STRACE_PNPDRV("<< CPnpDevice::OnPowerComplete()\n");
return STATUS_SUCCESS;
}
//****************************************************************************
// --- CPnpDevice::OnIrpPower ---
//
// Purpose: Handle IRP_MJ_POWER request
// Input: PIRP pIrp - I/O request package
// NTSTATUS & ntStatus - Operation status
// Output: BOOLEAN - TRUE if request was completed
// Written: by Anton V. Krivenko 4/9/2002
//****************************************************************************
BOOLEAN CPnpDevice::OnIrpPower(PIRP pIrp, NTSTATUS & ntStatus)
{
STRACE_PNPDRV(">> CPnpDevice::OnIrpPower()\n");
BOOLEAN fRet = TRUE; // Prevent second completion
PIO_STACK_LOCATION pStack; // Current stack location
pStack = IoGetCurrentIrpStackLocation(pIrp);
ntStatus = STATUS_UNSUCCESSFUL;
if (!LockDevice())
{
pIrp->IoStatus.Status = ntStatus = STATUS_DELETE_PENDING;
PoStartNextPowerIrp(pIrp);
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
} // if (!LockDevice())
else
{
BOOLEAN fHookIt = FALSE;
POWER_STATE_TYPE pwType = pStack->Parameters.Power.Type;
POWER_STATE pwState = pStack->Parameters.Power.State;
switch (pStack->MinorFunction)
{
case IRP_MN_QUERY_POWER:
pIrp->IoStatus.Status = ntStatus
= OnQueryPower(pIrp, pwType, pwState);
break;
case IRP_MN_SET_POWER:
pIrp->IoStatus.Status = ntStatus = STATUS_SUCCESS;
switch (pwType)
{
case DevicePowerState:
STRACE_PNPDRV(" Type: DevicePowerState\n");
STRACE_PNPDRV(" Requested State: %i\n", pwState.DeviceState);
STRACE_PNPDRV(" Current State: %i\n", m_DeviceState);
if (m_DeviceState < pwState.DeviceState)
{
// Powering down
PoSetPowerState (m_pDevObject, pwType, pwState);
if (m_DeviceState == PowerDeviceD0)
{
// Do the power down stuff here
PowerOff();
}
m_DeviceState = pwState.DeviceState;
}
else
if (pwState.DeviceState < m_DeviceState)
{
// Powering Up
fHookIt = TRUE;
}
break;
case SystemPowerState:
if (m_SystemState < pwState.SystemState)
{
// Powering down
if (m_SystemState == PowerSystemWorking)
{
// Do the system shut down stuff here
}
if (m_DeviceState != PowerDeviceD3)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -