TODO: inline this logic everywhere and delete this function
fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!windows.HANDLE
fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!windows.HANDLE {
if (std.mem.eql(u16, sub_path_w, &.{'.'}) and options.filter == .non_directory_only) {
return error.IsDir;
}
if (std.mem.eql(u16, sub_path_w, &.{ '.', '.' }) and options.filter == .non_directory_only) {
return error.IsDir;
}
var result: windows.HANDLE = undefined;
const attr: windows.OBJECT.ATTRIBUTES = .{
.RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir,
.Attributes = .{ .INHERIT = if (options.sa) |sa| sa.bInheritHandle.toBool() else false },
.ObjectName = @constCast(&windows.UNICODE_STRING.init(sub_path_w)),
.SecurityDescriptor = if (options.sa) |ptr| ptr.lpSecurityDescriptor else null,
};
var iosb: windows.IO_STATUS_BLOCK = undefined;
var attempt: u5 = 0;
var syscall: Syscall = try .start();
while (true) {
switch (windows.ntdll.NtCreateFile(
&result,
options.access_mask,
&attr,
&iosb,
null,
.{ .NORMAL = true },
options.share_access,
options.creation,
.{
.DIRECTORY_FILE = options.filter == .dir_only,
.NON_DIRECTORY_FILE = options.filter == .non_directory_only,
.IO = .SYNCHRONOUS_NONALERT,
.OPEN_REPARSE_POINT = !options.follow_symlinks,
},
null,
0,
)) {
.SUCCESS => {
syscall.finish();
return result;
},
.CANCELLED => {
try syscall.checkCancel();
continue;
},
.SHARING_VIOLATION => {
// This occurs if the file attempting to be opened is a running
// executable. However, there's a kernel bug: the error may be
// incorrectly returned for an indeterminate amount of time
// after an executable file is closed. Here we work around the
// kernel bug with retry attempts.
syscall.finish();
if (max_windows_kernel_bug_retries - attempt == 0) return error.FileBusy;
try parking_sleep.sleep(.{ .duration = .{
.raw = .fromMilliseconds((@as(u32, 1) << attempt) >> 1),
.clock = .awake,
} });
attempt += 1;
syscall = try .start();
continue;
},
.DELETE_PENDING => {
// This error means that there *was* a file in this location on
// the file system, but it was deleted. However, the OS is not
// finished with the deletion operation, and so this CreateFile
// call has failed. There is not really a sane way to handle
// this other than retrying the creation after the OS finishes
// the deletion.
syscall.finish();
if (max_windows_kernel_bug_retries - attempt == 0) return error.FileBusy;
try parking_sleep.sleep(.{ .duration = .{
.raw = .fromMilliseconds((@as(u32, 1) << attempt) >> 1),
.clock = .awake,
} });
attempt += 1;
syscall = try .start();
continue;
},
.OBJECT_NAME_INVALID => return syscall.fail(error.BadPathName),
.OBJECT_NAME_NOT_FOUND => return syscall.fail(error.FileNotFound),
.OBJECT_PATH_NOT_FOUND => return syscall.fail(error.FileNotFound),
.BAD_NETWORK_PATH => return syscall.fail(error.NetworkNotFound), // \\server was not found
.BAD_NETWORK_NAME => return syscall.fail(error.NetworkNotFound), // \\server was found but \\server\share wasn't
.NO_MEDIA_IN_DEVICE => return syscall.fail(error.NoDevice),
.ACCESS_DENIED => return syscall.fail(error.AccessDenied),
.PIPE_BUSY => return syscall.fail(error.PipeBusy),
.PIPE_NOT_AVAILABLE => return syscall.fail(error.NoDevice),
.OBJECT_NAME_COLLISION => return syscall.fail(error.PathAlreadyExists),
.FILE_IS_A_DIRECTORY => return syscall.fail(error.IsDir),
.NOT_A_DIRECTORY => return syscall.fail(error.NotDir),
.USER_MAPPED_FILE => return syscall.fail(error.AccessDenied),
.VIRUS_INFECTED, .VIRUS_DELETED => return syscall.fail(error.AntivirusInterference),
.INVALID_PARAMETER => |status| return syscall.ntstatusBug(status),
.OBJECT_PATH_SYNTAX_BAD => |status| return syscall.ntstatusBug(status),
.INVALID_HANDLE => |status| return syscall.ntstatusBug(status),
else => |status| return syscall.unexpectedNtstatus(status),
}
}
}