@@ -17,12 +17,15 @@ fn reg_key() -> io::Result<RegKey> {
17
17
// let subkey_path_release = "SOFTWARE\\450699d2-1c81-5ee5-aec6-08dddb7af9d7"
18
18
19
19
// the client saves the path to the executable to hklm/software/Clients/Mail/tutanota/EXEPath
20
+ // or hkcu/software/Clients/Mail/tutanota/EXEPath
20
21
// that key must be there, otherwise windows couldn't have called this DLL because
21
22
// the path to it is next to it under DLLPath.
22
23
23
24
let hklm = RegKey :: predef ( HKEY_LOCAL_MACHINE ) ;
25
+ let hkcu = RegKey :: predef ( HKEY_CURRENT_USER ) ;
26
+ let subk = "SOFTWARE\\ Clients\\ Mail\\ tutanota" ;
24
27
// if this fails, the client is not installed correctly or the registry is borked.
25
- hklm. open_subkey ( "SOFTWARE \\ Clients \\ Mail \\ tutanota" )
28
+ hkcu . open_subkey ( subk ) . or_else ( |_| hklm. open_subkey ( subk ) )
26
29
}
27
30
28
31
/// access the registry to try and get
@@ -38,20 +41,32 @@ pub fn client_path() -> io::Result<OsString> {
38
41
#[ cfg( not( test) ) ]
39
42
fn log_path ( ) -> io:: Result < OsString > {
40
43
let tutanota_key = reg_key ( ) ?;
41
- tutanota_key. get_value ( "LOGPath" )
44
+ let log_dir: String = tutanota_key. get_value ( "LOGPath" ) ?;
45
+ replace_profile ( log_dir)
42
46
}
43
47
44
48
#[ cfg( test) ]
45
49
fn log_path ( ) -> io:: Result < OsString > {
46
50
Ok ( OsString :: from ( "C:\\ some\\ weird\\ path" ) )
47
51
}
48
52
53
+ /// replace the %USERPROFILE% placeholder in a String with
54
+ /// the value of the USERPROFILE env variable
55
+ fn replace_profile ( val : String ) -> io:: Result < OsString > {
56
+ let profile =
57
+ std:: env:: var ( "USERPROFILE" ) . map_err ( |_e| io:: Error :: from ( io:: ErrorKind :: NotFound ) ) ?;
58
+ Ok ( OsString :: from (
59
+ val. replace ( "%USERPROFILE%" , profile. as_str ( ) ) ,
60
+ ) )
61
+ }
62
+
49
63
/// retrieve the configured tmp dir from the registry and
50
64
/// try to ensure the directory is there.
51
65
#[ cfg( not( test) ) ]
52
66
pub fn tmp_path ( ) -> io:: Result < OsString > {
53
67
let tutanota_key = reg_key ( ) ?;
54
- let tmp_dir = tutanota_key. get_value ( "TMPPath" ) ?;
68
+ let tmp_dir: String = tutanota_key. get_value ( "TMPPath" ) ?;
69
+ let tmp_dir = replace_profile ( tmp_dir) ?;
55
70
fs:: create_dir_all ( & tmp_dir) ?;
56
71
Ok ( tmp_dir)
57
72
}
@@ -140,6 +155,8 @@ pub fn current_time_formatted() -> String {
140
155
141
156
#[ cfg( test) ]
142
157
mod test {
158
+ use crate :: environment:: replace_profile;
159
+
143
160
#[ test]
144
161
fn sha_head_works ( ) {
145
162
use crate :: environment:: sha_head;
@@ -150,4 +167,19 @@ mod test {
150
167
assert_eq ! ( "e3b0" , out) ;
151
168
assert_eq ! ( 4 , out. capacity( ) ) ;
152
169
}
170
+
171
+ #[ test]
172
+ fn replace_profile_works ( ) {
173
+ let var = std:: env:: var ( "USERPROFILE" ) ;
174
+ std:: env:: set_var ( "USERPROFILE" , "C:\\ meck" ) ;
175
+ assert_eq ! (
176
+ "C:\\ meck\\ a\\ file.txt" ,
177
+ replace_profile( "%USERPROFILE%\\ a\\ file.txt" . to_owned( ) ) . unwrap( )
178
+ ) ;
179
+ std:: env:: remove_var ( "USERPROFILE" ) ;
180
+ assert ! ( replace_profile( "%USERPROFILE%\\ a\\ file.txt" . to_owned( ) ) . is_err( ) ) ;
181
+ if var. is_ok ( ) {
182
+ std:: env:: set_var ( "USERPROFILE" , var. unwrap ( ) ) ;
183
+ }
184
+ }
153
185
}
0 commit comments