Skip to content

Commit fce0065

Browse files
author
deeleeramone
committed
now we are just going in circles. this is probably a probably with the way that codeql is analyzing the unsafe block
1 parent aa77fe0 commit fce0065

File tree

1 file changed

+57
-121
lines changed

1 file changed

+57
-121
lines changed

desktop/src-tauri/src/utils/autostart/windows_autostart.rs

Lines changed: 57 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -51,65 +51,27 @@ pub fn enable_autostart(app_handle: &AppHandle) -> Result<(), String> {
5151
Data4: [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46],
5252
};
5353

54-
// RAII wrapper for IShellLinkW
55-
struct ShellLinkGuard(*mut IShellLinkW);
56-
57-
impl ShellLinkGuard {
58-
unsafe fn as_ref(&self) -> Option<&IShellLinkW> {
59-
if self.0.is_null() {
60-
None
61-
} else {
62-
// SAFETY: We've checked that the pointer is not null
63-
unsafe { Some(&*self.0) }
64-
}
65-
}
66-
}
67-
68-
impl Drop for ShellLinkGuard {
69-
fn drop(&mut self) {
70-
unsafe {
71-
if !self.0.is_null() {
72-
(*self.0).Release();
73-
}
74-
}
75-
}
76-
}
77-
78-
// RAII wrapper for IPersistFile
79-
struct PersistFileGuard(*mut IPersistFile);
80-
81-
impl PersistFileGuard {
82-
/// Execute a closure with the raw IPersistFile pointer if it is non-null.
83-
///
84-
/// Returns an error if the pointer is null.
85-
unsafe fn with<F, R>(&self, f: F) -> Result<R, String>
86-
where
87-
F: FnOnce(*mut IPersistFile) -> R,
88-
{
89-
if self.0.is_null() {
90-
Err("Persist file pointer is null".to_string())
91-
} else {
92-
// SAFETY: We've checked that the pointer is not null, and we
93-
// only pass the pointer into the provided closure without
94-
// extending its lifetime beyond this call.
95-
Ok(f(self.0))
96-
}
97-
}
98-
}
99-
100-
impl Drop for PersistFileGuard {
101-
fn drop(&mut self) {
102-
unsafe {
103-
if !self.0.is_null() {
104-
(*self.0).Release();
105-
}
106-
}
107-
}
108-
}
54+
// Precompute wide strings outside unsafe to avoid early returns inside COM section
55+
let wide_exe_path: Vec<u16> = executable_path
56+
.to_str()
57+
.ok_or("Failed to convert path to string")?
58+
.encode_utf16()
59+
.chain(std::iter::once(0))
60+
.collect();
61+
62+
let wide_shortcut_path: Vec<u16> = shortcut_path
63+
.to_str()
64+
.ok_or("Failed to convert shortcut path to string")?
65+
.encode_utf16()
66+
.chain(std::iter::once(0))
67+
.collect();
10968

11069
unsafe {
11170
// Initialize COM
112-
CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED);
71+
let hr_init = CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED);
72+
if !SUCCEEDED(hr_init) {
73+
return Err(format!("Failed to initialize COM: {hr_init:#x}"));
74+
}
11375

11476
// Create shell link object
11577
let mut shell_link: *mut IShellLinkW = ptr::null_mut();
@@ -121,75 +83,49 @@ pub fn enable_autostart(app_handle: &AppHandle) -> Result<(), String> {
12183
&mut shell_link as *mut _ as *mut _,
12284
);
12385

124-
if SUCCEEDED(hr) && !shell_link.is_null() {
125-
let shell_link_guard = ShellLinkGuard(shell_link);
126-
let shell_link_ref = shell_link_guard
127-
.as_ref()
128-
.ok_or("Shell link pointer is null".to_string())?;
129-
130-
// Set the path to the executable
131-
let wide_path: Vec<u16> = match executable_path.to_str() {
132-
Some(path) => path.encode_utf16().chain(std::iter::once(0)).collect(),
133-
None => {
134-
CoUninitialize();
135-
return Err("Failed to convert path to string".to_string());
136-
}
137-
};
138-
139-
let hr_set_path = shell_link_ref.SetPath(wide_path.as_ptr());
140-
if !SUCCEEDED(hr_set_path) {
141-
CoUninitialize();
142-
return Err(format!("Failed to set shortcut path: {hr_set_path:#x}"));
143-
}
144-
145-
let hr_set_show = shell_link_ref.SetShowCmd(SW_SHOW);
146-
if !SUCCEEDED(hr_set_show) {
147-
CoUninitialize();
148-
return Err(format!("Failed to set show command: {hr_set_show:#x}"));
149-
}
150-
151-
// Get the IPersistFile interface
152-
let mut persist_file: *mut IPersistFile = ptr::null_mut();
153-
let hr_query = shell_link_ref.QueryInterface(
154-
&IPersistFile::uuidof(),
155-
&mut persist_file as *mut _ as *mut _,
156-
);
157-
158-
if !SUCCEEDED(hr_query) {
159-
CoUninitialize();
160-
return Err(format!(
161-
"Failed to get IPersistFile interface: {hr_query:#x}"
162-
));
163-
}
164-
165-
// Convert shortcut path to wide string before using persist_file
166-
let wide_shortcut_path: Vec<u16> = match shortcut_path.to_str() {
167-
Some(path) => path.encode_utf16().chain(std::iter::once(0)).collect(),
168-
None => {
169-
CoUninitialize();
170-
return Err("Failed to convert shortcut path to string".to_string());
171-
}
172-
};
173-
174-
if !persist_file.is_null() {
175-
let persist_file_guard = PersistFileGuard(persist_file);
176-
177-
// Save the shortcut
178-
let hr_save = {
179-
persist_file_guard.with(|pf| (*pf).Save(wide_shortcut_path.as_ptr(), 1))?
180-
};
181-
182-
if !SUCCEEDED(hr_save) {
183-
CoUninitialize();
184-
return Err(format!("Failed to save shortcut: {hr_save:#x}"));
185-
}
186-
}
187-
} else {
86+
if !SUCCEEDED(hr) || shell_link.is_null() {
18887
CoUninitialize();
18988
return Err(format!("Failed to create shell link: {hr:#x}"));
19089
}
19190

192-
// Uninitialize COM
91+
let hr_set_path = (*shell_link).SetPath(wide_exe_path.as_ptr());
92+
if !SUCCEEDED(hr_set_path) {
93+
(*shell_link).Release();
94+
CoUninitialize();
95+
return Err(format!("Failed to set shortcut path: {hr_set_path:#x}"));
96+
}
97+
98+
let hr_set_show = (*shell_link).SetShowCmd(SW_SHOW);
99+
if !SUCCEEDED(hr_set_show) {
100+
(*shell_link).Release();
101+
CoUninitialize();
102+
return Err(format!("Failed to set show command: {hr_set_show:#x}"));
103+
}
104+
105+
let mut persist_file: *mut IPersistFile = ptr::null_mut();
106+
let hr_query = (*shell_link).QueryInterface(
107+
&IPersistFile::uuidof(),
108+
&mut persist_file as *mut _ as *mut _,
109+
);
110+
111+
if !SUCCEEDED(hr_query) || persist_file.is_null() {
112+
(*shell_link).Release();
113+
CoUninitialize();
114+
return Err(format!(
115+
"Failed to get IPersistFile interface: {hr_query:#x}"
116+
));
117+
}
118+
119+
let hr_save = (*persist_file).Save(wide_shortcut_path.as_ptr(), 1);
120+
if !SUCCEEDED(hr_save) {
121+
(*persist_file).Release();
122+
(*shell_link).Release();
123+
CoUninitialize();
124+
return Err(format!("Failed to save shortcut: {hr_save:#x}"));
125+
}
126+
127+
(*persist_file).Release();
128+
(*shell_link).Release();
193129
CoUninitialize();
194130
}
195131

0 commit comments

Comments
 (0)