Hi @Mesut Topal ,
Two of your three items can be answered more concretely from the Windows file system algorithms specification than from the API reference pages, because the protection you measured comes from sharing and rename rules rather than from a directory handle contract. I also ran the relevant cases locally, and the results follow those rules.
[MS-FSA] describes the object store behavior that Windows file systems implement. Its sharing check for an existing stream or directory runs only when the new open requests FILE_READ_DATA, FILE_EXECUTE, FILE_WRITE_DATA, FILE_APPEND_DATA or DELETE, and an existing open counts only if its own granted access contains one of those bits. The dwShareMode description in CreateFileW, which you already listed as D3, says the same from the caller side: access requests to attributes are not affected by the share mode, and delete access covers both delete and rename. FileRenameInformation fails with STATUS_ACCESS_DENIED unless the open was granted DELETE, and also fails with STATUS_ACCESS_DENIED when the directory being renamed has open files anywhere beneath it.
For namespace continuity (PO-01), I would classify it as Conditional. A held handle prevents rename or move of the directory it names only when it carries one of those data access bits and omits FILE_SHARE_DELETE. 0x00100081 qualifies through FILE_LIST_DIRECTORY, which uses the same bit as FILE_READ_DATA. 0x80 does not, so a metadata-only handle gives no rename protection to its own directory. That matches your Win32 32 with share3 and the successful move with share7. Ancestors are covered by the second rule instead: any open beneath an ancestor, including a 0x80 handle, makes renaming that ancestor fail, which matches your Win32 5.
The other conditions you listed follow from the same rules. FILE_DELETE_CHILD on the containing parent can grant DELETE during the access check, but the sharing check still runs afterwards, so it should not bypass the guard. If a DELETE-capable open already exists, your guard open fails with a sharing violation, so acquisition fails closed, although that says nothing about where the directory was before the guard existed. Sharing state is tracked per file rather than per name, so an 8.3 short name should reach the same check. I did not test the FILE_DELETE_CHILD or 8.3 cases.
Two limits matter here. [MS-FSA] is a protocol specification, not a version-qualified Win32 API contract, and its rename rule for open files beneath a directory carries product behavior notes. Kernel-mode callers can also pass IO_IGNORE_SHARE_ACCESS_CHECK to IoCreateFileEx, which tells the I/O manager to skip its share-access check, although the documentation notes the file system might still perform it.
As for the guard handoff (PO-03), I would also classify it as Conditional. The original 0x00120080 handle contains no data access bits, so under the sharing rule above it never takes part in a sharing check. Its share1 mode has no effect, and another caller with DELETE permission can open and move the new directory while you hold that handle. A handoff to a second handle cannot close that gap, because the directory may already have moved by the time the second open runs. A simpler design is to request the guard access in the creating call itself, for example DesiredAccess 0x00120081 with a share mode that omits FILE_SHARE_DELETE. The creating handle then acts as the guard from the moment the directory exists, and no handoff is needed.
To check these points, I ran two separate x64 processes on local NTFS, Windows build 26300.9457, which differs from your build. While the original 0x00120080/share1 handle stayed open, the second process opened the new child for DELETE and moved it outside the parent, and the creating handle then reported the new path with the same volume serial and File ID. With 0x00120081/share1 at creation, that DELETE open failed with Win32 32, and with 0x00120081/share7 the move succeeded again. A parent held with 0x80/share3 could itself be moved, while 0x00100081/share3 blocked the DELETE open with Win32 32. Holding only a 0x80 handle on the parent made renaming its ancestor fail with Win32 5. When the other process already held a DELETE handle with share7, opening a 0x00100081/share3 guard returned 0xC0000043 (STATUS_SHARING_VIOLATION), while the same open with share7 succeeded. After the blocking handles were closed, every blocked rename or guard open succeeded, which rules out permissions or destination problems. Both processes used restricted medium-integrity tokens with the Administrators group set to deny-only, not a separate standard-user logon. These results confirm the sharing and rename behavior on this configuration only. They do not cover an atomic handoff, first-mutation ordering, your build or other Windows versions.
For reparse rejection (PO-02), I found no published statement covering packaged full-trust processes, but two documented points may help alongside OBJ_DONT_REPARSE. The RedirectionGuard mitigation, enabled through SetProcessMitigationPolicy, prevents the process from following file system junctions created by non-admin users. It can act as a process-wide backstop, but it covers junctions only. Your fixtures also ran with Developer Mode enabled, and in that mode CreateSymbolicLinkW lets non-elevated processes create symbolic links with SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE. Whether symbolic links belong in your threat model on customer machines therefore depends partly on that setting. I did not test either point in this round.
Everything above is what I could observe and collect within this Q&A thread, from the published specifications and API references I could find and from my own local tests on one configuration. That is the limit of what I can confirm here, and I cannot give an official support statement on behalf of the Windows team. If you need a version-qualified statement, or confirmation of the first-mutation ordering and filter coverage, Windows Developer Support, under technical support for app platforms and Windows SDK, is the route for that.
I hope the test results and documentation above help explain the behavior and give you a clear way to troubleshoot the issue. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guidance so that others in the community facing a similar issue can find it more easily and help each other.
Thank you.