NtCreateFile: Is FILE_DIRECTORY_FILE compatible with FILE_OPEN_REPARSE_POINT for secure directory creation?

Suresh kumar V 0 Reputation points
2026-11-06T12:00:54.26+00:00

Dear Microsoft Windows Developer Support Team,

We are developing a Windows desktop application that requires secure directory creation using native Windows filesystem APIs.

During our implementation review, we identified an ambiguity in Microsoft's published NtCreateFile documentation regarding the compatibility of FILE_DIRECTORY_FILE and FILE_OPEN_REPARSE_POINT.

We have reviewed the official Windows API documentation, relevant Microsoft Q&A discussions, and the Go programming language's Windows filesystem implementation.

We request clarification from the Windows filesystem/API engineering team regarding the following.

1. Exact API Combination

Our proposed implementation uses NtCreateFile with:

  • FILE_DIRECTORY_FILE (0x00000001)

FILE_SYNCHRONOUS_IO_NONALERT (0x00000020)

FILE_OPEN_REPARSE_POINT (0x00200000)

Combined CreateOptions: 0x00200021

The operation uses:

A retained parent-directory handle through OBJECT_ATTRIBUTES.RootDirectory.

A fixed single-component relative directory name.

FILE_CREATE for strict collision handling.

An explicit protected security descriptor during creation.

A subsequent independent relative reopen using FILE_OPEN.

Microsoft's published documentation lists options compatible with FILE_DIRECTORY_FILE but does not include FILE_OPEN_REPARSE_POINT.

2. Existing Implementation Evidence

We observed that the Go programming language's Windows implementation uses related combinations:

Go Mkdirat: FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT

CreateOptions: 0x00200001

Go directory Symlinkat: FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT

CreateOptions: 0x00204021

Reference: https://go.dev/src/internal/syscall/windows/at_windows.go

We recognize that these implementations do not constitute Microsoft's formal API support commitment and do not exactly match our proposed operation.

3. Clarification Requested

We would appreciate confirmation of the following:

Q1. Is CreateOptions 0x00200021 officially supported for directory creation and reopening through user-mode NtCreateFile?

Q2. If supported, which Windows versions and filesystems are covered?

Q3. When RootDirectory references a retained directory handle and ObjectName contains one relative component, what guarantees exist against unintended reparse-point traversal?

Q4. Does the API guarantee that creation remains bound to the originally opened parent directory, or fails, if another process concurrently substitutes or converts a directory entry into a junction or another reparse point?

Q5. Is OBJ_DONT_REPARSE a supported and documented alternative for this use case?

Q6. If the proposed combination is not officially supported, what alternative API sequence is recommended that preserves all of the following?

Parent-handle-relative directory creation.

Prevention of unintended reparse-point traversal.

Strict collision handling.

Creation-time security descriptor application.

Independent verification of the resulting directory identity.

Q7. Are there any limitations associated with filesystem filter drivers, NTFS reparse points, or specific Windows builds?

4. Requested Engineering Guidance

We would appreciate an authoritative Microsoft API reference, written engineering clarification, or recommendation identifying the supported implementation.

Our objective is to use a documented and maintainable filesystem security design suitable for deployment across customer Windows environments.

We can provide a minimal, non-confidential reproducer if required.

Thank you for your assistance.

Best regards,

Software Development TeamDear Microsoft Windows Developer Support Team,

We are developing a Windows desktop application that requires secure directory creation using native Windows filesystem APIs.

During our implementation review, we identified an ambiguity in Microsoft's published NtCreateFile documentation regarding the compatibility of FILE_DIRECTORY_FILE and FILE_OPEN_REPARSE_POINT.

We have reviewed the official Windows API documentation, relevant Microsoft Q&A discussions, and the Go programming language's Windows filesystem implementation.

We request clarification from the Windows filesystem/API engineering team regarding the following.

1. Exact API Combination

Our proposed implementation uses NtCreateFile with:

FILE_DIRECTORY_FILE (0x00000001)

FILE_SYNCHRONOUS_IO_NONALERT (0x00000020)

FILE_OPEN_REPARSE_POINT (0x00200000)

Combined CreateOptions: 0x00200021

The operation uses:

A retained parent-directory handle through OBJECT_ATTRIBUTES.RootDirectory.

A fixed single-component relative directory name.

FILE_CREATE for strict collision handling.

An explicit protected security descriptor during creation.

A subsequent independent relative reopen using FILE_OPEN.

Microsoft's published documentation lists options compatible with FILE_DIRECTORY_FILE but does not include FILE_OPEN_REPARSE_POINT.

2. Existing Implementation Evidence

We observed that the Go programming language's Windows implementation uses related combinations:

Go Mkdirat:
FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT

CreateOptions: 0x00200001

Go directory Symlinkat:
FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT

CreateOptions: 0x00204021

Reference:
https://go.dev/src/internal/syscall/windows/at_windows.go

We recognize that these implementations do not constitute Microsoft's formal API support commitment and do not exactly match our proposed operation.

3. Clarification Requested

We would appreciate confirmation of the following:

Q1. Is CreateOptions 0x00200021 officially supported for directory creation and reopening through user-mode NtCreateFile?

Q2. If supported, which Windows versions and filesystems are covered?

Q3. When RootDirectory references a retained directory handle and ObjectName contains one relative component, what guarantees exist against unintended reparse-point traversal?

Q4. Does the API guarantee that creation remains bound to the originally opened parent directory, or fails, if another process concurrently substitutes or converts a directory entry into a junction or another reparse point?

Q5. Is OBJ_DONT_REPARSE a supported and documented alternative for this use case?

Q6. If the proposed combination is not officially supported, what alternative API sequence is recommended that preserves all of the following?

Parent-handle-relative directory creation.

Prevention of unintended reparse-point traversal.

Strict collision handling.

Creation-time security descriptor application.

Independent verification of the resulting directory identity.

Q7. Are there any limitations associated with filesystem filter drivers, NTFS reparse points, or specific Windows builds?

4. Requested Engineering Guidance

We would appreciate an authoritative Microsoft API reference, written engineering clarification, or recommendation identifying the supported implementation.

Our objective is to use a documented and maintainable filesystem security design suitable for deployment across customer Windows environments.

We can provide a minimal, non-confidential reproducer if required.

Thank you for your assistance.

Best regards,

Software Development Team

Windows development | Windows API - Win32
0 comments No comments

1 answer

Sort by: Most helpful
  1. Gatlin Le (WICLOUD CORPORATION) 1,470 Reputation points Microsoft External Staff Moderator
    2026-11-09T06:54:50.38+00:00

    Hi @Suresh kumar V ,

    The current NtCreateFile reference does not document 0x00200021 as a compatible combination. The FILE_DIRECTORY_FILE entry says the other compatible options include only FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_NONALERT, FILE_WRITE_THROUGH, FILE_OPEN_FOR_BACKUP_INTENT and FILE_OPEN_BY_FILE_ID, and the Remarks state that the call fails if inconsistent CreateOptions are specified. FILE_OPEN_REPARSE_POINT is not in that list, and I found no published Windows version or filesystem coverage for this combination. The local test below shows it is accepted on one build, which is observed behavior rather than a support statement.

    On reparse handling, the same page documents that a non-NULL RootDirectory makes ObjectName relative to that directory, that FILE_CREATE fails if the name already exists, and that ACLs from the supplied security descriptor are applied only when the object is created. FILE_OPEN_REPARSE_POINT is described as skipping normal reparse processing and opening the reparse point itself when the target is one. It does not make the call fail when a reparse point is encountered, and none of these descriptions covers concurrent substitution of the parent.

    To check the concurrency question, I ran a local test on Windows 11 build 26300.9457, local NTFS, calling NtCreateFile relative to a retained parent handle with FILE_CREATE, CreateOptions 0x00200021, DesiredAccess 0x00130081, ShareAccess 0x00000007 and a protected security descriptor. The create mask is DELETE | READ_CONTROL | SYNCHRONIZE | FILE_LIST_DIRECTORY | FILE_READ_ATTRIBUTES, where DELETE was included only to clean up the test directories through the handle. The parent handle was opened with 0x001200A5 and the independent reopen used 0x00120081, both with ShareAccess 0x00000007. The directory was created with the protected DACL, and the independent relative reopen matched its identity. A second thread in the same process then acted as the competitor. While the parent directory entry was repeatedly swapped, all 5,000 creates succeeded and every reopen matched. While the parent was converted in place into a junction, 2,519 creates succeeded and 2,481 failed with STATUS_REPARSE_POINT_NOT_RESOLVED. No create was observed at the junction target, and every successful reopen matched. These results cover one build, local NTFS, the filters present on the test machine and bounded schedules, so they do not establish the guarantee you describe in Q4.

    OBJ_DONT_REPARSE is documented on the OBJECT_ATTRIBUTES page as failing with STATUS_REPARSE_POINT_ENCOUNTERED when a reparse is encountered, while the user-mode NtCreateFile page lists only zero or OBJ_CASE_INSENSITIVE for Attributes. In my test, opening a final-component junction with OBJ_DONT_REPARSE alone returned STATUS_REPARSE_POINT_ENCOUNTERED, but combining it with FILE_OPEN_REPARSE_POINT opened the junction itself. When the two flags are combined, OBJ_DONT_REPARSE should therefore not be treated as proof that the returned object has no reparse point. The create race scenarios above did not include OBJ_DONT_REPARSE.

    As for an alternative sequence, I did not find one documented to preserve all five requirements together. For independent verification, keep the creation handle open, compare the volume serial number and file ID against the reopened handle as described in FILE_ID_INFO, and check the directory and reparse attributes through GetFileInformationByHandleEx with FileAttributeTagInfo. As a negative control, replacing the child between creation and reopen made both opens succeed with different IDs, which is exactly the mismatch this check is meant to catch. A match identifies the object at that moment. It does not prevent later modification or undo a directory created elsewhere.

    For filter drivers, ReFS, SMB and other Windows builds (Q7), I found no published qualification matrix, and my test does not cover them beyond the filters already present on the test machine.

    My support here is limited to documentation research and testing on this Q&A forum, and I cannot provide an official support statement on behalf of the Windows filesystem team. For authoritative confirmation, please sign in to Microsoft Engage Center with an account that has an eligible support plan.

    I hope that the test results and documentation I’ve shared can be of some help and provide a little more clarity around the behavior you’re investigating. 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.

    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.