summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2023-02-22 16:20:07 +0100
committerDavid Lönnhager <david.l@mullvad.net>2023-02-27 18:52:45 +0100
commit025c9d1fd3a16b354d502e83d49a671f657a59e2 (patch)
tree3cfd7a380f925887f04470f4769ddd99acaeb4c9
parent34a8b2e914454e0457a3d2637d6c9e263694935c (diff)
downloadmullvadvpn-025c9d1fd3a16b354d502e83d49a671f657a59e2.tar.xz
mullvadvpn-025c9d1fd3a16b354d502e83d49a671f657a59e2.zip
Retrieve system app dir path from mullvad-paths in cleanup plugin
using mullvad-nsis
-rw-r--r--Cargo.lock52
-rw-r--r--Cargo.toml1
-rw-r--r--mullvad-nsis/Cargo.toml17
-rw-r--r--mullvad-nsis/build.rs14
-rw-r--r--mullvad-nsis/include/mullvad-nsis.h24
-rw-r--r--mullvad-nsis/src/lib.rs58
-rw-r--r--mullvad-paths/Cargo.toml2
-rw-r--r--mullvad-paths/src/lib.rs2
-rw-r--r--mullvad-paths/src/windows.rs254
-rw-r--r--windows/nsis-plugins/src/cleanup/cleaningops.cpp39
-rw-r--r--windows/nsis-plugins/src/cleanup/cleanup.vcxproj20
11 files changed, 295 insertions, 188 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8c7c22bd09..f058410aea 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -289,6 +289,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
+name = "cbindgen"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
+dependencies = [
+ "clap",
+ "heck",
+ "indexmap",
+ "log",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_json",
+ "syn",
+ "tempfile",
+ "toml",
+]
+
+[[package]]
name = "cc"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -358,15 +377,15 @@ dependencies = [
[[package]]
name = "clap"
-version = "3.0.14"
+version = "3.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b63edc3f163b3c71ec8aa23f9bd6070f77edbf3d1d198b164afa90ff00e4ec62"
+checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
dependencies = [
"atty",
"bitflags",
+ "clap_lex",
"indexmap",
- "lazy_static",
- "os_str_bytes",
+ "once_cell",
"strsim 0.10.0",
"termcolor",
"textwrap",
@@ -382,6 +401,15 @@ dependencies = [
]
[[package]]
+name = "clap_lex"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
name = "classic-mceliece-rust"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1745,11 +1773,20 @@ dependencies = [
]
[[package]]
+name = "mullvad-nsis"
+version = "0.0.0"
+dependencies = [
+ "cbindgen",
+ "mullvad-paths",
+]
+
+[[package]]
name = "mullvad-paths"
version = "0.0.0"
dependencies = [
"err-derive",
"log",
+ "once_cell",
"widestring 1.0.2",
"windows-sys 0.42.0",
]
@@ -2066,9 +2103,6 @@ name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
-dependencies = [
- "memchr",
-]
[[package]]
name = "p256"
@@ -3450,9 +3484,9 @@ dependencies = [
[[package]]
name = "textwrap"
-version = "0.14.2"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
+checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]]
name = "thiserror"
diff --git a/Cargo.toml b/Cargo.toml
index 1868ba9dfe..9cfeba5053 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,6 +13,7 @@ members = [
"mullvad-api",
"mullvad-exclude",
"mullvad-version",
+ "mullvad-nsis",
"talpid-openvpn-plugin",
"talpid-core",
"talpid-dbus",
diff --git a/mullvad-nsis/Cargo.toml b/mullvad-nsis/Cargo.toml
new file mode 100644
index 0000000000..0c83da480b
--- /dev/null
+++ b/mullvad-nsis/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "mullvad-nsis"
+version = "0.0.0"
+authors = ["Mullvad VPN"]
+description = "Helper library used by Mullvad NSIS plugins"
+license = "GPL-3.0"
+edition = "2021"
+publish = false
+
+[lib]
+crate_type = ["staticlib"]
+
+[target.i686-pc-windows-msvc.dependencies]
+mullvad-paths = { path = "../mullvad-paths" }
+
+[target.i686-pc-windows-msvc.build-dependencies]
+cbindgen = "0.24.3"
diff --git a/mullvad-nsis/build.rs b/mullvad-nsis/build.rs
new file mode 100644
index 0000000000..1765ff54ed
--- /dev/null
+++ b/mullvad-nsis/build.rs
@@ -0,0 +1,14 @@
+fn main() {
+ #[cfg(all(target_arch = "x86", target_os = "windows"))]
+ {
+ extern crate cbindgen;
+ use std::env;
+
+ let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
+ let mut config: cbindgen::Config = Default::default();
+ config.language = cbindgen::Language::Cxx;
+ cbindgen::generate_with_config(&crate_dir, config)
+ .unwrap()
+ .write_to_file("include/mullvad-nsis.h");
+ }
+}
diff --git a/mullvad-nsis/include/mullvad-nsis.h b/mullvad-nsis/include/mullvad-nsis.h
new file mode 100644
index 0000000000..5c71a517f1
--- /dev/null
+++ b/mullvad-nsis/include/mullvad-nsis.h
@@ -0,0 +1,24 @@
+#include <cstdarg>
+#include <cstdint>
+#include <cstdlib>
+#include <ostream>
+#include <new>
+
+enum class Status {
+ Ok,
+ InvalidArguments,
+ InsufficientBufferSize,
+ OsError,
+ Panic,
+};
+
+extern "C" {
+
+/// Writes the system's app data path into `buffer` when `Status::Ok` is returned.
+/// If `buffer` is `null`, or if the buffer is too small, `InsufficientBufferSize`
+/// is returned, and the required buffer size (in chars) is returned in `buffer_size`.
+/// On success, `buffer_size` is set to the length of the string, including
+/// the final null terminator.
+Status get_system_local_appdata(uint16_t *buffer, uintptr_t *buffer_size);
+
+} // extern "C"
diff --git a/mullvad-nsis/src/lib.rs b/mullvad-nsis/src/lib.rs
new file mode 100644
index 0000000000..0ac85418e8
--- /dev/null
+++ b/mullvad-nsis/src/lib.rs
@@ -0,0 +1,58 @@
+#![cfg(all(target_arch = "x86", target_os = "windows"))]
+
+use std::{os::windows::ffi::OsStrExt, panic::UnwindSafe, ptr};
+
+#[repr(C)]
+pub enum Status {
+ Ok,
+ InvalidArguments,
+ InsufficientBufferSize,
+ OsError,
+ Panic,
+}
+
+/// Writes the system's app data path into `buffer` when `Status::Ok` is returned.
+/// If `buffer` is `null`, or if the buffer is too small, `InsufficientBufferSize`
+/// is returned, and the required buffer size (in chars) is returned in `buffer_size`.
+/// On success, `buffer_size` is set to the length of the string, including
+/// the final null terminator.
+#[no_mangle]
+pub unsafe extern "C" fn get_system_local_appdata(
+ buffer: *mut u16,
+ buffer_size: *mut usize,
+) -> Status {
+ catch_and_log_unwind(|| {
+ if buffer_size.is_null() {
+ return Status::InvalidArguments;
+ }
+
+ let path = match mullvad_paths::windows::get_system_service_appdata() {
+ Ok(path) => path,
+ Err(_error) => {
+ return Status::OsError;
+ }
+ };
+
+ let path = path.as_os_str();
+ let path_u16: Vec<u16> = path.encode_wide().chain(std::iter::once(0u16)).collect();
+
+ let prev_len = *buffer_size;
+
+ *buffer_size = path_u16.len();
+
+ if prev_len < path_u16.len() || buffer.is_null() {
+ return Status::InsufficientBufferSize;
+ }
+
+ ptr::copy_nonoverlapping(path_u16.as_ptr(), buffer, path_u16.len());
+
+ Status::Ok
+ })
+}
+
+fn catch_and_log_unwind(func: impl FnOnce() -> Status + UnwindSafe) -> Status {
+ match std::panic::catch_unwind(func) {
+ Ok(status) => status,
+ Err(_error) => Status::Panic,
+ }
+}
diff --git a/mullvad-paths/Cargo.toml b/mullvad-paths/Cargo.toml
index 3c4303c5b9..1d56987aaf 100644
--- a/mullvad-paths/Cargo.toml
+++ b/mullvad-paths/Cargo.toml
@@ -15,12 +15,14 @@ log = "0.4"
[target.'cfg(windows)'.dependencies]
widestring = "1.0"
+once_cell = "1.13"
[target.'cfg(target_os = "windows")'.dependencies.windows-sys]
version = "0.42.0"
features = [
"Win32_Foundation",
"Win32_Security",
+ "Win32_Storage_FileSystem",
"Win32_System_Com",
"Win32_System_ProcessStatus",
"Win32_System_SystemServices",
diff --git a/mullvad-paths/src/lib.rs b/mullvad-paths/src/lib.rs
index 88bd23d74b..e78b02bf2d 100644
--- a/mullvad-paths/src/lib.rs
+++ b/mullvad-paths/src/lib.rs
@@ -71,4 +71,4 @@ mod settings;
pub use crate::settings::{get_default_settings_dir, settings_dir};
#[cfg(windows)]
-mod windows;
+pub mod windows;
diff --git a/mullvad-paths/src/windows.rs b/mullvad-paths/src/windows.rs
index 166c0dae7f..8237a983b9 100644
--- a/mullvad-paths/src/windows.rs
+++ b/mullvad-paths/src/windows.rs
@@ -1,11 +1,12 @@
+use once_cell::sync::OnceCell;
use std::{io, mem, path::PathBuf, ptr};
use widestring::{WideCStr, WideCString};
use windows_sys::{
core::{GUID, PWSTR},
Win32::{
Foundation::{
- CloseHandle, ERROR_INSUFFICIENT_BUFFER, ERROR_NO_TOKEN, ERROR_SUCCESS, HANDLE, LUID,
- S_OK,
+ CloseHandle, ERROR_INSUFFICIENT_BUFFER, ERROR_SUCCESS, HANDLE, INVALID_HANDLE_VALUE,
+ LUID, S_OK,
},
Security::{
AdjustTokenPrivileges, CreateWellKnownSid, EqualSid, GetTokenInformation,
@@ -33,105 +34,85 @@ struct Handle(HANDLE);
impl Drop for Handle {
fn drop(&mut self) {
- unsafe {
- CloseHandle(self.0);
+ if self.0 != 0 && self.0 != INVALID_HANDLE_VALUE {
+ unsafe {
+ CloseHandle(self.0);
+ }
}
}
}
-pub(crate) fn get_system_service_appdata() -> io::Result<PathBuf> {
- let result = get_appdata_as_system_user()
- .or_else(|error| {
- log::error!("get_appdata_as_system_user failed: {error}");
- get_appdata_as_admin()
+/// Get local AppData path for the system service user.
+pub fn get_system_service_appdata() -> io::Result<PathBuf> {
+ static APPDATA_PATH: OnceCell<PathBuf> = OnceCell::new();
+
+ APPDATA_PATH
+ .get_or_try_init(|| {
+ let join_handle = std::thread::spawn(|| {
+ impersonate_self(|| {
+ let user_token = get_system_user_token()?;
+ get_known_folder_path(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, user_token.0)
+ })
+ .or_else(|error| {
+ log::error!("Failed to get AppData path: {error}");
+ infer_appdata_from_system_directory()
+ })
+ });
+ join_handle.join().unwrap()
})
- .or_else(|error| {
- log::error!("get_appdata_as_admin failed: {error}");
- infer_appdata_from_system()
- });
- if unsafe { RevertToSelf() } == 0 {
- log::error!("RevertToSelf failed: {}", io::Error::last_os_error());
- }
- result
+ .cloned()
}
-/// Get local AppData path if the current user is the system service user.
-fn get_appdata_as_system_user() -> io::Result<PathBuf> {
- let current_token = Handle(get_current_thread_token()?);
- let current_user_is_system = is_local_system_user_token(current_token.0);
+/// Get user token 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.
+/// If the current user is system, this function succeeds and returns a `NULL` handle;
+fn get_system_user_token() -> io::Result<Handle> {
+ let thread_token = get_current_thread_token()?;
- if current_user_is_system.map_err(|error| {
- log::error!("is_local_system_user_token failed: {error}");
- error
- })? {
- log::trace!("Is system user");
- return get_known_folder_path(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, 0);
+ if is_local_system_user_token(thread_token.0)? {
+ return Ok(Handle(0));
}
- log::trace!("Is not system user");
- Err(io::Error::new(
- io::ErrorKind::Other,
- "current user is not SYSTEM",
- ))
-}
-
-/// 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_appdata_as_admin() -> std::io::Result<PathBuf> {
let system_debug_priv = WideCString::from_str("SeDebugPrivilege").unwrap();
- let current_token = Handle(get_current_thread_token()?);
- adjust_token_privilege(current_token.0, &system_debug_priv, true)?;
+ adjust_token_privilege(thread_token.0, &system_debug_priv, true)?;
- let known_path = find_process(|process_handle| {
- let mut process_token = 0;
+ let find_result = find_process(|process_handle| {
+ let process_token = open_process_token(
+ process_handle,
+ GENERIC_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
+ )
+ .ok()?;
- let status = unsafe {
- OpenProcessToken(
- process_handle,
- GENERIC_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
- &mut process_token,
- )
- };
- if status == 0 {
- log::error!(
- "Failed to open process token: {}",
- io::Error::last_os_error()
- );
- return None;
+ match is_local_system_user_token(process_token.0) {
+ Ok(true) => Some(process_token),
+ _ => None,
}
-
- let result = if let Ok(true) = is_local_system_user_token(process_token) {
- match get_known_folder_path(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, process_token) {
- Ok(path) => Some(Ok(path)),
- Err(error) => {
- log::error!("Failed to obtain folder path: {}", error);
- None
- }
- }
- } else {
- None
- };
- unsafe { CloseHandle(process_token) };
-
- result
});
- if let Err(err) = adjust_token_privilege(current_token.0, &system_debug_priv, false) {
+ if let Err(err) = adjust_token_privilege(thread_token.0, &system_debug_priv, false) {
log::error!("Failed to drop SeDebugPrivilege: {}", err);
}
- known_path
+ find_result
+}
+
+fn open_process_token(process: HANDLE, access: u32) -> io::Result<Handle> {
+ let mut process_token = 0;
+ if unsafe { OpenProcessToken(process, access, &mut process_token) } == 0 {
+ return Err(io::Error::last_os_error());
+ }
+ Ok(Handle(process_token))
}
/// If all else fails, infer the AppData path from the system directory.
-fn infer_appdata_from_system() -> io::Result<PathBuf> {
+fn infer_appdata_from_system_directory() -> io::Result<PathBuf> {
let mut sysdir = get_known_folder_path(&FOLDERID_System, KF_FLAG_DEFAULT, 0)?;
sysdir.extend(["config", "systemprofile", "AppData", "Local"]);
Ok(sysdir)
}
-fn get_current_thread_token() -> std::io::Result<HANDLE> {
+fn get_current_thread_token() -> std::io::Result<Handle> {
let mut token_handle: HANDLE = 0;
if unsafe {
OpenThreadToken(
@@ -142,29 +123,23 @@ fn get_current_thread_token() -> std::io::Result<HANDLE> {
)
} == 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) } == 0 {
- return Err(std::io::Error::last_os_error());
- }
+ return Err(std::io::Error::last_os_error());
+ }
+ Ok(Handle(token_handle))
+}
- if unsafe {
- OpenThreadToken(
- GetCurrentThread(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- 0,
- &mut token_handle,
- )
- } == 0
- {
- return Err(std::io::Error::last_os_error());
- }
- } else {
- return Err(thread_token_error);
- }
+fn impersonate_self<T>(func: impl FnOnce() -> io::Result<T>) -> io::Result<T> {
+ if unsafe { ImpersonateSelf(SecurityImpersonation) } == 0 {
+ return Err(std::io::Error::last_os_error());
}
- Ok(token_handle)
+ let result = func();
+
+ if unsafe { RevertToSelf() } == 0 {
+ log::error!("RevertToSelf failed: {}", io::Error::last_os_error());
+ }
+
+ result
}
fn adjust_token_privilege(
@@ -214,7 +189,7 @@ fn get_known_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())
+ Ok(PathBuf::from(path.to_os_string()))
} else {
Err(io::Error::new(
io::ErrorKind::NotFound,
@@ -228,7 +203,7 @@ fn get_known_folder_path(
/// Enumerate over all processes until `handle_process` returns a result or until there are
/// no more processes left. In the latter case, an error is returned.
-fn find_process<T>(handle_process: impl Fn(HANDLE) -> Option<io::Result<T>>) -> io::Result<T> {
+fn find_process<T>(handle_process: impl Fn(HANDLE) -> Option<T>) -> io::Result<T> {
let mut pid_buffer = vec![0u32; 2048];
let mut num_procs: u32 = u32::try_from(pid_buffer.len()).unwrap();
@@ -243,64 +218,55 @@ fn find_process<T>(handle_process: impl Fn(HANDLE) -> Option<io::Result<T>>) ->
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, 0, process) };
- if process_handle == 0 {
- log::error!(
- "Failed to open process {}: {}",
- process,
- io::Error::last_os_error()
- );
- continue;
- }
-
- let result = handle_process(process_handle);
-
- unsafe { CloseHandle(process_handle) };
-
- if let Some(result) = result {
- return result;
- }
- }
-
- Err(io::Error::new(
- io::ErrorKind::NotFound,
- "Could not find matching process",
- ))
+ pid_buffer
+ .into_iter()
+ .find_map(|process| {
+ let process_handle =
+ Handle(unsafe { OpenProcess(PROCESS_QUERY_INFORMATION, 0, process) });
+ if process_handle.0 == 0 {
+ return None;
+ }
+ handle_process(process_handle.0)
+ })
+ .ok_or(io::Error::new(
+ io::ErrorKind::NotFound,
+ "Could not find matching process",
+ ))
}
fn is_local_system_user_token(token: HANDLE) -> io::Result<bool> {
- let mut token_info_len = 0;
-
- let info_result =
- unsafe { GetTokenInformation(token, TokenUser, ptr::null_mut(), 0, &mut token_info_len) };
- let err = io::Error::last_os_error();
+ let mut token_info = vec![0u8; 1024];
- if info_result != 0 || err.raw_os_error() != Some(ERROR_INSUFFICIENT_BUFFER as i32) {
- log::error!("Failed to obtain token information (length): {}", err);
- return Err(err);
- }
+ loop {
+ let mut returned_info_len = 0;
- let mut token_info = vec![0u8; usize::try_from(token_info_len).expect("i32 must fit in usize")];
- let mut _ret_len = 0;
+ let info_result = unsafe {
+ GetTokenInformation(
+ token,
+ TokenUser,
+ token_info.as_mut_ptr() as _,
+ u32::try_from(token_info.len()).expect("len must fit in u32"),
+ &mut returned_info_len,
+ )
+ };
- if unsafe {
- GetTokenInformation(
- token,
- TokenUser,
- token_info.as_mut_ptr() as _,
- token_info_len,
- &mut _ret_len,
- )
- } == 0
- {
let err = io::Error::last_os_error();
- log::error!("Failed to obtain token information: {}", err);
- return Err(err);
+ if info_result == 0 && err.raw_os_error() != Some(ERROR_INSUFFICIENT_BUFFER as i32) {
+ log::error!("Failed to obtain token information: {}", err);
+ return Err(err);
+ }
+
+ token_info.resize(
+ usize::try_from(returned_info_len).expect("u32 must fit in usize"),
+ 0,
+ );
+ if info_result != 0 {
+ break;
+ }
}
// SAFETY: We specified `TokenUser` as the class, so that is what GetTokenInformation should
- // return.
+ // return. This reference is valid for as long as `token_info` is valid.
let token_user = unsafe { &*(token_info.as_mut_ptr() as *const TOKEN_USER) };
let mut local_system_sid = [0u8; MAX_SID_SIZE as usize];
diff --git a/windows/nsis-plugins/src/cleanup/cleaningops.cpp b/windows/nsis-plugins/src/cleanup/cleaningops.cpp
index 2a29e8dd1c..831cf96bf3 100644
--- a/windows/nsis-plugins/src/cleanup/cleaningops.cpp
+++ b/windows/nsis-plugins/src/cleanup/cleaningops.cpp
@@ -12,6 +12,7 @@
#include <utility>
#include <functional>
#include <processthreadsapi.h>
+#include <mullvad-nsis.h>
namespace
{
@@ -66,43 +67,25 @@ std::wstring ConstructUserPath(const std::wstring &users, const std::wstring &us
std::wstring GetSystemUserLocalAppData()
{
- common::security::AdjustCurrentProcessTokenPrivilege(L"SeDebugPrivilege");
+ std::vector<uint16_t> buffer(256);
+ size_t bufferSize = buffer.size();
- common::memory::ScopeDestructor sd;
+GET_LOCAL_APPDATA:
- sd += []
- {
- common::security::AdjustCurrentProcessTokenPrivilege(L"SeDebugPrivilege", false);
- };
-
- auto systemDir = common::fs::GetKnownFolderPath(FOLDERID_System);
- auto lsassPath = std::filesystem::path(systemDir).append(L"lsass.exe");
- auto lsassPid = common::process::GetProcessIdFromName(lsassPath);
+ auto result = get_system_local_appdata(buffer.data(), &bufferSize);
- auto processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, lsassPid);
-
- if (nullptr == processHandle)
+ if (Status::InsufficientBufferSize == result)
{
- THROW_ERROR("Failed to access the \"LSASS\" process");
+ buffer.resize(bufferSize);
+ goto GET_LOCAL_APPDATA;
}
- HANDLE processToken;
-
- auto status = OpenProcessToken(processHandle, TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &processToken);
-
- CloseHandle(processHandle);
-
- if (FALSE == status)
+ if (Status::Ok != result)
{
- THROW_ERROR("Failed to acquire process token for the \"LSASS\" process");
+ THROW_ERROR("Failed to acquire system app data path");
}
- sd += [&]()
- {
- CloseHandle(processToken);
- };
-
- return common::fs::GetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_DEFAULT, processToken);
+ return std::wstring(reinterpret_cast<wchar_t *>(buffer.data()));
}
std::filesystem::path GetSystemCacheDirectory()
diff --git a/windows/nsis-plugins/src/cleanup/cleanup.vcxproj b/windows/nsis-plugins/src/cleanup/cleanup.vcxproj
index 879866e530..287c7ab418 100644
--- a/windows/nsis-plugins/src/cleanup/cleanup.vcxproj
+++ b/windows/nsis-plugins/src/cleanup/cleanup.vcxproj
@@ -61,7 +61,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;CLEANUP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
- <AdditionalIncludeDirectories>$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(ProjectDir)../../../../mullvad-nsis/include;$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
@@ -69,11 +69,15 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- <AdditionalLibraryDirectories>$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/nsis/;$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
- <AdditionalDependencies>libcommon.lib;pluginapi-x86-unicode.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(ProjectDir)../../../../target/i686-pc-windows-msvc/release;$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/nsis/;$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>mullvad_nsis.lib;libcommon.lib;pluginapi-x86-unicode.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries>
<ModuleDefinitionFile>cleanup.def</ModuleDefinitionFile>
</Link>
+ <PreBuildEvent>
+ <Command>cargo build --target i686-pc-windows-msvc --release -p mullvad-nsis</Command>
+ <Message>Build mullvad-nsis library</Message>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@@ -85,7 +89,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;CLEANUP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
- <AdditionalIncludeDirectories>$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(ProjectDir)../../../../mullvad-nsis/include;$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
@@ -95,11 +99,15 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- <AdditionalLibraryDirectories>$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/nsis/;$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
- <AdditionalDependencies>libcommon.lib;pluginapi-x86-unicode.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(ProjectDir)../../../../target/i686-pc-windows-msvc/release;$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/nsis/;$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>mullvad_nsis.lib;libcommon.lib;pluginapi-x86-unicode.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries>
<ModuleDefinitionFile>cleanup.def</ModuleDefinitionFile>
</Link>
+ <PreBuildEvent>
+ <Command>cargo build --target i686-pc-windows-msvc --release -p mullvad-nsis</Command>
+ <Message>Build mullvad-nsis library</Message>
+ </PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="cleaningops.h" />