Share via

Folder-level "Free Up Space" remains disabled after on-demand hydration of a child placeholder. What is the platform's aggregation rule?

Ramesh Verma 20 Reputation points
2026-05-12T05:21:41.0366667+00:00

Environment

  • Windows 11 23H2 / 24H2 (also reproduced on Windows 10 22H2)
    • Sync provider built on the Cloud Files API (CFAPI), in-process; sync root registered via CfRegisterSyncRoot
    • Files are created as placeholders with CF_PIN_STATE_UNSPECIFIED; folders are created with CF_PIN_STATE_UNSPECIFIED
    • IShellNotifyAction.Changed (i.e. SHChangeNotify(SHCNE_UPDATEITEM, …)) is delivered correctly elsewhere in our provider

Reproduction

  1. In a synced folder, create one or more child files as placeholders (CF_PIN_STATE_UNSPECIFIED, dehydrated — i.e. all children are in the "Placeholder" state per Build a Cloud Sync Engine (https://learn.microsoft.com/windows/win32/cfapi/build-a-cloud-file-sync-engine#supported-features)).
  2. Right-click the parent folder in File Explorer. "Free up space" is correctly disabled (grey) — there is nothing locally cached to release.
  3. Double-click one of the placeholder files to trigger on-demand hydration. The provider services CF_CALLBACK_TYPE_FETCH_DATA, calls CfExecute with CF_OPERATION_TYPE_TRANSFER_DATA, and the call completes with STATUS_SUCCESS. The file becomes a "Full file" (UNSPECIFIED + cached, per the three-state model in the doc above). The file's own context menu now shows "Free up space" as enabled — confirming Windows knows it has cached bytes to release.
  4. Close the file. Right-click the parent folder again, or press F5, or navigate away and back.

Expected: the parent folder's "Free up space" entry becomes enabled, since at least one descendant has cached bytes that could be released. Actual: the parent folder's "Free up space" entry remains disabled (grey) until either:

  • the user explicitly invokes "Always keep on this device" on the child (transitioning it to CF_PIN_STATE_PINNED), or
    • the provider calls CfSetPinState(child, CF_PIN_STATE_PINNED) itself.
    Once any descendant is PINNED, the parent's "Free up space" entry lights up immediately, even without an explicit shell notification. What we've tried
  • Issuing SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, parentPath, NULL) on the parent folder from the FETCH_DATA callback after a successful transfer. (This is the same notification we issue from CfSetPinState flows, which works there.) For on-demand hydration this has no effect on the folder menu.
    • SHCNE_ATTRIBUTES and SHCNE_UPDATEDIR on the parent — also no effect.
  • Calling CfUpdatePlaceholder on the child with CF_UPDATE_FLAG_MARK_IN_SYNC (already done as part of our normal flow). No effect on the folder menu.
  • F5 / fresh Explorer window / ie4uinit -show / log off-on — none flip the folder menu to enabled. Only setting a descendant to PINNED does. What the docs say (and don't say)
  • The three file states are documented in Build a Cloud Sync Engine (https://learn.microsoft.com/windows/win32/cfapi/build-a-cloud-file-sync-engine#supported-features): Placeholder, Full file (UNSPECIFIED + cached), Pinned full file (PINNED + cached). The Full file state notes "could be dehydrated by the system if space is needed.
  • CF_PIN_STATE (https://learn.microsoft.com/windows/win32/api/cfapi/ne-cfapi-cf_pin_state) describes UNSPECIFIED as the platform can decide freely when the placeholder's content needs to present or absent locally on the disk.
  • Query and set Files On-Demand states (https://learn.microsoft.com/sharepoint/files-on-demand-windows) maps the user-facing states — "Always available" = Pinned, "Locally available" = Clearpin (UNSPECIFIED), "Online-only" = Unpinned — and notes "To set an online-only file or folder to 'locally available,' you must first set it to 'always available.'"
  • An existing Microsoft Q&A response (FAQ-2) (https://learn.microsoft.com/answers/a/12503334) notes that there is no documented API to force Explorer to refresh sync-icon UI.

What is not documented is the exact rule by which Explorer decides whether to enable the folder context menu's "Free up space" entry. Our empirical observation is that the folder entry is enabled if at least one descendant has CF_PIN_STATE_PINNED, regardless of whether other descendants are Full files with cached bytes. We would like to confirm or correct this.

Questions

  1. Is folder-level "Free up space" enablement defined by descendant pin state (PINNED) only, or by cached-bytes presence (Full file or Pinned full file)? Our observation is the former; we'd like definitive confirmation.
  2. If pin state, is this by design? A Full file (UNSPECIFIED + cached) is, per the three-state doc, eligible for system-initiated dehydration — yet the user cannot manually free that space at the folder level. The asymmetry between the file's own context menu (which is enabled) and the parent folder's (which is not) is surprising for end-users.
  3. Is there a sync-provider-side mechanism, short of pinning the file, to make a folder's "Free up space" entry reflect Full-file descendants? For example: a CfUpdatePlaceholder flag, a documented SHChangeNotify pattern, or a folder-level placeholder attribute we should be setting on hydration completion. Auto-pinning on on-demand hydration is not acceptable for our scenario because it would prevent the platform from reclaiming space automatically (defeating the purpose of Files On-Demand for our users).

If the answer to (3) is "no mechanism exists", that's a useful answer too — it would let us close this as a platform limitation and document the behavior for our users.

Thank you.

Windows development | Windows API - Win32
0 comments No comments

Answer accepted by question author

Taki Ly (WICLOUD CORPORATION) 1,500 Reputation points Microsoft External Staff Moderator
2026-05-12T09:23:41.07+00:00

Hello @Ramesh Verma ,

Thank you for sharing a detailed explanation. I have analyzed the Cloud Files API (CFAPI) architecture based on your observations and available Microsoft documentation.

I believe this might be a design choice to keep Windows Explorer running fast. As noted in the Build a Cloud Sync Engine documentation, there is a difference between a normal "Full file" (hydrated implicitly) and a "Pinned full file" (hydrated explicitly). If Explorer tried to check the actual downloaded size to find those normal "Full files" inside a folder, it would have to scan every single item. This could be very slow and might freeze the screen. Just looking for the "Pinned" flag is a much faster shortcut.

Because of this, there might not be a way for your sync app to change how this menu behaves. Calling commands like SHChangeNotify or CfUpdatePlaceholder probably won't help, as Explorer might just run its same quick check all over again. This also matches the Microsoft Q&A post you shared, which suggests there is no official way to force Explorer to act differently.

Since this looks like a limitation in Windows itself, you might want to add a small note in your user guide. You could suggest that users right-click individual files to free up space.

I hope this gives you a helpful perspective on the issue. Please let me know if you need anything else. If you found my response helpful, please follow this guide to provide feedback.

Thank you.

Was this answer helpful?

1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. AI answer

    2026-05-12T05:22:05.1933333+00:00

    Explorer’s folder-level “Free up space” behavior is not documented in detail, and the provided documentation does not define an aggregation rule based on cached bytes vs. pin state. From the available material, only the following can be stated:

    1. File states and pinning behavior
    • The platform exposes three effective user-visible states for Files On-Demand:
      • Online-only (Unpinned)
      • Locally available (Clearpin / UNSPECIFIED with cached content)
      • Always available (Pinned)
    • In CFAPI terms, pinning is controlled via CF_PIN_STATE:
      • CF_PIN_STATE_PINNED: provider is notified to fetch content; dehydration requests are rejected by the platform.
      • CF_PIN_STATE_UNPINNED: provider is notified to dehydrate/invalidate content.
      • CF_PIN_STATE_UNSPECIFIED: platform may decide freely when content is present or absent.
    • The Files On-Demand mapping explicitly treats “Always available” as Pinned, “Locally available” as Clearpin (UNSPECIFIED), and “Online-only” as Unpinned, and notes that to move an online-only item to “locally available” via script, it must first be set to “always available” (Pinned) and then cleared.

    This confirms that the platform’s primary control surface for user-driven space management is the pin state, not just the presence of cached bytes.

    1. What can be inferred about folder-level “Free up space”
    • The documentation describes:
      • Placeholder vs. full vs. pinned full files and emphasizes that pinned files are guaranteed offline and protected from dehydration.
      • CF_PIN_STATE_UNSPECIFIED as allowing the platform to decide when content is present or absent.
    • There is no description of a folder-level aggregation rule based on “any descendant has cached bytes” vs. “any descendant is pinned.”
    • There is also no documented API or SHChangeNotify pattern that instructs Explorer to treat a folder as having releasable space based on descendants that are merely “full” (UNSPECIFIED + cached) rather than pinned.

    Given this, the only behavior that can be grounded in the documentation is that pin state is the explicit, supported mechanism for controlling whether content is protected from dehydration (PINNED) or eligible for dehydration (UNPINNED/UNSPECIFIED). The folder-level “Free up space” enablement logic is not specified.

    1. Answers to the specific questions (within documented limits)
    1. Is folder-level enablement based on pin state only, or cached bytes?
    • The documentation does not define the folder-level aggregation rule for “Free up space.”
    • It does define pin states and their semantics, and it maps user-facing Files On-Demand states to pin states, but it does not state that Explorer’s folder menu uses cached-byte presence as a signal.
    1. If pin state, is this by design?
    • The design that is documented is:
      • Pinned items are guaranteed offline and not dehydrated by the platform.
      • Unspecified items can be hydrated/dehydrated automatically by the platform.
    • Whether Explorer’s folder menu intentionally ignores “full but unspecified” descendants is not described; only the pin-state semantics are.
    1. Is there a provider-side mechanism (short of pinning) to make folder “Free up space” reflect full-file descendants?
    • No such mechanism is documented in the provided material:
      • No CfUpdatePlaceholder flag is documented that would change folder-level “Free up space” behavior.
      • No special folder attribute or SHChangeNotify pattern is documented for this purpose.
      • A Microsoft Q&A answer explicitly notes that there is no documented API to force Explorer to refresh sync-icon UI; similarly, there is no documented API here to control folder-level “Free up space” enablement.

    Within the provided documentation, this must be treated as a platform behavior that is not configurable by the sync provider except via pin state. There is no documented way to have folder-level “Free up space” reflect descendants that are full (UNSPECIFIED + cached) without pinning.


    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.