diff options
| author | David Lönnhager <david.l@mullvad.net> | 2022-09-01 10:56:14 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2022-09-01 10:56:14 +0200 |
| commit | 47875ccb743e4ab7d89c8da0edf3bb27a484559b (patch) | |
| tree | 500a33559a4b1d36bc7ecd1376b4533c528939be | |
| parent | 5ade6d8c5c346d8ab5fdd559a4d2b27956d7176c (diff) | |
| parent | 44478a1c7276d2bf57605829bde8a0e237243f1a (diff) | |
| download | mullvadvpn-47875ccb743e4ab7d89c8da0edf3bb27a484559b.tar.xz mullvadvpn-47875ccb743e4ab7d89c8da0edf3bb27a484559b.zip | |
Merge branch 'mig-mullvad-windows-sys'
| -rw-r--r-- | Cargo.lock | 12 | ||||
| -rw-r--r-- | mullvad-cli/Cargo.toml | 7 | ||||
| -rw-r--r-- | mullvad-cli/build.rs | 11 | ||||
| -rw-r--r-- | mullvad-daemon/Cargo.toml | 22 | ||||
| -rw-r--r-- | mullvad-daemon/build.rs | 11 | ||||
| -rw-r--r-- | mullvad-daemon/src/exception_logging/win.rs | 65 | ||||
| -rw-r--r-- | mullvad-daemon/src/migrations/mod.rs | 25 | ||||
| -rw-r--r-- | mullvad-daemon/src/system_service.rs | 21 | ||||
| -rw-r--r-- | mullvad-problem-report/Cargo.toml | 7 | ||||
| -rw-r--r-- | mullvad-problem-report/build.rs | 11 | ||||
| -rw-r--r-- | mullvad-setup/Cargo.toml | 21 | ||||
| -rw-r--r-- | mullvad-setup/src/daemon_paths.rs | 103 | ||||
| -rw-r--r-- | talpid-openvpn-plugin/Cargo.toml | 7 | ||||
| -rw-r--r-- | talpid-openvpn-plugin/build.rs | 11 | ||||
| -rw-r--r-- | talpid-platform-metadata/Cargo.toml | 10 | ||||
| -rw-r--r-- | talpid-platform-metadata/src/windows.rs | 19 |
16 files changed, 208 insertions, 155 deletions
diff --git a/Cargo.lock b/Cargo.lock index ae54ff53cc..f782e783e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1564,7 +1564,7 @@ dependencies = [ "serde", "talpid-types", "tokio", - "winapi", + "windows-sys", "winres", ] @@ -1609,6 +1609,7 @@ dependencies = [ "uuid", "winapi", "windows-service", + "windows-sys", "winres", ] @@ -1693,7 +1694,7 @@ dependencies = [ "talpid-types", "tokio", "uuid", - "winapi", + "windows-sys", "winres", ] @@ -1736,8 +1737,7 @@ dependencies = [ "talpid-types", "tokio", "widestring 0.5.1", - "winapi", - "winres", + "windows-sys", ] [[package]] @@ -3153,7 +3153,7 @@ dependencies = [ "tonic", "tonic-build", "tower", - "winapi", + "windows-sys", "winres", ] @@ -3163,7 +3163,7 @@ version = "0.1.0" dependencies = [ "rs-release", "talpid-dbus", - "winapi", + "windows-sys", ] [[package]] diff --git a/mullvad-cli/Cargo.toml b/mullvad-cli/Cargo.toml index 73fc3a8d79..f817e83de6 100644 --- a/mullvad-cli/Cargo.toml +++ b/mullvad-cli/Cargo.toml @@ -34,7 +34,12 @@ clap_complete = { version = "3.0" } [target.'cfg(windows)'.build-dependencies] winres = "0.1" -winapi = "0.3" + +[target.'cfg(windows)'.build-dependencies.windows-sys] +version = "0.36.1" +features = [ + "Win32_System_SystemServices", +] [package.metadata.winres] ProductName = "Mullvad VPN" diff --git a/mullvad-cli/build.rs b/mullvad-cli/build.rs index 4c19603b76..b2cc9c3d9a 100644 --- a/mullvad-cli/build.rs +++ b/mullvad-cli/build.rs @@ -1,5 +1,10 @@ use std::{env, fs, path::PathBuf}; +#[cfg(windows)] +fn make_lang_id(p: u16, s: u16) -> u16 { + (s << 10) | p +} + fn main() { let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); let product_version = env!("CARGO_PKG_VERSION").replacen(".0", "", 1); @@ -10,9 +15,9 @@ fn main() { let mut res = winres::WindowsResource::new(); res.set("ProductVersion", &product_version); res.set_icon("../dist-assets/icon.ico"); - res.set_language(winapi::um::winnt::MAKELANGID( - winapi::um::winnt::LANG_ENGLISH, - winapi::um::winnt::SUBLANG_ENGLISH_US, + res.set_language(make_lang_id( + windows_sys::Win32::System::SystemServices::LANG_ENGLISH as u16, + windows_sys::Win32::System::SystemServices::SUBLANG_ENGLISH_US as u16, )); res.compile().expect("Unable to generate windows resources"); } diff --git a/mullvad-daemon/Cargo.toml b/mullvad-daemon/Cargo.toml index e05c2e7ca7..6a811659c5 100644 --- a/mullvad-daemon/Cargo.toml +++ b/mullvad-daemon/Cargo.toml @@ -52,12 +52,30 @@ simple-signal = "1.1" ctrlc = "3.0" duct = "0.13" windows-service = "0.5.0" -winapi = { version = "0.3", features = ["errhandlingapi", "handleapi", "libloaderapi", "ntlsa", "synchapi", "tlhelp32", "winbase", "winerror", "winuser"] } +winapi = { version = "0.3", features = ["winnt", "excpt"] } dirs-next = "2.0" +[target.'cfg(windows)'.dependencies.windows-sys] +version = "0.36.1" +features = [ + "Win32_Foundation", + "Win32_Security", + "Win32_Security_Authorization", + "Win32_Security_Authentication_Identity", + "Win32_System_Diagnostics_Debug", + "Win32_System_Kernel", + "Win32_System_Memory", + "Win32_System_Threading", +] + [target.'cfg(windows)'.build-dependencies] winres = "0.1" -winapi = "0.3" + +[target.'cfg(windows)'.build-dependencies.windows-sys] +version = "0.36.1" +features = [ + "Win32_System_SystemServices", +] [package.metadata.winres] ProductName = "Mullvad VPN" diff --git a/mullvad-daemon/build.rs b/mullvad-daemon/build.rs index c2571ca799..5e09506171 100644 --- a/mullvad-daemon/build.rs +++ b/mullvad-daemon/build.rs @@ -1,5 +1,10 @@ use std::{env, fs, path::PathBuf, process::Command}; +#[cfg(windows)] +fn make_lang_id(p: u16, s: u16) -> u16 { + (s << 10) | p +} + fn main() { let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); @@ -12,9 +17,9 @@ fn main() { let mut res = winres::WindowsResource::new(); res.set("ProductVersion", &product_version); res.set_icon("../dist-assets/icon.ico"); - res.set_language(winapi::um::winnt::MAKELANGID( - winapi::um::winnt::LANG_ENGLISH, - winapi::um::winnt::SUBLANG_ENGLISH_US, + res.set_language(make_lang_id( + windows_sys::Win32::System::SystemServices::LANG_ENGLISH as u16, + windows_sys::Win32::System::SystemServices::SUBLANG_ENGLISH_US as u16, )); println!("cargo:rerun-if-env-changed=MULLVAD_ADD_MANIFEST"); if env::var("MULLVAD_ADD_MANIFEST") diff --git a/mullvad-daemon/src/exception_logging/win.rs b/mullvad-daemon/src/exception_logging/win.rs index c6e2422398..bada89af8e 100644 --- a/mullvad-daemon/src/exception_logging/win.rs +++ b/mullvad-daemon/src/exception_logging/win.rs @@ -1,3 +1,4 @@ +use libc::c_void; use mullvad_paths::log_dir; use std::{ borrow::Cow, @@ -10,24 +11,21 @@ use std::{ }; use talpid_types::ErrorExt; use winapi::{ - ctypes::c_void, - shared::{ - minwindef::{BOOL, BYTE, DWORD, FALSE}, - winerror::ERROR_NO_MORE_FILES, - }, - um::{ - errhandlingapi::SetUnhandledExceptionFilter, - handleapi::{CloseHandle, INVALID_HANDLE_VALUE}, - processthreadsapi::{GetCurrentProcess, GetCurrentProcessId, GetCurrentThreadId}, - tlhelp32::{ - CreateToolhelp32Snapshot, Module32First, Module32Next, MODULEENTRY32, TH32CS_SNAPMODULE, - }, - winnt::{ - CONTEXT, CONTEXT_CONTROL, CONTEXT_INTEGER, CONTEXT_SEGMENTS, EXCEPTION_POINTERS, - EXCEPTION_RECORD, HANDLE, LONG, + um::winnt::{CONTEXT_CONTROL, CONTEXT_INTEGER, CONTEXT_SEGMENTS}, + vc::excpt::EXCEPTION_EXECUTE_HANDLER, +}; +use windows_sys::Win32::{ + Foundation::{CloseHandle, BOOL, ERROR_NO_MORE_FILES, HANDLE, INVALID_HANDLE_VALUE}, + System::{ + Diagnostics::{ + Debug::{SetUnhandledExceptionFilter, CONTEXT, EXCEPTION_POINTERS, EXCEPTION_RECORD}, + ToolHelp::{ + CreateToolhelp32Snapshot, Module32First, Module32Next, MODULEENTRY32, + TH32CS_SNAPMODULE, + }, }, + Threading::{GetCurrentProcess, GetCurrentProcessId, GetCurrentThreadId}, }, - vc::excpt::EXCEPTION_EXECUTE_HANDLER, }; /// Minidump file name @@ -44,7 +42,7 @@ enum MINIDUMP_TYPE { #[derive(Clone, Copy, Debug)] #[allow(non_snake_case)] struct MINIDUMP_EXCEPTION_INFORMATION { - ThreadId: DWORD, + ThreadId: u32, ExceptionPointers: *const EXCEPTION_POINTERS, ClientPointers: BOOL, } @@ -54,7 +52,7 @@ extern "system" { /// Store exception information, stack trace, etc. in a file. fn MiniDumpWriteDump( hProcess: HANDLE, - ProcessId: DWORD, + ProcessId: u32, hFile: HANDLE, DumpType: MINIDUMP_TYPE, ExceptionParam: *const MINIDUMP_EXCEPTION_INFORMATION, @@ -95,20 +93,20 @@ fn generate_minidump( let exception_parameters = MINIDUMP_EXCEPTION_INFORMATION { ThreadId: thread_id, ExceptionPointers: exception_pointers, - ClientPointers: FALSE, + ClientPointers: 0, }; if unsafe { MiniDumpWriteDump( process, process_id, - handle, + handle as HANDLE, MINIDUMP_TYPE::MiniDumpNormal, &exception_parameters, ptr::null(), ptr::null(), ) - } == FALSE + } == 0 { return Err(MinidumpError::GenerateError(io::Error::last_os_error())); } @@ -122,7 +120,7 @@ pub fn enable() { } fn exception_code_to_string(value: &EXCEPTION_RECORD) -> Option<Cow<'_, str>> { - use winapi::um::minwinbase::*; + use windows_sys::Win32::Foundation::*; let name = match value.ExceptionCode { EXCEPTION_ACCESS_VIOLATION => "EXCEPTION_ACCESS_VIOLATION", EXCEPTION_IN_PAGE_ERROR => "EXCEPTION_IN_PAGE_ERROR", @@ -163,10 +161,10 @@ fn exception_code_to_string(value: &EXCEPTION_RECORD) -> Option<Cow<'_, str>> { } } -extern "system" fn logging_exception_filter(info: *mut EXCEPTION_POINTERS) -> LONG { +unsafe extern "system" fn logging_exception_filter(info: *const EXCEPTION_POINTERS) -> i32 { // SAFETY: Windows gives us valid pointers - let info: &EXCEPTION_POINTERS = unsafe { &*info }; - let record: &EXCEPTION_RECORD = unsafe { &*info.ExceptionRecord }; + let info: &EXCEPTION_POINTERS = &*info; + let record: &EXCEPTION_RECORD = &*info.ExceptionRecord; // Generate minidump let dump_path = match log_dir() { @@ -190,7 +188,7 @@ extern "system" fn logging_exception_filter(info: *mut EXCEPTION_POINTERS) -> LO } // Log exception information - let context_info = get_context_info(unsafe { &*info.ContextRecord }); + let context_info = get_context_info(&*info.ContextRecord); let error_str = match exception_code_to_string(record) { Some(errstr) => errstr, @@ -300,8 +298,8 @@ fn find_address_module(address: *mut c_void) -> io::Result<Option<ModuleInfo>> { for module in snap.modules() { let module = module?; let module_end_address = unsafe { module.base_address.offset(module.size as isize) }; - if (address as *const BYTE) >= module.base_address - && (address as *const BYTE) < module_end_address + if (address as *const u8) >= module.base_address + && (address as *const u8) < module_end_address { return Ok(Some(module)); } @@ -312,7 +310,7 @@ fn find_address_module(address: *mut c_void) -> io::Result<Option<ModuleInfo>> { struct ModuleInfo { name: String, - base_address: *const BYTE, + base_address: *const u8, size: usize, } @@ -321,7 +319,7 @@ struct ProcessSnapshot { } impl ProcessSnapshot { - fn new(flags: DWORD, process_id: DWORD) -> io::Result<ProcessSnapshot> { + fn new(flags: u32, process_id: u32) -> io::Result<ProcessSnapshot> { let snap = unsafe { CreateToolhelp32Snapshot(flags, process_id) }; if snap == INVALID_HANDLE_VALUE { @@ -366,7 +364,7 @@ impl Iterator for ProcessSnapshotModules<'_> { fn next(&mut self) -> Option<io::Result<ModuleInfo>> { if self.iter_started { - if unsafe { Module32Next(self.snapshot.handle(), &mut self.temp_entry) } == FALSE { + if unsafe { Module32Next(self.snapshot.handle(), &mut self.temp_entry) } == 0 { let last_error = io::Error::last_os_error(); return if last_error.raw_os_error().unwrap() as u32 == ERROR_NO_MORE_FILES { @@ -376,13 +374,14 @@ impl Iterator for ProcessSnapshotModules<'_> { }; } } else { - if unsafe { Module32First(self.snapshot.handle(), &mut self.temp_entry) } == FALSE { + if unsafe { Module32First(self.snapshot.handle(), &mut self.temp_entry) } == 0 { return Some(Err(io::Error::last_os_error())); } self.iter_started = true; } - let cstr = unsafe { CStr::from_ptr(&self.temp_entry.szModule[0] as *const c_char) }; + let cstr_ref = &self.temp_entry.szModule[0]; + let cstr = unsafe { CStr::from_ptr(cstr_ref as *const u8 as *const c_char) }; Some(Ok(ModuleInfo { name: cstr.to_string_lossy().into_owned(), base_address: self.temp_entry.modBaseAddr, diff --git a/mullvad-daemon/src/migrations/mod.rs b/mullvad-daemon/src/migrations/mod.rs index b4a1d18979..243b6d0f85 100644 --- a/mullvad-daemon/src/migrations/mod.rs +++ b/mullvad-daemon/src/migrations/mod.rs @@ -199,20 +199,19 @@ mod windows { use std::{ffi::OsStr, io, os::windows::ffi::OsStrExt, path::Path, ptr}; use talpid_types::ErrorExt; use tokio::fs; - use winapi::{ - shared::{minwindef::TRUE, winerror::ERROR_SUCCESS}, - um::{ - accctrl::{SE_FILE_OBJECT, SE_OBJECT_TYPE}, - aclapi::GetNamedSecurityInfoW, - securitybaseapi::IsWellKnownSid, - winbase::LocalFree, - winnt::{ - WinBuiltinAdministratorsSid, WinLocalSystemSid, OWNER_SECURITY_INFORMATION, PSID, - SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SID, WELL_KNOWN_SID_TYPE, - }, + use windows_sys::Win32::{ + Foundation::{ERROR_SUCCESS, HANDLE, PSID}, + Security::{ + Authorization::{GetNamedSecurityInfoW, SE_FILE_OBJECT, SE_OBJECT_TYPE}, + IsWellKnownSid, WinBuiltinAdministratorsSid, WinLocalSystemSid, + OWNER_SECURITY_INFORMATION, SECURITY_DESCRIPTOR, SID, WELL_KNOWN_SID_TYPE, }, + System::Memory::LocalFree, }; + #[allow(non_camel_case_types)] + type SECURITY_INFORMATION = u32; + const MIGRATION_DIRNAME: &str = "windows.old"; const MIGRATE_FILES: [(&str, bool); 3] = [ ("settings.json", true), @@ -382,11 +381,11 @@ mod windows { impl Drop for SecurityInformation { fn drop(&mut self) { - unsafe { LocalFree(self.security_descriptor as *mut _) }; + unsafe { LocalFree(self.security_descriptor as HANDLE) }; } } fn is_well_known_sid(sid: &SID, well_known_sid_type: WELL_KNOWN_SID_TYPE) -> bool { - unsafe { IsWellKnownSid(sid as *const SID as *mut _, well_known_sid_type) == TRUE } + unsafe { IsWellKnownSid(sid as *const SID as *mut _, well_known_sid_type) == 1 } } } diff --git a/mullvad-daemon/src/system_service.rs b/mullvad-daemon/src/system_service.rs index 0b87b4f2b1..bb22f2d04a 100644 --- a/mullvad-daemon/src/system_service.rs +++ b/mullvad-daemon/src/system_service.rs @@ -1,4 +1,5 @@ use crate::cli; +use libc::c_void; use mullvad_daemon::{runtime::new_runtime_builder, DaemonShutdownHandle}; use std::{ env, @@ -12,14 +13,6 @@ use std::{ time::{Duration, Instant}, }; use talpid_types::ErrorExt; -use winapi::{ - ctypes::c_void, - shared::{minwindef::ULONG, ntdef::LUID, ntstatus::STATUS_SUCCESS}, - um::ntlsa::{ - LsaEnumerateLogonSessions, LsaFreeReturnBuffer, LsaGetLogonSessionData, - SECURITY_LOGON_SESSION_DATA, - }, -}; use windows_service::{ service::{ PowerEventParam, Service, ServiceAccess, ServiceAction, ServiceActionType, ServiceControl, @@ -31,6 +24,13 @@ use windows_service::{ service_dispatcher, service_manager::{ServiceManager, ServiceManagerAccess}, }; +use windows_sys::Win32::{ + Foundation::{LUID, STATUS_SUCCESS}, + Security::Authentication::Identity::{ + LsaEnumerateLogonSessions, LsaFreeReturnBuffer, LsaGetLogonSessionData, + SECURITY_LOGON_SESSION_DATA, + }, +}; static SERVICE_NAME: &'static str = "MullvadVPN"; static SERVICE_DISPLAY_NAME: &'static str = "Mullvad VPN Service"; @@ -457,7 +457,7 @@ impl HibernationDetector { } fn is_interactive_session(session_id: u32) -> bool { - let mut logon_session_count: ULONG = 0; + let mut logon_session_count = 0u32; let mut logon_session_list: *mut LUID = ptr::null_mut(); let status = unsafe { LsaEnumerateLogonSessions(&mut logon_session_count, &mut logon_session_list) }; @@ -472,8 +472,7 @@ impl HibernationDetector { for logon in logons { let mut session_data: *mut SECURITY_LOGON_SESSION_DATA = ptr::null_mut(); // SAFETY: `LsaGetLogonSessionData` does not mutate `logon` - let status = - unsafe { LsaGetLogonSessionData(logon as *const _ as *mut _, &mut session_data) }; + let status = unsafe { LsaGetLogonSessionData(logon, &mut session_data) }; if status != STATUS_SUCCESS { log::warn!("LsaGetLogonSessionData() failed, error code: {}", status); continue; diff --git a/mullvad-problem-report/Cargo.toml b/mullvad-problem-report/Cargo.toml index 598abb7596..8dba9f52cf 100644 --- a/mullvad-problem-report/Cargo.toml +++ b/mullvad-problem-report/Cargo.toml @@ -30,7 +30,12 @@ duct = "0.13" [target.'cfg(windows)'.build-dependencies] winres = "0.1" -winapi = "0.3" + +[target.'cfg(windows)'.build-dependencies.windows-sys] +version = "0.36.1" +features = [ + "Win32_System_SystemServices", +] [package.metadata.winres] diff --git a/mullvad-problem-report/build.rs b/mullvad-problem-report/build.rs index 93e8577394..1da519a32e 100644 --- a/mullvad-problem-report/build.rs +++ b/mullvad-problem-report/build.rs @@ -1,5 +1,10 @@ use std::{env, fs, path::PathBuf}; +#[cfg(windows)] +fn make_lang_id(p: u16, s: u16) -> u16 { + (s << 10) | p +} + fn main() { let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); @@ -11,9 +16,9 @@ fn main() { let mut res = winres::WindowsResource::new(); res.set("ProductVersion", &product_version); res.set_icon("../dist-assets/icon.ico"); - res.set_language(winapi::um::winnt::MAKELANGID( - winapi::um::winnt::LANG_ENGLISH, - winapi::um::winnt::SUBLANG_ENGLISH_US, + res.set_language(make_lang_id( + windows_sys::Win32::System::SystemServices::LANG_ENGLISH as u16, + windows_sys::Win32::System::SystemServices::SUBLANG_ENGLISH_US as u16, )); res.compile().expect("Unable to generate windows resources"); } diff --git a/mullvad-setup/Cargo.toml b/mullvad-setup/Cargo.toml index d61322a6cc..8ce7e72c8e 100644 --- a/mullvad-setup/Cargo.toml +++ b/mullvad-setup/Cargo.toml @@ -29,16 +29,15 @@ talpid-core = { path = "../talpid-core" } talpid-types = { path = "../talpid-types" } [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3.6", features = ["securitybaseapi", "impl-default", "impl-debug", "handleapi", "psapi"]} widestring = "0.5" -[target.'cfg(windows)'.build-dependencies] -winres = "0.1" -winapi = "0.3" - -[package.metadata.winres] -ProductName = "Mullvad VPN" -CompanyName = "Mullvad VPN AB" -LegalCopyright = "(c) 2022 Mullvad VPN AB" -InternalName = "mullvad-setup" -OriginalFilename = "mullvad-setup.exe" +[target.'cfg(windows)'.dependencies.windows-sys] +version = "0.36.1" +features = [ + "Win32_Foundation", + "Win32_Security", + "Win32_System_Com", + "Win32_System_ProcessStatus", + "Win32_System_Threading", + "Win32_UI_Shell", +] diff --git a/mullvad-setup/src/daemon_paths.rs b/mullvad-setup/src/daemon_paths.rs index a0a0b8cfba..1a084d7655 100644 --- a/mullvad-setup/src/daemon_paths.rs +++ b/mullvad-setup/src/daemon_paths.rs @@ -6,50 +6,50 @@ use std::{ ptr, }; use widestring::{WideCStr, WideCString}; -use winapi::{ - shared::{ - minwindef::{DWORD, FALSE}, - ntdef::LUID, - winerror::{ERROR_NO_TOKEN, ERROR_SUCCESS, S_OK}, - }, - um::{ - combaseapi::CoTaskMemFree, - handleapi::CloseHandle, - knownfolders::{FOLDERID_LocalAppData, FOLDERID_System}, - processthreadsapi::{GetCurrentThread, OpenProcess, OpenProcessToken, OpenThreadToken}, - psapi::K32EnumProcesses, - securitybaseapi::{AdjustTokenPrivileges, ImpersonateSelf, RevertToSelf}, - shlobj::{SHGetKnownFolderPath, KF_FLAG_DEFAULT}, - shtypes::KNOWNFOLDERID, - winbase::{LookupPrivilegeValueW, QueryFullProcessImageNameW}, - winnt::{ - SecurityImpersonation, HANDLE, LUID_AND_ATTRIBUTES, PROCESS_QUERY_INFORMATION, PWSTR, - SE_PRIVILEGE_ENABLED, TOKEN_ADJUST_PRIVILEGES, TOKEN_DUPLICATE, TOKEN_IMPERSONATE, - TOKEN_PRIVILEGES, TOKEN_QUERY, TOKEN_READ, +use windows_sys::{ + core::{GUID, PWSTR}, + Win32::{ + Foundation::{CloseHandle, ERROR_NO_TOKEN, ERROR_SUCCESS, HANDLE, LUID, S_OK}, + Security::{ + AdjustTokenPrivileges, ImpersonateSelf, LookupPrivilegeValueW, RevertToSelf, + SecurityImpersonation, LUID_AND_ATTRIBUTES, SE_PRIVILEGE_ENABLED, + TOKEN_ADJUST_PRIVILEGES, TOKEN_DUPLICATE, TOKEN_IMPERSONATE, TOKEN_PRIVILEGES, + TOKEN_QUERY, + }, + System::{ + Com::CoTaskMemFree, + ProcessStatus::K32EnumProcesses, + SystemServices::GENERIC_READ, + Threading::{ + GetCurrentThread, OpenProcess, OpenProcessToken, OpenThreadToken, + QueryFullProcessImageNameW, PROCESS_QUERY_INFORMATION, + }, + }, + UI::Shell::{ + FOLDERID_LocalAppData, FOLDERID_System, SHGetKnownFolderPath, KF_FLAG_DEFAULT, }, }, }; pub fn get_mullvad_daemon_settings_path() -> io::Result<PathBuf> { - get_system_service_known_folder(FOLDERID_LocalAppData) + get_system_service_known_folder(&FOLDERID_LocalAppData) .map(|settings| settings.join(mullvad_paths::PRODUCT_NAME)) } /// Get local AppData path for the system service user. Requires elevated privileges to work. /// Useful for deducing the config path for the daemon on Windows when running as a user that /// isn't the system service. -fn get_system_service_known_folder(known_folder_id: KNOWNFOLDERID) -> std::io::Result<PathBuf> { +fn get_system_service_known_folder(known_folder_id: *const GUID) -> std::io::Result<PathBuf> { let system_debug_priv = WideCString::from_str("SeDebugPrivilege").unwrap(); adjust_current_thread_token_privilege(&system_debug_priv, true)?; let known_folder: io::Result<PathBuf> = (|| { - let mut lsass_path = - get_known_folder_path(FOLDERID_System, KF_FLAG_DEFAULT, ptr::null_mut())?; + let mut lsass_path = get_known_folder_path(&FOLDERID_System, KF_FLAG_DEFAULT as u32, 0)?; lsass_path.push("lsass.exe"); let lsass_pid = get_running_process_id_from_name(&lsass_path)?; - let lsass_handle = unsafe { OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, lsass_pid) }; - if lsass_handle.is_null() { + let lsass_handle = unsafe { OpenProcess(PROCESS_QUERY_INFORMATION, 0, lsass_pid) }; + if lsass_handle == 0 { return Err(io::Error::new( io::ErrorKind::NotFound, format!( @@ -59,23 +59,24 @@ fn get_system_service_known_folder(known_folder_id: KNOWNFOLDERID) -> std::io::R )); } - let mut lsass_token = ptr::null_mut(); + let mut lsass_token: HANDLE = 0; let status = unsafe { OpenProcessToken( lsass_handle, - TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, + GENERIC_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &mut lsass_token, ) }; unsafe { CloseHandle(lsass_handle) }; - if status == FALSE { + if status == 0 { return Err(io::Error::new( io::ErrorKind::PermissionDenied, format!("Failed to open process token, failure code {}", status), )); } - let known_folder = get_known_folder_path(known_folder_id, KF_FLAG_DEFAULT, lsass_token); + let known_folder = + get_known_folder_path(known_folder_id, KF_FLAG_DEFAULT as u32, lsass_token); unsafe { CloseHandle(lsass_token) }; known_folder @@ -84,7 +85,7 @@ fn get_system_service_known_folder(known_folder_id: KNOWNFOLDERID) -> std::io::R if let Err(err) = adjust_current_thread_token_privilege(&system_debug_priv, false) { eprintln!("Failed to drop system privileges: {}", err); } - if unsafe { RevertToSelf() } == FALSE { + if unsafe { RevertToSelf() } == 0 { return Err(io::Error::last_os_error()); } @@ -95,19 +96,19 @@ fn adjust_current_thread_token_privilege( privilege: &WideCString, enable: bool, ) -> std::io::Result<()> { - let mut token_handle: HANDLE = ptr::null_mut(); + let mut token_handle: HANDLE = 0; if unsafe { OpenThreadToken( GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, - FALSE, + 0, &mut token_handle, ) - } == FALSE + } == 0 { let thread_token_error = std::io::Error::last_os_error(); if thread_token_error.raw_os_error() == Some(ERROR_NO_TOKEN as i32) { - if unsafe { ImpersonateSelf(SecurityImpersonation) } == FALSE { + if unsafe { ImpersonateSelf(SecurityImpersonation) } == 0 { return Err(std::io::Error::last_os_error()); } @@ -115,10 +116,10 @@ fn adjust_current_thread_token_privilege( OpenThreadToken( GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, - FALSE, + 0, &mut token_handle, ) - } == FALSE + } == 0 { return Err(std::io::Error::last_os_error()); } @@ -137,11 +138,9 @@ fn adjust_token_privilege( privilege: &WideCString, enable: bool, ) -> std::io::Result<()> { - let mut privilege_luid: LUID = Default::default(); + let mut privilege_luid: LUID = unsafe { mem::zeroed() }; - if unsafe { LookupPrivilegeValueW(ptr::null(), privilege.as_ptr(), &mut privilege_luid) } - == FALSE - { + if unsafe { LookupPrivilegeValueW(ptr::null(), privilege.as_ptr(), &mut privilege_luid) } == 0 { return Err(std::io::Error::last_os_error()); } @@ -155,7 +154,7 @@ fn adjust_token_privilege( let result = unsafe { AdjustTokenPrivileges( token_handle, - FALSE, + 0, &mut privileges, 0, ptr::null_mut(), @@ -165,7 +164,7 @@ fn adjust_token_privilege( // Terrible interface. // Odd 2018 let last_error = std::io::Error::last_os_error(); - if result == FALSE || last_error.raw_os_error() != Some(ERROR_SUCCESS as i32) { + if result == 0 || last_error.raw_os_error() != Some(ERROR_SUCCESS as i32) { return Err(last_error); } @@ -173,12 +172,12 @@ fn adjust_token_privilege( } fn get_known_folder_path( - folder_id: KNOWNFOLDERID, - flags: DWORD, + folder_id: *const GUID, + flags: u32, user_token: HANDLE, ) -> std::io::Result<PathBuf> { let mut folder_path: PWSTR = ptr::null_mut(); - let status = unsafe { SHGetKnownFolderPath(&folder_id, flags, user_token, &mut folder_path) }; + let status = unsafe { SHGetKnownFolderPath(folder_id, flags, user_token, &mut folder_path) }; let result = if status == S_OK { let path = unsafe { WideCStr::from_ptr_str(folder_path) }; Ok(path.to_ustring().to_os_string().into()) @@ -196,7 +195,7 @@ fn get_known_folder_path( /// Find the PID of a process with the given image path. In case of multiple processes matching /// the path, the first one found to match the path will be returned - the ordering of PIDs is /// determined by `K32EnumProcesses`. -fn get_running_process_id_from_name(target_name: &Path) -> io::Result<DWORD> { +fn get_running_process_id_from_name(target_name: &Path) -> io::Result<u32> { let mut num_procs: u32 = 2048; let mut pid_buffer = vec![]; let canonical_target = target_name @@ -204,20 +203,20 @@ fn get_running_process_id_from_name(target_name: &Path) -> io::Result<DWORD> { .unwrap_or(target_name.to_path_buf()); pid_buffer.resize(num_procs as usize, 0); - let bytes_available = num_procs * (mem::size_of::<DWORD>() as u32); + let bytes_available = num_procs * (mem::size_of::<u32>() as u32); let mut bytes_written = 0; if unsafe { K32EnumProcesses(pid_buffer.as_mut_ptr(), bytes_available, &mut bytes_written) } - == FALSE + == 0 { return Err(io::Error::last_os_error()); } - num_procs = bytes_written / (mem::size_of::<DWORD>() as u32); + num_procs = bytes_written / (mem::size_of::<u32>() as u32); pid_buffer.resize(num_procs as usize, 0); for process in pid_buffer { - let process_handle = unsafe { OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process) }; - if process_handle.is_null() { + let process_handle = unsafe { OpenProcess(PROCESS_QUERY_INFORMATION, 0, process) }; + if process_handle == 0 { eprintln!( "Failed to open process {}: {}", process, diff --git a/talpid-openvpn-plugin/Cargo.toml b/talpid-openvpn-plugin/Cargo.toml index 4a11ba59ca..2793869635 100644 --- a/talpid-openvpn-plugin/Cargo.toml +++ b/talpid-openvpn-plugin/Cargo.toml @@ -30,7 +30,12 @@ tonic-build = { version = "0.5", default-features = false, features = ["transpor [target.'cfg(windows)'.build-dependencies] winres = "0.1" -winapi = "0.3" + +[target.'cfg(windows)'.build-dependencies.windows-sys] +version = "0.36.1" +features = [ + "Win32_System_SystemServices", +] [package.metadata.winres] ProductName = "Mullvad VPN" diff --git a/talpid-openvpn-plugin/build.rs b/talpid-openvpn-plugin/build.rs index 08c9e4944d..b3f12019a0 100644 --- a/talpid-openvpn-plugin/build.rs +++ b/talpid-openvpn-plugin/build.rs @@ -1,3 +1,8 @@ +#[cfg(windows)] +fn make_lang_id(p: u16, s: u16) -> u16 { + (s << 10) | p +} + fn main() { const PROTO_FILE: &str = "proto/openvpn_plugin.proto"; tonic_build::compile_protos(PROTO_FILE).unwrap(); @@ -9,9 +14,9 @@ fn main() { let mut res = winres::WindowsResource::new(); res.set("ProductVersion", &product_version); res.set_icon("../dist-assets/icon.ico"); - res.set_language(winapi::um::winnt::MAKELANGID( - winapi::um::winnt::LANG_ENGLISH, - winapi::um::winnt::SUBLANG_ENGLISH_US, + res.set_language(make_lang_id( + windows_sys::Win32::System::SystemServices::LANG_ENGLISH as u16, + windows_sys::Win32::System::SystemServices::SUBLANG_ENGLISH_US as u16, )); res.compile().expect("Unable to generate windows resources"); } diff --git a/talpid-platform-metadata/Cargo.toml b/talpid-platform-metadata/Cargo.toml index de4b470fcd..170e88c74d 100644 --- a/talpid-platform-metadata/Cargo.toml +++ b/talpid-platform-metadata/Cargo.toml @@ -12,5 +12,11 @@ publish = false rs-release = "0.1.7" talpid-dbus = { path = "../talpid-dbus" } -[target.'cfg(target_os = "windows")'.dependencies] -winapi = { version = "0.3.6", features = ["winbase"] } +[target.'cfg(target_os = "windows")'.dependencies.windows-sys] +version = "0.36.1" +features = [ + "Win32_Foundation", + "Win32_System_LibraryLoader", + "Win32_System_SystemInformation", + "Win32_System_SystemServices", +] diff --git a/talpid-platform-metadata/src/windows.rs b/talpid-platform-metadata/src/windows.rs index 5488268d01..56db7c7919 100644 --- a/talpid-platform-metadata/src/windows.rs +++ b/talpid-platform-metadata/src/windows.rs @@ -3,13 +3,15 @@ use std::{ io, iter, mem::{self, MaybeUninit}, os::windows::ffi::OsStrExt, - ptr, }; -use winapi::um::{ - libloaderapi::{GetModuleHandleW, GetProcAddress}, - winnt::RTL_OSVERSIONINFOW, +use windows_sys::Win32::System::{ + LibraryLoader::{GetModuleHandleW, GetProcAddress}, + SystemInformation::OSVERSIONINFOW, }; +#[allow(non_camel_case_types)] +type RTL_OSVERSIONINFOW = OSVERSIONINFOW; + pub fn version() -> String { let (major, build) = WindowsVersion::new() .map(|version_info| { @@ -47,15 +49,12 @@ impl WindowsVersion { .collect(); let ntdll = unsafe { GetModuleHandleW(module_name.as_ptr()) }; - if ntdll == ptr::null_mut() { + if ntdll == 0 { return Err(io::Error::last_os_error()); } - let function_address = - unsafe { GetProcAddress(ntdll, b"RtlGetVersion\0" as *const _ as *const i8) }; - if function_address == ptr::null_mut() { - return Err(io::Error::last_os_error()); - } + let function_address = unsafe { GetProcAddress(ntdll, b"RtlGetVersion\0" as *const u8) } + .ok_or_else(|| io::Error::last_os_error())?; let rtl_get_version: extern "stdcall" fn(*mut RTL_OSVERSIONINFOW) = unsafe { *(&function_address as *const _ as *const _) }; |
