mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2025-12-11 20:15:30 +01:00
Fix builds on windows (#2864)
* Fix builds on windows * Fix rust compile issues * Autoformat * Fix windows volumes compile again --------- Co-authored-by: Arnab Chakraborty <11457760+Rocky43007@users.noreply.github.com>
This commit is contained in:
parent
fbae190393
commit
28a390f167
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -100,10 +100,6 @@ jobs:
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Run pnpm prep
|
||||
run: |
|
||||
pnpm prep
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
pnpm tauri build --ci -v --target ${{ matrix.settings.target }} --bundles ${{ matrix.settings.bundles }}
|
||||
|
||||
@ -74,6 +74,9 @@ export const commands = {
|
||||
else return { status: 'error', error: e as any };
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Stops the cursor position tracking for drag operations
|
||||
*/
|
||||
async stopDrag(): Promise<void> {
|
||||
await TAURI_INVOKE('stop_drag');
|
||||
},
|
||||
|
||||
@ -95,6 +95,7 @@ http-range = "0.1.5"
|
||||
hyper-util = { version = "0.1.9", features = ["tokio"] }
|
||||
int-enum = "0.5" # Update blocked due to API breaking changes
|
||||
mini-moka = "0.10.3"
|
||||
once_cell = "1.19.0"
|
||||
serde-hashkey = "0.4.5"
|
||||
serde_repr = "0.1.19"
|
||||
serde_with = "3.8"
|
||||
@ -104,7 +105,6 @@ tar = "0.4.41"
|
||||
tower-service = "0.3.2"
|
||||
tracing-appender = "0.2.3"
|
||||
whoami = "1.5.2"
|
||||
once_cell = "1.19.0"
|
||||
|
||||
[dependencies.tokio]
|
||||
features = ["io-util", "macros", "process", "rt-multi-thread", "sync", "time"]
|
||||
@ -130,12 +130,17 @@ plist = "1.6"
|
||||
trash = "5.1"
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
trash = "5.1"
|
||||
inotify = "0.11.0"
|
||||
trash = "5.1"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
trash = "5.1"
|
||||
windows = { features = ["Win32_Storage_FileSystem"], version = "0.58" }
|
||||
windows = { features = [
|
||||
"Win32_Storage_FileSystem",
|
||||
"Win32_System_IO",
|
||||
"Win32_System_Ioctl",
|
||||
"Win32_System_WindowsProgramming"
|
||||
], version = "0.58" }
|
||||
|
||||
[target.'cfg(target_os = "ios")'.dependencies]
|
||||
icrate = { version = "0.1.2", features = [
|
||||
|
||||
@ -10,7 +10,6 @@ use quic_rpc::{transport::quinn::QuinnConnector, RpcClient, RpcMessage};
|
||||
use quinn::{crypto::rustls::QuicClientConfig, ClientConfig, Endpoint};
|
||||
use reqwest::{IntoUrl, Url};
|
||||
use reqwest_middleware::{reqwest, ClientBuilder, ClientWithMiddleware};
|
||||
use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use tracing::warn;
|
||||
|
||||
|
||||
@ -39,8 +39,12 @@ pub async fn update_library_statistics(
|
||||
|
||||
if total_capacity == 0 && available_capacity == 0 {
|
||||
// Failed to fetch volume statistics from database, so we compute from local volumes
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
let volumes = crate::volume::get_volumes().await?;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let volumes = crate::volume::get_volumes().await;
|
||||
|
||||
let mut local_total_capacity: u64 = 0;
|
||||
let mut local_available_capacity: u64 = 0;
|
||||
for volume in volumes {
|
||||
|
||||
@ -27,7 +27,7 @@ mod common {
|
||||
pub fn parse_size(size_str: &str) -> u64 {
|
||||
size_str
|
||||
.chars()
|
||||
.filter(|c| c.is_digit(10))
|
||||
.filter(|c| c.is_ascii_digit())
|
||||
.collect::<String>()
|
||||
.parse()
|
||||
.unwrap_or(0)
|
||||
@ -315,19 +315,23 @@ pub mod linux {
|
||||
pub mod windows {
|
||||
use super::*;
|
||||
use std::ffi::OsString;
|
||||
use std::os::windows::ffi::OsStringExt;
|
||||
use windows::Win32::Storage::FileSystem::{
|
||||
GetDiskFreeSpaceExW, GetDriveTypeW, GetVolumeInformationW, DRIVE_FIXED, DRIVE_REMOTE,
|
||||
DRIVE_REMOVABLE,
|
||||
use std::path::PathBuf;
|
||||
|
||||
use ::windows::core::PCWSTR;
|
||||
use ::windows::Win32::Storage::FileSystem::{
|
||||
GetDiskFreeSpaceExW, GetDriveTypeW, GetVolumeInformationW,
|
||||
};
|
||||
use windows::Win32::System::Ioctl::STORAGE_PROPERTY_QUERY;
|
||||
use ::windows::Win32::System::WindowsProgramming::{
|
||||
DRIVE_FIXED, DRIVE_REMOTE, DRIVE_REMOVABLE,
|
||||
};
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
|
||||
pub async fn get_volumes() -> Vec<Volume> {
|
||||
task::spawn_blocking(|| {
|
||||
let mut volumes = Vec::new();
|
||||
|
||||
// Get available drives
|
||||
let drives = unsafe { windows::Win32::Storage::FileSystem::GetLogicalDrives() };
|
||||
let drives = unsafe { ::windows::Win32::Storage::FileSystem::GetLogicalDrives() };
|
||||
|
||||
for i in 0..26 {
|
||||
if (drives & (1 << i)) != 0 {
|
||||
@ -338,7 +342,7 @@ pub mod windows {
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
|
||||
let drive_type = unsafe { GetDriveTypeW(wide_path.as_ptr()) };
|
||||
let drive_type = unsafe { GetDriveTypeW(PCWSTR(wide_path.as_ptr())) };
|
||||
|
||||
// Skip CD-ROM drives and other unsupported types
|
||||
if drive_type == DRIVE_FIXED
|
||||
@ -379,29 +383,25 @@ pub mod windows {
|
||||
|
||||
unsafe {
|
||||
let success = GetVolumeInformationW(
|
||||
wide_path.as_ptr(),
|
||||
name_buf.as_mut_ptr(),
|
||||
name_buf.len() as u32,
|
||||
&mut serial_number,
|
||||
&mut max_component_length,
|
||||
&mut flags,
|
||||
fs_name_buf.as_mut_ptr(),
|
||||
fs_name_buf.len() as u32,
|
||||
PCWSTR(wide_path.as_ptr()),
|
||||
Some(name_buf.as_mut_slice()),
|
||||
Some(&mut serial_number),
|
||||
Some(&mut max_component_length),
|
||||
Some(&mut flags),
|
||||
Some(&mut fs_name_buf),
|
||||
);
|
||||
|
||||
if success.as_bool() {
|
||||
if let Ok(_) = success {
|
||||
let mut total_bytes = 0;
|
||||
let mut free_bytes = 0;
|
||||
let mut available_bytes = 0;
|
||||
|
||||
if GetDiskFreeSpaceExW(
|
||||
wide_path.as_ptr(),
|
||||
&mut available_bytes,
|
||||
&mut total_bytes,
|
||||
&mut free_bytes,
|
||||
)
|
||||
.as_bool()
|
||||
{
|
||||
if let Ok(_) = GetDiskFreeSpaceExW(
|
||||
PCWSTR(wide_path.as_ptr()),
|
||||
Some(&mut available_bytes),
|
||||
Some(&mut total_bytes),
|
||||
Some(&mut free_bytes),
|
||||
) {
|
||||
let mount_type = match drive_type {
|
||||
DRIVE_FIXED => MountType::System,
|
||||
DRIVE_REMOVABLE => MountType::External,
|
||||
@ -425,10 +425,12 @@ pub mod windows {
|
||||
},
|
||||
mount_type,
|
||||
PathBuf::from(path),
|
||||
vec![PathBuf::from(path)],
|
||||
detect_disk_type(path),
|
||||
FileSystem::from_string(&fs_name),
|
||||
total_bytes as u64,
|
||||
available_bytes as u64,
|
||||
total_bytes,
|
||||
available_bytes,
|
||||
false,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
@ -440,37 +442,39 @@ pub mod windows {
|
||||
}
|
||||
|
||||
pub async fn unmount_volume(path: &std::path::Path) -> Result<(), VolumeError> {
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use windows::core::PWSTR;
|
||||
use windows::Win32::Storage::FileSystem::{
|
||||
use ::windows::core::PWSTR;
|
||||
use ::windows::Win32::Storage::FileSystem::{
|
||||
DeleteVolumeMountPointW, GetVolumeNameForVolumeMountPointW,
|
||||
};
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
|
||||
// Convert path to wide string for Windows API
|
||||
let wide_path: Vec<u16> = OsStr::new(path)
|
||||
let mut wide_path: Vec<u16> = OsStr::new(path)
|
||||
.encode_wide()
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
|
||||
let wide_path_ptr = PWSTR(wide_path.as_mut_ptr());
|
||||
|
||||
unsafe {
|
||||
// Buffer for volume name
|
||||
let mut volume_name = [0u16; 50];
|
||||
let mut volume_name_ptr = PWSTR(volume_name.as_mut_ptr());
|
||||
|
||||
// Get the volume name for the mount point
|
||||
let result = GetVolumeNameForVolumeMountPointW(wide_path.as_ptr(), volume_name_ptr);
|
||||
let result =
|
||||
GetVolumeNameForVolumeMountPointW(wide_path_ptr, volume_name.as_mut_slice());
|
||||
|
||||
if !result.as_bool() {
|
||||
if result.is_err() {
|
||||
return Err(VolumeError::Platform(
|
||||
"Failed to get volume name".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
// Delete the mount point
|
||||
let result = DeleteVolumeMountPointW(wide_path.as_ptr());
|
||||
let result = DeleteVolumeMountPointW(wide_path_ptr);
|
||||
|
||||
if result.as_bool() {
|
||||
if let Ok(_) = result {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(VolumeError::Platform(
|
||||
|
||||
@ -2,7 +2,7 @@ use crate::{
|
||||
library::Library,
|
||||
volume::{
|
||||
speed::SpeedTest,
|
||||
types::{LibraryId, Volume, VolumeEvent, VolumeFingerprint, VolumePubId},
|
||||
types::{Volume, VolumeEvent, VolumeFingerprint},
|
||||
},
|
||||
};
|
||||
|
||||
@ -84,7 +84,12 @@ impl VolumeManagerState {
|
||||
}
|
||||
|
||||
pub async fn scan_volumes(&mut self) -> Result<(), VolumeError> {
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
let detected_volumes = super::os::get_volumes().await?;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let detected_volumes = super::os::get_volumes().await;
|
||||
|
||||
let mut registry = self.registry.write().await;
|
||||
|
||||
// Track existing volumes for removal detection
|
||||
@ -192,7 +197,7 @@ impl VolumeManagerState {
|
||||
for (fingerprint, volume) in registry.volumes() {
|
||||
let mut volume = volume.clone();
|
||||
|
||||
if let Some(db_volume) = db_volumes.get(&fingerprint) {
|
||||
if let Some(db_volume) = db_volumes.get(fingerprint) {
|
||||
volume = Volume::merge_with_db(&volume, db_volume);
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ use tokio::{
|
||||
sync::{broadcast, mpsc, RwLock},
|
||||
time::{sleep, Instant},
|
||||
};
|
||||
use tracing::{debug, error, warn};
|
||||
use tracing::{debug, error};
|
||||
|
||||
const DEBOUNCE_MS: u64 = 100;
|
||||
|
||||
@ -58,8 +58,19 @@ impl VolumeWatcher {
|
||||
}
|
||||
last_check = Instant::now();
|
||||
|
||||
match super::os::get_volumes().await {
|
||||
Ok(discovered_volumes) => {
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
let discovered_volumes = match super::os::get_volumes().await {
|
||||
Ok(volumes) => volumes,
|
||||
Err(e) => {
|
||||
error!("Failed to get volumes: {}", e);
|
||||
// Return empty volumes to avoid sending events
|
||||
vec![]
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let discovered_volumes = super::os::get_volumes().await;
|
||||
|
||||
let actor = actor.lock().await;
|
||||
|
||||
// Find new volumes
|
||||
@ -80,13 +91,7 @@ impl VolumeWatcher {
|
||||
.iter()
|
||||
.any(|v| VolumeFingerprint::new(&device_id, v) == fingerprint)
|
||||
{
|
||||
let _ =
|
||||
event_tx.send(VolumeEvent::VolumeRemoved(volume.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Failed to get volumes during watch: {}", e);
|
||||
let _ = event_tx.send(VolumeEvent::VolumeRemoved(volume.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,10 +188,7 @@ impl VolumeWatcher {
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use windows::Win32::Storage::FileSystem::{
|
||||
FindFirstVolumeW, FindNextVolumeW, FindVolumeClose, ReadDirectoryChangesW,
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME,
|
||||
};
|
||||
use ::windows::Win32::Storage::FileSystem::{FindFirstVolumeW, FindVolumeClose};
|
||||
|
||||
let check_tx = check_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
@ -194,13 +196,23 @@ impl VolumeWatcher {
|
||||
// Watch for volume arrival/removal
|
||||
unsafe {
|
||||
let mut volume_name = [0u16; 260];
|
||||
let handle = FindFirstVolumeW(volume_name.as_mut_ptr());
|
||||
let mut volume_change_detected = false;
|
||||
match FindFirstVolumeW(volume_name.as_mut_slice()) {
|
||||
Ok(handle) => {
|
||||
if !handle.is_invalid() {
|
||||
volume_change_detected = true;
|
||||
FindVolumeClose(handle);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to get a volume handle: {}", e);
|
||||
}
|
||||
}
|
||||
if volume_change_detected {
|
||||
// Volume change detected
|
||||
if let Err(e) = check_tx.send(()).await {
|
||||
error!("Failed to trigger volume check: {}", e);
|
||||
}
|
||||
FindVolumeClose(handle);
|
||||
}
|
||||
}
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user