commit c13857e504f5893cabf182dde1e826131f2acf24 (tree)
parent 27e5047a888fbfd6c9db6a8374e070eb0deb5d0a
Author: Jacob Young <jacobly0@users.noreply.github.com>
Date: Tue, 9 Dec 2025 13:59:59 -0500
windows: type safety improvements and more ntdll functions
Diffstat:
16 files changed, 3131 insertions(+), 1343 deletions(-)
diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig
@@ -366,7 +366,7 @@ const Os = switch (builtin.os.tag) {
var attr = windows.OBJECT_ATTRIBUTES{
.Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
.RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else root_fd,
- .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
+ .Attributes = .{},
.ObjectName = &nt_name,
.SecurityDescriptor = null,
.SecurityQualityOfService = null,
@@ -375,14 +375,23 @@ const Os = switch (builtin.os.tag) {
switch (windows.ntdll.NtCreateFile(
&dir_handle,
- windows.SYNCHRONIZE | windows.GENERIC_READ | windows.FILE_LIST_DIRECTORY,
+ .{
+ .SPECIFIC = .{ .FILE_DIRECTORY = .{
+ .LIST = true,
+ } },
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{ .READ = true },
+ },
&attr,
&io,
null,
- 0,
- windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE,
- windows.FILE_OPEN,
- windows.FILE_DIRECTORY_FILE | windows.FILE_OPEN_FOR_BACKUP_INTENT,
+ .{},
+ .VALID_FLAGS,
+ .OPEN,
+ .{
+ .DIRECTORY_FILE = true,
+ .OPEN_FOR_BACKUP_INTENT = true,
+ },
null,
0,
)) {
@@ -437,13 +446,13 @@ const Os = switch (builtin.os.tag) {
fn getFileId(handle: windows.HANDLE) !FileId {
var file_id: FileId = undefined;
var io_status: windows.IO_STATUS_BLOCK = undefined;
- var volume_info: windows.FILE_FS_VOLUME_INFORMATION = undefined;
+ var volume_info: windows.FILE.FS_VOLUME_INFORMATION = undefined;
switch (windows.ntdll.NtQueryVolumeInformationFile(
handle,
&io_status,
&volume_info,
- @sizeOf(windows.FILE_FS_VOLUME_INFORMATION),
- .FileFsVolumeInformation,
+ @sizeOf(windows.FILE.FS_VOLUME_INFORMATION),
+ .Volume,
)) {
.SUCCESS => {},
// Buffer overflow here indicates that there is more information available than was able to be stored in the buffer
@@ -453,13 +462,13 @@ const Os = switch (builtin.os.tag) {
else => |rc| return windows.unexpectedStatus(rc),
}
file_id.volumeSerialNumber = volume_info.VolumeSerialNumber;
- var internal_info: windows.FILE_INTERNAL_INFORMATION = undefined;
+ var internal_info: windows.FILE.INTERNAL_INFORMATION = undefined;
switch (windows.ntdll.NtQueryInformationFile(
handle,
&io_status,
&internal_info,
- @sizeOf(windows.FILE_INTERNAL_INFORMATION),
- .FileInternalInformation,
+ @sizeOf(windows.FILE.INTERNAL_INFORMATION),
+ .Internal,
)) {
.SUCCESS => {},
else => |rc| return windows.unexpectedStatus(rc),
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
@@ -1301,8 +1301,11 @@ fn dirMakeWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode
_ = mode;
const sub_dir_handle = windows.OpenFile(sub_path_w.span(), .{
.dir = dir.handle,
- .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,
- .creation = windows.FILE_CREATE,
+ .access_mask = .{
+ .GENERIC = .{ .READ = true },
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ },
+ .creation = .CREATE,
.filter = .dir_only,
}) catch |err| switch (err) {
error.IsDir => return error.Unexpected,
@@ -1370,9 +1373,6 @@ fn dirMakeOpenPathWindows(
const t: *Threaded = @ptrCast(@alignCast(userdata));
const current_thread = Thread.getCurrent(t);
const w = windows;
- const access_mask = w.STANDARD_RIGHTS_READ | w.FILE_READ_ATTRIBUTES | w.FILE_READ_EA |
- w.SYNCHRONIZE | w.FILE_TRAVERSE |
- (if (options.iterate) w.FILE_LIST_DIRECTORY else @as(u32, 0));
var it = std.fs.path.componentIterator(sub_path);
// If there are no components in the path, then create a dummy component with the full path.
@@ -1387,7 +1387,7 @@ fn dirMakeOpenPathWindows(
const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, component.path);
const sub_path_w = sub_path_w_array.span();
const is_last = it.peekNext() == null;
- const create_disposition: u32 = if (is_last) w.FILE_OPEN_IF else w.FILE_CREATE;
+ const create_disposition: w.FILE.CREATE_DISPOSITION = if (is_last) .OPEN_IF else .CREATE;
var result: Io.Dir = .{ .handle = undefined };
@@ -1397,26 +1397,40 @@ fn dirMakeOpenPathWindows(
.MaximumLength = path_len_bytes,
.Buffer = @constCast(sub_path_w.ptr),
};
- var attr: w.OBJECT_ATTRIBUTES = .{
- .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
- .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
- .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
- .ObjectName = &nt_name,
- .SecurityDescriptor = null,
- .SecurityQualityOfService = null,
- };
- const open_reparse_point: w.DWORD = if (!options.follow_symlinks) w.FILE_OPEN_REPARSE_POINT else 0x0;
var io_status_block: w.IO_STATUS_BLOCK = undefined;
const rc = w.ntdll.NtCreateFile(
&result.handle,
- access_mask,
- &attr,
+ .{
+ .SPECIFIC = .{ .FILE_DIRECTORY = .{
+ .LIST = options.iterate,
+ .READ_EA = true,
+ .READ_ATTRIBUTES = true,
+ .TRAVERSE = true,
+ } },
+ .STANDARD = .{
+ .RIGHTS = .READ,
+ .SYNCHRONIZE = true,
+ },
+ },
+ &.{
+ .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
+ .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
+ .Attributes = .{},
+ .ObjectName = &nt_name,
+ .SecurityDescriptor = null,
+ .SecurityQualityOfService = null,
+ },
&io_status_block,
null,
- w.FILE_ATTRIBUTE_NORMAL,
- w.FILE_SHARE_READ | w.FILE_SHARE_WRITE | w.FILE_SHARE_DELETE,
+ .{ .NORMAL = true },
+ .VALID_FLAGS,
create_disposition,
- w.FILE_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT | w.FILE_OPEN_FOR_BACKUP_INTENT | open_reparse_point,
+ .{
+ .DIRECTORY_FILE = true,
+ .IO = .SYNCHRONOUS_NONALERT,
+ .OPEN_FOR_BACKUP_INTENT = true,
+ .OPEN_REPARSE_POINT = !options.follow_symlinks,
+ },
null,
0,
);
@@ -1749,8 +1763,8 @@ fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.Fi
try current_thread.checkCancel();
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
- var info: windows.FILE_ALL_INFORMATION = undefined;
- const rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
+ var info: windows.FILE.ALL_INFORMATION = undefined;
+ const rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &info, @sizeOf(windows.FILE.ALL_INFORMATION), .All);
switch (rc) {
.SUCCESS => {},
// Buffer overflow here indicates that there is more information available than was able to be stored in the buffer
@@ -1765,9 +1779,9 @@ fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.Fi
.inode = info.InternalInformation.IndexNumber,
.size = @as(u64, @bitCast(info.StandardInformation.EndOfFile)),
.mode = 0,
- .kind = if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_REPARSE_POINT != 0) reparse_point: {
- var tag_info: windows.FILE_ATTRIBUTE_TAG_INFO = undefined;
- const tag_rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &tag_info, @sizeOf(windows.FILE_ATTRIBUTE_TAG_INFO), .FileAttributeTagInformation);
+ .kind = if (info.BasicInformation.FileAttributes.REPARSE_POINT) reparse_point: {
+ var tag_info: windows.FILE.ATTRIBUTE_TAG_INFO = undefined;
+ const tag_rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &tag_info, @sizeOf(windows.FILE.ATTRIBUTE_TAG_INFO), .AttributeTag);
switch (tag_rc) {
.SUCCESS => {},
// INFO_LENGTH_MISMATCH and ACCESS_DENIED are the only documented possible errors
@@ -1776,12 +1790,10 @@ fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.Fi
.ACCESS_DENIED => return error.AccessDenied,
else => return windows.unexpectedStatus(rc),
}
- if (tag_info.ReparseTag & windows.reparse_tag_name_surrogate_bit != 0) {
- break :reparse_point .sym_link;
- }
+ if (tag_info.ReparseTag.IsSurrogate) break :reparse_point .sym_link;
// Unknown reparse point
break :reparse_point .unknown;
- } else if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_DIRECTORY != 0)
+ } else if (info.BasicInformation.FileAttributes.DIRECTORY)
.directory
else
.file,
@@ -1983,15 +1995,15 @@ fn dirAccessWindows(
.MaximumLength = path_len_bytes,
.Buffer = @constCast(sub_path_w.ptr),
};
- var attr = windows.OBJECT_ATTRIBUTES{
+ var attr: windows.OBJECT_ATTRIBUTES = .{
.Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
.RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
- .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
+ .Attributes = .{},
.ObjectName = &nt_name,
.SecurityDescriptor = null,
.SecurityQualityOfService = null,
};
- var basic_info: windows.FILE_BASIC_INFORMATION = undefined;
+ var basic_info: windows.FILE.BASIC_INFORMATION = undefined;
switch (windows.ntdll.NtQueryAttributesFile(&attr, &basic_info)) {
.SUCCESS => return,
.OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
@@ -2187,16 +2199,21 @@ fn dirCreateFileWindows(
const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path);
const sub_path_w = sub_path_w_array.span();
- const read_flag = if (flags.read) @as(u32, w.GENERIC_READ) else 0;
const handle = try w.OpenFile(sub_path_w, .{
.dir = dir.handle,
- .access_mask = w.SYNCHRONIZE | w.GENERIC_WRITE | read_flag,
+ .access_mask = .{
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{
+ .WRITE = true,
+ .READ = flags.read,
+ },
+ },
.creation = if (flags.exclusive)
- @as(u32, w.FILE_CREATE)
+ .CREATE
else if (flags.truncate)
- @as(u32, w.FILE_OVERWRITE_IF)
+ .OVERWRITE_IF
else
- @as(u32, w.FILE_OPEN_IF),
+ .OPEN_IF,
});
errdefer w.CloseHandle(handle);
var io_status_block: w.IO_STATUS_BLOCK = undefined;
@@ -2511,18 +2528,12 @@ pub fn dirOpenFileWtf16(
var attr: w.OBJECT_ATTRIBUTES = .{
.Length = @sizeOf(w.OBJECT_ATTRIBUTES),
.RootDirectory = dir_handle,
- .Attributes = 0,
+ .Attributes = .{},
.ObjectName = &nt_name,
.SecurityDescriptor = null,
.SecurityQualityOfService = null,
};
var io_status_block: w.IO_STATUS_BLOCK = undefined;
- const blocking_flag: w.ULONG = w.FILE_SYNCHRONOUS_IO_NONALERT;
- const file_or_dir_flag: w.ULONG = w.FILE_NON_DIRECTORY_FILE;
- // If we're not following symlinks, we need to ensure we don't pass in any
- // synchronization flags such as FILE_SYNCHRONOUS_IO_NONALERT.
- const create_file_flags: w.ULONG = file_or_dir_flag |
- if (flags.follow_symlinks) blocking_flag else w.FILE_OPEN_REPARSE_POINT;
// There are multiple kernel bugs being worked around with retries.
const max_attempts = 13;
@@ -2534,16 +2545,24 @@ pub fn dirOpenFileWtf16(
var result: w.HANDLE = undefined;
const rc = w.ntdll.NtCreateFile(
&result,
- w.SYNCHRONIZE |
- (if (flags.isRead()) @as(u32, w.GENERIC_READ) else 0) |
- (if (flags.isWrite()) @as(u32, w.GENERIC_WRITE) else 0),
+ .{
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{
+ .READ = flags.isRead(),
+ .WRITE = flags.isWrite(),
+ },
+ },
&attr,
&io_status_block,
null,
- w.FILE_ATTRIBUTE_NORMAL,
- w.FILE_SHARE_WRITE | w.FILE_SHARE_READ | w.FILE_SHARE_DELETE,
- w.FILE_OPEN,
- create_file_flags,
+ .{ .NORMAL = true },
+ .VALID_FLAGS,
+ .OPEN,
+ .{
+ .IO = if (flags.follow_symlinks) .SYNCHRONOUS_NONALERT else .ASYNCHRONOUS,
+ .NON_DIRECTORY_FILE = true,
+ .OPEN_REPARSE_POINT = !flags.follow_symlinks,
+ },
null,
0,
);
@@ -2835,10 +2854,6 @@ pub fn dirOpenDirWindows(
) Io.Dir.OpenError!Io.Dir {
const current_thread = Thread.getCurrent(t);
const w = windows;
- // TODO remove some of these flags if options.access_sub_paths is false
- const base_flags = w.STANDARD_RIGHTS_READ | w.FILE_READ_ATTRIBUTES | w.FILE_READ_EA |
- w.SYNCHRONIZE | w.FILE_TRAVERSE;
- const access_mask: u32 = if (options.iterate) base_flags | w.FILE_LIST_DIRECTORY else base_flags;
const path_len_bytes: u16 = @intCast(sub_path_w.len * 2);
var nt_name: w.UNICODE_STRING = .{
@@ -2846,28 +2861,43 @@ pub fn dirOpenDirWindows(
.MaximumLength = path_len_bytes,
.Buffer = @constCast(sub_path_w.ptr),
};
- var attr: w.OBJECT_ATTRIBUTES = .{
- .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
- .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
- .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
- .ObjectName = &nt_name,
- .SecurityDescriptor = null,
- .SecurityQualityOfService = null,
- };
- const open_reparse_point: w.DWORD = if (!options.follow_symlinks) w.FILE_OPEN_REPARSE_POINT else 0x0;
var io_status_block: w.IO_STATUS_BLOCK = undefined;
var result: Io.Dir = .{ .handle = undefined };
try current_thread.checkCancel();
const rc = w.ntdll.NtCreateFile(
&result.handle,
- access_mask,
- &attr,
+ // TODO remove some of these flags if options.access_sub_paths is false
+ .{
+ .SPECIFIC = .{ .FILE_DIRECTORY = .{
+ .LIST = options.iterate,
+ .READ_EA = true,
+ .TRAVERSE = true,
+ .READ_ATTRIBUTES = true,
+ } },
+ .STANDARD = .{
+ .RIGHTS = .READ,
+ .SYNCHRONIZE = true,
+ },
+ },
+ &.{
+ .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
+ .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
+ .Attributes = .{},
+ .ObjectName = &nt_name,
+ .SecurityDescriptor = null,
+ .SecurityQualityOfService = null,
+ },
&io_status_block,
null,
- w.FILE_ATTRIBUTE_NORMAL,
- w.FILE_SHARE_READ | w.FILE_SHARE_WRITE | w.FILE_SHARE_DELETE,
- w.FILE_OPEN,
- w.FILE_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT | w.FILE_OPEN_FOR_BACKUP_INTENT | open_reparse_point,
+ .{ .NORMAL = true },
+ .VALID_FLAGS,
+ .OPEN,
+ .{
+ .DIRECTORY_FILE = true,
+ .IO = .SYNCHRONOUS_NONALERT,
+ .OPEN_FOR_BACKUP_INTENT = true,
+ .OPEN_REPARSE_POINT = !options.follow_symlinks,
+ },
null,
0,
);
diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig
@@ -226,7 +226,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
switch (windows.ntdll.NtSetInformationThread(
self.getHandle(),
- .ThreadNameInformation,
+ .NameInformation,
&unicode_string,
@sizeOf(windows.UNICODE_STRING),
)) {
@@ -338,7 +338,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
switch (windows.ntdll.NtQueryInformationThread(
self.getHandle(),
- .ThreadNameInformation,
+ .NameInformation,
&buf,
buf_capacity,
null,
@@ -521,12 +521,10 @@ pub const YieldError = error{
/// Yields the current thread potentially allowing other threads to run.
pub fn yield() YieldError!void {
- if (native_os == .windows) {
- // The return value has to do with how many other threads there are; it is not
- // an error condition on Windows.
- _ = windows.kernel32.SwitchToThread();
- return;
- }
+ if (native_os == .windows) switch (windows.ntdll.NtYieldExecution()) {
+ .SUCCESS, .NO_YIELD_PERFORMED => return,
+ else => return error.SystemCannotYield,
+ };
switch (posix.errno(posix.system.sched_yield())) {
.SUCCESS => return,
.NOSYS => return error.SystemCannotYield,
@@ -647,11 +645,11 @@ const WindowsThreadImpl = struct {
const ThreadCompletion = struct {
completion: Completion,
heap_ptr: windows.PVOID,
- heap_handle: windows.HANDLE,
+ heap_handle: *windows.HEAP,
thread_handle: windows.HANDLE = undefined,
fn free(self: ThreadCompletion) void {
- const status = windows.kernel32.HeapFree(self.heap_handle, 0, self.heap_ptr);
+ const status = windows.ntdll.RtlFreeHeap(self.heap_handle, .{}, self.heap_ptr);
assert(status != 0);
}
};
@@ -673,10 +671,10 @@ const WindowsThreadImpl = struct {
}
};
- const heap_handle = windows.kernel32.GetProcessHeap() orelse return error.OutOfMemory;
+ const heap_handle = windows.GetProcessHeap() orelse return error.OutOfMemory;
const alloc_bytes = @alignOf(Instance) + @sizeOf(Instance);
- const alloc_ptr = windows.ntdll.RtlAllocateHeap(heap_handle, 0, alloc_bytes) orelse return error.OutOfMemory;
- errdefer assert(windows.kernel32.HeapFree(heap_handle, 0, alloc_ptr) != 0);
+ const alloc_ptr = windows.ntdll.RtlAllocateHeap(heap_handle, .{}, alloc_bytes) orelse return error.OutOfMemory;
+ errdefer assert(windows.ntdll.RtlFreeHeap(heap_handle, .{}, alloc_ptr) != 0);
const instance_bytes = @as([*]u8, @ptrCast(alloc_ptr))[0..alloc_bytes];
var fba = std.heap.FixedBufferAllocator.init(instance_bytes);
@@ -693,8 +691,7 @@ const WindowsThreadImpl = struct {
// Windows appears to only support SYSTEM_INFO.dwAllocationGranularity minimum stack size.
// Going lower makes it default to that specified in the executable (~1mb).
// Its also fine if the limit here is incorrect as stack size is only a hint.
- var stack_size = std.math.cast(u32, config.stack_size) orelse std.math.maxInt(u32);
- stack_size = @max(64 * 1024, stack_size);
+ const stack_size = @max(64 * 1024, std.math.lossyCast(u32, config.stack_size));
instance.thread.thread_handle = windows.kernel32.CreateThread(
null,
diff --git a/lib/std/debug/SelfInfo/Windows.zig b/lib/std/debug/SelfInfo/Windows.zig
@@ -154,10 +154,10 @@ pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) Error
_ = gpa;
const current_regs = context.cur.getRegs();
- var image_base: windows.DWORD64 = undefined;
+ var image_base: usize = undefined;
if (windows.ntdll.RtlLookupFunctionEntry(current_regs.ip, &image_base, &context.history_table)) |runtime_function| {
var handler_data: ?*anyopaque = null;
- var establisher_frame: u64 = undefined;
+ var establisher_frame: usize = undefined;
_ = windows.ntdll.RtlVirtualUnwind(
windows.UNW_FLAG_NHANDLER,
image_base,
@@ -351,13 +351,19 @@ const Module = struct {
var section_handle: windows.HANDLE = undefined;
const create_section_rc = windows.ntdll.NtCreateSection(
§ion_handle,
- windows.STANDARD_RIGHTS_REQUIRED | windows.SECTION_QUERY | windows.SECTION_MAP_READ,
+ .{
+ .SPECIFIC = .{ .SECTION = .{
+ .QUERY = true,
+ .MAP_READ = true,
+ } },
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ },
null,
null,
- windows.PAGE_READONLY,
+ .{ .READONLY = true },
// The documentation states that if no AllocationAttribute is specified, then SEC_COMMIT is the default.
// In practice, this isn't the case and specifying 0 will result in INVALID_PARAMETER_6.
- windows.SEC_COMMIT,
+ .{ .COMMIT = true },
coff_file.handle,
);
if (create_section_rc != .SUCCESS) return error.MissingDebugInfo;
@@ -372,9 +378,9 @@ const Module = struct {
0,
null,
&coff_len,
- .ViewUnmap,
- 0,
- windows.PAGE_READONLY,
+ .Unmap,
+ .{},
+ .{ .READONLY = true },
);
if (map_section_rc != .SUCCESS) return error.MissingDebugInfo;
errdefer assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(section_view_ptr.?)) == .SUCCESS);
diff --git a/lib/std/enums.zig b/lib/std/enums.zig
@@ -61,7 +61,9 @@ pub fn values(comptime E: type) []const E {
/// panic when `e` has no tagged value.
/// Returns the tag name for `e` or null if no tag exists.
pub fn tagName(comptime E: type, e: E) ?[:0]const u8 {
- return inline for (@typeInfo(E).@"enum".fields) |f| {
+ const fields = @typeInfo(E).@"enum".fields;
+ @setEvalBranchQuota(fields.len);
+ return inline for (fields) |f| {
if (@intFromEnum(e) == f.value) break f.name;
} else null;
}
diff --git a/lib/std/fs/Dir.zig b/lib/std/fs/Dir.zig
@@ -453,10 +453,10 @@ pub const Iterator = switch (native_os) {
&io,
&self.buf,
self.buf.len,
- .FileBothDirectoryInformation,
+ .BothDirectory,
w.FALSE,
null,
- if (self.first_iter) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE),
+ @intFromBool(self.first_iter),
);
self.first_iter = false;
if (io.Information == 0) return null;
@@ -487,8 +487,8 @@ pub const Iterator = switch (native_os) {
const name_wtf8 = self.name_data[0..name_wtf8_len];
const kind: Entry.Kind = blk: {
const attrs = dir_info.FileAttributes;
- if (attrs & w.FILE_ATTRIBUTE_DIRECTORY != 0) break :blk .directory;
- if (attrs & w.FILE_ATTRIBUTE_REPARSE_POINT != 0) break :blk .sym_link;
+ if (attrs.DIRECTORY) break :blk .directory;
+ if (attrs.REPARSE_POINT) break :blk .sym_link;
break :blk .file;
};
return Entry{
@@ -1013,15 +1013,14 @@ pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u8) RealPathErr
pub fn realpathW2(self: Dir, pathname: []const u16, out_buffer: []u16) RealPathError![]u16 {
const w = windows;
- const access_mask = w.GENERIC_READ | w.SYNCHRONIZE;
- const share_access = w.FILE_SHARE_READ | w.FILE_SHARE_WRITE | w.FILE_SHARE_DELETE;
- const creation = w.FILE_OPEN;
const h_file = blk: {
const res = w.OpenFile(pathname, .{
.dir = self.fd,
- .access_mask = access_mask,
- .share_access = share_access,
- .creation = creation,
+ .access_mask = .{
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{ .READ = true },
+ },
+ .creation = .OPEN,
.filter = .any,
}) catch |err| switch (err) {
error.WouldBlock => unreachable,
diff --git a/lib/std/fs/File.zig b/lib/std/fs/File.zig
@@ -146,13 +146,13 @@ pub fn isCygwinPty(file: File) bool {
// for handles that aren't named pipes.
{
var io_status: windows.IO_STATUS_BLOCK = undefined;
- var device_info: windows.FILE_FS_DEVICE_INFORMATION = undefined;
- const rc = windows.ntdll.NtQueryVolumeInformationFile(handle, &io_status, &device_info, @sizeOf(windows.FILE_FS_DEVICE_INFORMATION), .FileFsDeviceInformation);
+ var device_info: windows.FILE.FS_DEVICE_INFORMATION = undefined;
+ const rc = windows.ntdll.NtQueryVolumeInformationFile(handle, &io_status, &device_info, @sizeOf(windows.FILE.FS_DEVICE_INFORMATION), .Device);
switch (rc) {
.SUCCESS => {},
else => return false,
}
- if (device_info.DeviceType != windows.FILE_DEVICE_NAMED_PIPE) return false;
+ if (device_info.DeviceType.FileDevice != .NAMED_PIPE) return false;
}
const name_bytes_offset = @offsetOf(windows.FILE_NAME_INFO, "FileName");
@@ -166,7 +166,7 @@ pub fn isCygwinPty(file: File) bool {
var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
- const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @intCast(name_info_bytes.len), .FileNameInformation);
+ const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @intCast(name_info_bytes.len), .Name);
switch (rc) {
.SUCCESS => {},
.INVALID_PARAMETER => unreachable,
@@ -485,7 +485,7 @@ pub fn setPermissions(self: File, permissions: Permissions) SetPermissionsError!
&io_status_block,
&info,
@sizeOf(windows.FILE_BASIC_INFORMATION),
- .FileBasicInformation,
+ .Basic,
);
switch (rc) {
.SUCCESS => return,
@@ -1324,7 +1324,7 @@ pub fn unlock(file: File) void {
&io_status_block,
&range_off,
&range_len,
- null,
+ 0,
) catch |err| switch (err) {
error.RangeNotLocked => unreachable, // Function assumes unlocked.
error.Unexpected => unreachable, // Resource deallocation must succeed.
@@ -1415,7 +1415,7 @@ pub fn downgradeLock(file: File) LockError!void {
&io_status_block,
&range_off,
&range_len,
- null,
+ 0,
) catch |err| switch (err) {
error.RangeNotLocked => unreachable, // File was not locked.
error.Unexpected => unreachable, // Resource deallocation must succeed.
diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig
@@ -256,13 +256,11 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
try setupSymlink(ctx.dir, dir_target_path, "symlink", .{ .is_directory = true });
- var symlink = switch (builtin.target.os.tag) {
+ var symlink: Dir = switch (builtin.target.os.tag) {
.windows => windows_symlink: {
const sub_path_w = try windows.cStrToPrefixedFileW(ctx.dir.fd, "symlink");
- var result = Dir{
- .fd = undefined,
- };
+ var handle: windows.HANDLE = undefined;
const path_len_bytes = @as(u16, @intCast(sub_path_w.span().len * 2));
var nt_name = windows.UNICODE_STRING{
@@ -270,32 +268,46 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
.MaximumLength = path_len_bytes,
.Buffer = @constCast(&sub_path_w.data),
};
- var attr = windows.OBJECT_ATTRIBUTES{
+ var attr: windows.OBJECT_ATTRIBUTES = .{
.Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
.RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else ctx.dir.fd,
- .Attributes = 0,
+ .Attributes = .{},
.ObjectName = &nt_name,
.SecurityDescriptor = null,
.SecurityQualityOfService = null,
};
var io: windows.IO_STATUS_BLOCK = undefined;
const rc = windows.ntdll.NtCreateFile(
- &result.fd,
- windows.STANDARD_RIGHTS_READ | windows.FILE_READ_ATTRIBUTES | windows.FILE_READ_EA | windows.SYNCHRONIZE | windows.FILE_TRAVERSE,
+ &handle,
+ .{
+ .SPECIFIC = .{ .FILE_DIRECTORY = .{
+ .READ_EA = true,
+ .TRAVERSE = true,
+ .READ_ATTRIBUTES = true,
+ } },
+ .STANDARD = .{
+ .RIGHTS = .READ,
+ .SYNCHRONIZE = true,
+ },
+ },
&attr,
&io,
null,
- windows.FILE_ATTRIBUTE_NORMAL,
- windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE,
- windows.FILE_OPEN,
- // FILE_OPEN_REPARSE_POINT is the important thing here
- windows.FILE_OPEN_REPARSE_POINT | windows.FILE_DIRECTORY_FILE | windows.FILE_SYNCHRONOUS_IO_NONALERT | windows.FILE_OPEN_FOR_BACKUP_INTENT,
+ .{ .NORMAL = true },
+ .VALID_FLAGS,
+ .OPEN,
+ .{
+ .DIRECTORY_FILE = true,
+ .IO = .SYNCHRONOUS_NONALERT,
+ .OPEN_FOR_BACKUP_INTENT = true,
+ .OPEN_REPARSE_POINT = true, // the important thing here
+ },
null,
0,
);
switch (rc) {
- .SUCCESS => break :windows_symlink result,
+ .SUCCESS => break :windows_symlink .{ .fd = handle },
else => return windows.unexpectedStatus(rc),
}
},
diff --git a/lib/std/heap/PageAllocator.zig b/lib/std/heap/PageAllocator.zig
@@ -30,7 +30,8 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
var base_addr: ?*anyopaque = null;
var size: windows.SIZE_T = n;
- var status = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), 0, &size, windows.MEM_COMMIT | windows.MEM_RESERVE, windows.PAGE_READWRITE);
+ const current_process = windows.GetCurrentProcess();
+ var status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .COMMIT = true, .RESERVE = true }, .{ .READWRITE = true });
if (status == SUCCESS and mem.isAligned(@intFromPtr(base_addr), alignment_bytes)) {
return @ptrCast(base_addr);
@@ -38,7 +39,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
if (status == SUCCESS) {
var region_size: windows.SIZE_T = 0;
- _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), ®ion_size, windows.MEM_RELEASE);
+ _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&base_addr), ®ion_size, .{ .RELEASE = true });
}
const overalloc_len = n + alignment_bytes - page_size;
@@ -47,7 +48,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
base_addr = null;
size = overalloc_len;
- status = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), 0, &size, windows.MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, windows.PAGE_NOACCESS);
+ status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .RESERVE = true, .RESERVE_PLACEHOLDER = true }, .{ .NOACCESS = true });
if (status != SUCCESS) return null;
@@ -58,7 +59,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
if (prefix_size > 0) {
var prefix_base = base_addr;
var prefix_size_param: windows.SIZE_T = prefix_size;
- _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&prefix_base), &prefix_size_param, windows.MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&prefix_base), &prefix_size_param, .{ .RELEASE = true, .PRESERVE_PLACEHOLDER = true });
}
const suffix_start = aligned_addr + aligned_len;
@@ -66,13 +67,13 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
if (suffix_size > 0) {
var suffix_base = @as(?*anyopaque, @ptrFromInt(suffix_start));
var suffix_size_param: windows.SIZE_T = suffix_size;
- _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&suffix_base), &suffix_size_param, windows.MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
+ _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&suffix_base), &suffix_size_param, .{ .RELEASE = true, .PRESERVE_PLACEHOLDER = true });
}
base_addr = @ptrFromInt(aligned_addr);
size = aligned_len;
- status = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), 0, &size, windows.MEM_COMMIT | MEM_PRESERVE_PLACEHOLDER, windows.PAGE_READWRITE);
+ status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .COMMIT = true }, .{ .READWRITE = true });
if (status == SUCCESS) {
return @ptrCast(base_addr);
@@ -80,7 +81,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
base_addr = @as(?*anyopaque, @ptrFromInt(aligned_addr));
size = aligned_len;
- _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), &size, windows.MEM_RELEASE);
+ _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&base_addr), &size, .{ .RELEASE = true });
return null;
}
@@ -145,7 +146,7 @@ pub fn unmap(memory: []align(page_size_min) u8) void {
if (native_os == .windows) {
var base_addr: ?*anyopaque = memory.ptr;
var region_size: windows.SIZE_T = 0;
- _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), ®ion_size, windows.MEM_RELEASE);
+ _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), ®ion_size, .{ .RELEASE = true });
} else {
const page_aligned_len = mem.alignForward(usize, memory.len, std.heap.pageSize());
posix.munmap(memory.ptr[0..page_aligned_len]);
@@ -166,7 +167,7 @@ pub fn realloc(uncasted_memory: []u8, new_len: usize, may_move: bool) ?[*]u8 {
var decommit_addr: ?*anyopaque = @ptrFromInt(new_addr_end);
var decommit_size: windows.SIZE_T = old_addr_end - new_addr_end;
- _ = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&decommit_addr), 0, &decommit_size, windows.MEM_RESET, windows.PAGE_NOACCESS);
+ _ = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&decommit_addr), 0, &decommit_size, .{ .RESET = true }, .{ .NOACCESS = true });
}
return memory.ptr;
}
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
@@ -28,9 +28,2265 @@ pub const ws2_32 = @import("windows/ws2_32.zig");
pub const crypt32 = @import("windows/crypt32.zig");
pub const nls = @import("windows/nls.zig");
-pub const self_process_handle = @as(HANDLE, @ptrFromInt(maxInt(usize)));
+pub const FILE = struct {
+ // ref: km/ntddk.h
-const Self = @This();
+ pub const END_OF_FILE_INFORMATION = extern struct {
+ EndOfFile: LARGE_INTEGER,
+ };
+
+ pub const ALIGNMENT_INFORMATION = extern struct {
+ AlignmentRequirement: ULONG,
+ };
+
+ pub const NAME_INFORMATION = extern struct {
+ FileNameLength: ULONG,
+ FileName: [1]WCHAR,
+ };
+
+ pub const DISPOSITION = packed struct(ULONG) {
+ DELETE: bool = false,
+ POSIX_SEMANTICS: bool = false,
+ FORCE_IMAGE_SECTION_CHECK: bool = false,
+ ON_CLOSE: bool = false,
+ IGNORE_READONLY_ATTRIBUTE: bool = false,
+ Reserved5: u27 = 0,
+
+ pub const DO_NOT_DELETE: DISPOSITION = .{};
+
+ pub const INFORMATION = extern struct {
+ DeleteFile: BOOLEAN,
+
+ pub const EX = extern struct {
+ Flags: DISPOSITION,
+ };
+ };
+ };
+
+ pub const FS_VOLUME_INFORMATION = extern struct {
+ VolumeCreationTime: LARGE_INTEGER,
+ VolumeSerialNumber: ULONG,
+ VolumeLabelLength: ULONG,
+ SupportsObjects: BOOLEAN,
+ VolumeLabel: [0]WCHAR,
+
+ pub fn getVolumeLabel(fvi: *const FS_VOLUME_INFORMATION) []const WCHAR {
+ return (&fvi).ptr[0..@divExact(fvi.VolumeLabelLength, @sizeOf(WCHAR))];
+ }
+ };
+
+ // ref: km/ntifs.h
+
+ pub const PIPE = struct {
+ /// Define the `NamedPipeType` flags for `NtCreateNamedPipeFile`
+ pub const TYPE = packed struct(ULONG) {
+ TYPE: enum(u1) {
+ BYTE_STREAM = 0b0,
+ MESSAGE = 0b1,
+ } = .BYTE_STREAM,
+ REMOTE_CLIENTS: enum(u1) {
+ ACCEPT = 0b0,
+ REJECT = 0b1,
+ } = .ACCEPT,
+ Reserved2: u30 = 0,
+
+ pub const VALID_MASK: TYPE = .{
+ .TYPE = .MESSAGE,
+ .REMOTE_CLIENTS = .REJECT,
+ };
+ };
+
+ /// Define the `CompletionMode` flags for `NtCreateNamedPipeFile`
+ pub const COMPLETION_MODE = packed struct(ULONG) {
+ OPERATION: enum(u1) {
+ QUEUE = 0b0,
+ COMPLETE = 0b1,
+ } = .QUEUE,
+ Reserved1: u31 = 0,
+ };
+
+ /// Define the `ReadMode` flags for `NtCreateNamedPipeFile`
+ pub const READ_MODE = packed struct(ULONG) {
+ MODE: enum(u1) {
+ BYTE_STREAM = 0b0,
+ MESSAGE = 0b1,
+ },
+ Reserved1: u31 = 0,
+ };
+
+ /// Define the `NamedPipeConfiguration` flags for `NtQueryInformationFile`
+ pub const CONFIGURATION = enum(ULONG) {
+ INBOUND = 0x00000000,
+ OUTBOUND = 0x00000001,
+ FULL_DUPLEX = 0x00000002,
+ };
+
+ /// Define the `NamedPipeState` flags for `NtQueryInformationFile`
+ pub const STATE = enum(ULONG) {
+ DISCONNECTED = 0x00000001,
+ LISTENING = 0x00000002,
+ CONNECTED = 0x00000003,
+ CLOSING = 0x00000004,
+ };
+
+ /// Define the `NamedPipeEnd` flags for `NtQueryInformationFile`
+ pub const END = enum(ULONG) {
+ CLIENT = 0x00000000,
+ SERVER = 0x00000001,
+ };
+
+ pub const INFORMATION = extern struct {
+ ReadMode: READ_MODE,
+ CompletionMode: COMPLETION_MODE,
+ };
+
+ pub const LOCAL_INFORMATION = extern struct {
+ NamedPipeType: TYPE,
+ NamedPipeConfiguration: CONFIGURATION,
+ MaximumInstances: ULONG,
+ CurrentInstances: ULONG,
+ InboundQuota: ULONG,
+ ReadDataAvailable: ULONG,
+ OutboundQuota: ULONG,
+ WriteQuotaAvailable: ULONG,
+ NamedPipeState: STATE,
+ NamedPipeEnd: END,
+ };
+
+ pub const REMOTE_INFORMATION = extern struct {
+ CollectDataTime: LARGE_INTEGER,
+ MaximumCollectionCount: ULONG,
+ };
+
+ pub const WAIT_FOR_BUFFER = extern struct {
+ Timeout: LARGE_INTEGER,
+ NameLength: ULONG,
+ TimeoutSpecified: BOOLEAN,
+ Name: [PATH_MAX_WIDE]WCHAR,
+
+ pub const WAIT_FOREVER: LARGE_INTEGER = std.math.minInt(LARGE_INTEGER);
+
+ pub fn init(opts: struct {
+ Timeout: ?LARGE_INTEGER = null,
+ Name: []const WCHAR,
+ }) WAIT_FOR_BUFFER {
+ var fpwfb: WAIT_FOR_BUFFER = .{
+ .Timeout = opts.Timeout orelse undefined,
+ .NameLength = @intCast(@sizeOf(WCHAR) * opts.Name.len),
+ .TimeoutSpecified = @intFromBool(opts.Timeout != null),
+ .Name = undefined,
+ };
+ @memcpy(fpwfb.Name[0..opts.Name.len], opts.Name);
+ return fpwfb;
+ }
+
+ pub fn getName(fpwfb: *const WAIT_FOR_BUFFER) []const WCHAR {
+ return fpwfb.Name[0..@divExact(fpwfb.NameLength, @sizeOf(WCHAR))];
+ }
+
+ pub fn toBuffer(fpwfb: *const WAIT_FOR_BUFFER) []const u8 {
+ const start: [*]const u8 = @ptrCast(fpwfb);
+ return start[0 .. @offsetOf(WAIT_FOR_BUFFER, "Name") + fpwfb.NameLength];
+ }
+ };
+ };
+
+ pub const ALL_INFORMATION = extern struct {
+ BasicInformation: BASIC_INFORMATION,
+ StandardInformation: STANDARD_INFORMATION,
+ InternalInformation: INTERNAL_INFORMATION,
+ EaInformation: EA_INFORMATION,
+ AccessInformation: ACCESS_INFORMATION,
+ PositionInformation: POSITION_INFORMATION,
+ ModeInformation: MODE.INFORMATION,
+ AlignmentInformation: ALIGNMENT_INFORMATION,
+ NameInformation: NAME_INFORMATION,
+ };
+
+ pub const INTERNAL_INFORMATION = extern struct {
+ IndexNumber: LARGE_INTEGER,
+ };
+
+ pub const EA_INFORMATION = extern struct {
+ EaSize: ULONG,
+ };
+
+ pub const ACCESS_INFORMATION = extern struct {
+ AccessFlags: ACCESS_MASK,
+ };
+
+ pub const RENAME_INFORMATION = extern struct {
+ Flags: FLAGS,
+ RootDirectory: ?HANDLE,
+ FileNameLength: ULONG,
+ FileName: [PATH_MAX_WIDE]WCHAR,
+
+ pub fn init(opts: struct {
+ Flags: FLAGS = .{},
+ RootDirectory: ?HANDLE = null,
+ FileName: []const WCHAR,
+ }) RENAME_INFORMATION {
+ var fri: RENAME_INFORMATION = .{
+ .Flags = opts.Flags,
+ .RootDirectory = opts.RootDirectory,
+ .FileNameLength = @intCast(@sizeOf(WCHAR) * opts.FileName.len),
+ .FileName = undefined,
+ };
+ @memcpy(fri.FileName[0..opts.FileName.len], opts.FileName);
+ return fri;
+ }
+
+ pub const FLAGS = packed struct(ULONG) {
+ REPLACE_IF_EXISTS: bool = false,
+ POSIX_SEMANTICS: bool = false,
+ SUPPRESS_PIN_STATE_INHERITANCE: bool = false,
+ SUPPRESS_STORAGE_RESERVE_INHERITANCE: bool = false,
+ AVAILABLE_SPACE: enum(u2) {
+ NO_PRESERVE = 0b00,
+ NO_INCREASE = 0b01,
+ NO_DECREASE = 0b10,
+ PRESERVE = 0b11,
+ } = .NO_PRESERVE,
+ IGNORE_READONLY_ATTRIBUTE: bool = false,
+ RESIZE_SR: enum(u2) {
+ NO_FORCE = 0b00,
+ FORCE_TARGET = 0b01,
+ FORCE_SOURCE = 0b10,
+ FORCE = 0b11,
+ } = .NO_FORCE,
+ Reserved9: u23 = 0,
+ };
+
+ pub fn getFileName(ri: *const RENAME_INFORMATION) []const WCHAR {
+ return ri.FileName[0..@divExact(ri.FileNameLength, @sizeOf(WCHAR))];
+ }
+
+ pub fn toBuffer(fri: *const RENAME_INFORMATION) []const u8 {
+ const start: [*]const u8 = @ptrCast(fri);
+ return start[0 .. @offsetOf(RENAME_INFORMATION, "FileName") + fri.FileNameLength];
+ }
+ };
+
+ // ref: km/wdm.h
+
+ pub const INFORMATION_CLASS = enum(c_int) {
+ Directory = 1,
+ FullDirectory = 2,
+ BothDirectory = 3,
+ Basic = 4,
+ Standard = 5,
+ Internal = 6,
+ Ea = 7,
+ Access = 8,
+ Name = 9,
+ Rename = 10,
+ Link = 11,
+ Names = 12,
+ Disposition = 13,
+ Position = 14,
+ FullEa = 15,
+ Mode = 16,
+ Alignment = 17,
+ All = 18,
+ Allocation = 19,
+ EndOfFile = 20,
+ AlternateName = 21,
+ Stream = 22,
+ Pipe = 23,
+ PipeLocal = 24,
+ PipeRemote = 25,
+ MailslotQuery = 26,
+ MailslotSet = 27,
+ Compression = 28,
+ ObjectId = 29,
+ Completion = 30,
+ MoveCluster = 31,
+ Quota = 32,
+ ReparsePoint = 33,
+ NetworkOpen = 34,
+ AttributeTag = 35,
+ Tracking = 36,
+ IdBothDirectory = 37,
+ IdFullDirectory = 38,
+ ValidDataLength = 39,
+ ShortName = 40,
+ IoCompletionNotification = 41,
+ IoStatusBlockRange = 42,
+ IoPriorityHint = 43,
+ SfioReserve = 44,
+ SfioVolume = 45,
+ HardLink = 46,
+ ProcessIdsUsingFile = 47,
+ NormalizedName = 48,
+ NetworkPhysicalName = 49,
+ IdGlobalTxDirectory = 50,
+ IsRemoteDevice = 51,
+ Unused = 52,
+ NumaNode = 53,
+ StandardLink = 54,
+ RemoteProtocol = 55,
+ RenameBypassAccessCheck = 56,
+ LinkBypassAccessCheck = 57,
+ VolumeName = 58,
+ Id = 59,
+ IdExtdDirectory = 60,
+ ReplaceCompletion = 61,
+ HardLinkFullId = 62,
+ IdExtdBothDirectory = 63,
+ DispositionEx = 64,
+ RenameEx = 65,
+ RenameExBypassAccessCheck = 66,
+ DesiredStorageClass = 67,
+ Stat = 68,
+ MemoryPartition = 69,
+ StatLx = 70,
+ CaseSensitive = 71,
+ LinkEx = 72,
+ LinkExBypassAccessCheck = 73,
+ StorageReserveId = 74,
+ CaseSensitiveForceAccessCheck = 75,
+ KnownFolder = 76,
+ StatBasic = 77,
+ Id64ExtdDirectory = 78,
+ Id64ExtdBothDirectory = 79,
+ IdAllExtdDirectory = 80,
+ IdAllExtdBothDirectory = 81,
+ StreamReservation = 82,
+ MupProvider = 83,
+
+ pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len;
+ };
+
+ pub const BASIC_INFORMATION = extern struct {
+ CreationTime: LARGE_INTEGER,
+ LastAccessTime: LARGE_INTEGER,
+ LastWriteTime: LARGE_INTEGER,
+ ChangeTime: LARGE_INTEGER,
+ FileAttributes: ATTRIBUTE,
+ };
+
+ pub const STANDARD_INFORMATION = extern struct {
+ AllocationSize: LARGE_INTEGER,
+ EndOfFile: LARGE_INTEGER,
+ NumberOfLinks: ULONG,
+ DeletePending: BOOLEAN,
+ Directory: BOOLEAN,
+ };
+
+ pub const POSITION_INFORMATION = extern struct {
+ CurrentByteOffset: LARGE_INTEGER,
+ };
+
+ pub const FS_DEVICE_INFORMATION = extern struct {
+ DeviceType: DEVICE_TYPE,
+ Characteristics: ULONG,
+ };
+
+ // ref: um/WinBase.h
+
+ pub const ATTRIBUTE_TAG_INFO = extern struct {
+ FileAttributes: DWORD,
+ ReparseTag: IO_REPARSE_TAG,
+ };
+
+ // ref: um/winnt.h
+
+ pub const SHARE = packed struct(ULONG) {
+ /// The file can be opened for read access by other threads.
+ READ: bool = false,
+ /// The file can be opened for write access by other threads.
+ WRITE: bool = false,
+ /// The file can be opened for delete access by other threads.
+ DELETE: bool = false,
+ Reserved3: u29 = 0,
+
+ pub const VALID_FLAGS: SHARE = .{
+ .READ = true,
+ .WRITE = true,
+ .DELETE = true,
+ };
+ };
+
+ pub const ATTRIBUTE = packed struct(ULONG) {
+ /// The file is read only. Applications can read the file, but cannot write to or delete it.
+ READONLY: bool = false,
+ /// The file is hidden. Do not include it in an ordinary directory listing.
+ HIDDEN: bool = false,
+ /// The file is part of or used exclusively by an operating system.
+ SYSTEM: bool = false,
+ Reserved3: u1 = 0,
+ DIRECTORY: bool = false,
+ /// The file should be archived. Applications use this attribute to mark files for backup or removal.
+ ARCHIVE: bool = false,
+ DEVICE: bool = false,
+ /// The file does not have other attributes set. This attribute is valid only if used alone.
+ NORMAL: bool = false,
+ /// The file is being used for temporary storage.
+ TEMPORARY: bool = false,
+ SPARSE_FILE: bool = false,
+ REPARSE_POINT: bool = false,
+ COMPRESSED: bool = false,
+ /// The data of a file is not immediately available. This attribute indicates that file data is physically moved to offline storage.
+ /// This attribute is used by Remote Storage, the hierarchical storage management software. Applications should not arbitrarily change this attribute.
+ OFFLINE: bool = false,
+ NOT_CONTENT_INDEXED: bool = false,
+ /// The file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is
+ /// the default for newly created files and subdirectories. For more information, see File Encryption.
+ ///
+ /// This flag has no effect if `SYSTEM` is also specified.
+ ///
+ /// This flag is not supported on Home, Home Premium, Starter, or ARM editions of Windows.
+ ENCRYPTED: bool = false,
+ INTEGRITY_STREAM: bool = false,
+ VIRTUAL: bool = false,
+ NO_SCRUB_DATA: bool = false,
+ EA_or_RECALL_ON_OPEN: bool = false,
+ PINNED: bool = false,
+ UNPINNED: bool = false,
+ Reserved21: u1 = 0,
+ RECALL_ON_DATA_ACCESS: bool = false,
+ Reserved23: u6 = 0,
+ STRICTLY_SEQUENTIAL: bool = false,
+ Reserved30: u2 = 0,
+ };
+
+ // ref: um/winternl.h
+
+ /// Define the create disposition values
+ pub const CREATE_DISPOSITION = enum(ULONG) {
+ /// If the file already exists, replace it with the given file. If it does not, create the given file.
+ SUPERSEDE = 0x00000000,
+ /// If the file already exists, open it instead of creating a new file. If it does not, fail the request and do not create a new file.
+ OPEN = 0x00000001,
+ /// If the file already exists, fail the request and do not create or open the given file. If it does not, create the given file.
+ CREATE = 0x00000002,
+ /// If the file already exists, open it. If it does not, create the given file.
+ OPEN_IF = 0x00000003,
+ /// If the file already exists, open it and overwrite it. If it does not, fail the request.
+ OVERWRITE = 0x00000004,
+ /// If the file already exists, open it and overwrite it. If it does not, create the given file.
+ OVERWRITE_IF = 0x00000005,
+
+ pub const MAXIMUM_DISPOSITION: CREATE_DISPOSITION = .OVERWRITE_IF;
+ };
+
+ /// Define the create/open option flags
+ pub const MODE = packed struct(ULONG) {
+ /// The file being created or opened is a directory file. With this flag, the CreateDisposition parameter must be set to `.CREATE`, `.FILE_OPEN`, or `.OPEN_IF`.
+ /// With this flag, other compatible CreateOptions flags include only the following: `SYNCHRONOUS_IO`, `WRITE_THROUGH`, `OPEN_FOR_BACKUP_INTENT`, and `OPEN_BY_FILE_ID`.
+ DIRECTORY_FILE: bool = false,
+ /// Applications that write data to the file must actually transfer the data into the file before any requested write operation is considered complete.
+ /// This flag is automatically set if the CreateOptions flag `NO_INTERMEDIATE_BUFFERING` is set.
+ WRITE_THROUGH: bool = false,
+ /// All accesses to the file are sequential.
+ SEQUENTIAL_ONLY: bool = false,
+ /// The file cannot be cached or buffered in a driver's internal buffers. This flag is incompatible with the DesiredAccess `FILE_APPEND_DATA` flag.
+ NO_INTERMEDIATE_BUFFERING: bool = false,
+ IO: enum(u2) {
+ /// All operations on the file are performed asynchronously.
+ ASYNCHRONOUS = 0b00,
+ /// All operations on the file are performed synchronously. Any wait on behalf of the caller is subject to premature termination from alerts.
+ /// This flag also causes the I/O system to maintain the file position context. If this flag is set, the DesiredAccess `SYNCHRONIZE` flag also must be set.
+ SYNCHRONOUS_ALERT = 0b01,
+ /// All operations on the file are performed synchronously. Waits in the system to synchronize I/O queuing and completion are not subject to alerts.
+ /// This flag also causes the I/O system to maintain the file position context. If this flag is set, the DesiredAccess `SYNCHRONIZE` flag also must be set.
+ SYNCHRONOUS_NONALERT = 0b10,
+ _,
+
+ pub const VALID_FLAGS: @This() = @enumFromInt(0b11);
+ } = .ASYNCHRONOUS,
+ /// The file being opened must not be a directory file or this call fails. The file object being opened can represent a data file, a logical, virtual, or physical
+ /// device, or a volume.
+ NON_DIRECTORY_FILE: bool = false,
+ /// Create a tree connection for this file in order to open it over the network. This flag is not used by device and intermediate drivers.
+ CREATE_TREE_CONNECTION: bool = false,
+ /// Complete this operation immediately with an alternate success code of `STATUS_OPLOCK_BREAK_IN_PROGRESS` if the target file is oplocked, rather than blocking
+ /// the caller's thread. If the file is oplocked, another caller already has access to the file. This flag is not used by device and intermediate drivers.
+ COMPLETE_IF_OPLOCKED: bool = false,
+ /// If the extended attributes on an existing file being opened indicate that the caller must understand EAs to properly interpret the file, fail this request
+ /// because the caller does not understand how to deal with EAs. This flag is irrelevant for device and intermediate drivers.
+ NO_EA_KNOWLEDGE: bool = false,
+ OPEN_REMOTE_INSTANCE: bool = false,
+ /// Accesses to the file can be random, so no sequential read-ahead operations should be performed on the file by FSDs or the system.
+ RANDOM_ACCESS: bool = false,
+ /// Delete the file when the last handle to it is passed to `NtClose`. If this flag is set, the `DELETE` flag must be set in the DesiredAccess parameter.
+ DELETE_ON_CLOSE: bool = false,
+ /// The file name that is specified by the `ObjectAttributes` parameter includes the 8-byte file reference number for the file. This number is assigned by and
+ /// specific to the particular file system. If the file is a reparse point, the file name will also include the name of a device. Note that the FAT file system
+ /// does not support this flag. This flag is not used by device and intermediate drivers.
+ OPEN_BY_FILE_ID: bool = false,
+ /// The file is being opened for backup intent. Therefore, the system should check for certain access rights and grant the caller the appropriate access to the
+ /// file before checking the DesiredAccess parameter against the file's security descriptor. This flag not used by device and intermediate drivers.
+ OPEN_FOR_BACKUP_INTENT: bool = false,
+ /// Suppress inheritance of `FILE_ATTRIBUTE.COMPRESSED` from the parent directory. This allows creation of a non-compressed file in a directory that is marked
+ /// compressed.
+ NO_COMPRESSION: bool = false,
+ /// The file is being opened and an opportunistic lock on the file is being requested as a single atomic operation. The file system checks for oplocks before it
+ /// performs the create operation and will fail the create with a return code of STATUS_CANNOT_BREAK_OPLOCK if the result would be to break an existing oplock.
+ /// For more information, see the Remarks section.
+ ///
+ /// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This flag is not supported.
+ ///
+ /// This flag is supported on the following file systems: NTFS, FAT, and exFAT.
+ OPEN_REQUIRING_OPLOCK: bool = false,
+ Reserved17: u3 = 0,
+ /// This flag allows an application to request a filter opportunistic lock to prevent other applications from getting share violations. If there are already open
+ /// handles, the create request will fail with STATUS_OPLOCK_NOT_GRANTED. For more information, see the Remarks section.
+ RESERVE_OPFILTER: bool = false,
+ /// Open a file with a reparse point and bypass normal reparse point processing for the file. For more information, see the Remarks section.
+ OPEN_REPARSE_POINT: bool = false,
+ /// Instructs any filters that perform offline storage or virtualization to not recall the contents of the file as a result of this open.
+ OPEN_NO_RECALL: bool = false,
+ /// This flag instructs the file system to capture the user associated with the calling thread. Any subsequent calls to `FltQueryVolumeInformation` or
+ /// `ZwQueryVolumeInformationFile` using the returned handle will assume the captured user, rather than the calling user at the time, for purposes of computing
+ /// the free space available to the caller. This applies to the following FsInformationClass values: `FileFsSizeInformation`, `FileFsFullSizeInformation`, and
+ /// `FileFsFullSizeInformationEx`.
+ OPEN_FOR_FREE_SPACE_QUERY: bool = false,
+ Reserved24: u8 = 0,
+
+ pub const VALID_OPTION_FLAGS: MODE = .{
+ .DIRECTORY_FILE = true,
+ .WRITE_THROUGH = true,
+ .SEQUENTIAL_ONLY = true,
+ .NO_INTERMEDIATE_BUFFERING = true,
+ .IO = .VALID_FLAGS,
+ .NON_DIRECTORY_FILE = true,
+ .CREATE_TREE_CONNECTION = true,
+ .COMPLETE_IF_OPLOCKED = true,
+ .NO_EA_KNOWLEDGE = true,
+ .OPEN_REMOTE_INSTANCE = true,
+ .RANDOM_ACCESS = true,
+ .DELETE_ON_CLOSE = true,
+ .OPEN_BY_FILE_ID = true,
+ .OPEN_FOR_BACKUP_INTENT = true,
+ .NO_COMPRESSION = true,
+ .OPEN_REQUIRING_OPLOCK = true,
+ .Reserved17 = 0b111,
+ .RESERVE_OPFILTER = true,
+ .OPEN_REPARSE_POINT = true,
+ .OPEN_NO_RECALL = true,
+ .OPEN_FOR_FREE_SPACE_QUERY = true,
+ };
+
+ pub const VALID_PIPE_OPTION_FLAGS: MODE = .{
+ .WRITE_THROUGH = true,
+ .IO = .VALID_FLAGS,
+ };
+
+ pub const VALID_MAILSLOT_OPTION_FLAGS: MODE = .{
+ .WRITE_THROUGH = true,
+ .IO = .VALID_FLAGS,
+ };
+
+ pub const VALID_SET_OPTION_FLAGS: MODE = .{
+ .WRITE_THROUGH = true,
+ .SEQUENTIAL_ONLY = true,
+ .IO = .VALID_FLAGS,
+ };
+
+ // ref: km/ntifs.h
+
+ pub const INFORMATION = extern struct {
+ /// The set of flags that specify the mode in which the file can be accessed. These flags are a subset of `MODE`.
+ Mode: MODE,
+ };
+ };
+};
+
+// ref: km/ntddk.h
+
+pub const PROCESSINFOCLASS = enum(c_int) {
+ BasicInformation = 0,
+ QuotaLimits = 1,
+ IoCounters = 2,
+ VmCounters = 3,
+ Times = 4,
+ BasePriority = 5,
+ RaisePriority = 6,
+ DebugPort = 7,
+ ExceptionPort = 8,
+ AccessToken = 9,
+ LdtInformation = 10,
+ LdtSize = 11,
+ DefaultHardErrorMode = 12,
+ IoPortHandlers = 13,
+ PooledUsageAndLimits = 14,
+ WorkingSetWatch = 15,
+ UserModeIOPL = 16,
+ EnableAlignmentFaultFixup = 17,
+ PriorityClass = 18,
+ Wx86Information = 19,
+ HandleCount = 20,
+ AffinityMask = 21,
+ PriorityBoost = 22,
+ DeviceMap = 23,
+ SessionInformation = 24,
+ ForegroundInformation = 25,
+ Wow64Information = 26,
+ ImageFileName = 27,
+ LUIDDeviceMapsEnabled = 28,
+ BreakOnTermination = 29,
+ DebugObjectHandle = 30,
+ DebugFlags = 31,
+ HandleTracing = 32,
+ IoPriority = 33,
+ ExecuteFlags = 34,
+ TlsInformation = 35,
+ Cookie = 36,
+ ImageInformation = 37,
+ CycleTime = 38,
+ PagePriority = 39,
+ InstrumentationCallback = 40,
+ ThreadStackAllocation = 41,
+ WorkingSetWatchEx = 42,
+ ImageFileNameWin32 = 43,
+ ImageFileMapping = 44,
+ AffinityUpdateMode = 45,
+ MemoryAllocationMode = 46,
+ GroupInformation = 47,
+ TokenVirtualizationEnabled = 48,
+ OwnerInformation = 49,
+ WindowInformation = 50,
+ HandleInformation = 51,
+ MitigationPolicy = 52,
+ DynamicFunctionTableInformation = 53,
+ HandleCheckingMode = 54,
+ KeepAliveCount = 55,
+ RevokeFileHandles = 56,
+ WorkingSetControl = 57,
+ HandleTable = 58,
+ CheckStackExtentsMode = 59,
+ CommandLineInformation = 60,
+ ProtectionInformation = 61,
+ MemoryExhaustion = 62,
+ FaultInformation = 63,
+ TelemetryIdInformation = 64,
+ CommitReleaseInformation = 65,
+ Reserved1Information = 66,
+ Reserved2Information = 67,
+ SubsystemProcess = 68,
+ InPrivate = 70,
+ RaiseUMExceptionOnInvalidHandleClose = 71,
+ SubsystemInformation = 75,
+ Win32kSyscallFilterInformation = 79,
+ EnergyTrackingState = 82,
+ NetworkIoCounters = 114,
+ _,
+
+ pub const Max: @typeInfo(@This()).@"enum".tag_type = 117;
+};
+
+pub const THREADINFOCLASS = enum(c_int) {
+ BasicInformation = 0,
+ Times = 1,
+ Priority = 2,
+ BasePriority = 3,
+ AffinityMask = 4,
+ ImpersonationToken = 5,
+ DescriptorTableEntry = 6,
+ EnableAlignmentFaultFixup = 7,
+ EventPair_Reusable = 8,
+ QuerySetWin32StartAddress = 9,
+ ZeroTlsCell = 10,
+ PerformanceCount = 11,
+ AmILastThread = 12,
+ IdealProcessor = 13,
+ PriorityBoost = 14,
+ SetTlsArrayAddress = 15,
+ IsIoPending = 16,
+ // Windows 2000+ from here
+ HideFromDebugger = 17,
+ // Windows XP+ from here
+ BreakOnTermination = 18,
+ SwitchLegacyState = 19,
+ IsTerminated = 20,
+ // Windows Vista+ from here
+ LastSystemCall = 21,
+ IoPriority = 22,
+ CycleTime = 23,
+ PagePriority = 24,
+ ActualBasePriority = 25,
+ TebInformation = 26,
+ CSwitchMon = 27,
+ // Windows 7+ from here
+ CSwitchPmu = 28,
+ Wow64Context = 29,
+ GroupInformation = 30,
+ UmsInformation = 31,
+ CounterProfiling = 32,
+ IdealProcessorEx = 33,
+ // Windows 8+ from here
+ CpuAccountingInformation = 34,
+ // Windows 8.1+ from here
+ SuspendCount = 35,
+ // Windows 10+ from here
+ HeterogeneousCpuPolicy = 36,
+ ContainerId = 37,
+ NameInformation = 38,
+ SelectedCpuSets = 39,
+ SystemThreadInformation = 40,
+ ActualGroupAffinity = 41,
+ DynamicCodePolicyInfo = 42,
+ SubsystemInformation = 45,
+
+ pub const Max: @typeInfo(@This()).@"enum".tag_type = 60;
+};
+
+// ref: km/ntifs.h
+
+pub const HEAP = opaque {
+ pub const FLAGS = packed struct(u8) {
+ /// Serialized access is not used when the heap functions access this heap. This option
+ /// applies to all subsequent heap function calls. Alternatively, you can specify this
+ /// option on individual heap function calls.
+ ///
+ /// The low-fragmentation heap (LFH) cannot be enabled for a heap created with this option.
+ ///
+ /// A heap created with this option cannot be locked.
+ NO_SERIALIZE: bool = false,
+ /// Specifies that the heap is growable. Must be specified if `HeapBase` is `NULL`.
+ GROWABLE: bool = false,
+ /// The system raises an exception to indicate failure (for example, an out-of-memory
+ /// condition) for calls to `HeapAlloc` and `HeapReAlloc` instead of returning `NULL`.
+ ///
+ /// To ensure that exceptions are generated for all calls to an allocation function, specify
+ /// `GENERATE_EXCEPTIONS` in the call to `HeapCreate`. In this case, it is not necessary to
+ /// additionally specify `GENERATE_EXCEPTIONS` in the allocation function calls.
+ GENERATE_EXCEPTIONS: bool = false,
+ /// The allocated memory will be initialized to zero. Otherwise, the memory is not
+ /// initialized to zero.
+ ZERO_MEMORY: bool = false,
+ REALLOC_IN_PLACE_ONLY: bool = false,
+ TAIL_CHECKING_ENABLED: bool = false,
+ FREE_CHECKING_ENABLED: bool = false,
+ DISABLE_COALESCE_ON_FREE: bool = false,
+
+ pub const CLASS = enum(u4) {
+ /// process heap
+ PROCESS,
+ /// private heap
+ PRIVATE,
+ /// Kernel Heap
+ KERNEL,
+ /// GDI heap
+ GDI,
+ /// User heap
+ USER,
+ /// Console heap
+ CONSOLE,
+ /// User Desktop heap
+ USER_DESKTOP,
+ /// Csrss Shared heap
+ CSRSS_SHARED,
+ /// Csr Port heap
+ CSR_PORT,
+ _,
+
+ pub const MASK: CLASS = @enumFromInt(maxInt(@typeInfo(CLASS).@"enum".tag_type));
+ };
+
+ pub const CREATE = packed struct(ULONG) {
+ COMMON: FLAGS = .{},
+ SEGMENT_HEAP: bool = false,
+ /// Only applies to segment heap. Applies pointer obfuscation which is
+ /// generally excessive and unnecessary but is necessary for certain insecure
+ /// heaps in win32k.
+ ///
+ /// Specifying HEAP_CREATE_HARDENED prevents the heap from using locks as
+ /// pointers would potentially be exposed in heap metadata lock variables.
+ /// Callers are therefore responsible for synchronizing access to hardened heaps.
+ HARDENED: bool = false,
+ Reserved10: u2 = 0,
+ CLASS: CLASS = @enumFromInt(0),
+ /// Create heap with 16 byte alignment (obsolete)
+ ALIGN_16: bool = false,
+ /// Create heap call tracing enabled (obsolete)
+ ENABLE_TRACING: bool = false,
+ /// Create heap with executable pages
+ ///
+ /// All memory blocks that are allocated from this heap allow code execution, if the
+ /// hardware enforces data execution prevention. Use this flag heap in applications that
+ /// run code from the heap. If `ENABLE_EXECUTE` is not specified and an application
+ /// attempts to run code from a protected page, the application receives an exception
+ /// with the status code `STATUS_ACCESS_VIOLATION`.
+ ENABLE_EXECUTE: bool = false,
+ Reserved19: u13 = 0,
+
+ pub const VALID_MASK: CREATE = .{
+ .COMMON = .{
+ .NO_SERIALIZE = true,
+ .GROWABLE = true,
+ .GENERATE_EXCEPTIONS = true,
+ .ZERO_MEMORY = true,
+ .REALLOC_IN_PLACE_ONLY = true,
+ .TAIL_CHECKING_ENABLED = true,
+ .FREE_CHECKING_ENABLED = true,
+ .DISABLE_COALESCE_ON_FREE = true,
+ },
+ .CLASS = .MASK,
+ .ALIGN_16 = true,
+ .ENABLE_TRACING = true,
+ .ENABLE_EXECUTE = true,
+ .SEGMENT_HEAP = true,
+ .HARDENED = true,
+ };
+ };
+
+ pub const ALLOCATION = packed struct(ULONG) {
+ COMMON: FLAGS = .{},
+ SETTABLE_USER: packed struct(u4) {
+ VALUE: u1 = 0,
+ FLAGS: packed struct(u3) {
+ FLAG1: bool = false,
+ FLAG2: bool = false,
+ FLAG3: bool = false,
+ } = .{},
+ } = .{},
+ CLASS: CLASS = @enumFromInt(0),
+ Reserved16: u2 = 0,
+ TAG: u12 = 0,
+ Reserved30: u2 = 0,
+ };
+ };
+
+ pub const RTL_PARAMETERS = extern struct {
+ Length: ULONG,
+ SegmentReserve: SIZE_T,
+ SegmentCommit: SIZE_T,
+ DeCommitFreeBlockThreshold: SIZE_T,
+ DeCommitTotalFreeThreshold: SIZE_T,
+ MaximumAllocationSize: SIZE_T,
+ VirtualMemoryThreshold: SIZE_T,
+ InitialCommit: SIZE_T,
+ InitialReserve: SIZE_T,
+ CommitRoutine: *const COMMIT_ROUTINE,
+ Reserved: [2]SIZE_T = @splat(0),
+
+ pub const COMMIT_ROUTINE = fn (
+ Base: PVOID,
+ CommitAddress: *PVOID,
+ CommitSize: *SIZE_T,
+ ) callconv(.winapi) NTSTATUS;
+
+ pub const SEGMENT = extern struct {
+ Version: VERSION,
+ Size: USHORT,
+ Flags: FLG,
+ MemorySource: MEMORY_SOURCE,
+ Reserved: [4]SIZE_T,
+
+ pub const VERSION = enum(USHORT) {
+ CURRENT = 3,
+ _,
+ };
+
+ pub const FLG = packed struct(ULONG) {
+ USE_PAGE_HEAP: bool = false,
+ NO_LFH: bool = false,
+ Reserved2: u30 = 0,
+
+ pub const VALID_FLAGS: FLG = .{
+ .USE_PAGE_HEAP = true,
+ .NO_LFH = true,
+ };
+ };
+
+ pub const MEMORY_SOURCE = extern struct {
+ Flags: ULONG,
+ MemoryTypeMask: TYPE,
+ NumaNode: ULONG,
+ u: extern union {
+ PartitionHandle: HANDLE,
+ Callbacks: *const VA_CALLBACKS,
+ },
+ Reserved: [2]SIZE_T = @splat(0),
+
+ pub const TYPE = enum(ULONG) {
+ Paged,
+ NonPaged,
+ @"64KPage",
+ LargePage,
+ HugePage,
+ Custom,
+ _,
+
+ pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len;
+ };
+
+ pub const VA_CALLBACKS = extern struct {
+ CallbackContext: HANDLE,
+ AllocateVirtualMemory: *const ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK,
+ FreeVirtualMemory: *const FREE_VIRTUAL_MEMORY_EX_CALLBACK,
+ QueryVirtualMemory: *const QUERY_VIRTUAL_MEMORY_CALLBACK,
+
+ pub const ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK = fn (
+ CallbackContext: HANDLE,
+ BaseAddress: *PVOID,
+ RegionSize: *SIZE_T,
+ AllocationType: ULONG,
+ PageProtection: ULONG,
+ ExtendedParameters: ?[*]MEM.EXTENDED_PARAMETER,
+ ExtendedParameterCount: ULONG,
+ ) callconv(.c) NTSTATUS;
+
+ pub const FREE_VIRTUAL_MEMORY_EX_CALLBACK = fn (
+ CallbackContext: HANDLE,
+ ProcessHandle: HANDLE,
+ BaseAddress: *PVOID,
+ RegionSize: *SIZE_T,
+ FreeType: ULONG,
+ ) callconv(.c) NTSTATUS;
+
+ pub const QUERY_VIRTUAL_MEMORY_CALLBACK = fn (
+ CallbackContext: HANDLE,
+ ProcessHandle: HANDLE,
+ BaseAddress: *PVOID,
+ MemoryInformationClass: MEMORY_INFO_CLASS,
+ MemoryInformation: PVOID,
+ MemoryInformationLength: SIZE_T,
+ ReturnLength: ?*SIZE_T,
+ ) callconv(.c) NTSTATUS;
+
+ pub const MEMORY_INFO_CLASS = enum(c_int) {
+ Basic,
+ _,
+ };
+ };
+ };
+ };
+ };
+};
+
+pub const CTL_CODE = packed struct(ULONG) {
+ Method: METHOD,
+ Function: u12,
+ Access: FILE_ACCESS,
+ DeviceType: FILE_DEVICE,
+
+ pub const METHOD = enum(u2) {
+ BUFFERED = 0,
+ IN_DIRECT = 1,
+ OUT_DIRECT = 2,
+ NEITHER = 3,
+ };
+
+ pub const FILE_ACCESS = packed struct(u2) {
+ READ: bool = false,
+ WRITE: bool = false,
+
+ pub const ANY: FILE_ACCESS = .{ .READ = false, .WRITE = false };
+ pub const SPECIAL = ANY;
+ };
+
+ pub const FILE_DEVICE = enum(u16) {
+ BEEP = 0x00000001,
+ CD_ROM = 0x00000002,
+ CD_ROM_FILE_SYSTEM = 0x00000003,
+ CONTROLLER = 0x00000004,
+ DATALINK = 0x00000005,
+ DFS = 0x00000006,
+ DISK = 0x00000007,
+ DISK_FILE_SYSTEM = 0x00000008,
+ FILE_SYSTEM = 0x00000009,
+ INPORT_PORT = 0x0000000a,
+ KEYBOARD = 0x0000000b,
+ MAILSLOT = 0x0000000c,
+ MIDI_IN = 0x0000000d,
+ MIDI_OUT = 0x0000000e,
+ MOUSE = 0x0000000f,
+ MULTI_UNC_PROVIDER = 0x00000010,
+ NAMED_PIPE = 0x00000011,
+ NETWORK = 0x00000012,
+ NETWORK_BROWSER = 0x00000013,
+ NETWORK_FILE_SYSTEM = 0x00000014,
+ NULL = 0x00000015,
+ PARALLEL_PORT = 0x00000016,
+ PHYSICAL_NETCARD = 0x00000017,
+ PRINTER = 0x00000018,
+ SCANNER = 0x00000019,
+ SERIAL_MOUSE_PORT = 0x0000001a,
+ SERIAL_PORT = 0x0000001b,
+ SCREEN = 0x0000001c,
+ SOUND = 0x0000001d,
+ STREAMS = 0x0000001e,
+ TAPE = 0x0000001f,
+ TAPE_FILE_SYSTEM = 0x00000020,
+ TRANSPORT = 0x00000021,
+ UNKNOWN = 0x00000022,
+ VIDEO = 0x00000023,
+ VIRTUAL_DISK = 0x00000024,
+ WAVE_IN = 0x00000025,
+ WAVE_OUT = 0x00000026,
+ @"8042_PORT" = 0x00000027,
+ NETWORK_REDIRECTOR = 0x00000028,
+ BATTERY = 0x00000029,
+ BUS_EXTENDER = 0x0000002a,
+ MODEM = 0x0000002b,
+ VDM = 0x0000002c,
+ MASS_STORAGE = 0x0000002d,
+ SMB = 0x0000002e,
+ KS = 0x0000002f,
+ CHANGER = 0x00000030,
+ SMARTCARD = 0x00000031,
+ ACPI = 0x00000032,
+ DVD = 0x00000033,
+ FULLSCREEN_VIDEO = 0x00000034,
+ DFS_FILE_SYSTEM = 0x00000035,
+ DFS_VOLUME = 0x00000036,
+ SERENUM = 0x00000037,
+ TERMSRV = 0x00000038,
+ KSEC = 0x00000039,
+ FIPS = 0x0000003A,
+ INFINIBAND = 0x0000003B,
+ VMBUS = 0x0000003E,
+ CRYPT_PROVIDER = 0x0000003F,
+ WPD = 0x00000040,
+ BLUETOOTH = 0x00000041,
+ MT_COMPOSITE = 0x00000042,
+ MT_TRANSPORT = 0x00000043,
+ BIOMETRIC = 0x00000044,
+ PMI = 0x00000045,
+ EHSTOR = 0x00000046,
+ DEVAPI = 0x00000047,
+ GPIO = 0x00000048,
+ USBEX = 0x00000049,
+ CONSOLE = 0x00000050,
+ NFP = 0x00000051,
+ SYSENV = 0x00000052,
+ VIRTUAL_BLOCK = 0x00000053,
+ POINT_OF_SERVICE = 0x00000054,
+ STORAGE_REPLICATION = 0x00000055,
+ TRUST_ENV = 0x00000056,
+ UCM = 0x00000057,
+ UCMTCPCI = 0x00000058,
+ PERSISTENT_MEMORY = 0x00000059,
+ NVDIMM = 0x0000005a,
+ HOLOGRAPHIC = 0x0000005b,
+ SDFXHCI = 0x0000005c,
+ UCMUCSI = 0x0000005d,
+ PRM = 0x0000005e,
+ EVENT_COLLECTOR = 0x0000005f,
+ USB4 = 0x00000060,
+ SOUNDWIRE = 0x00000061,
+
+ MOUNTMGRCONTROLTYPE = 'm',
+
+ _,
+ };
+};
+
+pub const IOCTL = struct {
+ pub const MOUNTMGR = struct {
+ pub const QUERY_POINTS: CTL_CODE = .{ .DeviceType = .MOUNTMGRCONTROLTYPE, .Function = 2, .Method = .BUFFERED, .Access = .ANY };
+ pub const QUERY_DOS_VOLUME_PATH: CTL_CODE = .{ .DeviceType = .MOUNTMGRCONTROLTYPE, .Function = 12, .Method = .BUFFERED, .Access = .ANY };
+ };
+};
+
+pub const FSCTL = struct {
+ pub const SET_REPARSE_POINT: CTL_CODE = .{ .DeviceType = .FILE_SYSTEM, .Function = 41, .Method = .BUFFERED, .Access = .SPECIAL };
+ pub const GET_REPARSE_POINT: CTL_CODE = .{ .DeviceType = .FILE_SYSTEM, .Function = 42, .Method = .BUFFERED, .Access = .ANY };
+
+ pub const PIPE = struct {
+ pub const ASSIGN_EVENT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 0, .Method = .BUFFERED, .Access = .ANY };
+ pub const DISCONNECT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 1, .Method = .BUFFERED, .Access = .ANY };
+ pub const LISTEN: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2, .Method = .BUFFERED, .Access = .ANY };
+ pub const PEEK: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 3, .Method = .BUFFERED, .Access = .{ .READ = true } };
+ pub const QUERY_EVENT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 4, .Method = .BUFFERED, .Access = .ANY };
+ pub const TRANSCEIVE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 5, .Method = .NEITHER, .Access = .{ .READ = true, .WRITE = true } };
+ pub const WAIT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 6, .Method = .BUFFERED, .Access = .ANY };
+ pub const IMPERSONATE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 7, .Method = .BUFFERED, .Access = .ANY };
+ pub const SET_CLIENT_PROCESS: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 8, .Method = .BUFFERED, .Access = .ANY };
+ pub const QUERY_CLIENT_PROCESS: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 9, .Method = .BUFFERED, .Access = .ANY };
+ pub const GET_PIPE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 10, .Method = .BUFFERED, .Access = .ANY };
+ pub const SET_PIPE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 11, .Method = .BUFFERED, .Access = .ANY };
+ pub const GET_CONNECTION_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 12, .Method = .BUFFERED, .Access = .ANY };
+ pub const SET_CONNECTION_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 13, .Method = .BUFFERED, .Access = .ANY };
+ pub const GET_HANDLE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 14, .Method = .BUFFERED, .Access = .ANY };
+ pub const SET_HANDLE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 15, .Method = .BUFFERED, .Access = .ANY };
+ pub const FLUSH: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 16, .Method = .BUFFERED, .Access = .{ .WRITE = true } };
+
+ pub const INTERNAL_READ: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2045, .Method = .BUFFERED, .Access = .{ .READ = true } };
+ pub const INTERNAL_WRITE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2046, .Method = .BUFFERED, .Access = .{ .WRITE = true } };
+ pub const INTERNAL_TRANSCEIVE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2047, .Method = .NEITHER, .Access = .{ .READ = true, .WRITE = true } };
+ pub const INTERNAL_READ_OVFLOW: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2048, .Method = .BUFFERED, .Access = .{ .READ = true } };
+ };
+};
+
+pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024;
+
+pub const IO_REPARSE_TAG = packed struct(ULONG) {
+ Value: u12,
+ Index: u4 = 0,
+ ReservedBits: u12 = 0,
+ /// Can have children if a directory.
+ IsDirectory: bool = false,
+ /// Represents another named entity in the system.
+ IsSurrogate: bool = false,
+ /// Must be `false` for non-Microsoft tags.
+ IsReserved: bool = false,
+ /// Owned by Microsoft.
+ IsMicrosoft: bool = false,
+
+ pub const RESERVED_INVALID: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Index = 0x8, .Value = 0x000 };
+ pub const MOUNT_POINT: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x003 };
+ pub const HSM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Value = 0x004 };
+ pub const DRIVE_EXTENDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x005 };
+ pub const HSM2: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x006 };
+ pub const SIS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x007 };
+ pub const WIM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x008 };
+ pub const CSV: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x009 };
+ pub const DFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x00A };
+ pub const FILTER_MANAGER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x00B };
+ pub const SYMLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x00C };
+ pub const IIS_CACHE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x010 };
+ pub const DFSR: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x012 };
+ pub const DEDUP: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x013 };
+ pub const APPXSTRM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Value = 0x014 };
+ pub const NFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x014 };
+ pub const FILE_PLACEHOLDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x015 };
+ pub const DFM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x016 };
+ pub const WOF: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x017 };
+ pub inline fn WCI(index: u1) IO_REPARSE_TAG {
+ return .{ .IsMicrosoft = true, .IsDirectory = index == 0x1, .Index = index, .Value = 0x018 };
+ }
+ pub const GLOBAL_REPARSE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x0019 };
+ pub inline fn CLOUD(index: u4) IO_REPARSE_TAG {
+ return .{ .IsMicrosoft = true, .IsDirectory = true, .Index = index, .Value = 0x01A };
+ }
+ pub const APPEXECLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x01B };
+ pub const PROJFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsDirectory = true, .Value = 0x01C };
+ pub const LX_SYMLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x01D };
+ pub const STORAGE_SYNC: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x01E };
+ pub const WCI_TOMBSTONE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x01F };
+ pub const UNHANDLED: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x020 };
+ pub const ONEDRIVE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x021 };
+ pub const PROJFS_TOMBSTONE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x022 };
+ pub const AF_UNIX: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x023 };
+ pub const LX_FIFO: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x024 };
+ pub const LX_CHR: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x025 };
+ pub const LX_BLK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x026 };
+ pub const LX_STORAGE_SYNC_FOLDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsDirectory = true, .Value = 0x027 };
+ pub inline fn WCI_LINK(index: u1) IO_REPARSE_TAG {
+ return .{ .IsMicrosoft = true, .IsSurrogate = true, .Index = index, .Value = 0x027 };
+ }
+ pub const DATALESS_CIM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x28 };
+};
+
+// ref: km/wdm.h
+
+pub const ACCESS_MASK = packed struct(DWORD) {
+ SPECIFIC: Specific = .{ .bits = 0 },
+ STANDARD: Standard = .{},
+ Reserved21: u3 = 0,
+ ACCESS_SYSTEM_SECURITY: bool = false,
+ MAXIMUM_ALLOWED: bool = false,
+ Reserved26: u2 = 0,
+ GENERIC: Generic = .{},
+
+ pub const Specific = packed union {
+ bits: u16,
+
+ // ref: km/wdm.h
+
+ /// Define access rights to files and directories
+ FILE: File,
+ FILE_DIRECTORY: File.Directory,
+ FILE_PIPE: File.Pipe,
+ /// Registry Specific Access Rights.
+ KEY: Key,
+ /// Object Manager Object Type Specific Access Rights.
+ OBJECT_TYPE: ObjectType,
+ /// Object Manager Directory Specific Access Rights.
+ DIRECTORY: Directory,
+ /// Object Manager Symbolic Link Specific Access Rights.
+ SYMBOLIC_LINK: SymbolicLink,
+ /// Section Access Rights.
+ SECTION: Section,
+ /// Session Specific Access Rights.
+ SESSION: Session,
+ /// Process Specific Access Rights.
+ PROCESS: Process,
+ /// Thread Specific Access Rights.
+ THREAD: Thread,
+ /// Partition Specific Access Rights.
+ MEMORY_PARTITION: MemoryPartition,
+ /// Generic mappings for transaction manager rights.
+ TRANSACTIONMANAGER: TransactionManager,
+ /// Generic mappings for transaction rights.
+ TRANSACTION: Transaction,
+ /// Generic mappings for resource manager rights.
+ RESOURCEMANAGER: ResourceManager,
+ /// Generic mappings for enlistment rights.
+ ENLISTMENT: Enlistment,
+ /// Event Specific Access Rights.
+ EVENT: Event,
+ /// Semaphore Specific Access Rights.
+ SEMAPHORE: Semaphore,
+
+ // ref: km/ntifs.h
+
+ /// Token Specific Access Rights.
+ TOKEN: Token,
+
+ // um/winnt.h
+
+ /// Job Object Specific Access Rights.
+ JOB_OBJECT: JobObject,
+ /// Mutant Specific Access Rights.
+ MUTANT: Mutant,
+ /// Timer Specific Access Rights.
+ TIMER: Timer,
+ /// I/O Completion Specific Access Rights.
+ IO_COMPLETION: IoCompletion,
+
+ pub const File = packed struct(u16) {
+ READ_DATA: bool = false,
+ WRITE_DATA: bool = false,
+ APPEND_DATA: bool = false,
+ READ_EA: bool = false,
+ WRITE_EA: bool = false,
+ EXECUTE: bool = false,
+ Reserved6: u1 = 0,
+ READ_ATTRIBUTES: bool = false,
+ WRITE_ATTRIBUTES: bool = false,
+ Reserved9: u7 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .FILE = .{
+ .READ_DATA = true,
+ .WRITE_DATA = true,
+ .APPEND_DATA = true,
+ .READ_EA = true,
+ .WRITE_EA = true,
+ .EXECUTE = true,
+ .Reserved6 = maxInt(@FieldType(File, "Reserved6")),
+ .READ_ATTRIBUTES = true,
+ .WRITE_ATTRIBUTES = true,
+ } },
+ };
+
+ pub const GENERIC_READ: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .READ,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .FILE = .{
+ .READ_DATA = true,
+ .READ_ATTRIBUTES = true,
+ .READ_EA = true,
+ } },
+ };
+
+ pub const GENERIC_WRITE: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .WRITE,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .FILE = .{
+ .WRITE_DATA = true,
+ .WRITE_ATTRIBUTES = true,
+ .WRITE_EA = true,
+ .APPEND_DATA = true,
+ } },
+ };
+
+ pub const GENERIC_EXECUTE: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .EXECUTE,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .FILE = .{
+ .READ_ATTRIBUTES = true,
+ .EXECUTE = true,
+ } },
+ };
+
+ pub const Directory = packed struct(u16) {
+ LIST: bool = false,
+ ADD_FILE: bool = false,
+ ADD_SUBDIRECTORY: bool = false,
+ READ_EA: bool = false,
+ WRITE_EA: bool = false,
+ TRAVERSE: bool = false,
+ DELETE_CHILD: bool = false,
+ READ_ATTRIBUTES: bool = false,
+ WRITE_ATTRIBUTES: bool = false,
+ Reserved9: u7 = 0,
+ };
+
+ pub const Pipe = packed struct(u16) {
+ READ_DATA: bool = false,
+ WRITE_DATA: bool = false,
+ CREATE_PIPE_INSTANCE: bool = false,
+ Reserved3: u4 = 0,
+ READ_ATTRIBUTES: bool = false,
+ WRITE_ATTRIBUTES: bool = false,
+ Reserved9: u7 = 0,
+ };
+ };
+
+ pub const Key = packed struct(u16) {
+ /// Required to query the values of a registry key.
+ QUERY_VALUE: bool = false,
+ /// Required to create, delete, or set a registry value.
+ SET_VALUE: bool = false,
+ /// Required to create a subkey of a registry key.
+ CREATE_SUB_KEY: bool = false,
+ /// Required to enumerate the subkeys of a registry key.
+ ENUMERATE_SUB_KEYS: bool = false,
+ /// Required to request change notifications for a registry key or for subkeys of a registry key.
+ NOTIFY: bool = false,
+ /// Reserved for system use.
+ CREATE_LINK: bool = false,
+ Reserved6: u2 = 0,
+ /// Indicates that an application on 64-bit Windows should operate on the 64-bit registry view.
+ /// This flag is ignored by 32-bit Windows.
+ WOW64_64KEY: bool = false,
+ /// Indicates that an application on 64-bit Windows should operate on the 32-bit registry view.
+ /// This flag is ignored by 32-bit Windows.
+ WOW64_32KEY: bool = false,
+ Reserved10: u6 = 0,
+
+ pub const WOW64_RES: ACCESS_MASK = .{
+ .SPECIFIC = .{ .KEY = .{
+ .WOW64_32KEY = true,
+ .WOW64_64KEY = true,
+ } },
+ };
+
+ /// Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
+ pub const READ: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .READ,
+ .SYNCHRONIZE = false,
+ },
+ .SPECIFIC = .{ .KEY = .{
+ .QUERY_VALUE = true,
+ .ENUMERATE_SUB_KEYS = true,
+ .NOTIFY = true,
+ } },
+ };
+
+ /// Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
+ pub const WRITE: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .WRITE,
+ .SYNCHRONIZE = false,
+ },
+ .SPECIFIC = .{ .KEY = .{
+ .SET_VALUE = true,
+ .CREATE_SUB_KEY = true,
+ } },
+ };
+
+ /// Equivalent to KEY_READ.
+ pub const EXECUTE = READ;
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .ALL,
+ .SYNCHRONIZE = false,
+ },
+ .SPECIFIC = .{ .KEY = .{
+ .QUERY_VALUE = true,
+ .SET_VALUE = true,
+ .CREATE_SUB_KEY = true,
+ .ENUMERATE_SUB_KEYS = true,
+ .NOTIFY = true,
+ .CREATE_LINK = true,
+ } },
+ };
+ };
+
+ pub const ObjectType = packed struct(u16) {
+ CREATE: bool = false,
+ Reserved1: u15 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .OBJECT_TYPE = .{
+ .CREATE = true,
+ } },
+ };
+ };
+
+ pub const Directory = packed struct(u16) {
+ QUERY: bool = false,
+ TRAVERSE: bool = false,
+ CREATE_OBJECT: bool = false,
+ CREATE_SUBDIRECTORY: bool = false,
+ Reserved3: u12 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .DIRECTORY = .{
+ .QUERY = true,
+ .TRAVERSE = true,
+ .CREATE_OBJECT = true,
+ .CREATE_SUBDIRECTORY = true,
+ } },
+ };
+ };
+
+ pub const SymbolicLink = packed struct(u16) {
+ QUERY: bool = false,
+ SET: bool = false,
+ Reserved2: u14 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .SYMBOLIC_LINK = .{
+ .QUERY = true,
+ } },
+ };
+
+ pub const ALL_ACCESS_EX: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .SYMBOLIC_LINK = .{
+ .QUERY = true,
+ .SET = true,
+ .Reserved2 = maxInt(@FieldType(SymbolicLink, "Reserved2")),
+ } },
+ };
+ };
+
+ pub const Section = packed struct(u16) {
+ QUERY: bool = false,
+ MAP_WRITE: bool = false,
+ MAP_READ: bool = false,
+ MAP_EXECUTE: bool = false,
+ EXTEND_SIZE: bool = false,
+ /// not included in `ALL_ACCESS`
+ MAP_EXECUTE_EXPLICIT: bool = false,
+ Reserved6: u10 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .SECTION = .{
+ .QUERY = true,
+ .MAP_WRITE = true,
+ .MAP_READ = true,
+ .MAP_EXECUTE = true,
+ .EXTEND_SIZE = true,
+ } },
+ };
+ };
+
+ pub const Session = packed struct(u16) {
+ QUERY_ACCESS: bool = false,
+ MODIFY_ACCESS: bool = false,
+ Reserved2: u14 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .SESSION = .{
+ .QUERY_ACCESS = true,
+ .MODIFY_ACCESS = true,
+ } },
+ };
+ };
+
+ pub const Process = packed struct(u16) {
+ TERMINATE: bool = false,
+ CREATE_THREAD: bool = false,
+ SET_SESSIONID: bool = false,
+ VM_OPERATION: bool = false,
+ VM_READ: bool = false,
+ VM_WRITE: bool = false,
+ DUP_HANDLE: bool = false,
+ CREATE_PROCESS: bool = false,
+ SET_QUOTA: bool = false,
+ SET_INFORMATION: bool = false,
+ QUERY_INFORMATION: bool = false,
+ SUSPEND_RESUME: bool = false,
+ QUERY_LIMITED_INFORMATION: bool = false,
+ SET_LIMITED_INFORMATION: bool = false,
+ Reserved14: u2 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .PROCESS = .{
+ .TERMINATE = true,
+ .CREATE_THREAD = true,
+ .SET_SESSIONID = true,
+ .VM_OPERATION = true,
+ .VM_READ = true,
+ .VM_WRITE = true,
+ .DUP_HANDLE = true,
+ .CREATE_PROCESS = true,
+ .SET_QUOTA = true,
+ .SET_INFORMATION = true,
+ .QUERY_INFORMATION = true,
+ .SUSPEND_RESUME = true,
+ .QUERY_LIMITED_INFORMATION = true,
+ .SET_LIMITED_INFORMATION = true,
+ .Reserved14 = maxInt(@FieldType(Process, "Reserved14")),
+ } },
+ };
+ };
+
+ pub const Thread = packed struct(u16) {
+ TERMINATE: bool = false,
+ SUSPEND_RESUME: bool = false,
+ ALERT: bool = false,
+ GET_CONTEXT: bool = false,
+ SET_CONTEXT: bool = false,
+ SET_INFORMATION: bool = false,
+ QUERY_INFORMATION: bool = false,
+ SET_THREAD_TOKEN: bool = false,
+ IMPERSONATE: bool = false,
+ DIRECT_IMPERSONATION: bool = false,
+ SET_LIMITED_INFORMATION: bool = false,
+ QUERY_LIMITED_INFORMATION: bool = false,
+ RESUME: bool = false,
+ Reserved13: u3 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .THREAD = .{
+ .TERMINATE = true,
+ .SUSPEND_RESUME = true,
+ .ALERT = true,
+ .GET_CONTEXT = true,
+ .SET_CONTEXT = true,
+ .SET_INFORMATION = true,
+ .QUERY_INFORMATION = true,
+ .SET_THREAD_TOKEN = true,
+ .IMPERSONATE = true,
+ .DIRECT_IMPERSONATION = true,
+ .SET_LIMITED_INFORMATION = true,
+ .QUERY_LIMITED_INFORMATION = true,
+ .RESUME = true,
+ .Reserved13 = maxInt(@FieldType(Thread, "Reserved13")),
+ } },
+ };
+ };
+
+ pub const MemoryPartition = packed struct(u16) {
+ QUERY_ACCESS: bool = false,
+ MODIFY_ACCESS: bool = false,
+ Required2: u14 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .MEMORY_PARTITION = .{
+ .QUERY_ACCESS = true,
+ .MODIFY_ACCESS = true,
+ } },
+ };
+ };
+
+ pub const TransactionManager = packed struct(u16) {
+ QUERY_INFORMATION: bool = false,
+ SET_INFORMATION: bool = false,
+ RECOVER: bool = false,
+ RENAME: bool = false,
+ CREATE_RM: bool = false,
+ /// The following right is intended for DTC's use only; it will be deprecated, and no one else should take a dependency on it.
+ BIND_TRANSACTION: bool = false,
+ Reserved6: u10 = 0,
+
+ pub const GENERIC_READ: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .READ },
+ .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
+ .QUERY_INFORMATION = true,
+ } },
+ };
+
+ pub const GENERIC_WRITE: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .WRITE },
+ .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
+ .SET_INFORMATION = true,
+ .RECOVER = true,
+ .RENAME = true,
+ .CREATE_RM = true,
+ } },
+ };
+
+ pub const GENERIC_EXECUTE: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .EXECUTE },
+ .SPECIFIC = .{ .TRANSACTIONMANAGER = .{} },
+ };
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
+ .QUERY_INFORMATION = true,
+ .SET_INFORMATION = true,
+ .RECOVER = true,
+ .RENAME = true,
+ .CREATE_RM = true,
+ .BIND_TRANSACTION = true,
+ } },
+ };
+ };
+
+ pub const Transaction = packed struct(u16) {
+ QUERY_INFORMATION: bool = false,
+ SET_INFORMATION: bool = false,
+ ENLIST: bool = false,
+ COMMIT: bool = false,
+ ROLLBACK: bool = false,
+ PROPAGATE: bool = false,
+ RIGHT_RESERVED1: bool = false,
+ Reserved7: u9 = 0,
+
+ pub const GENERIC_READ: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .READ,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .TRANSACTION = .{
+ .QUERY_INFORMATION = true,
+ } },
+ };
+
+ pub const GENERIC_WRITE: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .WRITE,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .TRANSACTION = .{
+ .SET_INFORMATION = true,
+ .COMMIT = true,
+ .ENLIST = true,
+ .ROLLBACK = true,
+ .PROPAGATE = true,
+ } },
+ };
+
+ pub const GENERIC_EXECUTE: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .EXECUTE,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .TRANSACTION = .{
+ .COMMIT = true,
+ .ROLLBACK = true,
+ } },
+ };
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .TRANSACTION = .{
+ .QUERY_INFORMATION = true,
+ .SET_INFORMATION = true,
+ .COMMIT = true,
+ .ENLIST = true,
+ .ROLLBACK = true,
+ .PROPAGATE = true,
+ } },
+ };
+
+ pub const RESOURCE_MANAGER_RIGHTS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .{
+ .READ_CONTROL = true,
+ },
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .TRANSACTION = .{
+ .QUERY_INFORMATION = true,
+ .SET_INFORMATION = true,
+ .ENLIST = true,
+ .ROLLBACK = true,
+ .PROPAGATE = true,
+ } },
+ };
+ };
+
+ pub const ResourceManager = packed struct(u16) {
+ QUERY_INFORMATION: bool = false,
+ SET_INFORMATION: bool = false,
+ RECOVER: bool = false,
+ ENLIST: bool = false,
+ GET_NOTIFICATION: bool = false,
+ REGISTER_PROTOCOL: bool = false,
+ COMPLETE_PROPAGATION: bool = false,
+ Reserved7: u9 = 0,
+
+ pub const GENERIC_READ: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .READ,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .RESOURCEMANAGER = .{
+ .QUERY_INFORMATION = true,
+ } },
+ };
+
+ pub const GENERIC_WRITE: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .WRITE,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .RESOURCEMANAGER = .{
+ .SET_INFORMATION = true,
+ .RECOVER = true,
+ .ENLIST = true,
+ .GET_NOTIFICATION = true,
+ .REGISTER_PROTOCOL = true,
+ .COMPLETE_PROPAGATION = true,
+ } },
+ };
+
+ pub const GENERIC_EXECUTE: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .EXECUTE,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .RESOURCEMANAGER = .{
+ .RECOVER = true,
+ .ENLIST = true,
+ .GET_NOTIFICATION = true,
+ .COMPLETE_PROPAGATION = true,
+ } },
+ };
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .RESOURCEMANAGER = .{
+ .QUERY_INFORMATION = true,
+ .SET_INFORMATION = true,
+ .RECOVER = true,
+ .ENLIST = true,
+ .GET_NOTIFICATION = true,
+ .REGISTER_PROTOCOL = true,
+ .COMPLETE_PROPAGATION = true,
+ } },
+ };
+ };
+
+ pub const Enlistment = packed struct(u16) {
+ QUERY_INFORMATION: bool = false,
+ SET_INFORMATION: bool = false,
+ RECOVER: bool = false,
+ SUBORDINATE_RIGHTS: bool = false,
+ SUPERIOR_RIGHTS: bool = false,
+ Reserved5: u11 = 0,
+
+ pub const GENERIC_READ: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .READ },
+ .SPECIFIC = .{ .ENLISTMENT = .{
+ .QUERY_INFORMATION = true,
+ } },
+ };
+
+ pub const GENERIC_WRITE: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .WRITE },
+ .SPECIFIC = .{ .ENLISTMENT = .{
+ .SET_INFORMATION = true,
+ .RECOVER = true,
+ .SUBORDINATE_RIGHTS = true,
+ .SUPERIOR_RIGHTS = true,
+ } },
+ };
+
+ pub const GENERIC_EXECUTE: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .EXECUTE },
+ .SPECIFIC = .{ .ENLISTMENT = .{
+ .RECOVER = true,
+ .SUBORDINATE_RIGHTS = true,
+ .SUPERIOR_RIGHTS = true,
+ } },
+ };
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .ENLISTMENT = .{
+ .QUERY_INFORMATION = true,
+ .SET_INFORMATION = true,
+ .RECOVER = true,
+ .SUBORDINATE_RIGHTS = true,
+ .SUPERIOR_RIGHTS = true,
+ } },
+ };
+ };
+
+ pub const Event = packed struct(u16) {
+ QUERY_STATE: bool = false,
+ MODIFY_STATE: bool = false,
+ Reserved2: u14 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .EVENT = .{
+ .QUERY_STATE = true,
+ .MODIFY_STATE = true,
+ } },
+ };
+ };
+
+ pub const Semaphore = packed struct(u16) {
+ QUERY_STATE: bool = false,
+ MODIFY_STATE: bool = false,
+ Reserved2: u14 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .SEMAPHORE = .{
+ .QUERY_STATE = true,
+ .MODIFY_STATE = true,
+ } },
+ };
+ };
+
+ pub const Token = packed struct(u16) {
+ ASSIGN_PRIMARY: bool = false,
+ DUPLICATE: bool = false,
+ IMPERSONATE: bool = false,
+ QUERY: bool = false,
+ QUERY_SOURCE: bool = false,
+ ADJUST_PRIVILEGES: bool = false,
+ ADJUST_GROUPS: bool = false,
+ ADJUST_DEFAULT: bool = false,
+ ADJUST_SESSIONID: bool = false,
+ Reserved9: u7 = 0,
+
+ pub const ALL_ACCESS_P: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .TOKEN = .{
+ .ASSIGN_PRIMARY = true,
+ .DUPLICATE = true,
+ .IMPERSONATE = true,
+ .QUERY = true,
+ .QUERY_SOURCE = true,
+ .ADJUST_PRIVILEGES = true,
+ .ADJUST_GROUPS = true,
+ .ADJUST_DEFAULT = true,
+ } },
+ };
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ .SPECIFIC = .{ .TOKEN = .{
+ .ASSIGN_PRIMARY = true,
+ .DUPLICATE = true,
+ .IMPERSONATE = true,
+ .QUERY = true,
+ .QUERY_SOURCE = true,
+ .ADJUST_PRIVILEGES = true,
+ .ADJUST_GROUPS = true,
+ .ADJUST_DEFAULT = true,
+ .ADJUST_SESSIONID = true,
+ } },
+ };
+
+ pub const READ: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .READ },
+ .SPECIFIC = .{ .TOKEN = .{
+ .QUERY = true,
+ } },
+ };
+
+ pub const WRITE: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .WRITE },
+ .SPECIFIC = .{ .TOKEN = .{
+ .ADJUST_PRIVILEGES = true,
+ .ADJUST_GROUPS = true,
+ .ADJUST_DEFAULT = true,
+ } },
+ };
+
+ pub const EXECUTE: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .EXECUTE },
+ .SPECIFIC = .{ .TOKEN = .{} },
+ };
+
+ pub const TRUST_CONSTRAINT_MASK: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .READ },
+ .SPECIFIC = .{ .TOKEN = .{
+ .QUERY = true,
+ .QUERY_SOURCE = true,
+ } },
+ };
+
+ pub const TRUST_ALLOWED_MASK: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .READ },
+ .SPECIFIC = .{ .TOKEN = .{
+ .QUERY = true,
+ .QUERY_SOURCE = true,
+ .DUPLICATE = true,
+ .IMPERSONATE = true,
+ } },
+ };
+ };
+
+ pub const JobObject = packed struct(u16) {
+ ASSIGN_PROCESS: bool = false,
+ SET_ATTRIBUTES: bool = false,
+ QUERY: bool = false,
+ TERMINATE: bool = false,
+ SET_SECURITY_ATTRIBUTES: bool = false,
+ IMPERSONATE: bool = false,
+ Reserved6: u10 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .JOB_OBJECT = .{
+ .ASSIGN_PROCESS = true,
+ .SET_ATTRIBUTES = true,
+ .QUERY = true,
+ .TERMINATE = true,
+ .SET_SECURITY_ATTRIBUTES = true,
+ .IMPERSONATE = true,
+ } },
+ };
+ };
+
+ pub const Mutant = packed struct(u16) {
+ QUERY_STATE: bool = false,
+ Reserved1: u15 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .MUTANT = .{
+ .QUERY_STATE = true,
+ } },
+ };
+ };
+
+ pub const Timer = packed struct(u16) {
+ QUERY_STATE: bool = false,
+ MODIFY_STATE: bool = false,
+ Reserved2: u14 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{
+ .RIGHTS = .REQUIRED,
+ .SYNCHRONIZE = true,
+ },
+ .SPECIFIC = .{ .TIMER = .{
+ .QUERY_STATE = true,
+ .MODIFY_STATE = true,
+ } },
+ };
+ };
+
+ pub const IoCompletion = packed struct(u16) {
+ Reserved0: u1 = 0,
+ MODIFY_STATE: bool = false,
+ Reserved2: u14 = 0,
+
+ pub const ALL_ACCESS: ACCESS_MASK = .{
+ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true },
+ .SPECIFIC = .{ .IO_COMPLETION = .{
+ .Reserved0 = maxInt(@FieldType(IoCompletion, "Reserved0")),
+ .MODIFY_STATE = true,
+ } },
+ };
+ };
+
+ pub const RIGHTS_ALL: Specific = .{ .bits = maxInt(@FieldType(Specific, "bits")) };
+ };
+
+ pub const Standard = packed struct(u5) {
+ RIGHTS: Rights = .{},
+ SYNCHRONIZE: bool = false,
+
+ pub const RIGHTS_ALL: Standard = .{
+ .RIGHTS = .ALL,
+ .SYNCHRONIZE = true,
+ };
+
+ pub const Rights = packed struct(u4) {
+ DELETE: bool = false,
+ READ_CONTROL: bool = false,
+ WRITE_DAC: bool = false,
+ WRITE_OWNER: bool = false,
+
+ pub const REQUIRED: Rights = .{
+ .DELETE = true,
+ .READ_CONTROL = true,
+ .WRITE_DAC = true,
+ .WRITE_OWNER = true,
+ };
+
+ pub const READ: Rights = .{
+ .READ_CONTROL = true,
+ };
+ pub const WRITE: Rights = .{
+ .READ_CONTROL = true,
+ };
+ pub const EXECUTE: Rights = .{
+ .READ_CONTROL = true,
+ };
+
+ pub const ALL = REQUIRED;
+ };
+ };
+
+ pub const Generic = packed struct(u4) {
+ ALL: bool = false,
+ EXECUTE: bool = false,
+ WRITE: bool = false,
+ READ: bool = false,
+ };
+};
+
+pub const DEVICE_TYPE = packed struct(ULONG) {
+ FileDevice: CTL_CODE.FILE_DEVICE,
+ Reserved16: u16 = 0,
+};
+
+pub const FS_INFORMATION_CLASS = enum(c_int) {
+ Volume = 1,
+ Label = 2,
+ Size = 3,
+ Device = 4,
+ Attribute = 5,
+ Control = 6,
+ FullSize = 7,
+ ObjectId = 8,
+ DriverPath = 9,
+ VolumeFlags = 10,
+ SectorSize = 11,
+ DataCopy = 12,
+ MetadataSize = 13,
+ FullSizeEx = 14,
+ Guid = 15,
+ _,
+
+ pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len;
+};
+
+pub const SECTION_INHERIT = enum(c_int) {
+ Share = 1,
+ Unmap = 2,
+};
+
+pub const PAGE = packed struct(ULONG) {
+ NOACCESS: bool = false,
+ READONLY: bool = false,
+ READWRITE: bool = false,
+ WRITECOPY: bool = false,
+
+ EXECUTE: bool = false,
+ EXECUTE_READ: bool = false,
+ EXECUTE_READWRITE: bool = false,
+ EXECUTE_WRITECOPY: bool = false,
+
+ GUARD: bool = false,
+ NOCACHE: bool = false,
+ WRITECOMBINE: bool = false,
+
+ GRAPHICS_NOACCESS: bool = false,
+ GRAPHICS_READONLY: bool = false,
+ GRAPHICS_READWRITE: bool = false,
+ GRAPHICS_EXECUTE: bool = false,
+ GRAPHICS_EXECUTE_READ: bool = false,
+ GRAPHICS_EXECUTE_READWRITE: bool = false,
+ GRAPHICS_COHERENT: bool = false,
+ GRAPHICS_NOCACHE: bool = false,
+
+ Reserved19: u12 = 0,
+
+ REVERT_TO_FILE_MAP: bool = false,
+};
+
+pub const MEM = struct {
+ pub const ALLOCATE = packed struct(ULONG) {
+ Reserved0: u12 = 0,
+ COMMIT: bool = false,
+ RESERVE: bool = false,
+ REPLACE_PLACEHOLDER: bool = false,
+ Reserved15: u3 = 0,
+ RESERVE_PLACEHOLDER: bool = false,
+ RESET: bool = false,
+ TOP_DOWN: bool = false,
+ WRITE_WATCH: bool = false,
+ PHYSICAL: bool = false,
+ Reserved23: u1 = 0,
+ RESET_UNDO: bool = false,
+ Reserved25: u4 = 0,
+ LARGE_PAGES: bool = false,
+ Reserved30: u1 = 0,
+ @"4MB_PAGES": bool = false,
+
+ pub const @"64K_PAGES": ALLOCATE = .{
+ .LARGE_PAGES = true,
+ .PHYSICAL = true,
+ };
+ };
+
+ pub const FREE = packed struct(ULONG) {
+ COALESCE_PLACEHOLDERS: bool = false,
+ PRESERVE_PLACEHOLDER: bool = false,
+ Reserved2: u12 = 0,
+ DECOMMIT: bool = false,
+ RELEASE: bool = false,
+ FREE: bool = false,
+ Reserved17: u15 = 0,
+ };
+
+ pub const MAP = packed struct(ULONG) {
+ Reserved0: u13 = 0,
+ RESERVE: bool = false,
+ REPLACE_PLACEHOLDER: bool = false,
+ Reserved15: u14 = 0,
+ LARGE_PAGES: bool = false,
+ Reserved30: u2 = 0,
+ };
+
+ pub const UNMAP = packed struct(ULONG) {
+ WITH_TRANSIENT_BOOST: bool = false,
+ PRESERVE_PLACEHOLDER: bool = false,
+ Reserved2: u30 = 0,
+ };
+
+ pub const EXTENDED_PARAMETER = extern struct {
+ s: packed struct(ULONG64) {
+ Type: TYPE,
+ Reserved: u56,
+ },
+ u: extern union {
+ ULong64: ULONG64,
+ Pointer: PVOID,
+ Size: SIZE_T,
+ Handle: HANDLE,
+ ULong: ULONG,
+ },
+
+ pub const TYPE = enum(u8) {
+ InvalidType = 0,
+ AddressRequirements,
+ NumaNode,
+ PartitionHandle,
+ UserPhysicalHandle,
+ AttributeFlags,
+ ImageMachine,
+ _,
+
+ pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len;
+ };
+ };
+};
+
+pub const SEC = packed struct(ULONG) {
+ Reserved0: u17 = 0,
+ HUGE_PAGES: bool = false,
+ PARTITION_OWNER_HANDLE: bool = false,
+ @"64K_PAGES": bool = false,
+ Reserved19: u3 = 0,
+ FILE: bool = false,
+ IMAGE: bool = false,
+ PROTECTED_IMAGE: bool = false,
+ RESERVE: bool = false,
+ COMMIT: bool = false,
+ NOCACHE: bool = false,
+ Reserved29: u1 = 0,
+ WRITECOMBINE: bool = false,
+ LARGE_PAGES: bool = false,
+
+ pub const IMAGE_NO_EXECUTE: SEC = .{
+ .IMAGE = true,
+ .NOCACHE = true,
+ };
+};
+
+pub const ERESOURCE = opaque {};
+
+// ref: shared/ntdef.h
+
+pub const EVENT_TYPE = enum(c_int) {
+ Notification,
+ Synchronization,
+};
+
+pub const TIMER_TYPE = enum(c_int) {
+ Notification,
+ Synchronization,
+};
+
+pub const WAIT_TYPE = enum(c_int) {
+ All,
+ Any,
+};
+
+pub const LOGICAL = ULONG;
+
+pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS;
+
+// ref: um/heapapi.h
+
+pub fn GetProcessHeap() ?*HEAP {
+ return peb().ProcessHeap;
+}
+
+// ref: um/winternl.h
+
+pub const OBJECT_ATTRIBUTES = extern struct {
+ Length: ULONG,
+ RootDirectory: ?HANDLE,
+ ObjectName: *UNICODE_STRING,
+ Attributes: ATTRIBUTES,
+ SecurityDescriptor: ?*anyopaque,
+ SecurityQualityOfService: ?*anyopaque,
+
+ // Valid values for the Attributes field
+ pub const ATTRIBUTES = packed struct(ULONG) {
+ Reserved0: u1 = 0,
+ INHERIT: bool = false,
+ Reserved2: u2 = 0,
+ PERMANENT: bool = false,
+ EXCLUSIVE: bool = false,
+ /// If name-lookup code should ignore the case of the ObjectName member rather than performing an exact-match search.
+ CASE_INSENSITIVE: bool = true,
+ OPENIF: bool = false,
+ OPENLINK: bool = false,
+ KERNEL_HANDLE: bool = false,
+ FORCE_ACCESS_CHECK: bool = false,
+ IGNORE_IMPERSONATED_DEVICEMAP: bool = false,
+ DONT_REPARSE: bool = false,
+ Reserved13: u19 = 0,
+
+ pub const VALID_ATTRIBUTES: ATTRIBUTES = .{
+ .INHERIT = true,
+ .PERMANENT = true,
+ .EXCLUSIVE = true,
+ .CASE_INSENSITIVE = true,
+ .OPENIF = true,
+ .OPENLINK = true,
+ .KERNEL_HANDLE = true,
+ .FORCE_ACCESS_CHECK = true,
+ .IGNORE_IMPERSONATED_DEVICEMAP = true,
+ .DONT_REPARSE = true,
+ };
+ };
+};
+
+// ref none
pub const OpenError = error{
IsDir,
@@ -52,8 +2308,8 @@ pub const OpenFileOptions = struct {
access_mask: ACCESS_MASK,
dir: ?HANDLE = null,
sa: ?*SECURITY_ATTRIBUTES = null,
- share_access: ULONG = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
- creation: ULONG,
+ share_access: FILE.SHARE = .VALID_FLAGS,
+ creation: FILE.CREATE_DISPOSITION,
/// If true, tries to open path as a directory.
/// Defaults to false.
filter: Filter = .file_only,
@@ -82,32 +2338,22 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
var result: HANDLE = undefined;
const path_len_bytes = math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;
- var nt_name = UNICODE_STRING{
+ var nt_name: UNICODE_STRING = .{
.Length = path_len_bytes,
.MaximumLength = path_len_bytes,
.Buffer = @constCast(sub_path_w.ptr),
};
- var attr = OBJECT_ATTRIBUTES{
+ const attr: OBJECT_ATTRIBUTES = .{
.Length = @sizeOf(OBJECT_ATTRIBUTES),
.RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir,
- .Attributes = if (options.sa) |ptr| blk: { // Note we do not use OBJ_CASE_INSENSITIVE here.
- const inherit: ULONG = if (ptr.bInheritHandle == TRUE) OBJ_INHERIT else 0;
- break :blk inherit;
- } else 0,
+ .Attributes = .{
+ .INHERIT = if (options.sa) |sa| sa.bInheritHandle != FALSE else false,
+ },
.ObjectName = &nt_name,
.SecurityDescriptor = if (options.sa) |ptr| ptr.lpSecurityDescriptor else null,
.SecurityQualityOfService = null,
};
var io: IO_STATUS_BLOCK = undefined;
- const blocking_flag: ULONG = FILE_SYNCHRONOUS_IO_NONALERT;
- const file_or_dir_flag: ULONG = switch (options.filter) {
- .file_only => FILE_NON_DIRECTORY_FILE,
- .dir_only => FILE_DIRECTORY_FILE,
- .any => 0,
- };
- // If we're not following symlinks, we need to ensure we don't pass in any synchronization flags such as FILE_SYNCHRONOUS_IO_NONALERT.
- const flags: ULONG = if (options.follow_symlinks) file_or_dir_flag | blocking_flag else file_or_dir_flag | FILE_OPEN_REPARSE_POINT;
-
while (true) {
const rc = ntdll.NtCreateFile(
&result,
@@ -115,10 +2361,15 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
&attr,
&io,
null,
- FILE_ATTRIBUTE_NORMAL,
+ .{ .NORMAL = true },
options.share_access,
options.creation,
- flags,
+ .{
+ .DIRECTORY_FILE = options.filter == .dir_only,
+ .NON_DIRECTORY_FILE = options.filter == .file_only,
+ .IO = if (options.follow_symlinks) .SYNCHRONOUS_NONALERT else .ASYNCHRONOUS,
+ .OPEN_REPARSE_POINT = !options.follow_symlinks,
+ },
null,
0,
);
@@ -201,16 +2452,16 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
const dev_handle = opt_dev_handle orelse blk: {
const str = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\NamedPipe\\");
const len: u16 = @truncate(str.len * @sizeOf(u16));
- const name = UNICODE_STRING{
+ const name: UNICODE_STRING = .{
.Length = len,
.MaximumLength = len,
.Buffer = @ptrCast(@constCast(str)),
};
- const attrs = OBJECT_ATTRIBUTES{
+ const attrs: OBJECT_ATTRIBUTES = .{
.ObjectName = @constCast(&name),
.Length = @sizeOf(OBJECT_ATTRIBUTES),
.RootDirectory = null,
- .Attributes = 0,
+ .Attributes = .{},
.SecurityDescriptor = null,
.SecurityQualityOfService = null,
};
@@ -219,14 +2470,17 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
var handle: HANDLE = undefined;
switch (ntdll.NtCreateFile(
&handle,
- GENERIC_READ | SYNCHRONIZE,
+ .{
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{ .READ = true },
+ },
@constCast(&attrs),
&iosb,
null,
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT,
+ .{},
+ .VALID_FLAGS,
+ .OPEN,
+ .{ .IO = .SYNCHRONOUS_NONALERT },
null,
0,
)) {
@@ -242,16 +2496,15 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
} else break :blk handle;
};
- const name = UNICODE_STRING{ .Buffer = null, .Length = 0, .MaximumLength = 0 };
- var attrs = OBJECT_ATTRIBUTES{
+ const name: UNICODE_STRING = .{ .Buffer = null, .Length = 0, .MaximumLength = 0 };
+ var attrs: OBJECT_ATTRIBUTES = .{
.ObjectName = @constCast(&name),
.Length = @sizeOf(OBJECT_ATTRIBUTES),
.RootDirectory = dev_handle,
- .Attributes = OBJ_CASE_INSENSITIVE,
+ .Attributes = .{ .INHERIT = sattr.bInheritHandle != FALSE },
.SecurityDescriptor = sattr.lpSecurityDescriptor,
.SecurityQualityOfService = null,
};
- if (sattr.bInheritHandle != 0) attrs.Attributes |= OBJ_INHERIT;
// 120 second relative timeout in 100ns units.
const default_timeout: LARGE_INTEGER = (-120 * std.time.ns_per_s) / 100;
@@ -259,15 +2512,21 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
var read: HANDLE = undefined;
switch (ntdll.NtCreateNamedPipeFile(
&read,
- GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
+ .{
+ .SPECIFIC = .{ .FILE_PIPE = .{
+ .WRITE_ATTRIBUTES = true,
+ } },
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{ .READ = true },
+ },
&attrs,
&iosb,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_CREATE,
- FILE_SYNCHRONOUS_IO_NONALERT,
- FILE_PIPE_BYTE_STREAM_TYPE,
- FILE_PIPE_BYTE_STREAM_MODE,
- FILE_PIPE_QUEUE_OPERATION,
+ .{ .READ = true, .WRITE = true },
+ .CREATE,
+ .{ .IO = .SYNCHRONOUS_NONALERT },
+ .{ .TYPE = .BYTE_STREAM },
+ .{ .MODE = .BYTE_STREAM },
+ .{ .OPERATION = .QUEUE },
1,
4096,
4096,
@@ -285,14 +2544,23 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
var write: HANDLE = undefined;
switch (ntdll.NtCreateFile(
&write,
- GENERIC_WRITE | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+ .{
+ .SPECIFIC = .{ .FILE_PIPE = .{
+ .READ_ATTRIBUTES = true,
+ } },
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{ .WRITE = true },
+ },
&attrs,
&iosb,
null,
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
+ .{},
+ .VALID_FLAGS,
+ .OPEN,
+ .{
+ .IO = .SYNCHRONOUS_NONALERT,
+ .NON_DIRECTORY_FILE = true,
+ },
null,
0,
)) {
@@ -311,6 +2579,15 @@ pub const DeviceIoControlError = error{
/// The volume does not contain a recognized file system. File system
/// drivers might not be loaded, or the volume may be corrupt.
UnrecognizedVolume,
+ Pending,
+ /// Attempted to connect a named pipe in the "closing" state, meaning a previous client has
+ /// has closed their handle but we have not yet disconnected the pipe.
+ PipeClosing,
+ /// Attempted to connect a named pipe in the "connected" state, meaning a client has already
+ /// opened the pipe; there is a good connection between client and server.
+ PipeAlreadyConnected,
+ /// Attempted to connect a non-blocking named pipe which is already listening for connections.
+ PipeAlreadyListening,
Unexpected,
};
@@ -319,56 +2596,55 @@ pub const DeviceIoControlError = error{
/// as a direct substitute for that call.
/// TODO work out if we need to expose other arguments to the underlying syscalls.
pub fn DeviceIoControl(
- h: HANDLE,
- ioControlCode: ULONG,
- in: ?[]const u8,
- out: ?[]u8,
+ device: HANDLE,
+ io_control_code: CTL_CODE,
+ opts: struct {
+ event: ?HANDLE = null,
+ apc_routine: ?*const IO_APC_ROUTINE = null,
+ apc_context: ?*anyopaque = null,
+ io_status_block: ?*IO_STATUS_BLOCK = null,
+ in: []const u8 = &.{},
+ out: []u8 = &.{},
+ },
) DeviceIoControlError!void {
- // Logic from: https://doxygen.reactos.org/d3/d74/deviceio_8c.html
- const is_fsctl = (ioControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM;
-
- var io: IO_STATUS_BLOCK = undefined;
- const in_ptr = if (in) |i| i.ptr else null;
- const in_len = if (in) |i| @as(ULONG, @intCast(i.len)) else 0;
- const out_ptr = if (out) |o| o.ptr else null;
- const out_len = if (out) |o| @as(ULONG, @intCast(o.len)) else 0;
-
- const rc = blk: {
- if (is_fsctl) {
- break :blk ntdll.NtFsControlFile(
- h,
- null,
- null,
- null,
- &io,
- ioControlCode,
- in_ptr,
- in_len,
- out_ptr,
- out_len,
- );
- } else {
- break :blk ntdll.NtDeviceIoControlFile(
- h,
- null,
- null,
- null,
- &io,
- ioControlCode,
- in_ptr,
- in_len,
- out_ptr,
- out_len,
- );
- }
+ var io_status_block: IO_STATUS_BLOCK = undefined;
+ const rc = switch (io_control_code.DeviceType) {
+ .FILE_SYSTEM, .NAMED_PIPE => ntdll.NtFsControlFile(
+ device,
+ opts.event,
+ opts.apc_routine,
+ opts.apc_context,
+ opts.io_status_block orelse &io_status_block,
+ io_control_code,
+ if (opts.in.len > 0) opts.in.ptr else null,
+ @intCast(opts.in.len),
+ if (opts.out.len > 0) opts.out.ptr else null,
+ @intCast(opts.out.len),
+ ),
+ else => ntdll.NtDeviceIoControlFile(
+ device,
+ opts.event,
+ opts.apc_routine,
+ opts.apc_context,
+ opts.io_status_block orelse &io_status_block,
+ io_control_code,
+ if (opts.in.len > 0) opts.in.ptr else null,
+ @intCast(opts.in.len),
+ if (opts.out.len > 0) opts.out.ptr else null,
+ @intCast(opts.out.len),
+ ),
};
switch (rc) {
.SUCCESS => {},
+ .PIPE_CLOSING => return error.PipeClosing,
+ .PIPE_CONNECTED => return error.PipeAlreadyConnected,
+ .PIPE_LISTENING => return error.PipeAlreadyListening,
.PRIVILEGE_NOT_HELD => return error.AccessDenied,
.ACCESS_DENIED => return error.AccessDenied,
.INVALID_DEVICE_REQUEST => return error.AccessDenied, // Not supported by the underlying filesystem
.INVALID_PARAMETER => unreachable,
.UNRECOGNIZED_VOLUME => return error.UnrecognizedVolume,
+ .PENDING => return error.Pending,
else => return unexpectedStatus(rc),
}
}
@@ -704,7 +2980,7 @@ pub const SetCurrentDirectoryError = error{
pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void {
const path_len_bytes = math.cast(u16, path_name.len * 2) orelse return error.NameTooLong;
- var nt_name = UNICODE_STRING{
+ var nt_name: UNICODE_STRING = .{
.Length = path_len_bytes,
.MaximumLength = path_len_bytes,
.Buffer = @constCast(path_name.ptr),
@@ -780,7 +3056,7 @@ pub fn CreateSymbolicLink(
is_directory: bool,
) CreateSymbolicLinkError!void {
const SYMLINK_DATA = extern struct {
- ReparseTag: ULONG,
+ ReparseTag: IO_REPARSE_TAG,
ReparseDataLength: USHORT,
Reserved: USHORT,
SubstituteNameOffset: USHORT,
@@ -791,9 +3067,12 @@ pub fn CreateSymbolicLink(
};
const symlink_handle = OpenFile(sym_link_path, .{
- .access_mask = SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,
+ .access_mask = .{
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{ .WRITE = true, .READ = true },
+ },
.dir = dir,
- .creation = FILE_CREATE,
+ .creation = .CREATE,
.filter = if (is_directory) .dir_only else .file_only,
}) catch |err| switch (err) {
error.IsDir => return error.PathAlreadyExists,
@@ -845,8 +3124,8 @@ pub fn CreateSymbolicLink(
const buf_len = @sizeOf(SYMLINK_DATA) + final_target_path.len * 4;
const header_len = @sizeOf(ULONG) + @sizeOf(USHORT) * 2;
const target_is_absolute = std.fs.path.isAbsoluteWindowsWtf16(final_target_path);
- const symlink_data = SYMLINK_DATA{
- .ReparseTag = IO_REPARSE_TAG_SYMLINK,
+ const symlink_data: SYMLINK_DATA = .{
+ .ReparseTag = .SYMLINK,
.ReparseDataLength = @intCast(buf_len - header_len),
.Reserved = 0,
.SubstituteNameOffset = @intCast(final_target_path.len * 2),
@@ -860,7 +3139,13 @@ pub fn CreateSymbolicLink(
@memcpy(buffer[@sizeOf(SYMLINK_DATA)..][0 .. final_target_path.len * 2], @as([*]const u8, @ptrCast(final_target_path)));
const paths_start = @sizeOf(SYMLINK_DATA) + final_target_path.len * 2;
@memcpy(buffer[paths_start..][0 .. final_target_path.len * 2], @as([*]const u8, @ptrCast(final_target_path)));
- _ = try DeviceIoControl(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null);
+ _ = DeviceIoControl(symlink_handle, FSCTL.SET_REPARSE_POINT, .{ .in = buffer[0..buf_len] }) catch |err| switch (err) {
+ error.PipeClosing => unreachable,
+ error.PipeAlreadyConnected => unreachable,
+ error.PipeAlreadyListening => unreachable,
+ error.Pending => unreachable,
+ else => |e| return e,
+ };
}
pub const ReadLinkError = error{
@@ -878,9 +3163,14 @@ pub const ReadLinkError = error{
/// is safe to reuse a single buffer for both.
pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLinkError![]u16 {
const result_handle = OpenFile(sub_path_w, .{
- .access_mask = FILE_READ_ATTRIBUTES | SYNCHRONIZE,
+ .access_mask = .{
+ .SPECIFIC = .{ .FILE = .{
+ .READ_ATTRIBUTES = true,
+ } },
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ },
.dir = dir,
- .creation = FILE_OPEN,
+ .creation = .OPEN,
.follow_symlinks = false,
.filter = .any,
}) catch |err| switch (err) {
@@ -894,15 +3184,20 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLi
defer CloseHandle(result_handle);
var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 align(@alignOf(REPARSE_DATA_BUFFER)) = undefined;
- _ = DeviceIoControl(result_handle, FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..]) catch |err| switch (err) {
+ _ = DeviceIoControl(result_handle, FSCTL.GET_REPARSE_POINT, .{ .out = reparse_buf[0..] }) catch |err| switch (err) {
+ error.PipeClosing => unreachable,
+ error.PipeAlreadyConnected => unreachable,
+ error.PipeAlreadyListening => unreachable,
error.AccessDenied => return error.Unexpected,
error.UnrecognizedVolume => return error.Unexpected,
+ error.Pending => unreachable,
else => |e| return e,
};
const reparse_struct: *const REPARSE_DATA_BUFFER = @ptrCast(@alignCast(&reparse_buf[0]));
- switch (reparse_struct.ReparseTag) {
- IO_REPARSE_TAG_SYMLINK => {
+ const IoReparseTagInt = @typeInfo(IO_REPARSE_TAG).@"struct".backing_integer.?;
+ switch (@as(IoReparseTagInt, @bitCast(reparse_struct.ReparseTag))) {
+ @as(IoReparseTagInt, @bitCast(IO_REPARSE_TAG.SYMLINK)) => {
const buf: *const SYMBOLIC_LINK_REPARSE_BUFFER = @ptrCast(@alignCast(&reparse_struct.DataBuffer[0]));
const offset = buf.SubstituteNameOffset >> 1;
const len = buf.SubstituteNameLength >> 1;
@@ -910,16 +3205,14 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLi
const is_relative = buf.Flags & SYMLINK_FLAG_RELATIVE != 0;
return parseReadLinkPath(path_buf[offset..][0..len], is_relative, out_buffer);
},
- IO_REPARSE_TAG_MOUNT_POINT => {
+ @as(IoReparseTagInt, @bitCast(IO_REPARSE_TAG.MOUNT_POINT)) => {
const buf: *const MOUNT_POINT_REPARSE_BUFFER = @ptrCast(@alignCast(&reparse_struct.DataBuffer[0]));
const offset = buf.SubstituteNameOffset >> 1;
const len = buf.SubstituteNameLength >> 1;
const path_buf = @as([*]const u16, &buf.PathBuffer);
return parseReadLinkPath(path_buf[offset..][0..len], false, out_buffer);
},
- else => {
- return error.UnsupportedReparsePointType;
- },
+ else => return error.UnsupportedReparsePointType,
}
}
@@ -956,13 +3249,8 @@ pub const DeleteFileOptions = struct {
};
pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFileError!void {
- const create_options_flags: ULONG = if (options.remove_dir)
- FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT
- else
- FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT; // would we ever want to delete the target instead?
-
const path_len_bytes = @as(u16, @intCast(sub_path_w.len * 2));
- var nt_name = UNICODE_STRING{
+ var nt_name: UNICODE_STRING = .{
.Length = path_len_bytes,
.MaximumLength = path_len_bytes,
// The Windows API makes this mutable, but it will not mutate here.
@@ -978,26 +3266,32 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
return error.FileBusy;
}
- var attr = OBJECT_ATTRIBUTES{
- .Length = @sizeOf(OBJECT_ATTRIBUTES),
- .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir,
- .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
- .ObjectName = &nt_name,
- .SecurityDescriptor = null,
- .SecurityQualityOfService = null,
- };
var io: IO_STATUS_BLOCK = undefined;
var tmp_handle: HANDLE = undefined;
var rc = ntdll.NtCreateFile(
&tmp_handle,
- SYNCHRONIZE | DELETE,
- &attr,
+ .{ .STANDARD = .{
+ .RIGHTS = .{ .DELETE = true },
+ .SYNCHRONIZE = true,
+ } },
+ &.{
+ .Length = @sizeOf(OBJECT_ATTRIBUTES),
+ .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir,
+ .Attributes = .{},
+ .ObjectName = &nt_name,
+ .SecurityDescriptor = null,
+ .SecurityQualityOfService = null,
+ },
&io,
null,
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- FILE_OPEN,
- create_options_flags,
+ .{},
+ .VALID_FLAGS,
+ .OPEN,
+ .{
+ .DIRECTORY_FILE = options.remove_dir,
+ .NON_DIRECTORY_FILE = !options.remove_dir,
+ .OPEN_REPARSE_POINT = true, // would we ever want to delete the target instead?
+ },
null,
0,
);
@@ -1031,18 +3325,17 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
// FileDispositionInformation if the return value lets us know that some aspect of it is not supported.
const need_fallback = need_fallback: {
// Deletion with posix semantics if the filesystem supports it.
- var info = FILE_DISPOSITION_INFORMATION_EX{
- .Flags = FILE_DISPOSITION_DELETE |
- FILE_DISPOSITION_POSIX_SEMANTICS |
- FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE,
- };
-
+ const info: FILE.DISPOSITION.INFORMATION.EX = .{ .Flags = .{
+ .DELETE = true,
+ .POSIX_SEMANTICS = true,
+ .IGNORE_READONLY_ATTRIBUTE = true,
+ } };
rc = ntdll.NtSetInformationFile(
tmp_handle,
&io,
&info,
- @sizeOf(FILE_DISPOSITION_INFORMATION_EX),
- .FileDispositionInformationEx,
+ @sizeOf(FILE.DISPOSITION.INFORMATION.EX),
+ .DispositionEx,
);
switch (rc) {
.SUCCESS => return,
@@ -1061,16 +3354,15 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
if (need_fallback) {
// Deletion with file pending semantics, which requires waiting or moving
// files to get them removed (from here).
- var file_dispo = FILE_DISPOSITION_INFORMATION{
+ const file_dispo: FILE.DISPOSITION.INFORMATION = .{
.DeleteFile = TRUE,
};
-
rc = ntdll.NtSetInformationFile(
tmp_handle,
&io,
&file_dispo,
- @sizeOf(FILE_DISPOSITION_INFORMATION),
- .FileDispositionInformation,
+ @sizeOf(FILE.DISPOSITION.INFORMATION),
+ .Disposition,
);
}
switch (rc) {
@@ -1112,8 +3404,14 @@ pub fn RenameFile(
) RenameError!void {
const src_fd = OpenFile(old_path_w, .{
.dir = old_dir_fd,
- .access_mask = SYNCHRONIZE | GENERIC_WRITE | DELETE,
- .creation = FILE_OPEN,
+ .access_mask = .{
+ .STANDARD = .{
+ .RIGHTS = .{ .DELETE = true },
+ .SYNCHRONIZE = true,
+ },
+ .GENERIC = .{ .WRITE = true },
+ },
+ .creation = .OPEN,
.filter = .any, // This function is supposed to rename both files and directories.
.follow_symlinks = false,
}) catch |err| switch (err) {
@@ -1135,29 +3433,23 @@ pub fn RenameFile(
// The strategy here is just to try using FileRenameInformationEx and fall back to
// FileRenameInformation if the return value lets us know that some aspect of it is not supported.
const need_fallback = need_fallback: {
- const struct_buf_len = @sizeOf(FILE_RENAME_INFORMATION_EX) + (PATH_MAX_WIDE * 2);
- var rename_info_buf: [struct_buf_len]u8 align(@alignOf(FILE_RENAME_INFORMATION_EX)) = undefined;
- const struct_len = @sizeOf(FILE_RENAME_INFORMATION_EX) + new_path_w.len * 2;
- if (struct_len > struct_buf_len) return error.NameTooLong;
-
- const rename_info: *FILE_RENAME_INFORMATION_EX = @ptrCast(&rename_info_buf);
- var io_status_block: IO_STATUS_BLOCK = undefined;
-
- var flags: ULONG = FILE_RENAME_POSIX_SEMANTICS | FILE_RENAME_IGNORE_READONLY_ATTRIBUTE;
- if (replace_if_exists) flags |= FILE_RENAME_REPLACE_IF_EXISTS;
- rename_info.* = .{
- .Flags = flags,
+ const rename_info: FILE.RENAME_INFORMATION = .init(.{
+ .Flags = .{
+ .REPLACE_IF_EXISTS = replace_if_exists,
+ .POSIX_SEMANTICS = true,
+ .IGNORE_READONLY_ATTRIBUTE = true,
+ },
.RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(new_path_w)) null else new_dir_fd,
- .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong
- .FileName = undefined,
- };
- @memcpy((&rename_info.FileName).ptr, new_path_w);
+ .FileName = new_path_w,
+ });
+ var io_status_block: IO_STATUS_BLOCK = undefined;
+ const rename_info_buf = rename_info.toBuffer();
rc = ntdll.NtSetInformationFile(
src_fd,
&io_status_block,
- rename_info,
- @intCast(struct_len), // already checked for error.NameTooLong
- .FileRenameInformationEx,
+ rename_info_buf.ptr,
+ @intCast(rename_info_buf.len), // already checked for error.NameTooLong
+ .RenameEx,
);
switch (rc) {
.SUCCESS => return,
@@ -1174,28 +3466,19 @@ pub fn RenameFile(
};
if (need_fallback) {
- const struct_buf_len = @sizeOf(FILE_RENAME_INFORMATION) + (PATH_MAX_WIDE * 2);
- var rename_info_buf: [struct_buf_len]u8 align(@alignOf(FILE_RENAME_INFORMATION)) = undefined;
- const struct_len = @sizeOf(FILE_RENAME_INFORMATION) + new_path_w.len * 2;
- if (struct_len > struct_buf_len) return error.NameTooLong;
-
- const rename_info: *FILE_RENAME_INFORMATION = @ptrCast(&rename_info_buf);
- var io_status_block: IO_STATUS_BLOCK = undefined;
-
- rename_info.* = .{
- .Flags = @intFromBool(replace_if_exists),
+ const rename_info: FILE.RENAME_INFORMATION = .init(.{
+ .Flags = .{ .REPLACE_IF_EXISTS = replace_if_exists },
.RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(new_path_w)) null else new_dir_fd,
- .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong
- .FileName = undefined,
- };
- @memcpy((&rename_info.FileName).ptr, new_path_w);
-
+ .FileName = new_path_w,
+ });
+ var io_status_block: IO_STATUS_BLOCK = undefined;
+ const rename_info_buf = rename_info.toBuffer();
rc = ntdll.NtSetInformationFile(
src_fd,
&io_status_block,
- rename_info,
- @intCast(struct_len), // already checked for error.NameTooLong
- .FileRenameInformation,
+ rename_info_buf.ptr,
+ @intCast(rename_info_buf.len), // already checked for error.NameTooLong
+ .Rename,
);
}
@@ -1308,7 +3591,7 @@ pub fn QueryObjectName(handle: HANDLE, out_buffer: []u16) QueryObjectNameError![
const info = @as(*OBJECT_NAME_INFORMATION, @ptrCast(out_buffer_aligned));
// buffer size is specified in bytes
- const out_buffer_len = std.math.cast(ULONG, out_buffer_aligned.len * 2) orelse std.math.maxInt(ULONG);
+ const out_buffer_len = std.math.cast(ULONG, out_buffer_aligned.len * 2) orelse maxInt(ULONG);
// last argument would return the length required for full_buffer, not exposed here
return switch (ntdll.NtQueryObject(handle, .ObjectNameInformation, info, out_buffer_len, null)) {
.SUCCESS => blk: {
@@ -1440,9 +3723,8 @@ pub fn GetFinalPathNameByHandle(
// This is the NT namespaced version of \\.\MountPointManager
const mgmt_path_u16 = std.unicode.utf8ToUtf16LeStringLiteral("\\??\\MountPointManager");
const mgmt_handle = OpenFile(mgmt_path_u16, .{
- .access_mask = SYNCHRONIZE,
- .share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- .creation = FILE_OPEN,
+ .access_mask = .{ .STANDARD = .{ .SYNCHRONIZE = true } },
+ .creation = .OPEN,
}) catch |err| switch (err) {
error.IsDir => return error.Unexpected,
error.NotDir => return error.Unexpected,
@@ -1462,8 +3744,12 @@ pub fn GetFinalPathNameByHandle(
input_struct.DeviceNameLength = @intCast(volume_name_u16.len * 2);
@memcpy(input_buf[@sizeOf(MOUNTMGR_MOUNT_POINT)..][0 .. volume_name_u16.len * 2], @as([*]const u8, @ptrCast(volume_name_u16.ptr)));
- DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_POINTS, &input_buf, &output_buf) catch |err| switch (err) {
+ DeviceIoControl(mgmt_handle, IOCTL.MOUNTMGR.QUERY_POINTS, .{ .in = &input_buf, .out = &output_buf }) catch |err| switch (err) {
+ error.PipeClosing => unreachable,
+ error.PipeAlreadyConnected => unreachable,
+ error.PipeAlreadyListening => unreachable,
error.AccessDenied => return error.Unexpected,
+ error.Pending => unreachable,
else => |e| return e,
};
const mount_points_struct: *const MOUNTMGR_MOUNT_POINTS = @ptrCast(&output_buf[0]);
@@ -1517,8 +3803,12 @@ pub fn GetFinalPathNameByHandle(
vol_input_struct.DeviceNameLength = @intCast(symlink.len * 2);
@memcpy(@as([*]WCHAR, &vol_input_struct.DeviceName)[0..symlink.len], symlink);
- DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, &vol_input_buf, &vol_output_buf) catch |err| switch (err) {
+ DeviceIoControl(mgmt_handle, IOCTL.MOUNTMGR.QUERY_DOS_VOLUME_PATH, .{ .in = &vol_input_buf, .out = &vol_output_buf }) catch |err| switch (err) {
+ error.PipeClosing => unreachable,
+ error.PipeAlreadyConnected => unreachable,
+ error.PipeAlreadyListening => unreachable,
error.AccessDenied => return error.Unexpected,
+ error.Pending => unreachable,
else => |e| return e,
};
const volume_paths_struct: *const MOUNTMGR_VOLUME_PATHS = @ptrCast(&vol_output_buf[0]);
@@ -1758,7 +4048,7 @@ pub fn VirtualProtect(lpAddress: ?LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, l
// ntdll takes an extra level of indirection here
var addr = lpAddress;
var size = dwSize;
- switch (ntdll.NtProtectVirtualMemory(self_process_handle, &addr, &size, flNewProtect, lpflOldProtect)) {
+ switch (ntdll.NtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, flNewProtect, lpflOldProtect)) {
.SUCCESS => {},
.INVALID_ADDRESS => return error.InvalidAddress,
else => |st| return unexpectedStatus(st),
@@ -2018,7 +4308,7 @@ pub const LockFileError = error{
pub fn LockFile(
FileHandle: HANDLE,
Event: ?HANDLE,
- ApcRoutine: ?*IO_APC_ROUTINE,
+ ApcRoutine: ?*const IO_APC_ROUTINE,
ApcContext: ?*anyopaque,
IoStatusBlock: *IO_STATUS_BLOCK,
ByteOffset: *const LARGE_INTEGER,
@@ -2057,7 +4347,7 @@ pub fn UnlockFile(
IoStatusBlock: *IO_STATUS_BLOCK,
ByteOffset: *const LARGE_INTEGER,
Length: *const LARGE_INTEGER,
- Key: ?*ULONG,
+ Key: ULONG,
) !void {
const rc = ntdll.NtUnlockFile(FileHandle, IoStatusBlock, ByteOffset, Length, Key);
switch (rc) {
@@ -2168,13 +4458,13 @@ pub fn eqlIgnoreCaseWtf16(a: []const u16, b: []const u16) bool {
// Use RtlEqualUnicodeString on Windows when not in comptime to avoid including a
// redundant copy of the uppercase data.
const a_bytes = @as(u16, @intCast(a.len * 2));
- const a_string = UNICODE_STRING{
+ const a_string: UNICODE_STRING = .{
.Length = a_bytes,
.MaximumLength = a_bytes,
.Buffer = @constCast(a.ptr),
};
const b_bytes = @as(u16, @intCast(b.len * 2));
- const b_string = UNICODE_STRING{
+ const b_string: UNICODE_STRING = .{
.Length = b_bytes,
.MaximumLength = b_bytes,
.Buffer = @constCast(b.ptr),
@@ -2206,7 +4496,7 @@ pub fn eqlIgnoreCaseWtf8(a: []const u8, b: []const u8) bool {
const a_cp = a_wtf8_it.nextCodepoint() orelse break;
const b_cp = b_wtf8_it.nextCodepoint() orelse return false;
- if (a_cp <= std.math.maxInt(u16) and b_cp <= std.math.maxInt(u16)) {
+ if (a_cp <= maxInt(u16) and b_cp <= maxInt(u16)) {
if (a_cp != b_cp and upcaseImpl(@intCast(a_cp)) != upcaseImpl(@intCast(b_cp))) {
return false;
}
@@ -2783,7 +5073,10 @@ pub fn unexpectedWSAError(err: ws2_32.WinsockError) UnexpectedError {
/// and you get an unexpected status.
pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {
if (std.posix.unexpected_error_tracing) {
- std.debug.print("error.Unexpected NTSTATUS=0x{x}\n", .{@intFromEnum(status)});
+ std.debug.print("error.Unexpected NTSTATUS=0x{x} ({s})\n", .{
+ @intFromEnum(status),
+ std.enums.tagName(NTSTATUS, status) orelse "<unnamed>",
+ });
std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() });
}
return error.Unexpected;
@@ -2791,20 +5084,25 @@ pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {
pub fn statusBug(status: NTSTATUS) UnexpectedError {
switch (builtin.mode) {
- .Debug => std.debug.panic("programmer bug caused syscall status: {t}", .{status}),
+ .Debug => std.debug.panic("programmer bug caused syscall status: 0x{x} ({s})", .{
+ @intFromEnum(status),
+ std.enums.tagName(NTSTATUS, status) orelse "<unnamed>",
+ }),
else => return error.Unexpected,
}
}
pub fn errorBug(err: Win32Error) UnexpectedError {
switch (builtin.mode) {
- .Debug => std.debug.panic("programmer bug caused syscall status: {t}", .{err}),
+ .Debug => std.debug.panic("programmer bug caused syscall error: 0x{x} ({s})", .{
+ @intFromEnum(err),
+ std.enums.tagName(Win32Error, err) orelse "<unnamed>",
+ }),
else => return error.Unexpected,
}
}
pub const Win32Error = @import("windows/win32error.zig").Win32Error;
-pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS;
pub const LANG = @import("windows/lang.zig");
pub const SUBLANG = @import("windows/sublang.zig");
@@ -2885,217 +5183,9 @@ pub const PCTSTR = @compileError("Deprecated: choose between `PCSTR` or `PCWSTR`
pub const TRUE = 1;
pub const FALSE = 0;
-pub const DEVICE_TYPE = ULONG;
-pub const FILE_DEVICE_BEEP: DEVICE_TYPE = 0x0001;
-pub const FILE_DEVICE_CD_ROM: DEVICE_TYPE = 0x0002;
-pub const FILE_DEVICE_CD_ROM_FILE_SYSTEM: DEVICE_TYPE = 0x0003;
-pub const FILE_DEVICE_CONTROLLER: DEVICE_TYPE = 0x0004;
-pub const FILE_DEVICE_DATALINK: DEVICE_TYPE = 0x0005;
-pub const FILE_DEVICE_DFS: DEVICE_TYPE = 0x0006;
-pub const FILE_DEVICE_DISK: DEVICE_TYPE = 0x0007;
-pub const FILE_DEVICE_DISK_FILE_SYSTEM: DEVICE_TYPE = 0x0008;
-pub const FILE_DEVICE_FILE_SYSTEM: DEVICE_TYPE = 0x0009;
-pub const FILE_DEVICE_INPORT_PORT: DEVICE_TYPE = 0x000a;
-pub const FILE_DEVICE_KEYBOARD: DEVICE_TYPE = 0x000b;
-pub const FILE_DEVICE_MAILSLOT: DEVICE_TYPE = 0x000c;
-pub const FILE_DEVICE_MIDI_IN: DEVICE_TYPE = 0x000d;
-pub const FILE_DEVICE_MIDI_OUT: DEVICE_TYPE = 0x000e;
-pub const FILE_DEVICE_MOUSE: DEVICE_TYPE = 0x000f;
-pub const FILE_DEVICE_MULTI_UNC_PROVIDER: DEVICE_TYPE = 0x0010;
-pub const FILE_DEVICE_NAMED_PIPE: DEVICE_TYPE = 0x0011;
-pub const FILE_DEVICE_NETWORK: DEVICE_TYPE = 0x0012;
-pub const FILE_DEVICE_NETWORK_BROWSER: DEVICE_TYPE = 0x0013;
-pub const FILE_DEVICE_NETWORK_FILE_SYSTEM: DEVICE_TYPE = 0x0014;
-pub const FILE_DEVICE_NULL: DEVICE_TYPE = 0x0015;
-pub const FILE_DEVICE_PARALLEL_PORT: DEVICE_TYPE = 0x0016;
-pub const FILE_DEVICE_PHYSICAL_NETCARD: DEVICE_TYPE = 0x0017;
-pub const FILE_DEVICE_PRINTER: DEVICE_TYPE = 0x0018;
-pub const FILE_DEVICE_SCANNER: DEVICE_TYPE = 0x0019;
-pub const FILE_DEVICE_SERIAL_MOUSE_PORT: DEVICE_TYPE = 0x001a;
-pub const FILE_DEVICE_SERIAL_PORT: DEVICE_TYPE = 0x001b;
-pub const FILE_DEVICE_SCREEN: DEVICE_TYPE = 0x001c;
-pub const FILE_DEVICE_SOUND: DEVICE_TYPE = 0x001d;
-pub const FILE_DEVICE_STREAMS: DEVICE_TYPE = 0x001e;
-pub const FILE_DEVICE_TAPE: DEVICE_TYPE = 0x001f;
-pub const FILE_DEVICE_TAPE_FILE_SYSTEM: DEVICE_TYPE = 0x0020;
-pub const FILE_DEVICE_TRANSPORT: DEVICE_TYPE = 0x0021;
-pub const FILE_DEVICE_UNKNOWN: DEVICE_TYPE = 0x0022;
-pub const FILE_DEVICE_VIDEO: DEVICE_TYPE = 0x0023;
-pub const FILE_DEVICE_VIRTUAL_DISK: DEVICE_TYPE = 0x0024;
-pub const FILE_DEVICE_WAVE_IN: DEVICE_TYPE = 0x0025;
-pub const FILE_DEVICE_WAVE_OUT: DEVICE_TYPE = 0x0026;
-pub const FILE_DEVICE_8042_PORT: DEVICE_TYPE = 0x0027;
-pub const FILE_DEVICE_NETWORK_REDIRECTOR: DEVICE_TYPE = 0x0028;
-pub const FILE_DEVICE_BATTERY: DEVICE_TYPE = 0x0029;
-pub const FILE_DEVICE_BUS_EXTENDER: DEVICE_TYPE = 0x002a;
-pub const FILE_DEVICE_MODEM: DEVICE_TYPE = 0x002b;
-pub const FILE_DEVICE_VDM: DEVICE_TYPE = 0x002c;
-pub const FILE_DEVICE_MASS_STORAGE: DEVICE_TYPE = 0x002d;
-pub const FILE_DEVICE_SMB: DEVICE_TYPE = 0x002e;
-pub const FILE_DEVICE_KS: DEVICE_TYPE = 0x002f;
-pub const FILE_DEVICE_CHANGER: DEVICE_TYPE = 0x0030;
-pub const FILE_DEVICE_SMARTCARD: DEVICE_TYPE = 0x0031;
-pub const FILE_DEVICE_ACPI: DEVICE_TYPE = 0x0032;
-pub const FILE_DEVICE_DVD: DEVICE_TYPE = 0x0033;
-pub const FILE_DEVICE_FULLSCREEN_VIDEO: DEVICE_TYPE = 0x0034;
-pub const FILE_DEVICE_DFS_FILE_SYSTEM: DEVICE_TYPE = 0x0035;
-pub const FILE_DEVICE_DFS_VOLUME: DEVICE_TYPE = 0x0036;
-pub const FILE_DEVICE_SERENUM: DEVICE_TYPE = 0x0037;
-pub const FILE_DEVICE_TERMSRV: DEVICE_TYPE = 0x0038;
-pub const FILE_DEVICE_KSEC: DEVICE_TYPE = 0x0039;
-pub const FILE_DEVICE_FIPS: DEVICE_TYPE = 0x003a;
-pub const FILE_DEVICE_INFINIBAND: DEVICE_TYPE = 0x003b;
-// TODO: missing values?
-pub const FILE_DEVICE_VMBUS: DEVICE_TYPE = 0x003e;
-pub const FILE_DEVICE_CRYPT_PROVIDER: DEVICE_TYPE = 0x003f;
-pub const FILE_DEVICE_WPD: DEVICE_TYPE = 0x0040;
-pub const FILE_DEVICE_BLUETOOTH: DEVICE_TYPE = 0x0041;
-pub const FILE_DEVICE_MT_COMPOSITE: DEVICE_TYPE = 0x0042;
-pub const FILE_DEVICE_MT_TRANSPORT: DEVICE_TYPE = 0x0043;
-pub const FILE_DEVICE_BIOMETRIC: DEVICE_TYPE = 0x0044;
-pub const FILE_DEVICE_PMI: DEVICE_TYPE = 0x0045;
-pub const FILE_DEVICE_EHSTOR: DEVICE_TYPE = 0x0046;
-pub const FILE_DEVICE_DEVAPI: DEVICE_TYPE = 0x0047;
-pub const FILE_DEVICE_GPIO: DEVICE_TYPE = 0x0048;
-pub const FILE_DEVICE_USBEX: DEVICE_TYPE = 0x0049;
-pub const FILE_DEVICE_CONSOLE: DEVICE_TYPE = 0x0050;
-pub const FILE_DEVICE_NFP: DEVICE_TYPE = 0x0051;
-pub const FILE_DEVICE_SYSENV: DEVICE_TYPE = 0x0052;
-pub const FILE_DEVICE_VIRTUAL_BLOCK: DEVICE_TYPE = 0x0053;
-pub const FILE_DEVICE_POINT_OF_SERVICE: DEVICE_TYPE = 0x0054;
-pub const FILE_DEVICE_STORAGE_REPLICATION: DEVICE_TYPE = 0x0055;
-pub const FILE_DEVICE_TRUST_ENV: DEVICE_TYPE = 0x0056;
-pub const FILE_DEVICE_UCM: DEVICE_TYPE = 0x0057;
-pub const FILE_DEVICE_UCMTCPCI: DEVICE_TYPE = 0x0058;
-pub const FILE_DEVICE_PERSISTENT_MEMORY: DEVICE_TYPE = 0x0059;
-pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a;
-pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b;
-pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c;
-
-/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes
-pub const TransferType = enum(u2) {
- METHOD_BUFFERED = 0,
- METHOD_IN_DIRECT = 1,
- METHOD_OUT_DIRECT = 2,
- METHOD_NEITHER = 3,
-};
-
-pub const FILE_ANY_ACCESS = 0;
-pub const FILE_READ_ACCESS = 1;
-pub const FILE_WRITE_ACCESS = 2;
-
-/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
-pub fn CTL_CODE(deviceType: u16, function: u12, method: TransferType, access: u2) DWORD {
- return (@as(DWORD, deviceType) << 16) |
- (@as(DWORD, access) << 14) |
- (@as(DWORD, function) << 2) |
- @intFromEnum(method);
-}
-
-pub const INVALID_HANDLE_VALUE = @as(HANDLE, @ptrFromInt(maxInt(usize)));
-
-pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
-
-pub const FILE_ALL_INFORMATION = extern struct {
- BasicInformation: FILE_BASIC_INFORMATION,
- StandardInformation: FILE_STANDARD_INFORMATION,
- InternalInformation: FILE_INTERNAL_INFORMATION,
- EaInformation: FILE_EA_INFORMATION,
- AccessInformation: FILE_ACCESS_INFORMATION,
- PositionInformation: FILE_POSITION_INFORMATION,
- ModeInformation: FILE_MODE_INFORMATION,
- AlignmentInformation: FILE_ALIGNMENT_INFORMATION,
- NameInformation: FILE_NAME_INFORMATION,
-};
-
-pub const FILE_BASIC_INFORMATION = extern struct {
- CreationTime: LARGE_INTEGER,
- LastAccessTime: LARGE_INTEGER,
- LastWriteTime: LARGE_INTEGER,
- ChangeTime: LARGE_INTEGER,
- FileAttributes: ULONG,
-};
-
-pub const FILE_STANDARD_INFORMATION = extern struct {
- AllocationSize: LARGE_INTEGER,
- EndOfFile: LARGE_INTEGER,
- NumberOfLinks: ULONG,
- DeletePending: BOOLEAN,
- Directory: BOOLEAN,
-};
-
-pub const FILE_INTERNAL_INFORMATION = extern struct {
- IndexNumber: LARGE_INTEGER,
-};
-
-pub const FILE_EA_INFORMATION = extern struct {
- EaSize: ULONG,
-};
-
-pub const FILE_ACCESS_INFORMATION = extern struct {
- AccessFlags: ACCESS_MASK,
-};
-
-pub const FILE_POSITION_INFORMATION = extern struct {
- CurrentByteOffset: LARGE_INTEGER,
-};
-
-pub const FILE_END_OF_FILE_INFORMATION = extern struct {
- EndOfFile: LARGE_INTEGER,
-};
-
-pub const FILE_MODE_INFORMATION = extern struct {
- Mode: ULONG,
-};
-
-pub const FILE_ALIGNMENT_INFORMATION = extern struct {
- AlignmentRequirement: ULONG,
-};
-
-pub const FILE_NAME_INFORMATION = extern struct {
- FileNameLength: ULONG,
- FileName: [1]WCHAR,
-};
-
-pub const FILE_DISPOSITION_INFORMATION_EX = extern struct {
- /// combination of FILE_DISPOSITION_* flags
- Flags: ULONG,
-};
-
-pub const FILE_DISPOSITION_DO_NOT_DELETE: ULONG = 0x00000000;
-pub const FILE_DISPOSITION_DELETE: ULONG = 0x00000001;
-pub const FILE_DISPOSITION_POSIX_SEMANTICS: ULONG = 0x00000002;
-pub const FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK: ULONG = 0x00000004;
-pub const FILE_DISPOSITION_ON_CLOSE: ULONG = 0x00000008;
-pub const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: ULONG = 0x00000010;
-
-// FILE_RENAME_INFORMATION.Flags
-pub const FILE_RENAME_REPLACE_IF_EXISTS = 0x00000001;
-pub const FILE_RENAME_POSIX_SEMANTICS = 0x00000002;
-pub const FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE = 0x00000004;
-pub const FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x00000008;
-pub const FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE = 0x00000010;
-pub const FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE = 0x00000020;
-pub const FILE_RENAME_PRESERVE_AVAILABLE_SPACE = 0x00000030;
-pub const FILE_RENAME_IGNORE_READONLY_ATTRIBUTE = 0x00000040;
-pub const FILE_RENAME_FORCE_RESIZE_TARGET_SR = 0x00000080;
-pub const FILE_RENAME_FORCE_RESIZE_SOURCE_SR = 0x00000100;
-pub const FILE_RENAME_FORCE_RESIZE_SR = 0x00000180;
-
-pub const FILE_RENAME_INFORMATION = extern struct {
- Flags: BOOLEAN,
- RootDirectory: ?HANDLE,
- FileNameLength: ULONG,
- FileName: [1]WCHAR,
-};
+pub const INVALID_HANDLE_VALUE: HANDLE = @ptrFromInt(maxInt(usize));
-// FileRenameInformationEx (since .win10_rs1)
-pub const FILE_RENAME_INFORMATION_EX = extern struct {
- Flags: ULONG,
- RootDirectory: ?HANDLE,
- FileNameLength: ULONG,
- FileName: [1]WCHAR,
-};
+pub const INVALID_FILE_ATTRIBUTES: DWORD = maxInt(DWORD);
pub const IO_STATUS_BLOCK = extern struct {
// "DUMMYUNIONNAME" expands to "u"
@@ -3106,130 +5196,6 @@ pub const IO_STATUS_BLOCK = extern struct {
Information: ULONG_PTR,
};
-pub const FILE_INFORMATION_CLASS = enum(c_int) {
- FileDirectoryInformation = 1,
- FileFullDirectoryInformation,
- FileBothDirectoryInformation,
- FileBasicInformation,
- FileStandardInformation,
- FileInternalInformation,
- FileEaInformation,
- FileAccessInformation,
- FileNameInformation,
- FileRenameInformation,
- FileLinkInformation,
- FileNamesInformation,
- FileDispositionInformation,
- FilePositionInformation,
- FileFullEaInformation,
- FileModeInformation,
- FileAlignmentInformation,
- FileAllInformation,
- FileAllocationInformation,
- FileEndOfFileInformation,
- FileAlternateNameInformation,
- FileStreamInformation,
- FilePipeInformation,
- FilePipeLocalInformation,
- FilePipeRemoteInformation,
- FileMailslotQueryInformation,
- FileMailslotSetInformation,
- FileCompressionInformation,
- FileObjectIdInformation,
- FileCompletionInformation,
- FileMoveClusterInformation,
- FileQuotaInformation,
- FileReparsePointInformation,
- FileNetworkOpenInformation,
- FileAttributeTagInformation,
- FileTrackingInformation,
- FileIdBothDirectoryInformation,
- FileIdFullDirectoryInformation,
- FileValidDataLengthInformation,
- FileShortNameInformation,
- FileIoCompletionNotificationInformation,
- FileIoStatusBlockRangeInformation,
- FileIoPriorityHintInformation,
- FileSfioReserveInformation,
- FileSfioVolumeInformation,
- FileHardLinkInformation,
- FileProcessIdsUsingFileInformation,
- FileNormalizedNameInformation,
- FileNetworkPhysicalNameInformation,
- FileIdGlobalTxDirectoryInformation,
- FileIsRemoteDeviceInformation,
- FileUnusedInformation,
- FileNumaNodeInformation,
- FileStandardLinkInformation,
- FileRemoteProtocolInformation,
- FileRenameInformationBypassAccessCheck,
- FileLinkInformationBypassAccessCheck,
- FileVolumeNameInformation,
- FileIdInformation,
- FileIdExtdDirectoryInformation,
- FileReplaceCompletionInformation,
- FileHardLinkFullIdInformation,
- FileIdExtdBothDirectoryInformation,
- FileDispositionInformationEx,
- FileRenameInformationEx,
- FileRenameInformationExBypassAccessCheck,
- FileDesiredStorageClassInformation,
- FileStatInformation,
- FileMemoryPartitionInformation,
- FileStatLxInformation,
- FileCaseSensitiveInformation,
- FileLinkInformationEx,
- FileLinkInformationExBypassAccessCheck,
- FileStorageReserveIdInformation,
- FileCaseSensitiveInformationForceAccessCheck,
- FileMaximumInformation,
-};
-
-pub const FILE_ATTRIBUTE_TAG_INFO = extern struct {
- FileAttributes: DWORD,
- ReparseTag: DWORD,
-};
-
-/// "If this bit is set, the file or directory represents another named entity in the system."
-/// https://learn.microsoft.com/en-us/windows/win32/fileio/reparse-point-tags
-pub const reparse_tag_name_surrogate_bit = 0x20000000;
-
-pub const FILE_DISPOSITION_INFORMATION = extern struct {
- DeleteFile: BOOLEAN,
-};
-
-pub const FILE_FS_DEVICE_INFORMATION = extern struct {
- DeviceType: DEVICE_TYPE,
- Characteristics: ULONG,
-};
-
-pub const FILE_FS_VOLUME_INFORMATION = extern struct {
- VolumeCreationTime: LARGE_INTEGER,
- VolumeSerialNumber: ULONG,
- VolumeLabelLength: ULONG,
- SupportsObjects: BOOLEAN,
- // Flexible array member
- VolumeLabel: [1]WCHAR,
-};
-
-pub const FS_INFORMATION_CLASS = enum(c_int) {
- FileFsVolumeInformation = 1,
- FileFsLabelInformation,
- FileFsSizeInformation,
- FileFsDeviceInformation,
- FileFsAttributeInformation,
- FileFsControlInformation,
- FileFsFullSizeInformation,
- FileFsObjectIdInformation,
- FileFsDriverPathInformation,
- FileFsVolumeFlagsInformation,
- FileFsSectorSizeInformation,
- FileFsDataCopyInformation,
- FileFsMetadataSizeInformation,
- FileFsFullSizeInformationEx,
- FileFsMaximumInformation,
-};
-
pub const OVERLAPPED = extern struct {
Internal: ULONG_PTR,
InternalHigh: ULONG_PTR,
@@ -3331,129 +5297,16 @@ pub const PIPE_READMODE_MESSAGE = 0x00000002;
pub const PIPE_WAIT = 0x00000000;
pub const PIPE_NOWAIT = 0x00000001;
-pub const GENERIC_READ = 0x80000000;
-pub const GENERIC_WRITE = 0x40000000;
-pub const GENERIC_EXECUTE = 0x20000000;
-pub const GENERIC_ALL = 0x10000000;
-
-pub const FILE_SHARE_DELETE = 0x00000004;
-pub const FILE_SHARE_READ = 0x00000001;
-pub const FILE_SHARE_WRITE = 0x00000002;
-
-pub const DELETE = 0x00010000;
-pub const READ_CONTROL = 0x00020000;
-pub const WRITE_DAC = 0x00040000;
-pub const WRITE_OWNER = 0x00080000;
-pub const SYNCHRONIZE = 0x00100000;
-pub const STANDARD_RIGHTS_READ = READ_CONTROL;
-pub const STANDARD_RIGHTS_WRITE = READ_CONTROL;
-pub const STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
-pub const STANDARD_RIGHTS_REQUIRED = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER;
-pub const MAXIMUM_ALLOWED = 0x02000000;
-
-// disposition for NtCreateFile
-pub const FILE_SUPERSEDE = 0;
-pub const FILE_OPEN = 1;
-pub const FILE_CREATE = 2;
-pub const FILE_OPEN_IF = 3;
-pub const FILE_OVERWRITE = 4;
-pub const FILE_OVERWRITE_IF = 5;
-pub const FILE_MAXIMUM_DISPOSITION = 5;
-
-// flags for NtCreateFile and NtOpenFile
-pub const FILE_READ_DATA = 0x00000001;
-pub const FILE_LIST_DIRECTORY = 0x00000001;
-pub const FILE_WRITE_DATA = 0x00000002;
-pub const FILE_ADD_FILE = 0x00000002;
-pub const FILE_APPEND_DATA = 0x00000004;
-pub const FILE_ADD_SUBDIRECTORY = 0x00000004;
-pub const FILE_CREATE_PIPE_INSTANCE = 0x00000004;
-pub const FILE_READ_EA = 0x00000008;
-pub const FILE_WRITE_EA = 0x00000010;
-pub const FILE_EXECUTE = 0x00000020;
-pub const FILE_TRAVERSE = 0x00000020;
-pub const FILE_DELETE_CHILD = 0x00000040;
-pub const FILE_READ_ATTRIBUTES = 0x00000080;
-pub const FILE_WRITE_ATTRIBUTES = 0x00000100;
-
-pub const FILE_DIRECTORY_FILE = 0x00000001;
-pub const FILE_WRITE_THROUGH = 0x00000002;
-pub const FILE_SEQUENTIAL_ONLY = 0x00000004;
-pub const FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008;
-pub const FILE_SYNCHRONOUS_IO_ALERT = 0x00000010;
-pub const FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020;
-pub const FILE_NON_DIRECTORY_FILE = 0x00000040;
-pub const FILE_CREATE_TREE_CONNECTION = 0x00000080;
-pub const FILE_COMPLETE_IF_OPLOCKED = 0x00000100;
-pub const FILE_NO_EA_KNOWLEDGE = 0x00000200;
-pub const FILE_OPEN_FOR_RECOVERY = 0x00000400;
-pub const FILE_RANDOM_ACCESS = 0x00000800;
-pub const FILE_DELETE_ON_CLOSE = 0x00001000;
-pub const FILE_OPEN_BY_FILE_ID = 0x00002000;
-pub const FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000;
-pub const FILE_NO_COMPRESSION = 0x00008000;
-pub const FILE_RESERVE_OPFILTER = 0x00100000;
-pub const FILE_OPEN_REPARSE_POINT = 0x00200000;
-pub const FILE_OPEN_OFFLINE_FILE = 0x00400000;
-pub const FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000;
-
pub const CREATE_ALWAYS = 2;
pub const CREATE_NEW = 1;
pub const OPEN_ALWAYS = 4;
pub const OPEN_EXISTING = 3;
pub const TRUNCATE_EXISTING = 5;
-pub const FILE_ATTRIBUTE_ARCHIVE = 0x20;
-pub const FILE_ATTRIBUTE_COMPRESSED = 0x800;
-pub const FILE_ATTRIBUTE_DEVICE = 0x40;
-pub const FILE_ATTRIBUTE_DIRECTORY = 0x10;
-pub const FILE_ATTRIBUTE_ENCRYPTED = 0x4000;
-pub const FILE_ATTRIBUTE_HIDDEN = 0x2;
-pub const FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000;
-pub const FILE_ATTRIBUTE_NORMAL = 0x80;
-pub const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000;
-pub const FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x20000;
-pub const FILE_ATTRIBUTE_OFFLINE = 0x1000;
-pub const FILE_ATTRIBUTE_READONLY = 0x1;
-pub const FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x400000;
-pub const FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x40000;
-pub const FILE_ATTRIBUTE_REPARSE_POINT = 0x400;
-pub const FILE_ATTRIBUTE_SPARSE_FILE = 0x200;
-pub const FILE_ATTRIBUTE_SYSTEM = 0x4;
-pub const FILE_ATTRIBUTE_TEMPORARY = 0x100;
-pub const FILE_ATTRIBUTE_VIRTUAL = 0x10000;
-
-pub const FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1ff;
-pub const FILE_GENERIC_READ = STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE;
-pub const FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE;
-pub const FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE;
-
-// Flags for NtCreateNamedPipeFile
-// NamedPipeType
-pub const FILE_PIPE_BYTE_STREAM_TYPE = 0x0;
-pub const FILE_PIPE_MESSAGE_TYPE = 0x1;
-pub const FILE_PIPE_ACCEPT_REMOTE_CLIENTS = 0x0;
-pub const FILE_PIPE_REJECT_REMOTE_CLIENTS = 0x2;
-pub const FILE_PIPE_TYPE_VALID_MASK = 0x3;
-// CompletionMode
-pub const FILE_PIPE_QUEUE_OPERATION = 0x0;
-pub const FILE_PIPE_COMPLETE_OPERATION = 0x1;
-// ReadMode
-pub const FILE_PIPE_BYTE_STREAM_MODE = 0x0;
-pub const FILE_PIPE_MESSAGE_MODE = 0x1;
-
// flags for CreateEvent
pub const CREATE_EVENT_INITIAL_SET = 0x00000002;
pub const CREATE_EVENT_MANUAL_RESET = 0x00000001;
-pub const EVENT_ALL_ACCESS = 0x1F0003;
-pub const EVENT_MODIFY_STATE = 0x0002;
-
-// MEMORY_BASIC_INFORMATION.Type flags for VirtualQuery
-pub const MEM_IMAGE = 0x1000000;
-pub const MEM_MAPPED = 0x40000;
-pub const MEM_PRIVATE = 0x20000;
-
pub const PROCESS_INFORMATION = extern struct {
hProcess: HANDLE,
hThread: HANDLE,
@@ -3521,45 +5374,6 @@ pub const FILE_BEGIN = 0;
pub const FILE_CURRENT = 1;
pub const FILE_END = 2;
-pub const HEAP_CREATE_ENABLE_EXECUTE = 0x00040000;
-pub const HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010;
-pub const HEAP_GENERATE_EXCEPTIONS = 0x00000004;
-pub const HEAP_NO_SERIALIZE = 0x00000001;
-
-// AllocationType values
-pub const MEM_COMMIT = 0x1000;
-pub const MEM_RESERVE = 0x2000;
-pub const MEM_FREE = 0x10000;
-pub const MEM_RESET = 0x80000;
-pub const MEM_RESET_UNDO = 0x1000000;
-pub const MEM_LARGE_PAGES = 0x20000000;
-pub const MEM_PHYSICAL = 0x400000;
-pub const MEM_TOP_DOWN = 0x100000;
-pub const MEM_WRITE_WATCH = 0x200000;
-pub const MEM_RESERVE_PLACEHOLDER = 0x00040000;
-pub const MEM_PRESERVE_PLACEHOLDER = 0x00000400;
-
-// Protect values
-pub const PAGE_EXECUTE = 0x10;
-pub const PAGE_EXECUTE_READ = 0x20;
-pub const PAGE_EXECUTE_READWRITE = 0x40;
-pub const PAGE_EXECUTE_WRITECOPY = 0x80;
-pub const PAGE_NOACCESS = 0x01;
-pub const PAGE_READONLY = 0x02;
-pub const PAGE_READWRITE = 0x04;
-pub const PAGE_WRITECOPY = 0x08;
-pub const PAGE_TARGETS_INVALID = 0x40000000;
-pub const PAGE_TARGETS_NO_UPDATE = 0x40000000; // Same as PAGE_TARGETS_INVALID
-pub const PAGE_GUARD = 0x100;
-pub const PAGE_NOCACHE = 0x200;
-pub const PAGE_WRITECOMBINE = 0x400;
-
-// FreeType values
-pub const MEM_COALESCE_PLACEHOLDERS = 0x1;
-pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
-pub const MEM_DECOMMIT = 0x4000;
-pub const MEM_RELEASE = 0x8000;
-
pub const PTHREAD_START_ROUTINE = *const fn (LPVOID) callconv(.winapi) DWORD;
pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
@@ -3743,38 +5557,8 @@ pub const PIMAGE_TLS_CALLBACK = ?*const fn (PVOID, DWORD, PVOID) callconv(.winap
pub const PROV_RSA_FULL = 1;
pub const REGSAM = ACCESS_MASK;
-pub const ACCESS_MASK = DWORD;
pub const LSTATUS = LONG;
-pub const SECTION_INHERIT = enum(c_int) {
- ViewShare = 0,
- ViewUnmap = 1,
-};
-
-pub const SECTION_QUERY = 0x0001;
-pub const SECTION_MAP_WRITE = 0x0002;
-pub const SECTION_MAP_READ = 0x0004;
-pub const SECTION_MAP_EXECUTE = 0x0008;
-pub const SECTION_EXTEND_SIZE = 0x0010;
-pub const SECTION_ALL_ACCESS =
- STANDARD_RIGHTS_REQUIRED |
- SECTION_QUERY |
- SECTION_MAP_WRITE |
- SECTION_MAP_READ |
- SECTION_MAP_EXECUTE |
- SECTION_EXTEND_SIZE;
-
-pub const SEC_64K_PAGES = 0x80000;
-pub const SEC_FILE = 0x800000;
-pub const SEC_IMAGE = 0x1000000;
-pub const SEC_PROTECTED_IMAGE = 0x2000000;
-pub const SEC_RESERVE = 0x4000000;
-pub const SEC_COMMIT = 0x8000000;
-pub const SEC_IMAGE_NO_EXECUTE = SEC_IMAGE | SEC_NOCACHE;
-pub const SEC_NOCACHE = 0x10000000;
-pub const SEC_WRITECOMBINE = 0x40000000;
-pub const SEC_LARGE_PAGES = 0x80000000;
-
pub const HKEY = *opaque {};
pub const HKEY_CLASSES_ROOT: HKEY = @ptrFromInt(0x80000000);
@@ -3788,34 +5572,6 @@ pub const HKEY_CURRENT_CONFIG: HKEY = @ptrFromInt(0x80000005);
pub const HKEY_DYN_DATA: HKEY = @ptrFromInt(0x80000006);
pub const HKEY_CURRENT_USER_LOCAL_SETTINGS: HKEY = @ptrFromInt(0x80000007);
-/// Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY,
-/// KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK access rights.
-pub const KEY_ALL_ACCESS = 0xF003F;
-/// Reserved for system use.
-pub const KEY_CREATE_LINK = 0x0020;
-/// Required to create a subkey of a registry key.
-pub const KEY_CREATE_SUB_KEY = 0x0004;
-/// Required to enumerate the subkeys of a registry key.
-pub const KEY_ENUMERATE_SUB_KEYS = 0x0008;
-/// Equivalent to KEY_READ.
-pub const KEY_EXECUTE = 0x20019;
-/// Required to request change notifications for a registry key or for subkeys of a registry key.
-pub const KEY_NOTIFY = 0x0010;
-/// Required to query the values of a registry key.
-pub const KEY_QUERY_VALUE = 0x0001;
-/// Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
-pub const KEY_READ = 0x20019;
-/// Required to create, delete, or set a registry value.
-pub const KEY_SET_VALUE = 0x0002;
-/// Indicates that an application on 64-bit Windows should operate on the 32-bit registry view.
-/// This flag is ignored by 32-bit Windows.
-pub const KEY_WOW64_32KEY = 0x0200;
-/// Indicates that an application on 64-bit Windows should operate on the 64-bit registry view.
-/// This flag is ignored by 32-bit Windows.
-pub const KEY_WOW64_64KEY = 0x0100;
-/// Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
-pub const KEY_WRITE = 0x20006;
-
/// Open symbolic link.
pub const REG_OPTION_OPEN_LINK: DWORD = 0x8;
@@ -4466,14 +6222,14 @@ pub const EXCEPTION_DISPOSITION = i32;
pub const EXCEPTION_ROUTINE = *const fn (
ExceptionRecord: ?*EXCEPTION_RECORD,
EstablisherFrame: PVOID,
- ContextRecord: *(Self.CONTEXT),
+ ContextRecord: *CONTEXT,
DispatcherContext: PVOID,
) callconv(.winapi) EXCEPTION_DISPOSITION;
pub const UNWIND_HISTORY_TABLE_SIZE = 12;
pub const UNWIND_HISTORY_TABLE_ENTRY = extern struct {
ImageBase: ULONG64,
- FunctionEntry: *Self.RUNTIME_FUNCTION,
+ FunctionEntry: *RUNTIME_FUNCTION,
};
pub const UNWIND_HISTORY_TABLE = extern struct {
@@ -4492,24 +6248,6 @@ pub const UNW_FLAG_EHANDLER = 0x1;
pub const UNW_FLAG_UHANDLER = 0x2;
pub const UNW_FLAG_CHAININFO = 0x4;
-pub const OBJECT_ATTRIBUTES = extern struct {
- Length: ULONG,
- RootDirectory: ?HANDLE,
- ObjectName: *UNICODE_STRING,
- Attributes: ULONG,
- SecurityDescriptor: ?*anyopaque,
- SecurityQualityOfService: ?*anyopaque,
-};
-
-pub const OBJ_INHERIT = 0x00000002;
-pub const OBJ_PERMANENT = 0x00000010;
-pub const OBJ_EXCLUSIVE = 0x00000020;
-pub const OBJ_CASE_INSENSITIVE = 0x00000040;
-pub const OBJ_OPENIF = 0x00000080;
-pub const OBJ_OPENLINK = 0x00000100;
-pub const OBJ_KERNEL_HANDLE = 0x00000200;
-pub const OBJ_VALID_ATTRIBUTES = 0x000003F2;
-
pub const UNICODE_STRING = extern struct {
Length: c_ushort,
MaximumLength: c_ushort,
@@ -4617,7 +6355,7 @@ pub const PEB = extern struct {
Ldr: *PEB_LDR_DATA,
ProcessParameters: *RTL_USER_PROCESS_PARAMETERS,
SubSystemData: PVOID,
- ProcessHeap: HANDLE,
+ ProcessHeap: ?*HEAP,
// Versions: 5.1+
FastPebLock: *RTL_CRITICAL_SECTION,
@@ -4862,7 +6600,7 @@ pub const FILE_DIRECTORY_INFORMATION = extern struct {
ChangeTime: LARGE_INTEGER,
EndOfFile: LARGE_INTEGER,
AllocationSize: LARGE_INTEGER,
- FileAttributes: ULONG,
+ FileAttributes: FILE.ATTRIBUTE,
FileNameLength: ULONG,
FileName: [1]WCHAR,
};
@@ -4876,7 +6614,7 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {
ChangeTime: LARGE_INTEGER,
EndOfFile: LARGE_INTEGER,
AllocationSize: LARGE_INTEGER,
- FileAttributes: ULONG,
+ FileAttributes: FILE.ATTRIBUTE,
FileNameLength: ULONG,
EaSize: ULONG,
ShortNameLength: CHAR,
@@ -4905,7 +6643,7 @@ pub fn FileInformationIterator(comptime FileInformationType: type) type {
};
}
-pub const IO_APC_ROUTINE = *const fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.winapi) void;
+pub const IO_APC_ROUTINE = fn (?*anyopaque, *IO_STATUS_BLOCK, ULONG) callconv(.winapi) void;
pub const CURDIR = extern struct {
DosPath: UNICODE_STRING,
@@ -4974,7 +6712,7 @@ pub const GetProcessMemoryInfoError = error{
pub fn GetProcessMemoryInfo(hProcess: HANDLE) GetProcessMemoryInfoError!VM_COUNTERS {
var vmc: VM_COUNTERS = undefined;
- const rc = ntdll.NtQueryInformationProcess(hProcess, .ProcessVmCounters, &vmc, @sizeOf(VM_COUNTERS), null);
+ const rc = ntdll.NtQueryInformationProcess(hProcess, .VmCounters, &vmc, @sizeOf(VM_COUNTERS), null);
switch (rc) {
.SUCCESS => return vmc,
.ACCESS_DENIED => return error.AccessDenied,
@@ -5029,7 +6767,7 @@ pub const OSVERSIONINFOW = extern struct {
pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
pub const REPARSE_DATA_BUFFER = extern struct {
- ReparseTag: ULONG,
+ ReparseTag: IO_REPARSE_TAG,
ReparseDataLength: USHORT,
Reserved: USHORT,
DataBuffer: [1]UCHAR,
@@ -5049,18 +6787,11 @@ pub const MOUNT_POINT_REPARSE_BUFFER = extern struct {
PrintNameLength: USHORT,
PathBuffer: [1]WCHAR,
};
-pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024;
-pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
-pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
-pub const IO_REPARSE_TAG_SYMLINK: ULONG = 0xa000000c;
-pub const IO_REPARSE_TAG_MOUNT_POINT: ULONG = 0xa0000003;
pub const SYMLINK_FLAG_RELATIVE: ULONG = 0x1;
pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
-pub const MOUNTMGRCONTROLTYPE = 0x0000006D;
-
pub const MOUNTMGR_MOUNT_POINT = extern struct {
SymbolicLinkNameOffset: ULONG,
SymbolicLinkNameLength: USHORT,
@@ -5077,7 +6808,6 @@ pub const MOUNTMGR_MOUNT_POINTS = extern struct {
NumberOfMountPoints: ULONG,
MountPoints: [1]MOUNTMGR_MOUNT_POINT,
};
-pub const IOCTL_MOUNTMGR_QUERY_POINTS = CTL_CODE(MOUNTMGRCONTROLTYPE, 2, .METHOD_BUFFERED, FILE_ANY_ACCESS);
pub const MOUNTMGR_TARGET_NAME = extern struct {
DeviceNameLength: USHORT,
@@ -5087,7 +6817,6 @@ pub const MOUNTMGR_VOLUME_PATHS = extern struct {
MultiSzLength: ULONG,
MultiSz: [1]WCHAR,
};
-pub const IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH = CTL_CODE(MOUNTMGRCONTROLTYPE, 12, .METHOD_BUFFERED, FILE_ANY_ACCESS);
pub const OBJECT_INFORMATION_CLASS = enum(c_int) {
ObjectBasicInformation = 0,
@@ -5479,113 +7208,6 @@ pub const SYSTEM_BASIC_INFORMATION = extern struct {
NumberOfProcessors: UCHAR,
};
-pub const THREADINFOCLASS = enum(c_int) {
- ThreadBasicInformation,
- ThreadTimes,
- ThreadPriority,
- ThreadBasePriority,
- ThreadAffinityMask,
- ThreadImpersonationToken,
- ThreadDescriptorTableEntry,
- ThreadEnableAlignmentFaultFixup,
- ThreadEventPair_Reusable,
- ThreadQuerySetWin32StartAddress,
- ThreadZeroTlsCell,
- ThreadPerformanceCount,
- ThreadAmILastThread,
- ThreadIdealProcessor,
- ThreadPriorityBoost,
- ThreadSetTlsArrayAddress,
- ThreadIsIoPending,
- // Windows 2000+ from here
- ThreadHideFromDebugger,
- // Windows XP+ from here
- ThreadBreakOnTermination,
- ThreadSwitchLegacyState,
- ThreadIsTerminated,
- // Windows Vista+ from here
- ThreadLastSystemCall,
- ThreadIoPriority,
- ThreadCycleTime,
- ThreadPagePriority,
- ThreadActualBasePriority,
- ThreadTebInformation,
- ThreadCSwitchMon,
- // Windows 7+ from here
- ThreadCSwitchPmu,
- ThreadWow64Context,
- ThreadGroupInformation,
- ThreadUmsInformation,
- ThreadCounterProfiling,
- ThreadIdealProcessorEx,
- // Windows 8+ from here
- ThreadCpuAccountingInformation,
- // Windows 8.1+ from here
- ThreadSuspendCount,
- // Windows 10+ from here
- ThreadHeterogeneousCpuPolicy,
- ThreadContainerId,
- ThreadNameInformation,
- ThreadSelectedCpuSets,
- ThreadSystemThreadInformation,
- ThreadActualGroupAffinity,
-};
-
-pub const PROCESSINFOCLASS = enum(c_int) {
- ProcessBasicInformation,
- ProcessQuotaLimits,
- ProcessIoCounters,
- ProcessVmCounters,
- ProcessTimes,
- ProcessBasePriority,
- ProcessRaisePriority,
- ProcessDebugPort,
- ProcessExceptionPort,
- ProcessAccessToken,
- ProcessLdtInformation,
- ProcessLdtSize,
- ProcessDefaultHardErrorMode,
- ProcessIoPortHandlers,
- ProcessPooledUsageAndLimits,
- ProcessWorkingSetWatch,
- ProcessUserModeIOPL,
- ProcessEnableAlignmentFaultFixup,
- ProcessPriorityClass,
- ProcessWx86Information,
- ProcessHandleCount,
- ProcessAffinityMask,
- ProcessPriorityBoost,
- ProcessDeviceMap,
- ProcessSessionInformation,
- ProcessForegroundInformation,
- ProcessWow64Information,
- ProcessImageFileName,
- ProcessLUIDDeviceMapsEnabled,
- ProcessBreakOnTermination,
- ProcessDebugObjectHandle,
- ProcessDebugFlags,
- ProcessHandleTracing,
- ProcessIoPriority,
- ProcessExecuteFlags,
- ProcessTlsInformation,
- ProcessCookie,
- ProcessImageInformation,
- ProcessCycleTime,
- ProcessPagePriority,
- ProcessInstrumentationCallback,
- ProcessThreadStackAllocation,
- ProcessWorkingSetWatchEx,
- ProcessImageFileNameWin32,
- ProcessImageFileMapping,
- ProcessAffinityUpdateMode,
- ProcessMemoryAllocationMode,
- ProcessGroupInformation,
- ProcessTokenVirtualizationEnabled,
- ProcessConsoleHostProcess,
- ProcessWindowInformation,
- MaxProcessInfoClass,
-};
-
pub const PROCESS_BASIC_INFORMATION = extern struct {
ExitStatus: NTSTATUS,
PebBaseAddress: *PEB,
@@ -5641,7 +7263,7 @@ pub fn ProcessBaseAddress(handle: HANDLE) ProcessBaseAddressError!HMODULE {
var nread: DWORD = 0;
const rc = ntdll.NtQueryInformationProcess(
handle,
- .ProcessBasicInformation,
+ .BasicInformation,
&info,
@sizeOf(PROCESS_BASIC_INFORMATION),
&nread,
diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig
@@ -1,6 +1,7 @@
const std = @import("../../std.zig");
const windows = std.os.windows;
+const ACCESS_MASK = windows.ACCESS_MASK;
const BOOL = windows.BOOL;
const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;
const CONSOLE_SCREEN_BUFFER_INFO = windows.CONSOLE_SCREEN_BUFFER_INFO;
@@ -66,7 +67,7 @@ pub extern "kernel32" fn CancelIoEx(
pub extern "kernel32" fn CreateFileW(
lpFileName: LPCWSTR,
- dwDesiredAccess: DWORD,
+ dwDesiredAccess: ACCESS_MASK,
dwShareMode: DWORD,
lpSecurityAttributes: ?*SECURITY_ATTRIBUTES,
dwCreationDisposition: DWORD,
@@ -160,7 +161,7 @@ pub extern "kernel32" fn DuplicateHandle(
hSourceHandle: HANDLE,
hTargetProcessHandle: HANDLE,
lpTargetHandle: *HANDLE,
- dwDesiredAccess: DWORD,
+ dwDesiredAccess: ACCESS_MASK,
bInheritHandle: BOOL,
dwOptions: DWORD,
) callconv(.winapi) BOOL;
@@ -308,9 +309,6 @@ pub extern "kernel32" fn CreateThread(
lpThreadId: ?*DWORD,
) callconv(.winapi) ?HANDLE;
-// TODO: Wrapper around RtlDelayExecution.
-pub extern "kernel32" fn SwitchToThread() callconv(.winapi) BOOL;
-
// Locks, critical sections, initializers
pub extern "kernel32" fn InitOnceExecuteOnce(
@@ -401,34 +399,6 @@ pub extern "kernel32" fn ReadConsoleOutputCharacterW(
lpNumberOfCharsRead: *DWORD,
) callconv(.winapi) BOOL;
-// Memory Mapping/Allocation
-
-// TODO: Wrapper around RtlCreateHeap.
-pub extern "kernel32" fn HeapCreate(
- flOptions: DWORD,
- dwInitialSize: SIZE_T,
- dwMaximumSize: SIZE_T,
-) callconv(.winapi) ?HANDLE;
-
-// TODO: Fowrarder to RtlFreeHeap before win11_zn.
-// Since win11_zn this function points to unexported symbol RtlFreeHeapFast.
-// See https://github.com/ziglang/zig/pull/25766#discussion_r2479727640
-pub extern "kernel32" fn HeapFree(
- hHeap: HANDLE,
- dwFlags: DWORD,
- lpMem: LPVOID,
-) callconv(.winapi) BOOL;
-
-// TODO: Wrapper around RtlValidateHeap (BOOLEAN -> BOOL)
-pub extern "kernel32" fn HeapValidate(
- hHeap: HANDLE,
- dwFlags: DWORD,
- lpMem: ?*const anyopaque,
-) callconv(.winapi) BOOL;
-
-// TODO: Getter for peb.ProcessHeap
-pub extern "kernel32" fn GetProcessHeap() callconv(.winapi) ?HANDLE;
-
// Code Libraries/Modules
// TODO: Wrapper around LdrGetDllFullName.
diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig
@@ -1,277 +1,279 @@
const std = @import("../../std.zig");
const windows = std.os.windows;
+const ACCESS_MASK = windows.ACCESS_MASK;
const BOOL = windows.BOOL;
+const BOOLEAN = windows.BOOLEAN;
+const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;
+const CONTEXT = windows.CONTEXT;
+const CRITICAL_SECTION = windows.CRITICAL_SECTION;
+const CTL_CODE = windows.CTL_CODE;
+const CURDIR = windows.CURDIR;
const DWORD = windows.DWORD;
const DWORD64 = windows.DWORD64;
-const ULONG = windows.ULONG;
-const ULONG_PTR = windows.ULONG_PTR;
-const NTSTATUS = windows.NTSTATUS;
-const WORD = windows.WORD;
+const ERESOURCE = windows.ERESOURCE;
+const EVENT_TYPE = windows.EVENT_TYPE;
+const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE;
+const FILE = windows.FILE;
+const FS_INFORMATION_CLASS = windows.FS_INFORMATION_CLASS;
const HANDLE = windows.HANDLE;
-const ACCESS_MASK = windows.ACCESS_MASK;
+const HEAP = windows.HEAP;
const IO_APC_ROUTINE = windows.IO_APC_ROUTINE;
-const BOOLEAN = windows.BOOLEAN;
-const OBJECT_ATTRIBUTES = windows.OBJECT_ATTRIBUTES;
-const PVOID = windows.PVOID;
const IO_STATUS_BLOCK = windows.IO_STATUS_BLOCK;
+const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS;
const LARGE_INTEGER = windows.LARGE_INTEGER;
+const LOGICAL = windows.LOGICAL;
+const LONG = windows.LONG;
+const LPCVOID = windows.LPCVOID;
+const LPVOID = windows.LPVOID;
+const MEM = windows.MEM;
+const NTSTATUS = windows.NTSTATUS;
+const OBJECT_ATTRIBUTES = windows.OBJECT_ATTRIBUTES;
const OBJECT_INFORMATION_CLASS = windows.OBJECT_INFORMATION_CLASS;
-const FILE_INFORMATION_CLASS = windows.FILE_INFORMATION_CLASS;
-const FS_INFORMATION_CLASS = windows.FS_INFORMATION_CLASS;
-const UNICODE_STRING = windows.UNICODE_STRING;
-const RTL_OSVERSIONINFOW = windows.RTL_OSVERSIONINFOW;
-const FILE_BASIC_INFORMATION = windows.FILE_BASIC_INFORMATION;
-const SIZE_T = windows.SIZE_T;
-const CURDIR = windows.CURDIR;
+const PAGE = windows.PAGE;
const PCWSTR = windows.PCWSTR;
+const PROCESSINFOCLASS = windows.PROCESSINFOCLASS;
+const PVOID = windows.PVOID;
+const RTL_OSVERSIONINFOW = windows.RTL_OSVERSIONINFOW;
const RTL_QUERY_REGISTRY_TABLE = windows.RTL_QUERY_REGISTRY_TABLE;
-const CONTEXT = windows.CONTEXT;
-const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE;
const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION;
-const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS;
-const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE;
+const SEC = windows.SEC;
+const SECTION_INHERIT = windows.SECTION_INHERIT;
+const SIZE_T = windows.SIZE_T;
+const SRWLOCK = windows.SRWLOCK;
const SYSTEM_INFORMATION_CLASS = windows.SYSTEM_INFORMATION_CLASS;
const THREADINFOCLASS = windows.THREADINFOCLASS;
-const PROCESSINFOCLASS = windows.PROCESSINFOCLASS;
-const LPVOID = windows.LPVOID;
-const LPCVOID = windows.LPCVOID;
-const SECTION_INHERIT = windows.SECTION_INHERIT;
+const ULONG = windows.ULONG;
+const ULONG_PTR = windows.ULONG_PTR;
+const UNICODE_STRING = windows.UNICODE_STRING;
+const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE;
+const USHORT = windows.USHORT;
const VECTORED_EXCEPTION_HANDLER = windows.VECTORED_EXCEPTION_HANDLER;
-const CRITICAL_SECTION = windows.CRITICAL_SECTION;
-const SRWLOCK = windows.SRWLOCK;
-const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;
+const WORD = windows.WORD;
-pub extern "ntdll" fn NtQueryInformationProcess(
- ProcessHandle: HANDLE,
- ProcessInformationClass: PROCESSINFOCLASS,
- ProcessInformation: *anyopaque,
- ProcessInformationLength: ULONG,
- ReturnLength: ?*ULONG,
-) callconv(.winapi) NTSTATUS;
+// ref: km/ntifs.h
-pub extern "ntdll" fn NtQueryInformationThread(
- ThreadHandle: HANDLE,
- ThreadInformationClass: THREADINFOCLASS,
- ThreadInformation: *anyopaque,
- ThreadInformationLength: ULONG,
- ReturnLength: ?*ULONG,
-) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn RtlCreateHeap(
+ Flags: HEAP.FLAGS.CREATE,
+ HeapBase: ?PVOID,
+ ReserveSize: SIZE_T,
+ CommitSize: SIZE_T,
+ Lock: ?*ERESOURCE,
+ Parameters: ?*const HEAP.RTL_PARAMETERS,
+) callconv(.winapi) ?*HEAP;
-pub extern "ntdll" fn NtQuerySystemInformation(
- SystemInformationClass: SYSTEM_INFORMATION_CLASS,
- SystemInformation: PVOID,
- SystemInformationLength: ULONG,
- ReturnLength: ?*ULONG,
-) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn RtlDestroyHeap(
+ HeapHandle: *HEAP,
+) callconv(.winapi) ?*HEAP;
-pub extern "ntdll" fn NtSetInformationThread(
- ThreadHandle: HANDLE,
- ThreadInformationClass: THREADINFOCLASS,
- ThreadInformation: *const anyopaque,
- ThreadInformationLength: ULONG,
-) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn RtlAllocateHeap(
+ HeapHandle: *HEAP,
+ Flags: HEAP.FLAGS.ALLOCATION,
+ Size: SIZE_T,
+) callconv(.winapi) ?PVOID;
+
+pub extern "ntdll" fn RtlFreeHeap(
+ HeapHandle: *HEAP,
+ Flags: HEAP.FLAGS.ALLOCATION,
+ BaseAddress: ?PVOID,
+) callconv(.winapi) LOGICAL;
-pub extern "ntdll" fn RtlGetVersion(
- lpVersionInformation: *RTL_OSVERSIONINFOW,
-) callconv(.winapi) NTSTATUS;
pub extern "ntdll" fn RtlCaptureStackBackTrace(
- FramesToSkip: DWORD,
- FramesToCapture: DWORD,
+ FramesToSkip: ULONG,
+ FramesToCapture: ULONG,
BackTrace: **anyopaque,
- BackTraceHash: ?*DWORD,
-) callconv(.winapi) WORD;
-pub extern "ntdll" fn RtlCaptureContext(ContextRecord: *CONTEXT) callconv(.winapi) void;
-pub extern "ntdll" fn RtlLookupFunctionEntry(
- ControlPc: DWORD64,
- ImageBase: *DWORD64,
- HistoryTable: *UNWIND_HISTORY_TABLE,
-) callconv(.winapi) ?*RUNTIME_FUNCTION;
-pub extern "ntdll" fn RtlVirtualUnwind(
- HandlerType: DWORD,
- ImageBase: DWORD64,
- ControlPc: DWORD64,
- FunctionEntry: *RUNTIME_FUNCTION,
- ContextRecord: *CONTEXT,
- HandlerData: *?PVOID,
- EstablisherFrame: *DWORD64,
- ContextPointers: ?*KNONVOLATILE_CONTEXT_POINTERS,
-) callconv(.winapi) *EXCEPTION_ROUTINE;
-pub extern "ntdll" fn RtlGetSystemTimePrecise() callconv(.winapi) LARGE_INTEGER;
-pub extern "ntdll" fn NtQueryInformationFile(
- FileHandle: HANDLE,
- IoStatusBlock: *IO_STATUS_BLOCK,
- FileInformation: *anyopaque,
- Length: ULONG,
- FileInformationClass: FILE_INFORMATION_CLASS,
-) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtSetInformationFile(
- FileHandle: HANDLE,
- IoStatusBlock: *IO_STATUS_BLOCK,
- FileInformation: PVOID,
- Length: ULONG,
- FileInformationClass: FILE_INFORMATION_CLASS,
-) callconv(.winapi) NTSTATUS;
+ BackTraceHash: ?*ULONG,
+) callconv(.winapi) USHORT;
-pub extern "ntdll" fn NtQueryAttributesFile(
- ObjectAttributes: *OBJECT_ATTRIBUTES,
- FileAttributes: *FILE_BASIC_INFORMATION,
-) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn RtlCaptureContext(
+ ContextRecord: *CONTEXT,
+) callconv(.winapi) void;
-pub extern "ntdll" fn RtlQueryPerformanceCounter(PerformanceCounter: *LARGE_INTEGER) callconv(.winapi) BOOL;
-pub extern "ntdll" fn RtlQueryPerformanceFrequency(PerformanceFrequency: *LARGE_INTEGER) callconv(.winapi) BOOL;
-pub extern "ntdll" fn NtQueryPerformanceCounter(
- PerformanceCounter: *LARGE_INTEGER,
- PerformanceFrequency: ?*LARGE_INTEGER,
+pub extern "ntdll" fn NtSetInformationThread(
+ ThreadHandle: HANDLE,
+ ThreadInformationClass: THREADINFOCLASS,
+ ThreadInformation: *const anyopaque,
+ ThreadInformationLength: ULONG,
) callconv(.winapi) NTSTATUS;
pub extern "ntdll" fn NtCreateFile(
FileHandle: *HANDLE,
DesiredAccess: ACCESS_MASK,
- ObjectAttributes: *OBJECT_ATTRIBUTES,
+ ObjectAttributes: *const OBJECT_ATTRIBUTES,
IoStatusBlock: *IO_STATUS_BLOCK,
- AllocationSize: ?*LARGE_INTEGER,
- FileAttributes: ULONG,
- ShareAccess: ULONG,
- CreateDisposition: ULONG,
- CreateOptions: ULONG,
+ AllocationSize: ?*const LARGE_INTEGER,
+ FileAttributes: FILE.ATTRIBUTE,
+ ShareAccess: FILE.SHARE,
+ CreateDisposition: FILE.CREATE_DISPOSITION,
+ CreateOptions: FILE.MODE,
EaBuffer: ?*anyopaque,
EaLength: ULONG,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtCreateSection(
- SectionHandle: *HANDLE,
- DesiredAccess: ACCESS_MASK,
- ObjectAttributes: ?*OBJECT_ATTRIBUTES,
- MaximumSize: ?*LARGE_INTEGER,
- SectionPageProtection: ULONG,
- AllocationAttributes: ULONG,
- FileHandle: ?HANDLE,
-) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtMapViewOfSection(
- SectionHandle: HANDLE,
- ProcessHandle: HANDLE,
- BaseAddress: *PVOID,
- ZeroBits: ?*ULONG,
- CommitSize: SIZE_T,
- SectionOffset: ?*LARGE_INTEGER,
- ViewSize: *SIZE_T,
- InheritDispostion: SECTION_INHERIT,
- AllocationType: ULONG,
- Win32Protect: ULONG,
-) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtUnmapViewOfSection(
- ProcessHandle: HANDLE,
- BaseAddress: PVOID,
-) callconv(.winapi) NTSTATUS;
+
pub extern "ntdll" fn NtDeviceIoControlFile(
FileHandle: HANDLE,
Event: ?HANDLE,
- ApcRoutine: ?IO_APC_ROUTINE,
+ ApcRoutine: ?*const IO_APC_ROUTINE,
ApcContext: ?*anyopaque,
IoStatusBlock: *IO_STATUS_BLOCK,
- IoControlCode: ULONG,
+ IoControlCode: CTL_CODE,
InputBuffer: ?*const anyopaque,
InputBufferLength: ULONG,
OutputBuffer: ?PVOID,
OutputBufferLength: ULONG,
) callconv(.winapi) NTSTATUS;
+
pub extern "ntdll" fn NtFsControlFile(
FileHandle: HANDLE,
Event: ?HANDLE,
- ApcRoutine: ?IO_APC_ROUTINE,
+ ApcRoutine: ?*const IO_APC_ROUTINE,
ApcContext: ?*anyopaque,
IoStatusBlock: *IO_STATUS_BLOCK,
- FsControlCode: ULONG,
+ FsControlCode: CTL_CODE,
InputBuffer: ?*const anyopaque,
InputBufferLength: ULONG,
OutputBuffer: ?PVOID,
OutputBufferLength: ULONG,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtClose(Handle: HANDLE) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn RtlDosPathNameToNtPathName_U(
- DosPathName: [*:0]const u16,
- NtPathName: *UNICODE_STRING,
- NtFileNamePart: ?*?[*:0]const u16,
- DirectoryInfo: ?*CURDIR,
-) callconv(.winapi) BOOL;
-pub extern "ntdll" fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) callconv(.winapi) void;
-/// Returns the number of bytes written to `Buffer`.
-/// If the returned count is larger than `BufferByteLength`, the buffer was too small.
-/// If the returned count is zero, an error occurred.
-pub extern "ntdll" fn RtlGetFullPathName_U(
- FileName: [*:0]const u16,
- BufferByteLength: ULONG,
- Buffer: [*]u16,
- ShortName: ?*[*:0]const u16,
-) callconv(.winapi) windows.ULONG;
+pub extern "ntdll" fn NtLockFile(
+ FileHandle: HANDLE,
+ Event: ?HANDLE,
+ ApcRoutine: ?*const IO_APC_ROUTINE,
+ ApcContext: ?*anyopaque,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ ByteOffset: *const LARGE_INTEGER,
+ Length: *const LARGE_INTEGER,
+ Key: ?*const ULONG,
+ FailImmediately: BOOLEAN,
+ ExclusiveLock: BOOLEAN,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtOpenFile(
+ FileHandle: *HANDLE,
+ DesiredAccess: ACCESS_MASK,
+ ObjectAttributes: *const OBJECT_ATTRIBUTES,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ ShareAccess: FILE.SHARE,
+ OpenOptions: FILE.MODE,
+) callconv(.winapi) NTSTATUS;
pub extern "ntdll" fn NtQueryDirectoryFile(
FileHandle: HANDLE,
Event: ?HANDLE,
- ApcRoutine: ?IO_APC_ROUTINE,
+ ApcRoutine: ?*const IO_APC_ROUTINE,
ApcContext: ?*anyopaque,
IoStatusBlock: *IO_STATUS_BLOCK,
FileInformation: *anyopaque,
Length: ULONG,
- FileInformationClass: FILE_INFORMATION_CLASS,
+ FileInformationClass: FILE.INFORMATION_CLASS,
ReturnSingleEntry: BOOLEAN,
- FileName: ?*UNICODE_STRING,
+ FileName: ?*const UNICODE_STRING,
RestartScan: BOOLEAN,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtCreateKeyedEvent(
- KeyedEventHandle: *HANDLE,
- DesiredAccess: ACCESS_MASK,
- ObjectAttributes: ?PVOID,
- Flags: ULONG,
+pub extern "ntdll" fn NtQueryInformationFile(
+ FileHandle: HANDLE,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ FileInformation: *anyopaque,
+ Length: ULONG,
+ FileInformationClass: FILE.INFORMATION_CLASS,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtReleaseKeyedEvent(
- EventHandle: ?HANDLE,
- Key: ?*const anyopaque,
- Alertable: BOOLEAN,
- Timeout: ?*const LARGE_INTEGER,
+pub extern "ntdll" fn NtQueryVolumeInformationFile(
+ FileHandle: HANDLE,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ FsInformation: *anyopaque,
+ Length: ULONG,
+ FsInformationClass: FS_INFORMATION_CLASS,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtWaitForKeyedEvent(
- EventHandle: ?HANDLE,
- Key: ?*const anyopaque,
- Alertable: BOOLEAN,
- Timeout: ?*const LARGE_INTEGER,
+pub extern "ntdll" fn NtReadFile(
+ FileHandle: HANDLE,
+ Event: ?HANDLE,
+ ApcRoutine: ?*const IO_APC_ROUTINE,
+ ApcContext: ?*anyopaque,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ Buffer: *anyopaque,
+ Length: ULONG,
+ ByteOffset: ?*const LARGE_INTEGER,
+ Key: ?*const ULONG,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtSetInformationFile(
+ FileHandle: HANDLE,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ FileInformation: *const anyopaque,
+ Length: ULONG,
+ FileInformationClass: FILE.INFORMATION_CLASS,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtWriteFile(
+ FileHandle: HANDLE,
+ Event: ?HANDLE,
+ ApcRoutine: ?*const IO_APC_ROUTINE,
+ ApcContext: ?*anyopaque,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ Buffer: *const anyopaque,
+ Length: ULONG,
+ ByteOffset: ?*const LARGE_INTEGER,
+ Key: ?*const ULONG,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn RtlSetCurrentDirectory_U(PathName: *UNICODE_STRING) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn NtUnlockFile(
+ FileHandle: HANDLE,
+ IoStatusBlock: *IO_STATUS_BLOCK,
+ ByteOffset: *const LARGE_INTEGER,
+ Length: *const LARGE_INTEGER,
+ Key: ULONG,
+) callconv(.winapi) NTSTATUS;
pub extern "ntdll" fn NtQueryObject(
Handle: HANDLE,
ObjectInformationClass: OBJECT_INFORMATION_CLASS,
- ObjectInformation: PVOID,
+ ObjectInformation: ?PVOID,
ObjectInformationLength: ULONG,
ReturnLength: ?*ULONG,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtQueryVolumeInformationFile(
- FileHandle: HANDLE,
- IoStatusBlock: *IO_STATUS_BLOCK,
- FsInformation: *anyopaque,
- Length: ULONG,
- FsInformationClass: FS_INFORMATION_CLASS,
+pub extern "ntdll" fn NtClose(
+ Handle: HANDLE,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn RtlWakeAddressAll(
- Address: ?*const anyopaque,
-) callconv(.winapi) void;
+pub extern "ntdll" fn NtCreateSection(
+ SectionHandle: *HANDLE,
+ DesiredAccess: ACCESS_MASK,
+ ObjectAttributes: ?*const OBJECT_ATTRIBUTES,
+ MaximumSize: ?*const LARGE_INTEGER,
+ SectionPageProtection: PAGE,
+ AllocationAttributes: SEC,
+ FileHandle: ?HANDLE,
+) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn RtlWakeAddressSingle(
- Address: ?*const anyopaque,
-) callconv(.winapi) void;
+pub extern "ntdll" fn NtAllocateVirtualMemory(
+ ProcessHandle: HANDLE,
+ BaseAddress: *PVOID,
+ ZeroBits: ULONG_PTR,
+ RegionSize: *SIZE_T,
+ AllocationType: MEM.ALLOCATE,
+ Protect: PAGE,
+) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn RtlWaitOnAddress(
- Address: ?*const anyopaque,
- CompareAddress: ?*const anyopaque,
- AddressSize: SIZE_T,
- Timeout: ?*const LARGE_INTEGER,
+pub extern "ntdll" fn NtFreeVirtualMemory(
+ ProcessHandle: HANDLE,
+ BaseAddress: *PVOID,
+ RegionSize: *SIZE_T,
+ FreeType: MEM.FREE,
+) callconv(.winapi) NTSTATUS;
+
+// ref: km/wdm.h
+
+pub extern "ntdll" fn RtlQueryRegistryValues(
+ RelativeTo: ULONG,
+ Path: PCWSTR,
+ QueryTable: [*]RTL_QUERY_REGISTRY_TABLE,
+ Context: ?*const anyopaque,
+ Environment: ?*const anyopaque,
) callconv(.winapi) NTSTATUS;
pub extern "ntdll" fn RtlEqualUnicodeString(
@@ -284,39 +286,153 @@ pub extern "ntdll" fn RtlUpcaseUnicodeChar(
SourceCharacter: u16,
) callconv(.winapi) u16;
-pub extern "ntdll" fn NtLockFile(
- FileHandle: HANDLE,
- Event: ?HANDLE,
- ApcRoutine: ?*IO_APC_ROUTINE,
- ApcContext: ?*anyopaque,
- IoStatusBlock: *IO_STATUS_BLOCK,
- ByteOffset: *const LARGE_INTEGER,
- Length: *const LARGE_INTEGER,
- Key: ?*ULONG,
- FailImmediately: BOOLEAN,
- ExclusiveLock: BOOLEAN,
+pub extern "ntdll" fn RtlFreeUnicodeString(
+ UnicodeString: *UNICODE_STRING,
+) callconv(.winapi) void;
+
+pub extern "ntdll" fn RtlGetVersion(
+ lpVersionInformation: *RTL_OSVERSIONINFOW,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn NtUnlockFile(
- FileHandle: HANDLE,
+// ref: um/winnt.h
+
+pub extern "ntdll" fn RtlLookupFunctionEntry(
+ ControlPc: usize,
+ ImageBase: *usize,
+ HistoryTable: *UNWIND_HISTORY_TABLE,
+) callconv(.winapi) ?*RUNTIME_FUNCTION;
+
+pub extern "ntdll" fn RtlVirtualUnwind(
+ HandlerType: DWORD,
+ ImageBase: usize,
+ ControlPc: usize,
+ FunctionEntry: *RUNTIME_FUNCTION,
+ ContextRecord: *CONTEXT,
+ HandlerData: *?PVOID,
+ EstablisherFrame: *usize,
+ ContextPointers: ?*KNONVOLATILE_CONTEXT_POINTERS,
+) callconv(.winapi) *EXCEPTION_ROUTINE;
+
+// ref: um/winternl.h
+
+pub extern "ntdll" fn NtWaitForSingleObject(
+ Handle: HANDLE,
+ Alertable: BOOLEAN,
+ Timeout: ?*const LARGE_INTEGER,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtQueryInformationProcess(
+ ProcessHandle: HANDLE,
+ ProcessInformationClass: PROCESSINFOCLASS,
+ ProcessInformation: *anyopaque,
+ ProcessInformationLength: ULONG,
+ ReturnLength: ?*ULONG,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtQueryInformationThread(
+ ThreadHandle: HANDLE,
+ ThreadInformationClass: THREADINFOCLASS,
+ ThreadInformation: *anyopaque,
+ ThreadInformationLength: ULONG,
+ ReturnLength: ?*ULONG,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtQuerySystemInformation(
+ SystemInformationClass: SYSTEM_INFORMATION_CLASS,
+ SystemInformation: PVOID,
+ SystemInformationLength: ULONG,
+ ReturnLength: ?*ULONG,
+) callconv(.winapi) NTSTATUS;
+
+// ref none
+
+pub extern "ntdll" fn NtQueryAttributesFile(
+ ObjectAttributes: *const OBJECT_ATTRIBUTES,
+ FileAttributes: *FILE.BASIC_INFORMATION,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtCreateEvent(
+ EventHandle: *HANDLE,
+ DesiredAccess: ACCESS_MASK,
+ ObjectAttributes: ?*const OBJECT_ATTRIBUTES,
+ EventType: EVENT_TYPE,
+ InitialState: BOOLEAN,
+) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn NtSetEvent(
+ EventHandle: HANDLE,
+ PreviousState: ?*LONG,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtCreateKeyedEvent(
+ KeyedEventHandle: *HANDLE,
+ DesiredAccess: ACCESS_MASK,
+ ObjectAttributes: ?*const OBJECT_ATTRIBUTES,
+ Flags: ULONG,
+) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn NtReleaseKeyedEvent(
+ EventHandle: ?HANDLE,
+ Key: ?*const anyopaque,
+ Alertable: BOOLEAN,
+ Timeout: ?*const LARGE_INTEGER,
+) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn NtWaitForKeyedEvent(
+ EventHandle: ?HANDLE,
+ Key: ?*const anyopaque,
+ Alertable: BOOLEAN,
+ Timeout: ?*const LARGE_INTEGER,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtCreateNamedPipeFile(
+ FileHandle: *HANDLE,
+ DesiredAccess: ACCESS_MASK,
+ ObjectAttributes: *const OBJECT_ATTRIBUTES,
IoStatusBlock: *IO_STATUS_BLOCK,
- ByteOffset: *const LARGE_INTEGER,
- Length: *const LARGE_INTEGER,
- Key: ?*ULONG,
+ ShareAccess: FILE.SHARE,
+ CreateDisposition: FILE.CREATE_DISPOSITION,
+ CreateOptions: FILE.MODE,
+ NamedPipeType: FILE.PIPE.TYPE,
+ ReadMode: FILE.PIPE.READ_MODE,
+ CompletionMode: FILE.PIPE.COMPLETION_MODE,
+ MaximumInstances: ULONG,
+ InboundQuota: ULONG,
+ OutboundQuota: ULONG,
+ DefaultTimeout: ?*const LARGE_INTEGER,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn NtMapViewOfSection(
+ SectionHandle: HANDLE,
+ ProcessHandle: HANDLE,
+ BaseAddress: ?*PVOID,
+ ZeroBits: ?*const ULONG,
+ CommitSize: SIZE_T,
+ SectionOffset: ?*LARGE_INTEGER,
+ ViewSize: *SIZE_T,
+ InheritDispostion: SECTION_INHERIT,
+ AllocationType: MEM.MAP,
+ PageProtection: PAGE,
+) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn NtUnmapViewOfSection(
+ ProcessHandle: HANDLE,
+ BaseAddress: PVOID,
+) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn NtUnmapViewOfSectionEx(
+ ProcessHandle: HANDLE,
+ BaseAddress: PVOID,
+ UnmapFlags: MEM.UNMAP,
) callconv(.winapi) NTSTATUS;
pub extern "ntdll" fn NtOpenKey(
KeyHandle: *HANDLE,
DesiredAccess: ACCESS_MASK,
- ObjectAttributes: OBJECT_ATTRIBUTES,
+ ObjectAttributes: *const OBJECT_ATTRIBUTES,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn RtlQueryRegistryValues(
- RelativeTo: ULONG,
- Path: PCWSTR,
- QueryTable: [*]RTL_QUERY_REGISTRY_TABLE,
- Context: ?*anyopaque,
- Environment: ?*anyopaque,
+pub extern "ntdll" fn NtQueueApcThread(
+ ThreadHandle: HANDLE,
+ ApcRoutine: *const IO_APC_ROUTINE,
+ ApcArgument1: ?*anyopaque,
+ ApcArgument2: ?*anyopaque,
+ ApcArgument3: ?*anyopaque,
) callconv(.winapi) NTSTATUS;
pub extern "ntdll" fn NtReadVirtualMemory(
@@ -326,7 +442,6 @@ pub extern "ntdll" fn NtReadVirtualMemory(
NumberOfBytesToRead: SIZE_T,
NumberOfBytesRead: ?*SIZE_T,
) callconv(.winapi) NTSTATUS;
-
pub extern "ntdll" fn NtWriteVirtualMemory(
ProcessHandle: HANDLE,
BaseAddress: ?PVOID,
@@ -334,51 +449,15 @@ pub extern "ntdll" fn NtWriteVirtualMemory(
NumberOfBytesToWrite: SIZE_T,
NumberOfBytesWritten: ?*SIZE_T,
) callconv(.winapi) NTSTATUS;
-
pub extern "ntdll" fn NtProtectVirtualMemory(
ProcessHandle: HANDLE,
BaseAddress: *?PVOID,
NumberOfBytesToProtect: *SIZE_T,
- NewAccessProtection: ULONG,
- OldAccessProtection: *ULONG,
+ NewAccessProtection: PAGE,
+ OldAccessProtection: *PAGE,
) callconv(.winapi) NTSTATUS;
-pub extern "ntdll" fn RtlExitUserProcess(
- ExitStatus: u32,
-) callconv(.winapi) noreturn;
-
-pub extern "ntdll" fn NtCreateNamedPipeFile(
- FileHandle: *HANDLE,
- DesiredAccess: ULONG,
- ObjectAttributes: *OBJECT_ATTRIBUTES,
- IoStatusBlock: *IO_STATUS_BLOCK,
- ShareAccess: ULONG,
- CreateDisposition: ULONG,
- CreateOptions: ULONG,
- NamedPipeType: ULONG,
- ReadMode: ULONG,
- CompletionMode: ULONG,
- MaximumInstances: ULONG,
- InboundQuota: ULONG,
- OutboundQuota: ULONG,
- DefaultTimeout: *LARGE_INTEGER,
-) callconv(.winapi) NTSTATUS;
-
-pub extern "ntdll" fn NtAllocateVirtualMemory(
- ProcessHandle: HANDLE,
- BaseAddress: ?*PVOID,
- ZeroBits: ULONG_PTR,
- RegionSize: ?*SIZE_T,
- AllocationType: ULONG,
- PageProtection: ULONG,
-) callconv(.winapi) NTSTATUS;
-
-pub extern "ntdll" fn NtFreeVirtualMemory(
- ProcessHandle: HANDLE,
- BaseAddress: ?*PVOID,
- RegionSize: *SIZE_T,
- FreeType: ULONG,
-) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn NtYieldExecution() callconv(.winapi) NTSTATUS;
pub extern "ntdll" fn RtlAddVectoredExceptionHandler(
First: ULONG,
@@ -388,6 +467,29 @@ pub extern "ntdll" fn RtlRemoveVectoredExceptionHandler(
Handle: HANDLE,
) callconv(.winapi) ULONG;
+pub extern "ntdll" fn RtlDosPathNameToNtPathName_U(
+ DosPathName: [*:0]const u16,
+ NtPathName: *UNICODE_STRING,
+ NtFileNamePart: ?*?[*:0]const u16,
+ DirectoryInfo: ?*CURDIR,
+) callconv(.winapi) BOOL;
+
+pub extern "ntdll" fn RtlExitUserProcess(
+ ExitStatus: u32,
+) callconv(.winapi) noreturn;
+
+/// Returns the number of bytes written to `Buffer`.
+/// If the returned count is larger than `BufferByteLength`, the buffer was too small.
+/// If the returned count is zero, an error occurred.
+pub extern "ntdll" fn RtlGetFullPathName_U(
+ FileName: [*:0]const u16,
+ BufferByteLength: ULONG,
+ Buffer: [*]u16,
+ ShortName: ?*[*:0]const u16,
+) callconv(.winapi) ULONG;
+
+pub extern "ntdll" fn RtlGetSystemTimePrecise() callconv(.winapi) LARGE_INTEGER;
+
pub extern "ntdll" fn RtlInitializeCriticalSection(
lpCriticalSection: *CRITICAL_SECTION,
) callconv(.winapi) NTSTATUS;
@@ -401,6 +503,28 @@ pub extern "ntdll" fn RtlDeleteCriticalSection(
lpCriticalSection: *CRITICAL_SECTION,
) callconv(.winapi) NTSTATUS;
+pub extern "ntdll" fn RtlQueryPerformanceCounter(
+ PerformanceCounter: *LARGE_INTEGER,
+) callconv(.winapi) BOOL;
+pub extern "ntdll" fn RtlQueryPerformanceFrequency(
+ PerformanceFrequency: *LARGE_INTEGER,
+) callconv(.winapi) BOOL;
+pub extern "ntdll" fn NtQueryPerformanceCounter(
+ PerformanceCounter: *LARGE_INTEGER,
+ PerformanceFrequency: ?*LARGE_INTEGER,
+) callconv(.winapi) NTSTATUS;
+
+pub extern "ntdll" fn RtlReAllocateHeap(
+ HeapHandle: *HEAP,
+ Flags: HEAP.FLAGS.ALLOCATION,
+ BaseAddress: ?PVOID,
+ Size: SIZE_T,
+) callconv(.winapi) ?PVOID;
+
+pub extern "ntdll" fn RtlSetCurrentDirectory_U(
+ PathName: *UNICODE_STRING,
+) callconv(.winapi) NTSTATUS;
+
pub extern "ntdll" fn RtlTryAcquireSRWLockExclusive(
SRWLock: *SRWLOCK,
) callconv(.winapi) BOOLEAN;
@@ -411,21 +535,22 @@ pub extern "ntdll" fn RtlReleaseSRWLockExclusive(
SRWLock: *SRWLOCK,
) callconv(.winapi) void;
+pub extern "ntdll" fn RtlWakeAddressAll(
+ Address: ?*const anyopaque,
+) callconv(.winapi) void;
+pub extern "ntdll" fn RtlWakeAddressSingle(
+ Address: ?*const anyopaque,
+) callconv(.winapi) void;
+pub extern "ntdll" fn RtlWaitOnAddress(
+ Address: ?*const anyopaque,
+ CompareAddress: ?*const anyopaque,
+ AddressSize: SIZE_T,
+ Timeout: ?*const LARGE_INTEGER,
+) callconv(.winapi) NTSTATUS;
+
pub extern "ntdll" fn RtlWakeConditionVariable(
ConditionVariable: *CONDITION_VARIABLE,
) callconv(.winapi) void;
pub extern "ntdll" fn RtlWakeAllConditionVariable(
ConditionVariable: *CONDITION_VARIABLE,
) callconv(.winapi) void;
-
-pub extern "ntdll" fn RtlReAllocateHeap(
- HeapHandle: HANDLE,
- Flags: ULONG,
- BaseAddress: PVOID,
- Size: SIZE_T,
-) callconv(.winapi) ?PVOID;
-pub extern "ntdll" fn RtlAllocateHeap(
- HeapHandle: HANDLE,
- Flags: ULONG,
- Size: SIZE_T,
-) callconv(.winapi) ?PVOID;
diff --git a/lib/std/posix.zig b/lib/std/posix.zig
@@ -1041,18 +1041,16 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
if (native_os == .windows) {
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
- var eof_info = windows.FILE_END_OF_FILE_INFORMATION{
+ const eof_info: windows.FILE.END_OF_FILE_INFORMATION = .{
.EndOfFile = signed_len,
};
-
const rc = windows.ntdll.NtSetInformationFile(
fd,
&io_status_block,
&eof_info,
- @sizeOf(windows.FILE_END_OF_FILE_INFORMATION),
- .FileEndOfFileInformation,
+ @sizeOf(windows.FILE.END_OF_FILE_INFORMATION),
+ .EndOfFile,
);
-
switch (rc) {
.SUCCESS => return,
.INVALID_HANDLE => unreachable, // Handle not open for writing
@@ -2691,8 +2689,11 @@ pub fn mkdirW(dir_path_w: []const u16, mode: mode_t) MakeDirError!void {
_ = mode;
const sub_dir_handle = windows.OpenFile(dir_path_w, .{
.dir = fs.cwd().fd,
- .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,
- .creation = windows.FILE_CREATE,
+ .access_mask = .{
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{ .READ = true },
+ },
+ .creation = .CREATE,
.filter = .dir_only,
}) catch |err| switch (err) {
error.IsDir => return error.Unexpected,
diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig
@@ -762,10 +762,12 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void {
const nul_handle = if (any_ignore)
// "\Device\Null" or "\??\NUL"
windows.OpenFile(&[_]u16{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'N', 'u', 'l', 'l' }, .{
- .access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE | windows.SYNCHRONIZE,
- .share_access = windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE,
+ .access_mask = .{
+ .STANDARD = .{ .SYNCHRONIZE = true },
+ .GENERIC = .{ .WRITE = true, .READ = true },
+ },
.sa = &saAttr,
- .creation = windows.OPEN_EXISTING,
+ .creation = .OPEN,
}) catch |err| switch (err) {
error.PathAlreadyExists => return error.Unexpected, // not possible for "NUL"
error.PipeBusy => return error.Unexpected, // not possible for "NUL"
@@ -1174,7 +1176,7 @@ fn windowsCreateProcessPathExt(
&io_status,
&file_information_buf,
file_information_buf.len,
- .FileDirectoryInformation,
+ .Directory,
windows.FALSE, // single result
&app_name_unicode_string,
windows.FALSE, // restart iteration
@@ -1198,7 +1200,7 @@ fn windowsCreateProcessPathExt(
var it = windows.FileInformationIterator(windows.FILE_DIRECTORY_INFORMATION){ .buf = &file_information_buf };
while (it.next()) |info| {
// Skip directories
- if (info.FileAttributes & windows.FILE_ATTRIBUTE_DIRECTORY != 0) continue;
+ if (info.FileAttributes.DIRECTORY) continue;
const filename = @as([*]u16, @ptrCast(&info.FileName))[0 .. info.FileNameLength / 2];
// Because all results start with the app_name since we're using the wildcard `app_name*`,
// if the length is equal to app_name then this is an exact match
@@ -1415,11 +1417,11 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
var sattr_copy = sattr.*;
const write_handle = windows.kernel32.CreateFileW(
pipe_path.ptr,
- windows.GENERIC_WRITE,
+ .{ .GENERIC = .{ .WRITE = true } },
0,
&sattr_copy,
windows.OPEN_EXISTING,
- windows.FILE_ATTRIBUTE_NORMAL,
+ @bitCast(windows.FILE.ATTRIBUTE{ .NORMAL = true }),
null,
);
if (write_handle == windows.INVALID_HANDLE_VALUE) {
diff --git a/lib/std/zig/WindowsSdk.zig b/lib/std/zig/WindowsSdk.zig
@@ -250,13 +250,15 @@ const RegistryWtf16Le = struct {
/// After finishing work, call `closeKey`.
fn openKey(hkey: windows.HKEY, key_wtf16le: [:0]const u16, options: OpenOptions) error{KeyNotFound}!RegistryWtf16Le {
var key: windows.HKEY = undefined;
- var access: windows.REGSAM = windows.KEY_QUERY_VALUE | windows.KEY_ENUMERATE_SUB_KEYS;
- if (options.wow64_32) access |= windows.KEY_WOW64_32KEY;
const return_code_int: windows.HRESULT = windows.advapi32.RegOpenKeyExW(
hkey,
key_wtf16le,
0,
- access,
+ .{ .SPECIFIC = .{ .KEY = .{
+ .QUERY_VALUE = true,
+ .ENUMERATE_SUB_KEYS = true,
+ .WOW64_32KEY = options.wow64_32,
+ } } },
&key,
);
const return_code: windows.Win32Error = @enumFromInt(return_code_int);
@@ -389,7 +391,10 @@ const RegistryWtf16Le = struct {
const return_code_int: windows.HRESULT = std.os.windows.advapi32.RegLoadAppKeyW(
absolute_path_as_wtf16le,
&key,
- windows.KEY_QUERY_VALUE | windows.KEY_ENUMERATE_SUB_KEYS,
+ .{ .SPECIFIC = .{ .KEY = .{
+ .QUERY_VALUE = true,
+ .ENUMERATE_SUB_KEYS = true,
+ } } },
0,
0,
);
diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig
@@ -953,12 +953,19 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {
if (is_windows) {
if (mf.section == windows.INVALID_HANDLE_VALUE) switch (windows.ntdll.NtCreateSection(
&mf.section,
- windows.STANDARD_RIGHTS_REQUIRED | windows.SECTION_QUERY |
- windows.SECTION_MAP_WRITE | windows.SECTION_MAP_READ | windows.SECTION_EXTEND_SIZE,
+ .{
+ .SPECIFIC = .{ .SECTION = .{
+ .QUERY = true,
+ .MAP_WRITE = true,
+ .MAP_READ = true,
+ .EXTEND_SIZE = true,
+ } },
+ .STANDARD = .{ .RIGHTS = .REQUIRED },
+ },
null,
@constCast(&@as(i64, @intCast(aligned_capacity))),
- windows.PAGE_READWRITE,
- windows.SEC_COMMIT,
+ .{ .READWRITE = true },
+ .{ .COMMIT = true },
mf.file.handle,
)) {
.SUCCESS => {},
@@ -974,9 +981,9 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {
0,
null,
&contents_len,
- .ViewUnmap,
- 0,
- windows.PAGE_READWRITE,
+ .Unmap,
+ .{},
+ .{ .READWRITE = true },
)) {
.SUCCESS => mf.contents = contents_ptr.?[0..contents_len],
else => return error.MemoryMappingNotSupported,