Hi @Adam Togstad,
Thanks for the clear write-up and for separating the two remaining questions.
1. Directory CreateOptions compatibility
The published NtCreateFile documentation for user-mode applications and the corresponding NtCreateFile documentation in the WDK do not list FILE_OPEN_REPARSE_POINT among the options compatible with FILE_DIRECTORY_FILE.
Therefore, the public documentation does not establish that the exact directory combination
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT
is officially supported for local NTFS directory creation or opening. It also does not identify Windows-version, filesystem, filter, or parameter qualifications under which that combination is guaranteed to be supported.
The use of FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT by Go’s Windows Mkdirat implementation, and acceptance of the combination on particular Windows builds, are useful implementation evidence. The related Go vulnerability advisory also explains the security issue that motivated the change. However, neither source establishes that Microsoft’s published compatibility list is incomplete or provides a supported Windows contract for this combination.
2. Concurrent conversion of retained parent H
The NtCreateFile documentation states that, when RootDirectory is non-null, ObjectName is interpreted relative to the directory represented by that handle. The OBJECT_ATTRIBUTES documentation likewise describes RootDirectory as the optional handle to the root directory used for relative object names.
However, these documents do not define an atomic object/effect boundary between the relative NtCreateFile operation and a concurrent FSCTL_SET_REPARSE_POINT operation on that directory.
The public documentation therefore does not establish the requested object-or-refusal guarantee for the following timing cases:
Conversion completed before entry into NtCreateFile
The observed refusal is relevant behavior for the tested Windows build and NTFS configuration. However, the documentation does not state that refusal before creating an object elsewhere is the required outcome in every supported environment.
Conversion occurs during name resolution or insertion within NtCreateFile
The documentation does not identify the internal serialization point or state whether the relative lookup remains bound to the original directory object throughout the operation. It therefore does not establish that creation in the original directory and refusal before any external effect are the only possible outcomes.
Conversely, the documentation also does not establish that this exact single-component relative call can reparse the retained handle’s target and create outside the original directory. The conclusion supported by the public documentation is only that such an outcome cannot be excluded contractually.
Conversion occurs after child creation
The public documentation does not define a general ordering guarantee for this overlap. If creation in the original directory completes first, the subsequent conversion may fail because the directory is no longer empty, as observed in the test. That observation does not establish the outcome of every concurrent interleaving.
FILE_OPEN_REPARSE_POINT does not remove this uncertainty. The NtCreateFile documentation describes how the flag affects normal reparse-point processing, but it does not state that the reparse state of RootDirectory is frozen for the duration of the call. The broader Reparse Points and Reparse Points and File Operations documentation also does not define the requested concurrency boundary.
Accordingly, success within the original directory is consistent with the requested safety property, as is failure before any external creation. However, the public documentation does not establish that these are the only possible outcomes for every within-call interleaving.
This documentation gap affects the requested guarantee for both exact option combinations:
- Directory creation with
CreateOptions=0x00200021. - Regular-file creation with
CreateOptions=0x00200060.
For the directory combination, there is the additional issue that FILE_OPEN_REPARSE_POINT is absent from the documented compatibility list for FILE_DIRECTORY_FILE. For the regular-file combination, the individual options are documented, but their documentation still does not provide the requested concurrency or object/effect guarantee.
The public documentation identified above does not provide a supported-version matrix or a guarantee covering all local NTFS versions, Microsoft or third-party filesystem filters, access masks, sharing modes, and relevant reparse-processing interleavings. The results from Windows build 26300 should therefore be treated as observations for that tested configuration, not as evidence of a version-independent or filter-independent contract.
An authoritative determination of the internal serialization boundary, supported Windows and NTFS versions, filter qualifications, access and sharing prerequisites, and the status of the unlisted directory-option combination would require opening a Microsoft Support case so that the issue can be reviewed and routed through the appropriate Windows support and engineering channels.
If this instruction is applicable to your situation, I would greatly appreciate it if you could follow the instruction here so others experiencing similar behavior can benefit from it as well.