{"id":48725561,"url":"https://github.com/itswindows11/owlmount","last_synced_at":"2026-04-11T22:01:12.368Z","repository":{"id":350081508,"uuid":"1203942181","full_name":"itsWindows11/OwlMount","owner":"itsWindows11","description":"Experiment for OwlCore.Storage abstraction for mounting implementations as drives.","archived":false,"fork":false,"pushed_at":"2026-04-08T21:11:14.000Z","size":160,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-08T21:13:59.062Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itsWindows11.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"itsWindows11"}},"created_at":"2026-04-07T14:35:06.000Z","updated_at":"2026-04-08T17:21:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/itsWindows11/OwlMount","commit_stats":null,"previous_names":["itswindows11/owlmount"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/itsWindows11/OwlMount","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsWindows11%2FOwlMount","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsWindows11%2FOwlMount/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsWindows11%2FOwlMount/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsWindows11%2FOwlMount/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itsWindows11","download_url":"https://codeload.github.com/itsWindows11/OwlMount/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsWindows11%2FOwlMount/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31696743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T21:17:31.016Z","status":"ssl_error","status_checked_at":"2026-04-11T21:17:24.556Z","response_time":54,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-11T22:00:48.260Z","updated_at":"2026-04-11T22:01:12.361Z","avatar_url":"https://github.com/itsWindows11.png","language":"C#","funding_links":["https://github.com/sponsors/itsWindows11"],"categories":[],"sub_categories":[],"readme":"# OwlMount\n\nMount any filesystem in the universe as a Windows drive using WinFsp!\n\nOwlMount is a Windows-only .NET 10 portable console application that mounts any\n[OwlCore.Storage](https://github.com/Arlodotexe/OwlCore.Storage) `IFolder` implementation as a\nWindows drive letter using [WinFsp](https://winfsp.dev).\n\n## Features (MVP)\n\n* **Read/write mounts where supported** — mutable providers are exposed as writable drives\n* **Forced read-only mode** — pass `--read-only` to mount any provider as read-only\n* **Live refresh where supported** — providers that expose `IFolderWatcher` push folder changes into the mounted drive view\n* **Immutable providers stay read-only** — providers such as `kubo-ipfs` are mounted read-only by capability\n* **Block cache** — 256 KiB blocks persisted to disk under\n  `%LocalAppData%\\OwlMount\\Cache\\` to avoid re-downloading data\n* **Adapter registry** — plug in custom `IRangeReader` / `ISizeProvider`\n  implementations for specific provider types without touching core VFS logic\n* **Path index** — in-memory normalized-path → entry map populated during\n  directory enumeration; avoids redundant provider look-ups\n* **Directory cache** — short TTL (15 s default) per-folder listing cache for\n  snappy Explorer browsing\n* **In-memory provider** — zero-config drive backed by `OwlCore.Storage.Memory`; great for testing and ephemeral scratch space\n* **Archive provider** — mount a local archive file as a browsable read-only drive\n\n## Prerequisites\n\n1. **.NET 10 SDK** — \u003chttps://dot.net\u003e\n2. **WinFsp** (Windows File System Proxy) must be installed on the host machine:\n   * Download the latest MSI from \u003chttps://winfsp.dev/rel/\u003e\n   * Minimal install: *WinFsp Core* component is sufficient\n\n## Building\n\n```bash\ngit clone https://github.com/itsWindows11/OwlMount\ncd OwlMount\ndotnet build\n```\n\n## Running\n\n```\nowlmount mount --provider memory --letter R\n```\n\n### Mount options\n\n| Flag | Default | Description |\n|---|---|---|\n| `--provider` | `memory` | Provider name. See table below. |\n| `--letter` | `M` | Drive letter to mount (without the colon) |\n| `--label` | *(auto)* | Volume label shown in Explorer (e.g. `\"My Files\"`) |\n| `--read-only` | `false` | Force the mount to open as read-only, even if the provider supports writes |\n\nPressing **Ctrl+C**, running `owlmount unmount --letter \u003cX\u003e` from another terminal, or ejecting/unmounting the drive from Windows Explorer all cleanly exit the process.\n\n### Subcommands\n\n| Command | Description |\n|---|---|\n| `mount` | Mount a provider as a drive letter |\n| `unmount --letter \u003cX\u003e` | Unmount a running mount by drive letter |\n| `list` | List all active mounts and their PIDs |\n\n### Supported providers\n\n| `--provider` | Default access | Extra flags | Description |\n|---|---|---|---|\n| `memory` | Read/write | *(none)* | Empty in-memory filesystem (default; lives until process exits) |\n| `archive` | Read-only | `--archive-file \u003clocal-archive-path\u003e` | Mount a local archive file as a browsable filesystem |\n| `kubo-mfs` | Read/write | `--path \u003cmfs-path\u003e` `[--api-url]` | Kubo MFS (Mutable File System) |\n| `kubo-ipfs` | Read-only | `--cid \u003cCID\u003e` `[--api-url]` | Immutable IPFS directory by CID |\n| `kubo-ipns` | Read/write | `--ipns \u003caddress\u003e` `[--api-url]` | IPNS-addressed directory |\n| `s3` | Read/write | `--bucket` `[--prefix]` `[--access-key]` `[--secret-key]` `[--region]` `[--endpoint]` | Amazon S3 bucket/prefix |\n| `nfs` | Read/write | `--host \u003cip\u003e` `--export \u003c/path\u003e` `[--nfs-path \u003cpath\u003e]` | NFS v3 share |\n\n\u003e Pass `--read-only` with any provider to suppress write support for that mount.\n\u003e\n\u003e Live folder refresh is enabled only for providers and folders that successfully expose `IFolderWatcher`; unsupported providers continue to rely on cache TTL and local invalidation.\n\u003e\n\u003e The `archive` provider is mounted read-only and reports volume capacity using the current free space on the local disk that stores the archive file.\n\u003e\n\u003e **OneDrive** is supported as a code-level provider (`OneDriveFolder` / `OneDriveFile` from `OwlCore.Storage.OneDrive`) but requires a pre-authenticated `GraphServiceClient` from MSAL — see the *Adding a custom provider* section.\n\n### Example — empty in-memory filesystem as `R:`\n\n```bat\nowlmount mount --provider memory --letter R --label \"RAM Drive\"\n```\n\nThe drive starts completely empty. Any files or folders you copy into `R:\\` exist only in RAM and are gone when the process exits. Unmount from a second terminal, or eject from Explorer:\n\n```bat\nowlmount unmount --letter R\n```\n\n### Example — same in-memory filesystem forced read-only\n\n```bat\nowlmount mount --provider memory --letter R --label \"RAM Drive\" --read-only\n```\n\n### Example — archive file as `A:`\n\n```bat\nowlmount mount --provider archive --archive-file C:\\data\\backup.zip --letter A\n```\n\nMounts the contents of a local archive file as a read-only drive.\n\n### Example — Kubo MFS as `K:`\n\n```bat\nowlmount mount --provider kubo-mfs --path / --letter K --label \"IPFS Files\"\n```\n\nRequires a running Kubo daemon (default API: `http://127.0.0.1:5001`). Override with `--api-url`.\n\n### Example — S3 bucket as `S:`\n\n```bat\nowlmount mount --provider s3 --bucket my-bucket --prefix data/ --letter S ^\n  --access-key AKIA... --secret-key secret --region us-east-1\n```\n\n### Example — NFS share as `N:`\n\n```bat\nowlmount mount --provider nfs --host 192.168.1.10 --export /srv/share --letter N\n```\n\n## Architecture\n\n```\nOwlMount.slnx\n├── src/\n│   ├── OwlMount.Core/            Cross-platform .NET 10 library\n│   │   ├── Abstractions/         IRangeReader, ISizeProvider, PathIndexEntry\n│   │   ├── Cache/                BlockCache (disk-backed, block-sized reads)\n│   │   ├── Index/                PathIndex (in-memory normalized-path map)\n│   │   └── Registry/             RangeReaderRegistry, SizeProviderRegistry,\n│   │                             DefaultRangeReader, DefaultSizeProvider\n│   └── OwlMount.WinFspHost/      Windows-only .NET 10 console app\n│       ├── OwlMountFileSystem.cs WinFsp FileSystemBase implementation\n│       ├── DirectoryCache.cs     TTL-based per-folder listing cache\n│       ├── Contexts.cs           FileContext / FolderContext open-handle objects\n│       └── Program.cs            CLI entry point\n└── tests/\n    └── OwlMount.Tests/           Cross-platform xUnit tests\n        ├── PathNormalizationTests.cs\n        └── BlockCacheTests.cs\n```\n\n### Adding a custom provider\n\n1. Create a class implementing `OwlCore.Storage.IFolder` (and `IFile` for its children).\n2. Instantiate your `IFolder` in `Program.cs` (or wire it via DI) and pass it to\n   `OwlMountFileSystem`.\n3. Optionally register a provider-specific `IRangeReader` for optimised ranged reads:\n\n```csharp\nrangeReaders.Register(\n    matcher: f =\u003e f is MyCustomFile,\n    reader:  new MyCustomRangeReader());\n```\n\n### Block cache location\n\n```\n%LocalAppData%\\OwlMount\\Cache\\\u003cproviderId\u003e\\\u003cfileHash\u003e_\u003cblockIndex\u003e.blk\n```\n\nBlock size defaults to **256 KiB**; pass a custom value to the `BlockCache` constructor.\n\n## Running Tests\n\n```bash\ndotnet test tests/OwlMount.Tests/\n```\n\nTests are cross-platform and do not require WinFsp or Windows.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitswindows11%2Fowlmount","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitswindows11%2Fowlmount","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitswindows11%2Fowlmount/lists"}