Skip to content

windows: FILE_DISPOSITION_POSIX_SEMANTICS is not supported on FAT filesystems #16497

@squeek502

Description

@squeek502

Zig Version

0.11.0-dev.4059+17255bed4

Steps to Reproduce and Observed Behavior

#15501 made std.os.windows.DeleteFile use NtSetInformationFile with FILE_DISPOSITION_POSIX_SEMANTICS if builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs1).

However, this flag is only supported if the underlying filesystem is NTFS. On FAT filesystems, calling NtSetInformationFile with FILE_DISPOSITION_POSIX_SEMANTICS results in STATUS_INVALID_PARAMETER:

E:\zigstd\lib\std\os\windows.zig:975:31: 0x7ff6cd6687a1 in DeleteFile (test.exe.obj)
        .INVALID_PARAMETER => unreachable,
                              ^
E:\zigstd\lib\std\os.zig:2463:30: 0x7ff6cd53d593 in unlinkatW (test.exe.obj)
    return windows.DeleteFile(sub_path_w, .{ .dir = dirfd, .remove_dir = remove_dir });
                             ^

To avoid this, it should be possible to use NtQueryVolumeInformationFile before the NtSetInformationFile in std.os.windows.DeleteFile with FileFsAttributeInformation/FILE_FS_ATTRIBUTE_INFORMATION. The FileSystemAttributes can then be checked for FILE_SUPPORTS_POSIX_UNLINK_RENAME.

Tested to make sure the FILE_SUPPORTS_POSIX_UNLINK_RENAME flag works the expected way using the higher level Windows APIs in C:

#include <windows.h>
#include <fileapi.h>
#include <stdio.h>
#include <winnt.h>

int main() {
	HANDLE file = CreateFile("build.zig", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if (file == INVALID_HANDLE_VALUE) {
		exit(1);
	}

	DWORD flags;
	BOOL result = GetVolumeInformationByHandleW(file, NULL, 0, NULL, NULL, &flags, NULL, 0);
	if (result == 0) {
		exit(1);
	}

	printf("supports posix unlink: %d\n", (flags & FILE_SUPPORTS_POSIX_UNLINK_RENAME) != 0);

	CloseHandle(file);
}

On NTFS:

C:\Users\Ryan\Programming\Zig\tmp> volume.exe
supports posix unlink: 1

On FAT:

E:\zigtest> "C:\Users\Ryan\Programming\Zig\tmp\volume.exe"
supports posix unlink: 0

Expected Behavior

std.fs delete APIs to work on FAT filesystems on Windows

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavioros-windowsMicrosoft Windowsstandard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions