【问题标题】:Converting volume GUID path to device path将卷 GUID 路径转换为设备路径
【发布时间】:2011-10-30 00:08:58
【问题描述】:

我的任务是跟踪从 Windows 服务中添加和删除磁盘驱动器。我使用 RegisterServiceCtrlHandlerEx 和 RegisterDeviceNotification 来实现这一点。我的服务控制处理程序例程成功接收 SERVICE_CONTROL_DEVICEEVENT 控制代码并处理 GUID_DEVINTERFACE_VOLUME clsss 的 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 路径。如果在我的服务运行时该卷将被删除,那么我将从 DBT_DEVICEREMOVECOMPLETE 事件。

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

请给我一些关于这个问题的建议。

【问题讨论】:

    标签: windows winapi windows-services


    【解决方案1】:

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

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

    您首先调用SetupDiGetClassDevs,并为您的设备类使用适当的 GUID,例如GUID_DEVINTERFACE_VOLUME,然后反复调用SetupDiEnumDeviceInfo迭代设备。

    示例代码展示了如何做到这一点:

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

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

    【讨论】:

    • 您的回答很有用,但我需要添加一些说明。如您所述,我尝试使用 SetupDiEnumDeviceInfo 和 SetupDiGetDeviceRegistryProperty。但是这样我无法获得设备路径。正确的方法是使用 SetupDiEnumDeviceInterfaces 和 SetupDiGetDeviceInterfaceDetail。
    【解决方案2】:

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

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

    1. 调用 SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME,NULL,NULL,DIGCF_INTERFACEDEVICE|DIGCF_PRESENT) 以检索设备信息集。
    2. 使用 SetupDiEnumDeviceInterfaces(devinfoset,NULL,&GUID_DEVINTERFACE_VOLUME,idx,&devitf) 枚举设备接口。
    3. 对于每个设备接口,调用 SetupDiGetDeviceInterfaceDetail 来检索设备路径。

    不幸的是,以这种方式检索的设备路径与 Windows 在 DBT_DEVICEARRIVAL 和 DBT_DEVICEREMOVECOMPLETE 事件中传递的设备路径不同。所以我们需要在比较设备路径时对其进行归一化。

    【讨论】:

      猜你喜欢
      • 2015-04-20
      • 2018-06-27
      • 2019-09-06
      • 2019-10-01
      • 2010-10-13
      • 2014-01-28
      • 1970-01-01
      • 2017-08-23
      • 2010-10-27
      相关资源
      最近更新 更多