zig icon indicating copy to clipboard operation
zig copied to clipboard

Build Runner: Initial Implementation for File System Watching on Windows

Open jayrod246 opened this issue 1 year ago • 5 comments

Closes #20598.

This initial implementation has the limit of 64 directories due to the usage of WaitForMultipleObjects. If merged, a follow up issue should be created to track overcoming that limitation.

BTW First time contributing, not very experienced with contributing on GitHub in general, but I love Zig. And I saw this issue and thought it would be a good learning opportunity for me.

jayrod246 avatar Jul 17 '24 21:07 jayrod246

windows.kernel32.ReadDirectoryChangesW is recently removed in #19641

Thoughts on where or how I can reintroduce it? Or if there is an Nt way it can be replicated?

jayrod246 avatar Jul 18 '24 22:07 jayrod246

I added an error return to readChanges and some accountability for resources.

I still need to deal with this point though:

Note, though, that it also may be true that the dh_gop.found_existing case is impossible. Opening the same directory twice does not result in the same HANDLE:

const std = @import("std");

pub fn main() !void {
    var dir1 = try std.fs.cwd().openDir(".", .{});
    defer dir1.close();

    var dir2 = try std.fs.cwd().openDir(".", .{});
    defer dir2.close();

    std.debug.print("1: {}\n2: {}\n", .{ dir1.fd, dir2.fd });
}

results in

1: anyopaque@9c
2: anyopaque@98

jayrod246 avatar Jul 19 '24 10:07 jayrod246

Instead of keying on the file handle itself, which is determined to be different each NtCreateFile call, would it be best to key on a FILE_ID_INFORMATION structure returned by NtQueryInformationFile? I believe that it is unique per file and volume. If it already exists, I would just close that handle and keep the existing one open.

edit: Further reading I found that FileId is not supported on Fat32. To determine that, you check if the FileId is zero and if so, the file system doesn’t support it. So, I could hash on the VolumeSerialNumber and, the FileId when non-zero, or a number based on I’m guessing an all lowercase full path?

jayrod246 avatar Jul 20 '24 14:07 jayrod246

I think the way to go might be:

Then hash the combination of those.

Some examples of calling NtQueryInformationFile/NtQueryVolumeInformationFile can be found here:

  • https://github.com/ziglang/zig/blob/ff02bf403b546ffc91158e976a4e9567ab02582d/lib/std/fs/File.zig#L211-L217
  • https://github.com/ziglang/zig/blob/ff02bf403b546ffc91158e976a4e9567ab02582d/lib/std/fs/File.zig#L457-L469

(I'd recommend using that BUFFER_OVERFLOW handling for the NtQueryVolumeInformationFile since we don't care about the volume name)

squeek502 avatar Jul 21 '24 00:07 squeek502

Forgot that I had to add FILE_FS_VOLUME_INFORMATION in windows.zig, will fix later today.

jayrod246 avatar Jul 23 '24 10:07 jayrod246

Nice work!

andrewrk avatar Jul 29 '24 03:07 andrewrk