将卷GUID路径转换为设备路径

时间:2011-08-18 17:27:43

标签: windows winapi windows-services

我的任务是跟踪从Windows服务添加和删除磁盘驱动器。我使用RegisterServiceCtrlHandlerEx和RegisterDeviceNotification来实现它。我的服务控制处理程序例程成功接收SERVICE_CONTROL_DEVICEEVENT控制代码,并处理GUID_DEVINTERFACE_VOLUME clss的DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE事件。顺便说一句,Windows不会向我的例程发送DBT_DEVICEQUERYREMOVE,DBT_DEVICEQUERYREMOVEFAILED,DBT_DEVICEREMOVEPENDING事件,但现在我想解决另一个问题。

当我收到DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE事件且dbch_devicetype是DBT_DEVTYP_DEVICEINTERFACE时,我可以从DEV_BROADCAST_DEVICEINTERFACE结构的dbcc_name字段读取设备名称。它看起来像这样:\?\ STORAGE#RemovableMedia#7& 331a4e33& 0& RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}

我只能在DBT_DEVICEARRIVAL事件上使用GetVolumeNameForVolumeMountPoint过程将此字符串转换为卷guid路径。在DBT_DEVICEREMOVECOMPLETE事件上GetVolumeNameForVolumeMountPoint返回错误3(系统找不到指定的路径)。

另一方面,在服务启动期间,我使用FindFirstVolume / FindNextVolume扫描系统中的所有卷,它返回所有卷的卷GUID路径列表。

因此,如果我的服务启动时存在卷,我可以收到其卷GUID路径。如果在我的服务运行期间删除该卷,那么我将收到设备名称(如\?\ STORAGE#RemovableMedia#7& 331a4e33& 0& RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}) DBT_DEVICEREMOVECOMPLETE事件。

正如我上面所写,我无法在DBT_DEVICEREMOVECOMPLETE事件期间使用GetVolumeNameForVolumeMountPoint来获取卷GUID路径。所以我想找到一种方法将从FindFirstVolume / FindNextVolume收到的卷GUID路径转换为设备名称。我需要这个来维护我自己的系统中现有的可移动磁盘驱动器列表。

请就这个问题给我一些建议。

2 个答案:

答案 0 :(得分:1)

要枚举用于构建自己的设备列表的设备,您可以使用SetupAPI

  

通过使用SetupAPI例程,您可以枚举中的所有设备   指定设备接口类并检索设备路径   设备

您首先使用适用于您的设备类的GUID致电SetupDiGetClassDevs,例如GUID_DEVINTERFACE_VOLUME,然后反复调用SetupDiEnumDeviceInfo来迭代设备。

显示如何操作的示例代码:

  • Knowledge base article显示所有内容
  • 可以找到该过程的另一个描述here,查看部分使用以下步骤为USB设备创建文件句柄。

可以使用SetupDiGetDeviceRegistryProperty查询各个设备的属性(路径就在其中)。

答案 1 :(得分:1)

所以我发现无法从FindFisrtVolume / FindNextVolume返回的卷GUID路径中检索设备路径。相反,我将使用SetupApi枚举设备接口替换FindFisrtVolume / FindNextVolume。

以下是执行此操作的步骤:

  1. 调用SetupDiGetClassDevs(& GUID_DEVINTERFACE_VOLUME,NULL,NULL,DIGCF_INTERFACEDEVICE | DIGCF_PRESENT)以检索设备信息集。
  2. Enum设备与SetupDiEnumDeviceInterfaces接口(devinfoset,NULL和& GUID_DEVINTERFACE_VOLUME,idx和& devitf)。
  3. 为每个设备接口调用SetupDiGetDeviceInterfaceDetail以检索设备路径。
  4. 不幸的是,以这种方式检索的设备路径与Windows在DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE事件中传递的设备路径的情况不同。因此,我们需要在比较它们时规范化设备路径。