Skip to content

Commit 8adb3b7

Browse files
committed
One way to handle posix semantics
1 parent a0a17b7 commit 8adb3b7

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed

lib/std/os/windows.zig

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -939,8 +939,35 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
939939
}
940940
defer CloseHandle(tmp_handle);
941941

942-
if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs1)) {
943-
// Deletion with posix semantics.
942+
const use_posix_semantics = supports_posix_semantics: {
943+
if (!comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs1)) {
944+
break :supports_posix_semantics false;
945+
}
946+
947+
// We provide exactly a FILE_FS_ATTRIBUTE_INFORMATION even though
948+
// the FileSystemName would need extra bytes to write into because
949+
// we don't care about the FileSystemName and only want the flags.
950+
// In theory FILE_FS_VOLUME_FLAGS_INFORMATION could be used here but
951+
// it was returning STATUS_ACCESS_DENIED (maybe it needs admin permissions?)
952+
var volume_info: FILE_FS_ATTRIBUTE_INFORMATION = undefined;
953+
rc = ntdll.NtQueryVolumeInformationFile(
954+
tmp_handle,
955+
&io,
956+
&volume_info,
957+
@sizeOf(FILE_FS_ATTRIBUTE_INFORMATION),
958+
.FileFsAttributeInformation,
959+
);
960+
switch (rc) {
961+
// Buffer overflow is expected since we don't provide enough space for the FileSystemName
962+
.SUCCESS, .BUFFER_OVERFLOW => {},
963+
else => return unexpectedStatus(rc),
964+
}
965+
966+
break :supports_posix_semantics volume_info.FileSystemAttributes & FILE_SUPPORTS_POSIX_UNLINK_RENAME != 0;
967+
};
968+
969+
if (use_posix_semantics) {
970+
// Deletion with posix semantics if the filesystem supports it.
944971
var info = FILE_DISPOSITION_INFORMATION_EX{
945972
.Flags = FILE_DISPOSITION_DELETE |
946973
FILE_DISPOSITION_POSIX_SEMANTICS |
@@ -2711,6 +2738,13 @@ pub const FILE_FS_DEVICE_INFORMATION = extern struct {
27112738
Characteristics: ULONG,
27122739
};
27132740

2741+
pub const FILE_FS_ATTRIBUTE_INFORMATION = extern struct {
2742+
FileSystemAttributes: ULONG,
2743+
MaximumComponentNameLength: LONG,
2744+
FileSystemNameLength: ULONG,
2745+
FileSystemName: [1]WCHAR,
2746+
};
2747+
27142748
pub const FS_INFORMATION_CLASS = enum(c_int) {
27152749
FileFsVolumeInformation = 1,
27162750
FileFsLabelInformation,
@@ -3173,6 +3207,35 @@ pub const FILE_FLAG_SESSION_AWARE = 0x00800000;
31733207
pub const FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000;
31743208
pub const FILE_FLAG_WRITE_THROUGH = 0x80000000;
31753209

3210+
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa
3211+
pub const FILE_CASE_SENSITIVE_SEARCH = 0x00000001;
3212+
pub const FILE_CASE_PRESERVED_NAMES = 0x00000002;
3213+
pub const FILE_UNICODE_ON_DISK = 0x00000004;
3214+
pub const FILE_PERSISTENT_ACLS = 0x00000008;
3215+
pub const FILE_FILE_COMPRESSION = 0x00000010;
3216+
pub const FILE_VOLUME_QUOTAS = 0x00000020;
3217+
pub const FILE_SUPPORTS_SPARSE_FILES = 0x00000040;
3218+
pub const FILE_SUPPORTS_REPARSE_POINTS = 0x00000080;
3219+
pub const FILE_SUPPORTS_REMOTE_STORAGE = 0x00000100;
3220+
pub const FILE_RETURNS_CLEANUP_RESULT_INFO = 0x00000200;
3221+
pub const FILE_SUPPORTS_POSIX_UNLINK_RENAME = 0x00000400;
3222+
pub const FILE_VOLUME_IS_COMPRESSED = 0x00008000;
3223+
pub const FILE_SUPPORTS_OBJECT_IDS = 0x00010000;
3224+
pub const FILE_SUPPORTS_ENCRYPTION = 0x00020000;
3225+
pub const FILE_NAMED_STREAMS = 0x00040000;
3226+
pub const FILE_READ_ONLY_VOLUME = 0x00080000;
3227+
pub const FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000;
3228+
pub const FILE_SUPPORTS_TRANSACTIONS = 0x00200000;
3229+
pub const FILE_SUPPORTS_HARD_LINKS = 0x00400000;
3230+
pub const FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000;
3231+
pub const FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000;
3232+
pub const FILE_SUPPORTS_USN_JOURNAL = 0x02000000;
3233+
pub const FILE_SUPPORTS_INTEGRITY_STREAMS = 0x04000000;
3234+
pub const FILE_SUPPORTS_BLOCK_REFCOUNTING = 0x08000000;
3235+
pub const FILE_SUPPORTS_SPARSE_VDL = 0x10000000;
3236+
pub const FILE_DAX_VOLUME = 0x20000000;
3237+
pub const FILE_SUPPORTS_GHOSTING = 0x40000000;
3238+
31763239
pub const RECT = extern struct {
31773240
left: LONG,
31783241
top: LONG,

0 commit comments

Comments
 (0)