diff --git a/Cargo.lock b/Cargo.lock index 9fde579..41ce587 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -585,7 +585,7 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "furumi-client-core" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "async-trait", @@ -607,7 +607,7 @@ dependencies = [ [[package]] name = "furumi-common" -version = "0.2.0" +version = "0.2.1" dependencies = [ "prost", "protobuf-src", @@ -617,7 +617,7 @@ dependencies = [ [[package]] name = "furumi-mount-linux" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "clap", @@ -634,7 +634,7 @@ dependencies = [ [[package]] name = "furumi-mount-macos" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "async-trait", diff --git a/windows-implementation-plan.md b/windows-implementation-plan.md new file mode 100644 index 0000000..8814d3b --- /dev/null +++ b/windows-implementation-plan.md @@ -0,0 +1,56 @@ +# Implementation Plan for `furumi-mount-windows` Client + +## Architectural Decision + +- **VFS Driver:** `WinFSP` (Windows File System Proxy). +- **Justification:** Excellent performance, perfect compatibility with the FUSE model, widely used in similar projects (e.g., rclone, sshfs-win). +- **Installation:** A unified installer (bundle) will be created (for example, using Inno Setup or WiX Toolkit), which will: + - Check if WinFSP is already installed. + - Automatically install the official `winfsp.msi` silently (using `/qn` flags) if the driver is missing. + - Install the `furumi-mount-windows.exe` client itself. + +--- + +## Implementation Details + +### 1. Application Scaffold +- Create a new binary crate `furumi-mount-windows` within the workspace. +- Add dependencies: `winfsp` (or `wfd`), `tokio`, `clap`, `tracing`, and an internal dependency on `furumi-client-core`. + +### 2. Entry Point (CLI) +- In `main.rs`, configure parsing for command-line arguments and environment variables (`--server`, `--token`, `--mount`), similar to `furumi-mount-macos`. +- Initialize the gRPC connection to the server via `furumi-client-core`. +- Configure directory mounting: + - As a network drive (e.g., `Z:`). + - Or as a transparent folder within an existing NTFS filesystem (depending on driver support/flags). + +### 3. VFS Implementation +- Create an `fs.rs` module. +- Implement the trait or callback structure required by WinFSP (e.g., the `WinFspFileSystem` structure). +- Action mapping: + - `GetFileInfo` / `GetSecurityByName` → gRPC `GetAttr` call. + - `ReadDirectory` → Streaming gRPC `ReadDir` call. + - `ReadFile` → `ReadFile` gRPC call (with support for stream chunking). +- **Crucial Part:** Translating Unix file attributes (from gRPC) into Windows File Attributes to ensure the system permits high-performance continuous stream reading (especially for media). + +### 4. Installer Creation +- Write a configuration script for a Windows installer builder (e.g., `windows/setup.iss` for Inno Setup). +- Neatly bundle both `winfsp-x.y.z.msi` and `furumi-mount-windows.exe` together. +- Add Custom Actions / Logic to: + - Check the Windows Registry for an existing WinFSP installation. + - Trigger the `winfsp.msi` installation conditionally. + +### 5. CI/CD Integration +- Update the GitHub Actions workflow (`docker-publish.yml` or create a dedicated release workflow). +- Add the target toolchain: `x86_64-pc-windows-msvc`. +- Add a step to compile: `cargo build --release --bin furumi-mount-windows`. +- Add a step to build the installer (e.g., `iscc setup.iss` or via `cargo-wix`). +- Output the final `setup.exe` as a GitHub Release artifact alongside other binaries. + +### 6. Testing Strategy +- Write unit tests in Rust covering attribute translation and path mapping (mapping slashes `/` to backslashes `\`). +- Manual System Testing: + - Start `furumi-server` locally. + - Run the installer on a clean Windows machine (VM without pre-installed WinFSP). + - Verify that the drive mounts correctly and seamlessly. + - Launch media playback (e.g., via VLC/mpv) to ensure streaming stability over the VFS connection.