我的任务是跟踪从Windows服务添加和删除磁盘驱动器。 我使用RegisterServiceCtrlHandlerEx和RegisterDeviceNotification来实现这一点。 我的服务控制处理程序例程成功接收SERVICE_CONTROL_DEVICEEVENT控制代码,并处理GUID_DEVINTERFACE_VOLUME clsss的DBT_DEVICEAREMIVAL和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过程将此string转换为卷GUIDpath。 在DBT_DEVICEREMOVECOMPLETE事件GetVolumeNameForVolumeMountPoint返回错误3(系统找不到指定的path)。
另一方面,在服务启动期间,我使用FindFirstVolume / FindNextVolume扫描系统中的所有卷,并返回给我所有卷的GUIDpath列表。
所以如果卷存在,当我的服务启动我可以收到其卷GUIDpath。 如果这个卷将被删除,而我的服务正在运行,那么我将从DBT_DEVICEREMOVECOMPLETE事件接收设备名称(如\?\ STORAGE#RemovableMedia#7&331a4e33&0&RM#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b})。
正如我上面写的,我不能使用GetVolumeNameForVolumeMountPoint在DBT_DEVICEREMOVECOMPLETE事件获取卷GUIDpath。 所以我想find一种方法来将从FindFirstVolume / FindNextVolume接收到的卷GUIDpath转换为设备名称。 我需要这个维护我自己的系统中的可移动磁盘驱动器列表。
请给我一些关于这个问题的build议。
要枚举用于构建自己的设备列表的设备,可以使用SetupAPI :
通过使用SetupAPI例程,可以枚举指定的设备接口类中的所有设备,并检索设备的设备路径。
首先调用SetupDiGetClassDevs,并为设备类使用适当的GUID,例如GUID_DEVINTERFACE_VOLUME
,然后重复调用SetupDiEnumDeviceInfo来迭代设备。
示例代码显示如何执行此操作:
可以使用SetupDiGetDeviceRegistryProperty查询各个设备的属性(路径在其中)。
所以我找不到从FindFisrtVolume / FindNextVolume返回的卷GUID路径检索设备路径。 相反,我将使用SetupApi枚举设备接口来替换FindFisrtVolume / FindNextVolume。
这是步骤:
不幸的是,以这种方式检索到的设备路径与窗口在DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE事件中传递的设备路径不同。 所以当我们比较它们时,我们需要规范设备路径。