让设备驱动支持弹出操作

在这里插入图片描述

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;
}

驱动加载后就可以看到安全删除设备的图标
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值