2011-08-18 209 views
2

我的任务是跟踪从Windows服务添加和删除磁盘驱动器。我使用RegisterServiceCtrlHandlerEx和RegisterDeviceNotification来实现这一点。我的服务控制处理程序例程成功接收SERVICE_CONTROL_DEVICEEVENT控制代码,并处理GUID_DEVINTERFACE_VOLUME clsss的DBT_DEVICEAREMIVAL和DBT_DEVICEREMOVECOMPLETE事件。顺便说一下,Windows不会将DBT_DEVICEQUERYREMOVE,DBT_DEVICEQUERYREMOVEFAILED,DBT_DEVICEREMOVEPENDING事件发送到我的例程,但现在我想解决另一个问题。将卷GUID路径转换为设备路径

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

我可以在这个字符串中使用GetVolumeNameForVolumeMountPoint过程仅在DBT_DEVICEARRIVAL转换成卷GUID路径事件。在DBT_DEVICEREMOVECOMPLETE事件GetVolumeNameForVolumeMountPoint返回错误3(系统找不到指定的路径)。

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

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

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

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

回答

1

所以我发现没有办法从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来检索设备路径。

不幸的是,以这种方式检索到的设备路径与窗口在DBT_DEVICEAREMIVETE和DBT_DEVICEREMOVECOMPLETE事件中通过的设备路径不同。所以当我们比较它们时,我们需要规范设备路径。

1

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

通过使用SETUPAPI程序,您可以枚举 指定的设备接口类的所有设备和检索的设备路径 设备。

您先拨打SetupDiGetClassDevs,并为您的设备类别提供适当的GUID,例如: GUID_DEVINTERFACE_VOLUME,然后重复调用SetupDiEnumDeviceInfo来迭代设备。

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

  • Knowledge base article展示这一切
  • 过程的另一个描述可以发现here,看看对部分使用以下步骤来创建一个文件处理USB设备。

的各个装置可使用SetupDiGetDeviceRegistryProperty中查询的属性(该路径是其中)。

+1

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

+0

听起来不错。很高兴你找到了一个方法! –