16

您知道什么是 API 或 API 调用序列,Windows 使用这些 API 来完成可移动卷的 shell 上下文菜单中提供的“弹出”功能吗?

到目前为止,我已经尝试了两件事:

  1. 使用CM_Request_Device_Eject,我枚举可移动磁盘(使用SetupDiXXX API),找到我感兴趣的磁盘,遍历设备管理器层次结构(使用CM_XXX API),最后调用我感兴趣CM_Request_Device_EjectdevInst设备。这个从某种意义上说,它确实从我的电脑中删除了卷并使设备“安全删除”(准备删除),但它与外壳上下文菜单“弹出”功能不同我知道这是因为我试图弹出的设备在弹出时应该做一些事情,当我使用CM_Request_Device_Eject.

  2. DeviceIoControlIOCTL_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 上下文菜单的“弹出”功能使用的方法。使用这种方法,设备会做出正确的反应。

4

2 回答 2

2

最终,我发现我在方法#2 中犯了错误。

事实证明,由于某种原因,在使用 CreateFile 打开卷的句柄时,我没有正确设置所需的访问权限。

正确的访问模式是GENERIC_READ | GENERIC_WRITE,我正在通过0. 纠正我的错误后,我能够使用 DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA 以及使用方法 #1 使用 CM_Request_Device_Eject 成功弹出设备。

最后,方法#2 确实是shell 上下文菜单的“弹出”功能使用的方法。使用这种方法,设备会做出正确的反应。

于 2015-03-20T02:56:22.390 回答
0

我在搜索“CM_Request_Device_Eject”时意外来到这里,发现它类似于我最近通过将类似的解决方案组合在一起完成的解决方案。原谅迟到的答案。

我已经在这个 SO answer 中总结了我在我的项目中为此所做的步骤。

于 2015-03-19T01:27:06.013 回答