@@ -51,6 +51,32 @@ 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 Drop for ShellLinkGuard {
58+ fn drop ( & mut self ) {
59+ unsafe {
60+ if !self . 0 . is_null ( ) {
61+ ( * self . 0 ) . Release ( ) ;
62+ }
63+ }
64+ }
65+ }
66+
67+ // RAII wrapper for IPersistFile
68+ struct PersistFileGuard ( * mut IPersistFile ) ;
69+
70+ impl Drop for PersistFileGuard {
71+ fn drop ( & mut self ) {
72+ unsafe {
73+ if !self . 0 . is_null ( ) {
74+ ( * self . 0 ) . Release ( ) ;
75+ }
76+ }
77+ }
78+ }
79+
5480 unsafe {
5581 // Initialize COM
5682 CoInitializeEx ( ptr:: null_mut ( ) , COINIT_APARTMENTTHREADED ) ;
@@ -66,68 +92,61 @@ pub fn enable_autostart(app_handle: &AppHandle) -> Result<(), String> {
6692 ) ;
6793
6894 if SUCCEEDED ( hr) && !shell_link. is_null ( ) {
95+ let shell_link = ShellLinkGuard ( shell_link) ;
96+
6997 // Set the path to the executable
7098 let wide_path: Vec < u16 > = match executable_path. to_str ( ) {
7199 Some ( path) => path. encode_utf16 ( ) . chain ( std:: iter:: once ( 0 ) ) . collect ( ) ,
72100 None => {
73- ( * shell_link) . Release ( ) ;
74101 CoUninitialize ( ) ;
75102 return Err ( "Failed to convert path to string" . to_string ( ) ) ;
76103 }
77104 } ;
78- let hr_set_path = ( * shell_link) . SetPath ( wide_path. as_ptr ( ) ) ;
105+ let hr_set_path = ( * shell_link. 0 ) . SetPath ( wide_path. as_ptr ( ) ) ;
79106 if !SUCCEEDED ( hr_set_path) {
80- ( * shell_link) . Release ( ) ;
81107 CoUninitialize ( ) ;
82108 return Err ( format ! ( "Failed to set shortcut path: {hr_set_path:#x}" ) ) ;
83109 }
84110
85- let hr_set_show = ( * shell_link) . SetShowCmd ( SW_SHOW ) ;
111+ let hr_set_show = ( * shell_link. 0 ) . SetShowCmd ( SW_SHOW ) ;
86112 if !SUCCEEDED ( hr_set_show) {
87- ( * shell_link) . Release ( ) ;
88113 CoUninitialize ( ) ;
89114 return Err ( format ! ( "Failed to set show command: {hr_set_show:#x}" ) ) ;
90115 }
91116
92117 // Get the IPersistFile interface
93118 let mut persist_file: * mut IPersistFile = ptr:: null_mut ( ) ;
94- let hr_query = ( * shell_link) . QueryInterface (
119+ let hr_query = ( * shell_link. 0 ) . QueryInterface (
95120 & IPersistFile :: uuidof ( ) ,
96121 & mut persist_file as * mut _ as * mut _ ,
97122 ) ;
98123
99124 if !SUCCEEDED ( hr_query) {
100- ( * shell_link) . Release ( ) ;
101125 CoUninitialize ( ) ;
102126 return Err ( format ! (
103127 "Failed to get IPersistFile interface: {hr_query:#x}"
104128 ) ) ;
105129 }
106130
107131 if !persist_file. is_null ( ) {
132+ let persist_file = PersistFileGuard ( persist_file) ;
133+
108134 // Convert shortcut path to wide string
109135 let wide_shortcut_path: Vec < u16 > = match shortcut_path. to_str ( ) {
110136 Some ( path) => path. encode_utf16 ( ) . chain ( std:: iter:: once ( 0 ) ) . collect ( ) ,
111137 None => {
112- ( * persist_file) . Release ( ) ;
113- ( * shell_link) . Release ( ) ;
114138 CoUninitialize ( ) ;
115139 return Err ( "Failed to convert shortcut path to string" . to_string ( ) ) ;
116140 }
117141 } ;
118142
119143 // Save the shortcut
120- let hr_save = ( * persist_file) . Save ( wide_shortcut_path. as_ptr ( ) , 1 ) ;
144+ let hr_save = ( * persist_file. 0 ) . Save ( wide_shortcut_path. as_ptr ( ) , 1 ) ;
121145 if !SUCCEEDED ( hr_save) {
122- ( * persist_file) . Release ( ) ;
123- ( * shell_link) . Release ( ) ;
124146 CoUninitialize ( ) ;
125147 return Err ( format ! ( "Failed to save shortcut: {hr_save:#x}" ) ) ;
126148 }
127- ( * persist_file) . Release ( ) ;
128149 }
129-
130- ( * shell_link) . Release ( ) ;
131150 } else {
132151 CoUninitialize ( ) ;
133152 return Err ( format ! ( "Failed to create shell link: {hr:#x}" ) ) ;
0 commit comments