outlook_mapi_sys/
installation.rs1use std::path::{Path, PathBuf};
2use windows::{
3 Win32::Storage::FileSystem::GetBinaryTypeW,
4 core::{PCWSTR, w},
5};
6
7use crate::load_mapi::{
8 OFFICE_QUALIFIERS, OUTLOOK_QUALIFIED_COMPONENTS, get_office_executable_path,
9 get_office_mapi_path_no_install, get_outlook_mapi_path,
10};
11
12#[derive(Debug, Clone, Copy, PartialEq)]
13pub enum Architecture {
14 X64,
15 X86,
16}
17
18pub enum InstallationState {
24 Installed {
26 architecture: Architecture,
28 dll_path: PathBuf,
30 is_outlook_installed: bool,
33 },
34 NotInstalled,
35}
36
37fn get_binary_architecture(file_path: &Path) -> Result<Architecture, Box<dyn std::error::Error>> {
38 let path_str = file_path.to_string_lossy();
39 let path_wide: Vec<u16> = path_str.encode_utf16().chain(std::iter::once(0)).collect();
40 let mut binary_type: u32 = 0;
41
42 unsafe {
43 GetBinaryTypeW(PCWSTR::from_raw(path_wide.as_ptr()), &mut binary_type)?;
44
45 match binary_type {
46 0 => Ok(Architecture::X86), 6 => Ok(Architecture::X64), _ => Err(format!("Unsupported binary type: {binary_type}").into()),
49 }
50 }
51}
52
53fn try_office_installation(category: PCWSTR, qualifier: PCWSTR) -> Option<InstallationState> {
54 let exe_path = unsafe { get_office_executable_path(category, qualifier) }.ok()?;
60
61 let actual_arch = get_binary_architecture(&exe_path).ok()?;
63
64 let dll_path = unsafe { get_office_mapi_path_no_install(category, qualifier) }.ok()?;
66
67 Some(InstallationState::Installed {
68 architecture: actual_arch,
69 dll_path,
70 is_outlook_installed: false,
71 })
72}
73
74pub fn check_outlook_mapi_installation() -> InstallationState {
75 const OUTLOOK_QUALIFIERS: [(Architecture, PCWSTR); 2] = [
76 (Architecture::X64, w!("outlook.x64.exe")),
77 (Architecture::X86, w!("outlook.exe")),
78 ];
79
80 for category in OUTLOOK_QUALIFIED_COMPONENTS {
82 for (bitness, qualifier) in OUTLOOK_QUALIFIERS {
83 if let Ok(path) = unsafe { get_outlook_mapi_path(category, qualifier) } {
84 return InstallationState::Installed {
85 architecture: bitness,
86 dll_path: path,
87 is_outlook_installed: true,
88 };
89 }
90 }
91 }
92
93 for category in OUTLOOK_QUALIFIED_COMPONENTS {
102 for qualifier in OFFICE_QUALIFIERS {
103 if let Some(installation) = try_office_installation(category, qualifier) {
104 return installation;
105 }
106 }
107 }
108
109 InstallationState::NotInstalled
110}