feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.fileStatWindows
fn fileStatWindows(userdata: ?*anyopaque, file: File) File.StatError!File.Stat
File
Code
fn fileStatWindows(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
const t: *Threaded = @ptrCast(@alignCast(userdata));
const block_size: u32 = if (t.systemBasicInformation()) |sbi|
@intCast(@max(sbi.PageSize, sbi.AllocationGranularity))
else
std.heap.page_size_max;
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
var info: windows.FILE.ALL_INFORMATION = undefined;
{
const syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtQueryInformationFile(
file.handle,
&io_status_block,
&info,
@sizeOf(windows.FILE.ALL_INFORMATION),
.All,
)) {
.SUCCESS => break syscall.finish(),
// size provided. This is treated as success because the type of variable-length information that this would be relevant for
// (name, volume name, etc) we don't care about.
.BUFFER_OVERFLOW => break syscall.finish(),
.INVALID_PARAMETER => |err| return syscall.ntstatusBug(err),
.ACCESS_DENIED => return syscall.fail(error.AccessDenied),
.CANCELLED => {
try syscall.checkCancel();
continue;
},
else => |s| return syscall.unexpectedNtstatus(s),
};
}
return .{
.inode = info.InternalInformation.IndexNumber,
.size = @as(u64, @bitCast(info.StandardInformation.EndOfFile)),
.permissions = .default_file,
.kind = if (info.BasicInformation.FileAttributes.REPARSE_POINT) reparse_point: {
var tag_info: windows.FILE.ATTRIBUTE_TAG_INFO = undefined;
const syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtQueryInformationFile(
file.handle,
&io_status_block,
&tag_info,
@sizeOf(windows.FILE.ATTRIBUTE_TAG_INFO),
.AttributeTag,
)) {
.SUCCESS => break syscall.finish(),
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/d295752f-ce89-4b98-8553-266d37c84f0e
.INFO_LENGTH_MISMATCH => |err| return syscall.ntstatusBug(err),
.ACCESS_DENIED => return syscall.fail(error.AccessDenied),
.CANCELLED => {
try syscall.checkCancel();
continue;
},
else => |s| return syscall.unexpectedNtstatus(s),
};
if (tag_info.ReparseTag.IsSurrogate) break :reparse_point .sym_link;
break :reparse_point .unknown;
} else if (info.BasicInformation.FileAttributes.DIRECTORY)
.directory
else
.file,
.atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
.mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
.ctime = windows.fromSysTime(info.BasicInformation.ChangeTime),
.nlink = info.StandardInformation.NumberOfLinks,
.block_size = block_size,
};
}