您知道什么是 API 或 API 调用序列,Windows 使用这些 API 来完成可移动卷的 shell 上下文菜单中提供的“弹出”功能吗?
到目前为止,我已经尝试了两件事:
使用CM_Request_Device_Eject,我枚举可移动磁盘(使用SetupDiXXX API),找到我感兴趣的磁盘,遍历设备管理器层次结构(使用CM_XXX API),最后调用我感兴趣
CM_Request_Device_Eject
的devInst
设备。这个从某种意义上说,它确实从我的电脑中删除了卷并使设备“安全删除”(准备删除),但它与外壳上下文菜单“弹出”功能不同。我知道这是因为我试图弹出的设备在弹出时应该做一些事情,而当我使用CM_Request_Device_Eject
.将DeviceIoControl与IOCTL_STORAGE_EJECT_MEDIA控制代码一起使用。事件的顺序是:
- 按照文档中的建议,获取我有兴趣使用CreateFile的卷的句柄
- 尝试使用FSCTL_LOCK_VOLUME锁定卷
- 尝试使用FSCTL_DISMOUNT_VOLUME卸载它
- 使用IOCTL_STORAGE_MEDIA_REMOVAL禁用防止存储介质移除
- 最后执行IOCTL_STORAGE_EJECT_MEDIA函数。
这根本行不通。每个调用都以(0x00000001)
DeviceIoControl
失败。ERROR_IVALID_FUNCTION
我不知道为什么通话失败。我已经验证了对 DeviceIoControl 的其他调用对于同一个文件句柄(例如IOCTL_STORAGE_GET_DEVICE_NUMBER)工作正常
最后,我的开发机器运行的是 Windows 7 x64,为了让第二种方法工作,我尝试以管理员权限运行我的应用程序,但这并没有改变任何东西。
编辑
最终,我发现我在方法#2 中犯了错误。事实证明,由于某种原因,在使用CreateFile
. 正确的访问模式是GENERIC_READ | GENERIC_WRITE
,我通过了 0。纠正错误后,我能够使用 成功弹出设备DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA
,以及使用方法#1,使用CM_Request_Device_Eject
.
事实证明,方法 #2 确实是 shell 上下文菜单的“弹出”功能使用的方法。使用这种方法,设备会做出正确的反应。