-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
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