Skip to content

Commit 9287eb6

Browse files
committed
fix: improve log output again
Also cleanup some error handling
1 parent 65f9340 commit 9287eb6

6 files changed

Lines changed: 116 additions & 111 deletions

File tree

src/cleanup_modules/device_cleanup.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
use async_trait::async_trait;
2-
use error_stack::{report, IntoReport, Result, ResultExt};
2+
use error_stack::{IntoReport, Result, ResultExt};
33
use serde::Deserialize;
44
use uuid::Uuid;
55
use windows::{
66
core::HSTRING,
7-
Win32::{
8-
Devices::DeviceAndDriverInstallation::*,
9-
Foundation::{GetLastError, BOOL},
10-
},
7+
Win32::{Devices::DeviceAndDriverInstallation::*, Foundation::BOOL},
118
};
129

1310
use super::{
14-
get_path_to_dump, Dumper, IntoModuleReport, ModuleError, ModuleMetadata, ModuleRunInfo,
15-
ModuleStrategy, ToUninstall, UninstallError,
11+
get_path_to_dump, Dumper, IntoModuleReport, IntoUninstallReport, ModuleError, ModuleMetadata,
12+
ModuleRunInfo, ModuleStrategy, ToUninstall, UninstallError,
1613
};
1714
use crate::{
1815
cleanup_modules::create_dump_file,
1916
services::{
2017
self, identifiers, regex_cache,
21-
windows::{enumerate_devices, inf_regex, Device, HResultExt},
18+
windows::{enumerate_devices, inf_regex, Device},
2219
},
2320
State,
2421
};
@@ -85,15 +82,15 @@ impl ModuleStrategy for DeviceCleanupModule {
8582
async fn uninstall_object(
8683
&self,
8784
object: Self::Object,
88-
_to_uninstall: &Self::ToUninstall,
85+
to_uninstall: &Self::ToUninstall,
8986
_state: &State,
9087
run_info: &mut ModuleRunInfo,
9188
) -> Result<(), UninstallError> {
9289
unsafe {
9390
let device_info_set = SetupDiCreateDeviceInfoList(None, None)
9491
.into_report()
95-
.change_context(UninstallError::UninstallFailed)
96-
.attach_printable_lazy(|| "failed to create a device list")?;
92+
.attach_printable_lazy(|| "failed to create a device list")
93+
.into_uninstall_report(to_uninstall)?;
9794
let mut device_info_data = SP_DEVINFO_DATA {
9895
cbSize: std::mem::size_of::<SP_DEVINFO_DATA>() as u32,
9996
..SP_DEVINFO_DATA::default()
@@ -108,12 +105,13 @@ impl ModuleStrategy for DeviceCleanupModule {
108105
)
109106
.as_bool()
110107
{
111-
let error = GetLastError();
112-
return Err(report!(UninstallError::UninstallFailed))
108+
let error = windows::core::Error::from_win32();
109+
return Err(error)
110+
.into_report()
113111
.attach_printable_lazy(|| {
114112
format!("failed to open device info of {}", object.instance_id())
115113
})
116-
.attach_win32_error(error);
114+
.into_uninstall_report(to_uninstall);
117115
}
118116

119117
let mut reboot: BOOL = false.into();
@@ -126,12 +124,13 @@ impl ModuleStrategy for DeviceCleanupModule {
126124
)
127125
.as_bool()
128126
{
129-
let error = GetLastError();
130-
return Err(report!(UninstallError::UninstallFailed))
127+
let error = windows::core::Error::from_win32();
128+
return Err(error)
129+
.into_report()
131130
.attach_printable_lazy(|| {
132131
format!("failed to uninstall device {}", object.instance_id())
133132
})
134-
.attach_win32_error(error);
133+
.into_uninstall_report(to_uninstall);
135134
}
136135

137136
if reboot.as_bool() {

src/cleanup_modules/driver_cleanup.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
11
use std::path::Path;
22

33
use async_trait::async_trait;
4-
use error_stack::{report, IntoReport, Result, ResultExt};
4+
use error_stack::{IntoReport, Result, ResultExt};
55
use serde::Deserialize;
66
use uuid::Uuid;
77
use windows::{
88
core::HSTRING,
9-
Win32::{
10-
Devices::DeviceAndDriverInstallation::DiUninstallDriverW,
11-
Foundation::{GetLastError, BOOL},
12-
},
9+
Win32::{Devices::DeviceAndDriverInstallation::DiUninstallDriverW, Foundation::BOOL},
1310
};
1411

1512
use super::{
16-
Dumper, IntoModuleReport, ModuleError, ModuleMetadata, ModuleRunInfo, ModuleStrategy,
17-
ToUninstall, UninstallError,
13+
Dumper, IntoModuleReport, IntoUninstallReport, ModuleError, ModuleMetadata, ModuleRunInfo,
14+
ModuleStrategy, ToUninstall, UninstallError,
1815
};
1916
use crate::{
2017
cleanup_modules::{create_dump_file, get_path_to_dump},
2118
services::{
2219
self, identifiers, regex_cache,
23-
windows::{enumerate_drivers, Driver, HResultExt},
20+
windows::{enumerate_drivers, Driver},
2421
},
2522
State,
2623
};
@@ -87,7 +84,7 @@ impl ModuleStrategy for DriverCleanupModule {
8784
async fn uninstall_object(
8885
&self,
8986
object: Self::Object,
90-
_to_uninstall: &Self::ToUninstall,
87+
to_uninstall: &Self::ToUninstall,
9188
_state: &State,
9289
run_info: &mut ModuleRunInfo,
9390
) -> Result<(), UninstallError> {
@@ -104,12 +101,13 @@ impl ModuleStrategy for DriverCleanupModule {
104101
)
105102
.as_bool()
106103
{
107-
let err = GetLastError();
108-
return Err(report!(UninstallError::UninstallFailed))
104+
let err = windows::core::Error::from_win32();
105+
return Err(err)
106+
.into_report()
109107
.attach_printable_lazy(|| {
110108
format!("failed to uninstall inf: {}", inf_path.display())
111109
})
112-
.attach_win32_error(err);
110+
.into_uninstall_report(to_uninstall);
113111
}
114112

115113
if reboot.as_bool() {

src/cleanup_modules/driver_package_cleanup.rs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey};
1616
use wmi::{COMLibrary, WMIConnection, WMIError};
1717

1818
use super::{
19-
create_dump_file, Dumper, IntoModuleReport, ModuleError, ModuleMetadata, ModuleRunInfo,
20-
ModuleStrategy, ToUninstall, UninstallError,
19+
create_dump_file, Dumper, IntoModuleReport, IntoUninstallReport, ModuleError, ModuleMetadata,
20+
ModuleRunInfo, ModuleStrategy, ToUninstall, UninstallError,
2121
};
2222
use crate::{
2323
cleanup_modules::get_path_to_dump,
@@ -99,21 +99,18 @@ impl ModuleStrategy for DriverPackageCleanupModule {
9999
use UninstallMethod::*;
100100

101101
match &to_uninstall.uninstall_method {
102-
Normal => {
103-
run_uninstall_method(uninstall_normal, state, &object, to_uninstall).await
104-
},
102+
Normal => run_uninstall_method(uninstall_normal, state, &object, to_uninstall).await,
105103
Deferred => {
106104
run_uninstall_method(uninstall_deferred, state, &object, to_uninstall).await
107105
}
108106
RegistryOnly => {
109-
uninstall_registry_only(object, to_uninstall)
110-
.attach_printable_lazy(|| {
111-
format!(
112-
"failed to open uninstall key for driver package '{}'",
113-
to_uninstall.friendly_name
114-
)
115-
})
116-
},
107+
uninstall_registry_only(object, to_uninstall).attach_printable_lazy(|| {
108+
format!(
109+
"failed to open uninstall key for driver package '{}'",
110+
to_uninstall.friendly_name
111+
)
112+
})
113+
}
117114
}
118115
}
119116

@@ -124,7 +121,7 @@ impl ModuleStrategy for DriverPackageCleanupModule {
124121

125122
fn uninstall_registry_only(
126123
object: DriverPackage,
127-
_to_uninstall: &DriverPackageToUninstall,
124+
to_uninstall: &DriverPackageToUninstall,
128125
) -> Result<(), UninstallError> {
129126
let key_path = Path::new(object.key_name());
130127
let key_parent = key_path.parent().unwrap();
@@ -135,13 +132,13 @@ fn uninstall_registry_only(
135132
.open_subkey_with_flags(key_parent, flags)
136133
.into_report()
137134
.attach_printable_lazy(|| key_parent.to_string_lossy().to_string())
138-
.change_context(UninstallError::UninstallFailed)?;
135+
.into_uninstall_report(to_uninstall)?;
139136

140137
uninstall_key
141138
.delete_subkey_all(key_name)
142139
.into_report()
143140
.attach_printable_lazy(|| key_path.to_string_lossy().to_string())
144-
.change_context(UninstallError::UninstallFailed)
141+
.into_uninstall_report(to_uninstall)
145142
}
146143

147144
#[derive(Default)]
@@ -226,40 +223,40 @@ where
226223
async fn uninstall_normal(
227224
_state: &State,
228225
object: &DriverPackage,
229-
_to_uninstall: &DriverPackageToUninstall,
226+
to_uninstall: &DriverPackageToUninstall,
230227
_ct: CancellationToken,
231228
) -> Result<(), UninstallError> {
232229
let uninstall_string = object.uninstall_string().unwrap();
233230
let child_process = match to_command(uninstall_string).spawn() {
234231
Ok(child) => child,
235232
Err(err) => match err.kind() {
236-
ErrorKind::NotFound => bail!(UninstallError::AlreadyUninstalled),
233+
ErrorKind::NotFound => bail!(UninstallError::uninstalled(to_uninstall)),
237234
_ => {
238235
return Err(err)
239236
.into_report()
240-
.change_context(UninstallError::UninstallFailed)
241237
.attach_printable_lazy(|| {
242238
format!("failed to launch uninstaller: {}", uninstall_string)
243239
})
240+
.into_uninstall_report(to_uninstall)
244241
}
245242
},
246243
};
247244

248245
wait_for_process_async(child_process)
249246
.await
250247
.into_report()
251-
.change_context(UninstallError::UninstallFailed)
252248
.attach_printable_lazy(|| {
253249
format!("failed to wait on child process, exe: {}", uninstall_string)
254-
})?;
250+
})
251+
.into_uninstall_report(to_uninstall)?;
255252

256253
Ok(())
257254
}
258255

259256
async fn uninstall_deferred(
260257
_state: &State,
261258
object: &DriverPackage,
262-
_to_uninstall: &DriverPackageToUninstall,
259+
to_uninstall: &DriverPackageToUninstall,
263260
_ct: CancellationToken,
264261
) -> Result<(), UninstallError> {
265262
let uninstall_string = object.uninstall_string().unwrap();
@@ -274,14 +271,14 @@ async fn uninstall_deferred(
274271
let child = match command.spawn() {
275272
Ok(child) => child,
276273
Err(err) => match err.kind() {
277-
ErrorKind::NotFound => bail!(UninstallError::AlreadyUninstalled),
274+
ErrorKind::NotFound => bail!(UninstallError::uninstalled(to_uninstall)),
278275
_ => {
279276
return Err(err)
280277
.into_report()
281-
.change_context(UninstallError::UninstallFailed)
282278
.attach_printable_lazy(|| {
283279
format!("failed to launch uninstaller: {}", uninstall_string)
284280
})
281+
.into_uninstall_report(to_uninstall)
285282
}
286283
},
287284
};
@@ -314,22 +311,22 @@ async fn uninstall_deferred(
314311
(Err(err), _) => {
315312
return Err(err)
316313
.into_report()
317-
.change_context(UninstallError::UninstallFailed)
318314
.attach_printable("failed to wait for main uninstaller process")
315+
.into_uninstall_report(to_uninstall)
319316
}
320317
(_, Err(err)) => {
321318
return Err(err)
322-
.change_context(UninstallError::UninstallFailed)
323319
.attach_printable("failed to wait for uninstaller's delegated process")
320+
.into_uninstall_report(to_uninstall)
324321
}
325322
}
326323
ct.cancel();
327324
} else {
328325
wait_for_process_async(child)
329326
.await
330327
.into_report()
331-
.change_context(UninstallError::UninstallFailed)
332-
.attach_printable("failed to wait for main uninstaller process")?;
328+
.attach_printable("failed to wait for main uninstaller process")
329+
.into_uninstall_report(to_uninstall)?;
333330
}
334331

335332
Ok(())

src/cleanup_modules/mod.rs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,29 @@ pub struct ModuleError {
3535
}
3636

3737
#[derive(Debug, Error)]
38-
enum UninstallError {
39-
#[error("failed to uninstall")]
40-
UninstallFailed,
41-
#[error("the component is already uninstalled")]
42-
AlreadyUninstalled,
38+
pub(crate) enum UninstallError {
39+
#[error("Failed to uninstall {0}")]
40+
UninstallFailed(&'static str),
41+
#[error("{0} is already uninstalled")]
42+
AlreadyUninstalled(&'static str),
43+
}
44+
45+
impl UninstallError {
46+
fn failed<T>(uninstall_object: &T) -> Self
47+
where
48+
T: Display,
49+
{
50+
let str: &'static str = Box::leak(uninstall_object.to_string().into_boxed_str());
51+
Self::UninstallFailed(str)
52+
}
53+
54+
fn uninstalled<T>(uninstall_object: &T) -> Self
55+
where
56+
T: Display,
57+
{
58+
let str: &'static str = Box::leak(uninstall_object.to_string().into_boxed_str());
59+
Self::AlreadyUninstalled(str)
60+
}
4361
}
4462

4563
trait ToUninstall<T> {
@@ -125,17 +143,8 @@ where
125143
.uninstall_object(object, object_to_uninstall, state, &mut module_run_info)
126144
.await;
127145

128-
match ret {
129-
Ok(_) => {}
130-
Err(err) => match err.current_context() {
131-
UninstallError::AlreadyUninstalled => {
132-
println!("'{}' is already uninstalled!", object_to_uninstall)
133-
}
134-
UninstallError::UninstallFailed => {
135-
eprintln!("Failed to uninstall '{}'!", object_to_uninstall);
136-
eprintln!("{:?}", err);
137-
}
138-
},
146+
if let Err(err) = ret {
147+
eprintln!("{:?}", err);
139148
}
140149
}
141150
}
@@ -204,3 +213,17 @@ where
204213
self.change_context_lazy(|| ModuleError { name: module_name })
205214
}
206215
}
216+
217+
pub(crate) trait IntoUninstallReport<T, T2> {
218+
fn into_uninstall_report(self, uninstall_object: &T2) -> Result<T, UninstallError>;
219+
}
220+
221+
impl<T, T2, E> IntoUninstallReport<T, T2> for CResult<T, Report<E>>
222+
where
223+
T2: Display,
224+
E: Error + Context + Display,
225+
{
226+
fn into_uninstall_report(self, uninstall_object: &T2) -> Result<T, UninstallError> {
227+
self.change_context_lazy(|| UninstallError::failed(uninstall_object))
228+
}
229+
}

src/services/identifiers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ pub async fn get_resource(identifier: &'static str, state: &State) -> Result<Sou
8989
match resource {
9090
Ok(resource) => {
9191
no_color(|| info!("Got resource '{}' embedded", identifier));
92-
return Ok(resource);
92+
Ok(resource)
9393
}
9494
Err(err) => {
9595
no_color(|| warn!("{:?}", err));
96-
return Err(err);
96+
Err(err)
9797
}
9898
}
9999
}

0 commit comments

Comments
 (0)