P4-2: Windows provider — Cloud Filter API #45

Open
opened 2026-09-10 18:09:09 +00:00 by Cordy · 0 comments
Owner

Depends on P4-1. Requires the Windows runner (#19).

Goal

Implement vfs.PlaceholderFS on Windows using the Cloud Files API (CfAPI) — the same
mechanism OneDrive uses. Windows 10 1709 and later.

Why Windows first

Of the three platforms, Windows has the most mature and best-documented placeholder API, and
the largest share of the enterprise desktops this feature is aimed at. Getting the abstraction
right against a real OS here makes P4-3 and P4-4 easier.

What CfAPI gives you

  • CfRegisterSyncRoot / CfConnectSyncRoot — declare the folder as cloud-backed.
  • CfCreatePlaceholders — create metadata-only entries.
  • Hydration callbacksCF_CALLBACK_TYPE_FETCH_DATA fires when something reads a
    placeholder. You stream the content back with CfExecute.
  • CfSetPinState — the OS's own pin concept; map it onto vfs.PinState rather than inventing
    a parallel one, so "Always keep on this device" in Explorer does the expected thing.
  • Explorer shows hydration state natively — cloud icon, green tick — with no work from us.

Go and cgo — the constraint that bites

The repo is CGO_ENABLED=0 everywhere. CfAPI is a C API.

Resolve this before writing code, and record the decision in the issue:

  • golang.org/x/sys/windows with syscall.NewLazyDLL / NewProc to call cldapi.dll
    directly — keeps CGO_ENABLED=0. Preferred. The callback registration is the hard part;
    verify it is reachable this way before committing to it.
  • A cgo shim, Windows-only, behind a build tag — works, but breaks the project-wide
    CGO_ENABLED=0 rule and complicates cross-compilation. Only if the first genuinely cannot
    work.

Whichever you choose, it must not leak past internal/vfs. The engine never learns Windows
exists.

Traps

  • Callbacks run on OS threads. Use runtime.LockOSThread where required and never block a
    fetch callback on a slow network without reporting progress — Explorer will appear frozen.
  • Report progress with CfReportProviderProgress, or large hydrations look like a hang.
  • Hydration must be cancellable. A user who opens a 4 GB file and changes their mind must
    not wedge Explorer.
  • The sync root must be re-registered after an update or reboot; handle an already-registered
    root idempotently.
  • Uninstall must unregister the sync root and either hydrate or clean up placeholders.
    Orphaned placeholders after uninstall are files the user can see and never open — which reads
    exactly like data loss.

Steps

  • Decide and document the cgo-free approach.
  • Register/connect the sync root; handle re-registration.
  • Implement CreatePlaceholder, Hydrate, Dehydrate, SetPin, Pin.
  • Wire the fetch callback to the remote.Remote ranged GET.
  • Wire watcher suppression during hydration (issue #31 amendment).
  • Handle uninstall cleanly.
  • Test on a real Windows machine: create 1,000 placeholders, confirm Explorer shows them,
    open one, confirm only that one hydrates.
  • Commit: git commit -s -m "feat(vfs): Windows Cloud Filter placeholder provider"

Acceptance criteria

  • Placeholders appear in Explorer with correct size and cloud status icon.
  • Opening one file hydrates exactly that file.
  • "Always keep on this device" and "Free up space" in Explorer map to our pin states.
  • Cancelling a large hydration leaves Explorer responsive.
  • Uninstall leaves no orphaned placeholders.
  • internal/sync is unchanged.
Depends on P4-1. Requires the Windows runner (#19). ## Goal Implement `vfs.PlaceholderFS` on Windows using the **Cloud Files API (CfAPI)** — the same mechanism OneDrive uses. Windows 10 1709 and later. ## Why Windows first Of the three platforms, Windows has the most mature and best-documented placeholder API, and the largest share of the enterprise desktops this feature is aimed at. Getting the abstraction right against a real OS here makes P4-3 and P4-4 easier. ## What CfAPI gives you - `CfRegisterSyncRoot` / `CfConnectSyncRoot` — declare the folder as cloud-backed. - `CfCreatePlaceholders` — create metadata-only entries. - **Hydration callbacks** — `CF_CALLBACK_TYPE_FETCH_DATA` fires when something reads a placeholder. You stream the content back with `CfExecute`. - `CfSetPinState` — the OS's own pin concept; map it onto `vfs.PinState` rather than inventing a parallel one, so "Always keep on this device" in Explorer does the expected thing. - Explorer shows hydration state natively — cloud icon, green tick — with no work from us. ## Go and cgo — the constraint that bites The repo is `CGO_ENABLED=0` everywhere. CfAPI is a C API. **Resolve this before writing code**, and record the decision in the issue: - `golang.org/x/sys/windows` with `syscall.NewLazyDLL` / `NewProc` to call `cldapi.dll` directly — keeps `CGO_ENABLED=0`. **Preferred.** The callback registration is the hard part; verify it is reachable this way before committing to it. - A cgo shim, Windows-only, behind a build tag — works, but breaks the project-wide `CGO_ENABLED=0` rule and complicates cross-compilation. Only if the first genuinely cannot work. Whichever you choose, **it must not leak past `internal/vfs`.** The engine never learns Windows exists. ## Traps - **Callbacks run on OS threads.** Use `runtime.LockOSThread` where required and never block a fetch callback on a slow network without reporting progress — Explorer will appear frozen. - **Report progress** with `CfReportProviderProgress`, or large hydrations look like a hang. - **Hydration must be cancellable.** A user who opens a 4 GB file and changes their mind must not wedge Explorer. - **The sync root must be re-registered after an update or reboot**; handle an already-registered root idempotently. - **Uninstall must unregister the sync root** and either hydrate or clean up placeholders. Orphaned placeholders after uninstall are files the user can see and never open — which reads exactly like data loss. ## Steps - [ ] Decide and document the cgo-free approach. - [ ] Register/connect the sync root; handle re-registration. - [ ] Implement `CreatePlaceholder`, `Hydrate`, `Dehydrate`, `SetPin`, `Pin`. - [ ] Wire the fetch callback to the `remote.Remote` ranged GET. - [ ] Wire watcher suppression during hydration (issue #31 amendment). - [ ] Handle uninstall cleanly. - [ ] Test on a real Windows machine: create 1,000 placeholders, confirm Explorer shows them, open one, confirm only that one hydrates. - [ ] Commit: `git commit -s -m "feat(vfs): Windows Cloud Filter placeholder provider"` ## Acceptance criteria - Placeholders appear in Explorer with correct size and cloud status icon. - Opening one file hydrates exactly that file. - "Always keep on this device" and "Free up space" in Explorer map to our pin states. - Cancelling a large hydration leaves Explorer responsive. - Uninstall leaves no orphaned placeholders. - `internal/sync` is unchanged.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/cairn-desktop#45
No description provided.