diff --git a/src/ffi.rs b/src/ffi.rs index 9f6622c..9254cb6 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -25,6 +25,8 @@ extern "C" { #[link_name = "MsiDoActionA"] pub fn MsiDoAction(hInstall: MSIHANDLE, szAction: LPCSTR) -> u32; + pub fn MsiGetLastErrorRecord() -> MSIHANDLE; + pub fn MsiGetMode(hInstall: MSIHANDLE, eRunMode: RunMode) -> BOOL; #[link_name = "MsiGetPropertyA"] diff --git a/src/lib.rs b/src/lib.rs index 4cea410..2177766 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,26 @@ pub enum RunMode { Commit = 18, } +/// Gets the last Windows Installer error for the current process. +/// +/// # Example +/// +/// ``` +/// use msica::*; +/// +/// if let Some(error) = last_error_record() { +/// println!("last error: {}", error.format_text()); +/// } +/// ``` +pub fn last_error_record() -> Option { + unsafe { + match ffi::MsiGetLastErrorRecord() { + h if !h.is_null() => Some(h.into()), + _ => None, + } + } +} + /// A Windows Installer handle. This handle is not automatically closed. #[derive(Clone, Copy)] #[repr(transparent)] @@ -84,6 +104,10 @@ impl MSIHANDLE { fn to_owned(&self) -> PMSIHANDLE { PMSIHANDLE(*self) } + + fn is_null(&self) -> bool { + self.0 == 0 + } } impl From for MSIHANDLE { diff --git a/src/record.rs b/src/record.rs index 4345afd..93ca472 100644 --- a/src/record.rs +++ b/src/record.rs @@ -263,6 +263,12 @@ impl Deref for Record { } } +impl From for Record { + fn from(h: MSIHANDLE) -> Self { + Record { h: h.to_owned() } + } +} + impl From<&str> for Record { fn from(s: &str) -> Self { unsafe {