summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-10-23 14:45:58 +0200
committerDavid Lönnhager <david.l@mullvad.net>2020-10-23 14:45:58 +0200
commit64f6c93f0c6a19647e8b656cdfa4126da3563ac0 (patch)
tree899147c822da4922ba64cbc53d9003ad4e1be4d1
parentd8157467bf48e81e91ee360033bd78e938ecec8c (diff)
parent1004445070cd67c610b79ac1f37c0ca42b070d6c (diff)
downloadmullvadvpn-64f6c93f0c6a19647e8b656cdfa4126da3563ac0.tar.xz
mullvadvpn-64f6c93f0c6a19647e8b656cdfa4126da3563ac0.zip
Merge branch 'fix-log-encoding'
-rw-r--r--CHANGELOG.md3
-rw-r--r--talpid-core/Cargo.toml2
-rw-r--r--talpid-core/src/logging/windows.rs45
3 files changed, 47 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a14e60aaba..ad8a93a850 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -55,6 +55,9 @@ Line wrap the file at 100 chars. Th
settings tile.
- Fix app starting by itself sometimes.
+#### Windows
+- Fix log output encoding for Windows modules.
+
### Security
- Restore the last target state if the daemon crashes. Previously, if auto-connect and
"Always require VPN" were disabled, the service would reset the firewall upon starting back up,
diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml
index eafceb2854..7a38c982ab 100644
--- a/talpid-core/Cargo.toml
+++ b/talpid-core/Cargo.toml
@@ -72,7 +72,7 @@ tun = "0.5"
[target.'cfg(windows)'.dependencies]
widestring = "0.4"
winreg = { version = "0.7", features = ["transactions"] }
-winapi = { version = "0.3.6", features = ["handleapi", "ifdef", "libloaderapi", "netioapi", "synchapi", "winbase", "winuser"] }
+winapi = { version = "0.3.6", features = ["handleapi", "ifdef", "libloaderapi", "netioapi", "stringapiset", "synchapi", "winbase", "winuser"] }
socket2 = "0.3"
pnet_packet = "0.26"
diff --git a/talpid-core/src/logging/windows.rs b/talpid-core/src/logging/windows.rs
index 97d6a47b0d..c853d3cd9d 100644
--- a/talpid-core/src/logging/windows.rs
+++ b/talpid-core/src/logging/windows.rs
@@ -1,5 +1,6 @@
use libc::{c_char, c_void};
-use std::ffi::CStr;
+use std::{ffi::CStr, io, ptr};
+use winapi::um::{stringapiset::MultiByteToWideChar, winnls::CP_ACP};
/// Logging callback type.
pub type LogSink = extern "system" fn(level: log::Level, msg: *const c_char, context: *mut c_void);
@@ -17,7 +18,13 @@ pub extern "system" fn log_sink(level: log::Level, msg: *const c_char, context:
unsafe { CStr::from_ptr(context as *const _).to_string_lossy() }
};
- let managed_msg = unsafe { CStr::from_ptr(msg).to_string_lossy() };
+ let mb_string = unsafe { CStr::from_ptr(msg) };
+
+ let managed_msg = match multibyte_to_wide(mb_string, CP_ACP) {
+ Ok(wide_str) => String::from_utf16_lossy(&wide_str),
+ // Best effort:
+ Err(_) => mb_string.to_string_lossy().into_owned(),
+ };
log::logger().log(
&log::Record::builder()
@@ -28,3 +35,37 @@ pub extern "system" fn log_sink(level: log::Level, msg: *const c_char, context:
);
}
}
+
+fn multibyte_to_wide(mb_string: &CStr, codepage: u32) -> Result<Vec<u16>, io::Error> {
+ if unsafe { *mb_string.as_ptr() } == 0 {
+ return Ok(vec![]);
+ }
+
+ let wc_size =
+ unsafe { MultiByteToWideChar(codepage, 0, mb_string.as_ptr(), -1, ptr::null_mut(), 0) };
+
+ if wc_size == 0 {
+ return Err(io::Error::last_os_error());
+ }
+
+ let mut wc_buffer = Vec::with_capacity(wc_size as usize);
+
+ let chars_written = unsafe {
+ MultiByteToWideChar(
+ codepage,
+ 0,
+ mb_string.as_ptr(),
+ -1,
+ wc_buffer.as_mut_ptr(),
+ wc_size,
+ )
+ };
+
+ if chars_written == 0 {
+ return Err(io::Error::last_os_error());
+ }
+
+ unsafe { wc_buffer.set_len((chars_written - 1) as usize) };
+
+ Ok(wc_buffer)
+}