如何弹出USB可移动磁盘/卷,类似于“弹出"Windows 资源管理器中的功能? [英] How to eject a USB removable disk/volume, similar to the "Eject" function in Windows Explorer?

查看:32
本文介绍了如何弹出USB可移动磁盘/卷,类似于“弹出"Windows 资源管理器中的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您是否知道 Windows 用于完成可移动卷的外壳上下文菜单上提供的弹出"功能的 API 或 API 调用序列是什么?

Do you know what is the API, or sequence of API calls that windows uses to accomplish the "Eject" function which is available on the shell context menu for removable volumes?

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

So far I've tried two things:

  1. 使用CM_Request_Device_Eject,我列举了可移动磁盘(使用 SetupDiXXX APIs),找到我感兴趣的那个,遍历设备管理器层次结构(使用 CM_XXX APIs),最后在我感兴趣的设备的 devInst 上调用 CM_Request_Device_Eject.这工作,因为它确实从我的电脑中删除了卷并使设备安全删除"(准备删除),但它与外壳上下文菜单弹出"功能不同.我知道这是因为我尝试弹出的设备应该在弹出时执行某些操作,而当我使用 CM_Request_Device_Eject某事 不会发生代码>.

  1. using CM_Request_Device_Eject, I enumerate the removable disks (using the SetupDiXXX APIs), find the one that I'm interested in, walk the device manager hierarchy (using CM_XXX APIs) and finally call CM_Request_Device_Eject on the devInst of the device I'm interesed in. This works in the sense that it does remove the volumes from My Computer and makes the device "safe to remove" (ready to be removed) but it is not the same as the shell context menu "Eject" function. The way I know this is because the device that I'm trying to eject is supposed to do something when it is ejected and that something is not happening when I do the eject using CM_Request_Device_Eject.

使用 DeviceIoControlIOCTL_STORAGE_EJECT_MEDIA 控制代码.事件的顺序是:

using DeviceIoControl with the IOCTL_STORAGE_EJECT_MEDIA control code. The sequence of events is:

  • obtain a handle to the volume I'm interested in using CreateFile as suggested in the documentation
  • try to lock the volume with FSCTL_LOCK_VOLUME
  • try to dismount it using FSCTL_DISMOUNT_VOLUME
  • disable the prevent storage media removal using IOCTL_STORAGE_MEDIA_REMOVAL
  • and finally execute the IOCTL_STORAGE_EJECT_MEDIA function.

这根本行不通.DeviceIoControl 调用中的每一个都失败并显示 ERROR_IVALID_FUNCTION (0x00000001).我不知道为什么调用失败.我已经验证对 DeviceIoControl 的其他调用对于相同的文件句柄工作正常(例如 IOCTL_STORAGE_GET_DEVICE_NUMBER)

This doesn't work at all. Each one of the DeviceIoControl calls fails with ERROR_IVALID_FUNCTION (0x00000001). I don't know why the calls fail. I've verified that other calls to DeviceIoControl work fine for the same file handle (such as IOCTL_STORAGE_GET_DEVICE_NUMBER)

最后,我的开发机器运行的是 Windows 7 x64,为了让第二种方法起作用,我尝试以管理员权限运行我的应用程序,但没有任何改变.

Finally, my development machine is running Windows 7 x64, and in order to get the second method to work I've tried running my application with Administrator privileges and that did not change anything.

编辑

最终,我发现了我在方法 2 中犯的错误.事实证明,由于某种原因,我在使用 CreateFile 打开卷的句柄时没有正确设置所需的访问权限.正确的访问模式是 GENERIC_READ |GENERIC_WRITE 并且我传递了 0.纠正我的错误后,我能够使用 DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA 以及方法 #1 成功弹出设备,使用 CM_Request_Device_Eject代码>.

Eventually, I found out where I was making a mistake with approach #2. It turns out that for some reason I was not setting the desired access correctly when opening the handle to the volume using CreateFile. The correct access mode is GENERIC_READ | GENERIC_WRITE and I was passing 0. After correcting my error I was able to successfully eject the device using DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA, as well as with method #1, using CM_Request_Device_Eject.

事实证明,方法#2 确实是外壳上下文菜单的弹出"功能使用的方法.使用这种方法,设备反应正确.

And it turns out that method #2 is indeed the method used by the shell context menu's "Eject" function. Using this method the device reacts correctly.

推荐答案

最终,我发现了我在方法 2 中犯的错误.

Eventually, I found out where I was making a mistake with approach #2.

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

It turns out that for some reason I was not setting the desired access correctly when opening the handle to the volume using CreateFile.

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

The correct access mode is GENERIC_READ | GENERIC_WRITE and I was passing 0. After correcting my error I was able to successfully eject the device using DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA, as well as with method #1, using CM_Request_Device_Eject.

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

Finally, it turns out that method #2 is indeed the method used by the shell context menu's "Eject" function. Using this method the device reacts correctly.

这篇关于如何弹出USB可移动磁盘/卷,类似于“弹出"Windows 资源管理器中的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆