S0:全功率工作状态
S1:初级休眠
S4:CPU停止.内存保存到休眠文件里面
D0:设备全功率工作
D1:低功耗模式,设备环境可以被保留
D2:低功耗模式,设备环境无效
typedef _Struct_size_bytes_(Size) struct _DEVICE_CAPABILITIES {
USHORT Size;
USHORT Version; // 值为1
//一下为一个ULONG 的位域
ULONG DeviceD1:1;
ULONG DeviceD2:1;
ULONG LockSupported:1; //设备是否支持锁定
ULONG EjectSupported:1; // 设备是否支持拔出
ULONG Removable:1; //U盘这种可移动设备 该值为1 表示可移除
ULONG DockDevice:1; //设备是否支持悬挂
ULONG UniqueID:1; //这里指设备的VEN ID 和 DEV ID是否唯一
ULONG SilentInstall:1; //是否支持静默安装
ULONG RawDeviceOK:1; //原始的设备是否正常
ULONG SurpriseRemovalOK:1; //是否支持突然拔出(热拔出) U盘可以突然拔出 但是系统不会崩溃
ULONG WakeFromD0:1; //是否支持从D0状态唤醒
ULONG WakeFromD1:1;
ULONG WakeFromD2:1;
ULONG WakeFromD3:1;
ULONG HardwareDisabled:1; //硬件是否是屏蔽的
ULONG NonDynamic:1;
ULONG WarmEjectSupported:1;
ULONG NoDisplayInUI:1;
ULONG Reserved1:1;
ULONG WakeFromInterrupt:1;
ULONG Reserved:12;
ULONG Address;
ULONG UINumber;
DEVICE_POWER_STATE DeviceState[POWER_SYSTEM_MAXIMUM]; //设备当前处于什么电源状态
SYSTEM_POWER_STATE SystemWake; //系统是否处于苏醒状态
DEVICE_POWER_STATE DeviceWake;
ULONG D1Latency;
ULONG D2Latency;
ULONG D3Latency;
} DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES;
NTSTATUS OnRequestComplete(PDEVICE_OBJECT junk, PIRP Irp, PKEVENT pev)
{ // OnRequestComplete
//在完成例程中设置等待事件
KeSetEvent(pev, 0, FALSE);
//标志本IRP还需要再次被完成
return STATUS_MORE_PROCESSING_REQUIRED;
}
#pragma PAGEDCODE
//Forward 传递 转发
NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
{ // ForwardAndWait
PAGED_CODE();
DbgPrint("enter my ForwardAndWait function \n");
KEVENT event;
//初始化事件
KeInitializeEvent(&event, NotificationEvent, FALSE);
//将本层堆栈拷贝到下一层堆栈
IoCopyCurrentIrpStackLocationToNext(Irp);
//设置完成例程
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)OnRequestComplete,
(PVOID)&event, TRUE, TRUE, TRUE);
//调用底层驱动,即PDO
IoCallDriver(pdx->NextStackDevice, Irp);
//等待PDO完成
KeWaitForSingleObject(&event,Executive, KernelMode, FALSE, NULL);
return Irp->IoStatus.Status;
}
//处理 IRP_MN_QUERY_CAPABILITIES
NTSTATUS PnpQuertCapbilityHandler(IN PDEVICE_EXTENSION fdo,
IN PIRP Irp)
{
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack;
PDEVICE_CAPABILITIES pdc;
KdPrint(("enter PnpQuertCapbilityHandler\n"));
status = ForwardAndWait(fdo,Irp);
if (NT_SUCCESS(status))
{
stack = IoGetCurrentIrpStackLocation(Irp);
//Capabilities 性能
pdc = stack->Parameters.DeviceCapabilities.Capabilities;
for (ULONG i = PowerSystemWorking; i < PowerSystemMaximum; i++)
{
KdPrint(("未改之前的电源状态:%x,%x\n",i,pdc->DeviceState[i]));
}
pdc->DeviceState[PowerSystemWorking] = PowerDeviceD0;
pdc->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
pdc->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
pdc->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
pdc->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
pdc->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
pdc->Removable = TRUE;
for (ULONG i = PowerSystemWorking; i < PowerSystemMaximum; i++)
{
KdPrint(("修改之后的电源状态:%x,%x\n", i, pdc->DeviceState[i]));
}
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; // no bytes xfered
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
驱动加载后就可以看到安全删除设备的图标