summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--installer-downloader/Cargo.toml1
-rw-r--r--installer-downloader/src/controller.rs15
-rw-r--r--talpid-platform-metadata/Cargo.toml1
-rw-r--r--talpid-platform-metadata/src/arch.rs58
-rw-r--r--talpid-platform-metadata/src/lib.rs4
6 files changed, 78 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d2eb110f8f..4205eb9adc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2033,6 +2033,7 @@ dependencies = [
"rand 0.8.5",
"reqwest",
"serde",
+ "talpid-platform-metadata",
"tokio",
"windows-sys 0.52.0",
"winres",
diff --git a/installer-downloader/Cargo.toml b/installer-downloader/Cargo.toml
index 80b7450b7c..a468abb8cb 100644
--- a/installer-downloader/Cargo.toml
+++ b/installer-downloader/Cargo.toml
@@ -28,6 +28,7 @@ chrono = { workspace = true, features = ["clock"] }
fern = { version = "0.6", default-features = false }
log = { workspace = true }
+talpid-platform-metadata = { path = "../talpid-platform-metadata" }
mullvad-update = { path = "../mullvad-update", features = ["client"] }
[target.'cfg(target_os = "windows")'.dependencies]
diff --git a/installer-downloader/src/controller.rs b/installer-downloader/src/controller.rs
index 2f8f228d83..ff02b3cd0c 100644
--- a/installer-downloader/src/controller.rs
+++ b/installer-downloader/src/controller.rs
@@ -129,10 +129,12 @@ async fn fetch_app_version_info<Delegate, VersionProvider>(
Delegate: AppDelegate + 'static,
VersionProvider: VersionInfoProvider + Send,
{
+ // TODO: Do not unwrap
+ // TODO: Construct a proper error instead
+ let architecture = get_arch().unwrap().unwrap();
loop {
let version_params = VersionParameters {
- // TODO: detect current architecture
- architecture: VersionArchitecture::X86,
+ architecture,
// For the downloader, the rollout version is always preferred
rollout: 1.,
// The downloader allows any version
@@ -410,3 +412,12 @@ fn select_cdn_url(urls: &[String]) -> Option<&str> {
fn format_latest_version(version: &Version) -> String {
format!("{}: {}", resource::LATEST_VERSION_PREFIX, version.version)
}
+
+/// Try to map the host's CPU architecture to one of the CPU architectures the Mullvad VPN app
+/// supports.
+fn get_arch() -> Result<Option<VersionArchitecture>, std::io::Error> {
+ match talpid_platform_metadata::get_native_arch()?? {
+ talpid_platform_metadata::Architecture::X86 => VersionArchitecture::X86,
+ talpid_platform_metadata::Architecture::Arm64 => VersionArchitecture::Arm64,
+ }
+}
diff --git a/talpid-platform-metadata/Cargo.toml b/talpid-platform-metadata/Cargo.toml
index d82479c0c4..9eb58f4a55 100644
--- a/talpid-platform-metadata/Cargo.toml
+++ b/talpid-platform-metadata/Cargo.toml
@@ -25,4 +25,5 @@ features = [
"Win32_System_LibraryLoader",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
+ "Win32_System_Threading",
]
diff --git a/talpid-platform-metadata/src/arch.rs b/talpid-platform-metadata/src/arch.rs
new file mode 100644
index 0000000000..1f6de901cd
--- /dev/null
+++ b/talpid-platform-metadata/src/arch.rs
@@ -0,0 +1,58 @@
+//! Detect the running platform's CPU architecture.
+
+/// CPU architectures supported by the talpid family of crates.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Architecture {
+ /// x86-64 architecture
+ X86,
+ /// ARM64 architecture
+ Arm64,
+}
+
+/// Return native architecture (ignoring WOW64). If the native architecture can not be detected,
+/// [`None`] is returned. This should never be the case on working X86_64 or Arm64 systems.
+#[cfg(target_os = "windows")]
+pub fn get_native_arch() -> Result<Option<Architecture>, std::io::Error> {
+ use core::ffi::c_ushort;
+ use windows_sys::Win32::System::SystemInformation::{
+ IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_ARM64,
+ };
+ use windows_sys::Win32::System::Threading::{GetCurrentProcess, IsWow64Process2};
+
+ let native_arch = {
+ let mut running_arch: c_ushort = 0;
+ let mut native_arch: c_ushort = 0;
+
+ // SAFETY: Trivially safe. The current process handle is a glorified constant.
+ let current_process = unsafe { GetCurrentProcess() };
+
+ // IsWow64Process2:
+ // Determines whether the specified process is running under WOW64; also returns additional machine process and architecture information.
+ //
+ // SAFETY: Trivially safe, since we provide the required arguments.
+ if 0 == unsafe { IsWow64Process2(current_process, &mut running_arch, &mut native_arch) } {
+ return Err(std::io::Error::last_os_error());
+ }
+
+ native_arch
+ };
+
+ match native_arch {
+ IMAGE_FILE_MACHINE_AMD64 => Ok(Some(Architecture::X86)),
+ IMAGE_FILE_MACHINE_ARM64 => Ok(Some(Architecture::Arm64)),
+ _other => Ok(None),
+ }
+}
+
+/// Return native architecture.
+#[cfg(not(target_os = "windows"))]
+pub fn get_native_arch() -> Result<Option<Architecture>, std::io::Error> {
+ const TARGET_ARCH: Option<Architecture> = if cfg!(any(target_arch = "x86_64",)) {
+ Some(Architecture::X86)
+ } else if cfg!(target_arch = "aarch64") {
+ Some(Architecture::Arm64)
+ } else {
+ None
+ };
+ Ok(TARGET_ARCH)
+}
diff --git a/talpid-platform-metadata/src/lib.rs b/talpid-platform-metadata/src/lib.rs
index 7a11c97f18..98640fabef 100644
--- a/talpid-platform-metadata/src/lib.rs
+++ b/talpid-platform-metadata/src/lib.rs
@@ -1,3 +1,4 @@
+mod arch;
#[cfg(target_os = "linux")]
#[path = "linux.rs"]
mod imp;
@@ -19,3 +20,6 @@ pub use self::imp::MacosVersion;
#[cfg(windows)]
pub use self::imp::WindowsVersion;
pub use self::imp::{extra_metadata, short_version, version};
+
+pub use arch::get_native_arch;
+pub use arch::Architecture;