Rename IRP silently dropped after successful open with DELETE access - never forwarded to user-mode Rename callback
Environment
- WinFsp 2.1.25156.ddca7bd
- Windows 11 Pro (build 26200)
- User-mode file system: custom FS in Rust via winfsp-rust 0.13.0 (all FSP_FILE_SYSTEM_INTERFACE callbacks implemented)
- Drive letter mount
- VolumeParams: filesystem_name, case_sensitive_search=TRUE, case_preserved_names=TRUE, unicode_on_disk=TRUE, sector_size=512, sectors_per_allocation_unit=8, max_component_length=255, no_reparse_points_dir_check=TRUE, supports_posix_unlink_rename=TRUE
Symptom
All rename operations return STATUS_ACCESS_DENIED to the caller immediately. The rename IRP is never forwarded to the user-mode Rename callback — traced via entry-point logging on every callback.
What works on the same files
CreateFileW(file, DELETE_ACCESS)— succeeds, DELETE is in granted accessFileDispositionInformation(delete) viaSetDelete→Cleanup— works, file removed from backing store- create, read, write, flush, close — all work
- Directory rename also fails with the same ACCESS_DENIED
Control experiment (minimal stub FS, same driver, same volume params)
A minimal stub FS with only 4 required callbacks + rename on a fresh drive letter: rename works perfectly in all scenarios (fresh file, subdirectory file, leaked handles, concurrent polling). This rules out: driver version, volume params, caller behavior, handle leaks, oplock, concurrent access.
IRP sequences (traced from user-mode callbacks)
Stub FS (rename succeeds):
gsbn(source) → create(source)
gsbn(source) → open(source,128) ×3
gsbn(source) → open(source, DELETE=1114240)
gsbn(root) → open(root,1048578) ← driver opens target parent dir
gsbn(target) exists=false ← driver queries target
→ Rename callback invoked → SUCCESSApp FS (rename fails):
gsbn(source) → create(source)
[write + close + cleanup]
gsbn(source) → open(source,128) ×3
gsbn(source) → open(source, DELETE=1114240)
【nothing — driver never sends open(root) / gsbn(target) / rename】
Caller gets ERROR_ACCESS_DENIEDKey observation
The divergence point is between the successful open(source, DELETE) and the expected open(target_parent_dir) + gsbn(target_name) — meaning FspFsvolSetRenameInformation exits in driver-internal checks (PosixDelete flag at :1788 or RenameCheck at :1870 in fileinfo.c) before forwarding to user-mode.
What we've ruled out
- DACL/SD:
icaclsshows Everyone:(OI)(CI)(F) with explicit DELETE;open(source, DELETE)succeeds with DELETE in granted access - file_info_timeout: removed, still fails
PosixDeleteflag: fresh files with no prior delete attempts- Oplock: replicated oplock-hold + rename on stub, passes
- SetDelete/cleanup semantics: replicated on stub, passes
- Leaked handles: replicated on stub, passes
- Volume params: stub uses identical set, passes
Question
Is there a known issue in WinFsp 2.1 where FspFsvolSetRenameInformation can return ACCESS_DENIED without forwarding to user-mode when the FileNode was created by the user-mode FS? Could certain FileInfo field values (e.g. index_number, hard_links, ea_size) or the absence of a GetSecurityByName pattern trigger driver-internal rename checks to fail?
Happy to run experiments or provide additional traces.
Source: winfsp/winfsp