I think Rust would be much more maintainable than C++.
I asked ChatGPT to convert the existing C++ to Rust. That may be a good starting point:
extern crate com;
use com::{com_interface, ComRc, ComItf};
use std::ffi::OsString;
use std::io::{self, Write};
use winapi::{LPWSTR, MAX_PATH, WPSTYLE_SPAN, WPSTYLE_CENTER, WPSTYLE_TILE, WPSTYLE_STRETCH, WPSTYLE_KEEPASPECT};
#[com_interface("6D5140C1-7436-11CE-8034-00AA006009FA")]
pub trait IActiveDesktop: ComItf {
fn GetWallpaper(&self, wp: LPWSTR, len: i32, flags: i32) -> HRESULT;
fn SetWallpaper(&self, wp: LPWSTR, flags: i32) -> HRESULT;
fn SetWallpaperOptions(&self, opts: &WALLPAPEROPT, flags: i32) -> HRESULT;
fn ApplyChanges(&self, flags: i32) -> HRESULT;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct WALLPAPEROPT {
dwSize: u32,
dwStyle: i32,
}
fn get_wallpaper(sz_wallpaper: &mut [u16]) -> io::Result<()> {
unsafe {
let result = CoInitialize(std::ptr::null_mut());
if result != S_OK {
return Err(io::Error::new(
io::ErrorKind::Other,
"Failed to initialize COM",
));
}
let mut p_desk: *mut IActiveDesktop = std::ptr::null_mut();
let hr = CoCreateInstance(
&CLSID_ActiveDesktop,
std::ptr::null_mut(),
CLSCTX_INPROC_SERVER,
&IID_IActiveDesktop,
&mut p_desk as *mut *mut IActiveDesktop as *mut *mut std::ffi::c_void,
);
if hr != S_OK {
return Err(io::Error::new(
io::ErrorKind::Other,
"Failed to get the desktop wallpaper",
));
}
(*p_desk).GetWallpaper(sz_wallpaper.as_mut_ptr(), MAX_PATH, 0);
(*p_desk).Release();
CoFreeUnusedLibraries();
CoUninitialize();
}
Ok(())
}
fn set_wallpaper(full_path: &[u16], wp_style: i32) -> io::Result<()> {
unsafe {
let result = CoInitialize(std::ptr::null_mut());
if result != S_OK {
return Err(io::Error::new(
io::ErrorKind::Other,
"Failed to initialize COM",
));
}
let mut p_desk: *mut IActiveDesktop = std::ptr::null_mut();
let hr = CoCreateInstance(
&CLSID_ActiveDesktop,
std::ptr::null_mut(),