拦截Windows关机事件,直接抛弃
#include <ntddk.h>
// 你的PnP驱动的设备扩展
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT DeviceObject;
// 其他字段
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
NTSTATUS MyDeviceAdd (
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
NTSTATUS status;
PDEVICE_OBJECT deviceObject;
PDEVICE_EXTENSION deviceExtension;
// 创建你的设备对象
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&deviceObject
);
if (!NT_SUCCESS(status)) {
return status;
}
deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
deviceExtension->DeviceObject = deviceObject;
// 添加类似以下代码来设置你的设备的电源相关函数
deviceObject->Flags |= DO_POWER_INRUSH;
// 设置你的设备以进行电源IRP处理
deviceObject->Flags |= DO_POWER_PAGABLE;
return status;
}
NTSTATUS MyPower (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION stack;
stack = IoGetCurrentIrpStackLocation(Irp);
if (stack->MinorFunction == IRP_MN_SET_POWER) {
if (stack->Parameters.Power.Type == SystemPowerState) {
// 检查是否是要到关机状态
if (stack->Parameters.Power.State.SystemState == PowerSystemShutdown) {
// 你可以在这里编写代码来拒绝关机操作,比如直接返回 STATUS_SUCCESS。
return STATUS_SUCCESS;
}
}
}
// 默认情况下,所有其他 IRPs 都会通过
return IoPassIrpDown(DeviceObject, Irp);
}
VOID DriverUnload (
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT deviceObject;
deviceObject = DriverObject->DeviceObject;
while (deviceObject)
{
PDEVICE_OBJECT nextDeviceObject;
nextDeviceObject = deviceObject->NextDevice;
IoDeleteDevice(deviceObject);
deviceObject = nextDeviceObject;
}
}
NTSTATUS DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = MyDeviceAdd;
DriverObject->MajorFunction[IRP_MJ_POWER] = MyPower;
return STATUS_SUCCESS;
}
NTSTATUS IoPassIrpDown(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
UNREFERENCED_PARAMETER(pDeviceObject);
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
编译 安装到 Windows
需要按照以下一般步骤进行:
1. **设置内核模式调试环境:** – 在运行内核模式驱动程序之前,必须建立一个内核模式调试环境。 –
使用 WinDbg 或 Visual Studio 进行内核调试。
2. **编译驱动程序:** – 使用 Windows
驱动程序开发工具包 (WDK) 和相应的编译器构建你的驱动程序。 – 确保项目设置正确配置。
3. **安装驱动程序:** –
一旦编译完成,需要在目标系统上安装驱动程序。 – 使用 `sc` (Service Control) 命令或其他方法安装驱动程序。
4.
**加载驱动程序:** – 安装完成后,使用 `sc start` 命令或其他方式加载驱动程序。 –
检查系统日志以查看加载过程中是否有任何错误。
5. **测试驱动程序:** –
通过与相关设备交互或触发与电源相关的事件来测试驱动程序的功能。
6. **调试:** –
使用内核调试器设置断点、检查变量,并诊断任何问题。 – 分析调试输出和日志以进行故障排除。
7. **卸载驱动程序:** –
在修改或重新编译驱动程序之前,使用 `sc stop` 命令卸载驱动程序。
8. **修改并重复:** –
根据需求进行必要的代码修改。 – 重新编译和安装驱动程序。 –
重复测试过程。
请记住,开发和测试内核模式驱动程序可能对系统稳定性产生重大影响。请谨慎行事,并确保你熟悉内核调试技术以及相关风险。
此外,在开发和测试内核模式驱动程序时,请遵守法律和伦理规定。内核模式开发通常在受控制的环境中进行,不建议用于普通用户系统。
评论抢沙发