4026defe79
Registriert den Sync-Ordner als Shell-Namespace-Extension unter
HKEY_CURRENT_USER (kein Admin noetig), sodass er mit eigenem Icon
in der linken Leiste des Datei-Explorers erscheint - wie bei
OneDrive oder Dropbox.
- Neues Modul cloud_files::shell_integration mit install/uninstall
- Registry-Eintraege unter HKCU\Software\Classes\CLSID\{GUID} und
HKCU\...\Explorer\Desktop\NameSpace\{GUID}
- Nutzt die laufende .exe als Icon-Quelle (fallback: imageres.dll)
- SHChangeNotify(SHCNE_ASSOCCHANGED) damit Explorer sofort aktualisiert
- install/uninstall werden aus register_sync_root/unregister aufgerufen
- winreg-Crate fuer sauberen Registry-Zugriff
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
122 lines
4.1 KiB
Rust
122 lines
4.1 KiB
Rust
//! Native File-Provider-Integration (Platzhalter-Dateien wie bei OneDrive).
|
|
//!
|
|
//! Auf Windows realisiert ueber die Cloud Files API (cfapi.dll), auf Linux
|
|
//! ueber FUSE (optional, hinter `linux_fuse`-Feature). macOS folgt spaeter
|
|
//! ueber NSFileProviderExtension (braucht Apple-Signatur).
|
|
//!
|
|
//! Der bestehende `sync::engine` bleibt unberuehrt und bietet weiterhin
|
|
//! den klassischen "kopiere-alles-lokal"-Modus. Der Cloud-Files-Modus
|
|
//! ist sozusagen "files-on-demand": Datei wird erst bei Zugriff geladen.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use std::path::PathBuf;
|
|
|
|
/// Ein Eintrag aus dem Mini-Cloud-Syncbaum, so wie er vom Server kommt.
|
|
/// Wird von beiden Plattformen genutzt, um Platzhalter / FUSE-Inodes zu
|
|
/// erzeugen.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct RemoteEntry {
|
|
pub id: i64,
|
|
pub name: String,
|
|
pub parent_id: Option<i64>,
|
|
pub is_folder: bool,
|
|
pub size: i64,
|
|
/// UTC-ISO8601
|
|
pub modified_at: String,
|
|
/// SHA-256 falls vom Server ausgeliefert, sonst None.
|
|
pub checksum: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum SyncState {
|
|
/// Datei existiert nur als Platzhalter (online-only).
|
|
Cloud,
|
|
/// Datei ist vollstaendig lokal vorhanden und aktuell.
|
|
InSync,
|
|
/// Lokal geaendert, Upload ausstehend.
|
|
PendingUpload,
|
|
/// Auf dem Server gesperrt (durch anderen Nutzer).
|
|
LockedByOther,
|
|
/// Durch diesen Client gesperrt.
|
|
LockedLocal,
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub mod windows;
|
|
#[cfg(windows)]
|
|
pub mod shell_integration;
|
|
#[cfg(all(target_os = "linux", feature = "linux_fuse"))]
|
|
pub mod linux;
|
|
pub mod sync_loop;
|
|
pub mod watcher;
|
|
|
|
/// Registriere den Sync-Root beim Betriebssystem. Ruft je nach Plattform
|
|
/// cfapi/CfRegisterSyncRoot bzw. mountet ein FUSE-Dateisystem.
|
|
#[allow(unused_variables)]
|
|
pub fn register_sync_root(
|
|
mount_point: &PathBuf,
|
|
provider_name: &str,
|
|
account_id: &str,
|
|
) -> Result<(), String> {
|
|
#[cfg(windows)]
|
|
return windows::register_sync_root(mount_point, provider_name, account_id);
|
|
|
|
#[cfg(all(target_os = "linux", feature = "linux_fuse"))]
|
|
return linux::mount(mount_point);
|
|
|
|
#[cfg(not(any(windows, all(target_os = "linux", feature = "linux_fuse"))))]
|
|
Err("File-Provider-Integration fuer diese Plattform noch nicht verfuegbar".into())
|
|
}
|
|
|
|
#[allow(unused_variables)]
|
|
pub fn unregister_sync_root(mount_point: &PathBuf) -> Result<(), String> {
|
|
#[cfg(windows)]
|
|
return windows::unregister_sync_root(mount_point);
|
|
|
|
#[cfg(all(target_os = "linux", feature = "linux_fuse"))]
|
|
return linux::unmount(mount_point);
|
|
|
|
#[cfg(not(any(windows, all(target_os = "linux", feature = "linux_fuse"))))]
|
|
Err("File-Provider-Integration fuer diese Plattform noch nicht verfuegbar".into())
|
|
}
|
|
|
|
/// Erzeuge fuer alle Remote-Eintraege Platzhalter (cloud-only Dateien).
|
|
/// Ordner werden als echte Verzeichnisse angelegt, Dateien als
|
|
/// Platzhalter mit gespeicherten Metadaten (Groesse, Mtime, ID).
|
|
#[allow(unused_variables)]
|
|
pub fn populate_placeholders(
|
|
mount_point: &PathBuf,
|
|
entries: &[RemoteEntry],
|
|
) -> Result<(), String> {
|
|
#[cfg(windows)]
|
|
return windows::populate_placeholders(mount_point, entries);
|
|
|
|
#[cfg(all(target_os = "linux", feature = "linux_fuse"))]
|
|
return linux::populate(mount_point, entries);
|
|
|
|
#[cfg(not(any(windows, all(target_os = "linux", feature = "linux_fuse"))))]
|
|
Err("File-Provider-Integration fuer diese Plattform noch nicht verfuegbar".into())
|
|
}
|
|
|
|
/// Ist File-Provider-Integration auf dieser Plattform grundsaetzlich verfuegbar?
|
|
pub fn is_supported() -> bool {
|
|
cfg!(windows) || cfg!(all(target_os = "linux", feature = "linux_fuse"))
|
|
}
|
|
|
|
/// Markiere eine lokal bereits vorhandene Datei als "immer offline halten".
|
|
#[allow(unused_variables)]
|
|
pub fn pin_file(path: &PathBuf) -> Result<(), String> {
|
|
#[cfg(windows)]
|
|
return windows::set_pin_state(path, true);
|
|
#[cfg(not(windows))]
|
|
Err("Nur auf Windows unterstuetzt".into())
|
|
}
|
|
|
|
#[allow(unused_variables)]
|
|
pub fn unpin_file(path: &PathBuf) -> Result<(), String> {
|
|
#[cfg(windows)]
|
|
return windows::set_pin_state(path, false);
|
|
#[cfg(not(windows))]
|
|
Err("Nur auf Windows unterstuetzt".into())
|
|
}
|