您知道Windows使用什么API或API调用序列来完成可移动卷的shell上下文菜单中提供的“弹出”功能吗?
到目前为止,我尝试了两件事:
使用CM_Request_Device_Eject,我枚举可移动磁盘(使用SetupDiXXX APIs),找到我感兴趣的磁盘,走设备管理器层次结构(使用CM_XXX APIs )并最终在我所介入的设备的CM_Request_Device_Eject
上调用devInst
。这个工作,因为它确实从我的电脑中移除了卷并使设备成为可能“安全删除”(准备删除)但它与shell上下文菜单“弹出”功能不同。我知道这个的方式是因为我试图弹出的设备应该在弹出时执行某些操作,并且当我使用CM_Request_Device_Eject
进行弹出时,某些没有发生。
将DeviceIoControl与IOCTL_STORAGE_EJECT_MEDIA控制代码一起使用。事件的顺序是:
这根本不起作用。 DeviceIoControl
调用中的每一个都以ERROR_IVALID_FUNCTION
(0x00000001)失败。我不知道为什么呼叫失败了。我已经验证了对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上下文菜单的“弹出”功能所使用的方法。使用此方法,设备可以正确反应。
答案 0 :(得分:2)
最终,我发现了方法#2的错误。
事实证明,由于某种原因,我在使用CreateFile打开卷的句柄时没有正确设置所需的访问权限。
正确的访问模式是GENERIC_READ | GENERIC_WRITE
,我正在通过0
。纠正错误后,我能够使用DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA以及使用CM_Request_Device_Eject的方法#1成功弹出设备。
最后,事实证明方法#2确实是shell上下文菜单使用的方法" Eject"功能。使用此方法,设备可以正确反应。
答案 1 :(得分:0)
我在搜索“CM_Request_Device_Eject”时意外地来到这里,并且看到它类似于我最近通过将类似的解决方案组合在一起所做的解决方案。原谅迟到的答案。
我在项目in this SO answer上总结了我为此做的步骤。