我的任务是跟踪从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路径转换为设备名称。我需要这个来维护我自己的系统中现有的可移动磁盘驱动器列表。
请就这个问题给我一些建议。
答案 0 :(得分:1)
要枚举用于构建自己的设备列表的设备,您可以使用SetupAPI:
通过使用SetupAPI例程,您可以枚举中的所有设备 指定设备接口类并检索设备路径 设备
您首先使用适用于您的设备类的GUID致电SetupDiGetClassDevs,例如GUID_DEVINTERFACE_VOLUME
,然后反复调用SetupDiEnumDeviceInfo来迭代设备。
显示如何操作的示例代码:
可以使用SetupDiGetDeviceRegistryProperty查询各个设备的属性(路径就在其中)。
答案 1 :(得分:1)
所以我发现无法从FindFisrtVolume / FindNextVolume返回的卷GUID路径中检索设备路径。相反,我将使用SetupApi枚举设备接口替换FindFisrtVolume / FindNextVolume。
以下是执行此操作的步骤:
不幸的是,以这种方式检索的设备路径与Windows在DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE事件中传递的设备路径的情况不同。因此,我们需要在比较它们时规范化设备路径。