Do not loop forever when a device removal needs a reboot

This commit is contained in:
David Lönnhager committed 2026-09-02 14:43:07 +02:00
1 parent c179a44911
commit df3ef0dba6
2 files changed
+17 -4

No files matched your search

+4 -2
View File
@@ -204,8 +204,10 @@ pub struct DeviceInfo<'a> {
impl DeviceInfo<'_> {
/// Uninstalls the device represented by this `DeviceInfo`. This calls [`DiUninstallDevice`].
///
/// Returns whether a reboot is needed to complete the removal.
///
/// [`DiUninstallDevice`]: https://learn.microsoft.com/en-us/windows/win32/api/newdev/nf-newdev-diuninstalldevice.
pub fn uninstall_device(self) -> io::Result<()> {
pub fn uninstall_device(self) -> io::Result<bool> {
let mut needs_reboot: windows_sys::core::BOOL = 0;
// SAFETY: `self.set.0` and `self.data` are valid and belong to the same enumeration.
// `needs_reboot` is a writable BOOL.
@@ -223,7 +225,7 @@ impl DeviceInfo<'_> {
return Err(io::Error::last_os_error());
}
Ok(())
Ok(needs_reboot != FALSE)
}
/// Read the `NetCfgInstanceId` registry value from a device's driver key.
+13 -2
View File
@@ -51,9 +51,12 @@ pub fn remove_wintun_abandoned_device() -> Result<(), Error> {
if let Ok(id) = device_info.get_device_net_cfg_instance_id()
&& id.eq_ignore_ascii_case(WINTUN_ABANDONED_GUID)
{
device_info
let needs_reboot = device_info
.uninstall_device()
.map_err(Error::DeviceEnumeration)?;
if needs_reboot {
tracing::warn!("A reboot is needed to finish removing the Wintun adapter");
}
return Ok(());
}
}
@@ -102,10 +105,18 @@ fn uninstall_devices_by_hardware_id(hardware_id: &str) -> Result<usize, Error> {
if let Ok(ids) = device_info.get_hardware_ids()
&& ids.iter().any(|id| id.eq_ignore_ascii_case(hardware_id))
{
device_info
let needs_reboot = device_info
.uninstall_device()
.map_err(Error::DeviceEnumeration)?;
removed += 1;
// Avoid looping forever if we couldn't remove it right away.
if needs_reboot {
tracing::warn!("A reboot is needed to finish uninstalling {hardware_id}");
return Ok(removed);
}
continue 'outer;
}
}